Skip to content

Commit c84b09f

Browse files
authored
fix(api-markdown-documenter): Fix example parsing (#25078)
Fixes `stripTitleFromExampleComment` to ensure empty parent nodes are omitted after stripping out the title. See updated test assets for impact.
1 parent 790842c commit c84b09f

File tree

5 files changed

+33
-30
lines changed

5 files changed

+33
-30
lines changed

tools/api-markdown-documenter/src/api-item-transforms/helpers/Helpers.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ function createExampleSection(
714714
): SectionNode {
715715
const { logger } = config;
716716

717-
let exampleSection: SectionNode = new SectionNode(
717+
let exampleSection: SectionNode | undefined = new SectionNode(
718718
transformTsdoc(example.content, example.apiItem, config),
719719
);
720720

@@ -748,7 +748,8 @@ function createExampleSection(
748748
example.exampleNumber ?? ""
749749
}`;
750750

751-
return wrapInSection(exampleSection.children, {
751+
// Always emit the section, even if the body is empty after stripping out the title.
752+
return wrapInSection(exampleSection?.children ?? [], {
752753
title: headingTitle,
753754
id: headingId,
754755
});
@@ -806,12 +807,14 @@ function extractTitleFromExampleSection(sectionNode: DocSection): string | undef
806807
*
807808
* In the case where the output is not in a form we expect, we will log an error and return the node we were given,
808809
* rather than making a copy.
810+
*
811+
* @returns The updated node, if any content remains. Otherwise, `undefined`.
809812
*/
810813
function stripTitleFromExampleComment<TNode extends DocumentationParentNode>(
811814
node: TNode,
812815
title: string,
813816
logger: Logger | undefined,
814-
): TNode {
817+
): TNode | undefined {
815818
// Verify title matches text of first plain text in output.
816819
// This is an expected invariant. If this is not the case, then something has gone wrong.
817820
// Note: if we ever allow consumers to provide custom DocNode transformations, this invariant will likely
@@ -833,13 +836,18 @@ function stripTitleFromExampleComment<TNode extends DocumentationParentNode>(
833836
logger,
834837
);
835838

836-
const newChildren: DocumentationNode[] = [newFirstChild, ...children.slice(1)];
839+
const remainingChildren = children.slice(1);
840+
const newChildren: DocumentationNode[] =
841+
newFirstChild === undefined ? remainingChildren : [newFirstChild, ...remainingChildren];
837842

838-
return {
839-
...node,
840-
children: newChildren,
841-
hasChildren: newChildren.length > 0,
842-
};
843+
// If there are no remaining children under this parent after stripping out the title, omit this parent node.
844+
return newChildren.length === 0
845+
? undefined
846+
: {
847+
...node,
848+
children: newChildren,
849+
hasChildren: newChildren.length > 0,
850+
};
843851
}
844852

845853
if (firstChild.isLiteral) {
@@ -851,11 +859,14 @@ function stripTitleFromExampleComment<TNode extends DocumentationParentNode>(
851859
while (newChildren.length > 0 && newChildren[0].type === "lineBreak") {
852860
newChildren.shift();
853861
}
854-
return {
855-
...node,
856-
children: newChildren,
857-
hasChildren: newChildren.length > 0,
858-
};
862+
// If there are no remaining children under this parent after stripping out the title, omit this parent node.
863+
return newChildren.length === 0
864+
? undefined
865+
: {
866+
...node,
867+
children: newChildren,
868+
hasChildren: newChildren.length > 0,
869+
};
859870
} else {
860871
logger?.error(
861872
"Transformed example paragraph does not begin with expected title. This is unexpected and indicates a bug.",

tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/deep-config/test-suite-a/testnamespace-namespace/index.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ <h2 id="testnamespace-remarks">Remarks</h2>
2222
<section>
2323
<h2 id="testnamespace-examples">Examples</h2>
2424
<section>
25-
<h3 id="testnamespace-example1">Example: TypeScript Example</h3>
26-
<p></p><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
25+
<h3 id="testnamespace-example1">Example: TypeScript Example</h3><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
2726
</section>
2827
<section>
29-
<h3 id="testnamespace-example2">Example: JavaScript Example</h3>
30-
<p></p><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
28+
<h3 id="testnamespace-example2">Example: JavaScript Example</h3><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
3129
</section>
3230
</section>
3331
<section>

tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/default-config/test-suite-a/testnamespace-namespace/index.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ <h2 id="testnamespace-remarks">Remarks</h2>
2222
<section>
2323
<h2 id="testnamespace-examples">Examples</h2>
2424
<section>
25-
<h3 id="testnamespace-example1">Example: TypeScript Example</h3>
26-
<p></p><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
25+
<h3 id="testnamespace-example1">Example: TypeScript Example</h3><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
2726
</section>
2827
<section>
29-
<h3 id="testnamespace-example2">Example: JavaScript Example</h3>
30-
<p></p><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
28+
<h3 id="testnamespace-example2">Example: JavaScript Example</h3><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
3129
</section>
3230
</section>
3331
<section>

tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/flat-config/test-suite-a.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,12 +1617,10 @@ <h3 id="testnamespace-remarks">Remarks</h3>
16171617
<section>
16181618
<h3 id="testnamespace-examples">Examples</h3>
16191619
<section>
1620-
<h4 id="testnamespace-example1">Example: TypeScript Example</h4>
1621-
<p></p><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
1620+
<h4 id="testnamespace-example1">Example: TypeScript Example</h4><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
16221621
</section>
16231622
<section>
1624-
<h4 id="testnamespace-example2">Example: JavaScript Example</h4>
1625-
<p></p><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
1623+
<h4 id="testnamespace-example2">Example: JavaScript Example</h4><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
16261624
</section>
16271625
</section>
16281626
<section>

tools/api-markdown-documenter/src/test/snapshots/html/simple-suite-test/sparse-config/test-suite-a/testnamespace-namespace.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ <h3 id="testnamespace-remarks">Remarks</h3>
1919
<section>
2020
<h3 id="testnamespace-examples">Examples</h3>
2121
<section>
22-
<h4 id="testnamespace-example1">Example: TypeScript Example</h4>
23-
<p></p><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
22+
<h4 id="testnamespace-example1">Example: TypeScript Example</h4><code>const foo: Foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
2423
</section>
2524
<section>
26-
<h4 id="testnamespace-example2">Example: JavaScript Example</h4>
27-
<p></p><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
25+
<h4 id="testnamespace-example2">Example: JavaScript Example</h4><code>const foo = {<br>bar: "Hello world!";<br>baz = 42;<br>};</code>
2826
</section>
2927
</section>
3028
<section>

0 commit comments

Comments
 (0)