Docs: handle errors gracefully when extracting headings from JSX

This commit is contained in:
gbuomprisco
2024-11-01 15:03:42 +08:00
parent 9681d51a08
commit 124edb006e

View File

@@ -53,79 +53,89 @@ export function extractHeadingsFromJSX(jsx: {
function getTextContent( function getTextContent(
children: React.ReactElement[] | string | React.ReactElement, children: React.ReactElement[] | string | React.ReactElement,
): string { ): string {
if (typeof children === 'string') { try {
return children; if (typeof children === 'string') {
} return children;
}
if (Array.isArray(children)) { if (Array.isArray(children)) {
return children.map((child) => getTextContent(child)).join(''); return children.map((child) => getTextContent(child)).join('');
} }
if ( if (
( (
children.props as { children.props as {
children: React.ReactElement; children: React.ReactElement;
} }
).children ).children
) { ) {
return getTextContent((children.props as { children: React.ReactElement }).children); return getTextContent(
} (children.props as { children: React.ReactElement }).children,
);
}
return ''; return '';
} catch {
return '';
}
} }
jsx.props.children.forEach((node) => { try {
if (!node || typeof node !== 'object' || !('type' in node)) { jsx.props.children.forEach((node) => {
return; if (!node || typeof node !== 'object' || !('type' in node)) {
} return;
const nodeType = node.type as string;
const text = getTextContent(
(
node.props as {
children: React.ReactElement[];
}
).children,
);
if (nodeType === 'h1') {
const slug = generateSlug(text);
headings.push({
text,
level: 1,
href: `#${slug}`,
children: [],
});
} else if (nodeType === 'h2') {
const slug = generateSlug(text);
currentH2 = {
text,
level: 2,
href: `#${slug}`,
children: [],
};
if (headings.length > 0) {
headings[headings.length - 1]!.children.push(currentH2);
} else {
headings.push(currentH2);
} }
} else if (nodeType === 'h3' && currentH2) {
const slug = generateSlug(text);
currentH2.children.push({ const nodeType = node.type as string;
text,
level: 3,
href: `#${slug}`,
children: [],
});
}
});
return headings; const text = getTextContent(
(
node.props as {
children: React.ReactElement[];
}
).children,
);
if (nodeType === 'h1') {
const slug = generateSlug(text);
headings.push({
text,
level: 1,
href: `#${slug}`,
children: [],
});
} else if (nodeType === 'h2') {
const slug = generateSlug(text);
currentH2 = {
text,
level: 2,
href: `#${slug}`,
children: [],
};
if (headings.length > 0) {
headings[headings.length - 1]!.children.push(currentH2);
} else {
headings.push(currentH2);
}
} else if (nodeType === 'h3' && currentH2) {
const slug = generateSlug(text);
currentH2.children.push({
text,
level: 3,
href: `#${slug}`,
children: [],
});
}
});
return headings;
} catch {
return [];
}
} }
function generateSlug(text: string): string { function generateSlug(text: string): string {