diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlock.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlock.java index 789fa8f0f..72e2801ff 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlock.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlock.java @@ -16,11 +16,24 @@ public interface AbstractBlock extends AbstractNode { */ String style(); String getStyle(); + /** + * @return The list of child blocks of this block * @deprecated Please use {@linkplain #getBlocks()} instead */ List blocks(); + + /** + * @return The list of child blocks of this block + */ List getBlocks(); + + /** + * Appends a new child block as the last block to this block. + * @param block The new child block added as last child to this block. + */ + void append(AbstractBlock block); + /** * @deprecated Please use {@linkplain #getContent()} instead */ diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlockImpl.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlockImpl.java index 02878af93..1a3a101df 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlockImpl.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractBlockImpl.java @@ -53,6 +53,12 @@ public List getBlocks() { return new RubyBlockListDecorator(rubyBlocks); } + @Override + public void append(AbstractBlock block) { + + getRubyObject().callMethod(runtime.getCurrentContext(), "<<", ((AbstractBlockImpl) block).getRubyObject()); + } + @Override public Object content() { return getContent(); diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNode.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNode.java index 9adebe732..f168c8356 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNode.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNode.java @@ -16,6 +16,8 @@ public interface AbstractNode { */ String getId(); + void setId(String id); + String getNodeName(); /** * @deprecated Use {@linkplain #getParent()} instead. diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNodeImpl.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNodeImpl.java index d9a508f48..aefceaffc 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNodeImpl.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/AbstractNodeImpl.java @@ -27,6 +27,11 @@ public String getId() { return getString("id"); } + @Override + public void setId(String id) { + setString("id", id); + } + @Override public String context() { return getContext(); diff --git a/asciidoctorj-core/src/test/groovy/org/asciidoctor/extension/WhenAnExtensionAppendsChildBlocks.groovy b/asciidoctorj-core/src/test/groovy/org/asciidoctor/extension/WhenAnExtensionAppendsChildBlocks.groovy new file mode 100644 index 000000000..853d7eb53 --- /dev/null +++ b/asciidoctorj-core/src/test/groovy/org/asciidoctor/extension/WhenAnExtensionAppendsChildBlocks.groovy @@ -0,0 +1,65 @@ +package org.asciidoctor.extension + +import org.asciidoctor.Asciidoctor +import org.asciidoctor.OptionsBuilder +import org.asciidoctor.ast.Block +import org.asciidoctor.ast.DocumentRuby +import org.asciidoctor.ast.Section +import org.jboss.arquillian.spock.ArquillianSputnik +import org.jboss.arquillian.test.api.ArquillianResource +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.junit.runner.RunWith +import spock.lang.Specification + +@RunWith(ArquillianSputnik) +class WhenAnExtensionAppendsChildBlocks extends Specification { + + String document = '''= Test document + +== Section 1 + +some text + +== Section 2 + +more text + +''' + + @ArquillianResource + private Asciidoctor asciidoctor + + def 'should be able to blocks via Block.append'() { + + given: + + final String additionalText = 'Text added by Treeprocessor' + asciidoctor.javaExtensionRegistry().treeprocessor(new Treeprocessor() { + + int lastid = 0 + + @Override + DocumentRuby process(DocumentRuby document) { + document.blocks.findAll { block -> block instanceof Section }.each { + block -> + Block newBlock = createBlock(block, 'paragraph', additionalText, [:]) + newBlock.id = "NewBlock_${lastid++}" + block.append(newBlock) + } + document + } + }) + + when: + String result = asciidoctor.convert(this.document, OptionsBuilder.options().headerFooter(false)) + + then: + Document htmlDocument = Jsoup.parse(result) + !htmlDocument.select('#NewBlock_0').empty + !htmlDocument.select('#NewBlock_1').empty + htmlDocument.select('#NewBlock_2').empty + + } + +}