before if a header that was using `code` in the title (i.e. launch template) the header should so the link icon but would not link anywhere because the rendered id tag would be an empty string  after the id tag is correctly linked by checking the rendering children contains a `code` tag and pulls the code children out. added benefit includes the code headers being linked in the side nav correct too  Example showing working from preview: https://nx-dev-git-docs-allow-linking-code-headers-nrwl.vercel.app/ci/reference/launch-templates#launchtemplatestemplatenameinitsteps
65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
import { RenderableTreeNode, Schema, Tag } from '@markdoc/markdoc';
|
|
|
|
export function generateID(
|
|
children: RenderableTreeNode[],
|
|
attributes: Record<string, any>
|
|
) {
|
|
if (attributes['id'] && typeof attributes['id'] === 'string') {
|
|
return attributes['id'];
|
|
}
|
|
|
|
const validChildrenNodes: RenderableTreeNode[] = [];
|
|
|
|
for (const child of children) {
|
|
if (!child) {
|
|
continue;
|
|
}
|
|
|
|
if (typeof child === 'string') {
|
|
validChildrenNodes.push(child);
|
|
} else if (
|
|
// allow rendering titles that are wrapped in `code` tags
|
|
typeof child === 'object' &&
|
|
'children' in child &&
|
|
child.name === 'code' &&
|
|
Array.isArray(child.children)
|
|
) {
|
|
const validNestedChild = child.children.filter(
|
|
(c) => typeof c === 'string'
|
|
);
|
|
validChildrenNodes.push(...validNestedChild);
|
|
}
|
|
}
|
|
|
|
return validChildrenNodes
|
|
.join(' ')
|
|
.normalize('NFD')
|
|
.replace(/[\u0300-\u036f]/g, '')
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9 ]/g, '')
|
|
.trim()
|
|
.replace(/\s+/g, '-');
|
|
}
|
|
|
|
export const heading: Schema = {
|
|
render: 'Heading',
|
|
children: ['inline'],
|
|
attributes: {
|
|
id: { type: 'String' },
|
|
level: { type: 'Number', required: true, default: 1 },
|
|
className: { type: 'String' },
|
|
},
|
|
transform(node, config) {
|
|
const attributes = node.transformAttributes(config);
|
|
const children = node.transformChildren(config);
|
|
const id = generateID(children, attributes);
|
|
|
|
return new Tag(
|
|
this.render,
|
|
// `h${node.attributes['level']}`,
|
|
{ ...attributes, id },
|
|
children
|
|
);
|
|
},
|
|
};
|