Merge remote-tracking branch 'origin/main' into dev

This commit is contained in:
viettranx
2026-04-09 23:48:14 +07:00
2 changed files with 56 additions and 0 deletions
+17
View File
@@ -61,6 +61,17 @@ func markdownToTelegramHTML(text string) string {
inlineCodes := extractInlineCodes(text)
text = inlineCodes.text
// Extract and protect bare URLs from italic parsing.
// URLs with underscores (e.g. syngas_dailymail_2026_ai) get broken by
// the italic regex which matches _text_ patterns inside URLs.
var urlPlaceholders []string
reURL := regexp.MustCompile(`https?://[^\s<>\)\]]+`)
text = reURL.ReplaceAllStringFunc(text, func(s string) string {
idx := len(urlPlaceholders)
urlPlaceholders = append(urlPlaceholders, s)
return fmt.Sprintf("\x00URL%d\x00", idx)
})
// Strip markdown headers
text = regexp.MustCompile(`(?m)^#{1,6}\s+(.+)$`).ReplaceAllString(text, "$1")
@@ -115,6 +126,12 @@ func markdownToTelegramHTML(text string) string {
// List items
text = regexp.MustCompile(`(?m)^[-*]\s+`).ReplaceAllString(text, "• ")
// Restore bare URLs (protected from italic parsing above).
for i, u := range urlPlaceholders {
escaped := escapeHTML(u)
text = strings.ReplaceAll(text, fmt.Sprintf("\x00URL%d\x00", i), escaped)
}
// Restore inline code
for i, code := range inlineCodes.codes {
escaped := escapeHTML(code)
+39
View File
@@ -182,3 +182,42 @@ func TestChunkHTML(t *testing.T) {
})
}
}
func TestMarkdownToTelegramHTML_URLsWithUnderscores(t *testing.T) {
tests := []struct {
name string
input string
want string
deny string
}{
{
name: "bare URL with underscores not broken by italic",
input: "Check https://pre.glomotra.dev/uk/syngas_dailymail_2026_ai/?fname=James here",
want: "https://pre.glomotra.dev/uk/syngas_dailymail_2026_ai/?fname=James",
deny: "<i>",
},
{
name: "URL without underscores unchanged",
input: "Visit https://example.com/path today",
want: "https://example.com/path",
},
{
name: "markdown link with underscored URL preserved",
input: "[Click](https://example.com/a_b_c)",
want: `href="https://example.com/a_b_c"`,
deny: "<i>",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := markdownToTelegramHTML(tt.input)
if !strings.Contains(got, tt.want) {
t.Errorf("expected %q in output, got: %s", tt.want, got)
}
if tt.deny != "" && strings.Contains(got, tt.deny) {
t.Errorf("unexpected %q in output, got: %s", tt.deny, got)
}
})
}
}