memento-dev/app/markdoc/nodes.ts

60 lines
1.5 KiB
TypeScript

import { Config, nodes as defaultNodes, Node, Tag } from "@markdoc/markdoc";
import { slugifyWithCounter } from "@sindresorhus/slugify";
import yaml from "js-yaml";
import { DocsLayout } from "@syntax/DocsLayout";
import { Fence } from "@syntax/Fence";
let documentSlugifyMap = new Map();
const nodes = {
document: {
...defaultNodes.document,
render: DocsLayout,
transform(node: Node, config: Config) {
documentSlugifyMap.set(config, slugifyWithCounter());
return new Tag(
this.render,
{
frontmatter: yaml.load(node.attributes.frontmatter),
nodes: node.children,
},
node.transformChildren(config),
);
},
},
heading: {
...defaultNodes.heading,
transform(node: Node, config: Config) {
const slugify = documentSlugifyMap.get(config);
const attributes = node.transformAttributes(config);
const children = node.transformChildren(config);
const text = children.filter((child) => typeof child === "string").join(" ");
const id = attributes.id ?? slugify(text);
return new Tag(`h${node.attributes.level}`, { ...attributes, id }, children);
},
},
th: {
...defaultNodes.th,
attributes: {
...defaultNodes.th.attributes,
scope: {
type: String,
default: "col",
},
},
},
fence: {
render: Fence,
attributes: {
language: {
type: String,
},
},
},
};
export default nodes;