71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
/**
|
||
* @typedef {import('hast').Root} HastRoot
|
||
* @typedef {import('mdast').Root} MdastRoot
|
||
* @typedef {import('mdast-util-to-hast').Options} Options
|
||
* @typedef {import('unified').Processor<any, any, any, any>} Processor
|
||
*
|
||
* @typedef {import('mdast-util-to-hast')} DoNotTouchAsThisImportIncludesRawInTree
|
||
*/
|
||
|
||
import {toHast} from 'mdast-util-to-hast'
|
||
|
||
// Note: the `<MdastRoot, HastRoot>` overload doesn’t seem to work :'(
|
||
|
||
/**
|
||
* Plugin that turns markdown into HTML to support rehype.
|
||
*
|
||
* * If a destination processor is given, that processor runs with a new HTML
|
||
* (hast) tree (bridge-mode).
|
||
* As the given processor runs with a hast tree, and rehype plugins support
|
||
* hast, that means rehype plugins can be used with the given processor.
|
||
* The hast tree is discarded in the end.
|
||
* It’s highly unlikely that you want to do this.
|
||
* * The common case is to not pass a destination processor, in which case the
|
||
* current processor continues running with a new HTML (hast) tree
|
||
* (mutate-mode).
|
||
* As the current processor continues with a hast tree, and rehype plugins
|
||
* support hast, that means rehype plugins can be used after
|
||
* `remark-rehype`.
|
||
* It’s likely that this is what you want to do.
|
||
*
|
||
* @param destination
|
||
* Optional unified processor.
|
||
* @param options
|
||
* Options passed to `mdast-util-to-hast`.
|
||
*/
|
||
const remarkRehype =
|
||
/** @type {(import('unified').Plugin<[Processor, Options?]|[null|undefined, Options?]|[Options]|[], MdastRoot>)} */
|
||
(
|
||
function (destination, options) {
|
||
return destination && 'run' in destination
|
||
? bridge(destination, options)
|
||
: mutate(destination || options)
|
||
}
|
||
)
|
||
|
||
export default remarkRehype
|
||
|
||
/**
|
||
* Bridge-mode.
|
||
* Runs the destination with the new hast tree.
|
||
*
|
||
* @type {import('unified').Plugin<[Processor, Options?], MdastRoot>}
|
||
*/
|
||
function bridge(destination, options) {
|
||
return (node, file, next) => {
|
||
destination.run(toHast(node, options), file, (error) => {
|
||
next(error)
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Mutate-mode.
|
||
* Further plugins run on the hast tree.
|
||
*
|
||
* @type {import('unified').Plugin<[Options?]|void[], MdastRoot, HastRoot>}
|
||
*/
|
||
function mutate(options) {
|
||
// @ts-expect-error: assume a corresponding node is returned by `toHast`.
|
||
return (node) => toHast(node, options)
|
||
}
|