Skip to content

Commit 54c86d8

Browse files
committed
Expose displayPartsToMarkdown
Closes #2115
1 parent 37fe883 commit 54c86d8

File tree

4 files changed

+65
-51
lines changed

4 files changed

+65
-51
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Added `Application.EVENT_VALIDATE_PROJECT` event for plugins which implement custom validation, #2183.
66
- Plugins may now return an object from external symbol resolvers, #2066.
7+
- Expose `Comment.displayPartsToMarkdown` on for themes overwriting the `comment` helper, #2115.
78

89
### Bug Fixes
910

src/lib/models/comments/comment.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,65 @@ export class Comment {
121121
return result;
122122
}
123123

124+
/**
125+
* Helper function to convert an array of comment display parts into markdown suitable for
126+
* passing into Marked. `urlTo` will be used to resolve urls to any reflections linked to with
127+
* `@link` tags.
128+
*/
129+
static displayPartsToMarkdown(
130+
parts: readonly CommentDisplayPart[],
131+
urlTo: (ref: Reflection) => string
132+
) {
133+
const result: string[] = [];
134+
135+
for (const part of parts) {
136+
switch (part.kind) {
137+
case "text":
138+
case "code":
139+
result.push(part.text);
140+
break;
141+
case "inline-tag":
142+
switch (part.tag) {
143+
case "@label":
144+
case "@inheritdoc": // Shouldn't happen
145+
break; // Not rendered.
146+
case "@link":
147+
case "@linkcode":
148+
case "@linkplain": {
149+
if (part.target) {
150+
const url =
151+
typeof part.target === "string"
152+
? part.target
153+
: urlTo(part.target);
154+
const text =
155+
part.tag === "@linkcode"
156+
? `<code>${part.text}</code>`
157+
: part.text;
158+
result.push(
159+
url
160+
? `<a href="${url}">${text}</a>`
161+
: part.text
162+
);
163+
} else {
164+
result.push(part.text);
165+
}
166+
break;
167+
}
168+
default:
169+
// Hmm... probably want to be able to render these somehow, so custom inline tags can be given
170+
// special rendering rules. Future capability. For now, just render their text.
171+
result.push(`{${part.tag} ${part.text}}`);
172+
break;
173+
}
174+
break;
175+
default:
176+
assertNever(part);
177+
}
178+
}
179+
180+
return result.join("");
181+
}
182+
124183
/**
125184
* Helper utility to clone {@link Comment.summary} or {@link CommentTag.content}
126185
*/

src/lib/output/themes/default/DefaultThemeRenderContext.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { RendererHooks } from "../..";
2-
import type {
2+
import {
3+
Comment,
34
CommentDisplayPart,
45
ReferenceType,
56
Reflection,
67
} from "../../../models";
78
import type { NeverIfInternal, Options } from "../../../utils";
8-
import { displayPartsToMarkdown } from "../lib";
99
import type { DefaultTheme } from "./DefaultTheme";
1010
import { defaultLayout } from "./layouts/default";
1111
import { index } from "./partials";
@@ -62,14 +62,14 @@ export class DefaultThemeRenderContext {
6262
return url ? this.theme.markedPlugin.getRelativeUrl(url) : url;
6363
};
6464

65-
urlTo = (reflection: Reflection) => this.relativeURL(reflection.url);
65+
urlTo = (reflection: Reflection) => this.relativeURL(reflection.url)!;
6666

6767
markdown = (
6868
md: readonly CommentDisplayPart[] | NeverIfInternal<string | undefined>
6969
) => {
7070
if (md instanceof Array) {
7171
return this.theme.markedPlugin.parseMarkdown(
72-
displayPartsToMarkdown(md, this.urlTo)
72+
Comment.displayPartsToMarkdown(md, this.urlTo)
7373
);
7474
}
7575
return md ? this.theme.markedPlugin.parseMarkdown(md) : "";

src/lib/output/themes/lib.tsx

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import {
22
Comment,
3-
CommentDisplayPart,
43
DeclarationReflection,
54
Reflection,
65
ReflectionFlags,
76
SignatureReflection,
87
TypeParameterReflection,
98
} from "../../models";
10-
import { assertNever, JSX } from "../../utils";
11-
import type { DefaultThemeRenderContext } from "./default/DefaultThemeRenderContext";
9+
import { JSX } from "../../utils";
1210

1311
export function stringify(data: unknown) {
1412
if (typeof data === "bigint") {
@@ -117,50 +115,6 @@ export function camelToTitleCase(text: string) {
117115
return text.substring(0, 1).toUpperCase() + text.substring(1).replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`);
118116
}
119117

120-
export function displayPartsToMarkdown(
121-
parts: readonly CommentDisplayPart[],
122-
urlTo: DefaultThemeRenderContext["urlTo"]
123-
) {
124-
const result: string[] = [];
125-
126-
for (const part of parts) {
127-
switch (part.kind) {
128-
case "text":
129-
case "code":
130-
result.push(part.text);
131-
break;
132-
case "inline-tag":
133-
switch (part.tag) {
134-
case "@label":
135-
case "@inheritdoc": // Shouldn't happen
136-
break; // Not rendered.
137-
case "@link":
138-
case "@linkcode":
139-
case "@linkplain": {
140-
if (part.target) {
141-
const url = typeof part.target === "string" ? part.target : urlTo(part.target);
142-
const text = part.tag === "@linkcode" ? `<code>${part.text}</code>` : part.text;
143-
result.push(url ? `<a href="${url}">${text}</a>` : part.text);
144-
} else {
145-
result.push(part.text);
146-
}
147-
break;
148-
}
149-
default:
150-
// Hmm... probably want to be able to render these somehow, so custom inline tags can be given
151-
// special rendering rules. Future capability. For now, just render their text.
152-
result.push(`{${part.tag} ${part.text}}`);
153-
break;
154-
}
155-
break;
156-
default:
157-
assertNever(part);
158-
}
159-
}
160-
161-
return result.join("");
162-
}
163-
164118
/**
165119
* Renders the reflection name with an additional `?` if optional.
166120
*/

0 commit comments

Comments
 (0)