Skip to content

Commit

Permalink
feature(parser): custom subs on paragraphs
Browse files Browse the repository at this point in the history
Support for one or more custom substitutions
Starting with Rawline elements which are parsed
and result in other elements. Subsequent substitutions
only apply on the StringElements.
At the end of the substitutions, the lines are preserved

Also, fix issues with single line comments which should not
start with spaces before the `//` marker

Fixes #597

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon committed Aug 2, 2020
1 parent 70a1ec4 commit fd51649
Show file tree
Hide file tree
Showing 12 changed files with 5,901 additions and 4,526 deletions.
2 changes: 1 addition & 1 deletion make/go.mk
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ generate-optimized: install-pigeon

.PHONY: build
## build the binary executable from CLI
build: prebuild-checks generate-optimized
build: prebuild-checks verify-parser generate-optimized
$(eval BUILD_COMMIT:=$(shell git rev-parse --short HEAD))
$(eval BUILD_TAG:=$(shell git tag --contains $(BUILD_COMMIT)))
$(eval BUILD_TIME:=$(shell date -u '+%Y-%m-%dT%H:%M:%SZ'))
Expand Down
169 changes: 106 additions & 63 deletions pkg/parser/comment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,6 @@ var _ = Describe("comments", func() {
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

It("single line comment with prefixing spaces alone", func() {
source := ` // A single-line comment.`
expected := types.DraftDocument{
Blocks: []interface{}{
types.SingleLineComment{
Content: " A single-line comment.",
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

It("single line comment with prefixing tabs alone", func() {
source := "\t\t// A single-line comment."
expected := types.DraftDocument{
Blocks: []interface{}{
types.SingleLineComment{
Content: " A single-line comment.",
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

It("single line comment at end of line", func() {
source := `foo // A single-line comment.`
expected := types.DraftDocument{
Expand All @@ -71,7 +47,7 @@ var _ = Describe("comments", func() {
It("single line comment within a paragraph", func() {
source := `a first line
// A single-line comment.
another line`
another line // with a comment`
expected := types.DraftDocument{
Blocks: []interface{}{
types.Paragraph{
Expand All @@ -88,44 +64,85 @@ another line`
},
[]interface{}{
types.StringElement{
Content: "another line",
Content: "another line // with a comment",
},
},
},
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
result, err := ParseDraftDocument(source)
Expect(err).NotTo(HaveOccurred())
Expect(result).To(MatchDraftDocument(expected))
})

It("single line comment within a paragraph with tab", func() {
source := `a first line
Context("invalid", func() {

It("single line comment with prefixing spaces alone", func() {
source := ` // A single-line comment.`
expected := types.DraftDocument{
Blocks: []interface{}{
types.LiteralBlock{
Attributes: types.Attributes{
types.AttrKind: types.Literal,
types.AttrLiteralBlockType: types.LiteralBlockWithSpacesOnFirstLine,
},
Lines: []string{
" // A single-line comment.",
},
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

It("single line comment with prefixing tabs alone", func() {
source := "\t\t// A single-line comment."
expected := types.DraftDocument{
Blocks: []interface{}{
types.LiteralBlock{
Attributes: types.Attributes{
types.AttrKind: types.Literal,
types.AttrLiteralBlockType: types.LiteralBlockWithSpacesOnFirstLine,
},
Lines: []string{
"\t\t// A single-line comment.",
},
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

It("single line comment within a paragraph with tab", func() {
source := `a first line
// A single-line comment.
another line`
expected := types.DraftDocument{
Blocks: []interface{}{
types.Paragraph{
Lines: []interface{}{
[]interface{}{
types.StringElement{
Content: "a first line",
expected := types.DraftDocument{
Blocks: []interface{}{
types.Paragraph{
Lines: []interface{}{
[]interface{}{
types.StringElement{
Content: "a first line",
},
},
},
[]interface{}{
types.SingleLineComment{
Content: " A single-line comment.",
[]interface{}{
types.StringElement{
Content: "\t// A single-line comment.",
},
},
},
[]interface{}{
types.StringElement{
Content: "another line",
[]interface{}{
types.StringElement{
Content: "another line",
},
},
},
},
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})
})
})

Expand Down Expand Up @@ -216,15 +233,35 @@ a second paragraph`
It("single line comment with prefixing spaces alone", func() {
source := ` // A single-line comment.`
expected := types.Document{
Elements: []interface{}{},
Elements: []interface{}{
types.LiteralBlock{
Attributes: types.Attributes{
types.AttrKind: types.Literal,
types.AttrLiteralBlockType: types.LiteralBlockWithSpacesOnFirstLine,
},
Lines: []string{
" // A single-line comment.",
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("single line comment with prefixing tabs alone", func() {
source := "\t\t// A single-line comment."
expected := types.Document{
Elements: []interface{}{},
Elements: []interface{}{
types.LiteralBlock{
Attributes: types.Attributes{
types.AttrKind: types.Literal,
types.AttrLiteralBlockType: types.LiteralBlockWithSpacesOnFirstLine,
},
Lines: []string{
"\t\t// A single-line comment.",
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
Expand Down Expand Up @@ -266,25 +303,31 @@ another line`
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("single line comment within a paragraph with tab", func() {
source := `a first line
Context("invalid", func() {

It("single line comment within a paragraph with tab", func() {
source := `a first line
// A single-line comment.
another line`
expected := types.Document{
Elements: []interface{}{
types.Paragraph{
Lines: []interface{}{
[]interface{}{
types.StringElement{Content: "a first line"},
},
[]interface{}{
types.StringElement{Content: "another line"},
expected := types.Document{
Elements: []interface{}{
types.Paragraph{
Lines: []interface{}{
[]interface{}{
types.StringElement{Content: "a first line"},
},
[]interface{}{
types.StringElement{Content: "\t// A single-line comment."},
},
[]interface{}{
types.StringElement{Content: "another line"},
},
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})

Expand Down
37 changes: 37 additions & 0 deletions pkg/parser/delimited_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,39 @@ var _ = Describe("delimited blocks", func() {
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

Context("with custom substitutions", func() {

It("should apply the 'none' substitution", func() {
source := "[subs=none]\n```" + "\n" +
"a http://website.com[]" + "\n" +
"and more text on the" + "\n" +
"next lines" + "\n" +
"```"
expected := types.DraftDocument{
Blocks: []interface{}{
types.DelimitedBlock{
Kind: types.Fenced,
Attributes: types.Attributes{
types.AttrSubstitutions: "none",
},
Elements: []interface{}{
types.VerbatimLine{
Content: "a http://website.com[]",
},
types.VerbatimLine{
Content: "and more text on the",
},
types.VerbatimLine{
Content: "next lines",
},
},
},
},
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})
})
})

Context("listing block", func() {
Expand Down Expand Up @@ -663,6 +696,10 @@ import <a>
}
Expect(ParseDraftDocument(source)).To(MatchDraftDocument(expected))
})

Context("with custom substitutions", func() {

})
})

Context("example block", func() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/document_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func ParseRawDocument(r io.Reader, config configuration.Configuration, options .
return types.RawDocument{}, err
}
if log.IsLevelEnabled(log.DebugLevel) {
log.Debug("draft document:")
log.Debug("raw document:")
spew.Fdump(log.StandardLogger().Out, doc)
}
return doc, nil
Expand Down
Loading

0 comments on commit fd51649

Please sign in to comment.