@docfuse/plugins 0.1.0
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/LICENSE +21 -0
- package/README.md +52 -0
- package/README.zh-CN.md +52 -0
- package/dist/client/kroki.js +221 -0
- package/dist/client/mermaid.js +366 -0
- package/dist/client/plantuml.js +221 -0
- package/dist/diagram.css +195 -0
- package/dist/external-links.d.ts +10 -0
- package/dist/external-links.js +49 -0
- package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +757 -0
- package/dist/kroki.d.ts +12 -0
- package/dist/kroki.js +293 -0
- package/dist/link-card.d.ts +9 -0
- package/dist/link-card.js +87 -0
- package/dist/math.css +3 -0
- package/dist/math.d.ts +19 -0
- package/dist/math.js +140 -0
- package/dist/mermaid.d.ts +10 -0
- package/dist/mermaid.js +290 -0
- package/dist/pagefind.d.ts +66 -0
- package/dist/pagefind.js +84 -0
- package/dist/plantuml.d.ts +10 -0
- package/dist/plantuml.js +297 -0
- package/dist/reading-time.d.ts +20 -0
- package/dist/reading-time.js +90 -0
- package/package.json +122 -0
package/dist/kroki.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MarkdownPlugin } from '@docfuse/markdown';
|
|
2
|
+
|
|
3
|
+
interface KrokiOptions {
|
|
4
|
+
server?: string;
|
|
5
|
+
/** Map Markdown fence labels to Kroki diagram types. */
|
|
6
|
+
languages?: Readonly<Record<string, string>>;
|
|
7
|
+
format?: 'svg' | 'png';
|
|
8
|
+
}
|
|
9
|
+
/** Render plugin-owned diagram fences through a Kroki-compatible server. */
|
|
10
|
+
declare function kroki(options?: KrokiOptions): MarkdownPlugin;
|
|
11
|
+
|
|
12
|
+
export { type KrokiOptions, kroki };
|
package/dist/kroki.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// src/kroki/index.ts
|
|
2
|
+
import { defineMarkdownPlugin } from "@docfuse/markdown";
|
|
3
|
+
import { strToU8, zlibSync } from "fflate";
|
|
4
|
+
|
|
5
|
+
// src/shared/diagram.ts
|
|
6
|
+
import { visit } from "unist-util-visit";
|
|
7
|
+
function displayKind(kind) {
|
|
8
|
+
if (kind === "plantuml") return "PlantUML";
|
|
9
|
+
return kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
10
|
+
}
|
|
11
|
+
var DIAGRAM_LABELS = {
|
|
12
|
+
en: {
|
|
13
|
+
copy: "Copy source",
|
|
14
|
+
source: "Show source",
|
|
15
|
+
preview: "Show preview",
|
|
16
|
+
expand: "Expand diagram",
|
|
17
|
+
close: "Close expanded diagram",
|
|
18
|
+
controls: "Diagram zoom controls",
|
|
19
|
+
zoomOut: "Zoom out",
|
|
20
|
+
zoomReset: "Reset zoom",
|
|
21
|
+
zoomIn: "Zoom in",
|
|
22
|
+
imageAlt: (kind) => `${displayKind(kind)} diagram`,
|
|
23
|
+
loadingPreview: "Diagram preview loads in the browser."
|
|
24
|
+
},
|
|
25
|
+
zh: {
|
|
26
|
+
copy: "\u590D\u5236\u56FE\u8868\u6E90\u7801",
|
|
27
|
+
source: "\u663E\u793A\u56FE\u8868\u6E90\u7801",
|
|
28
|
+
preview: "\u663E\u793A\u56FE\u8868\u9884\u89C8",
|
|
29
|
+
expand: "\u653E\u5927\u56FE\u8868",
|
|
30
|
+
close: "\u5173\u95ED\u56FE\u8868\u9884\u89C8",
|
|
31
|
+
controls: "\u56FE\u8868\u7F29\u653E\u63A7\u4EF6",
|
|
32
|
+
zoomOut: "\u7F29\u5C0F\u56FE\u8868",
|
|
33
|
+
zoomReset: "\u91CD\u7F6E\u56FE\u8868\u7F29\u653E",
|
|
34
|
+
zoomIn: "\u653E\u5927\u56FE\u8868",
|
|
35
|
+
imageAlt: (kind) => `${displayKind(kind)} \u56FE\u8868`,
|
|
36
|
+
loadingPreview: "\u56FE\u8868\u9884\u89C8\u5C06\u5728\u6D4F\u89C8\u5668\u4E2D\u52A0\u8F7D\u3002"
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function labelsFromFile(file) {
|
|
40
|
+
if (!file || typeof file !== "object" || !("data" in file)) return DIAGRAM_LABELS.en;
|
|
41
|
+
const data = file.data;
|
|
42
|
+
if (!data || typeof data !== "object" || !("docfuseLocale" in data)) return DIAGRAM_LABELS.en;
|
|
43
|
+
const locale = typeof data.docfuseLocale === "string" ? data.docfuseLocale.toLowerCase() : "";
|
|
44
|
+
return locale === "zh" || locale.startsWith("zh-") ? DIAGRAM_LABELS.zh : DIAGRAM_LABELS.en;
|
|
45
|
+
}
|
|
46
|
+
function languageOf(node) {
|
|
47
|
+
const code = node.children.find(
|
|
48
|
+
(child) => child.type === "element" && child.tagName === "code"
|
|
49
|
+
);
|
|
50
|
+
if (!code) return void 0;
|
|
51
|
+
const classes = Array.isArray(code.properties.className) ? code.properties.className : [];
|
|
52
|
+
const language = classes.map(String).find((className) => className.startsWith("language-"))?.slice("language-".length).toLowerCase();
|
|
53
|
+
const source = code.children.filter((child) => child.type === "text").map((child) => child.value).join("");
|
|
54
|
+
return language ? { language, source } : void 0;
|
|
55
|
+
}
|
|
56
|
+
function action(name, label, properties = {}) {
|
|
57
|
+
return {
|
|
58
|
+
type: "element",
|
|
59
|
+
tagName: "button",
|
|
60
|
+
properties: { type: "button", dataDfDiagramAction: name, ariaLabel: label, ...properties },
|
|
61
|
+
children: [{ type: "text", value: label }]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function zoomControl(name, label) {
|
|
65
|
+
return {
|
|
66
|
+
type: "element",
|
|
67
|
+
tagName: "button",
|
|
68
|
+
properties: { type: "button", dataDfDiagramAction: name, ariaLabel: label, title: label },
|
|
69
|
+
children: [{ type: "text", value: label }]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function diagramFence(options) {
|
|
73
|
+
return () => (tree, file) => {
|
|
74
|
+
const labels = labelsFromFile(file);
|
|
75
|
+
visit(tree, "element", (node, index, parent) => {
|
|
76
|
+
if (!parent || index === void 0 || node.tagName !== "pre") return;
|
|
77
|
+
const fence = languageOf(node);
|
|
78
|
+
if (!fence || !options.languages.has(fence.language)) return;
|
|
79
|
+
const imageUrl = options.imageUrl?.(fence.source, fence.language);
|
|
80
|
+
const hasVisualPreview = Boolean(imageUrl || options.kind === "mermaid");
|
|
81
|
+
const preview = imageUrl ? {
|
|
82
|
+
type: "element",
|
|
83
|
+
tagName: "img",
|
|
84
|
+
properties: {
|
|
85
|
+
className: ["df-diagram-img"],
|
|
86
|
+
src: imageUrl,
|
|
87
|
+
alt: labels.imageAlt(options.kind),
|
|
88
|
+
loading: "lazy"
|
|
89
|
+
},
|
|
90
|
+
children: []
|
|
91
|
+
} : {
|
|
92
|
+
type: "element",
|
|
93
|
+
tagName: "div",
|
|
94
|
+
properties: { className: ["df-diagram-placeholder"] },
|
|
95
|
+
children: [{ type: "text", value: labels.loadingPreview }]
|
|
96
|
+
};
|
|
97
|
+
parent.children[index] = {
|
|
98
|
+
type: "element",
|
|
99
|
+
tagName: "figure",
|
|
100
|
+
properties: {
|
|
101
|
+
className: ["df-diagram-window"],
|
|
102
|
+
dataDfPluginDiagram: options.kind,
|
|
103
|
+
dataDfSource: fence.source,
|
|
104
|
+
...options.moduleUrl ? { dataDfModuleUrl: options.moduleUrl } : {}
|
|
105
|
+
},
|
|
106
|
+
children: [
|
|
107
|
+
{
|
|
108
|
+
type: "element",
|
|
109
|
+
tagName: "figcaption",
|
|
110
|
+
properties: { className: ["df-diagram-toolbar"] },
|
|
111
|
+
children: [
|
|
112
|
+
{
|
|
113
|
+
type: "element",
|
|
114
|
+
tagName: "span",
|
|
115
|
+
properties: { className: ["df-diagram-title"] },
|
|
116
|
+
children: [{ type: "text", value: options.filename(fence.language) }]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: "element",
|
|
120
|
+
tagName: "span",
|
|
121
|
+
properties: { className: ["df-diagram-actions"] },
|
|
122
|
+
children: [
|
|
123
|
+
action("copy", labels.copy),
|
|
124
|
+
action("source", labels.source, { dataDfDiagramPreviewLabel: labels.preview }),
|
|
125
|
+
action("expand", labels.expand, { dataDfDiagramCloseLabel: labels.close })
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: "element",
|
|
132
|
+
tagName: "div",
|
|
133
|
+
properties: { className: ["df-diagram-stage"] },
|
|
134
|
+
children: [
|
|
135
|
+
{
|
|
136
|
+
type: "element",
|
|
137
|
+
tagName: "div",
|
|
138
|
+
properties: { className: ["df-diagram-preview"] },
|
|
139
|
+
children: [preview]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
type: "element",
|
|
143
|
+
tagName: "pre",
|
|
144
|
+
properties: { className: ["df-diagram-source"], hidden: true },
|
|
145
|
+
children: [
|
|
146
|
+
{
|
|
147
|
+
type: "element",
|
|
148
|
+
tagName: "code",
|
|
149
|
+
properties: {},
|
|
150
|
+
children: [{ type: "text", value: fence.source }]
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
...hasVisualPreview ? [
|
|
155
|
+
{
|
|
156
|
+
type: "element",
|
|
157
|
+
tagName: "div",
|
|
158
|
+
properties: {
|
|
159
|
+
className: ["df-diagram-zoom-controls"],
|
|
160
|
+
role: "group",
|
|
161
|
+
ariaLabel: labels.controls
|
|
162
|
+
},
|
|
163
|
+
children: [
|
|
164
|
+
zoomControl("zoom-out", labels.zoomOut),
|
|
165
|
+
zoomControl("zoom-reset", labels.zoomReset),
|
|
166
|
+
zoomControl("zoom-in", labels.zoomIn)
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
] : []
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/shared/markdownSource.ts
|
|
179
|
+
function stripColumns(value, columns) {
|
|
180
|
+
let index = 0;
|
|
181
|
+
let consumed = 0;
|
|
182
|
+
while (index < value.length && consumed < columns) {
|
|
183
|
+
if (value[index] === " ") consumed += 1;
|
|
184
|
+
else if (value[index] === " ") consumed += 4 - consumed % 4;
|
|
185
|
+
else break;
|
|
186
|
+
index += 1;
|
|
187
|
+
}
|
|
188
|
+
return consumed >= columns ? value.slice(index) : void 0;
|
|
189
|
+
}
|
|
190
|
+
function containerContent(line, state) {
|
|
191
|
+
let value = line;
|
|
192
|
+
while (true) {
|
|
193
|
+
const quote = value.match(/^ {0,3}>[ \t]?/);
|
|
194
|
+
if (!quote) break;
|
|
195
|
+
value = value.slice(quote[0].length);
|
|
196
|
+
}
|
|
197
|
+
const continued = state.listIndent > 0 ? stripColumns(value, state.listIndent) : void 0;
|
|
198
|
+
const content = continued ?? value;
|
|
199
|
+
const item = content.match(/^ {0,3}(?:[-+*]|\d{1,9}[.)])([ \t]+)(.*)$/);
|
|
200
|
+
if (item) {
|
|
201
|
+
const body = item[2] ?? "";
|
|
202
|
+
state.listIndent = (continued === void 0 ? 0 : state.listIndent) + content.length - body.length;
|
|
203
|
+
return body;
|
|
204
|
+
}
|
|
205
|
+
if (continued !== void 0 || value.trim() === "") return content;
|
|
206
|
+
state.listIndent = 0;
|
|
207
|
+
return value;
|
|
208
|
+
}
|
|
209
|
+
function openingFence(line) {
|
|
210
|
+
const match = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
211
|
+
if (!match?.[1]) return void 0;
|
|
212
|
+
const marker = match[1][0];
|
|
213
|
+
const info = match[2]?.trim() ?? "";
|
|
214
|
+
if (marker === "`" && info.includes("`")) return void 0;
|
|
215
|
+
return {
|
|
216
|
+
marker,
|
|
217
|
+
size: match[1].length,
|
|
218
|
+
language: info.split(/\s+/, 1)[0]?.toLowerCase() ?? ""
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function closesFence(line, fence) {
|
|
222
|
+
const match = line.match(/^ {0,3}(`+|~+)[ \t]*$/);
|
|
223
|
+
return Boolean(match?.[1]?.[0] === fence.marker && match[1].length >= fence.size);
|
|
224
|
+
}
|
|
225
|
+
function hasMarkdownFenceLanguage(source, languages) {
|
|
226
|
+
let open;
|
|
227
|
+
const container = { listIndent: 0 };
|
|
228
|
+
for (const line of source.split(/\r?\n/)) {
|
|
229
|
+
const content = containerContent(line, container);
|
|
230
|
+
if (open) {
|
|
231
|
+
if (closesFence(content, open)) open = void 0;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const fence = openingFence(content);
|
|
235
|
+
if (!fence) continue;
|
|
236
|
+
if (languages.has(fence.language)) return true;
|
|
237
|
+
open = fence;
|
|
238
|
+
}
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// src/kroki/index.ts
|
|
243
|
+
var PLUGIN_VERSION = "3";
|
|
244
|
+
var DEFAULT_SERVER = "https://kroki.io";
|
|
245
|
+
var DEFAULT_LANGUAGES = {
|
|
246
|
+
graphviz: "graphviz",
|
|
247
|
+
dot: "graphviz",
|
|
248
|
+
gv: "graphviz",
|
|
249
|
+
d2: "d2"
|
|
250
|
+
};
|
|
251
|
+
function encodeKroki(source) {
|
|
252
|
+
let binary = "";
|
|
253
|
+
for (const byte of zlibSync(strToU8(source), { level: 9 })) binary += String.fromCharCode(byte);
|
|
254
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
255
|
+
}
|
|
256
|
+
function krokiUrl(server, type, format, source) {
|
|
257
|
+
return `${server}/${encodeURIComponent(type)}/${format}/${encodeKroki(source)}`;
|
|
258
|
+
}
|
|
259
|
+
function kroki(options = {}) {
|
|
260
|
+
const server = options.server?.replace(/\/+$/, "") || DEFAULT_SERVER;
|
|
261
|
+
const languages = { ...DEFAULT_LANGUAGES, ...options.languages };
|
|
262
|
+
const format = options.format === "png" ? "png" : "svg";
|
|
263
|
+
const languageMap = Object.fromEntries(
|
|
264
|
+
Object.entries(languages).map(([language, type]) => [language.trim().toLowerCase(), type.trim().toLowerCase()]).filter(([language, type]) => language && type)
|
|
265
|
+
);
|
|
266
|
+
return defineMarkdownPlugin({
|
|
267
|
+
name: "kroki",
|
|
268
|
+
version: PLUGIN_VERSION,
|
|
269
|
+
cacheKey: { server, languages: languageMap, format },
|
|
270
|
+
browserCompiler: {
|
|
271
|
+
module: "@docfuse/plugins/kroki",
|
|
272
|
+
exportName: "kroki",
|
|
273
|
+
options: { server, languages: languageMap, format }
|
|
274
|
+
},
|
|
275
|
+
fenceLanguages: Object.keys(languageMap),
|
|
276
|
+
appliesTo: ({ source }) => hasMarkdownFenceLanguage(source, new Set(Object.keys(languageMap))),
|
|
277
|
+
assets: {
|
|
278
|
+
clients: [{ id: "kroki", module: "@docfuse/plugins/client/kroki" }],
|
|
279
|
+
styles: [{ id: "diagrams", module: "@docfuse/plugins/diagram.css" }]
|
|
280
|
+
},
|
|
281
|
+
rehypePlugins: [
|
|
282
|
+
diagramFence({
|
|
283
|
+
languages: new Set(Object.keys(languageMap)),
|
|
284
|
+
kind: "kroki",
|
|
285
|
+
filename: (language) => `diagram.${languageMap[language] ?? language}`,
|
|
286
|
+
imageUrl: (source, language) => krokiUrl(server, languageMap[language] ?? language, format, source)
|
|
287
|
+
})
|
|
288
|
+
]
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
export {
|
|
292
|
+
kroki
|
|
293
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MarkdownPlugin } from '@docfuse/markdown';
|
|
2
|
+
|
|
3
|
+
interface LinkCardOptions {
|
|
4
|
+
internalHosts?: readonly string[];
|
|
5
|
+
includeRelative?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare function linkCard(options?: LinkCardOptions): MarkdownPlugin;
|
|
8
|
+
|
|
9
|
+
export { type LinkCardOptions, linkCard };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/link-card/index.ts
|
|
2
|
+
import { defineMarkdownPlugin } from "@docfuse/markdown";
|
|
3
|
+
import { SKIP, visit } from "unist-util-visit";
|
|
4
|
+
|
|
5
|
+
// src/shared/hast.ts
|
|
6
|
+
function element(tagName, properties = {}, children = []) {
|
|
7
|
+
return { type: "element", tagName, properties, children };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/shared/urls.ts
|
|
11
|
+
function hostnameOf(href) {
|
|
12
|
+
try {
|
|
13
|
+
return new URL(href).hostname.toLowerCase();
|
|
14
|
+
} catch {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isInternalHost(host, internalHosts) {
|
|
19
|
+
return internalHosts.some((internal) => host === internal || host.endsWith(`.${internal}`));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/link-card/index.ts
|
|
23
|
+
var PLUGIN_VERSION = "1";
|
|
24
|
+
function isExternalHttpLink(href, internalHosts, includeRelative) {
|
|
25
|
+
if (!href) return false;
|
|
26
|
+
if (href.startsWith("/") || href.startsWith("#") || href.startsWith("mailto:"))
|
|
27
|
+
return includeRelative && href.startsWith("/");
|
|
28
|
+
if (!/^https?:\/\//i.test(href)) return false;
|
|
29
|
+
const host = hostnameOf(href);
|
|
30
|
+
return Boolean(host && !isInternalHost(host, internalHosts));
|
|
31
|
+
}
|
|
32
|
+
function textOf(node) {
|
|
33
|
+
if (node.type === "text") return node.value;
|
|
34
|
+
if ("children" in node) return node.children.map((child) => textOf(child)).join("");
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
function displayHost(href) {
|
|
38
|
+
try {
|
|
39
|
+
const url = new URL(href);
|
|
40
|
+
return url.hostname + (url.pathname === "/" ? "" : url.pathname);
|
|
41
|
+
} catch {
|
|
42
|
+
return href;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function linkCard(options = {}) {
|
|
46
|
+
const internalHosts = (options.internalHosts ?? []).map((host) => host.toLowerCase());
|
|
47
|
+
const includeRelative = options.includeRelative === true;
|
|
48
|
+
return defineMarkdownPlugin({
|
|
49
|
+
name: "link-card",
|
|
50
|
+
version: PLUGIN_VERSION,
|
|
51
|
+
cacheKey: { internalHosts, includeRelative },
|
|
52
|
+
browserCompiler: {
|
|
53
|
+
module: "@docfuse/plugins/link-card",
|
|
54
|
+
exportName: "linkCard",
|
|
55
|
+
options: { internalHosts, includeRelative }
|
|
56
|
+
},
|
|
57
|
+
rehypePlugins: [
|
|
58
|
+
() => (tree) => {
|
|
59
|
+
visit(tree, "element", (node, index, parent) => {
|
|
60
|
+
if (node.tagName !== "p" || !parent || index === void 0) return;
|
|
61
|
+
const meaningful = node.children.filter(
|
|
62
|
+
(child) => child.type !== "text" || child.value.trim() !== ""
|
|
63
|
+
);
|
|
64
|
+
const onlyChild = meaningful[0];
|
|
65
|
+
if (meaningful.length !== 1 || onlyChild?.type !== "element" || onlyChild.tagName !== "a") return;
|
|
66
|
+
const href = String(onlyChild.properties.href ?? "");
|
|
67
|
+
if (!isExternalHttpLink(href, internalHosts, includeRelative)) return;
|
|
68
|
+
if (onlyChild.properties.dataDfElement === "file-link") return;
|
|
69
|
+
const title = textOf(onlyChild).trim() || displayHost(href);
|
|
70
|
+
const meta = displayHost(href);
|
|
71
|
+
parent.children[index] = element(
|
|
72
|
+
"a",
|
|
73
|
+
{ ...onlyChild.properties, className: ["df-link-card"], href, dataDfComponent: "link-card" },
|
|
74
|
+
[
|
|
75
|
+
element("strong", {}, [{ type: "text", value: title }]),
|
|
76
|
+
...meta && meta !== title ? [element("span", {}, [{ type: "text", value: meta }])] : []
|
|
77
|
+
]
|
|
78
|
+
);
|
|
79
|
+
return [SKIP, index];
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
linkCard
|
|
87
|
+
};
|
package/dist/math.css
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/* KaTeX */
|
|
2
|
+
@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2")}@font-face{font-display:block;font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2")}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.17.0"}.katex .katex-mathml{border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}
|
|
3
|
+
|
package/dist/math.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MarkdownPlugin } from '@docfuse/markdown';
|
|
2
|
+
|
|
3
|
+
interface MathOptions {
|
|
4
|
+
/** KaTeX should throw instead of rendering unsupported input. */
|
|
5
|
+
throwOnError?: boolean;
|
|
6
|
+
/** Color used by KaTeX when `throwOnError` is false. */
|
|
7
|
+
errorColor?: string;
|
|
8
|
+
/** Trust KaTeX commands that can emit URLs or HTML. Disabled by default. */
|
|
9
|
+
trust?: boolean;
|
|
10
|
+
/** KaTeX strictness policy. */
|
|
11
|
+
strict?: boolean | 'ignore' | 'warn' | 'error';
|
|
12
|
+
/** Macros passed to KaTeX. */
|
|
13
|
+
macros?: Readonly<Record<string, string>>;
|
|
14
|
+
}
|
|
15
|
+
/** Conservative opt-in detector; escaped dollar signs and code do not activate KaTeX. */
|
|
16
|
+
declare function hasMathSyntax(source: string): boolean;
|
|
17
|
+
declare function math(options?: MathOptions): MarkdownPlugin;
|
|
18
|
+
|
|
19
|
+
export { type MathOptions, hasMathSyntax, math };
|
package/dist/math.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/math/index.ts
|
|
2
|
+
import { defineMarkdownPlugin } from "@docfuse/markdown";
|
|
3
|
+
import rehypeKatex from "rehype-katex";
|
|
4
|
+
import remarkMath from "remark-math";
|
|
5
|
+
|
|
6
|
+
// src/shared/markdownSource.ts
|
|
7
|
+
function stripColumns(value, columns) {
|
|
8
|
+
let index = 0;
|
|
9
|
+
let consumed = 0;
|
|
10
|
+
while (index < value.length && consumed < columns) {
|
|
11
|
+
if (value[index] === " ") consumed += 1;
|
|
12
|
+
else if (value[index] === " ") consumed += 4 - consumed % 4;
|
|
13
|
+
else break;
|
|
14
|
+
index += 1;
|
|
15
|
+
}
|
|
16
|
+
return consumed >= columns ? value.slice(index) : void 0;
|
|
17
|
+
}
|
|
18
|
+
function containerContent(line, state) {
|
|
19
|
+
let value = line;
|
|
20
|
+
while (true) {
|
|
21
|
+
const quote = value.match(/^ {0,3}>[ \t]?/);
|
|
22
|
+
if (!quote) break;
|
|
23
|
+
value = value.slice(quote[0].length);
|
|
24
|
+
}
|
|
25
|
+
const continued = state.listIndent > 0 ? stripColumns(value, state.listIndent) : void 0;
|
|
26
|
+
const content = continued ?? value;
|
|
27
|
+
const item = content.match(/^ {0,3}(?:[-+*]|\d{1,9}[.)])([ \t]+)(.*)$/);
|
|
28
|
+
if (item) {
|
|
29
|
+
const body = item[2] ?? "";
|
|
30
|
+
state.listIndent = (continued === void 0 ? 0 : state.listIndent) + content.length - body.length;
|
|
31
|
+
return body;
|
|
32
|
+
}
|
|
33
|
+
if (continued !== void 0 || value.trim() === "") return content;
|
|
34
|
+
state.listIndent = 0;
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function openingFence(line) {
|
|
38
|
+
const match = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
39
|
+
if (!match?.[1]) return void 0;
|
|
40
|
+
const marker = match[1][0];
|
|
41
|
+
const info = match[2]?.trim() ?? "";
|
|
42
|
+
if (marker === "`" && info.includes("`")) return void 0;
|
|
43
|
+
return {
|
|
44
|
+
marker,
|
|
45
|
+
size: match[1].length,
|
|
46
|
+
language: info.split(/\s+/, 1)[0]?.toLowerCase() ?? ""
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function closesFence(line, fence) {
|
|
50
|
+
const match = line.match(/^ {0,3}(`+|~+)[ \t]*$/);
|
|
51
|
+
return Boolean(match?.[1]?.[0] === fence.marker && match[1].length >= fence.size);
|
|
52
|
+
}
|
|
53
|
+
function hasMarkdownFenceLanguage(source, languages) {
|
|
54
|
+
let open;
|
|
55
|
+
const container = { listIndent: 0 };
|
|
56
|
+
for (const line of source.split(/\r?\n/)) {
|
|
57
|
+
const content = containerContent(line, container);
|
|
58
|
+
if (open) {
|
|
59
|
+
if (closesFence(content, open)) open = void 0;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const fence = openingFence(content);
|
|
63
|
+
if (!fence) continue;
|
|
64
|
+
if (languages.has(fence.language)) return true;
|
|
65
|
+
open = fence;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
function removeInlineCode(line) {
|
|
70
|
+
let result = "";
|
|
71
|
+
let index = 0;
|
|
72
|
+
while (index < line.length) {
|
|
73
|
+
if (line[index] !== "`") {
|
|
74
|
+
result += line[index];
|
|
75
|
+
index += 1;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
let endOfOpening = index + 1;
|
|
79
|
+
while (line[endOfOpening] === "`") endOfOpening += 1;
|
|
80
|
+
const delimiter = line.slice(index, endOfOpening);
|
|
81
|
+
const closing = line.indexOf(delimiter, endOfOpening);
|
|
82
|
+
if (closing === -1) {
|
|
83
|
+
result += delimiter;
|
|
84
|
+
index = endOfOpening;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
result += " ".repeat(closing + delimiter.length - index);
|
|
88
|
+
index = closing + delimiter.length;
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
function markdownProse(source) {
|
|
93
|
+
let open;
|
|
94
|
+
const container = { listIndent: 0 };
|
|
95
|
+
return source.split(/\r?\n/).map((line) => {
|
|
96
|
+
const content = containerContent(line, container);
|
|
97
|
+
if (open) {
|
|
98
|
+
if (closesFence(content, open)) open = void 0;
|
|
99
|
+
return "";
|
|
100
|
+
}
|
|
101
|
+
const fence = openingFence(content);
|
|
102
|
+
if (fence) {
|
|
103
|
+
open = fence;
|
|
104
|
+
return "";
|
|
105
|
+
}
|
|
106
|
+
if (/^(?: {4}|\t)/.test(content)) return "";
|
|
107
|
+
return removeInlineCode(content);
|
|
108
|
+
}).join("\n");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/math/index.ts
|
|
112
|
+
var PLUGIN_VERSION = "3";
|
|
113
|
+
function hasMathSyntax(source) {
|
|
114
|
+
const prose = markdownProse(source);
|
|
115
|
+
return hasMarkdownFenceLanguage(source, /* @__PURE__ */ new Set(["math"])) || /(^|[^\\])\$\$[\s\S]+?\$\$/.test(prose) || /(^|[^\\$])\$(?!\s)(?:\\.|[^$\n])+?(?<!\s)\$/.test(prose);
|
|
116
|
+
}
|
|
117
|
+
function math(options = {}) {
|
|
118
|
+
const resolved = {
|
|
119
|
+
throwOnError: options.throwOnError ?? false,
|
|
120
|
+
errorColor: options.errorColor ?? "#b42318",
|
|
121
|
+
trust: options.trust ?? false,
|
|
122
|
+
strict: options.strict ?? "warn",
|
|
123
|
+
macros: { ...options.macros ?? {} }
|
|
124
|
+
};
|
|
125
|
+
return defineMarkdownPlugin({
|
|
126
|
+
name: "math",
|
|
127
|
+
version: PLUGIN_VERSION,
|
|
128
|
+
cacheKey: resolved,
|
|
129
|
+
browserCompiler: { module: "@docfuse/plugins/math", exportName: "math", options: resolved },
|
|
130
|
+
appliesTo: ({ source }) => hasMathSyntax(source),
|
|
131
|
+
fenceLanguages: ["math"],
|
|
132
|
+
assets: { math: true },
|
|
133
|
+
remarkPlugins: [remarkMath],
|
|
134
|
+
rehypePlugins: [[rehypeKatex, resolved]]
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
hasMathSyntax,
|
|
139
|
+
math
|
|
140
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MarkdownPlugin } from '@docfuse/markdown';
|
|
2
|
+
|
|
3
|
+
interface MermaidOptions {
|
|
4
|
+
/** Optional browser ESM module. The bundled Mermaid runtime is used by default. */
|
|
5
|
+
moduleUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Enable Mermaid fenced code blocks as an opt-in official plugin. */
|
|
8
|
+
declare function mermaid(options?: MermaidOptions): MarkdownPlugin;
|
|
9
|
+
|
|
10
|
+
export { type MermaidOptions, mermaid };
|