Skip to content

Commit

Permalink
feat: TypeDoc 0.23 compatibility fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tgreyuk committed Jun 27, 2022
1 parent 7c23fec commit f39318e
Show file tree
Hide file tree
Showing 22 changed files with 119 additions and 276 deletions.
2 changes: 1 addition & 1 deletion packages/typedoc-plugin-markdown/package.json
Expand Up @@ -38,7 +38,7 @@
"typedoc"
],
"peerDependencies": {
"typedoc": ">=0.22.0"
"typedoc": ">=0.23.0"
},
"dependencies": {
"handlebars": "^4.7.7"
Expand Down
2 changes: 2 additions & 0 deletions packages/typedoc-plugin-markdown/src/render-utils.ts
Expand Up @@ -22,6 +22,7 @@ import referenceMember from './resources/helpers/reference-member';
import reflectionPathHelper from './resources/helpers/reflection-path';
import reflectionTitleHelper from './resources/helpers/reflection-title';
import relativeUrlHelper from './resources/helpers/relative-url';
import returns from './resources/helpers/returns';
import signatureTitleHelper from './resources/helpers/signature-title';
import tocHelper from './resources/helpers/toc';
import typeHelper from './resources/helpers/type';
Expand Down Expand Up @@ -77,6 +78,7 @@ export function registerHelpers(theme: MarkdownTheme) {
reflectionPathHelper();
reflectionTitleHelper(theme);
relativeUrlHelper(theme);
returns();
signatureTitleHelper(theme);
tocHelper(theme);
typeHelper();
Expand Down
158 changes: 38 additions & 120 deletions packages/typedoc-plugin-markdown/src/resources/helpers/comment.ts
@@ -1,130 +1,48 @@
import * as Handlebars from 'handlebars';
import { CommentDisplayPart } from 'typedoc/dist/lib/models/comments/comment';
import { MarkdownTheme } from '../../theme';
import * as path from 'path';
import * as fs from 'fs';
import { Reflection } from 'typedoc';

const URL_PREFIX = /^(http|ftp)s?:\/\//;
const BRACKETS = /\[\[([^\]]+)\]\]/g;
const INLINE_TAG =
/(?:\[(.+?)\])?\{@(link|linkcode|linkplain)\s+((?:.|\n)+?)\}/gi;
const INCLUDE_PATTERN = /\[\[include:([^\]]+?)\]\]/g;
const MEDIA_PATTERN = /media:\/\/([^ "\)\]\}]+)/g;

export default function (theme: MarkdownTheme) {
Handlebars.registerHelper('comment', function (this: string) {
const { project, reflection, includes, mediaDirectory } = theme;

function replaceBrackets(text: string) {
return text.replace(
BRACKETS,
(match: string, content: string): string => {
const split = splitLinkText(content);
return buildLink(match, split.target, split.caption);
},
);
}

function replaceInlineTags(text: string): string {
return text.replace(
INLINE_TAG,
(match: string, leading: string, tagName: string, content: string) => {
const split = splitLinkText(content);
const target = split.target;
const caption = leading || split.caption;

return buildLink(match, target, caption, tagName === 'linkcode');
},
);
}

function buildLink(
original: string,
target: string,
caption: string,
monospace = false,
) {
if (monospace) {
caption = '`' + caption + '`';
}

if (URL_PREFIX.test(target)) {
return `[${caption}](${target})`;
}

let targetReflection: Reflection | undefined;
if (reflection) {
targetReflection = reflection.findReflectionByName(target);
} else if (project) {
targetReflection = project.findReflectionByName(target);
}

if (targetReflection && targetReflection.url) {
return `[${caption}](${Handlebars.helpers.relativeURL(
targetReflection.url,
)})`;
} else {
return original;
}
}

function splitLinkText(text: string) {
let splitIndex = text.indexOf('|');
if (splitIndex === -1) {
splitIndex = text.search(/\s/);
}
if (splitIndex !== -1) {
return {
caption: text
.substr(splitIndex + 1)
.replace(/\n+/, ' ')
.trim(),
target: text.substr(0, splitIndex).trim(),
};
} else {
return {
caption: text,
target: text,
};
}
}

let text = this;
const context = Object.assign(text, '');

if (includes) {
text = text.replace(
INCLUDE_PATTERN,
(match: string, includesPath: string) => {
includesPath = path.join(includes!, includesPath.trim());
if (
fs.existsSync(includesPath) &&
fs.statSync(includesPath).isFile()
) {
const contents = fs.readFileSync(includesPath, 'utf-8');
if (includesPath.substr(-4).toLocaleLowerCase() === '.hbs') {
const template = Handlebars.compile(contents);
return template(context);
} else {
return contents;
Handlebars.registerHelper('comment', function (parts: CommentDisplayPart[]) {
const result: string[] = [];
for (const part of parts) {
switch (part.kind) {
case 'text':
case 'code':
result.push(part.text);
break;
case 'inline-tag':
switch (part.tag) {
case '@label':
case '@inheritdoc':
break;
case '@link':
case '@linkcode':
case '@linkplain': {
if (part.target) {
const url =
typeof part.target === 'string'
? part.target
: Handlebars.helpers.relativeURL(part.target.url);
const wrap = part.tag === '@linkcode' ? '`' : '';
result.push(
url ? `[${wrap}${part.text}${wrap}](${url})` : part.text,
);
} else {
result.push(part.text);
}
break;
}
} else {
return '';
default:
result.push(`{${part.tag} ${part.text}}`);
break;
}
},
);
}

if (mediaDirectory) {
text = text.replace(MEDIA_PATTERN, (match: string, mediaPath: string) => {
if (fs.existsSync(path.join(mediaDirectory!, mediaPath))) {
return Handlebars.helpers.relativeURL('media') + '/' + mediaPath;
} else {
return match;
}
});
break;
default:
result.push('');
}
}

return replaceInlineTags(replaceBrackets(text));
return result.join('');
});
}
30 changes: 12 additions & 18 deletions packages/typedoc-plugin-markdown/src/resources/helpers/comments.ts
Expand Up @@ -2,28 +2,22 @@ import * as Handlebars from 'handlebars';
import { Comment } from 'typedoc';

export default function () {
Handlebars.registerHelper('comments', function (this: Comment) {
Handlebars.registerHelper('comments', function (comment: Comment) {
const md: string[] = [];

if (this.shortText) {
md.push(Handlebars.helpers.comment.call(this.shortText));
if (comment.summary) {
md.push(Handlebars.helpers.comment(comment.summary));
}

if (this.text) {
md.push(Handlebars.helpers.comment.call(this.text));
}

if (this.tags) {
const tags = this.tags.map(
(tag) =>
`**\`${tag.tagName}\`**${
tag.text
? Handlebars.helpers.comment.call(
(tag.text.startsWith('\n') ? '' : ' ') + tag.text,
)
: ''
}`,
);
if (comment.blockTags?.length) {
const tags = comment.blockTags
.filter((tag) => tag.tag !== '@returns')
.map(
(tag) =>
`**\`${tag.tag.substring(1)}\`** ${Handlebars.helpers.comment(
tag.content,
)}`,
);
md.push(tags.join('\n\n'));
}

Expand Down
Expand Up @@ -41,8 +41,7 @@ function table(parameters: any) {
const showDefaults = hasDefaultValues(parameters);

const comments = parameters.map(
(param) =>
!!param.comment?.text?.trim() || !!param.comment?.shortText?.trim(),
(param) => !!param.comment?.hasVisibleComponent(),
);
const hasComments = !comments.every((value) => !value);

Expand Down Expand Up @@ -78,7 +77,7 @@ function table(parameters: any) {
if (parameter.comment) {
row.push(
stripLineBreaks(
Handlebars.helpers.comments.call(parameter.comment),
Handlebars.helpers.comments(parameter.comment),
).replace(/\|/g, '\\|'),
);
} else {
Expand Down
Expand Up @@ -7,8 +7,7 @@ export default function () {
'propertyTable',
function (this: DeclarationReflection[]) {
const comments = this.map(
(param) =>
!!param.comment?.text?.trim() || !!param.comment?.shortText?.trim(),
(param) => !!param.comment?.hasVisibleComponent(),
);
const hasComments = !comments.every((value) => !value);

Expand Down Expand Up @@ -64,9 +63,10 @@ export default function () {
const comments = getComments(property);
if (comments) {
row.push(
stripLineBreaks(
Handlebars.helpers.comments.call(comments),
).replace(/\|/g, '\\|'),
stripLineBreaks(Handlebars.helpers.comments(comments)).replace(
/\|/g,
'\\|',
),
);
} else {
row.push('-');
Expand Down
17 changes: 17 additions & 0 deletions packages/typedoc-plugin-markdown/src/resources/helpers/returns.ts
@@ -0,0 +1,17 @@
import * as Handlebars from 'handlebars';
import { Comment } from 'typedoc';

export default function () {
Handlebars.registerHelper('returns', function (comment: Comment) {
const md: string[] = [];

if (comment.blockTags?.length) {
const tags = comment.blockTags
.filter((tag) => tag.tag === '@returns')
.map((tag) => Handlebars.helpers.comment(tag.content));
md.push(tags.join('\n\n'));
}

return md.join('');
});
}
Expand Up @@ -13,10 +13,11 @@ export default function () {

function table(parameters: any) {
const showTypeCol = hasTypes(parameters);

const comments = parameters.map(
(param) =>
!!param.comment?.text?.trim() || !!param.comment?.shortText?.trim(),
(param) => !!param.comment?.hasVisibleComponent(),
);

const hasComments = !comments.every((value) => !value);

const headers = ['Name'];
Expand Down Expand Up @@ -57,7 +58,7 @@ function table(parameters: any) {
if (parameter.comment) {
row.push(
stripLineBreaks(
Handlebars.helpers.comments.call(parameter.comment),
Handlebars.helpers.returns(parameter.comment),
).replace(/\|/g, '\\|'),
);
} else {
Expand Down
Expand Up @@ -2,7 +2,7 @@

{{#if hasVisibleComponent}}

{{{comments}}}
{{{comments this}}}

{{/if}}

Expand Down
Expand Up @@ -62,16 +62,12 @@

{{/with}}

{{#if comment.returns}}
{{#with comment}}

{{#with comment.returns}}

{{{comment}}}
{{{returns this}}}

{{/with}}

{{/if}}

{{#with type}}

{{#if declaration.signatures}}
Expand Down
Expand Up @@ -2,6 +2,6 @@

{{#with model.readme}}

{{{comment}}}
{{{comment this}}}

{{/with}}
7 changes: 5 additions & 2 deletions packages/typedoc-plugin-markdown/src/theme.ts
@@ -1,5 +1,6 @@
import * as path from 'path';
import {
BindOption,
ContainerReflection,
DeclarationReflection,
PageEvent,
Expand All @@ -23,11 +24,14 @@ import {
import { formatContents } from './utils';

export class MarkdownTheme extends Theme {
@BindOption('hideBreadcrumbs')
hideBreadcrumbs!: boolean;

allReflectionsHaveOwnDocument!: boolean;
entryDocument: string;
entryPoints!: string[];
filenameSeparator!: string;
hideBreadcrumbs!: boolean;

hideInPageTOC!: boolean;
hidePageTitle!: boolean;
hideMembersSymbol!: boolean;
Expand Down Expand Up @@ -55,7 +59,6 @@ export class MarkdownTheme extends Theme {
this.entryDocument = this.getOption('entryDocument') as string;
this.entryPoints = this.getOption('entryPoints') as string[];
this.filenameSeparator = this.getOption('filenameSeparator') as string;
this.hideBreadcrumbs = this.getOption('hideBreadcrumbs') as boolean;
this.hideInPageTOC = this.getOption('hideInPageTOC') as boolean;
this.hidePageTitle = this.getOption('hidePageTitle') as boolean;
this.hideMembersSymbol = this.getOption('hideMembersSymbol') as boolean;
Expand Down

0 comments on commit f39318e

Please sign in to comment.