Skip to content

Commit

Permalink
Improve handling of nested spoiler tags
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulSonOfLars committed Feb 29, 2024
1 parent 918e614 commit 3cf1fcf
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 21 deletions.
6 changes: 3 additions & 3 deletions commonV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func isClosingTag(in []rune, pos int) bool {
return false
}

func getClosingTag(in []rune, tag string) (int, int) {
func getClosingTag(in []rune, openingTag string, closingTag string) (int, int) {
offset := 0
subtags := 0
for offset < len(in) {
Expand All @@ -164,9 +164,9 @@ func getClosingTag(in []rune, tag string) (int, int) {
}

closingTagIdx := openingTagIdx + 2 + c
if string(in[openingTagIdx+1:closingTagIdx]) == tag { // found a nested tag, this is annoying
if string(in[openingTagIdx+1:closingTagIdx]) == openingTag { // found a nested tag, this is annoying
subtags++
} else if isClosingTag(in, openingTagIdx) && string(in[openingTagIdx+2:closingTagIdx]) == tag {
} else if isClosingTag(in, openingTagIdx) && string(in[openingTagIdx+2:closingTagIdx]) == closingTag {
if subtags == 0 {
return openingTagIdx, closingTagIdx
}
Expand Down
11 changes: 9 additions & 2 deletions md2htmlV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ var basicMDv2 = []struct {
}, {
in: "||hello||",
out: "<span class=\"tg-spoiler\">hello</span>",
}, {
in: "||<hello>||",
out: "<span class=\"tg-spoiler\">&lt;hello&gt;</span>",
}, {
in: "```content```",
out: "<pre>content</pre>",
Expand Down Expand Up @@ -75,13 +78,17 @@ var basicMDv2 = []struct {

func TestMD2HTMLV2Basic(t *testing.T) {
for _, x := range append(basicMD, basicMDv2...) {
assert.Equal(t, x.out, tg_md2html.MD2HTMLV2(x.in))
t.Run(x.in, func(t *testing.T) {
assert.Equal(t, x.out, tg_md2html.MD2HTMLV2(x.in))
})
}
}

func TestMD2HTMLV2Advanced(t *testing.T) {
for _, x := range advancedMD {
assert.Equal(t, x.out, tg_md2html.MD2HTMLV2(x.in))
t.Run(x.in, func(t *testing.T) {
assert.Equal(t, x.out, tg_md2html.MD2HTMLV2(x.in))
})
}
}

Expand Down
14 changes: 7 additions & 7 deletions reverseV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ func (cv ConverterV2) reverse(in []rune, buttons []ButtonV2) (string, error) {
if len(tagFields) < 1 {
return "", fmt.Errorf("no tag name for HTML tag started at %d", i)
}
tag := tagFields[0]
tagType := tagFields[0]

co, cc := getClosingTag(in[closeTag+1:], tag)
co, cc := getClosingTag(in[closeTag+1:], tagContent, tagType)
if co < 0 || cc < 0 {
// "no closing open"
return "", fmt.Errorf("no closing tag for HTML tag %q started at %d", tag, i)
return "", fmt.Errorf("no closing tag for HTML tag %q started at %d", tagType, i)
}
closingOpen, closingClose := closeTag+1+co, closeTag+1+cc
out.WriteString(html.UnescapeString(string(in[prev:i])))
Expand All @@ -53,7 +53,7 @@ func (cv ConverterV2) reverse(in []rune, buttons []ButtonV2) (string, error) {
return "", err
}

switch tag {
switch tagType {
case "b", "strong":
out.WriteString("*" + nested + "*")
case "i", "em":
Expand Down Expand Up @@ -85,9 +85,9 @@ func (cv ConverterV2) reverse(in []rune, buttons []ButtonV2) (string, error) {

switch spanType := tagFields[1]; spanType {
case "class=\"tg-spoiler\"":
out.WriteString("||" + html.UnescapeString(string(in[closeTag+1:closingOpen])) + "||")
out.WriteString("||" + nested + "||")
default:
return "", fmt.Errorf("unknown tag type %q", spanType)
return "", fmt.Errorf("unknown span type %q", spanType)
}
case "a":
if link.MatchString(tagContent) {
Expand All @@ -107,7 +107,7 @@ func (cv ConverterV2) reverse(in []rune, buttons []ButtonV2) (string, error) {
out.WriteString(">" + strings.Join(strings.Split(nested, "\n"), "\n>"))

default:
return "", fmt.Errorf("unknown tag %q", tag)
return "", fmt.Errorf("unknown tag %q", tagType)
}

prev = closingClose + 1
Expand Down
23 changes: 14 additions & 9 deletions reverseV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,26 @@ func TestReverseV2(t *testing.T) {
for _, test := range append(append(basicMD, basicMDv2...), advancedMD...) {
t.Run(test.in, func(t *testing.T) {
out, err := tg_md2html.ReverseV2(tg_md2html.MD2HTMLV2(test.in), nil)
assert.NoError(t, err, "Error for:\n%s", test)
assert.NoError(t, err, " Error for:\n%s", test)
assert.Equal(t, tg_md2html.MD2HTMLV2(test.in), tg_md2html.MD2HTMLV2(out))
})
}

for _, test := range []string{
"___________test_______",
"|||||spoiler|||",
"![👍](tg://emoji?id=5368324170671202286)",
"> ",
"test\n>\ntest",
"___________test_______", // uneven underlines
"|||||spoiler|||", // uneven spoilers
"||<spoiler>||", // spoilers, but with HTML bits inside
"![👍](tg://emoji?id=5368324170671202286)", // premium emoji
"> ", // empty quotes
"test\n>\ntest", // multiline quotes
"||||||||| test", // nested spoilers
} {
out, err := tg_md2html.ReverseV2(tg_md2html.MD2HTMLV2(test), nil)
assert.NoError(t, err, "Error for:\n%s", test)
assert.Equal(t, tg_md2html.MD2HTMLV2(test), tg_md2html.MD2HTMLV2(out))
t.Run(test, func(t *testing.T) {
htmlv2 := tg_md2html.MD2HTMLV2(test)
out, err := tg_md2html.ReverseV2(htmlv2, nil)
assert.NoError(t, err, "Error for:\n%s", test)
assert.Equal(t, htmlv2, tg_md2html.MD2HTMLV2(out))
})
}
}

Expand Down

0 comments on commit 3cf1fcf

Please sign in to comment.