@willwang-io/react-djot 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -10,25 +10,95 @@ var jsxRuntime = require('react/jsx-runtime');
10
10
  function isParentNode(node) {
11
11
  return Array.isArray(node.children);
12
12
  }
13
- function isSoftBreakNode(node) {
14
- return node.tag === "soft_break" || node.tag === "softbreak";
13
+ function collectFootnoteReferences(nodes, indexByLabel, order) {
14
+ for (const node of nodes) {
15
+ if (node.tag === "footnote_reference") {
16
+ const label = node.text;
17
+ if (!indexByLabel.has(label)) {
18
+ const index = order.length + 1;
19
+ indexByLabel.set(label, index);
20
+ order.push(label);
21
+ }
22
+ continue;
23
+ }
24
+ if (isParentNode(node)) {
25
+ collectFootnoteReferences(node.children, indexByLabel, order);
26
+ }
27
+ }
15
28
  }
16
- function isHardBreakNode(node) {
17
- return node.tag === "hard_break" || node.tag === "hardbreak";
29
+ function createFootnoteState(node) {
30
+ const indexByLabel = /* @__PURE__ */ new Map();
31
+ const order = [];
32
+ collectFootnoteReferences(node.children, indexByLabel, order);
33
+ return {
34
+ autoReferencesByLabel: node.autoReferences ?? {},
35
+ firstRefIdByLabel: /* @__PURE__ */ new Map(),
36
+ indexByLabel,
37
+ order,
38
+ referencesByLabel: node.references ?? {},
39
+ refCountByLabel: /* @__PURE__ */ new Map()
40
+ };
18
41
  }
19
- function pickComponent(components, primary, alias) {
20
- if (!components) {
42
+ function resolveReferenceNode(node, footnoteState) {
43
+ if (!node.reference || !footnoteState) {
21
44
  return void 0;
22
45
  }
23
- return components[primary] ?? (alias ? components[alias] : void 0);
46
+ return footnoteState.referencesByLabel[node.reference] ?? footnoteState.autoReferencesByLabel[node.reference];
24
47
  }
25
- function renderChildren(children, components) {
26
- return children.map(
27
- (child, index) => renderNode(child, {
28
- components,
29
- key: index
30
- })
31
- );
48
+ function resolveReferenceDestination(node, footnoteState) {
49
+ if (node.destination) {
50
+ return node.destination;
51
+ }
52
+ return resolveReferenceNode(node, footnoteState)?.destination;
53
+ }
54
+ function ensureFootnoteIndex(label, footnoteState) {
55
+ const existing = footnoteState.indexByLabel.get(label);
56
+ if (existing) {
57
+ return existing;
58
+ }
59
+ const index = footnoteState.order.length + 1;
60
+ footnoteState.indexByLabel.set(label, index);
61
+ footnoteState.order.push(label);
62
+ return index;
63
+ }
64
+ function appendBacklink(nodes, backlink) {
65
+ if (nodes.length === 0) {
66
+ return [backlink];
67
+ }
68
+ const next = nodes.slice();
69
+ const lastIndex = next.length - 1;
70
+ const last = next[lastIndex];
71
+ if (react.isValidElement(last)) {
72
+ next[lastIndex] = react.cloneElement(last, void 0, last.props.children, backlink);
73
+ return next;
74
+ }
75
+ next.push(backlink);
76
+ return next;
77
+ }
78
+
79
+ // src/renderNode.utils.ts
80
+ function isParentNode2(node) {
81
+ return Array.isArray(node.children);
82
+ }
83
+ function toSmartPunctuation(type, fallback) {
84
+ switch (type) {
85
+ case "left_double_quote":
86
+ return "\u201C";
87
+ case "right_double_quote":
88
+ return "\u201D";
89
+ case "left_single_quote":
90
+ return "\u2018";
91
+ case "right_single_quote":
92
+ return "\u2019";
93
+ case "em_dash":
94
+ return "\u2014";
95
+ case "en_dash":
96
+ return "\u2013";
97
+ case "ellipses":
98
+ return "\u2026";
99
+ default:
100
+ return fallback;
101
+ }
32
102
  }
33
103
  function toAltText(nodes) {
34
104
  let output = "";
@@ -37,8 +107,27 @@ function toAltText(nodes) {
37
107
  case "str":
38
108
  case "code":
39
109
  case "verbatim":
110
+ case "inline_math":
111
+ case "display_math":
40
112
  case "code_block":
41
- output += node.text;
113
+ case "raw_block":
114
+ case "raw_inline":
115
+ case "symb":
116
+ case "url":
117
+ case "email":
118
+ output += node.tag === "symb" ? `:${node.alias}:` : node.text;
119
+ break;
120
+ case "non_breaking_space":
121
+ output += "\xA0";
122
+ break;
123
+ case "smart_punctuation":
124
+ output += toSmartPunctuation(node.type, node.text);
125
+ break;
126
+ case "double_quoted":
127
+ output += `\u201C${toAltText(node.children)}\u201D`;
128
+ break;
129
+ case "single_quoted":
130
+ output += `\u2018${toAltText(node.children)}\u2019`;
42
131
  break;
43
132
  case "soft_break":
44
133
  case "softbreak":
@@ -49,7 +138,7 @@ function toAltText(nodes) {
49
138
  output += "\n";
50
139
  break;
51
140
  default:
52
- if (isParentNode(node)) {
141
+ if (isParentNode2(node)) {
53
142
  output += toAltText(node.children);
54
143
  }
55
144
  break;
@@ -75,6 +164,354 @@ function withKey(props, key) {
75
164
  key
76
165
  };
77
166
  }
167
+ function toDomPropsFromAttributes(attributes) {
168
+ if (!attributes) {
169
+ return {};
170
+ }
171
+ const props = {};
172
+ for (const [name, value] of Object.entries(attributes)) {
173
+ if (name === "class") {
174
+ props.className = value;
175
+ } else {
176
+ props[name] = value;
177
+ }
178
+ }
179
+ return props;
180
+ }
181
+ function toDomPropsFromNode(node) {
182
+ return {
183
+ ...toDomPropsFromAttributes(node.autoAttributes),
184
+ ...toDomPropsFromAttributes(node.attributes)
185
+ };
186
+ }
187
+ function joinClassNames(...values) {
188
+ const classes = values.filter((value) => Boolean(value && value.length > 0));
189
+ return classes.length > 0 ? classes.join(" ") : void 0;
190
+ }
191
+ function toStyleObject(value) {
192
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
193
+ return void 0;
194
+ }
195
+ return value;
196
+ }
197
+ function mergeDomProps(node, extra = {}) {
198
+ const nodeProps = toDomPropsFromNode(node);
199
+ const merged = {
200
+ ...extra,
201
+ ...nodeProps
202
+ };
203
+ const className = joinClassNames(
204
+ typeof extra.className === "string" ? extra.className : void 0,
205
+ typeof nodeProps.className === "string" ? nodeProps.className : void 0
206
+ );
207
+ if (className) {
208
+ merged.className = className;
209
+ }
210
+ const extraStyle = toStyleObject(extra.style);
211
+ const nodeStyle = toStyleObject(nodeProps.style);
212
+ if (extraStyle || nodeStyle) {
213
+ merged.style = {
214
+ ...extraStyle ?? {},
215
+ ...nodeStyle ?? {}
216
+ };
217
+ }
218
+ return merged;
219
+ }
220
+ function textAlignForCell(align) {
221
+ if (align === "left") {
222
+ return "left";
223
+ }
224
+ if (align === "right") {
225
+ return "right";
226
+ }
227
+ if (align === "center") {
228
+ return "center";
229
+ }
230
+ return void 0;
231
+ }
232
+ function toOrderedListType(style) {
233
+ if (!style || /1/.test(style)) {
234
+ return void 0;
235
+ }
236
+ const type = style.replace(/[().]/g, "");
237
+ return type.length > 0 ? type : void 0;
238
+ }
239
+
240
+ // src/renderNode.rawHtml.tsx
241
+ var RAW_HTML_ATTR_PATTERN = /([^\s"'=<>`/]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
242
+ var RAW_HTML_TOKEN_PATTERN = /<!--[\s\S]*?-->|<\/?[A-Za-z][^>]*>|[^<]+|</g;
243
+ var RAW_HTML_BLOCKED_TAGS = /* @__PURE__ */ new Set([
244
+ "base",
245
+ "embed",
246
+ "form",
247
+ "iframe",
248
+ "meta",
249
+ "object",
250
+ "script"
251
+ ]);
252
+ var RAW_HTML_BOOLEAN_ATTRS = /* @__PURE__ */ new Set([
253
+ "allowfullscreen",
254
+ "async",
255
+ "autofocus",
256
+ "autoplay",
257
+ "checked",
258
+ "controls",
259
+ "default",
260
+ "defer",
261
+ "disabled",
262
+ "hidden",
263
+ "loop",
264
+ "multiple",
265
+ "muted",
266
+ "novalidate",
267
+ "open",
268
+ "playsinline",
269
+ "readonly",
270
+ "required",
271
+ "reversed",
272
+ "selected"
273
+ ]);
274
+ var RAW_HTML_UNSAFE_PROTOCOL = /^\s*(?:javascript:|vbscript:|data:)/i;
275
+ var RAW_HTML_URL_ATTRS = /* @__PURE__ */ new Set([
276
+ "action",
277
+ "formaction",
278
+ "href",
279
+ "poster",
280
+ "src",
281
+ "xlink:href"
282
+ ]);
283
+ var RAW_HTML_VOID_TAGS = /* @__PURE__ */ new Set([
284
+ "area",
285
+ "base",
286
+ "br",
287
+ "col",
288
+ "embed",
289
+ "hr",
290
+ "img",
291
+ "input",
292
+ "link",
293
+ "meta",
294
+ "param",
295
+ "source",
296
+ "track",
297
+ "wbr"
298
+ ]);
299
+ function decodeHtmlEntities(value) {
300
+ return value.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (_match, entity) => {
301
+ if (entity.startsWith("#x") || entity.startsWith("#X")) {
302
+ const codePoint = Number.parseInt(entity.slice(2), 16);
303
+ if (!Number.isNaN(codePoint)) {
304
+ return String.fromCodePoint(codePoint);
305
+ }
306
+ return _match;
307
+ }
308
+ if (entity.startsWith("#")) {
309
+ const codePoint = Number.parseInt(entity.slice(1), 10);
310
+ if (!Number.isNaN(codePoint)) {
311
+ return String.fromCodePoint(codePoint);
312
+ }
313
+ return _match;
314
+ }
315
+ switch (entity) {
316
+ case "amp":
317
+ return "&";
318
+ case "apos":
319
+ return "'";
320
+ case "gt":
321
+ return ">";
322
+ case "lt":
323
+ return "<";
324
+ case "nbsp":
325
+ return "\xA0";
326
+ case "quot":
327
+ return '"';
328
+ default:
329
+ return _match;
330
+ }
331
+ });
332
+ }
333
+ function parseRawHtmlAttributes(source) {
334
+ const attributes = [];
335
+ for (const match of source.matchAll(RAW_HTML_ATTR_PATTERN)) {
336
+ const name = match[1]?.toLowerCase();
337
+ if (!name) {
338
+ continue;
339
+ }
340
+ const rawValue = match[2] ?? match[3] ?? match[4] ?? "";
341
+ const value = decodeHtmlEntities(rawValue);
342
+ attributes.push({ name, value });
343
+ }
344
+ return attributes;
345
+ }
346
+ function parseRawHtmlFragment(source) {
347
+ const root = {
348
+ attributes: [],
349
+ children: [],
350
+ tagName: "#root",
351
+ type: "element"
352
+ };
353
+ const stack = [root];
354
+ for (const match of source.matchAll(RAW_HTML_TOKEN_PATTERN)) {
355
+ const token = match[0];
356
+ if (token.startsWith("<!--")) {
357
+ continue;
358
+ }
359
+ if (token === "<") {
360
+ stack[stack.length - 1]?.children.push({ text: "<", type: "text" });
361
+ continue;
362
+ }
363
+ const closingTag = /^<\/\s*([A-Za-z][\w:-]*)\s*>$/.exec(token);
364
+ if (closingTag) {
365
+ const closingTagName = closingTag[1];
366
+ if (!closingTagName) {
367
+ continue;
368
+ }
369
+ const tagName = closingTagName.toLowerCase();
370
+ for (let index = stack.length - 1; index > 0; index -= 1) {
371
+ if (stack[index]?.tagName === tagName) {
372
+ stack.length = index;
373
+ break;
374
+ }
375
+ }
376
+ continue;
377
+ }
378
+ const openingTag = /^<\s*([A-Za-z][\w:-]*)([\s\S]*?)>$/.exec(token);
379
+ if (openingTag) {
380
+ const openingTagName = openingTag[1];
381
+ if (!openingTagName) {
382
+ continue;
383
+ }
384
+ const tagName = openingTagName.toLowerCase();
385
+ const rawAttributes = openingTag[2] ?? "";
386
+ const selfClosing = /\/\s*$/.test(rawAttributes) || RAW_HTML_VOID_TAGS.has(tagName);
387
+ const attrSource = selfClosing ? rawAttributes.replace(/\/\s*$/, "") : rawAttributes;
388
+ const element = {
389
+ attributes: parseRawHtmlAttributes(attrSource),
390
+ children: [],
391
+ tagName,
392
+ type: "element"
393
+ };
394
+ stack[stack.length - 1]?.children.push(element);
395
+ if (!selfClosing) {
396
+ stack.push(element);
397
+ }
398
+ continue;
399
+ }
400
+ stack[stack.length - 1]?.children.push({
401
+ text: decodeHtmlEntities(token),
402
+ type: "text"
403
+ });
404
+ }
405
+ return root.children;
406
+ }
407
+ function toCamelCaseCssProperty(name) {
408
+ return name.trim().replace(/^-+/, "").replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
409
+ }
410
+ function parseStyleAttribute(value) {
411
+ const style = {};
412
+ for (const declaration of value.split(";")) {
413
+ const separatorIndex = declaration.indexOf(":");
414
+ if (separatorIndex === -1) {
415
+ continue;
416
+ }
417
+ const property = toCamelCaseCssProperty(declaration.slice(0, separatorIndex));
418
+ const propertyValue = declaration.slice(separatorIndex + 1).trim();
419
+ if (!property || !propertyValue) {
420
+ continue;
421
+ }
422
+ style[property] = propertyValue;
423
+ }
424
+ if (Object.keys(style).length === 0) {
425
+ return void 0;
426
+ }
427
+ return style;
428
+ }
429
+ function toRawHtmlDomProps(attributes) {
430
+ const props = {};
431
+ for (const { name, value } of attributes) {
432
+ if (name.startsWith("on")) {
433
+ continue;
434
+ }
435
+ if (RAW_HTML_URL_ATTRS.has(name) && RAW_HTML_UNSAFE_PROTOCOL.test(value)) {
436
+ continue;
437
+ }
438
+ if (name === "class") {
439
+ props.className = value;
440
+ continue;
441
+ }
442
+ if (name === "for") {
443
+ props.htmlFor = value;
444
+ continue;
445
+ }
446
+ if (name === "style") {
447
+ const style = parseStyleAttribute(value);
448
+ if (style) {
449
+ props.style = style;
450
+ }
451
+ continue;
452
+ }
453
+ if (RAW_HTML_BOOLEAN_ATTRS.has(name) && value.length === 0) {
454
+ props[name] = true;
455
+ continue;
456
+ }
457
+ props[name] = value;
458
+ }
459
+ return props;
460
+ }
461
+ function renderRawHtmlNode(node, key) {
462
+ if (node.type === "text") {
463
+ return node.text;
464
+ }
465
+ if (RAW_HTML_BLOCKED_TAGS.has(node.tagName)) {
466
+ return null;
467
+ }
468
+ const children = renderRawHtmlNodes(node.children, key);
469
+ return react.createElement(
470
+ node.tagName,
471
+ withKey(toRawHtmlDomProps(node.attributes), key),
472
+ children.length > 0 ? children : void 0
473
+ );
474
+ }
475
+ function renderRawHtmlNodes(nodes, keyPrefix) {
476
+ const rendered = [];
477
+ for (const [index, node] of nodes.entries()) {
478
+ const next = renderRawHtmlNode(node, `${keyPrefix}-${index}`);
479
+ if (next !== null) {
480
+ rendered.push(next);
481
+ }
482
+ }
483
+ return rendered;
484
+ }
485
+ function rawHtmlChildren(value, keyPrefix) {
486
+ return renderRawHtmlNodes(parseRawHtmlFragment(value), keyPrefix);
487
+ }
488
+
489
+ // src/renderNode.tsx
490
+ function isParentNode3(node) {
491
+ return Array.isArray(node.children);
492
+ }
493
+ function isSoftBreakNode(node) {
494
+ return node.tag === "soft_break" || node.tag === "softbreak";
495
+ }
496
+ function isHardBreakNode(node) {
497
+ return node.tag === "hard_break" || node.tag === "hardbreak";
498
+ }
499
+ function pickComponent(components, primary, alias) {
500
+ if (!components) {
501
+ return void 0;
502
+ }
503
+ return components[primary] ?? (alias ? components[alias] : void 0);
504
+ }
505
+ function renderChildren(children, components, footnoteState, listTight) {
506
+ return children.map(
507
+ (child, index) => renderNode(child, {
508
+ components,
509
+ footnoteState,
510
+ key: index,
511
+ listTight
512
+ })
513
+ );
514
+ }
78
515
  function renderWithOverride(override, fallback, domProps, customProps, key, children) {
79
516
  const Component = override ?? fallback;
80
517
  const props = typeof Component === "string" ? withKey(domProps, key) : withKey(
@@ -84,52 +521,386 @@ function renderWithOverride(override, fallback, domProps, customProps, key, chil
84
521
  },
85
522
  key
86
523
  );
87
- return react.createElement(Component, props, children);
524
+ return react.createElement(Component, props, children);
525
+ }
526
+ function renderDoc(node, components, key) {
527
+ const footnoteState = createFootnoteState(node);
528
+ const children = renderChildren(node.children, components, footnoteState);
529
+ const endnotes = renderEndnotes(node, components, footnoteState);
530
+ const allChildren = endnotes ? [...children, endnotes] : children;
531
+ const Component = pickComponent(components, "doc");
532
+ if (Component) {
533
+ const domProps = mergeDomProps(node);
534
+ if (typeof Component === "string") {
535
+ return react.createElement(Component, withKey(domProps, key), allChildren);
536
+ }
537
+ return react.createElement(Component, withKey({ ...domProps, node }, key), allChildren);
538
+ }
539
+ return react.createElement(react.Fragment, withKey({}, key), allChildren);
540
+ }
541
+ function renderSection(node, components, footnoteState, key) {
542
+ const children = renderChildren(node.children, components, footnoteState);
543
+ return renderWithOverride(
544
+ pickComponent(components, "section"),
545
+ "section",
546
+ mergeDomProps(node),
547
+ {
548
+ node
549
+ },
550
+ key,
551
+ children
552
+ );
553
+ }
554
+ function renderDiv(node, components, footnoteState, key) {
555
+ const children = renderChildren(node.children, components, footnoteState);
556
+ return renderWithOverride(
557
+ pickComponent(components, "div"),
558
+ "div",
559
+ mergeDomProps(node),
560
+ {
561
+ node
562
+ },
563
+ key,
564
+ children
565
+ );
566
+ }
567
+ function renderTable(node, components, footnoteState, key) {
568
+ const captionChildren = [];
569
+ const headRows = [];
570
+ const bodyRows = [];
571
+ const otherChildren = [];
572
+ for (const [index, child] of node.children.entries()) {
573
+ const rendered = renderNode(child, {
574
+ components,
575
+ footnoteState,
576
+ key: index
577
+ });
578
+ if (child.tag === "caption") {
579
+ captionChildren.push(rendered);
580
+ continue;
581
+ }
582
+ if (child.tag === "row") {
583
+ if (child.head && bodyRows.length === 0) {
584
+ headRows.push(rendered);
585
+ } else {
586
+ bodyRows.push(rendered);
587
+ }
588
+ continue;
589
+ }
590
+ otherChildren.push(rendered);
591
+ }
592
+ const children = [...captionChildren];
593
+ if (headRows.length > 0) {
594
+ children.push(react.createElement("thead", { key: "thead" }, headRows));
595
+ }
596
+ if (bodyRows.length > 0) {
597
+ children.push(react.createElement("tbody", { key: "tbody" }, bodyRows));
598
+ }
599
+ if (otherChildren.length > 0) {
600
+ children.push(...otherChildren);
601
+ }
602
+ return renderWithOverride(
603
+ pickComponent(components, "table"),
604
+ "table",
605
+ mergeDomProps(node),
606
+ {
607
+ node
608
+ },
609
+ key,
610
+ children
611
+ );
612
+ }
613
+ function renderCaption(node, components, footnoteState, key) {
614
+ const children = renderChildren(node.children, components, footnoteState);
615
+ const Component = pickComponent(components, "caption");
616
+ if (!Component && children.length === 0) {
617
+ return null;
618
+ }
619
+ return renderWithOverride(
620
+ Component,
621
+ "caption",
622
+ mergeDomProps(node),
623
+ {
624
+ node
625
+ },
626
+ key,
627
+ children
628
+ );
629
+ }
630
+ function renderRow(node, components, footnoteState, key) {
631
+ const children = renderChildren(node.children, components, footnoteState);
632
+ return renderWithOverride(
633
+ pickComponent(components, "row"),
634
+ "tr",
635
+ mergeDomProps(node),
636
+ {
637
+ head: node.head,
638
+ node
639
+ },
640
+ key,
641
+ children
642
+ );
643
+ }
644
+ function renderCell(node, components, footnoteState, key) {
645
+ const children = renderChildren(node.children, components, footnoteState);
646
+ const textAlign = textAlignForCell(node.align);
647
+ const domProps = mergeDomProps(node, {
648
+ style: textAlign ? { textAlign } : void 0
649
+ });
650
+ return renderWithOverride(
651
+ pickComponent(components, "cell"),
652
+ node.head ? "th" : "td",
653
+ domProps,
654
+ {
655
+ align: node.align,
656
+ head: node.head,
657
+ node
658
+ },
659
+ key,
660
+ children
661
+ );
662
+ }
663
+ function renderHeading(node, components, footnoteState, key) {
664
+ const level = clampHeadingLevel(node.level);
665
+ const children = renderChildren(node.children, components, footnoteState);
666
+ return renderWithOverride(
667
+ pickComponent(components, "heading"),
668
+ `h${level}`,
669
+ mergeDomProps(node),
670
+ {
671
+ level,
672
+ node
673
+ },
674
+ key,
675
+ children
676
+ );
677
+ }
678
+ function renderMark(node, components, footnoteState, key, primary, alias) {
679
+ const children = renderChildren(node.children, components, footnoteState);
680
+ return renderWithOverride(
681
+ pickComponent(components, primary, alias),
682
+ "mark",
683
+ mergeDomProps(node),
684
+ {
685
+ node
686
+ },
687
+ key,
688
+ children
689
+ );
690
+ }
691
+ function renderSuperscript(node, components, footnoteState, key, primary, alias) {
692
+ const children = renderChildren(node.children, components, footnoteState);
693
+ return renderWithOverride(
694
+ pickComponent(components, primary, alias),
695
+ "sup",
696
+ mergeDomProps(node),
697
+ {
698
+ node
699
+ },
700
+ key,
701
+ children
702
+ );
703
+ }
704
+ function renderSubscript(node, components, footnoteState, key) {
705
+ const children = renderChildren(node.children, components, footnoteState);
706
+ return renderWithOverride(
707
+ pickComponent(components, "subscript"),
708
+ "sub",
709
+ mergeDomProps(node),
710
+ {
711
+ node
712
+ },
713
+ key,
714
+ children
715
+ );
716
+ }
717
+ function renderInsert(node, components, footnoteState, key) {
718
+ const children = renderChildren(node.children, components, footnoteState);
719
+ return renderWithOverride(
720
+ pickComponent(components, "insert"),
721
+ "ins",
722
+ mergeDomProps(node),
723
+ {
724
+ node
725
+ },
726
+ key,
727
+ children
728
+ );
729
+ }
730
+ function renderDelete(node, components, footnoteState, key) {
731
+ const children = renderChildren(node.children, components, footnoteState);
732
+ return renderWithOverride(
733
+ pickComponent(components, "delete"),
734
+ "del",
735
+ mergeDomProps(node),
736
+ {
737
+ node
738
+ },
739
+ key,
740
+ children
741
+ );
742
+ }
743
+ function renderFootnoteReference(node, components, footnoteState, key) {
744
+ const label = node.text;
745
+ const index = footnoteState ? ensureFootnoteIndex(label, footnoteState) : 1;
746
+ const refCount = (footnoteState?.refCountByLabel.get(label) ?? 0) + 1;
747
+ if (footnoteState) {
748
+ footnoteState.refCountByLabel.set(label, refCount);
749
+ }
750
+ const id = refCount === 1 ? `fnref${index}` : `fnref${index}-${refCount}`;
751
+ if (footnoteState && !footnoteState.firstRefIdByLabel.has(label)) {
752
+ footnoteState.firstRefIdByLabel.set(label, id);
753
+ }
754
+ const href = `#fn${index}`;
755
+ const children = react.createElement("sup", null, index);
756
+ return renderWithOverride(
757
+ pickComponent(components, "footnote_reference"),
758
+ "a",
759
+ mergeDomProps(node, {
760
+ href,
761
+ id,
762
+ role: "doc-noteref"
763
+ }),
764
+ {
765
+ index,
766
+ label,
767
+ node
768
+ },
769
+ key,
770
+ children
771
+ );
772
+ }
773
+ function renderEndnotes(node, components, footnoteState) {
774
+ if (footnoteState.order.length === 0) {
775
+ return null;
776
+ }
777
+ const items = footnoteState.order.map((label, itemIndex) => {
778
+ const index = itemIndex + 1;
779
+ const footnoteNode = node.footnotes?.[label] ?? {
780
+ children: [],
781
+ label,
782
+ tag: "footnote"
783
+ };
784
+ const footnoteChildren = renderChildren(footnoteNode.children, components, footnoteState);
785
+ const backlink = react.createElement(
786
+ "a",
787
+ {
788
+ href: `#${footnoteState.firstRefIdByLabel.get(label) ?? `fnref${index}`}`,
789
+ role: "doc-backlink"
790
+ },
791
+ "\u21A9\uFE0E"
792
+ );
793
+ const content = appendBacklink(footnoteChildren, backlink);
794
+ return renderWithOverride(
795
+ pickComponent(components, "footnote"),
796
+ "li",
797
+ mergeDomProps(footnoteNode, {
798
+ id: `fn${index}`,
799
+ key: label
800
+ }),
801
+ {
802
+ index,
803
+ label,
804
+ node: footnoteNode
805
+ },
806
+ label,
807
+ content
808
+ );
809
+ });
810
+ const ol = react.createElement("ol", null, items);
811
+ const sectionChildren = [react.createElement("hr", { key: "hr" }), react.createElement(react.Fragment, { key: "ol" }, ol)];
812
+ return renderWithOverride(
813
+ pickComponent(components, "endnotes"),
814
+ "section",
815
+ {
816
+ role: "doc-endnotes"
817
+ },
818
+ {
819
+ node,
820
+ order: footnoteState.order
821
+ },
822
+ "endnotes",
823
+ sectionChildren
824
+ );
825
+ }
826
+ function renderQuoted(node, components, footnoteState, key, primary, alias, openQuote, closeQuote) {
827
+ const children = renderChildren(node.children, components, footnoteState);
828
+ const Component = pickComponent(components, primary, alias);
829
+ const domProps = mergeDomProps(node);
830
+ if (!Component) {
831
+ return react.createElement(react.Fragment, withKey({}, key), openQuote, children, closeQuote);
832
+ }
833
+ if (typeof Component === "string") {
834
+ return react.createElement(Component, withKey(domProps, key), openQuote, children, closeQuote);
835
+ }
836
+ return react.createElement(
837
+ Component,
838
+ withKey(
839
+ {
840
+ ...domProps,
841
+ node
842
+ },
843
+ key
844
+ ),
845
+ openQuote,
846
+ children,
847
+ closeQuote
848
+ );
88
849
  }
89
- function renderDoc(node, components, key) {
90
- const children = renderChildren(node.children, components);
91
- const Component = pickComponent(components, "doc");
92
- if (Component) {
93
- if (typeof Component === "string") {
94
- return react.createElement(Component, withKey({}, key), children);
95
- }
96
- return react.createElement(Component, withKey({ node }, key), children);
850
+ function renderSmartPunctuation(node, components, key) {
851
+ const value = toSmartPunctuation(node.type, node.text);
852
+ const Component = pickComponent(components, "smart_punctuation");
853
+ const domProps = mergeDomProps(node);
854
+ if (!Component) {
855
+ return value;
97
856
  }
98
- return react.createElement(react.Fragment, withKey({}, key), children);
99
- }
100
- function renderSection(node, components, key) {
101
- const children = renderChildren(node.children, components);
102
- const Component = pickComponent(components, "section");
103
- if (Component) {
104
- if (typeof Component === "string") {
105
- return react.createElement(Component, withKey({}, key), children);
106
- }
107
- return react.createElement(
108
- Component,
109
- withKey(
110
- {
111
- node
112
- },
113
- key
114
- ),
115
- children
116
- );
857
+ if (typeof Component === "string") {
858
+ return react.createElement(Component, withKey(domProps, key), value);
117
859
  }
118
- return react.createElement(react.Fragment, withKey({}, key), children);
860
+ return react.createElement(
861
+ Component,
862
+ withKey(
863
+ {
864
+ ...domProps,
865
+ kind: node.type,
866
+ node,
867
+ value
868
+ },
869
+ key
870
+ ),
871
+ value
872
+ );
119
873
  }
120
- function renderHeading(node, components, key) {
121
- const level = clampHeadingLevel(node.level);
122
- const children = renderChildren(node.children, components);
874
+ function renderInlineMath(node, components, key) {
875
+ const value = node.text;
123
876
  return renderWithOverride(
124
- pickComponent(components, "heading"),
125
- `h${level}`,
126
- {},
877
+ pickComponent(components, "inline_math"),
878
+ "span",
879
+ mergeDomProps(node, {
880
+ className: "math inline"
881
+ }),
127
882
  {
128
- level,
129
- node
883
+ node,
884
+ value
130
885
  },
131
886
  key,
132
- children
887
+ `\\(${value}\\)`
888
+ );
889
+ }
890
+ function renderDisplayMath(node, components, key) {
891
+ const value = node.text;
892
+ return renderWithOverride(
893
+ pickComponent(components, "display_math"),
894
+ "span",
895
+ mergeDomProps(node, {
896
+ className: "math display"
897
+ }),
898
+ {
899
+ node,
900
+ value
901
+ },
902
+ key,
903
+ `\\[${value}\\]`
133
904
  );
134
905
  }
135
906
  function renderCode(node, components, key, primary, alias) {
@@ -137,7 +908,7 @@ function renderCode(node, components, key, primary, alias) {
137
908
  return renderWithOverride(
138
909
  pickComponent(components, primary, alias),
139
910
  "code",
140
- {},
911
+ mergeDomProps(node),
141
912
  {
142
913
  node,
143
914
  value
@@ -159,7 +930,7 @@ function renderCodeBlock(node, components, key) {
159
930
  return renderWithOverride(
160
931
  pickComponent(components, "code_block"),
161
932
  "pre",
162
- {},
933
+ mergeDomProps(node),
163
934
  {
164
935
  language,
165
936
  node,
@@ -169,15 +940,136 @@ function renderCodeBlock(node, components, key) {
169
940
  fallbackChildren
170
941
  );
171
942
  }
172
- function renderLink(node, components, key) {
173
- const children = renderChildren(node.children, components);
174
- const href = node.destination;
943
+ function renderRawBlock(node, components, key) {
944
+ const format = node.format;
945
+ const value = node.text;
946
+ const htmlChildren = format === "html" ? rawHtmlChildren(value, `raw-block-${String(key ?? "node")}`) : void 0;
947
+ const Component = pickComponent(components, "raw_block");
948
+ const domProps = mergeDomProps(node);
949
+ if (!Component) {
950
+ if (format !== "html") {
951
+ return null;
952
+ }
953
+ return react.createElement(react.Fragment, withKey({}, key), htmlChildren);
954
+ }
955
+ if (typeof Component === "string") {
956
+ return react.createElement(Component, withKey(domProps, key), htmlChildren ?? value);
957
+ }
958
+ return react.createElement(
959
+ Component,
960
+ withKey(
961
+ {
962
+ ...domProps,
963
+ format,
964
+ node,
965
+ value
966
+ },
967
+ key
968
+ ),
969
+ htmlChildren ?? value
970
+ );
971
+ }
972
+ function renderRawInline(node, components, key) {
973
+ const format = node.format;
974
+ const value = node.text;
975
+ const htmlChildren = format === "html" ? rawHtmlChildren(value, `raw-inline-${String(key ?? "node")}`) : void 0;
976
+ const Component = pickComponent(components, "raw_inline");
977
+ const domProps = mergeDomProps(node);
978
+ if (!Component) {
979
+ if (format !== "html") {
980
+ return null;
981
+ }
982
+ return react.createElement(react.Fragment, withKey({}, key), htmlChildren);
983
+ }
984
+ if (typeof Component === "string") {
985
+ return react.createElement(Component, withKey(domProps, key), htmlChildren ?? value);
986
+ }
987
+ return react.createElement(
988
+ Component,
989
+ withKey(
990
+ {
991
+ ...domProps,
992
+ format,
993
+ node,
994
+ value
995
+ },
996
+ key
997
+ ),
998
+ htmlChildren ?? value
999
+ );
1000
+ }
1001
+ function renderUrl(node, components, key) {
1002
+ const value = node.text;
1003
+ const href = value;
175
1004
  return renderWithOverride(
176
- pickComponent(components, "link"),
1005
+ pickComponent(components, "url"),
177
1006
  "a",
1007
+ mergeDomProps(node, {
1008
+ href
1009
+ }),
178
1010
  {
1011
+ href,
1012
+ node,
1013
+ value
1014
+ },
1015
+ key,
1016
+ value
1017
+ );
1018
+ }
1019
+ function renderEmail(node, components, key) {
1020
+ const value = node.text;
1021
+ const href = `mailto:${value}`;
1022
+ return renderWithOverride(
1023
+ pickComponent(components, "email"),
1024
+ "a",
1025
+ mergeDomProps(node, {
179
1026
  href
1027
+ }),
1028
+ {
1029
+ href,
1030
+ node,
1031
+ value
180
1032
  },
1033
+ key,
1034
+ value
1035
+ );
1036
+ }
1037
+ function renderSymb(node, components, key) {
1038
+ const alias = node.alias;
1039
+ const value = `:${alias}:`;
1040
+ const Component = pickComponent(components, "symb");
1041
+ if (!Component) {
1042
+ return value;
1043
+ }
1044
+ if (typeof Component === "string") {
1045
+ return react.createElement(Component, withKey(mergeDomProps(node), key), value);
1046
+ }
1047
+ return react.createElement(
1048
+ Component,
1049
+ withKey(
1050
+ {
1051
+ ...mergeDomProps(node),
1052
+ alias,
1053
+ node,
1054
+ value
1055
+ },
1056
+ key
1057
+ ),
1058
+ value
1059
+ );
1060
+ }
1061
+ function renderLink(node, components, footnoteState, key) {
1062
+ const children = renderChildren(node.children, components, footnoteState);
1063
+ const referenceNode = resolveReferenceNode(node, footnoteState);
1064
+ const referenceProps = referenceNode ? toDomPropsFromNode(referenceNode) : {};
1065
+ const href = resolveReferenceDestination(node, footnoteState);
1066
+ return renderWithOverride(
1067
+ pickComponent(components, "link"),
1068
+ "a",
1069
+ mergeDomProps(node, {
1070
+ href,
1071
+ ...referenceProps
1072
+ }),
181
1073
  {
182
1074
  node
183
1075
  },
@@ -185,16 +1077,19 @@ function renderLink(node, components, key) {
185
1077
  children
186
1078
  );
187
1079
  }
188
- function renderImage(node, components, key) {
1080
+ function renderImage(node, components, footnoteState, key) {
189
1081
  const alt = toAltText(node.children) || void 0;
190
- const src = node.destination;
1082
+ const referenceNode = resolveReferenceNode(node, footnoteState);
1083
+ const referenceProps = referenceNode ? toDomPropsFromNode(referenceNode) : {};
1084
+ const src = resolveReferenceDestination(node, footnoteState);
191
1085
  return renderWithOverride(
192
1086
  pickComponent(components, "image"),
193
1087
  "img",
194
- {
1088
+ mergeDomProps(node, {
195
1089
  alt,
196
- src
197
- },
1090
+ src,
1091
+ ...referenceProps
1092
+ }),
198
1093
  {
199
1094
  alt,
200
1095
  node
@@ -202,28 +1097,165 @@ function renderImage(node, components, key) {
202
1097
  key
203
1098
  );
204
1099
  }
205
- function renderOrderedList(node, components, key) {
206
- const children = renderChildren(node.children, components);
1100
+ function renderOrderedList(node, components, footnoteState, key) {
1101
+ const tight = node.tight ?? false;
1102
+ const children = renderChildren(node.children, components, footnoteState, tight);
1103
+ const start = node.start !== void 0 && node.start !== 1 ? node.start : void 0;
1104
+ const type = toOrderedListType(node.style);
207
1105
  return renderWithOverride(
208
1106
  pickComponent(components, "ordered_list"),
209
1107
  "ol",
1108
+ mergeDomProps(node, {
1109
+ start,
1110
+ type
1111
+ }),
1112
+ {
1113
+ node,
1114
+ start,
1115
+ tight
1116
+ },
1117
+ key,
1118
+ children
1119
+ );
1120
+ }
1121
+ function renderDefinitionList(node, components, footnoteState, key) {
1122
+ const children = renderChildren(node.children, components, footnoteState);
1123
+ return renderWithOverride(
1124
+ pickComponent(components, "definition_list"),
1125
+ "dl",
1126
+ mergeDomProps(node),
210
1127
  {
211
- start: node.start
1128
+ node
212
1129
  },
1130
+ key,
1131
+ children
1132
+ );
1133
+ }
1134
+ function renderDefinitionListItem(node, components, footnoteState, key) {
1135
+ const children = renderChildren(node.children, components, footnoteState);
1136
+ const Component = pickComponent(components, "definition_list_item");
1137
+ const domProps = mergeDomProps(node);
1138
+ if (Component) {
1139
+ if (typeof Component === "string") {
1140
+ return react.createElement(Component, withKey(domProps, key), children);
1141
+ }
1142
+ return react.createElement(
1143
+ Component,
1144
+ withKey(
1145
+ {
1146
+ ...domProps,
1147
+ node
1148
+ },
1149
+ key
1150
+ ),
1151
+ children
1152
+ );
1153
+ }
1154
+ return react.createElement(react.Fragment, withKey({}, key), children);
1155
+ }
1156
+ function renderBulletList(node, components, footnoteState, key) {
1157
+ const tight = node.tight ?? false;
1158
+ const children = renderChildren(node.children, components, footnoteState, tight);
1159
+ return renderWithOverride(
1160
+ pickComponent(components, "bullet_list"),
1161
+ "ul",
1162
+ mergeDomProps(node),
213
1163
  {
214
1164
  node,
215
- start: node.start
1165
+ tight
1166
+ },
1167
+ key,
1168
+ children
1169
+ );
1170
+ }
1171
+ function renderListItem(node, components, footnoteState, listTight, key) {
1172
+ const override = pickComponent(components, "list_item");
1173
+ if (override) {
1174
+ const domProps = mergeDomProps(node);
1175
+ const contentChildren2 = renderChildren(node.children, components, footnoteState);
1176
+ if (typeof override === "string") {
1177
+ return react.createElement(override, withKey(domProps, key), contentChildren2);
1178
+ }
1179
+ return react.createElement(
1180
+ override,
1181
+ withKey({ ...domProps, node, tight: listTight }, key),
1182
+ contentChildren2
1183
+ );
1184
+ }
1185
+ const firstChild = node.children[0];
1186
+ const inlineSource = listTight === true && node.children.length === 1 && firstChild?.tag === "para" ? firstChild.children : node.children;
1187
+ const contentChildren = renderChildren(inlineSource, components, footnoteState);
1188
+ return react.createElement("li", withKey(mergeDomProps(node), key), contentChildren);
1189
+ }
1190
+ function renderTerm(node, components, footnoteState, key) {
1191
+ const children = renderChildren(node.children, components, footnoteState);
1192
+ return renderWithOverride(
1193
+ pickComponent(components, "term"),
1194
+ "dt",
1195
+ mergeDomProps(node),
1196
+ {
1197
+ node
1198
+ },
1199
+ key,
1200
+ children
1201
+ );
1202
+ }
1203
+ function renderDefinition(node, components, footnoteState, key) {
1204
+ const children = renderChildren(node.children, components, footnoteState);
1205
+ return renderWithOverride(
1206
+ pickComponent(components, "definition"),
1207
+ "dd",
1208
+ mergeDomProps(node),
1209
+ {
1210
+ node
216
1211
  },
217
1212
  key,
218
1213
  children
219
1214
  );
220
1215
  }
221
- function renderBlockQuote(node, components, key, primary, alias) {
222
- const children = renderChildren(node.children, components);
1216
+ function renderTaskList(node, components, footnoteState, key) {
1217
+ const tight = node.tight ?? false;
1218
+ const children = renderChildren(node.children, components, footnoteState, tight);
1219
+ return renderWithOverride(
1220
+ pickComponent(components, "task_list"),
1221
+ "ul",
1222
+ mergeDomProps(node, { className: "task-list" }),
1223
+ { node, tight },
1224
+ key,
1225
+ children
1226
+ );
1227
+ }
1228
+ function renderTaskListItem(node, components, footnoteState, listTight, key) {
1229
+ const override = pickComponent(components, "task_list_item");
1230
+ if (override) {
1231
+ const domProps = mergeDomProps(node);
1232
+ const contentChildren2 = renderChildren(node.children, components, footnoteState);
1233
+ if (typeof override === "string") {
1234
+ return react.createElement(override, withKey(domProps, key), contentChildren2);
1235
+ }
1236
+ return react.createElement(
1237
+ override,
1238
+ withKey({ ...domProps, node, checkbox: node.checkbox, tight: listTight }, key),
1239
+ contentChildren2
1240
+ );
1241
+ }
1242
+ const firstChild = node.children[0];
1243
+ const inlineSource = listTight === true && node.children.length === 1 && firstChild?.tag === "para" ? firstChild.children : node.children;
1244
+ const contentChildren = renderChildren(inlineSource, components, footnoteState);
1245
+ const checkboxEl = react.createElement("input", {
1246
+ key: "checkbox",
1247
+ type: "checkbox",
1248
+ disabled: true,
1249
+ checked: node.checkbox === "checked"
1250
+ });
1251
+ return react.createElement("li", withKey(mergeDomProps(node), key), [checkboxEl, contentChildren]);
1252
+ }
1253
+ function renderBlockQuote(node, components, footnoteState, key, primary, alias) {
1254
+ const children = renderChildren(node.children, components, footnoteState);
223
1255
  return renderWithOverride(
224
1256
  pickComponent(components, primary, alias),
225
1257
  "blockquote",
226
- {},
1258
+ mergeDomProps(node),
227
1259
  {
228
1260
  node
229
1261
  },
@@ -234,16 +1266,49 @@ function renderBlockQuote(node, components, key, primary, alias) {
234
1266
  function renderStr(node, components, key) {
235
1267
  const value = node.text;
236
1268
  const Component = pickComponent(components, "str");
1269
+ const domProps = mergeDomProps(node);
1270
+ const hasNodeDomProps = Object.keys(domProps).length > 0;
1271
+ if (!Component) {
1272
+ if (hasNodeDomProps) {
1273
+ return react.createElement("span", withKey(domProps, key), value);
1274
+ }
1275
+ return value;
1276
+ }
1277
+ if (typeof Component === "string") {
1278
+ return react.createElement(Component, withKey(domProps, key), value);
1279
+ }
1280
+ return react.createElement(
1281
+ Component,
1282
+ withKey(
1283
+ {
1284
+ ...domProps,
1285
+ node,
1286
+ value
1287
+ },
1288
+ key
1289
+ ),
1290
+ value
1291
+ );
1292
+ }
1293
+ function renderNonBreakingSpace(node, components, key) {
1294
+ const value = "\xA0";
1295
+ const Component = pickComponent(components, "non_breaking_space");
1296
+ const domProps = mergeDomProps(node);
1297
+ const hasNodeDomProps = Object.keys(domProps).length > 0;
237
1298
  if (!Component) {
1299
+ if (hasNodeDomProps) {
1300
+ return react.createElement("span", withKey(domProps, key), value);
1301
+ }
238
1302
  return value;
239
1303
  }
240
1304
  if (typeof Component === "string") {
241
- return react.createElement(Component, withKey({}, key), value);
1305
+ return react.createElement(Component, withKey(domProps, key), value);
242
1306
  }
243
1307
  return react.createElement(
244
1308
  Component,
245
1309
  withKey(
246
1310
  {
1311
+ ...domProps,
247
1312
  node,
248
1313
  value
249
1314
  },
@@ -254,16 +1319,18 @@ function renderStr(node, components, key) {
254
1319
  }
255
1320
  function renderSoftBreak(node, components, key) {
256
1321
  const Component = pickComponent(components, "soft_break", "softbreak");
1322
+ const domProps = mergeDomProps(node);
257
1323
  if (!Component) {
258
1324
  return "\n";
259
1325
  }
260
1326
  if (typeof Component === "string") {
261
- return react.createElement(Component, withKey({}, key), "\n");
1327
+ return react.createElement(Component, withKey(domProps, key), "\n");
262
1328
  }
263
1329
  return react.createElement(
264
1330
  Component,
265
1331
  withKey(
266
1332
  {
1333
+ ...domProps,
267
1334
  node
268
1335
  },
269
1336
  key
@@ -275,7 +1342,7 @@ function renderHardBreak(node, components, key) {
275
1342
  return renderWithOverride(
276
1343
  pickComponent(components, "hard_break", "hardbreak"),
277
1344
  "br",
278
- {},
1345
+ mergeDomProps(node),
279
1346
  {
280
1347
  node
281
1348
  },
@@ -283,18 +1350,28 @@ function renderHardBreak(node, components, key) {
283
1350
  );
284
1351
  }
285
1352
  function renderNode(node, options = {}) {
286
- const { components, key } = options;
287
- const children = isParentNode(node) ? renderChildren(node.children, components) : void 0;
1353
+ const { components, footnoteState, key, listTight } = options;
1354
+ const children = isParentNode3(node) ? renderChildren(node.children, components, footnoteState, listTight) : void 0;
288
1355
  switch (node.tag) {
289
1356
  case "doc":
290
1357
  return renderDoc(node, components, key);
291
1358
  case "section":
292
- return renderSection(node, components, key);
1359
+ return renderSection(node, components, footnoteState, key);
1360
+ case "div":
1361
+ return renderDiv(node, components, footnoteState, key);
1362
+ case "table":
1363
+ return renderTable(node, components, footnoteState, key);
1364
+ case "caption":
1365
+ return renderCaption(node, components, footnoteState, key);
1366
+ case "row":
1367
+ return renderRow(node, components, footnoteState, key);
1368
+ case "cell":
1369
+ return renderCell(node, components, footnoteState, key);
293
1370
  case "para":
294
1371
  return renderWithOverride(
295
1372
  pickComponent(components, "para"),
296
1373
  "p",
297
- {},
1374
+ mergeDomProps(node),
298
1375
  {
299
1376
  node
300
1377
  },
@@ -302,12 +1379,12 @@ function renderNode(node, options = {}) {
302
1379
  children
303
1380
  );
304
1381
  case "heading":
305
- return renderHeading(node, components, key);
1382
+ return renderHeading(node, components, footnoteState, key);
306
1383
  case "emph":
307
1384
  return renderWithOverride(
308
1385
  pickComponent(components, "emph"),
309
1386
  "em",
310
- {},
1387
+ mergeDomProps(node),
311
1388
  {
312
1389
  node
313
1390
  },
@@ -318,56 +1395,128 @@ function renderNode(node, options = {}) {
318
1395
  return renderWithOverride(
319
1396
  pickComponent(components, "strong"),
320
1397
  "strong",
321
- {},
1398
+ mergeDomProps(node),
322
1399
  {
323
1400
  node
324
1401
  },
325
1402
  key,
326
1403
  children
327
1404
  );
328
- case "code":
329
- return renderCode(node, components, key, "code", "verbatim");
330
- case "verbatim":
331
- return renderCode(node, components, key, "verbatim", "code");
332
- case "code_block":
333
- return renderCodeBlock(node, components, key);
334
- case "link":
335
- return renderLink(node, components, key);
336
- case "image":
337
- return renderImage(node, components, key);
338
- case "bullet_list":
1405
+ case "mark":
1406
+ return renderMark(node, components, footnoteState, key, "mark", "highlighted");
1407
+ case "highlighted":
1408
+ return renderMark(node, components, footnoteState, key, "highlighted", "mark");
1409
+ case "superscript":
1410
+ return renderSuperscript(node, components, footnoteState, key, "superscript", "supe");
1411
+ case "supe":
1412
+ return renderSuperscript(node, components, footnoteState, key, "supe", "superscript");
1413
+ case "subscript":
1414
+ return renderSubscript(node, components, footnoteState, key);
1415
+ case "insert":
1416
+ return renderInsert(node, components, footnoteState, key);
1417
+ case "delete":
1418
+ return renderDelete(node, components, footnoteState, key);
1419
+ case "span":
339
1420
  return renderWithOverride(
340
- pickComponent(components, "bullet_list"),
341
- "ul",
342
- {},
1421
+ pickComponent(components, "span"),
1422
+ "span",
1423
+ mergeDomProps(node),
343
1424
  {
344
1425
  node
345
1426
  },
346
1427
  key,
347
1428
  children
348
1429
  );
349
- case "ordered_list":
350
- return renderOrderedList(node, components, key);
351
- case "list_item":
1430
+ case "footnote_reference":
1431
+ return renderFootnoteReference(node, components, footnoteState, key);
1432
+ case "footnote":
352
1433
  return renderWithOverride(
353
- pickComponent(components, "list_item"),
1434
+ pickComponent(components, "footnote"),
354
1435
  "li",
355
- {},
1436
+ mergeDomProps(node),
356
1437
  {
1438
+ index: 0,
1439
+ label: node.label,
357
1440
  node
358
1441
  },
359
1442
  key,
360
1443
  children
361
1444
  );
1445
+ case "double_quoted":
1446
+ return renderQuoted(
1447
+ node,
1448
+ components,
1449
+ footnoteState,
1450
+ key,
1451
+ "double_quoted",
1452
+ "single_quoted",
1453
+ "\u201C",
1454
+ "\u201D"
1455
+ );
1456
+ case "single_quoted":
1457
+ return renderQuoted(
1458
+ node,
1459
+ components,
1460
+ footnoteState,
1461
+ key,
1462
+ "single_quoted",
1463
+ "double_quoted",
1464
+ "\u2018",
1465
+ "\u2019"
1466
+ );
1467
+ case "smart_punctuation":
1468
+ return renderSmartPunctuation(node, components, key);
1469
+ case "symb":
1470
+ return renderSymb(node, components, key);
1471
+ case "inline_math":
1472
+ return renderInlineMath(node, components, key);
1473
+ case "display_math":
1474
+ return renderDisplayMath(node, components, key);
1475
+ case "code":
1476
+ return renderCode(node, components, key, "code", "verbatim");
1477
+ case "verbatim":
1478
+ return renderCode(node, components, key, "verbatim", "code");
1479
+ case "code_block":
1480
+ return renderCodeBlock(node, components, key);
1481
+ case "raw_block":
1482
+ return renderRawBlock(node, components, key);
1483
+ case "raw_inline":
1484
+ return renderRawInline(node, components, key);
1485
+ case "url":
1486
+ return renderUrl(node, components, key);
1487
+ case "email":
1488
+ return renderEmail(node, components, key);
1489
+ case "link":
1490
+ return renderLink(node, components, footnoteState, key);
1491
+ case "image":
1492
+ return renderImage(node, components, footnoteState, key);
1493
+ case "bullet_list":
1494
+ return renderBulletList(node, components, footnoteState, key);
1495
+ case "ordered_list":
1496
+ return renderOrderedList(node, components, footnoteState, key);
1497
+ case "list_item":
1498
+ return renderListItem(node, components, footnoteState, listTight, key);
1499
+ case "definition_list":
1500
+ return renderDefinitionList(node, components, footnoteState, key);
1501
+ case "definition_list_item":
1502
+ return renderDefinitionListItem(node, components, footnoteState, key);
1503
+ case "term":
1504
+ return renderTerm(node, components, footnoteState, key);
1505
+ case "definition":
1506
+ return renderDefinition(node, components, footnoteState, key);
1507
+ case "task_list":
1508
+ return renderTaskList(node, components, footnoteState, key);
1509
+ case "task_list_item":
1510
+ return renderTaskListItem(node, components, footnoteState, listTight, key);
362
1511
  case "blockquote":
363
- return renderBlockQuote(node, components, key, "blockquote", "block_quote");
1512
+ return renderBlockQuote(node, components, footnoteState, key, "blockquote", "block_quote");
364
1513
  case "block_quote":
365
- return renderBlockQuote(node, components, key, "block_quote", "blockquote");
1514
+ return renderBlockQuote(node, components, footnoteState, key, "block_quote", "blockquote");
366
1515
  case "thematic_break":
367
1516
  return renderWithOverride(
368
1517
  pickComponent(components, "thematic_break"),
369
1518
  "hr",
370
- {},
1519
+ mergeDomProps(node),
371
1520
  {
372
1521
  node
373
1522
  },
@@ -375,6 +1524,8 @@ function renderNode(node, options = {}) {
375
1524
  );
376
1525
  case "str":
377
1526
  return renderStr(node, components, key);
1527
+ case "non_breaking_space":
1528
+ return renderNonBreakingSpace(node, components, key);
378
1529
  default:
379
1530
  if (isSoftBreakNode(node)) {
380
1531
  return renderSoftBreak(node, components, key);
@@ -385,17 +1536,52 @@ function renderNode(node, options = {}) {
385
1536
  return null;
386
1537
  }
387
1538
  }
388
- function Djot({ children, components }) {
389
- const source = children ?? "";
1539
+ var COMPILE_CACHE_LIMIT = 100;
1540
+ var compileCache = /* @__PURE__ */ new Map();
1541
+ function getCachedAst(source) {
1542
+ const cached = compileCache.get(source);
1543
+ if (!cached) {
1544
+ return void 0;
1545
+ }
1546
+ compileCache.delete(source);
1547
+ compileCache.set(source, cached);
1548
+ return cached;
1549
+ }
1550
+ function setCachedAst(source, ast) {
1551
+ compileCache.set(source, ast);
1552
+ if (compileCache.size > COMPILE_CACHE_LIMIT) {
1553
+ const oldestSource = compileCache.keys().next().value;
1554
+ if (oldestSource !== void 0) {
1555
+ compileCache.delete(oldestSource);
1556
+ }
1557
+ }
1558
+ return ast;
1559
+ }
1560
+ function compileDjot(source) {
1561
+ const cached = getCachedAst(source);
1562
+ if (cached) {
1563
+ return cached;
1564
+ }
1565
+ const ast = djot.parse(source);
1566
+ return setCachedAst(source, ast);
1567
+ }
1568
+ function Djot(props) {
1569
+ const { components } = props;
1570
+ const astFromProps = props.ast;
1571
+ if (astFromProps !== void 0) {
1572
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: renderNode(astFromProps, { components }) });
1573
+ }
1574
+ const source = props.children ?? "";
390
1575
  if (source.length === 0) {
391
1576
  return null;
392
1577
  }
393
- const ast = djot.parse(source);
1578
+ const ast = compileDjot(source);
394
1579
  return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: renderNode(ast, { components }) });
395
1580
  }
396
1581
  var Djot_default = Djot;
397
1582
 
398
1583
  exports.Djot = Djot;
1584
+ exports.compileDjot = compileDjot;
399
1585
  exports.default = Djot_default;
400
1586
  exports.renderNode = renderNode;
401
1587
  //# sourceMappingURL=index.cjs.map