Skip to content

[DRAFT] refactor(api-markdown-documenter): Simplify DocumentationNode domain #24667

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49aef32
refactor: Update extensibility model for `SectionNode`
Josmithr May 19, 2025
56bbc04
fix: Node typing
Josmithr May 20, 2025
bfcf064
refactor: [WIP] Add PhrasingContent and use it in ParagraphNode
Josmithr May 20, 2025
16f53db
refactor: Add `BlockContent`
Josmithr May 20, 2025
a0bfd0a
refactor: [WIP] More type restrictions
Josmithr May 20, 2025
d8d9377
docs: Update docs
Josmithr May 20, 2025
29aedc0
refactor: Remove MultiLineDocumentationNode
Josmithr May 20, 2025
0a3c799
refactor: "Fix" the build
Josmithr May 20, 2025
12ab659
test: Temporarily throw rather than logging errors
Josmithr May 20, 2025
b458ccf
refactor: Simplify summary section generation
Josmithr May 20, 2025
cc03633
improvement: Optimize away empty / redundant paragraph and section nodes
Josmithr May 20, 2025
3c42ffa
refactor: Simplify/restrict LinkNode
Josmithr May 20, 2025
d1f4572
test: Fix cell test
Josmithr May 20, 2025
be135f6
test: Fix test
Josmithr May 20, 2025
cefac8f
refactor: Simplify/restrict CodeSpanNode
Josmithr May 20, 2025
c672f29
refactor: Simplify PlainTextNode
Josmithr May 20, 2025
5280d20
refactor: Simplify/restrict HeadingNode
Josmithr May 20, 2025
e3734f3
refactor: Update list node types to be in terms of PhrasingContent in…
Josmithr May 20, 2025
da8d3f8
refactor: Remove SingleLineSpanNode
Josmithr May 20, 2025
d99561e
refactor: Simplify SpanNode
Josmithr May 20, 2025
70b3ed3
remove: SingleLineDocumentationNode
Josmithr May 20, 2025
19aba1d
Merge branch 'main' into api-markdown-documenter/update-extensibility…
Josmithr May 21, 2025
6fc539f
refactor: Simplify TSDoc transformation domain
Josmithr May 21, 2025
f567ac8
improvement: Improve error syntax
Josmithr May 21, 2025
409d4d9
refactor: Limit API exposure for TSDoc transforms
Josmithr May 21, 2025
14b4c8f
feat: Accommodate API changes
Josmithr May 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/infra/api-markdown-documenter/api-documentation-layout.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
ReleaseTag,
SectionNode,
SpanNode,
transformTsdocNode,
transformTsdoc,
} from "@fluid-tools/api-markdown-documenter";

import { AdmonitionNode } from "./admonition-node.mjs";
Expand Down Expand Up @@ -181,9 +181,9 @@ export function layoutContent(apiItem, itemSpecificContent, config) {
const sections = [];

// Render summary comment (if any)
const summary = LayoutUtilities.createSummaryParagraph(apiItem, config);
const summary = LayoutUtilities.createSummarySection(apiItem, config);
if (summary !== undefined) {
sections.push(new SectionNode([summary]));
sections.push(summary);
}

// Render system notice (if any) that supersedes deprecation and import notices
Expand Down Expand Up @@ -279,13 +279,13 @@ function createDeprecationNoticeSection(apiItem, config) {
return undefined;
}

const transformedDeprecatedBlock = transformTsdocNode(deprecatedBlock, apiItem, config);
const transformedDeprecatedBlock = transformTsdoc(deprecatedBlock, apiItem, config);
if (transformedDeprecatedBlock === undefined) {
throw new Error("Failed to transform deprecated block.");
}

return new AdmonitionNode(
[transformedDeprecatedBlock],
transformedDeprecatedBlock,
"Warning",
"This API is deprecated and will be removed in a future release.",
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { ApiPropertySignature } from '@microsoft/api-extractor-model';
import { ApiTypeAlias } from '@microsoft/api-extractor-model';
import { ApiVariable } from '@microsoft/api-extractor-model';
import type { Data } from 'unist';
import { DocNode } from '@microsoft/tsdoc';
import { DocSection } from '@microsoft/tsdoc';
import { Excerpt } from '@microsoft/api-extractor-model';
import type { Literal } from 'unist';
Expand Down Expand Up @@ -158,20 +157,45 @@ export { ApiPackage }
export type ApiSignatureLike = ApiCallSignature | ApiIndexSignature;

// @public
export class BlockQuoteNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[]);
export type BlockContent = BlockContentMap[keyof BlockContentMap];

// @public
export interface BlockContentMap {
// (undocumented)
blockquote: BlockQuoteNode;
// (undocumented)
fencedCodeBlock: FencedCodeBlockNode;
// (undocumented)
horizontalRule: HorizontalRuleNode;
// (undocumented)
lineBreak: LineBreakNode;
// (undocumented)
orderedList: OrderedListNode;
// (undocumented)
paragraph: ParagraphNode;
// (undocumented)
table: TableNode;
// (undocumented)
unorderedList: UnorderedListNode;
}

// @public
export class BlockQuoteNode extends DocumentationParentNodeBase<PhrasingContent> {
constructor(children: PhrasingContent[]);
static createFromPlainText(text: string): BlockQuoteNode;
static readonly Empty: BlockQuoteNode;
get singleLine(): false;
readonly type = DocumentationNodeType.BlockQuote;
}

// @public
export class CodeSpanNode extends DocumentationParentNodeBase<PlainTextNode> {
constructor(children: PlainTextNode[]);
export class CodeSpanNode extends DocumentationLiteralNodeBase<PlainTextNode> {
constructor(value: PlainTextNode);
static createFromPlainText(text: string): CodeSpanNode;
static readonly Empty: CodeSpanNode;
get singleLine(): true;
// (undocumented)
get isEmpty(): boolean;
readonly singleLine = true;
readonly type = DocumentationNodeType.CodeSpan;
}

Expand Down Expand Up @@ -374,8 +398,8 @@ export namespace DocumentWriter {
}

// @public
export class FencedCodeBlockNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[], language?: string);
export class FencedCodeBlockNode extends DocumentationParentNodeBase<PhrasingContent> {
constructor(children: PhrasingContent[], language?: string);
static createFromPlainText(text: string, language?: string): FencedCodeBlockNode;
readonly language?: string;
get singleLine(): false;
Expand Down Expand Up @@ -462,12 +486,21 @@ export interface Heading {
}

// @public
export class HeadingNode extends DocumentationParentNodeBase implements Omit<Heading, "title"> {
constructor(content: DocumentationNode[], id?: string);
export class HeadingNode implements DocumentationNode<PlainTextNode>, Omit<Heading, "title"> {
constructor(text: PlainTextNode,
id?: string | undefined);
static createFromPlainText(text: string, id?: string): HeadingNode;
static createFromPlainTextHeading(heading: Heading): HeadingNode;
readonly id?: string;
get singleLine(): false;
readonly id?: string | undefined;
// (undocumented)
get isEmpty(): boolean;
// (undocumented)
readonly isLiteral = false;
// (undocumented)
readonly isParent = false;
readonly singleLine = true;
// (undocumented)
readonly text: PlainTextNode;
readonly type = DocumentationNodeType.Heading;
}

Expand Down Expand Up @@ -576,12 +609,21 @@ export interface Link {
}

// @public
export class LinkNode extends DocumentationParentNodeBase implements Omit<Link, "text"> {
constructor(content: DocumentationNode[], target: UrlTarget);
export class LinkNode implements DocumentationNode {
constructor(
text: PlainTextNode,
target: UrlTarget);
static createFromPlainText(text: string, target: UrlTarget): LinkNode;
static createFromPlainTextLink(link: Link): LinkNode;
get singleLine(): true;
// (undocumented)
get isEmpty(): boolean;
// (undocumented)
readonly isLiteral = false;
// (undocumented)
readonly isParent = false;
readonly singleLine = true;
readonly target: UrlTarget;
readonly text: PlainTextNode;
readonly type = DocumentationNodeType.Link;
}

Expand Down Expand Up @@ -667,23 +709,40 @@ export interface MarkdownRenderers {
export { NewlineKind }

// @public
export class OrderedListNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[]);
export class OrderedListNode extends DocumentationParentNodeBase<PhrasingContent> {
constructor(children: PhrasingContent[]);
static createFromPlainTextEntries(entries: string[]): OrderedListNode;
static readonly Empty: OrderedListNode;
get singleLine(): false;
readonly type = DocumentationNodeType.OrderedList;
}

// @public
export class ParagraphNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[]);
export class ParagraphNode extends DocumentationParentNodeBase<PhrasingContent> {
constructor(children: PhrasingContent[]);
static createFromPlainText(text: string): ParagraphNode;
static readonly Empty: ParagraphNode;
get singleLine(): false;
readonly type = DocumentationNodeType.Paragraph;
}

// @public
export type PhrasingContent = PhrasingContentMap[keyof PhrasingContentMap];

// @public
export interface PhrasingContentMap {
// (undocumented)
codeSpan: CodeSpanNode;
// (undocumented)
lineBreak: LineBreakNode;
// (undocumented)
link: LinkNode;
// (undocumented)
span: SpanNode;
// (undocumented)
text: PlainTextNode;
}

// @public
export class PlainTextNode extends DocumentationLiteralNodeBase<string> {
constructor(text: string, escaped?: boolean);
Expand Down Expand Up @@ -752,15 +811,17 @@ function renderNode(node: DocumentationNode, writer: DocumentWriter, context: Ma
// @public
function renderNodes(children: DocumentationNode[], writer: DocumentWriter, childContext: MarkdownRenderContext): void;

// @public
export type SectionContent = BlockContent | SectionNode;

// @public @sealed
export interface SectionHierarchyConfiguration extends DocumentationHierarchyConfigurationBase {
readonly kind: HierarchyKind.Section;
}

// @public
export class SectionNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[], heading?: HeadingNode);
static combine(...sections: SectionNode[]): SectionNode;
export class SectionNode extends DocumentationParentNodeBase<SectionContent> {
constructor(children: SectionContent[], heading?: HeadingNode);
static readonly Empty: SectionNode;
readonly heading?: HeadingNode;
get singleLine(): false;
Expand All @@ -771,8 +832,11 @@ export class SectionNode extends DocumentationParentNodeBase {
function shouldItemBeIncluded(apiItem: ApiItem, config: ApiItemTransformationConfiguration): boolean;

// @public
export class SpanNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[], formatting?: TextFormatting);
export type SpanContent = PhrasingContent | BlockContent;

// @public
export class SpanNode extends DocumentationParentNodeBase<SpanContent> {
constructor(children: SpanContent[], formatting?: TextFormatting);
static createFromPlainText(text: string, formatting?: TextFormatting): SpanNode;
static readonly Empty: SpanNode;
readonly textFormatting?: TextFormatting;
Expand All @@ -781,7 +845,7 @@ export class SpanNode extends DocumentationParentNodeBase {

// @public
export class TableBodyCellNode extends TableCellNode {
constructor(children: DocumentationNode[]);
constructor(children: TableCellContent[]);
static createFromPlainText(text: string): TableBodyCellNode;
static readonly Empty: TableBodyCellNode;
}
Expand All @@ -792,22 +856,25 @@ export class TableBodyRowNode extends TableRowNode {
static readonly Empty: TableBodyRowNode;
}

// @public
export type TableCellContent = PhrasingContent | BlockContent;

// @public
export enum TableCellKind {
Body = "Body",
Header = "Header"
}

// @public
export abstract class TableCellNode extends DocumentationParentNodeBase {
protected constructor(children: DocumentationNode[], cellKind: TableCellKind);
export abstract class TableCellNode extends DocumentationParentNodeBase<TableCellContent> {
protected constructor(children: TableCellContent[], cellKind: TableCellKind);
readonly cellKind: TableCellKind;
readonly type = DocumentationNodeType.TableCell;
}

// @public
export class TableHeaderCellNode extends TableCellNode {
constructor(children: DocumentationNode[]);
constructor(children: TableCellContent[]);
static createFromPlainText(text: string): TableHeaderCellNode;
static readonly Empty: TableHeaderCellNode;
}
Expand Down Expand Up @@ -880,11 +947,11 @@ export type TransformApiItemWithoutChildren<TApiItem extends ApiItem> = (apiItem
export function transformApiModel(options: ApiItemTransformationOptions): DocumentNode[];

// @public
export function transformTsdocNode(node: DocNode, contextApiItem: ApiItem, config: ApiItemTransformationConfiguration): DocumentationNode | undefined;
export function transformTsdoc(node: DocSection, contextApiItem: ApiItem, config: ApiItemTransformationConfiguration): BlockContent[];

// @public
export class UnorderedListNode extends DocumentationParentNodeBase {
constructor(children: DocumentationNode[]);
export class UnorderedListNode extends DocumentationParentNodeBase<PhrasingContent> {
constructor(children: PhrasingContent[]);
static createFromPlainTextEntries(entries: string[]): UnorderedListNode;
static readonly Empty: UnorderedListNode;
get singleLine(): false;
Expand Down
Loading
Loading