Skip to content

Commit

Permalink
feat(parser/renderer): support rich content in labeled list item terms (
Browse files Browse the repository at this point in the history
#466)

Modify the grammar to include a new rule to parse the labeled list item term to find footnotes, images, links and quoted text, but only when processing the draft document into the final document. The draft document will still have a "raw" string term, to keep the parsing of the whole document fast.

Fixes #456
Fixes #460

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Jan 5, 2020
1 parent 6acb277 commit 6b58ad2
Show file tree
Hide file tree
Showing 12 changed files with 2,976 additions and 2,292 deletions.
Empty file added -s
Empty file.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ generate: prebuild-checks
generate-optimized:
@echo "generating the parser (optimized)..."
@pigeon -optimize-parser \
-alternate-entrypoints AsciidocDocument,AsciidocDocumentWithinDelimitedBlock,TextDocument,DocumentBlock,InlineElementsWithoutSubtitution,FileLocation,IncludedFileLine,InlineLinks \
-alternate-entrypoints AsciidocDocument,AsciidocDocumentWithinDelimitedBlock,TextDocument,DocumentBlock,InlineElementsWithoutSubtitution,FileLocation,IncludedFileLine,InlineLinks,LabeledListItemTerm \
-o ./pkg/parser/parser.go ./pkg/parser/parser.peg

.PHONY: test
Expand Down
30 changes: 23 additions & 7 deletions pkg/parser/document_processing_rearrange_lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parser

import (
"reflect"
"strings"

"github.com/bytesparadise/libasciidoc/pkg/types"

Expand Down Expand Up @@ -139,13 +140,6 @@ func appendOrderedListItem(lists []types.List, item *types.OrderedListItem) ([]t
list := types.NewOrderedList(item)
// also, force the current item level to (last seen level + 1)
item.Level = maxLevel + 1
// also, attach this list to the one above, if it exists ;)
// if len(lists) > 0 {
// parentList := &(lists[len(lists)-1])
// parentItem := (*parentList).LastItem()
// parentItem.AddElement(list)
// return append(lists, list), nil
// }
return append(lists, list), nil
}

Expand Down Expand Up @@ -185,6 +179,16 @@ func appendUnorderedListItem(lists []types.List, item *types.UnorderedListItem)
}

func appendLabeledListItem(lists []types.List, item types.LabeledListItem) ([]types.List, error) {
// first, let's parse the labeled list item term for more complex content
if len(item.Term) == 1 {
if term, ok := item.Term[0].(types.StringElement); ok {
var err error
item.Term, err = parseLabeledListItemTerm(term.Content)
if err != nil {
return nil, err
}
}
}
maxLevel := 0
log.Debugf("looking-up list for labeled list item with level=%d and term=%s", item.Level, item.Term)
for i, list := range lists {
Expand All @@ -210,6 +214,18 @@ func appendLabeledListItem(lists []types.List, item types.LabeledListItem) ([]ty
return append(lists, list), nil
}

// a labeled list item term may contain links, images, quoted text, footnotes, etc.
func parseLabeledListItemTerm(term string) ([]interface{}, error) {
result := []interface{}{}
elements, err := ParseReader("", strings.NewReader(term), Entrypoint("LabeledListItemTerm"))
if err != nil {
return []interface{}{}, errors.Wrap(err, "error while parsing content for inline links")
}
log.Debugf("parsed labeled list item term: '%+v'", elements)
result = append(result, elements.([]interface{})...)
return result, nil
}

func appendContinuedListItemElement(lists []types.List, item types.ContinuedListItemElement) []types.List {
lists = pruneLists(lists, len(lists)-1+item.Offset)
log.Debugf("appending continued list item element with offset=%d (depth=%d)", item.Offset, len(lists))
Expand Down
112 changes: 112 additions & 0 deletions pkg/parser/document_processing_rearrange_lists_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,4 +420,116 @@ var _ = Describe("rearrange lists", func() {
Expect(err).NotTo(HaveOccurred())
Expect(result).To(Equal(expected))
})

It("labeled list with rich terms", func() {
actual := []interface{}{
types.LabeledListItem{
Attributes: types.ElementAttributes{},
Level: 1,
Term: []interface{}{
types.StringElement{
Content: "`foo` term",
},
},
Elements: []interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: [][]interface{}{
{
types.StringElement{Content: "description 1"},
},
},
},
},
},
types.LabeledListItem{
Attributes: types.ElementAttributes{},
Level: 2,
Term: []interface{}{
types.StringElement{
Content: "`bar` term",
},
},
Elements: []interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: [][]interface{}{
{
types.StringElement{Content: "description 2"},
},
},
},
},
},
}
expected := []interface{}{
types.LabeledList{
Attributes: types.ElementAttributes{},
Items: []types.LabeledListItem{
types.LabeledListItem{
Attributes: types.ElementAttributes{},
Level: 1,
Term: []interface{}{
types.QuotedText{
Kind: types.Monospace,
Elements: []interface{}{
types.StringElement{
Content: "foo",
},
},
},
types.StringElement{
Content: " term",
},
},
Elements: []interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: [][]interface{}{
{
types.StringElement{Content: "description 1"},
},
},
},
types.LabeledList{
Attributes: types.ElementAttributes{},
Items: []types.LabeledListItem{
types.LabeledListItem{
Attributes: types.ElementAttributes{},
Level: 2,
Term: []interface{}{
types.QuotedText{
Kind: types.Monospace,
Elements: []interface{}{
types.StringElement{
Content: "bar",
},
},
},
types.StringElement{
Content: " term",
},
},
Elements: []interface{}{
types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: [][]interface{}{
{
types.StringElement{Content: "description 2"},
},
},
},
},
},
},
},
},
},
},
},
}
result, err := rearrangeListItems(actual, false)
Expect(err).NotTo(HaveOccurred())
Expect(result).To(Equal(expected))
})
})
Loading

0 comments on commit 6b58ad2

Please sign in to comment.