package telegram import ( "fmt" "strings" ) func markdownToTelegramHTML(text string) string { if text == "" { return "" } codeBlocks := extractCodeBlocks(text) text = codeBlocks.text inlineCodes := extractInlineCodes(text) text = inlineCodes.text text = reHeading.ReplaceAllString(text, "$1") text = reBlockquote.ReplaceAllString(text, "$1") text = escapeHTML(text) text = reLink.ReplaceAllString(text, `$1`) text = reBoldStar.ReplaceAllString(text, "$1") text = reBoldUnder.ReplaceAllString(text, "$1") text = reItalic.ReplaceAllStringFunc(text, func(s string) string { match := reItalic.FindStringSubmatch(s) if len(match) < 2 { return s } return "" + match[1] + "" }) text = reStrike.ReplaceAllString(text, "$1") text = reListItem.ReplaceAllString(text, "• ") for i, code := range inlineCodes.codes { escaped := escapeHTML(code) text = strings.ReplaceAll(text, fmt.Sprintf("\x00IC%d\x00", i), fmt.Sprintf("%s", escaped)) } for i, code := range codeBlocks.codes { escaped := escapeHTML(code) text = strings.ReplaceAll( text, fmt.Sprintf("\x00CB%d\x00", i), fmt.Sprintf("
%s
", escaped), ) } return text } type codeBlockMatch struct { text string codes []string } func extractCodeBlocks(text string) codeBlockMatch { matches := reCodeBlock.FindAllStringSubmatch(text, -1) codes := make([]string, 0, len(matches)) for _, match := range matches { codes = append(codes, match[1]) } i := 0 text = reCodeBlock.ReplaceAllStringFunc(text, func(m string) string { placeholder := fmt.Sprintf("\x00CB%d\x00", i) i++ return placeholder }) return codeBlockMatch{text: text, codes: codes} } type inlineCodeMatch struct { text string codes []string } func extractInlineCodes(text string) inlineCodeMatch { matches := reInlineCode.FindAllStringSubmatch(text, -1) codes := make([]string, 0, len(matches)) for _, match := range matches { codes = append(codes, match[1]) } i := 0 text = reInlineCode.ReplaceAllStringFunc(text, func(m string) string { placeholder := fmt.Sprintf("\x00IC%d\x00", i) i++ return placeholder }) return inlineCodeMatch{text: text, codes: codes} } func escapeHTML(text string) string { text = strings.ReplaceAll(text, "&", "&") text = strings.ReplaceAll(text, "<", "<") text = strings.ReplaceAll(text, ">", ">") return text }