|
1 | 1 | /**
|
2 |
| - * @typedef {import('mdast').Root|import('mdast').Content} Node |
| 2 | + * @typedef {import('mdast').Root} Root |
| 3 | + * @typedef {import('mdast').Content} Content |
3 | 4 | * @typedef {import('mdast').Paragraph} Paragraph
|
4 | 5 | */
|
5 | 6 |
|
6 |
| -import {remove} from 'unist-util-remove' |
| 7 | +/** |
| 8 | + * @typedef {Content | Root} Node |
| 9 | + */ |
| 10 | + |
| 11 | +import {visit} from 'unist-util-visit' |
7 | 12 |
|
8 | 13 | /**
|
9 | 14 | * Remove empty paragraphs in `tree`.
|
10 | 15 | *
|
11 | 16 | * @template {Node} Tree
|
| 17 | + * Node type. |
12 | 18 | * @param {Tree} tree
|
| 19 | + * Tree to change. |
13 | 20 | * @returns {Tree extends Paragraph ? Tree | null : Tree}
|
| 21 | + * Changed tree, or `null` if it was an empty paragraph. |
14 | 22 | */
|
15 | 23 | export function squeezeParagraphs(tree) {
|
16 |
| - /** |
17 |
| - * @param {Node} node |
18 |
| - * @returns {boolean} |
19 |
| - */ |
20 |
| - const filter = (node) => |
21 |
| - Boolean( |
22 |
| - node.type === 'paragraph' && |
23 |
| - node.children.every( |
24 |
| - (node) => node.type === 'text' && /^\s*$/.test(node.value) |
25 |
| - ) |
26 |
| - ) |
| 24 | + if (emptyParagraph(tree)) { |
| 25 | + // @ts-expect-error: it’s an empty paragraph. |
| 26 | + return null |
| 27 | + } |
| 28 | + |
| 29 | + visit(tree, function (node, index, parent) { |
| 30 | + if (index !== null && parent && emptyParagraph(node)) { |
| 31 | + parent.children.splice(index, 1) |
| 32 | + return index |
| 33 | + } |
| 34 | + }) |
27 | 35 |
|
28 |
| - // @ts-expect-error: `remove` can’t narrow the above test. |
29 |
| - return remove(tree, {cascade: false}, filter) |
| 36 | + // @ts-expect-error: it’s not an empty paragraph. |
| 37 | + return tree |
| 38 | +} |
| 39 | + |
| 40 | +/** |
| 41 | + * Check if a node is an empty paragraph. |
| 42 | + * |
| 43 | + * @param {Node} node |
| 44 | + * Node to check. |
| 45 | + * @returns {boolean} |
| 46 | + * Whether `node` was an empty paragraph. |
| 47 | + */ |
| 48 | +function emptyParagraph(node) { |
| 49 | + return ( |
| 50 | + node.type === 'paragraph' && |
| 51 | + node.children.every( |
| 52 | + (child) => child.type === 'text' && /^\s*$/.test(child.value) |
| 53 | + ) |
| 54 | + ) |
30 | 55 | }
|
0 commit comments