Skip to content

Commit

Permalink
Merge pull request #4 from PaulSonOfLars/paul/add-blockquote-formatting
Browse files Browse the repository at this point in the history
Add basic blockquote formatting
  • Loading branch information
PaulSonOfLars authored Jan 1, 2024
2 parents f7f2bb4 + 0289bee commit 51ad059
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 22 deletions.
86 changes: 72 additions & 14 deletions md2htmlV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"html"
"sort"
"strings"
"unicode"
)

var defaultConverterV2 = ConverterV2{
Expand Down Expand Up @@ -42,20 +43,22 @@ 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 links
"]": "", // for links/emoji
"(": "", // for links/emoji
")": "", // for links/emoji
"\\": "", // for escapes
"`": "code",
"```": "pre",
"_": "i",
"*": "b",
"~": "s",
"__": "u",
"|": "", // this is a placeholder for || to work
"||": "span class=\"tg-spoiler\"",
"!": "", // for emoji
"[": "", // for links
"]": "", // for links/emoji
"(": "", // for links/emoji
")": "", // for links/emoji
"\\": "", // for escapes
">": "blockquote",
"&": "", // for blockquotes
}

var AllMarkdownV2Chars = func() []rune {
Expand Down Expand Up @@ -174,6 +177,47 @@ func (cv ConverterV2) md2html(in []rune, enableButtons bool) (string, []ButtonV2
nestedT, nestedB := cv.md2html(in[nStart:nEnd], enableButtons)
return out.String() + "<" + chars[item] + ">" + nestedT + "</" + closeSpans(chars[item]) + ">" + followT, append(nestedB, followB...)

case '&':
if !(i+3 < len(in) && in[i+1] == 'g' && in[i+2] == 't' && in[i+3] == ';') {
out.WriteRune(c)
continue
}

if !validBlockQuoteStart(in, i) {
out.WriteRune(c)
continue
}
nStart := i + 4
for unicode.IsSpace(in[nStart]) {
nStart++
}

nEnd := len(in)
var contents []rune // We store all the contents, minus the > characters, so we avoid double-html tags
lineStart := true
for j := i + 4; j < len(in); j++ {
if lineStart && in[j] == ' ' {
// Skip space chars at start of lines
continue
}

lineStart = in[j] == '\n'
contents = append(contents, in[j])

if in[j] == '\n' {
if j+4 < len(in) && in[j+1] == '&' && in[j+2] == 'g' && in[j+3] == 't' && in[j+4] == ';' {
j = j + 4 // skip '>' symbol
continue
}
nEnd = j
break
}
}

nestedT, nestedB := cv.md2html(contents, enableButtons)
followT, followB := cv.md2html(in[nEnd:], enableButtons)
return out.String() + "<blockquote>" + strings.TrimSpace(nestedT) + "</blockquote>" + followT, append(nestedB, followB...)

case '!':
if len(in) <= i+1 || in[i+1] != '[' {
out.WriteRune(c)
Expand Down Expand Up @@ -245,6 +289,20 @@ func (cv ConverterV2) md2html(in []rune, enableButtons bool) (string, []ButtonV2
return out.String(), nil
}

func validBlockQuoteStart(in []rune, i int) bool {
for j := i - 1; j >= 0; j-- {
if !unicode.IsSpace(in[j]) {
return false
}
if in[j] == '\n' {
return true
}
}

// Start of message; must be valid.
return true
}

func EscapeMarkdownV2(r []rune) string {
out := strings.Builder{}
for i, x := range r {
Expand Down
17 changes: 16 additions & 1 deletion md2htmlV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ var basicMDv2 = []struct {
}, { // ensure that premium stickers can get converted
in: `![👍](tg://emoji?id=5368324170671202286)`,
out: `<tg-emoji emoji-id="5368324170671202286">👍</tg-emoji>`,
}, {},
}, {
in: "> quote",
out: "<blockquote>quote</blockquote>",
}, {
in: ">multi\n> line",
out: "<blockquote>multi\nline</blockquote>",
},
}

func TestMD2HTMLV2Basic(t *testing.T) {
Expand Down Expand Up @@ -243,6 +249,15 @@ var md2HTMLV2Buttons = []struct {
SameLine: false,
},
},
}, {
in: "text\n> quote\ntext",
out: "text\n<blockquote>quote</blockquote>\ntext",
}, {
in: "> `code quote`",
out: "<blockquote><code>code quote</code></blockquote>",
}, {
in: "```go\ntext\n> not quote\nmore text```",
out: "<pre><code class=\"language-go\">text\n&gt; not quote\nmore text</code></pre>",
},
}

Expand Down
5 changes: 4 additions & 1 deletion reverseV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,17 @@ func (cv ConverterV2) reverse(in []rune, buttons []ButtonV2) (string, error) {
} else {
return "", fmt.Errorf("badly formatted anchor tag %q", tagContent)
}
case "blockquote":
out.WriteString(">" + strings.Join(strings.Split(nested, "\n"), "\n>"))

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

prev = closingClose + 1
i = closingClose

case '\\', '_', '*', '~', '`', '[', ']', '(', ')': // these all need to be escaped to ensure we retain the same message
case '\\', '_', '*', '~', '`', '[', ']', '(', ')', '>': // these all need to be escaped to ensure we retain the same message
out.WriteString(html.UnescapeString(string(in[prev:i])))
out.WriteRune('\\')
out.WriteRune(in[i])
Expand Down
16 changes: 10 additions & 6 deletions reverseV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ import (

func TestReverseV2(t *testing.T) {
for _, test := range reverseTest {
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) {
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))
})
}

for _, test := range append(append(basicMD, basicMDv2...), advancedMD...) {
out, err := tg_md2html.ReverseV2(tg_md2html.MD2HTMLV2(test.in), nil)
assert.NoError(t, err, "Error for:\n%s", test)
assert.Equal(t, tg_md2html.MD2HTMLV2(test.in), tg_md2html.MD2HTMLV2(out))
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.Equal(t, tg_md2html.MD2HTMLV2(test.in), tg_md2html.MD2HTMLV2(out))
})
}

for _, test := range []string{
Expand Down

0 comments on commit 51ad059

Please sign in to comment.