return out.text.String(), out.entities
}
+// telegramEscapeTags puts a backslash before each < of markdown outside inline
+// code and fenced code blocks, so that rich Markdown shows a tag name as text
+// and reads no raw HTML. A < that a backslash already makes plain stays as it
+// is. A code block that does not close runs to the end, as in Markdown.
+func telegramEscapeTags(markdown string) string {
+ var out strings.Builder
+ lines := strings.Split(markdown, "\n")
+ for index := 0; index < len(lines); index++ {
+ if index > 0 {
+ out.WriteString("\n")
+ }
+
+ line := lines[index]
+ _, fence := telegramCodeFence(line)
+ if fence == "" {
+ telegramEscapeLineTags(&out, line)
+ continue
+ }
+
+ end := telegramClosingFence(lines, index, fence)
+ if end < 0 {
+ end = len(lines) - 1
+ }
+
+ out.WriteString(strings.Join(lines[index:end+1], "\n"))
+ index = end
+ }
+
+ return out.String()
+}
+
// telegramCodeFence returns the language of a line that opens a fenced code
// block, and the fence. The fence is "" when line does not open a block.
func telegramCodeFence(line string) (string, string) {
return rest
}
+// telegramEscapeLineTags writes line to out with a backslash before each < that
+// is outside inline code and not already plain. A run of backticks that opens
+// no inline code stays as text whole, as in Markdown.
+func telegramEscapeLineTags(out *strings.Builder, line string) {
+ for index := 0; index < len(line); {
+ switch line[index] {
+ case '\\':
+ if index+1 < len(line) && strings.IndexByte(telegramMarkdownPunctuation, line[index+1]) >= 0 {
+ out.WriteString(line[index : index+2])
+ index += 2
+
+ continue
+ }
+ case '`':
+ end := index + telegramBackticks(line[index:])
+ span, found := telegramCodeSpan(line, index)
+ if found {
+ end = span.end
+ }
+
+ out.WriteString(line[index:end])
+ index = end
+
+ continue
+ case '<':
+ out.WriteByte('\\')
+ }
+
+ out.WriteByte(line[index])
+ index++
+ }
+}
+
// telegramMarkSpan returns the inline mark that starts at index of line and
// closes in line. It returns false when no mark starts there or the mark does
// not close.