astro/packages/markdown/remark/src/rehype-collect-headers.ts
Juan Martín Seery de123b28b3
refactor(markdown): removed rehype-slug in favor of our own implementation (#3234)
* Moved types arround

* Removed `rehype-slug` in favor of our own implementation

* Changeset

* Removed rehype-slug from examples

* Remove rehype-slug from tests

* Updated reference

* rehypeCollectHeaders is a function again

* Reverted rehype-slug removes

* Re-added rehype-slug to reference
2022-04-29 21:07:09 -03:00

40 lines
980 B
TypeScript

import { visit } from 'unist-util-visit';
import Slugger from 'github-slugger';
import type { MarkdownHeader, RehypePlugin } from './types.js';
export default function createCollectHeaders() {
const headers: MarkdownHeader[] = [];
const slugger = new Slugger();
function rehypeCollectHeaders(): ReturnType<RehypePlugin> {
return function (tree) {
visit(tree, (node) => {
if (node.type !== 'element') return;
const { tagName } = node;
if (tagName[0] !== 'h') return;
const [_, level] = tagName.match(/h([0-6])/) ?? [];
if (!level) return;
const depth = Number.parseInt(level);
let text = '';
visit(node, 'text', (child) => {
text += child.value;
});
node.properties = node.properties || {};
if (typeof node.properties.id !== 'string') {
node.properties.id = slugger.slug(text);
}
headers.push({ depth, slug: node.properties.id, text });
});
};
}
return {
headers,
rehypeCollectHeaders,
};
}