Skip to content

Commit

Permalink
feat(parser): support double punctuation in quoted text
Browse files Browse the repository at this point in the history
Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon committed Oct 28, 2017
1 parent 56d7119 commit e00b7e1
Show file tree
Hide file tree
Showing 3 changed files with 597 additions and 370 deletions.
52 changes: 33 additions & 19 deletions parser/asciidoc-grammar.peg
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ DocumentAttributeSubstitution <- "{" name:(AttributeName) "}" {

// AttributeName must be at least one character long,
// must begin with a word character (A-Z, a-z, 0-9 or _) and
// must only contain word characters and hyphens ('-').
// must only contain word characters and hyphens ("-").
AttributeName <- ([A-Z] / [a-z] / [0-9] / "_") ([A-Z] / [a-z] / [0-9] / "-")*

// ------------------------------------------
Expand Down Expand Up @@ -194,11 +194,11 @@ List <- attributes:(ElementAttribute)*
return types.NewList(elements.([]interface{}), attributes.([]interface{}))
}

ListItem <- WS* level:('*'+ / '-') WS+ content:(ListItemContent) {
ListItem <- WS* level:("*"+ / "-") WS+ content:(ListItemContent) {
return types.NewListItem(level, content.(*types.ListItemContent), nil)
}

ListItemContent <- lines:(!(WS* ('*'+ / '-') WS+) InlineContent EOL)+ {
ListItemContent <- lines:(!(WS* ("*"+ / "-") WS+) InlineContent EOL)+ {
return types.NewListItemContent(c.text, lines.([]interface{}))
}
// ------------------------------------------
Expand All @@ -212,7 +212,7 @@ Paragraph <- attributes:(ElementAttribute)* !("="+ WS+) lines:(InlineContent EOL

// an inline content element may start with and end with spaces,
// but it must contain at least an inline element (image, quoted text, external link, document attribute substitution, word, etc.)
InlineContent <- !FencedBlockDelimiter elements:(WS* InlineElement WS*)+ &EOL { // needs an 'EOL' but does not consume it here.
InlineContent <- !FencedBlockDelimiter elements:(WS* InlineElement WS*)+ &EOL { // needs an "EOL" but does not consume it here.
return types.NewInlineContent(c.text, elements.([]interface{}))
}

Expand All @@ -221,31 +221,45 @@ InlineElement <- InlineImage / QuotedText / ExternalLink / DocumentAttributeSubs
// ------------------------------------------
// Quoted Texts (bold, italic and monospace)
// ------------------------------------------
QuotedText <- BoldText / ItalicText / MonospaceText
QuotedText <- BoldTextDoublePunctuation / BoldTextSimplePunctuation // double punctuation must be evaluated first
/ ItalicTextDoublePunctuation / ItalicTextSimplePunctuation
/ MonospaceTextDoublePunctuation / MonospaceTextSimplePunctuation

BoldText <- '*' content:(QuotedTextContent) '*' {
BoldTextSimplePunctuation <- "*" content:(QuotedTextContent) "*" {
return types.NewQuotedText(types.Bold, content.([]interface{}))
}

ItalicText <- '_' content:(QuotedTextContent) '_' {
BoldTextDoublePunctuation <- "**" content:(QuotedTextContent) "**" {
return types.NewQuotedText(types.Bold, content.([]interface{}))
}

ItalicTextSimplePunctuation <- "_" content:(QuotedTextContent) "_" {
return types.NewQuotedText(types.Italic, content.([]interface{}))
}

MonospaceText <- '`' content:(QuotedTextContent) '`' {
ItalicTextDoublePunctuation <- "__" content:(QuotedTextContent) "__" {
return types.NewQuotedText(types.Italic, content.([]interface{}))
}

MonospaceTextSimplePunctuation <- "`" content:(QuotedTextContent) "`" {
return types.NewQuotedText(types.Monospace, content.([]interface{}))
}

MonospaceTextDoublePunctuation <- "``" content:(QuotedTextContent) "``" {
return types.NewQuotedText(types.Monospace, content.([]interface{}))
}

QuotedTextContent <- QuotedTextContentElement (WS+ QuotedTextContentElement)*

QuotedTextContentElement <- QuotedText / QuotedTextContentWord / InvalidQuotedTextContentWord

QuotedTextContentWord <- (!NEWLINE !WS !'*' !'_' !'`' .)+ // cannot have '*', '_' or '`' within
InvalidQuotedTextContentWord <- (!NEWLINE !WS .)+ // can have '*', '_' or '`' within, maybe because the user made an error (extra or missing space, for example)
QuotedTextContentWord <- (!NEWLINE !WS !"*" !"_" !"`" .)+ // cannot have "*", "_" or "`" within
InvalidQuotedTextContentWord <- (!NEWLINE !WS .)+ // can have "*", "_" or "`" within, maybe because the user made an error (extra or missing space, for example)

// ------------------------------------------
// Links
// ------------------------------------------
ExternalLink <- url:(URL_SCHEME URL) text:('[' (URL_TEXT)* ']')? {
ExternalLink <- url:(URL_SCHEME URL) text:("[" (URL_TEXT)* "]")? {
if text != nil {
return types.NewExternalLink(url.([]interface{}), text.([]interface{}))
}
Expand All @@ -260,7 +274,7 @@ BlockImage <- attributes:(ElementAttribute)* image:BlockImageMacro WS* EOL {
return types.NewBlockImage(c.text, *image.(*types.ImageMacro), attributes.([]interface{}))
}

BlockImageMacro <- "image::" path:(URL) '[' attributes:(URL_TEXT?) ']' {
BlockImageMacro <- "image::" path:(URL) "[" attributes:(URL_TEXT?) "]" {
return types.NewImageMacro(c.text, path.(string), attributes)
}

Expand All @@ -269,7 +283,7 @@ InlineImage <- image:InlineImageMacro {
return types.NewInlineImage(c.text, *image.(*types.ImageMacro))
}

InlineImageMacro <- "image:" !":" path:(URL) '[' attributes:(URL_TEXT?) ']' {
InlineImageMacro <- "image:" !":" path:(URL) "[" attributes:(URL_TEXT?) "]" {
return types.NewImageMacro(c.text, path.(string), attributes)
}

Expand Down Expand Up @@ -328,12 +342,12 @@ ElementLink <- "[" WS* "link" WS* "=" WS* path:URL WS* "]" EOL {
}

// an id attached to an element, such as a BlockImage
ElementID <- "[" WS* '#' id:(ID) WS* "]" EOL {
ElementID <- "[" WS* "#" id:(ID) WS* "]" EOL {
return types.NewElementID(id.(string))
}

// a title attached to an element, such as a BlockImage (
// a title starts with a single '.' followed by the value, without space in-between
// a title starts with a single "." followed by the value, without space in-between
ElementTitle <- "." !"." !WS title:(!NEWLINE .)+ EOL {
return types.NewElementTitle(title.([]interface{}))
}
Expand All @@ -349,15 +363,15 @@ BlankLine <- !EOF WS* EOL {
return types.NewBlankLine()
}

URL <- (!NEWLINE !WS !'[' !']' .)+ {
URL <- (!NEWLINE !WS !"[" !"]" .)+ {
return string(c.text), nil
}

ID <- (!NEWLINE !WS !'[' !']' .)+ {
ID <- (!NEWLINE !WS !"[" !"]" .)+ {
return string(c.text), nil
}

URL_TEXT <- (!NEWLINE !'[' !']' .)+ {
URL_TEXT <- (!NEWLINE !"[" !"]" .)+ {
return string(c.text), nil
}

Expand All @@ -367,7 +381,7 @@ DIGIT <- [0-9]

NEWLINE <- "\r\n" / "\r" / "\n"

WS <- ' ' / '\t' {
WS <- " " / "\t" {
return string(c.text), nil
}

Expand Down
Loading

0 comments on commit e00b7e1

Please sign in to comment.