Skip to content

Commit

Permalink
feat(parser/renderer): support explicit line breaks
Browse files Browse the repository at this point in the history
supported with the ` +` suffix in paragraph lines,
and the `[%hardbreaks] attribute on a paragraph.

fixes #189

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon committed Oct 6, 2018
1 parent e8a26b0 commit 4c18c43
Show file tree
Hide file tree
Showing 18 changed files with 14,049 additions and 13,055 deletions.
27 changes: 17 additions & 10 deletions pkg/parser/asciidoc-grammar.peg
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ TitleElements <- elements:(!NEWLINE WS* !InlineElementID TitleElement WS*)+ { //
return types.NewInlineElements(elements.([]interface{}))
}

TitleElement <- element:(CrossReference / Passthrough / InlineImage / QuotedText / Link / DocumentAttributeSubstitution / InlineFootnote / Word / Parenthesis) {
TitleElement <- element:(CrossReference / Passthrough / InlineImage / QuotedText / Link / DocumentAttributeSubstitution / InlineFootnote / Parenthesis / LineBreak / Word) {
return element, nil
}

Expand Down Expand Up @@ -538,25 +538,32 @@ MasqueradeParagraph <- // admonition paragraph
InlineElements <-
comment:(SingleLineComment) {
return types.NewInlineElements([]interface{}{comment})
} / !EOF !BlockDelimiter elements:(!EOL WS* !InlineElementID InlineElement WS*)+ EOL { // absorbs heading and trailing spaces
return types.NewInlineElements(elements.([]interface{}))
} / !BlankLine !BlockDelimiter elements:(InlineElement)+ linebreak:(LineBreak)? EOL? { // absorbs heading and trailing spaces
return types.NewInlineElements(append(elements.([]interface{}), linebreak))
}

InlineElement <- element:(QuotedText / CrossReference / Passthrough / InlineImage / Link / DocumentAttributeSubstitution / InlineFootnote / Word / Parenthesis) {
InlineElement <- !EOL !LineBreak element:(QuotedText / CrossReference / Passthrough / InlineImage / Link / DocumentAttributeSubstitution / InlineFootnote / InlineElementID / Parenthesis / LineBreak / Word / WS*) {
return element, nil
}

// special case for re-parsing a group of elements after a document substitution:
// we should treat substitution that did not happen (eg: missing attribute) as regulart
// strings
InlineElementsWithoutSubtitution <- !EOF !BlockDelimiter elements:(!EOL WS* !InlineElementID InlineElementWithoutSubtitution WS*)+ EOL { // absorbs heading and trailing spaces
return types.NewInlineElements(elements.([]interface{}))
// we should treat substitution that did not happen (eg: missing attribute) as regular
// strings - (used by the inline element renderer)
InlineElementsWithoutSubtitution <- !BlankLine !BlockDelimiter elements:(InlineElementWithoutSubtitution)+ linebreak:(LineBreak)? EOL? { // absorbs heading and trailing spaces
return types.NewInlineElements(append(elements.([]interface{}), linebreak))
}

InlineElementWithoutSubtitution <- element:(QuotedText / CrossReference / Passthrough / InlineImage / Link / Word / Parenthesis) {
InlineElementWithoutSubtitution <- !EOL !LineBreak element:(QuotedText / CrossReference / Passthrough / InlineImage / Link / InlineElementID/ Parenthesis / Word / WS*) {
return element, nil
}

// ----------------------------------------------------------------------------
// Explicit line breaks
// ----------------------------------------------------------------------------
LineBreak <- WS "+" WS* EOL {
return types.NewLineBreak()
}

// ----------------------------------------------------------------------------
// Quoted Texts (bold, italic and monospace) including substitution prevention
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -1015,7 +1022,7 @@ Alphanum <- [a-zA-Z0-9]

Parenthesis <- "(" / ")" / "[" / "]"

Word <- (!NEWLINE !WS !Parenthesis .)+ {
Word <- (!NEWLINE !WS !Parenthesis .)+ { // word cannot contain parenthesis
return string(c.text), nil
}

Expand Down
26,235 changes: 13,498 additions & 12,737 deletions pkg/parser/asciidoc_parser.go

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions pkg/parser/paragraph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,72 @@ a paragraph`
}
verify(GinkgoT(), expectedResult, actualContent, parser.Entrypoint("DocumentBlock"))
})

Context("paragraphs with line break", func() {

It("with explicit line break", func() {

actualContent := `foo +
bar
baz`
expectedResult := types.Paragraph{
Attributes: types.ElementAttributes{},
Lines: []types.InlineElements{
{
types.StringElement{Content: "foo"},
types.LineBreak{},
},
{
types.StringElement{Content: "bar"},
},
{
types.StringElement{Content: "baz"},
},
},
}
verify(GinkgoT(), expectedResult, actualContent, parser.Entrypoint("DocumentBlock"))
})

It("with paragraph attribute", func() {

actualContent := `[%hardbreaks]
foo
bar
baz`
expectedResult := types.Paragraph{
Attributes: types.ElementAttributes{
"%hardbreaks": nil,
},
Lines: []types.InlineElements{
{
types.StringElement{Content: "foo"},
},
{
types.StringElement{Content: "bar"},
},
{
types.StringElement{Content: "baz"},
},
},
}
verify(GinkgoT(), expectedResult, actualContent, parser.Entrypoint("DocumentBlock"))
})
})

// It("paragraph with InlineElementID", func() {
// actualContent := `foo [[id]] bar`
// expectedResult := types.Paragraph{
// Attributes: types.ElementAttributes{},
// Lines: []types.InlineElements{
// {
// types.StringElement{Content: "foo "},
// types.StringElement{Content: " bar"},
// },
// },
// }
// verify(GinkgoT(), expectedResult, actualContent, parser.Entrypoint("DocumentBlock"))
// })

})

Context("admonition paragraphs", func() {
Expand Down
Loading

0 comments on commit 4c18c43

Please sign in to comment.