diff --git a/.changeset/chatty-cheetahs-love.md b/.changeset/chatty-cheetahs-love.md new file mode 100644 index 000000000..8df8d950a --- /dev/null +++ b/.changeset/chatty-cheetahs-love.md @@ -0,0 +1,5 @@ +--- +'typedoc-plugin-markdown': minor +--- + +- Exposed formatting with prettier options (--formatWithPrettier and --prettierConfigFile). diff --git a/docs/pages/docs/options.mdx b/docs/pages/docs/options.mdx index d06d22a10..ae321a3de 100644 --- a/docs/pages/docs/options.mdx +++ b/docs/pages/docs/options.mdx @@ -47,6 +47,8 @@ Options that are used to configure how the output is structured and displayed. Options that are used for general configuration and utility purposes. +- [--formatWithPrettier](./options/utility-options.mdx#--formatwithprettier) +- [--prettierConfigFile](./options/utility-options.mdx#--prettierconfigfile) - [--sanitizeComments](./options/utility-options.mdx#--sanitizecomments) - [--publicPath](./options/utility-options.mdx#--publicpath) - [--anchorPrefix](./options/utility-options.mdx#--anchorprefix) diff --git a/docs/pages/docs/options/utility-options.mdx b/docs/pages/docs/options/utility-options.mdx index e046fd070..7d6b555dc 100644 --- a/docs/pages/docs/options/utility-options.mdx +++ b/docs/pages/docs/options/utility-options.mdx @@ -4,6 +4,49 @@ import { Callout, FileTree } from "nextra/components"; Options that are used for general configuration and utility purposes. +## --formatWithPrettier + +Apply additional output formatting with Prettier. + +> Accepts a boolean value. Defaults to `false`. + +`typedoc-plugin-markdown` plugin generates well-formatted code, however, integrating the popular formatting package [Prettier](https://prettier.io/) can provide additional enhancements, such as: + +- Formats code inside fenced blocks using the respective Prettier configuration for that language. +- Aligns markdown table cells. +- Removes unnecessary escape characters. +- Wraps long lines of text to fit within a configurable line width. + +Please note that Prettier is not a dependency of this plugin and must be installed in your project for this option to work. + +If Prettier is not already installed please `npm i prettier --save-dev` to use this option. + +```json filename="typedoc.json" +{ + "formatWithPrettier": false +} +``` + +## --prettierConfigFile + + + Specify a custom Prettier configuration file location. + + +> Defaults to `"undefined"`. + +By default Prettier uses the options resolved from a discovered Prettier [configuration file](https://prettier.io/docs/en/configuration.html). + +Use this option to specify a separate Prettier configuration file in a custom location. + +Please note this option is only applicable when `formatWithPrettier` is set to `true`. + +```json filename="typedoc.json" +{ + "prettierConfigFile": "./path/to/.prettierrc.json" +} +``` + ## --sanitizeComments Sanitize HTML and JSX inside JsDoc comments. diff --git a/docs/pages/plugins/remark/useful-plugins.mdx b/docs/pages/plugins/remark/useful-plugins.mdx index 020a06402..2b4d17cce 100644 --- a/docs/pages/plugins/remark/useful-plugins.mdx +++ b/docs/pages/plugins/remark/useful-plugins.mdx @@ -2,26 +2,6 @@ Here are some [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) that might be useful. -## unified-prettier - -https://github.com/remcohaszing/unified-prettier - -Improving code formatting by parsing with [Prettier](https://prettier.io/): - -- Produces a consistent format. -- Removes unnecessary escape characters. -- Formats code blocks inside comment fenced blocks. - -```sh npm2yarn -npm install unified-prettier --save-dev -``` - -```json filename="typedoc.json" -{ - "remarkPlugins": ["unified-prettier"] -} -``` - ## remark-toc https://github.com/remarkjs/remark-toc diff --git a/package-lock.json b/package-lock.json index b1dce13ec..50fbe2430 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "workspaces": [ - "packages/typedoc-plugin-markdown", + "packages/typedoc-pslugin-markdown", "packages/typedoc-plugin-remark", "packages/typedoc-plugin-frontmatter", "packages/docusaurus-plugin-typedoc", @@ -46,8 +46,7 @@ "tsx": "^4.19.2", "typedoc": "^0.27.0-beta.2", "typescript": "^5.7.2", - "typescript-eslint": "^8.15.0", - "unified-prettier": "^2.0.1" + "typescript-eslint": "^8.16.0" } }, "devtools/packages/fixtures": { @@ -6845,16 +6844,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", - "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", + "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/type-utils": "8.15.0", - "@typescript-eslint/utils": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/type-utils": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -6878,15 +6877,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", - "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", + "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "debug": "^4.3.4" }, "engines": { @@ -6906,13 +6905,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", - "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0" + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6923,13 +6922,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", - "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", + "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.15.0", - "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/utils": "8.16.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -6950,9 +6949,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", - "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6963,13 +6962,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", - "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/visitor-keys": "8.15.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -7015,15 +7014,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", - "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.15.0", - "@typescript-eslint/types": "8.15.0", - "@typescript-eslint/typescript-estree": "8.15.0" + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7042,12 +7041,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", - "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/types": "8.16.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -21700,14 +21699,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.15.0.tgz", - "integrity": "sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.16.0.tgz", + "integrity": "sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.15.0", - "@typescript-eslint/parser": "8.15.0", - "@typescript-eslint/utils": "8.15.0" + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", + "@typescript-eslint/utils": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -21816,21 +21815,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unified-prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unified-prettier/-/unified-prettier-2.0.1.tgz", - "integrity": "sha512-6KKgdlY8wLsUMdGOFx61RVfCggKF47iE1cFvUcrs5jjH9xbkVMaQ48Qy8MXNjhexzKwxsoBYB/Qc7ZtPw7/Oyg==", - "dev": true, - "dependencies": { - "unified": "^11.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - }, - "peerDependencies": { - "prettier": "^3.0.0" - } - }, "node_modules/unique-string": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", diff --git a/package.json b/package.json index a779dab42..52fcd084d 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "tsx": "^4.19.2", "typedoc": "^0.27.0-beta.2", "typescript": "^5.7.2", - "typescript-eslint": "^8.15.0", - "unified-prettier": "^2.0.1" + "typescript-eslint": "^8.16.0" } } diff --git a/packages/typedoc-plugin-markdown/src/_typedoc.d.ts b/packages/typedoc-plugin-markdown/src/_typedoc.d.ts index 8c2d57f51..1f86fdf79 100644 --- a/packages/typedoc-plugin-markdown/src/_typedoc.d.ts +++ b/packages/typedoc-plugin-markdown/src/_typedoc.d.ts @@ -14,6 +14,7 @@ declare module 'typedoc' { expandParameters: boolean; fileExtension: string; flattenOutputFiles: boolean; + formatWithPrettier: boolean; hideBreadcrumbs: boolean; hideGroupHeadings: boolean; hidePageHeader: boolean; @@ -38,6 +39,7 @@ declare module 'typedoc' { outputFileStrategy: 'members' | 'modules'; parametersFormat: 'list' | 'table' | 'htmlTable'; preserveAnchorCasing: boolean; + prettierConfigFile: string; propertiesFormat: 'list' | 'table' | 'htmlTable'; propertyMembersFormat: 'list' | 'table' | 'htmlTable'; publicPath: string; diff --git a/packages/typedoc-plugin-markdown/src/options/declarations.ts b/packages/typedoc-plugin-markdown/src/options/declarations.ts index 7ab7c5810..d4e805369 100644 --- a/packages/typedoc-plugin-markdown/src/options/declarations.ts +++ b/packages/typedoc-plugin-markdown/src/options/declarations.ts @@ -551,6 +551,42 @@ export const tableColumnSettings: Partial = { }, }; +/** + * `typedoc-plugin-markdown` plugin generates well-formatted code, however, integrating the popular formatting package [Prettier](https://prettier.io/) can provide additional enhancements, such as: + * + * - Formats code inside fenced blocks using the respective Prettier configuration for that language. + * - Aligns markdown table cells. + * - Removes unnecessary escape characters. + * - Wraps long lines of text to fit within a configurable line width. + * + * Please note that Prettier is not a dependency of this plugin and must be installed in your project for this option to work. + * + * If Prettier is not already installed please `npm i prettier --save-dev` to use this option. + * + * @category Utility + */ +export const formatWithPrettier: Partial = { + help: 'Apply additional output formatting with Prettier.', + type: ParameterType.Boolean, + defaultValue: false, +}; + +/** + * By default Prettier uses the options resolved from a discovered Prettier [configuration file](https://prettier.io/docs/en/configuration.html). + * + * Use this option to specify a separate Prettier configuration file in a custom location. + * + * Please note this option is only applicable when `formatWithPrettier` is set to `true`. + * + * @example "./path/to/.prettierrc.json" + * + * @category Utility + */ +export const prettierConfigFile: Partial = { + help: 'Specify a custom Prettier configuration file location.', + type: ParameterType.Path, +}; + /** * *Please note this options does not affect the rendering of inline code or code blocks (using single/triple backticks).* * diff --git a/packages/typedoc-plugin-markdown/src/renderer/render.ts b/packages/typedoc-plugin-markdown/src/renderer/render.ts index c185e10c7..c8de912f2 100644 --- a/packages/typedoc-plugin-markdown/src/renderer/render.ts +++ b/packages/typedoc-plugin-markdown/src/renderer/render.ts @@ -49,7 +49,7 @@ export async function render( await executeJobs(renderer.preRenderAsyncJobs, output); - renderPages(renderer, output); + await renderPages(renderer, output); copyMediaFiles(project, outputDirectory); @@ -116,7 +116,10 @@ function initializeTheme(renderer: Renderer): MarkdownTheme { } // Helper to render all pages -function renderPages(renderer: Renderer, output: MarkdownRendererEvent) { +async function renderPages(renderer: Renderer, output: MarkdownRendererEvent) { + const formatWithPrettier = + renderer.application.options.getValue('formatWithPrettier'); + renderer.application.logger.verbose( `There are ${output.urls?.length} pages to write.`, ); @@ -132,12 +135,20 @@ function renderPages(renderer: Renderer, output: MarkdownRendererEvent) { renderer.trigger(MarkdownPageEvent.BEGIN, page); if (page.model instanceof Reflection) { - page.contents = page.contents + renderer.theme!.render(page, template); + const markdownFromTheme = renderer.theme!.render(page, template); + + if (formatWithPrettier) { + page.contents = + page.contents + + (await formatWithPrettierIfAvailable(renderer, markdownFromTheme)); + } else { + page.contents = page.contents + markdownFromTheme; + } renderer.trigger(MarkdownPageEvent.END, page); try { - writeFileSync(page.filename, page.contents); + writeFileSync(page.filename, page.contents || ''); } catch { renderer.application.logger.error( renderer.application.i18n.could_not_write_0(page.filename), @@ -149,6 +160,56 @@ function renderPages(renderer: Renderer, output: MarkdownRendererEvent) { } } +async function formatWithPrettierIfAvailable(renderer: Renderer, code: string) { + const prettier = await getPrettier(); + if (!prettier) { + renderer.application.logger.warn( + '[typedoc-plugin-markdown] Prettier formatting skipped as Prettier must be installed for the `formatWithPrettier` option to work. Please npm i prettier --save-dev.', + ); + return code; + } + + // Check Prettier version + const version = prettier.version; + + // Ensure compatibility with a specific version (if needed) + const [major] = version.split('.'); + if (Number(major) < 3) { + renderer.application.logger.warn( + '[typedoc-plugin-markdown] Prettier formatting skipped as Prettier must be above version 3 for the `formatWithPrettier` option to work.', + ); + return code; + } + + const prettierConfigPath = + renderer.application.options.getValue('prettierConfigFile') || + process.cwd(); + + // Resolve Prettier configuration + const config = await prettier.resolveConfig(prettierConfigPath); + + // Format code using Prettier + const formattedCode = prettier.format(code, { + ...config, + parser: 'markdown', + }); + + renderer.application.logger.verbose( + '[typedoc-plugin-markdown] Markdown formatted with Prettier.', + ); + + return formattedCode; +} + +async function getPrettier() { + try { + //@ts-error - prettier is optional and doesn't have to be installed + return await import('prettier'); + } catch { + return null; + } +} + // Helper to copy media files function copyMediaFiles(project: ProjectReflection, outputDirectory: string) { const media = path.join(outputDirectory, '_media'); diff --git a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.declaration.ts b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.declaration.ts index f1c080913..58e2ff3eb 100644 --- a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.declaration.ts +++ b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.declaration.ts @@ -102,7 +102,11 @@ export function declaration( if (this.helpers.useTableFormat('parameters')) { md.push(this.partials.typeParametersTable(model.typeParameters)); } else { - md.push(this.partials.typeParametersList(model.typeParameters)); + md.push( + this.partials.typeParametersList(model.typeParameters, { + headingLevel: options.headingLevel, + }), + ); } } diff --git a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.memberWithGroups.ts b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.memberWithGroups.ts index e75fccef9..9c4fb70c7 100644 --- a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.memberWithGroups.ts +++ b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.memberWithGroups.ts @@ -40,7 +40,11 @@ export function memberWithGroups( if (this.helpers.useTableFormat('parameters')) { md.push(this.partials.typeParametersTable(model.typeParameters)); } else { - md.push(this.partials.typeParametersList(model.typeParameters)); + md.push( + this.partials.typeParametersList(model.typeParameters, { + headingLevel: options.headingLevel, + }), + ); } } diff --git a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.signature.ts b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.signature.ts index 73a3a7258..070838542 100644 --- a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.signature.ts +++ b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.signature.ts @@ -76,7 +76,11 @@ export function signature( if (this.helpers.useTableFormat('parameters')) { md.push(this.partials.typeParametersTable(model.typeParameters)); } else { - md.push(this.partials.typeParametersList(model.typeParameters)); + md.push( + this.partials.typeParametersList(model.typeParameters, { + headingLevel: options.headingLevel, + }), + ); } } diff --git a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.typeParametersList.ts b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.typeParametersList.ts index 2e435d9a9..0d34aaeda 100644 --- a/packages/typedoc-plugin-markdown/src/theme/context/partials/member.typeParametersList.ts +++ b/packages/typedoc-plugin-markdown/src/theme/context/partials/member.typeParametersList.ts @@ -1,31 +1,40 @@ -import { bold, italic } from '@plugin/libs/markdown/index.js'; +import { heading, italic } from '@plugin/libs/markdown/index.js'; import { MarkdownThemeContext } from '@plugin/theme/index.js'; import { TypeParameterReflection } from 'typedoc'; export function typeParametersList( this: MarkdownThemeContext, model: TypeParameterReflection[], + options: { headingLevel: number }, ): string { const rows: string[] = []; model?.forEach((typeParameter) => { const row: string[] = []; - const nameCol: string[] = [bold(typeParameter.name)]; + row.push(heading(options.headingLevel + 1, typeParameter.name)); + + const nameCol: string[] = []; if (typeParameter.type) { nameCol.push( - `${italic('extends')} ${this.partials.someType(typeParameter.type)}`, + `${italic('extends')}: ${this.partials.someType(typeParameter.type)}`, ); } if (typeParameter.default) { - nameCol.push(`= ${this.partials.someType(typeParameter.default)}`); + nameCol.push( + `${this.i18n.theme_default_type()} ${this.partials.someType(typeParameter.default)}`, + ); } - row.push('• ' + nameCol.join(' ')); + row.push(nameCol.join('')); if (typeParameter.comment) { row.push(this.partials.comment(typeParameter.comment)); + } else { + if (nameCol.join('').length === 0) { + row.push('\\-'); + } } rows.push(row.join('\n\n')); diff --git a/packages/typedoc-plugin-markdown/src/theme/context/resources.ts b/packages/typedoc-plugin-markdown/src/theme/context/resources.ts index 0da49b0c1..8dee6e736 100644 --- a/packages/typedoc-plugin-markdown/src/theme/context/resources.ts +++ b/packages/typedoc-plugin-markdown/src/theme/context/resources.ts @@ -228,8 +228,10 @@ There is no association list partial for properties as these are handled as a st options: { kind?: ReflectionKind | undefined }, ) => partials.typeDeclarationTable.apply(context, [model, options]) as string, - typeParametersList: (model: TypeParameterReflection[]) => - partials.typeParametersList.apply(context, [model]) as string, + typeParametersList: ( + model: TypeParameterReflection[], + options: { headingLevel: number }, + ) => partials.typeParametersList.apply(context, [model, options]) as string, typeParametersTable: (model: TypeParameterReflection[]) => partials.typeParametersTable.apply(context, [model]) as string, breadcrumbs: () => partials.breadcrumbs.apply(context, []) as string, diff --git a/packages/typedoc-plugin-markdown/src/types/options.ts b/packages/typedoc-plugin-markdown/src/types/options.ts index fce256b63..faecbd7bc 100644 --- a/packages/typedoc-plugin-markdown/src/types/options.ts +++ b/packages/typedoc-plugin-markdown/src/types/options.ts @@ -65,6 +65,11 @@ export interface PluginOptions { */ flattenOutputFiles: boolean; + /** + * Apply additional output formatting with Prettier. + */ + formatWithPrettier: boolean; + /** * Do not print breadcrumbs. */ @@ -141,6 +146,11 @@ export interface PluginOptions { */ preserveAnchorCasing: boolean; + /** + * Specify a custom Prettier configuration file location. + */ + prettierConfigFile: string; + /** * Sets the format of property groups for interfaces and classes. */ diff --git a/packages/typedoc-plugin-markdown/test/fixtures/config.ts b/packages/typedoc-plugin-markdown/test/fixtures/config.ts index 507c01c41..1510a0813 100644 --- a/packages/typedoc-plugin-markdown/test/fixtures/config.ts +++ b/packages/typedoc-plugin-markdown/test/fixtures/config.ts @@ -281,8 +281,16 @@ const config: Record = { readme: 'none', expandObjects: true, useHTMLEncodedBrackets: true, + parametersFormat: 'table', }, - options: [{}, { useCodeBlocks: true }], + options: [ + {}, + { + useCodeBlocks: true, + formatWithPrettier: true, + prettierConfigFile: './test/fixtures/prettier-config/.prettierrc.json', + }, + ], }, customize: { only: false, diff --git a/packages/typedoc-plugin-markdown/test/fixtures/prettier-config/.prettierrc.json b/packages/typedoc-plugin-markdown/test/fixtures/prettier-config/.prettierrc.json new file mode 100644 index 000000000..1ca87ab7d --- /dev/null +++ b/packages/typedoc-plugin-markdown/test/fixtures/prettier-config/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "singleQuote": false +} diff --git a/packages/typedoc-plugin-markdown/test/fixtures/src/reflections/classes.ts b/packages/typedoc-plugin-markdown/test/fixtures/src/reflections/classes.ts index d4a9d93dd..4200229c7 100644 --- a/packages/typedoc-plugin-markdown/test/fixtures/src/reflections/classes.ts +++ b/packages/typedoc-plugin-markdown/test/fixtures/src/reflections/classes.ts @@ -132,8 +132,8 @@ export class ClassWithConstructorOverloads { /** * Comments for ClassWithTypeParameters * - * @param A Comments for param A * @param B Comments for param B + * @param C Comments for param C */ export class ClassWithTypeParameters {} diff --git a/packages/typedoc-plugin-markdown/test/fixtures/src/utils/index.ts b/packages/typedoc-plugin-markdown/test/fixtures/src/utils/index.ts index 29bd9f530..57f5d2c6a 100644 --- a/packages/typedoc-plugin-markdown/test/fixtures/src/utils/index.ts +++ b/packages/typedoc-plugin-markdown/test/fixtures/src/utils/index.ts @@ -14,3 +14,23 @@ export const variableWithChars = { ['']: '<', ['']: '', }; + +/** + * ```ts + * reallyUgly ( + * javascript + * ) + * ``` + * + * ```ts + * const originalSingleQuote = 'hello' + * const originalDoubleQuote = "hello" + * ``` + * + *```css + *.h1 { color : red } + *``` + */ +export function some_prettier_function(param: string) { + return param; +} diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.class.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.class.spec.ts.snap index ef8c883db..2546f9a5d 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.class.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.class.spec.ts.snap @@ -1238,15 +1238,21 @@ Comments for ClassWithTypeParameters ## Type Parameters -• **A** +### A -Comments for param A +\\- -• **B** *extends* \`string\` +### B + +*extends*: \`string\` Comments for param B -• **C** = \`boolean\` +### C + +Default type \`boolean\` + +Comments for param C ## Constructors @@ -1269,9 +1275,9 @@ Comments for ClassWithTypeParameters | Type Parameter | Default type | Description | | :------ | :------ | :------ | -| \`A\` | - | Comments for param A | +| \`A\` | - | - | | \`B\` *extends* \`string\` | - | Comments for param B | -| \`C\` | \`boolean\` | - | +| \`C\` | \`boolean\` | Comments for param C | ## Constructors 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 e1ffdc188..2560502f0 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 @@ -23,7 +23,9 @@ Comments for current function 1 #### Type Parameters -• **Value** +##### Value + +\\- #### Parameters @@ -47,7 +49,9 @@ Comments for iterable arg ### Type Parameters -• **Value** +#### Value + +\\- ### Parameters @@ -154,7 +158,9 @@ Comments for function ### Type Parameters -• **T** +#### T + +\\- ### Parameters @@ -1161,11 +1167,13 @@ Function with type parameters ## Type Parameters -• **T** +### T Comments for T -• **Item** = \`string\` \\| \`boolean\` +### Item + +Default type \`string\` \\| \`boolean\` ## Returns diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.interface.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.interface.spec.ts.snap index a1554e63e..09226a588 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.interface.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/reflection.interface.spec.ts.snap @@ -641,22 +641,22 @@ And some more comments ## Type Parameters -• **A** +### A This is a parameter. -• **B** +### B Comments for a parameter. This sentence is on a soft new line. -• **C** +### C This is a parameter. Documentation with a double line -• **D** +### D

These are comments with paras

These are comments with paras

@@ -842,7 +842,9 @@ Comments for InterfaceWithTypeParameters ## Type Parameters -• **A** +### A + +\\- ## Properties 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 695eada1f..02ea350fd 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 @@ -37,7 +37,9 @@ Comments for ConditionalType ## Type Parameters -• **T** +### T + +\\- ## Source @@ -429,7 +431,9 @@ Comments for PartialMappedType ## Type Parameters -• **T** +### T + +\\- ## Source @@ -523,7 +527,9 @@ Comments for ReadonlyMapedType ## Type Parameters -• **T** +### T + +\\- ## Source @@ -623,9 +629,13 @@ Comments for TypeWithTypeParams ## Type Parameters -• **T** +### T + +\\- + +### R -• **R** +\\- ## Source diff --git a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/utils.spec.ts.snap b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/utils.spec.ts.snap index 1056e12d9..ae30741fd 100644 --- a/packages/typedoc-plugin-markdown/test/specs/__snapshots__/utils.spec.ts.snap +++ b/packages/typedoc-plugin-markdown/test/specs/__snapshots__/utils.spec.ts.snap @@ -5,7 +5,9 @@ exports[`Utils should get class with brackets: (Output File Strategy "members") ## Type Parameters -• **T** +| Type Parameter | +| ------ | +| \`T\` | ## Constructors @@ -30,7 +32,9 @@ exports[`Utils should get class with brackets: (Output File Strategy "members") ## Type Parameters -• **T** +| Type Parameter | +| -------------- | +| \`T\` | ## Constructors @@ -59,7 +63,9 @@ exports[`Utils should get interface with brackets: (Output File Strategy "member ## Type Parameters -• **T** +| Type Parameter | +| ------ | +| \`T\` | ## Properties @@ -92,7 +98,9 @@ exports[`Utils should get interface with brackets: (Output File Strategy "member ## Type Parameters -• **T** +| Type Parameter | +| -------------- | +| \`T\` | ## Properties @@ -102,7 +110,7 @@ exports[`Utils should get interface with brackets: (Output File Strategy "member <: string; \`\`\` -*** +--- ### <tag> @@ -110,7 +118,7 @@ exports[`Utils should get interface with brackets: (Output File Strategy "member : string; \`\`\` -*** +--- ### > @@ -118,7 +126,7 @@ exports[`Utils should get interface with brackets: (Output File Strategy "member >: string; \`\`\` -*** +--- ### prop @@ -128,6 +136,72 @@ prop: T; " `; +exports[`Utils should get prettified function: (Output File Strategy "members") (Option Group "1") 1`] = ` +"# Function: some\\_prettier\\_function() + +> **some\\_prettier\\_function**(\`param\`): \`string\` + +\`\`\`ts +reallyUgly ( +javascript + ) +\`\`\` + +\`\`\`ts +const originalSingleQuote = 'hello' +const originalDoubleQuote = "hello" +\`\`\` + +\`\`\`css +.h1 { color : red } +\`\`\` + +## Parameters + +| Parameter | Type | +| ------ | ------ | +| \`param\` | \`string\` | + +## Returns + +\`string\` +" +`; + +exports[`Utils should get prettified function: (Output File Strategy "members") (Option Group "2") 1`] = ` +"# Function: some_prettier_function() + +\`\`\`ts +function some_prettier_function(param): string; +\`\`\` + +\`\`\`ts +reallyUgly(javascript); +\`\`\` + +\`\`\`ts +const originalSingleQuote = "hello"; +const originalDoubleQuote = "hello"; +\`\`\` + +\`\`\`css +.h1 { + color: red; +} +\`\`\` + +## Parameters + +| Parameter | Type | +| --------- | -------- | +| \`param\` | \`string\` | + +## Returns + +\`string\` +" +`; + exports[`Utils should get variable with brackets: (Output File Strategy "members") (Option Group "1") 1`] = ` "# Variable: variableWithChars diff --git a/packages/typedoc-plugin-markdown/test/specs/utils.spec.ts b/packages/typedoc-plugin-markdown/test/specs/utils.spec.ts index ea8c4e723..01dd9bdae 100644 --- a/packages/typedoc-plugin-markdown/test/specs/utils.spec.ts +++ b/packages/typedoc-plugin-markdown/test/specs/utils.spec.ts @@ -12,4 +12,12 @@ describe(`Utils`, () => { test(`should get variable with brackets`, () => { expectFileToEqual('utils', 'members', 'variables/variableWithChars.md'); }); + + test(`should get prettified function`, () => { + expectFileToEqual( + 'utils', + 'members', + 'functions/some_prettier_function.md', + ); + }); }); diff --git a/packages/typedoc-plugin-remark/test/specs/__snapshots__/remark.spec.ts.snap b/packages/typedoc-plugin-remark/test/specs/__snapshots__/remark.spec.ts.snap index a0be93a33..eaa5873ff 100644 --- a/packages/typedoc-plugin-remark/test/specs/__snapshots__/remark.spec.ts.snap +++ b/packages/typedoc-plugin-remark/test/specs/__snapshots__/remark.spec.ts.snap @@ -5,10 +5,10 @@ exports[`Remark should parse globals page 1`] = ` ## CustomTOC -- [Variables](#variables) - - [someVariable](#somevariable) -- [Functions](#functions) - - [some_function()](#some_function) +* [Variables](#variables) + * [someVariable](#somevariable) +* [Functions](#functions) + * [some\\_function()](#some_function) ## Variables @@ -18,12 +18,11 @@ exports[`Remark should parse globals page 1`] = ` ## Functions -### some_function() +### some\\_function() -> **some_function**(\`param\`): \`void\` +> **some\\_function**(\`param\`): \`void\` #### Parameters - @@ -48,10 +47,6 @@ exports[`Remark should parse globals page 1`] = ` Default text content for \`@category\` tag. -\`\`\`ts -const x = 1; -\`\`\` - @@ -74,12 +69,11 @@ exports[`Remark should parse globals page without toc 1`] = ` ## Functions -### some_function() +### some\\_function() -> **some_function**(\`param\`): \`void\` +> **some\\_function**(\`param\`): \`void\` #### Parameters -
@@ -104,10 +98,6 @@ exports[`Remark should parse globals page without toc 1`] = ` Default text content for \`@category\` tag. -\`\`\`ts -const x = 1; -\`\`\` - @@ -121,23 +111,22 @@ const x = 1; exports[`Remark should parse members class page 1`] = ` "--- -title: 'test' +title: "test" --- # Class: SomeClass\\ -- list item 1 +* list item 1 ## Contents -- [Type Parameters](#type-parameters) -- [Constructors](#constructors) - - [Constructor](#constructor) -- [Properties](#properties) - - [someProp](#someprop) +* [Type Parameters](#type-parameters) +* [Constructors](#constructors) + * [Constructor](#constructor) +* [Properties](#properties) + * [someProp](#someprop) ## Type Parameters -
@@ -178,14 +167,14 @@ exports[`Remark should parse members index 1`] = ` ## Modules -- [module-1](module-1/README.md) -- [module-2](module-2/README.md) +* [module-1](module-1/README.md) +* [module-2](module-2/README.md) " `; exports[`Remark should parse members module page 1`] = ` "--- -title: 'test' +title: "test" --- # module-1 @@ -194,33 +183,19 @@ Comments form module comments Thanks [**@tgrey**](https://github.com/tgrey) please see issue [#1](https://github.com/typedoc2md/typedoc-plugin-markdown/issues/1). -\`\`\`js -reallyUgly(javascript); -\`\`\` - -\`\`\`css -.h1 { - color: red; -} -\`\`\` - ## Index ### Classes -- [SomeClass](classes/SomeClass.md) +* [SomeClass](classes/SomeClass.md) ### Interfaces -- [SomeInterface](interfaces/SomeInterface.md) - -### Variables - -- [\\_\\_variable_with_underscores\\_\\_](variables/variable_with_underscores.md) +* [SomeInterface](interfaces/SomeInterface.md) ### Functions -- [some_function](functions/some_function.md) +* [some\\_function](functions/some_function.md) " `; @@ -245,24 +220,12 @@ Comments form module comments Thanks [**@tgrey**](https://github.com/tgrey) please see issue [#1](https://github.com/typedoc2md/typedoc-plugin-markdown/issues/1). -~~~js -reallyUgly ( -javascript - ) -~~~ - -~~~css -.h1 { color : red } -~~~ - ## Contents + [Classes](#classes) + [SomeClass\\](#someclasst) + [Interfaces](#interfaces) + [SomeInterface\\](#someinterfacet) -+ [Variables](#variables) - + [\\_\\_variable\\_with\\_underscores\\_\\_](#__variable_with_underscores__) + [Functions](#functions) + [some\\_function()](#some_function) @@ -342,12 +305,6 @@ javascript > **someProp**: \`string\` -## Variables - -### \\_\\_variable\\_with\\_underscores\\_\\_ - -> \`const\` **\\_\\_variable\\_with\\_underscores\\_\\_**: \`true\` = \`true\` - ## Functions ### some\\_function() diff --git a/packages/typedoc-plugin-remark/test/stubs/module-1.ts b/packages/typedoc-plugin-remark/test/stubs/module-1.ts index 766cf8fbe..bdc8c11c9 100644 --- a/packages/typedoc-plugin-remark/test/stubs/module-1.ts +++ b/packages/typedoc-plugin-remark/test/stubs/module-1.ts @@ -3,20 +3,9 @@ * * Thanks \@tgrey please see issue #1. * - * ```js - * reallyUgly ( - * javascript - * ) - * ``` - * - *```css - *.h1 { color : red } - *``` - * * @module */ -export const __variable_with_underscores__ = true; export function some_function(param: string | boolean) {} export interface SomeInterface { diff --git a/packages/typedoc-plugin-remark/test/stubs/module-2.ts b/packages/typedoc-plugin-remark/test/stubs/module-2.ts index be9f350d5..6ffa568df 100644 --- a/packages/typedoc-plugin-remark/test/stubs/module-2.ts +++ b/packages/typedoc-plugin-remark/test/stubs/module-2.ts @@ -5,8 +5,5 @@ export const someVariable = true; * * Default text content for `@category` tag. * - * ```ts - * const x = 1; - * ``` */ export function some_function(param: string) {} diff --git a/packages/typedoc-plugin-remark/test/typedoc.globals-notoc.json b/packages/typedoc-plugin-remark/test/typedoc.globals-notoc.json index 992196a6c..cf470b674 100644 --- a/packages/typedoc-plugin-remark/test/typedoc.globals-notoc.json +++ b/packages/typedoc-plugin-remark/test/typedoc.globals-notoc.json @@ -2,5 +2,5 @@ "extends": "./typedoc.base.json", "entryPoints": ["./stubs/module-2.ts"], "outputFileStrategy": "modules", - "remarkPlugins": ["remark-github", "unified-prettier"] + "remarkPlugins": ["remark-github"] } diff --git a/packages/typedoc-plugin-remark/test/typedoc.globals.json b/packages/typedoc-plugin-remark/test/typedoc.globals.json index db7fa5a23..0fa17e2a6 100644 --- a/packages/typedoc-plugin-remark/test/typedoc.globals.json +++ b/packages/typedoc-plugin-remark/test/typedoc.globals.json @@ -4,7 +4,6 @@ "outputFileStrategy": "modules", "remarkPlugins": [ "remark-github", - "unified-prettier", ["remark-toc", { "maxDepth": 3, "heading": "CustomTOC" }] ] } diff --git a/packages/typedoc-plugin-remark/test/typedoc.members.json b/packages/typedoc-plugin-remark/test/typedoc.members.json index 78da92345..ef7838133 100644 --- a/packages/typedoc-plugin-remark/test/typedoc.members.json +++ b/packages/typedoc-plugin-remark/test/typedoc.members.json @@ -1,9 +1,5 @@ { "extends": "./typedoc.base.json", "entryPoints": ["./stubs/*.ts"], - "remarkPlugins": [ - "remark-github", - "unified-prettier", - ["remark-toc", { "maxDepth": 3 }] - ] + "remarkPlugins": ["remark-github", ["remark-toc", { "maxDepth": 3 }]] }