A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

Fix: keep literal <br> in code samples from collapsing to newlines

highlightOne() decoded entities before stripping <br> tags, which
conflated genuine line-separator breaks (stored unescaped) with a
literal <br> typed in a code sample (stored escaped as &lt;br&gt;).
A code block containing an HTML/Markdown <br> example had it silently
turned into a newline. Strip the breaks on the still-escaped source so
only real break tags are affected; add a regression test.

+14 -2
+10
src/lib/reader/highlight.test.ts
··· 64 64 expect( out ).toContain( '\n' ); // line breaks preserved as real newlines 65 65 expect( out ).toContain( 'class="hljs' ); // still highlighted 66 66 } ); 67 + 68 + it( 'keeps a literal <br> typed in a code sample as text, not a newline', () => { 69 + // A literal `<br>` in a code sample is stored escaped (`&lt;br&gt;`), unlike the 70 + // real break tags above. It must survive as escaped tag text after highlighting, 71 + // not be collapsed into a newline along with the genuine separators. 72 + const out = highlightCodeBlocks( block( 'const html = "&lt;br&gt;";' ) ); 73 + expect( out ).toContain( '&lt;br&gt;' ); // literal example tag preserved as text 74 + expect( out ).not.toContain( '\n' ); // not turned into a line break 75 + expect( out ).toContain( 'class="hljs' ); // still highlighted 76 + } ); 67 77 } );
+4 -2
src/lib/reader/highlight.ts
··· 58 58 // Stored code may use <br> for line breaks (render.ts passes it through and the 59 59 // sanitiser keeps it as a real break). Turn those into real newlines BEFORE tokenising, 60 60 // or the highlighter treats "<br>" as an xml tag and emits literal "<br>" text, 61 - // collapsing the code's line structure. 62 - const raw = decodeEntities( escapedSource ).replace( /<br\s*\/?>/gi, '\n' ); 61 + // collapsing the code's line structure. Strip the breaks on the still-escaped source 62 + // so only genuine break tags are affected — a literal `<br>` typed in a code sample is 63 + // stored escaped (`&lt;br&gt;`) and must survive as text, not become a newline. 64 + const raw = decodeEntities( escapedSource.replace( /<br\s*\/?>/gi, '\n' ) ); 63 65 try { 64 66 const { value, language, relevance } = hljs.highlightAuto( raw ); 65 67 // Zero relevance / no detected language → no useful tokens; keep it plain.