Skip to content

Commit c3bc0da

Browse files
committed
Reduce manually maintained duplication in generated site
1 parent 344d4bf commit c3bc0da

File tree

4 files changed

+105
-113
lines changed

4 files changed

+105
-113
lines changed

site/options.md

+7-112
Original file line numberDiff line numberDiff line change
@@ -13,148 +13,43 @@ children:
1313
Any command line arguments that are passed without a flag will be parsed as entry points.
1414
Any options passed on the command line will override options set in a configuration file.
1515

16-
<!--
17-
Updating these lists can be easily done by going to each page and running the
18-
following JS to copy what they should be to your clipboard. Ideally, someday this
19-
becomes automated...
20-
21-
copy($$(".tsd-page-navigation > .tsd-accordion-details > a").map(a => [a.textContent, a.href.substring(a.href.lastIndexOf("/") + "/Options.".length).replace(/^./, x => x[0].toLowerCase()).replace(".html", ".md").replace("md:", "")]).map(l => `- [${l[0]}](options/${l[1]})`).join("\n"))
22-
-->
23-
2416
## Configuration Options
2517

2618
Options which control what files TypeDoc reads.
2719

28-
- [options](options/configuration.md#options)
29-
- [tsconfig](options/configuration.md#tsconfig)
30-
- [compilerOptions](options/configuration.md#compileroptions)
31-
- [plugin](options/configuration.md#plugin)
20+
{@listOptions options/configuration.md}
3221

3322
## Input Options
3423

3524
Options which control how input is converted into a project that can be rendered
3625
to HTML or JSON.
3726

38-
- [entryPoints](options/input.md#entrypoints)
39-
- [entryPointStrategy](options/input.md#entrypointstrategy)
40-
- [packageOptions](options/input.md#packageoptions)
41-
- [alwaysCreateEntryPointModule](options/input.md#alwayscreateentrypointmodule)
42-
- [projectDocuments](options/input.md#projectdocuments)
43-
- [exclude](options/input.md#exclude)
44-
- [externalPattern](options/input.md#externalpattern)
45-
- [excludeExternals](options/input.md#excludeexternals)
46-
- [excludeNotDocumented](options/input.md#excludenotdocumented)
47-
- [excludeNotDocumentedKinds](options/input.md#excludenotdocumentedkinds)
48-
- [excludeInternal](options/input.md#excludeinternal)
49-
- [excludePrivate](options/input.md#excludeprivate)
50-
- [excludeProtected](options/input.md#excludeprotected)
51-
- [excludeReferences](options/input.md#excludereferences)
52-
- [excludeCategories](options/input.md#excludecategories)
53-
- [maxTypeConversionDepth](options/input.md#maxtypeconversiondepth)
54-
- [name](options/input.md#name)
55-
- [includeVersion](options/input.md#includeversion)
56-
- [disableSources](options/input.md#disablesources)
57-
- [sourceLinkTemplate](options/input.md#sourcelinktemplate)
58-
- [gitRevision](options/input.md#gitrevision)
59-
- [gitRemote](options/input.md#gitremote)
60-
- [disableGit](options/input.md#disablegit)
61-
- [readme](options/input.md#readme)
62-
- [includeHierarchySummary](options/input.md#includehierarchysummary)
27+
{@listOptions options/input.md}
6328

6429
## Output Options
6530

6631
Options which control TypeDoc's HTML output.
6732

68-
- [outputs](options/output.md#outputs)
69-
- [out](options/output.md#out)
70-
- [html](options/output.md#html)
71-
- [json](options/output.md#json)
72-
- [pretty](options/output.md#pretty)
73-
- [emit](options/output.md#emit)
74-
- [theme](options/output.md#theme)
75-
- [lightHighlightTheme](options/output.md#lighthighlighttheme)
76-
- [darkHighlightTheme](options/output.md#darkhighlighttheme)
77-
- [highlightLanguages](options/output.md#highlightlanguages)
78-
- [typePrintWidth](options/output.md#typeprintwidth)
79-
- [customCss](options/output.md#customcss)
80-
- [customJs](options/output.md#customjs)
81-
- [customFooterHtml](options/output.md#customfooterhtml)
82-
- [customFooterHtmlDisableWrapper](options/output.md#customfooterhtmldisablewrapper)
83-
- [markdownItOptions](options/output.md#markdownitoptions)
84-
- [markdownItLoader](options/output.md#markdownitloader)
85-
- [basePath](options/output.md#basepath)
86-
- [cname](options/output.md#cname)
87-
- [favicon](options/output.md#favicon)
88-
- [sourceLinkExternal](options/output.md#sourcelinkexternal)
89-
- [markdownLinkExternal](options/output.md#markdownlinkexternal)
90-
- [lang](options/output.md#lang)
91-
- [locales](options/output.md#locales)
92-
- [githubPages](options/output.md#githubpages)
93-
- [cacheBust](options/output.md#cachebust)
94-
- [hideGenerator](options/output.md#hidegenerator)
95-
- [searchInComments](options/output.md#searchincomments)
96-
- [searchInDocuments](options/output.md#searchindocuments)
97-
- [cleanOutputDir](options/output.md#cleanoutputdir)
98-
- [titleLink](options/output.md#titlelink)
99-
- [navigationLinks](options/output.md#navigationlinks)
100-
- [sidebarLinks](options/output.md#sidebarlinks)
101-
- [navigation](options/output.md#navigation)
102-
- [headings](options/output.md#headings)
103-
- [sluggerConfiguration](options/output.md#sluggerconfiguration)
104-
- [navigationLeaves](options/output.md#navigationleaves)
105-
- [visibilityFilters](options/output.md#visibilityfilters)
106-
- [searchCategoryBoosts](options/output.md#searchcategoryboosts)
107-
- [searchGroupBoosts](options/output.md#searchgroupboosts)
108-
- [hostedBaseUrl](options/output.md#hostedbaseurl)
109-
- [useHostedBaseUrlForAbsoluteLinks](options/output.md#usehostedbaseurlforabsolutelinks)
110-
- [useFirstParagraphOfCommentAsSummary](options/output.md#usefirstparagraphofcommentassummary)
33+
{@listOptions options/output.md}
11134

11235
## Comment Options
11336

11437
Options which control how TypeDoc parses comments.
11538

116-
- [commentStyle](options/comments.md#commentstyle)
117-
- [useTsLinkResolution](options/comments.md#usetslinkresolution)
118-
- [preserveLinkText](options/comments.md#preservelinktext)
119-
- [jsDocCompatibility](options/comments.md#jsdoccompatibility)
120-
- [suppressCommentWarningsInDeclarationFiles](options/comments.md#suppresscommentwarningsindeclarationfiles)
121-
- [blockTags](options/comments.md#blocktags)
122-
- [inlineTags](options/comments.md#inlinetags)
123-
- [modifierTags](options/comments.md#modifiertags)
124-
- [cascadedModifierTags](options/comments.md#cascadedmodifiertags)
125-
- [excludeTags](options/comments.md#excludetags)
126-
- [notRenderedTags](options/comments.md#notrenderedtags)
127-
- [externalSymbolLinkMappings](options/comments.md#externalsymbollinkmappings)
39+
{@listOptions options/comments.md}
12840

12941
## Organization Options
13042

13143
Controls how TypeDoc organizes content within a converted project.
13244

133-
- [groupReferencesByType](options/organization.md#groupreferencesbytype)
134-
- [categorizeByGroup](options/organization.md#categorizebygroup)
135-
- [defaultCategory](options/organization.md#defaultcategory)
136-
- [categoryOrder](options/organization.md#categoryorder)
137-
- [groupOrder](options/organization.md#grouporder)
138-
- [sort](options/organization.md#sort)
139-
- [sortEntryPoints](options/organization.md#sortentrypoints)
140-
- [kindSortOrder](options/organization.md#kindsortorder)
45+
{@listOptions options/organization.md}
14146

14247
## Validation Options
14348

14449
Configures the validation performed by TypeDoc on a converted project.
14550

146-
- [validation](options/validation.md#validation)
147-
- [treatWarningsAsErrors](options/validation.md#treatwarningsaserrors)
148-
- [treatValidationWarningsAsErrors](options/validation.md#treatvalidationwarningsaserrors)
149-
- [intentionallyNotExported](options/validation.md#intentionallynotexported)
150-
- [requiredToBeDocumented](options/validation.md#requiredtobedocumented)
51+
{@listOptions options/validation.md}
15152

15253
## Other Options
15354

154-
- [watch](options/other.md#watch)
155-
- [preserveWatchOutput](options/other.md#preservewatchoutput)
156-
- [help](options/other.md#help)
157-
- [version](options/other.md#version)
158-
- [showConfig](options/other.md#showconfig)
159-
- [logLevel](options/other.md#loglevel)
160-
- [skipErrorChecking](options/other.md#skiperrorchecking)
55+
{@listOptions options/other.md}

site/site-plugin.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// @ts-check
2+
import { readFileSync } from "node:fs";
3+
import { dirname, join } from "node:path";
4+
import { Application, Converter, OptionDefaults } from "typedoc";
5+
/** @import { CommentDisplayPart, FileRegistry, TranslatedString} from "typedoc" */
6+
7+
/** @param {Application} app */
8+
export function load(app) {
9+
app.on(Application.EVENT_BOOTSTRAP_END, () => {
10+
app.options.setValue("inlineTags", [
11+
...OptionDefaults.inlineTags,
12+
"@listOptions",
13+
]);
14+
});
15+
16+
app.converter.on(Converter.EVENT_CREATE_DOCUMENT, (_ctx, doc) => {
17+
// Known we have this as documents always have a file path
18+
const fileName = /** @type {string} */ (
19+
doc.project.files.getReflectionPath(doc)
20+
);
21+
22+
replaceListOptions(fileName, doc.content, doc.project.files);
23+
});
24+
25+
/**
26+
*
27+
* @param {string} sourceFile
28+
* @param {CommentDisplayPart[]} parts
29+
* @param {FileRegistry} files
30+
*/
31+
function replaceListOptions(sourceFile, parts, files) {
32+
for (let i = 0; i < parts.length; ++i) {
33+
const part = parts[i];
34+
if (part.kind === "inline-tag" && part.tag === "@listOptions") {
35+
parts.splice(
36+
i,
37+
1,
38+
...buildListOptions(sourceFile, part.text.trim(), files),
39+
);
40+
}
41+
}
42+
}
43+
44+
/**
45+
* @param {string} sourceFile
46+
* @param {string} userPath
47+
* @param {FileRegistry} files
48+
* @returns {CommentDisplayPart[]}
49+
*/
50+
function buildListOptions(sourceFile, userPath, files) {
51+
const file = join(dirname(sourceFile), userPath.trim());
52+
53+
/** @type {string[]} */
54+
const headings = [];
55+
const content = readFileSync(file, "utf-8");
56+
for (const line of content.split("\n")) {
57+
if (line.startsWith("## ")) {
58+
headings.push(line.substring(3).trim());
59+
}
60+
}
61+
62+
/** @type {CommentDisplayPart[]} */
63+
const result = [];
64+
65+
for (const heading of headings) {
66+
result.push({ kind: "text", text: `- [${heading}](` });
67+
const text = userPath + "#" + heading.toLowerCase();
68+
const relPath = files.register(sourceFile, text);
69+
if (!relPath) {
70+
app.logger.warn(
71+
/** @type {TranslatedString} */ (
72+
`@listOptions specified a file "${text}" which does not exist`
73+
),
74+
);
75+
return [];
76+
}
77+
78+
result.push({
79+
kind: "relative-link",
80+
target: relPath?.target,
81+
targetAnchor: relPath?.anchor,
82+
text,
83+
});
84+
result.push({ kind: "text", text: ")\n" });
85+
}
86+
87+
return result;
88+
}
89+
}

site/typedoc.config.jsonc

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"alwaysCreateEntryPointModule": true,
88
"out": "../docs-site",
99
"name": "TypeDoc",
10-
"plugin": ["./typedoc-plugin-redirect.js"],
10+
"plugin": ["./typedoc-plugin-redirect.js", "./site-plugin.js"],
1111

1212
"readme": "index.md",
1313
"projectDocuments": [

src/lib/converter/converter.ts

+8
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ export class Converter extends AbstractComponent<Application, ConverterEvents> {
191191
static readonly EVENT_CREATE_DECLARATION =
192192
ConverterEvents.CREATE_DECLARATION;
193193

194+
/**
195+
* Triggered when the converter has created a document reflection.
196+
* The listener will be given `undefined` (for consistency with the
197+
* other create events) and a {@link Models.DocumentReflection}.
198+
* @event
199+
*/
200+
static readonly EVENT_CREATE_DOCUMENT = ConverterEvents.CREATE_DOCUMENT;
201+
194202
/**
195203
* Triggered when the converter has created a signature reflection.
196204
* The listener will be given {@link Context}, {@link Models.SignatureReflection} | {@link Models.ProjectReflection} the declaration,

0 commit comments

Comments
 (0)