Files
documentation/node_modules/@mdx-js/mdx/lib/plugin/remark-mark-and-unravel.js
2024-03-22 03:47:51 +05:30

98 lines
2.5 KiB
JavaScript

/**
* @typedef {import('mdast').Root} Root
* @typedef {import('mdast').RootContent} RootContent
*/
import {collapseWhiteSpace} from 'collapse-white-space'
import {visit} from 'unist-util-visit'
/**
* A tiny plugin that unravels `<p><h1>x</h1></p>` but also
* `<p><Component /></p>` (so it has no knowledge of “HTML”).
*
* It also marks JSX as being explicitly JSX, so when a user passes a `h1`
* component, it is used for `# heading` but not for `<h1>heading</h1>`.
*
* @returns
* Transform.
*/
export function remarkMarkAndUnravel() {
/**
* @param {Root} tree
* Tree.
* @returns {undefined}
* Nothing.
*/
return function (tree) {
visit(tree, function (node, index, parent) {
let offset = -1
let all = true
let oneOrMore = false
if (parent && typeof index === 'number' && node.type === 'paragraph') {
const children = node.children
while (++offset < children.length) {
const child = children[offset]
if (
child.type === 'mdxJsxTextElement' ||
child.type === 'mdxTextExpression'
) {
oneOrMore = true
} else if (
child.type === 'text' &&
collapseWhiteSpace(child.value, {style: 'html', trim: true}) === ''
) {
// Empty.
} else {
all = false
break
}
}
if (all && oneOrMore) {
offset = -1
/** @type {Array<RootContent>} */
const newChildren = []
while (++offset < children.length) {
const child = children[offset]
if (child.type === 'mdxJsxTextElement') {
// @ts-expect-error: mutate because it is faster; content model is fine.
child.type = 'mdxJsxFlowElement'
}
if (child.type === 'mdxTextExpression') {
// @ts-expect-error: mutate because it is faster; content model is fine.
child.type = 'mdxFlowExpression'
}
if (
child.type === 'text' &&
/^[\t\r\n ]+$/.test(String(child.value))
) {
// Empty.
} else {
newChildren.push(child)
}
}
parent.children.splice(index, 1, ...newChildren)
return index
}
}
if (
node.type === 'mdxJsxFlowElement' ||
node.type === 'mdxJsxTextElement'
) {
const data = node.data || (node.data = {})
data._mdxExplicitJsx = true
}
})
}
}