remark-heading-id
remark-heading-id copied to clipboard
Removes id when used with remarkStringify
Hello,
I've been trying your package in my project, but I've found when I stringify my mdast
tree back into markdown, the heading id is now lost.
I've tried to hack together a solution which works for basic text titles, but I think it's an over-simplification of the problem and probably breaks a lot of stuff:
import { unified, Processor } from 'unified';
import { Heading, Root, Text } from 'mdast';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import { visit } from 'unist-util-visit';
function remarkHeadingId() {
// @ts-expect-error
const self = this as Processor;
const data = self.data();
const toMarkdownExtensions = data.toMarkdownExtensions || [];
toMarkdownExtensions.push({
handlers: {
heading(node: Heading) {
const text = node.children[0] as Text;
const idValue = String(node.data?.hProperties?.id || '');
const id = idValue === '' ? '' : `{#${idValue}}`;
return `${'#'.repeat(node.depth)} ${text.value} ${id}`;
},
},
});
return (tree: Root) => {
visit(tree, 'heading', (node) => {
const text = node.children[0] as Text;
const match = text.value.match(/ {#([^]+?)}$/);
if (match !== null) {
node.data = {
hProperties: {
id: match[1],
},
};
text.value = text.value.slice(0, match.index);
}
});
};
}
const processor = unified()
.use(remarkParse)
.use(remarkHeadingId)
.use(remarkStringify)
const markdown = `### Hello {#hi}`;
const mdast = processor.parse(markdown);
const transformed = await processor.run(mdast);
console.dir(transformed, { depth: null });
console.log(processor.stringify(transformed as Root))
Transformed (position data removed):
{
type: 'root',
children: [
{
type: 'heading',
depth: 3,
children: [
{
type: 'text',
value: 'Hello'
}
],
data: { hProperties: { id: 'hi' } }
}
]
}
Stringify Result:
### Hello {#hi}
With your plugin, the result is:
### Hello
I had a look at the way Micromark parses ATX headings to see if I could replicate the logic but it looks pretty complex!
Thanks.