documents.js 1.47.0 → 1.49.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/dist/index.cjs CHANGED
@@ -80,6 +80,7 @@ function zipBytesSchema(label) {
80
80
  }
81
81
  const DocxBytesSchema = zipBytesSchema("docx");
82
82
  const PptxBytesSchema = zipBytesSchema("pptx");
83
+ const XlsxBytesSchema = zipBytesSchema("xlsx");
83
84
  const PdfBytesSchema = zod.z.instanceof(Uint8Array).refine((bytes) => containsBytesWithin(bytes, PDF_HEADER, PDF_HEADER_SEARCH_WINDOW), { message: "not a valid PDF file: missing the %PDF- header" });
84
85
  const MIMETYPE_ENTRY_FILENAME = "mimetype";
85
86
  const MIMETYPE_FILENAME_OFFSET = 30;
@@ -536,7 +537,7 @@ function needsSpacePreserve(text) {
536
537
  }
537
538
  //#endregion
538
539
  //#region src/edit/docx/run.ts
539
- function directChild$10(parent, tag) {
540
+ function directChild$11(parent, tag) {
540
541
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
541
542
  }
542
543
  function appendUElement(rPr, value) {
@@ -545,7 +546,7 @@ function appendUElement(rPr, value) {
545
546
  return created;
546
547
  }
547
548
  function findOrCreateT(run) {
548
- const existing = directChild$10(run, "w:t");
549
+ const existing = directChild$11(run, "w:t");
549
550
  if (existing !== void 0) return existing;
550
551
  const created = el("w:t");
551
552
  run.children.push(created);
@@ -565,7 +566,7 @@ var DocxRun = class {
565
566
  }
566
567
  rPr(create) {
567
568
  const node = this.live();
568
- return create ? ensureFirstChild(node, "w:rPr") : directChild$10(node, "w:rPr");
569
+ return create ? ensureFirstChild(node, "w:rPr") : directChild$11(node, "w:rPr");
569
570
  }
570
571
  get text() {
571
572
  return (0, ooxml_js.textContent)(this.live());
@@ -589,14 +590,14 @@ var DocxRun = class {
589
590
  }
590
591
  get underline() {
591
592
  const rPr = this.rPr(false);
592
- const uElement = rPr === void 0 ? void 0 : directChild$10(rPr, "w:u");
593
+ const uElement = rPr === void 0 ? void 0 : directChild$11(rPr, "w:u");
593
594
  if (uElement === void 0) return false;
594
595
  for (const a of uElement.attributes) if (a.name === "w:val") return a.value !== "none";
595
596
  return true;
596
597
  }
597
598
  set underline(value) {
598
599
  const rPr = this.rPr(true);
599
- const existing = directChild$10(rPr, "w:u");
600
+ const existing = directChild$11(rPr, "w:u");
600
601
  if (existing === void 0) {
601
602
  appendUElement(rPr, value);
602
603
  return;
@@ -670,7 +671,7 @@ function buildRun$1(init = {}) {
670
671
  }
671
672
  //#endregion
672
673
  //#region src/edit/docx/paragraph.ts
673
- function directChild$9(parent, tag) {
674
+ function directChild$10(parent, tag) {
674
675
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
675
676
  }
676
677
  var DocxParagraph = class {
@@ -689,7 +690,7 @@ var DocxParagraph = class {
689
690
  }
690
691
  pPr(create) {
691
692
  const node = this.live();
692
- return create ? ensureFirstChild(node, "w:pPr") : directChild$9(node, "w:pPr");
693
+ return create ? ensureFirstChild(node, "w:pPr") : directChild$10(node, "w:pPr");
693
694
  }
694
695
  get text() {
695
696
  return (0, ooxml_js.textContent)(this.live());
@@ -726,7 +727,7 @@ var DocxParagraph = class {
726
727
  set styleId(value) {
727
728
  if (value === void 0) {
728
729
  const pPr = this.pPr(false);
729
- const existing = pPr === void 0 ? void 0 : directChild$9(pPr, "w:pStyle");
730
+ const existing = pPr === void 0 ? void 0 : directChild$10(pPr, "w:pStyle");
730
731
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
731
732
  return;
732
733
  }
@@ -738,7 +739,7 @@ var DocxParagraph = class {
738
739
  set alignment(value) {
739
740
  if (value === void 0) {
740
741
  const pPr = this.pPr(false);
741
- const existing = pPr === void 0 ? void 0 : directChild$9(pPr, "w:jc");
742
+ const existing = pPr === void 0 ? void 0 : directChild$10(pPr, "w:jc");
742
743
  if (existing !== void 0 && pPr !== void 0) removeChild(pPr.children, existing);
743
744
  return;
744
745
  }
@@ -746,12 +747,12 @@ var DocxParagraph = class {
746
747
  }
747
748
  get list() {
748
749
  const pPr = this.pPr(false);
749
- const numPr = pPr === void 0 ? void 0 : directChild$9(pPr, "w:numPr");
750
+ const numPr = pPr === void 0 ? void 0 : directChild$10(pPr, "w:numPr");
750
751
  if (numPr === void 0) return;
751
- const numIdElement = directChild$9(numPr, "w:numId");
752
+ const numIdElement = directChild$10(numPr, "w:numId");
752
753
  const numId = numIdElement === void 0 ? void 0 : (0, ooxml_js.attr)(numIdElement, "w:val");
753
754
  if (numId === void 0) return;
754
- const ilvlElement = directChild$9(numPr, "w:ilvl");
755
+ const ilvlElement = directChild$10(numPr, "w:ilvl");
755
756
  const ilvl = ilvlElement === void 0 ? void 0 : (0, ooxml_js.attr)(ilvlElement, "w:val");
756
757
  return {
757
758
  numId,
@@ -761,7 +762,7 @@ var DocxParagraph = class {
761
762
  set list(value) {
762
763
  const pPr = this.pPr(true);
763
764
  if (value === void 0) {
764
- const existing = directChild$9(pPr, "w:numPr");
765
+ const existing = directChild$10(pPr, "w:numPr");
765
766
  if (existing !== void 0) removeChild(pPr.children, existing);
766
767
  return;
767
768
  }
@@ -1095,6 +1096,7 @@ function buildDocxPackage(content) {
1095
1096
  function populateParagraph$1(paragraph, block) {
1096
1097
  paragraph.styleId = block.styleId;
1097
1098
  paragraph.alignment = block.alignment;
1099
+ paragraph.list = block.list;
1098
1100
  for (const run of block.runs) {
1099
1101
  if (run.text === " ") {
1100
1102
  paragraph.appendTab();
@@ -1426,7 +1428,7 @@ function createEmptyPptxPackage() {
1426
1428
  }
1427
1429
  //#endregion
1428
1430
  //#region src/edit/pptx/shape.ts
1429
- function directChild$8(parent, tag) {
1431
+ function directChild$9(parent, tag) {
1430
1432
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1431
1433
  }
1432
1434
  function parseEmuAttr(element, name) {
@@ -1447,7 +1449,7 @@ var PptxShape = class {
1447
1449
  }
1448
1450
  spPrElement(create) {
1449
1451
  const node = this.live();
1450
- const existing = directChild$8(node, "p:spPr");
1452
+ const existing = directChild$9(node, "p:spPr");
1451
1453
  if (existing !== void 0 || !create) return existing;
1452
1454
  const created = el("p:spPr");
1453
1455
  node.children.push(created);
@@ -1455,10 +1457,10 @@ var PptxShape = class {
1455
1457
  }
1456
1458
  get frame() {
1457
1459
  const spPr = this.spPrElement(false);
1458
- const xfrm = spPr === void 0 ? void 0 : directChild$8(spPr, "a:xfrm");
1460
+ const xfrm = spPr === void 0 ? void 0 : directChild$9(spPr, "a:xfrm");
1459
1461
  if (xfrm === void 0) return;
1460
- const off = directChild$8(xfrm, "a:off");
1461
- const ext = directChild$8(xfrm, "a:ext");
1462
+ const off = directChild$9(xfrm, "a:off");
1463
+ const ext = directChild$9(xfrm, "a:ext");
1462
1464
  if (off === void 0 || ext === void 0) return;
1463
1465
  const x = parseEmuAttr(off, "x");
1464
1466
  const y = parseEmuAttr(off, "y");
@@ -1474,7 +1476,7 @@ var PptxShape = class {
1474
1476
  }
1475
1477
  set frame(value) {
1476
1478
  const spPr = this.spPrElement(true);
1477
- let xfrm = directChild$8(spPr, "a:xfrm");
1479
+ let xfrm = directChild$9(spPr, "a:xfrm");
1478
1480
  if (xfrm === void 0) {
1479
1481
  xfrm = el("a:xfrm");
1480
1482
  spPr.children.unshift(xfrm);
@@ -1488,12 +1490,12 @@ var PptxShape = class {
1488
1490
  })];
1489
1491
  }
1490
1492
  get text() {
1491
- const txBody = directChild$8(this.live(), "p:txBody");
1493
+ const txBody = directChild$9(this.live(), "p:txBody");
1492
1494
  return txBody === void 0 ? "" : (0, ooxml_js.textContent)(txBody);
1493
1495
  }
1494
1496
  set text(value) {
1495
1497
  const node = this.live();
1496
- let txBody = directChild$8(node, "p:txBody");
1498
+ let txBody = directChild$9(node, "p:txBody");
1497
1499
  if (txBody === void 0) {
1498
1500
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1499
1501
  node.children.push(txBody);
@@ -1504,7 +1506,7 @@ var PptxShape = class {
1504
1506
  }
1505
1507
  setParagraphs(paragraphs) {
1506
1508
  const node = this.live();
1507
- let txBody = directChild$8(node, "p:txBody");
1509
+ let txBody = directChild$9(node, "p:txBody");
1508
1510
  if (txBody === void 0) {
1509
1511
  txBody = el("p:txBody", {}, [el("a:bodyPr"), el("a:lstStyle")]);
1510
1512
  node.children.push(txBody);
@@ -1615,12 +1617,12 @@ function insertPictureShapeMedia(context, slideRoot, frame, image) {
1615
1617
  }
1616
1618
  //#endregion
1617
1619
  //#region src/edit/pptx/slide.ts
1618
- function directChild$7(parent, tag) {
1620
+ function directChild$8(parent, tag) {
1619
1621
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1620
1622
  }
1621
1623
  function findSpTree(slideRoot) {
1622
- const cSld = directChild$7(slideRoot, "p:cSld");
1623
- const spTree = cSld === void 0 ? void 0 : directChild$7(cSld, "p:spTree");
1624
+ const cSld = directChild$8(slideRoot, "p:cSld");
1625
+ const spTree = cSld === void 0 ? void 0 : directChild$8(cSld, "p:spTree");
1624
1626
  if (spTree === void 0) throw new Error("slide has no p:cSld/p:spTree element");
1625
1627
  return spTree;
1626
1628
  }
@@ -1752,7 +1754,7 @@ const PRESENTATION_PART_PATH = "ppt/presentation.xml";
1752
1754
  const MEDIA_DIR = "ppt/media";
1753
1755
  const SLIDE_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
1754
1756
  const SLIDE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide";
1755
- function directChild$6(parent, tag) {
1757
+ function directChild$7(parent, tag) {
1756
1758
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
1757
1759
  }
1758
1760
  function attrValue(element, name) {
@@ -1764,12 +1766,12 @@ function findPresentationRoot(pkg) {
1764
1766
  return root;
1765
1767
  }
1766
1768
  function findSldIdLst(presentationRoot) {
1767
- const sldIdLst = directChild$6(presentationRoot, "p:sldIdLst");
1769
+ const sldIdLst = directChild$7(presentationRoot, "p:sldIdLst");
1768
1770
  if (sldIdLst === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldIdLst element`);
1769
1771
  return sldIdLst;
1770
1772
  }
1771
1773
  function findSldSz(presentationRoot) {
1772
- const sldSz = directChild$6(presentationRoot, "p:sldSz");
1774
+ const sldSz = directChild$7(presentationRoot, "p:sldSz");
1773
1775
  if (sldSz === void 0) throw new Error(`${PRESENTATION_PART_PATH} has no p:sldSz element`);
1774
1776
  return sldSz;
1775
1777
  }
@@ -1968,12 +1970,12 @@ function appendShape$2(slide, shape) {
1968
1970
  }
1969
1971
  //#endregion
1970
1972
  //#region src/edit/odt/automatic-styles.ts
1971
- const CONTENT_PART_PATH$4 = "content.xml";
1973
+ const CONTENT_PART_PATH$5 = "content.xml";
1972
1974
  function ensureAutomaticStyles(pkg) {
1973
- const part = pkg.parts[CONTENT_PART_PATH$4];
1974
- if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$4} part`);
1975
+ const part = pkg.parts[CONTENT_PART_PATH$5];
1976
+ if (part?.kind !== "xml") throw new Error(`ensureAutomaticStyles: package has no ${CONTENT_PART_PATH$5} part`);
1975
1977
  const root = part.nodes.find((n) => n.type === "element");
1976
- if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$4} has no root element`);
1978
+ if (root === void 0) throw new Error(`ensureAutomaticStyles: ${CONTENT_PART_PATH$5} has no root element`);
1977
1979
  for (const child of root.children) if (child.type === "element" && child.tag === "office:automatic-styles") return child;
1978
1980
  const created = el("office:automatic-styles");
1979
1981
  const insertBeforeTags = /* @__PURE__ */ new Set([
@@ -2067,7 +2069,7 @@ function applyStyleChange(pkg, element, family, change) {
2067
2069
  ...readCurrentStyleProperties(pkg, element, family),
2068
2070
  ...change
2069
2071
  };
2070
- const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$4).intern({
2072
+ const name = odf_js.StyleRegistry.forPart(pkg, CONTENT_PART_PATH$5).intern({
2071
2073
  family,
2072
2074
  properties: merged
2073
2075
  });
@@ -2326,7 +2328,7 @@ const META_NS_PREFIXES$3 = [
2326
2328
  const ODF_VERSION$3 = "1.3";
2327
2329
  const PAGE_LAYOUT_NAME$3 = "PM1";
2328
2330
  const MASTER_PAGE_NAME$3 = "Standard";
2329
- const DEFAULT_MARGIN_PT = 72;
2331
+ const DEFAULT_MARGIN_PT$1 = 72;
2330
2332
  function declaration$3() {
2331
2333
  return {
2332
2334
  type: "declaration",
@@ -2350,10 +2352,10 @@ function buildPageLayout$3() {
2350
2352
  return el("style:page-layout", { "style:name": PAGE_LAYOUT_NAME$3 }, [el("style:page-layout-properties", {
2351
2353
  "fo:page-width": `${document_content_model.PAGE_SIZE_LETTER.widthPt}pt`,
2352
2354
  "fo:page-height": `${document_content_model.PAGE_SIZE_LETTER.heightPt}pt`,
2353
- "fo:margin-top": `${DEFAULT_MARGIN_PT}pt`,
2354
- "fo:margin-right": `${DEFAULT_MARGIN_PT}pt`,
2355
- "fo:margin-bottom": `${DEFAULT_MARGIN_PT}pt`,
2356
- "fo:margin-left": `${DEFAULT_MARGIN_PT}pt`
2355
+ "fo:margin-top": `${DEFAULT_MARGIN_PT$1}pt`,
2356
+ "fo:margin-right": `${DEFAULT_MARGIN_PT$1}pt`,
2357
+ "fo:margin-bottom": `${DEFAULT_MARGIN_PT$1}pt`,
2358
+ "fo:margin-left": `${DEFAULT_MARGIN_PT$1}pt`
2357
2359
  })]);
2358
2360
  }
2359
2361
  function buildStylesXml$3() {
@@ -2514,20 +2516,20 @@ function buildTable(pkg, init) {
2514
2516
  }
2515
2517
  //#endregion
2516
2518
  //#region src/edit/odt/editor.ts
2517
- const CONTENT_PART_PATH$3 = "content.xml";
2519
+ const CONTENT_PART_PATH$4 = "content.xml";
2518
2520
  function findContentRoot(pkg) {
2519
- const part = pkg.parts[CONTENT_PART_PATH$3];
2521
+ const part = pkg.parts[CONTENT_PART_PATH$4];
2520
2522
  const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2521
- if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH$3}`);
2523
+ if (root === void 0) throw new Error(`package has no root element at ${CONTENT_PART_PATH$4}`);
2522
2524
  return root;
2523
2525
  }
2524
- function directChild$5(parent, tag) {
2526
+ function directChild$6(parent, tag) {
2525
2527
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2526
2528
  }
2527
2529
  function findOfficeText(contentRoot) {
2528
- const body = directChild$5(contentRoot, "office:body");
2529
- const text = body === void 0 ? void 0 : directChild$5(body, "office:text");
2530
- if (text === void 0) throw new Error(`${CONTENT_PART_PATH$3} has no office:body/office:text element`);
2530
+ const body = directChild$6(contentRoot, "office:body");
2531
+ const text = body === void 0 ? void 0 : directChild$6(body, "office:text");
2532
+ if (text === void 0) throw new Error(`${CONTENT_PART_PATH$4} has no office:body/office:text element`);
2531
2533
  return text;
2532
2534
  }
2533
2535
  var OdtBodyImpl = class {
@@ -2607,11 +2609,60 @@ function buildOdtPackage(content) {
2607
2609
  const editor = createOdt();
2608
2610
  content.sections.forEach((section, sectionIndex) => {
2609
2611
  if (sectionIndex > 0) editor.body.appendPageBreak();
2610
- for (const block of section.blocks) appendBlock(editor.body, block);
2612
+ appendBlocks(editor.body, section.blocks);
2611
2613
  });
2612
2614
  return editor.toPackage();
2613
2615
  }
2616
+ function appendBlocks(body, blocks) {
2617
+ let i = 0;
2618
+ while (i < blocks.length) {
2619
+ const block = blocks[i];
2620
+ if (block === void 0) {
2621
+ i++;
2622
+ continue;
2623
+ }
2624
+ if (block.kind === "paragraph" && block.list !== void 0) {
2625
+ const run = [];
2626
+ while (i < blocks.length) {
2627
+ const candidate = blocks[i];
2628
+ if (candidate?.kind !== "paragraph" || candidate.list === void 0) break;
2629
+ run.push(candidate);
2630
+ i++;
2631
+ }
2632
+ appendListRun(body, run);
2633
+ continue;
2634
+ }
2635
+ appendBlock(body, block);
2636
+ i++;
2637
+ }
2638
+ }
2639
+ function appendListRun(body, paragraphs) {
2640
+ let stack = [];
2641
+ let lastItem;
2642
+ let activeNumId;
2643
+ for (const para of paragraphs) {
2644
+ const membership = para.list;
2645
+ if (membership === void 0) continue;
2646
+ if (activeNumId === void 0 || membership.numId !== activeNumId) {
2647
+ stack = [body.appendList()];
2648
+ lastItem = void 0;
2649
+ activeNumId = membership.numId;
2650
+ }
2651
+ const targetLevel = lastItem === void 0 ? 0 : membership.level;
2652
+ while (stack.length - 1 < targetLevel && lastItem !== void 0) {
2653
+ stack.push(lastItem.addNestedList());
2654
+ lastItem = void 0;
2655
+ }
2656
+ while (stack.length - 1 > targetLevel) stack.pop();
2657
+ const currentList = stack[stack.length - 1];
2658
+ if (currentList === void 0) continue;
2659
+ const item = currentList.addItem();
2660
+ populateParagraph(item.appendParagraph(), para);
2661
+ lastItem = item;
2662
+ }
2663
+ }
2614
2664
  function populateParagraph(paragraph, block) {
2665
+ if (block.styleId !== void 0) paragraph.styleId = block.styleId;
2615
2666
  if (block.alignment !== void 0) paragraph.alignment = block.alignment;
2616
2667
  for (const run of block.runs) {
2617
2668
  if (run.text === " ") {
@@ -2790,7 +2841,7 @@ function addImageMedia(pkg, imageBytes, format) {
2790
2841
  }
2791
2842
  //#endregion
2792
2843
  //#region src/edit/odp/shape.ts
2793
- function directChild$4(parent, tag) {
2844
+ function directChild$5(parent, tag) {
2794
2845
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2795
2846
  }
2796
2847
  function buildTransformAttr(frame, rotationDeg) {
@@ -2858,7 +2909,7 @@ var OdpShape = class {
2858
2909
  }
2859
2910
  textBox(create) {
2860
2911
  const node = this.live();
2861
- const existing = directChild$4(node, "draw:text-box");
2912
+ const existing = directChild$5(node, "draw:text-box");
2862
2913
  if (existing !== void 0 || !create) return existing;
2863
2914
  const created = el("draw:text-box");
2864
2915
  node.children.push(created);
@@ -2919,7 +2970,7 @@ function insertImageFrameMedia(context, frame, image) {
2919
2970
  }
2920
2971
  //#endregion
2921
2972
  //#region src/edit/odp/slide.ts
2922
- function directChild$3(parent, tag) {
2973
+ function directChild$4(parent, tag) {
2923
2974
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2924
2975
  }
2925
2976
  const NOTES_FRAME_X_PT = 20;
@@ -2968,13 +3019,13 @@ var OdpSlide = class {
2968
3019
  return new OdpShape(node.children, frameElement, this.context.pkg);
2969
3020
  }
2970
3021
  get notes() {
2971
- const notesElement = directChild$3(this.live(), "presentation:notes");
3022
+ const notesElement = directChild$4(this.live(), "presentation:notes");
2972
3023
  if (notesElement === void 0) return "";
2973
3024
  return (0, ooxml_js.elementsWithTag)(notesElement.children, "text:p").map((p) => decodeOdfText(p.children)).join("\n");
2974
3025
  }
2975
3026
  set notes(value) {
2976
3027
  const node = this.live();
2977
- const existing = directChild$3(node, "presentation:notes");
3028
+ const existing = directChild$4(node, "presentation:notes");
2978
3029
  const notesElement = buildNotesElement(this.context.pkg, value);
2979
3030
  if (existing === void 0) node.children.push(notesElement);
2980
3031
  else existing.children = notesElement.children;
@@ -2986,27 +3037,27 @@ var OdpSlide = class {
2986
3037
  };
2987
3038
  //#endregion
2988
3039
  //#region src/edit/odp/editor.ts
2989
- const CONTENT_PART_PATH$2 = "content.xml";
2990
- const STYLES_PART_PATH$1 = "styles.xml";
2991
- function directChild$2(parent, tag) {
3040
+ const CONTENT_PART_PATH$3 = "content.xml";
3041
+ const STYLES_PART_PATH$2 = "styles.xml";
3042
+ function directChild$3(parent, tag) {
2992
3043
  for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
2993
3044
  }
2994
- function findRoot$2(pkg, partPath) {
3045
+ function findRoot$3(pkg, partPath) {
2995
3046
  const part = pkg.parts[partPath];
2996
3047
  const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
2997
3048
  if (root === void 0) throw new Error(`package has no root element at ${partPath}`);
2998
3049
  return root;
2999
3050
  }
3000
3051
  function findOfficePresentation(pkg) {
3001
- const body = directChild$2(findRoot$2(pkg, CONTENT_PART_PATH$2), "office:body");
3002
- const presentation = body === void 0 ? void 0 : directChild$2(body, "office:presentation");
3003
- if (presentation === void 0) throw new Error(`${CONTENT_PART_PATH$2} has no office:body/office:presentation element`);
3052
+ const body = directChild$3(findRoot$3(pkg, CONTENT_PART_PATH$3), "office:body");
3053
+ const presentation = body === void 0 ? void 0 : directChild$3(body, "office:presentation");
3054
+ if (presentation === void 0) throw new Error(`${CONTENT_PART_PATH$3} has no office:body/office:presentation element`);
3004
3055
  return presentation;
3005
3056
  }
3006
3057
  function findPageLayoutProperties$1(pkg) {
3007
- const pageLayout = directChild$2(findRoot$2(pkg, STYLES_PART_PATH$1), "office:automatic-styles")?.children.find((c) => c.type === "element" && c.tag === "style:page-layout" && (0, ooxml_js.attr)(c, "style:name") === "PM1");
3008
- const properties = pageLayout === void 0 ? void 0 : directChild$2(pageLayout, "style:page-layout-properties");
3009
- if (properties === void 0) throw new Error(`${STYLES_PART_PATH$1} has no style:page-layout[style:name="PM1"]/style:page-layout-properties element`);
3058
+ const pageLayout = directChild$3(findRoot$3(pkg, STYLES_PART_PATH$2), "office:automatic-styles")?.children.find((c) => c.type === "element" && c.tag === "style:page-layout" && (0, ooxml_js.attr)(c, "style:name") === "PM1");
3059
+ const properties = pageLayout === void 0 ? void 0 : directChild$3(pageLayout, "style:page-layout-properties");
3060
+ if (properties === void 0) throw new Error(`${STYLES_PART_PATH$2} has no style:page-layout[style:name="PM1"]/style:page-layout-properties element`);
3010
3061
  return properties;
3011
3062
  }
3012
3063
  var OdpEditor = class {
@@ -3508,6 +3559,87 @@ var OdsCell = class {
3508
3559
  }
3509
3560
  };
3510
3561
  //#endregion
3562
+ //#region src/edit/ods/print-settings.ts
3563
+ const STYLES_PART_PATH$1 = "styles.xml";
3564
+ const CONTENT_PART_PATH$2 = "content.xml";
3565
+ function findRoot$2(pkg, partPath) {
3566
+ const part = pkg.parts[partPath];
3567
+ const root = part?.kind === "xml" ? part.nodes.find((n) => n.type === "element") : void 0;
3568
+ if (root === void 0) throw new Error(`package has no root element at ${partPath}`);
3569
+ return root;
3570
+ }
3571
+ function directChild$2(parent, tag) {
3572
+ for (const child of parent.children) if (child.type === "element" && child.tag === tag) return child;
3573
+ }
3574
+ function findStylesAutomaticStyles(pkg) {
3575
+ const found = directChild$2(findRoot$2(pkg, STYLES_PART_PATH$1), "office:automatic-styles");
3576
+ if (found === void 0) throw new Error(`${STYLES_PART_PATH$1} has no office:automatic-styles element`);
3577
+ return found;
3578
+ }
3579
+ function findMasterStyles(pkg) {
3580
+ const found = directChild$2(findRoot$2(pkg, STYLES_PART_PATH$1), "office:master-styles");
3581
+ if (found === void 0) throw new Error(`${STYLES_PART_PATH$1} has no office:master-styles element`);
3582
+ return found;
3583
+ }
3584
+ function findContentAutomaticStyles(pkg) {
3585
+ const found = directChild$2(findRoot$2(pkg, CONTENT_PART_PATH$2), "office:automatic-styles");
3586
+ if (found === void 0) throw new Error(`${CONTENT_PART_PATH$2} has no office:automatic-styles element`);
3587
+ return found;
3588
+ }
3589
+ const DEFAULT_MARGIN_PT = 56.69291338582677;
3590
+ const DEFAULT_MARGINS = {
3591
+ topPt: DEFAULT_MARGIN_PT,
3592
+ rightPt: DEFAULT_MARGIN_PT,
3593
+ bottomPt: DEFAULT_MARGIN_PT,
3594
+ leftPt: DEFAULT_MARGIN_PT
3595
+ };
3596
+ function readSheetPrintSettings(pkg, tableElement) {
3597
+ const tableStyleName = (0, ooxml_js.attr)(tableElement, "table:style-name");
3598
+ const tableStyleElement = tableStyleName === void 0 ? void 0 : (0, odf_js.findStyleElement)(tableStyleName, "table", pkg);
3599
+ const masterPageName = tableStyleElement === void 0 ? void 0 : (0, ooxml_js.attr)(tableStyleElement, "style:master-page-name");
3600
+ const layoutProperties = (0, odf_js.resolvePageLayoutProperties)(pkg, masterPageName);
3601
+ const pageSize = layoutProperties === void 0 ? void 0 : (0, odf_js.parsePageSize)(layoutProperties);
3602
+ const margins = layoutProperties === void 0 ? void 0 : (0, odf_js.parseMargins)(layoutProperties);
3603
+ const printTokens = new Set((layoutProperties === void 0 ? void 0 : (0, ooxml_js.attr)(layoutProperties, "style:print"))?.split(" ").filter((token) => token.length > 0) ?? []);
3604
+ const pageOrder = (layoutProperties === void 0 ? void 0 : (0, ooxml_js.attr)(layoutProperties, "style:print-page-order")) === "ltr" ? "overThenDown" : "downThenOver";
3605
+ return {
3606
+ pageSize: pageSize ?? document_content_model.PAGE_SIZE_A4,
3607
+ margins: margins ?? DEFAULT_MARGINS,
3608
+ gridlines: printTokens.has("grid"),
3609
+ headers: printTokens.has("headers"),
3610
+ pageOrder
3611
+ };
3612
+ }
3613
+ function writeSheetPrintSettings(pkg, tableElement, settings) {
3614
+ const stylesAutomaticStyles = findStylesAutomaticStyles(pkg);
3615
+ const masterStyles = findMasterStyles(pkg);
3616
+ const contentAutomaticStyles = findContentAutomaticStyles(pkg);
3617
+ const printTokens = [settings.gridlines ? "grid" : void 0, settings.headers ? "headers" : void 0].filter((token) => token !== void 0);
3618
+ const pageLayoutName = nextStyleName(stylesAutomaticStyles, "style:page-layout", "OdsPageLayout");
3619
+ stylesAutomaticStyles.children.push(el("style:page-layout", { "style:name": pageLayoutName }, [el("style:page-layout-properties", {
3620
+ "fo:page-width": (0, odf_js.formatOdfLength)(settings.pageSize.widthPt),
3621
+ "fo:page-height": (0, odf_js.formatOdfLength)(settings.pageSize.heightPt),
3622
+ "fo:margin-top": (0, odf_js.formatOdfLength)(settings.margins.topPt),
3623
+ "fo:margin-right": (0, odf_js.formatOdfLength)(settings.margins.rightPt),
3624
+ "fo:margin-bottom": (0, odf_js.formatOdfLength)(settings.margins.bottomPt),
3625
+ "fo:margin-left": (0, odf_js.formatOdfLength)(settings.margins.leftPt),
3626
+ ...printTokens.length > 0 ? { "style:print": printTokens.join(" ") } : {},
3627
+ "style:print-page-order": settings.pageOrder === "overThenDown" ? "ltr" : "ttb"
3628
+ })]));
3629
+ const masterPageName = nextStyleName(masterStyles, "style:master-page", "OdsMasterPage");
3630
+ masterStyles.children.push(el("style:master-page", {
3631
+ "style:name": masterPageName,
3632
+ "style:page-layout-name": pageLayoutName
3633
+ }));
3634
+ const tableStyleName = nextStyleName(contentAutomaticStyles, "style:style", "OdsSheetPrint");
3635
+ contentAutomaticStyles.children.push(el("style:style", {
3636
+ "style:name": tableStyleName,
3637
+ "style:family": "table",
3638
+ "style:master-page-name": masterPageName
3639
+ }));
3640
+ setAttr(tableElement, "table:style-name", tableStyleName);
3641
+ }
3642
+ //#endregion
3511
3643
  //#region src/edit/ods/sheet.ts
3512
3644
  const NAME_ATTR = "table:name";
3513
3645
  var OdsSheet = class {
@@ -3532,6 +3664,12 @@ var OdsSheet = class {
3532
3664
  set name(value) {
3533
3665
  setAttr(this.live(), NAME_ATTR, value);
3534
3666
  }
3667
+ get printSettings() {
3668
+ return readSheetPrintSettings(this.pkg, this.live());
3669
+ }
3670
+ set printSettings(value) {
3671
+ writeSheetPrintSettings(this.pkg, this.live(), value);
3672
+ }
3535
3673
  cell(row, column) {
3536
3674
  const node = resolveCellNode(this.live(), row, column);
3537
3675
  if (node.tag === "table:covered-table-cell") throw new Error(`cell (${row}, ${column}) is covered by a merged range -- address the merge's own anchor cell instead`);
@@ -3644,6 +3782,7 @@ function buildOdsPackage(content) {
3644
3782
  if (content.sheets.length > 0) editor.removeSheetAt(0);
3645
3783
  for (const sheet of content.sheets) {
3646
3784
  const odsSheet = editor.addSheet(sheet.name);
3785
+ odsSheet.printSettings = sheet.printSettings;
3647
3786
  for (const cell of sheet.cells) appendCell(odsSheet, cell);
3648
3787
  }
3649
3788
  return editor.toPackage();
@@ -11024,6 +11163,275 @@ function layoutTextToShape(item, pageHeightPt) {
11024
11163
  }]
11025
11164
  };
11026
11165
  }
11166
+ function extractLineCandidates(items) {
11167
+ const segments = [];
11168
+ for (const item of items) {
11169
+ if (item.kind === "line") {
11170
+ segments.push({
11171
+ x1Pt: item.x1Pt,
11172
+ y1Pt: item.y1Pt,
11173
+ x2Pt: item.x2Pt,
11174
+ y2Pt: item.y2Pt
11175
+ });
11176
+ continue;
11177
+ }
11178
+ if (item.kind === "path" && item.stroke !== void 0 && item.subpaths.length === 1) {
11179
+ const subpath = item.subpaths[0];
11180
+ if (subpath.segments.length === 1 && subpath.segments[0].kind === "line") {
11181
+ const segment = subpath.segments[0];
11182
+ segments.push({
11183
+ x1Pt: subpath.startXPt,
11184
+ y1Pt: subpath.startYPt,
11185
+ x2Pt: segment.xPt,
11186
+ y2Pt: segment.yPt
11187
+ });
11188
+ }
11189
+ }
11190
+ }
11191
+ return segments;
11192
+ }
11193
+ const AXIS_ALIGNMENT_TOLERANCE_PT = .5;
11194
+ const MIN_GRIDLINE_LENGTH_PT = 4;
11195
+ function classifyAxisLine(seg) {
11196
+ const dx = Math.abs(seg.x2Pt - seg.x1Pt);
11197
+ const dy = Math.abs(seg.y2Pt - seg.y1Pt);
11198
+ if (dy <= AXIS_ALIGNMENT_TOLERANCE_PT && dx >= MIN_GRIDLINE_LENGTH_PT) return {
11199
+ axis: "horizontal",
11200
+ position: (seg.y1Pt + seg.y2Pt) / 2,
11201
+ spanPt: dx
11202
+ };
11203
+ if (dx <= AXIS_ALIGNMENT_TOLERANCE_PT && dy >= MIN_GRIDLINE_LENGTH_PT) return {
11204
+ axis: "vertical",
11205
+ position: (seg.x1Pt + seg.x2Pt) / 2,
11206
+ spanPt: dy
11207
+ };
11208
+ }
11209
+ const POSITION_DEDUPE_TOLERANCE_PT = .5;
11210
+ function dedupeAxisLines(lines, descending) {
11211
+ const sorted = [...lines].sort((a, b) => descending ? b.position - a.position : a.position - b.position);
11212
+ const result = [];
11213
+ for (const candidate of sorted) {
11214
+ const last = result[result.length - 1];
11215
+ if (last !== void 0 && Math.abs(candidate.position - last.position) <= POSITION_DEDUPE_TOLERANCE_PT) last.spanPt = Math.max(last.spanPt, candidate.spanPt);
11216
+ else result.push({
11217
+ position: candidate.position,
11218
+ spanPt: candidate.spanPt
11219
+ });
11220
+ }
11221
+ return result;
11222
+ }
11223
+ const MIN_GRIDLINE_COUNT_PER_AXIS = 3;
11224
+ const GRID_SPAN_CONSISTENCY_RATIO = .9;
11225
+ function isRegularLattice(lines) {
11226
+ if (lines.length < MIN_GRIDLINE_COUNT_PER_AXIS) return false;
11227
+ const maxSpanPt = Math.max(...lines.map((l) => l.spanPt));
11228
+ return lines.filter((l) => l.spanPt >= maxSpanPt * GRID_SPAN_CONSISTENCY_RATIO).length >= MIN_GRIDLINE_COUNT_PER_AXIS;
11229
+ }
11230
+ function detectGridLattice(items) {
11231
+ const horizontal = [];
11232
+ const vertical = [];
11233
+ for (const seg of extractLineCandidates(items)) {
11234
+ const classified = classifyAxisLine(seg);
11235
+ if (classified === void 0) continue;
11236
+ (classified.axis === "horizontal" ? horizontal : vertical).push(classified);
11237
+ }
11238
+ const rowBoundaries = dedupeAxisLines(horizontal, true);
11239
+ const columnBoundaries = dedupeAxisLines(vertical, false);
11240
+ if (!isRegularLattice(rowBoundaries) || !isRegularLattice(columnBoundaries)) return;
11241
+ return {
11242
+ rowBoundariesDescPt: rowBoundaries.map((l) => l.position),
11243
+ columnBoundariesAscPt: columnBoundaries.map((l) => l.position)
11244
+ };
11245
+ }
11246
+ const OUTER_EDGE_TOLERANCE_PT = 3;
11247
+ function findRowIndex(rowBoundariesDescPt, yPt) {
11248
+ const lastIndex = rowBoundariesDescPt.length - 1;
11249
+ if (yPt > rowBoundariesDescPt[0] + OUTER_EDGE_TOLERANCE_PT || yPt < rowBoundariesDescPt[lastIndex] - OUTER_EDGE_TOLERANCE_PT) return;
11250
+ for (let i = 0; i < lastIndex; i++) if (yPt > rowBoundariesDescPt[i + 1]) return i;
11251
+ return lastIndex - 1;
11252
+ }
11253
+ function findColumnIndex(columnBoundariesAscPt, xPt) {
11254
+ const lastIndex = columnBoundariesAscPt.length - 1;
11255
+ if (xPt < columnBoundariesAscPt[0] - OUTER_EDGE_TOLERANCE_PT || xPt > columnBoundariesAscPt[lastIndex] + OUTER_EDGE_TOLERANCE_PT) return;
11256
+ for (let j = 0; j < lastIndex; j++) if (xPt < columnBoundariesAscPt[j + 1]) return j;
11257
+ return lastIndex - 1;
11258
+ }
11259
+ function joinCellText(items) {
11260
+ const sorted = [...items].sort((a, b) => a.xPt - b.xPt);
11261
+ let text = "";
11262
+ sorted.forEach((item, i) => {
11263
+ if (i > 0) {
11264
+ const prev = sorted[i - 1];
11265
+ if (item.xPt - (prev.xPt + (prev.widthPt ?? 0)) > MIN_WORD_GAP_PT) text += " ";
11266
+ }
11267
+ text += item.text;
11268
+ });
11269
+ return text;
11270
+ }
11271
+ function groupKey(row, column) {
11272
+ return `${row},${column}`;
11273
+ }
11274
+ function addToGroup(groups, row, column, item) {
11275
+ const key = groupKey(row, column);
11276
+ const existing = groups.get(key);
11277
+ if (existing === void 0) groups.set(key, [item]);
11278
+ else existing.push(item);
11279
+ }
11280
+ function buildCellsFromGroups(groups) {
11281
+ const cells = [];
11282
+ for (const [key, items] of groups) {
11283
+ const displayText = joinCellText(items);
11284
+ if (displayText.length === 0) continue;
11285
+ const [rowPart, columnPart] = key.split(",");
11286
+ cells.push({
11287
+ row: Number(rowPart),
11288
+ column: Number(columnPart),
11289
+ value: {
11290
+ kind: "string",
11291
+ value: displayText
11292
+ },
11293
+ displayText
11294
+ });
11295
+ }
11296
+ cells.sort((a, b) => a.row - b.row || a.column - b.column);
11297
+ return cells;
11298
+ }
11299
+ function buildGridFromLattice(textItems, lattice) {
11300
+ const groups = /* @__PURE__ */ new Map();
11301
+ for (const item of textItems) {
11302
+ const row = findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
11303
+ const column = findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
11304
+ if (row === void 0 || column === void 0) continue;
11305
+ addToGroup(groups, row, column, item);
11306
+ }
11307
+ const columns = [];
11308
+ for (let j = 0; j < lattice.columnBoundariesAscPt.length - 1; j++) columns.push({
11309
+ index: j,
11310
+ widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]
11311
+ });
11312
+ const rows = [];
11313
+ for (let i = 0; i < lattice.rowBoundariesDescPt.length - 1; i++) rows.push({
11314
+ index: i,
11315
+ heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
11316
+ });
11317
+ return {
11318
+ cells: buildCellsFromGroups(groups),
11319
+ columns,
11320
+ rows,
11321
+ gridlines: true
11322
+ };
11323
+ }
11324
+ const COLUMN_ALIGNMENT_TOLERANCE_PT = 3;
11325
+ const MIN_COLUMN_RECURRENCE = 2;
11326
+ function detectColumnPositions(segmentsByLine) {
11327
+ const allXs = segmentsByLine.flatMap((segments) => segments.map((segment) => segment.items[0].xPt));
11328
+ if (allXs.length === 0) return [];
11329
+ const counts = bucketCounts(allXs, COLUMN_ALIGNMENT_TOLERANCE_PT);
11330
+ const recurring = [...counts.entries()].filter(([, count]) => count >= MIN_COLUMN_RECURRENCE).map(([bucket]) => bucket);
11331
+ const positions = recurring.length > 0 ? recurring : [...counts.keys()];
11332
+ positions.sort((a, b) => a - b);
11333
+ return positions;
11334
+ }
11335
+ function nearestColumnIndex(positions, xPt) {
11336
+ let bestIndex = 0;
11337
+ let bestDistancePt = Number.POSITIVE_INFINITY;
11338
+ positions.forEach((position, index) => {
11339
+ const distancePt = Math.abs(position - xPt);
11340
+ if (distancePt < bestDistancePt) {
11341
+ bestDistancePt = distancePt;
11342
+ bestIndex = index;
11343
+ }
11344
+ });
11345
+ return bestIndex;
11346
+ }
11347
+ const DEFAULT_COLUMN_WIDTH_FALLBACK_PT = 40;
11348
+ function lastColumnWidthPt(groups, columnIndex, anchorXPt) {
11349
+ let maxWidthPt = 0;
11350
+ for (const [key, items] of groups) {
11351
+ const [, columnPart] = key.split(",");
11352
+ if (Number(columnPart) !== columnIndex) continue;
11353
+ for (const item of items) maxWidthPt = Math.max(maxWidthPt, item.xPt + (item.widthPt ?? 0) - anchorXPt);
11354
+ }
11355
+ return maxWidthPt > 0 ? maxWidthPt : DEFAULT_COLUMN_WIDTH_FALLBACK_PT;
11356
+ }
11357
+ function buildGridFromTextClustering(textItems) {
11358
+ const lines = clusterIntoLines(textItems);
11359
+ if (lines.length === 0) return {
11360
+ cells: [],
11361
+ columns: [],
11362
+ rows: [],
11363
+ gridlines: false
11364
+ };
11365
+ const segmentsByLine = lines.map((l) => splitLineByLargeGaps(l));
11366
+ const columnPositions = detectColumnPositions(segmentsByLine);
11367
+ const groups = /* @__PURE__ */ new Map();
11368
+ segmentsByLine.forEach((segments, rowIndex) => {
11369
+ for (const segment of segments) {
11370
+ const key = groupKey(rowIndex, nearestColumnIndex(columnPositions, segment.items[0].xPt));
11371
+ const existing = groups.get(key);
11372
+ if (existing === void 0) groups.set(key, [...segment.items]);
11373
+ else existing.push(...segment.items);
11374
+ }
11375
+ });
11376
+ const nominalRowHeightPt = estimateModalLineSpacing(lines);
11377
+ const rows = lines.map((line, i) => {
11378
+ const nextBaselineY = lines[i + 1]?.baselineY;
11379
+ const heightPt = nextBaselineY !== void 0 ? line.baselineY - nextBaselineY : nominalRowHeightPt;
11380
+ return {
11381
+ index: i,
11382
+ heightPt: heightPt > 0 ? heightPt : nominalRowHeightPt
11383
+ };
11384
+ });
11385
+ const columns = columnPositions.map((position, j) => {
11386
+ const nextPosition = columnPositions[j + 1];
11387
+ return {
11388
+ index: j,
11389
+ widthPt: nextPosition !== void 0 ? nextPosition - position : lastColumnWidthPt(groups, j, position)
11390
+ };
11391
+ });
11392
+ return {
11393
+ cells: buildCellsFromGroups(groups),
11394
+ columns,
11395
+ rows,
11396
+ gridlines: false
11397
+ };
11398
+ }
11399
+ function reconstructSheet(page, pageIndex) {
11400
+ const textItems = page.items.filter((i) => i.kind === "text");
11401
+ const lattice = detectGridLattice(page.items);
11402
+ const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice) : buildGridFromTextClustering(textItems);
11403
+ const printSettings = {
11404
+ pageSize: {
11405
+ widthPt: page.widthPt,
11406
+ heightPt: page.heightPt
11407
+ },
11408
+ margins: ZERO_MARGINS,
11409
+ gridlines: grid.gridlines,
11410
+ headers: false,
11411
+ pageOrder: "downThenOver"
11412
+ };
11413
+ return {
11414
+ name: `Sheet${pageIndex + 1}`,
11415
+ cells: grid.cells,
11416
+ columns: grid.columns,
11417
+ rows: grid.rows,
11418
+ images: [],
11419
+ printSettings
11420
+ };
11421
+ }
11422
+ function reconstructSpreadsheet(doc, options) {
11423
+ const signal = options?.signal;
11424
+ const sheets = doc.pages.map((page, index) => {
11425
+ throwIfAborted(signal);
11426
+ return reconstructSheet(page, index);
11427
+ });
11428
+ return {
11429
+ kind: "spreadsheet",
11430
+ formatVersion: 1,
11431
+ metadata: doc.metadata,
11432
+ sheets
11433
+ };
11434
+ }
11027
11435
  //#endregion
11028
11436
  //#region src/convert/convert.ts
11029
11437
  function docxToPdf(bytes, options) {
@@ -11112,6 +11520,56 @@ function pdfToOdg(bytes, options) {
11112
11520
  }), { signal: options?.signal });
11113
11521
  return (0, odf_js.encodePackage)(buildOdgPackage(content));
11114
11522
  }
11523
+ function pdfToOds(bytes, options) {
11524
+ const content = reconstructSpreadsheet(readPdf(bytes, {
11525
+ signal: options?.signal,
11526
+ sink: options?.sink
11527
+ }), { signal: options?.signal });
11528
+ return (0, odf_js.encodePackage)(buildOdsPackage(content));
11529
+ }
11530
+ function odtToDocx(bytes, options) {
11531
+ throwIfAborted(options?.signal);
11532
+ const content = readOdtContent((0, odf_js.decodePackage)(bytes));
11533
+ if (content.kind !== "wordprocessing") throw new Error("readOdtContent returned a non-wordprocessing ContentDocument");
11534
+ throwIfAborted(options?.signal);
11535
+ return (0, ooxml_js.encodePackage)(buildDocxPackage(content));
11536
+ }
11537
+ function docxToOdt(bytes, options) {
11538
+ throwIfAborted(options?.signal);
11539
+ const content = readDocxContent((0, ooxml_js.decodePackage)(bytes));
11540
+ if (content.kind !== "wordprocessing") throw new Error("readDocxContent returned a non-wordprocessing ContentDocument");
11541
+ throwIfAborted(options?.signal);
11542
+ return (0, odf_js.encodePackage)(buildOdtPackage(content));
11543
+ }
11544
+ function odpToPptx(bytes, options) {
11545
+ throwIfAborted(options?.signal);
11546
+ const content = readOdpContent((0, odf_js.decodePackage)(bytes));
11547
+ if (content.kind !== "presentation") throw new Error("readOdpContent returned a non-presentation ContentDocument");
11548
+ throwIfAborted(options?.signal);
11549
+ return (0, ooxml_js.encodePackage)(buildPptxPackage(content));
11550
+ }
11551
+ function pptxToOdp(bytes, options) {
11552
+ throwIfAborted(options?.signal);
11553
+ const content = readPptxContent((0, ooxml_js.decodePackage)(bytes));
11554
+ if (content.kind !== "presentation") throw new Error("readPptxContent returned a non-presentation ContentDocument");
11555
+ throwIfAborted(options?.signal);
11556
+ return (0, odf_js.encodePackage)(buildOdpPackage(content));
11557
+ }
11558
+ function odsToXlsx(bytes, options) {
11559
+ throwIfAborted(options?.signal);
11560
+ const content = readOdsContent((0, odf_js.decodePackage)(bytes));
11561
+ if (content.kind !== "spreadsheet") throw new Error("readOdsContent returned a non-spreadsheet ContentDocument");
11562
+ throwIfAborted(options?.signal);
11563
+ return (0, ooxml_js.encodePackage)((0, ooxml_js.buildXlsxPackage)(content));
11564
+ }
11565
+ function xlsxToOds(bytes, options) {
11566
+ throwIfAborted(options?.signal);
11567
+ const pkg = (0, ooxml_js.decodePackage)(bytes);
11568
+ const content = (0, ooxml_js.readXlsxContent)(pkg);
11569
+ if (content.kind !== "spreadsheet") throw new Error("readXlsxContent returned a non-spreadsheet ContentDocument");
11570
+ throwIfAborted(options?.signal);
11571
+ return (0, odf_js.encodePackage)(buildOdsPackage(content));
11572
+ }
11115
11573
  //#endregion
11116
11574
  //#region src/convert/codec.ts
11117
11575
  const docxPdfCodec = zod.z.codec(DocxBytesSchema, PdfBytesSchema, {
@@ -11130,10 +11588,26 @@ const odpPdfCodec = zod.z.codec(OdpBytesSchema, PdfBytesSchema, {
11130
11588
  decode: (odpBytes) => odpToPdf(odpBytes),
11131
11589
  encode: (pdfBytes) => pdfToOdp(pdfBytes)
11132
11590
  });
11591
+ const odsPdfCodec = zod.z.codec(OdsBytesSchema, PdfBytesSchema, {
11592
+ decode: (odsBytes) => odsToPdf(odsBytes),
11593
+ encode: (pdfBytes) => pdfToOds(pdfBytes)
11594
+ });
11133
11595
  const odgPdfCodec = zod.z.codec(OdgBytesSchema, PdfBytesSchema, {
11134
11596
  decode: (odgBytes) => odgToPdf(odgBytes),
11135
11597
  encode: (pdfBytes) => pdfToOdg(pdfBytes)
11136
11598
  });
11599
+ const odtDocxCodec = zod.z.codec(OdtBytesSchema, DocxBytesSchema, {
11600
+ decode: (odtBytes) => odtToDocx(odtBytes),
11601
+ encode: (docxBytes) => docxToOdt(docxBytes)
11602
+ });
11603
+ const odpPptxCodec = zod.z.codec(OdpBytesSchema, PptxBytesSchema, {
11604
+ decode: (odpBytes) => odpToPptx(odpBytes),
11605
+ encode: (pptxBytes) => pptxToOdp(pptxBytes)
11606
+ });
11607
+ const odsXlsxCodec = zod.z.codec(OdsBytesSchema, XlsxBytesSchema, {
11608
+ decode: (odsBytes) => odsToXlsx(odsBytes),
11609
+ encode: (xlsxBytes) => xlsxToOds(xlsxBytes)
11610
+ });
11137
11611
  //#endregion
11138
11612
  //#region src/convert/local.ts
11139
11613
  const SUPPORTED_CONVERSIONS = [
@@ -11177,9 +11651,37 @@ const SUPPORTED_CONVERSIONS = [
11177
11651
  source: "pdf",
11178
11652
  target: "odp"
11179
11653
  },
11654
+ {
11655
+ source: "pdf",
11656
+ target: "ods"
11657
+ },
11180
11658
  {
11181
11659
  source: "pdf",
11182
11660
  target: "odg"
11661
+ },
11662
+ {
11663
+ source: "odt",
11664
+ target: "docx"
11665
+ },
11666
+ {
11667
+ source: "docx",
11668
+ target: "odt"
11669
+ },
11670
+ {
11671
+ source: "odp",
11672
+ target: "pptx"
11673
+ },
11674
+ {
11675
+ source: "pptx",
11676
+ target: "odp"
11677
+ },
11678
+ {
11679
+ source: "ods",
11680
+ target: "xlsx"
11681
+ },
11682
+ {
11683
+ source: "xlsx",
11684
+ target: "ods"
11183
11685
  }
11184
11686
  ];
11185
11687
  function substitutionDiagnostic(substitution, context) {
@@ -11335,6 +11837,19 @@ function createLocalDocumentConverter() {
11335
11837
  diagnostics
11336
11838
  });
11337
11839
  }
11840
+ if (source.format === "pdf" && targetFormat === "ods") {
11841
+ const bytes = pdfToOds(source.bytes, {
11842
+ signal: options.signal,
11843
+ sink: (d) => diagnostics.push(fromPdfDiagnostic(d))
11844
+ });
11845
+ return Promise.resolve({
11846
+ document: {
11847
+ format: "ods",
11848
+ bytes
11849
+ },
11850
+ diagnostics
11851
+ });
11852
+ }
11338
11853
  if (source.format === "pdf" && targetFormat === "odg") {
11339
11854
  const bytes = pdfToOdg(source.bytes, {
11340
11855
  signal: options.signal,
@@ -11348,6 +11863,66 @@ function createLocalDocumentConverter() {
11348
11863
  diagnostics
11349
11864
  });
11350
11865
  }
11866
+ if (source.format === "odt" && targetFormat === "docx") {
11867
+ const bytes = odtToDocx(source.bytes, { signal: options.signal });
11868
+ return Promise.resolve({
11869
+ document: {
11870
+ format: "docx",
11871
+ bytes
11872
+ },
11873
+ diagnostics
11874
+ });
11875
+ }
11876
+ if (source.format === "docx" && targetFormat === "odt") {
11877
+ const bytes = docxToOdt(source.bytes, { signal: options.signal });
11878
+ return Promise.resolve({
11879
+ document: {
11880
+ format: "odt",
11881
+ bytes
11882
+ },
11883
+ diagnostics
11884
+ });
11885
+ }
11886
+ if (source.format === "odp" && targetFormat === "pptx") {
11887
+ const bytes = odpToPptx(source.bytes, { signal: options.signal });
11888
+ return Promise.resolve({
11889
+ document: {
11890
+ format: "pptx",
11891
+ bytes
11892
+ },
11893
+ diagnostics
11894
+ });
11895
+ }
11896
+ if (source.format === "pptx" && targetFormat === "odp") {
11897
+ const bytes = pptxToOdp(source.bytes, { signal: options.signal });
11898
+ return Promise.resolve({
11899
+ document: {
11900
+ format: "odp",
11901
+ bytes
11902
+ },
11903
+ diagnostics
11904
+ });
11905
+ }
11906
+ if (source.format === "ods" && targetFormat === "xlsx") {
11907
+ const bytes = odsToXlsx(source.bytes, { signal: options.signal });
11908
+ return Promise.resolve({
11909
+ document: {
11910
+ format: "xlsx",
11911
+ bytes
11912
+ },
11913
+ diagnostics
11914
+ });
11915
+ }
11916
+ if (source.format === "xlsx" && targetFormat === "ods") {
11917
+ const bytes = xlsxToOds(source.bytes, { signal: options.signal });
11918
+ return Promise.resolve({
11919
+ document: {
11920
+ format: "ods",
11921
+ bytes
11922
+ },
11923
+ diagnostics
11924
+ });
11925
+ }
11351
11926
  return Promise.reject(/* @__PURE__ */ new Error(`unsupported conversion: ${source.format} -> ${targetFormat}`));
11352
11927
  }
11353
11928
  };
@@ -11645,6 +12220,7 @@ Object.defineProperty(exports, "SLIDE_SIZE_WIDESCREEN", {
11645
12220
  return document_content_model.SLIDE_SIZE_WIDESCREEN;
11646
12221
  }
11647
12222
  });
12223
+ exports.XlsxBytesSchema = XlsxBytesSchema;
11648
12224
  Object.defineProperty(exports, "XmlCdataSchema", {
11649
12225
  enumerable: true,
11650
12226
  get: function() {
@@ -11771,6 +12347,7 @@ Object.defineProperty(exports, "decodePackage", {
11771
12347
  }
11772
12348
  });
11773
12349
  exports.docxPdfCodec = docxPdfCodec;
12350
+ exports.docxToOdt = docxToOdt;
11774
12351
  exports.docxToPdf = docxToPdf;
11775
12352
  Object.defineProperty(exports, "elementsWithTag", {
11776
12353
  enumerable: true,
@@ -11819,9 +12396,16 @@ Object.defineProperty(exports, "isXmlNode", {
11819
12396
  exports.odgPdfCodec = odgPdfCodec;
11820
12397
  exports.odgToPdf = odgToPdf;
11821
12398
  exports.odpPdfCodec = odpPdfCodec;
12399
+ exports.odpPptxCodec = odpPptxCodec;
11822
12400
  exports.odpToPdf = odpToPdf;
12401
+ exports.odpToPptx = odpToPptx;
12402
+ exports.odsPdfCodec = odsPdfCodec;
11823
12403
  exports.odsToPdf = odsToPdf;
12404
+ exports.odsToXlsx = odsToXlsx;
12405
+ exports.odsXlsxCodec = odsXlsxCodec;
12406
+ exports.odtDocxCodec = odtDocxCodec;
11824
12407
  exports.odtPdfCodec = odtPdfCodec;
12408
+ exports.odtToDocx = odtToDocx;
11825
12409
  exports.odtToPdf = odtToPdf;
11826
12410
  exports.openDocx = openDocx;
11827
12411
  exports.openOdg = openOdg;
@@ -11851,9 +12435,11 @@ exports.pdfCodec = pdfCodec;
11851
12435
  exports.pdfToDocx = pdfToDocx;
11852
12436
  exports.pdfToOdg = pdfToOdg;
11853
12437
  exports.pdfToOdp = pdfToOdp;
12438
+ exports.pdfToOds = pdfToOds;
11854
12439
  exports.pdfToOdt = pdfToOdt;
11855
12440
  exports.pdfToPptx = pdfToPptx;
11856
12441
  exports.pptxPdfCodec = pptxPdfCodec;
12442
+ exports.pptxToOdp = pptxToOdp;
11857
12443
  exports.pptxToPdf = pptxToPdf;
11858
12444
  exports.readDocxContent = readDocxContent;
11859
12445
  exports.readOdgContent = readOdgContent;
@@ -11864,6 +12450,7 @@ exports.readPdf = readPdf;
11864
12450
  exports.readPptxContent = readPptxContent;
11865
12451
  exports.reconstructDrawing = reconstructDrawing;
11866
12452
  exports.reconstructPresentation = reconstructPresentation;
12453
+ exports.reconstructSpreadsheet = reconstructSpreadsheet;
11867
12454
  exports.reconstructWordprocessing = reconstructWordprocessing;
11868
12455
  Object.defineProperty(exports, "resolveRelationships", {
11869
12456
  enumerable: true,
@@ -11916,6 +12503,7 @@ Object.defineProperty(exports, "walk", {
11916
12503
  }
11917
12504
  });
11918
12505
  exports.writePdf = writePdf;
12506
+ exports.xlsxToOds = xlsxToOds;
11919
12507
  Object.defineProperty(exports, "xmlCodec", {
11920
12508
  enumerable: true,
11921
12509
  get: function() {