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 role attributes, refactor attributes and image type #171

Merged
merged 1 commit into from
Aug 23, 2018
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ generate: prebuild-checks
.PHONY: generate-optimized
## generate the .go file based on the asciidoc grammar
generate-optimized:
@echo "generating the parser..."
@echo "generating the parser (optimized)..."
@pigeon -optimize-grammar ./pkg/parser/asciidoc-grammar.peg > ./pkg/parser/asciidoc_parser.go


Expand Down
111 changes: 45 additions & 66 deletions pkg/parser/asciidoc-grammar.peg
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ TableOfContentsMacro <- "toc::[]" NEWLINE
// ------------------------------------------
// Element Attributes
// ------------------------------------------
ElementAttribute <- attr:(ElementID / ElementTitle / AdmonitionMarkerAttribute / HorizontalLayout / AttributeGroup) WS* EOL {
ElementAttribute <- attr:(ElementID / ElementTitle / ElementRole / AdmonitionMarkerAttribute / HorizontalLayout / AttributeGroup) WS* EOL {
return attr, nil // avoid returning something like `[]interface{}{attr, EOL}`
}

Expand All @@ -136,44 +136,44 @@ InlineElementID <- "[[" id:(ID) "]]" {
return types.NewElementID(id.(string))
}

// a title attached to an element, such as a BlockImage (
// a title attached to an element, such as a BlockImage
// a title starts with a single "." followed by the value, without space in-between
ElementTitle <- "." !"." !WS title:(!NEWLINE .)+ {
return types.NewElementTitle(title.([]interface{}))
}

// a role attached to an element, such as a BlockImage
// a role starts is wrapped in "[. ]"
ElementRole <- "[." !WS role:(!NEWLINE !"]" .)+ "]"{
return types.NewElementRole(role.([]interface{}))
}

// expression for the whole admonition marker, but only retains the actual kind
AdmonitionMarkerAttribute <- "[" k:(AdmonitionKind) "]" {
return types.NewAdmonitionAttribute(k.(types.AdmonitionKind))
}

// one or more attributes. eg: [foo, key1=value1, key2=value2]other
AttributeGroup <- "[" attribute:(GenericAttribute) attributes:(OtherGenericAttribute)* "]" {
return types.NewAttributeGroup(append([]interface{}{attribute}, attributes.([]interface{})...))
// one or more attributes. eg: [foo, key1=value1, key2 = value2 , ]
AttributeGroup <- "[" !WS attributes:(GenericAttribute)* "]" {
return types.NewAttributeGroup(attributes.([]interface{}))
}

GenericAttribute <- key:(AttributeKey) "=" value:(AttributeValue) { // value is set
GenericAttribute <- key:(AttributeKey) "=" value:(AttributeValue) ","? WS* { // value is set
return types.NewGenericAttribute(key.([]interface{}), value.([]interface{}))
} / key:(AttributeKey) { // value is not set
} / key:(AttributeKey) ","? WS* { // value is not set
return types.NewGenericAttribute(key.([]interface{}), nil)
}

OtherGenericAttribute <- "," WS* key:(AttributeKey) "=" value:(AttributeValue) { // value is set
return types.NewGenericAttribute(key.([]interface{}), value.([]interface{}))
} / "," WS* key:(AttributeKey) { // value is not set
return types.NewGenericAttribute(key.([]interface{}), nil)
}

AttributeKey <- key:(!WS !"=" !"," !"]" .)+ WS* {
AttributeKey <- !VerseKind key:(!"=" !"," !"]" .)+ {
return key, nil
}

AttributeValue <- WS* value:(!WS !"=" !"]" .)* WS* {
AttributeValue <- value:(!"=" !"," !"]" .)* {
return value, nil
}

HorizontalLayout <- "[horizontal]" {
return map[string]interface{}{"layout": "horizontal"}, nil
return types.ElementAttributes{"layout": "horizontal"}, nil
}

QuoteAttributes <- "[" kind:(QuoteKind) WS* "," author:(QuoteAuthor) "," title:(QuoteTitle) "]" {
Expand Down Expand Up @@ -622,20 +622,20 @@ Link <- link:(RelativeLink / ExternalLink) {
}

ExternalLink <- url:(URL_SCHEME URL) attributes:(LinkAttributes) {
return types.NewLink(url.([]interface{}), attributes.(map[string]interface{}))
return types.NewLink(url.([]interface{}), attributes.(types.ElementAttributes))
} / url:(URL_SCHEME URL) {
return types.NewLink(url.([]interface{}), nil)
}

// url preceeding with `link:` MUST be followed by square brackets
RelativeLink <- "link:" url:(URL_SCHEME? URL) attributes:(LinkAttributes) {
return types.NewLink(url.([]interface{}), attributes.(map[string]interface{}))
return types.NewLink(url.([]interface{}), attributes.(types.ElementAttributes))
}

LinkAttributes <- "[" text:(LinkTextAttribute)
otherAttrs:(OtherGenericAttribute)* "]" {
otherAttrs:(GenericAttribute)* "]" {
return types.NewLinkAttributes(text.([]interface{}), otherAttrs.([]interface{}))
} / "[" otherAttrs:(OtherGenericAttribute)* "]" {
} / "[" otherAttrs:(GenericAttribute)* "]" {
return types.NewLinkAttributes(nil, otherAttrs.([]interface{}))
}

Expand All @@ -646,49 +646,33 @@ LinkTextAttribute <- value:(!"," !"]" .)+ {
// ------------------------------------------
// Images
// ------------------------------------------
BlockImage <- attributes:(ElementAttribute)* image:BlockImageMacro WS* EOL {
// here we can ignore the blank line in the returned element
return types.NewBlockImage(image.(types.ImageMacro), attributes.([]interface{}))
}

BlockImageMacro <- "image::" path:(URL) attributes:(ImageAttributes) {
return types.NewImageMacro(path.(string), attributes.(map[string]interface{}))
}

InlineImage <- image:InlineImageMacro {
// here we can ignore the blank line in the returned element
return types.NewInlineImage(image.(types.ImageMacro))
}

InlineImageMacro <- "image:" !":" path:(URL) attributes:(ImageAttributes) {
return types.NewImageMacro(path.(string), attributes.(map[string]interface{}))
}
BlockImage <- attributes:(ElementAttribute)* "image::" path:(URL) inlineAttributes:(ImageAttributes) WS* EOL {
return types.NewBlockImage(path.(string), attributes.([]interface{}), inlineAttributes.(types.ElementAttributes))
}

InlineImage <- "image:" !":" path:(URL) attributes:(ImageAttributes) {
return types.NewInlineImage(path.(string), attributes.(types.ElementAttributes))
}

// the 'ImageAttributes' rule could be simpler, but the grammar optimizer fails to produce a valid code :(
ImageAttributes <- "[" alt:(ImageAttribute)
width:(ImageAttribute)
height:(ImageAttribute)
otherAttrs:(GenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), width.([]interface{}), height.([]interface{}), otherAttrs.([]interface{}))
} / "[" alt:(ImageAttribute)
width:(ImageAttribute)
otherAttrs:(GenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), width.([]interface{}), nil, otherAttrs.([]interface{}))
} / "[" alt:(ImageAttribute)
otherAttrs:(GenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), nil, nil, otherAttrs.([]interface{}))
} / "[" otherAttrs:(GenericAttribute)* "]" {
return types.NewImageAttributes(nil, nil, nil, otherAttrs.([]interface{}))
}

ImageAttributes <- "[" alt:(ImageAltAttribute)
width:(ImageWidthAttribute)
height:(ImageHeightAttribute)
otherAttrs:(OtherGenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), width.([]interface{}), height.([]interface{}), otherAttrs.([]interface{}))
} / "[" alt:(ImageAltAttribute)
width:(ImageWidthAttribute)
otherAttrs:(OtherGenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), width.([]interface{}), nil, otherAttrs.([]interface{}))
} / "[" alt:(ImageAltAttribute)
otherAttrs:(OtherGenericAttribute)* "]" {
return types.NewImageAttributes(alt.([]interface{}), nil, nil, otherAttrs.([]interface{}))
} / "[" otherAttrs:(OtherGenericAttribute)* "]" {
return types.NewImageAttributes(nil, nil, nil, otherAttrs.([]interface{}))
}

ImageAltAttribute <- value:(!"," !"]" .)+ {
return value, nil
}

ImageWidthAttribute <- "," value:(!"," !"]" .)+ {
return value, nil
}

ImageHeightAttribute <- "," value:(!"," !"]" .)+ {
ImageAttribute <- value:(!"," !"=" !"]" .)+ ("," / &"]") { // attribute is followed by "," or "]" (but do not consume the latter)
return value, nil
}

Expand Down Expand Up @@ -784,9 +768,6 @@ VerseBlockAttributes <-
attribute:(VerseAttributes) WS* EOL {
return attribute, nil
}
// / attribute:(ElementAttribute) {
// return attribute, nil
// }

VerseBlockContent <- lines:(VerseBlockLine)+ {
return types.NewParagraph(lines.([]interface{}), nil)
Expand All @@ -803,7 +784,6 @@ VerseBlockLineContent <- elements:(!QuoteBlockDelimiter !EOL WS* InlineElement W
// -------------------------------------------------------------------------------------
// Tables
// -------------------------------------------------------------------------------------

Table <- attributes:(ElementAttribute)*
TableDelimiter WS* NEWLINE
header:(TableLineHeader)?
Expand Down Expand Up @@ -833,7 +813,6 @@ TableCell <- TableCellSeparator elements:(!TableCellSeparator !EOL WS* InlineEle
// -------------------------------------------------------------------------------------
// Comments
// -------------------------------------------------------------------------------------

CommentBlockDelimiter <- "////"

CommentBlock <- attributes:(ElementAttribute)* CommentBlockDelimiter WS* NEWLINE content:(CommentBlockLine)* ((CommentBlockDelimiter WS* EOL) / EOF) {
Expand Down
Loading