Skip to content

Commit d4db571

Browse files
committed
Add preserveLinkText option
Resolves #2355
1 parent 3d8ff29 commit d4db571

File tree

8 files changed

+55
-14
lines changed

8 files changed

+55
-14
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
### Features
1414

1515
- TypeDoc config files now support options default-exported from an ESM config file, #2268.
16+
- TypeDoc config files may now export a promise containing configuration, #2268.
17+
- Added `--preserveLinkText` option (defaults to true) which determines whether the reflection name or full link text is included
18+
in the output when no override is specified, #2355.
1619
- Added a no-results placeholder when no search results are available, #2347.
1720
- Implemented several miscellaneous performance improvements to generate docs faster, this took the time to generate TypeDoc's
1821
site from ~5.6 seconds to ~5.4 seconds.

src/lib/converter/comments/linkResolver.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,28 @@ export type ExternalSymbolResolver = (
3232
symbolId: ReflectionSymbolId | undefined,
3333
) => ExternalResolveResult | string | undefined;
3434

35+
export type LinkResolverOptions = {
36+
preserveLinkText: boolean;
37+
};
38+
3539
export function resolveLinks(
3640
comment: Comment,
3741
reflection: Reflection,
3842
externalResolver: ExternalSymbolResolver,
43+
options: LinkResolverOptions,
3944
) {
4045
comment.summary = resolvePartLinks(
4146
reflection,
4247
comment.summary,
4348
externalResolver,
49+
options,
4450
);
4551
for (const tag of comment.blockTags) {
4652
tag.content = resolvePartLinks(
4753
reflection,
4854
tag.content,
4955
externalResolver,
56+
options,
5057
);
5158
}
5259

@@ -55,6 +62,7 @@ export function resolveLinks(
5562
reflection,
5663
reflection.readme,
5764
externalResolver,
65+
options,
5866
);
5967
}
6068
}
@@ -63,24 +71,26 @@ export function resolvePartLinks(
6371
reflection: Reflection,
6472
parts: readonly CommentDisplayPart[],
6573
externalResolver: ExternalSymbolResolver,
74+
options: LinkResolverOptions,
6675
): CommentDisplayPart[] {
6776
return parts.flatMap((part) =>
68-
processPart(reflection, part, externalResolver),
77+
processPart(reflection, part, externalResolver, options),
6978
);
7079
}
7180

7281
function processPart(
7382
reflection: Reflection,
7483
part: CommentDisplayPart,
7584
externalResolver: ExternalSymbolResolver,
85+
options: LinkResolverOptions,
7686
): CommentDisplayPart | CommentDisplayPart[] {
7787
if (part.kind === "inline-tag") {
7888
if (
7989
part.tag === "@link" ||
8090
part.tag === "@linkcode" ||
8191
part.tag === "@linkplain"
8292
) {
83-
return resolveLinkTag(reflection, part, externalResolver);
93+
return resolveLinkTag(reflection, part, externalResolver, options);
8494
}
8595
}
8696

@@ -91,6 +101,7 @@ function resolveLinkTag(
91101
reflection: Reflection,
92102
part: InlineTagDisplayPart,
93103
externalResolver: ExternalSymbolResolver,
104+
options: LinkResolverOptions,
94105
): InlineTagDisplayPart {
95106
let defaultDisplayText = "";
96107
let pos = 0;
@@ -112,7 +123,9 @@ function resolveLinkTag(
112123
if (tsTarget) {
113124
target = tsTarget;
114125
pos = end;
115-
defaultDisplayText = part.tsLinkText || target.name;
126+
defaultDisplayText =
127+
part.tsLinkText ||
128+
(options.preserveLinkText ? part.text : target.name);
116129
} else if (declRef) {
117130
// If we didn't find a target, we might be pointing to a symbol in another project that will be merged in
118131
// or some external symbol, so ask external resolvers to try resolution. Don't use regular declaration ref
@@ -127,7 +140,9 @@ function resolveLinkTag(
127140
: undefined,
128141
);
129142

130-
defaultDisplayText = part.text.substring(0, pos);
143+
defaultDisplayText = options.preserveLinkText
144+
? part.text
145+
: part.text.substring(0, pos);
131146

132147
switch (typeof externalResolveResult) {
133148
case "string":
@@ -147,7 +162,9 @@ function resolveLinkTag(
147162
pos = declRef[1];
148163

149164
if (target) {
150-
defaultDisplayText = target.name;
165+
defaultDisplayText = options.preserveLinkText
166+
? part.text
167+
: target.name;
151168
} else {
152169
// If we didn't find a link, it might be a @link tag to an external symbol, check that next.
153170
const externalResolveResult = externalResolver(
@@ -159,7 +176,9 @@ function resolveLinkTag(
159176
: undefined,
160177
);
161178

162-
defaultDisplayText = part.text.substring(0, pos);
179+
defaultDisplayText = options.preserveLinkText
180+
? part.text
181+
: part.text.substring(0, pos);
163182

164183
switch (typeof externalResolveResult) {
165184
case "string":

src/lib/converter/converter.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ export class Converter extends ChildableComponent<
9090
@BindOption("useTsLinkResolution")
9191
useTsLinkResolution!: boolean;
9292

93+
/** @internal */
94+
@BindOption("preserveLinkText")
95+
preserveLinkText!: boolean;
96+
9397
private _config?: CommentParserConfig;
9498
private _externalSymbolResolvers: Array<ExternalSymbolResolver> = [];
9599

@@ -310,12 +314,20 @@ export class Converter extends ChildableComponent<
310314
owner: Reflection,
311315
): CommentDisplayPart[] | undefined {
312316
if (comment instanceof Comment) {
313-
resolveLinks(comment, owner, (ref, part, refl, id) =>
314-
this.resolveExternalLink(ref, part, refl, id),
317+
resolveLinks(
318+
comment,
319+
owner,
320+
(ref, part, refl, id) =>
321+
this.resolveExternalLink(ref, part, refl, id),
322+
{ preserveLinkText: this.preserveLinkText },
315323
);
316324
} else {
317-
return resolvePartLinks(owner, comment, (ref, part, refl, id) =>
318-
this.resolveExternalLink(ref, part, refl, id),
325+
return resolvePartLinks(
326+
owner,
327+
comment,
328+
(ref, part, refl, id) =>
329+
this.resolveExternalLink(ref, part, refl, id),
330+
{ preserveLinkText: this.preserveLinkText },
319331
);
320332
}
321333
}

src/lib/utils/options/declaration.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export interface TypeDocOptionMap {
155155
// Comment
156156
commentStyle: typeof CommentStyle;
157157
useTsLinkResolution: boolean;
158+
preserveLinkText: boolean;
158159
jsDocCompatibility: JsDocCompatibility;
159160
blockTags: `@${string}`[];
160161
inlineTags: `@${string}`[];

src/lib/utils/options/readers/typedoc.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ export class TypeDocReader implements OptionsReader {
8989
try {
9090
try {
9191
// eslint-disable-next-line @typescript-eslint/no-var-requires
92-
fileContent = require(file);
92+
fileContent = await require(file);
9393
} catch (error: any) {
9494
if (error?.code === "ERR_REQUIRE_ESM") {
9595
// On Windows, we need to ensure this path is a file path.
9696
// Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME
9797
const esmPath = pathToFileURL(file).toString();
98-
fileContent = (await import(esmPath)).default;
98+
fileContent = await (await import(esmPath)).default;
9999
} else {
100100
throw error;
101101
}

src/lib/utils/options/sources/typedoc.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,12 @@ export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
554554
type: ParameterType.Boolean,
555555
defaultValue: true,
556556
});
557+
options.addDeclaration({
558+
name: "preserveLinkText",
559+
help: "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name.",
560+
type: ParameterType.Boolean,
561+
defaultValue: true,
562+
});
557563

558564
options.addDeclaration({
559565
name: "blockTags",

src/test/behavior.c2.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ describe("Behavior Tests", () => {
752752
[ReflectionKind.Variable, "A"],
753753
[ReflectionKind.Variable, "A"],
754754
]);
755-
equal(getLinkTexts(localSymbolRef), ["A!", "A2!", "A"]);
755+
equal(getLinkTexts(localSymbolRef), ["A!", "A2!", "AnotherName"]);
756756

757757
equal(getLinks(query(project, "scoped")), [
758758
[ReflectionKind.Property, "Meanings.B.prop"],

src/test/issues.c2.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ describe("Issue Tests", () => {
471471
| InlineTagDisplayPart
472472
| undefined;
473473
equal(tag?.kind, "inline-tag");
474-
equal(tag.text, "method");
474+
equal(tag.text, "Test2.method");
475475
ok(
476476
tag.target === query(project, "Test.method"),
477477
"Incorrect resolution",

0 commit comments

Comments
 (0)