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: preserve <br> line breaks in highlighted code blocks

+18 -1
+13
src/lib/reader/highlight.test.ts
··· 51 51 expect( wrappers.length ).toBe( 2 ); 52 52 expect( out ).toContain( '<p>mid</p>' ); 53 53 } ); 54 + 55 + it( 'converts <br> line breaks in code to real newlines (never literal tag text)', () => { 56 + // Some stored code blocks use <br /> as the line separator (render.ts passes it 57 + // through; the sanitiser keeps it as a real break). Highlighting must tokenise 58 + // clean multi-line source, not turn the breaks into literal "<br>" text. 59 + const out = highlightCodeBlocks( 60 + block( '{<br /> "name": "potato",<br /> "value": 42<br />}' ) 61 + ); 62 + expect( out ).not.toContain( '<br' ); // no raw <br> passed through to hljs 63 + expect( out ).not.toContain( '&lt;' ); // and not escaped into literal "<br>" text 64 + expect( out ).toContain( '\n' ); // line breaks preserved as real newlines 65 + expect( out ).toContain( 'class="hljs' ); // still highlighted 66 + } ); 54 67 } );
+5 -1
src/lib/reader/highlight.ts
··· 55 55 const CODE_BLOCK = /<pre class="wp-block-code"><code>([\s\S]*?)<\/code><\/pre>/g; 56 56 57 57 function highlightOne( escapedSource: string ): string { 58 - const raw = decodeEntities( escapedSource ); 58 + // Stored code may use <br> for line breaks (render.ts passes it through and the 59 + // sanitiser keeps it as a real break). Turn those into real newlines BEFORE tokenising, 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' ); 59 63 try { 60 64 const { value, language, relevance } = hljs.highlightAuto( raw ); 61 65 // Zero relevance / no detected language → no useful tokens; keep it plain.