|
1 | 1 | /** |
2 | | - * @typedef {import('./lib/types.js').Node} Node |
3 | | - * @typedef {import('./lib/types.js').Element} Element |
4 | | - * @typedef {import('./lib/types.js').Text} Text |
5 | 2 | * @typedef {import('./lib/types.js').Options} Options |
6 | 3 | * @typedef {import('./lib/types.js').Context} Context |
7 | | - * @typedef {import('./lib/types.js').Properties} Properties |
8 | 4 | * @typedef {import('./lib/types.js').H} H |
9 | | - * @typedef {import('./lib/types.js').HWithoutProps} HWithoutProps |
10 | | - * @typedef {import('./lib/types.js').HWithProps} HWithProps |
11 | | - * @typedef {import('./lib/types.js').MdastNode} MdastNode |
12 | | - * @typedef {import('./lib/types.js').MdastRoot} MdastRoot |
| 5 | + * @typedef {import('./lib/types.js').Handle} Handle |
13 | 6 | */ |
14 | 7 |
|
15 | | -import {hasProperty} from 'hast-util-has-property' |
16 | | -// @ts-expect-error: next. |
17 | | -import minifyWhitespace from 'rehype-minify-whitespace' |
18 | | -import {convert} from 'unist-util-is' |
19 | | -import {visit} from 'unist-util-visit' |
20 | | -import {one} from './lib/one.js' |
21 | | -import {handlers} from './lib/handlers/index.js' |
22 | | -import {own} from './lib/util/own.js' |
23 | | - |
24 | | -export {one} from './lib/one.js' |
25 | | -export {all} from './lib/all.js' |
26 | | - |
27 | | -const block = convert(['heading', 'paragraph', 'root']) |
28 | | - |
29 | | -/** |
30 | | - * @param {Node} tree |
31 | | - * @param {Options} [options] |
32 | | - */ |
33 | | -export function toMdast(tree, options = {}) { |
34 | | - /** @type {Object.<string, Element>} */ |
35 | | - const byId = {} |
36 | | - /** @type {MdastNode|MdastRoot} */ |
37 | | - let mdast |
38 | | - |
39 | | - /** |
40 | | - * @type {H} |
41 | | - */ |
42 | | - const h = Object.assign( |
43 | | - /** |
44 | | - * @type {HWithProps & HWithoutProps} |
45 | | - */ |
46 | | - ( |
47 | | - /** |
48 | | - * @param {Node} node |
49 | | - * @param {string} type |
50 | | - * @param {Properties|string|Array.<Node>} [props] |
51 | | - * @param {string|Array.<Node>} [children] |
52 | | - */ |
53 | | - (node, type, props, children) => { |
54 | | - /** @type {Properties|undefined} */ |
55 | | - let properties |
56 | | - |
57 | | - if (typeof props === 'string' || Array.isArray(props)) { |
58 | | - children = props |
59 | | - properties = {} |
60 | | - } else { |
61 | | - properties = props |
62 | | - } |
63 | | - |
64 | | - /** @type {Node} */ |
65 | | - // @ts-expect-error Assume valid `type` and `children`/`value`. |
66 | | - const result = {type, ...properties} |
67 | | - |
68 | | - if (typeof children === 'string') { |
69 | | - result.value = children |
70 | | - } else if (children) { |
71 | | - result.children = children |
72 | | - } |
73 | | - |
74 | | - if (node.position) { |
75 | | - result.position = node.position |
76 | | - } |
77 | | - |
78 | | - return result |
79 | | - } |
80 | | - ), |
81 | | - { |
82 | | - nodeById: byId, |
83 | | - baseFound: false, |
84 | | - wrapText: true, |
85 | | - /** @type {string|null} */ |
86 | | - frozenBaseUrl: null, |
87 | | - qNesting: 0, |
88 | | - handlers: options.handlers |
89 | | - ? {...handlers, ...options.handlers} |
90 | | - : handlers, |
91 | | - document: options.document, |
92 | | - checked: options.checked || '[x]', |
93 | | - unchecked: options.unchecked || '[ ]', |
94 | | - quotes: options.quotes || ['"'] |
95 | | - } |
96 | | - ) |
97 | | - |
98 | | - visit(tree, 'element', onelement) |
99 | | - |
100 | | - minifyWhitespace({newlines: options.newlines === true})(tree) |
101 | | - |
102 | | - const result = one(h, tree, undefined) |
103 | | - |
104 | | - if (!result) { |
105 | | - mdast = {type: 'root', children: []} |
106 | | - } else if (Array.isArray(result)) { |
107 | | - mdast = {type: 'root', children: result} |
108 | | - } else { |
109 | | - mdast = result |
110 | | - } |
111 | | - |
112 | | - visit(mdast, 'text', ontext) |
113 | | - |
114 | | - return mdast |
115 | | - |
116 | | - /** @type {import('unist-util-visit').Visitor<Element>} */ |
117 | | - function onelement(node) { |
118 | | - const id = |
119 | | - // @ts-expect-error: `hasProperty` just checked it. |
120 | | - hasProperty(node, 'id') && String(node.properties.id).toUpperCase() |
121 | | - |
122 | | - if (id && !own.call(byId, id)) { |
123 | | - byId[id] = node |
124 | | - } |
125 | | - } |
126 | | - |
127 | | - /** |
128 | | - * Collapse text nodes, and fix whitespace. |
129 | | - * Most of this is taken care of by `rehype-minify-whitespace`, but |
130 | | - * we’re generating some whitespace too, and some nodes are in the end |
131 | | - * ignored. |
132 | | - * So clean up. |
133 | | - * |
134 | | - * @type {import('unist-util-visit').Visitor<Text>} |
135 | | - */ |
136 | | - function ontext(node, index, parent) { |
137 | | - /* c8 ignore next 3 */ |
138 | | - if (index === null || !parent) { |
139 | | - return |
140 | | - } |
141 | | - |
142 | | - const previous = parent.children[index - 1] |
143 | | - |
144 | | - if (previous && previous.type === node.type) { |
145 | | - previous.value += node.value |
146 | | - parent.children.splice(index, 1) |
147 | | - |
148 | | - if (previous.position && node.position) { |
149 | | - previous.position.end = node.position.end |
150 | | - } |
151 | | - |
152 | | - // Iterate over the previous node again, to handle its total value. |
153 | | - return index - 1 |
154 | | - } |
155 | | - |
156 | | - node.value = node.value.replace(/[\t ]*(\r?\n|\r)[\t ]*/, '$1') |
157 | | - |
158 | | - // We don’t care about other phrasing nodes in between (e.g., `[ asd ]()`), |
159 | | - // as there the whitespace matters. |
160 | | - if (parent && block(parent)) { |
161 | | - if (!index) { |
162 | | - node.value = node.value.replace(/^[\t ]+/, '') |
163 | | - } |
164 | | - |
165 | | - if (index === parent.children.length - 1) { |
166 | | - node.value = node.value.replace(/[\t ]+$/, '') |
167 | | - } |
168 | | - } |
169 | | - |
170 | | - if (!node.value) { |
171 | | - parent.children.splice(index, 1) |
172 | | - return index |
173 | | - } |
174 | | - } |
175 | | -} |
| 8 | +export {one, all, toMdast} from './lib/index.js' |
0 commit comments