@w100n/documents 0.14.0 → 0.15.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.
@@ -1,7 +1,267 @@
1
1
  'use client';
2
2
 
3
+ // src/editor/math.ts
4
+ var words = {
5
+ alpha: "\u03B1",
6
+ beta: "\u03B2",
7
+ gamma: "\u03B3",
8
+ delta: "\u03B4",
9
+ epsilon: "\u03B5",
10
+ zeta: "\u03B6",
11
+ eta: "\u03B7",
12
+ theta: "\u03B8",
13
+ iota: "\u03B9",
14
+ kappa: "\u03BA",
15
+ lambda: "\u03BB",
16
+ mu: "\u03BC",
17
+ nu: "\u03BD",
18
+ xi: "\u03BE",
19
+ pi: "\u03C0",
20
+ rho: "\u03C1",
21
+ sigma: "\u03C3",
22
+ tau: "\u03C4",
23
+ upsilon: "\u03C5",
24
+ phi: "\u03C6",
25
+ chi: "\u03C7",
26
+ psi: "\u03C8",
27
+ omega: "\u03C9",
28
+ Gamma: "\u0393",
29
+ Delta: "\u0394",
30
+ Theta: "\u0398",
31
+ Lambda: "\u039B",
32
+ Xi: "\u039E",
33
+ Pi: "\u03A0",
34
+ Sigma: "\u03A3",
35
+ Phi: "\u03A6",
36
+ Psi: "\u03A8",
37
+ Omega: "\u03A9",
38
+ infty: "\u221E",
39
+ partial: "\u2202",
40
+ nabla: "\u2207"
41
+ };
42
+ var ops = {
43
+ cdot: "\xB7",
44
+ times: "\xD7",
45
+ div: "\xF7",
46
+ pm: "\xB1",
47
+ mp: "\u2213",
48
+ le: "\u2264",
49
+ leq: "\u2264",
50
+ ge: "\u2265",
51
+ geq: "\u2265",
52
+ ne: "\u2260",
53
+ neq: "\u2260",
54
+ approx: "\u2248",
55
+ equiv: "\u2261",
56
+ to: "\u2192",
57
+ rightarrow: "\u2192",
58
+ leftarrow: "\u2190",
59
+ Rightarrow: "\u21D2",
60
+ in: "\u2208",
61
+ notin: "\u2209",
62
+ subset: "\u2282",
63
+ cup: "\u222A",
64
+ cap: "\u2229",
65
+ forall: "\u2200",
66
+ exists: "\u2203",
67
+ sum: "\u2211",
68
+ prod: "\u220F",
69
+ int: "\u222B",
70
+ oint: "\u222E",
71
+ degree: "\xB0"
72
+ };
73
+ var big = /* @__PURE__ */ new Set(["\u2211", "\u220F", "\u222B", "\u222E"]);
74
+ var glyph = {};
75
+ for (const [k, v] of [...Object.entries(words), ...Object.entries(ops)]) glyph[v] ?? (glyph[v] = k);
76
+ function parse(src) {
77
+ let i = 0;
78
+ const group = () => {
79
+ if (src[i] === "{") {
80
+ i++;
81
+ const kids2 = row("}");
82
+ i++;
83
+ return kids2.length === 1 ? kids2[0] : { t: "row", kids: kids2 };
84
+ }
85
+ return one() ?? { t: "row", kids: [] };
86
+ };
87
+ const one = () => {
88
+ while (src[i] === " ") i++;
89
+ if (i >= src.length) return null;
90
+ const c = src[i];
91
+ if (c === "{") return group();
92
+ if (c === "\\") {
93
+ const m = /^\\([a-zA-Z]+|.)/.exec(src.slice(i));
94
+ if (!m) {
95
+ i++;
96
+ return { t: "tok", v: "\\", kind: "mo" };
97
+ }
98
+ i += m[0].length;
99
+ const name = m[1];
100
+ if (name === "frac") return { t: "frac", num: group(), den: group() };
101
+ if (name === "sqrt") {
102
+ let deg = null;
103
+ if (src[i] === "[") {
104
+ const end = src.indexOf("]", i);
105
+ deg = parse(src.slice(i + 1, end < 0 ? src.length : end));
106
+ i = end < 0 ? src.length : end + 1;
107
+ }
108
+ return { t: "sqrt", body: group(), deg };
109
+ }
110
+ if (name === "text" || name === "mathrm") {
111
+ const g = src[i] === "{" ? src.indexOf("}", i) : -1;
112
+ const v = g < 0 ? "" : src.slice(i + 1, g);
113
+ i = g < 0 ? i : g + 1;
114
+ return { t: "tok", v, kind: "mtext" };
115
+ }
116
+ if (name === "left" || name === "right") return one();
117
+ if (words[name]) return { t: "tok", v: words[name], kind: "mi" };
118
+ if (ops[name]) return { t: "tok", v: ops[name], kind: "mo" };
119
+ return { t: "tok", v: name.length === 1 ? name : `\\${name}`, kind: name.length === 1 ? "mo" : "mi" };
120
+ }
121
+ if (/[0-9.]/.test(c)) {
122
+ const m = /^[0-9]*\.?[0-9]+|^[0-9]+/.exec(src.slice(i));
123
+ i += m[0].length;
124
+ return { t: "tok", v: m[0], kind: "mn" };
125
+ }
126
+ i++;
127
+ if (/[\p{L}]/u.test(c)) return { t: "tok", v: c, kind: big.has(c) ? "mo" : "mi" };
128
+ return { t: "tok", v: c, kind: "mo" };
129
+ };
130
+ const row = (stop) => {
131
+ const kids2 = [];
132
+ while (i < src.length && src[i] !== stop) {
133
+ while (src[i] === " ") i++;
134
+ if (i >= src.length || src[i] === stop) break;
135
+ if (src[i] === "^" || src[i] === "_") {
136
+ const base = kids2.pop() ?? { t: "row", kids: [] };
137
+ const s = base.t === "script" && !base.sub !== !base.sup ? base : { t: "script", base, sub: null, sup: null };
138
+ const which = src[i++] === "^" ? "sup" : "sub";
139
+ s[which] = group();
140
+ kids2.push(s);
141
+ continue;
142
+ }
143
+ if (src[i] === "}") {
144
+ i++;
145
+ continue;
146
+ }
147
+ const a = one();
148
+ if (a) kids2.push(a);
149
+ }
150
+ return kids2;
151
+ };
152
+ const kids = row("\0");
153
+ return kids.length === 1 ? kids[0] : { t: "row", kids };
154
+ }
155
+ var esc = (v) => v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
156
+ function ml(a) {
157
+ switch (a.t) {
158
+ case "tok":
159
+ return `<${a.kind}>${esc(a.v)}</${a.kind}>`;
160
+ case "row":
161
+ return `<mrow>${a.kids.map(ml).join("")}</mrow>`;
162
+ case "frac":
163
+ return `<mfrac>${ml(a.num)}${ml(a.den)}</mfrac>`;
164
+ case "sqrt":
165
+ return a.deg ? `<mroot>${ml(a.body)}${ml(a.deg)}</mroot>` : `<msqrt>${ml(a.body)}</msqrt>`;
166
+ case "script": {
167
+ const over = a.base.t === "tok" && big.has(a.base.v);
168
+ if (a.sub && a.sup) return `<${over ? "munderover" : "msubsup"}>${ml(a.base)}${ml(a.sub)}${ml(a.sup)}</${over ? "munderover" : "msubsup"}>`;
169
+ if (a.sub) return `<${over ? "munder" : "msub"}>${ml(a.base)}${ml(a.sub)}</${over ? "munder" : "msub"}>`;
170
+ return `<${over ? "mover" : "msup"}>${ml(a.base)}${ml(a.sup)}</${over ? "mover" : "msup"}>`;
171
+ }
172
+ }
173
+ }
174
+ var mathml = (latex) => `<math xmlns="http://www.w3.org/1998/Math/MathML">${ml(parse(latex))}</math>`;
175
+ var run = (v, plain2 = false) => `<m:r>${plain2 ? '<m:rPr><m:sty m:val="p"/></m:rPr>' : ""}<m:t xml:space="preserve">${esc(v)}</m:t></m:r>`;
176
+ function om(a) {
177
+ switch (a.t) {
178
+ case "tok":
179
+ return run(a.v, a.kind === "mtext" || a.kind === "mo" && !big.has(a.v));
180
+ case "row":
181
+ return a.kids.map(om).join("");
182
+ case "frac":
183
+ return `<m:f><m:num>${om(a.num)}</m:num><m:den>${om(a.den)}</m:den></m:f>`;
184
+ case "sqrt":
185
+ return a.deg ? `<m:rad><m:deg>${om(a.deg)}</m:deg><m:e>${om(a.body)}</m:e></m:rad>` : `<m:rad><m:radPr><m:degHide m:val="1"/></m:radPr><m:deg/><m:e>${om(a.body)}</m:e></m:rad>`;
186
+ case "script": {
187
+ if (a.base.t === "tok" && big.has(a.base.v)) return `<m:nary><m:naryPr><m:chr m:val="${a.base.v}"/>${a.sub ? "" : '<m:subHide m:val="1"/>'}${a.sup ? "" : '<m:supHide m:val="1"/>'}</m:naryPr><m:sub>${a.sub ? om(a.sub) : ""}</m:sub><m:sup>${a.sup ? om(a.sup) : ""}</m:sup><m:e/></m:nary>`;
188
+ if (a.sub && a.sup) return `<m:sSubSup><m:e>${om(a.base)}</m:e><m:sub>${om(a.sub)}</m:sub><m:sup>${om(a.sup)}</m:sup></m:sSubSup>`;
189
+ if (a.sub) return `<m:sSub><m:e>${om(a.base)}</m:e><m:sub>${om(a.sub)}</m:sub></m:sSub>`;
190
+ return `<m:sSup><m:e>${om(a.base)}</m:e><m:sup>${om(a.sup)}</m:sup></m:sSup>`;
191
+ }
192
+ }
193
+ }
194
+ var omml = (latex) => `<m:oMath xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">${om(parse(latex))}</m:oMath>`;
195
+ function tree(xml) {
196
+ const root = { name: "", kids: [], text: "", attrs: {} };
197
+ const stack = [root];
198
+ for (const m of xml.matchAll(/<(\/?)([\w:]+)([^>]*?)(\/?)>|([^<]+)/g)) {
199
+ const top = stack[stack.length - 1];
200
+ if (m[5] !== void 0) {
201
+ top.text += m[5];
202
+ continue;
203
+ }
204
+ if (m[1]) {
205
+ stack.pop();
206
+ continue;
207
+ }
208
+ const attrs2 = Object.fromEntries([...m[3].matchAll(/([\w:]+)="([^"]*)"/g)].map((a) => [a[1], a[2]]));
209
+ const node = { name: m[2], kids: [], text: "", attrs: attrs2 };
210
+ top.kids.push(node);
211
+ if (!m[4]) stack.push(node);
212
+ }
213
+ return root;
214
+ }
215
+ var unesc = (v) => v.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
216
+ var brace = (v) => v.length === 1 ? v : `{${v}}`;
217
+ function tex(n) {
218
+ const part = (name) => n.kids.find((k) => k.name === name);
219
+ const all = (k) => k ? k.kids.map(tex).join("") : "";
220
+ switch (n.name) {
221
+ case "m:t":
222
+ return [...unesc(n.text)].map((ch) => glyph[ch] ? `\\${glyph[ch]} ` : ch).join("");
223
+ case "m:f":
224
+ return `\\frac{${all(part("m:num"))}}{${all(part("m:den"))}}`;
225
+ case "m:sSup":
226
+ return `${brace(all(part("m:e")))}^${brace(all(part("m:sup")))}`;
227
+ case "m:sSub":
228
+ return `${brace(all(part("m:e")))}_${brace(all(part("m:sub")))}`;
229
+ case "m:sSubSup":
230
+ return `${brace(all(part("m:e")))}_${brace(all(part("m:sub")))}^${brace(all(part("m:sup")))}`;
231
+ case "m:rad": {
232
+ const deg = all(part("m:deg"));
233
+ return `\\sqrt${deg ? `[${deg}]` : ""}{${all(part("m:e"))}}`;
234
+ }
235
+ case "m:nary": {
236
+ const chr = part("m:naryPr")?.kids.find((k) => k.name === "m:chr")?.attrs["m:val"] ?? "\u222B";
237
+ const sub = all(part("m:sub")), sup = all(part("m:sup"));
238
+ return `${glyph[chr] ? `\\${glyph[chr]}` : chr}${sub ? `_${brace(sub)}` : ""}${sup ? `^${brace(sup)}` : ""} ${all(part("m:e"))}`.trim();
239
+ }
240
+ case "m:d": {
241
+ const pr = part("m:dPr")?.kids ?? [];
242
+ const beg = pr.find((k) => k.name === "m:begChr")?.attrs["m:val"] ?? "(";
243
+ const end = pr.find((k) => k.name === "m:endChr")?.attrs["m:val"] ?? ")";
244
+ return `${beg}${n.kids.filter((k) => k.name === "m:e").map(all).join(",")}${end}`;
245
+ }
246
+ case "m:rPr":
247
+ case "m:ctrlPr":
248
+ case "w:rPr":
249
+ case "m:naryPr":
250
+ case "m:dPr":
251
+ case "m:radPr":
252
+ case "m:fPr":
253
+ case "m:sSupPr":
254
+ case "m:sSubPr":
255
+ case "m:sSubSupPr":
256
+ return "";
257
+ default:
258
+ return n.kids.map(tex).join("");
259
+ }
260
+ }
261
+ var latexOf = (xml) => tex(tree(xml)).replace(/\s+/g, " ").trim();
262
+
3
263
  // src/docx/xml.ts
4
- function parse(s) {
264
+ function parse2(s) {
5
265
  const root = { name: "", start: 0, open: 0, close: s.length, end: s.length, kids: [] };
6
266
  const stack = [root];
7
267
  const n = s.length;
@@ -105,7 +365,7 @@ function opened(s, el) {
105
365
  return el.end === el.open ? tag.replace(/\s*\/>$/, ">") : tag;
106
366
  }
107
367
  function rebuild(pr, tag, order, set) {
108
- const root = parse(pr).kids[0];
368
+ const root = parse2(pr).kids[0];
109
369
  const parts = root ? root.kids.map((k) => ({ name: k.name, xml: pr.slice(k.start, k.end) })) : [];
110
370
  const seen = /* @__PURE__ */ new Set();
111
371
  const out = [];
@@ -334,7 +594,7 @@ var Styles = class {
334
594
  this.byId = /* @__PURE__ */ new Map();
335
595
  this.paragraph = null;
336
596
  this.memo = /* @__PURE__ */ new Map();
337
- const root = find(parse(s), "w:styles");
597
+ const root = find(parse2(s), "w:styles");
338
598
  for (const el of root?.kids ?? []) {
339
599
  if (el.name !== "w:style") continue;
340
600
  const id = attr(s, el, "w:styleId");
@@ -504,7 +764,7 @@ var Numbering = class {
504
764
  this.abs = /* @__PURE__ */ new Map();
505
765
  this.maxNum = 0;
506
766
  this.maxAbs = -1;
507
- const root = find(parse(s), "w:numbering");
767
+ const root = find(parse2(s), "w:numbering");
508
768
  const links = /* @__PURE__ */ new Map();
509
769
  for (const el of root?.kids ?? []) {
510
770
  if (el.name === "w:abstractNum") {
@@ -601,7 +861,7 @@ var Pkg = class {
601
861
  const s = this.text(this.relsPath(part));
602
862
  if (!s) return out;
603
863
  const dir = part.slice(0, part.lastIndexOf("/") + 1);
604
- for (const el of find(parse(s), "Relationships")?.kids ?? []) {
864
+ for (const el of find(parse2(s), "Relationships")?.kids ?? []) {
605
865
  const id = attr(s, el, "Id");
606
866
  const target = attr(s, el, "Target") ?? "";
607
867
  const external = attr(s, el, "TargetMode") === "External";
@@ -639,6 +899,7 @@ var Reader = class {
639
899
  this.pkg = pkg;
640
900
  this.n = 0;
641
901
  this.refs = /* @__PURE__ */ new Map();
902
+ this.footnotes = null;
642
903
  this.counters = /* @__PURE__ */ new Map();
643
904
  this.fmts = /* @__PURE__ */ new Map();
644
905
  this.media = /* @__PURE__ */ new Map();
@@ -648,7 +909,7 @@ var Reader = class {
648
909
  return `${this.pkg.fp}.${(this.n++).toString(36)}`;
649
910
  }
650
911
  body() {
651
- const body = find(parse(this.s), "w:body");
912
+ const body = find(parse2(this.s), "w:body");
652
913
  if (!body) throw new Error("DOCX document has no body");
653
914
  const { list, tail } = this.blocks(body);
654
915
  return { body, list, tail, sect: kid(body, "w:sectPr") };
@@ -796,6 +1057,14 @@ var Reader = class {
796
1057
  }
797
1058
  return b;
798
1059
  }
1060
+ notes() {
1061
+ if (!this.footnotes) {
1062
+ const rel = this.pkg.byType("/footnotes");
1063
+ const xml = rel ? this.pkg.text(rel.target) ?? "" : "";
1064
+ this.footnotes = new Map([...xml.matchAll(/<w:footnote\b[^>]*\bw:id="(-?\d+)"[^>]*>([\s\S]*?)<\/w:footnote>/g)].map((m) => [m[1], noteText(m[2])]));
1065
+ }
1066
+ return this.footnotes;
1067
+ }
799
1068
  src(embed) {
800
1069
  if (!this.media.has(embed)) {
801
1070
  const rel = this.pkg.rels.get(embed);
@@ -841,10 +1110,8 @@ var Reader = class {
841
1110
  const inside = [];
842
1111
  this.walk(k.kids, ctx, k, inside, { lock: null, task: false, box: false });
843
1112
  this.span(s.slice(k.start, k.end), inside, out, ctx, hyperlink(attr(s, k, "w:instr") ?? ""));
844
- } else if (name === "m:oMath") {
845
- const text = s.slice(k.start, k.end).match(/<m:t(?:\s[^>]*)?>[^<]*<\/m:t>/g)?.map((t) => inner(t, parse(t).kids[0])).join("") ?? "";
846
- this.span(s.slice(k.start, k.end), text ? [{ text, raw: null, run: null, ctx, span: null }] : [], out, ctx, null);
847
- } else if (name === "m:oMathPara") st.lock = "Equation";
1113
+ } else if (name === "m:oMath") out.push({ text: "\uE000", raw: s.slice(k.start, k.end), run: null, ctx, span: null, math: latexOf(s.slice(k.start, k.end)) });
1114
+ else if (name === "m:oMathPara") st.lock = "Equation";
848
1115
  else out.push({ text: null, raw: s.slice(k.start, k.end), run: null, ctx, span: null });
849
1116
  }
850
1117
  }
@@ -865,17 +1132,17 @@ var Reader = class {
865
1132
  out.push({ text: null, raw: s.slice(k.start, k.end), run: null, ctx, span: null });
866
1133
  return;
867
1134
  }
868
- const run = { open: opened(s, k), rPr: rPrEl ? s.slice(rPrEl.start, rPrEl.end) : "", fmt: f, el: k, parent };
1135
+ const run2 = { open: opened(s, k), rPr: rPrEl ? s.slice(rPrEl.start, rPrEl.end) : "", fmt: f, el: k, parent };
869
1136
  const push = (text, raw, extra) => {
870
1137
  if (text !== null && st.box) {
871
1138
  st.box = false;
872
1139
  if (text.startsWith(" ") && raw === null) {
873
- out.push({ text: null, raw: '<w:t xml:space="preserve"> </w:t>', run, ctx, span: null, box: true });
1140
+ out.push({ text: null, raw: '<w:t xml:space="preserve"> </w:t>', run: run2, ctx, span: null, box: true });
874
1141
  text = text.slice(1);
875
1142
  if (!text) return;
876
1143
  }
877
1144
  }
878
- out.push({ text, raw, run, ctx, span: null, ...extra });
1145
+ out.push({ text, raw, run: run2, ctx, span: null, ...extra });
879
1146
  };
880
1147
  for (const c of k.kids) {
881
1148
  const raw = s.slice(c.start, c.end);
@@ -908,6 +1175,11 @@ var Reader = class {
908
1175
  else push("\n", raw);
909
1176
  break;
910
1177
  }
1178
+ case "w:footnoteReference": {
1179
+ const id = attr(s, c, "w:id") ?? "";
1180
+ push("\uE001", raw, { note: { id, text: this.notes().get(id) ?? "" } });
1181
+ break;
1182
+ }
911
1183
  case "w:fldChar":
912
1184
  push(null, raw, { fld: attr(s, c, "w:fldCharType") ?? "" });
913
1185
  break;
@@ -1112,10 +1384,16 @@ function fmtAt(p) {
1112
1384
  link ?? (link = p.span?.link ?? null);
1113
1385
  return link === f.link && rev === f.rev ? f : { ...f, link, rev };
1114
1386
  }
1387
+ var noteText = (xml) => [...xml.matchAll(/<w:t(?:\s[^>]*)?>([^<]*)<\/w:t>/g)].map((m) => m[1]).join("").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&").trim();
1115
1388
  function inline(pieces) {
1116
1389
  const out = [];
1117
1390
  let key = "";
1118
1391
  for (const p of pieces) {
1392
+ if (p.math !== void 0 || p.note) {
1393
+ out.push(p.note ? { type: "footnote", attrs: { id: p.note.id, text: p.note.text } } : { type: "math", attrs: { latex: p.math } });
1394
+ key = "";
1395
+ continue;
1396
+ }
1119
1397
  if (p.img) {
1120
1398
  out.push({ type: "image", attrs: { ...p.img } });
1121
1399
  key = "";
@@ -1280,7 +1558,7 @@ function inlineSig(kids) {
1280
1558
  out += (next === key ? "" : `${next}`) + k.text;
1281
1559
  key = next;
1282
1560
  } else {
1283
- out += `${k.type}${k.type === "image" ? picture2(k.attrs ?? {}) : ""}`;
1561
+ out += `${k.type}${k.type === "image" ? picture2(k.attrs ?? {}) : k.type === "math" ? k.attrs?.latex : k.type === "footnote" ? `${k.attrs?.id}:${k.attrs?.text}` : ""}`;
1284
1562
  key = null;
1285
1563
  }
1286
1564
  }
@@ -1411,6 +1689,7 @@ var Writer = class {
1411
1689
  this.srcs = null;
1412
1690
  this.tocs = false;
1413
1691
  this.revs = /* @__PURE__ */ new Map();
1692
+ this.lastNote = null;
1414
1693
  this.r = new Reader(pkg);
1415
1694
  this.s = pkg.doc;
1416
1695
  for (const id of pkg.rels.keys()) this.relIds.add(id);
@@ -1433,6 +1712,7 @@ var Writer = class {
1433
1712
  if (this.last === "tbl" && list[list.length - 1]?.kind !== "tbl") xml += "<w:p/>";
1434
1713
  const changed = /* @__PURE__ */ new Map();
1435
1714
  const text = this.marginal(s.slice(0, body.open) + xml + rest + s.slice(tail), setup, changed);
1715
+ this.footnotes(doc, changed);
1436
1716
  if (text !== s) changed.set(this.pkg.main, text);
1437
1717
  if (this.rels.length) {
1438
1718
  const path = this.pkg.relsPath(this.pkg.main);
@@ -1558,6 +1838,37 @@ var Writer = class {
1558
1838
  if (o.kind === "toc") return b && sig(o.node) === sig(b.node) ? s.slice(b.start, b.end) : this.toc(o.node);
1559
1839
  return this.code(o);
1560
1840
  }
1841
+ noteId() {
1842
+ const rel = this.pkg.byType("/footnotes");
1843
+ const xml = rel ? this.pkg.text(rel.target) ?? "" : "";
1844
+ this.lastNote ?? (this.lastNote = Math.max(0, ...[...xml.matchAll(/<w:footnote\b[^>]*\bw:id="(-?\d+)"/g)].map((m) => +m[1])));
1845
+ return ++this.lastNote;
1846
+ }
1847
+ footnotes(doc, changed) {
1848
+ const notes = [];
1849
+ const walk = (n) => {
1850
+ if (n.type === "footnote" && n.attrs?.id) notes.push({ id: String(n.attrs.id), text: String(n.attrs.text ?? "") });
1851
+ n.content?.forEach(walk);
1852
+ };
1853
+ walk(doc);
1854
+ const rel = this.pkg.byType("/footnotes");
1855
+ const old = rel ? this.pkg.text(rel.target) : null;
1856
+ if (!notes.length) return;
1857
+ const path = rel ? rel.target : "word/footnotes.xml";
1858
+ let xml = old ?? `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1859
+ <w:footnotes xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="${REL}"><w:footnote w:type="separator" w:id="-1"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type="continuationSeparator" w:id="0"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote></w:footnotes>`;
1860
+ const fresh = (id, words2) => `<w:footnote w:id="${id}"><w:p><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr><w:r><w:rPr><w:vertAlign w:val="superscript"/></w:rPr><w:footnoteRef/></w:r><w:r><w:rPr><w:sz w:val="20"/></w:rPr><w:t xml:space="preserve"> ${escape(words2)}</w:t></w:r></w:p></w:footnote>`;
1861
+ for (const n of notes) {
1862
+ const found = new RegExp(`<w:footnote\\b[^>]*\\bw:id="${n.id}"[^>]*>([\\s\\S]*?)</w:footnote>`).exec(xml);
1863
+ if (found && noteText(found[1]) === n.text) continue;
1864
+ xml = found ? xml.replace(found[0], fresh(n.id, n.text)) : xml.replace(/<\/w:footnotes>\s*$/, fresh(n.id, n.text) + "</w:footnotes>");
1865
+ }
1866
+ if (xml === old) return;
1867
+ changed.set(path, xml);
1868
+ if (rel) return;
1869
+ this.rels.push(`<Relationship Id="${this.relId()}" Type="${REL}/footnotes" Target="footnotes.xml"/>`);
1870
+ this.types.add(`<Override PartName="/word/footnotes.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"/>`);
1871
+ }
1561
1872
  marginal(text, setup, changed) {
1562
1873
  if (!setup || !setup.page && setup.header === void 0 && setup.footer === void 0 && setup.numbers === void 0) return text;
1563
1874
  const end = text.lastIndexOf("</w:body>");
@@ -1621,11 +1932,11 @@ var Writer = class {
1621
1932
  const open = sec.indexOf(">") + 1;
1622
1933
  sec = sec.slice(0, open) + `<w:${kind}Reference w:type="default" r:id="${id}"/>` + sec.slice(open);
1623
1934
  };
1624
- const line = (words, page) => {
1935
+ const line = (words2, page) => {
1625
1936
  const field = '<w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r>';
1626
- const run = words ? `<w:r><w:t xml:space="preserve">${escape(words)}</w:t></w:r>` : "";
1627
- if (!words && !page) return "";
1628
- return `<w:p><w:pPr>${page && words ? `<w:tabs><w:tab w:val="right" w:pos="${this.textWidth()}"/></w:tabs>` : page ? '<w:jc w:val="right"/>' : ""}</w:pPr>${run}${page && words ? "<w:r><w:tab/></w:r>" : ""}${page ? field : ""}</w:p>`;
1937
+ const run2 = words2 ? `<w:r><w:t xml:space="preserve">${escape(words2)}</w:t></w:r>` : "";
1938
+ if (!words2 && !page) return "";
1939
+ return `<w:p><w:pPr>${page && words2 ? `<w:tabs><w:tab w:val="right" w:pos="${this.textWidth()}"/></w:tabs>` : page ? '<w:jc w:val="right"/>' : ""}</w:pPr>${run2}${page && words2 ? "<w:r><w:tab/></w:r>" : ""}${page ? field : ""}</w:p>`;
1629
1940
  };
1630
1941
  if (setup.header !== void 0) part("header", line(setup.header, false));
1631
1942
  if (setup.footer !== void 0 || setup.numbers !== void 0) part("footer", line(setup.footer ?? "", !!setup.numbers));
@@ -1719,7 +2030,7 @@ var Writer = class {
1719
2030
  const rPr = kid(el, "w:rPr");
1720
2031
  xml = rebuild(xml, "w:pPr", P, { "w:sectPr": null, "w:pPrChange": null, "w:rPr": rPr ? rebuild(s.slice(rPr.start, rPr.end), "w:rPr", R, { "w:ins": null, "w:del": null, "w:moveFrom": null, "w:moveTo": null, "w:rPrChange": null }) || null : null });
1721
2032
  }
1722
- const root = xml ? parse(xml).kids[0] : void 0;
2033
+ const root = xml ? parse2(xml).kids[0] : void 0;
1723
2034
  const get = (name) => root && kid(root, name);
1724
2035
  const styleEl = get("w:pStyle");
1725
2036
  const was = { style: styleEl ? attr(xml, styleEl, "w:val") : null, level: src?.level ?? null, quote: src?.quote ?? false, list: src?.list ?? null };
@@ -1818,7 +2129,7 @@ var Writer = class {
1818
2129
  const base = p.span ? fmtAt({ ...p, span: null }) : fmt;
1819
2130
  if (p.img) units.push({ ch: "\uFFFC", raw: p.raw, run: p.run, ctx: p.ctx, span: null, idx: n++, fmt, base, img: p.img });
1820
2131
  else if (p.text === null) units.push({ ch: null, raw: p.raw, run: p.run, ctx: p.ctx, span: null, idx: n++, fmt, base, box: p.box });
1821
- else if (p.raw !== null) units.push({ ch: p.text, raw: p.raw, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base });
2132
+ else if (p.raw !== null) units.push({ ch: p.text, raw: p.raw, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base, math: p.math, note: p.note });
1822
2133
  else for (const ch of p.text) units.push({ ch, raw: null, run: p.run, ctx: p.ctx, span: p.span, idx: n++, fmt, base });
1823
2134
  if (p.run) counts.set(p.run, n);
1824
2135
  }
@@ -1833,6 +2144,8 @@ var Writer = class {
1833
2144
  for (const ch of n.text ?? "") B.push({ ch: ch === "\r" ? "\n" : ch, fmt: f, key: k });
1834
2145
  } else if (n.type === "hardBreak") B.push({ ch: "\n", fmt: lastFmt, key: keyOf(lastFmt) });
1835
2146
  else if (n.type === "image") B.push({ ch: "\uFFFC", fmt: lastFmt, key: keyOf(lastFmt), img: n.attrs ?? {} });
2147
+ else if (n.type === "math") B.push({ ch: "\uE000", fmt: lastFmt, key: keyOf(lastFmt), math: String(n.attrs?.latex ?? "") });
2148
+ else if (n.type === "footnote") B.push({ ch: "\uE001", fmt: lastFmt, key: keyOf(lastFmt), note: n.attrs ?? (n.attrs = {}) });
1836
2149
  }
1837
2150
  const boxes = units.filter((u) => u.box);
1838
2151
  let box = null;
@@ -1888,6 +2201,20 @@ var Writer = class {
1888
2201
  } else out.push({ ch: want.ch, raw: this.drawing(want.img), run: { open: "<w:r>", rPr: "", fmt: plain, el: null, parent: null }, ctx: [], u: null, fmt: plain });
1889
2202
  continue;
1890
2203
  }
2204
+ if (want.math !== void 0) {
2205
+ const u = i >= 0 ? A[i] : null;
2206
+ out.push(u?.math === want.math ? { ch: u.ch, raw: u.raw, run: null, ctx: u.ctx, u, fmt: u.fmt } : { ch: want.ch, raw: omml(want.math), run: null, ctx: u?.ctx ?? [], u: null, fmt: plain });
2207
+ continue;
2208
+ }
2209
+ if (want.note) {
2210
+ const u = i >= 0 ? A[i] : null;
2211
+ if (u?.note && u.note.id === want.note.id) out.push({ ch: u.ch, raw: u.raw, run: u.run, ctx: u.ctx, u, fmt: u.fmt });
2212
+ else {
2213
+ want.note.id = typeof want.note.id === "string" && want.note.id ? want.note.id : String(this.noteId());
2214
+ out.push({ ch: want.ch, raw: `<w:footnoteReference w:id="${want.note.id}"/>`, run: { open: "<w:r>", rPr: '<w:rPr><w:vertAlign w:val="superscript"/></w:rPr>', fmt: plain, el: null, parent: null }, ctx: [], u: null, fmt: plain });
2215
+ }
2216
+ continue;
2217
+ }
1891
2218
  if (i >= 0) {
1892
2219
  const u = A[i];
1893
2220
  if (u.span && intact.has(u.span)) {
@@ -1897,18 +2224,18 @@ var Writer = class {
1897
2224
  const from = u.span ? u.base : u.fmt;
1898
2225
  const keep = u.ch === "\n" || keyOf(from) === want.key;
1899
2226
  const fmt = keep ? from : want.fmt;
1900
- const run = keep && u.run ? u.run : this.derive(u.run ?? paraBase.run, from, want.fmt);
1901
- out.push({ ch: u.ch, raw: u.raw, run, ctx: this.revised(this.linked(u.ctx, fmt.link, lastChar()), fmt.rev), u: keep && u.run ? u : null, fmt });
2227
+ const run2 = keep && u.run ? u.run : this.derive(u.run ?? paraBase.run, from, want.fmt);
2228
+ out.push({ ch: u.ch, raw: u.raw, run: run2, ctx: this.revised(this.linked(u.ctx, fmt.link, lastChar()), fmt.rev), u: keep && u.run ? u : null, fmt });
1902
2229
  } else {
1903
2230
  const left = lastChar();
1904
2231
  const right = next[j + 1] >= 0 ? A[next[j + 1]] : null;
1905
2232
  const base = left ? { run: left.run, fmt: left.fmt } : right ? { run: right.run ?? paraBase.run, fmt: right.span ? right.base : right.fmt } : paraBase;
1906
- const run = keyOf(base.fmt) === want.key ? base.run : this.derive(base.run, base.fmt, want.fmt);
2233
+ const run2 = keyOf(base.fmt) === want.key ? base.run : this.derive(base.run, base.fmt, want.fmt);
1907
2234
  const shared = [];
1908
2235
  if (left && right) {
1909
2236
  for (let k = 0; k < left.ctx.length && left.ctx[k] === right.ctx[k]; k++) if (!left.ctx[k].link) shared.push(left.ctx[k]);
1910
2237
  }
1911
- out.push({ ch: want.ch, raw: null, run, ctx: this.revised(this.linked(shared, want.fmt.link, left), want.fmt.rev), u: null, fmt: want.fmt });
2238
+ out.push({ ch: want.ch, raw: null, run: run2, ctx: this.revised(this.linked(shared, want.fmt.link, left), want.fmt.rev), u: null, fmt: want.fmt });
1912
2239
  }
1913
2240
  }
1914
2241
  let xml = "";
@@ -1991,14 +2318,14 @@ var Writer = class {
1991
2318
  this.relIds.add(`rId${n}`);
1992
2319
  return `rId${n}`;
1993
2320
  }
1994
- derive(run, from, to) {
1995
- const cache = run.derived ?? (run.derived = /* @__PURE__ */ new Map());
2321
+ derive(run2, from, to) {
2322
+ const cache = run2.derived ?? (run2.derived = /* @__PURE__ */ new Map());
1996
2323
  const key = keyOf(from) + ">" + keyOf(to);
1997
- if (!cache.has(key)) cache.set(key, { open: run.open, rPr: this.delta(run.rPr, from, to), fmt: to, el: null, parent: null });
2324
+ if (!cache.has(key)) cache.set(key, { open: run2.open, rPr: this.delta(run2.rPr, from, to), fmt: to, el: null, parent: null });
1998
2325
  return cache.get(key);
1999
2326
  }
2000
2327
  delta(rPr, from, to) {
2001
- const root = rPr ? parse(rPr).kids[0] : void 0;
2328
+ const root = rPr ? parse2(rPr).kids[0] : void 0;
2002
2329
  const get = (name) => root && kid(root, name);
2003
2330
  const styleEl = get("w:rStyle");
2004
2331
  const style = styleEl ? attr(rPr, styleEl, "w:val") : null;
@@ -2043,8 +2370,8 @@ var Writer = class {
2043
2370
  } else if (!to.link && from.link && this.pkg.styles.isLink(style)) set["w:rStyle"] = null;
2044
2371
  return Object.keys(set).length ? rebuild(rPr, "w:rPr", R, set) : rPr;
2045
2372
  }
2046
- runXml(run, glyphs, counts) {
2047
- if (run.el && glyphs.length === counts.get(run) && glyphs.every((g, n) => g.u && g.u.run === run && g.u.idx === n)) return this.s.slice(run.el.start, run.el.end);
2373
+ runXml(run2, glyphs, counts) {
2374
+ if (run2.el && glyphs.length === counts.get(run2) && glyphs.every((g, n) => g.u && g.u.run === run2 && g.u.idx === n)) return this.s.slice(run2.el.start, run2.el.end);
2048
2375
  let body = "";
2049
2376
  let text = "";
2050
2377
  const tag = glyphs[0]?.ctx.some((w) => w.rev?.startsWith('["del"')) ? "w:delText" : "w:t";
@@ -2059,7 +2386,7 @@ var Writer = class {
2059
2386
  } else text += g.ch;
2060
2387
  }
2061
2388
  flush();
2062
- return run.open + run.rPr + body + "</w:r>";
2389
+ return run2.open + run2.rPr + body + "</w:r>";
2063
2390
  }
2064
2391
  embed(src) {
2065
2392
  if (!this.srcs) {
@@ -2298,14 +2625,14 @@ async function readDocx(bytes) {
2298
2625
  const size2 = sect && kid(sect, "w:pgSz");
2299
2626
  const mar = sect && kid(sect, "w:pgMar");
2300
2627
  const px = (el, name, fallback) => Math.round(Math.abs(+((el && attr(s, el, name)) ?? fallback)) / 15 * 100) / 100;
2301
- const words = (kind) => {
2628
+ const words2 = (kind) => {
2302
2629
  const ref = sect?.kids.find((k) => k.name === `w:${kind}Reference` && attr(s, k, "w:type") === "default");
2303
2630
  const part = ref && pkg.rels.get(attr(s, ref, "r:id") ?? "");
2304
2631
  const xml = part ? pkg.text(part.target) ?? "" : "";
2305
2632
  return { text: [...xml.matchAll(/<w:t(?:\s[^>]*)?>([^<]*)<\/w:t>/g)].map((m) => m[1]).join("").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").trim(), page: /\bPAGE\b/.test(xml) };
2306
2633
  };
2307
- const head = words("header");
2308
- const foot = words("footer");
2634
+ const head = words2("header");
2635
+ const foot = words2("footer");
2309
2636
  return {
2310
2637
  marginal: { header: head.text, footer: foot.page ? foot.text.replace(/\s*\d+$/, "") : foot.text, numbers: foot.page },
2311
2638
  doc: { type: "doc", content: content.length ? content : [{ type: "paragraph", attrs: { align: null, indent: 0, ref: null } }] },
@@ -2455,6 +2782,14 @@ var en = {
2455
2782
  chooseFile: "Choose a file",
2456
2783
  put: "Insert",
2457
2784
  link: "Link",
2785
+ footnote: "Footnote",
2786
+ footnoteText: "Footnote text",
2787
+ formula: "Formula",
2788
+ formulaHint: "Saved as a Word equation",
2789
+ symbols: "Special characters",
2790
+ symbolSearch: "Search, for example arrow",
2791
+ update: "Update",
2792
+ removeFootnote: "Remove footnote",
2458
2793
  linkAddress: "Link address",
2459
2794
  apply: "Apply",
2460
2795
  unlink: "Remove link",
@@ -2773,6 +3108,14 @@ var pl = {
2773
3108
  chooseFile: "Wybierz plik",
2774
3109
  put: "Wstaw",
2775
3110
  link: "Link",
3111
+ footnote: "Przypis",
3112
+ footnoteText: "Tekst przypisu",
3113
+ formula: "Wz\xF3r",
3114
+ formulaHint: "Zapisany jako r\xF3wnanie Word",
3115
+ symbols: "Znaki specjalne",
3116
+ symbolSearch: "Szukaj, na przyk\u0142ad strza\u0142ka",
3117
+ update: "Zmie\u0144",
3118
+ removeFootnote: "Usu\u0144 przypis",
2776
3119
  linkAddress: "Adres linku",
2777
3120
  apply: "Zastosuj",
2778
3121
  unlink: "Usu\u0144 link",
@@ -3090,6 +3433,14 @@ var uk = {
3090
3433
  imageLink: "\u0410\u0434\u0440\u0435\u0441\u0430 \u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u043D\u044F",
3091
3434
  chooseFile: "\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B",
3092
3435
  put: "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u0438",
3436
+ footnote: "\u0412\u0438\u043D\u043E\u0441\u043A\u0430",
3437
+ footnoteText: "\u0422\u0435\u043A\u0441\u0442 \u0432\u0438\u043D\u043E\u0441\u043A\u0438",
3438
+ formula: "\u0424\u043E\u0440\u043C\u0443\u043B\u0430",
3439
+ formulaHint: "\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0454\u0442\u044C\u0441\u044F \u044F\u043A \u0440\u0456\u0432\u043D\u044F\u043D\u043D\u044F Word",
3440
+ symbols: "\u0421\u043F\u0435\u0446\u0441\u0438\u043C\u0432\u043E\u043B\u0438",
3441
+ symbolSearch: "\u041F\u043E\u0448\u0443\u043A, \u043D\u0430\u043F\u0440\u0438\u043A\u043B\u0430\u0434 \u0441\u0442\u0440\u0456\u043B\u043A\u0430",
3442
+ update: "\u0417\u043C\u0456\u043D\u0438\u0442\u0438",
3443
+ removeFootnote: "\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 \u0432\u0438\u043D\u043E\u0441\u043A\u0443",
3093
3444
  link: "\u041F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
3094
3445
  linkAddress: "\u0410\u0434\u0440\u0435\u0441\u0430 \u043F\u043E\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
3095
3446
  apply: "\u0417\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438",
@@ -3277,7 +3628,7 @@ var uk = {
3277
3628
  var texts = { en, pl, uk };
3278
3629
 
3279
3630
  export {
3280
- parse,
3631
+ parse2 as parse,
3281
3632
  attr,
3282
3633
  attrs,
3283
3634
  unescape,
@@ -3286,8 +3637,9 @@ export {
3286
3637
  inflate,
3287
3638
  entry,
3288
3639
  zip,
3640
+ mathml,
3289
3641
  readDocx,
3290
3642
  writeDocx,
3291
3643
  texts
3292
3644
  };
3293
- //# sourceMappingURL=chunk-DR3TTJWZ.js.map
3645
+ //# sourceMappingURL=chunk-M4OQG3EN.js.map