Merge consecutive text nodes when inspecting markdown (#9112)

* Fix assertion order

expected/actual were in wrong order, resulting in misleading output in
case of failing tests

* Merge consesutive markdown text nodes

This ensures that parser quirks such as "hello!" being parsed as
two separate nodes ("hello" and "!") are not exposed to code inspecting
a markdown strings.
This commit is contained in:
Adrian 2018-07-16 17:12:31 +02:00 committed by Joram Wilander
parent 940d0bbbc2
commit 88eef609ab
3 changed files with 57 additions and 23 deletions

View file

@ -476,6 +476,40 @@ func ParseInlines(markdown string, ranges []Range, referenceDefinitions []*Refer
return newInlineParser(markdown, ranges, referenceDefinitions).Parse()
}
func MergeInlineText(inlines []Inline) []Inline {
var ret []Inline
for i, v := range inlines {
// always add first node
if i == 0 {
ret = append(ret, v)
continue
}
// not a text node? nothing to merge
text, ok := v.(*Text)
if !ok {
ret = append(ret, v)
continue
}
// previous node is not a text node? nothing to merge
prevText, ok := ret[len(ret)-1].(*Text)
if !ok {
ret = append(ret, v)
continue
}
// previous node is not right before this one
if prevText.Range.End != text.Range.Position {
ret = append(ret, v)
continue
}
// we have two consecutive text nodes
ret[len(ret)-1] = &Text{
Text: prevText.Text + text.Text,
Range: Range{prevText.Range.Position, text.Range.End},
}
}
return ret
}
func Unescape(markdown string) string {
ret := ""

View file

@ -13,7 +13,7 @@ func Inspect(markdown string, f func(interface{}) bool) {
}
switch v := block.(type) {
case *Paragraph:
for _, inline := range v.ParseInlines(referenceDefinitions) {
for _, inline := range MergeInlineText(v.ParseInlines(referenceDefinitions)) {
InspectInline(inline, func(inline Inline) bool {
return f(inline)
})

View file

@ -22,8 +22,8 @@ func TestTextRanges(t *testing.T) {
},
"simple2": {
Markdown: "hello!",
ExpectedRanges: []Range{{0, 5}, {5, 6}},
ExpectedValues: []string{"hello", "!"},
ExpectedRanges: []Range{{0, 6}},
ExpectedValues: []string{"hello!"},
},
"multiline": {
Markdown: "hello world\nfoobar",
@ -37,13 +37,13 @@ func TestTextRanges(t *testing.T) {
},
"notcode": {
Markdown: "hello ` world",
ExpectedRanges: []Range{{0, 6}, {6, 7}, {7, 13}},
ExpectedValues: []string{"hello ", "`", " world"},
ExpectedRanges: []Range{{0, 13}},
ExpectedValues: []string{"hello ` world"},
},
"escape": {
Markdown: "\\*hello\\*",
ExpectedRanges: []Range{{1, 2}, {2, 7}, {8, 9}},
ExpectedValues: []string{"*", "hello", "*"},
ExpectedRanges: []Range{{1, 7}, {8, 9}},
ExpectedValues: []string{"*hello", "*"},
},
"escapeescape": {
Markdown: "\\\\",
@ -52,28 +52,28 @@ func TestTextRanges(t *testing.T) {
},
"notescape": {
Markdown: "foo\\x",
ExpectedRanges: []Range{{0, 3}, {3, 4}, {4, 5}},
ExpectedValues: []string{"foo", "\\", "x"},
ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"foo\\x"},
},
"notlink": {
Markdown: "[foo",
ExpectedRanges: []Range{{0, 1}, {1, 4}},
ExpectedValues: []string{"[", "foo"},
ExpectedRanges: []Range{{0, 4}},
ExpectedValues: []string{"[foo"},
},
"notlinkend": {
Markdown: "[foo]",
ExpectedRanges: []Range{{0, 1}, {1, 4}, {4, 5}},
ExpectedValues: []string{"[", "foo", "]"},
ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"[foo]"},
},
"notimage": {
Markdown: "![foo",
ExpectedRanges: []Range{{0, 2}, {2, 5}},
ExpectedValues: []string{"![", "foo"},
ExpectedRanges: []Range{{0, 5}},
ExpectedValues: []string{"![foo"},
},
"notimage2": {
Markdown: "!foo",
ExpectedRanges: []Range{{0, 1}, {1, 4}},
ExpectedValues: []string{"!", "foo"},
ExpectedRanges: []Range{{0, 4}},
ExpectedValues: []string{"!foo"},
},
"charref": {
Markdown: ""test",
@ -82,13 +82,13 @@ func TestTextRanges(t *testing.T) {
},
"notcharref": {
Markdown: "&amp test",
ExpectedRanges: []Range{{0, 1}, {1, 9}},
ExpectedValues: []string{"&", "amp test"},
ExpectedRanges: []Range{{0, 9}},
ExpectedValues: []string{"&amp test"},
},
"notcharref2": {
Markdown: "&mattermost;",
ExpectedRanges: []Range{{0, 1}, {1, 12}},
ExpectedValues: []string{"&", "mattermost;"},
ExpectedRanges: []Range{{0, 12}},
ExpectedValues: []string{"&mattermost;"},
},
} {
t.Run(name, func(t *testing.T) {
@ -101,8 +101,8 @@ func TestTextRanges(t *testing.T) {
}
return true
})
assert.Equal(t, ranges, tc.ExpectedRanges)
assert.Equal(t, values, tc.ExpectedValues)
assert.Equal(t, tc.ExpectedRanges, ranges)
assert.Equal(t, tc.ExpectedValues, values)
})
}