Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document breaking changes to processors in migration guide #1210

Merged
merged 3 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/modules/guides/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
* Help & Guides
** Updating to New Releases
***xref:api-migration-guide-v25x-to-v30.adoc[]
*** xref:api-migration-guide-v25x-to-v30.adoc[]
*** xref:extension-migration-guide-16-to-20.adoc[]
*** xref:extension-migration-guide-15-to-16.adoc[]
** Running in Frameworks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ Map<String, Object> attributesMap = attributes.map();
----

include::partial$removal-of-deprecated-methods-in-asciidoctor.adoc[]

include::partial$update-preprocessor-api.adoc[]

include::partial$update-macro-api.adoc[]
75 changes: 75 additions & 0 deletions docs/modules/guides/partials/update-macro-api.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
== Update Macro Processors

In the earlier version of AsciidoctorJ (2.5.x), the signature of Macro Processors required the implementation to return an unrestricted Object.
However, the specific type that a Macro Processor had to return was unclear, making it difficult to understand the necessary implementation steps.

To address this issue, AsciidoctorJ 3.x.x has introduced the following changes:

`InlineMacroProcessor::process`::
The implementation of this method now needs to return a `PhraseNode`.
Please update your code accordingly to ensure that the returned value is of type `PhraseNode`.
`BlockMacroProcessor::process`::
The implementation of this method now needs to return a `StructuralNode`.
Make sure to modify your implementation to return a `StructuralNode` as required.

Moreover, there was a problem with the first parameter of the process method in InlineMacroProcessors.
Previously, it incorrectly expected a `PhraseNode` as the first parameter.

To resolve this issue, AsciidoctorJ 3.x.x has rectified the first parameter of `InlineMacroProcessor::process` to be a `StructuralNode`.
Please ensure that you update your code accordingly to reflect this change.

If you have any further questions or concerns, please refer to the updated documentation.

=== Update Inline Macro Processors

If your existing InlineMacroProcessor looks like this for AsciidoctorJ 2.5.x:

[,java]
----
public class TestInlineMacro extends InlineMacroProcessor {
@Override
public Object process(ContentNode parent, String target, Map<String, Object> attributes) {
return createPhraseNode(parent, "quoted", "This is from an Inline Macro");
}
}
----

then you have to change it to this for AsciidoctorJ 3.x.x:

[,java]
----
public class TestInlineMacro extends InlineMacroProcessor {
@Override
public PhraseNode process(StructuralNode parent, String target, Map<String, Object> attributes) {
return createPhraseNode(parent, "quoted", "This is from an Inline Macro");
}
}
----

In the above example you can see that the return type and the type of the first parameter of the process method have changed.

=== Update Block Macro Processors

If your existing BlockMacroProcessor looks like this for AsciidoctorJ 2.5.x:

[,java]
----
public class TestBlockMacro extends BlockMacroProcessor {
@Override
public Object process(StructuralNode parent, String target, Map<String, Object> attributes) {
return createBlock(parent, "paragraph", "This is from a Block Macro");
}
}
----

then you have to change it to this for AsciidoctorJ 3.x.x:

[,java]
----
public class TestBlockMacro extends BlockMacroProcessor {
@Override
public StructuralNode process(StructuralNode parent, String target, Map<String, Object> attributes) {
return createBlock(parent, "paragraph", "This is from a Block Macro");
}
}
----
43 changes: 43 additions & 0 deletions docs/modules/guides/partials/update-preprocessor-api.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
== Update Preprocessors

In earlier versions of AsciidoctorJ (up to 2.5.x), Preprocessors were provided with a `Reader` object that they had to modify directly.
Unlike the Ruby implementation, the Java implementation of Asciidoctor did not support Preprocessors to return a new `Reader`.

To address this limitation, AsciidoctorJ 3.0.0 has introduced a fix, enabling Preprocessors to create and return a new `Reader`.
This enhancement allows Preprocessors to have more flexibility and enables a cleaner implementation.

If you have existing Preprocessors, it is essential to update the signature of their process method to return a Reader object, even if the implementation does not create a new Reader object and returns null.

The following example shows how to update a Preprocessor to return a new `Reader`:

.Preprocessor for AsciidoctorJ 2.5.x
[,java]
----
public static class MyPreprocessor extends Preprocessor {

@Override
public void process(Document document, PreprocessorReader reader) {
// Do something with the reader
}
}
----

To ensure compatibility with AsciidoctorJ 3.0.0, the process method of the Preprocessor needs to be modified to return a `Reader`.
However, if you wish to maintain the same behavior as before, the method can simply return `null`.

.Preprocessor for AsciidoctorJ 3.x.x
[,java]
----
public static class MyPreprocessor extends Preprocessor {

@Override
public Reader process(Document document, PreprocessorReader reader) {
// Do something with the reader
return null;
}
}
----

You may find it helpful to review the methods `Processor::newReader` and `PreprocessorReader::read` to simplify your code when creating a new `Reader` and reading the content of the existing `Reader`.

However, please note that following the steps mentioned above will be sufficient to migrate your existing processor.