wordinweb 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1598,6 +1598,14 @@ interface TextMeasurer {
1598
1598
  ascent: number;
1599
1599
  descent: number;
1600
1600
  } | undefined;
1601
+ /** Ink extents (actualBoundingBox*) of `text` in the RESOLVED paint face,
1602
+ * px above/below the baseline. The radical join needs the √ glyph's real
1603
+ * ink — which face paints it (real Cambria Math vs the STIX substitute)
1604
+ * changes the extents, so a baked table can't cover both. */
1605
+ inkBox?(text: string, font: FontSpec): {
1606
+ ascent: number;
1607
+ descent: number;
1608
+ } | undefined;
1601
1609
  }
1602
1610
 
1603
1611
  interface LayoutOptions {
package/dist/index.js CHANGED
@@ -5157,6 +5157,7 @@ var CanvasMeasurer = class {
5157
5157
  this.widthCache = /* @__PURE__ */ new Map();
5158
5158
  this.metricsCache = /* @__PURE__ */ new Map();
5159
5159
  this.paintBoxCache = /* @__PURE__ */ new Map();
5160
+ this.inkBoxCache = /* @__PURE__ */ new Map();
5160
5161
  this.currentFont = "";
5161
5162
  if (typeof OffscreenCanvas !== "undefined") {
5162
5163
  const c = new OffscreenCanvas(1, 1);
@@ -5200,6 +5201,18 @@ var CanvasMeasurer = class {
5200
5201
  }
5201
5202
  return m ?? void 0;
5202
5203
  }
5204
+ /** Glyph ink extents at 3x (like width()) from the resolved paint face. */
5205
+ inkBox(text, font) {
5206
+ const key = "ink " + fontKey(font) + " " + text;
5207
+ let m = this.inkBoxCache.get(key);
5208
+ if (m === void 0) {
5209
+ this.setFont({ ...font, size: font.size * 3 });
5210
+ const tm = this.ctx.measureText(text);
5211
+ m = tm.actualBoundingBoxAscent !== void 0 && tm.actualBoundingBoxDescent !== void 0 ? { ascent: tm.actualBoundingBoxAscent / 3, descent: tm.actualBoundingBoxDescent / 3 } : null;
5212
+ this.inkBoxCache.set(key, m);
5213
+ }
5214
+ return m ?? void 0;
5215
+ }
5203
5216
  metrics(font) {
5204
5217
  const key = fontKey(font);
5205
5218
  let m = this.metricsCache.get(key);
@@ -5853,14 +5866,12 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
5853
5866
  for (const r of degBox.rules) box.rules.push({ ...r, x1: box.width + r.x1, x2: box.width + r.x2, dy: degDy + r.dy });
5854
5867
  box.width += degBox.width + size * RAD_KERN_AFTER_DEG;
5855
5868
  }
5856
- let grow = Math.max(1, signInkH / (m.ascent + signDesc));
5857
- let signAnchor = -signDesc;
5858
- if (nestedGrown) {
5859
- const inkTopNat = size * RAD_VARIANTS[0].top / 2048;
5860
- const inkBotNat = size * RAD_VARIANTS[0].bot / 2048;
5861
- grow = (paintRuleTop + size * RAD_GROWN_FOOT) / (inkTopNat - inkBotNat);
5862
- signAnchor = (-size * RAD_GROWN_FOOT - inkBotNat * grow) / (1 - grow);
5863
- }
5869
+ const signInk = measurer.inkBox?.("\u221A", font);
5870
+ const inkTopNat = signInk ? signInk.ascent : size * RAD_VARIANTS[0].top / 2048;
5871
+ const inkBotNat = signInk ? -signInk.descent : size * RAD_VARIANTS[0].bot / 2048;
5872
+ const signFoot = nestedGrown ? size * RAD_GROWN_FOOT : signDesc;
5873
+ const grow = (paintRuleTop + signFoot) / (inkTopNat - inkBotNat);
5874
+ const signAnchor = grow === 1 ? 0 : (-signFoot - inkBotNat * grow) / (1 - grow);
5864
5875
  const topLevelDisplay = display && breakDepth === 0 && complexRad;
5865
5876
  const signW = measurer.width("\u221A", font);
5866
5877
  box.pieces.push({
@@ -15865,28 +15876,30 @@ function resizeTableColumn(doc, tblEl, boundary, deltaPx, renderedWidths) {
15865
15876
  setWidth(right, rw - d);
15866
15877
  }
15867
15878
  }
15868
- if (!hasSpans(tblEl)) {
15869
- for (const tr of rowsOf(tblEl)) {
15870
- const cells = cellsOf(tr);
15871
- cells.forEach((tc, i) => {
15872
- if (!cols[i]) return;
15873
- const w = prefixOf4(tc);
15874
- let tcPr = child(tc, "tcPr");
15875
- if (!tcPr) {
15876
- tcPr = { name: `${w}tcPr`, attrs: {}, children: [], text: "" };
15877
- tc.children.unshift(tcPr);
15878
- }
15879
- let tcW = child(tcPr, "tcW");
15880
- if (!tcW) {
15881
- tcW = { name: `${w}tcW`, attrs: { [`${w}type`]: "dxa" }, children: [], text: "" };
15882
- tcPr.children.unshift(tcW);
15883
- }
15884
- const typeKey = Object.keys(tcW.attrs).find((k) => localName(k) === "type");
15885
- if (!typeKey || tcW.attrs[typeKey] === "dxa") {
15886
- const wKey = Object.keys(tcW.attrs).find((k) => localName(k) === "w") ?? prefixOf4(tcW) + "w";
15887
- tcW.attrs[wKey] = String(widthOf2(cols[i]));
15888
- }
15889
- });
15879
+ for (const tr of rowsOf(tblEl)) {
15880
+ let col = 0;
15881
+ for (const tc of cellsOf(tr)) {
15882
+ const w = prefixOf4(tc);
15883
+ let tcPr = child(tc, "tcPr");
15884
+ if (!tcPr) {
15885
+ tcPr = { name: `${w}tcPr`, attrs: {}, children: [], text: "" };
15886
+ tc.children.unshift(tcPr);
15887
+ }
15888
+ const gs = child(tcPr, "gridSpan");
15889
+ const gsKey = gs && Object.keys(gs.attrs).find((k) => localName(k) === "val");
15890
+ const span = gs && gsKey ? Math.max(1, parseInt(gs.attrs[gsKey], 10) || 1) : 1;
15891
+ const total = cols.slice(col, col + span).reduce((a, c) => a + widthOf2(c), 0);
15892
+ col += span;
15893
+ if (!total) continue;
15894
+ let tcW = child(tcPr, "tcW");
15895
+ if (!tcW) {
15896
+ tcW = { name: `${w}tcW`, attrs: {}, children: [], text: "" };
15897
+ tcPr.children.unshift(tcW);
15898
+ }
15899
+ const typeKey = Object.keys(tcW.attrs).find((k) => localName(k) === "type") ?? `${w}type`;
15900
+ const wKey = Object.keys(tcW.attrs).find((k) => localName(k) === "w") ?? `${w}w`;
15901
+ tcW.attrs[typeKey] = "dxa";
15902
+ tcW.attrs[wKey] = String(total);
15890
15903
  }
15891
15904
  }
15892
15905
  doc.refresh();
@@ -16310,9 +16323,11 @@ function linearizeMath(nodes) {
16310
16323
  case "frac":
16311
16324
  out += group(n.num) + "/" + group(n.den);
16312
16325
  break;
16313
- case "rad":
16314
- out += "\u221A" + group(n.e);
16326
+ case "rad": {
16327
+ const deg = n.deg && n.deg.length ? linearizeMath(n.deg) : "";
16328
+ out += deg ? "\u221A[" + deg + "]" + group(n.e) : "\u221A" + group(n.e);
16315
16329
  break;
16330
+ }
16316
16331
  case "nary":
16317
16332
  out += n.chr + (n.sub.length ? "_" + group(n.sub) : "") + (n.sup.length ? "^" + group(n.sup) : "") + group(n.e);
16318
16333
  break;
@@ -16442,10 +16457,12 @@ function parseMathLinear(input) {
16442
16457
  const parseUnit = () => {
16443
16458
  const ch = input[i];
16444
16459
  if (ch === "{") return parseGroup();
16445
- if (ch === "\u221A") {
16460
+ if (ch === "\u221A" || ch === "\u221B" || ch === "\u221C") {
16446
16461
  i++;
16462
+ let deg = ch === "\u221B" ? [{ t: "run", text: "3" }] : ch === "\u221C" ? [{ t: "run", text: "4" }] : [];
16463
+ if (ch === "\u221A" && input[i] === "[") deg = parseMathLinear(scanDelim("[", "]"));
16447
16464
  const e = input[i] === "{" ? parseGroup() : parseUnit();
16448
- return [{ t: "rad", e }];
16465
+ return deg.length ? [{ t: "rad", e, deg }] : [{ t: "rad", e }];
16449
16466
  }
16450
16467
  if (NARY_CHRS.has(ch)) return parseNary();
16451
16468
  if (ch in DELIM_CLOSE) return parseDelim(ch);
@@ -16631,7 +16648,11 @@ function ommlToNodes(e) {
16631
16648
  }
16632
16649
  if (ln === "sSup") return [{ t: "sup", base: kids("e"), script: kids("sup") }];
16633
16650
  if (ln === "sSub") return [{ t: "sub", base: kids("e"), script: kids("sub") }];
16634
- if (ln === "rad") return [{ t: "rad", e: kids("e") }];
16651
+ if (ln === "rad") {
16652
+ const hide = chrAttr("radPr", "degHide", "0");
16653
+ const deg = hide === "1" || hide === "true" || hide === "on" ? [] : kids("deg");
16654
+ return deg.length ? [{ t: "rad", e: kids("e"), deg }] : [{ t: "rad", e: kids("e") }];
16655
+ }
16635
16656
  if (ln === "t") return e.text ? [{ t: "run", text: e.text }] : [];
16636
16657
  const out = [];
16637
16658
  for (const c of e.children) {
@@ -16663,9 +16684,11 @@ function sameStructure(a, b) {
16663
16684
  case "frac":
16664
16685
  if (!sameStructure(x.num, y.num) || !sameStructure(x.den, y.den)) return false;
16665
16686
  break;
16666
- case "rad":
16667
- if (!sameStructure(x.e, y.e)) return false;
16687
+ case "rad": {
16688
+ const yy = y;
16689
+ if (!sameStructure(x.e, yy.e) || !sameStructure(x.deg ?? [], yy.deg ?? [])) return false;
16668
16690
  break;
16691
+ }
16669
16692
  case "nary": {
16670
16693
  const yy = y;
16671
16694
  if (x.chr !== yy.chr || !sameStructure(x.sub, yy.sub) || !sameStructure(x.sup, yy.sup) || !sameStructure(x.e, yy.e))
@@ -19676,7 +19699,7 @@ var _DocxEditor = class _DocxEditor {
19676
19699
  row.style.cssText = "display:flex;gap:6px;align-items:center;";
19677
19700
  const input = document.createElement("input");
19678
19701
  input.value = original;
19679
- input.title = "Linear math: x^2, x_i, {a+b}/{2}, \u221A{x}";
19702
+ input.title = "Linear math: x^2, x_i, {a+b}/{2}, \u221A{x}, \u221A[n]{x}";
19680
19703
  input.style.cssText = "width:260px;border:1px solid #dadce0;border-radius:6px;padding:5px 8px;outline:none;font:14px 'Cambria Math','STIX Two Math',serif;transition:border-color .12s,background .12s;";
19681
19704
  const caption = document.createElement("div");
19682
19705
  caption.style.cssText = "font:11px system-ui,sans-serif;color:#5f6368;max-width:300px;";
@@ -19699,7 +19722,7 @@ var _DocxEditor = class _DocxEditor {
19699
19722
  }
19700
19723
  });
19701
19724
  } else {
19702
- caption.textContent = "Linear math: x^2, x_i, {a+b}/{2}, \u221A{x}. Enter to apply.";
19725
+ caption.textContent = "Linear math: x^2, x_i, {a+b}/{2}, \u221A{x}, \u221A[n]{x}. Enter to apply.";
19703
19726
  const apply = document.createElement("button");
19704
19727
  apply.textContent = "Apply";
19705
19728
  apply.style.cssText = "border:1px solid #dadce0;border-radius:14px;padding:3px 12px;cursor:pointer;background:#1a73e8;color:#fff;";