Keep generated prose out of Markdown structure
This commit is contained in:
89
internal/reporttemplate/plain_text.go
Normal file
89
internal/reporttemplate/plain_text.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package reporttemplate
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var inlineMarkdownReplacer = strings.NewReplacer(
|
||||
`\`, `\\`,
|
||||
"`", "\\`",
|
||||
"*", "\\*",
|
||||
"_", "\\_",
|
||||
"[", "\\[",
|
||||
"]", "\\]",
|
||||
"(", "\\(",
|
||||
")", "\\)",
|
||||
"<", "\\<",
|
||||
">", "\\>",
|
||||
"!", "\\!",
|
||||
"~", "\\~",
|
||||
"|", "\\|",
|
||||
"&", "\\&",
|
||||
)
|
||||
|
||||
// plainText preserves prose and paragraph breaks while preventing dynamic
|
||||
// values from creating Markdown structure owned by repository templates.
|
||||
func plainText(value string) string {
|
||||
value = strings.ReplaceAll(value, "\r\n", "\n")
|
||||
value = strings.ReplaceAll(value, "\r", "\n")
|
||||
lines := strings.Split(value, "\n")
|
||||
for index, line := range lines {
|
||||
lines[index] = escapeMarkdownLine(line)
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func escapeMarkdownLine(line string) string {
|
||||
indentEnd := 0
|
||||
spaces := 0
|
||||
hasTab := false
|
||||
for indentEnd < len(line) {
|
||||
switch line[indentEnd] {
|
||||
case ' ':
|
||||
spaces++
|
||||
indentEnd++
|
||||
case '\t':
|
||||
hasTab = true
|
||||
indentEnd++
|
||||
default:
|
||||
goto escaped
|
||||
}
|
||||
}
|
||||
|
||||
escaped:
|
||||
indent := line[:indentEnd]
|
||||
if hasTab || spaces >= 4 {
|
||||
indent = ""
|
||||
}
|
||||
return indent + escapeMarkdownBlockPrefix(escapeMarkdownInline(line[indentEnd:]))
|
||||
}
|
||||
|
||||
func escapeMarkdownInline(value string) string {
|
||||
value = inlineMarkdownReplacer.Replace(value)
|
||||
return strings.Map(func(r rune) rune {
|
||||
if unicode.IsControl(r) {
|
||||
return ' '
|
||||
}
|
||||
return r
|
||||
}, value)
|
||||
}
|
||||
|
||||
func escapeMarkdownBlockPrefix(value string) string {
|
||||
if value == "" {
|
||||
return value
|
||||
}
|
||||
switch value[0] {
|
||||
case '#', '+', '-', '>', '=':
|
||||
return "\\" + value
|
||||
}
|
||||
|
||||
index := 0
|
||||
for index < len(value) && value[index] >= '0' && value[index] <= '9' {
|
||||
index++
|
||||
}
|
||||
if index > 0 && index < len(value) && value[index] == '.' {
|
||||
return value[:index] + "\\" + value[index:]
|
||||
}
|
||||
return value
|
||||
}
|
||||
Reference in New Issue
Block a user