@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
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@xyd-js/content",
3
+ "version": "0.0.0-build+6952c2c-20250813013245",
4
+ "description": "",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "exports": {
8
+ "./package.json": "./package.json",
9
+ ".": "./dist/index.js",
10
+ "./vite": "./dist/vite.js",
11
+ "./md": "./dist/md.js"
12
+ },
13
+ "dependencies": {
14
+ "@mapbox/hast-util-to-jsx": "^2.1.0",
15
+ "@mdx-js/mdx": "^3.1.0",
16
+ "@mdx-js/rollup": "^3.0.1",
17
+ "acorn-jsx": "^5.3.2",
18
+ "codehike": "^1.0.4",
19
+ "estree-util-is-identifier-name": "^3.0.0",
20
+ "estree-util-value-to-estree": "^3.1.2",
21
+ "github-slugger": "^2.0.0",
22
+ "gray-matter": "^4.0.3",
23
+ "mdast": "^3.0.0",
24
+ "mdast-util-mdx": "^3.0.0",
25
+ "mdast-util-mdx-jsx": "^3.2.0",
26
+ "mdast-util-to-string": "^4.0.0",
27
+ "micromark-extension-mdxjs": "^3.0.0",
28
+ "react-element-to-jsx-string": "^17.0.0",
29
+ "rehype-katex": "^7.0.1",
30
+ "rehype-raw": "^7.0.0",
31
+ "rehype-react": "^8.0.0",
32
+ "remark-directive": "^3.0.0",
33
+ "remark-frontmatter": "^5.0.0",
34
+ "remark-gfm": "^4.0.0",
35
+ "remark-math": "^6.0.0",
36
+ "remark-mdx-frontmatter": "^5.0.0",
37
+ "unified": "^11.0.5",
38
+ "unist-util-visit": "^5.0.0",
39
+ "vfile": "^6.0.3",
40
+ "vfile-matter": "^5.0.1",
41
+ "@xyd-js/context": "0.0.0-build+6952c2c-20250813013245",
42
+ "@xyd-js/core": "0.0.0-build+6952c2c-20250813013245",
43
+ "@xyd-js/gql": "0.0.0-build+6952c2c-20250813013245",
44
+ "@xyd-js/openapi": "0.0.0-build+6952c2c-20250813013245",
45
+ "@xyd-js/sources": "0.0.0-build+6952c2c-20250813013245"
46
+ },
47
+ "peerDependencies": {
48
+ "@xyd-js/components": "0.0.0-build+6952c2c-20250813013245"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.14.1",
52
+ "@vitest/coverage-v8": "^1.3.1",
53
+ "rimraf": "^3.0.2",
54
+ "tsup": "^8.3.0",
55
+ "typescript": "^4.5.5",
56
+ "vite": "^7.0.0",
57
+ "vitest": "^1.3.1"
58
+ },
59
+ "scripts": {
60
+ "clean": "rimraf build",
61
+ "prebuild": "pnpm clean",
62
+ "build": "tsup",
63
+ "watch": "tsup --watch",
64
+ "test": "vitest",
65
+ "test:watch": "vitest watch"
66
+ }
67
+ }
@@ -0,0 +1,25 @@
1
+ import { Settings } from "@xyd-js/core";
2
+
3
+ import { defaultRecmaPlugins, defaultRehypePlugins, defaultRemarkPlugins } from "./plugins"
4
+ import { RemarkMdxTocOptions } from "./plugins/mdToc";
5
+
6
+ export { RemarkMdxTocOptions, } from "./plugins/mdToc";
7
+ export { mapSettingsToDocSections } from "./search"
8
+ export type { DocSectionSchema } from "./search/types"
9
+
10
+ export async function markdownPlugins(
11
+ toc: RemarkMdxTocOptions, // TODO: unify this cuz it should come from core -global settings and toc options?
12
+ settings?: Settings
13
+ ) {
14
+ const remarkPlugins = [...defaultRemarkPlugins(toc, settings)]
15
+
16
+ const rehypePlugins = [...(await defaultRehypePlugins(settings))]
17
+
18
+ const recmaPlugins = [...defaultRecmaPlugins(settings)]
19
+
20
+ return {
21
+ remarkPlugins,
22
+ rehypePlugins,
23
+ recmaPlugins,
24
+ }
25
+ }
@@ -0,0 +1,3 @@
1
+ export {
2
+ mdComponentDirective
3
+ } from "./mdComponentDirective"
@@ -0,0 +1,577 @@
1
+ import { Plugin, unified } from "unified";
2
+ import remarkParse from "remark-parse";
3
+ import remarkMdx from "remark-mdx";
4
+ import { visit } from "unist-util-visit";
5
+ import { VFile } from "vfile";
6
+ import { Node as UnistNode } from "unist";
7
+ import { highlight } from "codehike/code"
8
+
9
+ import { Settings } from "@xyd-js/core";
10
+ import { uniformToMiniUniform } from "@xyd-js/sources/ts";
11
+
12
+ import { FunctionName } from "../functions/types";
13
+ import { MarkdownComponentDirectiveMap } from "./types";
14
+ import { functionMatch, parseFunctionCall } from "../functions/utils";
15
+ import { processUniformFunctionCall } from "../functions/uniformProcessor";
16
+
17
+ import { getComponentName } from "./utils";
18
+ import { Reference, TypeDocReferenceContext } from "@xyd-js/uniform";
19
+ import { mdParameters } from "../utils/mdParameters";
20
+
21
+ // TODO: in the future custom component: `this.registerComponent(MyComponent, "my-component")` ? but core should move to `symbolx`?
22
+ const supportedDirectives: MarkdownComponentDirectiveMap = {
23
+ details: true,
24
+
25
+ callout: true,
26
+
27
+ table: true,
28
+
29
+ subtitle: true,
30
+
31
+ steps: true,
32
+
33
+ "guide-card": "GuideCard",
34
+
35
+ "code-group": "DirectiveCodeGroup",
36
+
37
+ tabs: "Tabs",
38
+
39
+ atlas: true,
40
+
41
+ badge: true,
42
+
43
+ grid: "GridDecorator",
44
+
45
+ button: true,
46
+
47
+ update: true,
48
+
49
+ card: true,
50
+
51
+ feature: true,
52
+ }
53
+
54
+ const supportedTextDirectives: MarkdownComponentDirectiveMap = {
55
+ icon: true,
56
+ br: true,
57
+ }
58
+
59
+ const supportedLeafDirectives: MarkdownComponentDirectiveMap = {
60
+ atlas: true,
61
+ card: true,
62
+ "color-scheme-button": "ColorSchemeButton",
63
+ }
64
+
65
+ const tableComponents: MarkdownComponentDirectiveMap = {
66
+ Table: true,
67
+ table: true
68
+ }
69
+
70
+ const stepsComponents: MarkdownComponentDirectiveMap = {
71
+ Steps: true,
72
+ steps: true
73
+ }
74
+
75
+ const codeComponents: MarkdownComponentDirectiveMap = {
76
+ "code-group": "DirectiveCodeGroup",
77
+ }
78
+
79
+ const navComponents: MarkdownComponentDirectiveMap = {
80
+ tabs: "Tabs",
81
+ }
82
+
83
+ const parseMarkdown = (content: string) => {
84
+ const ast = unified()
85
+ .use(remarkParse)
86
+ .use(remarkMdx)
87
+ .parse(content);
88
+
89
+ return ast.children;
90
+ };
91
+
92
+ // TODO: BETTER SETTINGS MANAGEMENT FOR MD
93
+
94
+ export function mdComponentDirective(settings?: Settings): Plugin {
95
+ return function () {
96
+ return async (tree: UnistNode, file: VFile) => {
97
+ console.time('plugin:mdComponentDirective');
98
+ const promises: Promise<void>[] = [];
99
+
100
+ visit(tree, 'containerDirective', recreateComponent(file, promises, supportedDirectives, settings));
101
+ visit(tree, 'textDirective', recreateComponent(file, promises, supportedTextDirectives, settings));
102
+ visit(tree, 'leafDirective', recreateComponent(file, promises, supportedLeafDirectives, settings));
103
+
104
+ await Promise.all(promises);
105
+ console.timeEnd('plugin:mdComponentDirective');
106
+ }
107
+ }
108
+ }
109
+
110
+ function recreateComponent(
111
+ file: VFile,
112
+ promises: Promise<void>[],
113
+ directivesMap: MarkdownComponentDirectiveMap,
114
+ settings?: Settings,
115
+ ) {
116
+ return function (node: any) {
117
+ if (!directivesMap[node.name]) {
118
+ return;
119
+ }
120
+
121
+ const attributes: any[] = [];
122
+
123
+ const componentName = getComponentName(node.name, directivesMap);
124
+
125
+ const isNavLike = navComponents[node.name];
126
+ const isTableLike = tableComponents[node.name];
127
+ const isStepsLike = stepsComponents[node.name];
128
+ const isCodeLike = codeComponents[node.name];
129
+
130
+ if (isNavLike) {
131
+ componentProps(
132
+ node,
133
+ attributes,
134
+ promises,
135
+ file,
136
+ settings,
137
+ );
138
+
139
+ mdNav(node, directivesMap, attributes);
140
+ return;
141
+ }
142
+
143
+ if (isStepsLike) {
144
+ componentProps(
145
+ node,
146
+ attributes,
147
+ promises,
148
+ file,
149
+ settings,
150
+ );
151
+
152
+ mdSteps(node, directivesMap, attributes);
153
+ return;
154
+ }
155
+
156
+ if (isTableLike) {
157
+ mdTable(node, directivesMap);
158
+ return;
159
+ }
160
+
161
+ if (isCodeLike) {
162
+ componentProps(
163
+ node,
164
+ attributes,
165
+ promises,
166
+ file,
167
+ settings,
168
+ );
169
+
170
+
171
+ mdCode(node, promises, directivesMap, settings, attributes);
172
+ return
173
+ }
174
+
175
+ if (node.attributes) {
176
+ componentProps(
177
+ node,
178
+ attributes,
179
+ promises,
180
+ file,
181
+ settings,
182
+ );
183
+ }
184
+
185
+ // recreate component from markdown directive
186
+ const jsxNode = {
187
+ type: 'mdxJsxFlowElement',
188
+ name: componentName,
189
+ attributes: attributes,
190
+ children: node.children,
191
+ };
192
+
193
+ Object.assign(node, jsxNode);
194
+ }
195
+ }
196
+
197
+ function mdNav(node: any, directivesMap: MarkdownComponentDirectiveMap, attributes: any[]) {
198
+ const componentName = getComponentName(node.name, directivesMap);
199
+
200
+ // Parse the nav directive content to extract tabs and their content
201
+ const tabItems: any[] = [];
202
+ const tabContents: any[] = [];
203
+
204
+ // Process each child node
205
+ node.children.forEach((child: any) => {
206
+ // Check if this is a list (ordered or unordered)
207
+ if (child.type === 'list') {
208
+ // Process each list item
209
+ child.children.forEach((listItem: any) => {
210
+ if (listItem.type === 'listItem') {
211
+ // The first child of a list item should be a paragraph with a link
212
+ const paragraph = listItem.children[0];
213
+ if (paragraph && paragraph.type === 'paragraph') {
214
+ const link = paragraph.children[0];
215
+
216
+ if (!link || link.type !== 'link' || !link.url) {
217
+ return;
218
+ }
219
+
220
+ // Extract tab value and label
221
+ let tabValue = '';
222
+ const linkUrlFormula = (link.url || "").split(" ").join("&")
223
+ if (link.url.startsWith('#')) {
224
+ tabValue = link.url;
225
+ } else {
226
+ tabValue = linkUrlFormula
227
+ }
228
+ const tabLabel = link.children[0].value;
229
+
230
+ // Create tab item
231
+ tabItems.push({
232
+ type: 'mdxJsxFlowElement',
233
+ name: `${componentName}.Item`,
234
+ attributes: [
235
+ {
236
+ type: 'mdxJsxAttribute',
237
+ name: 'value',
238
+ value: tabValue
239
+ },
240
+ {
241
+ type: 'mdxJsxAttribute',
242
+ name: 'href',
243
+ value: tabValue
244
+ }
245
+ ],
246
+ children: [{
247
+ type: 'text',
248
+ value: tabLabel
249
+ }]
250
+ });
251
+
252
+ // Get the content for this tab (everything after the paragraph)
253
+ const tabContent = listItem.children.slice(1);
254
+
255
+ // Create tab content
256
+ tabContents.push({
257
+ type: 'mdxJsxFlowElement',
258
+ name: `${componentName}.Content`,
259
+ attributes: [{
260
+ type: 'mdxJsxAttribute',
261
+ name: 'value',
262
+ value: tabValue
263
+ }],
264
+ children: tabContent
265
+ });
266
+ }
267
+ }
268
+ });
269
+ }
270
+ });
271
+
272
+ // Create the Tabs component with tabs and content
273
+ const jsxNode = {
274
+ type: 'mdxJsxFlowElement',
275
+ name: componentName,
276
+ attributes,
277
+ // attributes: [
278
+ // // We don't need to provide value or onChange for uncontrolled mode
279
+ // ],
280
+ children: [...tabItems, ...tabContents]
281
+ };
282
+
283
+ Object.assign(node, jsxNode);
284
+
285
+ return;
286
+ }
287
+
288
+ function mdSteps(node: any, directivesMap: MarkdownComponentDirectiveMap, attributes: any[]) {
289
+ const componentName = getComponentName(node.name, directivesMap);
290
+
291
+ const steps = node.children.map((child: any) => {
292
+ if (child.type !== "list") {
293
+ return child
294
+ }
295
+
296
+ return child.children.map((item: any) => {
297
+ if (item.type !== "listItem") {
298
+ return
299
+ }
300
+
301
+ const attributes: any[] = []
302
+
303
+ if (item.children.length) {
304
+ const firstChild = item.children[0]
305
+
306
+ if (firstChild?.children?.length === 1) {
307
+ const step = firstChild?.children[0]
308
+ if (step?.type === "text" || step?.type === "paragraph" && step?.value) {
309
+ const stepParams = mdParameters(step.value)
310
+
311
+ // TODO: sanitize text
312
+ if (stepParams.attributes && Object.keys(stepParams.attributes).length) {
313
+ firstChild.children[0].value = stepParams.sanitizedText
314
+
315
+ for (const [key, value] of Object.entries(stepParams.attributes)) {
316
+ attributes.push({
317
+ type: 'mdxJsxAttribute',
318
+ name: key,
319
+ value: value
320
+ })
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+
327
+ return {
328
+ type: 'mdxJsxFlowElement',
329
+ name: `${componentName}.Item`,
330
+ attributes,
331
+ children: item.children
332
+ };
333
+ }).flat();
334
+ }).flat();
335
+
336
+ const jsxNode = {
337
+ type: 'mdxJsxFlowElement',
338
+ name: componentName,
339
+ attributes,
340
+ children: steps
341
+ };
342
+
343
+ Object.assign(node, jsxNode);
344
+
345
+ return;
346
+ }
347
+
348
+ // TODO: support tsx tables like: [<>`Promise<Reference[]>`</>] ?
349
+ function mdTable(node: any, directivesMap: MarkdownComponentDirectiveMap) {
350
+ const componentName = getComponentName(node.name, directivesMap);
351
+ const tableData = JSON.parse(node.children[0].value);
352
+ const [header, ...rows] = tableData;
353
+
354
+ const jsxNode = {
355
+ type: 'mdxJsxFlowElement',
356
+ name: componentName,
357
+ attributes: [],
358
+ children: [
359
+ {
360
+ type: 'mdxJsxFlowElement',
361
+ name: `${componentName}.Head`,
362
+ attributes: [],
363
+ children: [
364
+ {
365
+ type: 'mdxJsxFlowElement',
366
+ name: `${componentName}.Tr`,
367
+ attributes: [],
368
+ children: header.map((cell: string) => ({
369
+ type: 'mdxJsxFlowElement',
370
+ name: `${componentName}.Th`,
371
+ attributes: [],
372
+ children: parseMarkdown(cell)
373
+ }))
374
+ }
375
+ ]
376
+ },
377
+ // TODO: Table.Cell ?
378
+ ...rows.map((row: string[]) => ({
379
+ type: 'mdxJsxFlowElement',
380
+ name: `${componentName}.Tr`,
381
+ attributes: [],
382
+ children: row.map((cell: string) => ({
383
+ type: 'mdxJsxFlowElement',
384
+ name: `${componentName}.Td`,
385
+ attributes: [],
386
+ children: parseMarkdown(cell)
387
+ }))
388
+ }))
389
+ ]
390
+ };
391
+
392
+ Object.assign(node, jsxNode);
393
+
394
+ return;
395
+ }
396
+
397
+ function mdCode(node: any, promises: Promise<any>[], directivesMap: MarkdownComponentDirectiveMap, settings?: Settings, attributes: any[]) {
398
+ const componentName = getComponentName(node.name, directivesMap);
399
+
400
+ const description = node.attributes?.title || '';
401
+ const codeblocks: any[] = [];
402
+
403
+ function rewriteNode() {
404
+ const jsxNode = {
405
+ type: 'mdxJsxFlowElement',
406
+ name: componentName,
407
+ attributes: [
408
+ ...attributes,
409
+ {
410
+ type: 'mdxJsxAttribute',
411
+ name: 'description',
412
+ value: description
413
+ },
414
+ {
415
+ type: 'mdxJsxAttribute',
416
+ name: 'codeblocks',
417
+ value: JSON.stringify(codeblocks)
418
+ }
419
+ ],
420
+ children: []
421
+ };
422
+
423
+ Object.assign(node, jsxNode);
424
+ }
425
+
426
+ for (const child of node.children) {
427
+ if (child.type === 'code') {
428
+
429
+ const meta = child.meta || '';
430
+ const value = child.value || '';
431
+ const lang = child.lang || '';
432
+
433
+ const promise = (async () => {
434
+ const highlighted = await highlight({
435
+ value: value,
436
+ lang,
437
+ meta: meta || lang || ""
438
+ }, settings?.theme?.coder?.syntaxHighlight || "github-dark") // TODO: theme
439
+
440
+ codeblocks.push({ value, lang, meta, highlighted: highlighted });
441
+ rewriteNode()
442
+ })()
443
+
444
+ promises.push(promise)
445
+ }
446
+ }
447
+ }
448
+
449
+
450
+ function componentProps(
451
+ node: any,
452
+ attributes: any[],
453
+ promises: Promise<void>[],
454
+ file: VFile,
455
+ settings?: Settings,
456
+ ) {
457
+
458
+ const jsxProps = []
459
+
460
+ for (let [key, value] of Object.entries(node.attributes)) {
461
+ const stringNonJsxProp = isStringNonJsxProp(value as string)
462
+
463
+ if (stringNonJsxProp) {
464
+ if (functionMatch(value as string, FunctionName.Uniform)) {
465
+ const promise = mdUniformAttribute(key, value as string, attributes, file, settings);
466
+
467
+ if (promise) {
468
+ promises.push(promise)
469
+ }
470
+
471
+ continue;
472
+ }
473
+
474
+ attributes.push({
475
+ type: 'mdxJsxAttribute',
476
+ name: key,
477
+ value: value
478
+ });
479
+ } else {
480
+ jsxProps.push(`${key}={${value}}`)
481
+ }
482
+ }
483
+
484
+ if (jsxProps.length > 0) {
485
+ attributes.push(...complexJSXPropsPollyfill(jsxProps))
486
+ }
487
+ }
488
+
489
+ // parses structure like: <Atlas references={@uniform("index.ts")} />
490
+ function mdUniformAttribute(
491
+ attrKey: string, // like `references`
492
+ attrValue: string, // like `@uniform("index.ts")`
493
+ attributes: any,
494
+ file: VFile,
495
+ settings?: Settings
496
+ ) {
497
+
498
+ const result = parseFunctionCall({
499
+ children: [
500
+ {
501
+ type: "text",
502
+ value: attrValue
503
+ }
504
+ ]
505
+ }, FunctionName.Uniform);
506
+
507
+ if (!result) {
508
+ return
509
+ };
510
+
511
+ const importPath = result[0];
512
+ const importArgs = result[1];
513
+
514
+ const promise = (async () => {
515
+ try {
516
+ // Process the uniform function call
517
+ let references = await processUniformFunctionCall(
518
+ importPath,
519
+ file,
520
+ "",
521
+ settings,
522
+ );
523
+
524
+ if (importArgs?.mini && references) { // TODO: move to `processUniformFunctionCall`
525
+ references = uniformToMiniUniform(importArgs.mini, references as Reference<TypeDocReferenceContext>[]);
526
+ }
527
+
528
+ if (references && references.length > 0) {
529
+ attributes.push({
530
+ type: 'mdxJsxAttribute',
531
+ name: attrKey,
532
+ value: JSON.stringify(references, null, 2)
533
+ });
534
+ }
535
+ } catch (error) {
536
+ console.error(`Error processing uniform function call: ${importPath}`, error);
537
+ // Keep the node as is if there's an error
538
+ }
539
+ })();
540
+
541
+ return promise
542
+ }
543
+
544
+ // TODO: FIND BETTER SOLUTION TO CONVERT MORE COMPLEX JSX PROPS?
545
+
546
+ //jsxProps = ["key=value", "key2=value2"]
547
+ function complexJSXPropsPollyfill(jsxProps: string[]) {
548
+ const attributes = [];
549
+
550
+ const mdxString = `<Fragment ${jsxProps.join(" ")}></Fragment>`
551
+
552
+ const ast = unified()
553
+ .use(remarkParse)
554
+ .use(remarkMdx)
555
+ .parse(mdxString);
556
+
557
+ // Check if the first child is an MDX JSX element with attributes
558
+ if (ast &&
559
+ ast.children[0] &&
560
+ 'type' in ast.children[0] &&
561
+ ast.children[0].type === 'mdxJsxFlowElement' &&
562
+ 'attributes' in ast.children[0] &&
563
+ ast.children[0].attributes) {
564
+ for (const attr of ast.children[0].attributes) {
565
+ // TODO: support markdown also e.g Hello `World` - currently it mus be: Hello <code>World</code>
566
+
567
+ attributes.push(attr);
568
+ }
569
+ }
570
+
571
+ return attributes
572
+ }
573
+
574
+ // TODO: better matching
575
+ function isStringNonJsxProp(value: string): boolean {
576
+ return typeof value === "string" && !value.startsWith("<");
577
+ }
@@ -0,0 +1 @@
1
+ export type MarkdownComponentDirectiveMap = { [key: string]: boolean | string }
@@ -0,0 +1,27 @@
1
+ import { MarkdownComponentDirectiveMap } from "./types"
2
+
3
+ export function getComponentName(
4
+ name: string,
5
+ supportedDirectives: MarkdownComponentDirectiveMap
6
+ ) {
7
+ let componentName = ""
8
+
9
+ const directive = supportedDirectives[name]
10
+
11
+ if (typeof directive === "string") {
12
+ componentName = directive
13
+ } else {
14
+ componentName = toPascalCase(name)
15
+ }
16
+
17
+ return componentName
18
+ }
19
+
20
+ function toPascalCase(str: string) {
21
+ return str
22
+ .replace(/([a-z])([A-Z])/g, "$1 $2") // Add space before capital letters
23
+ .replace(/[^a-zA-Z0-9]/g, " ") // Replace special characters with space
24
+ .split(" ") // Split by space
25
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize first letter
26
+ .join("");
27
+ }