Files
coopgo/node_modules/hast-util-to-mdast/lib/util/wrap.js
sgauthier 6e64e138e2
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s
planning
2024-10-14 09:15:30 +02:00

134 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict'
module.exports = wrap
wrap.needed = needed
var extend = require('extend')
var phrasing = require('mdast-util-phrasing')
var shallow = require('./shallow')
function wrap(nodes) {
return runs(nodes, onphrasing)
function onphrasing(nodes) {
var head = nodes[0]
if (
nodes.length === 1 &&
head.type === 'text' &&
(head.value === ' ' || head.value === '\n')
) {
return []
}
return {type: 'paragraph', children: nodes}
}
}
// Wrap all runs of mdast phrasing content in `paragraph` nodes.
function runs(nodes, onphrasing, onnonphrasing) {
var nonphrasing = onnonphrasing || identity
var flattened = flatten(nodes)
var result = []
var index = -1
var node
var queue
while (++index < flattened.length) {
node = flattened[index]
if (phrasing(node)) {
if (!queue) queue = []
queue.push(node)
} else {
if (queue) {
result = result.concat(onphrasing(queue))
queue = undefined
}
result = result.concat(nonphrasing(node))
}
}
if (queue) {
result = result.concat(onphrasing(queue))
}
return result
}
// Flatten a list of nodes.
function flatten(nodes) {
var flattened = []
var index = -1
var node
while (++index < nodes.length) {
node = nodes[index]
// Straddling: some elements are *weird*.
// Namely: `map`, `ins`, `del`, and `a`, as they are hybrid elements.
// See: <https://html.spec.whatwg.org/#paragraphs>.
// Paragraphs are the weirdest of them all.
// See the straddling fixture for more info!
// `ins` is ignored in mdast, so we dont need to worry about that.
// `map` maps to its content, so we dont need to worry about that either.
// `del` maps to `delete` and `a` to `link`, so we do handle those.
// What well do is split `node` over each of its children.
if (
(node.type === 'delete' || node.type === 'link') &&
needed(node.children)
) {
flattened = flattened.concat(split(node))
} else {
flattened.push(node)
}
}
return flattened
}
// Check if there are non-phrasing mdast nodes returned.
// This is needed if a fragment is given, which could just be a sentence, and
// doesnt need a wrapper paragraph.
function needed(nodes) {
var index = -1
var node
while (++index < nodes.length) {
node = nodes[index]
if (!phrasing(node) || (node.children && needed(node.children))) {
return true
}
}
}
function split(node) {
return runs(node.children, onphrasing, onnonphrasing)
// Use `child`, add `parent` as its first child, put the original children
// into `parent`.
function onnonphrasing(child) {
var parent = extend(true, {}, shallow(node))
var copy = shallow(child)
copy.children = [parent]
parent.children = child.children
return copy
}
// Use `parent`, put the phrasing run inside it.
function onphrasing(nodes) {
var parent = extend(true, {}, shallow(node))
parent.children = nodes
return parent
}
}
function identity(n) {
return n
}