Skip to content

Commit

Permalink
Add support for rendering @linkcode jsdoc tags as code
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed Aug 3, 2021
1 parent 5bc1431 commit e4eaed4
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

import * as assert from 'assert';
import 'mocha';
import { SymbolDisplayPart } from 'typescript/lib/protocol';
import { Uri } from 'vscode';
import { IFilePathToResourceConverter, markdownDocumentation, tagsMarkdownPreview } from '../../utils/previewer';
import { IFilePathToResourceConverter, markdownDocumentation, plainWithLinks, tagsMarkdownPreview } from '../../utils/previewer';

const noopToResource: IFilePathToResourceConverter = {
toResource: (path) => Uri.file(path)
Expand Down Expand Up @@ -85,5 +86,46 @@ suite('typescript.previewer', () => {
], noopToResource),
'*@param* `parámetroConDiacríticos` — this will not');
});

test('Should render @linkcode symbol name as code', async () => {
assert.strictEqual(
plainWithLinks([
{ "text": "a ", "kind": "text" },
{ "text": "{@linkcode ", "kind": "link" },
{
"text": "dog",
"kind": "linkName",
"target": {
"file": "/path/file.ts",
"start": { "line": 7, "offset": 5 },
"end": { "line": 7, "offset": 13 }
}
} as SymbolDisplayPart,
{ "text": "}", "kind": "link" },
{ "text": " b", "kind": "text" }
], noopToResource),
'a [`dog`](file:///path/file.ts#L7%2C5) b');
});

test('Should render @linkcode text as code', async () => {
assert.strictEqual(
plainWithLinks([
{ "text": "a ", "kind": "text" },
{ "text": "{@linkcode ", "kind": "link" },
{
"text": "dog",
"kind": "linkName",
"target": {
"file": "/path/file.ts",
"start": { "line": 7, "offset": 5 },
"end": { "line": 7, "offset": 13 }
}
} as SymbolDisplayPart,
{ "text": "husky", "kind": "linkText" },
{ "text": "}", "kind": "link" },
{ "text": " b", "kind": "text" }
], noopToResource),
'a [`husky`](file:///path/file.ts#L7%2C5) b');
});
});

20 changes: 14 additions & 6 deletions extensions/typescript-language-features/src/utils/previewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,36 +127,40 @@ function convertLinkTags(

const out: string[] = [];

let currentLink: { name?: string, target?: Proto.FileSpan, text?: string } | undefined;
let currentLink: { name?: string, target?: Proto.FileSpan, text?: string, readonly linkcode: boolean } | undefined;
for (const part of parts) {
switch (part.kind) {
case 'link':
if (currentLink) {
const text = currentLink.text ?? currentLink.name;
if (currentLink.target) {
const link = filePathConverter.toResource(currentLink.target.file)
.with({
fragment: `L${currentLink.target.start.line},${currentLink.target.start.offset}`
});

out.push(`[${text}](${link.toString()})`);
const linkText = currentLink.text ? currentLink.text : escapeMarkdownSyntaxTokensForCode(currentLink.name ?? '');
out.push(`[${currentLink.linkcode ? '`' + linkText + '`' : linkText}](${link.toString()})`);
} else {
const text = currentLink.text ?? currentLink.name;
if (text) {
if (/^https?:/.test(text)) {
const parts = text.split(' ');
if (parts.length === 1) {
out.push(parts[0]);
} else if (parts.length > 1) {
out.push(`[${parts.slice(1).join(' ')}](${parts[0]})`);
const linkText = escapeMarkdownSyntaxTokensForCode(parts.slice(1).join(' '));
out.push(`[${currentLink.linkcode ? '`' + linkText + '`' : linkText}](${parts[0]})`);
}
} else {
out.push(text);
out.push(escapeMarkdownSyntaxTokensForCode(text));
}
}
}
currentLink = undefined;
} else {
currentLink = {};
currentLink = {
linkcode: part.text === '{@linkcode '
};
}
break;

Expand Down Expand Up @@ -217,3 +221,7 @@ export function addMarkdownDocumentation(
}
return out;
}

function escapeMarkdownSyntaxTokensForCode(text: string): string {
return text.replace(/`/g, '\\$&');
}
Loading

0 comments on commit e4eaed4

Please sign in to comment.