documents.js 1.41.0 → 1.42.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.js CHANGED
@@ -1,21 +1,30 @@
1
1
  import { AttributeSchema, BinaryPartSchema, CommentSchema, CompactPackageSchema, CompactPartSchema, CompactXmlNodeSchema, DefinedNameSchema, PackageSchema, PartSchema, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, attr, attr as attr$1, base64ToBytes, base64ToBytes as base64ToBytes$1, buildXml, bytesToBase64, bytesToBase64 as bytesToBase64$1, childrenWithTag, compactCodec, compactPackageCodec, decodeCompactPackage, decodeEntities, decodePackage, decodePackage as decodePackage$1, elementsWithTag, elementsWithTag as elementsWithTag$1, encodeCompactPackage, encodePackage, encodePackage as encodePackage$1, fromCompact, isCompactXmlNode, isXmlNode, packageCodec, parsePackage, parseXml, readDocx, readPptx, resolveRelationships, resolveRelationships as resolveRelationships$1, rootElement, rootElement as rootElement$1, serializePackage, textContent, textContent as textContent$1, toCompact, unzipPackage, walk, xmlCodec, zipPackage } from "ooxml.js";
2
- import { COLOR_BLACK, ContentBlockSchema, ContentImageBlockSchema, ContentPageBreakSchema, ContentParagraphSchema, ContentRunSchema, ContentSectionSchema, ContentSectionSchema as ContentSectionSchema$1, ContentShapeSchema, ContentSlideSchema, ContentSlideSchema as ContentSlideSchema$1, ContentTableCellSchema, ContentTableRowSchema, ContentTableSchema, DEFAULT_LAYOUT_FONT, LAYOUT_FORMAT_VERSION, LAYOUT_FORMAT_VERSION as LAYOUT_FORMAT_VERSION$1, LayoutDocumentSchema, LayoutMetadataSchema, PAGE_SIZE_A4, PAGE_SIZE_LETTER, SLIDE_SIZE_STANDARD, SLIDE_SIZE_WIDESCREEN, colorToRgbHex, isContentBlock, rgbHexToColor } from "document-content-model";
2
+ import { COLOR_BLACK, ContentBlockSchema, ContentCellValueSchema, ContentImageBlockSchema, ContentPageBreakSchema, ContentParagraphSchema, ContentRunSchema, ContentSectionSchema, ContentSectionSchema as ContentSectionSchema$1, ContentShapeSchema, ContentSheetCellSchema, ContentSheetColumnSchema, ContentSheetPrintRangeSchema, ContentSheetPrintSettingsSchema, ContentSheetRepeatRangeSchema, ContentSheetRowSchema, ContentSheetSchema, ContentSheetSchema as ContentSheetSchema$1, ContentSlideSchema, ContentSlideSchema as ContentSlideSchema$1, ContentTableCellSchema, ContentTableRowSchema, ContentTableSchema, DEFAULT_LAYOUT_FONT, LAYOUT_FORMAT_VERSION, LAYOUT_FORMAT_VERSION as LAYOUT_FORMAT_VERSION$1, LayoutDocumentSchema, LayoutMetadataSchema, PAGE_SIZE_A4, PAGE_SIZE_LETTER, SLIDE_SIZE_STANDARD, SLIDE_SIZE_WIDESCREEN, colorToRgbHex, isContentBlock, rgbHexToColor } from "document-content-model";
3
3
  import { z } from "zod";
4
- import { ODF_MEDIA_TYPES, StyleRegistry, applyOdfTransform, base64ToBytes as base64ToBytes$2, bytesToBase64 as bytesToBase64$2, decodeOdfText, decodePackage as decodePackage$2, encodePackage as encodePackage$2, formatOdfLength, parseOdfLength, readOdp, readOdt, resolveOdfShapeGeometry, resolveStyle, setDocumentMediaType, syncManifest, syncManifest as syncManifest$1, xmlnsAttributes } from "odf.js";
4
+ import { ODF_MEDIA_TYPES, StyleRegistry, applyOdfTransform, base64ToBytes as base64ToBytes$2, bytesToBase64 as bytesToBase64$2, decodeOdfText, decodePackage as decodePackage$2, encodePackage as encodePackage$2, formatOdfLength, parseOdfLength, readOdp, readOds, readOdt, resolveOdfShapeGeometry, resolveStyle, setDocumentMediaType, syncManifest, syncManifest as syncManifest$1, xmlnsAttributes } from "odf.js";
5
5
  import { Unzlib, inflateSync, unzlibSync, zlibSync } from "fflate";
6
6
  //#region src/model/content.ts
7
7
  const CONTENT_FORMAT_VERSION = 1;
8
- const ContentDocumentSchema = z.discriminatedUnion("kind", [z.object({
9
- kind: z.literal("wordprocessing"),
10
- formatVersion: z.literal(1),
11
- metadata: LayoutMetadataSchema,
12
- sections: z.array(ContentSectionSchema$1)
13
- }), z.object({
14
- kind: z.literal("presentation"),
15
- formatVersion: z.literal(1),
16
- metadata: LayoutMetadataSchema,
17
- slides: z.array(ContentSlideSchema$1)
18
- })]);
8
+ const ContentDocumentSchema = z.discriminatedUnion("kind", [
9
+ z.object({
10
+ kind: z.literal("wordprocessing"),
11
+ formatVersion: z.literal(1),
12
+ metadata: LayoutMetadataSchema,
13
+ sections: z.array(ContentSectionSchema$1)
14
+ }),
15
+ z.object({
16
+ kind: z.literal("presentation"),
17
+ formatVersion: z.literal(1),
18
+ metadata: LayoutMetadataSchema,
19
+ slides: z.array(ContentSlideSchema$1)
20
+ }),
21
+ z.object({
22
+ kind: z.literal("spreadsheet"),
23
+ formatVersion: z.literal(1),
24
+ metadata: LayoutMetadataSchema,
25
+ sheets: z.array(ContentSheetSchema$1)
26
+ })
27
+ ]);
19
28
  //#endregion
20
29
  //#region src/model/geometry.ts
21
30
  function flipY(box, containerHeightPt) {
@@ -7915,6 +7924,17 @@ function readOdpContent(pkg) {
7915
7924
  };
7916
7925
  }
7917
7926
  //#endregion
7927
+ //#region src/odf/ods/read.ts
7928
+ function readOdsContent(pkg) {
7929
+ const odsDoc = readOds(pkg);
7930
+ return {
7931
+ kind: "spreadsheet",
7932
+ formatVersion: 1,
7933
+ metadata: { ...odsDoc.metadata },
7934
+ sheets: odsDoc.sheets
7935
+ };
7936
+ }
7937
+ //#endregion
7918
7938
  //#region src/pdf/text-layout.ts
7919
7939
  const WORD_OR_WHITESPACE_PATTERN = /\n|\s+|\S+/g;
7920
7940
  function atomizeRuns(runs, measurer) {
@@ -8542,6 +8562,410 @@ function convertPresentationToLayout(doc, options) {
8542
8562
  };
8543
8563
  }
8544
8564
  //#endregion
8565
+ //#region src/layout/sheets.ts
8566
+ const DEFAULT_COLUMN_WIDTH_PT = 64;
8567
+ const DEFAULT_ROW_HEIGHT_PT = 15;
8568
+ const NOMINAL_CELL_TEXT_SIZE_PT = 10;
8569
+ const HEADER_LABEL_SIZE_PT = 8;
8570
+ const CELL_TEXT_PADDING_PT = 2;
8571
+ const HEADER_LABEL_PADDING_PT = 2;
8572
+ const MINIMUM_SCALE = .01;
8573
+ const NUMERIC_OVERFLOW_TEXT = "###";
8574
+ const GRIDLINE_COLOR = rgbHexToColor("#D0D0D0");
8575
+ const GRIDLINE_WIDTH_PT = .5;
8576
+ const HEADER_LABEL_COLOR = rgbHexToColor("#606060");
8577
+ function columnLetters(index) {
8578
+ let n = index + 1;
8579
+ let letters = "";
8580
+ while (n > 0) {
8581
+ const remainder = (n - 1) % 26;
8582
+ letters = String.fromCharCode(65 + remainder) + letters;
8583
+ n = Math.floor((n - 1) / 26);
8584
+ }
8585
+ return letters;
8586
+ }
8587
+ function resolvePrintRange(sheet) {
8588
+ if (sheet.printSettings.printRange !== void 0) return sheet.printSettings.printRange;
8589
+ if (sheet.cells.length === 0) return;
8590
+ let startRow = Number.POSITIVE_INFINITY;
8591
+ let startColumn = Number.POSITIVE_INFINITY;
8592
+ let endRow = Number.NEGATIVE_INFINITY;
8593
+ let endColumn = Number.NEGATIVE_INFINITY;
8594
+ for (const cell of sheet.cells) {
8595
+ startRow = Math.min(startRow, cell.row);
8596
+ startColumn = Math.min(startColumn, cell.column);
8597
+ endRow = Math.max(endRow, cell.row + (cell.rowSpan ?? 1) - 1);
8598
+ endColumn = Math.max(endColumn, cell.column + (cell.colSpan ?? 1) - 1);
8599
+ }
8600
+ return {
8601
+ startRow,
8602
+ startColumn,
8603
+ endRow,
8604
+ endColumn
8605
+ };
8606
+ }
8607
+ function resolveAxis(entries, start, end, defaultSizePt) {
8608
+ const sorted = [...entries].sort((a, b) => a.index - b.index);
8609
+ const resolved = [];
8610
+ let pointer = 0;
8611
+ let currentSizePt = defaultSizePt;
8612
+ let currentHidden = false;
8613
+ for (let index = start; index <= end; index++) {
8614
+ while (pointer < sorted.length && sorted[pointer].index <= index) {
8615
+ currentSizePt = sorted[pointer].sizePt;
8616
+ currentHidden = sorted[pointer].hidden ?? false;
8617
+ pointer++;
8618
+ }
8619
+ resolved.push({
8620
+ index,
8621
+ sizePt: currentHidden ? 0 : currentSizePt,
8622
+ hidden: currentHidden
8623
+ });
8624
+ }
8625
+ return resolved;
8626
+ }
8627
+ function computeHeaderGutter(printSettings, range, measurer) {
8628
+ if (!printSettings.headers) return {
8629
+ widthPt: 0,
8630
+ heightPt: 0
8631
+ };
8632
+ const widestRowLabel = String(range.endRow + 1);
8633
+ return {
8634
+ widthPt: measurer.widthOfTextAtSize(widestRowLabel, DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT) + 4,
8635
+ heightPt: measurer.lineHeightAtSize(DEFAULT_LAYOUT_FONT, HEADER_LABEL_SIZE_PT)
8636
+ };
8637
+ }
8638
+ function resolveScale(printSettings, availableWidthPt, availableHeightPt, totalContentWidthPt, totalContentHeightPt) {
8639
+ if (printSettings.scale !== void 0) return Math.max(printSettings.scale / 100, MINIMUM_SCALE);
8640
+ if (printSettings.fitToPages !== void 0) {
8641
+ const budgetWidthPt = availableWidthPt * printSettings.fitToPages.width;
8642
+ const budgetHeightPt = availableHeightPt * printSettings.fitToPages.height;
8643
+ const widthRatio = totalContentWidthPt > 0 ? budgetWidthPt / totalContentWidthPt : 1;
8644
+ const heightRatio = totalContentHeightPt > 0 ? budgetHeightPt / totalContentHeightPt : 1;
8645
+ return Math.max(Math.min(widthRatio, heightRatio, 1), MINIMUM_SCALE);
8646
+ }
8647
+ return 1;
8648
+ }
8649
+ function partitionIndices(indices, sizeOf, availablePt, manualBreaks) {
8650
+ const bands = [];
8651
+ let current = [];
8652
+ let currentSizePt = 0;
8653
+ for (const index of indices) {
8654
+ if (manualBreaks.has(index) && current.length > 0) {
8655
+ bands.push(current);
8656
+ current = [];
8657
+ currentSizePt = 0;
8658
+ }
8659
+ const sizePt = sizeOf(index);
8660
+ if (current.length > 0 && currentSizePt + sizePt > availablePt) {
8661
+ bands.push(current);
8662
+ current = [];
8663
+ currentSizePt = 0;
8664
+ }
8665
+ current.push(index);
8666
+ currentSizePt += sizePt;
8667
+ }
8668
+ if (current.length > 0) bands.push(current);
8669
+ return bands;
8670
+ }
8671
+ function cellStyledRuns(cell) {
8672
+ if (cell.runs !== void 0 && cell.runs.length > 0) return toStyledRuns(cell.runs.map((run) => run.sizePt === void 0 ? {
8673
+ ...run,
8674
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT
8675
+ } : run));
8676
+ return [{
8677
+ text: cell.displayText,
8678
+ font: DEFAULT_LAYOUT_FONT,
8679
+ sizePt: NOMINAL_CELL_TEXT_SIZE_PT,
8680
+ color: COLOR_BLACK
8681
+ }];
8682
+ }
8683
+ function isNumericLikeValue(kind) {
8684
+ return kind === "number" || kind === "percentage" || kind === "currency" || kind === "date" || kind === "time";
8685
+ }
8686
+ function defaultAlignmentForValue(kind) {
8687
+ if (isNumericLikeValue(kind)) return "right";
8688
+ if (kind === "boolean" || kind === "error") return "center";
8689
+ return "left";
8690
+ }
8691
+ function isCellVisuallyEmpty(cell) {
8692
+ return cell === void 0 || cell.value.kind === "empty" && cell.displayText.length === 0;
8693
+ }
8694
+ function truncateFragmentsToWidth(fragments, measurer, maxWidthPt) {
8695
+ const result = [];
8696
+ for (const fragment of fragments) {
8697
+ if (fragment.xOffsetPt >= maxWidthPt) break;
8698
+ const remainingWidthPt = maxWidthPt - fragment.xOffsetPt;
8699
+ if (measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt) <= remainingWidthPt) {
8700
+ result.push(fragment);
8701
+ continue;
8702
+ }
8703
+ const chars = Array.from(fragment.text);
8704
+ let width = 0;
8705
+ let fitCount = 0;
8706
+ for (const char of chars) {
8707
+ const charWidthPt = measurer.widthOfTextAtSize(char, fragment.font, fragment.sizePt);
8708
+ if (width + charWidthPt > remainingWidthPt) break;
8709
+ width += charWidthPt;
8710
+ fitCount++;
8711
+ }
8712
+ if (fitCount > 0) result.push({
8713
+ ...fragment,
8714
+ text: chars.slice(0, fitCount).join("")
8715
+ });
8716
+ break;
8717
+ }
8718
+ return result;
8719
+ }
8720
+ function buildPositionedAxis(repeatIndices, repeatSizePtOf, bandIndices, bandSizePtOf) {
8721
+ const indices = [...repeatIndices, ...bandIndices];
8722
+ const sizesPt = [...repeatIndices.map(repeatSizePtOf), ...bandIndices.map(bandSizePtOf)];
8723
+ const offsetsPt = [0];
8724
+ let running = 0;
8725
+ for (const size of sizesPt) {
8726
+ running += size;
8727
+ offsetsPt.push(running);
8728
+ }
8729
+ return {
8730
+ indices,
8731
+ sizesPt,
8732
+ offsetsPt,
8733
+ positionByIndex: new Map(indices.map((index, position) => [index, position]))
8734
+ };
8735
+ }
8736
+ function axisSpanSizePt(axis, startIndex, span) {
8737
+ const startPosition = axis.positionByIndex.get(startIndex);
8738
+ if (startPosition === void 0) return 0;
8739
+ return sumColumnWidthsPt(axis.sizesPt, startPosition, span);
8740
+ }
8741
+ function renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
8742
+ const columnPosition = columnAxis.positionByIndex.get(cell.column);
8743
+ const rowPosition = rowAxis.positionByIndex.get(cell.row);
8744
+ if (columnPosition === void 0 || rowPosition === void 0) return;
8745
+ const ownWidthPt = axisSpanSizePt(columnAxis, cell.column, cell.colSpan ?? 1);
8746
+ const heightPt = axisSpanSizePt(rowAxis, cell.row, cell.rowSpan ?? 1);
8747
+ const xLeftPt = gridLeftXPt + columnAxis.offsetsPt[columnPosition];
8748
+ const yTopDownPt = gridTopYDownPt + rowAxis.offsetsPt[rowPosition];
8749
+ const alignment = defaultAlignmentForValue(cell.value.kind);
8750
+ const numericLike = isNumericLikeValue(cell.value.kind);
8751
+ const styledRuns = cellStyledRuns(cell);
8752
+ const naturalLine = wrapRunsToWidth(styledRuns, measurer, Number.POSITIVE_INFINITY)[0];
8753
+ let availableWidthPt = Math.max(0, ownWidthPt - 4);
8754
+ let fragments = naturalLine.fragments;
8755
+ let lineWidthPt = naturalLine.widthPt;
8756
+ if (lineWidthPt > availableWidthPt) if (numericLike) {
8757
+ const overflowLine = wrapRunsToWidth([{
8758
+ text: NUMERIC_OVERFLOW_TEXT,
8759
+ font: styledRuns[0].font,
8760
+ sizePt: styledRuns[0].sizePt,
8761
+ color: styledRuns[0].color
8762
+ }], measurer, Number.POSITIVE_INFINITY)[0];
8763
+ fragments = overflowLine.fragments;
8764
+ lineWidthPt = overflowLine.widthPt;
8765
+ } else if (cell.value.kind === "string") {
8766
+ let spillColumn = cell.column + (cell.colSpan ?? 1);
8767
+ while (lineWidthPt > availableWidthPt) {
8768
+ const neighborPosition = columnAxis.positionByIndex.get(spillColumn);
8769
+ if (neighborPosition === void 0 || !isCellVisuallyEmpty(rowCells?.get(spillColumn))) break;
8770
+ availableWidthPt += columnAxis.sizesPt[neighborPosition];
8771
+ spillColumn++;
8772
+ }
8773
+ if (lineWidthPt > availableWidthPt) fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
8774
+ } else fragments = truncateFragmentsToWidth(fragments, measurer, availableWidthPt);
8775
+ const alignOffsetPt = alignmentOffsetPt(alignment, availableWidthPt, lineWidthPt);
8776
+ const textStartXPt = xLeftPt + CELL_TEXT_PADDING_PT + alignOffsetPt;
8777
+ const lineHeightPt = lineNaturalHeightPt(naturalLine, measurer, styledRuns[0]);
8778
+ const baselineYDownPt = yTopDownPt + Math.max(CELL_TEXT_PADDING_PT, heightPt - CELL_TEXT_PADDING_PT - lineHeightPt) + naturalLine.ascentPt;
8779
+ for (const fragment of fragments) {
8780
+ const textItem = {
8781
+ kind: "text",
8782
+ text: fragment.text,
8783
+ xPt: textStartXPt + fragment.xOffsetPt,
8784
+ yPt: pageHeightPt - baselineYDownPt,
8785
+ font: fragment.font,
8786
+ sizePt: fragment.sizePt,
8787
+ color: fragment.color,
8788
+ underline: fragment.underline,
8789
+ sourcePath: fragment.sourcePath
8790
+ };
8791
+ out.push(textItem);
8792
+ }
8793
+ }
8794
+ function renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageHeightPt, measurer, out) {
8795
+ const labelFont = DEFAULT_LAYOUT_FONT;
8796
+ const lineHeightPt = measurer.lineHeightAtSize(labelFont, HEADER_LABEL_SIZE_PT);
8797
+ const ascentPt = measurer.ascenderAtSize(labelFont, HEADER_LABEL_SIZE_PT);
8798
+ columnAxis.indices.forEach((columnIndex, position) => {
8799
+ const label = columnLetters(columnIndex);
8800
+ const widthPt = columnAxis.sizesPt[position];
8801
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
8802
+ const xPt = gridLeftXPt + columnAxis.offsetsPt[position] + alignmentOffsetPt("center", widthPt, labelWidthPt);
8803
+ const baselineYDownPt = gridTopYDownPt - gutter.heightPt + (gutter.heightPt - lineHeightPt) / 2 + ascentPt;
8804
+ out.push({
8805
+ kind: "text",
8806
+ text: label,
8807
+ xPt,
8808
+ yPt: pageHeightPt - baselineYDownPt,
8809
+ font: labelFont,
8810
+ sizePt: HEADER_LABEL_SIZE_PT,
8811
+ color: HEADER_LABEL_COLOR
8812
+ });
8813
+ });
8814
+ rowAxis.indices.forEach((rowIndex, position) => {
8815
+ const label = String(rowIndex + 1);
8816
+ const heightPt = rowAxis.sizesPt[position];
8817
+ const labelWidthPt = measurer.widthOfTextAtSize(label, labelFont, HEADER_LABEL_SIZE_PT);
8818
+ const xPt = gridLeftXPt - gutter.widthPt + Math.max(HEADER_LABEL_PADDING_PT, gutter.widthPt - HEADER_LABEL_PADDING_PT - labelWidthPt);
8819
+ const baselineYDownPt = gridTopYDownPt + rowAxis.offsetsPt[position] + Math.max(0, (heightPt - lineHeightPt) / 2) + ascentPt;
8820
+ out.push({
8821
+ kind: "text",
8822
+ text: label,
8823
+ xPt,
8824
+ yPt: pageHeightPt - baselineYDownPt,
8825
+ font: labelFont,
8826
+ sizePt: HEADER_LABEL_SIZE_PT,
8827
+ color: HEADER_LABEL_COLOR
8828
+ });
8829
+ });
8830
+ }
8831
+ function renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnOffsetsPt, rowOffsetsPt, pageHeightPt, out) {
8832
+ for (const offsetPt of columnOffsetsPt) {
8833
+ const xPt = gridLeftXPt + offsetPt;
8834
+ const line = {
8835
+ kind: "line",
8836
+ x1Pt: xPt,
8837
+ y1Pt: pageHeightPt - gridTopYDownPt,
8838
+ x2Pt: xPt,
8839
+ y2Pt: pageHeightPt - (gridTopYDownPt + gridHeightPt),
8840
+ color: GRIDLINE_COLOR,
8841
+ widthPt: GRIDLINE_WIDTH_PT
8842
+ };
8843
+ out.push(line);
8844
+ }
8845
+ for (const offsetPt of rowOffsetsPt) {
8846
+ const yDownPt = gridTopYDownPt + offsetPt;
8847
+ const line = {
8848
+ kind: "line",
8849
+ x1Pt: gridLeftXPt,
8850
+ y1Pt: pageHeightPt - yDownPt,
8851
+ x2Pt: gridLeftXPt + gridWidthPt,
8852
+ y2Pt: pageHeightPt - yDownPt,
8853
+ color: GRIDLINE_COLOR,
8854
+ widthPt: GRIDLINE_WIDTH_PT
8855
+ };
8856
+ out.push(line);
8857
+ }
8858
+ }
8859
+ function bandableIndices(start, end, repeat) {
8860
+ const indices = [];
8861
+ for (let i = start; i <= end; i++) {
8862
+ if (repeat !== void 0 && i >= repeat.start && i <= repeat.end) continue;
8863
+ indices.push(i);
8864
+ }
8865
+ return indices;
8866
+ }
8867
+ function rangeIndices(start, end) {
8868
+ const indices = [];
8869
+ for (let i = start; i <= end; i++) indices.push(i);
8870
+ return indices;
8871
+ }
8872
+ function convertSheetToPages(sheet, measurer, signal, out) {
8873
+ throwIfAborted(signal);
8874
+ const range = resolvePrintRange(sheet);
8875
+ if (range === void 0) return;
8876
+ const { printSettings } = sheet;
8877
+ const { pageSize, margins } = printSettings;
8878
+ const pageContentWidthPt = Math.max(0, pageSize.widthPt - margins.leftPt - margins.rightPt);
8879
+ const pageContentHeightPt = Math.max(0, pageSize.heightPt - margins.topPt - margins.bottomPt);
8880
+ const columnEntries = resolveAxis(sheet.columns.map((c) => ({
8881
+ index: c.index,
8882
+ sizePt: c.widthPt,
8883
+ hidden: c.hidden
8884
+ })), range.startColumn, range.endColumn, DEFAULT_COLUMN_WIDTH_PT);
8885
+ const rowEntries = resolveAxis(sheet.rows.map((r) => ({
8886
+ index: r.index,
8887
+ sizePt: r.heightPt,
8888
+ hidden: r.hidden
8889
+ })), range.startRow, range.endRow, DEFAULT_ROW_HEIGHT_PT);
8890
+ const columnSizeByIndex = new Map(columnEntries.map((e) => [e.index, e.sizePt]));
8891
+ const rowSizeByIndex = new Map(rowEntries.map((e) => [e.index, e.sizePt]));
8892
+ const hiddenColumnIndices = new Set(columnEntries.filter((e) => e.hidden).map((e) => e.index));
8893
+ const hiddenRowIndices = new Set(rowEntries.filter((e) => e.hidden).map((e) => e.index));
8894
+ const gutter = computeHeaderGutter(printSettings, range, measurer);
8895
+ const repeatColumns = printSettings.repeatColumns;
8896
+ const repeatRows = printSettings.repeatRows;
8897
+ const repeatColumnIndices = repeatColumns === void 0 ? [] : rangeIndices(repeatColumns.start, repeatColumns.end);
8898
+ const repeatRowIndices = repeatRows === void 0 ? [] : rangeIndices(repeatRows.start, repeatRows.end);
8899
+ const repeatColumnsWidthPt = repeatColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0);
8900
+ const repeatRowsHeightPt = repeatRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0);
8901
+ const bandableColumnIndices = bandableIndices(range.startColumn, range.endColumn, repeatColumns);
8902
+ const bandableRowIndices = bandableIndices(range.startRow, range.endRow, repeatRows);
8903
+ const availableWidthPt = Math.max(0, pageContentWidthPt - gutter.widthPt - repeatColumnsWidthPt);
8904
+ const availableHeightPt = Math.max(0, pageContentHeightPt - gutter.heightPt - repeatRowsHeightPt);
8905
+ const scale = resolveScale(printSettings, availableWidthPt, availableHeightPt, bandableColumnIndices.reduce((sum, i) => sum + (columnSizeByIndex.get(i) ?? 0), 0), bandableRowIndices.reduce((sum, i) => sum + (rowSizeByIndex.get(i) ?? 0), 0));
8906
+ const descaledAvailableWidthPt = availableWidthPt / scale;
8907
+ const descaledAvailableHeightPt = availableHeightPt / scale;
8908
+ const manualBreakColumns = new Set(printSettings.manualBreaks?.columns ?? []);
8909
+ const manualBreakRows = new Set(printSettings.manualBreaks?.rows ?? []);
8910
+ throwIfAborted(signal);
8911
+ const columnBands = partitionIndices(bandableColumnIndices, (i) => columnSizeByIndex.get(i) ?? 0, descaledAvailableWidthPt, manualBreakColumns);
8912
+ const rowBands = partitionIndices(bandableRowIndices, (i) => rowSizeByIndex.get(i) ?? 0, descaledAvailableHeightPt, manualBreakRows);
8913
+ const cellsByRow = /* @__PURE__ */ new Map();
8914
+ for (const cell of sheet.cells) {
8915
+ let row = cellsByRow.get(cell.row);
8916
+ if (row === void 0) {
8917
+ row = /* @__PURE__ */ new Map();
8918
+ cellsByRow.set(cell.row, row);
8919
+ }
8920
+ row.set(cell.column, cell);
8921
+ }
8922
+ const scaledSizeOf = (sizeByIndex) => (index) => (sizeByIndex.get(index) ?? 0) * scale;
8923
+ const unscaledSizeOf = (sizeByIndex) => (index) => sizeByIndex.get(index) ?? 0;
8924
+ const bandPairs = printSettings.pageOrder === "overThenDown" ? rowBands.flatMap((rowBand) => columnBands.map((columnBand) => ({
8925
+ columnBand,
8926
+ rowBand
8927
+ }))) : columnBands.flatMap((columnBand) => rowBands.map((rowBand) => ({
8928
+ columnBand,
8929
+ rowBand
8930
+ })));
8931
+ for (const { columnBand, rowBand } of bandPairs) {
8932
+ throwIfAborted(signal);
8933
+ const columnAxis = buildPositionedAxis(repeatColumnIndices, unscaledSizeOf(columnSizeByIndex), columnBand, scaledSizeOf(columnSizeByIndex));
8934
+ const rowAxis = buildPositionedAxis(repeatRowIndices, unscaledSizeOf(rowSizeByIndex), rowBand, scaledSizeOf(rowSizeByIndex));
8935
+ const gridLeftXPt = margins.leftPt + gutter.widthPt;
8936
+ const gridTopYDownPt = margins.topPt + gutter.heightPt;
8937
+ const gridWidthPt = columnAxis.offsetsPt[columnAxis.offsetsPt.length - 1];
8938
+ const gridHeightPt = rowAxis.offsetsPt[rowAxis.offsetsPt.length - 1];
8939
+ const items = [];
8940
+ if (printSettings.gridlines) renderGridlines(gridLeftXPt, gridTopYDownPt, gridWidthPt, gridHeightPt, columnAxis.offsetsPt, rowAxis.offsetsPt, pageSize.heightPt, items);
8941
+ if (printSettings.headers) renderHeaderLabels(gutter, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
8942
+ for (const rowIndex of rowAxis.indices) {
8943
+ const rowCells = cellsByRow.get(rowIndex);
8944
+ if (rowCells === void 0) continue;
8945
+ for (const [columnIndex, cell] of rowCells) {
8946
+ throwIfAborted(signal);
8947
+ if (!columnAxis.positionByIndex.has(columnIndex) || hiddenColumnIndices.has(columnIndex) || hiddenRowIndices.has(cell.row)) continue;
8948
+ renderCellText(cell, rowCells, columnAxis, rowAxis, gridLeftXPt, gridTopYDownPt, pageSize.heightPt, measurer, items);
8949
+ }
8950
+ }
8951
+ out.push({
8952
+ widthPt: pageSize.widthPt,
8953
+ heightPt: pageSize.heightPt,
8954
+ items
8955
+ });
8956
+ }
8957
+ }
8958
+ function convertSpreadsheetToLayout(doc, options) {
8959
+ const pages = [];
8960
+ for (const sheet of doc.sheets) convertSheetToPages(sheet, options.measurer, options.signal, pages);
8961
+ return {
8962
+ formatVersion: LAYOUT_FORMAT_VERSION$1,
8963
+ metadata: doc.metadata,
8964
+ pages,
8965
+ images: {}
8966
+ };
8967
+ }
8968
+ //#endregion
8545
8969
  //#region src/layout/reconstruct.ts
8546
8970
  const ZERO_MARGINS = {
8547
8971
  topPt: 0,
@@ -8910,6 +9334,17 @@ function odpToPdf(bytes, options) {
8910
9334
  onSubstitution: options?.onSubstitution
8911
9335
  });
8912
9336
  }
9337
+ function odsToPdf(bytes, options) {
9338
+ const content = readOdsContent(decodePackage$2(bytes));
9339
+ if (content.kind !== "spreadsheet") throw new Error("readOdsContent returned a non-spreadsheet ContentDocument");
9340
+ return writePdf(convertSpreadsheetToLayout(content, {
9341
+ measurer: createStandardFontMeasurer(),
9342
+ signal: options?.signal
9343
+ }), {
9344
+ signal: options?.signal,
9345
+ onSubstitution: options?.onSubstitution
9346
+ });
9347
+ }
8913
9348
  function pdfToDocx(bytes, options) {
8914
9349
  const content = reconstructWordprocessing(readPdf(bytes, {
8915
9350
  signal: options?.signal,
@@ -8975,6 +9410,10 @@ const SUPPORTED_CONVERSIONS = [
8975
9410
  source: "odp",
8976
9411
  target: "pdf"
8977
9412
  },
9413
+ {
9414
+ source: "ods",
9415
+ target: "pdf"
9416
+ },
8978
9417
  {
8979
9418
  source: "pdf",
8980
9419
  target: "docx"
@@ -9067,6 +9506,19 @@ function createLocalDocumentConverter() {
9067
9506
  diagnostics
9068
9507
  });
9069
9508
  }
9509
+ if (source.format === "ods" && targetFormat === "pdf") {
9510
+ const bytes = odsToPdf(source.bytes, {
9511
+ signal: options.signal,
9512
+ onSubstitution: (s, c) => diagnostics.push(substitutionDiagnostic(s, c))
9513
+ });
9514
+ return Promise.resolve({
9515
+ document: {
9516
+ format: "pdf",
9517
+ bytes
9518
+ },
9519
+ diagnostics
9520
+ });
9521
+ }
9070
9522
  if (source.format === "pdf" && targetFormat === "docx") {
9071
9523
  const bytes = pdfToDocx(source.bytes, {
9072
9524
  signal: options.signal,
@@ -9130,4 +9582,4 @@ function fixedClock(date) {
9130
9582
  return { now: () => date };
9131
9583
  }
9132
9584
  //#endregion
9133
- export { AttributeSchema, BinaryPartSchema, COLOR_BLACK, CONTENT_FORMAT_VERSION, CommentSchema, CompactPackageSchema, CompactPartSchema, CompactXmlNodeSchema, ContentBlockSchema, ContentDocumentSchema, ContentImageBlockSchema, ContentPageBreakSchema, ContentParagraphSchema, ContentRunSchema, ContentSectionSchema, ContentShapeSchema, ContentSlideSchema, ContentTableCellSchema, ContentTableRowSchema, ContentTableSchema, DEFAULT_LAYOUT_FONT, DefinedNameSchema, DocxBytesSchema, DocxEditor, DocxParagraph, DocxRun, DocxTable, DocxTableCell, DocxTableRow, LAYOUT_FORMAT_VERSION, NOOP_DIAGNOSTIC_SINK, OdgBytesSchema, OdpBytesSchema, OdpEditor, OdpShape, OdpSlide, OdsBytesSchema, OdtBytesSchema, OdtEditor, OdtList, OdtListItem, OdtParagraph, OdtRun, OdtTable, OdtTableCell, OdtTableRow, PAGE_SIZE_A4, PAGE_SIZE_LETTER, PackageSchema, PartSchema, PdfBytesSchema, PdfEncryptedError, PdfParseError, PptxBytesSchema, PptxEditor, PptxShape, PptxSlide, SLIDE_SIZE_STANDARD, SLIDE_SIZE_WIDESCREEN, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, attr, base64ToBytes, buildDocxPackage, buildOdpPackage, buildOdtPackage, buildPptxPackage, buildXml, bytesToBase64, childrenWithTag, compactCodec, compactPackageCodec, convertPresentationToLayout, convertWordprocessingToLayout, createDocx, createLocalDocumentConverter, createOdp, createOdt, createPptx, decodeCompactPackage, decodeEntities, decodePackage, docxPdfCodec, docxToPdf, elementsWithTag, encodeCompactPackage, encodePackage, fixedClock, flipY, fromCompact, isCompactXmlNode, isContentBlock, isXmlNode, odpPdfCodec, odpToPdf, odtPdfCodec, odtToPdf, openDocx, openOdp, openOdt, openPptx, packageCodec, parsePackage, parseXml, pdfCodec, pdfToDocx, pdfToOdp, pdfToOdt, pdfToPptx, pptxPdfCodec, pptxToPdf, readDocxContent, readOdpContent, readOdtContent, readPdf, readPptxContent, reconstructPresentation, reconstructWordprocessing, resolveRelationships, rgbHexToColor, rootElement, serializePackage, systemClock, textContent, throwIfAborted, toCompact, unzipPackage, walk, writePdf, xmlCodec, zipPackage };
9585
+ export { AttributeSchema, BinaryPartSchema, COLOR_BLACK, CONTENT_FORMAT_VERSION, CommentSchema, CompactPackageSchema, CompactPartSchema, CompactXmlNodeSchema, ContentBlockSchema, ContentCellValueSchema, ContentDocumentSchema, ContentImageBlockSchema, ContentPageBreakSchema, ContentParagraphSchema, ContentRunSchema, ContentSectionSchema, ContentShapeSchema, ContentSheetCellSchema, ContentSheetColumnSchema, ContentSheetPrintRangeSchema, ContentSheetPrintSettingsSchema, ContentSheetRepeatRangeSchema, ContentSheetRowSchema, ContentSheetSchema, ContentSlideSchema, ContentTableCellSchema, ContentTableRowSchema, ContentTableSchema, DEFAULT_LAYOUT_FONT, DefinedNameSchema, DocxBytesSchema, DocxEditor, DocxParagraph, DocxRun, DocxTable, DocxTableCell, DocxTableRow, LAYOUT_FORMAT_VERSION, NOOP_DIAGNOSTIC_SINK, OdgBytesSchema, OdpBytesSchema, OdpEditor, OdpShape, OdpSlide, OdsBytesSchema, OdtBytesSchema, OdtEditor, OdtList, OdtListItem, OdtParagraph, OdtRun, OdtTable, OdtTableCell, OdtTableRow, PAGE_SIZE_A4, PAGE_SIZE_LETTER, PackageSchema, PartSchema, PdfBytesSchema, PdfEncryptedError, PdfParseError, PptxBytesSchema, PptxEditor, PptxShape, PptxSlide, SLIDE_SIZE_STANDARD, SLIDE_SIZE_WIDESCREEN, XmlCdataSchema, XmlCommentSchema, XmlDeclarationSchema, XmlElementSchema, XmlNodeSchema, XmlPartSchema, XmlPiSchema, XmlTextSchema, attr, base64ToBytes, buildDocxPackage, buildOdpPackage, buildOdtPackage, buildPptxPackage, buildXml, bytesToBase64, childrenWithTag, compactCodec, compactPackageCodec, convertPresentationToLayout, convertSpreadsheetToLayout, convertWordprocessingToLayout, createDocx, createLocalDocumentConverter, createOdp, createOdt, createPptx, decodeCompactPackage, decodeEntities, decodePackage, docxPdfCodec, docxToPdf, elementsWithTag, encodeCompactPackage, encodePackage, fixedClock, flipY, fromCompact, isCompactXmlNode, isContentBlock, isXmlNode, odpPdfCodec, odpToPdf, odsToPdf, odtPdfCodec, odtToPdf, openDocx, openOdp, openOdt, openPptx, packageCodec, parsePackage, parseXml, pdfCodec, pdfToDocx, pdfToOdp, pdfToOdt, pdfToPptx, pptxPdfCodec, pptxToPdf, readDocxContent, readOdpContent, readOdsContent, readOdtContent, readPdf, readPptxContent, reconstructPresentation, reconstructWordprocessing, resolveRelationships, rgbHexToColor, rootElement, serializePackage, systemClock, textContent, throwIfAborted, toCompact, unzipPackage, walk, writePdf, xmlCodec, zipPackage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "documents.js",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
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": {