format: add method to quote string in markdown inline code

This commit is contained in:
Tulir Asokan 2025-04-28 00:54:00 +03:00
commit 287899435d
5 changed files with 33 additions and 24 deletions

View file

@ -187,25 +187,6 @@ func (parser *HTMLParser) listToString(node *html.Node, ctx Context) string {
return strings.Join(children, "\n")
}
func LongestSequence(in string, of rune) int {
currentSeq := 0
maxSeq := 0
for _, chr := range in {
if chr == of {
currentSeq++
} else {
if currentSeq > maxSeq {
maxSeq = currentSeq
}
currentSeq = 0
}
}
if currentSeq > maxSeq {
maxSeq = currentSeq
}
return maxSeq
}
func (parser *HTMLParser) basicFormatToString(node *html.Node, ctx Context) string {
str := parser.nodeToTagAwareString(node.FirstChild, ctx)
switch node.Data {
@ -232,8 +213,7 @@ func (parser *HTMLParser) basicFormatToString(node *html.Node, ctx Context) stri
if parser.MonospaceConverter != nil {
return parser.MonospaceConverter(str, ctx)
}
surround := strings.Repeat("`", LongestSequence(str, '`')+1)
return fmt.Sprintf("%s%s%s", surround, str, surround)
return SafeMarkdownCode(str)
}
return str
}

View file

@ -14,6 +14,7 @@ import (
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/renderer/html"
"go.mau.fi/util/exstrings"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format/mdext"
@ -49,6 +50,19 @@ func EscapeMarkdown(text string) string {
return text
}
func SafeMarkdownCode(text string) string {
text = strings.ReplaceAll(text, "\n", " ")
backtickCount := exstrings.LongestSequenceOf(text, '`')
if backtickCount == 0 {
return fmt.Sprintf("`%s`", text)
}
quotes := strings.Repeat("`", backtickCount+1)
if text[0] == '`' || text[len(text)-1] == '`' {
return fmt.Sprintf("%s %s %s", quotes, text, quotes)
}
return fmt.Sprintf("%s%s%s", quotes, text, quotes)
}
func RenderMarkdownCustom(text string, renderer goldmark.Markdown) event.MessageEventContent {
var buf strings.Builder
err := renderer.Convert([]byte(text), &buf)

View file

@ -196,3 +196,18 @@ func TestRenderMarkdown_CustomEmoji(t *testing.T) {
assert.Equal(t, html, rendered, "with input %q", markdown)
}
}
var codeTests = map[string]string{
"meow": "`meow`",
"me`ow": "``me`ow``",
"`me`ow": "`` `me`ow ``",
"me`ow`": "`` me`ow` ``",
"`meow`": "`` `meow` ``",
"`````````": "`````````` ````````` ``````````",
}
func TestSafeMarkdownCode(t *testing.T) {
for input, expected := range codeTests {
assert.Equal(t, expected, format.SafeMarkdownCode(input), "with input %q", input)
}
}

2
go.mod
View file

@ -18,7 +18,7 @@ require (
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
github.com/yuin/goldmark v1.7.10
go.mau.fi/util v0.8.6
go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c
go.mau.fi/zeroconfig v0.1.3
golang.org/x/crypto v0.37.0
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0

4
go.sum
View file

@ -53,8 +53,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI=
github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
go.mau.fi/util v0.8.6 h1:AEK13rfgtiZJL2YsNK+W4ihhYCuukcRom8WPP/w/L54=
go.mau.fi/util v0.8.6/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE=
go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c h1:qfJyMZq1pPyuXKoVWwHs6OmR9CzO3pHFRPYT/QpaaaA=
go.mau.fi/util v0.8.7-0.20250427215252-d2d18a7e463c/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE=
go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM=
go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=