Skip to content

Commit

Permalink
Merge pull request #917 from robertpanzer/create-list
Browse files Browse the repository at this point in the history
Fixes #916. Add factory methods to create lists
  • Loading branch information
robertpanzer authored May 2, 2020
2 parents 56371f3 + 0a463f1 commit 521490a
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 6 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ Improvement::
* Upgrade to Asciidoctor EPUB3 1.5.0-alpha.16
* Upgrade to Asciidoctor Diagram 2.0.1

Build::
Bug Fixes::

* Upgrade jruby-gradle-plugin to 2.0.0-alpha.7 and load Gems directly from rubygems.org instead of using torquebox Maven proxy.
* Add missing factory methods to create Lists. (@glisicivan) (#916)
The API `Processor.createList()` is experimental and may change with any release until declared to be stable.

Documentation::

Expand All @@ -33,6 +34,10 @@ Build::

* Upgrade to jruby-gradle-plugin 2.0.0

Known Limitations:

* The createList() and createListItem() API is not able to create DescriptionLists.

== 2.2.0 (2019-12-17)

Improvement::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,21 @@ public ListItem createListItem(org.asciidoctor.ast.List parent, String text) {
return delegate.createListItem(parent, text);
}

@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context) {
return delegate.createList(parent, context);
}

@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context, Map<String, Object> attributes, Map<Object, Object> options) {
return delegate.createList(parent, context, attributes, options);
}

@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context, Map<Object, Object> options) {
return delegate.createList(parent, context);
}

@Override
public ListItem createListItem(DescriptionList parent, String text) {
return delegate.createListItem(parent, text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,45 @@
*/
String PARAGRAPH = ":paragraph";

/**
* Predefined constant for making a Processor work on ordered lists.
*
* <pre>
* 1. First item
* 2. Second item
* </pre>
*/
String OLIST = ":olist";

/**
* Predefined constant for making a Processor work on unordered lists.
*
* <pre>
* . First item
* . Second item
* </pre>
*/
String ULIST = ":ulist";

/**
* Predefined constant for making a Processor work on unordered lists.
*
* <pre>
* . First item
* . Second item
* </pre>
*/
String COLIST = ":colist";

/**
* Predefined constant for making a Processor work on unordered lists.
*
* <pre>
* First:: The first item
* Second:: The second item
* </pre>
*/
String DLIST = ":dlist";

String[] value();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,36 @@ public interface Processor {
*/
Document createDocument(Document parentDocument);

/**
* Creates a new List.
* This method is experimental and may change in future minor releases until declared to be stable.
* @param parent The block to which the parsed content should be added as children.
* @param context Either {@code "olist"}, {@code ulist}, {@code colist} or {@code dlist}
* @return A List node that can be added to the AST of a document.
*/
org.asciidoctor.ast.List createList(StructuralNode parent, String context);

/**
* Creates a new List.
* This method is experimental and may change in future minor releases until declared to be stable.
* @param parent The block to which the parsed content should be added as children.
* @param context Either {@code "olist"}, {@code ulist}, {@code colist} or {@code dlist}
* @param attributes Additional attributes to be set on the new list node, e.g. <code>Collections.singletonMap("start", "2")</code>.
* @param options Additional options to be set on the new list node.
* @return A List node that can be added to the AST of a document.
*/
org.asciidoctor.ast.List createList(StructuralNode parent, String context, Map<String, Object> attributes, Map<Object, Object> options);

/**
* Creates a new List.
* This method is experimental and may change in future minor releases until declared to be stable.
* @param parent The block to which the parsed content should be added as children.
* @param context Either {@code "olist"}, {@code ulist}, {@code colist} or {@code dlist}
* @param options Additional options to be set on the new list node.
* @return A List node that can be added to the AST of a document.
*/
org.asciidoctor.ast.List createList(StructuralNode parent, String context, Map<Object, Object> options);

ListItem createListItem(final org.asciidoctor.ast.List parent, final String text);

ListItem createListItem(final org.asciidoctor.ast.DescriptionList parent, final String text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@
import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.ast.Document;
import org.asciidoctor.ast.ListItem;
import org.asciidoctor.jruby.ast.impl.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.extension.Processor;
import org.asciidoctor.extension.Reader;
import org.asciidoctor.jruby.ast.impl.ColumnImpl;
import org.asciidoctor.jruby.ast.impl.ContentNodeImpl;
import org.asciidoctor.jruby.ast.impl.DescriptionListImpl;
import org.asciidoctor.jruby.ast.impl.DocumentImpl;
import org.asciidoctor.jruby.ast.impl.ListImpl;
import org.asciidoctor.jruby.ast.impl.NodeConverter;
import org.asciidoctor.jruby.ast.impl.RowImpl;
import org.asciidoctor.jruby.ast.impl.StructuralNodeImpl;
import org.asciidoctor.extension.Processor;
import org.asciidoctor.extension.Reader;
import org.asciidoctor.jruby.internal.JRubyAsciidoctor;
import org.asciidoctor.jruby.internal.JRubyRuntimeContext;
import org.asciidoctor.jruby.internal.RubyHashUtil;
Expand Down Expand Up @@ -291,6 +291,38 @@ public Document createDocument(Document parentDocument) {
return (Document) NodeConverter.createASTNode(runtime, NodeConverter.NodeType.DOCUMENT_CLASS, runtime.getNil(), options);
}


@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context) {
return createList(parent, context, new HashMap<>(), new HashMap<>());

}

@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context,
Map<String, Object> attributes,
Map<Object, Object> options) {

options.put(Options.ATTRIBUTES, new HashMap<>(attributes));
return createList(parent, context, options);
}

@Override
public org.asciidoctor.ast.List createList(StructuralNode parent, String context,
Map<Object, Object> options) {

Ruby rubyRuntime = JRubyRuntimeContext.get(parent);

RubyHash convertMapToRubyHashWithSymbols = RubyHashUtil.convertMapToRubyHashWithSymbolsIfNecessary(rubyRuntime,
filterBlockOptions(parent, options, "subs", ContentModel.KEY));

IRubyObject[] parameters = {
((StructuralNodeImpl) parent).getRubyObject(),
RubyUtils.toSymbol(rubyRuntime, context),
convertMapToRubyHashWithSymbols};
return (org.asciidoctor.ast.List) NodeConverter.createASTNode(rubyRuntime, NodeConverter.NodeType.LIST_CLASS, parameters);
}

@Override
public ListItem createListItem(final org.asciidoctor.ast.List parent, final String text) {
Ruby rubyRuntime = JRubyRuntimeContext.get(parent);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.asciidoctor.extension


import org.asciidoctor.ast.StructuralNode

@Name('list')
class ListCreatorBlockMacro extends BlockMacroProcessor {

String context

ListCreatorBlockMacro(String context) {
this.context = context
}

@Override
Object process(StructuralNode parent, String target, Map<String, Object> attributes) {

def attrs = new HashMap<String, Object>()
attrs['start'] = '42'
def opts = new HashMap<Object, Object>()

org.asciidoctor.ast.List list = createList(parent, context, attrs, opts)

list.getBlocks().add(createListItem(list, 'First item'))
list.getBlocks().add(createListItem(list, 'Second item'))

list
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.asciidoctor.extension

import org.asciidoctor.Asciidoctor
import org.asciidoctor.OptionsBuilder
import org.asciidoctor.SafeMode
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 WhenABlockMacroProcessorCreatesAList extends Specification {

public static final String LISTMACRO_NAME = 'list'
public static final String UTF_8 = 'UTF-8'
public static final String OL = 'ol'
public static final String UL = 'ul'
public static final String LI = 'li'
public static final String FIRST_ITEM = 'First item'
public static final String SECOND_ITEM = 'Second item'

@ArquillianResource
private Asciidoctor asciidoctor

private static final String DOCUMENT = '''
= Section Creation Test
list::HelloWorld[]
'''

def "the ordered list should appear in the resulting document"() {

given:
asciidoctor.javaExtensionRegistry().blockMacro(LISTMACRO_NAME, new ListCreatorBlockMacro('olist'))

when:
String result = asciidoctor.convert(DOCUMENT, OptionsBuilder.options().safe(SafeMode.SAFE).toFile(false).headerFooter(false))

then:
noExceptionThrown()
Document htmlDocument = Jsoup.parse(result, UTF_8)

htmlDocument.select(OL).size() == 1
def ol = htmlDocument.select(OL).first()
ol.attr('start') == '42'
def items = ol.select(LI)
items.size() == 2
items.get(0).text() == FIRST_ITEM
items.get(1).text() == SECOND_ITEM
}

def "the unordered list should appear in the resulting document"() {

given:
asciidoctor.javaExtensionRegistry().blockMacro(LISTMACRO_NAME, new ListCreatorBlockMacro('ulist'))

when:
String result = asciidoctor.convert(DOCUMENT, OptionsBuilder.options().safe(SafeMode.SAFE).toFile(false).headerFooter(false))

then:
noExceptionThrown()
Document htmlDocument = Jsoup.parse(result, UTF_8)

htmlDocument.select(UL).size() == 1
def ul = htmlDocument.select(UL).first()
def items = ul.select(LI)
items.size() == 2
items.get(0).text() == FIRST_ITEM
items.get(1).text() == SECOND_ITEM
}
}
6 changes: 5 additions & 1 deletion config/codenarc/codenarc.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,9 @@ ruleset {
exclude 'UnnecessaryGetter'
exclude 'UnnecessaryCollectCall'
}
ruleset('rulesets/dry.xml')
ruleset('rulesets/dry.xml') {
'DuplicateNumberLiteral' {
ignoreNumbers = '0,1,2'
}
}
}

0 comments on commit 521490a

Please sign in to comment.