js.documents 2.2.0 → 2.3.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/README.md +30 -5
- package/dist/diagnostics-C5-bG09J.d.cts +18 -0
- package/dist/diagnostics-C5-bG09J.d.ts +18 -0
- package/dist/index.cjs +10 -0
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/latex/diagnostics.cjs +21 -0
- package/dist/latex/diagnostics.d.cts +2 -0
- package/dist/latex/diagnostics.d.ts +2 -0
- package/dist/latex/diagnostics.js +19 -0
- package/dist/latex/lint.cjs +82 -0
- package/dist/latex/lint.d.cts +6 -0
- package/dist/latex/lint.d.ts +6 -0
- package/dist/latex/lint.js +81 -0
- package/dist/latex/lower.cjs +550 -0
- package/dist/latex/lower.d.cts +24 -0
- package/dist/latex/lower.d.ts +24 -0
- package/dist/latex/lower.js +548 -0
- package/dist/latex/rational.cjs +29 -0
- package/dist/latex/rational.d.cts +11 -0
- package/dist/latex/rational.d.ts +11 -0
- package/dist/latex/rational.js +27 -0
- package/dist/latex/symbols.cjs +128 -0
- package/dist/latex/symbols.d.cts +16 -0
- package/dist/latex/symbols.d.ts +16 -0
- package/dist/latex/symbols.js +124 -0
- package/dist/latex/temml.cjs +121 -0
- package/dist/latex/temml.d.cts +25 -0
- package/dist/latex/temml.d.ts +25 -0
- package/dist/latex/temml.js +93 -0
- package/dist/markdown/math.cjs +110 -0
- package/dist/markdown/math.d.cts +9 -0
- package/dist/markdown/math.d.ts +9 -0
- package/dist/markdown/math.js +109 -0
- package/dist/markdown/read.cjs +3 -2
- package/dist/markdown/read.d.cts +2 -1
- package/dist/markdown/read.d.ts +2 -1
- package/dist/markdown/read.js +3 -2
- package/dist/markdown/write.cjs +23 -4
- package/dist/markdown/write.js +23 -4
- package/dist/model/formula.cjs +1 -1
- package/dist/model/formula.js +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/latex/symbols.ts
|
|
3
|
+
const COMMAND_GLYPHS = {
|
|
4
|
+
"\\alpha": "α",
|
|
5
|
+
"\\beta": "β",
|
|
6
|
+
"\\gamma": "γ",
|
|
7
|
+
"\\delta": "δ",
|
|
8
|
+
"\\epsilon": "ε",
|
|
9
|
+
"\\varepsilon": "ε",
|
|
10
|
+
"\\zeta": "ζ",
|
|
11
|
+
"\\eta": "η",
|
|
12
|
+
"\\theta": "θ",
|
|
13
|
+
"\\vartheta": "ϑ",
|
|
14
|
+
"\\iota": "ι",
|
|
15
|
+
"\\kappa": "κ",
|
|
16
|
+
"\\lambda": "λ",
|
|
17
|
+
"\\mu": "μ",
|
|
18
|
+
"\\nu": "ν",
|
|
19
|
+
"\\xi": "ξ",
|
|
20
|
+
"\\pi": "π",
|
|
21
|
+
"\\varpi": "ϖ",
|
|
22
|
+
"\\rho": "ρ",
|
|
23
|
+
"\\varrho": "ϱ",
|
|
24
|
+
"\\sigma": "σ",
|
|
25
|
+
"\\varsigma": "ς",
|
|
26
|
+
"\\tau": "τ",
|
|
27
|
+
"\\upsilon": "υ",
|
|
28
|
+
"\\phi": "φ",
|
|
29
|
+
"\\varphi": "φ",
|
|
30
|
+
"\\chi": "χ",
|
|
31
|
+
"\\psi": "ψ",
|
|
32
|
+
"\\omega": "ω",
|
|
33
|
+
"\\Gamma": "Γ",
|
|
34
|
+
"\\Delta": "Δ",
|
|
35
|
+
"\\Theta": "Θ",
|
|
36
|
+
"\\Lambda": "Λ",
|
|
37
|
+
"\\Xi": "Ξ",
|
|
38
|
+
"\\Pi": "Π",
|
|
39
|
+
"\\Sigma": "Σ",
|
|
40
|
+
"\\Upsilon": "Υ",
|
|
41
|
+
"\\Phi": "Φ",
|
|
42
|
+
"\\Psi": "Ψ",
|
|
43
|
+
"\\Omega": "Ω",
|
|
44
|
+
"\\infty": "∞",
|
|
45
|
+
"\\partial": "∂",
|
|
46
|
+
"\\nabla": "∇",
|
|
47
|
+
"\\ell": "ℓ",
|
|
48
|
+
"\\hbar": "ℏ",
|
|
49
|
+
"\\Re": "ℜ",
|
|
50
|
+
"\\Im": "ℑ",
|
|
51
|
+
"\\aleph": "ℵ"
|
|
52
|
+
};
|
|
53
|
+
function glyphOfSymbolText(text) {
|
|
54
|
+
if (!text.startsWith("\\")) return text;
|
|
55
|
+
return COMMAND_GLYPHS[text];
|
|
56
|
+
}
|
|
57
|
+
function mintedSymbolId(glyph) {
|
|
58
|
+
return `symbols:${glyph}`;
|
|
59
|
+
}
|
|
60
|
+
var SymbolResolver = class {
|
|
61
|
+
curated = /* @__PURE__ */ new Map();
|
|
62
|
+
minted = /* @__PURE__ */ new Map();
|
|
63
|
+
constructor(entries) {
|
|
64
|
+
for (const entry of entries) if (!this.curated.has(entry.glyph)) this.curated.set(entry.glyph, entry.id);
|
|
65
|
+
}
|
|
66
|
+
isCurated(glyph) {
|
|
67
|
+
return this.curated.has(glyph);
|
|
68
|
+
}
|
|
69
|
+
resolve(glyph) {
|
|
70
|
+
const curatedId = this.curated.get(glyph);
|
|
71
|
+
if (curatedId !== void 0) return curatedId;
|
|
72
|
+
const existing = this.minted.get(glyph);
|
|
73
|
+
if (existing !== void 0) return existing.id;
|
|
74
|
+
const id = mintedSymbolId(glyph);
|
|
75
|
+
this.minted.set(glyph, {
|
|
76
|
+
glyph,
|
|
77
|
+
scope: "document",
|
|
78
|
+
id
|
|
79
|
+
});
|
|
80
|
+
return id;
|
|
81
|
+
}
|
|
82
|
+
mintedEntries() {
|
|
83
|
+
return [...this.minted.values()];
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const PROSE_SYMBOL_PATTERN = /[A-Za-zΑ-ω](?:_[A-Za-z0-9]+)?/;
|
|
87
|
+
const PROSE_DEFINITION_PATTERNS = [/\bwhere\s+([^\s,.;:]+)\s+(?:is|are|denotes?|represents?|stands\s+for)\b/i, /\blet\s+([^\s,.;:]+)\s+(?:be|denote|represent|stand\s+for)\b/i];
|
|
88
|
+
function sentencesOf(text) {
|
|
89
|
+
return text.split(/(?<=[.!?])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
|
|
90
|
+
}
|
|
91
|
+
function extractSymbolDefinitionsFromProse(document, sink) {
|
|
92
|
+
if (document.kind !== "wordprocessing") return [];
|
|
93
|
+
const entries = [];
|
|
94
|
+
const seen = /* @__PURE__ */ new Set();
|
|
95
|
+
for (const section of document.sections) for (const block of section.blocks) {
|
|
96
|
+
if (block.kind !== "paragraph") continue;
|
|
97
|
+
const text = block.runs.map((run) => run.text).join("");
|
|
98
|
+
for (const sentence of sentencesOf(text)) {
|
|
99
|
+
const entry = proseDefinitionIn(sentence);
|
|
100
|
+
if (entry === void 0 || seen.has(entry.glyph)) continue;
|
|
101
|
+
seen.add(entry.glyph);
|
|
102
|
+
entries.push(entry);
|
|
103
|
+
sink?.({
|
|
104
|
+
code: "symbols/prose-definition-found",
|
|
105
|
+
detail: `"${entry.glyph}" from: ${sentence}`
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return entries;
|
|
110
|
+
}
|
|
111
|
+
function proseDefinitionIn(sentence) {
|
|
112
|
+
for (const pattern of PROSE_DEFINITION_PATTERNS) {
|
|
113
|
+
const candidate = pattern.exec(sentence)?.[1];
|
|
114
|
+
if (candidate === void 0) continue;
|
|
115
|
+
if (PROSE_SYMBOL_PATTERN.exec(candidate)?.[0] !== candidate) continue;
|
|
116
|
+
return {
|
|
117
|
+
glyph: candidate,
|
|
118
|
+
scope: "document",
|
|
119
|
+
id: mintedSymbolId(candidate),
|
|
120
|
+
definitionSource: sentence
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
exports.SymbolResolver = SymbolResolver;
|
|
126
|
+
exports.extractSymbolDefinitionsFromProse = extractSymbolDefinitionsFromProse;
|
|
127
|
+
exports.glyphOfSymbolText = glyphOfSymbolText;
|
|
128
|
+
exports.mintedSymbolId = mintedSymbolId;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { n as LatexDiagnostic } from "../diagnostics-C5-bG09J.cjs";
|
|
2
|
+
import { ContentDocument, MathSymbolEntry } from "document-schema.js";
|
|
3
|
+
//#region src/latex/symbols.d.ts
|
|
4
|
+
declare function glyphOfSymbolText(text: string): string | undefined;
|
|
5
|
+
declare function mintedSymbolId(glyph: string): string;
|
|
6
|
+
declare class SymbolResolver {
|
|
7
|
+
private readonly curated;
|
|
8
|
+
private readonly minted;
|
|
9
|
+
constructor(entries: readonly MathSymbolEntry[]);
|
|
10
|
+
isCurated(glyph: string): boolean;
|
|
11
|
+
resolve(glyph: string): string;
|
|
12
|
+
mintedEntries(): readonly MathSymbolEntry[];
|
|
13
|
+
}
|
|
14
|
+
declare function extractSymbolDefinitionsFromProse(document: ContentDocument, sink?: (diagnostic: LatexDiagnostic) => void): MathSymbolEntry[];
|
|
15
|
+
//#endregion
|
|
16
|
+
export { SymbolResolver, extractSymbolDefinitionsFromProse, glyphOfSymbolText, mintedSymbolId };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { n as LatexDiagnostic } from "../diagnostics-C5-bG09J.js";
|
|
2
|
+
import { ContentDocument, MathSymbolEntry } from "document-schema.js";
|
|
3
|
+
//#region src/latex/symbols.d.ts
|
|
4
|
+
declare function glyphOfSymbolText(text: string): string | undefined;
|
|
5
|
+
declare function mintedSymbolId(glyph: string): string;
|
|
6
|
+
declare class SymbolResolver {
|
|
7
|
+
private readonly curated;
|
|
8
|
+
private readonly minted;
|
|
9
|
+
constructor(entries: readonly MathSymbolEntry[]);
|
|
10
|
+
isCurated(glyph: string): boolean;
|
|
11
|
+
resolve(glyph: string): string;
|
|
12
|
+
mintedEntries(): readonly MathSymbolEntry[];
|
|
13
|
+
}
|
|
14
|
+
declare function extractSymbolDefinitionsFromProse(document: ContentDocument, sink?: (diagnostic: LatexDiagnostic) => void): MathSymbolEntry[];
|
|
15
|
+
//#endregion
|
|
16
|
+
export { SymbolResolver, extractSymbolDefinitionsFromProse, glyphOfSymbolText, mintedSymbolId };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//#region src/latex/symbols.ts
|
|
2
|
+
const COMMAND_GLYPHS = {
|
|
3
|
+
"\\alpha": "α",
|
|
4
|
+
"\\beta": "β",
|
|
5
|
+
"\\gamma": "γ",
|
|
6
|
+
"\\delta": "δ",
|
|
7
|
+
"\\epsilon": "ε",
|
|
8
|
+
"\\varepsilon": "ε",
|
|
9
|
+
"\\zeta": "ζ",
|
|
10
|
+
"\\eta": "η",
|
|
11
|
+
"\\theta": "θ",
|
|
12
|
+
"\\vartheta": "ϑ",
|
|
13
|
+
"\\iota": "ι",
|
|
14
|
+
"\\kappa": "κ",
|
|
15
|
+
"\\lambda": "λ",
|
|
16
|
+
"\\mu": "μ",
|
|
17
|
+
"\\nu": "ν",
|
|
18
|
+
"\\xi": "ξ",
|
|
19
|
+
"\\pi": "π",
|
|
20
|
+
"\\varpi": "ϖ",
|
|
21
|
+
"\\rho": "ρ",
|
|
22
|
+
"\\varrho": "ϱ",
|
|
23
|
+
"\\sigma": "σ",
|
|
24
|
+
"\\varsigma": "ς",
|
|
25
|
+
"\\tau": "τ",
|
|
26
|
+
"\\upsilon": "υ",
|
|
27
|
+
"\\phi": "φ",
|
|
28
|
+
"\\varphi": "φ",
|
|
29
|
+
"\\chi": "χ",
|
|
30
|
+
"\\psi": "ψ",
|
|
31
|
+
"\\omega": "ω",
|
|
32
|
+
"\\Gamma": "Γ",
|
|
33
|
+
"\\Delta": "Δ",
|
|
34
|
+
"\\Theta": "Θ",
|
|
35
|
+
"\\Lambda": "Λ",
|
|
36
|
+
"\\Xi": "Ξ",
|
|
37
|
+
"\\Pi": "Π",
|
|
38
|
+
"\\Sigma": "Σ",
|
|
39
|
+
"\\Upsilon": "Υ",
|
|
40
|
+
"\\Phi": "Φ",
|
|
41
|
+
"\\Psi": "Ψ",
|
|
42
|
+
"\\Omega": "Ω",
|
|
43
|
+
"\\infty": "∞",
|
|
44
|
+
"\\partial": "∂",
|
|
45
|
+
"\\nabla": "∇",
|
|
46
|
+
"\\ell": "ℓ",
|
|
47
|
+
"\\hbar": "ℏ",
|
|
48
|
+
"\\Re": "ℜ",
|
|
49
|
+
"\\Im": "ℑ",
|
|
50
|
+
"\\aleph": "ℵ"
|
|
51
|
+
};
|
|
52
|
+
function glyphOfSymbolText(text) {
|
|
53
|
+
if (!text.startsWith("\\")) return text;
|
|
54
|
+
return COMMAND_GLYPHS[text];
|
|
55
|
+
}
|
|
56
|
+
function mintedSymbolId(glyph) {
|
|
57
|
+
return `symbols:${glyph}`;
|
|
58
|
+
}
|
|
59
|
+
var SymbolResolver = class {
|
|
60
|
+
curated = /* @__PURE__ */ new Map();
|
|
61
|
+
minted = /* @__PURE__ */ new Map();
|
|
62
|
+
constructor(entries) {
|
|
63
|
+
for (const entry of entries) if (!this.curated.has(entry.glyph)) this.curated.set(entry.glyph, entry.id);
|
|
64
|
+
}
|
|
65
|
+
isCurated(glyph) {
|
|
66
|
+
return this.curated.has(glyph);
|
|
67
|
+
}
|
|
68
|
+
resolve(glyph) {
|
|
69
|
+
const curatedId = this.curated.get(glyph);
|
|
70
|
+
if (curatedId !== void 0) return curatedId;
|
|
71
|
+
const existing = this.minted.get(glyph);
|
|
72
|
+
if (existing !== void 0) return existing.id;
|
|
73
|
+
const id = mintedSymbolId(glyph);
|
|
74
|
+
this.minted.set(glyph, {
|
|
75
|
+
glyph,
|
|
76
|
+
scope: "document",
|
|
77
|
+
id
|
|
78
|
+
});
|
|
79
|
+
return id;
|
|
80
|
+
}
|
|
81
|
+
mintedEntries() {
|
|
82
|
+
return [...this.minted.values()];
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const PROSE_SYMBOL_PATTERN = /[A-Za-zΑ-ω](?:_[A-Za-z0-9]+)?/;
|
|
86
|
+
const PROSE_DEFINITION_PATTERNS = [/\bwhere\s+([^\s,.;:]+)\s+(?:is|are|denotes?|represents?|stands\s+for)\b/i, /\blet\s+([^\s,.;:]+)\s+(?:be|denote|represent|stand\s+for)\b/i];
|
|
87
|
+
function sentencesOf(text) {
|
|
88
|
+
return text.split(/(?<=[.!?])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
|
|
89
|
+
}
|
|
90
|
+
function extractSymbolDefinitionsFromProse(document, sink) {
|
|
91
|
+
if (document.kind !== "wordprocessing") return [];
|
|
92
|
+
const entries = [];
|
|
93
|
+
const seen = /* @__PURE__ */ new Set();
|
|
94
|
+
for (const section of document.sections) for (const block of section.blocks) {
|
|
95
|
+
if (block.kind !== "paragraph") continue;
|
|
96
|
+
const text = block.runs.map((run) => run.text).join("");
|
|
97
|
+
for (const sentence of sentencesOf(text)) {
|
|
98
|
+
const entry = proseDefinitionIn(sentence);
|
|
99
|
+
if (entry === void 0 || seen.has(entry.glyph)) continue;
|
|
100
|
+
seen.add(entry.glyph);
|
|
101
|
+
entries.push(entry);
|
|
102
|
+
sink?.({
|
|
103
|
+
code: "symbols/prose-definition-found",
|
|
104
|
+
detail: `"${entry.glyph}" from: ${sentence}`
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return entries;
|
|
109
|
+
}
|
|
110
|
+
function proseDefinitionIn(sentence) {
|
|
111
|
+
for (const pattern of PROSE_DEFINITION_PATTERNS) {
|
|
112
|
+
const candidate = pattern.exec(sentence)?.[1];
|
|
113
|
+
if (candidate === void 0) continue;
|
|
114
|
+
if (PROSE_SYMBOL_PATTERN.exec(candidate)?.[0] !== candidate) continue;
|
|
115
|
+
return {
|
|
116
|
+
glyph: candidate,
|
|
117
|
+
scope: "document",
|
|
118
|
+
id: mintedSymbolId(candidate),
|
|
119
|
+
definitionSource: sentence
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { SymbolResolver, extractSymbolDefinitionsFromProse, glyphOfSymbolText, mintedSymbolId };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let temml = require("temml");
|
|
25
|
+
temml = __toESM(temml, 1);
|
|
26
|
+
//#region src/latex/temml.ts
|
|
27
|
+
const TEMML_OPTIONS = { throwOnError: true };
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function isTemmlNode(value) {
|
|
32
|
+
return isRecord(value) && typeof value.type === "string";
|
|
33
|
+
}
|
|
34
|
+
function isTemmlNodeArray(value) {
|
|
35
|
+
return Array.isArray(value) && value.every(isTemmlNode);
|
|
36
|
+
}
|
|
37
|
+
function sourceSpanOf(node) {
|
|
38
|
+
const loc = node.loc;
|
|
39
|
+
if (!isRecord(loc)) return;
|
|
40
|
+
const start = loc.start;
|
|
41
|
+
const end = loc.end;
|
|
42
|
+
if (typeof start !== "number" || typeof end !== "number" || !Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) return;
|
|
43
|
+
return {
|
|
44
|
+
start,
|
|
45
|
+
end
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function sourceSlice(input, span) {
|
|
49
|
+
if (span === void 0) return "";
|
|
50
|
+
return input.slice(span.start, span.end);
|
|
51
|
+
}
|
|
52
|
+
function parseLatex(latex) {
|
|
53
|
+
try {
|
|
54
|
+
const nodes = temml.default.__parse(latex, TEMML_OPTIONS);
|
|
55
|
+
if (!isTemmlNodeArray(nodes)) return {
|
|
56
|
+
status: "unparseable",
|
|
57
|
+
message: "parser returned a shape this package does not recognise"
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
status: "parsed",
|
|
61
|
+
nodes,
|
|
62
|
+
mathml: mathmlOf(latex)
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
status: "unparseable",
|
|
67
|
+
message: errorMessage(error)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function errorMessage(error) {
|
|
72
|
+
return error instanceof Error ? error.message : String(error);
|
|
73
|
+
}
|
|
74
|
+
function mathmlOf(latex) {
|
|
75
|
+
let root;
|
|
76
|
+
try {
|
|
77
|
+
root = temml.default.__renderToMathMLTree(latex, TEMML_OPTIONS);
|
|
78
|
+
} catch {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return toMathMlNodes(root) ?? [];
|
|
82
|
+
}
|
|
83
|
+
function toMathMlNodes(value) {
|
|
84
|
+
if (!isRecord(value)) return;
|
|
85
|
+
if (typeof value.text === "string" && value.type === void 0) return [{
|
|
86
|
+
type: "text",
|
|
87
|
+
value: value.text
|
|
88
|
+
}];
|
|
89
|
+
if (!Array.isArray(value.children)) return;
|
|
90
|
+
const children = [];
|
|
91
|
+
for (const child of value.children) {
|
|
92
|
+
const converted = toMathMlNodes(child);
|
|
93
|
+
if (converted === void 0) return;
|
|
94
|
+
children.push(...converted);
|
|
95
|
+
}
|
|
96
|
+
if (value.type === void 0) return children;
|
|
97
|
+
if (typeof value.type !== "string") return;
|
|
98
|
+
const attributes = attributesOf(value.attributes);
|
|
99
|
+
if (attributes === void 0) return;
|
|
100
|
+
return [{
|
|
101
|
+
type: "element",
|
|
102
|
+
tag: value.type,
|
|
103
|
+
attributes,
|
|
104
|
+
children
|
|
105
|
+
}];
|
|
106
|
+
}
|
|
107
|
+
function attributesOf(value) {
|
|
108
|
+
if (!isRecord(value)) return;
|
|
109
|
+
const attributes = [];
|
|
110
|
+
for (const [name, attributeValue] of Object.entries(value)) if (typeof attributeValue === "string" || typeof attributeValue === "number" || typeof attributeValue === "boolean") attributes.push({
|
|
111
|
+
name,
|
|
112
|
+
value: String(attributeValue)
|
|
113
|
+
});
|
|
114
|
+
return attributes;
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
exports.isTemmlNode = isTemmlNode;
|
|
118
|
+
exports.isTemmlNodeArray = isTemmlNodeArray;
|
|
119
|
+
exports.parseLatex = parseLatex;
|
|
120
|
+
exports.sourceSlice = sourceSlice;
|
|
121
|
+
exports.sourceSpanOf = sourceSpanOf;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MathMlNode } from "document-schema.js";
|
|
2
|
+
//#region src/latex/temml.d.ts
|
|
3
|
+
interface TemmlNode {
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly [field: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
declare function isTemmlNode(value: unknown): value is TemmlNode;
|
|
8
|
+
declare function isTemmlNodeArray(value: unknown): value is TemmlNode[];
|
|
9
|
+
interface TemmlSourceSpan {
|
|
10
|
+
readonly start: number;
|
|
11
|
+
readonly end: number;
|
|
12
|
+
}
|
|
13
|
+
declare function sourceSpanOf(node: TemmlNode): TemmlSourceSpan | undefined;
|
|
14
|
+
declare function sourceSlice(input: string, span: TemmlSourceSpan | undefined): string;
|
|
15
|
+
type LatexParseResult = {
|
|
16
|
+
readonly status: 'parsed';
|
|
17
|
+
readonly nodes: readonly TemmlNode[];
|
|
18
|
+
readonly mathml: readonly MathMlNode[];
|
|
19
|
+
} | {
|
|
20
|
+
readonly status: 'unparseable';
|
|
21
|
+
readonly message: string;
|
|
22
|
+
};
|
|
23
|
+
declare function parseLatex(latex: string): LatexParseResult;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { LatexParseResult, TemmlNode, TemmlSourceSpan, isTemmlNode, isTemmlNodeArray, parseLatex, sourceSlice, sourceSpanOf };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MathMlNode } from "document-schema.js";
|
|
2
|
+
//#region src/latex/temml.d.ts
|
|
3
|
+
interface TemmlNode {
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly [field: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
declare function isTemmlNode(value: unknown): value is TemmlNode;
|
|
8
|
+
declare function isTemmlNodeArray(value: unknown): value is TemmlNode[];
|
|
9
|
+
interface TemmlSourceSpan {
|
|
10
|
+
readonly start: number;
|
|
11
|
+
readonly end: number;
|
|
12
|
+
}
|
|
13
|
+
declare function sourceSpanOf(node: TemmlNode): TemmlSourceSpan | undefined;
|
|
14
|
+
declare function sourceSlice(input: string, span: TemmlSourceSpan | undefined): string;
|
|
15
|
+
type LatexParseResult = {
|
|
16
|
+
readonly status: 'parsed';
|
|
17
|
+
readonly nodes: readonly TemmlNode[];
|
|
18
|
+
readonly mathml: readonly MathMlNode[];
|
|
19
|
+
} | {
|
|
20
|
+
readonly status: 'unparseable';
|
|
21
|
+
readonly message: string;
|
|
22
|
+
};
|
|
23
|
+
declare function parseLatex(latex: string): LatexParseResult;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { LatexParseResult, TemmlNode, TemmlSourceSpan, isTemmlNode, isTemmlNodeArray, parseLatex, sourceSlice, sourceSpanOf };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import temml from "temml";
|
|
2
|
+
//#region src/latex/temml.ts
|
|
3
|
+
const TEMML_OPTIONS = { throwOnError: true };
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function isTemmlNode(value) {
|
|
8
|
+
return isRecord(value) && typeof value.type === "string";
|
|
9
|
+
}
|
|
10
|
+
function isTemmlNodeArray(value) {
|
|
11
|
+
return Array.isArray(value) && value.every(isTemmlNode);
|
|
12
|
+
}
|
|
13
|
+
function sourceSpanOf(node) {
|
|
14
|
+
const loc = node.loc;
|
|
15
|
+
if (!isRecord(loc)) return;
|
|
16
|
+
const start = loc.start;
|
|
17
|
+
const end = loc.end;
|
|
18
|
+
if (typeof start !== "number" || typeof end !== "number" || !Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) return;
|
|
19
|
+
return {
|
|
20
|
+
start,
|
|
21
|
+
end
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function sourceSlice(input, span) {
|
|
25
|
+
if (span === void 0) return "";
|
|
26
|
+
return input.slice(span.start, span.end);
|
|
27
|
+
}
|
|
28
|
+
function parseLatex(latex) {
|
|
29
|
+
try {
|
|
30
|
+
const nodes = temml.__parse(latex, TEMML_OPTIONS);
|
|
31
|
+
if (!isTemmlNodeArray(nodes)) return {
|
|
32
|
+
status: "unparseable",
|
|
33
|
+
message: "parser returned a shape this package does not recognise"
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
status: "parsed",
|
|
37
|
+
nodes,
|
|
38
|
+
mathml: mathmlOf(latex)
|
|
39
|
+
};
|
|
40
|
+
} catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
status: "unparseable",
|
|
43
|
+
message: errorMessage(error)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function errorMessage(error) {
|
|
48
|
+
return error instanceof Error ? error.message : String(error);
|
|
49
|
+
}
|
|
50
|
+
function mathmlOf(latex) {
|
|
51
|
+
let root;
|
|
52
|
+
try {
|
|
53
|
+
root = temml.__renderToMathMLTree(latex, TEMML_OPTIONS);
|
|
54
|
+
} catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
return toMathMlNodes(root) ?? [];
|
|
58
|
+
}
|
|
59
|
+
function toMathMlNodes(value) {
|
|
60
|
+
if (!isRecord(value)) return;
|
|
61
|
+
if (typeof value.text === "string" && value.type === void 0) return [{
|
|
62
|
+
type: "text",
|
|
63
|
+
value: value.text
|
|
64
|
+
}];
|
|
65
|
+
if (!Array.isArray(value.children)) return;
|
|
66
|
+
const children = [];
|
|
67
|
+
for (const child of value.children) {
|
|
68
|
+
const converted = toMathMlNodes(child);
|
|
69
|
+
if (converted === void 0) return;
|
|
70
|
+
children.push(...converted);
|
|
71
|
+
}
|
|
72
|
+
if (value.type === void 0) return children;
|
|
73
|
+
if (typeof value.type !== "string") return;
|
|
74
|
+
const attributes = attributesOf(value.attributes);
|
|
75
|
+
if (attributes === void 0) return;
|
|
76
|
+
return [{
|
|
77
|
+
type: "element",
|
|
78
|
+
tag: value.type,
|
|
79
|
+
attributes,
|
|
80
|
+
children
|
|
81
|
+
}];
|
|
82
|
+
}
|
|
83
|
+
function attributesOf(value) {
|
|
84
|
+
if (!isRecord(value)) return;
|
|
85
|
+
const attributes = [];
|
|
86
|
+
for (const [name, attributeValue] of Object.entries(value)) if (typeof attributeValue === "string" || typeof attributeValue === "number" || typeof attributeValue === "boolean") attributes.push({
|
|
87
|
+
name,
|
|
88
|
+
value: String(attributeValue)
|
|
89
|
+
});
|
|
90
|
+
return attributes;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { isTemmlNode, isTemmlNodeArray, parseLatex, sourceSlice, sourceSpanOf };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_model_formula = require("../model/formula.cjs");
|
|
3
|
+
const require_latex_symbols = require("../latex/symbols.cjs");
|
|
4
|
+
const require_latex_lower = require("../latex/lower.cjs");
|
|
5
|
+
//#region src/markdown/math.ts
|
|
6
|
+
const MATH_BLOCK_STYLE_ID = "MathBlock";
|
|
7
|
+
const MATH_INLINE_FONT_MARKER = "Cambria Math";
|
|
8
|
+
const STAND_IN_FRAME = {
|
|
9
|
+
xPt: 0,
|
|
10
|
+
yPt: 0,
|
|
11
|
+
widthPt: 0,
|
|
12
|
+
heightPt: 22
|
|
13
|
+
};
|
|
14
|
+
const MATH_BLOCK_SOURCE = "markdown:math-block";
|
|
15
|
+
const MATH_INLINE_SOURCE = "markdown:math-inline";
|
|
16
|
+
function extractInlineMath(runs) {
|
|
17
|
+
const latexRuns = [];
|
|
18
|
+
const remainingRuns = [];
|
|
19
|
+
for (const run of runs) {
|
|
20
|
+
if (run.fontFamily === MATH_INLINE_FONT_MARKER && run.text.trim() !== "") {
|
|
21
|
+
latexRuns.push(run.text);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
remainingRuns.push(run);
|
|
25
|
+
}
|
|
26
|
+
const consumed = latexRuns.length > 0 && remainingRuns.every((run) => run.text === "");
|
|
27
|
+
return {
|
|
28
|
+
latexRuns,
|
|
29
|
+
remainingRuns: consumed ? [] : remainingRuns,
|
|
30
|
+
consumed
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function lowerMarkdownMath(document, options) {
|
|
34
|
+
if (document.kind !== "wordprocessing") return document;
|
|
35
|
+
const sink = options?.onDiagnostic;
|
|
36
|
+
const proseEntries = require_latex_symbols.extractSymbolDefinitionsFromProse(document, sink);
|
|
37
|
+
const known = new Map(proseEntries.map((entry) => [entry.glyph, entry]));
|
|
38
|
+
const minted = /* @__PURE__ */ new Map();
|
|
39
|
+
const lowerOne = (latex, source) => {
|
|
40
|
+
if (latex.trim() === "") return;
|
|
41
|
+
const result = require_latex_lower.latexToFormula(latex, {
|
|
42
|
+
symbolEntries: [...known.values()],
|
|
43
|
+
source
|
|
44
|
+
});
|
|
45
|
+
for (const diagnostic of result.diagnostics) sink?.(diagnostic);
|
|
46
|
+
for (const entry of result.mintedSymbols) if (!known.has(entry.glyph) && !minted.has(entry.glyph)) minted.set(entry.glyph, entry);
|
|
47
|
+
return require_model_formula.buildFormulaBlock(result.formula, STAND_IN_FRAME, source);
|
|
48
|
+
};
|
|
49
|
+
const lowerBlocks = (blocks) => {
|
|
50
|
+
const out = [];
|
|
51
|
+
for (const block of blocks) {
|
|
52
|
+
if (block.kind === "table") {
|
|
53
|
+
out.push({
|
|
54
|
+
...block,
|
|
55
|
+
rows: block.rows.map((row) => ({
|
|
56
|
+
...row,
|
|
57
|
+
cells: row.cells.map((cell) => ({
|
|
58
|
+
...cell,
|
|
59
|
+
blocks: lowerBlocks(cell.blocks)
|
|
60
|
+
}))
|
|
61
|
+
}))
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (block.kind !== "paragraph") {
|
|
66
|
+
out.push(block);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (block.styleId === MATH_BLOCK_STYLE_ID) {
|
|
70
|
+
const latex = block.runs.map((run) => run.text).join("");
|
|
71
|
+
const formulaBlock = lowerOne(latex, MATH_BLOCK_SOURCE);
|
|
72
|
+
out.push(formulaBlock ?? block);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const extraction = extractInlineMath(block.runs);
|
|
76
|
+
if (extraction.latexRuns.length === 0) {
|
|
77
|
+
out.push(block);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (!extraction.consumed) out.push({
|
|
81
|
+
...block,
|
|
82
|
+
runs: [...extraction.remainingRuns]
|
|
83
|
+
});
|
|
84
|
+
for (const latex of extraction.latexRuns) {
|
|
85
|
+
const formulaBlock = lowerOne(latex, MATH_INLINE_SOURCE);
|
|
86
|
+
if (formulaBlock !== void 0) out.push(formulaBlock);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
};
|
|
91
|
+
const sections = document.sections.map((section) => ({
|
|
92
|
+
...section,
|
|
93
|
+
blocks: lowerBlocks(section.blocks)
|
|
94
|
+
}));
|
|
95
|
+
const symbols = [...known.values(), ...minted.values()];
|
|
96
|
+
if (symbols.length === 0) return {
|
|
97
|
+
...document,
|
|
98
|
+
sections
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
...document,
|
|
102
|
+
sections,
|
|
103
|
+
symbolTable: {
|
|
104
|
+
symbols,
|
|
105
|
+
units: []
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
exports.lowerMarkdownMath = lowerMarkdownMath;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { i as LatexDiagnosticSink } from "../diagnostics-C5-bG09J.cjs";
|
|
2
|
+
import { ContentDocument } from "document-schema.js";
|
|
3
|
+
//#region src/markdown/math.d.ts
|
|
4
|
+
interface MarkdownMathLoweringOptions {
|
|
5
|
+
readonly onDiagnostic?: LatexDiagnosticSink;
|
|
6
|
+
}
|
|
7
|
+
declare function lowerMarkdownMath(document: ContentDocument, options?: MarkdownMathLoweringOptions): ContentDocument;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { MarkdownMathLoweringOptions, lowerMarkdownMath };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { i as LatexDiagnosticSink } from "../diagnostics-C5-bG09J.js";
|
|
2
|
+
import { ContentDocument } from "document-schema.js";
|
|
3
|
+
//#region src/markdown/math.d.ts
|
|
4
|
+
interface MarkdownMathLoweringOptions {
|
|
5
|
+
readonly onDiagnostic?: LatexDiagnosticSink;
|
|
6
|
+
}
|
|
7
|
+
declare function lowerMarkdownMath(document: ContentDocument, options?: MarkdownMathLoweringOptions): ContentDocument;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { MarkdownMathLoweringOptions, lowerMarkdownMath };
|