Skip to content

Commit 2a6bd2e

Browse files
authored
Merge pull request #236 from hbergren/see-tag
Add support for the `@see` tag
2 parents ae904cd + 738354c commit 2a6bd2e

File tree

6 files changed

+120
-3
lines changed

6 files changed

+120
-3
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/tsdoc",
5+
"comment": "Add support for `@see` tag",
6+
"type": "patch"
7+
}
8+
],
9+
"packageName": "@microsoft/tsdoc",
10+
"email": "hansbergren@gmail.com"
11+
}

playground/src/DocHtmlView.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,43 @@ export class DocHtmlView extends React.Component<IDocHtmlViewProps> {
7272
);
7373
}
7474

75+
const exampleBlocks: tsdoc.DocBlock[] = docComment.customBlocks.filter(x => x.blockTag.tagNameWithUpperCase
76+
=== tsdoc.StandardTags.example.tagNameWithUpperCase);
77+
78+
let exampleNumber: number = 1;
79+
for (const exampleBlock of exampleBlocks) {
80+
const heading: string = exampleBlocks.length > 1 ? `Example ${exampleNumber}` : 'Example';
81+
82+
outputElements.push(
83+
<React.Fragment key='seeAlso'>
84+
<h2 className='doc-heading'>{heading}</h2>
85+
{ this._renderContainer(exampleBlock.content) }
86+
</React.Fragment>
87+
);
88+
89+
++exampleNumber;
90+
}
91+
92+
if (docComment.seeBlocks.length > 0) {
93+
const listItems: React.ReactNode[] = [];
94+
for (const seeBlock of docComment.seeBlocks) {
95+
listItems.push(
96+
<li key={`item_${listItems.length}`}>
97+
{ this._renderContainer(seeBlock.content) }
98+
</li>
99+
);
100+
}
101+
102+
outputElements.push(
103+
<React.Fragment key='seeAlso'>
104+
<h2 className='doc-heading'>See Also</h2>
105+
<ul>
106+
{listItems}
107+
</ul>
108+
</React.Fragment>
109+
);
110+
}
111+
75112
const modifierTags: ReadonlyArray<tsdoc.DocBlockTag> = docComment.modifierTagSet.nodes;
76113

77114
if (modifierTags.length > 0) {

tsdoc/src/details/StandardTags.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,15 @@ export class StandardTags {
125125
* separate NPM package.
126126
*
127127
* What gets copied
128-
*
129-
* The `@inheritDoc` tag does not copy the entire comment body. Only the following
128+
*
129+
* The `@inheritDoc` tag does not copy the entire comment body. Only the following
130130
* components are copied:
131131
* - summary section
132132
* - `@remarks` block
133133
* - `@params` blocks
134134
* - `@typeParam` blocks
135135
* - `@returns` block
136-
* Other tags such as `@defaultValue` or `@example` are not copied, and need to be
136+
* Other tags such as `@defaultValue` or `@example` are not copied, and need to be
137137
* explicitly included after the `@inheritDoc` tag.
138138
*
139139
* TODO: The notation for API item references is still being standardized. See this issue:
@@ -328,6 +328,52 @@ export class StandardTags {
328328
standardization: Standardization.Extended
329329
});
330330

331+
/**
332+
* (Extended)
333+
*
334+
* Used to build a list of references to an API item or other resource that may be related to the
335+
* current item.
336+
*
337+
* @remarks
338+
*
339+
* For example:
340+
*
341+
* ```ts
342+
* /**
343+
* * Parses a string containing a Uniform Resource Locator (URL).
344+
* * @see {@link ParsedUrl} for the returned data structure
345+
* * @see {@link https://tools.ietf.org/html/rfc1738|RFC 1738}
346+
* * for syntax
347+
* * @see your developer SDK for code samples
348+
* * @param url - the string to be parsed
349+
* * @returns the parsed result
350+
* &#42;/
351+
* function parseURL(url: string): ParsedUrl;
352+
* ```
353+
*
354+
* `@see` is a block tag. Each block becomes an item in the list of references. For example, a documentation
355+
* system might render the above blocks as follows:
356+
*
357+
* ```markdown
358+
* `function parseURL(url: string): ParsedUrl;`
359+
*
360+
* Parses a string containing a Uniform Resource Locator (URL).
361+
*
362+
* ## See Also
363+
* - ParsedUrl for the returned data structure
364+
* - RFC 1738 for syntax
365+
* - your developer SDK for code samples
366+
* ```
367+
*
368+
* NOTE: JSDoc attempts to automatically hyperlink the text immediately after `@see`. Because this is ambiguous
369+
* with plain text, TSDoc instead requires an explicit `{@link}` tag to make hyperlinks.
370+
*/
371+
public static readonly see: TSDocTagDefinition = StandardTags._defineTag({
372+
tagName: '@see',
373+
syntaxKind: TSDocTagSyntaxKind.BlockTag,
374+
standardization: Standardization.Extended
375+
});
376+
331377
/**
332378
* (Extended)
333379
*
@@ -420,6 +466,7 @@ export class StandardTags {
420466
StandardTags.remarks,
421467
StandardTags.returns,
422468
StandardTags.sealed,
469+
StandardTags.see,
423470
StandardTags.throws,
424471
StandardTags.typeParam,
425472
StandardTags.virtual

tsdoc/src/emitters/TSDocEmitter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export class TSDocEmitter {
130130
docComment.typeParams,
131131
docComment.returnsBlock,
132132
...docComment.customBlocks,
133+
...docComment.seeBlocks,
133134
docComment.inheritDocTag
134135
]);
135136
if (docComment.modifierTagSet.nodes.length > 0) {

tsdoc/src/nodes/DocComment.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export class DocComment extends DocNode {
8787
*/
8888
public readonly modifierTagSet: StandardModifierTagSet;
8989

90+
private _seeBlocks: DocBlock[];
9091
private _customBlocks: DocBlock[];
9192

9293
/**
@@ -106,6 +107,7 @@ export class DocComment extends DocNode {
106107

107108
this.modifierTagSet = new StandardModifierTagSet();
108109

110+
this._seeBlocks = []
109111
this._customBlocks = [];
110112
}
111113

@@ -114,13 +116,28 @@ export class DocComment extends DocNode {
114116
return DocNodeKind.Comment;
115117
}
116118

119+
/**
120+
* The collection of all `@see` DockBlockTag nodes belonging to this doc comment.
121+
*/
122+
public get seeBlocks(): ReadonlyArray<DocBlock> {
123+
return this._seeBlocks;
124+
}
125+
117126
/**
118127
* The collection of all DocBlock nodes belonging to this doc comment.
119128
*/
120129
public get customBlocks(): ReadonlyArray<DocBlock> {
121130
return this._customBlocks;
122131
}
123132

133+
/**
134+
* Append an item to the seeBlocks collection.
135+
* @internal
136+
*/
137+
public _appendSeeBlock(block: DocBlock): void {
138+
this._seeBlocks.push(block);
139+
}
140+
124141
/**
125142
* Append an item to the customBlocks collection.
126143
*/
@@ -139,6 +156,7 @@ export class DocComment extends DocNode {
139156
this.typeParams.count > 0 ? this.typeParams : undefined,
140157
this.returnsBlock,
141158
...this.customBlocks,
159+
...this.seeBlocks,
142160
this.inheritDocTag,
143161
...this.modifierTagSet.nodes
144162
];

tsdoc/src/parser/NodeParser.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ export class NodeParser {
329329
case StandardTags.returns.tagNameWithUpperCase:
330330
docComment.returnsBlock = block;
331331
break;
332+
case StandardTags.see.tagNameWithUpperCase:
333+
docComment._appendSeeBlock(block);
334+
break;
332335
default:
333336
docComment.appendCustomBlock(block);
334337
}

0 commit comments

Comments
 (0)