@ai-matrx/rich-content 0.0.0-stage → 0.2.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/CHANGELOG.md +72 -0
- package/LICENSE +21 -0
- package/README.md +61 -2
- package/dist/display/blocks/csv/CsvBlock.d.ts +10 -0
- package/dist/display/blocks/csv/CsvBlock.js +245 -0
- package/dist/display/blocks/table/parseMarkdownTable.d.ts +20 -0
- package/dist/display/blocks/table/parseMarkdownTable.js +35 -0
- package/dist/display/chat-markdown/citations/remarkMatrxCite.d.ts +33 -0
- package/dist/display/chat-markdown/citations/remarkMatrxCite.js +71 -0
- package/dist/display/chat-markdown/matrx-variables/remarkMatrxVariable.d.ts +29 -0
- package/dist/display/chat-markdown/matrx-variables/remarkMatrxVariable.js +71 -0
- package/dist/display/chat-markdown/page-break/remarkMatrxPageBreak.d.ts +55 -0
- package/dist/display/chat-markdown/page-break/remarkMatrxPageBreak.js +108 -0
- package/dist/display/chat-markdown/rehypeSafeRawHtml.d.ts +59 -0
- package/dist/display/chat-markdown/rehypeSafeRawHtml.js +140 -0
- package/dist/display/markdown-classification/processors/bock-processors/parse-markdown-table.d.ts +14 -0
- package/dist/display/markdown-classification/processors/bock-processors/parse-markdown-table.js +171 -0
- package/dist/display/markdown-classification/processors/types.d.ts +120 -0
- package/dist/display/markdown-classification/processors/types.js +10 -0
- package/dist/display/markdown-classification/processors/utils/client-blocks.d.ts +169 -0
- package/dist/display/markdown-classification/processors/utils/client-blocks.js +0 -0
- package/dist/display/markdown-classification/processors/utils/content-splitter-core.d.ts +223 -0
- package/dist/display/markdown-classification/processors/utils/content-splitter-core.js +1791 -0
- package/dist/display/markdown-classification/processors/utils/content-splitter-v2.d.ts +15 -0
- package/dist/display/markdown-classification/processors/utils/content-splitter-v2.js +19 -0
- package/dist/display/markdown-classification/processors/utils/expand-text-blocks.d.ts +9 -0
- package/dist/display/markdown-classification/processors/utils/expand-text-blocks.js +36 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-lines.d.ts +5 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-lines.js +40 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-vector-inputs.d.ts +16 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-vector-inputs.js +385 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-vectors.d.ts +43 -0
- package/dist/display/markdown-classification/processors/utils/gfm-table-vectors.js +33 -0
- package/dist/display/markdown-classification/processors/utils/table-data-parser.d.ts +9 -0
- package/dist/display/markdown-classification/processors/utils/table-data-parser.js +30 -0
- package/dist/display/markdown-classification/processors/utils/thinking-parser.d.ts +7 -0
- package/dist/display/markdown-classification/processors/utils/thinking-parser.js +70 -0
- package/dist/display/render-block.d.ts +23 -0
- package/dist/display/render-block.js +0 -0
- package/dist/display/themes.d.ts +1023 -0
- package/dist/display/themes.js +1105 -0
- package/dist/display/types.d.ts +32 -0
- package/dist/display/types.js +0 -0
- package/dist/host/ContentIrHostBoundary.d.ts +8 -0
- package/dist/host/ContentIrHostBoundary.js +15 -0
- package/dist/host/ErrorActions.d.ts +4 -0
- package/dist/host/ErrorActions.js +11 -0
- package/dist/host/NestedContent.d.ts +3 -0
- package/dist/host/NestedContent.js +12 -0
- package/dist/host/ResourcePeek.d.ts +6 -0
- package/dist/host/ResourcePeek.js +14 -0
- package/dist/host/component-registry.d.ts +2 -0
- package/dist/host/component-registry.js +25 -0
- package/dist/host/diagnostics.d.ts +2 -0
- package/dist/host/diagnostics.js +15 -0
- package/dist/host/index.d.ts +3 -0
- package/dist/host/index.js +18 -0
- package/dist/host/kind-incident.d.ts +3 -0
- package/dist/host/kind-incident.js +12 -0
- package/dist/host/kind-registry.d.ts +2 -0
- package/dist/host/kind-registry.js +35 -0
- package/dist/host/people.d.ts +3 -0
- package/dist/host/people.js +12 -0
- package/dist/host/registry.d.ts +27 -0
- package/dist/host/registry.js +55 -0
- package/dist/host/splitter-envelopes.d.ts +2 -0
- package/dist/host/splitter-envelopes.js +7 -0
- package/dist/host/tables.d.ts +6 -0
- package/dist/host/tables.js +8 -0
- package/dist/host/toast.d.ts +2 -0
- package/dist/host/toast.js +57 -0
- package/dist/host/types.d.ts +157 -0
- package/dist/host/types.js +0 -0
- package/dist/host/wikilinks.d.ts +15 -0
- package/dist/host/wikilinks.js +23 -0
- package/dist/kinds/host/route-env.d.ts +33 -0
- package/dist/kinds/host/route-env.js +16 -0
- package/dist/kinds/react/KindEscapedNotice.d.ts +14 -0
- package/dist/kinds/react/KindEscapedNotice.js +72 -0
- package/dist/kinds/react/ProvisionalKindBoundary.d.ts +19 -0
- package/dist/kinds/react/ProvisionalKindBoundary.js +17 -0
- package/dist/kinds/react/ensure-kind-renderable.d.ts +14 -0
- package/dist/kinds/react/ensure-kind-renderable.js +45 -0
- package/dist/kinds/react/kind-problems.d.ts +62 -0
- package/dist/kinds/react/kind-problems.js +134 -0
- package/dist/kinds/react/kind-route.d.ts +23 -0
- package/dist/kinds/react/kind-route.js +24 -0
- package/dist/kinds/react/loading/infer-loading-slug.d.ts +58 -0
- package/dist/kinds/react/loading/infer-loading-slug.js +100 -0
- package/dist/kinds/react/loading/kind-loading-components.d.ts +48 -0
- package/dist/kinds/react/loading/kind-loading-components.js +447 -0
- package/dist/kinds/react/loading/kind-loading-registry.d.ts +21 -0
- package/dist/kinds/react/loading/kind-loading-registry.js +62 -0
- package/dist/kinds/react/loading/kind-loading-slugs.d.ts +18 -0
- package/dist/kinds/react/loading/kind-loading-slugs.js +34 -0
- package/dist/kinds/react/loading/kind-loading.types.d.ts +79 -0
- package/dist/kinds/react/loading/kind-loading.types.js +31 -0
- package/dist/kinds/react/loading/resolve-loading-slug.d.ts +29 -0
- package/dist/kinds/react/loading/resolve-loading-slug.js +51 -0
- package/dist/kinds/react/partial-kind-route.d.ts +32 -0
- package/dist/kinds/react/partial-kind-route.js +27 -0
- package/dist/kinds/react/registry-versioned.d.ts +54 -0
- package/dist/kinds/react/registry-versioned.js +18 -0
- package/dist/kinds/react/route-at-version.d.ts +38 -0
- package/dist/kinds/react/route-at-version.js +78 -0
- package/dist/kinds/react/slot/KindSlot.d.ts +87 -0
- package/dist/kinds/react/slot/KindSlot.js +65 -0
- package/dist/kinds/react/use-registry-repaint.d.ts +6 -0
- package/dist/kinds/react/use-registry-repaint.js +36 -0
- package/dist/kinds/react/useIrNode.d.ts +9 -0
- package/dist/kinds/react/useIrNode.js +46 -0
- package/dist/kinds/react/useLiveJsonRegion.d.ts +15 -0
- package/dist/kinds/react/useLiveJsonRegion.js +84 -0
- package/dist/kinds/redux/render-block-envelope.d.ts +14 -0
- package/dist/kinds/redux/render-block-envelope.js +26 -0
- package/dist/kinds/registry/kind-correctors.d.ts +63 -0
- package/dist/kinds/registry/kind-correctors.js +94 -0
- package/dist/kinds/registry/legacy-quiz-envelope.d.ts +1 -0
- package/dist/kinds/registry/legacy-quiz-envelope.js +1 -0
- package/dist/kinds/registry/region-envelope-memo.d.ts +45 -0
- package/dist/kinds/registry/region-envelope-memo.js +94 -0
- package/dist/kinds/registry/registry-debug.d.ts +38 -0
- package/dist/kinds/registry/registry-debug.js +39 -0
- package/dist/markdown-core/MarkdownCore.d.ts +6 -0
- package/dist/markdown-core/MarkdownCore.js +32 -0
- package/dist/markdown-core/MarkdownCoreImpl.d.ts +3 -0
- package/dist/markdown-core/MarkdownCoreImpl.js +27 -0
- package/dist/markdown-core/MarkdownCoreServer.d.ts +4 -0
- package/dist/markdown-core/MarkdownCoreServer.js +26 -0
- package/dist/markdown-core/heading-anchors-context.d.ts +2 -0
- package/dist/markdown-core/heading-anchors-context.js +11 -0
- package/dist/markdown-core/heading-anchors-props.d.ts +2 -0
- package/dist/markdown-core/heading-anchors-props.js +6 -0
- package/dist/markdown-core/markdown-core-html.d.ts +3 -0
- package/dist/markdown-core/markdown-core-html.js +33 -0
- package/dist/markdown-core/markdown-core-presets.d.ts +22 -0
- package/dist/markdown-core/markdown-core-presets.js +118 -0
- package/dist/markdown-core/markdown-core-types.d.ts +43 -0
- package/dist/markdown-core/markdown-core-types.js +0 -0
- package/dist/markdown-core/math/vendor/micromark-math-math-flow.d.ts +15 -0
- package/dist/markdown-core/math/vendor/micromark-math-math-flow.js +143 -0
- package/dist/markdown-core/math/vendor/micromark-math-math-text.d.ts +24 -0
- package/dist/markdown-core/math/vendor/micromark-math-math-text.js +127 -0
- package/dist/markdown-core/math/vendor/micromark-math-syntax.d.ts +30 -0
- package/dist/markdown-core/math/vendor/micromark-math-syntax.js +15 -0
- package/dist/markdown-core/math/vendor/rehype-katex.d.ts +15 -0
- package/dist/markdown-core/math/vendor/rehype-katex.js +83 -0
- package/dist/markdown-core/math/vendor/remark-math.d.ts +9 -0
- package/dist/markdown-core/math/vendor/remark-math.js +20 -0
- package/dist/markdown-core/math-normalizer.d.ts +57 -0
- package/dist/markdown-core/math-normalizer.js +315 -0
- package/dist/markdown-core/plain-title.d.ts +2 -0
- package/dist/markdown-core/plain-title.js +1 -0
- package/dist/markdown-core/stream-heal.d.ts +2 -0
- package/dist/markdown-core/stream-heal.js +184 -0
- package/dist/markdown-core/streaming-context.d.ts +2 -0
- package/dist/markdown-core/streaming-context.js +11 -0
- package/dist/markdown-core/syntax/callout-types.d.ts +9 -0
- package/dist/markdown-core/syntax/callout-types.js +101 -0
- package/dist/markdown-core/syntax/containers.d.ts +17 -0
- package/dist/markdown-core/syntax/containers.js +353 -0
- package/dist/markdown-core/syntax/document-numbering.d.ts +52 -0
- package/dist/markdown-core/syntax/document-numbering.js +184 -0
- package/dist/markdown-core/syntax/elements/CalloutIcon.d.ts +3 -0
- package/dist/markdown-core/syntax/elements/CalloutIcon.js +41 -0
- package/dist/markdown-core/syntax/elements/CrossRef.d.ts +12 -0
- package/dist/markdown-core/syntax/elements/CrossRef.js +57 -0
- package/dist/markdown-core/syntax/elements/CsvFence.d.ts +4 -0
- package/dist/markdown-core/syntax/elements/CsvFence.js +18 -0
- package/dist/markdown-core/syntax/elements/DetailsElements.d.ts +12 -0
- package/dist/markdown-core/syntax/elements/DetailsElements.js +38 -0
- package/dist/markdown-core/syntax/elements/DocumentNumbering.d.ts +20 -0
- package/dist/markdown-core/syntax/elements/DocumentNumbering.js +37 -0
- package/dist/markdown-core/syntax/elements/DocumentPropertiesPanel.d.ts +4 -0
- package/dist/markdown-core/syntax/elements/DocumentPropertiesPanel.js +46 -0
- package/dist/markdown-core/syntax/elements/InDocAnchor.d.ts +11 -0
- package/dist/markdown-core/syntax/elements/InDocAnchor.js +87 -0
- package/dist/markdown-core/syntax/elements/MarkdownSourceEdit.d.ts +24 -0
- package/dist/markdown-core/syntax/elements/MarkdownSourceEdit.js +28 -0
- package/dist/markdown-core/syntax/elements/MatrxTabs.d.ts +10 -0
- package/dist/markdown-core/syntax/elements/MatrxTabs.js +59 -0
- package/dist/markdown-core/syntax/elements/MentionChip.d.ts +7 -0
- package/dist/markdown-core/syntax/elements/MentionChip.js +69 -0
- package/dist/markdown-core/syntax/elements/NestedBody.d.ts +3 -0
- package/dist/markdown-core/syntax/elements/NestedBody.js +13 -0
- package/dist/markdown-core/syntax/elements/TableOfContents.d.ts +5 -0
- package/dist/markdown-core/syntax/elements/TableOfContents.js +44 -0
- package/dist/markdown-core/syntax/elements/TaskCheckbox.d.ts +7 -0
- package/dist/markdown-core/syntax/elements/TaskCheckbox.js +63 -0
- package/dist/markdown-core/syntax/elements/WikiEmbed.d.ts +7 -0
- package/dist/markdown-core/syntax/elements/WikiEmbed.js +68 -0
- package/dist/markdown-core/syntax/elements/WikiLink.d.ts +10 -0
- package/dist/markdown-core/syntax/elements/WikiLink.js +114 -0
- package/dist/markdown-core/syntax/elements/core-syntax-elements.d.ts +22 -0
- package/dist/markdown-core/syntax/elements/core-syntax-elements.js +70 -0
- package/dist/markdown-core/syntax/elements/find-in-document.d.ts +3 -0
- package/dist/markdown-core/syntax/elements/find-in-document.js +20 -0
- package/dist/markdown-core/syntax/elements/wiki-target.d.ts +5 -0
- package/dist/markdown-core/syntax/elements/wiki-target.js +8 -0
- package/dist/markdown-core/syntax/frontmatter.d.ts +26 -0
- package/dist/markdown-core/syntax/frontmatter.js +72 -0
- package/dist/markdown-core/syntax/gfm-cell-pipes.d.ts +11 -0
- package/dist/markdown-core/syntax/gfm-cell-pipes.js +4 -0
- package/dist/markdown-core/syntax/inline-syntax.d.ts +26 -0
- package/dist/markdown-core/syntax/inline-syntax.js +163 -0
- package/dist/markdown-core/syntax/linear-scan.d.ts +46 -0
- package/dist/markdown-core/syntax/linear-scan.js +129 -0
- package/dist/markdown-core/syntax/mdast-helpers.d.ts +48 -0
- package/dist/markdown-core/syntax/mdast-helpers.js +48 -0
- package/dist/markdown-core/syntax/mentions.d.ts +2 -0
- package/dist/markdown-core/syntax/mentions.js +42 -0
- package/dist/markdown-core/syntax/names.d.ts +6 -0
- package/dist/markdown-core/syntax/names.js +18 -0
- package/dist/markdown-core/syntax/prepare-syntax-source.d.ts +1 -0
- package/dist/markdown-core/syntax/prepare-syntax-source.js +78 -0
- package/dist/markdown-core/syntax/rehype-matrx-syntax.d.ts +9 -0
- package/dist/markdown-core/syntax/rehype-matrx-syntax.js +180 -0
- package/dist/markdown-core/syntax/remark-inline-only.d.ts +23 -0
- package/dist/markdown-core/syntax/remark-inline-only.js +25 -0
- package/dist/markdown-core/syntax/remark-matrx-syntax.d.ts +7 -0
- package/dist/markdown-core/syntax/remark-matrx-syntax.js +351 -0
- package/dist/markdown-core/syntax/remark-table-code-pipes.d.ts +7 -0
- package/dist/markdown-core/syntax/remark-table-code-pipes.js +23 -0
- package/dist/markdown-core/syntax/stream-heal-syntax.d.ts +2 -0
- package/dist/markdown-core/syntax/stream-heal-syntax.js +108 -0
- package/dist/markdown-core/syntax/task-source.d.ts +10 -0
- package/dist/markdown-core/syntax/task-source.js +34 -0
- package/dist/markdown-core/syntax/useDocumentProperties.d.ts +3 -0
- package/dist/markdown-core/syntax/useDocumentProperties.js +8 -0
- package/dist/styles.css +0 -0
- package/dist/utils/addressWithoutNavigating.d.ts +68 -0
- package/dist/utils/addressWithoutNavigating.js +60 -0
- package/dist/utils/client-lazy.d.ts +13 -0
- package/dist/utils/client-lazy.js +24 -0
- package/dist/utils/decision-options.d.ts +21 -0
- package/dist/utils/decision-options.js +32 -0
- package/dist/utils/gfm-lexer.d.ts +5 -0
- package/dist/utils/gfm-lexer.js +10 -0
- package/dist/utils/json.d.ts +63 -0
- package/dist/utils/json.js +22 -0
- package/dist/utils/plain-title.d.ts +25 -0
- package/dist/utils/plain-title.js +51 -0
- package/dist/utils/table-source.d.ts +62 -0
- package/dist/utils/table-source.js +191 -0
- package/dist/utils/youtube.d.ts +52 -0
- package/dist/utils/youtube.js +137 -0
- package/package.json +134 -4
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { DirectiveContainerTracker } from "@ai-matrx/content-ir/source";
|
|
2
|
+
import { TITLED_IMAGE_LINE } from "@ai-matrx/content-ir/source";
|
|
3
|
+
import { collectLinkDefinitions, fenceLineKinds } from "@ai-matrx/content-ir/source";
|
|
4
|
+
import { sectionHeading } from "./linear-scan.js";
|
|
5
|
+
const FIGURE_OPEN = /^[ \t]{0,3}:{3,}(figure|table)(?:\[((?:[^\]\\]|\\.)*)\])?(?:\{([^}]*)\})?/i;
|
|
6
|
+
const LABEL = /\\label\{([^{}]+)\}/g;
|
|
7
|
+
const TAG = /\\tag\*?\{([^{}]*)\}/;
|
|
8
|
+
function captionKey(kind, caption) {
|
|
9
|
+
return `${kind}|${caption.replace(/[*_`~=]/g, "").replace(/\s+/g, " ").trim().toLowerCase()}`;
|
|
10
|
+
}
|
|
11
|
+
function idFromAttrs(attrs) {
|
|
12
|
+
if (!attrs) return null;
|
|
13
|
+
const hash = /(?:^|\s)#([\w:.-]+)/.exec(attrs);
|
|
14
|
+
if (hash) return hash[1] ?? null;
|
|
15
|
+
const id = /(?:^|\s)id=["']?([\w:.-]+)/.exec(attrs);
|
|
16
|
+
return id ? id[1] ?? null : null;
|
|
17
|
+
}
|
|
18
|
+
function displayMath(text) {
|
|
19
|
+
const out = [];
|
|
20
|
+
const finder = (needle) => {
|
|
21
|
+
let askedFrom = -1;
|
|
22
|
+
let answer = -1;
|
|
23
|
+
return (from) => {
|
|
24
|
+
if (askedFrom < 0 || from < askedFrom || answer !== -1 && answer < from) {
|
|
25
|
+
askedFrom = from;
|
|
26
|
+
answer = text.indexOf(needle, from);
|
|
27
|
+
}
|
|
28
|
+
return answer;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const openDollar = finder("$$");
|
|
32
|
+
const closeDollar = finder("$$");
|
|
33
|
+
const openBracket = finder("\\[");
|
|
34
|
+
const closeBracket = finder("\\]");
|
|
35
|
+
let pos = 0;
|
|
36
|
+
while (pos < text.length) {
|
|
37
|
+
const d = openDollar(pos);
|
|
38
|
+
const b = openBracket(pos);
|
|
39
|
+
if (d === -1 && b === -1) break;
|
|
40
|
+
const at = d !== -1 && (b === -1 || d < b) ? d : b;
|
|
41
|
+
const dollar = at === d;
|
|
42
|
+
const end = dollar ? closeDollar(at + 2) : closeBracket(at + 2);
|
|
43
|
+
if (end === -1) {
|
|
44
|
+
pos = at + 1;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
out.push(text.slice(at + 2, end));
|
|
48
|
+
pos = end + 2;
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
function computeDocumentNumbering(source) {
|
|
53
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
54
|
+
const byCaption = /* @__PURE__ */ new Map();
|
|
55
|
+
const footnotes = /* @__PURE__ */ new Map();
|
|
56
|
+
if (!source) return { byLabel, byCaption, footnotes, footnoteMarkdown: "", linkDefinitions: "" };
|
|
57
|
+
const kinds = fenceLineKinds(source);
|
|
58
|
+
const prose = source.split("\n").map((line, i) => kinds[i] === "prose" ? line : "");
|
|
59
|
+
let figures = 0;
|
|
60
|
+
let tables = 0;
|
|
61
|
+
let insideFigure = null;
|
|
62
|
+
const addCaption = (key, display) => {
|
|
63
|
+
const list = byCaption.get(key) ?? [];
|
|
64
|
+
list.push(display);
|
|
65
|
+
byCaption.set(key, list);
|
|
66
|
+
};
|
|
67
|
+
for (const line of prose) {
|
|
68
|
+
if (insideFigure) {
|
|
69
|
+
if (insideFigure.consume(line)) insideFigure = null;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (TITLED_IMAGE_LINE.test(line)) {
|
|
73
|
+
const title = /\s(?:"([^"\n]+)"|'([^'\n]+)')\s*\)[ \t]*$/.exec(line);
|
|
74
|
+
addCaption(captionKey("fig", title?.[1] ?? title?.[2] ?? ""), `Figure ${++figures}`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const fig = FIGURE_OPEN.exec(line);
|
|
78
|
+
if (fig) {
|
|
79
|
+
insideFigure = new DirectiveContainerTracker(line);
|
|
80
|
+
const kind = fig[1].toLowerCase() === "table" ? "tbl" : "fig";
|
|
81
|
+
const display = kind === "fig" ? `Figure ${++figures}` : `Table ${++tables}`;
|
|
82
|
+
const id = idFromAttrs(fig[3]);
|
|
83
|
+
if (id) byLabel.set(id, { kind, display });
|
|
84
|
+
else addCaption(captionKey(kind, fig[2] ?? ""), display);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const sec = sectionHeading(line);
|
|
88
|
+
if (sec) byLabel.set(sec[1], { kind: "sec", display: sec[0].trim() });
|
|
89
|
+
}
|
|
90
|
+
let equations = 0;
|
|
91
|
+
for (const body of displayMath(prose.join("\n"))) {
|
|
92
|
+
const labels = [...body.matchAll(LABEL)].map((m) => (m[1] ?? "").trim());
|
|
93
|
+
if (labels.length === 0) continue;
|
|
94
|
+
const tag = TAG.exec(body);
|
|
95
|
+
const display = `(${tag ? tag[1] ?? "" : String(++equations)})`;
|
|
96
|
+
const first = labels[0];
|
|
97
|
+
if (first) byLabel.set(first, { kind: "eq", display });
|
|
98
|
+
}
|
|
99
|
+
const footnoteMarkdown = numberFootnotes(prose, footnotes);
|
|
100
|
+
return { byLabel, byCaption, footnotes, footnoteMarkdown, linkDefinitions: linkDefinitionLines(source) };
|
|
101
|
+
}
|
|
102
|
+
const DOCUMENT_FOOTNOTES_MARKER = "<!-- matrx:document-footnotes -->";
|
|
103
|
+
function documentFootnoteSource(numbering) {
|
|
104
|
+
return numbering?.footnoteMarkdown ? `${DOCUMENT_FOOTNOTES_MARKER}
|
|
105
|
+
|
|
106
|
+
${numbering.footnoteMarkdown}` : "";
|
|
107
|
+
}
|
|
108
|
+
const FOOTNOTE_DEF = /^ {0,3}\[\^([^\]\s]+)\]:[ \t]?(.*)$/;
|
|
109
|
+
const FOOTNOTE_REF = /\[\^([^\]\s]+)\](?!:)/g;
|
|
110
|
+
const INTERRUPTS_NOTE = /^ {0,3}(?:[-+*][ \t]|\d{1,9}[.)][ \t]|>|#{1,6}(?:[ \t]|$)|```|~~~|<|\[\^[^\]\s]+\]:|(?:-[ \t]*){3,}$|(?:\*[ \t]*){3,}$|(?:_[ \t]*){3,}$)/;
|
|
111
|
+
function footnoteRefs(line) {
|
|
112
|
+
if (!line.includes("[^")) return [];
|
|
113
|
+
return [...line.replace(/`+[^`]*`+/g, "").matchAll(FOOTNOTE_REF)].map((m) => (m[1] ?? "").toLowerCase());
|
|
114
|
+
}
|
|
115
|
+
function numberFootnotes(prose, footnotes) {
|
|
116
|
+
const notes = /* @__PURE__ */ new Map();
|
|
117
|
+
const written = /* @__PURE__ */ new Map();
|
|
118
|
+
const body = [];
|
|
119
|
+
for (let i = 0; i < prose.length; i += 1) {
|
|
120
|
+
const def = FOOTNOTE_DEF.exec(prose[i] ?? "");
|
|
121
|
+
if (!def) {
|
|
122
|
+
body.push(prose[i] ?? "");
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const label = (def[1] ?? "").toLowerCase();
|
|
126
|
+
const lines = [def[2] ?? ""];
|
|
127
|
+
const raw = [prose[i] ?? ""];
|
|
128
|
+
let previous = prose[i] ?? "";
|
|
129
|
+
let j = i + 1;
|
|
130
|
+
for (; j < prose.length; j += 1) {
|
|
131
|
+
const line = prose[j] ?? "";
|
|
132
|
+
const indented = /^(?: {4}|\t)/.test(line);
|
|
133
|
+
const lazy = line.trim() !== "" && previous.trim() !== "" && !INTERRUPTS_NOTE.test(line);
|
|
134
|
+
const blankThenIndented = line.trim() === "" && /^(?: {4}|\t)\S/.test(prose[j + 1] ?? "");
|
|
135
|
+
if (!indented && !lazy && !blankThenIndented) break;
|
|
136
|
+
lines.push(line);
|
|
137
|
+
raw.push(line);
|
|
138
|
+
previous = line;
|
|
139
|
+
}
|
|
140
|
+
if (!notes.has(label)) {
|
|
141
|
+
notes.set(label, lines);
|
|
142
|
+
written.set(label, raw);
|
|
143
|
+
}
|
|
144
|
+
i = j - 1;
|
|
145
|
+
}
|
|
146
|
+
if (notes.size === 0) return "";
|
|
147
|
+
const cite = (id) => {
|
|
148
|
+
if (notes.has(id) && !footnotes.has(id)) footnotes.set(id, footnotes.size + 1);
|
|
149
|
+
};
|
|
150
|
+
for (const line of body) footnoteRefs(line).forEach(cite);
|
|
151
|
+
for (const id of footnotes.keys()) for (const line of notes.get(id) ?? []) footnoteRefs(line).forEach(cite);
|
|
152
|
+
return [...footnotes.keys()].map((id) => (written.get(id) ?? []).join("\n").trimEnd()).join("\n\n");
|
|
153
|
+
}
|
|
154
|
+
function sameDocumentNumbering(a, b) {
|
|
155
|
+
if (a === b) return true;
|
|
156
|
+
if (a.linkDefinitions !== b.linkDefinitions || a.footnoteMarkdown !== b.footnoteMarkdown) return false;
|
|
157
|
+
if (a.byLabel.size !== b.byLabel.size || a.byCaption.size !== b.byCaption.size || a.footnotes.size !== b.footnotes.size) return false;
|
|
158
|
+
for (const [k, v] of a.byLabel) {
|
|
159
|
+
const o = b.byLabel.get(k);
|
|
160
|
+
if (!o || o.kind !== v.kind || o.display !== v.display) return false;
|
|
161
|
+
}
|
|
162
|
+
for (const [k, v] of a.byCaption) {
|
|
163
|
+
const o = b.byCaption.get(k);
|
|
164
|
+
if (!o || o.length !== v.length || o.some((d, i) => d !== v[i])) return false;
|
|
165
|
+
}
|
|
166
|
+
for (const [k, v] of a.footnotes) if (b.footnotes.get(k) !== v) return false;
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function linkDefinitionLines(source) {
|
|
170
|
+
if (!source.includes("]:")) return "";
|
|
171
|
+
const lines = [];
|
|
172
|
+
for (const [label, def] of collectLinkDefinitions(source)) {
|
|
173
|
+
const title = def.title === null ? "" : ` "${def.title.replace(/["\\]/g, "\\$&")}"`;
|
|
174
|
+
lines.push(`[${label.replace(/[\[\]\\]/g, "\\$&")}]: <${def.url.replace(/[<>]/g, encodeURIComponent)}>${title}`);
|
|
175
|
+
}
|
|
176
|
+
return lines.join("\n");
|
|
177
|
+
}
|
|
178
|
+
export {
|
|
179
|
+
DOCUMENT_FOOTNOTES_MARKER,
|
|
180
|
+
captionKey,
|
|
181
|
+
computeDocumentNumbering,
|
|
182
|
+
documentFootnoteSource,
|
|
183
|
+
sameDocumentNumbering
|
|
184
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
ChevronRight,
|
|
4
|
+
CircleCheck,
|
|
5
|
+
CircleHelp,
|
|
6
|
+
Info,
|
|
7
|
+
Lightbulb,
|
|
8
|
+
MessageSquareWarning,
|
|
9
|
+
OctagonAlert,
|
|
10
|
+
Pencil,
|
|
11
|
+
Quote,
|
|
12
|
+
TriangleAlert
|
|
13
|
+
} from "lucide-react";
|
|
14
|
+
const ICONS = {
|
|
15
|
+
note: Pencil,
|
|
16
|
+
tip: Lightbulb,
|
|
17
|
+
important: MessageSquareWarning,
|
|
18
|
+
warning: TriangleAlert,
|
|
19
|
+
caution: OctagonAlert,
|
|
20
|
+
info: Info,
|
|
21
|
+
success: CircleCheck,
|
|
22
|
+
question: CircleHelp,
|
|
23
|
+
quote: Quote
|
|
24
|
+
};
|
|
25
|
+
function CalloutIcon(props) {
|
|
26
|
+
const type = props["data-type"] ?? "note";
|
|
27
|
+
if (type === "chevron") {
|
|
28
|
+
return /* @__PURE__ */ jsx(
|
|
29
|
+
ChevronRight,
|
|
30
|
+
{
|
|
31
|
+
"aria-hidden": true,
|
|
32
|
+
className: "ml-auto h-4 w-4 shrink-0 opacity-70 transition-transform group-open/callout:rotate-90"
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
const Icon = ICONS[type] ?? Info;
|
|
37
|
+
return /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: "h-4 w-4 shrink-0" });
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
CalloutIcon
|
|
41
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
interface CrossRefProps {
|
|
3
|
+
href?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
"data-xref"?: string;
|
|
7
|
+
"data-xref-kind"?: string;
|
|
8
|
+
"data-xref-style"?: string;
|
|
9
|
+
"data-xref-resolved"?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function CrossRef(props: CrossRefProps): import("react").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { cn } from "@ai-matrx/design-system";
|
|
5
|
+
import { InDocAnchor } from "./InDocAnchor.js";
|
|
6
|
+
import { findInDocument } from "./find-in-document.js";
|
|
7
|
+
function labelFor(target, style) {
|
|
8
|
+
const label = target.getAttribute("data-xref-label");
|
|
9
|
+
if (label) {
|
|
10
|
+
if (label.startsWith("Equation ")) {
|
|
11
|
+
const n = label.slice("Equation ".length);
|
|
12
|
+
return style === "ref" ? n.replace(/[()]/g, "") : n;
|
|
13
|
+
}
|
|
14
|
+
return label;
|
|
15
|
+
}
|
|
16
|
+
if (/^H[1-6]$/.test(target.tagName)) {
|
|
17
|
+
const clone = target.cloneNode(true);
|
|
18
|
+
clone.querySelectorAll("[data-heading-anchor]").forEach((a) => a.remove());
|
|
19
|
+
return (clone.textContent ?? "").trim() || null;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function CrossRef(props) {
|
|
24
|
+
const label = String(props["data-xref"] ?? "");
|
|
25
|
+
const resolvedStatically = props["data-xref-resolved"] === "true";
|
|
26
|
+
const probe = useRef(null);
|
|
27
|
+
const [runtime, setRuntime] = useState(null);
|
|
28
|
+
const [looked, setLooked] = useState(resolvedStatically);
|
|
29
|
+
const style = props["data-xref-style"];
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (resolvedStatically) return;
|
|
32
|
+
const target = findInDocument(probe.current, label);
|
|
33
|
+
setRuntime(target ? labelFor(target, style) : null);
|
|
34
|
+
setLooked(true);
|
|
35
|
+
}, [label, resolvedStatically, style]);
|
|
36
|
+
if (resolvedStatically || runtime) {
|
|
37
|
+
return /* @__PURE__ */ jsx(InDocAnchor, { href: `#${label}`, "data-xref": label, "data-content-chrome": "", className: "no-underline hover:underline", children: runtime ?? props.children });
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsxs(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
ref: probe,
|
|
43
|
+
"data-xref": label,
|
|
44
|
+
"data-content-chrome": "",
|
|
45
|
+
"data-xref-missing": looked ? "" : void 0,
|
|
46
|
+
title: props.title,
|
|
47
|
+
className: cn(looked && "rounded-sm bg-amber-500/15 px-0.5 text-amber-700 dark:text-amber-300"),
|
|
48
|
+
children: [
|
|
49
|
+
props.children,
|
|
50
|
+
looked ? "?" : null
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
CrossRef
|
|
57
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { lazy, Suspense } from "react";
|
|
4
|
+
const CsvBlock = lazy(() => import("../../../display/blocks/csv/CsvBlock.js"));
|
|
5
|
+
function CsvFence(props) {
|
|
6
|
+
const source = String(props["data-source"] ?? "");
|
|
7
|
+
const delimiter = props["data-delimiter"] === "tab" ? " " : ",";
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
Suspense,
|
|
10
|
+
{
|
|
11
|
+
fallback: /* @__PURE__ */ jsx("pre", { className: "my-3 overflow-x-auto rounded-md border border-border bg-muted/40 p-3 font-mono text-xs", children: source }),
|
|
12
|
+
children: /* @__PURE__ */ jsx(CsvBlock, { content: source, delimiter, className: "my-3" })
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
CsvFence
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
type Props = {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
open?: boolean;
|
|
6
|
+
id?: string;
|
|
7
|
+
node?: unknown;
|
|
8
|
+
} & Record<string, unknown>;
|
|
9
|
+
export declare function DetailsElement({ children, className, open, id, node: _node, ...rest }: Props): import("react").JSX.Element;
|
|
10
|
+
export declare function SummaryElement({ children, className }: Props): import("react").JSX.Element;
|
|
11
|
+
export declare function KbdElement({ children, className }: Props): import("react").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@ai-matrx/design-system";
|
|
3
|
+
function DetailsElement({ children, className, open, id, node: _node, ...rest }) {
|
|
4
|
+
if (className?.includes("matrx-callout")) {
|
|
5
|
+
return /* @__PURE__ */ jsx("details", { ...rest, className, open, id, children });
|
|
6
|
+
}
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
"details",
|
|
9
|
+
{
|
|
10
|
+
...rest,
|
|
11
|
+
open,
|
|
12
|
+
id,
|
|
13
|
+
className: cn("matrx-details group/details my-3 rounded-md border border-border bg-card px-3 py-2 text-sm [&[open]>summary]:mb-2", className),
|
|
14
|
+
children
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function SummaryElement({ children, className }) {
|
|
19
|
+
if (className?.includes("matrx-callout-title")) return /* @__PURE__ */ jsx("summary", { className, children });
|
|
20
|
+
return /* @__PURE__ */ jsx("summary", { className: cn("cursor-pointer select-none font-medium text-foreground marker:text-muted-foreground", className), children });
|
|
21
|
+
}
|
|
22
|
+
function KbdElement({ children, className }) {
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
"kbd",
|
|
25
|
+
{
|
|
26
|
+
className: cn(
|
|
27
|
+
"rounded border border-b-2 border-border bg-muted px-1.5 py-px font-mono text-[0.8em] text-foreground",
|
|
28
|
+
className
|
|
29
|
+
),
|
|
30
|
+
children
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
DetailsElement,
|
|
36
|
+
KbdElement,
|
|
37
|
+
SummaryElement
|
|
38
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type DocumentNumbering } from "../document-numbering.js";
|
|
3
|
+
export declare function DocumentNumberingProvider({ source, children }: {
|
|
4
|
+
source: string;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
export declare function useDocumentNumbering(): DocumentNumbering | null;
|
|
8
|
+
/**
|
|
9
|
+
* THE DOCUMENT'S ONE FOOTNOTE SECTION (verify-RC-B4 round 16 ruling: notes go
|
|
10
|
+
* after the whole document, as in GFM, Google Docs and print). Every root that
|
|
11
|
+
* splits a document into blocks places this after its last block, inside its
|
|
12
|
+
* `data-matrx-doc-root`, and hands it its own prose renderer, so the notes look
|
|
13
|
+
* like the document's text. It renders the cited notes once (the numbering's
|
|
14
|
+
* `documentFootnoteSource`); a block never renders a definition itself. Beneath
|
|
15
|
+
* a nested provider (a container body, a nested section) it renders nothing —
|
|
16
|
+
* the root owns the section.
|
|
17
|
+
*/
|
|
18
|
+
export declare function DocumentFootnotes({ render }: {
|
|
19
|
+
render: (markdown: string) => ReactNode;
|
|
20
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useState } from "react";
|
|
4
|
+
import {
|
|
5
|
+
computeDocumentNumbering,
|
|
6
|
+
documentFootnoteSource,
|
|
7
|
+
sameDocumentNumbering
|
|
8
|
+
} from "../document-numbering.js";
|
|
9
|
+
const DocumentNumberingContext = createContext(null);
|
|
10
|
+
const NestedDocumentContext = createContext(false);
|
|
11
|
+
function DocumentNumberingProvider({ source, children }) {
|
|
12
|
+
const outer = useContext(DocumentNumberingContext);
|
|
13
|
+
if (outer) return /* @__PURE__ */ jsx(NestedDocumentContext.Provider, { value: true, children });
|
|
14
|
+
return /* @__PURE__ */ jsx(RootNumbering, { source, children });
|
|
15
|
+
}
|
|
16
|
+
function RootNumbering({ source, children }) {
|
|
17
|
+
const computed = computeDocumentNumbering(source);
|
|
18
|
+
const [stable, setStable] = useState(computed);
|
|
19
|
+
if (stable !== computed && !sameDocumentNumbering(stable, computed)) {
|
|
20
|
+
setStable(computed);
|
|
21
|
+
}
|
|
22
|
+
return /* @__PURE__ */ jsx(DocumentNumberingContext.Provider, { value: stable, children });
|
|
23
|
+
}
|
|
24
|
+
function useDocumentNumbering() {
|
|
25
|
+
return useContext(DocumentNumberingContext);
|
|
26
|
+
}
|
|
27
|
+
function DocumentFootnotes({ render }) {
|
|
28
|
+
const numbering = useContext(DocumentNumberingContext);
|
|
29
|
+
const nested = useContext(NestedDocumentContext);
|
|
30
|
+
const markdown = nested ? "" : documentFootnoteSource(numbering);
|
|
31
|
+
return markdown ? /* @__PURE__ */ jsx(Fragment, { children: render(markdown) }) : null;
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
DocumentFootnotes,
|
|
35
|
+
DocumentNumberingProvider,
|
|
36
|
+
useDocumentNumbering
|
|
37
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { TriangleAlert } from "lucide-react";
|
|
4
|
+
import { cn } from "@ai-matrx/design-system";
|
|
5
|
+
import { useDocumentProperties } from "../useDocumentProperties.js";
|
|
6
|
+
import { ErrorAlchemyMenu } from "../../../host/ErrorActions.js";
|
|
7
|
+
function show(value) {
|
|
8
|
+
if (value === null || value === void 0) return "\u2014";
|
|
9
|
+
if (Array.isArray(value)) return value.map(show).join(", ");
|
|
10
|
+
if (value instanceof Date) return value.toISOString().slice(0, 10);
|
|
11
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
12
|
+
return String(value);
|
|
13
|
+
}
|
|
14
|
+
function DocumentPropertiesPanel({ source, className }) {
|
|
15
|
+
const { properties, format, error } = useDocumentProperties(source);
|
|
16
|
+
const entries = Object.entries(properties);
|
|
17
|
+
if (!format) return null;
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"section",
|
|
20
|
+
{
|
|
21
|
+
"aria-label": "Document properties",
|
|
22
|
+
"data-document-properties": "",
|
|
23
|
+
className: cn("rounded-md border border-border bg-muted/30 px-3 py-2 text-xs", className),
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsxs("p", { className: "mb-1 font-semibold uppercase tracking-wide text-muted-foreground", children: [
|
|
26
|
+
"Properties ",
|
|
27
|
+
/* @__PURE__ */ jsxs("span", { className: "font-normal normal-case", children: [
|
|
28
|
+
"\xB7 ",
|
|
29
|
+
format.toUpperCase()
|
|
30
|
+
] })
|
|
31
|
+
] }),
|
|
32
|
+
error ? /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-amber-700 dark:text-amber-300", children: [
|
|
33
|
+
/* @__PURE__ */ jsx(TriangleAlert, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
|
|
34
|
+
error,
|
|
35
|
+
/* @__PURE__ */ jsx(ErrorAlchemyMenu, { error })
|
|
36
|
+
] }) : entries.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "The properties block is empty." }) : /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-3 gap-y-0.5", children: entries.map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "contents", children: [
|
|
37
|
+
/* @__PURE__ */ jsx("dt", { className: "font-medium text-muted-foreground", children: key }),
|
|
38
|
+
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words text-foreground", children: show(value) })
|
|
39
|
+
] }, key)) })
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
DocumentPropertiesPanel
|
|
46
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
type AnchorProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
3
|
+
href: string;
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
"data-footnote-ref"?: unknown;
|
|
6
|
+
"data-footnote-backref"?: unknown;
|
|
7
|
+
"data-heading-anchor"?: unknown;
|
|
8
|
+
node?: unknown;
|
|
9
|
+
};
|
|
10
|
+
export declare function InDocAnchor({ href, children, className, node: _node, onClick, ...rest }: AnchorProps): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useState } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { cn } from "@ai-matrx/design-system";
|
|
6
|
+
import { findInDocument } from "./find-in-document.js";
|
|
7
|
+
import { replaceAddressWithoutNavigating } from "../../../utils/addressWithoutNavigating.js";
|
|
8
|
+
function targetId(href) {
|
|
9
|
+
try {
|
|
10
|
+
return decodeURIComponent(href.slice(1));
|
|
11
|
+
} catch {
|
|
12
|
+
return href.slice(1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function noteText(target) {
|
|
16
|
+
const clone = target.cloneNode(true);
|
|
17
|
+
clone.querySelectorAll("[data-footnote-backref]").forEach((el) => el.remove());
|
|
18
|
+
return (clone.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
19
|
+
}
|
|
20
|
+
function InDocAnchor({ href, children, className, node: _node, onClick, ...rest }) {
|
|
21
|
+
const ref = useRef(null);
|
|
22
|
+
const [preview, setPreview] = useState(null);
|
|
23
|
+
const isFootnoteRef = rest["data-footnote-ref"] !== void 0 && rest["data-footnote-ref"] !== false;
|
|
24
|
+
const id = targetId(href);
|
|
25
|
+
const show = () => {
|
|
26
|
+
if (!isFootnoteRef) return;
|
|
27
|
+
const target = findInDocument(ref.current, id);
|
|
28
|
+
const rect = ref.current?.getBoundingClientRect();
|
|
29
|
+
if (!target || !rect) return;
|
|
30
|
+
const text = noteText(target);
|
|
31
|
+
if (!text) return;
|
|
32
|
+
setPreview({ text, top: rect.bottom + 6, left: Math.max(8, Math.min(rect.left, window.innerWidth - 336)) });
|
|
33
|
+
};
|
|
34
|
+
return /* @__PURE__ */ jsxs(
|
|
35
|
+
"a",
|
|
36
|
+
{
|
|
37
|
+
ref,
|
|
38
|
+
href,
|
|
39
|
+
...rest,
|
|
40
|
+
className: cn(
|
|
41
|
+
!rest["data-heading-anchor"] && "text-primary underline-offset-2 hover:underline",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
onMouseEnter: show,
|
|
45
|
+
onFocus: show,
|
|
46
|
+
onMouseLeave: () => setPreview(null),
|
|
47
|
+
onBlur: () => setPreview(null),
|
|
48
|
+
onClick: (event) => {
|
|
49
|
+
onClick?.(event);
|
|
50
|
+
if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.shiftKey) return;
|
|
51
|
+
const target = findInDocument(ref.current, id);
|
|
52
|
+
if (!target) return;
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
setPreview(null);
|
|
55
|
+
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
56
|
+
if (typeof target.animate === "function") {
|
|
57
|
+
target.animate(
|
|
58
|
+
[{ backgroundColor: "hsl(var(--primary) / 0.18)" }, { backgroundColor: "transparent" }],
|
|
59
|
+
{ duration: 1600, easing: "ease-out" }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
replaceAddressWithoutNavigating(`#${encodeURIComponent(id)}`);
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
children: [
|
|
68
|
+
children,
|
|
69
|
+
preview && typeof document !== "undefined" && createPortal(
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"span",
|
|
72
|
+
{
|
|
73
|
+
role: "tooltip",
|
|
74
|
+
style: { top: preview.top, left: preview.left },
|
|
75
|
+
className: "pointer-events-none fixed z-[100] block w-80 max-w-[calc(100vw-16px)] rounded-md border border-border bg-popover px-3 py-2 text-xs font-normal leading-relaxed text-popover-foreground shadow-lg",
|
|
76
|
+
children: preview.text
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
document.body
|
|
80
|
+
)
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
InDocAnchor
|
|
87
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface MarkdownSourceEdit {
|
|
3
|
+
/** The stored source exactly as saved (not a render-prepared copy). */
|
|
4
|
+
source: string;
|
|
5
|
+
/** Persist a new source. May be async; a rejection is shown to the person. */
|
|
6
|
+
save: (next: string) => void | Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export declare function MarkdownSourceEditProvider({ source, save, children, }: MarkdownSourceEdit & {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
export declare function useMarkdownSourceEdit(): MarkdownSourceEdit | null;
|
|
12
|
+
/**
|
|
13
|
+
* The adapter for a level that can save only SOMETIMES (a streamed answer
|
|
14
|
+
* saves once it has settled). It renders the same element either way, so
|
|
15
|
+
* gaining or losing `save` never remounts the document below it — a remount
|
|
16
|
+
* there unmounted every tool card at the instant a stream completed. With no
|
|
17
|
+
* `save`, the outer adapter (if any) stays in effect, exactly as if this level
|
|
18
|
+
* rendered nothing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function OptionalMarkdownSourceEditProvider({ source, save, children, }: {
|
|
21
|
+
source: string;
|
|
22
|
+
save?: MarkdownSourceEdit["save"];
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
const MarkdownSourceEditContext = createContext(null);
|
|
5
|
+
function MarkdownSourceEditProvider({
|
|
6
|
+
source,
|
|
7
|
+
save,
|
|
8
|
+
children
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ jsx(MarkdownSourceEditContext.Provider, { value: { source, save }, children });
|
|
11
|
+
}
|
|
12
|
+
function useMarkdownSourceEdit() {
|
|
13
|
+
return useContext(MarkdownSourceEditContext);
|
|
14
|
+
}
|
|
15
|
+
function OptionalMarkdownSourceEditProvider({
|
|
16
|
+
source,
|
|
17
|
+
save,
|
|
18
|
+
children
|
|
19
|
+
}) {
|
|
20
|
+
const outer = useContext(MarkdownSourceEditContext);
|
|
21
|
+
const value = save ? { source, save } : outer;
|
|
22
|
+
return /* @__PURE__ */ jsx(MarkdownSourceEditContext.Provider, { value, children });
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
MarkdownSourceEditProvider,
|
|
26
|
+
OptionalMarkdownSourceEditProvider,
|
|
27
|
+
useMarkdownSourceEdit
|
|
28
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export declare function MatrxTabs(props: {
|
|
3
|
+
"data-labels"?: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}): import("react").JSX.Element | null;
|
|
7
|
+
/** One tab's body; the label lives on the parent (`data-labels`). */
|
|
8
|
+
export declare function MatrxTab(props: {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}): import("react").JSX.Element;
|