mirror of
https://github.com/Snigdha-OS/documentation.git
synced 2025-09-07 19:25:13 +02:00
98 lines
2.5 KiB
JavaScript
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
|
|
}
|
|
})
|
|
}
|
|
}
|