diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/DescriptionListEntry.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/DescriptionListEntry.java
index bba3d9b25..9e6bbf2f6 100644
--- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/DescriptionListEntry.java
+++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/DescriptionListEntry.java
@@ -6,4 +6,22 @@ public interface DescriptionListEntry {
ListItem getDescription();
+ /**
+ * Sets a new description for a description list item.
+ * Description list items are ordinary ListItems and can be created using the factory methods of
+ * a processor:
+ *
+ * @param description The new description for this description list entry,
+ */
+ void setDescription(final ListItem description);
+
}
diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/impl/DescriptionListEntryImpl.java b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/impl/DescriptionListEntryImpl.java
index 32d11d22a..edf86b3a1 100644
--- a/asciidoctorj-core/src/main/java/org/asciidoctor/ast/impl/DescriptionListEntryImpl.java
+++ b/asciidoctorj-core/src/main/java/org/asciidoctor/ast/impl/DescriptionListEntryImpl.java
@@ -4,6 +4,7 @@
import org.asciidoctor.ast.ListItem;
import org.asciidoctor.ast.NodeConverter;
import org.asciidoctor.internal.RubyBlockListDecorator;
+import org.asciidoctor.internal.RubyObjectWrapper;
import org.jruby.RubyArray;
import org.jruby.runtime.builtin.IRubyObject;
@@ -26,7 +27,17 @@ public ListItem getDescription() {
return firstItem == null ? null : (ListItem) NodeConverter.createASTNode(firstItem);
}
+ public void setDescription(final ListItem description) {
+ setAt(1, description);
+ }
+
private Object getAt(int i) {
return ((RubyArray) getRubyObject()).get(i);
}
+
+ private void setAt(int i, Object object) {
+ ((RubyArray) getRubyObject()).set(i, RubyObjectWrapper.class.cast(object).getRubyObject());
+ }
+
+
}
diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/extension/Processor.java b/asciidoctorj-core/src/main/java/org/asciidoctor/extension/Processor.java
index e2278ecb2..36c52f110 100644
--- a/asciidoctorj-core/src/main/java/org/asciidoctor/extension/Processor.java
+++ b/asciidoctorj-core/src/main/java/org/asciidoctor/extension/Processor.java
@@ -1,10 +1,24 @@
package org.asciidoctor.extension;
import org.asciidoctor.Options;
-import org.asciidoctor.ast.*;
+import org.asciidoctor.ast.Block;
+import org.asciidoctor.ast.Cell;
+import org.asciidoctor.ast.Column;
+import org.asciidoctor.ast.ContentModel;
+import org.asciidoctor.ast.ContentNode;
+import org.asciidoctor.ast.Document;
+import org.asciidoctor.ast.ListItem;
+import org.asciidoctor.ast.NodeConverter;
+import org.asciidoctor.ast.PhraseNode;
+import org.asciidoctor.ast.Row;
+import org.asciidoctor.ast.Section;
+import org.asciidoctor.ast.StructuralNode;
+import org.asciidoctor.ast.Table;
import org.asciidoctor.ast.impl.ColumnImpl;
import org.asciidoctor.ast.impl.ContentNodeImpl;
+import org.asciidoctor.ast.impl.DescriptionListImpl;
import org.asciidoctor.ast.impl.DocumentImpl;
+import org.asciidoctor.ast.impl.ListImpl;
import org.asciidoctor.ast.impl.RowImpl;
import org.asciidoctor.ast.impl.StructuralNodeImpl;
import org.asciidoctor.internal.JRubyRuntimeContext;
@@ -21,7 +35,14 @@
import java.util.List;
import java.util.Map;
-import static org.asciidoctor.ast.NodeConverter.NodeType.*;
+import static org.asciidoctor.ast.NodeConverter.NodeType.BLOCK_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.DOCUMENT_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.INLINE_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.LIST_ITEM_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.SECTION_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.TABLE_CELL_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.TABLE_CLASS;
+import static org.asciidoctor.ast.NodeConverter.NodeType.TABLE_COLUMN_CLASS;
public class Processor {
@@ -352,6 +373,18 @@ public Document createDocument(Document parentDocument) {
return (Document) NodeConverter.createASTNode(runtime, DOCUMENT_CLASS, runtime.getNil(), options);
}
+ public ListItem createListItem(final org.asciidoctor.ast.List parent, final String text) {
+ Ruby rubyRuntime = JRubyRuntimeContext.get(parent);
+
+ return (ListItem) NodeConverter.createASTNode(rubyRuntime, LIST_ITEM_CLASS, ListImpl.class.cast(parent).getRubyObject(), rubyRuntime.newString(text));
+ }
+
+ public ListItem createListItem(final org.asciidoctor.ast.DescriptionList parent, final String text) {
+ Ruby rubyRuntime = JRubyRuntimeContext.get(parent);
+
+ return (ListItem) NodeConverter.createASTNode(rubyRuntime, LIST_ITEM_CLASS, DescriptionListImpl.class.cast(parent).getRubyObject(), rubyRuntime.newString(text));
+ }
+
/**
* Parses the given raw asciidoctor content, parses it and appends it as children to the given parent block.
*
+ * class MyTreeprocessor extends Treeprocessor() {
+ * public Document process(Document doc) {
+ * final String newDescription = "A new description for this entry.";
+ * DescriptionList dl = ...
+ * DescriptionListEntry dlEntry = ...
+ * dlEntry.setDescription(createListItem(dl, newDescription));
+ * return doc;
+ * }
+ * }
The following example will add two paragraphs with the role {@code newcontent} to all top diff --git a/asciidoctorj-core/src/test/groovy/org/asciidoctor/WhenADocumentContainsADefinitionList.groovy b/asciidoctorj-core/src/test/groovy/org/asciidoctor/WhenADocumentContainsADefinitionList.groovy index c8c449bbc..c10cf998a 100644 --- a/asciidoctorj-core/src/test/groovy/org/asciidoctor/WhenADocumentContainsADefinitionList.groovy +++ b/asciidoctorj-core/src/test/groovy/org/asciidoctor/WhenADocumentContainsADefinitionList.groovy @@ -6,14 +6,17 @@ import org.asciidoctor.ast.DescriptionListEntry import org.asciidoctor.ast.Document import org.asciidoctor.ast.ListItem import org.asciidoctor.converter.StringConverter +import org.asciidoctor.extension.Treeprocessor import org.jboss.arquillian.spock.ArquillianSputnik import org.jboss.arquillian.test.api.ArquillianResource +import org.jsoup.Jsoup import org.junit.runner.RunWith import spock.lang.Specification @RunWith(ArquillianSputnik) class WhenADocumentContainsADefinitionList extends Specification { + static final String TAG_DD = 'dd' @ArquillianResource private Asciidoctor asciidoctor @@ -142,4 +145,31 @@ A very nice description ''' } + def 'a processor should be able to set the description of a description list'() { + + given: + String document = '''= Test document + +Item A:: + Replace me +''' + String newDescription = 'A nice description' + + when: + asciidoctor.javaExtensionRegistry().treeprocessor(new Treeprocessor() { + @Override + Document process(Document doc) { + DescriptionList dl = doc.getBlocks().get(0) + DescriptionListEntry dlEntry = dl.items[0] + dlEntry.setDescription(createListItem(dl, newDescription)) + doc + } + }) + String result = asciidoctor.convert(document, OptionsBuilder.options().headerFooter(false).asMap()) + + then: + org.jsoup.nodes.Document htmlDoc = Jsoup.parse(result) + htmlDoc.getElementsByTag(TAG_DD).size() == 1 + htmlDoc.getElementsByTag(TAG_DD)[0].text() == newDescription + } }