@xyd-js/content 0.0.0-build

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/ISSUES.md +1 -0
  3. package/LICENSE +21 -0
  4. package/README.md +3 -0
  5. package/TODO.md +2 -0
  6. package/dist/index.d.ts +28 -0
  7. package/dist/index.js +1625 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/md.d.ts +72 -0
  10. package/dist/md.js +23508 -0
  11. package/dist/md.js.map +1 -0
  12. package/dist/mdToc-NBBxMJ4l.d.ts +12 -0
  13. package/dist/vite.d.ts +1066 -0
  14. package/dist/vite.js +20156 -0
  15. package/dist/vite.js.map +1 -0
  16. package/package.json +67 -0
  17. package/packages/md/index.ts +25 -0
  18. package/packages/md/plugins/component-directives/index.ts +3 -0
  19. package/packages/md/plugins/component-directives/mdComponentDirective.ts +577 -0
  20. package/packages/md/plugins/component-directives/types.ts +1 -0
  21. package/packages/md/plugins/component-directives/utils.ts +27 -0
  22. package/packages/md/plugins/composer/__fixtures__/1.single-example/input.md +7 -0
  23. package/packages/md/plugins/composer/__fixtures__/1.single-example/output.json +63 -0
  24. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/input.md +7 -0
  25. package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/output.json +63 -0
  26. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/input.md +15 -0
  27. package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/output.json +122 -0
  28. package/packages/md/plugins/composer/__fixtures__/4.example-groups/input.md +23 -0
  29. package/packages/md/plugins/composer/__fixtures__/4.example-groups/output.json +184 -0
  30. package/packages/md/plugins/composer/__tests__/mdComposer.test.ts +41 -0
  31. package/packages/md/plugins/composer/__tests__/testHelpers.ts +48 -0
  32. package/packages/md/plugins/composer/index.ts +1 -0
  33. package/packages/md/plugins/composer/mdComposer.ts +146 -0
  34. package/packages/md/plugins/developer-writing/index.ts +3 -0
  35. package/packages/md/plugins/developer-writing/mdCodeRehype.ts +81 -0
  36. package/packages/md/plugins/functions/__fixtures__/external.ts +4 -0
  37. package/packages/md/plugins/functions/__fixtures__/test-include.md +31 -0
  38. package/packages/md/plugins/functions/__fixtures__/test.js +11 -0
  39. package/packages/md/plugins/functions/__fixtures__/test.py +9 -0
  40. package/packages/md/plugins/functions/__fixtures__/test.ts +18 -0
  41. package/packages/md/plugins/functions/__tests__/mdFunctionImportCode.test.ts +314 -0
  42. package/packages/md/plugins/functions/__tests__/mdFunctionInclude.test.ts +44 -0
  43. package/packages/md/plugins/functions/__tests__/parseFunctionCall.test.ts +70 -0
  44. package/packages/md/plugins/functions/__tests__/testHelpers.ts +95 -0
  45. package/packages/md/plugins/functions/index.ts +15 -0
  46. package/packages/md/plugins/functions/mdFunctionChangelog.ts +135 -0
  47. package/packages/md/plugins/functions/mdFunctionImportCode.ts +92 -0
  48. package/packages/md/plugins/functions/mdFunctionInclude.ts +119 -0
  49. package/packages/md/plugins/functions/mdFunctionUniform.ts +79 -0
  50. package/packages/md/plugins/functions/types.ts +9 -0
  51. package/packages/md/plugins/functions/uniformProcessor.ts +349 -0
  52. package/packages/md/plugins/functions/utils.ts +457 -0
  53. package/packages/md/plugins/index.ts +125 -0
  54. package/packages/md/plugins/mdCode.ts +16 -0
  55. package/packages/md/plugins/mdHeadingId.ts +47 -0
  56. package/packages/md/plugins/mdImage.test.ts +59 -0
  57. package/packages/md/plugins/mdImage.ts +55 -0
  58. package/packages/md/plugins/mdImageRehype.ts +13 -0
  59. package/packages/md/plugins/mdPage.ts +35 -0
  60. package/packages/md/plugins/mdThemeSettings.ts +34 -0
  61. package/packages/md/plugins/mdToc.ts +229 -0
  62. package/packages/md/plugins/meta/index.ts +1 -0
  63. package/packages/md/plugins/meta/mdMeta.ts +198 -0
  64. package/packages/md/plugins/output-variables/__fixtures__/1.simple/input.md +22 -0
  65. package/packages/md/plugins/output-variables/__fixtures__/1.simple/output.json +191 -0
  66. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/input.md +21 -0
  67. package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/output.json +127 -0
  68. package/packages/md/plugins/output-variables/__tests__/index.test.ts +28 -0
  69. package/packages/md/plugins/output-variables/__tests__/testHelpers.ts +36 -0
  70. package/packages/md/plugins/output-variables/index.ts +1 -0
  71. package/packages/md/plugins/output-variables/lib/const.ts +4 -0
  72. package/packages/md/plugins/output-variables/lib/factoryAttributes.ts +350 -0
  73. package/packages/md/plugins/output-variables/lib/factoryLabel.ts +135 -0
  74. package/packages/md/plugins/output-variables/lib/factoryName.ts +59 -0
  75. package/packages/md/plugins/output-variables/lib/index.ts +21 -0
  76. package/packages/md/plugins/output-variables/lib/outputVarsContainer.ts +328 -0
  77. package/packages/md/plugins/output-variables/lib/util.ts +494 -0
  78. package/packages/md/plugins/output-variables/remarkOutputVars.ts +22 -0
  79. package/packages/md/plugins/recmaOverrideComponents.ts +74 -0
  80. package/packages/md/plugins/rehypeHeading.ts +58 -0
  81. package/packages/md/plugins/types.ts +15 -0
  82. package/packages/md/plugins/utils/componentLike.ts +76 -0
  83. package/packages/md/plugins/utils/index.ts +2 -0
  84. package/packages/md/plugins/utils/injectCodeMeta.ts +59 -0
  85. package/packages/md/plugins/utils/mdParameters.test.ts +114 -0
  86. package/packages/md/plugins/utils/mdParameters.ts +249 -0
  87. package/packages/md/plugins/utils/mdastTypes.ts +42 -0
  88. package/packages/md/search/index.ts +257 -0
  89. package/packages/md/search/types.ts +36 -0
  90. package/packages/vite/index.ts +20 -0
  91. package/src/fs.ts +81 -0
  92. package/src/index.ts +7 -0
  93. package/src/navigation.ts +147 -0
  94. package/src/types.ts +8 -0
  95. package/tsconfig.json +49 -0
  96. package/tsup.config.ts +32 -0
  97. package/vitest.config.ts +17 -0
@@ -0,0 +1,494 @@
1
+ /**
2
+ * @import {Directives, LeafDirective, TextDirective, ToMarkdownOptions} from 'mdast-util-directive'
3
+ * @import {
4
+ * CompileContext,
5
+ * Extension as FromMarkdownExtension,
6
+ * Handle as FromMarkdownHandle,
7
+ * Token
8
+ * } from 'mdast-util-from-markdown'
9
+ * @import {
10
+ * ConstructName,
11
+ * Handle as ToMarkdownHandle,
12
+ * Options as ToMarkdownExtension,
13
+ * State
14
+ * } from 'mdast-util-to-markdown'
15
+ * @import {Nodes, Paragraph} from 'mdast'
16
+ */
17
+
18
+ import { ccount } from 'ccount'
19
+ import { ok as assert } from 'devlop'
20
+ import { parseEntities } from 'parse-entities'
21
+ import { stringifyEntitiesLight } from 'stringify-entities'
22
+ import { visitParents } from 'unist-util-visit-parents'
23
+ import { PRIMARY_SYMBOL_STR } from './const'
24
+
25
+ const own = {}.hasOwnProperty
26
+
27
+ /** @type {Readonly<ToMarkdownOptions>} */
28
+ const emptyOptions = {}
29
+
30
+ const shortcut = /^[^\t\n\r "#'.<=>`}]+$/
31
+ const unquoted = /^[^\t\n\r "'<=>`}]+$/
32
+
33
+ /**
34
+ * Create an extension for `mdast-util-from-markdown` to enable directives in
35
+ * markdown.
36
+ *
37
+ * @returns {FromMarkdownExtension}
38
+ * Extension for `mdast-util-from-markdown` to enable directives.
39
+ */
40
+ export function outputVarsFromMarkdown() {
41
+ return {
42
+ canContainEols: ['textDirective'],
43
+ enter: {
44
+ outputVarContainer: enterContainer,
45
+ outputVarContainerAttributes: enterAttributes,
46
+ outputVarContainerLabel: enterContainerLabel,
47
+ },
48
+ exit: {
49
+ outputVarContainer: exit,
50
+ outputVarContainerAttributeClassValue: exitAttributeClassValue,
51
+ outputVarContainerAttributeIdValue: exitAttributeIdValue,
52
+ outputVarContainerAttributeName: exitAttributeName,
53
+ outputVarContainerAttributeValue: exitAttributeValue,
54
+ outputVarContainerAttributes: exitAttributes,
55
+ outputVarContainerLabel: exitContainerLabel,
56
+ outputVarContainerName: exitName,
57
+ }
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Create an extension for `mdast-util-to-markdown` to enable directives in
63
+ * markdown.
64
+ *
65
+ * @param {Readonly<ToMarkdownOptions> | null | undefined} [options]
66
+ * Configuration (optional).
67
+ * @returns {ToMarkdownExtension}
68
+ * Extension for `mdast-util-to-markdown` to enable directives.
69
+ */
70
+ export function outputVarsToMarkdown(options?: any) {
71
+ const settings = options || emptyOptions
72
+
73
+ if (
74
+ settings.quote !== '"' &&
75
+ settings.quote !== "'" &&
76
+ settings.quote !== null &&
77
+ settings.quote !== undefined
78
+ ) {
79
+ throw new Error(
80
+ 'Invalid quote `' + settings.quote + '`, expected `\'` or `"`'
81
+ )
82
+ }
83
+
84
+ handleOutputVars.peek = peekDirective
85
+
86
+ return {
87
+ handlers: {
88
+ outputVars: handleOutputVars,
89
+ },
90
+ unsafe: [
91
+ {
92
+ character: '\r',
93
+ inConstruct: ['leafDirectiveLabel', 'outputVarsLabel']
94
+ },
95
+ {
96
+ character: '\n',
97
+ inConstruct: ['leafDirectiveLabel', 'outputVarsLabel']
98
+ },
99
+ {
100
+ before: '[^>]',
101
+ character: '>',
102
+ after: '[A-Za-z]',
103
+ inConstruct: ['phrasing']
104
+ },
105
+ { atBreak: true, character: '>', after: '>' }
106
+ ]
107
+ }
108
+
109
+ /**
110
+ * @type {ToMarkdownHandle}
111
+ * @param {Directives} node
112
+ */
113
+ function handleOutputVars(node, _, state, info) {
114
+ const tracker = state.createTracker(info)
115
+ const sequence = fence(node)
116
+ const exit = state.enter(node.type)
117
+ let value = tracker.move(sequence + (node.name || ''))
118
+ /** @type {LeafDirective | Paragraph | TextDirective | undefined} */
119
+ let label
120
+
121
+ if (node.type === 'outputVars') {
122
+ const head = (node.children || [])[0]
123
+ label = inlineDirectiveLabel(head) ? head : undefined
124
+ } else {
125
+ label = node
126
+ }
127
+
128
+ if (label && label.children && label.children.length > 0) {
129
+ const exit = state.enter('label')
130
+ /** @type {ConstructName} */
131
+ const labelType = `${node.type}Label`
132
+ const subexit = state.enter(labelType)
133
+ value += tracker.move('[')
134
+ value += tracker.move(
135
+ state.containerPhrasing(label, {
136
+ ...tracker.current(),
137
+ before: value,
138
+ after: ']'
139
+ })
140
+ )
141
+ value += tracker.move(']')
142
+ subexit()
143
+ exit()
144
+ }
145
+
146
+ value += tracker.move(attributes(node, state))
147
+
148
+ if (node.type === 'outputVars') {
149
+ const head = (node.children || [])[0]
150
+ let shallow = node
151
+
152
+ if (inlineDirectiveLabel(head)) {
153
+ shallow = Object.assign({}, node, { children: node.children.slice(1) })
154
+ }
155
+
156
+ if (shallow && shallow.children && shallow.children.length > 0) {
157
+ value += tracker.move('\n')
158
+ value += tracker.move(state.containerFlow(shallow, tracker.current()))
159
+ }
160
+
161
+ value += tracker.move('\n' + sequence)
162
+ }
163
+
164
+ exit()
165
+ return value
166
+ }
167
+
168
+ /**
169
+ * @param {Directives} node
170
+ * @param {State} state
171
+ * @returns {string}
172
+ */
173
+ function attributes(node, state) {
174
+ const attributes = node.attributes || {}
175
+ /** @type {Array<string>} */
176
+ const values = []
177
+ /** @type {string | undefined} */
178
+ let classesFull
179
+ /** @type {string | undefined} */
180
+ let classes
181
+ /** @type {string | undefined} */
182
+ let id
183
+ /** @type {string} */
184
+ let key
185
+
186
+ for (key in attributes) {
187
+ if (
188
+ own.call(attributes, key) &&
189
+ attributes[key] !== undefined &&
190
+ attributes[key] !== null
191
+ ) {
192
+ const value = String(attributes[key])
193
+
194
+ // To do: next major:
195
+ // Do not reorder `id` and `class` attributes when they do not turn into
196
+ // shortcuts.
197
+ // Additionally, join shortcuts: `#a .b.c d="e"` -> `#a.b.c d="e"`
198
+ if (key === 'id') {
199
+ id =
200
+ settings.preferShortcut !== false && shortcut.test(value)
201
+ ? '#' + value
202
+ : quoted('id', value, node, state)
203
+ } else if (key === 'class') {
204
+ const list = value.split(/[\t\n\r ]+/g)
205
+ /** @type {Array<string>} */
206
+ const classesFullList = []
207
+ /** @type {Array<string>} */
208
+ const classesList = []
209
+ let index = -1
210
+
211
+ while (++index < list.length) {
212
+ ; (settings.preferShortcut !== false && shortcut.test(list[index])
213
+ ? classesList
214
+ : classesFullList
215
+ ).push(list[index])
216
+ }
217
+
218
+ classesFull =
219
+ classesFullList.length > 0
220
+ ? quoted('class', classesFullList.join(' '), node, state)
221
+ : ''
222
+ classes = classesList.length > 0 ? '.' + classesList.join('.') : ''
223
+ } else {
224
+ values.push(quoted(key, value, node, state))
225
+ }
226
+ }
227
+ }
228
+
229
+ if (classesFull) {
230
+ values.unshift(classesFull)
231
+ }
232
+
233
+ if (classes) {
234
+ values.unshift(classes)
235
+ }
236
+
237
+ if (id) {
238
+ values.unshift(id)
239
+ }
240
+
241
+ return values.length > 0 ? '{' + values.join(' ') + '}' : ''
242
+ }
243
+
244
+ /**
245
+ * @param {string} key
246
+ * @param {string} value
247
+ * @param {Directives} node
248
+ * @param {State} state
249
+ * @returns {string}
250
+ */
251
+ function quoted(key, value, node, state) {
252
+ if (settings.collapseEmptyAttributes !== false && !value) return key
253
+
254
+ if (settings.preferUnquoted && unquoted.test(value)) {
255
+ return key + '=' + value
256
+ }
257
+
258
+ // If the alternative is less common than `quote`, switch.
259
+ const preferred = settings.quote || state.options.quote || '"'
260
+ const alternative = preferred === '"' ? "'" : '"'
261
+ // If the alternative is less common than `quote`, switch.
262
+ const appliedQuote =
263
+ settings.quoteSmart &&
264
+ ccount(value, preferred) > ccount(value, alternative)
265
+ ? alternative
266
+ : preferred
267
+ const subset =
268
+ node.type === 'textDirective'
269
+ ? [appliedQuote]
270
+ : [appliedQuote, '\n', '\r']
271
+
272
+ return (
273
+ key +
274
+ '=' +
275
+ appliedQuote +
276
+ stringifyEntitiesLight(value, { subset }) +
277
+ appliedQuote
278
+ )
279
+ }
280
+ }
281
+
282
+ /**
283
+ * @this {CompileContext}
284
+ * @type {FromMarkdownHandle}
285
+ */
286
+ function enterContainer(token) {
287
+ enter.call(this, 'outputVars', token)
288
+ }
289
+
290
+ /**
291
+ * @this {CompileContext}
292
+ * @type {FromMarkdownHandle}
293
+ */
294
+ function enterLeaf(token) {
295
+ enter.call(this, 'leafDirective', token)
296
+ }
297
+
298
+ /**
299
+ * @this {CompileContext}
300
+ * @type {FromMarkdownHandle}
301
+ */
302
+ function enterText(token) {
303
+ enter.call(this, 'textDirective', token)
304
+ }
305
+
306
+ /**
307
+ * @this {CompileContext}
308
+ * @param {Directives['type']} type
309
+ * @param {Token} token
310
+ */
311
+ function enter(type, token) {
312
+ this.enter({ type, name: '', attributes: {}, children: [] }, token)
313
+ }
314
+
315
+ /**
316
+ * @this {CompileContext}
317
+ * @param {Token} token
318
+ */
319
+ function exitName(token) {
320
+ const node = this.stack[this.stack.length - 1]
321
+ assert(
322
+ node.type === 'outputVars' ||
323
+ node.type === 'leafDirective' ||
324
+ node.type === 'textDirective'
325
+ )
326
+ node.name = this.sliceSerialize(token)
327
+ }
328
+
329
+ /**
330
+ * @this {CompileContext}
331
+ * @type {FromMarkdownHandle}
332
+ */
333
+ function enterContainerLabel(token) {
334
+ this.enter(
335
+ { type: 'paragraph', data: { directiveLabel: true }, children: [] },
336
+ token
337
+ )
338
+ }
339
+
340
+ /**
341
+ * @this {CompileContext}
342
+ * @type {FromMarkdownHandle}
343
+ */
344
+ function exitContainerLabel(token) {
345
+ this.exit(token)
346
+ }
347
+
348
+ /**
349
+ * @this {CompileContext}
350
+ * @type {FromMarkdownHandle}
351
+ */
352
+ function enterAttributes() {
353
+ this.data.directiveAttributes = []
354
+ this.buffer() // Capture EOLs
355
+ }
356
+
357
+ /**
358
+ * @this {CompileContext}
359
+ * @type {FromMarkdownHandle}
360
+ */
361
+ function exitAttributeIdValue(token) {
362
+ const list = this.data.directiveAttributes
363
+ assert(list, 'expected `directiveAttributes`')
364
+ list.push([
365
+ 'id',
366
+ parseEntities(this.sliceSerialize(token), { attribute: true })
367
+ ])
368
+ }
369
+
370
+ /**
371
+ * @this {CompileContext}
372
+ * @type {FromMarkdownHandle}
373
+ */
374
+ function exitAttributeClassValue(token) {
375
+ const list = this.data.directiveAttributes
376
+ assert(list, 'expected `directiveAttributes`')
377
+ list.push([
378
+ 'class',
379
+ parseEntities(this.sliceSerialize(token), { attribute: true })
380
+ ])
381
+ }
382
+
383
+ /**
384
+ * @this {CompileContext}
385
+ * @type {FromMarkdownHandle}
386
+ */
387
+ function exitAttributeValue(token) {
388
+ const list = this.data.directiveAttributes
389
+ assert(list, 'expected `directiveAttributes`')
390
+ list[list.length - 1][1] = parseEntities(this.sliceSerialize(token), {
391
+ attribute: true
392
+ })
393
+ }
394
+
395
+ /**
396
+ * @this {CompileContext}
397
+ * @type {FromMarkdownHandle}
398
+ */
399
+ function exitAttributeName(token) {
400
+ const list = this.data.directiveAttributes
401
+ assert(list, 'expected `directiveAttributes`')
402
+
403
+ // Attribute names in CommonMark are significantly limited, so character
404
+ // references can't exist.
405
+ list.push([this.sliceSerialize(token), ''])
406
+ }
407
+
408
+ /**
409
+ * @this {CompileContext}
410
+ * @type {FromMarkdownHandle}
411
+ */
412
+ function exitAttributes() {
413
+ const list = this.data.directiveAttributes
414
+ assert(list, 'expected `directiveAttributes`')
415
+ /** @type {Record<string, string>} */
416
+ const cleaned = {}
417
+ let index = -1
418
+
419
+ while (++index < list.length) {
420
+ const attribute = list[index]
421
+
422
+ if (attribute[0] === 'class' && cleaned.class) {
423
+ cleaned.class += ' ' + attribute[1]
424
+ } else {
425
+ cleaned[attribute[0]] = attribute[1]
426
+ }
427
+ }
428
+
429
+ this.data.directiveAttributes = undefined
430
+ this.resume() // Drop EOLs
431
+ const node = this.stack[this.stack.length - 1]
432
+ assert(
433
+ node.type === 'outputVars' ||
434
+ node.type === 'leafDirective' ||
435
+ node.type === 'textDirective'
436
+ )
437
+ node.attributes = cleaned
438
+ }
439
+
440
+ /**
441
+ * @this {CompileContext}
442
+ * @type {FromMarkdownHandle}
443
+ */
444
+ function exit(token) {
445
+ this.exit(token)
446
+ }
447
+
448
+ /** @type {ToMarkdownHandle} */
449
+ function peekDirective() {
450
+ return ':'
451
+ }
452
+
453
+ /**
454
+ * @param {Nodes} node
455
+ * @returns {node is Paragraph & {data: {directiveLabel: true}}}
456
+ */
457
+ function inlineDirectiveLabel(node) {
458
+ return Boolean(
459
+ node && node.type === 'paragraph' && node.data && node.data.directiveLabel
460
+ )
461
+ }
462
+
463
+ /**
464
+ * @param {Directives} node
465
+ * @returns {string}
466
+ */
467
+ function fence(node) {
468
+ let size = 0
469
+
470
+ if (node.type === 'outputVars') {
471
+ visitParents(node, function (node, parents) {
472
+ if (node.type === 'outputVars') {
473
+ let index = parents.length
474
+ let nesting = 0
475
+
476
+ while (index--) {
477
+ if (parents[index].type === 'outputVars') {
478
+ nesting++
479
+ }
480
+ }
481
+
482
+ if (nesting > size) size = nesting
483
+ }
484
+ })
485
+ size += 3
486
+ return `${PRIMARY_SYMBOL_STR}`.repeat(size)
487
+ } else if (node.type === 'leafDirective') {
488
+ size = 2
489
+ return `${PRIMARY_SYMBOL_STR}`.repeat(size)
490
+ } else {
491
+ size = 1
492
+ return `${PRIMARY_SYMBOL_STR}`.repeat(size)
493
+ }
494
+ }
@@ -0,0 +1,22 @@
1
+ import { outputVars } from './lib'
2
+ import { outputVarsFromMarkdown, outputVarsToMarkdown } from './lib/util'
3
+
4
+ export function remarkOutputVars() {
5
+ console.time('plugin:remarkOutputVars');
6
+ const data = this.data()
7
+
8
+ const micromarkExtensions =
9
+ data.micromarkExtensions || (data.micromarkExtensions = [])
10
+ const fromMarkdownExtensions =
11
+ data.fromMarkdownExtensions || (data.fromMarkdownExtensions = [])
12
+ const toMarkdownExtensions =
13
+ data.toMarkdownExtensions || (data.toMarkdownExtensions = [])
14
+
15
+ micromarkExtensions.push(outputVars())
16
+ fromMarkdownExtensions.push(outputVarsFromMarkdown())
17
+ toMarkdownExtensions.push(outputVarsToMarkdown())
18
+
19
+ console.timeEnd('plugin:remarkOutputVars');
20
+ return function () { }
21
+ }
22
+
@@ -0,0 +1,74 @@
1
+ // TODO: !!! in the future better solution? currently its a hack to override mdx components (react-components) declared in the file !!!
2
+ export function recmaOverrideComponents() {
3
+ return (tree: any) => {
4
+ for (let i = 0; i < tree.body.length; i++) {
5
+ const node = tree.body[i];
6
+
7
+ if (
8
+ node.type === 'FunctionDeclaration' &&
9
+ /^[A-Z]/.test(node.id.name)
10
+ ) {
11
+ const name = node.id.name;
12
+
13
+ if (name === "MDXContent") {
14
+ continue
15
+ }
16
+
17
+ // Fallback: () => null
18
+ const nullFn = {
19
+ type: 'ArrowFunctionExpression',
20
+ params: [],
21
+ body: { type: 'Literal', value: null },
22
+ expression: true,
23
+ };
24
+
25
+ const fileComponentsAndProp = {
26
+ type: 'LogicalExpression',
27
+ operator: '&&',
28
+ left: { type: 'Identifier', name: 'fileComponents' },
29
+ right: {
30
+ type: 'MemberExpression',
31
+ object: { type: 'Identifier', name: 'fileComponents' },
32
+ property: { type: 'Identifier', name },
33
+ computed: false,
34
+ },
35
+ };
36
+
37
+ const fileComponentsFalse = {
38
+ type: 'BinaryExpression',
39
+ operator: '===',
40
+ left: { type: 'Identifier', name: 'fileComponents' },
41
+ right: { type: 'Literal', value: false },
42
+ };
43
+
44
+ const fallback = {
45
+ type: 'ConditionalExpression',
46
+ test: fileComponentsFalse,
47
+ consequent: nullFn, // ✅ return a function that returns null
48
+ alternate: { type: 'Identifier', name },
49
+ };
50
+
51
+ const overrideExpr = {
52
+ type: 'ConditionalExpression',
53
+ test: fileComponentsAndProp,
54
+ consequent: fileComponentsAndProp,
55
+ alternate: fallback,
56
+ };
57
+
58
+ const assignOverride = {
59
+ type: 'ExpressionStatement',
60
+ expression: {
61
+ type: 'AssignmentExpression',
62
+ operator: '=',
63
+ left: { type: 'Identifier', name },
64
+ right: overrideExpr,
65
+ },
66
+ };
67
+
68
+ tree.body.splice(i + 1, 0, assignOverride);
69
+ i++; // Skip newly inserted node
70
+ }
71
+ }
72
+ };
73
+ }
74
+
@@ -0,0 +1,58 @@
1
+ import { visit } from 'unist-util-visit';
2
+ import type { Plugin } from 'unified';
3
+ import type { Root } from 'hast';
4
+
5
+ import { mdParameters } from './utils/mdParameters';
6
+
7
+ export const rehypeHeading: Plugin<[], Root> = () => {
8
+ return (tree) => {
9
+ visit(tree, 'element', (node, index, parent) => {
10
+ if (!node.tagName?.match(/^h[1-6]$/)) {
11
+ return;
12
+ }
13
+
14
+ // Get the heading text
15
+ const text = node.children
16
+ .map((child) => ('value' in child ? child.value : ''))
17
+ .join('');
18
+
19
+ // Parse props using curly braces
20
+ const { props } = mdParameters(text);
21
+
22
+ if (node.properties?.removeHeading) {
23
+ // Remove the node from the parent's children array
24
+ if (parent && typeof index === 'number') {
25
+ parent.children.splice(index, 1);
26
+ }
27
+ return;
28
+ }
29
+
30
+ if (node.properties?.hideHeading) {
31
+ const existingStyle = node.properties?.style || '';
32
+ node.properties = {
33
+ ...node.properties,
34
+ style: `${existingStyle} visibility: hidden; display: block`.trim()
35
+ };
36
+ }
37
+
38
+ for (const child of node.children) {
39
+ if (!('value' in child)) {
40
+ continue
41
+ }
42
+ const { sanitizedText } = mdParameters(child.value);
43
+
44
+ child.value = sanitizedText;
45
+ }
46
+
47
+ // If no props were found, return
48
+ if (Object.keys(props).length === 0) {
49
+ return;
50
+ }
51
+
52
+ node.properties = {
53
+ ...node.properties,
54
+ ...props,
55
+ };
56
+ });
57
+ };
58
+ };
@@ -0,0 +1,15 @@
1
+ import { VFile } from "vfile";
2
+
3
+ // Define the structure of outputVars with support for multiple types
4
+ export type OutputVars<T extends Record<string, any>> = {
5
+ [K in keyof T]: T[K];
6
+ };
7
+
8
+ // Define a custom VFile type that includes outputVars
9
+ export interface SymbolxVfile<T extends Record<string, any>> extends VFile {
10
+ data: {
11
+ outputVars?: OutputVars<T>;
12
+ [key: string]: any;
13
+ };
14
+ }
15
+