Release v0.4.0: dev -> main #251

Merged
fen merged 138 commits from dev into main 2026-09-17 15:35:21 +00:00
3 changed files with 19 additions and 3 deletions
Showing only changes of commit 5034f156ee - Show all commits
+5 -2
View File
@@ -166,8 +166,11 @@ func TestHighlightCode(t *testing.T) {
if plain != "<b>x</b>" { if plain != "<b>x</b>" {
t.Fatalf("plain escaping wrong: %q", plain) t.Fatalf("plain escaping wrong: %q", plain)
} }
// line count preserved (gutter alignment) // #205: newline join preserved as the delimiter paste-lines.js splits on;
if got := len(splitLines(lang.HighlightCode("a\nb\nc", "go"))); got != 3 { // per-line segments survive and the client joins with '' so no newline
// text node reaches the rendered DOM.
hl := lang.HighlightCode("a\nb\nc", "go")
if got := len(splitLines(hl)); got != 3 {
t.Fatalf("want 3 lines, got %d", got) t.Fatalf("want 3 lines, got %d", got)
} }
} }
+4
View File
@@ -146,5 +146,9 @@ func HighlightCode(content, langID string) string {
for i, line := range lines { for i, line := range lines {
out[i] = highlightLine(line, h, langID) out[i] = highlightLine(line, h, langID)
} }
// Note: lines are joined with "\n" on purpose — paste-lines.js splits on
// the newline to build its per-line .codeline blocks, then joins those
// with "" and strips whitespace-only text nodes (#205), so no newline
// text node ever reaches the rendered DOM.
return strings.Join(out, "\n") return strings.Join(out, "\n")
} }
+10 -1
View File
@@ -17,7 +17,10 @@
// because HighlightCode highlights per line) in a .codeline block. The // because HighlightCode highlights per line) in a .codeline block. The
// spans are display:block, so they are joined with '' — a '\n' join leaves // spans are display:block, so they are joined with '' — a '\n' join leaves
// newline text nodes between blocks that pre-wrap renders as an extra line // newline text nodes between blocks that pre-wrap renders as an extra line
// box per line, which would shift every following number down one row (#167). // box per line, which would shift every following number down one row (#167,
// #205). Whitespace-only text nodes are also stripped defensively below: any
// that reach the DOM (older cached HTML, other templates) render as phantom
// rows under white-space: pre and drift the gutter.
function splitLines() { function splitLines() {
var html = body.innerHTML; var html = body.innerHTML;
var parts = html.split('\n'); var parts = html.split('\n');
@@ -26,6 +29,12 @@
out.push('<span class="codeline">' + parts[i] + '</span>'); out.push('<span class="codeline">' + parts[i] + '</span>');
} }
body.innerHTML = out.join(''); body.innerHTML = out.join('');
// #205: strip whitespace-only text nodes between the .codeline blocks.
var ws = [];
for (var n = body.firstChild; n; n = n.nextSibling) {
if (n.nodeType === 3 && !/\S/.test(n.nodeValue)) ws.push(n);
}
for (var w = 0; w < ws.length; w++) body.removeChild(ws[w]);
} }
// One .gutline block per visual row. The gutter must reproduce the code // One .gutline block per visual row. The gutter must reproduce the code