@tinacms/mdx 1.1.1 → 1.3.0

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 (30) hide show
  1. package/LICENSE +8 -0
  2. package/dist/extensions/tina-shortcodes/extension.d.ts +3 -0
  3. package/dist/extensions/tina-shortcodes/factory-attributes.d.ts +2 -0
  4. package/dist/extensions/tina-shortcodes/factory-name.d.ts +2 -0
  5. package/dist/extensions/tina-shortcodes/from-markdown.d.ts +2 -0
  6. package/dist/extensions/tina-shortcodes/shortcode-container.d.ts +3 -0
  7. package/dist/extensions/tina-shortcodes/shortcode-leaf.d.ts +5 -0
  8. package/dist/extensions/tina-shortcodes/to-markdown.d.ts +3 -0
  9. package/dist/index.d.ts +0 -12
  10. package/dist/index.es.js +2262 -0
  11. package/dist/index.js +10948 -6057
  12. package/dist/parse/acorn.d.ts +0 -12
  13. package/dist/parse/index.d.ts +2 -14
  14. package/dist/parse/mdx.d.ts +3 -12
  15. package/dist/parse/parseShortcode.d.ts +0 -12
  16. package/dist/parse/plate.d.ts +0 -12
  17. package/dist/parse/remarkToPlate.d.ts +2 -13
  18. package/dist/stringify/acorn.d.ts +4 -0
  19. package/dist/stringify/index.d.ts +8 -12
  20. package/dist/stringify/marks.d.ts +0 -12
  21. package/dist/stringify/stringifyShortcode.d.ts +0 -12
  22. package/dist/tests/autotest/_config.d.ts +0 -12
  23. package/dist/tests/setup.d.ts +0 -12
  24. package/dist/tests/{autotest → temp}/shortcodes.test.d.ts +0 -0
  25. package/package.json +48 -3
  26. package/dist/tests/autotest/invalid mdx with a closing tag.test.d.ts +0 -1
  27. package/dist/tests/autotest/invalid mdx with a const expression.test.d.ts +0 -1
  28. package/dist/tests/autotest/invalid mdx with an expression {{}}.test.d.ts +0 -1
  29. package/dist/tests/autotest/invalid mdx with an expression.test.d.ts +0 -1
  30. package/dist/tests/autotest/invalid mdx with an import statement.test.d.ts +0 -1
@@ -0,0 +1,2262 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+
8
+ // src/parse/index.ts
9
+ import { remark } from "remark";
10
+ import remarkMdx from "remark-mdx";
11
+ import { fromMarkdown } from "mdast-util-from-markdown";
12
+
13
+ // src/parse/remarkToPlate.ts
14
+ import { flatten } from "lodash-es";
15
+
16
+ // src/parse/acorn.ts
17
+ var extractAttributes = (attributes2, fields, imageCallback) => {
18
+ const properties = {};
19
+ attributes2?.forEach((attribute) => {
20
+ assertType(attribute, "mdxJsxAttribute");
21
+ const field = fields.find((field2) => field2.name === attribute.name);
22
+ if (!field) {
23
+ throw new Error(`Unable to find field definition for property "${attribute.name}"`);
24
+ }
25
+ try {
26
+ properties[attribute.name] = extractAttribute(attribute, field, imageCallback);
27
+ } catch (e) {
28
+ if (e instanceof Error) {
29
+ throw new Error(`Unable to parse field value for field "${field.name}" (type: ${field.type}). ${e.message}`);
30
+ }
31
+ throw e;
32
+ }
33
+ });
34
+ return properties;
35
+ };
36
+ var extractAttribute = (attribute, field, imageCallback) => {
37
+ switch (field.type) {
38
+ case "boolean":
39
+ case "number":
40
+ return extractScalar(extractExpression(attribute), field);
41
+ case "datetime":
42
+ case "string":
43
+ if (field.list) {
44
+ return extractScalar(extractExpression(attribute), field);
45
+ } else {
46
+ return extractString(attribute, field);
47
+ }
48
+ case "image":
49
+ if (field.list) {
50
+ const values2 = extractScalar(extractExpression(attribute), field);
51
+ return values2.split(",").map((value) => imageCallback(value));
52
+ } else {
53
+ const value = extractString(attribute, field);
54
+ return imageCallback(value);
55
+ }
56
+ case "reference":
57
+ if (field.list) {
58
+ return extractScalar(extractExpression(attribute), field);
59
+ } else {
60
+ return extractString(attribute, field);
61
+ }
62
+ case "object":
63
+ return extractObject(extractExpression(attribute), field);
64
+ case "rich-text":
65
+ const JSXString = extractRaw(attribute);
66
+ if (JSXString) {
67
+ return parseMDX(JSXString, field, imageCallback);
68
+ } else {
69
+ return {};
70
+ }
71
+ default:
72
+ throw new Error(`Extract attribute: Unhandled field type ${field.type}`);
73
+ }
74
+ };
75
+ var extractScalar = (attribute, field) => {
76
+ if (field.list) {
77
+ assertType(attribute.expression, "ArrayExpression");
78
+ return attribute.expression.elements.map((element) => {
79
+ assertHasType(element);
80
+ assertType(element, "Literal");
81
+ return element.value;
82
+ });
83
+ } else {
84
+ assertType(attribute.expression, "Literal");
85
+ return attribute.expression.value;
86
+ }
87
+ };
88
+ var extractObject = (attribute, field) => {
89
+ if (field.list) {
90
+ assertType(attribute.expression, "ArrayExpression");
91
+ return attribute.expression.elements.map((element) => {
92
+ assertHasType(element);
93
+ assertType(element, "ObjectExpression");
94
+ return extractObjectExpression(element, field);
95
+ });
96
+ } else {
97
+ assertType(attribute.expression, "ObjectExpression");
98
+ return extractObjectExpression(attribute.expression, field);
99
+ }
100
+ };
101
+ var extractObjectExpression = (expression, field) => {
102
+ const properties = {};
103
+ expression.properties?.forEach((property) => {
104
+ assertType(property, "Property");
105
+ const { key, value } = extractKeyValue(property, field);
106
+ properties[key] = value;
107
+ });
108
+ return properties;
109
+ };
110
+ var getField = (objectField, name) => {
111
+ if (objectField.fields) {
112
+ if (typeof objectField.fields === "string") {
113
+ throw new Error("Global templates not supported");
114
+ }
115
+ return objectField.fields.find((f) => f.name === name);
116
+ }
117
+ };
118
+ var extractKeyValue = (property, parentField) => {
119
+ assertType(property.key, "Identifier");
120
+ const key = property.key.name;
121
+ const field = getField(parentField, key);
122
+ if (field?.type === "object") {
123
+ if (field.list) {
124
+ assertType(property.value, "ArrayExpression");
125
+ const value = property.value.elements.map((element) => {
126
+ assertHasType(element);
127
+ assertType(element, "ObjectExpression");
128
+ return extractObjectExpression(element, field);
129
+ });
130
+ return { key, value };
131
+ } else {
132
+ assertType(property.value, "ObjectExpression");
133
+ const value = extractObjectExpression(property.value, field);
134
+ return { key, value };
135
+ }
136
+ } else {
137
+ assertType(property.value, "Literal");
138
+ return { key, value: property.value.value };
139
+ }
140
+ };
141
+ var extractStatement = (attribute) => {
142
+ const body = attribute.data?.estree?.body;
143
+ if (body) {
144
+ if (body[0]) {
145
+ assertType(body[0], "ExpressionStatement");
146
+ return body[0];
147
+ }
148
+ }
149
+ throw new Error(`Unable to extract body from expression`);
150
+ };
151
+ var extractString = (attribute, field) => {
152
+ if (attribute.type === "mdxJsxAttribute") {
153
+ if (typeof attribute.value === "string") {
154
+ return attribute.value;
155
+ }
156
+ }
157
+ return extractScalar(extractExpression(attribute), field);
158
+ };
159
+ var extractExpression = (attribute) => {
160
+ assertType(attribute, "mdxJsxAttribute");
161
+ assertHasType(attribute.value);
162
+ assertType(attribute.value, "mdxJsxAttributeValueExpression");
163
+ return extractStatement(attribute.value);
164
+ };
165
+ var extractRaw = (attribute) => {
166
+ assertType(attribute, "mdxJsxAttribute");
167
+ assertHasType(attribute.value);
168
+ assertType(attribute.value, "mdxJsxAttributeValueExpression");
169
+ const rawValue = attribute.value.value;
170
+ return trimFragments(rawValue);
171
+ };
172
+ function assertType(val, type) {
173
+ if (val.type !== type) {
174
+ throw new Error(`Expected type to be ${type} but received ${val.type}. ${MDX_PARSE_ERROR_MSG}`);
175
+ }
176
+ }
177
+ function assertHasType(val) {
178
+ if (val) {
179
+ if (typeof val !== "string") {
180
+ return;
181
+ }
182
+ }
183
+ throw new Error(`Expect value to be an object with property "type"`);
184
+ }
185
+ var trimFragments = (string) => {
186
+ const rawArr = string.split("\n");
187
+ let openingFragmentIndex = null;
188
+ let closingFragmentIndex = null;
189
+ rawArr.forEach((item, index) => {
190
+ if (item.trim() === "<>") {
191
+ if (!openingFragmentIndex) {
192
+ openingFragmentIndex = index + 1;
193
+ }
194
+ }
195
+ });
196
+ rawArr.reverse().forEach((item, index) => {
197
+ if (item.trim() === "</>") {
198
+ const length = rawArr.length - 1;
199
+ if (!closingFragmentIndex) {
200
+ closingFragmentIndex = length - index;
201
+ }
202
+ }
203
+ });
204
+ const value = rawArr.reverse().slice(openingFragmentIndex || 0, closingFragmentIndex || rawArr.length - 1).join("\n");
205
+ return value;
206
+ };
207
+
208
+ // src/stringify/index.ts
209
+ import { toMarkdown } from "mdast-util-to-markdown";
210
+ import { text as text2 } from "mdast-util-to-markdown/lib/handle/text";
211
+ import {
212
+ mdxJsxToMarkdown
213
+ } from "mdast-util-mdx-jsx";
214
+
215
+ // src/stringify/acorn.ts
216
+ import { format } from "prettier";
217
+ var stringifyPropsInline = (element, field, imageCallback) => {
218
+ return stringifyProps(element, field, true, imageCallback);
219
+ };
220
+ function stringifyProps(element, parentField, flatten2, imageCallback) {
221
+ const attributes2 = [];
222
+ const children = [];
223
+ let template;
224
+ let useDirective = false;
225
+ let directiveType = "leaf";
226
+ template = parentField.templates?.find((template2) => {
227
+ if (typeof template2 === "string") {
228
+ throw new Error("Global templates not supported");
229
+ }
230
+ return template2.name === element.name;
231
+ });
232
+ if (!template) {
233
+ template = parentField.templates?.find((template2) => {
234
+ const templateName = template2?.match?.name;
235
+ return templateName === element.name;
236
+ });
237
+ }
238
+ if (!template || typeof template === "string") {
239
+ throw new Error(`Unable to find template for JSX element ${element.name}`);
240
+ }
241
+ if (template.fields.find((f) => f.name === "children")) {
242
+ directiveType = "block";
243
+ }
244
+ useDirective = !!template.match;
245
+ Object.entries(element.props).forEach(([name, value]) => {
246
+ if (typeof template === "string") {
247
+ throw new Error(`Unable to find template for JSX element ${name}`);
248
+ }
249
+ const field = template?.fields?.find((field2) => field2.name === name);
250
+ if (!field) {
251
+ if (name === "children") {
252
+ return;
253
+ }
254
+ return;
255
+ }
256
+ switch (field.type) {
257
+ case "reference":
258
+ if (field.list) {
259
+ if (Array.isArray(value)) {
260
+ attributes2.push({
261
+ type: "mdxJsxAttribute",
262
+ name,
263
+ value: {
264
+ type: "mdxJsxAttributeValueExpression",
265
+ value: `[${value.map((item) => `"${item}"`).join(", ")}]`
266
+ }
267
+ });
268
+ }
269
+ } else {
270
+ if (typeof value === "string") {
271
+ attributes2.push({
272
+ type: "mdxJsxAttribute",
273
+ name,
274
+ value
275
+ });
276
+ }
277
+ }
278
+ break;
279
+ case "datetime":
280
+ case "string":
281
+ if (field.list) {
282
+ if (Array.isArray(value)) {
283
+ attributes2.push({
284
+ type: "mdxJsxAttribute",
285
+ name,
286
+ value: {
287
+ type: "mdxJsxAttributeValueExpression",
288
+ value: `[${value.map((item) => `"${item}"`).join(", ")}]`
289
+ }
290
+ });
291
+ }
292
+ } else {
293
+ if (typeof value === "string") {
294
+ attributes2.push({
295
+ type: "mdxJsxAttribute",
296
+ name,
297
+ value
298
+ });
299
+ } else {
300
+ throw new Error(`Expected string for attribute on field ${field.name}`);
301
+ }
302
+ }
303
+ break;
304
+ case "image":
305
+ if (field.list) {
306
+ if (Array.isArray(value)) {
307
+ attributes2.push({
308
+ type: "mdxJsxAttribute",
309
+ name,
310
+ value: {
311
+ type: "mdxJsxAttributeValueExpression",
312
+ value: `[${value.map((item) => `"${imageCallback(item)}"`).join(", ")}]`
313
+ }
314
+ });
315
+ }
316
+ } else {
317
+ attributes2.push({
318
+ type: "mdxJsxAttribute",
319
+ name,
320
+ value: imageCallback(String(value))
321
+ });
322
+ }
323
+ break;
324
+ case "number":
325
+ case "boolean":
326
+ if (field.list) {
327
+ if (Array.isArray(value)) {
328
+ attributes2.push({
329
+ type: "mdxJsxAttribute",
330
+ name,
331
+ value: {
332
+ type: "mdxJsxAttributeValueExpression",
333
+ value: `[${value.map((item) => `${item}`).join(", ")}]`
334
+ }
335
+ });
336
+ }
337
+ } else {
338
+ attributes2.push({
339
+ type: "mdxJsxAttribute",
340
+ name,
341
+ value: {
342
+ type: "mdxJsxAttributeValueExpression",
343
+ value: String(value)
344
+ }
345
+ });
346
+ }
347
+ break;
348
+ case "object":
349
+ attributes2.push({
350
+ type: "mdxJsxAttribute",
351
+ name,
352
+ value: {
353
+ type: "mdxJsxAttributeValueExpression",
354
+ value: stringifyObj(value, flatten2)
355
+ }
356
+ });
357
+ break;
358
+ case "rich-text":
359
+ if (typeof value === "string") {
360
+ throw new Error(`Unexpected string for rich-text, ensure the value has been properly parsed`);
361
+ }
362
+ if (field.list) {
363
+ throw new Error(`Rich-text list is not supported`);
364
+ } else {
365
+ const joiner = flatten2 ? " " : "\n";
366
+ let val = "";
367
+ assertShape(value, (value2) => value2.type === "root" && Array.isArray(value2.children), `Nested rich-text element is not a valid shape for field ${field.name}`);
368
+ if (field.name === "children") {
369
+ const root = rootElement(value, field, imageCallback);
370
+ root.children.forEach((child) => {
371
+ children.push(child);
372
+ });
373
+ return;
374
+ } else {
375
+ const stringValue = stringifyMDX(value, field, imageCallback);
376
+ if (stringValue) {
377
+ val = stringValue.trim().split("\n").map((str) => ` ${str.trim()}`).join(joiner);
378
+ }
379
+ }
380
+ if (flatten2) {
381
+ attributes2.push({
382
+ type: "mdxJsxAttribute",
383
+ name,
384
+ value: {
385
+ type: "mdxJsxAttributeValueExpression",
386
+ value: `<>${val.trim()}</>`
387
+ }
388
+ });
389
+ } else {
390
+ attributes2.push({
391
+ type: "mdxJsxAttribute",
392
+ name,
393
+ value: {
394
+ type: "mdxJsxAttributeValueExpression",
395
+ value: `<>
396
+ ${val}
397
+ </>`
398
+ }
399
+ });
400
+ }
401
+ }
402
+ break;
403
+ default:
404
+ throw new Error(`Stringify props: ${field.type} not yet supported`);
405
+ }
406
+ });
407
+ if (template.match) {
408
+ return {
409
+ useDirective,
410
+ directiveType,
411
+ attributes: attributes2,
412
+ children: children && children.length ? children : [
413
+ {
414
+ type: "paragraph",
415
+ children: [
416
+ {
417
+ type: "text",
418
+ value: ""
419
+ }
420
+ ]
421
+ }
422
+ ]
423
+ };
424
+ }
425
+ return { attributes: attributes2, children, useDirective, directiveType };
426
+ }
427
+ function stringifyObj(obj, flatten2) {
428
+ if (typeof obj === "object" && obj !== null) {
429
+ const dummyFunc = `const dummyFunc = `;
430
+ const res = format(`${dummyFunc}${JSON.stringify(obj)}`, {
431
+ parser: "acorn",
432
+ trailingComma: "none",
433
+ semi: false
434
+ }).trim().replace(dummyFunc, "");
435
+ return flatten2 ? res.replaceAll("\n", "").replaceAll(" ", " ") : res;
436
+ } else {
437
+ throw new Error(`stringifyObj must be passed an object or an array of objects, received ${typeof obj}`);
438
+ }
439
+ }
440
+ function assertShape(value, callback, errorMessage) {
441
+ if (!callback(value)) {
442
+ throw new Error(errorMessage || `Failed to assert shape`);
443
+ }
444
+ }
445
+
446
+ // src/stringify/marks.ts
447
+ var matches = (a, b) => {
448
+ return a.some((v) => b.includes(v));
449
+ };
450
+ var replaceLinksWithTextNodes = (content) => {
451
+ const newItems = [];
452
+ content?.forEach((item) => {
453
+ if (item.type === "a") {
454
+ if (item.children.length === 1) {
455
+ const firstChild = item.children[0];
456
+ if (firstChild?.type === "text") {
457
+ newItems.push({
458
+ ...firstChild,
459
+ linkifyTextNode: (a) => {
460
+ return {
461
+ type: "link",
462
+ url: item.url,
463
+ title: item.title,
464
+ children: [a]
465
+ };
466
+ }
467
+ });
468
+ } else {
469
+ newItems.push(item);
470
+ }
471
+ } else {
472
+ newItems.push(item);
473
+ }
474
+ } else {
475
+ newItems.push(item);
476
+ }
477
+ });
478
+ return newItems;
479
+ };
480
+ var inlineElementExceptLink = (content, field, imageCallback) => {
481
+ switch (content.type) {
482
+ case "a":
483
+ throw new Error(`Unexpected node of type "a", link elements should be processed after all inline elements have resolved`);
484
+ case "img":
485
+ return {
486
+ type: "image",
487
+ url: imageCallback(content.url),
488
+ alt: content.alt,
489
+ title: content.caption
490
+ };
491
+ case "break":
492
+ return {
493
+ type: "break"
494
+ };
495
+ case "mdxJsxTextElement": {
496
+ const { attributes: attributes2, children } = stringifyPropsInline(content, field, imageCallback);
497
+ return {
498
+ type: "mdxJsxTextElement",
499
+ name: content.name,
500
+ attributes: attributes2,
501
+ children
502
+ };
503
+ }
504
+ case "html_inline": {
505
+ return {
506
+ type: "html",
507
+ value: content.value
508
+ };
509
+ }
510
+ default:
511
+ if (!content.type && typeof content.text === "string") {
512
+ return text(content);
513
+ }
514
+ throw new Error(`InlineElement: ${content.type} is not supported`);
515
+ }
516
+ };
517
+ var text = (content) => {
518
+ return {
519
+ type: "text",
520
+ value: content.text
521
+ };
522
+ };
523
+ var eat = (c, field, imageCallback) => {
524
+ const content = replaceLinksWithTextNodes(c);
525
+ const first = content[0];
526
+ if (!first) {
527
+ return [];
528
+ }
529
+ if (first && first?.type !== "text") {
530
+ if (first.type === "a") {
531
+ return [
532
+ {
533
+ type: "link",
534
+ url: first.url,
535
+ title: first.title,
536
+ children: eat(first.children, field, imageCallback)
537
+ },
538
+ ...eat(content.slice(1), field, imageCallback)
539
+ ];
540
+ }
541
+ return [
542
+ inlineElementExceptLink(first, field, imageCallback),
543
+ ...eat(content.slice(1), field, imageCallback)
544
+ ];
545
+ }
546
+ const marks = getMarks(first);
547
+ if (marks.length === 0) {
548
+ if (first.linkifyTextNode) {
549
+ return [
550
+ first.linkifyTextNode(text(first)),
551
+ ...eat(content.slice(1), field, imageCallback)
552
+ ];
553
+ } else {
554
+ return [text(first), ...eat(content.slice(1), field, imageCallback)];
555
+ }
556
+ }
557
+ let nonMatchingSiblingIndex = 0;
558
+ if (content.slice(1).every((content2, index) => {
559
+ if (matches(marks, getMarks(content2))) {
560
+ return true;
561
+ } else {
562
+ nonMatchingSiblingIndex = index;
563
+ return false;
564
+ }
565
+ })) {
566
+ nonMatchingSiblingIndex = content.length - 1;
567
+ }
568
+ const matchingSiblings = content.slice(1, nonMatchingSiblingIndex + 1);
569
+ const markCounts = {};
570
+ marks.forEach((mark) => {
571
+ let count2 = 1;
572
+ matchingSiblings.every((sibling, index) => {
573
+ if (getMarks(sibling).includes(mark)) {
574
+ count2 = index + 1;
575
+ return true;
576
+ }
577
+ });
578
+ markCounts[mark] = count2;
579
+ });
580
+ let count = 0;
581
+ let markToProcess = null;
582
+ Object.entries(markCounts).forEach(([mark, markCount]) => {
583
+ const m = mark;
584
+ if (markCount > count) {
585
+ count = markCount;
586
+ markToProcess = m;
587
+ }
588
+ });
589
+ if (!markToProcess) {
590
+ return [text(first), ...eat(content.slice(1), field, imageCallback)];
591
+ }
592
+ if (markToProcess === "inlineCode") {
593
+ if (nonMatchingSiblingIndex) {
594
+ throw new Error(`Marks inside inline code are not supported`);
595
+ }
596
+ const node = {
597
+ type: markToProcess,
598
+ value: first.text
599
+ };
600
+ return [
601
+ first.linkifyTextNode?.(node) ?? node,
602
+ ...eat(content.slice(nonMatchingSiblingIndex + 1), field, imageCallback)
603
+ ];
604
+ }
605
+ return [
606
+ {
607
+ type: markToProcess,
608
+ children: eat([
609
+ ...[first, ...matchingSiblings].map((sibling) => cleanNode(sibling, markToProcess))
610
+ ], field, imageCallback)
611
+ },
612
+ ...eat(content.slice(nonMatchingSiblingIndex + 1), field, imageCallback)
613
+ ];
614
+ };
615
+ var cleanNode = (node, mark) => {
616
+ if (!mark) {
617
+ return node;
618
+ }
619
+ const cleanedNode = {};
620
+ const markToClear = {
621
+ strong: "bold",
622
+ emphasis: "italic",
623
+ inlineCode: "code"
624
+ }[mark];
625
+ Object.entries(node).map(([key, value]) => {
626
+ if (key !== markToClear) {
627
+ cleanedNode[key] = value;
628
+ }
629
+ });
630
+ if (node.linkifyTextNode) {
631
+ cleanedNode.callback = node.linkifyTextNode;
632
+ }
633
+ return cleanedNode;
634
+ };
635
+
636
+ // src/extensions/tina-shortcodes/to-markdown.ts
637
+ import { stringifyEntitiesLight } from "stringify-entities";
638
+ import { containerFlow } from "mdast-util-to-markdown/lib/util/container-flow";
639
+ import { containerPhrasing } from "mdast-util-to-markdown/lib/util/container-phrasing";
640
+ import { checkQuote } from "mdast-util-to-markdown/lib/util/check-quote";
641
+ import { track } from "mdast-util-to-markdown/lib/util/track";
642
+ var own = {}.hasOwnProperty;
643
+ var directiveToMarkdown = (patterns) => ({
644
+ unsafe: [
645
+ {
646
+ character: "\r",
647
+ inConstruct: ["leafDirectiveLabel", "containerDirectiveLabel"]
648
+ },
649
+ {
650
+ character: "\n",
651
+ inConstruct: ["leafDirectiveLabel", "containerDirectiveLabel"]
652
+ },
653
+ {
654
+ before: "[^:]",
655
+ character: ":",
656
+ after: "[A-Za-z]",
657
+ inConstruct: ["phrasing"]
658
+ },
659
+ { atBreak: true, character: ":", after: ":" }
660
+ ],
661
+ handlers: {
662
+ containerDirective: handleDirective(patterns),
663
+ leafDirective: handleDirective(patterns),
664
+ textDirective: handleDirective(patterns)
665
+ }
666
+ });
667
+ var handleDirective = function(patterns) {
668
+ const handleDirective2 = function(node, _, state, safeOptions) {
669
+ const tracker = track(safeOptions);
670
+ const exit2 = state.enter(node.type);
671
+ const pattern = patterns.find((p) => p.name === node.name || p.templateName === node.name);
672
+ if (!pattern) {
673
+ console.log("no pattern found for directive", node.name);
674
+ exit2();
675
+ return "";
676
+ }
677
+ const patternName = pattern.name || pattern.templateName;
678
+ const sequence = pattern.start;
679
+ let value = tracker.move(sequence + " " + patternName);
680
+ let label;
681
+ if (label && label.children && label.children.length > 0) {
682
+ const exit3 = state.enter("label");
683
+ const labelType = `${node.type}Label`;
684
+ const subexit = state.enter(labelType);
685
+ value += tracker.move("[");
686
+ value += tracker.move(containerPhrasing(label, state, {
687
+ ...tracker.current(),
688
+ before: value,
689
+ after: "]"
690
+ }));
691
+ value += tracker.move("]");
692
+ subexit();
693
+ exit3();
694
+ }
695
+ value += tracker.move(" ");
696
+ value += tracker.move(attributes(node, state));
697
+ value += tracker.move(pattern.end);
698
+ if (node.type === "containerDirective") {
699
+ const head = (node.children || [])[0];
700
+ let shallow = node;
701
+ if (inlineDirectiveLabel(head)) {
702
+ shallow = Object.assign({}, node, { children: node.children.slice(1) });
703
+ }
704
+ if (shallow && shallow.children && shallow.children.length > 0) {
705
+ value += tracker.move("\n");
706
+ value += tracker.move(containerFlow(shallow, state, tracker.current()));
707
+ }
708
+ value += tracker.move("\n" + sequence);
709
+ value += tracker.move(" \\" + patternName + " " + pattern.end);
710
+ }
711
+ exit2();
712
+ return value;
713
+ };
714
+ handleDirective2.peek = peekDirective;
715
+ return handleDirective2;
716
+ };
717
+ function peekDirective() {
718
+ return ":";
719
+ }
720
+ function attributes(node, state) {
721
+ const quote = checkQuote(state);
722
+ const subset = node.type === "textDirective" ? [quote] : [quote, "\n", "\r"];
723
+ const attrs = node.attributes || {};
724
+ const values2 = [];
725
+ let key;
726
+ for (key in attrs) {
727
+ if (own.call(attrs, key) && attrs[key] !== void 0 && attrs[key] !== null) {
728
+ const value = String(attrs[key]);
729
+ values2.push(quoted(key, value));
730
+ }
731
+ }
732
+ return values2.length > 0 ? values2.join(" ") + " " : "";
733
+ function quoted(key2, value) {
734
+ const v = quote + stringifyEntitiesLight(value, { subset }) + quote;
735
+ if (key2 === "_value") {
736
+ return v;
737
+ }
738
+ return key2 + (value ? "=" + v : "");
739
+ }
740
+ }
741
+ function inlineDirectiveLabel(node) {
742
+ return Boolean(node && node.type === "paragraph" && node.data && node.data.directiveLabel);
743
+ }
744
+
745
+ // src/stringify/stringifyShortcode.ts
746
+ function stringifyShortcode(preprocessedString, template) {
747
+ const match = template.match;
748
+ const unkeyedAttributes = !!template.fields.find((t) => t.name == "_value");
749
+ const regex = `<[\\s]*${template.name}[\\s]*${unkeyedAttributes ? "(?:_value=(.*?))?" : "(.+?)?"}[\\s]*>[\\s]*((?:.|
750
+ )*?)[\\s]*</[\\s]*${template.name}[\\s]*>`;
751
+ const closingRegex = `
752
+ $2
753
+ ${match.start} /${match.name || template.name} ${match.end}`;
754
+ const replace = `${match.start} ${match.name || template.name} $1 ${match.end}${template.fields.find((t) => t.name == "children") ? closingRegex : ""}`;
755
+ return replaceAll(preprocessedString, regex, replace);
756
+ }
757
+
758
+ // src/stringify/index.ts
759
+ var stringifyMDX = (value, field, imageCallback) => {
760
+ if (!value) {
761
+ return;
762
+ }
763
+ if (typeof value === "string") {
764
+ throw new Error("Expected an object to stringify, but received a string");
765
+ }
766
+ if (value?.children[0]) {
767
+ if (value?.children[0].type === "invalid_markdown") {
768
+ return value.children[0].value;
769
+ }
770
+ }
771
+ const tree = rootElement(value, field, imageCallback);
772
+ const res = toTinaMarkdown(tree, field);
773
+ const templatesWithMatchers = field.templates?.filter((template) => template.match);
774
+ let preprocessedString = res;
775
+ templatesWithMatchers?.forEach((template) => {
776
+ if (typeof template === "string") {
777
+ throw new Error("Global templates are not supported");
778
+ }
779
+ if (template.match) {
780
+ preprocessedString = stringifyShortcode(preprocessedString, template);
781
+ }
782
+ });
783
+ return preprocessedString;
784
+ };
785
+ var toTinaMarkdown = (tree, field) => {
786
+ const patterns = [];
787
+ field.templates?.forEach((template) => {
788
+ if (typeof template === "string") {
789
+ return;
790
+ }
791
+ if (template && template.match) {
792
+ const pattern = template.match;
793
+ pattern.templateName = template.name;
794
+ patterns.push(pattern);
795
+ }
796
+ });
797
+ const handlers = {};
798
+ handlers["text"] = (node, parent, context, safeOptions) => {
799
+ context.unsafe = context.unsafe.filter((unsafeItem) => {
800
+ if (unsafeItem.character === " " && unsafeItem.inConstruct === "phrasing") {
801
+ return false;
802
+ }
803
+ return true;
804
+ });
805
+ if (field.parser?.type === "markdown") {
806
+ if (field.parser.skipEscaping === "all") {
807
+ return node.value;
808
+ }
809
+ if (field.parser.skipEscaping === "html") {
810
+ context.unsafe = context.unsafe.filter((unsafeItem) => {
811
+ if (unsafeItem.character === "<") {
812
+ return false;
813
+ }
814
+ return true;
815
+ });
816
+ }
817
+ }
818
+ return text2(node, parent, context, safeOptions);
819
+ };
820
+ return toMarkdown(tree, {
821
+ extensions: [directiveToMarkdown(patterns), mdxJsxToMarkdown()],
822
+ listItemIndent: "one",
823
+ handlers
824
+ });
825
+ };
826
+ var rootElement = (content, field, imageCallback) => {
827
+ const children = [];
828
+ content.children?.forEach((child) => {
829
+ const value = blockElement(child, field, imageCallback);
830
+ if (value) {
831
+ children.push(value);
832
+ }
833
+ });
834
+ return {
835
+ type: "root",
836
+ children
837
+ };
838
+ };
839
+ var blockElement = (content, field, imageCallback) => {
840
+ switch (content.type) {
841
+ case "h1":
842
+ case "h2":
843
+ case "h3":
844
+ case "h4":
845
+ case "h5":
846
+ case "h6":
847
+ return {
848
+ type: "heading",
849
+ depth: { h1: 1, h2: 2, h3: 3, h4: 4, h5: 5, h6: 6 }[content.type],
850
+ children: eat(content.children, field, imageCallback)
851
+ };
852
+ case "p":
853
+ if (content.children.length === 1) {
854
+ const onlyChild = content.children[0];
855
+ if (onlyChild && (onlyChild.type === "text" || !onlyChild.type) && onlyChild.text === "") {
856
+ return null;
857
+ }
858
+ }
859
+ return {
860
+ type: "paragraph",
861
+ children: eat(content.children, field, imageCallback)
862
+ };
863
+ case "code_block":
864
+ return {
865
+ type: "code",
866
+ lang: content.lang,
867
+ value: content.value
868
+ };
869
+ case "mdxJsxFlowElement":
870
+ const { children, attributes: attributes2, useDirective, directiveType } = stringifyProps(content, field, false, imageCallback);
871
+ if (useDirective) {
872
+ const name = content.name;
873
+ if (!name) {
874
+ throw new Error(`Expective shortcode to have a name but it was not defined`);
875
+ }
876
+ const directiveAttributes = {};
877
+ attributes2?.forEach((att) => {
878
+ if (att.value && typeof att.value === "string") {
879
+ directiveAttributes[att.name] = att.value;
880
+ }
881
+ });
882
+ if (directiveType === "leaf") {
883
+ return {
884
+ type: "leafDirective",
885
+ name,
886
+ attributes: directiveAttributes,
887
+ children: []
888
+ };
889
+ } else {
890
+ return {
891
+ type: "containerDirective",
892
+ name,
893
+ attributes: directiveAttributes,
894
+ children
895
+ };
896
+ }
897
+ }
898
+ return {
899
+ type: "mdxJsxFlowElement",
900
+ name: content.name,
901
+ attributes: attributes2,
902
+ children
903
+ };
904
+ case "blockquote":
905
+ return {
906
+ type: "blockquote",
907
+ children: [
908
+ {
909
+ type: "paragraph",
910
+ children: eat(content.children, field, imageCallback)
911
+ }
912
+ ]
913
+ };
914
+ case "hr":
915
+ return {
916
+ type: "thematicBreak"
917
+ };
918
+ case "ol":
919
+ case "ul":
920
+ return {
921
+ type: "list",
922
+ ordered: content.type === "ol",
923
+ spread: false,
924
+ children: content.children.map((child) => listItemElement(child, field, imageCallback))
925
+ };
926
+ case "html": {
927
+ return {
928
+ type: "html",
929
+ value: content.value
930
+ };
931
+ }
932
+ case "img":
933
+ return {
934
+ type: "image",
935
+ url: imageCallback(content.url),
936
+ alt: content.alt,
937
+ title: content.caption
938
+ };
939
+ default:
940
+ throw new Error(`BlockElement: ${content.type} is not yet supported`);
941
+ }
942
+ };
943
+ var listItemElement = (content, field, imageCallback) => {
944
+ return {
945
+ type: "listItem",
946
+ spread: false,
947
+ children: content.children.map((child) => {
948
+ if (child.type === "lic") {
949
+ return {
950
+ type: "paragraph",
951
+ children: eat(child.children, field, imageCallback)
952
+ };
953
+ }
954
+ return blockContentElement(child, field, imageCallback);
955
+ })
956
+ };
957
+ };
958
+ var blockContentElement = (content, field, imageCallback) => {
959
+ switch (content.type) {
960
+ case "blockquote":
961
+ return {
962
+ type: "blockquote",
963
+ children: content.children.map((child) => blockContentElement(child, field, imageCallback))
964
+ };
965
+ case "p":
966
+ return {
967
+ type: "paragraph",
968
+ children: eat(content.children, field, imageCallback)
969
+ };
970
+ case "ol":
971
+ case "ul":
972
+ return {
973
+ type: "list",
974
+ ordered: content.type === "ol",
975
+ spread: false,
976
+ children: content.children.map((child) => listItemElement(child, field, imageCallback))
977
+ };
978
+ default:
979
+ throw new Error(`BlockContentElement: ${content.type} is not yet supported`);
980
+ }
981
+ };
982
+ var getMarks = (content) => {
983
+ const marks = [];
984
+ if (content.type !== "text") {
985
+ return [];
986
+ }
987
+ if (content.bold) {
988
+ marks.push("strong");
989
+ }
990
+ if (content.italic) {
991
+ marks.push("emphasis");
992
+ }
993
+ if (content.code) {
994
+ marks.push("inlineCode");
995
+ }
996
+ return marks;
997
+ };
998
+
999
+ // src/parse/mdx.ts
1000
+ import { source } from "unist-util-source";
1001
+ function mdxJsxElement(node, field, imageCallback) {
1002
+ try {
1003
+ const template = field.templates?.find((template2) => {
1004
+ const templateName = typeof template2 === "string" ? template2 : template2.name;
1005
+ return templateName === node.name;
1006
+ });
1007
+ if (typeof template === "string") {
1008
+ throw new Error("Global templates not yet supported");
1009
+ }
1010
+ if (!template) {
1011
+ const string = toTinaMarkdown({ type: "root", children: [node] }, field);
1012
+ return {
1013
+ type: node.type === "mdxJsxFlowElement" ? "html" : "html_inline",
1014
+ value: string.trim(),
1015
+ children: [{ type: "text", text: "" }]
1016
+ };
1017
+ }
1018
+ const props = extractAttributes(node.attributes, template.fields, imageCallback);
1019
+ const childField = template.fields.find((field2) => field2.name === "children");
1020
+ if (childField) {
1021
+ if (childField.type === "rich-text") {
1022
+ props.children = remarkToSlate(node, childField, imageCallback);
1023
+ }
1024
+ }
1025
+ return {
1026
+ type: node.type,
1027
+ name: node.name,
1028
+ children: [{ type: "text", text: "" }],
1029
+ props
1030
+ };
1031
+ } catch (e) {
1032
+ if (e instanceof Error) {
1033
+ throw new RichTextParseError(e.message, node.position);
1034
+ }
1035
+ throw e;
1036
+ }
1037
+ }
1038
+ var directiveElement = (node, field, imageCallback, raw) => {
1039
+ let template;
1040
+ template = field.templates?.find((template2) => {
1041
+ const templateName = typeof template2 === "string" ? template2 : template2.name;
1042
+ return templateName === node.name;
1043
+ });
1044
+ if (typeof template === "string") {
1045
+ throw new Error("Global templates not yet supported");
1046
+ }
1047
+ if (!template) {
1048
+ template = field.templates?.find((template2) => {
1049
+ const templateName = template2?.match?.name;
1050
+ return templateName === node.name;
1051
+ });
1052
+ }
1053
+ if (!template) {
1054
+ return {
1055
+ type: "p",
1056
+ children: [{ type: "text", text: source(node, raw || "") || "" }]
1057
+ };
1058
+ }
1059
+ if (typeof template === "string") {
1060
+ throw new Error(`Global templates not supported`);
1061
+ }
1062
+ const props = node.attributes || {};
1063
+ const childField = template.fields.find((field2) => field2.name === "children");
1064
+ if (childField) {
1065
+ if (childField.type === "rich-text") {
1066
+ if (node.type === "containerDirective") {
1067
+ props.children = remarkToSlate(node, childField, imageCallback, raw);
1068
+ }
1069
+ }
1070
+ }
1071
+ return {
1072
+ type: "mdxJsxFlowElement",
1073
+ name: template.name,
1074
+ props,
1075
+ children: [{ type: "text", text: "" }]
1076
+ };
1077
+ };
1078
+
1079
+ // src/parse/remarkToPlate.ts
1080
+ var remarkToSlate = (root, field, imageCallback, raw) => {
1081
+ const content = (content2) => {
1082
+ switch (content2.type) {
1083
+ case "blockquote":
1084
+ const children = [];
1085
+ content2.children.map((child) => {
1086
+ const inlineElements = unwrapBlockContent(child);
1087
+ inlineElements.forEach((child2) => {
1088
+ children.push(child2);
1089
+ });
1090
+ });
1091
+ return {
1092
+ type: "blockquote",
1093
+ children
1094
+ };
1095
+ case "heading":
1096
+ return heading(content2);
1097
+ case "code":
1098
+ return code(content2);
1099
+ case "paragraph":
1100
+ return paragraph(content2);
1101
+ case "mdxJsxFlowElement":
1102
+ return mdxJsxElement(content2, field, imageCallback);
1103
+ case "thematicBreak":
1104
+ return {
1105
+ type: "hr",
1106
+ children: [{ type: "text", text: "" }]
1107
+ };
1108
+ case "listItem":
1109
+ return {
1110
+ type: "li",
1111
+ children: [
1112
+ {
1113
+ type: "lic",
1114
+ children: flatten(content2.children.map((child) => unwrapBlockContent(child)))
1115
+ }
1116
+ ]
1117
+ };
1118
+ case "list":
1119
+ return list(content2);
1120
+ case "html":
1121
+ return html(content2);
1122
+ case "mdxFlowExpression":
1123
+ case "mdxjsEsm":
1124
+ throw new RichTextParseError(`Unexpected expression ${content2.value}.`, content2.position);
1125
+ case "leafDirective": {
1126
+ return directiveElement(content2, field, imageCallback, raw);
1127
+ }
1128
+ case "containerDirective": {
1129
+ return directiveElement(content2, field, imageCallback, raw);
1130
+ }
1131
+ default:
1132
+ throw new RichTextParseError(`Content: ${content2.type} is not yet supported`, content2.position);
1133
+ }
1134
+ };
1135
+ const html = (content2) => {
1136
+ return {
1137
+ type: "p",
1138
+ children: [{ type: "text", text: content2.value }]
1139
+ };
1140
+ };
1141
+ const html_inline = (content2) => {
1142
+ return { type: "text", text: content2.value };
1143
+ };
1144
+ const list = (content2) => {
1145
+ return {
1146
+ type: content2.ordered ? "ol" : "ul",
1147
+ children: content2.children.map((child) => listItem(child))
1148
+ };
1149
+ };
1150
+ const listItem = (content2) => {
1151
+ return {
1152
+ type: "li",
1153
+ children: content2.children.map((child) => {
1154
+ switch (child.type) {
1155
+ case "list":
1156
+ return list(child);
1157
+ case "heading":
1158
+ case "paragraph":
1159
+ return {
1160
+ type: "lic",
1161
+ children: flatten(child.children.map((child2) => phrasingContent(child2)))
1162
+ };
1163
+ case "blockquote": {
1164
+ return {
1165
+ ...blockquote(child),
1166
+ type: "lic"
1167
+ };
1168
+ }
1169
+ case "mdxJsxFlowElement":
1170
+ return {
1171
+ type: "lic",
1172
+ children: [
1173
+ mdxJsxElement({ ...child, type: "mdxJsxTextElement" }, field, imageCallback)
1174
+ ]
1175
+ };
1176
+ case "html":
1177
+ return {
1178
+ type: "lic",
1179
+ children: html_inline(child)
1180
+ };
1181
+ case "leafDirective": {
1182
+ return {
1183
+ type: "lic",
1184
+ children: [directiveElement(child, field, imageCallback)]
1185
+ };
1186
+ }
1187
+ case "code":
1188
+ case "thematicBreak":
1189
+ case "table":
1190
+ throw new RichTextParseError(`${child.type} inside list item is not supported`, child.position);
1191
+ default:
1192
+ throw new RichTextParseError(`Unknown list item of type ${child.type}`, child.position);
1193
+ }
1194
+ })
1195
+ };
1196
+ };
1197
+ const unwrapBlockContent = (content2) => {
1198
+ const flattenPhrasingContent = (children) => {
1199
+ const children2 = children.map((child) => phrasingContent(child));
1200
+ return flatten(Array.isArray(children2) ? children2 : [children2]);
1201
+ };
1202
+ switch (content2.type) {
1203
+ case "heading":
1204
+ case "paragraph":
1205
+ return flattenPhrasingContent(content2.children);
1206
+ case "html":
1207
+ return [html_inline(content2)];
1208
+ case "blockquote":
1209
+ default:
1210
+ throw new RichTextParseError(`UnwrapBlock: Unknown block content of type ${content2.type}`, content2.position);
1211
+ }
1212
+ };
1213
+ const code = (content2) => {
1214
+ const extra = {};
1215
+ if (content2.lang)
1216
+ extra["lang"] = content2.lang;
1217
+ return {
1218
+ type: "code_block",
1219
+ ...extra,
1220
+ value: content2.value,
1221
+ children: [{ type: "text", text: "" }]
1222
+ };
1223
+ };
1224
+ const link = (content2) => {
1225
+ return {
1226
+ type: "a",
1227
+ url: content2.url,
1228
+ title: content2.title,
1229
+ children: flatten(content2.children.map((child) => staticPhrasingContent(child)))
1230
+ };
1231
+ };
1232
+ const heading = (content2) => {
1233
+ return {
1234
+ type: ["h1", "h2", "h3", "h4", "h5", "h6"][content2.depth - 1],
1235
+ children: flatten(content2.children.map(phrasingContent))
1236
+ };
1237
+ };
1238
+ const staticPhrasingContent = (content2) => {
1239
+ switch (content2.type) {
1240
+ case "mdxJsxTextElement":
1241
+ return mdxJsxElement(content2, field, imageCallback);
1242
+ case "text":
1243
+ return text3(content2);
1244
+ case "inlineCode":
1245
+ case "emphasis":
1246
+ case "image":
1247
+ case "strong":
1248
+ return phrashingMark(content2);
1249
+ case "html":
1250
+ return html_inline(content2);
1251
+ default:
1252
+ throw new Error(`StaticPhrasingContent: ${content2.type} is not yet supported`);
1253
+ }
1254
+ };
1255
+ const phrasingContent = (content2) => {
1256
+ switch (content2.type) {
1257
+ case "text":
1258
+ return text3(content2);
1259
+ case "link":
1260
+ return link(content2);
1261
+ case "image":
1262
+ return image(content2);
1263
+ case "mdxJsxTextElement":
1264
+ return mdxJsxElement(content2, field, imageCallback);
1265
+ case "emphasis":
1266
+ return phrashingMark(content2);
1267
+ case "strong":
1268
+ return phrashingMark(content2);
1269
+ case "break":
1270
+ return breakContent();
1271
+ case "inlineCode":
1272
+ return phrashingMark(content2);
1273
+ case "html":
1274
+ return html_inline(content2);
1275
+ case "mdxTextExpression":
1276
+ throw new RichTextParseError(`Unexpected expression ${content2.value}.`, content2.position);
1277
+ default:
1278
+ throw new Error(`PhrasingContent: ${content2.type} is not yet supported`);
1279
+ }
1280
+ };
1281
+ const breakContent = () => {
1282
+ return {
1283
+ type: "break",
1284
+ children: [
1285
+ {
1286
+ type: "text",
1287
+ text: ""
1288
+ }
1289
+ ]
1290
+ };
1291
+ };
1292
+ const phrashingMark = (node, marks = []) => {
1293
+ const accum = [];
1294
+ switch (node.type) {
1295
+ case "emphasis": {
1296
+ const children = flatten(node.children.map((child) => phrashingMark(child, [...marks, "italic"])));
1297
+ children.forEach((child) => {
1298
+ accum.push(child);
1299
+ });
1300
+ break;
1301
+ }
1302
+ case "inlineCode": {
1303
+ const markProps2 = {};
1304
+ marks.forEach((mark) => markProps2[mark] = true);
1305
+ accum.push({
1306
+ type: "text",
1307
+ text: node.value,
1308
+ code: true,
1309
+ ...markProps2
1310
+ });
1311
+ break;
1312
+ }
1313
+ case "strong": {
1314
+ const children = flatten(node.children.map((child) => phrashingMark(child, [...marks, "bold"])));
1315
+ children.forEach((child) => {
1316
+ accum.push(child);
1317
+ });
1318
+ break;
1319
+ }
1320
+ case "image": {
1321
+ accum.push(image(node));
1322
+ break;
1323
+ }
1324
+ case "link": {
1325
+ const children = flatten(node.children.map((child) => phrashingMark(child, marks)));
1326
+ accum.push({ type: "a", url: node.url, title: node.title, children });
1327
+ break;
1328
+ }
1329
+ case "html":
1330
+ case "text":
1331
+ const markProps = {};
1332
+ marks.forEach((mark) => markProps[mark] = true);
1333
+ accum.push({ type: "text", text: node.value, ...markProps });
1334
+ break;
1335
+ case "break":
1336
+ accum.push(breakContent());
1337
+ break;
1338
+ default:
1339
+ throw new RichTextParseError(`Unexpected inline element of type ${node.type}`, node?.position);
1340
+ }
1341
+ return accum;
1342
+ };
1343
+ const image = (content2) => {
1344
+ return {
1345
+ type: "img",
1346
+ url: imageCallback(content2.url),
1347
+ alt: content2.alt || void 0,
1348
+ caption: content2.title,
1349
+ children: [{ type: "text", text: "" }]
1350
+ };
1351
+ };
1352
+ const text3 = (content2) => {
1353
+ return {
1354
+ type: "text",
1355
+ text: content2.value
1356
+ };
1357
+ };
1358
+ const blockquote = (content2) => {
1359
+ const children = [];
1360
+ content2.children.map((child) => {
1361
+ const inlineElements = unwrapBlockContent(child);
1362
+ inlineElements.forEach((child2) => {
1363
+ children.push(child2);
1364
+ });
1365
+ });
1366
+ return {
1367
+ type: "blockquote",
1368
+ children
1369
+ };
1370
+ };
1371
+ const paragraph = (content2) => {
1372
+ const children = flatten(content2.children.map(phrasingContent));
1373
+ if (children.length === 1) {
1374
+ if (children[0]) {
1375
+ if (children[0].type === "html_inline") {
1376
+ return {
1377
+ ...children[0],
1378
+ type: "html"
1379
+ };
1380
+ }
1381
+ }
1382
+ }
1383
+ return {
1384
+ type: "p",
1385
+ children
1386
+ };
1387
+ };
1388
+ return {
1389
+ type: "root",
1390
+ children: root.children.map((child) => {
1391
+ return content(child);
1392
+ })
1393
+ };
1394
+ };
1395
+ var RichTextParseError = class extends Error {
1396
+ constructor(message, position) {
1397
+ super(message);
1398
+ __publicField(this, "position");
1399
+ if (Error.captureStackTrace) {
1400
+ Error.captureStackTrace(this, RichTextParseError);
1401
+ }
1402
+ this.name = "RichTextParseError";
1403
+ this.position = position;
1404
+ }
1405
+ };
1406
+
1407
+ // src/extensions/tina-shortcodes/from-markdown.ts
1408
+ import { parseEntities } from "parse-entities";
1409
+ var enterContainer = function(token) {
1410
+ enter.call(this, "containerDirective", token);
1411
+ };
1412
+ var enterLeaf = function(token) {
1413
+ enter.call(this, "leafDirective", token);
1414
+ };
1415
+ var enterText = function(token) {
1416
+ enter.call(this, "textDirective", token);
1417
+ };
1418
+ var enter = function(type, token) {
1419
+ this.enter({ type, name: "", attributes: {}, children: [] }, token);
1420
+ };
1421
+ function exitName(token) {
1422
+ const node = this.stack[this.stack.length - 1];
1423
+ node.name = this.sliceSerialize(token);
1424
+ }
1425
+ var enterContainerLabel = function(token) {
1426
+ this.enter({ type: "paragraph", data: { directiveLabel: true }, children: [] }, token);
1427
+ };
1428
+ var exitContainerLabel = function(token) {
1429
+ this.exit(token);
1430
+ };
1431
+ var enterAttributes = function() {
1432
+ this.setData("directiveAttributes", []);
1433
+ this.buffer();
1434
+ };
1435
+ var exitAttributeIdValue = function(token) {
1436
+ const list = this.getData("directiveAttributes");
1437
+ if (list) {
1438
+ list.push([
1439
+ "id",
1440
+ parseEntities(this.sliceSerialize(token), {
1441
+ attribute: true
1442
+ })
1443
+ ]);
1444
+ }
1445
+ };
1446
+ var exitAttributeClassValue = function(token) {
1447
+ const list = this.getData("directiveAttributes");
1448
+ if (list) {
1449
+ list.push([
1450
+ "class",
1451
+ parseEntities(this.sliceSerialize(token), {
1452
+ attribute: true
1453
+ })
1454
+ ]);
1455
+ }
1456
+ };
1457
+ var exitAttributeValue = function(token) {
1458
+ const list = this.getData("directiveAttributes");
1459
+ if (list) {
1460
+ const item = list[list.length - 1];
1461
+ if (item) {
1462
+ item[1] = parseEntities(this.sliceSerialize(token), {
1463
+ attribute: true
1464
+ });
1465
+ }
1466
+ }
1467
+ };
1468
+ var exitAttributeName = function(token) {
1469
+ const list = this.getData("directiveAttributes");
1470
+ if (list) {
1471
+ const name = this.sliceSerialize(token);
1472
+ if (!name) {
1473
+ list.push(["_value", ""]);
1474
+ } else {
1475
+ list.push([this.sliceSerialize(token), ""]);
1476
+ }
1477
+ }
1478
+ };
1479
+ function exitAttributes() {
1480
+ const list = this.getData("directiveAttributes");
1481
+ const cleaned = {};
1482
+ let index = -1;
1483
+ if (list) {
1484
+ while (++index < list.length) {
1485
+ const attribute = list[index];
1486
+ if (attribute) {
1487
+ if (attribute[0] === "class" && cleaned.class) {
1488
+ cleaned.class += " " + attribute[1];
1489
+ } else {
1490
+ cleaned[attribute[0]] = attribute[1];
1491
+ }
1492
+ }
1493
+ }
1494
+ }
1495
+ this.setData("directiveAttributes");
1496
+ this.resume();
1497
+ const node = this.stack[this.stack.length - 1];
1498
+ node.attributes = cleaned;
1499
+ }
1500
+ function exit(token) {
1501
+ this.exit(token);
1502
+ }
1503
+ var directiveFromMarkdown = {
1504
+ canContainEols: ["textDirective"],
1505
+ enter: {
1506
+ directiveContainer: enterContainer,
1507
+ directiveContainerAttributes: enterAttributes,
1508
+ directiveContainerLabel: enterContainerLabel,
1509
+ directiveLeaf: enterLeaf,
1510
+ directiveLeafAttributes: enterAttributes,
1511
+ directiveText: enterText,
1512
+ directiveTextAttributes: enterAttributes
1513
+ },
1514
+ exit: {
1515
+ directiveContainer: exit,
1516
+ directiveContainerAttributeClassValue: exitAttributeClassValue,
1517
+ directiveContainerAttributeIdValue: exitAttributeIdValue,
1518
+ directiveContainerAttributeName: exitAttributeName,
1519
+ directiveContainerAttributeValue: exitAttributeValue,
1520
+ directiveContainerAttributes: exitAttributes,
1521
+ directiveContainerLabel: exitContainerLabel,
1522
+ directiveContainerName: exitName,
1523
+ directiveLeaf: exit,
1524
+ directiveLeafAttributeClassValue: exitAttributeClassValue,
1525
+ directiveLeafAttributeIdValue: exitAttributeIdValue,
1526
+ directiveLeafAttributeName: exitAttributeName,
1527
+ directiveLeafAttributeValue: exitAttributeValue,
1528
+ directiveLeafAttributes: exitAttributes,
1529
+ directiveLeafName: exitName,
1530
+ directiveText: exit,
1531
+ directiveTextAttributeClassValue: exitAttributeClassValue,
1532
+ directiveTextAttributeIdValue: exitAttributeIdValue,
1533
+ directiveTextAttributeName: exitAttributeName,
1534
+ directiveTextAttributeValue: exitAttributeValue,
1535
+ directiveTextAttributes: exitAttributes,
1536
+ directiveTextName: exitName
1537
+ }
1538
+ };
1539
+
1540
+ // src/extensions/tina-shortcodes/shortcode-leaf.ts
1541
+ import { factorySpace as factorySpace2 } from "micromark-factory-space";
1542
+ import { markdownLineEnding as markdownLineEnding2, markdownSpace as markdownSpace2 } from "micromark-util-character";
1543
+ import { codes as codes3 } from "micromark-util-symbol/codes";
1544
+ import { values } from "micromark-util-symbol/values";
1545
+ import { types as types2 } from "micromark-util-symbol/types";
1546
+
1547
+ // src/extensions/tina-shortcodes/factory-attributes.ts
1548
+ import { factorySpace } from "micromark-factory-space";
1549
+ import { factoryWhitespace } from "micromark-factory-whitespace";
1550
+ import {
1551
+ asciiAlpha,
1552
+ asciiAlphanumeric,
1553
+ markdownLineEnding,
1554
+ markdownLineEndingOrSpace,
1555
+ markdownSpace
1556
+ } from "micromark-util-character";
1557
+ import { codes } from "micromark-util-symbol/codes";
1558
+ import { types } from "micromark-util-symbol/types";
1559
+ function factoryAttributes(effects, ok, nnok, attributesType, attributesMarkerType, attributeType, attributeIdType, attributeClassType, attributeNameType, attributeInitializerType, attributeValueLiteralType, attributeValueType, attributeValueMarker, attributeValueData, disallowEol) {
1560
+ let type;
1561
+ let marker;
1562
+ const nok = function(code) {
1563
+ return nnok(code);
1564
+ };
1565
+ const start = function(code) {
1566
+ effects.enter(attributesType);
1567
+ return between(code);
1568
+ };
1569
+ const between = function(code) {
1570
+ if (code === codes.numberSign) {
1571
+ type = attributeIdType;
1572
+ return shortcutStart(code);
1573
+ }
1574
+ if (code === codes.dot) {
1575
+ type = attributeClassType;
1576
+ return shortcutStart(code);
1577
+ }
1578
+ if (code === codes.colon || code === codes.underscore || asciiAlpha(code)) {
1579
+ effects.enter(attributeType);
1580
+ effects.enter(attributeNameType);
1581
+ effects.consume(code);
1582
+ return name;
1583
+ }
1584
+ if (code === codes.quotationMark || code === codes.apostrophe) {
1585
+ effects.enter(attributeNameType);
1586
+ effects.exit(attributeNameType);
1587
+ effects.enter(attributeType);
1588
+ return valueBefore(code);
1589
+ }
1590
+ if (disallowEol && markdownSpace(code)) {
1591
+ return factorySpace(effects, between, types.whitespace)(code);
1592
+ }
1593
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
1594
+ return factoryWhitespace(effects, between)(code);
1595
+ }
1596
+ return end(code);
1597
+ };
1598
+ const shortcutStart = function(code) {
1599
+ effects.enter(attributeType);
1600
+ effects.enter(type);
1601
+ effects.enter(type + "Marker");
1602
+ effects.consume(code);
1603
+ effects.exit(type + "Marker");
1604
+ return shortcutStartAfter;
1605
+ };
1606
+ const shortcutStartAfter = function(code) {
1607
+ if (code === codes.eof || code === codes.quotationMark || code === codes.numberSign || code === codes.apostrophe || code === codes.dot || code === codes.lessThan || code === codes.equalsTo || code === codes.greaterThan || code === codes.graveAccent || code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code)) {
1608
+ return nok(code);
1609
+ }
1610
+ effects.enter(type + "Value");
1611
+ effects.consume(code);
1612
+ return shortcut;
1613
+ };
1614
+ const shortcut = function(code) {
1615
+ if (code === codes.eof || code === codes.quotationMark || code === codes.apostrophe || code === codes.lessThan || code === codes.equalsTo || code === codes.greaterThan || code === codes.graveAccent) {
1616
+ return nok(code);
1617
+ }
1618
+ if (code === codes.numberSign || code === codes.dot || code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code)) {
1619
+ effects.exit(type + "Value");
1620
+ effects.exit(type);
1621
+ effects.exit(attributeType);
1622
+ return between(code);
1623
+ }
1624
+ effects.consume(code);
1625
+ return shortcut;
1626
+ };
1627
+ const name = function(code) {
1628
+ if (code === codes.dash || code === codes.dot || code === codes.colon || code === codes.underscore || asciiAlphanumeric(code)) {
1629
+ effects.consume(code);
1630
+ return name;
1631
+ }
1632
+ effects.exit(attributeNameType);
1633
+ if (disallowEol && markdownSpace(code)) {
1634
+ return factorySpace(effects, nameAfter, types.whitespace)(code);
1635
+ }
1636
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
1637
+ return factoryWhitespace(effects, nameAfter)(code);
1638
+ }
1639
+ return nameAfter(code);
1640
+ };
1641
+ const nameAfter = function(code) {
1642
+ if (code === codes.equalsTo) {
1643
+ effects.enter(attributeInitializerType);
1644
+ effects.consume(code);
1645
+ effects.exit(attributeInitializerType);
1646
+ return valueBefore;
1647
+ }
1648
+ effects.exit(attributeType);
1649
+ return between(code);
1650
+ };
1651
+ const valueBefore = function(code) {
1652
+ if (code === codes.eof || code === codes.lessThan || code === codes.equalsTo || code === codes.greaterThan || code === codes.graveAccent || code === codes.rightCurlyBrace || disallowEol && markdownLineEnding(code)) {
1653
+ return nok(code);
1654
+ }
1655
+ if (code === codes.quotationMark || code === codes.apostrophe) {
1656
+ effects.enter(attributeValueLiteralType);
1657
+ effects.enter(attributeValueMarker);
1658
+ effects.consume(code);
1659
+ effects.exit(attributeValueMarker);
1660
+ marker = code;
1661
+ return valueQuotedStart;
1662
+ }
1663
+ if (disallowEol && markdownSpace(code)) {
1664
+ return factorySpace(effects, valueBefore, types.whitespace)(code);
1665
+ }
1666
+ if (!disallowEol && markdownLineEndingOrSpace(code)) {
1667
+ return factoryWhitespace(effects, valueBefore)(code);
1668
+ }
1669
+ effects.enter(attributeValueType);
1670
+ effects.enter(attributeValueData);
1671
+ effects.consume(code);
1672
+ marker = void 0;
1673
+ return valueUnquoted;
1674
+ };
1675
+ const valueUnquoted = function(code) {
1676
+ if (code === codes.eof || code === codes.quotationMark || code === codes.apostrophe || code === codes.lessThan || code === codes.equalsTo || code === codes.greaterThan || code === codes.graveAccent) {
1677
+ return nok(code);
1678
+ }
1679
+ if (code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code)) {
1680
+ effects.exit(attributeValueData);
1681
+ effects.exit(attributeValueType);
1682
+ effects.exit(attributeType);
1683
+ return between(code);
1684
+ }
1685
+ effects.consume(code);
1686
+ return valueUnquoted;
1687
+ };
1688
+ const valueQuotedStart = function(code) {
1689
+ if (code === marker) {
1690
+ effects.enter(attributeValueMarker);
1691
+ effects.consume(code);
1692
+ effects.exit(attributeValueMarker);
1693
+ effects.exit(attributeValueLiteralType);
1694
+ effects.exit(attributeType);
1695
+ return valueQuotedAfter;
1696
+ }
1697
+ effects.enter(attributeValueType);
1698
+ return valueQuotedBetween(code);
1699
+ };
1700
+ const valueQuotedBetween = function(code) {
1701
+ if (code === marker) {
1702
+ effects.exit(attributeValueType);
1703
+ return valueQuotedStart(code);
1704
+ }
1705
+ if (code === codes.eof) {
1706
+ return nok(code);
1707
+ }
1708
+ if (markdownLineEnding(code)) {
1709
+ return disallowEol ? nok(code) : factoryWhitespace(effects, valueQuotedBetween)(code);
1710
+ }
1711
+ effects.enter(attributeValueData);
1712
+ effects.consume(code);
1713
+ return valueQuoted;
1714
+ };
1715
+ const valueQuoted = function(code) {
1716
+ if (code === marker || code === codes.eof || markdownLineEnding(code)) {
1717
+ effects.exit(attributeValueData);
1718
+ return valueQuotedBetween(code);
1719
+ }
1720
+ effects.consume(code);
1721
+ return valueQuoted;
1722
+ };
1723
+ const valueQuotedAfter = function(code) {
1724
+ return code === codes.rightCurlyBrace || markdownLineEndingOrSpace(code) ? between(code) : end(code);
1725
+ };
1726
+ const end = function(code) {
1727
+ if (!asciiAlpha(code)) {
1728
+ effects.enter(attributesMarkerType);
1729
+ effects.exit(attributesMarkerType);
1730
+ effects.exit(attributesType);
1731
+ return ok(code);
1732
+ }
1733
+ return nok(code);
1734
+ };
1735
+ return start;
1736
+ }
1737
+
1738
+ // src/extensions/tina-shortcodes/factory-name.ts
1739
+ import { asciiAlpha as asciiAlpha2, asciiAlphanumeric as asciiAlphanumeric2 } from "micromark-util-character";
1740
+ import { codes as codes2 } from "micromark-util-symbol/codes";
1741
+ function factoryName(effects, ok, nok, type, patternName) {
1742
+ const self = this;
1743
+ let nameIndex = 0;
1744
+ const start = function(code) {
1745
+ const character = patternName[nameIndex];
1746
+ if (asciiAlpha2(code) && findCode(character) === code) {
1747
+ nameIndex++;
1748
+ effects.enter(type);
1749
+ effects.consume(code);
1750
+ return name;
1751
+ }
1752
+ return nok(code);
1753
+ };
1754
+ const name = function(code) {
1755
+ const character = patternName[nameIndex];
1756
+ if (code === codes2.dash || code === codes2.underscore || asciiAlphanumeric2(code)) {
1757
+ if (findCode(character) === code) {
1758
+ effects.consume(code);
1759
+ nameIndex++;
1760
+ return name;
1761
+ }
1762
+ return nok(code);
1763
+ }
1764
+ effects.exit(type);
1765
+ return self.previous === codes2.dash || self.previous === codes2.underscore ? nok(code) : ok(code);
1766
+ };
1767
+ return start;
1768
+ }
1769
+
1770
+ // src/extensions/tina-shortcodes/shortcode-leaf.ts
1771
+ var findValue = (string) => {
1772
+ let lookupValue = null;
1773
+ Object.entries(values).forEach(([key, value]) => {
1774
+ if (value === string) {
1775
+ lookupValue = key;
1776
+ }
1777
+ });
1778
+ return lookupValue;
1779
+ };
1780
+ var findCode = (string) => {
1781
+ if (!string) {
1782
+ return null;
1783
+ }
1784
+ const lookup = findValue(string);
1785
+ let lookupValue = null;
1786
+ if (lookup) {
1787
+ Object.entries(codes3).forEach(([key, value]) => {
1788
+ if (key === lookup) {
1789
+ lookupValue = value;
1790
+ }
1791
+ });
1792
+ }
1793
+ return lookupValue;
1794
+ };
1795
+ var directiveLeaf = (pattern) => {
1796
+ const tokenizeDirectiveLeaf = function(effects, ook, nnok) {
1797
+ const self = this;
1798
+ let startSequenceIndex = 1;
1799
+ let endSequenceIndex = 0;
1800
+ const ok = function(code) {
1801
+ return ook(code);
1802
+ };
1803
+ const nok = function(code) {
1804
+ return nnok(code);
1805
+ };
1806
+ const start = function(code) {
1807
+ const firstCharacter = pattern.start[0];
1808
+ if (findCode(firstCharacter) === code) {
1809
+ effects.enter("directiveLeaf");
1810
+ effects.enter("directiveLeafFence");
1811
+ effects.enter("directiveLeafSequence");
1812
+ effects.consume(code);
1813
+ return sequenceOpen(code);
1814
+ }
1815
+ return nok(code);
1816
+ };
1817
+ const sequenceOpen = function(code) {
1818
+ const nextCharacter = pattern.start[startSequenceIndex];
1819
+ if (findCode(nextCharacter) === code) {
1820
+ effects.consume(code);
1821
+ startSequenceIndex++;
1822
+ return sequenceOpen;
1823
+ }
1824
+ if (startSequenceIndex < pattern.start.length) {
1825
+ return nok(code);
1826
+ }
1827
+ effects.exit("directiveLeafSequence");
1828
+ return factorName(code);
1829
+ };
1830
+ const factorName = (code) => {
1831
+ if (markdownSpace2(code)) {
1832
+ return factorySpace2(effects, factorName, types2.whitespace)(code);
1833
+ }
1834
+ return factoryName.call(self, effects, afterName, nok, "directiveLeafName", pattern.name || pattern.templateName)(code);
1835
+ };
1836
+ const afterName = function(code) {
1837
+ if (markdownSpace2(code)) {
1838
+ return factorySpace2(effects, afterName, types2.whitespace)(code);
1839
+ }
1840
+ if (markdownLineEnding2(code)) {
1841
+ return nok;
1842
+ }
1843
+ return startAttributes;
1844
+ };
1845
+ const startAttributes = function(code) {
1846
+ const nextCharacter = pattern.end[endSequenceIndex];
1847
+ if (findCode(nextCharacter) === code) {
1848
+ return afterAttributes(code);
1849
+ }
1850
+ return effects.attempt(attributes2, afterAttributes, afterAttributes)(code);
1851
+ };
1852
+ const end = function(code) {
1853
+ effects.exit("directiveLeafFence");
1854
+ effects.exit("directiveLeaf");
1855
+ return ok(code);
1856
+ };
1857
+ const afterAttributes = function(code) {
1858
+ const nextCharacter = pattern.end[endSequenceIndex];
1859
+ if (pattern.end.length === endSequenceIndex) {
1860
+ return factorySpace2(effects, end, types2.whitespace)(code);
1861
+ }
1862
+ if (code === codes3.eof) {
1863
+ return nok;
1864
+ }
1865
+ if (findCode(nextCharacter) === code) {
1866
+ effects.consume(code);
1867
+ endSequenceIndex++;
1868
+ return afterAttributes;
1869
+ }
1870
+ return nok;
1871
+ };
1872
+ return start;
1873
+ };
1874
+ const tokenizeAttributes = function(effects, ok, nok) {
1875
+ return factoryAttributes(effects, ok, nok, "directiveLeafAttributes", "directiveLeafAttributesMarker", "directiveLeafAttribute", "directiveLeafAttributeId", "directiveLeafAttributeClass", "directiveLeafAttributeName", "directiveLeafAttributeInitializerMarker", "directiveLeafAttributeValueLiteral", "directiveLeafAttributeValue", "directiveLeafAttributeValueMarker", "directiveLeafAttributeValueData", true);
1876
+ };
1877
+ const attributes2 = { tokenize: tokenizeAttributes, partial: true };
1878
+ return {
1879
+ tokenize: tokenizeDirectiveLeaf
1880
+ };
1881
+ };
1882
+
1883
+ // src/extensions/tina-shortcodes/shortcode-container.ts
1884
+ import { ok as assert } from "uvu/assert";
1885
+ import { factorySpace as factorySpace3 } from "micromark-factory-space";
1886
+ import { markdownLineEnding as markdownLineEnding3, markdownSpace as markdownSpace3 } from "micromark-util-character";
1887
+ import { codes as codes4 } from "micromark-util-symbol/codes";
1888
+ import { constants } from "micromark-util-symbol/constants";
1889
+ import { types as types3 } from "micromark-util-symbol/types";
1890
+ var directiveContainer = (pattern) => {
1891
+ const tokenizeDirectiveContainer = function(effects, ook, nnok) {
1892
+ const self = this;
1893
+ const tail = self.events[self.events.length - 1];
1894
+ const initialSize = tail && tail[1].type === types3.linePrefix ? tail[2].sliceSerialize(tail[1], true).length : 0;
1895
+ let previous;
1896
+ let startSequenceIndex = 1;
1897
+ let closeStartSequenceIndex = 0;
1898
+ let endNameIndex = 0;
1899
+ let endSequenceIndex = 0;
1900
+ let closeEndSequenceIndex = 0;
1901
+ const ok = function(code) {
1902
+ return ook(code);
1903
+ };
1904
+ const nok = function(code) {
1905
+ return nnok(code);
1906
+ };
1907
+ const start = function(code) {
1908
+ const firstCharacter = pattern.start[0];
1909
+ if (findCode(firstCharacter) === code) {
1910
+ effects.enter("directiveContainer");
1911
+ effects.enter("directiveContainerFence");
1912
+ effects.enter("directiveContainerSequence");
1913
+ effects.consume(code);
1914
+ return sequenceOpen(code);
1915
+ }
1916
+ return nok(code);
1917
+ };
1918
+ const sequenceOpen = function(code) {
1919
+ const nextCharacter = pattern.start[startSequenceIndex];
1920
+ if (findCode(nextCharacter) === code) {
1921
+ effects.consume(code);
1922
+ startSequenceIndex++;
1923
+ return sequenceOpen;
1924
+ }
1925
+ if (startSequenceIndex < pattern.start.length) {
1926
+ return nok(code);
1927
+ }
1928
+ effects.exit("directiveContainerSequence");
1929
+ return factorName(code);
1930
+ };
1931
+ const factorName = (code) => {
1932
+ if (markdownSpace3(code)) {
1933
+ return factorySpace3(effects, factorName, types3.whitespace)(code);
1934
+ }
1935
+ return factoryName.call(self, effects, afterName, nok, "directiveContainerName", pattern.name || pattern.templateName)(code);
1936
+ };
1937
+ const afterName = function(code) {
1938
+ if (markdownSpace3(code)) {
1939
+ return factorySpace3(effects, afterName, types3.whitespace)(code);
1940
+ }
1941
+ if (markdownLineEnding3(code)) {
1942
+ return nok;
1943
+ }
1944
+ return startAttributes;
1945
+ };
1946
+ const startAttributes = function(code) {
1947
+ const nextCharacter = pattern.end[endSequenceIndex];
1948
+ if (findCode(nextCharacter) === code) {
1949
+ return afterAttributes(code);
1950
+ }
1951
+ return effects.attempt(attributes2, afterAttributes, afterAttributes)(code);
1952
+ };
1953
+ const afterAttributes = function(code) {
1954
+ const nextCharacter = pattern.end[endSequenceIndex];
1955
+ if (code === codes4.eof) {
1956
+ return nok;
1957
+ }
1958
+ if (findCode(nextCharacter) === code) {
1959
+ effects.consume(code);
1960
+ endSequenceIndex++;
1961
+ return afterAttributes;
1962
+ }
1963
+ if (pattern.end.length === endSequenceIndex) {
1964
+ return factorySpace3(effects, openAfter, types3.whitespace)(code);
1965
+ }
1966
+ return nok;
1967
+ };
1968
+ const openAfter = function(code) {
1969
+ effects.exit("directiveContainerFence");
1970
+ if (code === codes4.eof) {
1971
+ return afterOpening(code);
1972
+ }
1973
+ if (markdownLineEnding3(code)) {
1974
+ if (self.interrupt) {
1975
+ return nok(code);
1976
+ }
1977
+ return effects.attempt(nonLazyLine, contentStart, afterOpening)(code);
1978
+ }
1979
+ return nok(code);
1980
+ };
1981
+ const afterOpening = function(code) {
1982
+ return nok(code);
1983
+ };
1984
+ const contentStart = function(code) {
1985
+ if (code === codes4.eof) {
1986
+ return nok(code);
1987
+ }
1988
+ effects.enter("directiveContainerContent");
1989
+ return lineStart(code);
1990
+ };
1991
+ const lineStart = function(code) {
1992
+ if (code === codes4.eof) {
1993
+ return nok(code);
1994
+ }
1995
+ return effects.attempt({ tokenize: tokenizeClosingFence, partial: true }, after, initialSize ? factorySpace3(effects, chunkStart, types3.linePrefix, initialSize + 1) : chunkStart)(code);
1996
+ };
1997
+ const chunkStart = function(code) {
1998
+ if (code === codes4.eof) {
1999
+ return nok(code);
2000
+ }
2001
+ const token = effects.enter(types3.chunkDocument, {
2002
+ contentType: constants.contentTypeDocument,
2003
+ previous
2004
+ });
2005
+ if (previous)
2006
+ previous.next = token;
2007
+ previous = token;
2008
+ return contentContinue(code);
2009
+ };
2010
+ const contentContinue = function(code) {
2011
+ if (code === codes4.eof) {
2012
+ const t = effects.exit(types3.chunkDocument);
2013
+ self.parser.lazy[t.start.line] = false;
2014
+ return nok(code);
2015
+ }
2016
+ if (markdownLineEnding3(code)) {
2017
+ return effects.check(nonLazyLine, nonLazyLineAfter, lineAfter)(code);
2018
+ }
2019
+ effects.consume(code);
2020
+ return contentContinue;
2021
+ };
2022
+ const nonLazyLineAfter = function(code) {
2023
+ effects.consume(code);
2024
+ const t = effects.exit(types3.chunkDocument);
2025
+ self.parser.lazy[t.start.line] = false;
2026
+ return lineStart;
2027
+ };
2028
+ const lineAfter = function(code) {
2029
+ const t = effects.exit(types3.chunkDocument);
2030
+ self.parser.lazy[t.start.line] = false;
2031
+ return after(code);
2032
+ };
2033
+ const after = function(code) {
2034
+ effects.exit("directiveContainerContent");
2035
+ effects.exit("directiveContainer");
2036
+ return ok(code);
2037
+ };
2038
+ const tokenizeClosingFence = function(effects2, ok2, nok2) {
2039
+ const closingPrefixAfter = function(code) {
2040
+ effects2.enter("directiveContainerFence");
2041
+ effects2.enter("directiveContainerSequence");
2042
+ return closingSequence(code);
2043
+ };
2044
+ const closingSequence = function(code) {
2045
+ const nextCharacter = pattern.start[closeStartSequenceIndex];
2046
+ if (findCode(nextCharacter) === code) {
2047
+ effects2.consume(code);
2048
+ closeStartSequenceIndex++;
2049
+ return closingSequence;
2050
+ }
2051
+ if (closeStartSequenceIndex < pattern.end.length - 1) {
2052
+ return nok2(code);
2053
+ }
2054
+ effects2.exit("directiveContainerSequence");
2055
+ return factorySpace3(effects2, closingSequenceNameStart, types3.whitespace)(code);
2056
+ };
2057
+ const closingSequenceName = function(code) {
2058
+ const patternName = pattern.name || pattern.templateName;
2059
+ const nextCharacter = patternName[endNameIndex];
2060
+ if (code === codes4.eof) {
2061
+ return nok2;
2062
+ }
2063
+ if (markdownLineEnding3(code)) {
2064
+ return nok2;
2065
+ }
2066
+ if (findCode(nextCharacter) === code) {
2067
+ effects2.consume(code);
2068
+ endNameIndex++;
2069
+ return closingSequenceName;
2070
+ }
2071
+ if (patternName.length === endNameIndex) {
2072
+ return closingSequenceEnd;
2073
+ }
2074
+ return nok2;
2075
+ };
2076
+ const closingSequenceNameStart = function(code) {
2077
+ if (markdownSpace3(code)) {
2078
+ return factorySpace3(effects2, closingSequenceNameStart, types3.whitespace);
2079
+ }
2080
+ if (code === codes4.backslash) {
2081
+ effects2.consume(code);
2082
+ return closingSequenceName;
2083
+ }
2084
+ return nok2(code);
2085
+ };
2086
+ const closingSequenceEnd = function(code) {
2087
+ if (markdownSpace3(code)) {
2088
+ return factorySpace3(effects2, closingSequenceEnd, types3.whitespace);
2089
+ }
2090
+ if (code === codes4.eof) {
2091
+ return nok2;
2092
+ }
2093
+ if (pattern.end.length - 1 === closeEndSequenceIndex) {
2094
+ effects2.exit("directiveContainerFence");
2095
+ return ok2(code);
2096
+ }
2097
+ const nextCharacter = pattern.end[closeEndSequenceIndex];
2098
+ if (findCode(nextCharacter) === code) {
2099
+ effects2.consume(code);
2100
+ closeEndSequenceIndex++;
2101
+ return closingSequenceEnd;
2102
+ }
2103
+ return nok2(code);
2104
+ };
2105
+ return factorySpace3(effects2, closingPrefixAfter, types3.linePrefix, constants.tabSize);
2106
+ };
2107
+ return start;
2108
+ };
2109
+ const tokenizeAttributes = function(effects, ok, nok) {
2110
+ return factoryAttributes(effects, ok, nok, "directiveContainerAttributes", "directiveContainerAttributesMarker", "directiveContainerAttribute", "directiveContainerAttributeId", "directiveContainerAttributeClass", "directiveContainerAttributeName", "directiveContainerAttributeInitializerMarker", "directiveContainerAttributeValueLiteral", "directiveContainerAttributeValue", "directiveContainerAttributeValueMarker", "directiveContainerAttributeValueData", true);
2111
+ };
2112
+ const tokenizeNonLazyLine = function(effects, ok, nok) {
2113
+ const self = this;
2114
+ const lineStart = function(code) {
2115
+ return self.parser.lazy[self.now().line] ? nok(code) : ok(code);
2116
+ };
2117
+ const start = function(code) {
2118
+ assert(markdownLineEnding3(code), "expected eol");
2119
+ effects.enter(types3.lineEnding);
2120
+ effects.consume(code);
2121
+ effects.exit(types3.lineEnding);
2122
+ return lineStart;
2123
+ };
2124
+ return start;
2125
+ };
2126
+ const attributes2 = { tokenize: tokenizeAttributes, partial: true };
2127
+ const nonLazyLine = { tokenize: tokenizeNonLazyLine, partial: true };
2128
+ return {
2129
+ tokenize: tokenizeDirectiveContainer,
2130
+ concrete: true
2131
+ };
2132
+ };
2133
+
2134
+ // src/extensions/tina-shortcodes/extension.ts
2135
+ var tinaDirective = function(patterns) {
2136
+ const rules = {};
2137
+ patterns.forEach((pattern) => {
2138
+ const firstKey = pattern.start[0];
2139
+ if (firstKey) {
2140
+ const code = findCode(firstKey);
2141
+ if (code) {
2142
+ if (pattern.type === "leaf") {
2143
+ const directive = directiveLeaf(pattern);
2144
+ if (rules[code]) {
2145
+ rules[code] = [...rules[code] || [], directive];
2146
+ } else {
2147
+ rules[code] = [directive];
2148
+ }
2149
+ }
2150
+ if (pattern.type === "block") {
2151
+ const directive = directiveContainer(pattern);
2152
+ if (rules[code]) {
2153
+ rules[code] = [...rules[code] || [], directive];
2154
+ } else {
2155
+ rules[code] = [directive];
2156
+ }
2157
+ }
2158
+ }
2159
+ }
2160
+ });
2161
+ return {
2162
+ flow: rules
2163
+ };
2164
+ };
2165
+
2166
+ // src/parse/parseShortcode.ts
2167
+ function parseShortcode(preprocessedString, template) {
2168
+ const match = template.match;
2169
+ const unkeyedAttributes = !!template.fields.find((t) => t.name === "_value");
2170
+ const hasChildren = !!template.fields.find((t) => t.name == "children");
2171
+ const replacement = `<${template.name} ${unkeyedAttributes ? '_value="$1"' : "$1"}>${hasChildren ? "$2" : "\n"}</${template.name}>`;
2172
+ const endRegex = `((?:.|\\n)*)${match.start}\\s/\\s*${match.name || template.name}[\\s]*${match.end}`;
2173
+ const regex = `${match.start}\\s*${match.name || template.name}[\\s]+${unkeyedAttributes ? `['"]?(.*?)['"]?` : "(.*?)"}[\\s]*${match.end}${hasChildren ? endRegex : ""}`;
2174
+ return replaceAll(preprocessedString, regex, replacement);
2175
+ }
2176
+
2177
+ // src/parse/index.ts
2178
+ var markdownToAst = (value, field) => {
2179
+ const patterns = [];
2180
+ field.templates?.forEach((template) => {
2181
+ if (typeof template === "string") {
2182
+ return;
2183
+ }
2184
+ if (template && template.match) {
2185
+ patterns.push({
2186
+ ...template.match,
2187
+ name: template.match?.name || template.name,
2188
+ templateName: template.name,
2189
+ type: template.fields.find((f) => f.name === "children") ? "block" : "leaf"
2190
+ });
2191
+ }
2192
+ });
2193
+ return fromMarkdown(value, {
2194
+ extensions: [tinaDirective(patterns)],
2195
+ mdastExtensions: [directiveFromMarkdown]
2196
+ });
2197
+ };
2198
+ var mdxToAst = (value) => {
2199
+ return remark().use(remarkMdx).parse(value);
2200
+ };
2201
+ var MDX_PARSE_ERROR_MSG = "TinaCMS supports a stricter version of markdown and a subset of MDX. https://tina.io/docs/editing/mdx/#differences-from-other-mdx-implementations";
2202
+ var parseMDX = (value, field, imageCallback) => {
2203
+ if (!value) {
2204
+ return { type: "root", children: [] };
2205
+ }
2206
+ let tree;
2207
+ try {
2208
+ if (field.parser?.type === "markdown") {
2209
+ tree = markdownToAst(value, field);
2210
+ } else {
2211
+ let preprocessedString = value;
2212
+ const templatesWithMatchers = field.templates?.filter((template) => template.match);
2213
+ templatesWithMatchers?.forEach((template) => {
2214
+ if (typeof template === "string") {
2215
+ throw new Error("Global templates are not supported");
2216
+ }
2217
+ if (template.match) {
2218
+ if (preprocessedString) {
2219
+ preprocessedString = parseShortcode(preprocessedString, template);
2220
+ }
2221
+ }
2222
+ });
2223
+ tree = mdxToAst(preprocessedString);
2224
+ }
2225
+ if (tree) {
2226
+ return remarkToSlate(tree, field, imageCallback, value);
2227
+ } else {
2228
+ return { type: "root", children: [] };
2229
+ }
2230
+ } catch (e) {
2231
+ if (e instanceof RichTextParseError) {
2232
+ return invalidMarkdown(e, value);
2233
+ }
2234
+ return invalidMarkdown(new RichTextParseError(e.message), value);
2235
+ }
2236
+ };
2237
+ var invalidMarkdown = (e, value) => {
2238
+ const extra = {};
2239
+ if (e.position && Object.keys(e.position).length) {
2240
+ extra["position"] = e.position;
2241
+ }
2242
+ return {
2243
+ type: "root",
2244
+ children: [
2245
+ {
2246
+ type: "invalid_markdown",
2247
+ value,
2248
+ message: e.message || `Error parsing markdown ${MDX_PARSE_ERROR_MSG}`,
2249
+ children: [{ type: "text", text: "" }],
2250
+ ...extra
2251
+ }
2252
+ ]
2253
+ };
2254
+ };
2255
+ var replaceAll = (string, target, value) => {
2256
+ const regex = new RegExp(target, "g");
2257
+ return string.valueOf().replace(regex, value);
2258
+ };
2259
+ export {
2260
+ parseMDX,
2261
+ stringifyMDX
2262
+ };