0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-04-04 03:35:05 +02:00

Extract shared ControlCharPicture helper and improve badge styling

Extract charset.ControlCharPicture() shared between highlight and
charset escape paths. Add controlCharHTML helper to deduplicate HTML
template. Style control char badges with body color on gray background
matching the original styling.

Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
This commit is contained in:
silverwind 2026-04-03 10:19:55 +02:00
parent ec90482206
commit f80593bb23
3 changed files with 31 additions and 11 deletions

View File

@ -18,6 +18,19 @@ import (
// VScode defaultWordRegexp
var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`)
// ControlCharPicture returns the Unicode Control Picture for ASCII control
// characters (0x00-0x1F → U+2400-U+241F, 0x7F → U+2421). For other runes it
// returns 0, false.
func ControlCharPicture(r rune) (rune, bool) {
if r >= 0 && r <= 0x1f {
return 0x2400 + r, true
}
if r == 0x7f {
return 0x2421, true
}
return 0, false
}
func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer {
allowedM := make(map[rune]bool, len(allowed))
for _, v := range allowed {
@ -199,12 +212,11 @@ func (e *escapeStreamer) invisibleRune(r rune) error {
e.escaped.Escaped = true
e.escaped.HasInvisible = true
// Use Unicode Control Pictures for ASCII control chars
escaped := fmt.Sprintf("[U+%04X]", r)
if r >= 0 && r <= 0x1f {
escaped = string(0x2400 + r)
} else if r == 0x7f {
escaped = string(rune(0x2421))
var escaped string
if pic, ok := ControlCharPicture(r); ok {
escaped = string(pic)
} else {
escaped = fmt.Sprintf("[U+%04X]", r)
}
if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{

View File

@ -10,6 +10,7 @@ import (
"slices"
"sync"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -43,12 +44,12 @@ func globalVars() *globalVarsType {
globalVarsPtr.githubStyles = styles.Get("github")
globalVarsPtr.highlightMapping = setting.GetHighlightMapping()
globalVarsPtr.escCtrlCharsMap = make([]template.HTML, 256)
// ASCII control characters 0x00-0x1F map to Unicode Control Pictures U+2400-U+241F
for i := range 0x20 {
globalVarsPtr.escCtrlCharsMap[i] = template.HTML(`<span class="broken-code-point" data-escaped="` + string(rune(0x2400+i)) + `"><span class="char">` + string(byte(i)) + `</span></span>`)
pic, _ := charset.ControlCharPicture(rune(i))
globalVarsPtr.escCtrlCharsMap[i] = controlCharHTML(pic, byte(i))
}
// DEL (0x7F) maps to U+2421
globalVarsPtr.escCtrlCharsMap[0x7f] = template.HTML(`<span class="broken-code-point" data-escaped="` + string(rune(0x2421)) + `"><span class="char">` + string(byte(0x7f)) + `</span></span>`)
pic, _ := charset.ControlCharPicture(0x7f)
globalVarsPtr.escCtrlCharsMap[0x7f] = controlCharHTML(pic, 0x7f)
globalVarsPtr.escCtrlCharsMap['\t'] = ""
globalVarsPtr.escCtrlCharsMap['\n'] = ""
globalVarsPtr.escCtrlCharsMap['\r'] = ""
@ -64,6 +65,10 @@ func globalVars() *globalVarsType {
return globalVarsPtr
}
func controlCharHTML(pic rune, char byte) template.HTML {
return template.HTML(`<span class="broken-code-point" data-escaped="` + string(pic) + `"><span class="char">` + string(char) + `</span></span>`)
}
func escapeByMap(code []byte, escapeMap []template.HTML) template.HTML {
firstEscapePos := -1
for i, c := range code {

View File

@ -18,7 +18,10 @@ Only show the real-char:
.broken-code-point[data-escaped]::before {
visibility: visible;
content: attr(data-escaped);
color: var(--color-red);
border-radius: 2px;
padding: 0 1px;
color: var(--color-body);
background: var(--color-text-light-1);
}
.broken-code-point[data-escaped] .char {