50e6f491ad
* Use npm package names to load internal deps This is necessary so that published Astro components work. These components will be built by esinstall and therefore they cannot rely on `_astro_internal`. The fix is to use npm specifiers everywhere. * Move most of frontend to internal * Mark astro/internal/markdown.js as external * Move markdown stuff to its own package This moves the markdown stuff to its own package so that we can externalize it in the markdown component. * Add the changeset
30 lines
792 B
TypeScript
30 lines
792 B
TypeScript
import { visit } from 'unist-util-visit';
|
|
import slugger from 'github-slugger';
|
|
|
|
/** */
|
|
export default function createCollectHeaders() {
|
|
const headers: any[] = [];
|
|
|
|
const visitor = (node: any) => {
|
|
if (node.type !== 'element') return;
|
|
const { tagName, children } = node;
|
|
if (tagName[0] !== 'h') return;
|
|
let [_, depth] = tagName.match(/h([0-6])/) ?? [];
|
|
if (!depth) return;
|
|
depth = Number.parseInt(depth);
|
|
|
|
let text = '';
|
|
visit(node, 'text', (child) => {
|
|
text += child.value;
|
|
});
|
|
|
|
let slug = slugger.slug(text);
|
|
node.properties = node.properties || {};
|
|
node.properties.id = slug;
|
|
headers.push({ depth, slug, text });
|
|
|
|
return node;
|
|
};
|
|
|
|
return { headers, rehypeCollectHeaders: () => (tree: any) => visit(tree, visitor) };
|
|
}
|