@xyd-js/content 0.1.0-build.171
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.
- package/CHANGELOG.md +2174 -0
- package/ISSUES.md +1 -0
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/TODO.md +2 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +1625 -0
- package/dist/index.js.map +1 -0
- package/dist/md.d.ts +72 -0
- package/dist/md.js +23508 -0
- package/dist/md.js.map +1 -0
- package/dist/mdToc-NBBxMJ4l.d.ts +12 -0
- package/dist/vite.d.ts +1066 -0
- package/dist/vite.js +20156 -0
- package/dist/vite.js.map +1 -0
- package/package.json +67 -0
- package/packages/md/index.ts +25 -0
- package/packages/md/plugins/component-directives/index.ts +3 -0
- package/packages/md/plugins/component-directives/mdComponentDirective.ts +577 -0
- package/packages/md/plugins/component-directives/types.ts +1 -0
- package/packages/md/plugins/component-directives/utils.ts +27 -0
- package/packages/md/plugins/composer/__fixtures__/1.single-example/input.md +7 -0
- package/packages/md/plugins/composer/__fixtures__/1.single-example/output.json +63 -0
- package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/input.md +7 -0
- package/packages/md/plugins/composer/__fixtures__/2.single-example-with-name/output.json +63 -0
- package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/input.md +15 -0
- package/packages/md/plugins/composer/__fixtures__/3.multiple-examples/output.json +122 -0
- package/packages/md/plugins/composer/__fixtures__/4.example-groups/input.md +23 -0
- package/packages/md/plugins/composer/__fixtures__/4.example-groups/output.json +184 -0
- package/packages/md/plugins/composer/__tests__/mdComposer.test.ts +41 -0
- package/packages/md/plugins/composer/__tests__/testHelpers.ts +48 -0
- package/packages/md/plugins/composer/index.ts +1 -0
- package/packages/md/plugins/composer/mdComposer.ts +146 -0
- package/packages/md/plugins/developer-writing/index.ts +3 -0
- package/packages/md/plugins/developer-writing/mdCodeRehype.ts +81 -0
- package/packages/md/plugins/functions/__fixtures__/external.ts +4 -0
- package/packages/md/plugins/functions/__fixtures__/test-include.md +31 -0
- package/packages/md/plugins/functions/__fixtures__/test.js +11 -0
- package/packages/md/plugins/functions/__fixtures__/test.py +9 -0
- package/packages/md/plugins/functions/__fixtures__/test.ts +18 -0
- package/packages/md/plugins/functions/__tests__/mdFunctionImportCode.test.ts +314 -0
- package/packages/md/plugins/functions/__tests__/mdFunctionInclude.test.ts +44 -0
- package/packages/md/plugins/functions/__tests__/parseFunctionCall.test.ts +70 -0
- package/packages/md/plugins/functions/__tests__/testHelpers.ts +95 -0
- package/packages/md/plugins/functions/index.ts +15 -0
- package/packages/md/plugins/functions/mdFunctionChangelog.ts +135 -0
- package/packages/md/plugins/functions/mdFunctionImportCode.ts +92 -0
- package/packages/md/plugins/functions/mdFunctionInclude.ts +119 -0
- package/packages/md/plugins/functions/mdFunctionUniform.ts +79 -0
- package/packages/md/plugins/functions/types.ts +9 -0
- package/packages/md/plugins/functions/uniformProcessor.ts +349 -0
- package/packages/md/plugins/functions/utils.ts +457 -0
- package/packages/md/plugins/index.ts +125 -0
- package/packages/md/plugins/mdCode.ts +16 -0
- package/packages/md/plugins/mdHeadingId.ts +47 -0
- package/packages/md/plugins/mdImage.test.ts +59 -0
- package/packages/md/plugins/mdImage.ts +55 -0
- package/packages/md/plugins/mdImageRehype.ts +13 -0
- package/packages/md/plugins/mdPage.ts +35 -0
- package/packages/md/plugins/mdThemeSettings.ts +34 -0
- package/packages/md/plugins/mdToc.ts +229 -0
- package/packages/md/plugins/meta/index.ts +1 -0
- package/packages/md/plugins/meta/mdMeta.ts +198 -0
- package/packages/md/plugins/output-variables/__fixtures__/1.simple/input.md +22 -0
- package/packages/md/plugins/output-variables/__fixtures__/1.simple/output.json +191 -0
- package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/input.md +21 -0
- package/packages/md/plugins/output-variables/__fixtures__/2.multiple-vars/output.json +127 -0
- package/packages/md/plugins/output-variables/__tests__/index.test.ts +28 -0
- package/packages/md/plugins/output-variables/__tests__/testHelpers.ts +36 -0
- package/packages/md/plugins/output-variables/index.ts +1 -0
- package/packages/md/plugins/output-variables/lib/const.ts +4 -0
- package/packages/md/plugins/output-variables/lib/factoryAttributes.ts +350 -0
- package/packages/md/plugins/output-variables/lib/factoryLabel.ts +135 -0
- package/packages/md/plugins/output-variables/lib/factoryName.ts +59 -0
- package/packages/md/plugins/output-variables/lib/index.ts +21 -0
- package/packages/md/plugins/output-variables/lib/outputVarsContainer.ts +328 -0
- package/packages/md/plugins/output-variables/lib/util.ts +494 -0
- package/packages/md/plugins/output-variables/remarkOutputVars.ts +22 -0
- package/packages/md/plugins/recmaOverrideComponents.ts +74 -0
- package/packages/md/plugins/rehypeHeading.ts +58 -0
- package/packages/md/plugins/types.ts +15 -0
- package/packages/md/plugins/utils/componentLike.ts +76 -0
- package/packages/md/plugins/utils/index.ts +2 -0
- package/packages/md/plugins/utils/injectCodeMeta.ts +59 -0
- package/packages/md/plugins/utils/mdParameters.test.ts +114 -0
- package/packages/md/plugins/utils/mdParameters.ts +249 -0
- package/packages/md/plugins/utils/mdastTypes.ts +42 -0
- package/packages/md/search/index.ts +257 -0
- package/packages/md/search/types.ts +36 -0
- package/packages/vite/index.ts +20 -0
- package/src/fs.ts +81 -0
- package/src/index.ts +7 -0
- package/src/navigation.ts +147 -0
- package/src/types.ts +8 -0
- package/tsconfig.json +49 -0
- package/tsup.config.ts +32 -0
- 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
|
+
|