- closing++
- case '[':
- depth++
- case ']':
- depth--
- }
-
- if depth > 0 {
- continue
- }
-
- rest := line[closing+1:]
- if closing == index+1 || !strings.HasPrefix(rest, "(") {
- return TelegramMarkdownSpan{}, false
- }
-
- url, _, found := strings.Cut(rest[1:], ")")
- if !found || url == "" || strings.ContainsAny(url, " \t") {
- return TelegramMarkdownSpan{}, false
- }
-
- return TelegramMarkdownSpan{
- kind: "text_link",
- content: line[index+1 : closing],
- end: closing + 2 + len(url) + 1,
- url: url,
- }, true
- }
-
- return TelegramMarkdownSpan{}, false
-}
-
-// telegramDelimited returns the span of kind between the mark at index and the
-// same mark later in line. An opening mark is followed by a character that is
-// not a space, and a closing mark follows one. A single mark is not a part of a
-// double one. A mark of underscores does not open or close inside a word, so
-// snake_case stays as text. A code span inside the content is skipped whole.
-func telegramDelimited(line string, index int, mark, kind string) (TelegramMarkdownSpan, bool) {
- char := mark[0]
- after := index + len(mark)
- if !strings.HasPrefix(line[index:], mark) || after >= len(line) || telegramIsSpace(line[after]) {
- return TelegramMarkdownSpan{}, false
- }
-
- if len(mark) == 1 && (line[after] == char || index > 0 && line[index-1] == char) {
- return TelegramMarkdownSpan{}, false
- }
-
- if char == '_' && index > 0 && telegramWordCharBefore(line[:index]) {
- return TelegramMarkdownSpan{}, false
- }
-
- for closing := after + 1; closing < len(line); closing++ {
- switch {
- case line[closing] == '\\':
- closing++
- continue
- case line[closing] == '`':
- span, found := telegramCodeSpan(line, closing)