package matrix import ( "fmt" "regexp" "strings" ) var ( reBold = regexp.MustCompile(`\*\*(.+?)\*\*`) reItalic = regexp.MustCompile(`\*(.+?)\*`) reStrikethrough = regexp.MustCompile(`~~(.+?)~~`) reCode = regexp.MustCompile("`(.+?)`") ) // MarkdownToHTML converts simple markdown to HTML for Matrix messages. // Matches the exact behavior of the TypeScript markdownToHtml function. func MarkdownToHTML(text string) string { result := text result = reBold.ReplaceAllString(result, "$1") result = reItalic.ReplaceAllString(result, "$1") result = reStrikethrough.ReplaceAllString(result, "$1") result = reCode.ReplaceAllString(result, "$1") result = strings.ReplaceAll(result, "\n", "
") return result } // EscapeHTML escapes HTML special characters. func EscapeHTML(text string) string { r := strings.NewReplacer( "&", "&", "<", "<", ">", ">", `"`, """, "'", "'", ) return r.Replace(text) } // FormatNumberedList formats items as a numbered markdown list. func FormatNumberedList[T any](items []T, formatter func(T, int) string) string { var sb strings.Builder for i, item := range items { if i > 0 { sb.WriteByte('\n') } sb.WriteString(fmt.Sprintf("%d. %s", i+1, formatter(item, i))) } return sb.String() } // FormatBulletList formats items as a bullet markdown list. func FormatBulletList[T any](items []T, formatter func(T) string) string { var sb strings.Builder for i, item := range items { if i > 0 { sb.WriteByte('\n') } sb.WriteString("• ") sb.WriteString(formatter(item)) } return sb.String() }