@principal-ade/industry-themed-mdx-editor 0.1.2 → 0.1.4

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 (24) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.mjs +511 -1
  4. package/dist/src/components/ThemedMDXEditor.d.ts +1 -0
  5. package/dist/src/components/ThemedMDXEditor.d.ts.map +1 -1
  6. package/dist/src/plugins/mdx-auto-fix/index.d.ts +7 -0
  7. package/dist/src/plugins/mdx-auto-fix/index.d.ts.map +1 -0
  8. package/dist/src/plugins/mdx-auto-fix/plugin.d.ts +12 -0
  9. package/dist/src/plugins/mdx-auto-fix/plugin.d.ts.map +1 -0
  10. package/dist/src/plugins/mdx-auto-fix/preprocessor.d.ts +17 -0
  11. package/dist/src/plugins/mdx-auto-fix/preprocessor.d.ts.map +1 -0
  12. package/dist/src/plugins/mdx-auto-fix/transformers/code-block-language.d.ts +3 -0
  13. package/dist/src/plugins/mdx-auto-fix/transformers/code-block-language.d.ts.map +1 -0
  14. package/dist/src/plugins/mdx-auto-fix/transformers/greater-than-digit.d.ts +3 -0
  15. package/dist/src/plugins/mdx-auto-fix/transformers/greater-than-digit.d.ts.map +1 -0
  16. package/dist/src/plugins/mdx-auto-fix/transformers/index.d.ts +8 -0
  17. package/dist/src/plugins/mdx-auto-fix/transformers/index.d.ts.map +1 -0
  18. package/dist/src/plugins/mdx-auto-fix/transformers/invalid-tag-names.d.ts +3 -0
  19. package/dist/src/plugins/mdx-auto-fix/transformers/invalid-tag-names.d.ts.map +1 -0
  20. package/dist/src/plugins/mdx-auto-fix/transformers/less-than-digit.d.ts +3 -0
  21. package/dist/src/plugins/mdx-auto-fix/transformers/less-than-digit.d.ts.map +1 -0
  22. package/dist/src/plugins/mdx-auto-fix/types.d.ts +24 -0
  23. package/dist/src/plugins/mdx-auto-fix/types.d.ts.map +1 -0
  24. package/package.json +8 -3
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export { ThemedMDXEditorWithProvider } from './src/components/ThemedMDXEditorWit
4
4
  export type { ThemedMDXEditorWithProviderProps } from './src/components/ThemedMDXEditorWithProvider';
5
5
  export { useThemedMDXEditor } from './src/hooks/useThemedMDXEditor';
6
6
  export { createCodeMirrorTheme, createAutoCodeMirrorTheme } from './src/utils/codeMirrorTheme';
7
+ export { preprocessMDX, defaultPreprocessRules, mdxAutoFix, lessThanDigitTransformer, greaterThanDigitTransformer, invalidTagNamesTransformer, defaultTransformers, allTransformers, } from './src/plugins/mdx-auto-fix';
8
+ export type { PreprocessRule, MDXAutoFixOptions, Transformer, TransformerContext, TransformerStats, TransformerTestCase, } from './src/plugins/mdx-auto-fix';
7
9
  export type { Theme } from '@a24z/industry-theme';
8
10
  export type { MDXEditorMethods, MDXEditorProps } from '@mdxeditor/editor';
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAE9F,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAC3F,YAAY,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAGrG,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAG/F,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAE9F,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAC3F,YAAY,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAGrG,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAG/F,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,mBAAmB,EACnB,eAAe,GAChB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.mjs CHANGED
@@ -3,6 +3,499 @@ import {
3
3
  MDXEditor
4
4
  } from "@mdxeditor/editor";
5
5
  import "@mdxeditor/editor/style.css";
6
+
7
+ // src/plugins/mdx-auto-fix/preprocessor.ts
8
+ var defaultPreprocessRules = [
9
+ {
10
+ name: "normalize-code-block-language",
11
+ description: "Normalize unknown code block language identifiers",
12
+ pattern: /```(argdown|N\/A|n\/a)\n/gi,
13
+ replacement: (_match, lang) => {
14
+ const langLower = lang.toLowerCase();
15
+ if (langLower === "n/a") {
16
+ return "```text\n";
17
+ }
18
+ if (langLower === "argdown") {
19
+ return "```markdown\n";
20
+ }
21
+ return "```text\n";
22
+ }
23
+ },
24
+ {
25
+ name: "less-than-digit",
26
+ description: "Escape < followed by digit",
27
+ pattern: /<(?=\d)/g,
28
+ replacement: "&lt;"
29
+ },
30
+ {
31
+ name: "less-than-space-digit",
32
+ description: "Escape < followed by space and digit",
33
+ pattern: /<(\s+)(?=\d)/g,
34
+ replacement: (_match, spaces) => `&lt;${spaces}`
35
+ },
36
+ {
37
+ name: "greater-than-digit",
38
+ description: "Escape > followed by digit",
39
+ pattern: /(?<![-\w])>(?=\s?\d)/g,
40
+ replacement: "&gt;"
41
+ },
42
+ {
43
+ name: "invalid-tag-opening",
44
+ description: "Escape invalid opening tags starting with digit",
45
+ pattern: /<(\/?(?:\d[^>\s]*))/g,
46
+ replacement: (_match, tagContent) => `&lt;${tagContent}`
47
+ },
48
+ {
49
+ name: "numeric-only-tag",
50
+ description: "Escape tags that are only numbers",
51
+ pattern: /<(\d+)>/g,
52
+ replacement: (_match, number) => `&lt;${number}>`
53
+ }
54
+ ];
55
+ function preserveCode(markdown, transform) {
56
+ const parts = [];
57
+ const codeRegex = /(```[\s\S]*?```|`[^`\n]+`)/g;
58
+ let lastIndex = 0;
59
+ let match;
60
+ while ((match = codeRegex.exec(markdown)) !== null) {
61
+ if (match.index > lastIndex) {
62
+ parts.push({
63
+ type: "text",
64
+ content: markdown.slice(lastIndex, match.index)
65
+ });
66
+ }
67
+ parts.push({
68
+ type: "code",
69
+ content: match[0]
70
+ });
71
+ lastIndex = match.index + match[0].length;
72
+ }
73
+ if (lastIndex < markdown.length) {
74
+ parts.push({
75
+ type: "text",
76
+ content: markdown.slice(lastIndex)
77
+ });
78
+ }
79
+ return parts.map((part) => part.type === "code" ? part.content : transform(part.content)).join("");
80
+ }
81
+ function preprocessMDX(markdown, options = {}) {
82
+ const {
83
+ rules = defaultPreprocessRules,
84
+ enable,
85
+ disable,
86
+ preserveCodeBlocks = true,
87
+ onStats,
88
+ debug = false
89
+ } = options;
90
+ let activeRules = rules;
91
+ if (enable && enable.length > 0) {
92
+ activeRules = rules.filter((r) => enable.includes(r.name));
93
+ }
94
+ if (disable && disable.length > 0) {
95
+ activeRules = activeRules.filter((r) => !disable.includes(r.name));
96
+ }
97
+ if (debug) {
98
+ console.log("[mdx-auto-fix] Active preprocessing rules:", activeRules.map((r) => r.name));
99
+ }
100
+ const stats = {
101
+ totalFixes: 0,
102
+ byTransformer: {}
103
+ };
104
+ let result = markdown;
105
+ const codeBlockLangRule = activeRules.find((r) => r.name === "normalize-code-block-language");
106
+ if (codeBlockLangRule) {
107
+ let fixCount = 0;
108
+ if (typeof codeBlockLangRule.replacement === "function") {
109
+ result = result.replace(codeBlockLangRule.pattern, (...args) => {
110
+ fixCount++;
111
+ return codeBlockLangRule.replacement(...args);
112
+ });
113
+ } else {
114
+ result = result.replace(codeBlockLangRule.pattern, () => {
115
+ fixCount++;
116
+ return codeBlockLangRule.replacement;
117
+ });
118
+ }
119
+ if (fixCount > 0) {
120
+ stats.byTransformer[codeBlockLangRule.name] = fixCount;
121
+ stats.totalFixes += fixCount;
122
+ if (debug) {
123
+ console.log(`[mdx-auto-fix] ${codeBlockLangRule.name}: ${fixCount} fixes`);
124
+ }
125
+ }
126
+ }
127
+ const otherRules = activeRules.filter((r) => r.name !== "normalize-code-block-language");
128
+ const transform = (text) => {
129
+ let transformed = text;
130
+ for (const rule of otherRules) {
131
+ let fixCount = 0;
132
+ if (typeof rule.replacement === "function") {
133
+ transformed = transformed.replace(rule.pattern, (...args) => {
134
+ fixCount++;
135
+ return rule.replacement(...args);
136
+ });
137
+ } else {
138
+ transformed = transformed.replace(rule.pattern, () => {
139
+ fixCount++;
140
+ return rule.replacement;
141
+ });
142
+ }
143
+ if (fixCount > 0) {
144
+ stats.byTransformer[rule.name] = (stats.byTransformer[rule.name] || 0) + fixCount;
145
+ stats.totalFixes += fixCount;
146
+ if (debug) {
147
+ console.log(`[mdx-auto-fix] ${rule.name}: ${fixCount} fixes`);
148
+ }
149
+ }
150
+ }
151
+ return transformed;
152
+ };
153
+ result = preserveCodeBlocks ? preserveCode(result, transform) : transform(result);
154
+ if (onStats && stats.totalFixes > 0) {
155
+ onStats(stats);
156
+ }
157
+ if (debug && stats.totalFixes > 0) {
158
+ console.log(`[mdx-auto-fix] Total preprocessing fixes: ${stats.totalFixes}`);
159
+ }
160
+ return result;
161
+ }
162
+
163
+ // src/plugins/mdx-auto-fix/transformers/less-than-digit.ts
164
+ import { visit } from "unist-util-visit";
165
+ var lessThanDigitTransformer = {
166
+ name: "less-than-digit",
167
+ description: 'Escapes < when followed by a digit (e.g., "<5 minutes" \u2192 "&lt;5 minutes")',
168
+ defaultEnabled: true,
169
+ transform: (context) => {
170
+ let fixCount = 0;
171
+ visit(context.tree, "text", (node) => {
172
+ node.value = node.value.replace(/<(?=\d)/g, () => {
173
+ fixCount++;
174
+ return "&lt;";
175
+ });
176
+ node.value = node.value.replace(/<\s+(?=\d)/g, (match) => {
177
+ fixCount++;
178
+ return match.replace("<", "&lt;");
179
+ });
180
+ });
181
+ context.stats.byTransformer[lessThanDigitTransformer.name] = fixCount;
182
+ context.stats.totalFixes += fixCount;
183
+ },
184
+ testCases: [
185
+ {
186
+ description: "Basic less-than with digit",
187
+ input: "- <5 minutes to complete",
188
+ expected: "- &lt;5 minutes to complete",
189
+ shouldFix: "Should escape < immediately followed by digit"
190
+ },
191
+ {
192
+ description: "Less-than with space and digit",
193
+ input: "- < 5 minutes to complete",
194
+ expected: "- &lt; 5 minutes to complete",
195
+ shouldFix: "Should escape < followed by space and digit"
196
+ },
197
+ {
198
+ description: "Multiple occurrences",
199
+ input: "Metrics: <5ms latency, <10MB memory, <2% error rate",
200
+ expected: "Metrics: &lt;5ms latency, &lt;10MB memory, &lt;2% error rate",
201
+ shouldFix: "Should fix all occurrences in a line"
202
+ },
203
+ {
204
+ description: "Percentage comparisons",
205
+ input: "- <5% configuration error rate",
206
+ expected: "- &lt;5% configuration error rate",
207
+ shouldFix: "Should fix percentage comparisons"
208
+ },
209
+ {
210
+ description: "Size comparisons",
211
+ input: "Bundle size: <20MB",
212
+ expected: "Bundle size: &lt;20MB",
213
+ shouldFix: "Should fix size comparisons"
214
+ },
215
+ {
216
+ description: "Time estimates in lists",
217
+ input: `**Target**:
218
+ - 90%+ setup completion rate
219
+ - <5 minutes to first workflow
220
+ - <5% configuration error rate`,
221
+ expected: `**Target**:
222
+ - 90%+ setup completion rate
223
+ - &lt;5 minutes to first workflow
224
+ - &lt;5% configuration error rate`,
225
+ shouldFix: "Should fix real-world documentation patterns"
226
+ },
227
+ {
228
+ description: "Should not affect valid JSX",
229
+ input: "<Component prop={5} />",
230
+ expected: "<Component prop={5} />",
231
+ shouldFix: "Should preserve valid JSX tags"
232
+ }
233
+ ]
234
+ };
235
+
236
+ // src/plugins/mdx-auto-fix/transformers/greater-than-digit.ts
237
+ import { visit as visit2 } from "unist-util-visit";
238
+ var greaterThanDigitTransformer = {
239
+ name: "greater-than-digit",
240
+ description: 'Escapes > when followed by a digit (e.g., ">5 users" \u2192 "&gt;5 users")',
241
+ defaultEnabled: true,
242
+ transform: (context) => {
243
+ let fixCount = 0;
244
+ visit2(context.tree, "text", (node) => {
245
+ node.value = node.value.replace(/(?<![-\w])>(?=\s?\d)/g, () => {
246
+ fixCount++;
247
+ return "&gt;";
248
+ });
249
+ });
250
+ context.stats.byTransformer[greaterThanDigitTransformer.name] = fixCount;
251
+ context.stats.totalFixes += fixCount;
252
+ },
253
+ testCases: [
254
+ {
255
+ description: "Basic greater-than with digit",
256
+ input: "- >90% completion rate",
257
+ expected: "- &gt;90% completion rate",
258
+ shouldFix: "Should escape > immediately followed by digit"
259
+ },
260
+ {
261
+ description: "Greater-than with space and digit",
262
+ input: "- > 5 users online",
263
+ expected: "- &gt; 5 users online",
264
+ shouldFix: "Should escape > followed by space and digit"
265
+ },
266
+ {
267
+ description: "Multiple occurrences",
268
+ input: "Requirements: >5GB RAM, >10 cores, >100GB storage",
269
+ expected: "Requirements: &gt;5GB RAM, &gt;10 cores, &gt;100GB storage",
270
+ shouldFix: "Should fix all occurrences"
271
+ },
272
+ {
273
+ description: "Should not affect valid JSX closing tags",
274
+ input: "<Component>content</Component>",
275
+ expected: "<Component>content</Component>",
276
+ shouldFix: "Should preserve valid JSX closing tags"
277
+ }
278
+ ]
279
+ };
280
+
281
+ // src/plugins/mdx-auto-fix/transformers/invalid-tag-names.ts
282
+ import { visit as visit3 } from "unist-util-visit";
283
+ var invalidTagNamesTransformer = {
284
+ name: "invalid-tag-names",
285
+ description: 'Escapes tags with invalid names (e.g., "<5Column>" \u2192 "&lt;5Column>")',
286
+ defaultEnabled: true,
287
+ transform: (context) => {
288
+ let fixCount = 0;
289
+ visit3(context.tree, "text", (node) => {
290
+ node.value = node.value.replace(/<\/?(\d[^>\s]*)/g, (match) => {
291
+ fixCount++;
292
+ return match.replace("<", "&lt;");
293
+ });
294
+ node.value = node.value.replace(/<(\d+)>/g, (match) => {
295
+ fixCount++;
296
+ return match.replace("<", "&lt;");
297
+ });
298
+ });
299
+ context.stats.byTransformer[invalidTagNamesTransformer.name] = fixCount;
300
+ context.stats.totalFixes += fixCount;
301
+ },
302
+ testCases: [
303
+ {
304
+ description: "Tag starting with number",
305
+ input: "<5Column>Content</5Column>",
306
+ expected: "&lt;5Column>Content&lt;/5Column>",
307
+ shouldFix: "Should escape opening and closing tags that start with numbers"
308
+ },
309
+ {
310
+ description: "Numeric-only tag",
311
+ input: "<123>",
312
+ expected: "&lt;123>",
313
+ shouldFix: "Should escape tags that are only numbers"
314
+ },
315
+ {
316
+ description: "Tag with number prefix",
317
+ input: '<3DModel src="path" />',
318
+ expected: '&lt;3DModel src="path" />',
319
+ shouldFix: "Should escape self-closing tags that start with numbers"
320
+ },
321
+ {
322
+ description: "Should preserve valid tags",
323
+ input: "<Component5>Content</Component5>",
324
+ expected: "<Component5>Content</Component5>",
325
+ shouldFix: "Should not affect tags that start with valid characters"
326
+ }
327
+ ]
328
+ };
329
+
330
+ // src/plugins/mdx-auto-fix/transformers/code-block-language.ts
331
+ import { visit as visit4 } from "unist-util-visit";
332
+ var LANGUAGE_MAP = {
333
+ "N/A": "text",
334
+ "n/a": "text",
335
+ "argdown": "markdown"
336
+ // Map argdown to markdown for better syntax highlighting
337
+ // Add more mappings as needed
338
+ };
339
+ var KNOWN_LANGUAGES = /* @__PURE__ */ new Set([
340
+ "javascript",
341
+ "js",
342
+ "typescript",
343
+ "ts",
344
+ "jsx",
345
+ "tsx",
346
+ "python",
347
+ "py",
348
+ "java",
349
+ "c",
350
+ "cpp",
351
+ "csharp",
352
+ "cs",
353
+ "html",
354
+ "css",
355
+ "scss",
356
+ "sass",
357
+ "less",
358
+ "json",
359
+ "yaml",
360
+ "yml",
361
+ "xml",
362
+ "toml",
363
+ "bash",
364
+ "sh",
365
+ "shell",
366
+ "powershell",
367
+ "sql",
368
+ "graphql",
369
+ "markdown",
370
+ "md",
371
+ "rust",
372
+ "go",
373
+ "ruby",
374
+ "php",
375
+ "swift",
376
+ "kotlin",
377
+ "dart",
378
+ "r",
379
+ "matlab",
380
+ "diff",
381
+ "text",
382
+ "plaintext"
383
+ ]);
384
+ var codeBlockLanguageTransformer = {
385
+ name: "code-block-language",
386
+ description: "Normalizes unrecognized code block language identifiers to safe alternatives",
387
+ defaultEnabled: true,
388
+ transform: (context) => {
389
+ let fixCount = 0;
390
+ visit4(context.tree, "code", (node) => {
391
+ const lang = node.lang?.toLowerCase().trim();
392
+ if (!lang) {
393
+ node.lang = "text";
394
+ fixCount++;
395
+ return;
396
+ }
397
+ if (LANGUAGE_MAP[lang]) {
398
+ node.lang = LANGUAGE_MAP[lang];
399
+ fixCount++;
400
+ return;
401
+ }
402
+ if (!KNOWN_LANGUAGES.has(lang)) {
403
+ }
404
+ });
405
+ context.stats.byTransformer[codeBlockLanguageTransformer.name] = fixCount;
406
+ context.stats.totalFixes += fixCount;
407
+ },
408
+ testCases: [
409
+ {
410
+ description: "Code block with N/A language",
411
+ input: "```N/A\ncode here\n```",
412
+ expected: "```text\ncode here\n```",
413
+ shouldFix: "Should convert N/A to text"
414
+ },
415
+ {
416
+ description: "Code block with argdown language",
417
+ input: "```argdown\n[Claim]: Statement\n```",
418
+ expected: "```markdown\n[Claim]: Statement\n```",
419
+ shouldFix: "Should convert argdown to markdown"
420
+ },
421
+ {
422
+ description: "Code block without language",
423
+ input: "```\ncode here\n```",
424
+ expected: "```text\ncode here\n```",
425
+ shouldFix: "Should add text language to blocks without one"
426
+ },
427
+ {
428
+ description: "Should preserve known languages",
429
+ input: "```javascript\nconst x = 1;\n```",
430
+ expected: "```javascript\nconst x = 1;\n```",
431
+ shouldFix: "Should not modify known languages"
432
+ }
433
+ ]
434
+ };
435
+
436
+ // src/plugins/mdx-auto-fix/transformers/index.ts
437
+ var defaultTransformers = [
438
+ lessThanDigitTransformer,
439
+ greaterThanDigitTransformer,
440
+ invalidTagNamesTransformer,
441
+ codeBlockLanguageTransformer
442
+ ];
443
+ var allTransformers = [
444
+ lessThanDigitTransformer,
445
+ greaterThanDigitTransformer,
446
+ invalidTagNamesTransformer,
447
+ codeBlockLanguageTransformer
448
+ ];
449
+
450
+ // src/plugins/mdx-auto-fix/plugin.ts
451
+ var mdxAutoFix = (options = {}) => {
452
+ const {
453
+ transformers = defaultTransformers,
454
+ enable,
455
+ disable,
456
+ onStats,
457
+ debug = false
458
+ } = options;
459
+ return (tree) => {
460
+ const stats = {
461
+ totalFixes: 0,
462
+ byTransformer: {}
463
+ };
464
+ let activeTransformers = transformers.filter((t) => t.defaultEnabled);
465
+ if (enable && enable.length > 0) {
466
+ activeTransformers = transformers.filter((t) => enable.includes(t.name));
467
+ }
468
+ if (disable && disable.length > 0) {
469
+ activeTransformers = activeTransformers.filter((t) => !disable.includes(t.name));
470
+ }
471
+ if (debug) {
472
+ console.log("[mdx-auto-fix] Active transformers:", activeTransformers.map((t) => t.name));
473
+ }
474
+ for (const transformer of activeTransformers) {
475
+ try {
476
+ transformer.transform({
477
+ tree,
478
+ stats
479
+ });
480
+ if (debug && stats.byTransformer[transformer.name] > 0) {
481
+ console.log(
482
+ `[mdx-auto-fix] ${transformer.name}: ${stats.byTransformer[transformer.name]} fixes`
483
+ );
484
+ }
485
+ } catch (error) {
486
+ console.error(`[mdx-auto-fix] Error in transformer "${transformer.name}":`, error);
487
+ }
488
+ }
489
+ if (debug && stats.totalFixes > 0) {
490
+ console.log(`[mdx-auto-fix] Total fixes applied: ${stats.totalFixes}`);
491
+ }
492
+ if (onStats && stats.totalFixes > 0) {
493
+ onStats(stats);
494
+ }
495
+ };
496
+ };
497
+
498
+ // src/components/ThemedMDXEditor.tsx
6
499
  import {
7
500
  useCallback,
8
501
  useEffect,
@@ -91,6 +584,7 @@ var ThemedMDXEditor = forwardRef((props, ref) => {
91
584
  containerStyle = {},
92
585
  showLoadingState = false,
93
586
  documentPadding,
587
+ autoFixMDX = true,
94
588
  markdown: controlledMarkdown,
95
589
  onChange: externalOnChange,
96
590
  ...restEditorProps
@@ -110,6 +604,14 @@ var ThemedMDXEditor = forwardRef((props, ref) => {
110
604
  const [savedValue, setSavedValue] = useState(() => computeInitialValue());
111
605
  const [isDirty, setIsDirty] = useState(false);
112
606
  const currentValue = isControlled ? controlledMarkdown ?? "" : internalValue;
607
+ const processedMarkdown = useMemo(() => {
608
+ if (!autoFixMDX) {
609
+ return currentValue;
610
+ }
611
+ return preprocessMDX(currentValue, {
612
+ preserveCodeBlocks: true
613
+ });
614
+ }, [currentValue, autoFixMDX]);
113
615
  useEffect(() => {
114
616
  setIsMounted(true);
115
617
  if (showLoadingState) {
@@ -332,7 +834,7 @@ var ThemedMDXEditor = forwardRef((props, ref) => {
332
834
  MDXEditor,
333
835
  {
334
836
  ref: editorRef,
335
- markdown: currentValue,
837
+ markdown: processedMarkdown,
336
838
  onChange: handleChange,
337
839
  contentEditableClassName: "mdx-editor-content",
338
840
  ...restEditorProps
@@ -579,7 +1081,15 @@ function useThemedMDXEditor() {
579
1081
  export {
580
1082
  ThemedMDXEditor,
581
1083
  ThemedMDXEditorWithProvider,
1084
+ allTransformers,
582
1085
  createAutoCodeMirrorTheme,
583
1086
  createCodeMirrorTheme,
1087
+ defaultPreprocessRules,
1088
+ defaultTransformers,
1089
+ greaterThanDigitTransformer,
1090
+ invalidTagNamesTransformer,
1091
+ lessThanDigitTransformer,
1092
+ mdxAutoFix,
1093
+ preprocessMDX,
584
1094
  useThemedMDXEditor
585
1095
  };
@@ -24,6 +24,7 @@ export interface ThemedMDXEditorProps extends Omit<MDXEditorProps, 'className' |
24
24
  containerStyle?: React.CSSProperties;
25
25
  showLoadingState?: boolean;
26
26
  documentPadding?: DocumentPadding;
27
+ autoFixMDX?: boolean;
27
28
  }
28
29
  export declare const ThemedMDXEditor: React.ForwardRefExoticComponent<ThemedMDXEditorProps & React.RefAttributes<MDXEditorMethods>>;
29
30
  //# sourceMappingURL=ThemedMDXEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemedMDXEditor.d.ts","sourceRoot":"","sources":["../../../src/components/ThemedMDXEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,6BAA6B,CAAC;AACrC,OAAO,gCAAgC,CAAC;AACxC,OAAO,KAQN,MAAM,OAAO,CAAC;AAMf,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,MAAM,GACN;IACE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,GACD,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,MAAM,CAAC;AAEX,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,0BAA0B,CAAC;IAI1G,KAAK,EAAE,KAAK,CAAC;IAIb,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAInC,YAAY,CAAC,EAAE,MAAM,CAAC;IAItB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAIjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAI7B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAK3C,aAAa,CAAC,EAAE,OAAO,CAAC;IAIxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAI5B,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAIrC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAoB3B,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAuFD,eAAO,MAAM,eAAe,+FAiW1B,CAAC"}
1
+ {"version":3,"file":"ThemedMDXEditor.d.ts","sourceRoot":"","sources":["../../../src/components/ThemedMDXEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,6BAA6B,CAAC;AACrC,OAAO,gCAAgC,CAAC;AAExC,OAAO,KAQN,MAAM,OAAO,CAAC;AAMf,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,MAAM,GACN;IACE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,GACD,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,MAAM,CAAC;AAEX,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,0BAA0B,CAAC;IAI1G,KAAK,EAAE,KAAK,CAAC;IAIb,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAInC,YAAY,CAAC,EAAE,MAAM,CAAC;IAItB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAIjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAI7B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAK3C,aAAa,CAAC,EAAE,OAAO,CAAC;IAIxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAI5B,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAIrC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAoB3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAelC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAuFD,eAAO,MAAM,eAAe,+FA4W1B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { preprocessMDX, defaultPreprocessRules } from './preprocessor';
2
+ export type { PreprocessRule } from './preprocessor';
3
+ export { mdxAutoFix } from './plugin';
4
+ export type { MDXAutoFixOptions } from './plugin';
5
+ export type { Transformer, TransformerContext, TransformerStats, TransformerTestCase, } from './types';
6
+ export { lessThanDigitTransformer, greaterThanDigitTransformer, invalidTagNamesTransformer, defaultTransformers, allTransformers, } from './transformers';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/mdx-auto-fix/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGlD,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,mBAAmB,EACnB,eAAe,GAChB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Root } from 'mdast';
2
+ import type { Transformer, TransformerStats } from './types';
3
+ import type { Plugin } from 'unified';
4
+ export interface MDXAutoFixOptions {
5
+ transformers?: Transformer[];
6
+ enable?: string[];
7
+ disable?: string[];
8
+ onStats?: (stats: TransformerStats) => void;
9
+ debug?: boolean;
10
+ }
11
+ export declare const mdxAutoFix: Plugin<[MDXAutoFixOptions?], Root>;
12
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/mdx-auto-fix/plugin.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKtC,MAAM,WAAW,iBAAiB;IAIhC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAK7B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAKlB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAKnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAK5C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAKD,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,CA2DzD,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { TransformerStats } from './types';
2
+ export interface PreprocessRule {
3
+ name: string;
4
+ description: string;
5
+ pattern: RegExp;
6
+ replacement: string | ((match: string, ...args: any[]) => string);
7
+ }
8
+ export declare const defaultPreprocessRules: PreprocessRule[];
9
+ export declare function preprocessMDX(markdown: string, options?: {
10
+ rules?: PreprocessRule[];
11
+ enable?: string[];
12
+ disable?: string[];
13
+ preserveCodeBlocks?: boolean;
14
+ onStats?: (stats: TransformerStats) => void;
15
+ debug?: boolean;
16
+ }): string;
17
+ //# sourceMappingURL=preprocessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preprocessor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/mdx-auto-fix/preprocessor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAKhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC;CACnE;AAKD,eAAO,MAAM,sBAAsB,EAAE,cAAc,EA8ClD,CAAC;AAgDF,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,GACL,MAAM,CAyGR"}
@@ -0,0 +1,3 @@
1
+ import type { Transformer } from '../types';
2
+ export declare const codeBlockLanguageTransformer: Transformer;
3
+ //# sourceMappingURL=code-block-language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block-language.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/mdx-auto-fix/transformers/code-block-language.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC;AA8BhE,eAAO,MAAM,4BAA4B,EAAE,WA+D1C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Transformer } from '../types';
2
+ export declare const greaterThanDigitTransformer: Transformer;
3
+ //# sourceMappingURL=greater-than-digit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"greater-than-digit.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/mdx-auto-fix/transformers/greater-than-digit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC;AAKhE,eAAO,MAAM,2BAA2B,EAAE,WA+CzC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { lessThanDigitTransformer } from './less-than-digit';
2
+ export { greaterThanDigitTransformer } from './greater-than-digit';
3
+ export { invalidTagNamesTransformer } from './invalid-tag-names';
4
+ export { codeBlockLanguageTransformer } from './code-block-language';
5
+ import type { Transformer } from '../types';
6
+ export declare const defaultTransformers: Transformer[];
7
+ export declare const allTransformers: Transformer[];
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/mdx-auto-fix/transformers/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAMrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAK5C,eAAO,MAAM,mBAAmB,EAAE,WAAW,EAK5C,CAAC;AAKF,eAAO,MAAM,eAAe,EAAE,WAAW,EAKxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Transformer } from '../types';
2
+ export declare const invalidTagNamesTransformer: Transformer;
3
+ //# sourceMappingURL=invalid-tag-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalid-tag-names.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/mdx-auto-fix/transformers/invalid-tag-names.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC;AAKhE,eAAO,MAAM,0BAA0B,EAAE,WAqDxC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Transformer } from '../types';
2
+ export declare const lessThanDigitTransformer: Transformer;
3
+ //# sourceMappingURL=less-than-digit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"less-than-digit.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/mdx-auto-fix/transformers/less-than-digit.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAC;AAKhE,eAAO,MAAM,wBAAwB,EAAE,WA4EtC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Root } from 'mdast';
2
+ export interface TransformerContext {
3
+ tree: Root;
4
+ originalMarkdown?: string;
5
+ stats: TransformerStats;
6
+ }
7
+ export interface TransformerStats {
8
+ totalFixes: number;
9
+ byTransformer: Record<string, number>;
10
+ }
11
+ export interface Transformer {
12
+ name: string;
13
+ description: string;
14
+ defaultEnabled: boolean;
15
+ transform: (context: TransformerContext) => void;
16
+ testCases?: TransformerTestCase[];
17
+ }
18
+ export interface TransformerTestCase {
19
+ description: string;
20
+ input: string;
21
+ expected: string;
22
+ shouldFix?: string;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/mdx-auto-fix/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAKlC,MAAM,WAAW,kBAAkB;IAIjC,IAAI,EAAE,IAAI,CAAC;IAKX,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAK1B,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAKD,MAAM,WAAW,gBAAgB;IAI/B,UAAU,EAAE,MAAM,CAAC;IAKnB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAKD,MAAM,WAAW,WAAW;IAI1B,IAAI,EAAE,MAAM,CAAC;IAKb,WAAW,EAAE,MAAM,CAAC;IAKpB,cAAc,EAAE,OAAO,CAAC;IAKxB,SAAS,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAKjD,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAKD,MAAM,WAAW,mBAAmB;IAIlC,WAAW,EAAE,MAAM,CAAC;IAKpB,KAAK,EAAE,MAAM,CAAC;IAKd,QAAQ,EAAE,MAAM,CAAC;IAKjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ade/industry-themed-mdx-editor",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Industry-themed MDX editor wrapper with integrated theming",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "scripts": {
20
20
  "build": "bun run clean && bun run build:esm && bun run build:types && bun run build:styles",
21
- "build:esm": "NODE_ENV=production bun build ./index.ts --outfile ./dist/index.mjs --format esm --target browser --external react --external react-dom --external @mdxeditor/editor --external @a24z/industry-theme",
21
+ "build:esm": "esbuild index.ts --bundle --format=esm --outfile=dist/index.mjs --external:react --external:react-dom --external:@mdxeditor/editor --external:@a24z/industry-theme --external:remark --external:remark-mdx --external:unist-util-visit --external:mdast --external:@codemirror/state --external:@codemirror/view",
22
22
  "build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly --declaration --declarationMap",
23
23
  "build:styles": "cp src/styles/mdx-editor-theme.css dist/styles.css",
24
24
  "dev": "bun run build --watch",
@@ -75,6 +75,7 @@
75
75
  "@storybook/addon-webpack5-compiler-swc": "^4.0.1",
76
76
  "@storybook/react-webpack5": "^9.1.13",
77
77
  "@types/bun": "latest",
78
+ "@types/mdast": "^4.0.4",
78
79
  "@types/node": "^22.15.26",
79
80
  "@types/react": "^19.1.12",
80
81
  "@types/react-dom": "^19.1.8",
@@ -86,12 +87,16 @@
86
87
  "eslint-import-resolver-typescript": "^4.4.4",
87
88
  "eslint-plugin-import": "^2.32.0",
88
89
  "eslint-plugin-storybook": "^9.1.13",
90
+ "mdast": "^3.0.0",
89
91
  "prettier": "^3.6.2",
90
92
  "react": "^19.1.1",
91
93
  "react-dom": "^19.1.1",
94
+ "remark": "^15.0.1",
95
+ "remark-mdx": "^3.1.1",
92
96
  "storybook": "^9.1.13",
93
97
  "typescript": "^5.0.4",
94
- "typescript-eslint": "^8.38.0"
98
+ "typescript-eslint": "^8.38.0",
99
+ "unist-util-visit": "^5.0.0"
95
100
  },
96
101
  "files": [
97
102
  "dist",