Skip to content

Commit

Permalink
feat(parser): support delimiter with variable length (#946)
Browse files Browse the repository at this point in the history
Allow for extra delimiter characters and make sure that
the same length is used to end a delimited block

Fixes #942

Signed-off-by: Xavier Coulon <[email protected]>
  • Loading branch information
xcoulon authored Feb 21, 2022
1 parent 84b44c7 commit 688ec3e
Show file tree
Hide file tree
Showing 20 changed files with 22,031 additions and 16,633 deletions.
78 changes: 78 additions & 0 deletions pkg/parser/delimited_block_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,84 @@ some content
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

Context("with variable delimiter length", func() {

It("with 5 chars", func() {
source := `=====
some *example* content
=====`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Example,
Elements: []interface{}{
&types.Paragraph{
Elements: []interface{}{
&types.StringElement{
Content: "some ",
},
&types.QuotedText{
Kind: types.SingleQuoteBold,
Elements: []interface{}{
&types.StringElement{
Content: "example",
},
},
},
&types.StringElement{
Content: " content",
},
},
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := `=====
====
some *example* content
====
=====`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Example,
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Example,
Elements: []interface{}{
&types.Paragraph{
Elements: []interface{}{
&types.StringElement{
Content: "some ",
},
&types.QuotedText{
Kind: types.SingleQuoteBold,
Elements: []interface{}{
&types.StringElement{
Content: "example",
},
},
},
&types.StringElement{
Content: " content",
},
},
},
},
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})

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

// in normal blocks, the substiution should be defined and applied on the elements
Expand Down
47 changes: 45 additions & 2 deletions pkg/parser/delimited_block_fenced_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,64 @@ var _ = Describe("fenced blocks", func() {
It("with unrendered list", func() {
source := "```\n" +
"* some \n" +
"* listing \n" +
"* fenced \n" +
"* content \n```"
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Fenced,
Elements: []interface{}{
&types.StringElement{
Content: "* some\n* listing\n* content", // suffix spaces are trimmed
Content: "* some\n* fenced\n* content", // suffix spaces are trimmed
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

Context("with variable delimiter length", func() {

It("with 5 chars only", func() {
source := "`````\n" +
"some *fenced* content\n" +
"`````"
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Fenced,
Elements: []interface{}{
&types.StringElement{
Content: "some *fenced* content",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := "`````\n" +
"````\n" +
"some *fenced* content\n" +
"````\n" +
"`````"
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Fenced,
Elements: []interface{}{
&types.StringElement{
Content: "````\nsome *fenced* content\n````",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})
})
43 changes: 43 additions & 0 deletions pkg/parser/delimited_block_listing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,49 @@ and <more text> on the +
Expect(logs).To(ContainJSONLogWithOffset(log.ErrorLevel, 33, 182, "unsupported substitution: 'unknown'"))
})
})

Context("with variable delimiter length", func() {

It("with 5 chars", func() {
source := `-----
some *listing* content
-----`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Listing,
Elements: []interface{}{
&types.StringElement{
Content: "some *listing* content",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := `-----
----
some *listing* content
----
-----`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Listing,
Elements: []interface{}{
&types.StringElement{
Content: "----\nsome *listing* content\n----",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})

Context("as paragraph blocks", func() {
Expand Down
43 changes: 43 additions & 0 deletions pkg/parser/delimited_block_literal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,49 @@ a normal paragraph.`
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

Context("with variable delimiter length", func() {

It("with 5 chars", func() {
source := `.....
some *literal* content
.....`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Literal,
Elements: []interface{}{
&types.StringElement{
Content: "some *literal* content",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := `.....
....
some *literal* content
....
.....`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Literal,
Elements: []interface{}{
&types.StringElement{
Content: "....\nsome *literal* content\n....",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})

Context("with attribute", func() {
Expand Down
43 changes: 43 additions & 0 deletions pkg/parser/delimited_block_passthrough_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,49 @@ pass:[foo]
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

Context("with variable delimiter length", func() {

It("with 5 chars", func() {
source := `+++++
some *passthrough* content
+++++`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Passthrough,
Elements: []interface{}{
&types.StringElement{
Content: "some *passthrough* content",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := `+++++
++++
some *passthrough* content
++++
+++++`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Passthrough,
Elements: []interface{}{
&types.StringElement{
Content: "++++\nsome *passthrough* content\n++++",
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})

Context("paragraph with attribute", func() {
Expand Down
90 changes: 90 additions & 0 deletions pkg/parser/delimited_block_quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,96 @@ foo
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

Context("with variable delimiter length", func() {

It("with 5 chars", func() {
source := `[quote]
_____
some *quote* content
_____`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Quote,
Attributes: types.Attributes{
types.AttrStyle: types.Quote,
},
Elements: []interface{}{
&types.Paragraph{
Elements: []interface{}{
&types.StringElement{
Content: "some ",
},
&types.QuotedText{
Kind: types.SingleQuoteBold,
Elements: []interface{}{
&types.StringElement{
Content: "quote",
},
},
},
&types.StringElement{
Content: " content",
},
},
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})

It("with 5 chars with nested with 4 chars", func() {
source := `[quote]
_____
[quote]
____
some *quote* content
____
_____`
expected := &types.Document{
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Quote,
Attributes: types.Attributes{
types.AttrStyle: types.Quote,
},
Elements: []interface{}{
&types.DelimitedBlock{
Kind: types.Quote,
Attributes: types.Attributes{
types.AttrStyle: types.Quote,
},
Elements: []interface{}{
&types.Paragraph{
Elements: []interface{}{
&types.StringElement{
Content: "some ",
},
&types.QuotedText{
Kind: types.SingleQuoteBold,
Elements: []interface{}{
&types.StringElement{
Content: "quote",
},
},
},
&types.StringElement{
Content: " content",
},
},
},
},
},
},
},
},
}
Expect(ParseDocument(source)).To(MatchDocument(expected))
})
})
})
})
})
Loading

0 comments on commit 688ec3e

Please sign in to comment.