Skip to content

Commit

Permalink
feat(parser/renderer): support m-dashes and arrows (#998)
Browse files Browse the repository at this point in the history
Fixes #678 #934

Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
  • Loading branch information
xcoulon authored Apr 23, 2022
1 parent 18a5c23 commit f9eae6b
Show file tree
Hide file tree
Showing 7 changed files with 20,778 additions and 13,273 deletions.
33,176 changes: 19,943 additions & 13,233 deletions pkg/parser/parser.go

Large diffs are not rendered by default.

65 changes: 50 additions & 15 deletions pkg/parser/parser.peg
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,7 @@ InlineElement <-
/ ElementPlaceHolder // TODO: needed?
// if anything above did not match...
/ AnyChar)) {
c.trackSpaceSuffix(element)
c.trackSuffix(element)
return element, nil
}

Expand Down Expand Up @@ -1989,8 +1989,8 @@ DoubleQuoteBoldTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInDoubleQuoteBoldText
/ ElementPlaceHolder
/ DoubleQuoteBoldTextFallbackCharacter) {
Expand Down Expand Up @@ -2044,8 +2044,8 @@ SingleQuoteBoldTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInSingleQuoteBoldText
/ ElementPlaceHolder
/ SingleQuoteBoldTextFallbackCharacter
Expand Down Expand Up @@ -2131,8 +2131,8 @@ DoubleQuoteItalicTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInDoubleQuoteItalicText
/ ElementPlaceHolder
/ DoubleQuoteItalicTextFallbackCharacter) {
Expand Down Expand Up @@ -2198,8 +2198,8 @@ SingleQuoteItalicTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro // must be after InlineMacro (because of BareURL)
/ SpecialCharacter
/ Symbol
/ SpecialCharacter
/ QuotedTextInSingleQuoteItalicText
/ ElementPlaceHolder
/ SingleQuoteItalicTextFallbackCharacter
Expand Down Expand Up @@ -2283,8 +2283,8 @@ DoubleQuoteMonospaceTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ RawApostrophe // must be before SingleQuoteMonospaceText
/ QuotedTextInDoubleQuoteMonospaceText
/ ElementPlaceHolder
Expand Down Expand Up @@ -2353,9 +2353,9 @@ SingleQuoteMonospaceTextElement <-
/ Spaces
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro // must be after InlineMacro (because of BareURL)
/ SpecialCharacter
/ InlineMacro
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInSingleQuoteMonospaceText
/ RawApostrophe
/ ElementPlaceHolder
Expand Down Expand Up @@ -2441,8 +2441,8 @@ DoubleQuoteMarkedTextElement <- // may start and end with spaces
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInDoubleMarkedBoldText
/ ElementPlaceHolder
/ DoubleQuoteMarkedTextFallbackCharacter
Expand Down Expand Up @@ -2510,8 +2510,8 @@ SingleQuoteMarkedTextElement <-
/ Newline !Newline // 2 newlines split the paragraph
/ AttributeReference
/ InlineMacro
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ Symbol
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ QuotedTextInSingleQuoteMarkedText
/ ElementPlaceHolder
/ SingleQuoteMarkedTextFallbackCharacter
Expand Down Expand Up @@ -2660,11 +2660,11 @@ Substitutions <- // TODO: rename to `NormalGroup`
/ InlinePassthrough
/ InlineMacro // must be before SpecialCharacter (because of CrossReference)
/ Callout // must be placed before SpecialCharacter
/ Replacement
/ SpecialCharacter // must be after InlineMacro (because of BareURL)
/ AttributeReference
/ Replacement
/ AnyChar) {
c.trackSpaceSuffix(element)
c.trackSuffix(element)
return element, nil
}
)+ EOF {
Expand All @@ -2686,11 +2686,11 @@ HeaderGroupElement <-
/ InlinePassthrough
/ Quote
/ Link
/ Replacement
/ SpecialCharacter // must be after Link (because of BareURL)
/ InlineIcon
/ AttributeReference
/ ElementPlaceHolder // needed when parsing a second time, after first pass returned attribute substitutions
/ Replacement
/ InlineAnchor // must be after LegacyElementID
/ InlineFootnote
/ AnyChar) {
Expand Down Expand Up @@ -2783,11 +2783,11 @@ SingleLineCommentContent <- [^\r\n]* {
// -------------------------------------------------------------------------------------
Symbol <-
// escaped
`\` (QuotationMark / Copyright / Trademark / Registered / Ellipsis) {
`\` (QuotationMark / Copyright / Trademark / Registered / Ellipsis / SingleRightArrow / Mdash / SingleLeftArrow / DoubleRightArrow / DoubleLeftArrow) {
return types.NewStringElement(strings.TrimPrefix(string(c.text), `\`))
}
// unescaped
/ QuotationMark / Copyright / Trademark / Registered / Ellipsis
/ QuotationMark / Copyright / Trademark / Registered / Ellipsis / Mdash / SingleRightArrow / SingleLeftArrow / DoubleRightArrow / DoubleLeftArrow
//
/ TypographicQuote

Expand Down Expand Up @@ -2823,6 +2823,41 @@ Ellipsis <- "..." {
return types.NewSymbol("...")
}

Mdash <-
// 2 flavours:
// a. preceeded by a space character and followed by space or EOL
&{
return c.isPreceededBySpace(), nil
}
"--" (Space / &EOL) {
return types.NewSymbol(" -- ")
}
/
// b. preceeded and followed by an alphanum character
&{
return c.isPreceededByAlphanum(), nil
}
"--" &(Alphanum / EOL) {
return types.NewSymbol("--")
}


SingleRightArrow <- "->" {
return types.NewSymbol("->")
}

SingleLeftArrow <- "<-" {
return types.NewSymbol("<-")
}

DoubleRightArrow <- "=>" {
return types.NewSymbol("=>")
}

DoubleLeftArrow <- "<=" {
return types.NewSymbol("<=")
}



// The implied apostrophe is used in interior words, and intended to help
Expand Down
38 changes: 27 additions & 11 deletions pkg/parser/parser_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sort"
"strings"
"unicode"

"github.com/bytesparadise/libasciidoc/pkg/configuration"
"github.com/bytesparadise/libasciidoc/pkg/types"
Expand Down Expand Up @@ -101,31 +102,46 @@ func (p *parser) next() (val interface{}, err error) {
return val, p.errs.err()
}

const spaceSuffixTrackingKey = "space_suffix_tracking"
const suffixTrackingKey = "space_suffix_tracking"
const spaceSuffix = "space_suffix"
const alphanumSuffix = "alphanum_suffix"

func (c *current) trackSpaceSuffix(element interface{}) {
func (c *current) trackSuffix(element interface{}) {
// if log.IsLevelEnabled(log.DebugLevel) {
// log.Debugf("tracking space at the end of:\n%s", spew.Sdump(element))
// }
switch e := element.(type) {
case string:
c.globalStore[spaceSuffixTrackingKey] = strings.HasSuffix(e, " ")
doTrackSuffix(c, e)
case *types.StringElement:
c.globalStore[spaceSuffixTrackingKey] = strings.HasSuffix(e.Content, " ")
default:
delete(c.globalStore, spaceSuffixTrackingKey)
doTrackSuffix(c, e.Content)
}
// if log.IsLevelEnabled(log.DebugLevel) {
// log.Debugf("space suffix detected: %t", c.globalStore[spaceSuffixTrackingKey])
// }
}

func doTrackSuffix(c *current, content string) {
r := []rune(content)
suffix := r[len(r)-1]
switch {
case suffix == ' ': // strict space, not `\n`, `\r`, etc.
c.globalStore[suffixTrackingKey] = spaceSuffix
case unicode.IsLetter(suffix) || unicode.IsNumber(suffix):
c.globalStore[suffixTrackingKey] = alphanumSuffix
default:
delete(c.globalStore, suffixTrackingKey)
}
}

func (c *current) isPreceededBySpace() bool {
// if log.IsLevelEnabled(log.DebugLevel) {
// log.Debugf("checking if element ends with space: %t", c.globalStore[spaceSuffixTrackingKey])
// }
s, ok := c.globalStore[spaceSuffixTrackingKey].(bool)
return ok && s
k, found := c.globalStore[suffixTrackingKey]
return found && k == spaceSuffix
}

func (c *current) isPreceededByAlphanum() bool {
k, found := c.globalStore[suffixTrackingKey]
return found && k == alphanumSuffix
}

// verifies that the content does not end with a space
Expand Down
Loading

0 comments on commit f9eae6b

Please sign in to comment.