@nuucognition/ncm-ui 0.1.1-beta.1 → 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.
- package/dist/blocks/admonition/index.js +102 -35
- package/dist/blocks/aside/index.js +102 -35
- package/dist/blocks/blockquote/index.d.ts +7 -5
- package/dist/blocks/blockquote/index.js +1218 -36
- package/dist/blocks/container/index.js +72 -31
- package/dist/blocks/definition/index.js +101 -34
- package/dist/blocks/embedding/index.js +72 -31
- package/dist/blocks/figure/index.js +72 -31
- package/dist/blocks/footnote/index.js +102 -35
- package/dist/blocks/header/index.js +72 -31
- package/dist/blocks/index.js +102 -35
- package/dist/blocks/list/index.js +72 -31
- package/dist/blocks/paragraph/index.js +72 -31
- package/dist/blocks/spoiler/index.js +102 -35
- package/dist/blocks/table/index.js +72 -31
- package/dist/blocks/task-list/index.js +72 -31
- package/dist/components/index.js +141 -54
- package/dist/components/ncm-block.js +102 -35
- package/dist/components/ncm-document.js +141 -54
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +119 -44
- package/dist/hooks/index.js +102 -35
- package/dist/hooks/use-block-renderer.js +102 -35
- package/dist/index.d.ts +1 -1
- package/dist/index.js +148 -47
- package/dist/inline/index.d.ts +2 -3
- package/dist/inline/index.js +72 -31
- package/dist/lib/defaults.js +102 -35
- package/dist/references-BM-lvGrq.d.ts +99 -0
- package/package.json +3 -3
- package/dist/references-BYW5pnj_.d.ts +0 -63
|
@@ -3,8 +3,8 @@ import { createContext, useMemo, useContext, createElement, useRef, Component, u
|
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { serializeInlineContent, isTypedNestedList, parseNcm } from '@nuucognition/ncm';
|
|
6
7
|
import { extractExtension, embedTypeFromExtension } from '@nuucognition/mesh-core';
|
|
7
|
-
import { serializeInlineContent, isTypedNestedList } from '@nuucognition/ncm';
|
|
8
8
|
|
|
9
9
|
function blockKey(block) {
|
|
10
10
|
return block.stableId ? `${block.id}:${block.stableId}` : block.id;
|
|
@@ -153,6 +153,52 @@ function tryParseInlineRef(input) {
|
|
|
153
153
|
}
|
|
154
154
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
155
155
|
}
|
|
156
|
+
function runLength(input, index, char) {
|
|
157
|
+
let end = index;
|
|
158
|
+
while (end < input.length && input[end] === char) end++;
|
|
159
|
+
return end - index;
|
|
160
|
+
}
|
|
161
|
+
function tryParseEmphasis(input) {
|
|
162
|
+
const char = input[0];
|
|
163
|
+
if (char !== "*" && char !== "_") return null;
|
|
164
|
+
const open = Math.min(3, runLength(input, 0, char));
|
|
165
|
+
const need = open;
|
|
166
|
+
let i = open;
|
|
167
|
+
while (i < input.length) {
|
|
168
|
+
const ch = input[i];
|
|
169
|
+
if (ch === "`") {
|
|
170
|
+
const close = input.indexOf("`", i + 1);
|
|
171
|
+
if (close === -1) break;
|
|
172
|
+
i = close + 1;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (ch !== char) {
|
|
176
|
+
i++;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const run = runLength(input, i, char);
|
|
180
|
+
const closes = need === 1 ? run % 2 === 1 : run >= need;
|
|
181
|
+
if (!closes) {
|
|
182
|
+
i += run;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const extra = run - need;
|
|
186
|
+
const inner = input.slice(open, i + extra);
|
|
187
|
+
if (inner.length === 0) return null;
|
|
188
|
+
const length = i + run;
|
|
189
|
+
const children = parseInline(inner);
|
|
190
|
+
let token;
|
|
191
|
+
if (need === 3) {
|
|
192
|
+
token = { type: "bold", children: [{ type: "italic", children }] };
|
|
193
|
+
} else if (need === 2) {
|
|
194
|
+
token = { type: "bold", children };
|
|
195
|
+
} else {
|
|
196
|
+
token = { type: "italic", children };
|
|
197
|
+
}
|
|
198
|
+
return { token, length };
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
156
202
|
function parseInline(content) {
|
|
157
203
|
if (!content) return [];
|
|
158
204
|
const tokens = [];
|
|
@@ -224,17 +270,11 @@ function parseInline(content) {
|
|
|
224
270
|
remaining = remaining.slice(linkMatch[0].length);
|
|
225
271
|
continue;
|
|
226
272
|
}
|
|
227
|
-
const
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
type: "bold",
|
|
233
|
-
children: parseInline(innerContent)
|
|
234
|
-
});
|
|
235
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
273
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
274
|
+
if (emphasis) {
|
|
275
|
+
tokens.push(emphasis.token);
|
|
276
|
+
remaining = remaining.slice(emphasis.length);
|
|
277
|
+
continue;
|
|
238
278
|
}
|
|
239
279
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
240
280
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -245,18 +285,6 @@ function parseInline(content) {
|
|
|
245
285
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
246
286
|
continue;
|
|
247
287
|
}
|
|
248
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
249
|
-
if (italicMatch) {
|
|
250
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
251
|
-
if (innerContent !== void 0) {
|
|
252
|
-
tokens.push({
|
|
253
|
-
type: "italic",
|
|
254
|
-
children: parseInline(innerContent)
|
|
255
|
-
});
|
|
256
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
257
|
-
continue;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
288
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
261
289
|
if (nextSpecial > 0) {
|
|
262
290
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -407,48 +435,81 @@ function collectListStrings(items) {
|
|
|
407
435
|
}
|
|
408
436
|
return out;
|
|
409
437
|
}
|
|
410
|
-
function
|
|
438
|
+
function normalizeReferenceContent(content) {
|
|
439
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
440
|
+
}
|
|
441
|
+
var BIBLIOGRAPHY_ENTRY_RE = /^\s*\[(\d+)\]\s+([\s\S]+?)\s*$/;
|
|
442
|
+
function collectBibliography(blocks) {
|
|
443
|
+
const entries = /* @__PURE__ */ new Map();
|
|
444
|
+
for (const block of blocks) {
|
|
445
|
+
if (block.type !== "paragraph") continue;
|
|
446
|
+
const content = block.content ?? "";
|
|
447
|
+
const match = BIBLIOGRAPHY_ENTRY_RE.exec(content);
|
|
448
|
+
if (!match || !match[1] || !match[2]) continue;
|
|
449
|
+
const key = normalizeReferenceContent(match[2]);
|
|
450
|
+
if (key && !entries.has(key)) entries.set(key, Number(match[1]));
|
|
451
|
+
}
|
|
452
|
+
return entries;
|
|
453
|
+
}
|
|
454
|
+
function walkInlineRefs(tokens, visit) {
|
|
411
455
|
for (const token of tokens) {
|
|
412
456
|
if (token.type === "inline_ref") {
|
|
413
|
-
|
|
457
|
+
visit(token);
|
|
414
458
|
} else if ("children" in token) {
|
|
415
|
-
|
|
459
|
+
walkInlineRefs(token.children, visit);
|
|
416
460
|
}
|
|
417
461
|
}
|
|
418
462
|
}
|
|
419
|
-
function
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
function computeReferenceBases(blocks) {
|
|
427
|
-
const bases = /* @__PURE__ */ new Map();
|
|
428
|
-
const acc = { ref: 0, footnote: 0 };
|
|
463
|
+
function computeReferenceNumbering(blocks) {
|
|
464
|
+
const bibliography = collectBibliography(blocks);
|
|
465
|
+
let maxBibliography = 0;
|
|
466
|
+
for (const n of bibliography.values()) maxBibliography = Math.max(maxBibliography, n);
|
|
467
|
+
const numbering = { ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() };
|
|
468
|
+
let nextRef = maxBibliography;
|
|
469
|
+
let nextFootnote = 0;
|
|
429
470
|
for (const block of blocks) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
471
|
+
for (const str of collectInlineStrings(block)) {
|
|
472
|
+
if (!str) continue;
|
|
473
|
+
walkInlineRefs(parseInline(str), (token) => {
|
|
474
|
+
const key = normalizeReferenceContent(token.content);
|
|
475
|
+
const map = numbering[token.kind];
|
|
476
|
+
if (map.has(key)) return;
|
|
477
|
+
if (token.kind === "ref") {
|
|
478
|
+
const fromBibliography = bibliography.get(key);
|
|
479
|
+
map.set(key, fromBibliography ?? ++nextRef);
|
|
480
|
+
} else {
|
|
481
|
+
map.set(key, ++nextFootnote);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}
|
|
434
485
|
}
|
|
435
|
-
return
|
|
486
|
+
return numbering;
|
|
436
487
|
}
|
|
437
|
-
var
|
|
488
|
+
var ReferenceNumberingContext = createContext(null);
|
|
438
489
|
var BlockReferenceScopeContext = createContext(null);
|
|
439
490
|
function NcmReferencesProvider({ blocks, children }) {
|
|
440
|
-
const
|
|
441
|
-
return /* @__PURE__ */ jsx(
|
|
491
|
+
const numbering = useMemo(() => computeReferenceNumbering(blocks), [blocks]);
|
|
492
|
+
return /* @__PURE__ */ jsx(ReferenceNumberingContext.Provider, { value: numbering, children });
|
|
442
493
|
}
|
|
443
|
-
function BlockReferenceScope({
|
|
444
|
-
const
|
|
445
|
-
const
|
|
494
|
+
function BlockReferenceScope({ children }) {
|
|
495
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
496
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
446
497
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
447
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
448
498
|
const value = {
|
|
499
|
+
numberFor(kind, content) {
|
|
500
|
+
const key = normalizeReferenceContent(content);
|
|
501
|
+
const fromDocument = numbering?.[kind].get(key);
|
|
502
|
+
if (fromDocument !== void 0) return fromDocument;
|
|
503
|
+
const map = local.current[kind];
|
|
504
|
+
const existing = map.get(key);
|
|
505
|
+
if (existing !== void 0) return existing;
|
|
506
|
+
counter.current[kind] += 1;
|
|
507
|
+
map.set(key, counter.current[kind]);
|
|
508
|
+
return counter.current[kind];
|
|
509
|
+
},
|
|
449
510
|
next(kind) {
|
|
450
511
|
counter.current[kind] += 1;
|
|
451
|
-
return
|
|
512
|
+
return counter.current[kind];
|
|
452
513
|
}
|
|
453
514
|
};
|
|
454
515
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -456,7 +517,7 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
456
517
|
function useBlockReferenceScope() {
|
|
457
518
|
return useContext(BlockReferenceScopeContext);
|
|
458
519
|
}
|
|
459
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
520
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
460
521
|
function InertReferenceScope({ children }) {
|
|
461
522
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
462
523
|
}
|
|
@@ -747,7 +808,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
747
808
|
);
|
|
748
809
|
}
|
|
749
810
|
case "inline_ref": {
|
|
750
|
-
const number = refScope?.
|
|
811
|
+
const number = refScope?.numberFor(token.kind, token.content) ?? 0;
|
|
751
812
|
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 });
|
|
752
813
|
}
|
|
753
814
|
default:
|
|
@@ -813,8 +874,32 @@ function renderReadingText(content, opts) {
|
|
|
813
874
|
if (cursor < content.length) pieces.push(content.slice(cursor));
|
|
814
875
|
return /* @__PURE__ */ jsx(Fragment, { children: pieces });
|
|
815
876
|
}
|
|
877
|
+
function quoteBlocks(block) {
|
|
878
|
+
try {
|
|
879
|
+
const doc = parseNcm(block.content, {
|
|
880
|
+
preset: "ncm-full",
|
|
881
|
+
allowMissingFrontmatter: true,
|
|
882
|
+
// Attribution off, as the NUU Editor's bridge keeps it: the promoter's
|
|
883
|
+
// trigger is any last quote line starting with `-`, so a nested quote
|
|
884
|
+
// ending in a list item would lose that item to a `— Author` line.
|
|
885
|
+
blockOptions: { extensions: { attribution: false } }
|
|
886
|
+
});
|
|
887
|
+
const blocks = doc.blocks ?? [];
|
|
888
|
+
if (blocks.length === 0 || blocks.some((child) => child.type === "frontmatter")) {
|
|
889
|
+
return null;
|
|
890
|
+
}
|
|
891
|
+
return blocks.map((child, index) => ({ ...child, id: `${block.id}.${index + 1}`, stableId: void 0 }));
|
|
892
|
+
} catch {
|
|
893
|
+
return null;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
function QuotedLines({ content }) {
|
|
897
|
+
const lines = content.split("\n");
|
|
898
|
+
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)) });
|
|
899
|
+
}
|
|
816
900
|
function BlockquoteBlock({ block, className }) {
|
|
817
|
-
const
|
|
901
|
+
const multiline = block.content.includes("\n");
|
|
902
|
+
const blocks = useMemo(() => multiline ? quoteBlocks(block) : null, [block, multiline]);
|
|
818
903
|
return /* @__PURE__ */ jsx(
|
|
819
904
|
"blockquote",
|
|
820
905
|
{
|
|
@@ -824,7 +909,9 @@ function BlockquoteBlock({ block, className }) {
|
|
|
824
909
|
"data-block-id": block.id,
|
|
825
910
|
"data-ncm-blockquote": "",
|
|
826
911
|
className,
|
|
827
|
-
children:
|
|
912
|
+
children: !multiline ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : blocks === null ? /* @__PURE__ */ jsx(QuotedLines, { content: block.content }) : blocks.map(
|
|
913
|
+
(child) => child.type === "paragraph" ? /* @__PURE__ */ jsx(QuotedLines, { content: child.content ?? "" }, blockKey(child)) : /* @__PURE__ */ jsx(NcmBlock, { block: child }, blockKey(child))
|
|
914
|
+
)
|
|
828
915
|
}
|
|
829
916
|
);
|
|
830
917
|
}
|
package/dist/context/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { C as CodeConfig, E as EmbeddingsConfig, I as ImageErrorProps, a as InlineConfig, N as NcmConfig, b as NcmProvider, c as NcmProviderProps, u as useNcmConfig } from '../use-ncm-config-CnntcShj.js';
|
|
2
|
-
export { B as BlockReferenceScope, a as BlockReferenceScopeProps, b as BlockReferenceScopeValue, I as InertReferenceScope, N as NcmReferencesProvider, c as NcmReferencesProviderProps, R as ReferenceCounts, d as ReferenceKind, e as computeReferenceBases, u as useBlockReferenceScope } from '../references-
|
|
2
|
+
export { B as BlockReferenceScope, a as BlockReferenceScopeProps, b as BlockReferenceScopeValue, I as InertReferenceScope, N as NcmReferencesProvider, c as NcmReferencesProviderProps, R as ReferenceCounts, d as ReferenceKind, e as ReferenceNumbering, f as collectBibliography, g as computeReferenceBases, h as computeReferenceNumbering, n as normalizeReferenceContent, u as useBlockReferenceScope } from '../references-BM-lvGrq.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '@nuucognition/mesh-core';
|
|
5
5
|
import '@nuucognition/ncm';
|
package/dist/context/index.js
CHANGED
|
@@ -53,6 +53,52 @@ function tryParseInlineRef(input) {
|
|
|
53
53
|
}
|
|
54
54
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
55
55
|
}
|
|
56
|
+
function runLength(input, index, char) {
|
|
57
|
+
let end = index;
|
|
58
|
+
while (end < input.length && input[end] === char) end++;
|
|
59
|
+
return end - index;
|
|
60
|
+
}
|
|
61
|
+
function tryParseEmphasis(input) {
|
|
62
|
+
const char = input[0];
|
|
63
|
+
if (char !== "*" && char !== "_") return null;
|
|
64
|
+
const open = Math.min(3, runLength(input, 0, char));
|
|
65
|
+
const need = open;
|
|
66
|
+
let i = open;
|
|
67
|
+
while (i < input.length) {
|
|
68
|
+
const ch = input[i];
|
|
69
|
+
if (ch === "`") {
|
|
70
|
+
const close = input.indexOf("`", i + 1);
|
|
71
|
+
if (close === -1) break;
|
|
72
|
+
i = close + 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (ch !== char) {
|
|
76
|
+
i++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const run = runLength(input, i, char);
|
|
80
|
+
const closes = need === 1 ? run % 2 === 1 : run >= need;
|
|
81
|
+
if (!closes) {
|
|
82
|
+
i += run;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const extra = run - need;
|
|
86
|
+
const inner = input.slice(open, i + extra);
|
|
87
|
+
if (inner.length === 0) return null;
|
|
88
|
+
const length = i + run;
|
|
89
|
+
const children = parseInline(inner);
|
|
90
|
+
let token;
|
|
91
|
+
if (need === 3) {
|
|
92
|
+
token = { type: "bold", children: [{ type: "italic", children }] };
|
|
93
|
+
} else if (need === 2) {
|
|
94
|
+
token = { type: "bold", children };
|
|
95
|
+
} else {
|
|
96
|
+
token = { type: "italic", children };
|
|
97
|
+
}
|
|
98
|
+
return { token, length };
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
56
102
|
function parseInline(content) {
|
|
57
103
|
if (!content) return [];
|
|
58
104
|
const tokens = [];
|
|
@@ -124,17 +170,11 @@ function parseInline(content) {
|
|
|
124
170
|
remaining = remaining.slice(linkMatch[0].length);
|
|
125
171
|
continue;
|
|
126
172
|
}
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
type: "bold",
|
|
133
|
-
children: parseInline(innerContent)
|
|
134
|
-
});
|
|
135
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
173
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
174
|
+
if (emphasis) {
|
|
175
|
+
tokens.push(emphasis.token);
|
|
176
|
+
remaining = remaining.slice(emphasis.length);
|
|
177
|
+
continue;
|
|
138
178
|
}
|
|
139
179
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
140
180
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -145,18 +185,6 @@ function parseInline(content) {
|
|
|
145
185
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
146
186
|
continue;
|
|
147
187
|
}
|
|
148
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
149
|
-
if (italicMatch) {
|
|
150
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
151
|
-
if (innerContent !== void 0) {
|
|
152
|
-
tokens.push({
|
|
153
|
-
type: "italic",
|
|
154
|
-
children: parseInline(innerContent)
|
|
155
|
-
});
|
|
156
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
188
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
161
189
|
if (nextSpecial > 0) {
|
|
162
190
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -227,48 +255,95 @@ function collectListStrings(items) {
|
|
|
227
255
|
}
|
|
228
256
|
return out;
|
|
229
257
|
}
|
|
230
|
-
function
|
|
258
|
+
function normalizeReferenceContent(content) {
|
|
259
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
260
|
+
}
|
|
261
|
+
var BIBLIOGRAPHY_ENTRY_RE = /^\s*\[(\d+)\]\s+([\s\S]+?)\s*$/;
|
|
262
|
+
function collectBibliography(blocks) {
|
|
263
|
+
const entries = /* @__PURE__ */ new Map();
|
|
264
|
+
for (const block of blocks) {
|
|
265
|
+
if (block.type !== "paragraph") continue;
|
|
266
|
+
const content = block.content ?? "";
|
|
267
|
+
const match = BIBLIOGRAPHY_ENTRY_RE.exec(content);
|
|
268
|
+
if (!match || !match[1] || !match[2]) continue;
|
|
269
|
+
const key = normalizeReferenceContent(match[2]);
|
|
270
|
+
if (key && !entries.has(key)) entries.set(key, Number(match[1]));
|
|
271
|
+
}
|
|
272
|
+
return entries;
|
|
273
|
+
}
|
|
274
|
+
function walkInlineRefs(tokens, visit) {
|
|
231
275
|
for (const token of tokens) {
|
|
232
276
|
if (token.type === "inline_ref") {
|
|
233
|
-
|
|
277
|
+
visit(token);
|
|
234
278
|
} else if ("children" in token) {
|
|
235
|
-
|
|
279
|
+
walkInlineRefs(token.children, visit);
|
|
236
280
|
}
|
|
237
281
|
}
|
|
238
282
|
}
|
|
239
|
-
function
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
283
|
+
function computeReferenceNumbering(blocks) {
|
|
284
|
+
const bibliography = collectBibliography(blocks);
|
|
285
|
+
let maxBibliography = 0;
|
|
286
|
+
for (const n of bibliography.values()) maxBibliography = Math.max(maxBibliography, n);
|
|
287
|
+
const numbering = { ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() };
|
|
288
|
+
let nextRef = maxBibliography;
|
|
289
|
+
let nextFootnote = 0;
|
|
290
|
+
for (const block of blocks) {
|
|
291
|
+
for (const str of collectInlineStrings(block)) {
|
|
292
|
+
if (!str) continue;
|
|
293
|
+
walkInlineRefs(parseInline(str), (token) => {
|
|
294
|
+
const key = normalizeReferenceContent(token.content);
|
|
295
|
+
const map = numbering[token.kind];
|
|
296
|
+
if (map.has(key)) return;
|
|
297
|
+
if (token.kind === "ref") {
|
|
298
|
+
const fromBibliography = bibliography.get(key);
|
|
299
|
+
map.set(key, fromBibliography ?? ++nextRef);
|
|
300
|
+
} else {
|
|
301
|
+
map.set(key, ++nextFootnote);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
243
305
|
}
|
|
244
|
-
return
|
|
306
|
+
return numbering;
|
|
245
307
|
}
|
|
246
308
|
function computeReferenceBases(blocks) {
|
|
247
309
|
const bases = /* @__PURE__ */ new Map();
|
|
248
310
|
const acc = { ref: 0, footnote: 0 };
|
|
249
311
|
for (const block of blocks) {
|
|
250
312
|
bases.set(block.id, { ...acc });
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
313
|
+
for (const str of collectInlineStrings(block)) {
|
|
314
|
+
if (!str) continue;
|
|
315
|
+
walkInlineRefs(parseInline(str), (token) => {
|
|
316
|
+
acc[token.kind] += 1;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
254
319
|
}
|
|
255
320
|
return bases;
|
|
256
321
|
}
|
|
257
|
-
var
|
|
322
|
+
var ReferenceNumberingContext = createContext(null);
|
|
258
323
|
var BlockReferenceScopeContext = createContext(null);
|
|
259
324
|
function NcmReferencesProvider({ blocks, children }) {
|
|
260
|
-
const
|
|
261
|
-
return /* @__PURE__ */ jsx(
|
|
325
|
+
const numbering = useMemo(() => computeReferenceNumbering(blocks), [blocks]);
|
|
326
|
+
return /* @__PURE__ */ jsx(ReferenceNumberingContext.Provider, { value: numbering, children });
|
|
262
327
|
}
|
|
263
|
-
function BlockReferenceScope({
|
|
264
|
-
const
|
|
265
|
-
const
|
|
328
|
+
function BlockReferenceScope({ children }) {
|
|
329
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
330
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
266
331
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
267
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
268
332
|
const value = {
|
|
333
|
+
numberFor(kind, content) {
|
|
334
|
+
const key = normalizeReferenceContent(content);
|
|
335
|
+
const fromDocument = numbering?.[kind].get(key);
|
|
336
|
+
if (fromDocument !== void 0) return fromDocument;
|
|
337
|
+
const map = local.current[kind];
|
|
338
|
+
const existing = map.get(key);
|
|
339
|
+
if (existing !== void 0) return existing;
|
|
340
|
+
counter.current[kind] += 1;
|
|
341
|
+
map.set(key, counter.current[kind]);
|
|
342
|
+
return counter.current[kind];
|
|
343
|
+
},
|
|
269
344
|
next(kind) {
|
|
270
345
|
counter.current[kind] += 1;
|
|
271
|
-
return
|
|
346
|
+
return counter.current[kind];
|
|
272
347
|
}
|
|
273
348
|
};
|
|
274
349
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -276,9 +351,9 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
276
351
|
function useBlockReferenceScope() {
|
|
277
352
|
return useContext(BlockReferenceScopeContext);
|
|
278
353
|
}
|
|
279
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
354
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
280
355
|
function InertReferenceScope({ children }) {
|
|
281
356
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
282
357
|
}
|
|
283
358
|
|
|
284
|
-
export { BlockReferenceScope, InertReferenceScope, NcmProvider, NcmReferencesProvider, computeReferenceBases, useBlockReferenceScope, useNcmConfig };
|
|
359
|
+
export { BlockReferenceScope, InertReferenceScope, NcmProvider, NcmReferencesProvider, collectBibliography, computeReferenceBases, computeReferenceNumbering, normalizeReferenceContent, useBlockReferenceScope, useNcmConfig };
|