Skip to content

Commit

Permalink
feat(website): render tsdoc examples (#8494)
Browse files Browse the repository at this point in the history
  • Loading branch information
suneettipirneni authored Aug 16, 2022
1 parent c99b808 commit 7116647
Show file tree
Hide file tree
Showing 22 changed files with 377 additions and 204 deletions.
6 changes: 2 additions & 4 deletions packages/website/src/DocModel/DocEnum.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ApiEnum, ApiModel } from '@microsoft/api-extractor-model';
import { DocItem } from './DocItem';
import { CommentNodeContainer } from './comment/CommentNodeContainer';
import { nodeContainer } from './comment/CommentNodeContainer';
import { genToken, TokenDocumentation } from '~/util/parse.server';

export interface EnumMemberData {
Expand All @@ -18,9 +18,7 @@ export class DocEnum extends DocItem<ApiEnum> {
this.members = item.members.map((member) => ({
name: member.name,
initializerTokens: member.initializerExcerpt?.spannedTokens.map((token) => genToken(this.model, token)) ?? [],
summary: member.tsdocComment
? new CommentNodeContainer(member.tsdocComment.summarySection, model, member).toJSON()
: null,
summary: member.tsdocComment ? nodeContainer(member.tsdocComment.summarySection, model, member) : null,
}));
}

Expand Down
19 changes: 12 additions & 7 deletions packages/website/src/DocModel/DocItem.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ApiModel, ApiDeclaredItem } from '@microsoft/api-extractor-model';
import { CommentNodeContainer } from './comment/CommentNodeContainer';
import { createCommentNode } from './comment';
import type { AnyDocNodeJSON } from './comment/CommentNode';
import type { DocNodeContainerJSON } from './comment/CommentNodeContainer';
import type { ReferenceData } from '~/util/model.server';
import { resolveName, genReference, TokenDocumentation, genToken } from '~/util/parse.server';

Expand All @@ -13,9 +15,10 @@ export class DocItem<T extends ApiDeclaredItem = ApiDeclaredItem> {
public readonly excerpt: string;
public readonly excerptTokens: TokenDocumentation[] = [];
public readonly kind: string;
public readonly remarks: CommentNodeContainer | null;
public readonly summary: CommentNodeContainer | null;
public readonly remarks: DocNodeContainerJSON | null;
public readonly summary: DocNodeContainerJSON | null;
public readonly containerKey: string;
public readonly comment: AnyDocNodeJSON | null;

public constructor(model: ApiModel, item: T) {
this.item = item;
Expand All @@ -26,12 +29,13 @@ export class DocItem<T extends ApiDeclaredItem = ApiDeclaredItem> {
this.excerpt = item.excerpt.text;
this.excerptTokens = item.excerpt.spannedTokens.map((token) => genToken(model, token));
this.remarks = item.tsdocComment?.remarksBlock
? new CommentNodeContainer(item.tsdocComment.remarksBlock.content, model, item.parent)
? (createCommentNode(item.tsdocComment.remarksBlock, model, item.parent) as DocNodeContainerJSON)
: null;
this.summary = item.tsdocComment?.summarySection
? new CommentNodeContainer(item.tsdocComment.summarySection, model, item.parent)
? (createCommentNode(item.tsdocComment.summarySection, model, item.parent) as DocNodeContainerJSON)
: null;
this.containerKey = item.containerKey;
this.comment = item.tsdocComment ? createCommentNode(item.tsdocComment, model, item.parent) : null;
}

public get path() {
Expand All @@ -54,13 +58,14 @@ export class DocItem<T extends ApiDeclaredItem = ApiDeclaredItem> {
return {
name: this.name,
referenceData: this.referenceData,
summary: this.summary?.toJSON() ?? null,
summary: this.summary,
excerpt: this.excerpt,
excerptTokens: this.excerptTokens,
kind: this.kind,
remarks: this.remarks?.toJSON() ?? null,
remarks: this.remarks,
path: this.path,
containerKey: this.containerKey,
comment: this.comment,
};
}
}
18 changes: 18 additions & 0 deletions packages/website/src/DocModel/comment/CommentBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { ApiModel, ApiItem } from '@microsoft/api-extractor-model';
import type { DocBlock } from '@microsoft/tsdoc';
import { createCommentNode } from '.';
import { blockTag, DocBlockTagJSON } from './CommentBlockTag';
import { AnyDocNodeJSON, DocNodeJSON, node } from './CommentNode';

export interface DocBlockJSON extends DocNodeJSON {
content: AnyDocNodeJSON[];
tag: DocBlockTagJSON;
}

export function block(block: DocBlock, model: ApiModel, parentItem?: ApiItem) {
return {
...node(block),
content: block.content.nodes.map((node) => createCommentNode(node, model, parentItem)),
tag: blockTag(block.blockTag),
};
}
13 changes: 13 additions & 0 deletions packages/website/src/DocModel/comment/CommentBlockTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { DocBlockTag } from '@microsoft/tsdoc';
import { type DocNodeJSON, node } from './CommentNode';

export interface DocBlockTagJSON extends DocNodeJSON {
tagName: string;
}

export function blockTag(blockTag: DocBlockTag): DocBlockTagJSON {
return {
...node(blockTag),
tagName: blockTag.tagName,
};
}
13 changes: 13 additions & 0 deletions packages/website/src/DocModel/comment/CommentCodeSpan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { DocCodeSpan } from '@microsoft/tsdoc';
import { DocNodeJSON, node } from './CommentNode';

export interface DocCodeSpanJSON extends DocNodeJSON {
code: string;
}

export function codeSpan(codeSpan: DocCodeSpan): DocCodeSpanJSON {
return {
...node(codeSpan),
code: codeSpan.code,
};
}
42 changes: 24 additions & 18 deletions packages/website/src/DocModel/comment/CommentNode.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import type { ApiItem, ApiModel } from '@microsoft/api-extractor-model';
import type { DocNode } from '@microsoft/tsdoc';
import type { DocNode, DocNodeKind } from '@microsoft/tsdoc';
import type { DocBlockJSON } from './CommentBlock';
import type { DocCodeSpanJSON } from './CommentCodeSpan';
import type { DocNodeContainerJSON } from './CommentNodeContainer';
import type { DocFencedCodeJSON } from './FencedCodeCommentNode';
import type { DocLinkTagJSON } from './LinkTagCommentNode';
import type { DocPlainTextJSON } from './PlainTextCommentNode';
import type { DocCommentJSON } from './RootComment';

export class CommentNode<T extends DocNode = DocNode> {
public readonly node: T;
public readonly kind: string;
public readonly model: ApiModel;
public readonly parentItem: ApiItem | null;
export interface DocNodeJSON {
kind: DocNodeKind;
}

public constructor(node: T, model: ApiModel, parentItem?: ApiItem) {
this.node = node;
this.kind = node.kind;
this.model = model;
this.parentItem = parentItem ?? null;
}
export type AnyDocNodeJSON =
| DocNodeJSON
| DocPlainTextJSON
| DocNodeContainerJSON
| DocLinkTagJSON
| DocFencedCodeJSON
| DocBlockJSON
| DocCommentJSON
| DocCodeSpanJSON;

public toJSON() {
return {
kind: this.kind,
};
}
export function node(node: DocNode): DocNodeJSON {
return {
kind: node.kind as DocNodeKind,
};
}
27 changes: 13 additions & 14 deletions packages/website/src/DocModel/comment/CommentNodeContainer.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import type { ApiItem, ApiModel } from '@microsoft/api-extractor-model';
import type { DocNodeContainer } from '@microsoft/tsdoc';
import { createCommentNode } from '.';
import { CommentNode } from './CommentNode';
import { AnyDocNodeJSON, DocNodeJSON, node } from './CommentNode';

export class CommentNodeContainer<T extends DocNodeContainer = DocNodeContainer> extends CommentNode<DocNodeContainer> {
public readonly nodes: CommentNode[];

public constructor(container: T, model: ApiModel, parentItem?: ApiItem) {
super(container, model, parentItem);
this.nodes = container.nodes.map((node) => createCommentNode(node, model, parentItem));
}
export interface DocNodeContainerJSON extends DocNodeJSON {
nodes: AnyDocNodeJSON[];
}

public override toJSON() {
return {
...super.toJSON(),
nodes: this.nodes.map((node) => node.toJSON()),
};
}
export function nodeContainer(
container: DocNodeContainer,
model: ApiModel,
parentItem?: ApiItem,
): DocNodeContainerJSON {
return {
...node(container),
nodes: container.nodes.map((node) => createCommentNode(node, model, parentItem)),
};
}
29 changes: 11 additions & 18 deletions packages/website/src/DocModel/comment/FencedCodeCommentNode.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import type { ApiModel, ApiItem } from '@microsoft/api-extractor-model';
import type { DocFencedCode } from '@microsoft/tsdoc';
import { CommentNode } from './CommentNode';
import { DocNodeJSON, node } from './CommentNode';

export class FencedCodeCommentNode extends CommentNode<DocFencedCode> {
public readonly code: string;
public readonly language: string;

public constructor(node: DocFencedCode, model: ApiModel, parentItem?: ApiItem) {
super(node, model, parentItem);
this.code = node.code;
this.language = node.language;
}
export interface DocFencedCodeJSON extends DocNodeJSON {
code: string;
language: string;
}

public override toJSON() {
return {
...super.toJSON(),
code: this.code,
language: this.language,
};
}
export function fencedCode(fencedCode: DocFencedCode) {
return {
...node(fencedCode),
language: fencedCode.language,
code: fencedCode.code,
};
}
38 changes: 18 additions & 20 deletions packages/website/src/DocModel/comment/LinkTagCommentNode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type { ApiItem, ApiModel } from '@microsoft/api-extractor-model';
import type { DocDeclarationReference, DocLinkTag } from '@microsoft/tsdoc';
import { CommentNode } from './CommentNode';
import { DocNodeJSON, node } from './CommentNode';
import { generatePath, resolveName } from '~/util/parse.server';

export interface DocLinkTagJSON extends DocNodeJSON {
text: string | null;
codeDestination: LinkTagCodeLink | null;
urlDestination: string | null;
}

export function genToken(
model: ApiModel,
ref: DocDeclarationReference,
Expand Down Expand Up @@ -31,24 +37,16 @@ export interface LinkTagCodeLink {
path: string;
}

export class LinkTagCommentNode extends CommentNode<DocLinkTag> {
public readonly codeDestination: LinkTagCodeLink | null;
public readonly text: string | null;
public readonly urlDestination: string | null;

public constructor(node: DocLinkTag, model: ApiModel, parentItem?: ApiItem) {
super(node, model, parentItem);
this.codeDestination = node.codeDestination ? genToken(model, node.codeDestination, this.parentItem) : null;
this.text = node.linkText ?? null;
this.urlDestination = node.urlDestination ?? null;
}
export function linkTagNode(linkNode: DocLinkTag, model: ApiModel, parentItem?: ApiItem): DocLinkTagJSON {
const codeDestination =
linkNode.codeDestination && parentItem ? genToken(model, linkNode.codeDestination, parentItem) : null;
const text = linkNode.linkText ?? null;
const urlDestination = linkNode.urlDestination ?? null;

public override toJSON() {
return {
...super.toJSON(),
text: this.text,
codeDestination: this.codeDestination,
urlDestination: this.urlDestination,
};
}
return {
...node(linkNode),
text,
codeDestination,
urlDestination,
};
}
24 changes: 9 additions & 15 deletions packages/website/src/DocModel/comment/PlainTextCommentNode.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import type { ApiItem, ApiModel } from '@microsoft/api-extractor-model';
import type { DocPlainText } from '@microsoft/tsdoc';
import { CommentNode } from './CommentNode';
import { DocNodeJSON, node } from './CommentNode';

export class PlainTextCommentNode extends CommentNode<DocPlainText> {
public readonly text: string;

public constructor(node: DocPlainText, model: ApiModel, parentItem?: ApiItem) {
super(node, model, parentItem);
this.text = node.text;
}
export interface DocPlainTextJSON extends DocNodeJSON {
text: string;
}

public override toJSON() {
return {
...super.toJSON(),
text: this.text,
};
}
export function plainTextNode(plainTextNode: DocPlainText): DocPlainTextJSON {
return {
...node(plainTextNode),
text: plainTextNode.text,
};
}
20 changes: 20 additions & 0 deletions packages/website/src/DocModel/comment/RootComment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { ApiItem, ApiModel } from '@microsoft/api-extractor-model';
import type { DocComment } from '@microsoft/tsdoc';
import { createCommentNode } from '.';
import { block, DocBlockJSON } from './CommentBlock';
import { DocNodeJSON, node } from './CommentNode';

export interface DocCommentJSON extends DocNodeJSON {
summary: DocNodeJSON[];
remarks: DocNodeJSON[];
customBlocks: DocBlockJSON[];
}

export function comment(comment: DocComment, model: ApiModel, parentItem?: ApiItem): DocCommentJSON {
return {
...node(comment),
summary: comment.summarySection.nodes.map((node) => createCommentNode(node, model, parentItem)),
remarks: comment.remarksBlock?.content.nodes.map((node) => createCommentNode(node, model, parentItem)) ?? [],
customBlocks: comment.customBlocks.map((_block) => block(_block, model, parentItem)),
};
}
53 changes: 37 additions & 16 deletions packages/website/src/DocModel/comment/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
import type { ApiModel, ApiItem } from '@microsoft/api-extractor-model';
import type { DocNode, DocPlainText, DocLinkTag, DocParagraph, DocFencedCode } from '@microsoft/tsdoc';
import { CommentNode } from './CommentNode';
import { CommentNodeContainer } from './CommentNodeContainer';
import { FencedCodeCommentNode } from './FencedCodeCommentNode';
import { LinkTagCommentNode } from './LinkTagCommentNode';
import { PlainTextCommentNode } from './PlainTextCommentNode';
import {
type DocNode,
type DocPlainText,
type DocLinkTag,
type DocParagraph,
type DocFencedCode,
DocNodeKind,
type DocBlock,
DocComment,
DocCodeSpan,
} from '@microsoft/tsdoc';
import { block } from './CommentBlock';
import { codeSpan } from './CommentCodeSpan';
import type { AnyDocNodeJSON } from './CommentNode';
import { node as _node } from './CommentNode';
import { nodeContainer } from './CommentNodeContainer';
import { fencedCode } from './FencedCodeCommentNode';
import { linkTagNode } from './LinkTagCommentNode';
import { plainTextNode } from './PlainTextCommentNode';
import { comment } from './RootComment';

export function createCommentNode(node: DocNode, model: ApiModel, parentItem?: ApiItem): CommentNode {
export function createCommentNode(node: DocNode, model: ApiModel, parentItem?: ApiItem): AnyDocNodeJSON {
switch (node.kind) {
case 'PlainText':
return new PlainTextCommentNode(node as DocPlainText, model, parentItem);
case 'LinkTag':
return new LinkTagCommentNode(node as DocLinkTag, model, parentItem);
case 'Paragraph':
return new CommentNodeContainer(node as DocParagraph, model, parentItem);
case 'FencedCode':
return new FencedCodeCommentNode(node as DocFencedCode, model, parentItem);
case DocNodeKind.PlainText:
return plainTextNode(node as DocPlainText);
case DocNodeKind.LinkTag:
return linkTagNode(node as DocLinkTag, model, parentItem);
case DocNodeKind.Paragraph:
case DocNodeKind.Section:
return nodeContainer(node as DocParagraph, model, parentItem);
case DocNodeKind.FencedCode:
return fencedCode(node as DocFencedCode);
case DocNodeKind.CodeSpan:
return codeSpan(node as DocCodeSpan);
case DocNodeKind.Block:
return block(node as DocBlock, model, parentItem);
case DocNodeKind.Comment:
return comment(node as DocComment, model, parentItem);
default:
return new CommentNode(node, model, parentItem);
return _node(node);
}
}
Loading

1 comment on commit 7116647

@vercel
Copy link

@vercel vercel bot commented on 7116647 Aug 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.