diff --git a/.changeset/dirty-walls-serve.md b/.changeset/dirty-walls-serve.md new file mode 100644 index 000000000..de0b0d648 --- /dev/null +++ b/.changeset/dirty-walls-serve.md @@ -0,0 +1,6 @@ +--- +"typedoc-plugin-markdown": patch +--- + +- Expose theme hooks similar to default theme. +- Expose TypedDoc media and include syntax. diff --git a/.changeset/happy-rats-help.md b/.changeset/happy-rats-help.md new file mode 100644 index 000000000..ce9b53061 --- /dev/null +++ b/.changeset/happy-rats-help.md @@ -0,0 +1,8 @@ +--- +"docusaurus-plugin-typedoc": patch +"typedoc-github-wiki-theme": patch +"typedoc-gitlab-wiki-theme": patch +"typedoc-vitepress-theme": patch +--- + +- Update core package dependency diff --git a/dev-packages/helpers/src/constants.ts b/dev-packages/helpers/src/constants.ts index aeb1e6938..606f106b3 100644 --- a/dev-packages/helpers/src/constants.ts +++ b/dev-packages/helpers/src/constants.ts @@ -1,47 +1,52 @@ import { DocsConfig } from './models'; -export const DECLARATIONS_PATH = `${process.cwd()}/src/options/declarations.ts`; - export const PRESETS_PATH = `${process.cwd()}/src/options/presets.ts`; export const DOCS_CONFIG: Record = { ['typedoc-plugin-markdown']: { + declarationsPath: `${process.cwd()}/src/plugin/options/declarations.ts`, optionsPath: 'options', docsPath: '', declarations: true, presets: false, }, ['typedoc-plugin-frontmatter']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: 'utilities/frontmatter', docsPath: '/utilities/frontmatter', declarations: true, presets: false, }, ['typedoc-plugin-remark']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: 'utilities/remark', docsPath: '/utilities/remark', declarations: true, presets: false, }, ['typedoc-github-wiki-theme']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: 'themes/github-wiki', docsPath: '/themes/github-wiki', declarations: true, presets: true, }, ['typedoc-gitlab-wiki-theme']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: 'themes/gitlab-wiki', docsPath: '/themes/gitlab-wiki', declarations: true, presets: true, }, ['typedoc-vitepress-theme']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: 'themes/vitepress', docsPath: '/themes/vitepress', declarations: true, presets: false, }, ['docusaurus-plugin-typedoc']: { + declarationsPath: `${process.cwd()}/src/options/declarations.ts`, optionsPath: '/integrations/docusaurus/options', docsPath: '/integrations/docusaurus', declarations: false, diff --git a/dev-packages/helpers/src/models.ts b/dev-packages/helpers/src/models.ts index 7866a5a80..e6717d93e 100644 --- a/dev-packages/helpers/src/models.ts +++ b/dev-packages/helpers/src/models.ts @@ -1,4 +1,5 @@ export interface DocsConfig { + declarationsPath: string; optionsPath: string; docsPath: string; declarations: boolean; diff --git a/dev-packages/prebuild-options/cli.ts b/dev-packages/prebuild-options/cli.ts index 8cba95140..68cccceb7 100755 --- a/dev-packages/prebuild-options/cli.ts +++ b/dev-packages/prebuild-options/cli.ts @@ -10,7 +10,7 @@ main(); async function main() { const docsConfig: DocsConfig = DOCS_CONFIG[getPackageName()]; if (docsConfig.declarations) { - await generateModels(); + await generateModels(docsConfig.declarationsPath); } await generateDocs(docsConfig); consola.success(`[${getPackageName()}] Prebuild options complete`); diff --git a/dev-packages/prebuild-options/tasks/generate-docs.ts b/dev-packages/prebuild-options/tasks/generate-docs.ts index 0043b7fd6..87b6a365f 100644 --- a/dev-packages/prebuild-options/tasks/generate-docs.ts +++ b/dev-packages/prebuild-options/tasks/generate-docs.ts @@ -1,4 +1,3 @@ -import { DECLARATIONS_PATH } from '@dev-packages/helpers'; import { DocsConfig } from '@dev-packages/helpers/src/models'; import * as fs from 'fs'; import * as path from 'path'; @@ -21,8 +20,8 @@ export async function generateDocs(docsConfig: DocsConfig) { // DECLARATIONS if (docsConfig.declarations) { - const declarationsConfig: any = await import(DECLARATIONS_PATH); - const configFileTs = project.getSourceFile(DECLARATIONS_PATH); + const declarationsConfig: any = await import(docsConfig.declarationsPath); + const configFileTs = project.getSourceFile(docsConfig.declarationsPath); const optionsVariableStatements = configFileTs?.getVariableStatements() as VariableStatement[]; diff --git a/dev-packages/prebuild-options/tasks/generate-models.ts b/dev-packages/prebuild-options/tasks/generate-models.ts index d7544729b..5bee7e9eb 100644 --- a/dev-packages/prebuild-options/tasks/generate-models.ts +++ b/dev-packages/prebuild-options/tasks/generate-models.ts @@ -1,4 +1,3 @@ -import { DECLARATIONS_PATH } from '@dev-packages/helpers'; import * as fs from 'fs'; import * as path from 'path'; import * as prettier from 'prettier'; @@ -8,8 +7,8 @@ import { DeclarationOption, ParameterType } from 'typedoc'; * Creates models for plugin options */ -export async function generateModels() { - const optionsConfig = await import(DECLARATIONS_PATH); +export async function generateModels(declarationsPath: string) { + const optionsConfig = await import(declarationsPath); const mixedTypes = (Object.entries(optionsConfig) as any).filter( ([name, option]) => @@ -59,10 +58,8 @@ export async function generateModels() { `; const optionsModelFile = path.join( - process.cwd(), - 'src', - 'options', - 'models.ts', + path.dirname(declarationsPath), + 'option-types.ts', ); const formatted = await prettier.format(optionsOutput, { diff --git a/docs/pages/_meta.json b/docs/pages/_meta.json index c4a45b0b6..19b2f4208 100644 --- a/docs/pages/_meta.json +++ b/docs/pages/_meta.json @@ -2,6 +2,7 @@ "index": "Introduction", "quick-start": "", "options": "", + "guides": "Guides", "examples": "", "-- RelatedPlugin": { "type": "separator", diff --git a/docs/pages/guides/custom-output.mdx b/docs/pages/guides/custom-output.mdx new file mode 100644 index 000000000..476caa8ce --- /dev/null +++ b/docs/pages/guides/custom-output.mdx @@ -0,0 +1,99 @@ +import { Callout, FileTree } from 'nextra/components'; + +# Custom Output + +Output can be further extended following the an adapted version of TypeDoc's [Custom Theme docs](https://github.com/TypeStrong/typedoc/blob/master/internal-docs/custom-themes.md). + +## Local plugins + +To get started a create a local TypeDoc plugin file. TypeDoc supports both ESM and CommonJS +modules. This example is a guide only and written as ESM using an `.mjs` file extension - please adapt to your own needs. + +```js filename="custom-plugin.mjs" +// @ts-check + +/** + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + // Theme customization should be placed in the load function. +} +``` + +The file can the be referenced in the `typedoc.json` file. + +```json filename="typedoc.json" +{ + "plugin": ["typedoc-plugin-markdown", "./custom-plugin.mjs"] +} +``` + +## Hooks + +Hooks allows Markdown (or HTML) to be injected into the output in specific locations and are the most basic form form of customization. + +```js filename="local-plugins/custom-plugin.mjs" +// @ts-check + +/** + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + // Add a hook to insert markdown at the top of the page. + app.renderer.markdownHooks.on( + 'page.begin', + () => '> This is some markdown at the top of the page', + ); +} +``` + +Available hooks are: + +- `page.begin` - Applied at the start of the markdown output. +- `page.end` - Applied at the end of the markdown output. +- `content.begin` - Applied before the main markdown content is rendered.. + +## Custom Theme Class + +If there are some specific customization not achievable with hooks then a more advanced customization can be achieved by providing a new theme class which returns a different context class. + +In theory all available templates, partials and hepers can be overriden (and added to) with custom implementations, but please proceed with caution. + +Please consider raising a PR to the plugin directly if you think your customizations would be useful to others. + +```js filename="custom-plugin.mjs" +// @ts-check + +/** + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + // Add a hook to insert markdown at the top of the page. + app.renderer.defineTheme('custom-theme', MyMarkdownTheme); +} + +class MyMarkdownTheme extends MarkdownTheme { + /** + * @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page + */ + getRenderContext(page) { + return new MyMarkdownThemeRenderContext( + this, + page, + this.application.options, + ); + } +} + +class MyMarkdownThemeRenderContext extends MarkdownThemeRenderContext { + partials = { + ...this.partials, + /** + * @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page + */ + header: (page) => { + return `Welcome to ${page.project.name} custom header!`; + }, + }; +} +``` diff --git a/docs/pages/guides/custom-output/_meta.json b/docs/pages/guides/custom-output/_meta.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/docs/pages/guides/custom-output/_meta.json @@ -0,0 +1 @@ +{} diff --git a/docs/pages/quick-start.mdx b/docs/pages/quick-start.mdx index 62f03ce26..f4f8a8e25 100644 --- a/docs/pages/quick-start.mdx +++ b/docs/pages/quick-start.mdx @@ -31,7 +31,6 @@ The majority of [TypeDoc's options](https://typedoc.org/options/) are supported, Some typical (and frequently asked about) TypeDoc options that might be useful are: -- Using [githubPages](https://typedoc.org/options/output/#githubpages) to remove the generated `.nojekyll` file. - Using [hideGenerator](https://typedoc.org/options/output/#hidegenerator) to prevent outputting links in the footer. - Using [disableSources](https://typedoc.org/options/output/#disablesources) to prevent outputting source references. - Setting [readme](https://typedoc.org/options/input/#readme) to `none` to exclude the project readme from the docs. diff --git a/examples/docusaurus3/docusaurus.config.js b/examples/docusaurus3/docusaurus.config.js index 5aedbed74..65a5c4bf6 100644 --- a/examples/docusaurus3/docusaurus.config.js +++ b/examples/docusaurus3/docusaurus.config.js @@ -52,6 +52,7 @@ const config = { readme: 'none', sidebar: { pretty: true }, outputFileStrategy: 'members', + cleanOutputDir: true, }, ], [ @@ -61,6 +62,7 @@ const config = { out: './docs/api-2', ...require(path.join(__dirname, '../../stubs/typedoc.cjs')), entryPoints: '../../stubs/src/groups/**/*.ts', + cleanOutputDir: true, }, ], [ @@ -73,6 +75,7 @@ const config = { readme: 'none', outputFileStrategy: 'modules', entryModule: 'index', + cleanOutputDir: true, }, ], [ diff --git a/packages/docusaurus-plugin-typedoc/package.json b/packages/docusaurus-plugin-typedoc/package.json index e34e9d1fb..302f738bf 100644 --- a/packages/docusaurus-plugin-typedoc/package.json +++ b/packages/docusaurus-plugin-typedoc/package.json @@ -23,7 +23,8 @@ "prepublishOnly": "npm run lint && npm run build", "build": "rm -rf ./dist && tsc", "build-and-test": "npm run build && npm run test", - "test": "jest" + "test": "jest", + "test:update": "npm test -- -u" }, "author": "Thomas Grey", "license": "MIT", diff --git a/packages/docusaurus-plugin-typedoc/src/options.ts b/packages/docusaurus-plugin-typedoc/src/options.ts index d977e582f..51e1fcdb6 100644 --- a/packages/docusaurus-plugin-typedoc/src/options.ts +++ b/packages/docusaurus-plugin-typedoc/src/options.ts @@ -7,7 +7,6 @@ const DEFAULT_PLUGIN_OPTIONS = { hidePageHeader: true, entryFileName: 'index.md', theme: 'docusaurus', - githubPages: false, sidebar: { autoConfiguration: true, pretty: false, diff --git a/packages/docusaurus-plugin-typedoc/src/plugin.ts b/packages/docusaurus-plugin-typedoc/src/plugin.ts index 2ec806438..413490c4a 100644 --- a/packages/docusaurus-plugin-typedoc/src/plugin.ts +++ b/packages/docusaurus-plugin-typedoc/src/plugin.ts @@ -56,10 +56,6 @@ async function generateTypedoc(context: any, opts: Partial) { const outputDir = app.options.getValue('out'); - if (options.cleanOutputDir) { - removeDir(outputDir); - } - if (context.siteConfig?.markdown?.format !== 'mdx') { app.renderer.on(PageEvent.END, (event: PageEvent) => { event.contents = event.contents?.replace(/\\ 0) { - files.forEach(function (filename) { - if (fs.statSync(path + '/' + filename).isDirectory()) { - removeDir(path + '/' + filename); - } else { - fs.unlinkSync(path + '/' + filename); - } - }); - fs.rmdirSync(path); - } else { - fs.rmdirSync(path); - } - } -} diff --git a/packages/docusaurus-plugin-typedoc/src/theme.ts b/packages/docusaurus-plugin-typedoc/src/theme.ts index c06d42297..0d02f7e4b 100644 --- a/packages/docusaurus-plugin-typedoc/src/theme.ts +++ b/packages/docusaurus-plugin-typedoc/src/theme.ts @@ -17,13 +17,16 @@ export class DocusuaurusTheme extends MarkdownTheme { class DocusuaurusThemeThemeRenderContext extends MarkdownThemeRenderContext { // adds space around type arguments as docusaurus generates broken links without it in certain use-cases (see https://github.com/facebook/docusaurus/issues/9518) - override typeArguments = (typeArguments: SomeType[]) => { - return `\\< ${typeArguments - .map((typeArgument) => - typeArgument instanceof ReflectionType - ? this.reflectionType(typeArgument) - : this.someType(typeArgument), - ) - .join(', ')} \\>`; + override partials = { + ...this.partials, + typeArguments: (typeArguments: SomeType[]) => { + return `\\< ${typeArguments + .map((typeArgument) => + typeArgument instanceof ReflectionType + ? this.partials.reflectionType(typeArgument) + : this.partials.someType(typeArgument), + ) + .join(', ')} \\>`; + }, }; } diff --git a/packages/docusaurus-plugin-typedoc/test/specs/__snapshots__/docusaurus.spec.ts.snap b/packages/docusaurus-plugin-typedoc/test/specs/__snapshots__/docusaurus.spec.ts.snap index da9470ae8..8a448abc5 100644 --- a/packages/docusaurus-plugin-typedoc/test/specs/__snapshots__/docusaurus.spec.ts.snap +++ b/packages/docusaurus-plugin-typedoc/test/specs/__snapshots__/docusaurus.spec.ts.snap @@ -14,10 +14,6 @@ exports[`Docusaurus: Defaults should render 1`] = ` - [module-1](module-1/index.md) - [module-2](module-2/index.md) - -*** - -Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). " `; @@ -35,9 +31,5 @@ exports[`Docusaurus: Global members should render 2 1`] = ` - [module-1](module-1/index.md) - [module-2](module-2/index.md) - -*** - -Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). " `; diff --git a/packages/docusaurus-plugin-typedoc/test/specs/docusaurus.spec.ts b/packages/docusaurus-plugin-typedoc/test/specs/docusaurus.spec.ts index 7745761df..cda48295b 100644 --- a/packages/docusaurus-plugin-typedoc/test/specs/docusaurus.spec.ts +++ b/packages/docusaurus-plugin-typedoc/test/specs/docusaurus.spec.ts @@ -13,6 +13,8 @@ async function bootstrap( entryPoints, tsconfig: ['./test/stubs/tsconfig.json'], readme: 'none', + logLevel: 'Warn', + hideGenerator: true, }; const plugin = typedocPlugin( diff --git a/packages/typedoc-github-wiki-theme/package.json b/packages/typedoc-github-wiki-theme/package.json index 2af631074..ca713e9a7 100644 --- a/packages/typedoc-github-wiki-theme/package.json +++ b/packages/typedoc-github-wiki-theme/package.json @@ -22,7 +22,8 @@ "build": "tsc", "build-and-test": "npm run build && npm run test", "pretest": "ts-node ./test/__scripts__/prepare.ts", - "test": "jest" + "test": "jest", + "test:update": "npm run build && npm test -- -u" }, "author": "Thomas Grey", "license": "MIT", diff --git a/packages/typedoc-github-wiki-theme/src/options/option-types.ts b/packages/typedoc-github-wiki-theme/src/options/option-types.ts new file mode 100644 index 000000000..ecd770576 --- /dev/null +++ b/packages/typedoc-github-wiki-theme/src/options/option-types.ts @@ -0,0 +1,18 @@ +// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY. + +import { ManuallyValidatedOption } from 'typedoc'; + +declare module 'typedoc' { + export interface TypeDocOptionMap { + sidebar: ManuallyValidatedOption; + } +} + +export interface PluginOptions { + sidebar: ManuallyValidatedOption; +} + +export interface Sidebar { + autoConfiguration: boolean; + heading: string; +} diff --git a/packages/typedoc-github-wiki-theme/src/options/presets.ts b/packages/typedoc-github-wiki-theme/src/options/presets.ts index 657439691..60d4db98e 100644 --- a/packages/typedoc-github-wiki-theme/src/options/presets.ts +++ b/packages/typedoc-github-wiki-theme/src/options/presets.ts @@ -1,5 +1,4 @@ export default { entryFileName: 'Home.md', hidePageHeader: true, - githubPages: false, }; diff --git a/packages/typedoc-github-wiki-theme/src/theme.ts b/packages/typedoc-github-wiki-theme/src/theme.ts index 9f0b8c633..cfc09a79c 100644 --- a/packages/typedoc-github-wiki-theme/src/theme.ts +++ b/packages/typedoc-github-wiki-theme/src/theme.ts @@ -9,21 +9,20 @@ import { MarkdownTheme, MarkdownThemeRenderContext, } from 'typedoc-plugin-markdown'; -import { UrlMapping } from 'typedoc-plugin-markdown/dist/plugin/url-mapping'; export class GithubWikiTheme extends MarkdownTheme { override getRenderContext(pageEvent: MarkdownPageEvent) { return new ThemeRenderContext(this, pageEvent, this.application.options); } - getUrls(project: ProjectReflection): UrlMapping[] { + getUrls(project: ProjectReflection) { return super.getUrls(project).map((urlMapping) => { if (urlMapping.model.kindOf(ReflectionKind.Project)) { return urlMapping; } return { ...urlMapping, - url: this.getUrl(urlMapping.model), + url: this.getUrl(urlMapping.model as DeclarationReflection), }; }); } @@ -45,7 +44,10 @@ export class GithubWikiTheme extends MarkdownTheme { } class ThemeRenderContext extends MarkdownThemeRenderContext { - override parseUrl(url: string) { - return encodeURI('../wiki/' + url.replace('.md', '')); - } + override utils = { + ...this.utils, + parseUrl: (url: string) => { + return encodeURI('../wiki/' + url.replace('.md', '')); + }, + }; } diff --git a/packages/typedoc-github-wiki-theme/test/__scripts__/prepare.ts b/packages/typedoc-github-wiki-theme/test/__scripts__/prepare.ts index 963da526c..ef8760973 100644 --- a/packages/typedoc-github-wiki-theme/test/__scripts__/prepare.ts +++ b/packages/typedoc-github-wiki-theme/test/__scripts__/prepare.ts @@ -29,7 +29,7 @@ function writeMarkdown(fixture: any) { '-options', `./test/${fixture.options}`, '-logLevel', - 'Info', + 'Warn', '-out', `./test/out/${fixture.outDir}`, ], diff --git a/packages/typedoc-github-wiki-theme/test/typedoc.base.json b/packages/typedoc-github-wiki-theme/test/typedoc.base.json index b81c332a8..f56d3eaae 100644 --- a/packages/typedoc-github-wiki-theme/test/typedoc.base.json +++ b/packages/typedoc-github-wiki-theme/test/typedoc.base.json @@ -6,5 +6,6 @@ "readme": "none", "disableSources": true, "cleanOutputDir": true, - "hideGenerator": true + "hideGenerator": true, + "logLevel": "Warn" } diff --git a/packages/typedoc-gitlab-wiki-theme/src/options/option-types.ts b/packages/typedoc-gitlab-wiki-theme/src/options/option-types.ts new file mode 100644 index 000000000..ecd770576 --- /dev/null +++ b/packages/typedoc-gitlab-wiki-theme/src/options/option-types.ts @@ -0,0 +1,18 @@ +// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY. + +import { ManuallyValidatedOption } from 'typedoc'; + +declare module 'typedoc' { + export interface TypeDocOptionMap { + sidebar: ManuallyValidatedOption; + } +} + +export interface PluginOptions { + sidebar: ManuallyValidatedOption; +} + +export interface Sidebar { + autoConfiguration: boolean; + heading: string; +} diff --git a/packages/typedoc-gitlab-wiki-theme/src/options/presets.ts b/packages/typedoc-gitlab-wiki-theme/src/options/presets.ts index e64ab50b3..c692f3ee4 100644 --- a/packages/typedoc-gitlab-wiki-theme/src/options/presets.ts +++ b/packages/typedoc-gitlab-wiki-theme/src/options/presets.ts @@ -1,5 +1,4 @@ export default { entryFileName: 'home.md', hidePageHeader: true, - githubPages: false, }; diff --git a/packages/typedoc-gitlab-wiki-theme/src/theme.ts b/packages/typedoc-gitlab-wiki-theme/src/theme.ts index 064c8ed91..f020370d4 100644 --- a/packages/typedoc-gitlab-wiki-theme/src/theme.ts +++ b/packages/typedoc-gitlab-wiki-theme/src/theme.ts @@ -12,10 +12,13 @@ export class GitlabWikiTheme extends MarkdownTheme { } class ThemeRenderContext extends MarkdownThemeRenderContext { - override parseUrl(url: string) { - const relativeUrl = url?.replace(/(.*).md/, '$1').replace(/ /g, '-'); - return encodeURI( - relativeUrl?.startsWith('..') ? relativeUrl : './' + relativeUrl, - ); - } + override utils = { + ...this.utils, + parseUrl: (url: string) => { + const relativeUrl = url?.replace(/(.*).md/, '$1').replace(/ /g, '-'); + return encodeURI( + relativeUrl?.startsWith('..') ? relativeUrl : './' + relativeUrl, + ); + }, + }; } diff --git a/packages/typedoc-gitlab-wiki-theme/test/__scripts__/prepare.ts b/packages/typedoc-gitlab-wiki-theme/test/__scripts__/prepare.ts index 963da526c..ef8760973 100644 --- a/packages/typedoc-gitlab-wiki-theme/test/__scripts__/prepare.ts +++ b/packages/typedoc-gitlab-wiki-theme/test/__scripts__/prepare.ts @@ -29,7 +29,7 @@ function writeMarkdown(fixture: any) { '-options', `./test/${fixture.options}`, '-logLevel', - 'Info', + 'Warn', '-out', `./test/out/${fixture.outDir}`, ], diff --git a/packages/typedoc-plugin-frontmatter/src/options/option-types.ts b/packages/typedoc-plugin-frontmatter/src/options/option-types.ts new file mode 100644 index 000000000..404e39af1 --- /dev/null +++ b/packages/typedoc-plugin-frontmatter/src/options/option-types.ts @@ -0,0 +1,21 @@ +// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY. + +import { ManuallyValidatedOption } from 'typedoc'; + +declare module 'typedoc' { + export interface TypeDocOptionMap { + frontmatterGlobals: ManuallyValidatedOption; + frontmatterCommentTags: any[]; + preserveFrontmatterCommentTags: boolean; + frontmatterNamingConvention: 'camelCase' | 'snakeCase'; + } +} + +export interface PluginOptions { + frontmatterGlobals: ManuallyValidatedOption; + frontmatterCommentTags: any[]; + preserveFrontmatterCommentTags: boolean; + frontmatterNamingConvention: 'camelCase' | 'snakeCase'; +} + +export interface FrontmatterGlobals {} diff --git a/packages/typedoc-plugin-frontmatter/test/typedoc-base.json b/packages/typedoc-plugin-frontmatter/test/typedoc-base.json index 8925016a4..51f389705 100644 --- a/packages/typedoc-plugin-frontmatter/test/typedoc-base.json +++ b/packages/typedoc-plugin-frontmatter/test/typedoc-base.json @@ -6,6 +6,5 @@ "plugin": ["typedoc-plugin-markdown", "typedoc-plugin-frontmatter"], "hidePageHeader": true, "hideBreadcrumbs": true, - "hideGenerator": true, - "githubPages": false + "hideGenerator": true } diff --git a/packages/typedoc-plugin-markdown/CONTRIBUTING.md b/packages/typedoc-plugin-markdown/CONTRIBUTING.md index 6de8ea00c..8b102f34d 100644 --- a/packages/typedoc-plugin-markdown/CONTRIBUTING.md +++ b/packages/typedoc-plugin-markdown/CONTRIBUTING.md @@ -1,3 +1,82 @@ # Contributing guidelines -Contributions and suggestions are welcome. Contributing guidelines coming soon. +> Please note this guide is work in progress so read with caution! + +Thank you showing interest in contributing to this plugin - contributions and suggestions are very welcome. + +## Overview + +This is a simple monorepo managed by [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces) with `typedoc-plugin-markdown` the "core" package. This guide is for developing inside the `typedoc-plugin-markdown` core package. + +This guide does not cover TypeDoc specifically so it might be useful to read the [TypeDoc development guide](https://typedoc.org/guides/development/) for an overview on TypeDoc's architecture. + +## Getting started + +1. Clone the repository:
`git clone git@github.com:tgreyuk/typedoc-plugin-markdown.git` + +2. Checkout the `next` branch:
`git checkout next` + +3. Install dependecnices from the repository root.
`npm install` + +4. cd into the package:
`cd packages/typedoc-plugin-markdown` + +5. Build and run tests:
`npm run build-and-test` + +If the project builds and the tests run successfully you are ready to get going. + +## High-level architecture + +At a high level the codebase consists of an exposed TypeDoc plugin along side an assoicated theme. + +At a highlevel: + +- `index.ts` contains the public api and exports the required `load` funtion. +- The `plugin` folder contains functionality to setup the plugin and configure the renderer. +- The `support` folder contains agnostic support helpers used in the plugin. +- The `theme` folder contains the logic that sets up the custom Markdown theme. + +## Testing + +Test use the [Jest](https://jestjs.io/) with [ts-jest](https://kulshekhar.github.io/ts-jest/) as the test framework. To run all tests use the following command: + +```shell +npm run test +``` + +Jest snapshots are used quite heavily to compare the output generated from templates. To update the snapshots run with the `update` flag. + +## Linting + +To run linting on the project use: + +```shell +npm run lint +``` + +Both the code and some example generated markdown are linted using [eslint](https://eslint.org/) and [markdowmlint](https://github.com/DavidAnson/markdownlint) respectively. + +## Submitting a PR + +Please create a PR with a clear description of what the change is. + +If the PR requires a new package release please also create a [changeset](https://github.com/changesets/changesets) which is the tool used for versioning and releasing packages. + +Run the changeset command in the project root: + +```shell +npx changeset +``` + +A one line changeset description will be enough but please ensure the correct semantic version is selected `patch` for a bug fix or `minor` for a new feature. + +The resulting changeset file will something like this: + +```markdown +--- +'typedoc-plugin-markdown': patch +--- + +- A simple description for a patch fix. This message will also appear in the changelog. +``` + +Please also submit this file with the PR. diff --git a/packages/typedoc-plugin-markdown/docs/api/README.md b/packages/typedoc-plugin-markdown/docs/api/README.md new file mode 100644 index 000000000..ac63bf47a --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/README.md @@ -0,0 +1,14 @@ +# typedoc-plugin-markdown + +## Modules + +- [plugin/events](plugin/events.md) +- [plugin](plugin.md) +- [plugin/renderer](plugin/renderer.md) +- [plugin/types](plugin/types.md) +- [plugin/utils](plugin/utils.md) +- [theme/resources/partials](theme/resources/partials.md) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/plugin.md b/packages/typedoc-plugin-markdown/docs/api/plugin.md new file mode 100644 index 000000000..3bccae402 --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/plugin.md @@ -0,0 +1,771 @@ +# plugin + +## load() + +> **load**(`app`): `void` + +The function that is called by TypeDoc to bootstrap the plugin. {@see https://typedoc.org/guides/development/#plugins} + +Here we expose additional TypeDoc options and make some adjustments. + +### Parameters + +• **app**: [`Application`](https://typedoc.org/api/classes/Application.html) + +### Returns + +`void` + +### Source + +[plugin/index.ts:22](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/index.ts#L22) + +*** + +## OutputFileStrategy + +Defines outputFileStrategy model for the `outputFileStrategy` option. + +### Enumeration Members + +#### Members + +> **Members**: `"members"` + +##### Source + +[plugin/options/option-maps.ts:8](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts#L8) + +#### Modules + +> **Modules**: `"modules"` + +##### Source + +[plugin/options/option-maps.ts:9](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts#L9) + +*** + +## FormatStyle + +### Enumeration Members + +#### List + +> **List**: `"list"` + +##### Source + +[plugin/options/option-maps.ts:20](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts#L20) + +#### Table + +> **Table**: `"table"` + +##### Source + +[plugin/options/option-maps.ts:21](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts#L21) + +*** + +## PluginOptions + +### Properties + +#### outputFileStrategy + +> **outputFileStrategy**: `"members"` \| `"modules"` + +##### Source + +[plugin/options/option-types.ts:34](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L34) + +#### entryFileName + +> **entryFileName**: `string` + +##### Source + +[plugin/options/option-types.ts:35](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L35) + +#### entryModule + +> **entryModule**: `string` + +##### Source + +[plugin/options/option-types.ts:36](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L36) + +#### mergeReadme + +> **mergeReadme**: `boolean` + +##### Source + +[plugin/options/option-types.ts:37](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L37) + +#### hidePageHeader + +> **hidePageHeader**: `boolean` + +##### Source + +[plugin/options/option-types.ts:38](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L38) + +#### hidePageTitle + +> **hidePageTitle**: `boolean` + +##### Source + +[plugin/options/option-types.ts:39](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L39) + +#### hideBreadcrumbs + +> **hideBreadcrumbs**: `boolean` + +##### Source + +[plugin/options/option-types.ts:40](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L40) + +#### hideInPageTOC + +> **hideInPageTOC**: `boolean` + +##### Source + +[plugin/options/option-types.ts:41](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L41) + +#### indexPageTitle + +> **indexPageTitle**: `string` + +##### Source + +[plugin/options/option-types.ts:42](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L42) + +#### memberPageTitle + +> **memberPageTitle**: `string` + +##### Source + +[plugin/options/option-types.ts:43](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L43) + +#### excludeGroups + +> **excludeGroups**: `boolean` + +##### Source + +[plugin/options/option-types.ts:44](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L44) + +#### useCodeBlocks + +> **useCodeBlocks**: `boolean` + +##### Source + +[plugin/options/option-types.ts:45](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L45) + +#### expandObjects + +> **expandObjects**: `boolean` + +##### Source + +[plugin/options/option-types.ts:46](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L46) + +#### parametersFormat + +> **parametersFormat**: `"table"` \| `"list"` + +##### Source + +[plugin/options/option-types.ts:47](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L47) + +#### propertiesFormat + +> **propertiesFormat**: `"table"` \| `"list"` + +##### Source + +[plugin/options/option-types.ts:48](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L48) + +#### enumMembersFormat + +> **enumMembersFormat**: `"table"` \| `"list"` + +##### Source + +[plugin/options/option-types.ts:49](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L49) + +#### typeDeclarationFormat + +> **typeDeclarationFormat**: `"table"` \| `"list"` + +##### Source + +[plugin/options/option-types.ts:50](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L50) + +#### indexFormat + +> **indexFormat**: `"table"` \| `"list"` + +##### Source + +[plugin/options/option-types.ts:51](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L51) + +#### textContentMappings + +> **textContentMappings**: `ManuallyValidatedOption`\<[`TextContentMappings`](plugin.md#textcontentmappings-1)\> + +##### Source + +[plugin/options/option-types.ts:52](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L52) + +#### publicPath + +> **publicPath**: `string` + +##### Source + +[plugin/options/option-types.ts:53](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L53) + +#### preserveAnchorCasing + +> **preserveAnchorCasing**: `boolean` + +##### Source + +[plugin/options/option-types.ts:54](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L54) + +#### anchorPrefix + +> **anchorPrefix**: `string` + +##### Source + +[plugin/options/option-types.ts:55](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L55) + +#### namedAnchors + +> **namedAnchors**: `boolean` + +##### Source + +[plugin/options/option-types.ts:56](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L56) + +*** + +## TextContentMappings + +### Properties + +#### header.title + +> **header.title**: `string` + +##### Source + +[plugin/options/option-types.ts:60](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L60) + +#### header.readme + +> **header.readme**: `string` + +##### Source + +[plugin/options/option-types.ts:61](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L61) + +#### header.docs + +> **header.docs**: `string` + +##### Source + +[plugin/options/option-types.ts:62](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L62) + +#### breadcrumbs.home + +> **breadcrumbs.home**: `string` + +##### Source + +[plugin/options/option-types.ts:63](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L63) + +#### footer.generator + +> **footer.generator**: `string` + +##### Source + +[plugin/options/option-types.ts:64](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L64) + +#### title.indexPage + +> **title.indexPage**: `string` + +##### Source + +[plugin/options/option-types.ts:65](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L65) + +#### title.modulePage + +> **title.modulePage**: `string` + +##### Source + +[plugin/options/option-types.ts:66](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L66) + +#### title.memberPage + +> **title.memberPage**: `string` + +##### Source + +[plugin/options/option-types.ts:67](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L67) + +#### title.member + +> **title.member**: `string` + +##### Source + +[plugin/options/option-types.ts:68](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L68) + +#### label.defaultValue + +> **label.defaultValue**: `string` + +##### Source + +[plugin/options/option-types.ts:69](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L69) + +#### label.description + +> **label.description**: `string` + +##### Source + +[plugin/options/option-types.ts:70](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L70) + +#### label.extendedBy + +> **label.extendedBy**: `string` + +##### Source + +[plugin/options/option-types.ts:71](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L71) + +#### label.extends + +> **label.extends**: `string` + +##### Source + +[plugin/options/option-types.ts:72](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L72) + +#### label.globals + +> **label.globals**: `string` + +##### Source + +[plugin/options/option-types.ts:73](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L73) + +#### label.implements + +> **label.implements**: `string` + +##### Source + +[plugin/options/option-types.ts:74](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L74) + +#### label.implementationOf + +> **label.implementationOf**: `string` + +##### Source + +[plugin/options/option-types.ts:75](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L75) + +#### label.inheritedFrom + +> **label.inheritedFrom**: `string` + +##### Source + +[plugin/options/option-types.ts:76](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L76) + +#### label.index + +> **label.index**: `string` + +##### Source + +[plugin/options/option-types.ts:77](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L77) + +#### label.indexable + +> **label.indexable**: `string` + +##### Source + +[plugin/options/option-types.ts:78](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L78) + +#### label.indexSignature + +> **label.indexSignature**: `string` + +##### Source + +[plugin/options/option-types.ts:79](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L79) + +#### label.member + +> **label.member**: `string` + +##### Source + +[plugin/options/option-types.ts:80](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L80) + +#### label.modifier + +> **label.modifier**: `string` + +##### Source + +[plugin/options/option-types.ts:81](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L81) + +#### label.overrides + +> **label.overrides**: `string` + +##### Source + +[plugin/options/option-types.ts:82](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L82) + +#### label.packages + +> **label.packages**: `string` + +##### Source + +[plugin/options/option-types.ts:83](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L83) + +#### label.reExports + +> **label.reExports**: `string` + +##### Source + +[plugin/options/option-types.ts:84](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L84) + +#### label.renamesAndReExports + +> **label.renamesAndReExports**: `string` + +##### Source + +[plugin/options/option-types.ts:85](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L85) + +#### label.returns + +> **label.returns**: `string` + +##### Source + +[plugin/options/option-types.ts:86](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L86) + +#### label.source + +> **label.source**: `string` + +##### Source + +[plugin/options/option-types.ts:87](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L87) + +#### label.type + +> **label.type**: `string` + +##### Source + +[plugin/options/option-types.ts:88](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L88) + +#### label.typeDeclaration + +> **label.typeDeclaration**: `string` + +##### Source + +[plugin/options/option-types.ts:89](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L89) + +#### label.value + +> **label.value**: `string` + +##### Source + +[plugin/options/option-types.ts:90](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L90) + +#### kind.class.singular + +> **kind.class.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:91](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L91) + +#### kind.class.plural + +> **kind.class.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:92](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L92) + +#### kind.constructor.singular + +> **kind.constructor.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:93](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L93) + +#### kind.constructor.plural + +> **kind.constructor.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:94](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L94) + +#### kind.enum.singular + +> **kind.enum.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:95](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L95) + +#### kind.enum.plural + +> **kind.enum.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:96](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L96) + +#### kind.enumMember.singular + +> **kind.enumMember.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:97](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L97) + +#### kind.enumMember.plural + +> **kind.enumMember.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:98](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L98) + +#### kind.event.singular + +> **kind.event.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:99](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L99) + +#### kind.event.plural + +> **kind.event.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:100](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L100) + +#### kind.function.singular + +> **kind.function.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:101](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L101) + +#### kind.function.plural + +> **kind.function.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:102](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L102) + +#### kind.interface.singular + +> **kind.interface.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:103](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L103) + +#### kind.interface.plural + +> **kind.interface.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:104](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L104) + +#### kind.method.singular + +> **kind.method.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:105](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L105) + +#### kind.method.plural + +> **kind.method.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:106](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L106) + +#### kind.module.singular + +> **kind.module.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:107](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L107) + +#### kind.module.plural + +> **kind.module.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:108](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L108) + +#### kind.namespace.singular + +> **kind.namespace.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:109](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L109) + +#### kind.namespace.plural + +> **kind.namespace.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:110](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L110) + +#### kind.variable.singular + +> **kind.variable.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:111](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L111) + +#### kind.variable.plural + +> **kind.variable.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:112](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L112) + +#### kind.parameter.singular + +> **kind.parameter.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:113](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L113) + +#### kind.parameter.plural + +> **kind.parameter.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:114](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L114) + +#### kind.property.singular + +> **kind.property.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:115](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L115) + +#### kind.property.plural + +> **kind.property.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:116](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L116) + +#### kind.reference.singular + +> **kind.reference.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:117](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L117) + +#### kind.reference.plural + +> **kind.reference.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:118](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L118) + +#### kind.typeAlias.singular + +> **kind.typeAlias.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:119](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L119) + +#### kind.typeAlias.plural + +> **kind.typeAlias.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:120](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L120) + +#### kind.typeParameter.singular + +> **kind.typeParameter.singular**: `string` + +##### Source + +[plugin/options/option-types.ts:121](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L121) + +#### kind.typeParameter.plural + +> **kind.typeParameter.plural**: `string` + +##### Source + +[plugin/options/option-types.ts:122](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts#L122) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/plugin/events.md b/packages/typedoc-plugin-markdown/docs/api/plugin/events.md new file mode 100644 index 000000000..a20fa8a6a --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/plugin/events.md @@ -0,0 +1,221 @@ +# plugin/events + +## MarkdownRendererEvent + +Extends the RendererEvent from TypeDoc to expose navigation property. + +### Extends + +- `Event` + +### Constructors + +#### new MarkdownRendererEvent(name, outputDirectory, project) + +> **new MarkdownRendererEvent**(`name`, `outputDirectory`, `project`): [`MarkdownRendererEvent`](events.md#markdownrendererevent) + +##### Parameters + +• **name**: `string` + +• **outputDirectory**: `string` + +• **project**: [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +##### Returns + +[`MarkdownRendererEvent`](events.md#markdownrendererevent) + +##### Overrides + +`Event.constructor` + +##### Source + +[plugin/events.ts:20](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L20) + +### Properties + +#### project + +> **`readonly`** **project**: [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +##### Source + +[plugin/events.ts:10](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L10) + +#### outputDirectory + +> **`readonly`** **outputDirectory**: `string` + +##### Source + +[plugin/events.ts:12](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L12) + +#### navigation + +> **navigation**: `NavigationItem`[] + +##### Source + +[plugin/events.ts:15](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L15) + +#### urls? + +> **urls**?: `UrlMapping`\<[`Reflection`](https://typedoc.org/api/classes/Models.Reflection.html)\>[] + +##### Source + +[plugin/events.ts:14](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L14) + +#### BEGIN + +> **`static`** **`readonly`** **BEGIN**: `"beginRender"` = `'beginRender'` + +##### Source + +[plugin/events.ts:17](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L17) + +#### END + +> **`static`** **`readonly`** **END**: `"endRender"` = `'endRender'` + +##### Source + +[plugin/events.ts:18](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L18) + +### Methods + +#### createPageEvent() + +> **createPageEvent**\<`Model`\>(`mapping`): [`RenderTemplate`\<[`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\>\>, [`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\>] + +##### Type parameters + +• **Model** + +##### Parameters + +• **mapping**: `UrlMapping`\<`Model`\> + +##### Returns + +[`RenderTemplate`\<[`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\>\>, [`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\>] + +##### Source + +[plugin/events.ts:30](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L30) + +*** + +## MarkdownPageEvent\ + +### Extends + +- `Event` + +### Type parameters + +• **Model** = [`Reflection`]( https://typedoc.org/api/classes/Models.Reflection.html ) + +### Constructors + +#### new MarkdownPageEvent(name, model) + +> **new MarkdownPageEvent**\<`Model`\>(`name`, `model`): [`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\> + +##### Parameters + +• **name**: `string` + +• **model**: `Model` + +##### Returns + +[`MarkdownPageEvent`](events.md#markdownpageevent)\<`Model`\> + +##### Overrides + +`Event.constructor` + +##### Source + +[plugin/events.ts:54](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L54) + +### Properties + +#### project + +> **project**: [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +##### Source + +[plugin/events.ts:45](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L45) + +#### filename + +> **filename**: `string` + +##### Source + +[plugin/events.ts:46](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L46) + +#### url + +> **url**: `string` + +##### Source + +[plugin/events.ts:47](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L47) + +#### pageHeadings + +> **pageHeadings**: `any` + +##### Source + +[plugin/events.ts:50](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L50) + +#### model + +> **`readonly`** **model**: `Model` + +##### Source + +[plugin/events.ts:51](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L51) + +#### contents? + +> **contents**?: `string` + +##### Source + +[plugin/events.ts:48](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L48) + +#### frontmatter? + +> **frontmatter**?: `any` + +##### Source + +[plugin/events.ts:49](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L49) + +#### BEGIN + +> **`static`** **`readonly`** **BEGIN**: `"beginPage"` = `'beginPage'` + +##### Source + +[plugin/events.ts:52](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L52) + +#### END + +> **`static`** **`readonly`** **END**: `"endPage"` = `'endPage'` + +##### Source + +[plugin/events.ts:53](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/events.ts#L53) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/plugin/renderer.md b/packages/typedoc-plugin-markdown/docs/api/plugin/renderer.md new file mode 100644 index 000000000..9985968cc --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/plugin/renderer.md @@ -0,0 +1,53 @@ +# plugin/renderer + +## generateDocs() + +> **generateDocs**(`project`, `out`): `Promise`\<`void`\> + +Replacement of TypeDoc's Application.generateDocs method to decouple HTML logic. + +### Parameters + +• **project**: [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +• **out**: `string` + +### Returns + +`Promise`\<`void`\> + +### Source + +[plugin/renderer.ts:24](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/renderer.ts#L24) + +*** + +## render() + +> **render**(`project`, `outputDirectory`): `Promise`\<`void`\> + +Replacement of TypeDoc's Renderer.render method to decouple HTML logic. + +This is essentially a copy of the base method with a few tweaks. + +- Removes uneccessary async calls to load highlighters only required for html theme. +- Removes hooks logic that are jsx specific. +- Adds any logic specific to markdown rendering. + +### Parameters + +• **project**: [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +• **outputDirectory**: `string` + +### Returns + +`Promise`\<`void`\> + +### Source + +[plugin/renderer.ts:46](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/renderer.ts#L46) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/plugin/types.md b/packages/typedoc-plugin-markdown/docs/api/plugin/types.md new file mode 100644 index 000000000..3ed4d06af --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/plugin/types.md @@ -0,0 +1,95 @@ +# plugin/types + +## MarkdownApplication + +The plugin amends the renderer with additional hooks and options. + +This interface augments the TypeDoc Application with the updated renderer. + +### Extends + +- [`Application`](https://typedoc.org/api/classes/Application.html) + +### Properties + +#### renderer + +> **renderer**: [`MarkdownRenderer`](types.md#markdownrenderer) + +##### Overrides + +`Application.renderer` + +##### Source + +[plugin/types.ts:10](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L10) + +*** + +## MarkdownRenderer + +The plugin amends the renderer with additional hooks and options. + +### Extends + +- [`Renderer`](https://typedoc.org/api/classes/Renderer.html) + +### Properties + +#### markdownHooks + +> **markdownHooks**: `EventHooks`\<[`MarkdownRendererHooks`](types.md#markdownrendererhooks), `string`\> + +##### Source + +[plugin/types.ts:17](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L17) + +#### packageOptions + +> **packageOptions**: `Record`\<`string`, [`Options`](https://typedoc.org/api/classes/Configuration.Options.html)\> + +##### Source + +[plugin/types.ts:18](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L18) + +*** + +## MarkdownRendererHooks + +This is the custom render hooks method based on the equivalent TypeDoc class. + +### Properties + +#### page.begin + +> **page.begin**: [`MarkdownThemeRenderContext`] + +Applied at the start of the markdown output. + +##### Source + +[plugin/types.ts:28](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L28) + +#### page.end + +> **page.end**: [`MarkdownThemeRenderContext`] + +Applied at the end of the markdown output. + +##### Source + +[plugin/types.ts:33](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L33) + +#### content.begin + +> **content.begin**: [`MarkdownThemeRenderContext`] + +Applied before the main markdown content is rendered. + +##### Source + +[plugin/types.ts:38](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/types.ts#L38) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/plugin/utils.md b/packages/typedoc-plugin-markdown/docs/api/plugin/utils.md new file mode 100644 index 000000000..0f463999f --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/plugin/utils.md @@ -0,0 +1,65 @@ +# plugin/utils + +## writeFileSync() + +> **writeFileSync**(`fileName`, `data`): `void` + +Writes a file to disc. + +### Parameters + +• **fileName**: `string` + +• **data**: `string` + +### Returns + +`void` + +### Source + +[plugin/utils.ts:16](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/utils.ts#L16) + +*** + +## nicePath() + +> **nicePath**(`absPath`): `string` + +Returns a readable path from an absolute path. + +### Parameters + +• **absPath**: `string` + +### Returns + +`string` + +### Source + +[plugin/utils.ts:24](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/utils.ts#L24) + +*** + +## normalizePath() + +> **normalizePath**(`path`): `string` + +Normalizes directory seperators from a given path. + +### Parameters + +• **path**: `string` + +### Returns + +`string` + +### Source + +[plugin/utils.ts:36](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/plugin/utils.ts#L36) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/docs/api/theme/resources/partials.md b/packages/typedoc-plugin-markdown/docs/api/theme/resources/partials.md new file mode 100644 index 000000000..39c061bca --- /dev/null +++ b/packages/typedoc-plugin-markdown/docs/api/theme/resources/partials.md @@ -0,0 +1,1132 @@ +# theme/resources/partials + +## Other + +### breadcrumbs() + +> **breadcrumbs**(`context`, `page`): `string` + +Renders the breadcrumbs + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **page**: [`MarkdownPageEvent`](../../plugin/events.md#markdownpageevent)\<[`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html)\> + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/breadcrumbs.ts:10](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/breadcrumbs.ts#L10) + +*** + +### header() + +> **header**(`context`, `page`): `string` + +Docs for header!!! + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **page**: [`MarkdownPageEvent`](../../plugin/events.md#markdownpageevent)\<[`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html)\> + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/header.ts:13](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/header.ts#L13) + +*** + +### reflectionIndex() + +> **reflectionIndex**(`context`, `reflection`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html) + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/index.reflection.ts:10](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.reflection.ts#L10) + +*** + +### linkTo() + +> **linkTo**(`context`, `label`, `url`?): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **label**: `string` + +• **url?**: `string` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/link-to.ts:4](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/link-to.ts#L4) + +*** + +### memberHierarchy() + +> **memberHierarchy**(`context`, `declarationHierarchy`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **declarationHierarchy**: `DeclarationHierarchy` + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.hierarchy.ts:4](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.hierarchy.ts#L4) + +*** + +### inheritance() + +> **inheritance**(`context`, `reflection`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| `SignatureReflection` + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.inheritance.ts:9](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.inheritance.ts#L9) + +*** + +### members() + +> **members**(`context`, `container`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **container**: `ContainerReflection` + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/members.ts:10](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/members.ts#L10) + +*** + +### typeArguments() + +> **typeArguments**(`context`, `typeArguments`, `foreCollpase`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **typeArguments**: `SomeType`[] + +• **foreCollpase**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type-argumentsts.ts:4](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type-argumentsts.ts#L4) + +## Partials + +### commentParts() + +> **commentParts**(`context`, `parts`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **parts**: [`CommentDisplayPart`]( https://typedoc.org/api/types/Models.CommentDisplayPart.html )[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/comment.parts.ts:8](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.parts.ts#L8) + +*** + +### comment() + +> **comment**(`context`, `comment`, `headingLevel`?, `showSummary`?, `showTags`?): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **comment**: `Comment` + +• **headingLevel?**: `number` + +• **showSummary?**: `boolean`= `true` + +• **showTags?**: `boolean`= `true` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/comment.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.ts#L7) + +*** + +### generator() + +> **generator**(`context`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/generator.ts:6](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/generator.ts#L6) + +*** + +### pageIndex() + +> **pageIndex**(`context`, `page`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **page**: [`MarkdownPageEvent`](../../plugin/events.md#markdownpageevent)\<[`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html)\> + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/index.page.ts:13](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.page.ts#L13) + +*** + +### parametersList() + +> **parametersList**(`context`, `parameters`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **parameters**: `ParameterReflection`[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/list.parameters.ts:8](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.parameters.ts#L8) + +*** + +### typeParametersList() + +> **typeParametersList**(`context`, `typeParameters`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **typeParameters**: `TypeParameterReflection`[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/list.typeparameters.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.typeparameters.ts#L7) + +*** + +### accessorMember() + +> **accessorMember**(`context`, `declaration`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **declaration**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.accessor.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.accessor.ts#L7) + +*** + +### constructorMember() + +> **constructorMember**(`context`, `reflection`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.constructors.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.constructors.ts#L7) + +*** + +### declarationMemberIdentifier() + +> **declarationMemberIdentifier**(`context`, `reflection`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.declaration.identifier.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.identifier.ts#L7) + +*** + +### declarationMember() + +> **declarationMember**(`context`, `declaration`, `headingLevel`, `nested`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **declaration**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +• **nested**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.declaration.ts:12](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.ts#L12) + +*** + +### indexSignatureTitle() + +> **indexSignatureTitle**(`context`, `signature`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **signature**: `SignatureReflection` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.indexsignature.title.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.indexsignature.title.ts#L7) + +*** + +### referenceMember() + +> **referenceMember**(`context`, `props`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **props**: `ReferenceReflection` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.reference.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reference.ts#L7) + +*** + +### reflectionMember() + +> **reflectionMember**(`context`, `reflection`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.reflection.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reflection.ts#L7) + +*** + +### signatureMemberIdentifier() + +> **signatureMemberIdentifier**(`context`, `signature`, `opts`?): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **signature**: `SignatureReflection` + +• **opts?**: \{ + `accessor`: `string`; + `includeType`: `boolean`; + } + +• **opts\.accessor?**: `string` + +• **opts\.includeType?**: `boolean` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.signature.identifier.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.identifier.ts#L7) + +*** + +### signatureParameters() + +> **signatureParameters**(`context`, `parameters`, `format`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **parameters**: `ParameterReflection`[] + +• **format**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.signature.parameters.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.parameters.ts#L7) + +*** + +### signatureMemberReturns() + +> **signatureMemberReturns**(`context`, `signature`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **signature**: `SignatureReflection` + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.signature.returns.ts:13](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.returns.ts#L13) + +*** + +### signatureMember() + +> **signatureMember**(`context`, `signature`, `headingLevel`, `nested`, `accessor`?): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **signature**: `SignatureReflection` + +• **headingLevel**: `number` + +• **nested**: `boolean`= `false` + +• **accessor?**: `string` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.signature.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.ts#L7) + +*** + +### sources() + +> **sources**(`context`, `reflection`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| `SignatureReflection` + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.sources.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.sources.ts#L7) + +*** + +### memberTitle() + +> **memberTitle**(`context`, `reflection`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.title.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.title.ts#L7) + +*** + +### member() + +> **member**(`context`, `reflection`, `headingLevel`, `nested`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +• **nested**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.ts:11](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.ts#L11) + +*** + +### typeDeclarationMember() + +> **typeDeclarationMember**(`context`, `typeDeclaration`, `headingLevel`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **typeDeclaration**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +• **headingLevel**: `number` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/member.type-declaration.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.type-declaration.ts#L7) + +*** + +### pageTitle() + +> **pageTitle**(`context`, `page`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **page**: [`MarkdownPageEvent`](../../plugin/events.md#markdownpageevent)\<[`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) \| [`ProjectReflection`](https://typedoc.org/api/classes/Models.ProjectReflection.html)\> + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/page.title.ts:11](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/page.title.ts#L11) + +*** + +### enumMembersTable() + +> **enumMembersTable**(`context`, `props`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **props**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html)[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/table.enum-members.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.enum-members.ts#L7) + +*** + +### parametersTable() + +> **parametersTable**(`context`, `parameters`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **parameters**: `ParameterReflection`[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/table.parameters.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.parameters.ts#L7) + +*** + +### propertiesTable() + +> **propertiesTable**(`context`, `props`, `isEventProps`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **props**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html)[] + +• **isEventProps**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/table.properties.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.properties.ts#L7) + +*** + +### typeDeclarationTable() + +> **typeDeclarationTable**(`context`, `props`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **props**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html)[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/table.type-declaration.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.type-declaration.ts#L7) + +*** + +### typeParametersTable() + +> **typeParametersTable**(`context`, `typeParameters`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **typeParameters**: `TypeParameterReflection`[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/table.typeparameters.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.typeparameters.ts#L7) + +*** + +### arrayType() + +> **arrayType**(`context`, `arrayType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **arrayType**: `ArrayType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.array.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.array.ts#L7) + +*** + +### conditionalType() + +> **conditionalType**(`context`, `conditionalType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **conditionalType**: `ConditionalType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.conditional.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.conditional.ts#L7) + +*** + +### declarationType() + +> **declarationType**(`context`, `declarationReflection`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **declarationReflection**: [`DeclarationReflection`](https://typedoc.org/api/classes/Models.DeclarationReflection.html) + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.declaration.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.declaration.ts#L7) + +*** + +### functionType() + +> **functionType**(`context`, `modelSignatures`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **modelSignatures**: `SignatureReflection`[] + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.function.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.function.ts#L7) + +*** + +### indexAccessType() + +> **indexAccessType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `IndexedAccessType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.index-access.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.index-access.ts#L7) + +*** + +### inferredType() + +> **inferredType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `InferredType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.inferred.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.inferred.ts#L7) + +*** + +### intersectionType() + +> **intersectionType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `IntersectionType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.intersection.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intersection.ts#L7) + +*** + +### intrinsicType() + +> **intrinsicType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `IntrinsicType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.intrinsic.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intrinsic.ts#L7) + +*** + +### literalType() + +> **literalType**(`context`, `literalType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **literalType**: `LiteralType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.literal.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.literal.ts#L7) + +*** + +### namedTupleType() + +> **namedTupleType**(`context`, `member`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **member**: `NamedTupleMember` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.named-tuple.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.named-tuple.ts#L7) + +*** + +### queryType() + +> **queryType**(`context`, `queryType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **queryType**: `QueryType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.query.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.query.ts#L7) + +*** + +### referenceType() + +> **referenceType**(`context`, `referenceType`, `foreCollpase`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **referenceType**: `ReferenceType` + +• **foreCollpase**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.reference.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reference.ts#L7) + +*** + +### reflectionType() + +> **reflectionType**(`context`, `reflectionType`, `foreCollpase`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **reflectionType**: `ReflectionType` + +• **foreCollpase**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.reflection.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reflection.ts#L7) + +*** + +### someType() + +> **someType**(`context`, `someType`, `foreCollpase`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **someType**: `SomeType` + +• **foreCollpase**: `boolean`= `false` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.some.ts:23](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.some.ts#L23) + +*** + +### tupleType() + +> **tupleType**(`context`, `tupleType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **tupleType**: `TupleType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.tuple.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.tuple.ts#L7) + +*** + +### typeOperatorType() + +> **typeOperatorType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `TypeOperatorType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.type-operator.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.type-operator.ts#L7) + +*** + +### unionType() + +> **unionType**(`context`, `unionType`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **unionType**: `UnionType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.union.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.union.ts#L7) + +*** + +### unknownType() + +> **unknownType**(`context`, `model`): `string` + +#### Parameters + +• **context**: `MarkdownThemeRenderContext` + +• **model**: `UnknownType` + +#### Returns + +`string` + +#### Source + +[theme/resources/partials/type.unknown.ts:7](https://github.com/tgreyuk/typedoc-plugin-markdown/blob/8b03c29e/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.unknown.ts#L7) + +*** + +Generated using [TypeDoc](https://typedoc.org) and [typedoc-plugin-markdown](https://typedoc-plugin-markdown.org). diff --git a/packages/typedoc-plugin-markdown/package.json b/packages/typedoc-plugin-markdown/package.json index 79808bfaa..ebf5cafe2 100644 --- a/packages/typedoc-plugin-markdown/package.json +++ b/packages/typedoc-plugin-markdown/package.json @@ -9,15 +9,16 @@ "scripts": { "lint": "eslint ./src --ext .ts", "prepublishOnly": "npm run lint && npm run build", - "prebuild": "rm -rf dist && prebuild-options && ts-node scripts/prebuild-resources", + "prebuild": "rm -rf dist && prebuild-options && ts-node scripts/prebuild", "build": "tsc", - "pretest": "ts-node ./test/__scripts__/prepare.ts", - "test": "npm-run-all test:*", - "test:lint-md": "node test/__scripts__/lint.md.mjs", - "test:lint-mdx": "node test/__scripts__/lint.mdx.mjs", - "test:jest": "jest", + "pretest": "ts-node ./test/__scripts__/prepare", + "test-md": "node test/__scripts__/lint.md.mjs", + "test-mdx": "node test/__scripts__/lint.mdx.mjs", + "test": "npm run test-md && npm run test-mdx && jest", + "test:update": "npm run build && npm test -- -u", "build-and-run": "npm run build && npm run pretest", - "build-and-test": "npm run build && npm run test" + "build-and-test": "npm run build && npm run test", + "docs": "npm run build && typedoc --options ./typedoc.md.json --out ./docs/api && typedoc --options ./typedoc.base.json --out ./docs/api-html" }, "author": "Thomas Grey", "license": "MIT", diff --git a/packages/typedoc-plugin-markdown/scripts/prebuild-kinds.ts b/packages/typedoc-plugin-markdown/scripts/prebuild-kinds.ts new file mode 100644 index 000000000..a574be644 --- /dev/null +++ b/packages/typedoc-plugin-markdown/scripts/prebuild-kinds.ts @@ -0,0 +1,90 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as prettier from 'prettier'; +import { ReflectionKind } from 'typedoc'; + +export async function prebuildKinds() { + const themeRenderKindConstantsFile = path.join( + __dirname, + '..', + 'src', + 'plugin', + 'options', + 'text-mappings', + 'kind-defaults.ts', + ); + + const kinds = [ + { key: 'class', kind: ReflectionKind.Class }, + { key: 'constructor', kind: ReflectionKind.Constructor }, + { key: 'enum', kind: ReflectionKind.Enum }, + { key: 'enumMember', kind: ReflectionKind.EnumMember }, + { key: 'event', kind: undefined }, + { key: 'function', kind: ReflectionKind.Function }, + { key: 'interface', kind: ReflectionKind.Interface }, + { key: 'method', kind: ReflectionKind.Method }, + { key: 'module', kind: ReflectionKind.Module }, + { key: 'namespace', kind: ReflectionKind.Namespace }, + { key: 'variable', kind: ReflectionKind.Variable }, + { key: 'parameter', kind: ReflectionKind.Parameter }, + { key: 'property', kind: ReflectionKind.Property }, + { key: 'reference', kind: ReflectionKind.Reference }, + { key: 'typeAlias', kind: ReflectionKind.TypeAlias }, + { key: 'typeParameter', kind: ReflectionKind.TypeParameter }, + ]; + + const kindsString: string[] = []; + + const capitalize = (s: string) => s && s[0].toUpperCase() + s.slice(1); + + const singularString = (kind: any) => + kind.kind ? ReflectionKind.singularString(kind.kind) : capitalize(kind.key); + + const pluralString = (kind: any) => + kind.kind + ? ReflectionKind.pluralString(kind.kind) + : `${capitalize(kind.key)}s`; + + kindsString.push(` + // THIS FILE IS AUTOGENERATED - DO NOT EDIT DIRECTLY + + export const KIND_DEFAULTS: Record = { + ${kinds + .map((kind) => { + return ` + 'kind.${kind.key}.singular':'${singularString(kind)}', + 'kind.${kind.key}.plural':'${pluralString(kind)}' + `; + }) + .join(',')} + } + `); + + kindsString.push(` + export const SINGULAR_KIND_KEY_MAP: Record = { + ${kinds + .map((kind) => { + return `['${singularString(kind)}']: 'kind.${kind.key}.singular'`; + }) + .join(',')} + } + `); + + kindsString.push(` + export const PLURAL_KIND_KEY_MAP: Record= { + ${kinds + .map((kind) => { + return `['${pluralString(kind)}']: 'kind.${kind.key}.plural'`; + }) + .join(',')} + } + `); + + const formattedKinds = await prettier.format(kindsString.join('\n'), { + parser: 'typescript', + singleQuote: true, + trailingComma: 'all', + }); + + fs.writeFileSync(themeRenderKindConstantsFile, formattedKinds); +} diff --git a/packages/typedoc-plugin-markdown/scripts/prebuild-resources.ts b/packages/typedoc-plugin-markdown/scripts/prebuild-resources.ts index 56eb16d73..7b941cd32 100644 --- a/packages/typedoc-plugin-markdown/scripts/prebuild-resources.ts +++ b/packages/typedoc-plugin-markdown/scripts/prebuild-resources.ts @@ -1,9 +1,7 @@ -import { consola } from 'consola'; import * as fs from 'fs'; import * as path from 'path'; import * as prettier from 'prettier'; import { Project } from 'ts-morph'; -import { ReflectionKind } from 'typedoc'; const project = new Project({ tsConfigFilePath: 'tsconfig.json', @@ -11,191 +9,95 @@ const project = new Project({ const resourcesPath = path.join(__dirname, '..', 'src', 'theme', 'resources'); -main(); +export async function prebuildResources() { + writeBarrelsFile('partials'); + writeBarrelsFile('templates'); + writeResourcesFile(); +} + +function getFiles(type: string) { + const partialsFolder = path.join(resourcesPath, type); + return fs + .readdirSync(partialsFolder) + .map((partialsFile) => path.parse(partialsFile).name); +} -async function main() { - // WRITE CONSTANTS +function getSymbols(files: string[], type: string) { + return files.map((file) => { + const tsFile = project.getSourceFile( + path.join(resourcesPath, type, file + '.ts'), + ); + const symbolName = tsFile?.getExportSymbols()[0]?.getEscapedName(); + return { symbolName }; + }); +} - const themeRenderKindConstantsFile = path.join( +function writeBarrelsFile(resourceType: 'partials' | 'templates') { + const files = getFiles(resourceType).filter((file) => file !== 'index'); + const symbols = getSymbols(files, resourceType); + const barrelsFile = path.join( __dirname, '..', 'src', 'theme', - 'constants', - 'kinds.ts', + 'resources', + resourceType, + 'index.ts', ); - - const kinds = [ - { key: 'class', kind: ReflectionKind.Class }, - { key: 'constructor', kind: ReflectionKind.Constructor }, - { key: 'enum', kind: ReflectionKind.Enum }, - { key: 'enumMember', kind: ReflectionKind.EnumMember }, - { key: 'event', kind: undefined }, - { key: 'function', kind: ReflectionKind.Function }, - { key: 'interface', kind: ReflectionKind.Interface }, - { key: 'method', kind: ReflectionKind.Method }, - { key: 'module', kind: ReflectionKind.Module }, - { key: 'namespace', kind: ReflectionKind.Namespace }, - { key: 'variable', kind: ReflectionKind.Variable }, - { key: 'parameter', kind: ReflectionKind.Parameter }, - { key: 'property', kind: ReflectionKind.Property }, - { key: 'reference', kind: ReflectionKind.Reference }, - { key: 'typeAlias', kind: ReflectionKind.TypeAlias }, - { key: 'typeParameter', kind: ReflectionKind.TypeParameter }, - ]; - - const kindsString: string[] = []; - - const capitalize = (s: string) => s && s[0].toUpperCase() + s.slice(1); - - const singularString = (kind: any) => - kind.kind ? ReflectionKind.singularString(kind.kind) : capitalize(kind.key); - - const pluralString = (kind: any) => - kind.kind - ? ReflectionKind.pluralString(kind.kind) - : `${capitalize(kind.key)}s`; - - kindsString.push(` - export const KIND_DEFAULTS: Record = { - ${kinds - .map((kind) => { - return ` - 'kind.${kind.key}.singular':'${singularString(kind)}', - 'kind.${kind.key}.plural':'${pluralString(kind)}' - `; - }) - .join(',')} - } - `); - - kindsString.push(` - export const SINGULAR_KIND_KEY_MAP: Record = { - ${kinds - .map((kind) => { - return `['${singularString(kind)}']: 'kind.${kind.key}.singular'`; - }) - .join(',')} - } - `); - - kindsString.push(` - export const PLURAL_KIND_KEY_MAP: Record= { - ${kinds - .map((kind) => { - return `['${pluralString(kind)}']: 'kind.${kind.key}.plural'`; - }) - .join(',')} - } - `); - - const formattedKinds = await prettier.format(kindsString.join('\n'), { - parser: 'typescript', - singleQuote: true, - trailingComma: 'all', + const out: string[] = []; + files.forEach((file, index) => { + out.push(`export { ${symbols[index].symbolName} } from './${file}';`); }); + fs.writeFileSync(barrelsFile, out.join('\n')); +} - fs.writeFileSync(themeRenderKindConstantsFile, formattedKinds); - - // WRITE THEME CONTEXT - - const templateFiles = getFiles('templates').filter( - (file) => file !== 'index', - ); - const templateSymbols = [ - { symbolName: 'memberTemplate' }, - { symbolName: 'projectTemplate' }, - { symbolName: 'readmeTemplate' }, - { symbolName: 'reflectionTemplate' }, - ]; - - const partialsFiles = getFiles('partials').filter((file) => file !== 'index'); - const partialsSymbols = getSymbols(partialsFiles, 'partials'); - - const themeRenderContextFile = path.join( +async function writeResourcesFile() { + const resourcesFile = path.join( __dirname, '..', 'src', 'theme', - 'render-context.ts', + 'resources', + 'index.ts', ); - const importsOut: string[] = []; - const exportsOut: string[] = []; - - partialsFiles.forEach((file, index) => { - if (file !== 'index') { - importsOut.push( - `import { ${partialsSymbols[index].symbolName} } from './resources/partials/${file}';`, - ); - } - exportsOut.push(`export * from './${file}'`); - }); - - templateFiles.forEach((file, index) => { - if (file !== 'index') { - importsOut.push( - `import { ${templateSymbols[index].symbolName} } from './resources/templates/${file}';`, - ); - } - }); - - const resources: string[] = []; - - resources.push('\n// templates'); - templateSymbols.forEach((symbol) => { - resources.push('/** @hidden */'); - resources.push(`${symbol.symbolName} = bind(${symbol.symbolName}, this);`); - }); - - resources.push('\n// partials'); - partialsSymbols.forEach((symbol) => { - resources.push('/** @hidden */'); - resources.push(`${symbol.symbolName} = bind(${symbol.symbolName}, this);`); - }); - - const data = fs - .readFileSync(themeRenderContextFile) - ?.toString() - .replace( - /\/\* start_imports \*\/((.|\n)*)\/* end_imports \*\//g, - ` -/* start_imports */ -${importsOut.join('\n')} -/* end_imports */`, - ) - .replace( - /\/\* start_resources \*\/((.|\n)*)\/* end_resources \*\//g, - ` -/* start_resources */ -${resources.join('\n')} -/* end_resources */`, - ); - - const formatted = await prettier.format(data, { + const out = ` +import { MarkdownThemeRenderContext } from '../..'; +${getResourceImports('templates')} +${getResourceImports('partials')} +function bind(fn: (f: F, ...a: L) => R, first: F) { + return (...args: L) => fn(first, ...args); +} +${getResourceBinding('templates')} +${getResourceBinding('partials')} +`; + const formattedOut = await prettier.format(out, { parser: 'typescript', singleQuote: true, trailingComma: 'all', }); - - fs.writeFileSync(themeRenderContextFile, formatted); - - consola.success('[typedoc-plugin-markdown] Prebuild resources complete'); + fs.writeFileSync(resourcesFile, formattedOut); } -function getFiles(type: string) { - const partialsFolder = path.join(resourcesPath, type); - return fs - .readdirSync(partialsFolder) - .map((partialsFile) => path.parse(partialsFile).name); +function getResourceImports(resourceType: 'partials' | 'templates') { + const files = getFiles(resourceType).filter((file) => file !== 'index'); + const symbols = getSymbols(files, resourceType); + return ` + import { ${symbols + .map((symbol) => symbol.symbolName) + .join(', ')} } from './${resourceType}'; + `; } -function getSymbols(files: string[], type: string) { - return files.map((file) => { - const tsFile = project.getSourceFile( - path.join(resourcesPath, type, file + '.ts'), - ); - const symbolName = tsFile?.getExportSymbols()[0]?.getEscapedName(); - return { symbolName }; - }); +function getResourceBinding(resourceType: 'partials' | 'templates') { + const files = getFiles(resourceType).filter((file) => file !== 'index'); + const symbols = getSymbols(files, resourceType); + return ` + export const ${resourceType} = (context: MarkdownThemeRenderContext) => { + return { + ${symbols.map( + (symbol) => `${symbol.symbolName}: bind(${symbol.symbolName},context)`, + )} + }; + };`; } diff --git a/packages/typedoc-plugin-markdown/scripts/prebuild.ts b/packages/typedoc-plugin-markdown/scripts/prebuild.ts new file mode 100644 index 000000000..6da765879 --- /dev/null +++ b/packages/typedoc-plugin-markdown/scripts/prebuild.ts @@ -0,0 +1,11 @@ +import { consola } from 'consola'; +import { prebuildKinds } from './prebuild-kinds'; +import { prebuildResources } from './prebuild-resources'; + +main(); + +async function main() { + await prebuildKinds(); + await prebuildResources(); + consola.success('[typedoc-plugin-markdown] Prebuild code complete'); +} diff --git a/packages/typedoc-plugin-markdown/src/index.ts b/packages/typedoc-plugin-markdown/src/index.ts index 16ef31610..d86c541c0 100644 --- a/packages/typedoc-plugin-markdown/src/index.ts +++ b/packages/typedoc-plugin-markdown/src/index.ts @@ -1,9 +1,5 @@ /** * Exposes the public API of the plugin */ -export * from './options/maps'; -export { PluginOptions } from './options/models'; -export { load } from './plugin/bootstrap'; -export { MarkdownPageEvent, MarkdownRendererEvent } from './plugin/events'; -export { MarkdownTheme, MarkdownThemeRenderContext } from './theme'; -export { NavigationItem } from './theme/models'; +export * from './plugin'; +export * from './theme'; diff --git a/packages/typedoc-plugin-markdown/src/plugin/bootstrap.ts b/packages/typedoc-plugin-markdown/src/plugin/bootstrap.ts deleted file mode 100644 index 92ac29ca0..000000000 --- a/packages/typedoc-plugin-markdown/src/plugin/bootstrap.ts +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Exposes the {@link load} function that is called by TypeDoc to bootstrap the plugin. - * @module - */ - -import { - Application, - Context, - Converter, - DeclarationOption, - Renderer, - Theme, -} from 'typedoc'; -import * as options from '../options/declarations'; -import { MarkdownTheme } from '../theme'; -import { generateMarkdown, renderMarkdown } from './renderer'; - -/** - * - * The main plugin entrypoint containing all bootstrapping logic. - */ - -export function load(app: Application) { - /** - * add options - */ - Object.entries(options).forEach(([name, option]) => { - app.options.addDeclaration({ - name, - ...option, - } as DeclarationOption); - }); - - /** - * Apply custom renderer methods (there should probably be a better solution to this) - * See {@link plugin/renderer}. - */ - Object.defineProperty(app, 'generateDocs', { value: generateMarkdown }); - - Object.defineProperty(app.renderer, 'render', { - value: renderMarkdown, - }); - - Object.defineProperty(app.renderer, 'themes', { - value: new Map Theme>([ - ['default', MarkdownTheme], - ]), - }); - - app.converter.on(Converter.EVENT_RESOLVE_END, (context: Context) => { - if (app.options.packageDir) { - (app.renderer as any).packages = { - ...((app.renderer as any).packages || {}), - [context.project.name]: { dir: app.options.packageDir }, - }; - } - }); -} diff --git a/packages/typedoc-plugin-markdown/src/plugin/events.ts b/packages/typedoc-plugin-markdown/src/plugin/events.ts index 7a4589518..1ab9944f3 100644 --- a/packages/typedoc-plugin-markdown/src/plugin/events.ts +++ b/packages/typedoc-plugin-markdown/src/plugin/events.ts @@ -1,11 +1,11 @@ import * as path from 'path'; import { Event, ProjectReflection, Reflection } from 'typedoc'; -import { NavigationItem } from '../theme/models'; -import { RenderTemplate, UrlMapping } from './url-mapping'; +import { NavigationItem, RenderTemplate, UrlMapping } from '../theme'; /** * Extends the RendererEvent from TypeDoc to expose navigation property. */ + export class MarkdownRendererEvent extends Event { readonly project: ProjectReflection; diff --git a/packages/typedoc-plugin-markdown/src/plugin/index.ts b/packages/typedoc-plugin-markdown/src/plugin/index.ts new file mode 100644 index 000000000..e0448bccb --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/plugin/index.ts @@ -0,0 +1,106 @@ +import { + Application, + Context, + Converter, + DeclarationOption, + EventHooks, + Renderer, + Theme, +} from 'typedoc'; +import { MarkdownTheme } from '../theme'; +import * as declarations from './options/declarations'; +import { generateDocs, render } from './renderer'; +import { MarkdownRenderer, MarkdownRendererHooks } from './types'; + +/** + * + * The function that is called by TypeDoc to bootstrap the plugin. {@see https://typedoc.org/guides/development/#plugins} + * + * Here we expose additional TypeDoc options and make some adjustments. + * + */ +export function load(app: Application) { + /** + * ==================== + * 1. Bootstrap Options + * ==================== + */ + + /** + * Interate over declaration definitions and to the container. + */ + Object.entries(declarations).forEach(([name, declaration]) => { + app.options.addDeclaration({ + name, + ...declaration, + } as DeclarationOption); + }); + + /** + * ================================================= + * 2. Intercept and modify some TypeDoc core methods + * ================================================= + * + * Currently the TypeDoc {@link Renderer} class is quite coupled to the HTML theme so we override a couple of core methods. + * + * @todo Ideally there would be proper decoupling in the TypeDoc core between the {@link Application} and {@link Renderer} which requires further investigation. + * + */ + + /** + * Replace the default HTML theme the with the {@link MarkdownTheme} + */ + Object.defineProperty(app.renderer, 'themes', { + value: new Map Theme>([ + ['default', MarkdownTheme], + ]), + }); + + /** + * Replace TypeDoc's {@link app.generateDocs} method with our own {@link generateDocs} method. + */ + Object.defineProperty(app, 'generateDocs', { value: generateDocs }); + + /** + * Replace TypeDoc's {@link app.renderer.render} method with our own {@link render} method. + */ + Object.defineProperty(app.renderer, 'render', { + value: render, + }); + + /** + * Add a new {@link MarkdownRendererHooks} property to the {@link MarkdownRenderer} class. + * This is used to hook into the TypeDoc rendering system. + */ + Object.defineProperty(app.renderer, 'markdownHooks', { + value: new EventHooks(), + }); + + /** + * ============================ + * 3. Apply any other behaviour + * ============================ + */ + + /** + * Currently options set for packages are only stored on the converter and are destroyed before being passed to the {@link Renderer}. + * + * By intercepting the package options set in the converter and storing them on the renderer we can use them later in the theme. + * + * @todo Ideally this functionality would be available in TypeDoc core - to investigate. + */ + app.converter.on(Converter.EVENT_RESOLVE_END, (context: Context) => { + if (app.options.packageDir) { + const renderer = app.renderer as MarkdownRenderer; + renderer.packageOptions = { + ...(renderer.packageOptions || {}), + [context.project.name]: app.options, + }; + } + }); +} + +export * from './events'; +export * from './options/option-maps'; +export * from './options/option-types'; +export * from './types'; diff --git a/packages/typedoc-plugin-markdown/src/options/declarations.ts b/packages/typedoc-plugin-markdown/src/plugin/options/declarations.ts similarity index 92% rename from packages/typedoc-plugin-markdown/src/options/declarations.ts rename to packages/typedoc-plugin-markdown/src/plugin/options/declarations.ts index 7d412d258..60003497c 100644 --- a/packages/typedoc-plugin-markdown/src/options/declarations.ts +++ b/packages/typedoc-plugin-markdown/src/plugin/options/declarations.ts @@ -1,5 +1,6 @@ import { DeclarationOption, ParameterType } from 'typedoc'; -import { FormatStyle, OutputFileStrategy, StaticText } from './maps'; +import { FormatStyle, OutputFileStrategy } from './option-maps'; +import { TEXT_MAPPING_DEFAULTS } from './text-mappings/text-mapping-defaults'; /** * @@ -276,15 +277,31 @@ export const indexFormat: Partial = { export const textContentMappings: Partial = { help: 'Provides a mechanism to change the content of text used in documentation.', type: ParameterType.Mixed, - defaultValue: StaticText, + defaultValue: TEXT_MAPPING_DEFAULTS, validate(value) { if (!value || typeof value !== 'object') { - throw new Error('textContentMappings must be an object.'); + throw new Error( + '[typedoc-plugin-markdown] textContentMappings must be an object.', + ); } for (const val of Object.values(value)) { if (typeof val !== 'string') { - throw new Error(`All values of textContentMappings must be strings.`); + throw new Error( + `[typedoc-plugin-markdown] All values of textContentMappings must be strings.`, + ); + } + } + + for (const key of Object.keys(value)) { + if (!Object.keys(TEXT_MAPPING_DEFAULTS).includes(key)) { + throw new Error( + `[typedoc-plugin-markdown] "${key}" is not a valid "textContentMappings" key. Valid keys are ${Object.keys( + TEXT_MAPPING_DEFAULTS, + ) + .map((key) => `"${key}"`) + .join(', ')}.`, + ); } } }, diff --git a/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts b/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts new file mode 100644 index 000000000..9b1bd5bb7 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/plugin/options/option-maps.ts @@ -0,0 +1,24 @@ +/** + * Defines outputFileStrategy model for the `outputFileStrategy` option. + * + * @enum + * + */ +export const OutputFileStrategy = { + Members: 'members', + Modules: 'modules', +} as const; + +export type OutputFileStrategy = + (typeof OutputFileStrategy)[keyof typeof OutputFileStrategy]; + +/** + * + * @enum + */ +export const FormatStyle = { + List: 'list', + Table: 'table', +} as const; + +export type FormatStyle = (typeof FormatStyle)[keyof typeof FormatStyle]; diff --git a/packages/typedoc-plugin-markdown/src/options/models.ts b/packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts similarity index 100% rename from packages/typedoc-plugin-markdown/src/options/models.ts rename to packages/typedoc-plugin-markdown/src/plugin/options/option-types.ts diff --git a/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/index.ts b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/index.ts new file mode 100644 index 000000000..1341a68ae --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/index.ts @@ -0,0 +1,2 @@ +export * from './kind-defaults'; +export * from './text-mapping-defaults'; diff --git a/packages/typedoc-plugin-markdown/src/theme/constants/kinds.ts b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/kind-defaults.ts similarity index 98% rename from packages/typedoc-plugin-markdown/src/theme/constants/kinds.ts rename to packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/kind-defaults.ts index f92075a30..c57c62bcb 100644 --- a/packages/typedoc-plugin-markdown/src/theme/constants/kinds.ts +++ b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/kind-defaults.ts @@ -1,3 +1,5 @@ +// THIS FILE IS AUTOGENERATED - DO NOT EDIT DIRECTLY + export const KIND_DEFAULTS: Record = { 'kind.class.singular': 'Class', 'kind.class.plural': 'Classes', diff --git a/packages/typedoc-plugin-markdown/src/options/maps.ts b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/text-mapping-defaults.ts similarity index 58% rename from packages/typedoc-plugin-markdown/src/options/maps.ts rename to packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/text-mapping-defaults.ts index 2d19a73c9..7b4f5c064 100644 --- a/packages/typedoc-plugin-markdown/src/options/maps.ts +++ b/packages/typedoc-plugin-markdown/src/plugin/options/text-mappings/text-mapping-defaults.ts @@ -1,31 +1,6 @@ -import { KIND_DEFAULTS } from '../theme/constants/kinds'; +import { KIND_DEFAULTS } from './kind-defaults'; -/** - * Defines outputFileStrategy model for the `outputFileStrategy` option. - * - * @enum - * - */ -export const OutputFileStrategy = { - Members: 'members', - Modules: 'modules', -} as const; - -export type OutputFileStrategy = - (typeof OutputFileStrategy)[keyof typeof OutputFileStrategy]; - -/** - * - * @enum - */ -export const FormatStyle = { - List: 'list', - Table: 'table', -} as const; - -export type FormatStyle = (typeof FormatStyle)[keyof typeof FormatStyle]; - -export const StaticText = { +export const TEXT_MAPPING_DEFAULTS = { 'header.title': '{projectName} {version}', 'header.readme': 'Readme', 'header.docs': 'API', @@ -59,12 +34,3 @@ export const StaticText = { 'label.value': 'Value', ...KIND_DEFAULTS, }; - -/*export const MembersWithOwnFile = [ - ReflectionKind[ReflectionKind.Enum], - ReflectionKind[ReflectionKind.Variable], - ReflectionKind[ReflectionKind.Function], - ReflectionKind[ReflectionKind.Class], - ReflectionKind[ReflectionKind.Interface], - ReflectionKind[ReflectionKind.TypeAlias], -];*/ diff --git a/packages/typedoc-plugin-markdown/src/plugin/renderer.ts b/packages/typedoc-plugin-markdown/src/plugin/renderer.ts index ca65c603d..d6bc3b5cf 100644 --- a/packages/typedoc-plugin-markdown/src/plugin/renderer.ts +++ b/packages/typedoc-plugin-markdown/src/plugin/renderer.ts @@ -1,51 +1,52 @@ -/** - * Contains functionality to decouple HTML logic from the TypeDoc [Renderer](https://typedoc.org/api/classes/Renderer.html). - * @module - */ - import * as fs from 'fs'; -import * as path from 'path'; import { + Application, DeclarationReflection, - Options, ProjectReflection, Reflection, + Renderer, } from 'typedoc'; -import { formatContents } from '../support/utils'; import { MarkdownPageEvent, MarkdownRendererEvent } from './events'; +import { nicePath, writeFileSync } from './utils'; /** - * Replacement of TypeDoc's [Application.generateDocs](https://typedoc.org/api/classes/Application.html#generateDocs) to decouple HTML logic. + * Contains functionality to decouple HTML logic from the TypeDoc's {@link Renderer}. + * + * @todo Investigate ways to properly decouple HTML logic from the TypeDoc renderer. * + * @module */ -export async function generateMarkdown( - project: ProjectReflection, - out: string, -) { - const start = Date.now(); +/** + * Replacement of TypeDoc's {@link Application.generateDocs} method to decouple HTML logic. + * + */ +export async function generateDocs(project: ProjectReflection, out: string) { + const start = Date.now(); await this.renderer.render(project, out); - if (this.logger.hasErrors()) { this.logger.error( 'Documentation could not be generated due to the errors above.', ); } else { this.logger.info(`Documentation generated at ${nicePath(out)}`); - this.logger.verbose(`Markdown rendering took ${Date.now() - start}ms`); } } /** - * Replacement of TypeDoc's [Renderer.render](https://typedoc.org/api/classes/Renderer.html#render) to decouple HTML logic. - * - Removes uneccessary async calls to load highlighters - * - Removes hooks logic + * Replacement of TypeDoc's {@link Renderer.render} method to decouple HTML logic. + * + * This is essentially a copy of the base method with a few tweaks. + * + * - Removes uneccessary async calls to load highlighters only required for html theme. + * - Removes hooks logic that are jsx specific. + * - Adds any logic specific to markdown rendering. */ -export async function renderMarkdown( +export async function render( project: ProjectReflection, outputDirectory: string, -): Promise { +) { this.renderStartTime = Date.now(); if (this.cleanOutputDir) { @@ -66,20 +67,6 @@ export async function renderMarkdown( return; } - if (this.githubPages) { - try { - const text = - 'TypeDoc added this file to prevent GitHub Pages from ' + - 'using Jekyll. You can turn off this behavior by setting ' + - 'the `githubPages` option to false.'; - - fs.writeFileSync(path.join(outputDirectory, '.nojekyll'), text); - } catch (error) { - this.application.warn('Could not create .nojekyll file.'); - return; - } - } - this.prepareTheme(); const output = new MarkdownRendererEvent( @@ -88,30 +75,11 @@ export async function renderMarkdown( project, ); - if (this.packages) { - const getOptionsForPackage = new Promise((resolve, reject) => { - const packages = {}; - Object.entries(this.packages).forEach(async ([k, v]) => { - packages[k] = {}; - const origOptions = this.application.options; - const packageOptions: Options = origOptions.copyForPackage( - (v as any).dir, - ); - await packageOptions.read(this.application.logger, (v as any).dir); - const isSet = packageOptions.isSet('outputFileStrategy'); - packages[k].outputFileStrategy = isSet - ? packageOptions.getValue('outputFileStrategy') - : null; - resolve(packages); - }); - }); - - this.packages = await getOptionsForPackage; - } - output.urls = this.theme!.getUrls(project); output.navigation = this.theme!.getNavigation(project); + this.trigger(output); + await Promise.all(this.preRenderAsyncJobs.map((job) => job(output))); this.preRenderAsyncJobs = []; @@ -147,7 +115,7 @@ export async function renderMarkdown( } try { - writeFileSync(page.filename, formatContents(page.contents as string)); + writeFileSync(page.filename, page.contents as string); } catch (error) { this.application.logger.error(`Could not write ${page.filename}`); } @@ -161,22 +129,3 @@ export async function renderMarkdown( this.theme = void 0; } - -function writeFileSync(fileName: string, data: string) { - fs.mkdirSync(path.dirname(normalizePath(fileName)), { recursive: true }); - fs.writeFileSync(normalizePath(fileName), data); -} - -function normalizePath(path: string) { - return path.replace(/\\/g, '/'); -} - -function nicePath(absPath: string) { - if (!path.isAbsolute(absPath)) return absPath; - - const relativePath = path.relative(process.cwd(), absPath); - if (relativePath.startsWith('..')) { - return normalizePath(absPath); - } - return `./${normalizePath(relativePath)}`; -} diff --git a/packages/typedoc-plugin-markdown/src/plugin/types.ts b/packages/typedoc-plugin-markdown/src/plugin/types.ts new file mode 100644 index 000000000..9fc701040 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/plugin/types.ts @@ -0,0 +1,42 @@ +import { Application, EventHooks, Options, Renderer } from 'typedoc'; +import { MarkdownThemeRenderContext } from '../theme'; +import { MarkdownRendererEvent } from './events'; + +/** + * The plugin amends the renderer with additional hooks and options. + * + * This interface augments the TypeDoc {@link Application} with the updated renderer. + */ +export interface MarkdownApplication extends Application { + renderer: MarkdownRenderer; +} + +/** + * The plugin amends the renderer with additional hooks and options. + */ +export interface MarkdownRenderer extends Renderer { + markdownHooks: EventHooks; + packageOptions: Record; + preRenderAsyncJobs: Array<(output: MarkdownRendererEvent) => Promise>; + postRenderAsyncJobs: Array<(output: MarkdownRendererEvent) => Promise>; +} + +/** + * This is the custom render hooks method based on the equivalent TypeDoc class. + */ +export interface MarkdownRendererHooks { + /** + * Applied at the start of the markdown output. + */ + 'page.begin': [MarkdownThemeRenderContext]; + + /** + * Applied at the end of the markdown output. + */ + 'page.end': [MarkdownThemeRenderContext]; + + /** + * Applied before the main markdown content is rendered. + */ + 'content.begin': [MarkdownThemeRenderContext]; +} diff --git a/packages/typedoc-plugin-markdown/src/plugin/url-mapping.ts b/packages/typedoc-plugin-markdown/src/plugin/url-mapping.ts deleted file mode 100644 index deae9d388..000000000 --- a/packages/typedoc-plugin-markdown/src/plugin/url-mapping.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { MarkdownPageEvent } from './events'; - -export class UrlMapping { - url: string; - - model: Model; - - template: RenderTemplate>; - - constructor( - url: string, - model: Model, - template: RenderTemplate>, - ) { - this.url = url; - this.model = model; - this.template = template; - } -} - -export type RenderTemplate = (data: T) => string; diff --git a/packages/typedoc-plugin-markdown/src/plugin/utils.ts b/packages/typedoc-plugin-markdown/src/plugin/utils.ts new file mode 100644 index 000000000..411fd7fbc --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/plugin/utils.ts @@ -0,0 +1,38 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * Some useful utility functions - essentially cherry picked from: + * + * - https://github.com/TypeStrong/typedoc/blob/master/src/lib/utils/fs.ts + * - https://github.com/TypeStrong/typedoc/blob/master/src/lib/utils/path.ts + * + * @module + */ + +/** + * Writes a file to disc. + */ +export function writeFileSync(fileName: string, data: string) { + fs.mkdirSync(path.dirname(normalizePath(fileName)), { recursive: true }); + fs.writeFileSync(normalizePath(fileName), data); +} + +/** + * Returns a readable path from an absolute path. + */ +export function nicePath(absPath: string) { + if (!path.isAbsolute(absPath)) return absPath; + const relativePath = path.relative(process.cwd(), absPath); + if (relativePath.startsWith('..')) { + return normalizePath(absPath); + } + return `./${normalizePath(relativePath)}`; +} + +/** + * Normalizes directory seperators from a given path. + */ +export function normalizePath(path: string) { + return path.replace(/\\/g, '/'); +} diff --git a/packages/typedoc-plugin-markdown/src/support/elements.ts b/packages/typedoc-plugin-markdown/src/support/elements.ts deleted file mode 100644 index d360f65d0..000000000 --- a/packages/typedoc-plugin-markdown/src/support/elements.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** - * A set of pure functions that returns markdown elements as strings. - * - * @module - * - */ - -import { formatContents, trimLastLine, unEscapeChars } from './utils'; - -export const heading = (level: number, text: string) => { - level = level > 6 ? 6 : level; - return `${[...Array(level)].map(() => '#').join('')} ${text}`; -}; - -export const link = (label: string, url: string | null) => - url ? `[${label}](${url})` : ''; - -export const bold = (text: string) => `**${text}**`; - -export const italic = (text: string) => `*${text}*`; - -export const backTicks = (text: string) => - /(\`)/g.test(text) ? text.replace(/`/g, '\\`') : `\`${text}\``; - -export const unorderedList = (items: T[]) => - items.map((item) => `- ${item}`).join('\n'); - -export const horizontalRule = () => '\n\n***\n\n'; - -export const codeBlock = (content: string) => { - const trimmedContent = - content.endsWith('}') || - content.endsWith('};') || - content.endsWith('>') || - content.endsWith('>;') - ? trimLastLine(content) - : content; - return '```ts\n' + unEscapeChars(trimmedContent) + '\n```'; -}; - -export const strikeThrough = (content: string) => `~~${content}~~`; - -export const table = (headers: string[], rows: string[][]) => - `\n| ${headers.join(' | ')} |\n| ${headers - .map(() => ':------') - .join(' | ')} |\n${rows.map((row) => `| ${row.join(' | ')} |\n`).join('')}`; - -export const blockQuoteBlock = (content: string) => { - const lines = formatContents(content).split('\n'); - return lines - .map((line) => (line.length ? `> ${line.trim()}` : '>')) - .join('\n'); -}; - -export const indentBlock = (content: string) => { - const lines = content.split('\n'); - return lines - .filter((line) => Boolean(line.length)) - .map((line) => ` ${line}`) - .join('\n'); -}; diff --git a/packages/typedoc-plugin-markdown/src/support/utils.ts b/packages/typedoc-plugin-markdown/src/support/utils.ts deleted file mode 100644 index 52dd197ca..000000000 --- a/packages/typedoc-plugin-markdown/src/support/utils.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * A set of pure utils to be consumed accross the plugin. - * - * @module - */ - -export function escapeChars(str: string) { - return str - .replace(/>/g, '\\>') - .replace(//gi; - return str.replace(re, (tags) => { - const htmlRe = - /<(?!\/?(div|span|p|a|br|img|ul|li|strike|em|strong|b)(>|\s))[^<]+?>/g; - const shouldEscape = tags.match(htmlRe); - return shouldEscape ? tags.replace(/>/g, '>` ').replace(/ (index === lines.length - 1 ? line.trim() : line)) - .join('\n'); -} - -export function unEscapeChars(str: string) { - return str - .replace(/\\/g, '>') - .replace(/\\_/g, '_') - .replace(/\\{/g, '{') - .replace(/`/g, '') - .replace(/\*\*/g, '') - .replace(/\\\|/g, '|') - .replace(/\\\]/g, ']') - .replace(/\\\[/g, '[') - .replace(/\[([^\[\]]*)\]\((.*?)\)/gm, '$1'); -} - -export function stripComments(str: string) { - return str - .replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:^\s*\/\/(?:.*)$)/g, ' ') - .replace(/\n/g, '') - .replace(/^\s+|\s+$|(\s)+/g, '$1'); -} - -export function formatTableDescriptionCol(str: string) { - return str.replace(/\|/g, '\\|'); -} - -export function formatTableNameCol(str: string) { - return str.includes('|') ? str.replace(/\|/g, '\\|') : `\`${str}\``; -} - -export function stripLineBreaks(str: string, includeHTML = true) { - return str - .replace(/\n(?=(?:[^`]*`[^`]*`)*[^`]*$)/gi, includeHTML ? '
' : ' ') - .replace(/\`\`\`ts/g, '`') - .replace(/\`\`\`/g, '`') - .replace(/\n/g, ' '); -} - -export function camelToTitleCase(text: string) { - return ( - text.substring(0, 1).toUpperCase() + - text.substring(1).replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`) - ); -} - -export function slugify(str: string) { - return str - .trim() - .replace(/[^\w\s-]/g, '') - .replace(/[\s_-]+/g, '-') - .replace(/^-+|-+$/g, ''); -} - -export function formatContents(contents: string) { - return ( - contents.replace(/[\r\n]{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '') + '\n' - ); -} diff --git a/packages/typedoc-plugin-markdown/src/theme/helpers.ts b/packages/typedoc-plugin-markdown/src/theme/helpers.ts deleted file mode 100644 index 6cc1d43e5..000000000 --- a/packages/typedoc-plugin-markdown/src/theme/helpers.ts +++ /dev/null @@ -1,263 +0,0 @@ -/** - * - * A set of helpers that parses TypeDoc models to be consumed by theme resources. - * - * @module - */ - -import { - DeclarationReflection, - ParameterReflection, - ProjectReflection, - ReflectionKind, - SignatureReflection, -} from 'typedoc'; -import { backTicks, strikeThrough } from '../support/elements'; -import { escapeChars } from '../support/utils'; - -export function getDeclarationType(declaration: DeclarationReflection) { - if (declaration.signatures) { - return declaration.signatures[0].type; - } - if (declaration.getSignature) { - return declaration.getSignature.type; - } - if (declaration.setSignature) { - return declaration.setSignature.type; - } - return declaration.type; -} - -export function getProjectDisplayName( - project: ProjectReflection, - includeVersion: boolean, -): string { - const version = - includeVersion && project.packageVersion - ? ` v${project.packageVersion}` - : ''; - return `${project.name}${version ? version : ''}`; -} - -export function hasIndex( - reflection: DeclarationReflection | ProjectReflection, -) { - return reflection.groups?.some((group) => group.allChildrenHaveOwnDocument()); -} - -export function isAbsoluteIndex( - reflection: DeclarationReflection | ProjectReflection, -) { - return reflection.groups?.every((group) => - group.allChildrenHaveOwnDocument(), - ); -} - -export function isGroupKind( - reflection: DeclarationReflection | SignatureReflection, -) { - const groupKinds = [ - ReflectionKind.Class, - ReflectionKind.Interface, - ReflectionKind.Enum, - ReflectionKind.Function, - ReflectionKind.Variable, - ReflectionKind.TypeAlias, - ]; - return groupKinds.includes(reflection.kind); -} - -export function getModifier(reflection: DeclarationReflection) { - if (reflection.flags.isAbstract) { - return 'abstract'; - } - if (reflection.flags.isPrivate) { - return 'private'; - } - if (reflection.flags.isReadonly) { - return 'readonly'; - } - if (reflection.flags.isStatic) { - return 'static'; - } - if (reflection.flags.isProtected) { - return 'protected'; - } - if (reflection.flags.isPublic) { - return 'public'; - } - if (reflection.getSignature) { - return 'get'; - } - if (reflection.setSignature) { - return 'set'; - } - return null; -} - -export const KEYWORD_MAP = { - [ReflectionKind.Class]: 'class', - [ReflectionKind.Interface]: 'interface', - [ReflectionKind.Enum]: 'enum', - [ReflectionKind.TypeAlias]: 'type', - [ReflectionKind.Function]: 'function', -}; - -export function getMemberTitle(reflection: DeclarationReflection) { - const md: string[] = []; - - const name: string[] = []; - - if ( - reflection?.kind === ReflectionKind.Class && - reflection?.flags?.includes('Abstract') - ) { - name.push(backTicks('abstract') + ' '); - } - - name.push( - `${ - reflection.name.startsWith('[') && reflection.signatures?.length - ? backTicks(reflection.name) - : escapeChars(reflection.name) - }`, - ); - - if (reflection.signatures?.length) { - name.push('()'); - } - - if (reflection.typeParameters) { - const typeParameters = reflection.typeParameters - .map((typeParameter) => typeParameter.name) - .join(', '); - name.push(`${`\\<${typeParameters}\\>`}`); - } - - if (reflection.flags.isOptional) { - name.push('?'); - } - - if (reflection.isDeprecated && reflection.isDeprecated()) { - md.push(strikeThrough(name.join(''))); - } else { - md.push(name.join('')); - } - - return md.join(': '); -} - -export function flattenDeclarations( - props: DeclarationReflection[], - includeSignatures = false, -) { - const flattenDeclarations = (current: DeclarationReflection) => { - return (current.type as any)?.declaration?.children?.reduce( - (acc: DeclarationReflection[], child: DeclarationReflection) => { - const childObj = { - ...child, - name: `${current.name}.${child.name}`, - } as DeclarationReflection; - return parseDeclarations(childObj, acc); - }, - [], - ); - }; - - const parseDeclarations = ( - current: DeclarationReflection, - acc: DeclarationReflection[], - ) => { - const shouldFlatten = (current.type as any)?.declaration?.children; - const isAccessor = current.kind === ReflectionKind.Accessor; - - if (includeSignatures) { - if (isAccessor) { - const accessors: any[] = []; - if (current.getSignature) { - accessors.push({ - ...current, - name: `get ${current.name}`, - type: current.getSignature.type, - comment: current.getSignature?.comment, - }); - } - if (current.setSignature) { - accessors.push({ - ...current, - name: `set ${current.name}`, - type: current.setSignature.type, - comment: current.setSignature?.comment, - }); - } - return [...acc, ...accessors]; - } - - if (current.signatures?.length) { - const signatures = current.signatures.map((signature) => { - return { - ...current, - name: signature.name, - type: signature.type, - comment: signature.comment, - }; - }); - return [...acc, ...signatures]; - } - } - - return shouldFlatten - ? [...acc, current, ...flattenDeclarations(current)] - : [...acc, current]; - }; - - return props.reduce( - (acc: DeclarationReflection[], current: DeclarationReflection) => - parseDeclarations(current, acc), - [], - ); -} - -export function getSignatureParameters( - parameters: ParameterReflection[], - format = false, -) { - const firstOptionalParamIndex = parameters.findIndex( - (parameter) => parameter.flags.isOptional, - ); - return ( - '(' + - parameters - .map((param, i) => { - const paramsmd: string[] = []; - if (param.flags.isRest) { - paramsmd.push('...'); - } - const paramItem = `${backTicks(param.name)}${ - param.flags.isOptional || - (firstOptionalParamIndex !== -1 && i > firstOptionalParamIndex) - ? '?' - : '' - }`; - paramsmd.push( - `${format && parameters.length > 2 ? `\n ` : ''}${paramItem}`, - ); - return paramsmd.join(''); - }) - .join(`, `) + - ')' - ); -} - -export function getIndexFileName( - reflection: ProjectReflection | DeclarationReflection, - isPackages = false, -) { - if (isPackages) { - return 'packages.md'; - } - const isModules = reflection.children?.every((child) => - child.kindOf(ReflectionKind.Module), - ); - return isModules ? 'modules.md' : 'globals.md'; -} diff --git a/packages/typedoc-plugin-markdown/src/theme/index.ts b/packages/typedoc-plugin-markdown/src/theme/index.ts index f0cc7eb36..4f1960cc8 100644 --- a/packages/typedoc-plugin-markdown/src/theme/index.ts +++ b/packages/typedoc-plugin-markdown/src/theme/index.ts @@ -1,9 +1,8 @@ /** * * The in-built custom theme and context theme definitions that the plugin initiates. - * - * @module */ - -export * from './render-context'; -export * from './theme'; +export { NavigationItem } from './support/support.navigation'; +export { RenderTemplate, UrlMapping } from './support/support.urls'; +export { MarkdownTheme } from './theme'; +export { MarkdownThemeRenderContext } from './theme-render-context'; diff --git a/packages/typedoc-plugin-markdown/src/theme/models.ts b/packages/typedoc-plugin-markdown/src/theme/models.ts deleted file mode 100644 index 93d71cce3..000000000 --- a/packages/typedoc-plugin-markdown/src/theme/models.ts +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Interfaces used by the theme. - * - * @module - */ - -import { ReflectionKind } from 'typedoc'; -import { OutputFileStrategy } from '../options/maps'; - -export interface UrlOption { - parentUrl?: string; - directory?: string | null; - forceDirectory?: boolean; - outputFileStrategy?: OutputFileStrategy; -} - -export interface TemplateMapping { - directory: string | null; - template: any; - kind: ReflectionKind; -} - -export interface NavigationItem { - title: string; - url?: string; - children?: NavigationItem[]; - isReadme?: boolean; - isGroup?: boolean; -} diff --git a/packages/typedoc-plugin-markdown/src/theme/render-context.ts b/packages/typedoc-plugin-markdown/src/theme/render-context.ts deleted file mode 100644 index 8bfdbd93d..000000000 --- a/packages/typedoc-plugin-markdown/src/theme/render-context.ts +++ /dev/null @@ -1,251 +0,0 @@ -import * as path from 'path'; -import { Options, Reflection, ReflectionKind } from 'typedoc'; -import { TextContentMappings } from '../options/models'; -import { MarkdownPageEvent } from '../plugin/events'; -import { PLURAL_KIND_KEY_MAP, SINGULAR_KIND_KEY_MAP } from './constants/kinds'; -import { MarkdownTheme } from './theme'; - -/* start_imports */ -import { breadcrumbs } from './resources/partials/breadcrumbs'; -import { commentParts } from './resources/partials/comment.parts'; -import { comment } from './resources/partials/comment'; -import { footer } from './resources/partials/footer'; -import { header } from './resources/partials/header'; -import { pageIndex } from './resources/partials/index.page'; -import { reflectionIndex } from './resources/partials/index.reflection'; -import { parametersList } from './resources/partials/list.parameters'; -import { typeParametersList } from './resources/partials/list.typeparameters'; -import { accessorMember } from './resources/partials/member.accessor'; -import { constructorMember } from './resources/partials/member.constructors'; -import { declarationMemberIdentifier } from './resources/partials/member.declaration.identifier'; -import { declarationMember } from './resources/partials/member.declaration'; -import { memberHierarchy } from './resources/partials/member.hierarchy'; -import { indexSignatureTitle } from './resources/partials/member.indexsignature.title'; -import { inheritance } from './resources/partials/member.inheritance'; -import { referenceMember } from './resources/partials/member.reference'; -import { reflectionMember } from './resources/partials/member.reflection'; -import { signatureMemberIdentifier } from './resources/partials/member.signature.identifier'; -import { signatureMemberReturns } from './resources/partials/member.signature.returns'; -import { signatureMember } from './resources/partials/member.signature'; -import { sources } from './resources/partials/member.sources'; -import { member } from './resources/partials/member'; -import { typeDeclarationMember } from './resources/partials/member.type-declaration'; -import { members } from './resources/partials/members'; -import { pageTitle } from './resources/partials/page.title'; -import { enumMembersTable } from './resources/partials/table.enum-members'; -import { parametersTable } from './resources/partials/table.parameters'; -import { propertiesTable } from './resources/partials/table.properties'; -import { typeDeclarationTable } from './resources/partials/table.type-declaration'; -import { typeParametersTable } from './resources/partials/table.typeparameters'; -import { typeArguments } from './resources/partials/type-argumentsts'; -import { arrayType } from './resources/partials/type.array'; -import { conditionalType } from './resources/partials/type.conditional'; -import { declarationType } from './resources/partials/type.declaration'; -import { functionType } from './resources/partials/type.function'; -import { indexAccessType } from './resources/partials/type.index-access'; -import { inferredType } from './resources/partials/type.inferred'; -import { intersectionType } from './resources/partials/type.intersection'; -import { intrinsicType } from './resources/partials/type.intrinsic'; -import { literalType } from './resources/partials/type.literal'; -import { namedTupleType } from './resources/partials/type.named-tuple'; -import { queryType } from './resources/partials/type.query'; -import { referenceType } from './resources/partials/type.reference'; -import { reflectionType } from './resources/partials/type.reflection'; -import { someType } from './resources/partials/type.some'; -import { tupleType } from './resources/partials/type.tuple'; -import { typeOperatorType } from './resources/partials/type.type-operator'; -import { unionType } from './resources/partials/type.union'; -import { unknownType } from './resources/partials/type.unknown'; -import { memberTemplate } from './resources/templates/member'; -import { projectTemplate } from './resources/templates/project'; -import { readmeTemplate } from './resources/templates/read-me'; -import { reflectionTemplate } from './resources/templates/reflection'; -/* end_imports */ - -function bind(fn: (f: F, ...a: L) => R, first: F) { - return (...r: L) => fn(first, ...r); -} - -/** - * The render context of the {@link MarkdownTheme}. - * This follows the implementation of TypeDocs [DefaultThemeRenderContext](https://typedoc.org/api/classes/DefaultThemeRenderContext.html) - */ -export class MarkdownThemeRenderContext { - constructor( - private theme: MarkdownTheme, - public page: MarkdownPageEvent | null, - public options: Options, - ) {} - - urlTo = (reflection: Reflection) => { - return this.relativeURL(reflection.url); - }; - - relativeURL = (url: string | undefined) => { - const URL_PREFIX = /^(http|ftp)s?:\/\//; - if (!url) { - return null; - } - if (URL_PREFIX.test(url)) { - return url; - } else { - const publicPath = this.options.getValue('publicPath'); - - if (publicPath) { - return path.join(publicPath, url); - } - - const relative = path.relative( - path.dirname(this.page?.url || '.'), - path.dirname(url), - ); - return this.parseUrl( - path.join(relative, path.basename(url)).replace(/\\/g, '/'), - ); - } - }; - - getTextContent(key: keyof TextContentMappings) { - return this.theme.textMappings[key]; - } - - groupTitle(title: string) { - const key = PLURAL_KIND_KEY_MAP[title] as keyof TextContentMappings; - return this.getTextContent(key) || title; - } - - kindString(kind: ReflectionKind) { - const singularString = ReflectionKind.singularString(kind); - const key = SINGULAR_KIND_KEY_MAP[ - singularString - ] as keyof TextContentMappings; - return this.getTextContent(key) || singularString; - } - - indexTitle(textContent: string, name: string, version?: string) { - return textContent - .replace('{projectName}', name) - .replace('{version}', version ? `v${version}` : '') - .replace(/\s+/g, ' ') - .trim(); - } - - parseUrl(url: string) { - return encodeURI(url); - } - - /* start_resources */ - - // templates - /** @hidden */ - memberTemplate = bind(memberTemplate, this); - /** @hidden */ - projectTemplate = bind(projectTemplate, this); - /** @hidden */ - readmeTemplate = bind(readmeTemplate, this); - /** @hidden */ - reflectionTemplate = bind(reflectionTemplate, this); - - // partials - /** @hidden */ - breadcrumbs = bind(breadcrumbs, this); - /** @hidden */ - commentParts = bind(commentParts, this); - /** @hidden */ - comment = bind(comment, this); - /** @hidden */ - footer = bind(footer, this); - /** @hidden */ - header = bind(header, this); - /** @hidden */ - pageIndex = bind(pageIndex, this); - /** @hidden */ - reflectionIndex = bind(reflectionIndex, this); - /** @hidden */ - parametersList = bind(parametersList, this); - /** @hidden */ - typeParametersList = bind(typeParametersList, this); - /** @hidden */ - accessorMember = bind(accessorMember, this); - /** @hidden */ - constructorMember = bind(constructorMember, this); - /** @hidden */ - declarationMemberIdentifier = bind(declarationMemberIdentifier, this); - /** @hidden */ - declarationMember = bind(declarationMember, this); - /** @hidden */ - memberHierarchy = bind(memberHierarchy, this); - /** @hidden */ - indexSignatureTitle = bind(indexSignatureTitle, this); - /** @hidden */ - inheritance = bind(inheritance, this); - /** @hidden */ - referenceMember = bind(referenceMember, this); - /** @hidden */ - reflectionMember = bind(reflectionMember, this); - /** @hidden */ - signatureMemberIdentifier = bind(signatureMemberIdentifier, this); - /** @hidden */ - signatureMemberReturns = bind(signatureMemberReturns, this); - /** @hidden */ - signatureMember = bind(signatureMember, this); - /** @hidden */ - sources = bind(sources, this); - /** @hidden */ - member = bind(member, this); - /** @hidden */ - typeDeclarationMember = bind(typeDeclarationMember, this); - /** @hidden */ - members = bind(members, this); - /** @hidden */ - pageTitle = bind(pageTitle, this); - /** @hidden */ - enumMembersTable = bind(enumMembersTable, this); - /** @hidden */ - parametersTable = bind(parametersTable, this); - /** @hidden */ - propertiesTable = bind(propertiesTable, this); - /** @hidden */ - typeDeclarationTable = bind(typeDeclarationTable, this); - /** @hidden */ - typeParametersTable = bind(typeParametersTable, this); - /** @hidden */ - typeArguments = bind(typeArguments, this); - /** @hidden */ - arrayType = bind(arrayType, this); - /** @hidden */ - conditionalType = bind(conditionalType, this); - /** @hidden */ - declarationType = bind(declarationType, this); - /** @hidden */ - functionType = bind(functionType, this); - /** @hidden */ - indexAccessType = bind(indexAccessType, this); - /** @hidden */ - inferredType = bind(inferredType, this); - /** @hidden */ - intersectionType = bind(intersectionType, this); - /** @hidden */ - intrinsicType = bind(intrinsicType, this); - /** @hidden */ - literalType = bind(literalType, this); - /** @hidden */ - namedTupleType = bind(namedTupleType, this); - /** @hidden */ - queryType = bind(queryType, this); - /** @hidden */ - referenceType = bind(referenceType, this); - /** @hidden */ - reflectionType = bind(reflectionType, this); - /** @hidden */ - someType = bind(someType, this); - /** @hidden */ - tupleType = bind(tupleType, this); - /** @hidden */ - typeOperatorType = bind(typeOperatorType, this); - /** @hidden */ - unionType = bind(unionType, this); - /** @hidden */ - unknownType = bind(unknownType, this); - /* end_resources */ -} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/index.ts b/packages/typedoc-plugin-markdown/src/theme/resources/index.ts index 39bba396f..1d1a4bc79 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/index.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/index.ts @@ -1,6 +1,135 @@ -/** - * Contains templates and partials used when generating output. - * - * @module - */ -export * from '../helpers'; +import { MarkdownThemeRenderContext } from '../..'; + +import { + memberTemplate, + projectTemplate, + readmeTemplate, + reflectionTemplate, +} from './templates'; + +import { + breadcrumbs, + commentParts, + comment, + generator, + header, + pageIndex, + reflectionIndex, + linkTo, + parametersList, + typeParametersList, + accessorMember, + constructorMember, + declarationMemberIdentifier, + declarationMember, + memberHierarchy, + indexSignatureTitle, + inheritance, + referenceMember, + reflectionMember, + signatureMemberIdentifier, + signatureParameters, + signatureMemberReturns, + signatureMember, + sources, + memberTitle, + member, + typeDeclarationMember, + members, + pageTitle, + enumMembersTable, + parametersTable, + propertiesTable, + typeDeclarationTable, + typeParametersTable, + typeArguments, + arrayType, + conditionalType, + declarationType, + functionType, + indexAccessType, + inferredType, + intersectionType, + intrinsicType, + literalType, + namedTupleType, + queryType, + referenceType, + reflectionType, + someType, + tupleType, + typeOperatorType, + unionType, + unknownType, +} from './partials'; + +function bind(fn: (f: F, ...a: L) => R, first: F) { + return (...args: L) => fn(first, ...args); +} + +export const templates = (context: MarkdownThemeRenderContext) => { + return { + memberTemplate: bind(memberTemplate, context), + projectTemplate: bind(projectTemplate, context), + readmeTemplate: bind(readmeTemplate, context), + reflectionTemplate: bind(reflectionTemplate, context), + }; +}; + +export const partials = (context: MarkdownThemeRenderContext) => { + return { + breadcrumbs: bind(breadcrumbs, context), + commentParts: bind(commentParts, context), + comment: bind(comment, context), + generator: bind(generator, context), + header: bind(header, context), + pageIndex: bind(pageIndex, context), + reflectionIndex: bind(reflectionIndex, context), + linkTo: bind(linkTo, context), + parametersList: bind(parametersList, context), + typeParametersList: bind(typeParametersList, context), + accessorMember: bind(accessorMember, context), + constructorMember: bind(constructorMember, context), + declarationMemberIdentifier: bind(declarationMemberIdentifier, context), + declarationMember: bind(declarationMember, context), + memberHierarchy: bind(memberHierarchy, context), + indexSignatureTitle: bind(indexSignatureTitle, context), + inheritance: bind(inheritance, context), + referenceMember: bind(referenceMember, context), + reflectionMember: bind(reflectionMember, context), + signatureMemberIdentifier: bind(signatureMemberIdentifier, context), + signatureParameters: bind(signatureParameters, context), + signatureMemberReturns: bind(signatureMemberReturns, context), + signatureMember: bind(signatureMember, context), + sources: bind(sources, context), + memberTitle: bind(memberTitle, context), + member: bind(member, context), + typeDeclarationMember: bind(typeDeclarationMember, context), + members: bind(members, context), + pageTitle: bind(pageTitle, context), + enumMembersTable: bind(enumMembersTable, context), + parametersTable: bind(parametersTable, context), + propertiesTable: bind(propertiesTable, context), + typeDeclarationTable: bind(typeDeclarationTable, context), + typeParametersTable: bind(typeParametersTable, context), + typeArguments: bind(typeArguments, context), + arrayType: bind(arrayType, context), + conditionalType: bind(conditionalType, context), + declarationType: bind(declarationType, context), + functionType: bind(functionType, context), + indexAccessType: bind(indexAccessType, context), + inferredType: bind(inferredType, context), + intersectionType: bind(intersectionType, context), + intrinsicType: bind(intrinsicType, context), + literalType: bind(literalType, context), + namedTupleType: bind(namedTupleType, context), + queryType: bind(queryType, context), + referenceType: bind(referenceType, context), + reflectionType: bind(reflectionType, context), + someType: bind(someType, context), + tupleType: bind(tupleType, context), + typeOperatorType: bind(typeOperatorType, context), + unionType: bind(unionType, context), + unknownType: bind(unknownType, context), + }; +}; diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/breadcrumbs.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/breadcrumbs.ts index 9f36e79a3..6498d6626 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/breadcrumbs.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/breadcrumbs.ts @@ -1,20 +1,18 @@ import * as path from 'path'; import { DeclarationReflection, ProjectReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { link } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; -import { getProjectDisplayName } from '../../helpers'; +import { MarkdownPageEvent } from '../../..'; /** * Renders the breadcrumbs - * @mergeTarget + * */ export function breadcrumbs( context: MarkdownThemeRenderContext, page: MarkdownPageEvent, -): string { +) { const md: string[] = []; + const { escapeChars } = context.utils; const entryFileName = context.options.getValue('entryFileName'); @@ -25,11 +23,11 @@ export function breadcrumbs( return ''; } - const homeLabel = context - .getTextContent('breadcrumbs.home') - .replace('{projectName}', getProjectDisplayName(page.project, false)); + const homeLabel = context.text + .get('breadcrumbs.home') + .replace('{projectName}', page.project.name); - md.push(link(homeLabel, context.relativeURL(entryFileName))); + md.push(context.partials.linkTo(homeLabel, entryFileName)); const breadcrumb = (model: any) => { if (model?.parent?.parent) { @@ -42,7 +40,7 @@ export function breadcrumbs( } return model.url; }; - md.push(link(escapeChars(model.name), context.relativeURL(getUrl(model)))); + md.push(context.partials.linkTo(escapeChars(model.name), getUrl(model))); }; const pageName = escapeChars(page.model.name); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.parts.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.parts.ts index 29aab6591..6fabfcc13 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.parts.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.parts.ts @@ -1,3 +1,4 @@ +import * as fs from 'fs'; import { CommentDisplayPart, InlineTagDisplayPart } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; @@ -7,11 +8,54 @@ import { MarkdownThemeRenderContext } from '../..'; export function commentParts( context: MarkdownThemeRenderContext, parts: CommentDisplayPart[], -): string { +) { const md: string[] = []; + const parsedText = (text: string) => { + const mediaPattern = /media:\/\/([^ ")\]}]+)/g; + const includePattern = /\[\[include:([^\]]+?)\]\]/g; + const includeDirectory = context.options.getValue('includes'); + const mediaDirectory = context.options.getValue('media'); + + let parsedText = text; + + if (Boolean(includeDirectory)) { + parsedText = parsedText.replace( + includePattern, + (match: string, includeFile: string) => { + const includeDirectory = context.options.getValue('includes'); + const includesPath = context.utils.getRelativeUrl( + `${includeDirectory}/${includeFile}`, + context.page?.url, + ); + if (isFile(includesPath)) { + const includeContent = fs.readFileSync(includesPath); + return includeContent.toString(); + } else { + return match; + } + }, + ); + } + + if (Boolean(mediaDirectory)) { + parsedText = parsedText.replace( + mediaPattern, + (match: string, mediaFile: string) => { + return context.utils.getRelativeUrl( + `media/${mediaFile}`, + context.page?.url, + ); + }, + ); + } + + return parsedText; + }; for (const part of parts) { switch (part.kind) { case 'text': + md.push(parsedText(part.text)); + break; case 'code': md.push(part.text); break; @@ -24,9 +68,16 @@ export function commentParts( case '@linkcode': case '@linkplain': { if (part.target) { - const url = getUrl(context, part); + const url = getUrl(part); const wrap = part.tag === '@linkcode' ? '`' : ''; - md.push(url ? `[${wrap}${part.text}${wrap}](${url})` : part.text); + md.push( + url + ? `${context.partials.linkTo( + `${wrap}${part.text}${wrap}`, + url, + )}` + : part.text, + ); } else { md.push(part.text); } @@ -44,17 +95,22 @@ export function commentParts( return md.join(''); } -function getUrl( - context: MarkdownThemeRenderContext, - part: InlineTagDisplayPart, -) { +function getUrl(part: InlineTagDisplayPart) { if ((part.target as any).url) { - return context.relativeURL((part.target as any).url); + return (part.target as any).url; } if ((part.target as any)?.parent?.url) { - return context.relativeURL((part.target as any)?.parent?.url); + return (part.target as any)?.parent?.url; } return part.target; } + +export function isFile(file: string) { + try { + return fs.statSync(file).isFile(); + } catch { + return false; + } +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.ts index 668423527..b361364d4 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/comment.ts @@ -1,7 +1,5 @@ import { Comment } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { bold, heading } from '../../../support/elements'; -import { camelToTitleCase, escapeAngleBrackets } from '../../../support/utils'; /** * @category Partials @@ -15,8 +13,11 @@ export function comment( ): string { const md: string[] = []; + const { heading, bold } = context.markdown; + const { escapeAngleBrackets } = context.utils; + if (showSummary && comment.summary?.length > 0) { - md.push(context.commentParts(comment.summary)); + md.push(context.partials.commentParts(comment.summary)); } if (showTags && comment.blockTags?.length) { @@ -28,7 +29,7 @@ export function comment( const tagMd = [ headingLevel ? heading(headingLevel, tagText) + '\n' : bold(tagText), ]; - tagMd.push(context.commentParts(tag.content)); + tagMd.push(context.partials.commentParts(tag.content)); return tagMd.join('\n'); }); md.push(tags.join('\n\n')); @@ -36,3 +37,10 @@ export function comment( return escapeAngleBrackets(md.join('\n\n')); } + +function camelToTitleCase(text: string) { + return ( + text.substring(0, 1).toUpperCase() + + text.substring(1).replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`) + ); +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/footer.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/footer.ts deleted file mode 100644 index 7d6d5b6b8..000000000 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/footer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { MarkdownThemeRenderContext } from '../..'; -import { horizontalRule } from '../../../support/elements'; - -/** - * @category Partials - */ -export function footer(context: MarkdownThemeRenderContext): string { - if (!context.options.getValue('hideGenerator')) { - const generatorText = context - .getTextContent('footer.generator') - ?.replace(/TypeDoc/g, '[TypeDoc](https://typedoc.org)') - .replace( - /typedoc-plugin-markdown/g, - '[typedoc-plugin-markdown](https://typedoc-plugin-markdown.org)', - ); - return [horizontalRule(), generatorText].join(''); - } - return ''; -} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/generator.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/generator.ts new file mode 100644 index 000000000..ded1d9730 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/generator.ts @@ -0,0 +1,16 @@ +import { MarkdownThemeRenderContext } from '../..'; + +/** + * @category Partials + */ +export function generator(context: MarkdownThemeRenderContext): string { + const { horizontalRule } = context.markdown; + const generatorText = context.text + .get('footer.generator') + ?.replace(/TypeDoc/g, '[TypeDoc](https://typedoc.org)') + .replace( + /typedoc-plugin-markdown/g, + '[typedoc-plugin-markdown](https://typedoc-plugin-markdown.org)', + ); + return [horizontalRule(), generatorText].join(''); +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/header.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/header.ts index c00abefef..042e626bf 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/header.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/header.ts @@ -5,11 +5,10 @@ import { ReflectionKind, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { bold, link } from '../../../support/elements'; +import { MarkdownPageEvent } from '../../..'; /** - * @category Partials + * Docs for header!!! */ export function header( context: MarkdownThemeRenderContext, @@ -36,14 +35,16 @@ function projectHeader( const md: string[] = []; - const title = context.indexTitle( - context.getTextContent('header.title'), + const { bold, link } = context.markdown; + + const title = context.text.indexTitle( + context.text.get('header.title'), page.project.name, page.project.packageVersion, ); - const readmeLabel = context.getTextContent('header.readme'); - const indexLabel = context.getTextContent('header.docs'); + const readmeLabel = context.text.get('header.readme'); + const indexLabel = context.text.get('header.docs'); md.push(titleLink ? bold(link(title, titleLink)) : bold(title)); @@ -68,11 +69,9 @@ function projectHeader( links.push(readmeLabel); } else { links.push( - link( + context.partials.linkTo( readmeLabel, - context.relativeURL( - preserveModulesPage ? 'readme_.md' : entryFileName, - ), + preserveModulesPage ? 'readme_.md' : entryFileName, ), ); } @@ -82,7 +81,7 @@ function projectHeader( if (page.url === page.project.url) { links.push(indexLabel); } else { - links.push(link(indexLabel, context.relativeURL(page.project.url))); + links.push(context.partials.linkTo(indexLabel, page.project.url)); } md.push(`${links.join(' ')}`); @@ -104,9 +103,10 @@ function packageHeader( } const md: string[] = []; + const { bold } = context.markdown; - const readmeLabel = context.getTextContent('header.readme'); - const indexLabel = context.getTextContent('header.docs'); + const readmeLabel = context.text.get('header.readme'); + const indexLabel = context.text.get('header.docs'); const entryFileName = context.options.getValue('entryFileName'); @@ -128,7 +128,7 @@ function packageHeader( if (page.url === readmeUrl) { links.push(readmeLabel); } else { - links.push(link(readmeLabel, context.relativeURL(readmeUrl))); + links.push(context.partials.linkTo(readmeLabel, readmeUrl)); } links.push('\\|'); @@ -136,7 +136,7 @@ function packageHeader( if (page.url === packageItem.url) { links.push(indexLabel); } else { - links.push(link(indexLabel, context.relativeURL(packageItem.url))); + links.push(context.partials.linkTo(indexLabel, packageItem.url)); } md.push(`${links.join(' ')}`); } else { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.page.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.page.ts index d86f0bfba..bed62f32d 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.page.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.page.ts @@ -5,10 +5,7 @@ import { ProjectReflection, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { heading } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; -import { hasIndex } from '../../helpers'; +import { MarkdownPageEvent } from '../../..'; /** * @category Partials @@ -19,9 +16,11 @@ export function pageIndex( headingLevel: number, ): string { const md: string[] = []; + const { heading } = context.markdown; + const { escapeChars } = context.utils; - if (hasIndex(page.model)) { - md.push(context.reflectionIndex(page.model, false, headingLevel)); + if (page.model?.groups?.some((group) => group.allChildrenHaveOwnDocument())) { + md.push(context.partials.reflectionIndex(page.model, headingLevel)); return md.join('\n\n'); } @@ -31,15 +30,17 @@ export function pageIndex( EntryPointStrategy.Packages; if (isPackages && page.model.children?.length) { - md.push(heading(headingLevel, context.getTextContent('label.packages'))); + md.push(heading(headingLevel, context.text.get('label.packages'))); const packagesList = page.model.children?.map((projectPackage) => { - return `- [${escapeChars(projectPackage.name)}](${context.relativeURL( - Boolean(projectPackage.readme) - ? `${path.dirname( - projectPackage.url || '', - )}/${context.options.getValue('entryFileName')}` - : projectPackage.url, - )})`; + const urlTo = Boolean(projectPackage.readme) + ? `${path.dirname(projectPackage.url || '')}/${context.options.getValue( + 'entryFileName', + )}` + : projectPackage.url; + return `- ${context.partials.linkTo( + escapeChars(projectPackage.name), + urlTo, + )}`; }); md.push(packagesList?.join('\n') || ''); return md.join('\n\n'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.reflection.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.reflection.ts index df6959033..03e2e49bb 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.reflection.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.reflection.ts @@ -6,67 +6,42 @@ import { ReflectionKind, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading, indentBlock, link, table } from '../../../support/elements'; -import { - escapeChars, - formatTableDescriptionCol, - slugify, -} from '../../../support/utils'; export function reflectionIndex( context: MarkdownThemeRenderContext, reflection: ProjectReflection | DeclarationReflection, - inline = false, headingLevel: number, ): string { const md: string[] = []; + const { heading } = context.markdown; + const subHeadingLevel = headingLevel; if (reflection.categories) { reflection.categories.forEach((categoryGroup) => { md.push(heading(subHeadingLevel, categoryGroup.title) + '\n'); - md.push(getGroup(context, categoryGroup, inline) + '\n'); + md.push(getGroup(context, categoryGroup) + '\n'); }); } else { const groups = reflection.groups?.filter((group) => - inline - ? !group.allChildrenHaveOwnDocument() - : group.allChildrenHaveOwnDocument(), + group.allChildrenHaveOwnDocument(), ); groups?.forEach((reflectionGroup) => { if (reflectionGroup.categories) { md.push(heading(subHeadingLevel, reflectionGroup.title) + '\n'); reflectionGroup.categories.forEach((categoryGroup) => { md.push(heading(subHeadingLevel + 1, categoryGroup.title) + '\n'); - md.push(getGroup(context, categoryGroup, inline) + '\n'); + md.push(getGroup(context, categoryGroup) + '\n'); }); } else { - const hasChildren = reflectionGroup.children.some((child) => - Boolean(child.url), + md.push( + heading( + subHeadingLevel, + context.text.groupTitle(reflectionGroup.title), + ) + '\n', ); - if (inline) { - md.push( - `- [${context.groupTitle( - reflectionGroup.title, - )}](${context.relativeURL(context.page?.url)}#${slugify( - context.groupTitle(reflectionGroup.title), - ).toLowerCase()})`, - ); - if (hasChildren) { - md.push( - indentBlock(getGroup(context, reflectionGroup, inline) + '\n'), - ); - } - } else { - md.push( - heading( - subHeadingLevel, - context.groupTitle(reflectionGroup.title), - ) + '\n', - ); - md.push(getGroup(context, reflectionGroup, inline) + '\n'); - } + md.push(getGroup(context, reflectionGroup) + '\n'); } }); } @@ -76,9 +51,8 @@ export function reflectionIndex( function getGroup( context: MarkdownThemeRenderContext, group: ReflectionGroup | ReflectionCategory, - inline: boolean, ) { - if (!inline && context.options.getValue('indexFormat') === 'table') { + if (context.options.getValue('indexFormat') === 'table') { return getTable(context, group); } return getList(context, group); @@ -88,25 +62,28 @@ function getTable( context: MarkdownThemeRenderContext, group: ReflectionGroup | ReflectionCategory, ) { + const { escapeChars } = context.utils; const reflectionKind = group.children[0].kind; + const { table } = context.markdown; const headers = [ ReflectionKind.singularString(reflectionKind), - context.getTextContent('label.description'), + context.text.get('label.description'), ]; const rows: string[][] = []; + const { formatTableDescriptionCol } = context.utils; group.children.forEach((child) => { const row: string[] = []; - row.push(link(escapeChars(child.name), context.relativeURL(child.url))); + row.push(context.partials.linkTo(escapeChars(child.name), child.url)); const comment = getComment(child); if (comment?.summary?.length) { row.push( - formatTableDescriptionCol(context.commentParts(comment.summary)).split( - '\n', - )[0], + formatTableDescriptionCol( + context.partials.commentParts(comment.summary), + ).split('\n')[0], ); } else { row.push('-'); @@ -120,6 +97,7 @@ function getList( context: MarkdownThemeRenderContext, group: ReflectionGroup | ReflectionCategory, ) { + const { escapeChars } = context.utils; const children = group.children .filter((child) => Boolean(child.url)) .map((child) => { @@ -128,10 +106,10 @@ function getList( ? `${ child.signatures ? child.signatures[0].name - : context.getTextContent('kind.constructor.singular') + : context.text.get('kind.constructor.singular') }` : child.name; - return `- [${escapeChars(name)}](${context.relativeURL(child.url)})`; + return `- ${context.partials.linkTo(escapeChars(name), child.url)}`; }); return children.join('\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.ts new file mode 100644 index 000000000..32d5aff12 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/index.ts @@ -0,0 +1,53 @@ +export { breadcrumbs } from './breadcrumbs'; +export { commentParts } from './comment.parts'; +export { comment } from './comment'; +export { generator } from './generator'; +export { header } from './header'; +export { pageIndex } from './index.page'; +export { reflectionIndex } from './index.reflection'; +export { linkTo } from './link-to'; +export { parametersList } from './list.parameters'; +export { typeParametersList } from './list.typeparameters'; +export { accessorMember } from './member.accessor'; +export { constructorMember } from './member.constructors'; +export { declarationMemberIdentifier } from './member.declaration.identifier'; +export { declarationMember } from './member.declaration'; +export { memberHierarchy } from './member.hierarchy'; +export { indexSignatureTitle } from './member.indexsignature.title'; +export { inheritance } from './member.inheritance'; +export { referenceMember } from './member.reference'; +export { reflectionMember } from './member.reflection'; +export { signatureMemberIdentifier } from './member.signature.identifier'; +export { signatureParameters } from './member.signature.parameters'; +export { signatureMemberReturns } from './member.signature.returns'; +export { signatureMember } from './member.signature'; +export { sources } from './member.sources'; +export { memberTitle } from './member.title'; +export { member } from './member'; +export { typeDeclarationMember } from './member.type-declaration'; +export { members } from './members'; +export { pageTitle } from './page.title'; +export { enumMembersTable } from './table.enum-members'; +export { parametersTable } from './table.parameters'; +export { propertiesTable } from './table.properties'; +export { typeDeclarationTable } from './table.type-declaration'; +export { typeParametersTable } from './table.typeparameters'; +export { typeArguments } from './type-argumentsts'; +export { arrayType } from './type.array'; +export { conditionalType } from './type.conditional'; +export { declarationType } from './type.declaration'; +export { functionType } from './type.function'; +export { indexAccessType } from './type.index-access'; +export { inferredType } from './type.inferred'; +export { intersectionType } from './type.intersection'; +export { intrinsicType } from './type.intrinsic'; +export { literalType } from './type.literal'; +export { namedTupleType } from './type.named-tuple'; +export { queryType } from './type.query'; +export { referenceType } from './type.reference'; +export { reflectionType } from './type.reflection'; +export { someType } from './type.some'; +export { tupleType } from './type.tuple'; +export { typeOperatorType } from './type.type-operator'; +export { unionType } from './type.union'; +export { unknownType } from './type.unknown'; \ No newline at end of file diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/link-to.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/link-to.ts new file mode 100644 index 000000000..60a476555 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/link-to.ts @@ -0,0 +1,27 @@ +import * as path from 'path'; +import { MarkdownThemeRenderContext } from '../..'; + +export function linkTo( + context: MarkdownThemeRenderContext, + label: string, + url?: string, +) { + const URL_PREFIX = /^(http|ftp)s?:\/\//; + const { link } = context.markdown; + if (typeof url !== 'string') { + return label; + } + if (URL_PREFIX.test(url)) { + return link(label, url); + } else { + const publicPath = context.options.getValue('publicPath'); + + if (publicPath) { + return path.join(publicPath, url); + } + + const relativeUrl = context.utils.getRelativeUrl(url, context.page?.url); + + return link(label, context.utils.parseUrl(relativeUrl)); + } +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.parameters.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.parameters.ts index cad229a63..25a97b562 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.parameters.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.parameters.ts @@ -1,8 +1,6 @@ import { ParameterReflection, ReflectionKind } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, bold } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; /** * @category Partials @@ -11,6 +9,9 @@ export function parametersList( context: MarkdownThemeRenderContext, parameters: ParameterReflection[], ): string { + const { bold, backTicks } = context.markdown; + const { escapeChars } = context.utils; + const parseParams = (current: any, acc: any) => { const shouldFlatten = current.type?.declaration?.kind === ReflectionKind.TypeLiteral && @@ -60,17 +61,19 @@ export function parametersList( const identifier: string[] = [bold(name)]; if (parameter.type) { - identifier.push(': ' + context.someType(parameter.type)); + identifier.push(': ' + context.partials.someType(parameter.type)); } if (parameter.defaultValue) { - identifier.push('= ' + getDefaultValue(parameter)); + identifier.push( + '= ' + backTicks(context.helpers.getParameterDefaultValue(parameter)), + ); } row.push(`• ${rest}${identifier.join('')}`); if (parameter.comment) { - row.push(context.comment(parameter.comment)); + row.push(context.partials.comment(parameter.comment)); } rows.push(row.join('\n\n')); @@ -78,9 +81,3 @@ export function parametersList( return rows.join('\n\n'); } - -function getDefaultValue(parameter: ParameterReflection) { - return parameter.defaultValue && parameter.defaultValue !== '...' - ? backTicks(parameter.defaultValue) - : backTicks('undefined'); -} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.typeparameters.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.typeparameters.ts index 203673081..5ef15cb54 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.typeparameters.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/list.typeparameters.ts @@ -1,6 +1,5 @@ import { TypeParameterReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { bold } from '../../../support/elements'; /** * @category Partials @@ -8,26 +7,27 @@ import { bold } from '../../../support/elements'; export function typeParametersList( context: MarkdownThemeRenderContext, typeParameters: TypeParameterReflection[], - headingLevel: number, ): string { const rows: string[] = []; typeParameters?.forEach((typeParameter) => { const row: string[] = []; + const { bold } = context.markdown; + const nameCol: string[] = [bold(typeParameter.name)]; if (typeParameter.type) { - nameCol.push(`extends ${context.someType(typeParameter.type)}`); + nameCol.push(`extends ${context.partials.someType(typeParameter.type)}`); } if (typeParameter.default) { - nameCol.push(`= ${context.someType(typeParameter.default)}`); + nameCol.push(`= ${context.partials.someType(typeParameter.default)}`); } row.push('• ' + nameCol.join(' ')); if (typeParameter.comment) { - row.push(context.comment(typeParameter.comment)); + row.push(context.partials.comment(typeParameter.comment)); } rows.push(row.join('\n\n')); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.accessor.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.accessor.ts index a7068bfd1..4705a8d86 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.accessor.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.accessor.ts @@ -1,6 +1,5 @@ import { DeclarationReflection, ReflectionKind } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading } from '../../../support/elements'; /** * @category Partials @@ -12,41 +11,58 @@ export function accessorMember( ): string { const md: string[] = []; + const { heading } = context.markdown; + if (declaration.getSignature) { md.push( - context.signatureMemberIdentifier(declaration.getSignature, { + context.partials.signatureMemberIdentifier(declaration.getSignature, { accessor: 'get', }), ); if (declaration.getSignature.comment) { - md.push(context.comment(declaration.getSignature.comment, headingLevel)); + md.push( + context.partials.comment( + declaration.getSignature.comment, + headingLevel, + ), + ); } } if (declaration.setSignature) { md.push( - context.signatureMemberIdentifier(declaration.setSignature, { + context.partials.signatureMemberIdentifier(declaration.setSignature, { accessor: 'set', }), ); if (declaration.setSignature.comment) { - md.push(context.comment(declaration.setSignature.comment, headingLevel)); + md.push( + context.partials.comment( + declaration.setSignature.comment, + headingLevel, + ), + ); } } if (declaration.setSignature?.parameters?.length) { - md.push( - heading(headingLevel, context.getTextContent('kind.parameter.plural')), - ); + md.push(heading(headingLevel, context.text.get('kind.parameter.plural'))); if (context.options.getValue('parametersFormat') === 'table') { - md.push(context.parametersTable(declaration.setSignature.parameters)); + md.push( + context.partials.parametersTable(declaration.setSignature.parameters), + ); } else { - md.push(context.parametersList(declaration.setSignature.parameters)); + md.push( + context.partials.parametersList(declaration.setSignature.parameters), + ); } } if (declaration.getSignature?.type) { md.push( - context.signatureMemberReturns(declaration.getSignature, headingLevel), + context.partials.signatureMemberReturns( + declaration.getSignature, + headingLevel, + ), ); } @@ -54,9 +70,9 @@ export function accessorMember( if (showSources && !context.options.getValue('disableSources')) { if (declaration.getSignature?.sources) { - md.push(context.sources(declaration.getSignature, headingLevel)); + md.push(context.partials.sources(declaration.getSignature, headingLevel)); } else if (declaration.setSignature?.sources) { - md.push(context.sources(declaration.setSignature, headingLevel)); + md.push(context.partials.sources(declaration.setSignature, headingLevel)); } } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.constructors.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.constructors.ts index f9e163235..e5482a03b 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.constructors.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.constructors.ts @@ -1,7 +1,5 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; /** * @category Partials @@ -13,10 +11,13 @@ export function constructorMember( ): string { const md: string[] = []; + const { heading } = context.markdown; + const { escapeChars } = context.utils; + reflection.signatures?.forEach((signature) => { const params = signature.parameters?.map((param) => param.name).join(', '); md.push(heading(headingLevel, `${escapeChars(signature.name)}(${params})`)); - md.push(context.signatureMember(signature, headingLevel + 1)); + md.push(context.partials.signatureMember(signature, headingLevel + 1)); }); return md.join('\n\n'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.identifier.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.identifier.ts index 4ac572245..d23192c07 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.identifier.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.identifier.ts @@ -1,12 +1,5 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, bold, codeBlock } from '../../../support/elements'; -import { - escapeChars, - stripComments, - stripLineBreaks, -} from '../../../support/utils'; -import { KEYWORD_MAP, getDeclarationType, isGroupKind } from '../../helpers'; /** * @category Partials @@ -16,10 +9,12 @@ export function declarationMemberIdentifier( reflection: DeclarationReflection, ): string { const md: string[] = []; + const { backTicks, bold, codeBlock } = context.markdown; + const { escapeChars, stripComments, stripLineBreaks } = context.utils; const useCodeBlocks = context.options.getValue('useCodeBlocks'); - const declarationType = getDeclarationType(reflection); + const declarationType = context.helpers.getDeclarationType(reflection); const prefix: string[] = []; @@ -37,12 +32,10 @@ export function declarationMemberIdentifier( prefix.push('...'); } - if ( - useCodeBlocks && - isGroupKind(reflection) && - KEYWORD_MAP[reflection.kind] - ) { - prefix.push(KEYWORD_MAP[reflection.kind]); + const keyword = context.helpers.getKeyword(reflection.kind); + + if (useCodeBlocks && context.helpers.isGroupKind(reflection) && keyword) { + prefix.push(keyword); } if (prefix.length) { @@ -80,7 +73,7 @@ export function declarationMemberIdentifier( md.push(name.join('')); if (declarationType) { - md.push(context.someType(declarationType)); + md.push(context.partials.someType(declarationType)); } if (reflection.defaultValue && reflection.defaultValue !== '...') { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.ts index 5067cba5a..baa446373 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.declaration.ts @@ -5,7 +5,6 @@ import { ReflectionType, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading } from '../../../support/elements'; /** * @category Partials @@ -17,8 +16,9 @@ export function declarationMember( nested = false, ) { const md: string[] = []; + const { heading } = context.markdown; - md.push(context.declarationMemberIdentifier(declaration)); + md.push(context.partials.declarationMemberIdentifier(declaration)); const typeDeclaration = (declaration.type as any) ?.declaration as DeclarationReflection; @@ -29,7 +29,7 @@ export function declarationMember( ) ) { if (declaration.comment) { - md.push(context.comment(declaration.comment, headingLevel)); + md.push(context.partials.comment(declaration.comment, headingLevel)); } } @@ -38,7 +38,7 @@ export function declarationMember( if (intersectionType instanceof ReflectionType) { md.push(heading(headingLevel, 'Type declaration')); md.push( - context.typeDeclarationMember( + context.partials.typeDeclarationMember( intersectionType.declaration, headingLevel, ), @@ -52,11 +52,9 @@ export function declarationMember( declaration.type.typeArguments?.length ) { if (declaration.type.typeArguments[0] instanceof ReflectionType) { + md.push(heading(headingLevel, context.text.get('label.typeDeclaration'))); md.push( - heading(headingLevel, context.getTextContent('label.typeDeclaration')), - ); - md.push( - context.typeDeclarationMember( + context.partials.typeDeclarationMember( declaration.type.typeArguments[0].declaration, headingLevel, ), @@ -66,58 +64,51 @@ export function declarationMember( if (declaration.typeParameters) { md.push( - heading( - headingLevel, - context.getTextContent('kind.typeParameter.plural'), - ), + heading(headingLevel, context.text.get('kind.typeParameter.plural')), ); if (context.options.getValue('parametersFormat') === 'table') { - md.push(context.typeParametersTable(declaration.typeParameters)); + md.push(context.partials.typeParametersTable(declaration.typeParameters)); } else { - md.push( - context.typeParametersList( - declaration.typeParameters, - headingLevel + 1, - ), - ); + md.push(context.partials.typeParametersList(declaration.typeParameters)); } } if (typeDeclaration) { if (typeDeclaration?.indexSignature) { + md.push(heading(headingLevel, context.text.get('label.indexSignature'))); md.push( - heading(headingLevel, context.getTextContent('label.indexSignature')), + context.partials.indexSignatureTitle(typeDeclaration.indexSignature), ); - md.push(context.indexSignatureTitle(typeDeclaration.indexSignature)); } if (typeDeclaration?.signatures?.length) { typeDeclaration.signatures.forEach((signature) => { - md.push(context.signatureMember(signature, headingLevel, true)); + md.push( + context.partials.signatureMember(signature, headingLevel, true), + ); }); } if (typeDeclaration?.children?.length) { if (!nested && typeDeclaration?.children?.length) { md.push( - heading( - headingLevel, - context.getTextContent('label.typeDeclaration'), - ), + heading(headingLevel, context.text.get('label.typeDeclaration')), + ); + md.push( + context.partials.typeDeclarationMember(typeDeclaration, headingLevel), ); - md.push(context.typeDeclarationMember(typeDeclaration, headingLevel)); } } } - md.push(context.inheritance(declaration, headingLevel)); + md.push(context.partials.inheritance(declaration, headingLevel)); if ( !nested && declaration.sources && !context.options.getValue('disableSources') ) { - md.push(context.sources(declaration, headingLevel)); + md.push(context.partials.sources(declaration, headingLevel)); } return md.join('\n\n'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.hierarchy.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.hierarchy.ts index 328b76601..5414886f4 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.hierarchy.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.hierarchy.ts @@ -1,11 +1,5 @@ import { DeclarationHierarchy, SomeType, Type } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { - backTicks, - bold, - heading, - unorderedList, -} from '../../../support/elements'; export function memberHierarchy( context: MarkdownThemeRenderContext, @@ -13,6 +7,7 @@ export function memberHierarchy( headingLevel: number, ): string { const md: string[] = []; + const { heading, unorderedList } = context.markdown; const parent = !declarationHierarchy.isTarget ? declarationHierarchy.types .map((hierarchyType) => { @@ -26,12 +21,10 @@ export function memberHierarchy( : null; if (declarationHierarchy.next) { if (parent) { - md.push(heading(headingLevel, context.getTextContent('label.extends'))); + md.push(heading(headingLevel, context.text.get('label.extends'))); md.push(`- ${parent}`); } else { - md.push( - heading(headingLevel, context.getTextContent('label.extendedBy')), - ); + md.push(heading(headingLevel, context.text.get('label.extendedBy'))); const lines: string[] = []; declarationHierarchy.next.types.forEach((hierarchyType) => { lines.push( @@ -53,7 +46,8 @@ function getHierarchyType( isTarget: boolean, context: MarkdownThemeRenderContext, ) { + const { bold, backTicks } = context.markdown; return isTarget ? bold(backTicks(hierarchyType.toString())) - : context.someType(hierarchyType as SomeType); + : context.partials.someType(hierarchyType as SomeType); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.indexsignature.title.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.indexsignature.title.ts index b40d7621d..dd7295d32 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.indexsignature.title.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.indexsignature.title.ts @@ -1,6 +1,5 @@ import { SignatureReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -10,15 +9,20 @@ export function indexSignatureTitle( signature: SignatureReflection, ): string { const md = ['']; + const { backTicks } = context.markdown; const params = signature.parameters ? signature.parameters.map((parameter) => { return parameter.type - ? `${backTicks(parameter.name)}: ${context.someType(parameter.type)}` + ? `${backTicks(parameter.name)}: ${context.partials.someType( + parameter.type, + )}` : ''; }) : []; if (signature.type) { - md.push(`\\[${params.join('')}\\]: ${context.someType(signature.type)}`); + md.push( + `\\[${params.join('')}\\]: ${context.partials.someType(signature.type)}`, + ); } return md.join(' '); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.inheritance.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.inheritance.ts index cf25070cf..6bc6dd345 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.inheritance.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.inheritance.ts @@ -5,7 +5,6 @@ import { SignatureReflection, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, heading, link } from '../../../support/elements'; export function inheritance( context: MarkdownThemeRenderContext, @@ -13,11 +12,12 @@ export function inheritance( headingLevel: number, ): string { const md: string[] = []; + const { heading } = context.markdown; if (reflection.implementationOf) { if (headingLevel !== -1) { md.push( - heading(headingLevel, context.getTextContent('label.implementationOf')), + heading(headingLevel, context.text.get('label.implementationOf')), ); } md.push(typeAndParent(context, reflection.implementationOf)); @@ -25,15 +25,13 @@ export function inheritance( if (reflection.inheritedFrom) { if (headingLevel !== -1) { - md.push( - heading(headingLevel, context.getTextContent('label.inheritedFrom')), - ); + md.push(heading(headingLevel, context.text.get('label.inheritedFrom'))); } md.push(typeAndParent(context, reflection.inheritedFrom)); } if (reflection.overwrites) { - const overridesLabel = context.getTextContent('label.overrides'); + const overridesLabel = context.text.get('label.overrides'); if (headingLevel !== -1) { md.push(heading(headingLevel, overridesLabel)); } @@ -47,6 +45,7 @@ const typeAndParent = ( context: MarkdownThemeRenderContext, props: ArrayType | ReferenceType, ) => { + const { backTicks } = context.markdown; if (props) { if ('elementType' in props) { return typeAndParent(context, props.elementType as any) + '[]'; @@ -55,7 +54,7 @@ const typeAndParent = ( const name = props.reflection.getFriendlyFullName(); const url = props.reflection?.url || props.reflection?.parent?.url; const output = url - ? link(backTicks(name), context.relativeURL(url)) + ? context.partials.linkTo(backTicks(name), url) : backTicks(name); return output; } else { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reference.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reference.ts index fab17c7e9..6ffc3bdea 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reference.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reference.ts @@ -10,10 +10,8 @@ export function referenceMember( ): string { let referenced = props.tryGetTargetReflectionDeep(); - const reExportsText = context.getTextContent('label.reExports'); - const renamesAndReExportsText = context.getTextContent( - 'label.renamesAndReExports', - ); + const reExportsText = context.text.get('label.reExports'); + const renamesAndReExportsText = context.text.get('label.renamesAndReExports'); if (!referenced) { return `${reExportsText} ${props.name}`; @@ -28,12 +26,14 @@ export function referenceMember( } if (props.name === referenced.name) { - return `${reExportsText} [${referenced.name}](${context.urlTo( - referenced, - )})`; + return `${reExportsText} ${context.partials.linkTo( + referenced.name, + referenced.url, + )}`; } - return `${renamesAndReExportsText} [${referenced.name}](${context.urlTo( - referenced, - )})`; + return `${renamesAndReExportsText} ${context.partials.linkTo( + referenced.name, + referenced.url, + )}`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reflection.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reflection.ts index f194ccd23..5335c6ba9 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reflection.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.reflection.ts @@ -1,7 +1,5 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading, unorderedList } from '../../../support/elements'; -import { hasIndex, isAbsoluteIndex } from '../../helpers'; /** * @category Partials @@ -12,37 +10,35 @@ export function reflectionMember( headingLevel: number, ): string { const md: string[] = []; + const { heading, unorderedList } = context.markdown; if (reflection.comment) { - md.push(context.comment(reflection.comment, headingLevel)); + md.push(context.partials.comment(reflection.comment, headingLevel)); } if (reflection.typeHierarchy?.next) { - md.push(context.memberHierarchy(reflection.typeHierarchy, headingLevel)); + md.push( + context.partials.memberHierarchy(reflection.typeHierarchy, headingLevel), + ); } if (reflection.typeParameters) { md.push( - heading( - headingLevel, - context.getTextContent('kind.typeParameter.plural'), - ), + heading(headingLevel, context.text.get('kind.typeParameter.plural')), ); if (context.options.getValue('parametersFormat') === 'table') { - md.push(context.typeParametersTable(reflection.typeParameters)); + md.push(context.partials.typeParametersTable(reflection.typeParameters)); } else { - md.push( - context.typeParametersList(reflection.typeParameters, headingLevel + 1), - ); + md.push(context.partials.typeParametersList(reflection.typeParameters)); } } if (reflection.implementedTypes) { - md.push(heading(headingLevel, context.getTextContent('label.implements'))); + md.push(heading(headingLevel, context.text.get('label.implements'))); md.push( unorderedList( reflection.implementedTypes.map((implementedType) => - context.someType(implementedType), + context.partials.someType(implementedType), ), ), ); @@ -50,31 +46,31 @@ export function reflectionMember( if ('signatures' in reflection && reflection.signatures) { reflection.signatures.forEach((signature) => { - md.push(context.signatureMember(signature, headingLevel)); + md.push(context.partials.signatureMember(signature, headingLevel)); }); } if ('indexSignature' in reflection && reflection.indexSignature) { - md.push(heading(headingLevel, context.getTextContent('label.indexable'))); - md.push(context.indexSignatureTitle(reflection.indexSignature)); + md.push(heading(headingLevel, context.text.get('label.indexable'))); + md.push(context.partials.indexSignatureTitle(reflection.indexSignature)); } - if (hasIndex(reflection)) { - const isAbsolute = isAbsoluteIndex(reflection); - + if (reflection?.groups?.some((group) => group.allChildrenHaveOwnDocument())) { + const isAbsolute = reflection.groups?.every((group) => + group.allChildrenHaveOwnDocument(), + ); if (isAbsolute) { - md.push(heading(headingLevel, context.getTextContent('label.index'))); + md.push(heading(headingLevel, context.text.get('label.index'))); } md.push( - context.reflectionIndex( + context.partials.reflectionIndex( reflection, - false, isAbsolute ? headingLevel + 1 : headingLevel, ), ); } - md.push(context.members(reflection, headingLevel)); + md.push(context.partials.members(reflection, headingLevel)); return md.join('\n\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.identifier.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.identifier.ts index a9a52dfe3..6f46eafd4 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.identifier.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.identifier.ts @@ -1,12 +1,5 @@ import { SignatureReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, bold, codeBlock } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; -import { - KEYWORD_MAP, - getSignatureParameters, - isGroupKind, -} from '../../helpers'; /** * @category Partials @@ -20,6 +13,8 @@ export function signatureMemberIdentifier( }, ): string { const md: string[] = []; + const { backTicks, bold, codeBlock } = context.markdown; + const { escapeChars } = context.utils; const DEFAULT_OPTIONS = { accessor: null, @@ -27,15 +22,15 @@ export function signatureMemberIdentifier( }; const options = { ...DEFAULT_OPTIONS, ...opts }; - const useCodeBlocks = context.options.getValue('useCodeBlocks'); + const keyword = context.helpers.getKeyword(signature.parent.kind); if ( useCodeBlocks && - isGroupKind(signature.parent) && - KEYWORD_MAP[signature.parent.kind] + context.helpers.isGroupKind(signature.parent) && + keyword ) { - md.push(KEYWORD_MAP[signature.parent.kind] + ' '); + md.push(keyword + ' '); } if (options?.accessor) { @@ -62,10 +57,15 @@ export function signatureMemberIdentifier( ); } - md.push(getSignatureParameters(signature.parameters || [], useCodeBlocks)); + md.push( + context.partials.signatureParameters( + signature.parameters || [], + useCodeBlocks, + ), + ); if (signature.type) { - md.push(`: ${context.someType(signature.type)}`); + md.push(`: ${context.partials.someType(signature.type)}`); } const result = md.join(''); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.parameters.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.parameters.ts new file mode 100644 index 000000000..83a082407 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.parameters.ts @@ -0,0 +1,37 @@ +import { ParameterReflection } from 'typedoc'; +import { MarkdownThemeRenderContext } from '../..'; + +/** + * @category Partials + */ +export function signatureParameters( + context: MarkdownThemeRenderContext, + parameters: ParameterReflection[], + format = false, +): string { + const firstOptionalParamIndex = parameters.findIndex( + (parameter) => parameter.flags.isOptional, + ); + return ( + '(' + + parameters + .map((param, i) => { + const paramsmd: string[] = []; + if (param.flags.isRest) { + paramsmd.push('...'); + } + const paramItem = `${context.markdown.backTicks(param.name)}${ + param.flags.isOptional || + (firstOptionalParamIndex !== -1 && i > firstOptionalParamIndex) + ? '?' + : '' + }`; + paramsmd.push( + `${format && parameters.length > 2 ? `\n ` : ''}${paramItem}`, + ); + return paramsmd.join(''); + }) + .join(`, `) + + ')' + ); +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.returns.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.returns.ts index 3ab20960a..24f8041d2 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.returns.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.returns.ts @@ -6,7 +6,6 @@ import { SomeType, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, blockQuoteBlock, heading } from '../../../support/elements'; /** * @category Partials @@ -17,18 +16,19 @@ export function signatureMemberReturns( headingLevel: number, ): string { const md: string[] = []; + const { heading, blockQuoteBlock } = context.markdown; const typeDeclaration = (signature.type as any) ?.declaration as DeclarationReflection; - md.push(heading(headingLevel, context.getTextContent('label.returns'))); + md.push(heading(headingLevel, context.text.get('label.returns'))); md.push(getReturnType(context, typeDeclaration, signature.type)); if (signature.comment?.blockTags.length) { const tags = signature.comment.blockTags .filter((tag) => tag.tag === '@returns') - .map((tag) => context.commentParts(tag.content)); + .map((tag) => context.partials.commentParts(tag.content)); md.push(tags.join('\n\n')); } @@ -39,7 +39,7 @@ export function signatureMemberReturns( if (signature.type.typeArguments[0] instanceof ReflectionType) { md.push( blockQuoteBlock( - context.typeDeclarationMember( + context.partials.typeDeclarationMember( signature.type.typeArguments[0].declaration, headingLevel, ), @@ -52,7 +52,7 @@ export function signatureMemberReturns( typeDeclaration.signatures.forEach((signature) => { md.push( blockQuoteBlock( - context.signatureMember(signature, headingLevel + 1, true), + context.partials.signatureMember(signature, headingLevel + 1, true), ), ); }); @@ -61,7 +61,7 @@ export function signatureMemberReturns( if (typeDeclaration?.children) { md.push( blockQuoteBlock( - context.typeDeclarationMember(typeDeclaration, headingLevel), + context.partials.typeDeclarationMember(typeDeclaration, headingLevel), ), ); } @@ -74,11 +74,12 @@ function getReturnType( typeDeclaration?: DeclarationReflection, type?: SomeType, ) { + const { backTicks } = context.markdown; if (typeDeclaration?.children) { return backTicks('Object'); } if (typeDeclaration?.signatures) { return backTicks('Function'); } - return type ? context.someType(type, true).replace(/\n/g, ' ') : ''; + return type ? context.partials.someType(type, true).replace(/\n/g, ' ') : ''; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.ts index 629232dab..b95474b4b 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.signature.ts @@ -1,6 +1,5 @@ import { ReflectionKind, SignatureReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading } from '../../../support/elements'; /** * @category Partials @@ -13,17 +12,20 @@ export function signatureMember( accessor?: string, ): string { const md: string[] = []; + const { heading } = context.markdown; if (!nested) { md.push( - context.signatureMemberIdentifier(signature, { + context.partials.signatureMemberIdentifier(signature, { accessor, }), ); } if (signature.comment) { - md.push(context.comment(signature.comment, headingLevel, true, false)); + md.push( + context.partials.comment(signature.comment, headingLevel, true, false), + ); } if ( @@ -31,39 +33,34 @@ export function signatureMember( !signature.kindOf(ReflectionKind.ConstructorSignature) ) { md.push( - heading( - headingLevel, - context.getTextContent('kind.typeParameter.plural'), - ), + heading(headingLevel, context.text.get('kind.typeParameter.plural')), ); if (context.options.getValue('parametersFormat') === 'table') { - md.push(context.typeParametersTable(signature.typeParameters)); + md.push(context.partials.typeParametersTable(signature.typeParameters)); } else { - md.push( - context.typeParametersList(signature.typeParameters, headingLevel + 1), - ); + md.push(context.partials.typeParametersList(signature.typeParameters)); } } if (signature.parameters?.length) { - md.push( - heading(headingLevel, context.getTextContent('kind.parameter.plural')), - ); + md.push(heading(headingLevel, context.text.get('kind.parameter.plural'))); if (context.options.getValue('parametersFormat') === 'table') { - md.push(context.parametersTable(signature.parameters)); + md.push(context.partials.parametersTable(signature.parameters)); } else { - md.push(context.parametersList(signature.parameters)); + md.push(context.partials.parametersList(signature.parameters)); } } if (signature.type) { - md.push(context.signatureMemberReturns(signature, headingLevel)); + md.push(context.partials.signatureMemberReturns(signature, headingLevel)); } - md.push(context.inheritance(signature, headingLevel)); + md.push(context.partials.inheritance(signature, headingLevel)); if (signature.comment) { - md.push(context.comment(signature.comment, headingLevel, false, true)); + md.push( + context.partials.comment(signature.comment, headingLevel, false, true), + ); } if ( @@ -71,7 +68,7 @@ export function signatureMember( signature.sources && !context.options.getValue('disableSources') ) { - md.push(context.sources(signature, headingLevel)); + md.push(context.partials.sources(signature, headingLevel)); } return md.join('\n\n'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.sources.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.sources.ts index 10e6f2aa0..3851b18c9 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.sources.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.sources.ts @@ -1,7 +1,5 @@ import { DeclarationReflection, SignatureReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading, link } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; /** * @category Partials @@ -12,8 +10,10 @@ export function sources( headingLevel: number, ): string { const md: string[] = []; + const { heading, link } = context.markdown; + const { escapeChars } = context.utils; if (headingLevel !== -1) { - md.push(heading(headingLevel, context.getTextContent('label.source'))); + md.push(heading(headingLevel, context.text.get('label.source'))); } reflection.sources?.forEach((source, index) => { if (index === 0) { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.title.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.title.ts new file mode 100644 index 000000000..4ec7c3d0c --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.title.ts @@ -0,0 +1,53 @@ +import { DeclarationReflection, ReflectionKind } from 'typedoc'; +import { MarkdownThemeRenderContext } from '../../..'; + +/** + * @category Partials + */ +export function memberTitle( + context: MarkdownThemeRenderContext, + reflection: DeclarationReflection, +): string { + const md: string[] = []; + const name: string[] = []; + const { backTicks, strikeThrough } = context.markdown; + const { escapeChars } = context.utils; + + if ( + reflection?.kind === ReflectionKind.Class && + reflection.flags?.includes('Abstract') + ) { + name.push(backTicks('abstract') + ' '); + } + + name.push( + `${ + reflection.name.startsWith('[') && reflection.signatures?.length + ? backTicks(reflection.name) + : escapeChars(reflection.name) + }`, + ); + + if (reflection.signatures?.length) { + name.push('()'); + } + + if (reflection.typeParameters) { + const typeParameters = reflection.typeParameters + .map((typeParameter) => typeParameter.name) + .join(', '); + name.push(`${`\\<${typeParameters}\\>`}`); + } + + if (reflection.flags.isOptional) { + name.push('?'); + } + + if (reflection.isDeprecated && reflection.isDeprecated()) { + md.push(strikeThrough(name.join(''))); + } else { + md.push(name.join('')); + } + + return md.join(': '); +} diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.ts index 1448441ea..f9426820d 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.ts @@ -4,9 +4,6 @@ import { ReflectionKind, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading } from '../../../support/elements'; -import { escapeChars } from '../../../support/utils'; -import { getMemberTitle } from '../../helpers'; /** * @category Partials @@ -18,6 +15,8 @@ export function member( nested = false, ): string { const md: string[] = []; + const { heading } = context.markdown; + const { escapeChars } = context.utils; if (context.options.getValue('namedAnchors')) { md.push(``); @@ -27,11 +26,11 @@ export function member( !reflection.hasOwnDocument && !(reflection.kind === ReflectionKind.Constructor) ) { - const memberName = getMemberTitle(reflection); - const memberHeading = context - .getTextContent('title.member') + const memberName = context.partials.memberTitle(reflection); + const memberHeading = context.text + .get('title.member') .replace('{name}', memberName) - .replace('{kind}', context.kindString(reflection.kind)); + .replace('{kind}', context.text.kindString(reflection.kind)); md.push(heading(headingLevel, memberHeading)); } @@ -43,15 +42,15 @@ export function member( ReflectionKind.Enum, ].includes(reflection.kind) ) { - return context.reflectionMember(reflection, headingLevel + 1); + return context.partials.reflectionMember(reflection, headingLevel + 1); } if (reflection.kind === ReflectionKind.Constructor) { - return context.constructorMember(reflection, headingLevel); + return context.partials.constructorMember(reflection, headingLevel); } if (reflection.kind === ReflectionKind.Accessor) { - return context.accessorMember(reflection, headingLevel + 1); + return context.partials.accessorMember(reflection, headingLevel + 1); } if (reflection.signatures) { @@ -72,7 +71,7 @@ export function member( ); } signatureMd.push( - context.signatureMember( + context.partials.signatureMember( signature, multipleSignatures ? headingLevel + 2 : headingLevel + 1, nested, @@ -84,10 +83,14 @@ export function member( } if (reflection instanceof ReferenceReflection) { - return context.referenceMember(reflection); + return context.partials.referenceMember(reflection); } - return context.declarationMember(reflection, headingLevel + 1, nested); + return context.partials.declarationMember( + reflection, + headingLevel + 1, + nested, + ); }; const member = getMember(reflection); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.type-declaration.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.type-declaration.ts index 262989ba4..56edc1169 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.type-declaration.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/member.type-declaration.ts @@ -1,6 +1,5 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { flattenDeclarations } from '../../helpers'; /** * @category Partials @@ -14,11 +13,13 @@ export function typeDeclarationMember( if (typeDeclaration.children) { if (context.options.getValue('typeDeclarationFormat') === 'table') { - md.push(context.typeDeclarationTable(typeDeclaration.children)); + md.push(context.partials.typeDeclarationTable(typeDeclaration.children)); } else { - const declarations = flattenDeclarations(typeDeclaration.children); + const declarations = context.helpers.flattenDeclarations( + typeDeclaration.children, + ); declarations.forEach((declaration: DeclarationReflection) => { - md.push(context.member(declaration, headingLevel + 1, true)); + md.push(context.partials.member(declaration, headingLevel + 1, true)); }); } } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/members.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/members.ts index 2ec5a07d8..ddf5f3979 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/members.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/members.ts @@ -6,8 +6,6 @@ import { } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { heading, horizontalRule } from '../../../support/elements'; -import { isGroupKind } from '../../helpers'; export function members( context: MarkdownThemeRenderContext, @@ -15,14 +13,12 @@ export function members( headingLevel: number, ): string { const md: string[] = []; + const { heading, horizontalRule } = context.markdown; const displayHr = (reflection: DeclarationReflection) => { if (context.options.getValue('outputFileStrategy') === 'modules') { - return isGroupKind(reflection); + return context.helpers.isGroupKind(reflection); } - //return !context.options - // .getValue('membersWithOwnFile') - // ?.includes(reflection); return true; }; @@ -44,7 +40,9 @@ export function members( ) => { const items = children?.filter((item) => !item.hasOwnDocument); items?.forEach((item, index) => { - md.push(context.member(item, memberHeadingLevel || headingLevel)); + md.push( + context.partials.member(item, memberHeadingLevel || headingLevel), + ); if (index < items.length - 1 && displayHr(item)) { md.push(horizontalRule()); } @@ -73,7 +71,7 @@ export function members( ); groupsWithChildren?.forEach((group, index: number) => { if (group.categories) { - md.push(heading(headingLevel, context.groupTitle(group.title))); + md.push(heading(headingLevel, context.text.groupTitle(group.title))); pushCategories(group.categories, headingLevel + 1); } else { const isPropertiesGroup = group.children.every((child) => @@ -84,24 +82,24 @@ export function members( child.kindOf(ReflectionKind.EnumMember), ); - md.push(heading(headingLevel, context.groupTitle(group.title))); + md.push(heading(headingLevel, context.text.groupTitle(group.title))); if ( isPropertiesGroup && context.options.getValue('propertiesFormat') === 'table' ) { md.push( - context.propertiesTable( + context.partials.propertiesTable( group.children, - context.groupTitle(group.title) === - context.getTextContent('kind.event.plural'), + context.text.groupTitle(group.title) === + context.text.get('kind.event.plural'), ), ); } else if ( isEnumGroup && context.options.getValue('enumMembersFormat') === 'table' ) { - md.push(context.enumMembersTable(group.children)); + md.push(context.partials.enumMembersTable(group.children)); } else { pushChildren(group.children, headingLevel + 1); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/page.title.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/page.title.ts index 88361e813..b29860768 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/page.title.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/page.title.ts @@ -3,10 +3,7 @@ import { ProjectReflection, ReflectionKind, } from 'typedoc'; -import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; - -import { getMemberTitle } from '../../helpers'; +import { MarkdownPageEvent, MarkdownThemeRenderContext } from '../../..'; /** * @category Partials @@ -18,23 +15,25 @@ export function pageTitle( if (page.model?.url === page.project.url) { const titleContent = context.options.isSet('indexPageTitle') ? context.options.getValue('indexPageTitle') - : context.getTextContent('title.indexPage'); - return context.indexTitle( + : context.text.get('title.indexPage'); + return context.text.indexTitle( titleContent, page.project.name, page.project.packageVersion, ); } - const name = getMemberTitle(page.model as DeclarationReflection); + const name = context.partials.memberTitle( + page.model as DeclarationReflection, + ); const textContent = page.model.kindOf(ReflectionKind.Module) - ? context.getTextContent('title.modulePage') + ? context.text.get('title.modulePage') : context.options.isSet('memberPageTitle') ? context.options.getValue('memberPageTitle') - : context.getTextContent('title.memberPage'); + : context.text.get('title.memberPage'); return textContent .replace('{name}', name) - .replace('{kind}', context.kindString(page.model.kind)); + .replace('{kind}', context.text.kindString(page.model.kind)); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.enum-members.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.enum-members.ts index 529702b8d..03454723e 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.enum-members.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.enum-members.ts @@ -1,8 +1,5 @@ import { DeclarationReflection, ReflectionType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; -import { stripLineBreaks } from '../../../support/utils'; -import { getDeclarationType } from '../../helpers'; /** * @category Partials @@ -11,20 +8,22 @@ export function enumMembersTable( context: MarkdownThemeRenderContext, props: DeclarationReflection[], ): string { + const { backTicks } = context.markdown; + const { stripLineBreaks } = context.utils; const comments = props.map((param) => !!param.comment?.hasVisibleComponent()); const hasComments = comments.some((value) => Boolean(value)); const headers = [ - context.getTextContent('kind.enumMember.singular'), - context.getTextContent('label.value'), + context.text.get('kind.enumMember.singular'), + context.text.get('label.value'), ]; if (hasComments) { - headers.push(context.getTextContent('label.description')); + headers.push(context.text.get('label.description')); } const rows = props.map((property: DeclarationReflection) => { - const propertyType = getDeclarationType(property); + const propertyType = context.helpers.getDeclarationType(property); const row: string[] = []; const nameColumn: string[] = []; @@ -38,13 +37,16 @@ export function enumMembersTable( row.push(nameColumn.join(' ')); if (propertyType) { - row.push(stripLineBreaks(context.someType(propertyType))); + row.push(stripLineBreaks(context.partials.someType(propertyType))); } if (hasComments) { const comments = getComments(property); if (comments) { row.push( - stripLineBreaks(context.comment(comments)).replace(/\|/g, '\\|'), + stripLineBreaks(context.partials.comment(comments)).replace( + /\|/g, + '\\|', + ), ); } else { row.push('-'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.parameters.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.parameters.ts index 61d84f592..30ffc62b8 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.parameters.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.parameters.ts @@ -1,11 +1,5 @@ import { ParameterReflection, ReflectionKind } from 'typedoc'; - import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, table } from '../../../support/elements'; -import { - formatTableDescriptionCol, - stripLineBreaks, -} from '../../../support/utils'; /** * @category Partials @@ -14,6 +8,9 @@ export function parametersTable( context: MarkdownThemeRenderContext, parameters: ParameterReflection[], ): string { + const { table, backTicks } = context.markdown; + const { stripLineBreaks, formatTableDescriptionCol } = context.utils; + const parseParams = (current: any, acc: any) => { const shouldFlatten = current.type?.declaration?.kind === ReflectionKind.TypeLiteral && @@ -46,16 +43,16 @@ export function parametersTable( const hasComments = parsedParams.some((param) => Boolean(param.comment)); const headers = [ - context.getTextContent('kind.parameter.singular'), - context.getTextContent('label.type'), + context.text.get('kind.parameter.singular'), + context.text.get('label.type'), ]; if (showDefaults) { - headers.push(context.getTextContent('label.defaultValue')); + headers.push(context.text.get('label.defaultValue')); } if (hasComments) { - headers.push(context.getTextContent('label.description')); + headers.push(context.text.get('label.description')); } const firstOptionalParamIndex = parameters.findIndex( @@ -78,18 +75,22 @@ export function parametersTable( row.push(`${rest}${backTicks(parameter.name)}${optional}`); if (parameter.type) { - row.push(stripLineBreaks(context.someType(parameter.type), false)); + row.push( + stripLineBreaks(context.partials.someType(parameter.type), false), + ); } if (showDefaults) { - row.push(getDefaultValue(parameter)); + row.push(backTicks(context.helpers.getParameterDefaultValue(parameter))); } if (hasComments) { if (parameter.comment) { row.push( stripLineBreaks( - formatTableDescriptionCol(context.comment(parameter.comment)), + formatTableDescriptionCol( + context.partials.comment(parameter.comment), + ), ), ); } else { @@ -102,12 +103,6 @@ export function parametersTable( return table(headers, rows); } -function getDefaultValue(parameter: ParameterReflection) { - return parameter.defaultValue && parameter.defaultValue !== '...' - ? backTicks(parameter.defaultValue) - : backTicks('undefined'); -} - function hasDefaultValues(parameters: ParameterReflection[]) { const defaultValues = (parameters as ParameterReflection[]).map( (param) => diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.properties.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.properties.ts index 3f8517fb7..b7cf09c68 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.properties.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.properties.ts @@ -1,15 +1,5 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, strikeThrough, table } from '../../../support/elements'; -import { - formatTableDescriptionCol, - stripLineBreaks, -} from '../../../support/utils'; -import { - flattenDeclarations, - getDeclarationType, - getModifier, -} from '../../helpers'; /** * @category Partials @@ -19,7 +9,10 @@ export function propertiesTable( props: DeclarationReflection[], isEventProps = false, ): string { - const modifiers = props.map((param) => getModifier(param)); + const { backTicks, table, strikeThrough } = context.markdown; + const { formatTableDescriptionCol, stripLineBreaks } = context.utils; + + const modifiers = props.map((param) => context.helpers.getModifier(param)); const hasModifiers = modifiers.some((value) => Boolean(value)); const hasOverrides = props.some((prop) => Boolean(prop.overwrites)); const hasInheritance = props.some((prop) => Boolean(prop.inheritedFrom)); @@ -30,35 +23,35 @@ export function propertiesTable( const headers: string[] = []; if (hasModifiers) { - headers.push(context.getTextContent('label.modifier')); + headers.push(context.text.get('label.modifier')); } headers.push( isEventProps - ? context.getTextContent('kind.event.singular') - : context.getTextContent('kind.property.singular'), + ? context.text.get('kind.event.singular') + : context.text.get('kind.property.singular'), ); - headers.push(context.getTextContent('label.type')); + headers.push(context.text.get('label.type')); if (hasComments) { - headers.push(context.getTextContent('label.description')); + headers.push(context.text.get('label.description')); } if (hasOverrides) { - headers.push(context.getTextContent('label.overrides')); + headers.push(context.text.get('label.overrides')); } if (hasInheritance) { - headers.push(context.getTextContent('label.inheritedFrom')); + headers.push(context.text.get('label.inheritedFrom')); } const rows: string[][] = []; - const declarations = flattenDeclarations(props); + const declarations = context.helpers.flattenDeclarations(props); declarations.forEach((property: DeclarationReflection, index: number) => { - const propertyType = getDeclarationType(property); + const propertyType = context.helpers.getDeclarationType(property); const row: string[] = []; if (hasModifiers) { @@ -86,7 +79,7 @@ export function propertiesTable( row.push(nameColumn.join(' ')); if (propertyType) { - row.push(stripLineBreaks(context.someType(propertyType), false)); + row.push(stripLineBreaks(context.partials.someType(propertyType), false)); } if (hasComments) { @@ -96,7 +89,9 @@ export function propertiesTable( const comments = property?.comment; if (hasComment && comments) { row.push( - stripLineBreaks(formatTableDescriptionCol(context.comment(comments))), + stripLineBreaks( + formatTableDescriptionCol(context.partials.comment(comments)), + ), ); } else { row.push('-'); @@ -104,11 +99,11 @@ export function propertiesTable( } if (hasOverrides) { - row.push(context.inheritance(property, -1) || '-'); + row.push(context.partials.inheritance(property, -1) || '-'); } if (hasInheritance) { - row.push(context.inheritance(property, -1) || '-'); + row.push(context.partials.inheritance(property, -1) || '-'); } rows.push(row); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.type-declaration.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.type-declaration.ts index 19a6edb61..f4f575ed7 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.type-declaration.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.type-declaration.ts @@ -1,12 +1,5 @@ import { DeclarationReflection, SomeType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { table } from '../../../support/elements'; -import { - formatTableDescriptionCol, - formatTableNameCol, - stripLineBreaks, -} from '../../../support/utils'; -import { flattenDeclarations } from '../../helpers'; /** * @category Partials @@ -15,15 +8,19 @@ export function typeDeclarationTable( context: MarkdownThemeRenderContext, props: DeclarationReflection[], ): string { + const { table } = context.markdown; + const { formatTableDescriptionCol, stripLineBreaks, formatTableNameCol } = + context.utils; + const headers: string[] = []; - headers.push(context.getTextContent('label.member')); + headers.push(context.text.get('label.member')); - headers.push(context.getTextContent('label.type')); + headers.push(context.text.get('label.type')); - headers.push(context.getTextContent('label.description')); + headers.push(context.text.get('label.description')); - const declarations = flattenDeclarations(props, true); + const declarations = context.helpers.flattenDeclarations(props, true); const rows: string[][] = []; @@ -33,14 +30,18 @@ export function typeDeclarationTable( row.push(formatTableNameCol(declaration.name)); row.push( - context.someType(declaration.type as SomeType).replace(/\n/g, ' '), + context.partials + .someType(declaration.type as SomeType) + .replace(/\n/g, ' '), ); const comments = declaration.comment; if (comments) { row.push( - stripLineBreaks(formatTableDescriptionCol(context.comment(comments))), + stripLineBreaks( + formatTableDescriptionCol(context.partials.comment(comments)), + ), ); } else { row.push('-'); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.typeparameters.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.typeparameters.ts index 4bad09ba8..d0a0ed8f1 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.typeparameters.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/table.typeparameters.ts @@ -1,10 +1,5 @@ import { TypeParameterReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks, table } from '../../../support/elements'; -import { - formatTableDescriptionCol, - stripLineBreaks, -} from '../../../support/utils'; /** * @category Partials @@ -13,6 +8,9 @@ export function typeParametersTable( context: MarkdownThemeRenderContext, typeParameters: TypeParameterReflection[], ): string { + const { backTicks, table } = context.markdown; + const { formatTableDescriptionCol, stripLineBreaks } = context.utils; + const hasDefault = typeParameters.some((typeParameter) => Boolean(typeParameter.default), ); @@ -21,14 +19,14 @@ export function typeParametersTable( Boolean(typeParameter.comment), ); - const headers = [context.getTextContent('kind.typeParameter.singular')]; + const headers = [context.text.get('kind.typeParameter.singular')]; if (hasDefault) { - headers.push(context.getTextContent('label.value')); + headers.push(context.text.get('label.value')); } if (hasComments) { - headers.push(context.getTextContent('label.description')); + headers.push(context.text.get('label.description')); } const rows: string[][] = []; @@ -40,14 +38,14 @@ export function typeParametersTable( nameCol.push(backTicks(typeParameter.name)); if (typeParameter.type) { - nameCol.push(`extends ${context.someType(typeParameter.type)}`); + nameCol.push(`extends ${context.partials.someType(typeParameter.type)}`); } row.push(nameCol.join(' ')); if (hasDefault) { if (typeParameter.default) { - row.push(context.someType(typeParameter.default)); + row.push(context.partials.someType(typeParameter.default)); } else { row.push('-'); } @@ -57,7 +55,9 @@ export function typeParametersTable( if (typeParameter.comment) { row.push( stripLineBreaks( - formatTableDescriptionCol(context.comment(typeParameter.comment)), + formatTableDescriptionCol( + context.partials.comment(typeParameter.comment), + ), ), ); } else { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type-argumentsts.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type-argumentsts.ts index 404c8b372..071d2f023 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type-argumentsts.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type-argumentsts.ts @@ -9,8 +9,8 @@ export function typeArguments( return `\\<${typeArguments .map((typeArgument) => typeArgument instanceof ReflectionType - ? context.reflectionType(typeArgument, foreCollpase) - : context.someType(typeArgument, foreCollpase), + ? context.partials.reflectionType(typeArgument, foreCollpase) + : context.partials.someType(typeArgument, foreCollpase), ) .join(', ')}\\>`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.array.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.array.ts index 0cdce59dc..fe33d48e2 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.array.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.array.ts @@ -8,7 +8,7 @@ export function arrayType( context: MarkdownThemeRenderContext, arrayType: ArrayType, ): string { - const theType = context.someType(arrayType.elementType); + const theType = context.partials.someType(arrayType.elementType); return arrayType.elementType.type === 'union' ? `(${theType})[]` : `${theType}[]`; diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.conditional.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.conditional.ts index b65099ab9..9b1fe79f4 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.conditional.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.conditional.ts @@ -10,19 +10,19 @@ export function conditionalType( ): string { const md: string[] = []; if (conditionalType.checkType) { - md.push(context.someType(conditionalType.checkType)); + md.push(context.partials.someType(conditionalType.checkType)); } md.push('extends'); if (conditionalType.extendsType) { - md.push(context.someType(conditionalType.extendsType)); + md.push(context.partials.someType(conditionalType.extendsType)); } md.push('?'); if (conditionalType.trueType) { - md.push(context.someType(conditionalType.trueType)); + md.push(context.partials.someType(conditionalType.trueType)); } md.push(':'); if (conditionalType.falseType) { - md.push(context.someType(conditionalType.falseType)); + md.push(context.partials.someType(conditionalType.falseType)); } return md.join(' '); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.declaration.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.declaration.ts index eaec4464d..8ac9fea6f 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.declaration.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.declaration.ts @@ -1,7 +1,5 @@ import { DeclarationReflection, SomeType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; -import { getDeclarationType } from '../../helpers'; /** * @category Partials @@ -10,6 +8,7 @@ export function declarationType( context: MarkdownThemeRenderContext, declarationReflection: DeclarationReflection, ): string { + const { backTicks } = context.markdown; if (declarationReflection.indexSignature || declarationReflection.children) { let indexSignature = ''; const declarationIndexSignature = declarationReflection.indexSignature; @@ -19,7 +18,9 @@ export function declarationType( (param) => `\`[${param.name}: ${param.type}]\``, ) : ''; - const obj = context.someType(declarationIndexSignature.type as SomeType); + const obj = context.partials.someType( + declarationIndexSignature.type as SomeType, + ); indexSignature = `${key}: ${obj}; `; } @@ -41,9 +42,9 @@ export function declarationType( name.push(backTicks(obj.name)); - const theType = getDeclarationType(obj) as SomeType; + const theType = context.helpers.getDeclarationType(obj) as SomeType; - const typeString = context.someType(theType); + const typeString = context.partials.someType(theType); return ` ${name.join(' ')}: ${indentBlock(typeString, true)};\n`; }); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.function.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.function.ts index 657fce2a0..1a98136e4 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.function.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.function.ts @@ -1,6 +1,5 @@ import { SignatureReflection, SomeType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -9,6 +8,7 @@ export function functionType( context: MarkdownThemeRenderContext, modelSignatures: SignatureReflection[], ): string { + const { backTicks } = context.markdown; const functions = modelSignatures.map((fn) => { const typeParams = fn.typeParameters ? `\\<${fn.typeParameters @@ -22,7 +22,7 @@ export function functionType( }`; }) : []; - const returns = context.someType(fn.type as SomeType); + const returns = context.partials.someType(fn.type as SomeType); return typeParams + `(${params.join(', ')}) => ${returns}`; }); return functions.join(''); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.index-access.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.index-access.ts index 0efd012ef..7c42491f0 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.index-access.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.index-access.ts @@ -10,10 +10,10 @@ export function indexAccessType( ): string { const md: string[] = []; if (model.objectType) { - md.push(context.someType(model.objectType)); + md.push(context.partials.someType(model.objectType)); } if (model.indexType) { - md.push(`\\[${context.someType(model.indexType)}\\]`); + md.push(`\\[${context.partials.someType(model.indexType)}\\]`); } return md.join(''); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.inferred.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.inferred.ts index 0079c0860..d607cec63 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.inferred.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.inferred.ts @@ -1,6 +1,5 @@ import { InferredType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { escapeChars } from '../../../support/utils'; /** * @category Partials @@ -9,5 +8,6 @@ export function inferredType( context: MarkdownThemeRenderContext, model: InferredType, ): string { + const { escapeChars } = context.utils; return `infer ${escapeChars(model.name)}`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intersection.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intersection.ts index 5bf249ee0..3c7ae6ec6 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intersection.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intersection.ts @@ -9,6 +9,6 @@ export function intersectionType( model: IntersectionType, ): string { return model.types - .map((intersectionType) => context.someType(intersectionType)) + .map((intersectionType) => context.partials.someType(intersectionType)) .join(' & '); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intrinsic.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intrinsic.ts index 7dcd9589f..a62b73aad 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intrinsic.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.intrinsic.ts @@ -1,6 +1,5 @@ import { IntrinsicType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -9,5 +8,6 @@ export function intrinsicType( context: MarkdownThemeRenderContext, model: IntrinsicType, ): string { + const { backTicks } = context.markdown; return backTicks(model.name); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.named-tuple.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.named-tuple.ts index cad57dbc9..b3c5b0339 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.named-tuple.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.named-tuple.ts @@ -8,5 +8,5 @@ export function namedTupleType( context: MarkdownThemeRenderContext, member: NamedTupleMember, ): string { - return context.someType(member.element); + return context.partials.someType(member.element); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.query.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.query.ts index 002f649ae..e66711b5e 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.query.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.query.ts @@ -1,6 +1,5 @@ import { QueryType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { italic } from '../../../support/elements'; /** * @category Partials @@ -9,5 +8,8 @@ export function queryType( context: MarkdownThemeRenderContext, queryType: QueryType, ): string { - return `${italic('typeof')} ${context.someType(queryType.queryType)}`; + const { italic } = context.markdown; + return `${italic('typeof')} ${context.partials.someType( + queryType.queryType, + )}`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reference.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reference.ts index 6996466cb..8d8bc3f27 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reference.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reference.ts @@ -1,6 +1,5 @@ import { ReferenceType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -10,6 +9,7 @@ export function referenceType( referenceType: ReferenceType, foreCollpase = false, ): string { + const { backTicks } = context.markdown; if ( referenceType.reflection || (referenceType.name && referenceType.typeArguments) @@ -18,20 +18,27 @@ export function referenceType( if (referenceType.reflection?.url) { reflection.push( - `[${backTicks(referenceType.reflection.name)}](${context.relativeURL( + context.partials.linkTo( + backTicks(referenceType.reflection.name), referenceType.reflection.url, - )})`, + ), ); } else { reflection.push( referenceType.externalUrl - ? `[${backTicks(referenceType.name)}]( ${referenceType.externalUrl} )` + ? context.partials.linkTo( + backTicks(referenceType.name), + referenceType.externalUrl, + ) : backTicks(referenceType.name), ); } if (referenceType.typeArguments && referenceType.typeArguments.length) { reflection.push( - context.typeArguments(referenceType.typeArguments, foreCollpase), + context.partials.typeArguments( + referenceType.typeArguments, + foreCollpase, + ), ); } return reflection.join(''); diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reflection.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reflection.ts index 489d535ea..8403b8108 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reflection.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.reflection.ts @@ -1,6 +1,5 @@ import { ReflectionType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -10,16 +9,19 @@ export function reflectionType( reflectionType: ReflectionType, foreCollpase = false, ): string { + const { backTicks } = context.markdown; const root = reflectionType instanceof ReflectionType ? reflectionType.declaration : reflectionType; if (root.signatures) { - return context.functionType(root.signatures); + return context.partials.functionType(root.signatures); } const expandObjects = !foreCollpase && (context.options.getValue('expandObjects') as boolean); - return expandObjects ? context.declarationType(root) : backTicks('Object'); + return expandObjects + ? context.partials.declarationType(root) + : backTicks('Object'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.some.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.some.ts index 8d3fb7910..08b72b155 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.some.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.some.ts @@ -16,7 +16,6 @@ import { UnknownType, } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { backTicks } from '../../../support/elements'; /** * @category Partials @@ -26,64 +25,65 @@ export function someType( someType: SomeType, foreCollpase = false, ): string { + const { backTicks } = context.markdown; if (!someType) { return ''; } if (someType instanceof ArrayType) { - return context.arrayType(someType); + return context.partials.arrayType(someType); } if (someType instanceof ConditionalType) { - return context.conditionalType(someType); + return context.partials.conditionalType(someType); } if (someType instanceof IndexedAccessType) { - return context.indexAccessType(someType); + return context.partials.indexAccessType(someType); } if (someType instanceof InferredType) { - return context.inferredType(someType); + return context.partials.inferredType(someType); } if (someType instanceof IntersectionType && someType.types) { - return context.intersectionType(someType); + return context.partials.intersectionType(someType); } if (someType instanceof IntrinsicType && someType.name) { - return context.intrinsicType(someType); + return context.partials.intrinsicType(someType); } if (someType instanceof QueryType) { - return context.queryType(someType); + return context.partials.queryType(someType); } if (someType instanceof ReferenceType) { - return context.referenceType(someType, foreCollpase); + return context.partials.referenceType(someType, foreCollpase); } if (someType instanceof ReflectionType) { - return context.reflectionType(someType, foreCollpase); + return context.partials.reflectionType(someType, foreCollpase); } if (someType instanceof TypeOperatorType) { - return context.typeOperatorType(someType); + return context.partials.typeOperatorType(someType); } if (someType instanceof TupleType && someType.elements) { - return context.tupleType(someType); + return context.partials.tupleType(someType); } if (someType instanceof UnionType && someType.types) { - return context.unionType(someType); + return context.partials.unionType(someType); } if (someType instanceof UnknownType) { - return context.unknownType(someType); + return context.partials.unknownType(someType); } if (someType instanceof NamedTupleMember) { - return context.namedTupleType(someType); + return context.partials.namedTupleType(someType); } if (someType.toString() == 'null') { diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.tuple.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.tuple.ts index 14fb0fc86..d25c8fc57 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.tuple.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.tuple.ts @@ -9,6 +9,6 @@ export function tupleType( tupleType: TupleType, ): string { return `[${tupleType.elements - .map((element) => context.someType(element)) + .map((element) => context.partials.someType(element)) .join(', ')}]`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.type-operator.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.type-operator.ts index cd00df2f8..f992d1a60 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.type-operator.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.type-operator.ts @@ -8,5 +8,5 @@ export function typeOperatorType( context: MarkdownThemeRenderContext, model: TypeOperatorType, ): string { - return `${model.operator} ${context.someType(model.target)}`; + return `${model.operator} ${context.partials.someType(model.target)}`; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.union.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.union.ts index c9c40b2e5..7350c3c09 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.union.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.union.ts @@ -11,7 +11,7 @@ export function unionType( const useCodeBlocks = context.options.getValue('useCodeBlocks'); const shouldFormat = useCodeBlocks && unionType.types.length > 4; const md = unionType.types - .map((unionType) => context.someType(unionType)) + .map((unionType) => context.partials.someType(unionType)) .join(shouldFormat ? `\n \\| ` : ` \\| `); return shouldFormat ? `\n \\| ` + md : md; } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.unknown.ts b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.unknown.ts index 476ed4c10..5a752e15e 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.unknown.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/partials/type.unknown.ts @@ -1,6 +1,5 @@ import { UnknownType } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { escapeChars } from '../../../support/utils'; /** * @category Partials @@ -9,5 +8,5 @@ export function unknownType( context: MarkdownThemeRenderContext, model: UnknownType, ): string { - return escapeChars(model.name); + return context.utils.escapeChars(model.name); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/templates/index.ts b/packages/typedoc-plugin-markdown/src/theme/resources/templates/index.ts index 5eabc7ff2..9076fd795 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/templates/index.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/templates/index.ts @@ -1,4 +1,4 @@ -export * from './member'; -export * from './project'; -export * from './read-me'; -export * from './reflection'; +export { memberTemplate } from './member'; +export { projectTemplate } from './project'; +export { readmeTemplate } from './read-me'; +export { reflectionTemplate } from './reflection'; \ No newline at end of file diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/templates/member.ts b/packages/typedoc-plugin-markdown/src/theme/resources/templates/member.ts index 1df3a32a6..af234426c 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/templates/member.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/templates/member.ts @@ -1,10 +1,11 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { heading } from '../../../support/elements'; +import { MarkdownPageEvent } from '../../..'; /** - * @category Templates + * Function that renders a member template. + * + * @param page The page to render. */ export function memberTemplate( context: MarkdownThemeRenderContext, @@ -12,21 +13,29 @@ export function memberTemplate( ) { const md: string[] = []; + const { heading } = context.markdown; + + md.push(context.hook('page.begin').join('\n')); + if (!context.options.getValue('hidePageHeader')) { - md.push(context.header(page)); + md.push(context.partials.header(page)); } if (!context.options.getValue('hideBreadcrumbs')) { - md.push(context.breadcrumbs(page)); + md.push(context.partials.breadcrumbs(page)); } - if (!context.options.getValue('hidePageTitle')) { - md.push(heading(1, context.pageTitle(page))); - } + md.push(heading(1, context.partials.pageTitle(page))); - md.push(context.member(page.model, 1)); + md.push(context.hook('content.begin').join('\n')); + + md.push(context.partials.member(page.model, 1)); + + if (!context.options.getValue('hideGenerator')) { + md.push(context.partials.generator()); + } - md.push(context.footer()); + md.push(context.hook('page.end').join('\n')); return md.join('\n\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/templates/project.ts b/packages/typedoc-plugin-markdown/src/theme/resources/templates/project.ts index d45567765..875a1fd27 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/templates/project.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/templates/project.ts @@ -1,10 +1,11 @@ import { ProjectReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { heading } from '../../../support/elements'; +import { MarkdownPageEvent } from '../../..'; /** - * @category Templates + * Renders a project/index template. + * + * @param page The page to render. */ export function projectTemplate( context: MarkdownThemeRenderContext, @@ -12,34 +13,44 @@ export function projectTemplate( ) { const md: string[] = []; + md.push(context.hook('page.begin').join('\n')); + + const { heading } = context.markdown; + if (!context.options.getValue('hidePageHeader')) { - md.push(context.header(page)); + md.push(context.partials.header(page)); } if (!context.options.getValue('hideBreadcrumbs')) { - md.push(context.breadcrumbs(page)); + md.push(context.partials.breadcrumbs(page)); } const includeReadme = context.options.getValue('mergeReadme') && Boolean(page.model.readme); if (includeReadme && page.model.readme) { - md.push(context.commentParts(page.model.readme)); + md.push(context.partials.commentParts(page.model.readme)); } - if (!context.options.getValue('hidePageTitle') && !includeReadme) { - md.push(heading(1, context.pageTitle(page))); + if (!includeReadme) { + md.push(heading(1, context.partials.pageTitle(page))); } + md.push(context.hook('content.begin').join('\n')); + if (page.model.comment) { - md.push(context.comment(page.model.comment, 2)); + md.push(context.partials.comment(page.model.comment, 2)); } - md.push(context.pageIndex(page, 2)); + md.push(context.partials.pageIndex(page, 2)); - md.push(context.members(page.model, 2)); + md.push(context.partials.members(page.model, 2)); + + if (!context.options.getValue('hideGenerator')) { + md.push(context.partials.generator()); + } - md.push(context.footer()); + md.push(context.hook('page.end').join('\n')); return md.join('\n\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/templates/read-me.ts b/packages/typedoc-plugin-markdown/src/theme/resources/templates/read-me.ts index c2038f070..2d6476f7c 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/templates/read-me.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/templates/read-me.ts @@ -1,9 +1,11 @@ import { ProjectReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; +import { MarkdownPageEvent } from '../../../'; /** - * @category Templates + * Renders a readme template. + * + * @param page The page to render. */ export function readmeTemplate( context: MarkdownThemeRenderContext, @@ -11,19 +13,25 @@ export function readmeTemplate( ) { const md: string[] = []; + md.push(context.hook('page.begin').join('\n')); + if (!context.options.getValue('hidePageHeader')) { - md.push(context.header(page)); + md.push(context.partials.header(page)); } if (!context.options.getValue('hideBreadcrumbs')) { - md.push(context.breadcrumbs(page)); + md.push(context.partials.breadcrumbs(page)); } if (page.model.readme) { - md.push(context.commentParts(page.model.readme)); + md.push(context.partials.commentParts(page.model.readme)); + } + + if (!context.options.getValue('hideGenerator')) { + md.push(context.partials.generator()); } - md.push(context.footer()); + md.push(context.hook('page.end').join('\n')); return md.join('\n\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/resources/templates/reflection.ts b/packages/typedoc-plugin-markdown/src/theme/resources/templates/reflection.ts index b79fcc1a2..3e4edf602 100644 --- a/packages/typedoc-plugin-markdown/src/theme/resources/templates/reflection.ts +++ b/packages/typedoc-plugin-markdown/src/theme/resources/templates/reflection.ts @@ -1,10 +1,11 @@ import { DeclarationReflection } from 'typedoc'; import { MarkdownThemeRenderContext } from '../..'; -import { MarkdownPageEvent } from '../../../plugin/events'; -import { heading } from '../../../support/elements'; +import { MarkdownPageEvent } from '../../..'; /** - * @category Templates + * Renders a reflection template. + * + * @param page The page to render. */ export function reflectionTemplate( context: MarkdownThemeRenderContext, @@ -12,21 +13,29 @@ export function reflectionTemplate( ) { const md: string[] = []; + md.push(context.hook('page.begin').join('\n')); + + const { heading } = context.markdown; + if (!context.options.getValue('hidePageHeader')) { - md.push(context.header(page)); + md.push(context.partials.header(page)); } if (!context.options.getValue('hideBreadcrumbs')) { - md.push(context.breadcrumbs(page)); + md.push(context.partials.breadcrumbs(page)); } - if (!context.options.getValue('hidePageTitle')) { - md.push(heading(1, context.pageTitle(page))); - } + md.push(heading(1, context.partials.pageTitle(page))); - md.push(context.reflectionMember(page.model, 2)); + md.push(context.hook('content.begin').join('\n')); + + md.push(context.partials.reflectionMember(page.model, 2)); + + if (!context.options.getValue('hideGenerator')) { + md.push(context.partials.generator()); + } - md.push(context.footer()); + md.push(context.hook('page.end').join('\n')); return md.join('\n\n'); } diff --git a/packages/typedoc-plugin-markdown/src/theme/support/support.helpers.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.helpers.ts new file mode 100644 index 000000000..0c04a70ba --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.helpers.ts @@ -0,0 +1,146 @@ +import { + DeclarationReflection, + ParameterReflection, + ReflectionKind, + SignatureReflection, +} from 'typedoc'; + +export const helpers = () => { + return { + getKeyword: (kind: ReflectionKind) => { + const KEYWORD_MAP = { + [ReflectionKind.Class]: 'class', + [ReflectionKind.Interface]: 'interface', + [ReflectionKind.Enum]: 'enum', + [ReflectionKind.TypeAlias]: 'type', + [ReflectionKind.Function]: 'function', + }; + return KEYWORD_MAP[kind]; + }, + getDeclarationType: (declaration: DeclarationReflection) => { + if (declaration.signatures) { + return declaration.signatures[0].type; + } + if (declaration.getSignature) { + return declaration.getSignature.type; + } + if (declaration.setSignature) { + return declaration.setSignature.type; + } + return declaration.type; + }, + getParameterDefaultValue: (parameter: ParameterReflection) => { + return parameter.defaultValue && parameter.defaultValue !== '...' + ? parameter.defaultValue + : 'undefined'; + }, + getModifier(reflection: DeclarationReflection) { + if (reflection.flags.isAbstract) { + return 'abstract'; + } + if (reflection.flags.isPrivate) { + return 'private'; + } + if (reflection.flags.isReadonly) { + return 'readonly'; + } + if (reflection.flags.isStatic) { + return 'static'; + } + if (reflection.flags.isProtected) { + return 'protected'; + } + if (reflection.flags.isPublic) { + return 'public'; + } + if (reflection.getSignature) { + return 'get'; + } + if (reflection.setSignature) { + return 'set'; + } + return null; + }, + isGroupKind(reflection: DeclarationReflection | SignatureReflection) { + const groupKinds = [ + ReflectionKind.Class, + ReflectionKind.Interface, + ReflectionKind.Enum, + ReflectionKind.Function, + ReflectionKind.Variable, + ReflectionKind.TypeAlias, + ]; + return groupKinds.includes(reflection.kind); + }, + flattenDeclarations: ( + props: DeclarationReflection[], + includeSignatures = false, + ) => { + const flattenDeclarations = (current: DeclarationReflection) => { + return (current.type as any)?.declaration?.children?.reduce( + (acc: DeclarationReflection[], child: DeclarationReflection) => { + const childObj = { + ...child, + name: `${current.name}.${child.name}`, + } as DeclarationReflection; + return parseDeclarations(childObj, acc); + }, + [], + ); + }; + + const parseDeclarations = ( + current: DeclarationReflection, + acc: DeclarationReflection[], + ) => { + const shouldFlatten = (current.type as any)?.declaration?.children; + const isAccessor = current.kind === ReflectionKind.Accessor; + + if (includeSignatures) { + if (isAccessor) { + const accessors: any[] = []; + if (current.getSignature) { + accessors.push({ + ...current, + name: `get ${current.name}`, + type: current.getSignature.type, + comment: current.getSignature?.comment, + }); + } + if (current.setSignature) { + accessors.push({ + ...current, + name: `set ${current.name}`, + type: current.setSignature.type, + comment: current.setSignature?.comment, + }); + } + return [...acc, ...accessors]; + } + + if (current.signatures?.length) { + const signatures = current.signatures.map((signature) => { + return { + ...current, + name: signature.name, + type: signature.type, + comment: signature.comment, + }; + }); + return [...acc, ...signatures]; + } + } + + return shouldFlatten + ? [...acc, current, ...flattenDeclarations(current)] + : [...acc, current]; + }; + + return props.reduce( + (acc: DeclarationReflection[], current: DeclarationReflection) => + parseDeclarations(current, acc), + [], + ); + }, + }; +}; diff --git a/packages/typedoc-plugin-markdown/src/theme/support/support.markdown.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.markdown.ts new file mode 100644 index 000000000..73e89f4dd --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.markdown.ts @@ -0,0 +1,89 @@ +export const markdown = () => { + return { + /** + * Returns a heading in markdown format + * @param level The level of the heading + * @param text The text of the heading + */ + heading: (level: number, text: string) => { + level = level > 6 ? 6 : level; + return `${[...Array(level)].map(() => '#').join('')} ${text}`; + }, + /** + * The link element + * @param label The text to display for the link + * @param url The url to link to + */ + link: (label: string, url: string | null) => + url ? `[${label}](${url})` : '', + bold: (text: string) => `**${text}**`, + + italic: (text: string) => `*${text}*`, + + backTicks: (text: string) => + /(\`)/g.test(text) ? text.replace(/`/g, '\\`') : `\`${text}\``, + + unorderedList: (items: T[]) => + items.map((item) => `- ${item}`).join('\n'), + + horizontalRule: () => '\n\n***\n\n', + + codeBlock: (content: string) => { + const unEscapeChars = (str: string) => { + return str + .replace(/\\/g, '>') + .replace(/\\_/g, '_') + .replace(/\\{/g, '{') + .replace(/`/g, '') + .replace(/\*\*/g, '') + .replace(/\\\|/g, '|') + .replace(/\\\]/g, ']') + .replace(/\\\[/g, '[') + .replace(/\[([^\[\]]*)\]\((.*?)\)/gm, '$1'); + }; + const trimLastLine = (content: string) => { + const lines = content.split('\n'); + return lines + .map((line, index) => + index === lines.length - 1 ? line.trim() : line, + ) + .join('\n'); + }; + const trimmedContent = + content.endsWith('}') || + content.endsWith('};') || + content.endsWith('>') || + content.endsWith('>;') + ? trimLastLine(content) + : content; + return '```ts\n' + unEscapeChars(trimmedContent) + '\n```'; + }, + + strikeThrough: (content: string) => `~~${content}~~`, + + table: (headers: string[], rows: string[][]) => + `\n| ${headers.join(' | ')} |\n| ${headers + .map(() => ':------') + .join(' | ')} |\n${rows + .map((row) => `| ${row.join(' | ')} |\n`) + .join('')}`, + + blockQuoteBlock: (content: string) => { + const lines = ( + content.replace(/[\r\n]{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '') + '\n' + ).split('\n'); + return lines + .map((line) => (line.length ? `> ${line.trim()}` : '>')) + .join('\n'); + }, + + indentBlock: (content: string) => { + const lines = content.split('\n'); + return lines + .filter((line) => Boolean(line.length)) + .map((line) => ` ${line}`) + .join('\n'); + }, + }; +}; diff --git a/packages/typedoc-plugin-markdown/src/theme/navigation-context.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.navigation.ts similarity index 56% rename from packages/typedoc-plugin-markdown/src/theme/navigation-context.ts rename to packages/typedoc-plugin-markdown/src/theme/support/support.navigation.ts index 2f3f52163..fc9080cc7 100644 --- a/packages/typedoc-plugin-markdown/src/theme/navigation-context.ts +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.navigation.ts @@ -6,50 +6,56 @@ import { ReflectionCategory, ReflectionGroup, ReflectionKind, - Renderer, - TypeDocOptions, } from 'typedoc'; -import { OutputFileStrategy } from '../options/maps'; -import { NavigationItem } from '../theme/models'; -import { MarkdownTheme } from './theme'; - -export class NavigationContext { - navigation: NavigationItem[] = []; - - constructor( - public theme: MarkdownTheme, - public options: Partial, - public renderer: Renderer, - ) {} - - getNavigation(project: ProjectReflection): NavigationItem[] { - const isPackages = - this.options.entryPointStrategy === EntryPointStrategy.Packages; - - if (isPackages) { - if (Object.keys((this.renderer as any).packages)?.length === 1) { - this.buildNavigationFromProject(project); - } else { - project.children?.forEach((projectChild) => { - this.buildNavigationFromPackage(projectChild); - }); - } +import { MarkdownTheme } from '../..'; +import { OutputFileStrategy } from '../../plugin/options/option-maps'; +import { text } from './support.text'; + +export interface NavigationItem { + title: string; + url?: string; + children?: NavigationItem[]; + isReadme?: boolean; + isGroup?: boolean; +} + +export function getNavigation( + theme: MarkdownTheme, + project: ProjectReflection, +) { + const options = theme.application.options; + const navigation: NavigationItem[] = []; + const optionsForPackages = (theme.application.renderer as any).packageOptions; + + const isPackages = + options.getValue('entryPointStrategy') === EntryPointStrategy.Packages; + + if (isPackages) { + if (Object.keys(optionsForPackages)?.length === 1) { + buildNavigationFromProject(project); } else { - this.buildNavigationFromProject(project); + project.children?.forEach((projectChild) => { + buildNavigationFromPackage(projectChild); + }); } - - return this.navigation; + } else { + buildNavigationFromProject(project); } - buildNavigationFromPackage(projectChild: DeclarationReflection) { - const entryFileName = this.options.entryFileName as string; + return navigation; + + function buildNavigationFromPackage(projectChild: DeclarationReflection) { + const entryFileName = options.getValue('entryFileName'); const preservePackageReadme = - Boolean(projectChild.readme) && !this.options.mergeReadme; + Boolean(projectChild.readme) && !options.getValue('mergeReadme'); + + const packageOptions = optionsForPackages[projectChild.name]; - const packageMeta = (this.renderer as any).packages[projectChild.name]; + const isSet = packageOptions.isSet('outputFileStrategy'); - const outputFileStrategy = - packageMeta?.outputFileStrategy || this.options.outputFileStrategy; + const outputFileStrategy = isSet + ? packageOptions.getValue('outputFileStrategy') + : options.getValue('outputFileStrategy'); const projectChildUrl = preservePackageReadme ? `${path.dirname(projectChild.url as string)}/${entryFileName}` @@ -69,68 +75,62 @@ export class NavigationContext { outputFileStrategy === OutputFileStrategy.Modules ) { children.push({ - title: this.theme.getTextContent('label.globals'), + title: text(options).get('label.globals'), url: projectChild.url, }); } - const childGroups = this.getChildrenOrGroups( - projectChild, - outputFileStrategy, - ); + const childGroups = getChildrenOrGroups(projectChild, outputFileStrategy); if (childGroups) { children.push(...childGroups); } - this.navigation.push({ + navigation.push({ title: projectChild.name, children, ...(projectChildUrl && { url: projectChildUrl }), }); } - buildNavigationFromProject( + function buildNavigationFromProject( project: ProjectReflection | DeclarationReflection, ) { + const entryModule = options.getValue('entryModule'); if (project.groups?.length) { - const entryModule = Boolean( + const isEntryModule = Boolean( project?.groups[0]?.children.find( - (child) => child.name === this.options.entryModule, + (child) => child.name === entryModule, ), ); const isOnlyModules = project.children?.every((child) => child.kindOf(ReflectionKind.Module), ); if ( - (project.groups.length === 1 && !Boolean(entryModule)) || + (project.groups.length === 1 && !Boolean(isEntryModule)) || isOnlyModules ) { - const children = this.getGroupChildren(project.groups[0]); + const children = getGroupChildren(project.groups[0]); if (children) { - this.navigation.push( - ...children.filter( - (child) => child.title !== this.options.entryModule, - ), + navigation.push( + ...children.filter((child) => child.title !== entryModule), ); } } else { project.groups?.forEach((projectGroup) => { - const children = this.getGroupChildren(projectGroup); + const children = getGroupChildren(projectGroup); const indexModule = projectGroup.children.find( - (child) => child.name === this.options.entryModule, + (child) => child.name === entryModule, ); if (children.length) { - this.navigation.push({ + navigation.push({ title: projectGroup.title, - children: children.filter( - (child) => child.title !== this.options.entryModule, - ), + children: children.filter((child) => child.title !== entryModule), }); } if (indexModule) { - const children = this.getChildrenOrGroups(indexModule); + const children = getChildrenOrGroups(indexModule); if (children) { - this.navigation.push(...children); + navigation.push(...children); } } }); @@ -138,11 +138,11 @@ export class NavigationContext { } } - getCategoryGroupChildren(group: ReflectionCategory) { + function getCategoryGroupChildren(group: ReflectionCategory) { return group.children ?.filter((child) => child.hasOwnDocument) .map((child) => { - const children = this.getChildrenOrGroups(child); + const children = getChildrenOrGroups(child); return { title: child.name, url: child.url, @@ -151,7 +151,7 @@ export class NavigationContext { }); } - getGroupChildren( + function getGroupChildren( group: ReflectionGroup, outputFileStrategy?: OutputFileStrategy, ) { @@ -159,7 +159,7 @@ export class NavigationContext { return group.categories?.map((category) => { return { title: category.title, - children: this.getCategoryGroupChildren(category), + children: getCategoryGroupChildren(category), }; }); } @@ -167,7 +167,7 @@ export class NavigationContext { return group.children ?.filter((child) => child.hasOwnDocument) .map((child) => { - const mapping = this.theme.getTemplateMapping( + const mapping = theme.getTemplateMapping( child.kind, outputFileStrategy, ); @@ -176,7 +176,7 @@ export class NavigationContext { const children = child.categories?.length ? child.categories ?.map((category) => { - const catChildren = this.getCategoryGroupChildren(category); + const catChildren = getCategoryGroupChildren(category); return catChildren.length ? { title: category.title, @@ -186,7 +186,7 @@ export class NavigationContext { }) .filter((cat) => Boolean(cat)) - : this.getChildrenOrGroups(child, outputFileStrategy); + : getChildrenOrGroups(child, outputFileStrategy); return { title: child.name, url: child.url, @@ -196,21 +196,18 @@ export class NavigationContext { }); } - getChildrenOrGroups( + function getChildrenOrGroups( reflection: DeclarationReflection, outputFileStrategy?: OutputFileStrategy, ) { if ( reflection.groups?.some((group) => group.allChildrenHaveOwnDocument()) ) { - if (this.options.excludeGroups) { + if (options.getValue('excludeGroups')) { return reflection.children ?.filter((child) => child.hasOwnDocument) .map((child) => { - const children = this.getChildrenOrGroups( - child, - outputFileStrategy, - ); + const children = getChildrenOrGroups(child, outputFileStrategy); return { title: child.name, url: child.url, @@ -225,17 +222,13 @@ export class NavigationContext { if (isModulesGroup) { return ( - this.getGroupChildren(reflection.groups[0], outputFileStrategy) || - null + getGroupChildren(reflection.groups[0], outputFileStrategy) || null ); } return reflection.groups ?.map((group) => { - const groupChildren = this.getGroupChildren( - group, - outputFileStrategy, - ); + const groupChildren = getGroupChildren(group, outputFileStrategy); return groupChildren.length ? { title: group.title, diff --git a/packages/typedoc-plugin-markdown/src/theme/support/support.text.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.text.ts new file mode 100644 index 000000000..ac3da3ce4 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.text.ts @@ -0,0 +1,40 @@ +import { Options, ReflectionKind } from 'typedoc'; +import { TextContentMappings } from '../../plugin/options/option-types'; +import { + PLURAL_KIND_KEY_MAP, + SINGULAR_KIND_KEY_MAP, + TEXT_MAPPING_DEFAULTS, +} from '../../plugin/options/text-mappings'; + +export const text = (options: Options) => { + const textFromOptions = options.getValue('textContentMappings'); + const textMappings = { ...TEXT_MAPPING_DEFAULTS, ...(textFromOptions || {}) }; + return { + /** + * + * @param key The key of the text mapping to get. + * @returns + */ + get: (key: keyof TextContentMappings) => { + return textMappings[key]; + }, + groupTitle(title: string) { + const key = PLURAL_KIND_KEY_MAP[title] as keyof TextContentMappings; + return this.get(key) || title; + }, + kindString(kind: ReflectionKind) { + const singularString = ReflectionKind.singularString(kind); + const key = SINGULAR_KIND_KEY_MAP[ + singularString + ] as keyof TextContentMappings; + return this.get(key) || singularString; + }, + indexTitle(textContent: string, name: string, version?: string) { + return textContent + .replace('{projectName}', name) + .replace('{version}', version ? `v${version}` : '') + .replace(/\s+/g, ' ') + .trim(); + }, + }; +}; diff --git a/packages/typedoc-plugin-markdown/src/theme/support/support.urls.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.urls.ts new file mode 100644 index 000000000..096a90b8b --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.urls.ts @@ -0,0 +1,366 @@ +import * as path from 'path'; +import { + DeclarationReflection, + EntryPointStrategy, + ProjectReflection, + Reflection, + ReflectionKind, +} from 'typedoc'; +import { MarkdownPageEvent, MarkdownTheme } from '../..'; +import { OutputFileStrategy } from '../../plugin/options/option-maps'; + +export interface UrlOption { + parentUrl?: string; + directory?: string | null; + forceDirectory?: boolean; + outputFileStrategy?: OutputFileStrategy; +} + +export interface TemplateMapping { + directory: string | null; + template: any; + kind: ReflectionKind; +} + +export interface UrlMapping { + url: string; + model: Model; + template: RenderTemplate>; +} + +export type RenderTemplate = (data: T) => string; + +/** + * Map the models of the given project to the desired output files. + * Based on TypeDoc DefaultTheme.getUrls() + * + * @param project The project whose urls should be generated. + */ +export function getUrls(theme: MarkdownTheme, project: ProjectReflection) { + const options = theme.application.options; + const optionsForPackages = (theme.application.renderer as any).packageOptions; + const urls: UrlMapping[] = []; + const anchors: Record = {}; + + const preserveReadme = + Boolean(project.readme) && !options.getValue('mergeReadme'); + + const preserveModulesPage = + (project?.groups && + Boolean( + project?.groups[0]?.children.find( + (child) => child.name === options.getValue('entryModule'), + ), + )) || + false; + + const isPackages = + options.getValue('entryPointStrategy') === EntryPointStrategy.Packages; + + const entryFileName = options.getValue('entryFileName'); + + const indexFilename = getIndexFileName(project, isPackages); + + project.url = preserveReadme + ? indexFilename + : preserveModulesPage + ? indexFilename + : options.getValue('entryFileName'); + + if (preserveReadme) { + urls.push({ + url: preserveModulesPage ? 'readme_.md' : entryFileName, + model: project, + template: theme.readmeTemplate, + }); + urls.push({ + url: indexFilename, + model: project, + template: theme.projectTemplate, + }); + } else { + urls.push({ + url: preserveModulesPage ? indexFilename : entryFileName, + model: project, + template: theme.projectTemplate, + }); + } + + if (isPackages) { + if (Object.keys(optionsForPackages)?.length === 1) { + buildUrlsFromProject(project); + } else { + project.children?.forEach((projectChild) => { + buildUrlsFromPackage(projectChild); + }); + } + } else { + buildUrlsFromProject(project); + } + + return urls; + + function buildUrlsFromProject( + project: ProjectReflection | DeclarationReflection, + parentUrl?: string, + outputFileStrategy?: OutputFileStrategy, + ) { + project.groups?.forEach((projectGroup) => { + projectGroup.children?.forEach((projectGroupChild) => { + buildUrlsFromGroup(projectGroupChild, { + ...(parentUrl && { parentUrl }), + ...(outputFileStrategy && { outputFileStrategy }), + }); + }); + }); + } + + function buildUrlsFromPackage(projectChild: DeclarationReflection) { + const entryFileName = options.getValue('entryFileName'); + const preservePackageReadme = + Boolean(projectChild.readme) && !options.getValue('mergeReadme'); + + const packagesIndex = getIndexFileName(projectChild); + + const packageOptions = optionsForPackages[projectChild.name]; + + const isSet = packageOptions.isSet('outputFileStrategy'); + + const outputFileStrategy = isSet + ? packageOptions.getValue('outputFileStrategy') + : options.getValue('outputFileStrategy'); + + const url = `${projectChild.name}/${ + preservePackageReadme ? packagesIndex : entryFileName + }`; + + if (preservePackageReadme) { + urls.push({ + url: `${path.dirname(url)}/${entryFileName}`, + model: projectChild as any, + template: theme.readmeTemplate, + }); + } + urls.push({ + url: url, + model: projectChild as any, + template: theme.projectTemplate, + }); + + projectChild.url = url; + + buildUrlsFromProject(projectChild, url, outputFileStrategy); + } + + function buildUrlsFromGroup( + reflection: DeclarationReflection, + options: UrlOption, + ) { + const mapping: TemplateMapping = theme.getTemplateMapping( + reflection.kind, + options.outputFileStrategy, + ); + + if (mapping) { + const directory = options.directory || mapping.directory; + const urlPath = getUrlPath(reflection, { + ...options, + directory, + }); + + const url = getUrl(reflection, urlPath); + urls.push({ + url: url, + model: reflection, + template: mapping.template, + }); + + reflection.url = url; + reflection.hasOwnDocument = true; + + reflection.groups?.forEach((group) => { + group.children.forEach((groupChild) => { + const mapping = theme.getTemplateMapping( + groupChild.kind, + options.outputFileStrategy, + ); + buildUrlsFromGroup(groupChild, { + parentUrl: urlPath, + directory: mapping?.directory || null, + outputFileStrategy: options.outputFileStrategy, + }); + }); + }); + } else if (reflection.parent) { + applyAnchorUrl(reflection, reflection.parent); + } + } + + function getUrl(reflection: DeclarationReflection, urlPath: string) { + if (reflection.name === options.getValue('entryModule')) { + return options.getValue('entryFileName'); + } + if ( + options.getValue('outputFileStrategy') === OutputFileStrategy.Modules && + reflection.name === 'index' + ) { + return urlPath.replace('index.md', 'module.index.md'); + } + return urlPath; + } + + function getUrlPath(reflection: DeclarationReflection, urlOption: UrlOption) { + const alias = reflection.name + .replace(/^_+/, '') + .replace(//, '-'); + + const parentDir = urlOption.parentUrl + ? path.dirname(urlOption.parentUrl) + : null; + + const dir = () => { + if (reflection.kind === ReflectionKind.Namespace) { + return `${urlOption.directory}/${alias}`; + } + + if (reflection.kind === ReflectionKind.Module) { + return alias; + } + + const slugifyUrl = (url: string) => { + return url + .toLowerCase() + .trim() + .replace(/[^\w\s-]/g, '') + .replace(/[\s_-]+/g, '-') + .replace(/^-+|-+$/g, ''); + }; + + return urlOption.directory + ? urlOption.directory + : `${slugifyUrl( + ReflectionKind.singularString(reflection.kind), + )}.${alias}`; + }; + + const filename = () => { + if ( + [ReflectionKind.Module, ReflectionKind.Namespace].includes( + reflection.kind, + ) && + options.getValue('outputFileStrategy') === OutputFileStrategy.Modules && + !childrenIncludeNamespaces(reflection) + ) { + return null; + } + if ( + [ReflectionKind.Module, ReflectionKind.Namespace].includes( + reflection.kind, + ) + ) { + return path.parse(options.getValue('entryFileName')).name; + } + return alias; + }; + + return ( + [parentDir, dir(), filename()].filter((part) => Boolean(part)).join('/') + + '.md' + ); + } + + function applyAnchorUrl( + reflection: DeclarationReflection, + container: Reflection, + ) { + if (container.url) { + if (!reflection.kindOf(ReflectionKind.TypeLiteral)) { + const anchorPrefix = options.getValue('anchorPrefix'); + const anchorId = getAnchorId(reflection); + + if (anchorId) { + if (!anchors[container.url]) { + anchors[container.url] = []; + } + + anchors[container.url].push(anchorId); + + const count = anchors[container.url]?.filter((id) => id === anchorId) + ?.length; + + const anchorParts = [anchorId]; + + if (count > 1) { + anchorParts.push(`-${count - 1}`); + } + + if (anchorPrefix) { + anchorParts.unshift(`${anchorPrefix}`); + } + + reflection.url = container.url + '#' + anchorParts.join(''); + reflection.anchor = anchorParts.join(''); + } + } + reflection.hasOwnDocument = false; + } + if (reflection.parent) { + reflection.traverse((child) => { + if (child instanceof DeclarationReflection) { + applyAnchorUrl(child, container); + } + }); + } + } + + function getAnchorId(reflection: DeclarationReflection) { + const preserveAnchorCasing = options.getValue('preserveAnchorCasing'); + + const anchorName = getAnchorName(reflection); + + if (anchorName) { + return preserveAnchorCasing ? anchorName : anchorName.toLowerCase(); + } + + return null; + } + + function getAnchorName(reflection: DeclarationReflection) { + const htmlTableAnchors = options.getValue('namedAnchors'); + + if (!htmlTableAnchors) { + if ( + (reflection.kindOf(ReflectionKind.Property) && + options.getValue('propertiesFormat') === 'table') || + (reflection.kindOf(ReflectionKind.EnumMember) && + options.getValue('enumMembersFormat') === 'table') + ) { + return null; + } + } + if (reflection.kindOf(ReflectionKind.Constructor)) { + return 'Constructors'; + } + return reflection.name; + } + + function childrenIncludeNamespaces(reflection: DeclarationReflection) { + return reflection.children?.some( + (child) => child.kind === ReflectionKind.Namespace, + ); + } + + function getIndexFileName( + reflection: ProjectReflection | DeclarationReflection, + isPackages = false, + ) { + if (isPackages) { + return 'packages.md'; + } + const isModules = reflection.children?.every((child) => + child.kindOf(ReflectionKind.Module), + ); + return isModules ? 'modules.md' : 'globals.md'; + } +} diff --git a/packages/typedoc-plugin-markdown/src/theme/support/support.utils.ts b/packages/typedoc-plugin-markdown/src/theme/support/support.utils.ts new file mode 100644 index 000000000..dc2dc58d9 --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/support/support.utils.ts @@ -0,0 +1,73 @@ +import * as path from 'path'; + +/** + * A set of pure utils to be consumed accross the plugin. + * + */ +export const utils = () => { + return { + parseUrl: (url: string) => encodeURI(url), + escapeChars: (str: string) => { + return str + .replace(/>/g, '\\>') + .replace(/ { + const re = /<(?=(?:[^`]*`[^`]*`)*[^`]*$)[^<]+?>/gi; + return str.replace(re, (tags) => { + const htmlRe = + /<(?!\/?(div|span|p|a|br|img|ul|li|strike|em|strong|b)(>|\s))[^<]+?>/g; + const shouldEscape = tags.match(htmlRe); + return shouldEscape + ? tags.replace(/>/g, '>` ').replace(/ { + return str + .replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:^\s*\/\/(?:.*)$)/g, ' ') + .replace(/\n/g, '') + .replace(/^\s+|\s+$|(\s)+/g, '$1'); + }, + + formatTableDescriptionCol: (str: string) => { + return str.replace(/\|/g, '\\|'); + }, + + formatTableNameCol: (str: string) => { + return str.includes('|') ? str.replace(/\|/g, '\\|') : `\`${str}\``; + }, + + stripLineBreaks: (str: string, includeHTML = true) => { + return str + .replace( + /\n(?=(?:[^`]*`[^`]*`)*[^`]*$)/gi, + includeHTML ? '
' : ' ', + ) + .replace(/\`\`\`ts/g, '`') + .replace(/\`\`\`/g, '`') + .replace(/\n/g, ' '); + }, + getRelativeUrl(url: string, root?: string) { + const baseUrl = path.relative( + path.dirname(root || '.'), + path.dirname(url), + ); + const relativeUrl = path + .join(baseUrl, path.basename(url)) + .replace(/\\/g, '/'); + return relativeUrl; + }, + }; +}; diff --git a/packages/typedoc-plugin-markdown/src/theme/theme-render-context.ts b/packages/typedoc-plugin-markdown/src/theme/theme-render-context.ts new file mode 100644 index 000000000..efc08b61b --- /dev/null +++ b/packages/typedoc-plugin-markdown/src/theme/theme-render-context.ts @@ -0,0 +1,72 @@ +import { Options, Reflection } from 'typedoc'; +import { MarkdownPageEvent, MarkdownTheme } from '..'; +import { MarkdownRenderer, MarkdownRendererHooks } from '../plugin/types'; +import { partials, templates } from './resources'; +import { helpers } from './support/support.helpers'; +import { markdown } from './support/support.markdown'; +import { text } from './support/support.text'; +import { utils } from './support/support.utils'; + +/* start_imports */ +/* end_imports */ + +/** + * The render context of the {@link MarkdownTheme}. + * This follows the implementation of TypeDocs [DefaultThemeRenderContext](https://typedoc.org/api/classes/DefaultThemeRenderContext.html) + */ + +export class MarkdownThemeRenderContext { + /** + * @param page The page this context is created for. + * @param options The options used by TypeDoc. See TypeDoc's {@link typedoc!Options | Options} Class. + */ + constructor( + private theme: MarkdownTheme, + readonly page: MarkdownPageEvent | null, + readonly options: Options, + ) {} + + /** + * Returns an object with methods for generating markdown syntax. + * + * Each method returns a string formatted according to markdown rules. + * + * This can consumed by theme templates and partials using the syntax `context.markdown.method()`. + */ + markdown = markdown(); + + /** + * A set of pure utils to be consumed accross the plugin. + * + * These can be consumed by theme templates and partials using the syntax `context.utils.method()`. + */ + utils = utils(); + + /** + * A set of methods to return strings from specific TypeDoc models. + * + * These can be consumed by theme templates and partials using the syntax `context.models.method()`. + */ + helpers = helpers(); + + /** + * The theme's global text context. + */ + text = text(this.options); + + /** + * The theme's global templates context. + */ + templates = templates(this); + + /** + * The theme's global partials context. + */ + partials = partials(this); + + /** + * Hook into the TypeDoc rendering system. + */ + hook = (name: keyof MarkdownRendererHooks) => + (this.theme.owner as MarkdownRenderer).markdownHooks.emit(name, this); +} diff --git a/packages/typedoc-plugin-markdown/src/theme/theme.ts b/packages/typedoc-plugin-markdown/src/theme/theme.ts index bf0dffe1a..842054b1d 100644 --- a/packages/typedoc-plugin-markdown/src/theme/theme.ts +++ b/packages/typedoc-plugin-markdown/src/theme/theme.ts @@ -1,136 +1,86 @@ import { DeclarationReflection, + DefaultTheme, ProjectReflection, Reflection, ReflectionKind, - RenderTemplate, Renderer, Theme, } from 'typedoc'; -import { OutputFileStrategy, StaticText } from '../options/maps'; -import { TextContentMappings } from '../options/models'; -import { MarkdownPageEvent } from '../plugin/events'; -import { UrlMapping } from '../plugin/url-mapping'; -import { slugify } from '../support/utils'; -import { NavigationItem, TemplateMapping } from './models'; -import { NavigationContext } from './navigation-context'; -import { MarkdownThemeRenderContext } from './render-context'; -import { UrlsContext } from './urls-context'; + +import { MarkdownPageEvent } from '../plugin'; +import { OutputFileStrategy } from '../plugin/options/option-maps'; +import { getNavigation } from './support/support.navigation'; +import { RenderTemplate, getUrls } from './support/support.urls'; +import { MarkdownThemeRenderContext } from './theme-render-context'; /** * This is in-built MarkdownTheme which extends TypeDocs Theme class. - * This follows the implementation of TypeDoc's [DefaultTheme](https://typedoc.org/api/classes/DefaultThemeRender.html). + * This follows the implementation of TypeDoc's {@link DefaultTheme}. * - * The {@link render } and {@link getUrls} methods is where the work happens. */ export class MarkdownTheme extends Theme { - textMappings: TextContentMappings; - /** * * @param renderer The TypeDoc renderer instance the theme is attached to. */ constructor(renderer: Renderer) { super(renderer); - - // DEPRECATED PROPS WARNING (to delete) - const deprecatedOptions = [ - 'indexPageTitle', - 'memberPageTitle', - 'hideInPageTOC', - ]; - - deprecatedOptions.forEach((option) => { - if (this.application.options.isSet(option)) { - this.application.logger.warn( - `[typedoc-plugin-markdown] "${option}" is deprecated and will be removed in v4 release. Please see https://www.typedoc-plugin-markdown.org/options#${option.toLowerCase()}`, - ); - } - }); - - this.textMappings = this.getTextContentMappings(); - } - - getRenderContext(pageEvent: MarkdownPageEvent | null) { - return new MarkdownThemeRenderContext( - this, - pageEvent, - this.application.options, - ); + this.runDeprecatedWanings(); } - getTextContent(key: keyof TextContentMappings) { - return this.textMappings[key]; - } - - private getTextContentMappings() { - const textFromOptions = this.application.options.getValue( - 'textContentMappings', - ); - const knownKeys = Object.keys(StaticText); - for (const key of Object.keys(textFromOptions)) { - if (!knownKeys.includes(key)) { - this.application.logger.warn( - `[typedoc-plugin-markdown] "${key}" is not a valid "textContentMappings" key. Valid keys are ${knownKeys - .map((key) => `"${key}"`) - .join(', ')}.`, - ); - } + /** + * Renders a template and page model to a string. + */ + render( + page: MarkdownPageEvent, + template: RenderTemplate>, + ) { + try { + return this.formatContents(template(page)); + } catch (e) { + this.application.logger.error( + `Error rendering page ${page.url} using template ${template.name}: ${e.message}`, + ); + throw new Error(e); } - return { ...StaticText, ...(textFromOptions || {}) }; } - private getNavigationContext() { - return new NavigationContext( - this, - this.application.options.getRawValues(), - this.application.renderer, - ); - } - - private getUrlsContext(project: ProjectReflection) { - return new UrlsContext( - this, - project, - this.application.renderer, - this.application.options, - ); + /** + * Creates a instance of render context for each page template. + */ + getRenderContext(page: MarkdownPageEvent | null) { + return new MarkdownThemeRenderContext(this, page, this.application.options); } - readmeTemplate = (pageEvent: MarkdownPageEvent) => { - return this.getRenderContext(pageEvent).readmeTemplate(pageEvent); + readmeTemplate = (page: MarkdownPageEvent) => { + return this.getRenderContext(page).templates.readmeTemplate(page); }; - projectTemplate = (pageEvent: MarkdownPageEvent) => { - return this.getRenderContext(pageEvent).projectTemplate(pageEvent); + projectTemplate = (page: MarkdownPageEvent) => { + return this.getRenderContext(page).templates.projectTemplate(page); }; - reflectionTemplate = ( - pageEvent: MarkdownPageEvent, - ) => { - return this.getRenderContext(pageEvent).reflectionTemplate(pageEvent); + reflectionTemplate = (page: MarkdownPageEvent) => { + return this.getRenderContext(page).templates.reflectionTemplate(page); }; - memberTemplate = (pageEvent: MarkdownPageEvent) => { - return this.getRenderContext(pageEvent).memberTemplate(pageEvent); + memberTemplate = (page: MarkdownPageEvent) => { + return this.getRenderContext(page).templates.memberTemplate(page); }; - /** - * Renders a template and page model to a string. - */ - render( - page: MarkdownPageEvent, - template: RenderTemplate>, - ) { - return template(page) as string; + getUrls(project: ProjectReflection) { + return getUrls(this, project); } - getUrls(project: ProjectReflection): UrlMapping[] { - return this.getUrlsContext(project).getUrls(); + getNavigation(project: ProjectReflection) { + return getNavigation(this, project); } - getNavigation(project: ProjectReflection): NavigationItem[] { - return this.getNavigationContext().getNavigation(project); + formatContents(contents: string) { + return ( + contents.replace(/[\r\n]{3,}/g, '\n\n').replace(/^\s+|\s+$/g, '') + '\n' + ); } /** @@ -140,19 +90,16 @@ export class MarkdownTheme extends Theme { getTemplateMapping( kind: ReflectionKind, outputFileStrategyOverride?: OutputFileStrategy, - ): TemplateMapping { + ) { const outputFileStrategy = outputFileStrategyOverride || this.application.options.getValue('outputFileStrategy'); const getDirectoryName = (reflectionKind: ReflectionKind) => { const pluralString = ReflectionKind.pluralString(reflectionKind); - return slugify(pluralString).toLowerCase(); + return pluralString.replace(/[\s_-]+/g, '-').toLowerCase(); }; - // const membersWithOwnFile = - // this.application.options.getValue('membersWithOwnFile'); - const mappings = { [ReflectionKind.Module]: { template: this.reflectionTemplate, @@ -166,67 +113,70 @@ export class MarkdownTheme extends Theme { }, }; - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.Class]) - ) { - mappings[ReflectionKind.Class] = { - template: this.reflectionTemplate, - directory: getDirectoryName(ReflectionKind.Class), - kind: ReflectionKind.Class, + const getMemberMapping = ( + template: (pageEvent: MarkdownPageEvent) => string, + kind: ReflectionKind, + ) => { + return { + template, + directory: getDirectoryName(kind), + kind: kind, }; + }; + + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.Class] = getMemberMapping( + this.reflectionTemplate, + ReflectionKind.Class, + ); } - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.Interface]) - ) { - mappings[ReflectionKind.Interface] = { - isLeaf: false, - template: this.reflectionTemplate, - directory: getDirectoryName(ReflectionKind.Interface), - kind: ReflectionKind.Interface, - }; + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.Interface] = getMemberMapping( + this.reflectionTemplate, + ReflectionKind.Interface, + ); } - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.Enum]) - ) { - mappings[ReflectionKind.Enum] = { - template: this.reflectionTemplate, - directory: getDirectoryName(ReflectionKind.Enum), - kind: ReflectionKind.Enum, - }; + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.Enum] = getMemberMapping( + this.reflectionTemplate, + ReflectionKind.Enum, + ); } - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.Function]) - ) { - mappings[ReflectionKind.Function] = { - template: this.memberTemplate, - directory: getDirectoryName(ReflectionKind.Function), - kind: ReflectionKind.Function, - }; + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.Function] = getMemberMapping( + this.memberTemplate, + ReflectionKind.Function, + ); } - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.TypeAlias]) - ) { - mappings[ReflectionKind.TypeAlias] = { - template: this.memberTemplate, - directory: getDirectoryName(ReflectionKind.TypeAlias), - kind: ReflectionKind.TypeAlias, - }; + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.TypeAlias] = getMemberMapping( + this.memberTemplate, + ReflectionKind.TypeAlias, + ); } - if ( - outputFileStrategy === OutputFileStrategy.Members //&& - //membersWithOwnFile?.includes(ReflectionKind[ReflectionKind.Variable]) - ) { - mappings[ReflectionKind.Variable] = { - template: this.memberTemplate, - directory: getDirectoryName(ReflectionKind.Variable), - kind: ReflectionKind.Variable, - }; + if (outputFileStrategy === OutputFileStrategy.Members) { + mappings[ReflectionKind.Variable] = getMemberMapping( + this.memberTemplate, + ReflectionKind.Variable, + ); } return mappings[kind]; } + + private runDeprecatedWanings() { + // DEPRECATED PROPS WARNING (to delete) + const deprecatedOptions = [ + 'indexPageTitle', + 'memberPageTitle', + 'hideInPageTOC', + ]; + + deprecatedOptions.forEach((option) => { + if (this.application.options.isSet(option)) { + this.application.logger.warn( + `[typedoc-plugin-markdown] "${option}" is deprecated and will be removed in v4 release. Please see https://www.typedoc-plugin-markdown.org/options#${option.toLowerCase()}`, + ); + } + }); + } } diff --git a/packages/typedoc-plugin-markdown/src/theme/urls-context.ts b/packages/typedoc-plugin-markdown/src/theme/urls-context.ts deleted file mode 100644 index e7d3fc0eb..000000000 --- a/packages/typedoc-plugin-markdown/src/theme/urls-context.ts +++ /dev/null @@ -1,339 +0,0 @@ -import * as path from 'path'; -import { - DeclarationReflection, - EntryPointStrategy, - Options, - ProjectReflection, - Reflection, - ReflectionKind, - Renderer, -} from 'typedoc'; -import { OutputFileStrategy } from '../options/maps'; -import { UrlMapping } from '../plugin/url-mapping'; -import { slugify } from '../support/utils'; -import { getIndexFileName } from './helpers'; -import { UrlOption } from './models'; -import { MarkdownTheme } from './theme'; - -export class UrlsContext { - urls: UrlMapping[] = []; - anchors: Record = {}; - - constructor( - public theme: MarkdownTheme, - public project: ProjectReflection, - public renderer: Renderer, - public options: Options, - ) {} - - /** - * Map the models of the given project to the desired output files. - * Based on TypeDoc DefaultTheme.getUrls() - * - * @param project The project whose urls should be generated. - */ - getUrls(): UrlMapping[] { - const preserveReadme = - Boolean(this.project.readme) && !this.options.getValue('mergeReadme'); - - const preserveModulesPage = - (this.project?.groups && - Boolean( - this.project?.groups[0]?.children.find( - (child) => child.name === this.options.getValue('entryModule'), - ), - )) || - false; - - const isPackages = - this.options.getValue('entryPointStrategy') === - EntryPointStrategy.Packages; - - const entryFileName = this.options.getValue('entryFileName'); - - const indexFilename = getIndexFileName(this.project, isPackages); - - this.project.url = preserveReadme - ? indexFilename - : preserveModulesPage - ? indexFilename - : this.options.getValue('entryFileName'); - - if (preserveReadme) { - this.urls.push( - new UrlMapping( - preserveModulesPage ? 'readme_.md' : entryFileName, - this.project, - this.theme.readmeTemplate, - ), - ); - - this.urls.push( - new UrlMapping(indexFilename, this.project, this.theme.projectTemplate), - ); - } else { - this.urls.push( - new UrlMapping( - preserveModulesPage ? indexFilename : entryFileName, - this.project, - this.theme.projectTemplate, - ), - ); - } - - if (isPackages) { - if (Object.keys((this.renderer as any).packages)?.length === 1) { - this.buildUrlsFromProject(this.project); - } else { - this.project.children?.forEach((projectChild) => { - this.buildUrlsFromPackage(projectChild); - }); - } - } else { - this.buildUrlsFromProject(this.project); - } - return this.urls; - } - - private buildUrlsFromPackage(projectChild: DeclarationReflection) { - const entryFileName = this.options.getValue('entryFileName'); - const preservePackageReadme = - Boolean(projectChild.readme) && !this.options.getValue('mergeReadme'); - - const packagesIndex = getIndexFileName(projectChild); - const packageMeta = (this.renderer as any).packages[projectChild.name]; - - const outputFileStrategy = - packageMeta?.outputFileStrategy || - this.options.getValue('outputFileStrategy'); - - const url = `${projectChild.name}/${ - preservePackageReadme ? packagesIndex : entryFileName - }`; - - if (preservePackageReadme) { - this.urls.push( - new UrlMapping( - `${path.dirname(url)}/${entryFileName}`, - projectChild as any, - this.theme.readmeTemplate, - ), - ); - } - - this.urls.push( - new UrlMapping(url, projectChild as any, this.theme.projectTemplate), - ); - - projectChild.url = url; - - this.buildUrlsFromProject(projectChild, url, outputFileStrategy); - } - - /** - * - * @param project - * @param isPackage - */ - private buildUrlsFromProject( - project: ProjectReflection | DeclarationReflection, - parentUrl?: string, - outputFileStrategy?: OutputFileStrategy, - ) { - project.groups?.forEach((projectGroup) => { - projectGroup.children?.forEach((projectGroupChild) => { - this.buildUrlsFromGroup(projectGroupChild, { - ...(parentUrl && { parentUrl }), - ...(outputFileStrategy && { outputFileStrategy }), - }); - }); - }); - } - - private buildUrlsFromGroup( - reflection: DeclarationReflection, - options: UrlOption, - ) { - const mapping = this.theme.getTemplateMapping( - reflection.kind, - options.outputFileStrategy, - ); - - if (mapping) { - const directory = options.directory || mapping.directory; - const urlPath = this.getUrlPath(reflection, { - ...options, - directory, - }); - - const url = this.getUrl(reflection, urlPath); - - this.urls.push(new UrlMapping(url, reflection, mapping.template)); - reflection.url = url; - reflection.hasOwnDocument = true; - - reflection.groups?.forEach((group) => { - group.children.forEach((groupChild) => { - const mapping = this.theme.getTemplateMapping( - groupChild.kind, - options.outputFileStrategy, - ); - this.buildUrlsFromGroup(groupChild, { - parentUrl: urlPath, - directory: mapping?.directory || null, - outputFileStrategy: options.outputFileStrategy, - }); - }); - }); - } else if (reflection.parent) { - this.applyAnchorUrl(reflection, reflection.parent); - } - } - - getUrl(reflection: DeclarationReflection, urlPath: string) { - if (reflection.name === this.options.getValue('entryModule')) { - return this.options.getValue('entryFileName'); - } - if ( - this.options.getValue('outputFileStrategy') === - OutputFileStrategy.Modules && - reflection.name === 'index' - ) { - return urlPath.replace('index.md', 'module.index.md'); - } - return urlPath; - } - - getUrlPath(reflection: DeclarationReflection, options: UrlOption) { - const alias = reflection.name - .replace(/^_+/, '') - .replace(//, '-'); - - const parentDir = options.parentUrl - ? path.dirname(options.parentUrl) - : null; - - const dir = () => { - if (reflection.kind === ReflectionKind.Namespace) { - return `${options.directory}/${alias}`; - } - - if (reflection.kind === ReflectionKind.Module) { - return alias; - } - - return options.directory - ? options.directory - : `${slugify(ReflectionKind.singularString(reflection.kind))}.${alias}`; - }; - - const filename = () => { - if ( - [ReflectionKind.Module, ReflectionKind.Namespace].includes( - reflection.kind, - ) && - this.options.getValue('outputFileStrategy') === - OutputFileStrategy.Modules && - !this.childrenIncludeNamespaces(reflection) - ) { - return null; - } - if ( - [ReflectionKind.Module, ReflectionKind.Namespace].includes( - reflection.kind, - ) - ) { - return path.parse(this.options.getValue('entryFileName')).name; - } - return alias; - }; - - return ( - [parentDir, dir(), filename()].filter((part) => Boolean(part)).join('/') + - '.md' - ); - } - - private applyAnchorUrl( - reflection: DeclarationReflection, - container: Reflection, - ) { - if (container.url) { - if (!reflection.kindOf(ReflectionKind.TypeLiteral)) { - const anchorPrefix = this.options.getValue('anchorPrefix'); - const anchorId = this.getAnchorId(reflection); - - if (anchorId) { - if (!this.anchors[container.url]) { - this.anchors[container.url] = []; - } - - this.anchors[container.url].push(anchorId); - - const count = this.anchors[container.url]?.filter( - (id) => id === anchorId, - )?.length; - - const anchorParts = [anchorId]; - - if (count > 1) { - anchorParts.push(`-${count - 1}`); - } - - if (anchorPrefix) { - anchorParts.unshift(`${anchorPrefix}`); - } - - reflection.url = container.url + '#' + anchorParts.join(''); - reflection.anchor = anchorParts.join(''); - } - } - reflection.hasOwnDocument = false; - } - if (reflection.parent) { - reflection.traverse((child) => { - if (child instanceof DeclarationReflection) { - this.applyAnchorUrl(child, container); - } - }); - } - } - - private getAnchorId(reflection: DeclarationReflection) { - const preserveAnchorCasing = this.options.getValue('preserveAnchorCasing'); - - const anchorName = this.getAnchorName(reflection); - - if (anchorName) { - return preserveAnchorCasing ? anchorName : anchorName.toLowerCase(); - } - - return null; - } - - private getAnchorName(reflection: DeclarationReflection) { - const htmlTableAnchors = this.options.getValue('namedAnchors'); - - if (!htmlTableAnchors) { - if ( - (reflection.kindOf(ReflectionKind.Property) && - this.options.getValue('propertiesFormat') === 'table') || - (reflection.kindOf(ReflectionKind.EnumMember) && - this.options.getValue('enumMembersFormat') === 'table') - ) { - return null; - } - } - if (reflection.kindOf(ReflectionKind.Constructor)) { - return 'Constructors'; - } - return reflection.name; - } - - private childrenIncludeNamespaces(reflection: DeclarationReflection) { - return reflection.children?.some( - (child) => child.kind === ReflectionKind.Namespace, - ); - } -} diff --git a/packages/typedoc-plugin-markdown/test/__scripts__/prepare.ts b/packages/typedoc-plugin-markdown/test/__scripts__/prepare.ts index 3bfc73638..c87eb1d35 100644 --- a/packages/typedoc-plugin-markdown/test/__scripts__/prepare.ts +++ b/packages/typedoc-plugin-markdown/test/__scripts__/prepare.ts @@ -1,4 +1,4 @@ -import { spawn, spawnSync } from 'child_process'; +import { spawn } from 'child_process'; import { consola } from 'consola'; import * as fs from 'fs-extra'; import * as path from 'path'; @@ -31,12 +31,6 @@ consola.start(`Building ${fixtureCount} test fixtures...`); // remove output dir fs.removeSync(`./test/out`); -// build the custom plugin -spawnSync('tsc', { - stdio: 'inherit', - cwd: path.join(__dirname, '..', 'custom-plugins'), -}); - // write fixtures fixturesToRun.forEach((fixture) => { writeHtml(fixture.entryPoints, fixture.outDir); @@ -106,6 +100,10 @@ export function writeHtml( 'Warn', '--readme', 'none', + '--media', + '../../stubs/media', + '--includes', + '../../stubs/inc', '--includeVersion', '-entryPoints', `../../stubs/${entryPoints}`, @@ -144,7 +142,7 @@ function objectToOptions(obj: any) { '-plugin', 'typedoc-plugin-markdown', '-plugin', - path.join(__dirname, '..', 'custom-plugins', 'navigation-plugin'), + path.join(__dirname, '..', 'custom-plugins', 'navigation-plugin.mjs'), ], ); } diff --git a/packages/typedoc-plugin-markdown/test/__utils__/fixture-config.ts b/packages/typedoc-plugin-markdown/test/__utils__/fixture-config.ts index fabc337ad..8eb9e95b5 100644 --- a/packages/typedoc-plugin-markdown/test/__utils__/fixture-config.ts +++ b/packages/typedoc-plugin-markdown/test/__utils__/fixture-config.ts @@ -15,6 +15,7 @@ export enum FixtureEntryPoints { EntryFiles = '/src/entryfiles/*', Readme = '/src/readme/index.ts', Text = '/src/text/*.ts', + Customize = '/src/customize/index.ts', } export enum FixtureOutputDir { @@ -26,6 +27,7 @@ export enum FixtureOutputDir { EntryFiles = 'entryfiles', Readme = 'readme', Text = 'text', + Customize = 'customize', } export const FIXTURES: Fixture[] = [ @@ -68,9 +70,6 @@ export const FIXTURES: Fixture[] = [ categorizeByGroup: false, excludeGroups: true, namedAnchors: true, - //membersWithOwnFile: ['Class', 'Interface', 'Enum'], - plugin: [path.join(__dirname, '..', 'custom-plugins', 'custom-theme')], - theme: 'custom-theme', indexFormat: 'table', indexPageTitle: '{projectName}', }, @@ -87,6 +86,8 @@ export const FIXTURES: Fixture[] = [ enumMembersFormat: 'table', propertiesFormat: 'table', readme: 'none', + media: '../../stubs/media', + includes: '../../stubs/inc', }, options: [ {}, @@ -160,4 +161,23 @@ export const FIXTURES: Fixture[] = [ }, ], }, + { + outDir: FixtureOutputDir.Customize, + entryPoints: FixtureEntryPoints.Customize, + commonOptions: { + disableSources: true, + hideGenerator: true, + readme: 'none', + outputFileStrategy: 'modules', + }, + membersOnly: true, + options: [ + { + plugin: [ + path.join(__dirname, '..', 'custom-plugins', 'custom-theme.mjs'), + ], + theme: 'custom-theme', + }, + ], + }, ]; diff --git a/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.mjs b/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.mjs new file mode 100644 index 000000000..429aaea60 --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.mjs @@ -0,0 +1,74 @@ +// @ts-check +import * as fs from 'fs'; +import { + MarkdownTheme, + MarkdownThemeRenderContext, +} from 'typedoc-plugin-markdown'; + +/** + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + app.renderer.defineTheme('custom-theme', MyMarkdownTheme); + + app.renderer.markdownHooks.on( + 'page.begin', + () => '> TOP BANNER using `page.begin` hook', + ); + + app.renderer.markdownHooks.on( + 'page.end', + () => `**Generated using \`page.end\` hook**`, + ); + + app.renderer.markdownHooks.on( + 'content.begin', + () => '> CONTENT BANNER using `content.begin` hook', + ); + + app.renderer.preRenderAsyncJobs.push(async (output) => { + await new Promise((r) => setTimeout(r, 5)); + fs.writeFileSync( + `${output.outputDirectory}/pre-render.txt`, + 'pre render success', + ); + }); + + app.renderer.postRenderAsyncJobs.push(async (output) => { + await new Promise((r) => setTimeout(r, 5)); + fs.writeFileSync( + `${output.outputDirectory}/post-render.txt`, + 'post render success', + ); + }); +} + +class MyMarkdownTheme extends MarkdownTheme { + /** + * @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page + */ + getRenderContext(page) { + return new MyMarkdownThemeRenderContext( + this, + page, + this.application.options, + ); + } +} + +class MyMarkdownThemeRenderContext extends MarkdownThemeRenderContext { + partials = { + ...this.partials, + /** + * @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page + */ + header: (page) => { + return ` +
+ My logo + Welcome to ${page.project.name} with a customised header partial!! +
+`; + }, + }; +} diff --git a/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.ts b/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.ts deleted file mode 100644 index 1322039e2..000000000 --- a/packages/typedoc-plugin-markdown/test/custom-plugins/custom-theme.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Application, PageEvent, Reflection } from 'typedoc'; -import { MarkdownTheme, MarkdownThemeRenderContext } from '../../dist'; - -export function load(app: Application) { - app.renderer.defineTheme('custom-theme', CustomTheme); -} - -class CustomTheme extends MarkdownTheme { - override getRenderContext(pageEvent: PageEvent) { - return new ThemeRenderContext(this, pageEvent, this.application.options); - } -} - -class ThemeRenderContext extends MarkdownThemeRenderContext { - override footer = () => { - return 'CUSTOM FOOTER HERE'; - }; -} diff --git a/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.mjs b/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.mjs new file mode 100644 index 000000000..1a440965a --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.mjs @@ -0,0 +1,15 @@ +// @ts-check + +import * as fs from 'fs'; + +/** + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + app.renderer.postRenderAsyncJobs.push(async (output) => { + fs.writeFileSync( + `${output.outputDirectory}/sidebar.json`, + JSON.stringify(output.navigation, null, 2), + ); + }); +} diff --git a/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.ts b/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.ts deleted file mode 100644 index 053ce08bc..000000000 --- a/packages/typedoc-plugin-markdown/test/custom-plugins/navigation-plugin.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as fs from 'fs'; -import { Application } from 'typedoc'; -import { MarkdownRendererEvent } from '../../dist'; - -export function load(app: Application) { - app.renderer.postRenderAsyncJobs.push( - async (output: MarkdownRendererEvent) => { - fs.writeFileSync( - `${output.outputDirectory}/sidebar.json`, - JSON.stringify(output.navigation, null, 2), - ); - }, - ); -} diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/comments.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/comments.spec.ts.snap index 26f49aaeb..f09b0d0fd 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/comments.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/comments.spec.ts.snap @@ -45,6 +45,19 @@ A in a code block Some

html

inside codeblock \`\`\` +## Media + +You can include media in doc comments: + +![alt SomeAlt](media/logo.png) + +And include other files: + +This is a simple example on how to use include. + +![My image alt text](media/logo.png) + [[include:not-found.md]] + ## Enumerations - [CommentEnum](enumerations/CommentEnum.md) @@ -108,6 +121,19 @@ A in a code block Some

html

inside codeblock \`\`\` +## Media + +You can include media in doc comments: + +![alt SomeAlt](media/logo.png) + +And include other files: + +This is a simple example on how to use include. + +![My image alt text](media/logo.png) + [[include:not-found.md]] + ## Enumerations - [CommentEnum](enumerations/CommentEnum.md) @@ -171,6 +197,19 @@ A in a code block Some

html

inside codeblock \`\`\` +## Media + +You can include media in doc comments: + +![alt SomeAlt](media/logo.png) + +And include other files: + +This is a simple example on how to use include. + +![My image alt text](media/logo.png) + [[include:not-found.md]] + ## Enumerations ### CommentEnum @@ -275,6 +314,19 @@ A in a code block Some

html

inside codeblock \`\`\` +## Media + +You can include media in doc comments: + +![alt SomeAlt](media/logo.png) + +And include other files: + +This is a simple example on how to use include. + +![My image alt text](media/logo.png) + [[include:not-found.md]] + ## Enumerations diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/customization.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/customization.spec.ts.snap new file mode 100644 index 000000000..cc0310a36 --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/customization.spec.ts.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Customization should action post-render-async jobs: (Output File Strategy "members") (Option Group "1") 1`] = `"post render success"`; + +exports[`Customization should action pre-render-async jobs: (Output File Strategy "members") (Option Group "1") 1`] = `"post render success"`; + +exports[`Customization should insert content from hooks and apply custom theme: (Output File Strategy "members") (Option Group "1") 1`] = ` +"> TOP BANNER using \`page.begin\` hook + +
+ My logo + Welcome to typedoc-stubs with a customised header partial!! +
+ +# typedoc-stubs + +> CONTENT BANNER using \`content.begin\` hook + +Module commments + +## Functions + +### someFunction() + +> **someFunction**(): \`void\` + +#### Returns + +\`void\` + +**Generated using \`page.end\` hook** +" +`; diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/groups.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/groups.spec.ts.snap index 5a41c03ab..aed0f649f 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/groups.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/groups.spec.ts.snap @@ -75,8 +75,6 @@ A basic module | :------ | :------ | | [TypeA](type-aliases/TypeA.md) | - | | [TypeB](type-aliases/TypeB.md) | - | - -CUSTOM FOOTER HERE " `; @@ -257,8 +255,6 @@ A basic module ## TypeB > **TypeB**: \`string\` - -CUSTOM FOOTER HERE " `; @@ -389,8 +385,6 @@ A module that contains categories ### UnCategorizedInterace - -CUSTOM FOOTER HERE " `; @@ -478,8 +472,6 @@ A module that contains categories | :------ | :------ | | [UnCategorizedEnum](enumerations/UnCategorizedEnum.md) | - | | [UnCategorizedInterace](interfaces/UnCategorizedInterace.md) | - | - -CUSTOM FOOTER HERE " `; @@ -520,8 +512,6 @@ exports[`Groups should compile index page for project: (Output File Strategy "me | [has-namespaces](has-namespaces/index.md) | A module that contains namespaces | | [has-references](has-references/index.md) | A module that contains references | | [index](index/index.md) | A module named index | - -CUSTOM FOOTER HERE " `; @@ -562,8 +552,6 @@ exports[`Groups should compile index page for project: (Output File Strategy "mo | [has-namespaces](has-namespaces/index.md) | A module that contains namespaces | | [has-references](has-references.md) | A module that contains references | | [index](module.index.md) | A module named index | - -CUSTOM FOOTER HERE " `; @@ -610,8 +598,6 @@ exports[`Groups should compile module index for a namespace: (Output File Strate | Interface | Description | | :------ | :------ | | [NamespaceInterface](interfaces/NamespaceInterface.md) | - | - -CUSTOM FOOTER HERE " `; @@ -652,8 +638,6 @@ exports[`Groups should compile module index for a namespace: (Output File Strate ## NamespaceInterface - -CUSTOM FOOTER HERE " `; @@ -768,8 +752,6 @@ A module that contains namespaces | :------ | :------ | | [\\_function\\_A\\_](functions/function_A_.md) | - | | [functionB](functions/functionB.md) | - | - -CUSTOM FOOTER HERE " `; @@ -1010,8 +992,6 @@ A module that contains namespaces ### Returns \`void\` - -CUSTOM FOOTER HERE " `; @@ -1107,8 +1087,6 @@ Renames and re-exports [defaultFunction](has-references.md#defaultfunction) ### Returns \`string\` - -CUSTOM FOOTER HERE " `; @@ -1185,7 +1163,5 @@ Renames and re-exports [InterfaceB](../basic/interfaces/InterfaceB.md) ## default Renames and re-exports [defaultFunction](functions/defaultFunction.md) - -CUSTOM FOOTER HERE " `; diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.function.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.function.spec.ts.snap index bf41dddf1..7c12b3bd4 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.function.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.function.spec.ts.snap @@ -69,13 +69,13 @@ Comments for function exports[`Function Reflection should compile function returning a promise: (Output File Strategy "members") (Option Group "1") 1`] = ` "# Function: functionReturningAPromise() -> **functionReturningAPromise**(): [\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`Object\`\\> +> **functionReturningAPromise**(): [\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`Object\`\\> Comments for function ## Returns -[\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`Object\`\\> +[\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`Object\`\\> Return comments @@ -103,7 +103,7 @@ Comments for function ## Returns -[\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`Object\`\\> +[\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`Object\`\\> Return comments diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.type-alias.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.type-alias.spec.ts.snap index e92e7b1b5..0f77367bb 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.type-alias.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.type-alias.spec.ts.snap @@ -155,7 +155,7 @@ comment for y.z ### accessorA -> **\`get\`** **accessorA**(): [\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`string\`\\> +> **\`get\`** **accessorA**(): [\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`string\`\\> Comments for accessorA getter @@ -165,11 +165,11 @@ Comments for accessorA setter #### Parameters -• **x**: [\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`string\`\\> +• **x**: [\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`string\`\\> #### Returns -[\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`string\`\\> +[\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`string\`\\> ### accessorB @@ -195,7 +195,7 @@ Comments for someFunction #### Returns -[\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`any\`\\> +[\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`any\`\\> ## Source @@ -233,11 +233,11 @@ Comments for LiteralType | \`y.y\` | \`boolean\` \\| \`string\` | comment for y.y | | \`y.z\` | (\`x\`) => \`string\` | comment for y.z | | \`z\` | (\`x\`) => \`string\` | - | -| \`get accessorA\` | [\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`string\`\\> | Comments for accessorA getter | +| \`get accessorA\` | [\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`string\`\\> | Comments for accessorA getter | | \`set accessorA\` | \`void\` | Comments for accessorA setter | | \`get accessorB\` | \`string\` | - | | \`set accessorB\` | \`void\` | - | -| \`someFunction\` | [\`Promise\`]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise )\\<\`any\`\\> | Comments for someFunction | +| \`someFunction\` | [\`Promise\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\\<\`any\`\\> | Comments for someFunction | ## Source diff --git a/packages/typedoc-plugin-markdown/test/specs/customization.spec.ts b/packages/typedoc-plugin-markdown/test/specs/customization.spec.ts new file mode 100644 index 000000000..a401bf467 --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/specs/customization.spec.ts @@ -0,0 +1,31 @@ +import { + FixtureOutputDir, + FixtureOutputFileStrategy, +} from '../__utils__/fixture-config'; +import { expectFileToEqual } from '../__utils__/helpers'; + +describe(`Customization`, () => { + test(`should insert content from hooks and apply custom theme`, () => { + expectFileToEqual( + FixtureOutputDir.Customize, + FixtureOutputFileStrategy.Members, + ['README.md'], + ); + }); + + test(`should action pre-render-async jobs`, () => { + expectFileToEqual( + FixtureOutputDir.Customize, + FixtureOutputFileStrategy.Members, + ['post-render.txt'], + ); + }); + + test(`should action post-render-async jobs`, () => { + expectFileToEqual( + FixtureOutputDir.Customize, + FixtureOutputFileStrategy.Members, + ['post-render.txt'], + ); + }); +}); diff --git a/packages/typedoc-plugin-markdown/typedoc.base.json b/packages/typedoc-plugin-markdown/typedoc.base.json new file mode 100644 index 000000000..901417dc4 --- /dev/null +++ b/packages/typedoc-plugin-markdown/typedoc.base.json @@ -0,0 +1,28 @@ +{ + "entryPoints": ["./src/plugin/*", "./src/theme/resources/partials/index.ts"], + "readme": "none", + "excludePrivate": true, + "excludeReferences": true, + "excludeExternals": true, + "sort": ["instance-first", "required-first"], + "cleanOutputDir": true, + "externalSymbolLinkMappings": { + "typedoc": { + "Application": "https://typedoc.org/api/classes/Application.html", + "CommentDisplayPart": "https://typedoc.org/api/types/Models.CommentDisplayPart.html", + "DeclarationReflection": "https://typedoc.org/api/classes/Models.DeclarationReflection.html", + "DefaultThemeRenderContext": "https://typedoc.org/api/classes/DefaultThemeRenderContext.html", + "Options": "https://typedoc.org/api/classes/Configuration.Options.html", + "PageEvent": "https://typedoc.org/api/classes/PageEvent.html", + "ProjectReflection": "https://typedoc.org/api/classes/Models.ProjectReflection.html", + "Renderer": "https://typedoc.org/api/classes/Renderer.html", + "RendererEvent": "https://typedoc.org/api/classes/RendererEvent.html", + "RenderTemplate": "https://typedoc.org/api/types/RenderTemplate.html", + "Reflection": "https://typedoc.org/api/classes/Models.Reflection.html", + "ReflectionGroup": "https://typedoc.org/api/classes/Models.ReflectionGroup.html", + "Theme": "https://typedoc.org/api/classes/Theme.html", + "TypeDocOptions": "https://typedoc.org/api/interfaces/TypeDocOptions.html", + "UrlMapping": "https://typedoc.org/api/classes/UrlMapping.html" + } + } +} diff --git a/packages/typedoc-plugin-markdown/typedoc.md.json b/packages/typedoc-plugin-markdown/typedoc.md.json new file mode 100644 index 000000000..dee91c1bb --- /dev/null +++ b/packages/typedoc-plugin-markdown/typedoc.md.json @@ -0,0 +1,10 @@ +{ + "extends": "./typedoc.base.json", + "plugin": ["typedoc-plugin-markdown"], + "outputFileStrategy": "modules", + "hidePageHeader": true, + "hideBreadcrumbs": true, + "expandObjects": true, + "useCodeBlocks": false, + "excludeGroups": true +} diff --git a/packages/typedoc-plugin-remark/src/options/option-types.ts b/packages/typedoc-plugin-remark/src/options/option-types.ts new file mode 100644 index 000000000..6b653aaaa --- /dev/null +++ b/packages/typedoc-plugin-remark/src/options/option-types.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY. + +import { ManuallyValidatedOption } from 'typedoc'; + +declare module 'typedoc' { + export interface TypeDocOptionMap { + remarkPlugins: ManuallyValidatedOption; + } +} + +export interface PluginOptions { + remarkPlugins: ManuallyValidatedOption; +} + +export interface RemarkPlugins {} diff --git a/packages/typedoc-plugin-remark/test/typedoc.base.json b/packages/typedoc-plugin-remark/test/typedoc.base.json index 6ca02d0f7..c05ec3c1c 100644 --- a/packages/typedoc-plugin-remark/test/typedoc.base.json +++ b/packages/typedoc-plugin-remark/test/typedoc.base.json @@ -5,7 +5,6 @@ "plugin": ["typedoc-plugin-markdown", "typedoc-plugin-remark"], "readme": "none", "parametersFormat": "table", - "githubPages": false, "disableSources": true, "cleanOutputDir": true, "hideGenerator": true, diff --git a/packages/typedoc-vitepress-theme/package.json b/packages/typedoc-vitepress-theme/package.json index f03235f8d..6ad618622 100644 --- a/packages/typedoc-vitepress-theme/package.json +++ b/packages/typedoc-vitepress-theme/package.json @@ -23,7 +23,8 @@ "build": "tsc", "build-and-test": "npm run build && npm run test", "pretest": "ts-node ./test/__scripts__/prepare.ts", - "test": "jest" + "test": "jest", + "test:update": "npm run build && npm test -- -u" }, "peerDependencies": { "typedoc-plugin-markdown": ">=4.0.0-next.41" diff --git a/packages/typedoc-vitepress-theme/src/options/option-types.ts b/packages/typedoc-vitepress-theme/src/options/option-types.ts new file mode 100644 index 000000000..db7847cf9 --- /dev/null +++ b/packages/typedoc-vitepress-theme/src/options/option-types.ts @@ -0,0 +1,22 @@ +// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY. + +import { ManuallyValidatedOption } from 'typedoc'; + +declare module 'typedoc' { + export interface TypeDocOptionMap { + docsRoot: string; + sidebar: ManuallyValidatedOption; + } +} + +export interface PluginOptions { + docsRoot: string; + sidebar: ManuallyValidatedOption; +} + +export interface Sidebar { + autoConfiguration: boolean; + format: string; + pretty: boolean; + collapsed: boolean; +} diff --git a/packages/typedoc-vitepress-theme/src/theme.ts b/packages/typedoc-vitepress-theme/src/theme.ts index 85a305603..7cfa582b8 100644 --- a/packages/typedoc-vitepress-theme/src/theme.ts +++ b/packages/typedoc-vitepress-theme/src/theme.ts @@ -12,14 +12,17 @@ export class VitepressTheme extends MarkdownTheme { } class ThemeRenderContext extends MarkdownThemeRenderContext { - override parseUrl(url: string) { - const urlWithAnchor = url.split('#'); - if (urlWithAnchor.length > 1) { - const anchorPart = slugify(urlWithAnchor[1]); - return encodeURI(`${urlWithAnchor[0]}#${anchorPart}`); - } - return encodeURI(url); - } + override utils = { + ...this.utils, + parseUrl: (url: string) => { + const urlWithAnchor = url.split('#'); + if (urlWithAnchor.length > 1) { + const anchorPart = slugify(urlWithAnchor[1]); + return encodeURI(`${urlWithAnchor[0]}#${anchorPart}`); + } + return encodeURI(url); + }, + }; } function slugify(str: string) { diff --git a/packages/typedoc-vitepress-theme/test/__scripts__/prepare.ts b/packages/typedoc-vitepress-theme/test/__scripts__/prepare.ts index f25149301..11de50dff 100644 --- a/packages/typedoc-vitepress-theme/test/__scripts__/prepare.ts +++ b/packages/typedoc-vitepress-theme/test/__scripts__/prepare.ts @@ -27,7 +27,7 @@ function writeMarkdown(fixture: any) { '-options', `./test/${fixture.options}`, '-logLevel', - 'Info', + 'Warn', '-out', `./test/out/${fixture.outDir}`, ], diff --git a/packages/typedoc-vitepress-theme/test/specs/__snapshots__/vitepress.spec.ts.snap b/packages/typedoc-vitepress-theme/test/specs/__snapshots__/vitepress.spec.ts.snap index 4baa6f750..b0a571239 100644 --- a/packages/typedoc-vitepress-theme/test/specs/__snapshots__/vitepress.spec.ts.snap +++ b/packages/typedoc-vitepress-theme/test/specs/__snapshots__/vitepress.spec.ts.snap @@ -86,3 +86,10 @@ exports[`VitePress should output docs with vitepress theme 1`] = ` - [module-2](module-2/index.md) " `; + +exports[`VitePress should output members that require anchor slugification 1`] = ` +"# Interface: InterfaceA + +See [InterfaceB._prop_with_underscore_](InterfaceB.md#prop-with-underscore) +" +`; diff --git a/packages/typedoc-vitepress-theme/test/specs/vitepress.spec.ts b/packages/typedoc-vitepress-theme/test/specs/vitepress.spec.ts index 4a8579d21..faa471eab 100644 --- a/packages/typedoc-vitepress-theme/test/specs/vitepress.spec.ts +++ b/packages/typedoc-vitepress-theme/test/specs/vitepress.spec.ts @@ -8,6 +8,18 @@ describe(`VitePress`, () => { expect(contents).toMatchSnapshot(); }); + test(`should output members that require anchor slugification`, async () => { + const contents = fs + .readFileSync( + path.join( + __dirname, + '../out/default/module-1/interfaces/InterfaceA.md', + ), + ) + .toString(); + expect(contents).toMatchSnapshot(); + }); + test(`should generate typedoc sidebar`, async () => { const contents = fs .readFileSync(path.join(__dirname, '../out/default/typedoc-sidebar.json')) diff --git a/packages/typedoc-vitepress-theme/test/typedoc.base.json b/packages/typedoc-vitepress-theme/test/typedoc.base.json index 5a9935b63..9eaf4cc90 100644 --- a/packages/typedoc-vitepress-theme/test/typedoc.base.json +++ b/packages/typedoc-vitepress-theme/test/typedoc.base.json @@ -4,7 +4,6 @@ "out": "./out", "plugin": ["typedoc-plugin-markdown", "typedoc-vitepress-theme"], "readme": "none", - "githubPages": false, "disableSources": true, "cleanOutputDir": true, "hideGenerator": true, diff --git a/stubs/media/logo.svg b/stubs/media/logo.svg new file mode 100644 index 000000000..6c748a479 --- /dev/null +++ b/stubs/media/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stubs/src/comments/index.ts b/stubs/src/comments/index.ts index 3363c336e..21489919b 100644 --- a/stubs/src/comments/index.ts +++ b/stubs/src/comments/index.ts @@ -41,6 +41,15 @@ * A in a code block * Some

html

inside codeblock * ``` + * @media + * + * You can include media in doc comments: + * + * ![alt SomeAlt](media://logo.png) + * + * And include other files: + * + * [[include:example.md]] [[include:not-found.md]] */ export interface CommentInterface { diff --git a/stubs/src/customize/index.ts b/stubs/src/customize/index.ts new file mode 100644 index 000000000..3b90ec41f --- /dev/null +++ b/stubs/src/customize/index.ts @@ -0,0 +1,7 @@ +/** + * Module commments + * + * @module + */ + +export function someFunction() {} diff --git a/stubs/typedoc.cjs b/stubs/typedoc.cjs index d1ad532fc..92c36d8ab 100644 --- a/stubs/typedoc.cjs +++ b/stubs/typedoc.cjs @@ -1,7 +1,6 @@ const path = require('path'); module.exports = { cleanOutputDir: true, - githubPages: false, sourceLinkTemplate: 'http://source-url', tsconfig: path.join(__dirname, './tsconfig.json'), externalSymbolLinkMappings: {