Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(parser/renderer): support m-dashes and arrows #998

Merged
merged 1 commit into from
Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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