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
Fixes bytesparadise#456
Fixes bytesparadise#460

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon committed Jan 5, 2020
1 parent 6acb277 commit c952ad7
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 c952ad7

Please sign in to comment.