diff --git a/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.spec.ts b/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.spec.ts index e4f2172f7504c..946335d845b5f 100644 --- a/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.spec.ts +++ b/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.spec.ts @@ -7,4 +7,19 @@ describe('heading schema: generateID', () => { 'pro-simple-setup' ); }); + + it('should create id for code based headers', () => { + const codeHeader = [ + { + $$mdtype: 'Tag', + name: 'code', + attributes: {}, + children: ['launch-templates..init-steps[*].env'], + }, + ]; + + expect(generateID(codeHeader, {})).toEqual( + 'launchtemplatestemplatenameinitstepsenv' + ); + }); }); diff --git a/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.ts b/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.ts index 0fda4e70748a4..769de9bfb7fa5 100644 --- a/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.ts +++ b/nx-dev/ui-markdoc/src/lib/nodes/heading.schema.ts @@ -7,8 +7,31 @@ export function generateID( if (attributes['id'] && typeof attributes['id'] === 'string') { return attributes['id']; } - return children - .filter((child) => typeof child === 'string') + + 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, '')