mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-24 21:16:30 +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:
parent
ec90482206
commit
f80593bb23
@ -18,6 +18,19 @@ import (
|
|||||||
// VScode defaultWordRegexp
|
// VScode defaultWordRegexp
|
||||||
var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`)
|
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 {
|
func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer {
|
||||||
allowedM := make(map[rune]bool, len(allowed))
|
allowedM := make(map[rune]bool, len(allowed))
|
||||||
for _, v := range allowed {
|
for _, v := range allowed {
|
||||||
@ -199,12 +212,11 @@ func (e *escapeStreamer) invisibleRune(r rune) error {
|
|||||||
e.escaped.Escaped = true
|
e.escaped.Escaped = true
|
||||||
e.escaped.HasInvisible = true
|
e.escaped.HasInvisible = true
|
||||||
|
|
||||||
// Use Unicode Control Pictures for ASCII control chars
|
var escaped string
|
||||||
escaped := fmt.Sprintf("[U+%04X]", r)
|
if pic, ok := ControlCharPicture(r); ok {
|
||||||
if r >= 0 && r <= 0x1f {
|
escaped = string(pic)
|
||||||
escaped = string(0x2400 + r)
|
} else {
|
||||||
} else if r == 0x7f {
|
escaped = fmt.Sprintf("[U+%04X]", r)
|
||||||
escaped = string(rune(0x2421))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
|
if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/charset"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
@ -43,12 +44,12 @@ func globalVars() *globalVarsType {
|
|||||||
globalVarsPtr.githubStyles = styles.Get("github")
|
globalVarsPtr.githubStyles = styles.Get("github")
|
||||||
globalVarsPtr.highlightMapping = setting.GetHighlightMapping()
|
globalVarsPtr.highlightMapping = setting.GetHighlightMapping()
|
||||||
globalVarsPtr.escCtrlCharsMap = make([]template.HTML, 256)
|
globalVarsPtr.escCtrlCharsMap = make([]template.HTML, 256)
|
||||||
// ASCII control characters 0x00-0x1F map to Unicode Control Pictures U+2400-U+241F
|
|
||||||
for i := range 0x20 {
|
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
|
pic, _ := charset.ControlCharPicture(0x7f)
|
||||||
globalVarsPtr.escCtrlCharsMap[0x7f] = template.HTML(`<span class="broken-code-point" data-escaped="` + string(rune(0x2421)) + `"><span class="char">` + string(byte(0x7f)) + `</span></span>`)
|
globalVarsPtr.escCtrlCharsMap[0x7f] = controlCharHTML(pic, 0x7f)
|
||||||
globalVarsPtr.escCtrlCharsMap['\t'] = ""
|
globalVarsPtr.escCtrlCharsMap['\t'] = ""
|
||||||
globalVarsPtr.escCtrlCharsMap['\n'] = ""
|
globalVarsPtr.escCtrlCharsMap['\n'] = ""
|
||||||
globalVarsPtr.escCtrlCharsMap['\r'] = ""
|
globalVarsPtr.escCtrlCharsMap['\r'] = ""
|
||||||
@ -64,6 +65,10 @@ func globalVars() *globalVarsType {
|
|||||||
return globalVarsPtr
|
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 {
|
func escapeByMap(code []byte, escapeMap []template.HTML) template.HTML {
|
||||||
firstEscapePos := -1
|
firstEscapePos := -1
|
||||||
for i, c := range code {
|
for i, c := range code {
|
||||||
|
|||||||
@ -18,7 +18,10 @@ Only show the real-char:
|
|||||||
.broken-code-point[data-escaped]::before {
|
.broken-code-point[data-escaped]::before {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
content: attr(data-escaped);
|
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 {
|
.broken-code-point[data-escaped] .char {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user