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

improve blockquote detection #6

Merged
merged 1 commit into from
Jun 5, 2024
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 common.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func validStart(pos int, input []rune) bool {
}

func validEnd(pos int, input []rune) bool {
// First char is not a valid end char.
// First char is not a valid end char; we do NOT allow empty entities.
// If the end char has a space before it, its not valid either.
if pos == 0 || unicode.IsSpace(input[pos-1]) {
return false
Expand Down
59 changes: 30 additions & 29 deletions md2htmlV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,23 @@ func MD2HTMLButtonsV2(in string) (string, []ButtonV2) {
}

var chars = map[string]string{
"`": "code",
"```": "pre",
"_": "i",
"*": "b",
"~": "s",
"__": "u",
"|": "", // this is a placeholder for || to work
"||": "span class=\"tg-spoiler\"",
"!": "", // for emoji
"![": "", // for emoji
"[": "", // for links
"]": "", // for links/emoji
"(": "", // for links/emoji
")": "", // for links/emoji
"\\": "", // for escapes
"&": "", // for blockquotes
">": "blockquote",
"**>": "blockquote", // expandable blockquotes
"`": "code",
"```": "pre",
"_": "i",
"*": "b",
"~": "s",
"__": "u",
"|": "", // this is a placeholder for || to work
"||": "span class=\"tg-spoiler\"",
"!": "", // for emoji
"![": "", // for emoji
"[": "", // for links
"]": "", // for links/emoji
"(": "", // for links/emoji
")": "", // for links/emoji
"\\": "", // for escapes
"&": "", // for blockquotes
">": "blockquote",
}

var AllMarkdownV2Chars = func() []rune {
Expand Down Expand Up @@ -127,6 +126,7 @@ func getItem(in []rune, i int) (string, int, bool) {

} else if c == '*' &&
i+5 < len(in) && in[i+1] == '*' && in[i+2] == '&' && in[i+3] == 'g' && in[i+4] == 't' && in[i+5] == ';' &&
// We force support for **> to allow for people to separate quotes/expandable quote blocks with **
validBlockQuoteStart(in, i) {
return "**&gt;", 5, true

Expand Down Expand Up @@ -207,11 +207,11 @@ func (cv ConverterV2) md2html(in []rune, enableButtons bool) (string, []ButtonV2
continue
}

nEnd, contents := getBlockQuoteEnd(in, nStart, item == "**&gt;")
nEnd, contents, expandable := getBlockQuoteEnd(in, nStart)
nestedT, nestedB := cv.md2html(contents, enableButtons)
followT, followB := cv.md2html(in[nEnd:], enableButtons)

if item == "**&gt;" {
if expandable {
return out.String() + "<blockquote expandable>" + strings.TrimSpace(nestedT) + "</blockquote>" + followT, append(nestedB, followB...)
}
return out.String() + "<blockquote>" + strings.TrimSpace(nestedT) + "</blockquote>" + followT, append(nestedB, followB...)
Expand Down Expand Up @@ -282,7 +282,7 @@ func (cv ConverterV2) md2html(in []rune, enableButtons bool) (string, []ButtonV2
return out.String(), nil
}

func getBlockQuoteEnd(in []rune, nStart int, expandable bool) (int, []rune) {
func getBlockQuoteEnd(in []rune, nStart int) (int, []rune, bool) {
var contents []rune // We store all the contents, minus the > characters, so we avoid double-html tags
lineStart := true
for j := nStart; j < len(in); j++ {
Expand All @@ -299,26 +299,27 @@ func getBlockQuoteEnd(in []rune, nStart int, expandable bool) (int, []rune) {
continue
}

if isExpandableEnd(in, expandable, j) {
return j, contents[:len(contents)-3]
if isExpandableEnd(in, j) {
// Extra -1 to include newline
return j, contents[:len(contents)-3], true
}

if j+4 < len(in) && in[j+1] == '&' && in[j+2] == 'g' && in[j+3] == 't' && in[j+4] == ';' {
j = j + 4 // skip '>' symbol for the next blockquote start
continue
}
return j, contents
return j, contents, false
}

if isExpandableEnd(in, expandable, len(in)) {
return len(in), contents[:len(contents)-2]
if isExpandableEnd(in, len(in)) {
return len(in), contents[:len(contents)-2], true
}

return len(in), contents
return len(in), contents, false
}

func isExpandableEnd(in []rune, expandable bool, j int) bool {
return expandable && j-2 >= 0 && in[j-1] == '|' && in[j-2] == '|'
func isExpandableEnd(in []rune, j int) bool {
return j-2 >= 0 && in[j-1] == '|' && in[j-2] == '|'
}

func validBlockQuoteStart(in []rune, i int) bool {
Expand Down
10 changes: 8 additions & 2 deletions md2htmlV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,17 @@ var basicMDv2 = []struct {
in: ">multi\n> line",
out: "<blockquote>multi\nline</blockquote>",
}, {
in: "**>expandable multi\n>line\n>quote||",
in: ">expandable multi\n>line\n>quote||",
out: "<blockquote expandable>expandable multi\nline\nquote</blockquote>",
}, {
in: "**>expandable multi\n>line\n>quote||\nMore text on another line",
in: ">expandable multi\n>line\n>quote||\nMore text on another line",
out: "<blockquote expandable>expandable multi\nline\nquote</blockquote>\nMore text on another line",
}, {
in: "**>expandable multi with star prefix\n>line\n>quote||",
out: "<blockquote expandable>expandable multi with star prefix\nline\nquote</blockquote>",
}, {
in: ">normal quote\n**>expandable multi\n>idk||",
out: "<blockquote>normal quote</blockquote>\n<blockquote expandable>expandable multi\nidk</blockquote>",
},
}

Expand Down
Loading