Skip to content

Commit fc40dff

Browse files
committed
docs: document Markdown plugins
Documents the `markdown` option, the Shiki plugin options, and how generators declare their pipelines. The changeset also lists the `@doc-kit/core` modules that are removed or moved. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 3839ea9 commit fc40dff

3 files changed

Lines changed: 158 additions & 1 deletion

File tree

‎.changeset/markdown-plugins.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@doc-kit/core': minor
3+
'@doc-kit/generator-react': minor
4+
'@node-core/doc-kit-legacy': patch
5+
---
6+
7+
Add a `markdown` option to add remark, rehype, and recma plugins to the generators processing Markdown, or configure the ones they use, such as Shiki. The `@doc-kit/core` modules the generators' pipelines replace are removed (`utils/remark.mjs`, `utils/remark-shiki.mjs`, and `utils/highlighter.mjs`), and `utils/type-annotations` moves to `plugins/type-annotations`

‎docs/configuration.md‎

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,11 @@ Everything under the `global` key applies to every generator:
123123
a URL or path to parse, or a pre-parsed array. **Default:** `[]`
124124
(single-version output).
125125
- `index` {string|URL|Array} Index URL.
126+
- `markdown` {Object} [Markdown plugins](#markdown-plugins) for every
127+
generator processing Markdown.
126128

127129
A generator's own section (e.g., `html`, `legacy-json`) can override any of
128-
these for that generator alone.
130+
these for that generator alone, except `markdown`, which it adds to.
129131

130132
## Execution options
131133

@@ -155,6 +157,96 @@ export default {
155157
};
156158
```
157159

160+
## Markdown plugins
161+
162+
`doc-kit` processes Markdown with [unified](https://unifiedjs.com/).
163+
`global.markdown` adds plugins to every generator processing Markdown, and a
164+
generator's own `markdown` adds plugins to it alone, after the global ones.
165+
166+
```mjs displayName="doc-kit.config.mjs"
167+
export default {
168+
global: {
169+
markdown: {
170+
remarkPlugins: ['remark-math'],
171+
},
172+
},
173+
174+
// The generator rendering the site's pages
175+
'jsx-ast': {
176+
markdown: {
177+
rehypePlugins: [
178+
'rehype-katex',
179+
['./plugins/rehype-diagrams.mjs', { theme: 'neutral' }],
180+
],
181+
},
182+
},
183+
};
184+
```
185+
186+
Each plugin is a module specifier (a package name, or a path relative to the
187+
configuration file), alone or in a `[specifier, options]` pair. The module
188+
default-exports the plugin, a list of plugins, or a unified preset. Markdown is
189+
processed in worker threads, which import the plugins themselves, so options
190+
must be serializable: configure a plugin taking functions in a module of your
191+
own.
192+
193+
- `remarkPlugins` {Array} The global ones run on each document once the `ast`
194+
generator parses it, so every output sees their changes. A generator
195+
rendering Markdown, such as `jsx-ast`, runs its own on what it renders.
196+
- `rehypePlugins` {Array} Run on the HTML of the generators rendering
197+
Markdown, such as `jsx-ast`, before code is highlighted.
198+
- `recmaPlugins` {Array} Run on the JavaScript `jsx-ast` compiles the pages to.
199+
200+
A generator only takes the plugins its pipeline has a place for: `jsx-ast`
201+
takes all three kinds, `ast`, `metadata`, and `json` take remark plugins, and
202+
generators such as `html` take none. Plugins listed for a generator that
203+
doesn't take them are ignored with a warning.
204+
205+
A generator runs each plugin once: listing one it already has, its own or a
206+
global one, configures it instead, merging the options (arrays add up, and
207+
objects merge).
208+
209+
The plugins configured for `jsx-ast` don't apply to the fragments it renders
210+
on their own: types, parameter descriptions, and change history notes.
211+
212+
### Code highlighting
213+
214+
`jsx-ast` highlights code with the `@doc-kit/core/plugins/shiki/rehype.mjs`
215+
plugin, which runs [Shiki](https://shiki.style/) with every language it
216+
bundles. To configure it, list it with options in
217+
`jsx-ast.markdown.rehypePlugins` (with pnpm, add `@doc-kit/core` to your
218+
dependencies, so your configuration file can resolve it):
219+
220+
- `langs` {Array} More languages: grammars, or modules default-exporting them.
221+
- `langAlias` {Object} Aliases of languages, such as `{ conf: 'ini' }`.
222+
- `themes` {Object} The `light` and `dark` themes: names of themes Shiki
223+
bundles, modules default-exporting themes, or themes.
224+
- `transformers` {Array} Modules default-exporting
225+
[Shiki transformers](https://shiki.style/guide/transformers), or lists of
226+
them.
227+
228+
These modules are paths relative to the working directory, or URLs, such as
229+
the ones `import.meta.resolve()` gives:
230+
231+
```mjs displayName="doc-kit.config.mjs"
232+
export default {
233+
'jsx-ast': {
234+
markdown: {
235+
rehypePlugins: [
236+
[
237+
'@doc-kit/core/plugins/shiki/rehype.mjs',
238+
{
239+
langAlias: { conf: 'ini' },
240+
themes: { light: 'github-light', dark: 'github-dark' },
241+
transformers: [import.meta.resolve('./shiki-transformers.mjs')],
242+
},
243+
],
244+
],
245+
},
246+
},
247+
};
248+
```
249+
158250
## Configuration Merging
159251

160252
Configurations are merged in the following order (higher sources take

‎docs/creating-generators.md‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,64 @@ Use a dependent when a generator transforms an intermediate representation
468468
format of its own. See the [`section-pages`](./generators/section-pages.md) generator for
469469
a worked example.
470470

471+
## Markdown pipelines
472+
473+
A generator processing Markdown declares its [unified](https://unifiedjs.com/)
474+
pipeline as `markdown`, listing plugins as the
475+
[`markdown` option](./configuration.md#markdown-plugins) does, with paths
476+
relative to its module. The rehype list starts with `remark-rehype`, and the
477+
recma list with `rehype-recma`. Each list takes the configured plugins in place
478+
of its `'...'`, and a list without one takes none. As every thread running the
479+
generator imports it, options may be anything, functions included.
480+
481+
```mjs displayName="index.mjs"
482+
export default {
483+
name: 'my-generator',
484+
485+
dependsOn: '@doc-kit/core/metadata',
486+
487+
markdown: {
488+
remarkPlugins: ['remark-parse', 'remark-gfm', '...'],
489+
rehypePlugins: [
490+
['remark-rehype', { allowDangerousHtml: true }],
491+
'...',
492+
['rehype-stringify', { allowDangerousHtml: true }],
493+
],
494+
},
495+
496+
generate,
497+
};
498+
```
499+
500+
`getProcessor(name)` gives the generator's processor, on each thread it runs
501+
on:
502+
503+
```mjs displayName="generate.mjs"
504+
import { getProcessor } from '@doc-kit/core/utils/markdown/processor.mjs';
505+
506+
export async function generate(input) {
507+
const processor = getProcessor('my-generator');
508+
509+
return Promise.all(
510+
input.map(async ({ content }) =>
511+
processor.stringify(await processor.run(content))
512+
)
513+
);
514+
}
515+
```
516+
517+
`getProcessor(name, { mdx: true })` returns an MDX processor (plugins can
518+
check `this.data('mdx')`), and `getProcessor(name, { configured: false })` one
519+
without the configured plugins. A generator rendering Markdown (with rehype or
520+
recma plugins) only takes its own remark plugins, as the global ones already
521+
ran when `ast` parsed the Markdown.
522+
523+
A plugin needing asynchronous setup can export an async `load(options)`
524+
returning the plugin, instead of a default export. The Shiki plugin does, and
525+
`getHighlighter(name)` (from `@doc-kit/core/plugins/shiki/highlighter.mjs`)
526+
returns the highlighter of a generator's Shiki plugin, to highlight code as its
527+
pipeline does.
528+
471529
## File Output
472530

473531
### Writing Output Files

0 commit comments

Comments
 (0)