From ae2a16aa588cf8db6fee2aa8fa14d9fd698dcaa8 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 2 Apr 2026 21:00:12 +0800 Subject: [PATCH] use attr(data-escaped) --- modules/highlight/highlight.go | 7 +++++-- modules/highlight/highlight_test.go | 8 ++++---- web_src/css/modules/charescape.css | 28 +++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/modules/highlight/highlight.go b/modules/highlight/highlight.go index 62cb0d6aa3..cf3bc41a5f 100644 --- a/modules/highlight/highlight.go +++ b/modules/highlight/highlight.go @@ -50,10 +50,13 @@ func globalVars() *globalVarsType { "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", } + // uncomment this line if you'd like to debug the layout without really creating a file, then space will also be escaped + // don't worry, even if you forget to comment it out and push it to git repo, the CI tests will catch it and fail + // controlCharNames = append(controlCharNames, "SP") for i, s := range controlCharNames { - globalVarsPtr.escapeControlChars[i] = template.HTML(`` + s + ``) + globalVarsPtr.escapeControlChars[i] = template.HTML(`` + string(byte(i)) + ``) } - globalVarsPtr.escapeControlChars[0x7f] = `DEL` + globalVarsPtr.escapeControlChars[0x7f] = template.HTML(`` + string(byte(0x7f)) + ``) globalVarsPtr.escapeControlChars['\t'] = "" globalVarsPtr.escapeControlChars['\n'] = "" globalVarsPtr.escapeControlChars['\r'] = "" diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go index a626660903..cad22ba9bb 100644 --- a/modules/highlight/highlight_test.go +++ b/modules/highlight/highlight_test.go @@ -206,12 +206,12 @@ func TestUnsafeSplitHighlightedLines(t *testing.T) { } func TestEscape(t *testing.T) { - assert.Equal(t, template.HTML("\t\r\nNULUS&'\"<>"), escapeControlChars([]byte("\t\r\n\x00\x1f&'\"<>"))) - assert.Equal(t, template.HTML("NULUS&'"<>\t\r\n"), escapeFullString("\x00\x1f&'\"<>\t\r\n")) + assert.Equal(t, template.HTML("\t\r\n\x00\x1f&'\"<>"), escapeControlChars([]byte("\t\r\n\x00\x1f&'\"<>"))) + assert.Equal(t, template.HTML("\x00\x1f&'"<>\t\r\n"), escapeFullString("\x00\x1f&'\"<>\t\r\n")) out, _ := RenderFullFile("a.py", "", []byte("# \x7f<>")) - assert.Equal(t, template.HTML(`# DEL<>`), out[0]) + assert.Equal(t, template.HTML(`# `+string(byte(0x7f))+`<>`), out[0]) out = renderPlainText([]byte("# \x7f<>")) - assert.Equal(t, template.HTML(`# DEL<>`), out[0]) + assert.Equal(t, template.HTML(`# `+string(byte(0x7f))+`<>`), out[0]) } diff --git a/web_src/css/modules/charescape.css b/web_src/css/modules/charescape.css index 6d6662f33c..eac6d86a81 100644 --- a/web_src/css/modules/charescape.css +++ b/web_src/css/modules/charescape.css @@ -1,10 +1,36 @@ -.broken-code-point { +/* +Show the escaped and hide the real char: + {real-char} +Only show the real-char: + {real-char} +*/ +.broken-code-point:not([data-escaped]), +.broken-code-point[data-escaped]::before { border-radius: 4px; padding: 0 2px; color: var(--color-body); background: var(--color-text-light-1); } +.broken-code-point[data-escaped]::before { + visibility: visible; + content: attr(data-escaped); +} +.broken-code-point[data-escaped] .char { + display: inline-block; + width: 0; /* make it copyable by selecting the text */ +} + +/* +Show the escaped and hide the real-char: + + {real-char} + +Hide the escaped and show the real-char: + + {real-char} + +*/ .unicode-escaped .escaped-code-point[data-escaped]::before { visibility: visible; content: attr(data-escaped);