[dev] How to map definition lists to AsciidoctorJ API

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[dev] How to map definition lists to AsciidoctorJ API

Robert.Panzer
I am writing this question to gather comments for the pull request https://github.com/asciidoctor/asciidoctorj/pull/408

One point that I missed in the mapping between the Asciidoctor core AST classes and the respective AsciidoctorJ classes is that items of a definition list are not own classes in Asciidoctor core that extend AbstractNode.
Instead these are arrays with 2 entries, where the first entry is a list containing a ListItem for every definition term (<dt>).
The second entry is the ListItem containing the definition data (<dd>).

So while
- A
- B
maps to a structure like this:
List [
 ListItem A,
 ListItem B
]
, a definition list like this:
A::
B:: C
D:: E
maps to
List [
 [[ListItem A, ListItem B], ListItem C],
 [[ListItem D], ListItem E]
]

As these arrays ([[ListItem A, ListItem B], ListItem C]) and ([[ListItem D], ListItem E]) are returned by List::blocks and due to the dynamic nature of Ruby this cannot be simply mapped to List.getBlocks() in AsciidoctorJ without letting it return a List<Object> instead of a List<StructuralNode>.

There are several approaches to resolve this problem:

A. List and DefinitionList with getBlocks() returning null

One approach would be to add a new AST type DefinitionList, that models only definition lists.
In this class getBlocks() would return null.
To access the list items a method getItems() could return a List<DefinitionListItem>, which in turn contains a list of ListItems for the definitionTerms and one ListItem for the definitionData.

This approach could be mapped accordingly to the normal List by letting getItems() return a List<ListItem> and getBlocks() also return null.

B. Change getBlocks() and/or getItems() to return a list of Objects

This means that List.getItems() returns a list of Objects which are either all ListItems for ordered and unordered Lists or arrays for definition Lists.
In the same way getBlocks() would have to return a list of Objects for all StructuralNodes.:
List<Object> block = section.getBlocks()
This would be the closest mapping to Asciidoctor Ruby, yet my personal opinion is that it's very confusing and the API would not feel very Java-like.

C. Invent a new DefinitionListItem that extends ListItem

Without adding a new class for definition lists, getItems() could return a list of DefinitionListItems that extend ListItem.
There are variations what how this DefinitionListItem could represent in the corresponding Ruby object space, but in the end it has to be ensured that the structure shown above using the nested lists can be built if a definition list is built from within a Java extension and converted for example by the Ruby HTML5 backend.

It would be great to get some feedback even though I could imagine that it is very hard to follow my strange thoughts.

Wdyt?

- Robert