@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
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, useMemo, useContext, useRef, useState, useEffect, useId, useCallback } from 'react';
|
|
2
|
+
import { createContext, useMemo, useContext, useRef, createElement, Component, useState, useEffect, useId, useCallback } from 'react';
|
|
3
|
+
import { parseNcm, serializeInlineContent, isTypedNestedList } from '@nuucognition/ncm';
|
|
3
4
|
import { extractExtension, embedTypeFromExtension } from '@nuucognition/mesh-core';
|
|
4
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
|
-
import '
|
|
6
|
+
import { clsx } from 'clsx';
|
|
7
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
8
|
|
|
7
|
-
// src/
|
|
9
|
+
// src/blocks/blockquote/blockquote.tsx
|
|
8
10
|
|
|
9
11
|
// src/inline/parser.ts
|
|
10
12
|
function splitOnce(input, delimiter) {
|
|
@@ -46,6 +48,52 @@ function tryParseInlineRef(input) {
|
|
|
46
48
|
}
|
|
47
49
|
return { token: { type: "inline_ref", kind: "footnote", content: inner.trim() }, length };
|
|
48
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
|
+
}
|
|
49
97
|
function parseInline(content) {
|
|
50
98
|
if (!content) return [];
|
|
51
99
|
const tokens = [];
|
|
@@ -117,17 +165,11 @@ function parseInline(content) {
|
|
|
117
165
|
remaining = remaining.slice(linkMatch[0].length);
|
|
118
166
|
continue;
|
|
119
167
|
}
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
type: "bold",
|
|
126
|
-
children: parseInline(innerContent)
|
|
127
|
-
});
|
|
128
|
-
remaining = remaining.slice(boldMatch[0].length);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
168
|
+
const emphasis = tryParseEmphasis(remaining);
|
|
169
|
+
if (emphasis) {
|
|
170
|
+
tokens.push(emphasis.token);
|
|
171
|
+
remaining = remaining.slice(emphasis.length);
|
|
172
|
+
continue;
|
|
131
173
|
}
|
|
132
174
|
const strikeMatch = remaining.match(/^~~(.+?)~~/);
|
|
133
175
|
if (strikeMatch && strikeMatch[1] !== void 0) {
|
|
@@ -138,18 +180,6 @@ function parseInline(content) {
|
|
|
138
180
|
remaining = remaining.slice(strikeMatch[0].length);
|
|
139
181
|
continue;
|
|
140
182
|
}
|
|
141
|
-
const italicMatch = remaining.match(/^\*([^*]+)\*|^_([^_]+)_/);
|
|
142
|
-
if (italicMatch) {
|
|
143
|
-
const innerContent = italicMatch[1] ?? italicMatch[2];
|
|
144
|
-
if (innerContent !== void 0) {
|
|
145
|
-
tokens.push({
|
|
146
|
-
type: "italic",
|
|
147
|
-
children: parseInline(innerContent)
|
|
148
|
-
});
|
|
149
|
-
remaining = remaining.slice(italicMatch[0].length);
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
183
|
const nextSpecial = findNextSpecialChar(remaining);
|
|
154
184
|
if (nextSpecial > 0) {
|
|
155
185
|
tokens.push({ type: "text", content: remaining.slice(0, nextSpecial) });
|
|
@@ -260,17 +290,30 @@ function ReferenceMarker({ kind, number, children }) {
|
|
|
260
290
|
}
|
|
261
291
|
);
|
|
262
292
|
}
|
|
263
|
-
|
|
293
|
+
function normalizeReferenceContent(content) {
|
|
294
|
+
return content.replace(/\s+/g, " ").trim().toLowerCase();
|
|
295
|
+
}
|
|
296
|
+
var ReferenceNumberingContext = createContext(null);
|
|
264
297
|
var BlockReferenceScopeContext = createContext(null);
|
|
265
|
-
function BlockReferenceScope({
|
|
266
|
-
const
|
|
267
|
-
const
|
|
298
|
+
function BlockReferenceScope({ children }) {
|
|
299
|
+
const numbering = useContext(ReferenceNumberingContext);
|
|
300
|
+
const local = useRef({ ref: /* @__PURE__ */ new Map(), footnote: /* @__PURE__ */ new Map() });
|
|
268
301
|
const counter = useRef({ ref: 0, footnote: 0 });
|
|
269
|
-
counter.current = { ref: 0, footnote: 0 };
|
|
270
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
|
+
},
|
|
271
314
|
next(kind) {
|
|
272
315
|
counter.current[kind] += 1;
|
|
273
|
-
return
|
|
316
|
+
return counter.current[kind];
|
|
274
317
|
}
|
|
275
318
|
};
|
|
276
319
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value, children });
|
|
@@ -278,7 +321,7 @@ function BlockReferenceScope({ blockId, children }) {
|
|
|
278
321
|
function useBlockReferenceScope() {
|
|
279
322
|
return useContext(BlockReferenceScopeContext);
|
|
280
323
|
}
|
|
281
|
-
var INERT_SCOPE = { next: () => 0 };
|
|
324
|
+
var INERT_SCOPE = { numberFor: () => 0, next: () => 0 };
|
|
282
325
|
function InertReferenceScope({ children }) {
|
|
283
326
|
return /* @__PURE__ */ jsx(BlockReferenceScopeContext.Provider, { value: INERT_SCOPE, children });
|
|
284
327
|
}
|
|
@@ -569,7 +612,7 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
569
612
|
);
|
|
570
613
|
}
|
|
571
614
|
case "inline_ref": {
|
|
572
|
-
const number = refScope?.
|
|
615
|
+
const number = refScope?.numberFor(token.kind, token.content) ?? 0;
|
|
573
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 });
|
|
574
617
|
}
|
|
575
618
|
default:
|
|
@@ -635,8 +678,1145 @@ function renderReadingText(content, opts) {
|
|
|
635
678
|
if (cursor < content.length) pieces.push(content.slice(cursor));
|
|
636
679
|
return /* @__PURE__ */ jsx(Fragment, { children: pieces });
|
|
637
680
|
}
|
|
681
|
+
function blockKey(block) {
|
|
682
|
+
return block.stableId ? `${block.id}:${block.stableId}` : block.id;
|
|
683
|
+
}
|
|
684
|
+
function blockDataAttributes(block) {
|
|
685
|
+
return {
|
|
686
|
+
"data-ncm-block": block.id,
|
|
687
|
+
"data-ncm-stable": block.stableId,
|
|
688
|
+
"data-ncm-type": block.type,
|
|
689
|
+
"data-block-id": block.id
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
function BlockShell({
|
|
693
|
+
as = "div",
|
|
694
|
+
block,
|
|
695
|
+
children,
|
|
696
|
+
...props
|
|
697
|
+
}) {
|
|
698
|
+
return createElement(as, {
|
|
699
|
+
...blockDataAttributes(block),
|
|
700
|
+
...props
|
|
701
|
+
}, children);
|
|
702
|
+
}
|
|
703
|
+
function ChildBlocks({
|
|
704
|
+
as = "div",
|
|
705
|
+
blocks,
|
|
706
|
+
...props
|
|
707
|
+
}) {
|
|
708
|
+
return createElement(
|
|
709
|
+
as,
|
|
710
|
+
props,
|
|
711
|
+
blocks.map((block) => /* @__PURE__ */ jsx(NcmBlock, { block }, blockKey(block)))
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
function cn(...inputs) {
|
|
715
|
+
return twMerge(clsx(inputs));
|
|
716
|
+
}
|
|
717
|
+
function defaultTitle(type) {
|
|
718
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
719
|
+
}
|
|
720
|
+
function AdmonitionBlock({ block, className }) {
|
|
721
|
+
const title = block.title ?? defaultTitle(block.admonitionType);
|
|
722
|
+
const classes = cn("rounded-lg border border-border bg-card p-4", className);
|
|
723
|
+
if (block.collapsible) {
|
|
724
|
+
return /* @__PURE__ */ jsxs(
|
|
725
|
+
BlockShell,
|
|
726
|
+
{
|
|
727
|
+
as: "details",
|
|
728
|
+
block,
|
|
729
|
+
"data-ncm-admonition": "",
|
|
730
|
+
"data-ncm-admonition-type": block.admonitionType,
|
|
731
|
+
open: !block.collapsed,
|
|
732
|
+
className: classes,
|
|
733
|
+
children: [
|
|
734
|
+
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-medium", "data-ncm-admonition-title": "", children: title }),
|
|
735
|
+
/* @__PURE__ */ jsx(ChildBlocks, { blocks: block.children, className: "mt-2 space-y-2" })
|
|
736
|
+
]
|
|
737
|
+
}
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
return /* @__PURE__ */ jsxs(
|
|
741
|
+
BlockShell,
|
|
742
|
+
{
|
|
743
|
+
block,
|
|
744
|
+
"data-ncm-admonition": "",
|
|
745
|
+
"data-ncm-admonition-type": block.admonitionType,
|
|
746
|
+
className: classes,
|
|
747
|
+
children: [
|
|
748
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 font-medium", "data-ncm-admonition-title": "", children: title }),
|
|
749
|
+
/* @__PURE__ */ jsx(ChildBlocks, { blocks: block.children, className: "space-y-2" })
|
|
750
|
+
]
|
|
751
|
+
}
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
function AsideBlock({ block, className }) {
|
|
755
|
+
return /* @__PURE__ */ jsx(
|
|
756
|
+
BlockShell,
|
|
757
|
+
{
|
|
758
|
+
as: "aside",
|
|
759
|
+
block,
|
|
760
|
+
"data-ncm-aside": "",
|
|
761
|
+
className: cn("border-l-2 border-border pl-4 text-muted-foreground", className),
|
|
762
|
+
children: /* @__PURE__ */ jsx(ChildBlocks, { blocks: block.content, className: "space-y-2" })
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
function AttributionBlock({ block, className }) {
|
|
767
|
+
return /* @__PURE__ */ jsxs(
|
|
768
|
+
"p",
|
|
769
|
+
{
|
|
770
|
+
"data-ncm-block": block.id,
|
|
771
|
+
"data-ncm-stable": block.stableId,
|
|
772
|
+
"data-ncm-type": block.type,
|
|
773
|
+
"data-block-id": block.id,
|
|
774
|
+
"data-ncm-attribution": "",
|
|
775
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
776
|
+
children: [
|
|
777
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2014 " }),
|
|
778
|
+
block.url ? /* @__PURE__ */ jsx("a", { href: block.url, className: "hover:underline", children: /* @__PURE__ */ jsx("cite", { children: block.source }) }) : /* @__PURE__ */ jsx("cite", { children: block.source }),
|
|
779
|
+
block.date ? /* @__PURE__ */ jsxs("span", { children: [
|
|
780
|
+
", ",
|
|
781
|
+
block.date
|
|
782
|
+
] }) : null
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
function ChartBlock({ block, className }) {
|
|
788
|
+
return /* @__PURE__ */ jsx(
|
|
789
|
+
"pre",
|
|
790
|
+
{
|
|
791
|
+
"data-ncm-block": block.id,
|
|
792
|
+
"data-ncm-stable": block.stableId,
|
|
793
|
+
"data-ncm-type": block.type,
|
|
794
|
+
"data-block-id": block.id,
|
|
795
|
+
"data-ncm-chart": "",
|
|
796
|
+
"data-ncm-chart-type": block.chartType ?? "unknown",
|
|
797
|
+
className: cn(
|
|
798
|
+
// `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
|
|
799
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
800
|
+
className
|
|
801
|
+
),
|
|
802
|
+
children: /* @__PURE__ */ jsx("code", { children: block.content })
|
|
803
|
+
}
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
var highlighterPromise = import('shiki/bundle/web').then(async (shiki) => {
|
|
807
|
+
const highlighter = await shiki.createHighlighter({
|
|
808
|
+
themes: ["github-light", "github-dark"],
|
|
809
|
+
langs: Object.keys(shiki.bundledLanguages)
|
|
810
|
+
});
|
|
811
|
+
return highlighter;
|
|
812
|
+
}).catch(() => null);
|
|
813
|
+
function useIsDark() {
|
|
814
|
+
const [isDark, setIsDark] = useState(false);
|
|
815
|
+
useEffect(() => {
|
|
816
|
+
if (typeof document === "undefined") return;
|
|
817
|
+
const root = document.documentElement;
|
|
818
|
+
const update = () => setIsDark(root.classList.contains("dark"));
|
|
819
|
+
update();
|
|
820
|
+
const observer = new MutationObserver(update);
|
|
821
|
+
observer.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
822
|
+
return () => observer.disconnect();
|
|
823
|
+
}, []);
|
|
824
|
+
return isDark;
|
|
825
|
+
}
|
|
826
|
+
function DefaultShikiRenderer({
|
|
827
|
+
code,
|
|
828
|
+
language
|
|
829
|
+
}) {
|
|
830
|
+
const isDark = useIsDark();
|
|
831
|
+
const [highlighter, setHighlighter] = useState(null);
|
|
832
|
+
const shikiTheme = isDark ? "github-dark" : "github-light";
|
|
833
|
+
useEffect(() => {
|
|
834
|
+
let active = true;
|
|
835
|
+
highlighterPromise.then((h) => {
|
|
836
|
+
if (active) setHighlighter(h);
|
|
837
|
+
});
|
|
838
|
+
return () => {
|
|
839
|
+
active = false;
|
|
840
|
+
};
|
|
841
|
+
}, []);
|
|
842
|
+
const tokens = useMemo(() => {
|
|
843
|
+
if (!highlighter) return null;
|
|
844
|
+
const loaded = highlighter.getLoadedLanguages();
|
|
845
|
+
const lang = language && loaded.includes(language) ? language : "text";
|
|
846
|
+
try {
|
|
847
|
+
return highlighter.codeToTokens(code, { lang, theme: shikiTheme }).tokens;
|
|
848
|
+
} catch {
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
}, [code, language, highlighter, shikiTheme]);
|
|
852
|
+
if (!tokens) {
|
|
853
|
+
return /* @__PURE__ */ jsx(Fragment, { children: code });
|
|
854
|
+
}
|
|
855
|
+
return /* @__PURE__ */ jsx(Fragment, { children: tokens.map((line, lineIndex) => /* @__PURE__ */ jsx("span", { className: "block whitespace-pre", children: line.length === 0 ? " " : line.map((token, tokenIndex) => /* @__PURE__ */ jsx("span", { style: { color: token.color || "inherit" }, children: token.content }, tokenIndex)) }, lineIndex)) });
|
|
856
|
+
}
|
|
857
|
+
function CopyButton({ content }) {
|
|
858
|
+
const [copied, setCopied] = useState(false);
|
|
859
|
+
const handleCopy = useCallback(async () => {
|
|
860
|
+
try {
|
|
861
|
+
await navigator.clipboard.writeText(content);
|
|
862
|
+
setCopied(true);
|
|
863
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
864
|
+
} catch {
|
|
865
|
+
const textarea = document.createElement("textarea");
|
|
866
|
+
textarea.value = content;
|
|
867
|
+
document.body.appendChild(textarea);
|
|
868
|
+
textarea.select();
|
|
869
|
+
document.execCommand("copy");
|
|
870
|
+
document.body.removeChild(textarea);
|
|
871
|
+
setCopied(true);
|
|
872
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
873
|
+
}
|
|
874
|
+
}, [content]);
|
|
875
|
+
return /* @__PURE__ */ jsx(
|
|
876
|
+
"button",
|
|
877
|
+
{
|
|
878
|
+
type: "button",
|
|
879
|
+
onClick: handleCopy,
|
|
880
|
+
"aria-label": copied ? "Copied!" : "Copy code",
|
|
881
|
+
"data-ncm-copy-button": "",
|
|
882
|
+
className: "absolute right-2 top-2 rounded-md bg-background/80 px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-background hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring",
|
|
883
|
+
children: copied ? "Copied!" : "Copy"
|
|
884
|
+
}
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
function LineNumbers({ count }) {
|
|
888
|
+
return /* @__PURE__ */ jsx(
|
|
889
|
+
"div",
|
|
890
|
+
{
|
|
891
|
+
"aria-hidden": "true",
|
|
892
|
+
"data-ncm-line-numbers": "",
|
|
893
|
+
className: "select-none pr-4 text-right text-muted-foreground/60",
|
|
894
|
+
children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx("div", { children: i + 1 }, i + 1))
|
|
895
|
+
}
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
function CodeBlock({ block, className }) {
|
|
899
|
+
const config = useNcmConfig();
|
|
900
|
+
const { code: codeConfig } = config;
|
|
901
|
+
const lineCount = block.content.split("\n").length;
|
|
902
|
+
const languageLabel = block.language ? /* @__PURE__ */ jsx(
|
|
903
|
+
"div",
|
|
904
|
+
{
|
|
905
|
+
"data-ncm-code-language": "",
|
|
906
|
+
className: "absolute right-2 bottom-2 text-xs text-muted-foreground/60",
|
|
907
|
+
children: block.language
|
|
908
|
+
}
|
|
909
|
+
) : null;
|
|
910
|
+
if (codeConfig?.renderer) {
|
|
911
|
+
const CustomRenderer = codeConfig.renderer;
|
|
912
|
+
return /* @__PURE__ */ jsxs(
|
|
913
|
+
"div",
|
|
914
|
+
{
|
|
915
|
+
role: "region",
|
|
916
|
+
"aria-label": block.language ? `Code block: ${block.language}` : "Code block",
|
|
917
|
+
"data-ncm-block": block.id,
|
|
918
|
+
"data-ncm-stable": block.stableId,
|
|
919
|
+
"data-ncm-type": block.type,
|
|
920
|
+
"data-block-id": block.id,
|
|
921
|
+
"data-ncm-language": block.language,
|
|
922
|
+
className: cn("relative", className),
|
|
923
|
+
children: [
|
|
924
|
+
codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
925
|
+
/* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
|
|
926
|
+
languageLabel
|
|
927
|
+
]
|
|
928
|
+
}
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
return /* @__PURE__ */ jsxs(
|
|
932
|
+
"div",
|
|
933
|
+
{
|
|
934
|
+
role: "region",
|
|
935
|
+
"aria-label": block.language ? `Code block: ${block.language}` : "Code block",
|
|
936
|
+
"data-ncm-block": block.id,
|
|
937
|
+
"data-ncm-stable": block.stableId,
|
|
938
|
+
"data-ncm-type": block.type,
|
|
939
|
+
"data-block-id": block.id,
|
|
940
|
+
"data-ncm-language": block.language,
|
|
941
|
+
className: cn("relative", className),
|
|
942
|
+
children: [
|
|
943
|
+
codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
944
|
+
/* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
945
|
+
codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
|
|
946
|
+
/* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
|
|
947
|
+
] }) }),
|
|
948
|
+
languageLabel
|
|
949
|
+
]
|
|
950
|
+
}
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
function ContainerBlock({ block, className }) {
|
|
954
|
+
return /* @__PURE__ */ jsxs(
|
|
955
|
+
BlockShell,
|
|
956
|
+
{
|
|
957
|
+
block,
|
|
958
|
+
"data-ncm-container": "",
|
|
959
|
+
"data-ncm-directive": block.directive,
|
|
960
|
+
className: cn("rounded-lg border border-border bg-card p-4", className),
|
|
961
|
+
children: [
|
|
962
|
+
block.directive && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-md bg-muted px-1.5 py-0.5 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: block.directive }) }),
|
|
963
|
+
/* @__PURE__ */ jsx(InlineContent, { content: block.innerContent })
|
|
964
|
+
]
|
|
965
|
+
}
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
function DataviewBlock({ block, className }) {
|
|
969
|
+
return /* @__PURE__ */ jsx(
|
|
970
|
+
"pre",
|
|
971
|
+
{
|
|
972
|
+
"data-ncm-block": block.id,
|
|
973
|
+
"data-ncm-stable": block.stableId,
|
|
974
|
+
"data-ncm-type": block.type,
|
|
975
|
+
"data-block-id": block.id,
|
|
976
|
+
"data-ncm-dataview": "",
|
|
977
|
+
"data-ncm-query-type": block.queryType,
|
|
978
|
+
className: cn(
|
|
979
|
+
// `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
|
|
980
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
981
|
+
className
|
|
982
|
+
),
|
|
983
|
+
children: /* @__PURE__ */ jsx("code", { children: block.query })
|
|
984
|
+
}
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
function DefinitionBlock({ block, className }) {
|
|
988
|
+
return /* @__PURE__ */ jsxs(
|
|
989
|
+
BlockShell,
|
|
990
|
+
{
|
|
991
|
+
as: "dl",
|
|
992
|
+
block,
|
|
993
|
+
"data-ncm-definition": "",
|
|
994
|
+
className: cn("space-y-1", className),
|
|
995
|
+
children: [
|
|
996
|
+
/* @__PURE__ */ jsx("dt", { className: "font-medium", children: /* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(block.term) }) }),
|
|
997
|
+
/* @__PURE__ */ jsx(ChildBlocks, { as: "dd", blocks: block.definition, className: "ml-4 space-y-2" })
|
|
998
|
+
]
|
|
999
|
+
}
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
function toEmbeddingConfigType(embedType) {
|
|
1003
|
+
switch (embedType) {
|
|
1004
|
+
case "image":
|
|
1005
|
+
return "image";
|
|
1006
|
+
case "document":
|
|
1007
|
+
return "pdf";
|
|
1008
|
+
case "file":
|
|
1009
|
+
default:
|
|
1010
|
+
return "generic_file";
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function dataAttrs(block) {
|
|
1014
|
+
return {
|
|
1015
|
+
"data-ncm-block": block.id,
|
|
1016
|
+
"data-ncm-stable": block.stableId,
|
|
1017
|
+
"data-ncm-type": block.type,
|
|
1018
|
+
"data-block-id": block.id,
|
|
1019
|
+
"data-ncm-embed": "",
|
|
1020
|
+
"data-ncm-embed-type": block.embedType
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
function EmbedBlock({ block, className }) {
|
|
1024
|
+
const config = useNcmConfig();
|
|
1025
|
+
const configEmbedType = toEmbeddingConfigType(block.embedType);
|
|
1026
|
+
const resolvedUrl = config.embeddings?.resolveUrl?.(block.src, configEmbedType) ?? block.src;
|
|
1027
|
+
if (block.embedType === "image") {
|
|
1028
|
+
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 }) });
|
|
1029
|
+
}
|
|
1030
|
+
return /* @__PURE__ */ jsx("figure", { ...dataAttrs(block), className, children: /* @__PURE__ */ jsx("a", { href: resolvedUrl, title: block.title ?? void 0, children: block.alt || block.src }) });
|
|
1031
|
+
}
|
|
1032
|
+
var embedFrameStyle = {
|
|
1033
|
+
display: "block",
|
|
1034
|
+
width: "100%",
|
|
1035
|
+
maxWidth: "100%",
|
|
1036
|
+
height: "min(80vh, 900px)",
|
|
1037
|
+
minHeight: "min(360px, 80vh)"
|
|
1038
|
+
};
|
|
1039
|
+
var embedMediaStyle = {
|
|
1040
|
+
display: "block",
|
|
1041
|
+
maxWidth: "100%",
|
|
1042
|
+
height: "auto"
|
|
1043
|
+
};
|
|
1044
|
+
function EmbeddingBlock({ block, className }) {
|
|
1045
|
+
const config = useNcmConfig();
|
|
1046
|
+
const resolvedUrl = config.embeddings?.resolveUrl?.(block.target, block.embed_type) ?? block.target;
|
|
1047
|
+
const CustomRenderer = config.embeddings?.renderers?.[block.embed_type];
|
|
1048
|
+
if (CustomRenderer) {
|
|
1049
|
+
return /* @__PURE__ */ jsx(CustomRenderer, { block, className, resolvedUrl });
|
|
1050
|
+
}
|
|
1051
|
+
switch (block.embed_type) {
|
|
1052
|
+
case "image":
|
|
1053
|
+
return /* @__PURE__ */ jsx(
|
|
1054
|
+
ImageEmbed,
|
|
1055
|
+
{
|
|
1056
|
+
block,
|
|
1057
|
+
resolvedUrl,
|
|
1058
|
+
className: cn(config.embeddings?.imageClassName, className)
|
|
1059
|
+
}
|
|
1060
|
+
);
|
|
1061
|
+
case "video":
|
|
1062
|
+
return /* @__PURE__ */ jsx(
|
|
1063
|
+
VideoEmbed,
|
|
1064
|
+
{
|
|
1065
|
+
block,
|
|
1066
|
+
resolvedUrl,
|
|
1067
|
+
className: cn(config.embeddings?.videoClassName, className)
|
|
1068
|
+
}
|
|
1069
|
+
);
|
|
1070
|
+
case "audio":
|
|
1071
|
+
return /* @__PURE__ */ jsx(
|
|
1072
|
+
AudioEmbed,
|
|
1073
|
+
{
|
|
1074
|
+
block,
|
|
1075
|
+
resolvedUrl,
|
|
1076
|
+
className: cn(config.embeddings?.audioClassName, className)
|
|
1077
|
+
}
|
|
1078
|
+
);
|
|
1079
|
+
case "pdf":
|
|
1080
|
+
return /* @__PURE__ */ jsx(PdfEmbed, { block, resolvedUrl, className });
|
|
1081
|
+
case "ncm_embed":
|
|
1082
|
+
return /* @__PURE__ */ jsx(NcmEmbed, { block, resolvedUrl, className });
|
|
1083
|
+
case "iframe":
|
|
1084
|
+
return /* @__PURE__ */ jsx(IframeEmbed, { block, resolvedUrl, className });
|
|
1085
|
+
case "generic_file":
|
|
1086
|
+
default:
|
|
1087
|
+
return /* @__PURE__ */ jsx(GenericFileEmbed, { block, resolvedUrl, className });
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
function dataAttrs2(block, embedType) {
|
|
1091
|
+
return {
|
|
1092
|
+
"data-ncm-block": block.id,
|
|
1093
|
+
"data-ncm-stable": block.stableId,
|
|
1094
|
+
"data-ncm-type": block.type,
|
|
1095
|
+
"data-block-id": block.id,
|
|
1096
|
+
"data-ncm-embedding": "",
|
|
1097
|
+
"data-ncm-embed-type": embedType
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function ImageEmbed({ block, resolvedUrl, className }) {
|
|
1101
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "image"), className, children: [
|
|
1102
|
+
/* @__PURE__ */ jsx("img", { src: resolvedUrl, alt: block.caption ?? "" }),
|
|
1103
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1104
|
+
] });
|
|
1105
|
+
}
|
|
1106
|
+
function VideoEmbed({ block, resolvedUrl, className }) {
|
|
1107
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "video"), className, children: [
|
|
1108
|
+
/* @__PURE__ */ jsx("video", { src: resolvedUrl, controls: true }),
|
|
1109
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1110
|
+
] });
|
|
1111
|
+
}
|
|
1112
|
+
function AudioEmbed({ block, resolvedUrl, className }) {
|
|
1113
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "audio"), className, children: [
|
|
1114
|
+
/* @__PURE__ */ jsx("audio", { src: resolvedUrl, controls: true, className: "w-full" }),
|
|
1115
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1116
|
+
] });
|
|
1117
|
+
}
|
|
1118
|
+
function PdfEmbed({ block, resolvedUrl, className }) {
|
|
1119
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "pdf"), className: cn("w-full max-w-full", className), children: [
|
|
1120
|
+
/* @__PURE__ */ jsx(
|
|
1121
|
+
"iframe",
|
|
1122
|
+
{
|
|
1123
|
+
src: resolvedUrl,
|
|
1124
|
+
title: block.caption ?? "PDF document",
|
|
1125
|
+
className: "rounded-lg border border-border",
|
|
1126
|
+
style: embedFrameStyle
|
|
1127
|
+
}
|
|
1128
|
+
),
|
|
1129
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1130
|
+
] });
|
|
1131
|
+
}
|
|
1132
|
+
function IframeEmbed({ block, resolvedUrl, className }) {
|
|
1133
|
+
const [useFrame, setUseFrame] = useState(false);
|
|
1134
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "iframe"), className: cn("w-full max-w-full", className), children: [
|
|
1135
|
+
useFrame ? /* @__PURE__ */ jsx(
|
|
1136
|
+
"iframe",
|
|
1137
|
+
{
|
|
1138
|
+
src: resolvedUrl,
|
|
1139
|
+
title: block.caption ?? block.alt ?? block.target,
|
|
1140
|
+
className: "rounded-lg border border-border",
|
|
1141
|
+
style: embedFrameStyle
|
|
1142
|
+
}
|
|
1143
|
+
) : /* @__PURE__ */ jsx(
|
|
1144
|
+
"img",
|
|
1145
|
+
{
|
|
1146
|
+
src: resolvedUrl,
|
|
1147
|
+
alt: block.alt || block.caption || block.target,
|
|
1148
|
+
style: embedMediaStyle,
|
|
1149
|
+
onError: () => setUseFrame(true)
|
|
1150
|
+
}
|
|
1151
|
+
),
|
|
1152
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1153
|
+
] });
|
|
1154
|
+
}
|
|
1155
|
+
function NcmEmbed({ block, resolvedUrl, className }) {
|
|
1156
|
+
return /* @__PURE__ */ jsxs(
|
|
1157
|
+
"div",
|
|
1158
|
+
{
|
|
1159
|
+
...dataAttrs2(block, "ncm_embed"),
|
|
1160
|
+
className: cn("rounded-lg border border-dashed border-border bg-muted p-4", className),
|
|
1161
|
+
children: [
|
|
1162
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-muted-foreground", children: [
|
|
1163
|
+
"Embedded: ",
|
|
1164
|
+
/* @__PURE__ */ jsx("code", { className: "rounded bg-background px-1", children: block.target }),
|
|
1165
|
+
resolvedUrl !== block.target && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1166
|
+
" ",
|
|
1167
|
+
/* @__PURE__ */ jsx("a", { href: resolvedUrl, className: "underline underline-offset-4", children: "open" })
|
|
1168
|
+
] })
|
|
1169
|
+
] }),
|
|
1170
|
+
block.caption && /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-muted-foreground", children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1171
|
+
]
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
function GenericFileEmbed({ block, resolvedUrl, className }) {
|
|
1176
|
+
return /* @__PURE__ */ jsxs("figure", { ...dataAttrs2(block, "generic_file"), className, children: [
|
|
1177
|
+
/* @__PURE__ */ jsxs(
|
|
1178
|
+
"a",
|
|
1179
|
+
{
|
|
1180
|
+
href: resolvedUrl,
|
|
1181
|
+
download: true,
|
|
1182
|
+
className: "flex items-center gap-2 rounded-lg border border-border bg-muted p-4 hover:bg-background",
|
|
1183
|
+
children: [
|
|
1184
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: block.target }),
|
|
1185
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
1186
|
+
"(",
|
|
1187
|
+
block.file_format.toUpperCase(),
|
|
1188
|
+
")"
|
|
1189
|
+
] })
|
|
1190
|
+
]
|
|
1191
|
+
}
|
|
1192
|
+
),
|
|
1193
|
+
block.caption && /* @__PURE__ */ jsx("figcaption", { children: /* @__PURE__ */ jsx(InlineContent, { content: block.caption }) })
|
|
1194
|
+
] });
|
|
1195
|
+
}
|
|
1196
|
+
function FigureBlock({ block, className }) {
|
|
1197
|
+
const { embed, caption, number } = block;
|
|
1198
|
+
return /* @__PURE__ */ jsxs(
|
|
1199
|
+
BlockShell,
|
|
1200
|
+
{
|
|
1201
|
+
as: "figure",
|
|
1202
|
+
block,
|
|
1203
|
+
"data-ncm-figure": "",
|
|
1204
|
+
className: cn("space-y-2", className),
|
|
1205
|
+
children: [
|
|
1206
|
+
embed.embedType === "image" ? /* @__PURE__ */ jsx("img", { src: embed.src, alt: embed.alt, title: embed.title ?? void 0 }) : /* @__PURE__ */ jsx(
|
|
1207
|
+
"a",
|
|
1208
|
+
{
|
|
1209
|
+
href: embed.src,
|
|
1210
|
+
title: embed.title ?? void 0,
|
|
1211
|
+
"data-ncm-embed-type": embed.embedType,
|
|
1212
|
+
children: embed.alt || embed.src
|
|
1213
|
+
}
|
|
1214
|
+
),
|
|
1215
|
+
/* @__PURE__ */ jsxs(
|
|
1216
|
+
"figcaption",
|
|
1217
|
+
{
|
|
1218
|
+
className: "text-sm text-muted-foreground",
|
|
1219
|
+
"data-ncm-figure-number": number,
|
|
1220
|
+
children: [
|
|
1221
|
+
typeof number === "number" ? /* @__PURE__ */ jsxs("span", { "data-ncm-figure-label": "", children: [
|
|
1222
|
+
"Figure ",
|
|
1223
|
+
number,
|
|
1224
|
+
". "
|
|
1225
|
+
] }) : null,
|
|
1226
|
+
/* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(caption.content) })
|
|
1227
|
+
]
|
|
1228
|
+
}
|
|
1229
|
+
)
|
|
1230
|
+
]
|
|
1231
|
+
}
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
function FootnoteBlock({ block, className }) {
|
|
1235
|
+
return /* @__PURE__ */ jsxs(
|
|
1236
|
+
BlockShell,
|
|
1237
|
+
{
|
|
1238
|
+
id: block.stableId,
|
|
1239
|
+
block,
|
|
1240
|
+
"data-ncm-footnote": "",
|
|
1241
|
+
"data-ncm-footnote-label": block.label,
|
|
1242
|
+
className: cn("flex gap-2 text-sm text-muted-foreground", className),
|
|
1243
|
+
children: [
|
|
1244
|
+
/* @__PURE__ */ jsxs("span", { "data-ncm-footnote-marker": "", className: "font-medium", children: [
|
|
1245
|
+
block.label,
|
|
1246
|
+
"."
|
|
1247
|
+
] }),
|
|
1248
|
+
/* @__PURE__ */ jsx(ChildBlocks, { blocks: block.content, className: "space-y-2" })
|
|
1249
|
+
]
|
|
1250
|
+
}
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
function formatValue(value) {
|
|
1254
|
+
if (Array.isArray(value)) return value.map((v) => String(v)).join(", ");
|
|
1255
|
+
if (value === null || value === void 0) return "";
|
|
1256
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
1257
|
+
return String(value);
|
|
1258
|
+
}
|
|
1259
|
+
function FrontmatterBlock({ block, className }) {
|
|
1260
|
+
const entries = Object.entries(block.data ?? {});
|
|
1261
|
+
return /* @__PURE__ */ jsx(
|
|
1262
|
+
"dl",
|
|
1263
|
+
{
|
|
1264
|
+
"data-ncm-block": block.id,
|
|
1265
|
+
"data-ncm-stable": block.stableId,
|
|
1266
|
+
"data-ncm-type": block.type,
|
|
1267
|
+
"data-block-id": block.id,
|
|
1268
|
+
"data-ncm-frontmatter": "",
|
|
1269
|
+
className: cn(
|
|
1270
|
+
"grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 rounded-lg border border-border bg-muted/30 p-4 text-sm",
|
|
1271
|
+
className
|
|
1272
|
+
),
|
|
1273
|
+
children: entries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "contents", children: [
|
|
1274
|
+
/* @__PURE__ */ jsx("dt", { className: "font-medium text-muted-foreground", children: key }),
|
|
1275
|
+
/* @__PURE__ */ jsx("dd", { className: "text-foreground", children: formatValue(value) })
|
|
1276
|
+
] }, key))
|
|
1277
|
+
}
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
function HeaderBlock({ block, className }) {
|
|
1281
|
+
const Tag = `h${block.level}`;
|
|
1282
|
+
return /* @__PURE__ */ jsx(
|
|
1283
|
+
Tag,
|
|
1284
|
+
{
|
|
1285
|
+
id: block.stableId ?? block.id,
|
|
1286
|
+
"data-ncm-block": block.id,
|
|
1287
|
+
"data-ncm-stable": block.stableId,
|
|
1288
|
+
"data-ncm-type": block.type,
|
|
1289
|
+
"data-block-id": block.id,
|
|
1290
|
+
"data-ncm-level": block.level,
|
|
1291
|
+
className,
|
|
1292
|
+
children: /* @__PURE__ */ jsx(InlineContent, { content: block.content, disableBionic: true, disableBeeline: true })
|
|
1293
|
+
}
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
function HorizontalRuleBlock({ block, className }) {
|
|
1297
|
+
return /* @__PURE__ */ jsx(
|
|
1298
|
+
"hr",
|
|
1299
|
+
{
|
|
1300
|
+
"data-ncm-block": block.id,
|
|
1301
|
+
"data-ncm-stable": block.stableId,
|
|
1302
|
+
"data-ncm-type": block.type,
|
|
1303
|
+
"data-block-id": block.id,
|
|
1304
|
+
"data-ncm-horizontal-rule": "",
|
|
1305
|
+
className
|
|
1306
|
+
}
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
function HtmlBlock({ block, className }) {
|
|
1310
|
+
return /* @__PURE__ */ jsx(
|
|
1311
|
+
"pre",
|
|
1312
|
+
{
|
|
1313
|
+
"data-ncm-block": block.id,
|
|
1314
|
+
"data-ncm-stable": block.stableId,
|
|
1315
|
+
"data-ncm-type": block.type,
|
|
1316
|
+
"data-block-id": block.id,
|
|
1317
|
+
"data-ncm-html": "",
|
|
1318
|
+
className: cn(
|
|
1319
|
+
// `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
|
|
1320
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
1321
|
+
className
|
|
1322
|
+
),
|
|
1323
|
+
children: /* @__PURE__ */ jsx("code", { children: block.content })
|
|
1324
|
+
}
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
function LatexDisplayBlock({ block, className }) {
|
|
1328
|
+
const config = useNcmConfig();
|
|
1329
|
+
const CustomRenderer = config.inline?.customLatexRenderer;
|
|
1330
|
+
const html = useKatexHtml(block.content, true, !CustomRenderer);
|
|
1331
|
+
if (CustomRenderer) {
|
|
1332
|
+
return /* @__PURE__ */ jsx(
|
|
1333
|
+
"div",
|
|
1334
|
+
{
|
|
1335
|
+
role: "region",
|
|
1336
|
+
"aria-label": "Mathematical expression",
|
|
1337
|
+
"data-ncm-block": block.id,
|
|
1338
|
+
"data-ncm-stable": block.stableId,
|
|
1339
|
+
"data-ncm-type": block.type,
|
|
1340
|
+
"data-block-id": block.id,
|
|
1341
|
+
"data-ncm-latex-display": "",
|
|
1342
|
+
className,
|
|
1343
|
+
children: /* @__PURE__ */ jsx(CustomRenderer, { content: block.content, display: true })
|
|
1344
|
+
}
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
if (html) {
|
|
1348
|
+
return /* @__PURE__ */ jsx(
|
|
1349
|
+
"div",
|
|
1350
|
+
{
|
|
1351
|
+
role: "region",
|
|
1352
|
+
"aria-label": "Mathematical expression",
|
|
1353
|
+
"data-ncm-block": block.id,
|
|
1354
|
+
"data-ncm-stable": block.stableId,
|
|
1355
|
+
"data-ncm-type": block.type,
|
|
1356
|
+
"data-block-id": block.id,
|
|
1357
|
+
"data-ncm-latex-display": "",
|
|
1358
|
+
className: cn("overflow-x-auto overflow-y-hidden", className),
|
|
1359
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1360
|
+
}
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
return /* @__PURE__ */ jsx(
|
|
1364
|
+
"pre",
|
|
1365
|
+
{
|
|
1366
|
+
role: "region",
|
|
1367
|
+
"aria-label": "Mathematical expression (source)",
|
|
1368
|
+
"data-ncm-block": block.id,
|
|
1369
|
+
"data-ncm-stable": block.stableId,
|
|
1370
|
+
"data-ncm-type": block.type,
|
|
1371
|
+
"data-block-id": block.id,
|
|
1372
|
+
"data-ncm-latex-display": "",
|
|
1373
|
+
className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
|
|
1374
|
+
children: /* @__PURE__ */ jsx("code", { children: block.content })
|
|
1375
|
+
}
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
function LinkBlock({ block, className }) {
|
|
1379
|
+
return /* @__PURE__ */ jsx(
|
|
1380
|
+
"a",
|
|
1381
|
+
{
|
|
1382
|
+
"data-ncm-block": block.id,
|
|
1383
|
+
"data-ncm-stable": block.stableId,
|
|
1384
|
+
"data-ncm-type": block.type,
|
|
1385
|
+
"data-block-id": block.id,
|
|
1386
|
+
"data-ncm-link": "",
|
|
1387
|
+
href: block.url,
|
|
1388
|
+
title: block.title ?? void 0,
|
|
1389
|
+
className: cn("block text-primary hover:underline", className),
|
|
1390
|
+
children: block.text || block.url
|
|
1391
|
+
}
|
|
1392
|
+
);
|
|
1393
|
+
}
|
|
1394
|
+
function ListBlock({ block, className }) {
|
|
1395
|
+
const isOrdered = block.type === "list_ordered";
|
|
1396
|
+
const Tag = isOrdered ? "ol" : "ul";
|
|
1397
|
+
const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
|
|
1398
|
+
return /* @__PURE__ */ jsx(
|
|
1399
|
+
Tag,
|
|
1400
|
+
{
|
|
1401
|
+
role: "list",
|
|
1402
|
+
start,
|
|
1403
|
+
"data-ncm-block": block.id,
|
|
1404
|
+
"data-ncm-stable": block.stableId,
|
|
1405
|
+
"data-ncm-type": block.type,
|
|
1406
|
+
"data-block-id": block.id,
|
|
1407
|
+
"data-ncm-list": "",
|
|
1408
|
+
"data-ncm-list-type": isOrdered ? "ordered" : "unordered",
|
|
1409
|
+
className,
|
|
1410
|
+
children: /* @__PURE__ */ jsx(ListItems, { items: block.items, itemIds: block.itemIds, ordered: isOrdered })
|
|
1411
|
+
}
|
|
1412
|
+
);
|
|
1413
|
+
}
|
|
1414
|
+
function ItemContent({ content }) {
|
|
1415
|
+
return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
|
|
1416
|
+
}
|
|
1417
|
+
function nestedItemIdKey(id) {
|
|
1418
|
+
if (!id) {
|
|
1419
|
+
return void 0;
|
|
1420
|
+
}
|
|
1421
|
+
if (typeof id === "string") {
|
|
1422
|
+
return id;
|
|
1423
|
+
}
|
|
1424
|
+
if (Array.isArray(id)) {
|
|
1425
|
+
return id.map(nestedItemIdKey).filter(Boolean).join(".");
|
|
1426
|
+
}
|
|
1427
|
+
return `${id.kind}:${id.items.map(nestedItemIdKey).filter(Boolean).join(".")}`;
|
|
1428
|
+
}
|
|
1429
|
+
function ListItems({ items, itemIds, ordered }) {
|
|
1430
|
+
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
|
|
1431
|
+
const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
|
|
1432
|
+
if (typeof item === "string") {
|
|
1433
|
+
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
|
|
1434
|
+
}
|
|
1435
|
+
if (isTypedNestedList(item)) {
|
|
1436
|
+
return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
|
|
1437
|
+
}
|
|
1438
|
+
if (Array.isArray(item) && item.length > 0) {
|
|
1439
|
+
const [first, ...rest] = item;
|
|
1440
|
+
const content = typeof first === "string" ? first : "";
|
|
1441
|
+
const nestedContent = processNestedItems(rest, ordered);
|
|
1442
|
+
return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
|
|
1443
|
+
/* @__PURE__ */ jsx(ItemContent, { content }),
|
|
1444
|
+
nestedContent
|
|
1445
|
+
] }, key);
|
|
1446
|
+
}
|
|
1447
|
+
return null;
|
|
1448
|
+
}) });
|
|
1449
|
+
}
|
|
1450
|
+
function processNestedItems(items, parentOrdered) {
|
|
1451
|
+
if (items.length === 0) return null;
|
|
1452
|
+
const groups = [];
|
|
1453
|
+
for (const item of items) {
|
|
1454
|
+
if (isTypedNestedList(item)) {
|
|
1455
|
+
const isOrdered = item.kind === "ordered";
|
|
1456
|
+
const lastGroup = groups[groups.length - 1];
|
|
1457
|
+
if (lastGroup && lastGroup.ordered === isOrdered) {
|
|
1458
|
+
lastGroup.items.push(...item.items);
|
|
1459
|
+
} else {
|
|
1460
|
+
groups.push({ ordered: isOrdered, items: [...item.items] });
|
|
1461
|
+
}
|
|
1462
|
+
} else {
|
|
1463
|
+
const lastGroup = groups[groups.length - 1];
|
|
1464
|
+
if (lastGroup && lastGroup.ordered === parentOrdered) {
|
|
1465
|
+
lastGroup.items.push(item);
|
|
1466
|
+
} else {
|
|
1467
|
+
groups.push({ ordered: parentOrdered, items: [item] });
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
return groups.map((group, index) => {
|
|
1472
|
+
const Tag = group.ordered ? "ol" : "ul";
|
|
1473
|
+
return /* @__PURE__ */ jsx(Tag, { "data-ncm-list-nested": "", children: /* @__PURE__ */ jsx(ListItems, { items: group.items, ordered: group.ordered }) }, index);
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
function NestedTypedList({ list }) {
|
|
1477
|
+
const Tag = list.kind === "ordered" ? "ol" : "ul";
|
|
1478
|
+
return /* @__PURE__ */ jsx(Tag, { "data-ncm-list-nested": "", children: /* @__PURE__ */ jsx(ListItems, { items: list.items, ordered: list.kind === "ordered" }) });
|
|
1479
|
+
}
|
|
1480
|
+
function MathBlock({ block, className }) {
|
|
1481
|
+
const html = useKatexHtml(block.content, true);
|
|
1482
|
+
if (html) {
|
|
1483
|
+
return /* @__PURE__ */ jsx(
|
|
1484
|
+
"div",
|
|
1485
|
+
{
|
|
1486
|
+
role: "region",
|
|
1487
|
+
"aria-label": "Mathematical expression",
|
|
1488
|
+
"data-ncm-block": block.id,
|
|
1489
|
+
"data-ncm-stable": block.stableId,
|
|
1490
|
+
"data-ncm-type": block.type,
|
|
1491
|
+
"data-block-id": block.id,
|
|
1492
|
+
"data-ncm-math": "",
|
|
1493
|
+
className: cn("overflow-x-auto overflow-y-hidden", className),
|
|
1494
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
1495
|
+
}
|
|
1496
|
+
);
|
|
1497
|
+
}
|
|
1498
|
+
return /* @__PURE__ */ jsx(
|
|
1499
|
+
"pre",
|
|
1500
|
+
{
|
|
1501
|
+
role: "region",
|
|
1502
|
+
"aria-label": "Mathematical expression (source)",
|
|
1503
|
+
"data-ncm-block": block.id,
|
|
1504
|
+
"data-ncm-stable": block.stableId,
|
|
1505
|
+
"data-ncm-type": block.type,
|
|
1506
|
+
"data-block-id": block.id,
|
|
1507
|
+
"data-ncm-math": "",
|
|
1508
|
+
className: cn(
|
|
1509
|
+
// `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
|
|
1510
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
1511
|
+
className
|
|
1512
|
+
),
|
|
1513
|
+
children: /* @__PURE__ */ jsx("code", { children: block.content })
|
|
1514
|
+
}
|
|
1515
|
+
);
|
|
1516
|
+
}
|
|
1517
|
+
function MermaidBlock({ block, className }) {
|
|
1518
|
+
return /* @__PURE__ */ jsx(
|
|
1519
|
+
"pre",
|
|
1520
|
+
{
|
|
1521
|
+
"data-ncm-block": block.id,
|
|
1522
|
+
"data-ncm-stable": block.stableId,
|
|
1523
|
+
"data-ncm-type": block.type,
|
|
1524
|
+
"data-block-id": block.id,
|
|
1525
|
+
"data-ncm-mermaid": "",
|
|
1526
|
+
"data-ncm-diagram-type": block.diagramType,
|
|
1527
|
+
className: cn(
|
|
1528
|
+
// `overflow-y-hidden` pairs with `overflow-x-auto` on purpose — see the note in `lib/defaults.ts`.
|
|
1529
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
1530
|
+
className
|
|
1531
|
+
),
|
|
1532
|
+
children: /* @__PURE__ */ jsx("code", { children: block.content })
|
|
1533
|
+
}
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
function PageBreakerBlock({ block, className }) {
|
|
1537
|
+
return /* @__PURE__ */ jsx(
|
|
1538
|
+
"div",
|
|
1539
|
+
{
|
|
1540
|
+
"data-ncm-block": block.id,
|
|
1541
|
+
"data-ncm-stable": block.stableId,
|
|
1542
|
+
"data-ncm-type": block.type,
|
|
1543
|
+
"data-block-id": block.id,
|
|
1544
|
+
"data-ncm-page": block.page,
|
|
1545
|
+
"aria-hidden": "true",
|
|
1546
|
+
className,
|
|
1547
|
+
style: { height: 0, margin: 0, padding: 0, border: 0 }
|
|
1548
|
+
}
|
|
1549
|
+
);
|
|
1550
|
+
}
|
|
1551
|
+
function ParagraphBlock({ block, className }) {
|
|
1552
|
+
return /* @__PURE__ */ jsx(
|
|
1553
|
+
"p",
|
|
1554
|
+
{
|
|
1555
|
+
"data-ncm-block": block.id,
|
|
1556
|
+
"data-ncm-stable": block.stableId,
|
|
1557
|
+
"data-ncm-type": block.type,
|
|
1558
|
+
"data-block-id": block.id,
|
|
1559
|
+
"data-ncm-paragraph": "",
|
|
1560
|
+
className,
|
|
1561
|
+
children: /* @__PURE__ */ jsx(InlineContent, { content: block.content })
|
|
1562
|
+
}
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
function SpoilerBlock({ block, className }) {
|
|
1566
|
+
return /* @__PURE__ */ jsxs(
|
|
1567
|
+
BlockShell,
|
|
1568
|
+
{
|
|
1569
|
+
as: "details",
|
|
1570
|
+
block,
|
|
1571
|
+
"data-ncm-spoiler": "",
|
|
1572
|
+
open: block.open,
|
|
1573
|
+
className: cn("rounded-lg border border-border bg-card p-4", className),
|
|
1574
|
+
children: [
|
|
1575
|
+
/* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-medium", children: block.summary }),
|
|
1576
|
+
/* @__PURE__ */ jsx(ChildBlocks, { blocks: block.children, className: "mt-2 space-y-2" })
|
|
1577
|
+
]
|
|
1578
|
+
}
|
|
1579
|
+
);
|
|
1580
|
+
}
|
|
1581
|
+
function TableBlock({ block, className }) {
|
|
1582
|
+
return /* @__PURE__ */ jsx(
|
|
1583
|
+
"div",
|
|
1584
|
+
{
|
|
1585
|
+
"data-ncm-block": block.id,
|
|
1586
|
+
"data-ncm-stable": block.stableId,
|
|
1587
|
+
"data-ncm-type": block.type,
|
|
1588
|
+
"data-block-id": block.id,
|
|
1589
|
+
"data-ncm-table": "",
|
|
1590
|
+
className: cn("w-full overflow-x-auto overflow-y-hidden", className),
|
|
1591
|
+
children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
|
|
1592
|
+
/* @__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)) }) }),
|
|
1593
|
+
/* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
|
|
1594
|
+
const rowKey = block.rowIds?.[rowIndex] ?? `${block.id}.${rowIndex + 1}`;
|
|
1595
|
+
return /* @__PURE__ */ jsx("tr", { "data-ncm-table-row": "", children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx("td", { "data-ncm-table-cell": "", children: /* @__PURE__ */ jsx(InlineContent, { content: cell }) }, `${rowKey}.${cellIndex + 1}`)) }, rowKey);
|
|
1596
|
+
}) })
|
|
1597
|
+
] })
|
|
1598
|
+
}
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
function TaskItems({ items }) {
|
|
1602
|
+
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
1603
|
+
const status = item.checked ? "Completed" : "Incomplete";
|
|
1604
|
+
const text = serializeInlineContent(item.content);
|
|
1605
|
+
return /* @__PURE__ */ jsxs(
|
|
1606
|
+
"li",
|
|
1607
|
+
{
|
|
1608
|
+
"data-ncm-task-item": "",
|
|
1609
|
+
"data-block-id": item.id,
|
|
1610
|
+
"data-ncm-checked": item.checked ? "true" : "false",
|
|
1611
|
+
className: "flex flex-col",
|
|
1612
|
+
children: [
|
|
1613
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
1614
|
+
/* @__PURE__ */ jsx(
|
|
1615
|
+
"input",
|
|
1616
|
+
{
|
|
1617
|
+
type: "checkbox",
|
|
1618
|
+
checked: item.checked,
|
|
1619
|
+
disabled: true,
|
|
1620
|
+
readOnly: true,
|
|
1621
|
+
"aria-label": `${status} task`,
|
|
1622
|
+
className: "size-4 shrink-0"
|
|
1623
|
+
}
|
|
1624
|
+
),
|
|
1625
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
1626
|
+
/* @__PURE__ */ jsxs("span", { "data-ncm-task-status": "", className: "sr-only", children: [
|
|
1627
|
+
status,
|
|
1628
|
+
":",
|
|
1629
|
+
" "
|
|
1630
|
+
] }),
|
|
1631
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
1632
|
+
] })
|
|
1633
|
+
] }),
|
|
1634
|
+
item.children ? /* @__PURE__ */ jsx("ul", { role: "list", "data-ncm-list-nested": "", className: "ml-6 list-none", children: /* @__PURE__ */ jsx(TaskItems, { items: item.children.items }) }) : null
|
|
1635
|
+
]
|
|
1636
|
+
},
|
|
1637
|
+
item.stableId ?? item.id
|
|
1638
|
+
);
|
|
1639
|
+
}) });
|
|
1640
|
+
}
|
|
1641
|
+
function TaskListBlock({ block, className }) {
|
|
1642
|
+
return /* @__PURE__ */ jsx(
|
|
1643
|
+
BlockShell,
|
|
1644
|
+
{
|
|
1645
|
+
as: "ul",
|
|
1646
|
+
block,
|
|
1647
|
+
role: "list",
|
|
1648
|
+
"data-ncm-task-list": "",
|
|
1649
|
+
className: cn("list-none space-y-1", className),
|
|
1650
|
+
children: /* @__PURE__ */ jsx(TaskItems, { items: block.items })
|
|
1651
|
+
}
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
// src/lib/defaults.ts
|
|
1656
|
+
function fallbackSource(block) {
|
|
1657
|
+
const maybeSource = block;
|
|
1658
|
+
if (typeof maybeSource.raw === "string" && maybeSource.raw.length > 0) {
|
|
1659
|
+
return maybeSource.raw;
|
|
1660
|
+
}
|
|
1661
|
+
if (typeof maybeSource.content === "string" && maybeSource.content.length > 0) {
|
|
1662
|
+
return maybeSource.content;
|
|
1663
|
+
}
|
|
1664
|
+
return JSON.stringify(block, null, 2);
|
|
1665
|
+
}
|
|
1666
|
+
function FallbackBlock({ block, className }) {
|
|
1667
|
+
return createElement(
|
|
1668
|
+
"pre",
|
|
1669
|
+
{
|
|
1670
|
+
"data-ncm-block": block.id,
|
|
1671
|
+
"data-ncm-stable": block.stableId,
|
|
1672
|
+
"data-ncm-type": block.type,
|
|
1673
|
+
"data-block-id": block.id,
|
|
1674
|
+
"data-ncm-fallback": "",
|
|
1675
|
+
className: cn(
|
|
1676
|
+
"overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
|
|
1677
|
+
className
|
|
1678
|
+
)
|
|
1679
|
+
},
|
|
1680
|
+
createElement("code", null, fallbackSource(block))
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
var defaultRenderers = {
|
|
1684
|
+
// Standard blocks
|
|
1685
|
+
paragraph: ParagraphBlock,
|
|
1686
|
+
header: HeaderBlock,
|
|
1687
|
+
blockquote: BlockquoteBlock,
|
|
1688
|
+
code: CodeBlock,
|
|
1689
|
+
container: ContainerBlock,
|
|
1690
|
+
frontmatter: FrontmatterBlock,
|
|
1691
|
+
html: HtmlBlock,
|
|
1692
|
+
list_ordered: ListBlock,
|
|
1693
|
+
list_unordered: ListBlock,
|
|
1694
|
+
table: TableBlock,
|
|
1695
|
+
embed: EmbedBlock,
|
|
1696
|
+
embedding: EmbeddingBlock,
|
|
1697
|
+
latex_display: LatexDisplayBlock,
|
|
1698
|
+
horizontal_rule: HorizontalRuleBlock,
|
|
1699
|
+
page_breaker: PageBreakerBlock,
|
|
1700
|
+
// Promoted blocks
|
|
1701
|
+
link: LinkBlock,
|
|
1702
|
+
figure: FigureBlock,
|
|
1703
|
+
// Extension blocks
|
|
1704
|
+
admonition: AdmonitionBlock,
|
|
1705
|
+
footnote: FootnoteBlock,
|
|
1706
|
+
task_list: TaskListBlock,
|
|
1707
|
+
definition: DefinitionBlock,
|
|
1708
|
+
spoiler: SpoilerBlock,
|
|
1709
|
+
aside: AsideBlock,
|
|
1710
|
+
attribution: AttributionBlock,
|
|
1711
|
+
// Promoted code blocks
|
|
1712
|
+
mermaid: MermaidBlock,
|
|
1713
|
+
dataview: DataviewBlock,
|
|
1714
|
+
math: MathBlock,
|
|
1715
|
+
chart: ChartBlock,
|
|
1716
|
+
// custom_code is handled separately by language (see NcmBlock dispatch)
|
|
1717
|
+
custom_code: {},
|
|
1718
|
+
fallback: FallbackBlock
|
|
1719
|
+
};
|
|
1720
|
+
function CustomCodeBlock({ block, className }) {
|
|
1721
|
+
return /* @__PURE__ */ jsxs(
|
|
1722
|
+
"div",
|
|
1723
|
+
{
|
|
1724
|
+
role: "region",
|
|
1725
|
+
"aria-label": `Custom code block: ${block.language}`,
|
|
1726
|
+
"data-ncm-block": block.id,
|
|
1727
|
+
"data-ncm-stable": block.stableId,
|
|
1728
|
+
"data-ncm-type": block.type,
|
|
1729
|
+
"data-block-id": block.id,
|
|
1730
|
+
"data-ncm-custom-code": "",
|
|
1731
|
+
"data-ncm-language": block.language,
|
|
1732
|
+
className: cn("overflow-x-auto overflow-y-hidden", className),
|
|
1733
|
+
children: [
|
|
1734
|
+
/* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
|
|
1735
|
+
/* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
|
|
1736
|
+
]
|
|
1737
|
+
}
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
var NcmBlockErrorBoundary = class extends Component {
|
|
1741
|
+
state = {
|
|
1742
|
+
error: null
|
|
1743
|
+
};
|
|
1744
|
+
static getDerivedStateFromError(error) {
|
|
1745
|
+
return { error };
|
|
1746
|
+
}
|
|
1747
|
+
componentDidCatch(error, info) {
|
|
1748
|
+
console.warn(
|
|
1749
|
+
`[ncm-ui] Renderer for block '${this.props.block.type}' failed; rendering fallback.`,
|
|
1750
|
+
{ block: this.props.block, error, info }
|
|
1751
|
+
);
|
|
1752
|
+
}
|
|
1753
|
+
render() {
|
|
1754
|
+
if (this.state.error) {
|
|
1755
|
+
return /* @__PURE__ */ jsx(FallbackBlock, { block: this.props.block, className: this.props.className });
|
|
1756
|
+
}
|
|
1757
|
+
return this.props.children;
|
|
1758
|
+
}
|
|
1759
|
+
};
|
|
1760
|
+
function warnMissingRenderer(block) {
|
|
1761
|
+
console.warn(
|
|
1762
|
+
`[ncm-ui] No renderer registered for block type '${block.type}'; rendering fallback.`,
|
|
1763
|
+
{ block }
|
|
1764
|
+
);
|
|
1765
|
+
}
|
|
1766
|
+
function NcmBlock({ block, className, renderers }) {
|
|
1767
|
+
const contextRenderers = useNcmConfig().renderers;
|
|
1768
|
+
const mergedRenderers = { ...defaultRenderers, ...contextRenderers, ...renderers };
|
|
1769
|
+
let content = null;
|
|
1770
|
+
if (block.type === "custom_code") {
|
|
1771
|
+
const customCodeBlock = block;
|
|
1772
|
+
const customCodeRenderers = {
|
|
1773
|
+
...defaultRenderers.custom_code,
|
|
1774
|
+
...contextRenderers?.custom_code,
|
|
1775
|
+
...renderers?.custom_code
|
|
1776
|
+
};
|
|
1777
|
+
const LanguageRenderer = customCodeRenderers[customCodeBlock.language];
|
|
1778
|
+
content = LanguageRenderer ? /* @__PURE__ */ jsx(LanguageRenderer, { block: customCodeBlock, className }) : (
|
|
1779
|
+
// Fallback: use default CustomCodeBlock renderer
|
|
1780
|
+
/* @__PURE__ */ jsx(CustomCodeBlock, { block: customCodeBlock, className })
|
|
1781
|
+
);
|
|
1782
|
+
} else {
|
|
1783
|
+
const blockType = block.type;
|
|
1784
|
+
const Renderer = mergedRenderers[blockType];
|
|
1785
|
+
if (Renderer) {
|
|
1786
|
+
content = /* @__PURE__ */ jsx(Renderer, { block, className });
|
|
1787
|
+
} else if (mergedRenderers.fallback) {
|
|
1788
|
+
warnMissingRenderer(block);
|
|
1789
|
+
content = /* @__PURE__ */ jsx(mergedRenderers.fallback, { block, className });
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
return /* @__PURE__ */ jsx(BlockReferenceScope, { blockId: block.id, children: /* @__PURE__ */ jsx(NcmBlockErrorBoundary, { block, className, children: content }) });
|
|
1793
|
+
}
|
|
1794
|
+
function quoteBlocks(block) {
|
|
1795
|
+
try {
|
|
1796
|
+
const doc = parseNcm(block.content, {
|
|
1797
|
+
preset: "ncm-full",
|
|
1798
|
+
allowMissingFrontmatter: true,
|
|
1799
|
+
// Attribution off, as the NUU Editor's bridge keeps it: the promoter's
|
|
1800
|
+
// trigger is any last quote line starting with `-`, so a nested quote
|
|
1801
|
+
// ending in a list item would lose that item to a `— Author` line.
|
|
1802
|
+
blockOptions: { extensions: { attribution: false } }
|
|
1803
|
+
});
|
|
1804
|
+
const blocks = doc.blocks ?? [];
|
|
1805
|
+
if (blocks.length === 0 || blocks.some((child) => child.type === "frontmatter")) {
|
|
1806
|
+
return null;
|
|
1807
|
+
}
|
|
1808
|
+
return blocks.map((child, index) => ({ ...child, id: `${block.id}.${index + 1}`, stableId: void 0 }));
|
|
1809
|
+
} catch {
|
|
1810
|
+
return null;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
function QuotedLines({ content }) {
|
|
1814
|
+
const lines = content.split("\n");
|
|
1815
|
+
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)) });
|
|
1816
|
+
}
|
|
638
1817
|
function BlockquoteBlock({ block, className }) {
|
|
639
|
-
const
|
|
1818
|
+
const multiline = block.content.includes("\n");
|
|
1819
|
+
const blocks = useMemo(() => multiline ? quoteBlocks(block) : null, [block, multiline]);
|
|
640
1820
|
return /* @__PURE__ */ jsx(
|
|
641
1821
|
"blockquote",
|
|
642
1822
|
{
|
|
@@ -646,7 +1826,9 @@ function BlockquoteBlock({ block, className }) {
|
|
|
646
1826
|
"data-block-id": block.id,
|
|
647
1827
|
"data-ncm-blockquote": "",
|
|
648
1828
|
className,
|
|
649
|
-
children:
|
|
1829
|
+
children: !multiline ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : blocks === null ? /* @__PURE__ */ jsx(QuotedLines, { content: block.content }) : blocks.map(
|
|
1830
|
+
(child) => child.type === "paragraph" ? /* @__PURE__ */ jsx(QuotedLines, { content: child.content ?? "" }, blockKey(child)) : /* @__PURE__ */ jsx(NcmBlock, { block: child }, blockKey(child))
|
|
1831
|
+
)
|
|
650
1832
|
}
|
|
651
1833
|
);
|
|
652
1834
|
}
|