@nuucognition/ncm-ui 0.1.1-beta.0 → 0.1.1-beta.2

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 (39) hide show
  1. package/dist/blocks/admonition/index.js +118 -46
  2. package/dist/blocks/aside/index.js +118 -46
  3. package/dist/blocks/blockquote/index.d.ts +7 -5
  4. package/dist/blocks/blockquote/index.js +1218 -36
  5. package/dist/blocks/chart/index.js +2 -1
  6. package/dist/blocks/container/index.js +72 -31
  7. package/dist/blocks/custom-code/index.js +1 -1
  8. package/dist/blocks/dataview/index.js +2 -1
  9. package/dist/blocks/definition/index.js +117 -45
  10. package/dist/blocks/embedding/index.js +72 -31
  11. package/dist/blocks/figure/index.js +72 -31
  12. package/dist/blocks/footnote/index.js +118 -46
  13. package/dist/blocks/header/index.js +72 -31
  14. package/dist/blocks/html/index.js +2 -1
  15. package/dist/blocks/index.js +118 -46
  16. package/dist/blocks/latex/index.js +2 -2
  17. package/dist/blocks/list/index.js +72 -31
  18. package/dist/blocks/math/index.js +3 -2
  19. package/dist/blocks/mermaid/index.js +2 -1
  20. package/dist/blocks/paragraph/index.js +72 -31
  21. package/dist/blocks/spoiler/index.js +118 -46
  22. package/dist/blocks/table/index.js +73 -32
  23. package/dist/blocks/task-list/index.js +72 -31
  24. package/dist/components/index.js +157 -65
  25. package/dist/components/ncm-block.js +118 -46
  26. package/dist/components/ncm-document.js +157 -65
  27. package/dist/context/index.d.ts +1 -1
  28. package/dist/context/index.js +119 -44
  29. package/dist/hooks/index.js +118 -46
  30. package/dist/hooks/use-block-renderer.js +118 -46
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +164 -58
  33. package/dist/inline/index.d.ts +2 -3
  34. package/dist/inline/index.js +72 -31
  35. package/dist/lib/defaults.js +118 -46
  36. package/dist/references-BM-lvGrq.d.ts +99 -0
  37. package/dist/styles/nuu.css +39 -16
  38. package/package.json +3 -4
  39. package/dist/references-BYW5pnj_.d.ts +0 -63
package/dist/index.js CHANGED
@@ -56,6 +56,52 @@ function tryParseInlineRef(input) {
56
56
  }
57
57
  return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
58
58
  }
59
+ function runLength(input, index, char) {
60
+ let end = index;
61
+ while (end < input.length && input[end] === char) end++;
62
+ return end - index;
63
+ }
64
+ function tryParseEmphasis(input) {
65
+ const char = input[0];
66
+ if (char !== "*" && char !== "_") return null;
67
+ const open = Math.min(3, runLength(input, 0, char));
68
+ const need = open;
69
+ let i = open;
70
+ while (i < input.length) {
71
+ const ch = input[i];
72
+ if (ch === "`") {
73
+ const close = input.indexOf("`", i + 1);
74
+ if (close === -1) break;
75
+ i = close + 1;
76
+ continue;
77
+ }
78
+ if (ch !== char) {
79
+ i++;
80
+ continue;
81
+ }
82
+ const run = runLength(input, i, char);
83
+ const closes = need === 1 ? run % 2 === 1 : run >= need;
84
+ if (!closes) {
85
+ i += run;
86
+ continue;
87
+ }
88
+ const extra = run - need;
89
+ const inner = input.slice(open, i + extra);
90
+ if (inner.length === 0) return null;
91
+ const length = i + run;
92
+ const children = parseInline(inner);
93
+ let token;
94
+ if (need === 3) {
95
+ token = { type: "bold", children: [{ type: "italic", children }] };
96
+ } else if (need === 2) {
97
+ token = { type: "bold", children };
98
+ } else {
99
+ token = { type: "italic", children };
100
+ }
101
+ return { token, length };
102
+ }
103
+ return null;
104
+ }
59
105
  function parseInline(content) {
60
106
  if (!content) return [];
61
107
  const tokens = [];
@@ -127,17 +173,11 @@ function parseInline(content) {
127
173
  remaining = remaining.slice(linkMatch[0].length);
128
174
  continue;
129
175
  }
130
- const boldMatch = remaining.match(/^\*\*(.+?)\*\*|^__(.+?)__/);
131
- if (boldMatch) {
132
- const innerContent = boldMatch[1] ?? boldMatch[2];
133
- if (innerContent !== void 0) {
134
- tokens.push({
135
- type: "bold",
136
- children: parseInline(innerContent)
137
- });
138
- remaining = remaining.slice(boldMatch[0].length);
139
- continue;
140
- }
176
+ const emphasis = tryParseEmphasis(remaining);
177
+ if (emphasis) {
178
+ tokens.push(emphasis.token);
179
+ remaining = remaining.slice(emphasis.length);
180
+ continue;
141
181
  }
142
182
  const strikeMatch = remaining.match(/^~~(.+?)~~/);
143
183
  if (strikeMatch && strikeMatch[1] !== void 0) {
@@ -148,18 +188,6 @@ function parseInline(content) {
148
188
  remaining = remaining.slice(strikeMatch[0].length);
149
189
  continue;
150
190
  }
151
- const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
152
- if (italicMatch) {
153
- const innerContent = italicMatch[1] ?? italicMatch[2];
154
- if (innerContent !== void 0) {
155
- tokens.push({
156
- type: "italic",
157
- children: parseInline(innerContent)
158
- });
159
- remaining = remaining.slice(italicMatch[0].length);
160
- continue;
161
- }
162
- }
163
191
  const nextSpecial = findNextSpecialChar(remaining);
164
192
  if (nextSpecial > 0) {
165
193
  tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
@@ -230,48 +258,95 @@ function collectListStrings(items) {
230
258
  }
231
259
  return out;
232
260
  }
233
- function countInlineRefs(tokens, acc) {
261
+ function normalizeReferenceContent(content) {
262
+ return content.replace(/\s+/g, " ").trim().toLowerCase();
263
+ }
264
+ var BIBLIOGRAPHY_ENTRY_RE = /^\s*\[(\d+)\]\s+([\s\S]+?)\s*$/;
265
+ function collectBibliography(blocks) {
266
+ const entries = /* @__PURE__ */ new Map();
267
+ for (const block of blocks) {
268
+ if (block.type !== "paragraph") continue;
269
+ const content = block.content ?? "";
270
+ const match = BIBLIOGRAPHY_ENTRY_RE.exec(content);
271
+ if (!match || !match[1] || !match[2]) continue;
272
+ const key = normalizeReferenceContent(match[2]);
273
+ if (key && !entries.has(key)) entries.set(key, Number(match[1]));
274
+ }
275
+ return entries;
276
+ }
277
+ function walkInlineRefs(tokens, visit) {
234
278
  for (const token of tokens) {
235
279
  if (token.type === "inline_ref") {
236
- acc[token.kind] += 1;
280
+ visit(token);
237
281
  } else if ("children" in token) {
238
- countInlineRefs(token.children, acc);
282
+ walkInlineRefs(token.children, visit);
239
283
  }
240
284
  }
241
285
  }
242
- function countBlock(block) {
243
- const acc = { ref: 0, footnote: 0 };
244
- for (const str of collectInlineStrings(block)) {
245
- if (str) countInlineRefs(parseInline(str), acc);
286
+ function computeReferenceNumbering(blocks) {
287
+ const bibliography = collectBibliography(blocks);
288
+ let maxBibliography = 0;
289
+ for (const n of bibliography.values()) maxBibliography = Math.max(maxBibliography, n);
290
+ const numbering = { ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() };
291
+ let nextRef = maxBibliography;
292
+ let nextFootnote = 0;
293
+ for (const block of blocks) {
294
+ for (const str of collectInlineStrings(block)) {
295
+ if (!str) continue;
296
+ walkInlineRefs(parseInline(str), (token) => {
297
+ const key = normalizeReferenceContent(token.content);
298
+ const map = numbering[token.kind];
299
+ if (map.has(key)) return;
300
+ if (token.kind === "ref") {
301
+ const fromBibliography = bibliography.get(key);
302
+ map.set(key, fromBibliography ?? ++nextRef);
303
+ } else {
304
+ map.set(key, ++nextFootnote);
305
+ }
306
+ });
307
+ }
246
308
  }
247
- return acc;
309
+ return numbering;
248
310
  }
249
311
  function computeReferenceBases(blocks) {
250
312
  const bases = /* @__PURE__ */ new Map();
251
313
  const acc = { ref: 0, footnote: 0 };
252
314
  for (const block of blocks) {
253
315
  bases.set(block.id, { ...acc });
254
- const counts = countBlock(block);
255
- acc.ref += counts.ref;
256
- acc.footnote += counts.footnote;
316
+ for (const str of collectInlineStrings(block)) {
317
+ if (!str) continue;
318
+ walkInlineRefs(parseInline(str), (token) => {
319
+ acc[token.kind] += 1;
320
+ });
321
+ }
257
322
  }
258
323
  return bases;
259
324
  }
260
- var ReferenceBasesContext = createContext(null);
325
+ var ReferenceNumberingContext = createContext(null);
261
326
  var BlockReferenceScopeContext = createContext(null);
262
327
  function NcmReferencesProvider({ blocks, children }) {
263
- const bases = useMemo(() => computeReferenceBases(blocks), [blocks]);
264
- return /* @__PURE__ */ jsx(ReferenceBasesContext.Provider, { value: bases, children });
328
+ const numbering = useMemo(() => computeReferenceNumbering(blocks), [blocks]);
329
+ return /* @__PURE__ */ jsx(ReferenceNumberingContext.Provider, { value: numbering, children });
265
330
  }
266
- function BlockReferenceScope({ blockId, children }) {
267
- const bases = useContext(ReferenceBasesContext);
268
- const base = (blockId ? bases?.get(blockId) : void 0) ?? { ref: 0, footnote: 0 };
331
+ function BlockReferenceScope({ children }) {
332
+ const numbering = useContext(ReferenceNumberingContext);
333
+ const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
269
334
  const counter = useRef({ ref: 0, footnote: 0 });
270
- counter.current = { ref: 0, footnote: 0 };
271
335
  const value = {
336
+ numberFor(kind, content) {
337
+ const key = normalizeReferenceContent(content);
338
+ const fromDocument = numbering?.[kind].get(key);
339
+ if (fromDocument !== void 0) return fromDocument;
340
+ const map = local.current[kind];
341
+ const existing = map.get(key);
342
+ if (existing !== void 0) return existing;
343
+ counter.current[kind] += 1;
344
+ map.set(key, counter.current[kind]);
345
+ return counter.current[kind];
346
+ },
272
347
  next(kind) {
273
348
  counter.current[kind] += 1;
274
- return base[kind] + counter.current[kind];
349
+ return counter.current[kind];
275
350
  }
276
351
  };
277
352
  return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
@@ -279,7 +354,7 @@ function BlockReferenceScope({ blockId, children }) {
279
354
  function useBlockReferenceScope() {
280
355
  return useContext(BlockReferenceScopeContext);
281
356
  }
282
- var INERT_SCOPE = { next: () => 0 };
357
+ var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
283
358
  function InertReferenceScope({ children }) {
284
359
  return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
285
360
  }
@@ -715,7 +790,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
715
790
  );
716
791
  }
717
792
  case "inline_ref": {
718
- const number = refScope?.next(token.kind) ?? 0;
793
+ const number = refScope?.numberFor(token.kind, token.content) ?? 0;
719
794
  return /* @__PURE__ */ jsx(ReferenceMarker, { kind: token.kind, number, children: token.content ? /* @__PURE__ */ jsx(InertReferenceScope, { children: /* @__PURE__ */ jsx(InlineContent, { content: token.content, disableBionic: true, disableBeeline: true }) }) : null });
720
795
  }
721
796
  default:
@@ -787,8 +862,32 @@ function renderBionicText(content, ratio = 0.5) {
787
862
  function renderBeelineText(content) {
788
863
  return renderReadingText(content, { beeline: true });
789
864
  }
865
+ function quoteBlocks(block) {
866
+ try {
867
+ const doc = parseNcm(block.content, {
868
+ preset: "ncm-full",
869
+ allowMissingFrontmatter: true,
870
+ // Attribution off, as the NUU Editor's bridge keeps it: the promoter's
871
+ // trigger is any last quote line starting with `-`, so a nested quote
872
+ // ending in a list item would lose that item to a `— Author` line.
873
+ blockOptions: { extensions: { attribution: false } }
874
+ });
875
+ const blocks = doc.blocks ?? [];
876
+ if (blocks.length === 0 || blocks.some((child) => child.type === "frontmatter")) {
877
+ return null;
878
+ }
879
+ return blocks.map((child, index) => ({ ...child, id: `${block.id}.${index + 1}`, stableId: void 0 }));
880
+ } catch {
881
+ return null;
882
+ }
883
+ }
884
+ function QuotedLines({ content }) {
885
+ const lines = content.split("\n");
886
+ return /* @__PURE__ */ jsx(Fragment, { children: lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: line.trim().length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: line }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" }) }, index)) });
887
+ }
790
888
  function BlockquoteBlock({ block, className }) {
791
- const lines = block.content.split("\n");
889
+ const multiline = block.content.includes("\n");
890
+ const blocks = useMemo(() => multiline ? quoteBlocks(block) : null, [block, multiline]);
792
891
  return /* @__PURE__ */ jsx(
793
892
  "blockquote",
794
893
  {
@@ -798,7 +897,9 @@ function BlockquoteBlock({ block, className }) {
798
897
  "data-block-id": block.id,
799
898
  "data-ncm-blockquote": "",
800
899
  className,
801
- children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: line.trim().length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: line }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" }) }, index))
900
+ children: !multiline ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : blocks === null ? /* @__PURE__ */ jsx(QuotedLines, { content: block.content }) : blocks.map(
901
+ (child) => child.type === "paragraph" ? /* @__PURE__ */ jsx(QuotedLines, { content: child.content ?? "" }, blockKey(child)) : /* @__PURE__ */ jsx(NcmBlock, { block: child }, blockKey(child))
902
+ )
802
903
  }
803
904
  );
804
905
  }
@@ -813,7 +914,8 @@ function ChartBlock({ block, className }) {
813
914
  "data-ncm-chart": "",
814
915
  "data-ncm-chart-type": block.chartType ?? "unknown",
815
916
  className: cn(
816
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
917
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
918
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
817
919
  className
818
920
  ),
819
921
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -993,7 +1095,8 @@ function DataviewBlock({ block, className }) {
993
1095
  "data-ncm-dataview": "",
994
1096
  "data-ncm-query-type": block.queryType,
995
1097
  className: cn(
996
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1098
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
1099
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
997
1100
  className
998
1101
  ),
999
1102
  children: /* @__PURE__ */ jsx("code", { children: block.query })
@@ -1332,7 +1435,8 @@ function HtmlBlock({ block, className }) {
1332
1435
  "data-block-id": block.id,
1333
1436
  "data-ncm-html": "",
1334
1437
  className: cn(
1335
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1438
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
1439
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1336
1440
  className
1337
1441
  ),
1338
1442
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1393,7 +1497,7 @@ function LatexDisplayBlock({ block, className }) {
1393
1497
  "data-ncm-type": block.type,
1394
1498
  "data-block-id": block.id,
1395
1499
  "data-ncm-latex-display": "",
1396
- className: cn("overflow-x-auto", className),
1500
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1397
1501
  dangerouslySetInnerHTML: { __html: html }
1398
1502
  }
1399
1503
  );
@@ -1408,7 +1512,7 @@ function LatexDisplayBlock({ block, className }) {
1408
1512
  "data-ncm-type": block.type,
1409
1513
  "data-block-id": block.id,
1410
1514
  "data-ncm-latex-display": "",
1411
- className: cn("overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1515
+ className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1412
1516
  children: /* @__PURE__ */ jsx("code", { children: block.content })
1413
1517
  }
1414
1518
  );
@@ -1528,7 +1632,7 @@ function MathBlock({ block, className }) {
1528
1632
  "data-ncm-type": block.type,
1529
1633
  "data-block-id": block.id,
1530
1634
  "data-ncm-math": "",
1531
- className: cn("overflow-x-auto", className),
1635
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1532
1636
  dangerouslySetInnerHTML: { __html: html }
1533
1637
  }
1534
1638
  );
@@ -1544,7 +1648,8 @@ function MathBlock({ block, className }) {
1544
1648
  "data-block-id": block.id,
1545
1649
  "data-ncm-math": "",
1546
1650
  className: cn(
1547
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1651
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
1652
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1548
1653
  className
1549
1654
  ),
1550
1655
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1562,7 +1667,8 @@ function MermaidBlock({ block, className }) {
1562
1667
  "data-ncm-mermaid": "",
1563
1668
  "data-ncm-diagram-type": block.diagramType,
1564
1669
  className: cn(
1565
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1670
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
1671
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1566
1672
  className
1567
1673
  ),
1568
1674
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1623,7 +1729,7 @@ function TableBlock({ block, className }) {
1623
1729
  "data-ncm-type": block.type,
1624
1730
  "data-block-id": block.id,
1625
1731
  "data-ncm-table": "",
1626
- className: cn("w-full overflow-x-auto", className),
1732
+ className: cn("w-full overflow-x-auto overflow-y-hidden", className),
1627
1733
  children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
1628
1734
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { "data-ncm-table-row": "", children: block.headers.map((header, index) => /* @__PURE__ */ jsx("th", { "data-ncm-table-header": "", children: /* @__PURE__ */ jsx(InlineContent, { content: header }) }, index)) }) }),
1629
1735
  /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
@@ -1709,7 +1815,7 @@ function FallbackBlock({ block, className }) {
1709
1815
  "data-block-id": block.id,
1710
1816
  "data-ncm-fallback": "",
1711
1817
  className: cn(
1712
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1818
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1713
1819
  className
1714
1820
  )
1715
1821
  },
@@ -1765,7 +1871,7 @@ function CustomCodeBlock({ block, className }) {
1765
1871
  "data-block-id": block.id,
1766
1872
  "data-ncm-custom-code": "",
1767
1873
  "data-ncm-language": block.language,
1768
- className: cn("overflow-x-auto", className),
1874
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1769
1875
  children: [
1770
1876
  /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
1771
1877
  /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
@@ -1971,4 +2077,4 @@ function useCustomCodeRenderer(language) {
1971
2077
  return customCodeRenderers[language];
1972
2078
  }
1973
2079
 
1974
- export { AdmonitionBlock, AsideBlock, AttributionBlock, BlockReferenceScope, BlockShell, BlockquoteBlock, ChartBlock, ChildBlocks, CodeBlock, ContainerBlock, CustomCodeBlock, DataviewBlock, DefinitionBlock, EmbeddingBlock, FigureBlock, FootnoteBlock, FrontmatterBlock, HeaderBlock, HorizontalRuleBlock, HtmlBlock, InertReferenceScope, InlineContent, LatexDisplayBlock, LinkBlock, ListBlock, MathBlock, MermaidBlock, NcmBlock, NcmBlockPreview, NcmDocument, NcmProvider, NcmReferencesProvider, PageBreakerBlock, ParagraphBlock, ReferenceMarker, SanitizedHtmlBlock, SpoilerBlock, TableBlock, TaskListBlock, blockDataAttributes, blockKey, cn, computeReferenceBases, defaultRenderers, parseInline, renderBeelineText, renderBionicText, renderReadingText, useBlockReferenceScope, useBlockRenderer, useCustomCodeRenderer, useNcmConfig };
2080
+ export { AdmonitionBlock, AsideBlock, AttributionBlock, BlockReferenceScope, BlockShell, BlockquoteBlock, ChartBlock, ChildBlocks, CodeBlock, ContainerBlock, CustomCodeBlock, DataviewBlock, DefinitionBlock, EmbeddingBlock, FigureBlock, FootnoteBlock, FrontmatterBlock, HeaderBlock, HorizontalRuleBlock, HtmlBlock, InertReferenceScope, InlineContent, LatexDisplayBlock, LinkBlock, ListBlock, MathBlock, MermaidBlock, NcmBlock, NcmBlockPreview, NcmDocument, NcmProvider, NcmReferencesProvider, PageBreakerBlock, ParagraphBlock, ReferenceMarker, SanitizedHtmlBlock, SpoilerBlock, TableBlock, TaskListBlock, blockDataAttributes, blockKey, cn, collectBibliography, computeReferenceBases, computeReferenceNumbering, defaultRenderers, normalizeReferenceContent, parseInline, renderBeelineText, renderBionicText, renderReadingText, useBlockReferenceScope, useBlockRenderer, useCustomCodeRenderer, useNcmConfig };
@@ -1,7 +1,7 @@
1
1
  import { b as InlineToken } from '../inline-DwUYUmk4.js';
2
2
  import * as react from 'react';
3
3
  import { ReactNode } from 'react';
4
- import { d as ReferenceKind } from '../references-BYW5pnj_.js';
4
+ import { d as ReferenceKind } from '../references-BM-lvGrq.js';
5
5
  import '@nuucognition/ncm';
6
6
 
7
7
  /**
@@ -13,8 +13,7 @@ import '@nuucognition/ncm';
13
13
  * - Images: ![alt](src "title")
14
14
  * - Links: [text](url "title")
15
15
  * - Inline reference: ^[ref: ...] / ^[footnote: ...]
16
- * - Bold: **text** or __text__
17
- * - Italic: *text* or _text_
16
+ * - Emphasis: ***both***, **bold**, *italic* (and the `_` spellings)
18
17
  * - Strikethrough: ~~text~~
19
18
  */
20
19
  declare function parseInline(content: string): InlineToken[];
@@ -44,6 +44,52 @@ function tryParseInlineRef(input) {
44
44
  }
45
45
  return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
46
46
  }
47
+ function runLength(input, index, char) {
48
+ let end = index;
49
+ while (end < input.length && input[end] === char) end++;
50
+ return end - index;
51
+ }
52
+ function tryParseEmphasis(input) {
53
+ const char = input[0];
54
+ if (char !== "*" && char !== "_") return null;
55
+ const open = Math.min(3, runLength(input, 0, char));
56
+ const need = open;
57
+ let i = open;
58
+ while (i < input.length) {
59
+ const ch = input[i];
60
+ if (ch === "`") {
61
+ const close = input.indexOf("`", i + 1);
62
+ if (close === -1) break;
63
+ i = close + 1;
64
+ continue;
65
+ }
66
+ if (ch !== char) {
67
+ i++;
68
+ continue;
69
+ }
70
+ const run = runLength(input, i, char);
71
+ const closes = need === 1 ? run % 2 === 1 : run >= need;
72
+ if (!closes) {
73
+ i += run;
74
+ continue;
75
+ }
76
+ const extra = run - need;
77
+ const inner = input.slice(open, i + extra);
78
+ if (inner.length === 0) return null;
79
+ const length = i + run;
80
+ const children = parseInline(inner);
81
+ let token;
82
+ if (need === 3) {
83
+ token = { type: "bold", children: [{ type: "italic", children }] };
84
+ } else if (need === 2) {
85
+ token = { type: "bold", children };
86
+ } else {
87
+ token = { type: "italic", children };
88
+ }
89
+ return { token, length };
90
+ }
91
+ return null;
92
+ }
47
93
  function parseInline(content) {
48
94
  if (!content) return [];
49
95
  const tokens = [];
@@ -115,17 +161,11 @@ function parseInline(content) {
115
161
  remaining = remaining.slice(linkMatch[0].length);
116
162
  continue;
117
163
  }
118
- const boldMatch = remaining.match(/^\*\*(.+?)\*\*|^__(.+?)__/);
119
- if (boldMatch) {
120
- const innerContent = boldMatch[1] ?? boldMatch[2];
121
- if (innerContent !== void 0) {
122
- tokens.push({
123
- type: "bold",
124
- children: parseInline(innerContent)
125
- });
126
- remaining = remaining.slice(boldMatch[0].length);
127
- continue;
128
- }
164
+ const emphasis = tryParseEmphasis(remaining);
165
+ if (emphasis) {
166
+ tokens.push(emphasis.token);
167
+ remaining = remaining.slice(emphasis.length);
168
+ continue;
129
169
  }
130
170
  const strikeMatch = remaining.match(/^~~(.+?)~~/);
131
171
  if (strikeMatch && strikeMatch[1] !== void 0) {
@@ -136,18 +176,6 @@ function parseInline(content) {
136
176
  remaining = remaining.slice(strikeMatch[0].length);
137
177
  continue;
138
178
  }
139
- const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
140
- if (italicMatch) {
141
- const innerContent = italicMatch[1] ?? italicMatch[2];
142
- if (innerContent !== void 0) {
143
- tokens.push({
144
- type: "italic",
145
- children: parseInline(innerContent)
146
- });
147
- remaining = remaining.slice(italicMatch[0].length);
148
- continue;
149
- }
150
- }
151
179
  const nextSpecial = findNextSpecialChar(remaining);
152
180
  if (nextSpecial > 0) {
153
181
  tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
@@ -258,17 +286,30 @@ function ReferenceMarker({ kind, number, children }) {
258
286
  }
259
287
  );
260
288
  }
261
- var ReferenceBasesContext = createContext(null);
289
+ function normalizeReferenceContent(content) {
290
+ return content.replace(/\s+/g, " ").trim().toLowerCase();
291
+ }
292
+ var ReferenceNumberingContext = createContext(null);
262
293
  var BlockReferenceScopeContext = createContext(null);
263
- function BlockReferenceScope({ blockId, children }) {
264
- const bases = useContext(ReferenceBasesContext);
265
- const base = (blockId ? bases?.get(blockId) : void 0) ?? { ref: 0, footnote: 0 };
294
+ function BlockReferenceScope({ children }) {
295
+ const numbering = useContext(ReferenceNumberingContext);
296
+ const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
266
297
  const counter = useRef({ ref: 0, footnote: 0 });
267
- counter.current = { ref: 0, footnote: 0 };
268
298
  const value = {
299
+ numberFor(kind, content) {
300
+ const key = normalizeReferenceContent(content);
301
+ const fromDocument = numbering?.[kind].get(key);
302
+ if (fromDocument !== void 0) return fromDocument;
303
+ const map = local.current[kind];
304
+ const existing = map.get(key);
305
+ if (existing !== void 0) return existing;
306
+ counter.current[kind] += 1;
307
+ map.set(key, counter.current[kind]);
308
+ return counter.current[kind];
309
+ },
269
310
  next(kind) {
270
311
  counter.current[kind] += 1;
271
- return base[kind] + counter.current[kind];
312
+ return counter.current[kind];
272
313
  }
273
314
  };
274
315
  return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
@@ -276,7 +317,7 @@ function BlockReferenceScope({ blockId, children }) {
276
317
  function useBlockReferenceScope() {
277
318
  return useContext(BlockReferenceScopeContext);
278
319
  }
279
- var INERT_SCOPE = { next: () => 0 };
320
+ var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
280
321
  function InertReferenceScope({ children }) {
281
322
  return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
282
323
  }
@@ -567,7 +608,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
567
608
  );
568
609
  }
569
610
  case "inline_ref": {
570
- const number = refScope?.next(token.kind) ?? 0;
611
+ const number = refScope?.numberFor(token.kind, token.content) ?? 0;
571
612
  return /* @__PURE__ */ jsx(ReferenceMarker, { kind: token.kind, number, children: token.content ? /* @__PURE__ */ jsx(InertReferenceScope, { children: /* @__PURE__ */ jsx(InlineContent, { content: token.content, disableBionic: true, disableBeeline: true }) }) : null });
572
613
  }
573
614
  default: