@nuucognition/ncm-ui 0.1.1-beta.1 → 0.1.1-beta.3
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 +160 -36
- package/dist/blocks/aside/index.js +160 -36
- package/dist/blocks/blockquote/index.d.ts +7 -5
- package/dist/blocks/blockquote/index.js +1275 -36
- package/dist/blocks/container/index.js +72 -31
- package/dist/blocks/definition/index.js +159 -35
- package/dist/blocks/embed/index.js +46 -1
- package/dist/blocks/embedding/index.js +72 -31
- package/dist/blocks/figure/index.d.ts +3 -1
- package/dist/blocks/figure/index.js +128 -33
- package/dist/blocks/footnote/index.js +160 -36
- package/dist/blocks/header/index.js +72 -31
- package/dist/blocks/index.js +160 -36
- package/dist/blocks/list/index.js +72 -31
- package/dist/blocks/paragraph/index.js +72 -31
- package/dist/blocks/spoiler/index.js +160 -36
- package/dist/blocks/table/index.js +72 -31
- package/dist/blocks/task-list/index.js +72 -31
- package/dist/components/index.js +199 -55
- package/dist/components/ncm-block.js +160 -36
- package/dist/components/ncm-document.js +199 -55
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +119 -44
- package/dist/hooks/index.js +160 -36
- package/dist/hooks/use-block-renderer.js +160 -36
- package/dist/index.d.ts +1 -1
- package/dist/index.js +206 -48
- package/dist/inline/index.d.ts +2 -3
- package/dist/inline/index.js +72 -31
- package/dist/lib/defaults.js +160 -36
- package/dist/references-BM-lvGrq.d.ts +99 -0
- package/package.json +1 -1
- package/dist/references-BYW5pnj_.d.ts +0 -63
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, createElement, useContext, useRef, Component, useState, useEffect,
|
|
2
|
+
import { createContext, createElement, useContext, useMemo, useRef, Component, useState, useEffect, useCallback, useId } from 'react';
|
|
3
3
|
import { clsx } from 'clsx';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
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
|
// src/components/block-shell.tsx
|
|
10
10
|
function cn(...inputs) {
|
|
@@ -121,6 +121,52 @@ function tryParseInlineRef(input) {
|
|
|
121
121
|
}
|
|
122
122
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
123
123
|
}
|
|
124
|
+
function runLength(input, index, char) {
|
|
125
|
+
let end = index;
|
|
126
|
+
while (end < input.length && input[end] === char) end++;
|
|
127
|
+
return end - index;
|
|
128
|
+
}
|
|
129
|
+
function tryParseEmphasis(input) {
|
|
130
|
+
const char = input[0];
|
|
131
|
+
if (char !== "*" && char !== "_") return null;
|
|
132
|
+
const open = Math.min(3, runLength(input, 0, char));
|
|
133
|
+
const need = open;
|
|
134
|
+
let i = open;
|
|
135
|
+
while (i < input.length) {
|
|
136
|
+
const ch = input[i];
|
|
137
|
+
if (ch === "`") {
|
|
138
|
+
const close = input.indexOf("`", i + 1);
|
|
139
|
+
if (close === -1) break;
|
|
140
|
+
i = close + 1;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (ch !== char) {
|
|
144
|
+
i++;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const run = runLength(input, i, char);
|
|
148
|
+
const closes = need === 1 ? run % 2 === 1 : run >= need;
|
|
149
|
+
if (!closes) {
|
|
150
|
+
i += run;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const extra = run - need;
|
|
154
|
+
const inner = input.slice(open, i + extra);
|
|
155
|
+
if (inner.length === 0) return null;
|
|
156
|
+
const length = i + run;
|
|
157
|
+
const children = parseInline(inner);
|
|
158
|
+
let token;
|
|
159
|
+
if (need === 3) {
|
|
160
|
+
token = { type: "bold", children: [{ type: "italic", children }] };
|
|
161
|
+
} else if (need === 2) {
|
|
162
|
+
token = { type: "bold", children };
|
|
163
|
+
} else {
|
|
164
|
+
token = { type: "italic", children };
|
|
165
|
+
}
|
|
166
|
+
return { token, length };
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
124
170
|
function parseInline(content) {
|
|
125
171
|
if (!content) return [];
|
|
126
172
|
const tokens = [];
|
|
@@ -192,17 +238,11 @@ function parseInline(content) {
|
|
|
192
238
|
remaining = remaining.slice(linkMatch[0].length);
|
|
193
239
|
continue;
|
|
194
240
|
}
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
type: "bold",
|
|
201
|
-
children: parseInline(innerContent)
|
|
202
|
-
});
|
|
203
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
241
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
242
|
+
if (emphasis) {
|
|
243
|
+
tokens.push(emphasis.token);
|
|
244
|
+
remaining = remaining.slice(emphasis.length);
|
|
245
|
+
continue;
|
|
206
246
|
}
|
|
207
247
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
208
248
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -213,18 +253,6 @@ function parseInline(content) {
|
|
|
213
253
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
214
254
|
continue;
|
|
215
255
|
}
|
|
216
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
217
|
-
if (italicMatch) {
|
|
218
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
219
|
-
if (innerContent !== void 0) {
|
|
220
|
-
tokens.push({
|
|
221
|
-
type: "italic",
|
|
222
|
-
children: parseInline(innerContent)
|
|
223
|
-
});
|
|
224
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
256
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
229
257
|
if (nextSpecial > 0) {
|
|
230
258
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -335,17 +363,30 @@ function ReferenceMarker({ kind, number, children }) {
|
|
|
335
363
|
}
|
|
336
364
|
);
|
|
337
365
|
}
|
|
338
|
-
|
|
366
|
+
function normalizeReferenceContent(content) {
|
|
367
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
368
|
+
}
|
|
369
|
+
var ReferenceNumberingContext = createContext(null);
|
|
339
370
|
var BlockReferenceScopeContext = createContext(null);
|
|
340
|
-
function BlockReferenceScope({
|
|
341
|
-
const
|
|
342
|
-
const
|
|
371
|
+
function BlockReferenceScope({ children }) {
|
|
372
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
373
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
343
374
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
344
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
345
375
|
const value = {
|
|
376
|
+
numberFor(kind, content) {
|
|
377
|
+
const key = normalizeReferenceContent(content);
|
|
378
|
+
const fromDocument = numbering?.[kind].get(key);
|
|
379
|
+
if (fromDocument !== void 0) return fromDocument;
|
|
380
|
+
const map = local.current[kind];
|
|
381
|
+
const existing = map.get(key);
|
|
382
|
+
if (existing !== void 0) return existing;
|
|
383
|
+
counter.current[kind] += 1;
|
|
384
|
+
map.set(key, counter.current[kind]);
|
|
385
|
+
return counter.current[kind];
|
|
386
|
+
},
|
|
346
387
|
next(kind) {
|
|
347
388
|
counter.current[kind] += 1;
|
|
348
|
-
return
|
|
389
|
+
return counter.current[kind];
|
|
349
390
|
}
|
|
350
391
|
};
|
|
351
392
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -353,7 +394,7 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
353
394
|
function useBlockReferenceScope() {
|
|
354
395
|
return useContext(BlockReferenceScopeContext);
|
|
355
396
|
}
|
|
356
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
397
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
357
398
|
function InertReferenceScope({ children }) {
|
|
358
399
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
359
400
|
}
|
|
@@ -644,7 +685,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
644
685
|
);
|
|
645
686
|
}
|
|
646
687
|
case "inline_ref": {
|
|
647
|
-
const number = refScope?.
|
|
688
|
+
const number = refScope?.numberFor(token.kind, token.content) ?? 0;
|
|
648
689
|
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 });
|
|
649
690
|
}
|
|
650
691
|
default:
|
|
@@ -710,8 +751,32 @@ function renderReadingText(content, opts) {
|
|
|
710
751
|
if (cursor < content.length) pieces.push(content.slice(cursor));
|
|
711
752
|
return /* @__PURE__ */ jsx(Fragment, { children: pieces });
|
|
712
753
|
}
|
|
754
|
+
function quoteBlocks(block) {
|
|
755
|
+
try {
|
|
756
|
+
const doc = parseNcm(block.content, {
|
|
757
|
+
preset: "ncm-full",
|
|
758
|
+
allowMissingFrontmatter: true,
|
|
759
|
+
// Attribution off, as the NUU Editor's bridge keeps it: the promoter's
|
|
760
|
+
// trigger is any last quote line starting with `-`, so a nested quote
|
|
761
|
+
// ending in a list item would lose that item to a `— Author` line.
|
|
762
|
+
blockOptions: { extensions: { attribution: false } }
|
|
763
|
+
});
|
|
764
|
+
const blocks = doc.blocks ?? [];
|
|
765
|
+
if (blocks.length === 0 || blocks.some((child) => child.type === "frontmatter")) {
|
|
766
|
+
return null;
|
|
767
|
+
}
|
|
768
|
+
return blocks.map((child, index) => ({ ...child, id: `${block.id}.${index + 1}`, stableId: void 0 }));
|
|
769
|
+
} catch {
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
function QuotedLines({ content }) {
|
|
774
|
+
const lines = content.split("\n");
|
|
775
|
+
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)) });
|
|
776
|
+
}
|
|
713
777
|
function BlockquoteBlock({ block, className }) {
|
|
714
|
-
const
|
|
778
|
+
const multiline = block.content.includes("\n");
|
|
779
|
+
const blocks = useMemo(() => multiline ? quoteBlocks(block) : null, [block, multiline]);
|
|
715
780
|
return /* @__PURE__ */ jsx(
|
|
716
781
|
"blockquote",
|
|
717
782
|
{
|
|
@@ -721,7 +786,9 @@ function BlockquoteBlock({ block, className }) {
|
|
|
721
786
|
"data-block-id": block.id,
|
|
722
787
|
"data-ncm-blockquote": "",
|
|
723
788
|
className,
|
|
724
|
-
children:
|
|
789
|
+
children: !multiline ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : blocks === null ? /* @__PURE__ */ jsx(QuotedLines, { content: block.content }) : blocks.map(
|
|
790
|
+
(child) => child.type === "paragraph" ? /* @__PURE__ */ jsx(QuotedLines, { content: child.content ?? "" }, blockKey(child)) : /* @__PURE__ */ jsx(NcmBlock, { block: child }, blockKey(child))
|
|
791
|
+
)
|
|
725
792
|
}
|
|
726
793
|
);
|
|
727
794
|
}
|
|
@@ -940,6 +1007,48 @@ function DefinitionBlock({ block, className }) {
|
|
|
940
1007
|
}
|
|
941
1008
|
);
|
|
942
1009
|
}
|
|
1010
|
+
function fileNameOf(src) {
|
|
1011
|
+
let path = src.split(/[?#]/)[0] ?? "";
|
|
1012
|
+
if (/^https?:\/\//i.test(src)) {
|
|
1013
|
+
try {
|
|
1014
|
+
path = new URL(src).pathname;
|
|
1015
|
+
} catch {
|
|
1016
|
+
return "";
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return path.slice(path.lastIndexOf("/") + 1);
|
|
1020
|
+
}
|
|
1021
|
+
function isExtensionless(src) {
|
|
1022
|
+
const name = fileNameOf(src);
|
|
1023
|
+
const dot = name.lastIndexOf(".");
|
|
1024
|
+
return dot <= 0 || dot === name.length - 1;
|
|
1025
|
+
}
|
|
1026
|
+
function EmbedPictureOrLink({
|
|
1027
|
+
src,
|
|
1028
|
+
alt,
|
|
1029
|
+
title,
|
|
1030
|
+
imgClassName,
|
|
1031
|
+
linkAttrs
|
|
1032
|
+
}) {
|
|
1033
|
+
const [failedSrc, setFailedSrc] = useState(null);
|
|
1034
|
+
useEffect(() => {
|
|
1035
|
+
setFailedSrc(null);
|
|
1036
|
+
}, [src]);
|
|
1037
|
+
if (failedSrc === src) {
|
|
1038
|
+
return /* @__PURE__ */ jsx("a", { href: src, title, ...linkAttrs, children: alt || src });
|
|
1039
|
+
}
|
|
1040
|
+
return /* @__PURE__ */ jsx(
|
|
1041
|
+
"img",
|
|
1042
|
+
{
|
|
1043
|
+
"data-ncm-embed-picture": "",
|
|
1044
|
+
src,
|
|
1045
|
+
alt,
|
|
1046
|
+
title,
|
|
1047
|
+
className: imgClassName,
|
|
1048
|
+
onError: () => setFailedSrc(src)
|
|
1049
|
+
}
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
943
1052
|
function toEmbeddingConfigType(embedType) {
|
|
944
1053
|
switch (embedType) {
|
|
945
1054
|
case "image":
|
|
@@ -968,6 +1077,9 @@ function EmbedBlock({ block, className }) {
|
|
|
968
1077
|
if (block.embedType === "image") {
|
|
969
1078
|
return /* @__PURE__ */ jsx("figure", { ...dataAttrs(block), className: cn(config.embeddings?.imageClassName, className), children: /* @__PURE__ */ jsx("img", { src: resolvedUrl, alt: block.alt, title: block.title ?? void 0 }) });
|
|
970
1079
|
}
|
|
1080
|
+
if (block.embedType === "file" && isExtensionless(block.src)) {
|
|
1081
|
+
return /* @__PURE__ */ jsx("figure", { ...dataAttrs(block), className: cn(config.embeddings?.imageClassName, className), children: /* @__PURE__ */ jsx(EmbedPictureOrLink, { src: resolvedUrl, alt: block.alt, title: block.title ?? void 0 }) });
|
|
1082
|
+
}
|
|
971
1083
|
return /* @__PURE__ */ jsx("figure", { ...dataAttrs(block), className, children: /* @__PURE__ */ jsx("a", { href: resolvedUrl, title: block.title ?? void 0, children: block.alt || block.src }) });
|
|
972
1084
|
}
|
|
973
1085
|
var embedFrameStyle = {
|
|
@@ -1144,7 +1256,19 @@ function FigureBlock({ block, className }) {
|
|
|
1144
1256
|
"data-ncm-figure": "",
|
|
1145
1257
|
className: cn("space-y-2", className),
|
|
1146
1258
|
children: [
|
|
1147
|
-
embed.embedType === "image" ? /* @__PURE__ */ jsx("img", { src: embed.src, alt: embed.alt, title: embed.title ?? void 0 }) :
|
|
1259
|
+
embed.embedType === "image" ? /* @__PURE__ */ jsx("img", { src: embed.src, alt: embed.alt, title: embed.title ?? void 0 }) : embed.embedType === "file" && isExtensionless(embed.src) ? (
|
|
1260
|
+
// Same rule as the standalone embed block: an image spelling with an
|
|
1261
|
+
// extension-less destination is a picture until it fails to load.
|
|
1262
|
+
/* @__PURE__ */ jsx(
|
|
1263
|
+
EmbedPictureOrLink,
|
|
1264
|
+
{
|
|
1265
|
+
src: embed.src,
|
|
1266
|
+
alt: embed.alt,
|
|
1267
|
+
title: embed.title ?? void 0,
|
|
1268
|
+
linkAttrs: { "data-ncm-embed-type": embed.embedType }
|
|
1269
|
+
}
|
|
1270
|
+
)
|
|
1271
|
+
) : /* @__PURE__ */ jsx(
|
|
1148
1272
|
"a",
|
|
1149
1273
|
{
|
|
1150
1274
|
href: embed.src,
|
|
@@ -48,6 +48,52 @@ function tryParseInlineRef(input) {
|
|
|
48
48
|
}
|
|
49
49
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
50
50
|
}
|
|
51
|
+
function runLength(input, index, char) {
|
|
52
|
+
let end = index;
|
|
53
|
+
while (end < input.length && input[end] === char) end++;
|
|
54
|
+
return end - index;
|
|
55
|
+
}
|
|
56
|
+
function tryParseEmphasis(input) {
|
|
57
|
+
const char = input[0];
|
|
58
|
+
if (char !== "*" && char !== "_") return null;
|
|
59
|
+
const open = Math.min(3, runLength(input, 0, char));
|
|
60
|
+
const need = open;
|
|
61
|
+
let i = open;
|
|
62
|
+
while (i < input.length) {
|
|
63
|
+
const ch = input[i];
|
|
64
|
+
if (ch === "`") {
|
|
65
|
+
const close = input.indexOf("`", i + 1);
|
|
66
|
+
if (close === -1) break;
|
|
67
|
+
i = close + 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (ch !== char) {
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const run = runLength(input, i, char);
|
|
75
|
+
const closes = need === 1 ? run % 2 === 1 : run >= need;
|
|
76
|
+
if (!closes) {
|
|
77
|
+
i += run;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const extra = run - need;
|
|
81
|
+
const inner = input.slice(open, i + extra);
|
|
82
|
+
if (inner.length === 0) return null;
|
|
83
|
+
const length = i + run;
|
|
84
|
+
const children = parseInline(inner);
|
|
85
|
+
let token;
|
|
86
|
+
if (need === 3) {
|
|
87
|
+
token = { type: "bold", children: [{ type: "italic", children }] };
|
|
88
|
+
} else if (need === 2) {
|
|
89
|
+
token = { type: "bold", children };
|
|
90
|
+
} else {
|
|
91
|
+
token = { type: "italic", children };
|
|
92
|
+
}
|
|
93
|
+
return { token, length };
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
51
97
|
function parseInline(content) {
|
|
52
98
|
if (!content) return [];
|
|
53
99
|
const tokens = [];
|
|
@@ -119,17 +165,11 @@ function parseInline(content) {
|
|
|
119
165
|
remaining = remaining.slice(linkMatch[0].length);
|
|
120
166
|
continue;
|
|
121
167
|
}
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
type: "bold",
|
|
128
|
-
children: parseInline(innerContent)
|
|
129
|
-
});
|
|
130
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
168
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
169
|
+
if (emphasis) {
|
|
170
|
+
tokens.push(emphasis.token);
|
|
171
|
+
remaining = remaining.slice(emphasis.length);
|
|
172
|
+
continue;
|
|
133
173
|
}
|
|
134
174
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
135
175
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -140,18 +180,6 @@ function parseInline(content) {
|
|
|
140
180
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
141
181
|
continue;
|
|
142
182
|
}
|
|
143
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
144
|
-
if (italicMatch) {
|
|
145
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
146
|
-
if (innerContent !== void 0) {
|
|
147
|
-
tokens.push({
|
|
148
|
-
type: "italic",
|
|
149
|
-
children: parseInline(innerContent)
|
|
150
|
-
});
|
|
151
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
183
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
156
184
|
if (nextSpecial > 0) {
|
|
157
185
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -262,17 +290,30 @@ function ReferenceMarker({ kind, number, children }) {
|
|
|
262
290
|
}
|
|
263
291
|
);
|
|
264
292
|
}
|
|
265
|
-
|
|
293
|
+
function normalizeReferenceContent(content) {
|
|
294
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
295
|
+
}
|
|
296
|
+
var ReferenceNumberingContext = createContext(null);
|
|
266
297
|
var BlockReferenceScopeContext = createContext(null);
|
|
267
|
-
function BlockReferenceScope({
|
|
268
|
-
const
|
|
269
|
-
const
|
|
298
|
+
function BlockReferenceScope({ children }) {
|
|
299
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
300
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
270
301
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
271
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
272
302
|
const value = {
|
|
303
|
+
numberFor(kind, content) {
|
|
304
|
+
const key = normalizeReferenceContent(content);
|
|
305
|
+
const fromDocument = numbering?.[kind].get(key);
|
|
306
|
+
if (fromDocument !== void 0) return fromDocument;
|
|
307
|
+
const map = local.current[kind];
|
|
308
|
+
const existing = map.get(key);
|
|
309
|
+
if (existing !== void 0) return existing;
|
|
310
|
+
counter.current[kind] += 1;
|
|
311
|
+
map.set(key, counter.current[kind]);
|
|
312
|
+
return counter.current[kind];
|
|
313
|
+
},
|
|
273
314
|
next(kind) {
|
|
274
315
|
counter.current[kind] += 1;
|
|
275
|
-
return
|
|
316
|
+
return counter.current[kind];
|
|
276
317
|
}
|
|
277
318
|
};
|
|
278
319
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -280,7 +321,7 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
280
321
|
function useBlockReferenceScope() {
|
|
281
322
|
return useContext(BlockReferenceScopeContext);
|
|
282
323
|
}
|
|
283
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
324
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
284
325
|
function InertReferenceScope({ children }) {
|
|
285
326
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
286
327
|
}
|
|
@@ -571,7 +612,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
571
612
|
);
|
|
572
613
|
}
|
|
573
614
|
case "inline_ref": {
|
|
574
|
-
const number = refScope?.
|
|
615
|
+
const number = refScope?.numberFor(token.kind, token.content) ?? 0;
|
|
575
616
|
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 });
|
|
576
617
|
}
|
|
577
618
|
default:
|
|
@@ -51,6 +51,52 @@ function tryParseInlineRef(input) {
|
|
|
51
51
|
}
|
|
52
52
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
53
53
|
}
|
|
54
|
+
function runLength(input, index, char) {
|
|
55
|
+
let end = index;
|
|
56
|
+
while (end < input.length && input[end] === char) end++;
|
|
57
|
+
return end - index;
|
|
58
|
+
}
|
|
59
|
+
function tryParseEmphasis(input) {
|
|
60
|
+
const char = input[0];
|
|
61
|
+
if (char !== "*" && char !== "_") return null;
|
|
62
|
+
const open = Math.min(3, runLength(input, 0, char));
|
|
63
|
+
const need = open;
|
|
64
|
+
let i = open;
|
|
65
|
+
while (i < input.length) {
|
|
66
|
+
const ch = input[i];
|
|
67
|
+
if (ch === "`") {
|
|
68
|
+
const close = input.indexOf("`", i + 1);
|
|
69
|
+
if (close === -1) break;
|
|
70
|
+
i = close + 1;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (ch !== char) {
|
|
74
|
+
i++;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const run = runLength(input, i, char);
|
|
78
|
+
const closes = need === 1 ? run % 2 === 1 : run >= need;
|
|
79
|
+
if (!closes) {
|
|
80
|
+
i += run;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const extra = run - need;
|
|
84
|
+
const inner = input.slice(open, i + extra);
|
|
85
|
+
if (inner.length === 0) return null;
|
|
86
|
+
const length = i + run;
|
|
87
|
+
const children = parseInline(inner);
|
|
88
|
+
let token;
|
|
89
|
+
if (need === 3) {
|
|
90
|
+
token = { type: "bold", children: [{ type: "italic", children }] };
|
|
91
|
+
} else if (need === 2) {
|
|
92
|
+
token = { type: "bold", children };
|
|
93
|
+
} else {
|
|
94
|
+
token = { type: "italic", children };
|
|
95
|
+
}
|
|
96
|
+
return { token, length };
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
54
100
|
function parseInline(content) {
|
|
55
101
|
if (!content) return [];
|
|
56
102
|
const tokens = [];
|
|
@@ -122,17 +168,11 @@ function parseInline(content) {
|
|
|
122
168
|
remaining = remaining.slice(linkMatch[0].length);
|
|
123
169
|
continue;
|
|
124
170
|
}
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
type: "bold",
|
|
131
|
-
children: parseInline(innerContent)
|
|
132
|
-
});
|
|
133
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
171
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
172
|
+
if (emphasis) {
|
|
173
|
+
tokens.push(emphasis.token);
|
|
174
|
+
remaining = remaining.slice(emphasis.length);
|
|
175
|
+
continue;
|
|
136
176
|
}
|
|
137
177
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
138
178
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -143,18 +183,6 @@ function parseInline(content) {
|
|
|
143
183
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
144
184
|
continue;
|
|
145
185
|
}
|
|
146
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
147
|
-
if (italicMatch) {
|
|
148
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
149
|
-
if (innerContent !== void 0) {
|
|
150
|
-
tokens.push({
|
|
151
|
-
type: "italic",
|
|
152
|
-
children: parseInline(innerContent)
|
|
153
|
-
});
|
|
154
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
186
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
159
187
|
if (nextSpecial > 0) {
|
|
160
188
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -265,17 +293,30 @@ function ReferenceMarker({ kind, number, children }) {
|
|
|
265
293
|
}
|
|
266
294
|
);
|
|
267
295
|
}
|
|
268
|
-
|
|
296
|
+
function normalizeReferenceContent(content) {
|
|
297
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
298
|
+
}
|
|
299
|
+
var ReferenceNumberingContext = createContext(null);
|
|
269
300
|
var BlockReferenceScopeContext = createContext(null);
|
|
270
|
-
function BlockReferenceScope({
|
|
271
|
-
const
|
|
272
|
-
const
|
|
301
|
+
function BlockReferenceScope({ children }) {
|
|
302
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
303
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
273
304
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
274
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
275
305
|
const value = {
|
|
306
|
+
numberFor(kind, content) {
|
|
307
|
+
const key = normalizeReferenceContent(content);
|
|
308
|
+
const fromDocument = numbering?.[kind].get(key);
|
|
309
|
+
if (fromDocument !== void 0) return fromDocument;
|
|
310
|
+
const map = local.current[kind];
|
|
311
|
+
const existing = map.get(key);
|
|
312
|
+
if (existing !== void 0) return existing;
|
|
313
|
+
counter.current[kind] += 1;
|
|
314
|
+
map.set(key, counter.current[kind]);
|
|
315
|
+
return counter.current[kind];
|
|
316
|
+
},
|
|
276
317
|
next(kind) {
|
|
277
318
|
counter.current[kind] += 1;
|
|
278
|
-
return
|
|
319
|
+
return counter.current[kind];
|
|
279
320
|
}
|
|
280
321
|
};
|
|
281
322
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -283,7 +324,7 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
283
324
|
function useBlockReferenceScope() {
|
|
284
325
|
return useContext(BlockReferenceScopeContext);
|
|
285
326
|
}
|
|
286
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
327
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
287
328
|
function InertReferenceScope({ children }) {
|
|
288
329
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
289
330
|
}
|
|
@@ -574,7 +615,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
574
615
|
);
|
|
575
616
|
}
|
|
576
617
|
case "inline_ref": {
|
|
577
|
-
const number = refScope?.
|
|
618
|
+
const number = refScope?.numberFor(token.kind, token.content) ?? 0;
|
|
578
619
|
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 });
|
|
579
620
|
}
|
|
580
621
|
default:
|