asciidoctorj
asciidoctorj copied to clipboard
PreprocessorReader being manipulated is not acting like a Preprocessor
When registering a Preprocessor extension and pushing ifdef
or include
onto the PreprocessorReader, the directives are not being processed.
As @mojavelinux wrote in asciidoctor/asciidoctor-maven-plugin#210:
I tried this with a Ruby extension and it worked. I wonder if the delegation in AsciidoctorJ is causing the PreprocessorReader to not act like a preprocessor (instead just a regular reader).
...
In a quick test with AsciidoctorJ, but assumption seems to hold. The PreprocessorReader being manipulated is not acting like a Preprocessor. Very likely AsciidoctorJ would fail such a test. Therefore, this should be opened in AsciidoctorJ.
Until then, you'll have to push preprocessed lines onto the reader (in other words, you have to do the preprocessing yourself).
Hi systemdir!
Hmm, kinda works for me. I made the following test with the current master of asciidoctorj which is a few commits from 1.5.4, but nothing that could have any impact on this. (I guess :wink:)
I have the following asciidoctor files:
-
test.adoc
:
== Test
A test
XXX
-
included.adoc
:
This is the included content
The Preprocessor should add an include of included.doc
if it sees the content XXX
.
My Preprocessor looks like this:
public class IncluderPreprocessor extends Preprocessor {
public IncluderPreprocessor(Map<String, Object> config) {
super(config);
}
@Override
public PreprocessorReader process(Document document, PreprocessorReader reader) {
// Read the full document
List<String> lines = reader.readLines();
// Copy all lines into a new list, replacing a line 'XXX' with an include directive
List<String> newLines = new ArrayList<String>();
for (String line: lines) {
if (line.equals("XXX")) {
newLines.add("include::included.adoc[]");
} else if (line.trim().equals("")) {
newLines.add(" "); // That's a bad one: If we push empty lines they somehow get lost for whatever reason and we have no separate block, but that's another issue
} else {
newLines.add(line);
}
}
// For reuse. We always pass empty attributes
Map<String, Object> attributes = new HashMap<String, Object>();
// Finally push line by line in reverse order, it's a stack :)
for (int i = newLines.size() - 1; i >= 0; i--) {
reader.push_include(newLines.get(i), null, null, 1, attributes);
}
return reader;
}
}
And my test passes:
@Test
public void test() {
File f = classpath.getResource("includetest/test.adoc");
asciidoctor.javaExtensionRegistry().preprocessor(IncluderPreprocessor.class);
org.jsoup.nodes.Document document =
Jsoup.parse(
asciidoctor.convertFile(f, OptionsBuilder.options().toFile(false).headerFooter(false).safe(SafeMode.UNSAFE)));
assertEquals("This is the included content", document.select("p").get(1).text());
}
Cheers Robert
@robertpanzer Yes your test case works. But if included.adoc would include another .adoc then it will not be included and instead just the bare include::somefile.adoc will be printed out.