Skip to content

Commit 81dbb4a

Browse files
committed
fix(core): fix inline formatting of types when "useCodeBlocks" is used
1 parent cc80a0b commit 81dbb4a

16 files changed

+244
-47
lines changed

.changeset/selfish-pens-live.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'typedoc-plugin-markdown': patch
3+
---
4+
5+
- fix(core): Fix inline formatting of types when when "useCodeBlocks" is used (#742).

packages/typedoc-plugin-markdown/src/libs/markdown/back-ticks.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@ import { escapeChars } from '@plugin/libs/utils/index.js';
22

33
/**
44
* Wraps a string in backticks.
5-
* If the input string itself contains a backtick, pipe, or backslash (which can result in unwanted side effects) the string is escaped instead.
65
*/
76
export function backTicks(text: string) {
8-
return /(`|\||\\)/g.test(text) ? escapeChars(text) : `\`${text}\``;
7+
// If the input string itself contains a pipe, or backslash (which can result in unwanted side effects) the string is escaped instead.
8+
if (/(\||\\)/g.test(text)) {
9+
return escapeChars(text);
10+
}
11+
// If the input string itself contains a backtick, the string is wrapped in double backticks.
12+
if (/`/g.test(text)) {
13+
return `\`\` ${text} \`\``;
14+
}
15+
// Otherwise, the string is wrapped in single backticks.
16+
return `\`${text}\``;
917
}

packages/typedoc-plugin-markdown/src/libs/utils/un-escape-chars.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ export function unEscapeChars(str: string) {
1313
.replace(/\\_/g, '_')
1414
.replace(/\\{/g, '{')
1515
.replace(/\\}/g, '}')
16-
.replace(/(?<!\\)`/g, '')
16+
.replace(/``.*?``|(?<!\\)`/g, (match) =>
17+
match.startsWith('``') ? match : '',
18+
)
19+
.replace(/`` /g, '')
20+
.replace(/ ``/g, '')
1721
.replace(/\\`/g, '`')
1822
.replace(/\\\*/g, '*')
1923
.replace(/\\\|/g, '|')
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
1-
import { backTicks } from '@plugin/libs/markdown/index.js';
1+
import { backTicks, codeBlock } from '@plugin/libs/markdown/index.js';
22
import { MarkdownThemeContext } from '@plugin/theme/index.js';
33
import { SignatureReflection } from 'typedoc';
44

55
export function indexSignature(
66
this: MarkdownThemeContext,
77
model: SignatureReflection,
88
): string {
9-
const md = [''];
9+
const useCodeBlocks = this.options.getValue('useCodeBlocks');
10+
1011
const params = model.parameters
1112
? model.parameters.map((parameter) => {
1213
return parameter.type
13-
? `${backTicks(parameter.name)}: ${this.partials.someType(
14+
? `${useCodeBlocks ? parameter.name : backTicks(parameter.name)}: ${this.partials.someType(
1415
parameter.type,
1516
)}`
1617
: '';
1718
})
1819
: [];
1920
if (model.type) {
20-
md.push(`\\[${params.join('')}\\]: ${this.partials.someType(model.type)}`);
21+
if (this.options.getValue('useCodeBlocks')) {
22+
return codeBlock(
23+
`[${params.join('')}]: ${this.partials.someType(model.type)}`,
24+
);
25+
}
26+
return `\\[${params.join('')}\\]: ${this.partials.someType(model.type)}`;
2127
}
22-
return md.join(' ');
28+
return '';
2329
}

packages/typedoc-plugin-markdown/src/theme/context/partials/member.typeAndParent.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { backTicks, link } from '@plugin/libs/markdown/index.js';
1+
import { backTicks, codeBlock, link } from '@plugin/libs/markdown/index.js';
2+
import { removeLineBreaks } from '@plugin/libs/utils/index.js';
23
import { MarkdownThemeContext } from '@plugin/theme/index.js';
34
import { ArrayType, ReferenceType, SignatureReflection } from 'typedoc';
45

@@ -15,11 +16,11 @@ export function typeAndParent(
1516
}
1617

1718
if (model instanceof ReferenceType && model.reflection) {
18-
const refl =
19+
const reflection =
1920
model.reflection instanceof SignatureReflection
2021
? model.reflection.parent
2122
: model.reflection;
22-
const parent = refl?.parent;
23+
const parent = reflection?.parent;
2324
if (parent) {
2425
const resultWithParent: string[] = [];
2526
if (parent?.url) {
@@ -29,15 +30,18 @@ export function typeAndParent(
2930
} else {
3031
resultWithParent.push(backTicks(parent?.name));
3132
}
32-
if (refl?.url) {
33+
if (reflection?.url) {
3334
resultWithParent.push(
34-
link(backTicks(refl.name), this.getRelativeUrl(refl.url)),
35+
link(backTicks(reflection.name), this.getRelativeUrl(reflection.url)),
3536
);
3637
} else {
37-
resultWithParent.push(backTicks(refl?.name));
38+
resultWithParent.push(backTicks(reflection?.name));
3839
}
3940
return resultWithParent.join('.');
4041
}
4142
}
42-
return backTicks(model.toString());
43+
if (this.options.getValue('useCodeBlocks')) {
44+
return codeBlock(model.toString());
45+
}
46+
return backTicks(removeLineBreaks(model.toString()));
4347
}

packages/typedoc-plugin-markdown/src/theme/context/resources.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ There is no association list partial for properties as these are handled as a st
290290

291291
export const resourceHelpers = (context: MarkdownThemeContext) => {
292292
return {
293-
getAngleBracket: (bracket: '<' | '>') =>
293+
getAngleBracket: (bracket: '>' | '<') =>
294294
helpers.getAngleBracket.apply(context, [bracket]) as string,
295295
getCommentParts: (model: CommentDisplayPart[]) =>
296296
helpers.getCommentParts.apply(context, [model]) as string,

packages/typedoc-plugin-markdown/test/fixtures/config.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ const config = {
275275
},
276276
utils: {
277277
only: false,
278-
entryPoints: '/utils/index.ts',
278+
entryPoints: '/utils/*.ts',
279279
commonOptions: {
280280
hidePageHeader: true,
281281
hideBreadcrumbs: true,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export type Integrity = `sha512-${string}`;
2+
3+
export const isIntegrity = (i: unknown): i is Integrity =>
4+
typeof i === "string" && i.startsWith("sha512-");
5+
6+
export const asIntegrity = (i: unknown): Integrity => {
7+
if (!isIntegrity(i)) {
8+
throw new Error("not integrity");
9+
}
10+
return i;
11+
};
12+
13+
export const assertIntegrity: (i: unknown) => asserts i is Integrity = (i) => {
14+
asIntegrity(i);
15+
};
16+
17+
export type CustomString = string;
18+
19+
export const isString = (i: unknown): i is CustomString =>
20+
typeof i === "string";
21+
22+
export const asString = (i: unknown): CustomString => {
23+
if (!isString(i)) {
24+
throw new Error("not a custom string");
25+
}
26+
return i;
27+
};
28+
29+
export const assertString: (i: unknown) => asserts i is CustomString = (i) => {
30+
asString(i);
31+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export interface InterfaceWithChars<T> {
2+
prop: T;
3+
'>': string;
4+
'<': string;
5+
'<tag>': string;
6+
}
7+
8+
export class ClassWithChars<T> {
9+
prop!: T;
10+
}
11+
12+
export const variableWithChars = {
13+
['<x>']: '>',
14+
['<y>']: '<',
15+
['<z>']: '<tag>',
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class LRUCache<T, U, V> {
2+
constructor() {}
3+
}
4+
5+
type CacheFetchContext = {};
6+
7+
export class Cache extends LRUCache<
8+
CacheFetchContext,
9+
CacheFetchContext,
10+
CacheFetchContext
11+
> {
12+
constructor() {
13+
super();
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type Delimiter = "·";
2+
3+
type Id =
4+
| `${"git"}${Delimiter}${string}${Delimiter}${string}`
5+
| `${"remote"}${Delimiter}${string}${Delimiter}${string}`;
6+
7+
export type LongIndexSignature = {
8+
[key: `${Id} ${string}`]: `${"dev" | "prod"} ${Id}`;
9+
};

packages/typedoc-plugin-markdown/test/fixtures/src/utils/index.ts renamed to packages/typedoc-plugin-markdown/test/fixtures/src/utils/prettier.ts

-17
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
export interface InterfaceWithChars<T> {
2-
prop: T;
3-
'>': string;
4-
'<': string;
5-
'<tag>': string;
6-
}
7-
8-
export class ClassWithChars<T> {
9-
prop!: T;
10-
}
11-
12-
export const variableWithChars = {
13-
['<x>']: '>',
14-
['<y>']: '<',
15-
['<z>']: '<tag>',
16-
};
17-
181
/**
192
* ```ts
203
* reallyUgly (

packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.interface.spec.ts.snap

+12-6
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ Comments for IndexableInterface
600600
601601
## Indexable
602602
603-
\\[\`s\`: \`string\`\\]: \`string\`
603+
\\[\`s\`: \`string\`\\]: \`string\`
604604
605605
## Properties
606606
@@ -621,7 +621,9 @@ Comments for IndexableInterface
621621
622622
## Indexable
623623
624-
\\[\`s\`: \`string\`\\]: \`string\`
624+
\`\`\`ts
625+
[s: string]: string
626+
\`\`\`
625627
626628
## Properties
627629
@@ -882,9 +884,9 @@ exports[`Interface Reflection should compile multiple indexable interface: (Outp
882884
883885
## Indexable
884886
885-
\\[\`key\`: \`string\`\\]: \`string\`
887+
\\[\`key\`: \`string\`\\]: \`string\`
886888
887-
\\[\`index\`: \`number\`\\]: \`string\`
889+
\\[\`index\`: \`number\`\\]: \`string\`
888890
889891
## Properties
890892
@@ -905,9 +907,13 @@ exports[`Interface Reflection should compile multiple indexable interface: (Outp
905907
906908
## Indexable
907909
908-
\\[\`key\`: \`string\`\\]: \`string\`
910+
\`\`\`ts
911+
[key: string]: string
912+
\`\`\`
909913
910-
\\[\`index\`: \`number\`\\]: \`string\`
914+
\`\`\`ts
915+
[index: number]: string
916+
\`\`\`
911917
912918
## Properties
913919

packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.type-alias.spec.ts.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ Comments for ReadonlyMapedType
612612
exports[`Type Alias Reflection should compile string literal type: (Output File Strategy "members") (Option Group "1") 1`] = `
613613
"# Type Alias: StringLiteralType
614614
615-
> **StringLiteralType**: \`" "\` \\| \`"string"\` \\| "string\\|with\\|pipes" \\| "string\\\`with\\\`backticks" \\| \`"<foo>"\` \\| \`"*"\`
615+
> **StringLiteralType**: \`" "\` \\| \`"string"\` \\| "string\\|with\\|pipes" \\| \`\` "string\`with\`backticks" \`\` \\| \`"<foo>"\` \\| \`"*"\`
616616
617617
Comments for StringLiteralType
618618
@@ -751,7 +751,7 @@ Comments for TypeWithReturns
751751
exports[`Type Alias Reflection should compile union type with template strings: (Output File Strategy "members") (Option Group "1") 1`] = `
752752
"# Type Alias: UnionTypeWithTemplateStrings
753753
754-
> **UnionTypeWithTemplateStrings**: \\\`v$\\{number\\}\\\` \\| \\\`v$\\{number\\}.$\\{number\\}\\\` \\| \\\`v$\\{number\\}.$\\{number\\}.$\\{number\\}\\\`
754+
> **UnionTypeWithTemplateStrings**: \`\` \`v\${number}\` \`\` \\| \`\` \`v\${number}.\${number}\` \`\` \\| \`\` \`v\${number}.\${number}.\${number}\` \`\`
755755
756756
Union with template strings
757757

packages/typedoc-plugin-markdown/test/specs/__snapshots__/utils.spec.ts.snap

+86
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,91 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Utils should format index signature type: (Output File Strategy "members") (Option Group "1") 1`] = `
4+
"# Type Alias: LongIndexSignature
5+
6+
> **LongIndexSignature**: \\{\\}
7+
8+
## Index Signature
9+
10+
\\[\`key\`: \`\` \`git·\${string}·\${string} \${string}\` \`\` \\| \`\` \`remote·\${string}·\${string} \${string}\` \`\`\\]: \`\` \`dev git·\${string}·\${string}\` \`\` \\| \`\` \`dev remote·\${string}·\${string}\` \`\` \\| \`\` \`prod git·\${string}·\${string}\` \`\` \\| \`\` \`prod remote·\${string}·\${string}\` \`\`
11+
"
12+
`;
13+
14+
exports[`Utils should format index signature type: (Output File Strategy "members") (Option Group "2") 1`] = `
15+
"# Type Alias: LongIndexSignature
16+
17+
\`\`\`ts
18+
type LongIndexSignature = {};
19+
\`\`\`
20+
21+
## Index Signature
22+
23+
\`\`\`ts
24+
[key:
25+
| \`git·\${string}·\${string} \${string}\`
26+
| \`remote·\${string}·\${string} \${string}\`]:
27+
| \`dev git·\${string}·\${string}\`
28+
| \`dev remote·\${string}·\${string}\`
29+
| \`prod git·\${string}·\${string}\`
30+
| \`prod remote·\${string}·\${string}\`
31+
\`\`\`
32+
"
33+
`;
34+
35+
exports[`Utils should format type with constructor overrides: (Output File Strategy "members") (Option Group "1") 1`] = `
36+
"# Class: Cache
37+
38+
## Extends
39+
40+
- \`LRUCache\`&lt;\`CacheFetchContext\`, \`CacheFetchContext\`, \`CacheFetchContext\`&gt;
41+
42+
## Constructors
43+
44+
### new Cache()
45+
46+
> **new Cache**(): [\`Cache\`](Cache.md)
47+
48+
#### Returns
49+
50+
[\`Cache\`](Cache.md)
51+
52+
#### Overrides
53+
54+
\`LRUCache< CacheFetchContext, CacheFetchContext, CacheFetchContext >.constructor\`
55+
"
56+
`;
57+
58+
exports[`Utils should format type with constructor overrides: (Output File Strategy "members") (Option Group "2") 1`] = `
59+
"# Class: Cache
60+
61+
## Extends
62+
63+
- \`LRUCache\`&lt;\`CacheFetchContext\`, \`CacheFetchContext\`, \`CacheFetchContext\`&gt;
64+
65+
## Constructors
66+
67+
### new Cache()
68+
69+
\`\`\`ts
70+
new Cache(): Cache
71+
\`\`\`
72+
73+
#### Returns
74+
75+
[\`Cache\`](Cache.md)
76+
77+
#### Overrides
78+
79+
\`\`\`ts
80+
LRUCache<
81+
CacheFetchContext,
82+
CacheFetchContext,
83+
CacheFetchContext
84+
>.constructor
85+
\`\`\`
86+
"
87+
`;
88+
389
exports[`Utils should get class with brackets: (Output File Strategy "members") (Option Group "1") 1`] = `
490
"# Class: ClassWithChars&lt;T&gt;
591

0 commit comments

Comments
 (0)