_many") for the given language, falling back to the base key.
func pluralT(lang i18n.Lang, n int, key string) string {
suffix := "_many"
if i18n.Normalize(string(lang)) == i18n.EN {
if n == 1 {
suffix = "_one"
}
} else {
mod10, mod100 := n%10, n%100
switch {
case mod10 == 1 && mod100 != 11:
suffix = "_one"
case mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14):
suffix = "_few"
}
}
k := key + suffix
if v := i18n.T(lang, k); v != k {
return v
}
return i18n.T(lang, key)
}
// activityBadge localizes the status badge of an activity feed entry.
func activityBadge(lang i18n.Lang, itemType, badge string) string {
switch itemType {
case "commit":
return i18n.T(lang, "activity.badge_commit")
case "release":
return i18n.T(lang, "activity.badge_release")
case "pull":
return i18n.T(lang, "pulls.status."+badge)
case "issue":
return i18n.T(lang, "issue.status."+badge)
default:
return badge
}
}
var mdParser = goldmark.New(
goldmark.WithExtensions(
extension.GFM,
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
)
func RenderMarkdown(src []byte) template.HTML {
var buf bytes.Buffer
if err := mdParser.Convert(src, &buf); err != nil {
return template.HTML("" + html.EscapeString(string(src)) + "
")
}
policy := bluemonday.UGCPolicy()
policy.AllowAttrs("class").OnElements("code", "pre", "span")
policy.AllowAttrs("type", "checked", "disabled").OnElements("input")
sanitized := policy.SanitizeBytes(buf.Bytes())
return template.HTML(sanitized)
}
func HighlightCode(filename, code string) []HighlightedLine {
code = strings.ReplaceAll(code, "\r\n", "\n")
lexer := lexers.Match(filename)
if lexer == nil {
lexer = lexers.Fallback
}
lexer = chroma.Coalesce(lexer)
formatter := chromahtml.New(
chromahtml.WithClasses(true),
chromahtml.PreventSurroundingPre(true),
)
style := styles.Get("monokai")
if style == nil {
style = styles.Fallback
}
rawLines := strings.Split(code, "\n")
if len(rawLines) > 0 && rawLines[len(rawLines)-1] == "" {
rawLines = rawLines[:len(rawLines)-1]
}
result := make([]HighlightedLine, 0, len(rawLines))
iterator, err := lexer.Tokenise(nil, code)
if err != nil {
for idx, l := range rawLines {
result = append(result, HighlightedLine{
Num: idx + 1,
HTML: template.HTML(html.EscapeString(l)),
})
}
return result
}
var buf bytes.Buffer
if err := formatter.Format(&buf, style, iterator); err != nil {
for idx, l := range rawLines {
result = append(result, HighlightedLine{
Num: idx + 1,
HTML: template.HTML(html.EscapeString(l)),
})
}
return result
}
htmlLines := strings.Split(buf.String(), "\n")
if len(htmlLines) > 0 && htmlLines[len(htmlLines)-1] == "" {
htmlLines = htmlLines[:len(htmlLines)-1]
}
for idx, hl := range htmlLines {
result = append(result, HighlightedLine{
Num: idx + 1,
HTML: template.HTML(hl),
})
}
return result
}