js.documents 14.4.5 → 14.4.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.
@@ -4,6 +4,7 @@ const require_opc_content_types = require("../../opc/content-types.cjs");
4
4
  const require_opc_paths = require("../../opc/paths.cjs");
5
5
  const require_opc_rels = require("../../opc/rels.cjs");
6
6
  const require_opc_core_properties = require("../../opc/core-properties.cjs");
7
+ let ooxml_js = require("ooxml.js");
7
8
  //#region src/edit/pptx/scaffold.ts
8
9
  const CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types";
9
10
  const RELS_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
@@ -189,9 +190,10 @@ function ensureNotesMaster(pkg) {
189
190
  const presentationPart = pkg.parts[PRESENTATION_PART_PATH];
190
191
  const presentationElement = presentationPart?.kind === "xml" ? presentationPart.nodes.find((n) => n.type === "element") : void 0;
191
192
  if (presentationElement === void 0) throw new Error("ensureNotesMaster: package has no ppt/presentation.xml element");
192
- const sldMasterIdLstIndex = presentationElement.children.findIndex((c) => c.type === "element" && c.tag === "p:sldMasterIdLst");
193
+ const sldMasterIdLst = (0, ooxml_js.childrenWithTag)(presentationElement, "p:sldMasterIdLst")[0];
194
+ const sldMasterIdLstIndex = presentationElement.children.findIndex((child) => child === sldMasterIdLst);
193
195
  const notesMasterIdLst = require_xml_fragment.el("p:notesMasterIdLst", {}, [require_xml_fragment.el("p:notesMasterId", { "r:id": relId })]);
194
- presentationElement.children.splice(sldMasterIdLstIndex === -1 ? 0 : sldMasterIdLstIndex + 1, 0, notesMasterIdLst);
196
+ presentationElement.children.splice(sldMasterIdLstIndex + 1, 0, notesMasterIdLst);
195
197
  return NOTES_MASTER_PART_PATH;
196
198
  }
197
199
  function createEmptyPptxPackage(options) {
@@ -214,6 +216,10 @@ function createEmptyPptxPackage(options) {
214
216
  Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
215
217
  Target: PRESENTATION_PART_PATH
216
218
  })]);
219
+ const presentation = require_xml_fragment.el("p:presentation", {
220
+ "xmlns:p": PML_NS,
221
+ "xmlns:r": R_NS
222
+ });
217
223
  const pkg = { parts: {
218
224
  "[Content_Types].xml": {
219
225
  kind: "xml",
@@ -225,10 +231,7 @@ function createEmptyPptxPackage(options) {
225
231
  },
226
232
  [PRESENTATION_PART_PATH]: {
227
233
  kind: "xml",
228
- nodes: [declaration(), require_xml_fragment.el("p:presentation", {
229
- "xmlns:p": PML_NS,
230
- "xmlns:r": R_NS
231
- })]
234
+ nodes: [declaration(), presentation]
232
235
  }
233
236
  } };
234
237
  const layoutToMasterTarget = require_opc_paths.buildRelativeTarget(SLIDE_LAYOUT_PART_PATH, SLIDE_MASTER_PART_PATH);
@@ -266,10 +269,7 @@ function createEmptyPptxPackage(options) {
266
269
  type: SLIDE_MASTER_REL_TYPE,
267
270
  target: presentationToMasterTarget
268
271
  });
269
- const presentationPart = pkg.parts[PRESENTATION_PART_PATH];
270
- const presentationElement = presentationPart?.kind === "xml" ? presentationPart.nodes.find((n) => n.type === "element") : void 0;
271
- if (presentationElement === void 0) throw new Error("createEmptyPptxPackage: failed to build ppt/presentation.xml");
272
- presentationElement.children.push(require_xml_fragment.el("p:sldMasterIdLst", {}, [require_xml_fragment.el("p:sldMasterId", {
272
+ presentation.children.push(require_xml_fragment.el("p:sldMasterIdLst", {}, [require_xml_fragment.el("p:sldMasterId", {
273
273
  id: String(MIN_MASTER_OR_LAYOUT_ID),
274
274
  "r:id": presentationToMasterRelId
275
275
  })]), require_xml_fragment.el("p:sldIdLst"), require_xml_fragment.el("p:sldSz", {
@@ -3,6 +3,7 @@ import { ensureContentTypeOverride } from "../../opc/content-types.js";
3
3
  import { buildRelativeTarget } from "../../opc/paths.js";
4
4
  import { addRelationship } from "../../opc/rels.js";
5
5
  import { addCoreProperties } from "../../opc/core-properties.js";
6
+ import { childrenWithTag } from "ooxml.js";
6
7
  //#region src/edit/pptx/scaffold.ts
7
8
  const CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types";
8
9
  const RELS_NS = "http://schemas.openxmlformats.org/package/2006/relationships";
@@ -188,9 +189,10 @@ function ensureNotesMaster(pkg) {
188
189
  const presentationPart = pkg.parts[PRESENTATION_PART_PATH];
189
190
  const presentationElement = presentationPart?.kind === "xml" ? presentationPart.nodes.find((n) => n.type === "element") : void 0;
190
191
  if (presentationElement === void 0) throw new Error("ensureNotesMaster: package has no ppt/presentation.xml element");
191
- const sldMasterIdLstIndex = presentationElement.children.findIndex((c) => c.type === "element" && c.tag === "p:sldMasterIdLst");
192
+ const sldMasterIdLst = childrenWithTag(presentationElement, "p:sldMasterIdLst")[0];
193
+ const sldMasterIdLstIndex = presentationElement.children.findIndex((child) => child === sldMasterIdLst);
192
194
  const notesMasterIdLst = el("p:notesMasterIdLst", {}, [el("p:notesMasterId", { "r:id": relId })]);
193
- presentationElement.children.splice(sldMasterIdLstIndex === -1 ? 0 : sldMasterIdLstIndex + 1, 0, notesMasterIdLst);
195
+ presentationElement.children.splice(sldMasterIdLstIndex + 1, 0, notesMasterIdLst);
194
196
  return NOTES_MASTER_PART_PATH;
195
197
  }
196
198
  function createEmptyPptxPackage(options) {
@@ -213,6 +215,10 @@ function createEmptyPptxPackage(options) {
213
215
  Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
214
216
  Target: PRESENTATION_PART_PATH
215
217
  })]);
218
+ const presentation = el("p:presentation", {
219
+ "xmlns:p": PML_NS,
220
+ "xmlns:r": R_NS
221
+ });
216
222
  const pkg = { parts: {
217
223
  "[Content_Types].xml": {
218
224
  kind: "xml",
@@ -224,10 +230,7 @@ function createEmptyPptxPackage(options) {
224
230
  },
225
231
  [PRESENTATION_PART_PATH]: {
226
232
  kind: "xml",
227
- nodes: [declaration(), el("p:presentation", {
228
- "xmlns:p": PML_NS,
229
- "xmlns:r": R_NS
230
- })]
233
+ nodes: [declaration(), presentation]
231
234
  }
232
235
  } };
233
236
  const layoutToMasterTarget = buildRelativeTarget(SLIDE_LAYOUT_PART_PATH, SLIDE_MASTER_PART_PATH);
@@ -265,10 +268,7 @@ function createEmptyPptxPackage(options) {
265
268
  type: SLIDE_MASTER_REL_TYPE,
266
269
  target: presentationToMasterTarget
267
270
  });
268
- const presentationPart = pkg.parts[PRESENTATION_PART_PATH];
269
- const presentationElement = presentationPart?.kind === "xml" ? presentationPart.nodes.find((n) => n.type === "element") : void 0;
270
- if (presentationElement === void 0) throw new Error("createEmptyPptxPackage: failed to build ppt/presentation.xml");
271
- presentationElement.children.push(el("p:sldMasterIdLst", {}, [el("p:sldMasterId", {
271
+ presentation.children.push(el("p:sldMasterIdLst", {}, [el("p:sldMasterId", {
272
272
  id: String(MIN_MASTER_OR_LAYOUT_ID),
273
273
  "r:id": presentationToMasterRelId
274
274
  })]), el("p:sldIdLst"), el("p:sldSz", {
@@ -72,7 +72,7 @@ const IGNORABLE_STATEMENT_PREFIXES = [
72
72
  "SHUTDOWN"
73
73
  ];
74
74
  function isIgnorableStatement(statement) {
75
- const normalized = statement.replace(/\s+/g, " ").trim().toUpperCase();
75
+ const normalized = statement.replace(/\s+/g, " ").toUpperCase();
76
76
  return IGNORABLE_STATEMENT_PREFIXES.some((prefix) => normalized.startsWith(prefix));
77
77
  }
78
78
  const CREATE_TABLE_RE = /^CREATE\s+(?:(?:MEMORY|CACHED|TEXT|TEMP|TEMPORARY|GLOBAL\s+TEMPORARY)\s+)?TABLE\s+/i;
@@ -294,32 +294,31 @@ function unescapeSingleQuotes(s) {
294
294
  return s.replace(/''/g, "'");
295
295
  }
296
296
  function typeBucket(typeText) {
297
- const word = /^([A-Za-z_]+)/.exec(typeText.trim())?.[1]?.toUpperCase();
297
+ const word = /^([A-Za-z_]+)/.exec(typeText)?.[1]?.toUpperCase();
298
298
  if (word === "DATE") return "date";
299
299
  if (word === "TIME") return "time";
300
300
  return "other";
301
301
  }
302
302
  const NUMBER_LITERAL_RE = /^[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?$/;
303
303
  function parseLiteral(raw, bucket) {
304
- const trimmed = raw.trim();
305
- if (/^NULL$/i.test(trimmed)) return { kind: "empty" };
306
- const dateTyped = /^DATE\s*'((?:[^']|'')*)'$/i.exec(trimmed);
304
+ if (/^NULL$/i.test(raw)) return { kind: "empty" };
305
+ const dateTyped = /^DATE\s*'((?:[^']|'')*)'$/i.exec(raw);
307
306
  if (dateTyped?.[1] !== void 0) return {
308
307
  kind: "date",
309
308
  value: unescapeSingleQuotes(dateTyped[1])
310
309
  };
311
- const timeTyped = /^TIME\s*'((?:[^']|'')*)'$/i.exec(trimmed);
310
+ const timeTyped = /^TIME\s*'((?:[^']|'')*)'$/i.exec(raw);
312
311
  if (timeTyped?.[1] !== void 0) return {
313
312
  kind: "time",
314
313
  value: unescapeSingleQuotes(timeTyped[1])
315
314
  };
316
- const timestampTyped = /^TIMESTAMP\s*'((?:[^']|'')*)'$/i.exec(trimmed);
315
+ const timestampTyped = /^TIMESTAMP\s*'((?:[^']|'')*)'$/i.exec(raw);
317
316
  if (timestampTyped?.[1] !== void 0) return {
318
317
  kind: "date",
319
318
  value: unescapeSingleQuotes(timestampTyped[1])
320
319
  };
321
- if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
322
- const text = unescapeSingleQuotes(trimmed.slice(1, -1));
320
+ if (raw.length >= 2 && raw.startsWith("'") && raw.endsWith("'")) {
321
+ const text = unescapeSingleQuotes(raw.slice(1, -1));
323
322
  if (bucket === "date") return {
324
323
  kind: "date",
325
324
  value: text
@@ -333,19 +332,19 @@ function parseLiteral(raw, bucket) {
333
332
  value: text
334
333
  };
335
334
  }
336
- if (/^TRUE$/i.test(trimmed)) return {
335
+ if (/^TRUE$/i.test(raw)) return {
337
336
  kind: "boolean",
338
337
  value: true
339
338
  };
340
- if (/^FALSE$/i.test(trimmed)) return {
339
+ if (/^FALSE$/i.test(raw)) return {
341
340
  kind: "boolean",
342
341
  value: false
343
342
  };
344
- if (NUMBER_LITERAL_RE.test(trimmed)) return {
343
+ if (NUMBER_LITERAL_RE.test(raw)) return {
345
344
  kind: "number",
346
- value: Number(trimmed)
345
+ value: Number(raw)
347
346
  };
348
- throw new HsqldbScriptParseError(`unrecognised literal "${trimmed}"`, raw);
347
+ throw new HsqldbScriptParseError(`unrecognised literal "${raw}"`, raw);
349
348
  }
350
349
  function parseCreateTable(statement) {
351
350
  const match = CREATE_TABLE_RE.exec(statement);
@@ -382,7 +381,7 @@ function parseInsertInto(statement) {
382
381
  let explicitColumns;
383
382
  if (statement.charAt(i) === "(") {
384
383
  const { inner, next: afterCols } = readBalancedParens(statement, i);
385
- explicitColumns = splitTopLevel(inner, ",").map((part) => readIdentifier(part.trim(), 0).name);
384
+ explicitColumns = splitTopLevel(inner, ",").map((part) => readIdentifier(part, 0).name);
386
385
  i = skipWs(statement, afterCols);
387
386
  }
388
387
  const valuesMatch = /^VALUES\s*/i.exec(statement.slice(i));
@@ -390,7 +389,7 @@ function parseInsertInto(statement) {
390
389
  i = skipWs(statement, i + valuesMatch[0].length);
391
390
  if (statement.charAt(i) !== "(") throw new HsqldbScriptParseError(`INSERT INTO "${tableName}": expected "(" to start the VALUES tuple`, statement);
392
391
  const { inner, next: afterTuple } = readBalancedParens(statement, i);
393
- const trailing = statement.slice(afterTuple).trim();
392
+ const trailing = statement.slice(afterTuple);
394
393
  if (trailing.length > 0) throw new HsqldbScriptParseError(`INSERT INTO "${tableName}": unexpected trailing content after the VALUES tuple ("${trailing}") — multiple tuples per INSERT are outside this bounded parser's scope`, statement);
395
394
  return {
396
395
  tableName,
@@ -71,7 +71,7 @@ const IGNORABLE_STATEMENT_PREFIXES = [
71
71
  "SHUTDOWN"
72
72
  ];
73
73
  function isIgnorableStatement(statement) {
74
- const normalized = statement.replace(/\s+/g, " ").trim().toUpperCase();
74
+ const normalized = statement.replace(/\s+/g, " ").toUpperCase();
75
75
  return IGNORABLE_STATEMENT_PREFIXES.some((prefix) => normalized.startsWith(prefix));
76
76
  }
77
77
  const CREATE_TABLE_RE = /^CREATE\s+(?:(?:MEMORY|CACHED|TEXT|TEMP|TEMPORARY|GLOBAL\s+TEMPORARY)\s+)?TABLE\s+/i;
@@ -293,32 +293,31 @@ function unescapeSingleQuotes(s) {
293
293
  return s.replace(/''/g, "'");
294
294
  }
295
295
  function typeBucket(typeText) {
296
- const word = /^([A-Za-z_]+)/.exec(typeText.trim())?.[1]?.toUpperCase();
296
+ const word = /^([A-Za-z_]+)/.exec(typeText)?.[1]?.toUpperCase();
297
297
  if (word === "DATE") return "date";
298
298
  if (word === "TIME") return "time";
299
299
  return "other";
300
300
  }
301
301
  const NUMBER_LITERAL_RE = /^[-+]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?$/;
302
302
  function parseLiteral(raw, bucket) {
303
- const trimmed = raw.trim();
304
- if (/^NULL$/i.test(trimmed)) return { kind: "empty" };
305
- const dateTyped = /^DATE\s*'((?:[^']|'')*)'$/i.exec(trimmed);
303
+ if (/^NULL$/i.test(raw)) return { kind: "empty" };
304
+ const dateTyped = /^DATE\s*'((?:[^']|'')*)'$/i.exec(raw);
306
305
  if (dateTyped?.[1] !== void 0) return {
307
306
  kind: "date",
308
307
  value: unescapeSingleQuotes(dateTyped[1])
309
308
  };
310
- const timeTyped = /^TIME\s*'((?:[^']|'')*)'$/i.exec(trimmed);
309
+ const timeTyped = /^TIME\s*'((?:[^']|'')*)'$/i.exec(raw);
311
310
  if (timeTyped?.[1] !== void 0) return {
312
311
  kind: "time",
313
312
  value: unescapeSingleQuotes(timeTyped[1])
314
313
  };
315
- const timestampTyped = /^TIMESTAMP\s*'((?:[^']|'')*)'$/i.exec(trimmed);
314
+ const timestampTyped = /^TIMESTAMP\s*'((?:[^']|'')*)'$/i.exec(raw);
316
315
  if (timestampTyped?.[1] !== void 0) return {
317
316
  kind: "date",
318
317
  value: unescapeSingleQuotes(timestampTyped[1])
319
318
  };
320
- if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
321
- const text = unescapeSingleQuotes(trimmed.slice(1, -1));
319
+ if (raw.length >= 2 && raw.startsWith("'") && raw.endsWith("'")) {
320
+ const text = unescapeSingleQuotes(raw.slice(1, -1));
322
321
  if (bucket === "date") return {
323
322
  kind: "date",
324
323
  value: text
@@ -332,19 +331,19 @@ function parseLiteral(raw, bucket) {
332
331
  value: text
333
332
  };
334
333
  }
335
- if (/^TRUE$/i.test(trimmed)) return {
334
+ if (/^TRUE$/i.test(raw)) return {
336
335
  kind: "boolean",
337
336
  value: true
338
337
  };
339
- if (/^FALSE$/i.test(trimmed)) return {
338
+ if (/^FALSE$/i.test(raw)) return {
340
339
  kind: "boolean",
341
340
  value: false
342
341
  };
343
- if (NUMBER_LITERAL_RE.test(trimmed)) return {
342
+ if (NUMBER_LITERAL_RE.test(raw)) return {
344
343
  kind: "number",
345
- value: Number(trimmed)
344
+ value: Number(raw)
346
345
  };
347
- throw new HsqldbScriptParseError(`unrecognised literal "${trimmed}"`, raw);
346
+ throw new HsqldbScriptParseError(`unrecognised literal "${raw}"`, raw);
348
347
  }
349
348
  function parseCreateTable(statement) {
350
349
  const match = CREATE_TABLE_RE.exec(statement);
@@ -381,7 +380,7 @@ function parseInsertInto(statement) {
381
380
  let explicitColumns;
382
381
  if (statement.charAt(i) === "(") {
383
382
  const { inner, next: afterCols } = readBalancedParens(statement, i);
384
- explicitColumns = splitTopLevel(inner, ",").map((part) => readIdentifier(part.trim(), 0).name);
383
+ explicitColumns = splitTopLevel(inner, ",").map((part) => readIdentifier(part, 0).name);
385
384
  i = skipWs(statement, afterCols);
386
385
  }
387
386
  const valuesMatch = /^VALUES\s*/i.exec(statement.slice(i));
@@ -389,7 +388,7 @@ function parseInsertInto(statement) {
389
388
  i = skipWs(statement, i + valuesMatch[0].length);
390
389
  if (statement.charAt(i) !== "(") throw new HsqldbScriptParseError(`INSERT INTO "${tableName}": expected "(" to start the VALUES tuple`, statement);
391
390
  const { inner, next: afterTuple } = readBalancedParens(statement, i);
392
- const trailing = statement.slice(afterTuple).trim();
391
+ const trailing = statement.slice(afterTuple);
393
392
  if (trailing.length > 0) throw new HsqldbScriptParseError(`INSERT INTO "${tableName}": unexpected trailing content after the VALUES tuple ("${trailing}") — multiple tuples per INSERT are outside this bounded parser's scope`, statement);
394
393
  return {
395
394
  tableName,
@@ -458,8 +458,8 @@ function lowerSupsub(node, context) {
458
458
  if (binder.status === "degraded") return unparsed(binder.detail);
459
459
  const detail = spanOfNodes(context, [node]);
460
460
  const base = require_latex_temml.isTemmlNode(node.base) ? node.base : void 0;
461
- const sub = node.sub === void 0 ? void 0 : nodesOfScript(node.sub);
462
- const sup = node.sup === void 0 ? void 0 : nodesOfScript(node.sup);
461
+ const sub = nodesOfScript(node.sub);
462
+ const sup = nodesOfScript(node.sup);
463
463
  if (sub !== void 0) {
464
464
  const subWritten = simpleScriptGlyph(sub);
465
465
  const baseGlyph = base !== void 0 && (base.type === "mathord" || base.type === "textord") ? glyphOfNode(base) : void 0;
@@ -520,8 +520,8 @@ function readBinder(node, context) {
520
520
  if (base.name !== "\\sum" && base.name !== "\\prod") return { status: "not-a-binder" };
521
521
  const kind = base.name === "\\sum" ? "sum" : "prod";
522
522
  const detail = spanOfNodes(context, [node]);
523
- const sub = node.sub === void 0 ? void 0 : nodesOfScript(node.sub);
524
- const sup = node.sup === void 0 ? void 0 : nodesOfScript(node.sup);
523
+ const sub = nodesOfScript(node.sub);
524
+ const sup = nodesOfScript(node.sup);
525
525
  const upper = sup === void 0 ? implicitBound(context) : lowerNodeList(sup, context);
526
526
  if ((sub?.length ?? 0) >= 3) {
527
527
  const first = sub?.[0];
@@ -536,7 +536,7 @@ function readBinder(node, context) {
536
536
  upper
537
537
  };
538
538
  }
539
- if ((sub?.length ?? 0) === 1 && sub !== void 0) {
539
+ if (sub?.length === 1) {
540
540
  const singleGlyph = simpleScriptGlyph(sub);
541
541
  if (singleGlyph !== void 0) {
542
542
  diagnose(context, "latex/binder-bound-implicit", detail);
@@ -457,8 +457,8 @@ function lowerSupsub(node, context) {
457
457
  if (binder.status === "degraded") return unparsed(binder.detail);
458
458
  const detail = spanOfNodes(context, [node]);
459
459
  const base = isTemmlNode(node.base) ? node.base : void 0;
460
- const sub = node.sub === void 0 ? void 0 : nodesOfScript(node.sub);
461
- const sup = node.sup === void 0 ? void 0 : nodesOfScript(node.sup);
460
+ const sub = nodesOfScript(node.sub);
461
+ const sup = nodesOfScript(node.sup);
462
462
  if (sub !== void 0) {
463
463
  const subWritten = simpleScriptGlyph(sub);
464
464
  const baseGlyph = base !== void 0 && (base.type === "mathord" || base.type === "textord") ? glyphOfNode(base) : void 0;
@@ -519,8 +519,8 @@ function readBinder(node, context) {
519
519
  if (base.name !== "\\sum" && base.name !== "\\prod") return { status: "not-a-binder" };
520
520
  const kind = base.name === "\\sum" ? "sum" : "prod";
521
521
  const detail = spanOfNodes(context, [node]);
522
- const sub = node.sub === void 0 ? void 0 : nodesOfScript(node.sub);
523
- const sup = node.sup === void 0 ? void 0 : nodesOfScript(node.sup);
522
+ const sub = nodesOfScript(node.sub);
523
+ const sup = nodesOfScript(node.sup);
524
524
  const upper = sup === void 0 ? implicitBound(context) : lowerNodeList(sup, context);
525
525
  if ((sub?.length ?? 0) >= 3) {
526
526
  const first = sub?.[0];
@@ -535,7 +535,7 @@ function readBinder(node, context) {
535
535
  upper
536
536
  };
537
537
  }
538
- if ((sub?.length ?? 0) === 1 && sub !== void 0) {
538
+ if (sub?.length === 1) {
539
539
  const singleGlyph = simpleScriptGlyph(sub);
540
540
  if (singleGlyph !== void 0) {
541
541
  diagnose(context, "latex/binder-bound-implicit", detail);
@@ -14,18 +14,18 @@ function rootContext(options, diagnostics) {
14
14
  inheritedVariant: void 0,
15
15
  displayStyle: true,
16
16
  cramped: false,
17
- scriptLevel: 0,
17
+ firstScriptLevel: true,
18
18
  diagnostics
19
19
  };
20
20
  }
21
21
  function scriptContext(ctx, cramped) {
22
- const scale = ctx.scriptLevel === 0 ? ctx.metrics.scriptPercentScaleDown : ctx.metrics.scriptScriptPercentScaleDown;
22
+ const scale = ctx.firstScriptLevel ? ctx.metrics.scriptPercentScaleDown : ctx.metrics.scriptScriptPercentScaleDown;
23
23
  return {
24
24
  ...ctx,
25
25
  sizePt: ctx.sizePt * scale,
26
26
  displayStyle: false,
27
27
  cramped,
28
- scriptLevel: ctx.scriptLevel + 1
28
+ firstScriptLevel: false
29
29
  };
30
30
  }
31
31
  function unsupported(ctx, element) {
@@ -89,6 +89,10 @@ function isStretchyOperator(element) {
89
89
  if (require_mathml_nodes.attrValue(element, "stretchy") === "false") return false;
90
90
  return require_mathml_operators.operatorProperties(require_mathml_nodes.textContent(element).trim()).stretchy;
91
91
  }
92
+ function singleCodePoint(text) {
93
+ const codePoints = [...text];
94
+ return codePoints.length === 1 ? codePoints[0]?.codePointAt(0) : void 0;
95
+ }
92
96
  function stretchedBox(result, text, ctx) {
93
97
  const axisPt = ctx.metrics.axisHeightPt;
94
98
  const inkHeightPt = result.inkAscentPt + result.inkDescentPt;
@@ -116,9 +120,7 @@ function stretchedBox(result, text, ctx) {
116
120
  }
117
121
  function stretchOperator(element, targetSizePt, ctx) {
118
122
  const text = require_mathml_nodes.textContent(element).trim();
119
- const codePoints = [...text];
120
- if (codePoints.length !== 1) return;
121
- const codePoint = codePoints[0]?.codePointAt(0);
123
+ const codePoint = singleCodePoint(text);
122
124
  if (codePoint === void 0) return;
123
125
  const result = ctx.metrics.stretch(codePoint, "vertical", targetSizePt, ctx.sizePt);
124
126
  if (result === void 0 || result.kind === "base") return;
@@ -148,9 +150,7 @@ function horizontallyStretchedBox(result, text, ctx) {
148
150
  }
149
151
  function stretchHorizontalOperator(element, targetWidthPt, ctx) {
150
152
  const text = require_mathml_nodes.textContent(element).trim();
151
- const codePoints = [...text];
152
- if (codePoints.length !== 1) return;
153
- const codePoint = codePoints[0]?.codePointAt(0);
153
+ const codePoint = singleCodePoint(text);
154
154
  if (codePoint === void 0) return;
155
155
  const result = ctx.metrics.stretch(codePoint, "horizontal", targetWidthPt, ctx.sizePt);
156
156
  if (result === void 0 || result.kind === "base") return;
@@ -165,7 +165,6 @@ function layoutUnderOverChild(childElement, targetWidthPt, scriptCtx) {
165
165
  }
166
166
  function stretchRowOperators(children, boxes, ctx) {
167
167
  const stretchy = children.map(isStretchyOperator);
168
- if (!stretchy.includes(true)) return boxes;
169
168
  const others = boxes.filter((_, index) => stretchy[index] !== true);
170
169
  if (others.length === 0) return boxes;
171
170
  const axisPt = ctx.metrics.axisHeightPt;
@@ -180,14 +179,14 @@ function stretchRowOperators(children, boxes, ctx) {
180
179
  }
181
180
  function layoutRowChildren(children, ctx) {
182
181
  const boxes = stretchRowOperators(children, children.map((child) => layoutNode(child, ctx)), ctx);
183
- const gapsPt = children.map((child, index) => {
184
- if (index === 0) return 0;
185
- const previous = children[index - 1];
186
- let gapEm = 0;
187
- if (previous !== void 0 && require_mathml_nodes.elementLocalName(previous) === "mo") gapEm += require_mathml_operators.operatorProperties(require_mathml_nodes.textContent(previous).trim()).rspaceEm;
188
- if (require_mathml_nodes.elementLocalName(child) === "mo") gapEm += require_mathml_operators.operatorProperties(require_mathml_nodes.textContent(child).trim()).lspaceEm;
189
- return gapEm * ctx.sizePt;
190
- });
182
+ const gapsPt = [];
183
+ let carriedRspaceEm = 0;
184
+ for (const [index, child] of children.entries()) {
185
+ const properties = require_mathml_nodes.elementLocalName(child) === "mo" ? require_mathml_operators.operatorProperties(require_mathml_nodes.textContent(child).trim()) : void 0;
186
+ const gapEm = index === 0 ? 0 : carriedRspaceEm + (properties?.lspaceEm ?? 0);
187
+ gapsPt.push(gapEm * ctx.sizePt);
188
+ carriedRspaceEm = properties?.rspaceEm ?? 0;
189
+ }
191
190
  return require_mathml_compose.concatBoxesHorizontally(boxes, gapsPt);
192
191
  }
193
192
  function layoutSemantics(element, ctx) {
@@ -213,18 +212,15 @@ function mstyleContext(element, ctx) {
213
212
  }
214
213
  function layoutScripts(base, subscript, superscript, ctx) {
215
214
  const metrics = ctx.metrics;
216
- let supShiftUpPt = 0;
217
- let subShiftDownPt = 0;
218
- if (superscript !== void 0) supShiftUpPt = Math.max(ctx.cramped ? metrics.superscriptShiftUpCrampedPt : metrics.superscriptShiftUpPt, base.ascentPt - metrics.superscriptBaselineDropMaxPt);
219
- if (subscript !== void 0) subShiftDownPt = Math.max(metrics.subscriptShiftDownPt, base.descentPt + metrics.subscriptBaselineDropMinPt);
215
+ const initialSupShiftUpPt = Math.max(ctx.cramped ? metrics.superscriptShiftUpCrampedPt : metrics.superscriptShiftUpPt, base.ascentPt - metrics.superscriptBaselineDropMaxPt);
216
+ const initialSubShiftDownPt = Math.max(metrics.subscriptShiftDownPt, base.descentPt + metrics.subscriptBaselineDropMinPt);
217
+ let correctionPt = 0;
220
218
  if (superscript !== void 0 && subscript !== void 0) {
221
- const gapPt = supShiftUpPt - superscript.descentPt + (subShiftDownPt - subscript.ascentPt);
222
- const deficitPt = metrics.subSuperscriptGapMinPt - gapPt;
223
- if (deficitPt > 0) {
224
- supShiftUpPt += deficitPt / 2;
225
- subShiftDownPt += deficitPt / 2;
226
- }
219
+ const gapPt = initialSupShiftUpPt - superscript.descentPt + (initialSubShiftDownPt - subscript.ascentPt);
220
+ correctionPt = Math.max(0, metrics.subSuperscriptGapMinPt - gapPt) / 2;
227
221
  }
222
+ const supShiftUpPt = initialSupShiftUpPt + correctionPt;
223
+ const subShiftDownPt = initialSubShiftDownPt + correctionPt;
228
224
  const ascentPt = Math.max(base.ascentPt, superscript === void 0 ? 0 : supShiftUpPt + superscript.ascentPt);
229
225
  const descentPt = Math.max(base.descentPt, subscript === void 0 ? 0 : subShiftDownPt + subscript.descentPt);
230
226
  const scriptWidthPt = Math.max(superscript?.widthPt ?? 0, subscript?.widthPt ?? 0);
@@ -282,9 +278,7 @@ function resolveTopAccentXPt(baseElement, ctx) {
282
278
  rawText = require_mathml_nodes.textContent(baseElement).trim();
283
279
  intrinsicDefault = "normal";
284
280
  } else return;
285
- const codePoints = [...require_mathml_variant.applyMathVariant(rawText, tokenVariant(baseElement, intrinsicDefault, ctx))];
286
- if (codePoints.length !== 1) return;
287
- const codePoint = codePoints[0]?.codePointAt(0);
281
+ const codePoint = singleCodePoint(require_mathml_variant.applyMathVariant(rawText, tokenVariant(baseElement, intrinsicDefault, ctx)));
288
282
  if (codePoint === void 0) return;
289
283
  return ctx.metrics.glyph(codePoint, ctx.sizePt)?.topAccentXPt;
290
284
  }
@@ -295,7 +289,6 @@ function layoutUnderOverElement(element, kind, ctx) {
295
289
  if (!ctx.displayStyle && isMovableLimitsOperator(baseElement)) {
296
290
  const base = layoutNode(baseElement, ctx);
297
291
  const scriptCtx = scriptContext(ctx, ctx.cramped);
298
- if (kind === "munder") return layoutScripts(base, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), void 0, ctx);
299
292
  if (kind === "mover") return layoutScripts(base, void 0, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), ctx);
300
293
  return layoutScripts(base, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), children[2] === void 0 ? void 0 : layoutNode(children[2], scriptCtx), ctx);
301
294
  }
@@ -303,12 +296,10 @@ function layoutUnderOverElement(element, kind, ctx) {
303
296
  const scriptCtx = scriptContext(ctx, false);
304
297
  const isAccent = require_mathml_nodes.attrValue(element, "accent") === "true";
305
298
  const isAccentUnder = require_mathml_nodes.attrValue(element, "accentunder") === "true";
306
- const topAccentXPt = isAccent || isAccentUnder ? resolveTopAccentXPt(baseElement, ctx) : void 0;
307
299
  const accentAttachment = {
308
- overXPt: isAccent ? topAccentXPt : void 0,
309
- underXPt: isAccentUnder ? topAccentXPt : void 0
300
+ overXPt: isAccent ? resolveTopAccentXPt(baseElement, ctx) : void 0,
301
+ underXPt: isAccentUnder ? resolveTopAccentXPt(baseElement, ctx) : void 0
310
302
  };
311
- if (kind === "munder") return layoutUnderOver(base, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), void 0, ctx, accentAttachment);
312
303
  if (kind === "mover") return layoutUnderOver(base, void 0, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), ctx, accentAttachment);
313
304
  return layoutUnderOver(base, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), children[2] === void 0 ? void 0 : layoutUnderOverChild(children[2], base.widthPt, scriptCtx), ctx, accentAttachment);
314
305
  }
@@ -316,7 +307,8 @@ function layoutFraction(element, ctx) {
316
307
  const children = require_mathml_nodes.elementChildren(element);
317
308
  const numeratorElement = children[0];
318
309
  const denominatorElement = children[1];
319
- if (numeratorElement === void 0 || denominatorElement === void 0) return require_mathml_compose.EMPTY_BOX;
310
+ if (numeratorElement === void 0) return require_mathml_compose.EMPTY_BOX;
311
+ if (denominatorElement === void 0) return require_mathml_compose.EMPTY_BOX;
320
312
  const fracCtx = {
321
313
  ...ctx,
322
314
  displayStyle: false,
@@ -425,13 +417,12 @@ function wrapRadical(radicand, index, ctx) {
425
417
  }
426
418
  function layoutTable(element, ctx) {
427
419
  const rows = require_mathml_nodes.elementChildren(element).filter((child) => require_mathml_nodes.elementLocalName(child) === "mtr");
428
- if (rows.length === 0) return require_mathml_compose.EMPTY_BOX;
429
- const columnAligns = (require_mathml_nodes.attrValue(element, "columnalign") ?? "").trim().split(/\s+/).filter((s) => s.length > 0);
420
+ const columnAlignAttr = require_mathml_nodes.attrValue(element, "columnalign");
421
+ const columnAligns = columnAlignAttr === void 0 ? [] : columnAlignAttr.match(/\S+/g) ?? [];
430
422
  const rowCells = rows.map((row) => require_mathml_nodes.elementChildren(row).filter((child) => require_mathml_nodes.elementLocalName(child) === "mtd").map((cell) => layoutRowChildren(require_mathml_nodes.elementChildren(cell), ctx)));
431
423
  const columnCount = rowCells.reduce((max, row) => Math.max(max, row.length), 0);
432
424
  if (columnCount === 0) return require_mathml_compose.EMPTY_BOX;
433
- const columnWidthsPt = [];
434
- for (let column = 0; column < columnCount; column++) columnWidthsPt.push(rowCells.reduce((max, row) => Math.max(max, row[column]?.widthPt ?? 0), 0));
425
+ const columnWidthsPt = Array.from({ length: columnCount }, (_, column) => rowCells.reduce((max, row) => Math.max(max, row[column]?.widthPt ?? 0), 0));
435
426
  const columnGapPt = .8 * ctx.sizePt;
436
427
  const rowGapPt = .5 * ctx.sizePt;
437
428
  const items = [];
@@ -442,7 +433,7 @@ function layoutTable(element, ctx) {
442
433
  let cursorXPt = 0;
443
434
  row.forEach((cell, columnIndex) => {
444
435
  const columnWidthPt = columnWidthsPt[columnIndex] ?? cell.widthPt;
445
- const align = columnAligns[columnIndex] ?? columnAligns[columnAligns.length - 1] ?? "center";
436
+ const align = columnAligns[columnIndex] ?? columnAligns[columnAligns.length - 1];
446
437
  const extraPt = columnWidthPt - cell.widthPt;
447
438
  const dxPt = align === "left" ? 0 : align === "right" ? extraPt : extraPt / 2;
448
439
  items.push(...require_mathml_compose.placeChild(cell, cursorXPt + dxPt, 0, cursorYTopPt + rowAscentPt));
@@ -15,7 +15,7 @@ interface LayoutContext {
15
15
  readonly inheritedVariant: MathVariant | undefined;
16
16
  readonly displayStyle: boolean;
17
17
  readonly cramped: boolean;
18
- readonly scriptLevel: number;
18
+ readonly firstScriptLevel: boolean;
19
19
  readonly diagnostics: MathDiagnostic[];
20
20
  }
21
21
  declare function layoutNode(node: MathMlNode$1, ctx: LayoutContext): MathBox;
@@ -15,7 +15,7 @@ interface LayoutContext {
15
15
  readonly inheritedVariant: MathVariant | undefined;
16
16
  readonly displayStyle: boolean;
17
17
  readonly cramped: boolean;
18
- readonly scriptLevel: number;
18
+ readonly firstScriptLevel: boolean;
19
19
  readonly diagnostics: MathDiagnostic[];
20
20
  }
21
21
  declare function layoutNode(node: MathMlNode$1, ctx: LayoutContext): MathBox;
@@ -13,18 +13,18 @@ function rootContext(options, diagnostics) {
13
13
  inheritedVariant: void 0,
14
14
  displayStyle: true,
15
15
  cramped: false,
16
- scriptLevel: 0,
16
+ firstScriptLevel: true,
17
17
  diagnostics
18
18
  };
19
19
  }
20
20
  function scriptContext(ctx, cramped) {
21
- const scale = ctx.scriptLevel === 0 ? ctx.metrics.scriptPercentScaleDown : ctx.metrics.scriptScriptPercentScaleDown;
21
+ const scale = ctx.firstScriptLevel ? ctx.metrics.scriptPercentScaleDown : ctx.metrics.scriptScriptPercentScaleDown;
22
22
  return {
23
23
  ...ctx,
24
24
  sizePt: ctx.sizePt * scale,
25
25
  displayStyle: false,
26
26
  cramped,
27
- scriptLevel: ctx.scriptLevel + 1
27
+ firstScriptLevel: false
28
28
  };
29
29
  }
30
30
  function unsupported(ctx, element) {
@@ -88,6 +88,10 @@ function isStretchyOperator(element) {
88
88
  if (attrValue(element, "stretchy") === "false") return false;
89
89
  return operatorProperties(textContent(element).trim()).stretchy;
90
90
  }
91
+ function singleCodePoint(text) {
92
+ const codePoints = [...text];
93
+ return codePoints.length === 1 ? codePoints[0]?.codePointAt(0) : void 0;
94
+ }
91
95
  function stretchedBox(result, text, ctx) {
92
96
  const axisPt = ctx.metrics.axisHeightPt;
93
97
  const inkHeightPt = result.inkAscentPt + result.inkDescentPt;
@@ -115,9 +119,7 @@ function stretchedBox(result, text, ctx) {
115
119
  }
116
120
  function stretchOperator(element, targetSizePt, ctx) {
117
121
  const text = textContent(element).trim();
118
- const codePoints = [...text];
119
- if (codePoints.length !== 1) return;
120
- const codePoint = codePoints[0]?.codePointAt(0);
122
+ const codePoint = singleCodePoint(text);
121
123
  if (codePoint === void 0) return;
122
124
  const result = ctx.metrics.stretch(codePoint, "vertical", targetSizePt, ctx.sizePt);
123
125
  if (result === void 0 || result.kind === "base") return;
@@ -147,9 +149,7 @@ function horizontallyStretchedBox(result, text, ctx) {
147
149
  }
148
150
  function stretchHorizontalOperator(element, targetWidthPt, ctx) {
149
151
  const text = textContent(element).trim();
150
- const codePoints = [...text];
151
- if (codePoints.length !== 1) return;
152
- const codePoint = codePoints[0]?.codePointAt(0);
152
+ const codePoint = singleCodePoint(text);
153
153
  if (codePoint === void 0) return;
154
154
  const result = ctx.metrics.stretch(codePoint, "horizontal", targetWidthPt, ctx.sizePt);
155
155
  if (result === void 0 || result.kind === "base") return;
@@ -164,7 +164,6 @@ function layoutUnderOverChild(childElement, targetWidthPt, scriptCtx) {
164
164
  }
165
165
  function stretchRowOperators(children, boxes, ctx) {
166
166
  const stretchy = children.map(isStretchyOperator);
167
- if (!stretchy.includes(true)) return boxes;
168
167
  const others = boxes.filter((_, index) => stretchy[index] !== true);
169
168
  if (others.length === 0) return boxes;
170
169
  const axisPt = ctx.metrics.axisHeightPt;
@@ -179,14 +178,14 @@ function stretchRowOperators(children, boxes, ctx) {
179
178
  }
180
179
  function layoutRowChildren(children, ctx) {
181
180
  const boxes = stretchRowOperators(children, children.map((child) => layoutNode(child, ctx)), ctx);
182
- const gapsPt = children.map((child, index) => {
183
- if (index === 0) return 0;
184
- const previous = children[index - 1];
185
- let gapEm = 0;
186
- if (previous !== void 0 && elementLocalName(previous) === "mo") gapEm += operatorProperties(textContent(previous).trim()).rspaceEm;
187
- if (elementLocalName(child) === "mo") gapEm += operatorProperties(textContent(child).trim()).lspaceEm;
188
- return gapEm * ctx.sizePt;
189
- });
181
+ const gapsPt = [];
182
+ let carriedRspaceEm = 0;
183
+ for (const [index, child] of children.entries()) {
184
+ const properties = elementLocalName(child) === "mo" ? operatorProperties(textContent(child).trim()) : void 0;
185
+ const gapEm = index === 0 ? 0 : carriedRspaceEm + (properties?.lspaceEm ?? 0);
186
+ gapsPt.push(gapEm * ctx.sizePt);
187
+ carriedRspaceEm = properties?.rspaceEm ?? 0;
188
+ }
190
189
  return concatBoxesHorizontally(boxes, gapsPt);
191
190
  }
192
191
  function layoutSemantics(element, ctx) {
@@ -212,18 +211,15 @@ function mstyleContext(element, ctx) {
212
211
  }
213
212
  function layoutScripts(base, subscript, superscript, ctx) {
214
213
  const metrics = ctx.metrics;
215
- let supShiftUpPt = 0;
216
- let subShiftDownPt = 0;
217
- if (superscript !== void 0) supShiftUpPt = Math.max(ctx.cramped ? metrics.superscriptShiftUpCrampedPt : metrics.superscriptShiftUpPt, base.ascentPt - metrics.superscriptBaselineDropMaxPt);
218
- if (subscript !== void 0) subShiftDownPt = Math.max(metrics.subscriptShiftDownPt, base.descentPt + metrics.subscriptBaselineDropMinPt);
214
+ const initialSupShiftUpPt = Math.max(ctx.cramped ? metrics.superscriptShiftUpCrampedPt : metrics.superscriptShiftUpPt, base.ascentPt - metrics.superscriptBaselineDropMaxPt);
215
+ const initialSubShiftDownPt = Math.max(metrics.subscriptShiftDownPt, base.descentPt + metrics.subscriptBaselineDropMinPt);
216
+ let correctionPt = 0;
219
217
  if (superscript !== void 0 && subscript !== void 0) {
220
- const gapPt = supShiftUpPt - superscript.descentPt + (subShiftDownPt - subscript.ascentPt);
221
- const deficitPt = metrics.subSuperscriptGapMinPt - gapPt;
222
- if (deficitPt > 0) {
223
- supShiftUpPt += deficitPt / 2;
224
- subShiftDownPt += deficitPt / 2;
225
- }
218
+ const gapPt = initialSupShiftUpPt - superscript.descentPt + (initialSubShiftDownPt - subscript.ascentPt);
219
+ correctionPt = Math.max(0, metrics.subSuperscriptGapMinPt - gapPt) / 2;
226
220
  }
221
+ const supShiftUpPt = initialSupShiftUpPt + correctionPt;
222
+ const subShiftDownPt = initialSubShiftDownPt + correctionPt;
227
223
  const ascentPt = Math.max(base.ascentPt, superscript === void 0 ? 0 : supShiftUpPt + superscript.ascentPt);
228
224
  const descentPt = Math.max(base.descentPt, subscript === void 0 ? 0 : subShiftDownPt + subscript.descentPt);
229
225
  const scriptWidthPt = Math.max(superscript?.widthPt ?? 0, subscript?.widthPt ?? 0);
@@ -281,9 +277,7 @@ function resolveTopAccentXPt(baseElement, ctx) {
281
277
  rawText = textContent(baseElement).trim();
282
278
  intrinsicDefault = "normal";
283
279
  } else return;
284
- const codePoints = [...applyMathVariant(rawText, tokenVariant(baseElement, intrinsicDefault, ctx))];
285
- if (codePoints.length !== 1) return;
286
- const codePoint = codePoints[0]?.codePointAt(0);
280
+ const codePoint = singleCodePoint(applyMathVariant(rawText, tokenVariant(baseElement, intrinsicDefault, ctx)));
287
281
  if (codePoint === void 0) return;
288
282
  return ctx.metrics.glyph(codePoint, ctx.sizePt)?.topAccentXPt;
289
283
  }
@@ -294,7 +288,6 @@ function layoutUnderOverElement(element, kind, ctx) {
294
288
  if (!ctx.displayStyle && isMovableLimitsOperator(baseElement)) {
295
289
  const base = layoutNode(baseElement, ctx);
296
290
  const scriptCtx = scriptContext(ctx, ctx.cramped);
297
- if (kind === "munder") return layoutScripts(base, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), void 0, ctx);
298
291
  if (kind === "mover") return layoutScripts(base, void 0, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), ctx);
299
292
  return layoutScripts(base, children[1] === void 0 ? void 0 : layoutNode(children[1], scriptCtx), children[2] === void 0 ? void 0 : layoutNode(children[2], scriptCtx), ctx);
300
293
  }
@@ -302,12 +295,10 @@ function layoutUnderOverElement(element, kind, ctx) {
302
295
  const scriptCtx = scriptContext(ctx, false);
303
296
  const isAccent = attrValue(element, "accent") === "true";
304
297
  const isAccentUnder = attrValue(element, "accentunder") === "true";
305
- const topAccentXPt = isAccent || isAccentUnder ? resolveTopAccentXPt(baseElement, ctx) : void 0;
306
298
  const accentAttachment = {
307
- overXPt: isAccent ? topAccentXPt : void 0,
308
- underXPt: isAccentUnder ? topAccentXPt : void 0
299
+ overXPt: isAccent ? resolveTopAccentXPt(baseElement, ctx) : void 0,
300
+ underXPt: isAccentUnder ? resolveTopAccentXPt(baseElement, ctx) : void 0
309
301
  };
310
- if (kind === "munder") return layoutUnderOver(base, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), void 0, ctx, accentAttachment);
311
302
  if (kind === "mover") return layoutUnderOver(base, void 0, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), ctx, accentAttachment);
312
303
  return layoutUnderOver(base, children[1] === void 0 ? void 0 : layoutUnderOverChild(children[1], base.widthPt, scriptCtx), children[2] === void 0 ? void 0 : layoutUnderOverChild(children[2], base.widthPt, scriptCtx), ctx, accentAttachment);
313
304
  }
@@ -315,7 +306,8 @@ function layoutFraction(element, ctx) {
315
306
  const children = elementChildren(element);
316
307
  const numeratorElement = children[0];
317
308
  const denominatorElement = children[1];
318
- if (numeratorElement === void 0 || denominatorElement === void 0) return EMPTY_BOX;
309
+ if (numeratorElement === void 0) return EMPTY_BOX;
310
+ if (denominatorElement === void 0) return EMPTY_BOX;
319
311
  const fracCtx = {
320
312
  ...ctx,
321
313
  displayStyle: false,
@@ -424,13 +416,12 @@ function wrapRadical(radicand, index, ctx) {
424
416
  }
425
417
  function layoutTable(element, ctx) {
426
418
  const rows = elementChildren(element).filter((child) => elementLocalName(child) === "mtr");
427
- if (rows.length === 0) return EMPTY_BOX;
428
- const columnAligns = (attrValue(element, "columnalign") ?? "").trim().split(/\s+/).filter((s) => s.length > 0);
419
+ const columnAlignAttr = attrValue(element, "columnalign");
420
+ const columnAligns = columnAlignAttr === void 0 ? [] : columnAlignAttr.match(/\S+/g) ?? [];
429
421
  const rowCells = rows.map((row) => elementChildren(row).filter((child) => elementLocalName(child) === "mtd").map((cell) => layoutRowChildren(elementChildren(cell), ctx)));
430
422
  const columnCount = rowCells.reduce((max, row) => Math.max(max, row.length), 0);
431
423
  if (columnCount === 0) return EMPTY_BOX;
432
- const columnWidthsPt = [];
433
- for (let column = 0; column < columnCount; column++) columnWidthsPt.push(rowCells.reduce((max, row) => Math.max(max, row[column]?.widthPt ?? 0), 0));
424
+ const columnWidthsPt = Array.from({ length: columnCount }, (_, column) => rowCells.reduce((max, row) => Math.max(max, row[column]?.widthPt ?? 0), 0));
434
425
  const columnGapPt = .8 * ctx.sizePt;
435
426
  const rowGapPt = .5 * ctx.sizePt;
436
427
  const items = [];
@@ -441,7 +432,7 @@ function layoutTable(element, ctx) {
441
432
  let cursorXPt = 0;
442
433
  row.forEach((cell, columnIndex) => {
443
434
  const columnWidthPt = columnWidthsPt[columnIndex] ?? cell.widthPt;
444
- const align = columnAligns[columnIndex] ?? columnAligns[columnAligns.length - 1] ?? "center";
435
+ const align = columnAligns[columnIndex] ?? columnAligns[columnAligns.length - 1];
445
436
  const extraPt = columnWidthPt - cell.widthPt;
446
437
  const dxPt = align === "left" ? 0 : align === "right" ? extraPt : extraPt / 2;
447
438
  items.push(...placeChild(cell, cursorXPt + dxPt, 0, cursorYTopPt + rowAscentPt));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "14.4.5",
3
+ "version": "14.4.7",
4
4
  "description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "markdown-codec": "11.1.3",
87
87
  "odf.js": "11.1.3",
88
88
  "ooxml.js": "12.2.8",
89
- "pdf-codec": "5.2.13",
89
+ "pdf-codec": "5.2.14",
90
90
  "ppt-codec": "2.2.3",
91
91
  "rtf-codec": "8.1.3",
92
92
  "temml": "0.13.4",