Skip to content

Commit

Permalink
fix(mdsvex): Add <angle>bracket workaround transformer
Browse files Browse the repository at this point in the history
We want to be able to escape \<tag\> opens like that and like
&lt;this&gt; without the escapes being undone by the markdown parse
pipeline. (Specifically, remark-parse is sus ..)
  • Loading branch information
ckiee committed Jan 19, 2025
1 parent f29f31c commit 7b2efc0
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
2 changes: 2 additions & 0 deletions packages/mdsvex/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
smartypants_transformer,
highlight_blocks,
code_highlight,
escape_angle_brackets,
} from './transformers';

function stringify(this: Processor, options = {}) {
Expand Down Expand Up @@ -77,6 +78,7 @@ export function transform(
.use(markdown)
.use(mdsvex_parser)
.use(external, { target: false, rel: ['nofollow'] })
.use(escape_angle_brackets)
.use(escape_code, { blocks: !!highlight })
.use(extract_frontmatter, [{ type: fm_opts.type, marker: fm_opts.marker }])
.use(parse_frontmatter, { parse: fm_opts.parse, type: fm_opts.type });
Expand Down
44 changes: 34 additions & 10 deletions packages/mdsvex/src/transformers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,17 @@ export function parse_frontmatter({
return transformer;
}

// in code nodes replace the character witrh the html entities
// maybe I'll need more of these

const entites: Array<[RegExp, string]> = [
[/</g, '&lt;'],
[/>/g, '&gt;'],
[/{/g, '&#123;'],
[/}/g, '&#125;'],
];

export function escape_code({ blocks }: { blocks: boolean }): Transformer {
// in code nodes replace the character witrh the html entities
// maybe I'll need more of these

const entites: Array<[RegExp, string]> = [
[/</g, '&lt;'],
[/>/g, '&gt;'],
[/{/g, '&#123;'],
[/}/g, '&#125;'],
];

return function (tree) {
if (!blocks) {
visit(tree, 'code', escape);
Expand All @@ -91,6 +91,30 @@ export function escape_code({ blocks }: { blocks: boolean }): Transformer {
};
}

// remark-parse already partially escapes <>'s, but then re-emits them raw in the AST,
// which we stringify raw (Should we be?)
export function escape_angle_brackets(): Transformer {
const entites: Array<[RegExp, string]> = [
// remark-parse does not transform \<
[/\\</g, '&lt;'],
// remark-parse transforms \> to '>', and &gt; to '>'
[/^>$/g, '&gt;'],
// remark-parse transforms &lt; to '<'
[/^<$/g, '&lt;'],
];

return function (tree) {
visit(tree, 'text', escape);

function escape(node) {
for (let i = 0; i < entites.length; i += 1) {
node.value = node.value.replace(entites[i][0], entites[i][1]);
}
}
};
}


// special case - process nodes with retext and smartypants
// retext plugins can't work generally due to the difficulties in converting between the two trees

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
awa \<hi\>

awoo \<heyoo

And what happens when I escape like &lt;this&gt;?

This one shouldn't be \\<escaped>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<p>awa &lt;hi&gt;</p>
<p>awoo &lt;heyoo</p>
<p>And what happens when I escape like &lt;this&gt;?</p>
<p>This one shouldn't be \<escaped></p>

0 comments on commit 7b2efc0

Please sign in to comment.