documents.js 1.102.2 → 2.0.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.
Files changed (40) hide show
  1. package/README.md +8 -5
  2. package/dist/convert/composition.cjs +15 -4
  3. package/dist/convert/composition.js +15 -4
  4. package/dist/convert/convert.cjs +6 -3
  5. package/dist/convert/convert.js +6 -3
  6. package/dist/convert/from-package.cjs +179 -2
  7. package/dist/convert/from-package.d.cts +3 -2
  8. package/dist/convert/from-package.d.ts +3 -2
  9. package/dist/convert/from-package.js +179 -3
  10. package/dist/index.cjs +1 -0
  11. package/dist/index.d.cts +3 -3
  12. package/dist/index.d.ts +3 -3
  13. package/dist/index.js +2 -2
  14. package/dist/layout/drawing.cjs +71 -9
  15. package/dist/layout/drawing.d.cts +8 -3
  16. package/dist/layout/drawing.d.ts +8 -3
  17. package/dist/layout/drawing.js +71 -10
  18. package/dist/layout/engine.cjs +55 -43
  19. package/dist/layout/engine.d.cts +2 -1
  20. package/dist/layout/engine.d.ts +2 -1
  21. package/dist/layout/engine.js +57 -45
  22. package/dist/layout/reconstruct.cjs +259 -104
  23. package/dist/layout/reconstruct.js +259 -104
  24. package/dist/layout/shared.cjs +47 -2
  25. package/dist/layout/shared.d.cts +15 -4
  26. package/dist/layout/shared.d.ts +15 -4
  27. package/dist/layout/shared.js +44 -4
  28. package/dist/layout/sheets.cjs +18 -13
  29. package/dist/layout/sheets.d.cts +4 -2
  30. package/dist/layout/sheets.d.ts +4 -2
  31. package/dist/layout/sheets.js +20 -16
  32. package/dist/layout/slides.cjs +35 -31
  33. package/dist/layout/slides.d.cts +3 -2
  34. package/dist/layout/slides.d.ts +3 -2
  35. package/dist/layout/slides.js +37 -33
  36. package/dist/layout/text-layout.cjs +2 -1
  37. package/dist/layout/text-layout.d.cts +14 -3
  38. package/dist/layout/text-layout.d.ts +14 -3
  39. package/dist/layout/text-layout.js +2 -1
  40. package/package.json +5 -5
@@ -2,8 +2,8 @@ import { flipY, rotatePointAboutCenter } from "../model/geometry.js";
2
2
  import { formulaOfBlock } from "../model/formula.js";
3
3
  import { layoutFormula } from "../mathml/layout.js";
4
4
  import { wrapRunsToWidth } from "./text-layout.js";
5
- import { alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, justifyLineGapsPt, lineNaturalHeightPt, registerImage, sumColumnWidthsPt } from "./shared.js";
6
- import { COLOR_BLACK, LAYOUT_FORMAT_VERSION } from "document-schema.js";
5
+ import { alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, registerImage, stampFragmentFrame, stampFrame, sumColumnWidthsPt } from "./shared.js";
6
+ import { COLOR_BLACK } from "document-schema.js";
7
7
  //#region src/layout/slides.ts
8
8
  function shapePlacement(flippedFrame, rotationDeg) {
9
9
  if (rotationDeg === void 0 || rotationDeg === 0) return {
@@ -20,7 +20,7 @@ function shapePlacement(flippedFrame, rotationDeg) {
20
20
  layoutRotationDeg: ccwDeg
21
21
  };
22
22
  }
23
- function layoutParagraph(paragraph, contentLeftXDown, contentWidthPt, startYDown, slideHeightPt, placement, fontScale, spacingScale, measurer, out) {
23
+ function layoutParagraph(paragraph, contentLeftXDown, contentWidthPt, startYDown, slideHeightPt, pageIndex, placement, fontScale, spacingScale, measurer, out) {
24
24
  let cursorYDown = startYDown + (paragraph.spacingBeforePt ?? 0);
25
25
  const effectiveRuns = effectiveStyledRuns(paragraph.runs, fontScale);
26
26
  const fallbackRun = effectiveRuns[0];
@@ -52,6 +52,7 @@ function layoutParagraph(paragraph, contentLeftXDown, contentWidthPt, startYDown
52
52
  sourcePath: fragment.sourcePath
53
53
  };
54
54
  out.push(textItem);
55
+ stampFragmentFrame(paragraph.runs, fragment, pageIndex, textItem, measurer, line);
55
56
  if (fragment.hyperlink !== void 0) {
56
57
  const fragmentWidthPt = measurer.widthOfTextAtSize(fragment.text, fragment.font, fragment.sizePt);
57
58
  const linkBottomLeft = placement.place({
@@ -75,7 +76,7 @@ function layoutParagraph(paragraph, contentLeftXDown, contentWidthPt, startYDown
75
76
  cursorYDown += paragraph.spacingAfterPt ?? 0;
76
77
  return cursorYDown;
77
78
  }
78
- function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideHeightPt, placement, measurer, out) {
79
+ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideHeightPt, pageIndex, placement, measurer, out) {
79
80
  let cursorYDown = startYDown;
80
81
  const gridWidthPt = table.columnWidthsPt.reduce((sum, w) => sum + w, 0);
81
82
  const scale = gridWidthPt > 0 ? contentWidthPt / gridWidthPt : 1;
@@ -86,25 +87,24 @@ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideH
86
87
  for (const cell of row.cells) {
87
88
  const span = cell.colSpan ?? 1;
88
89
  const cellWidthPt = sumColumnWidthsPt(table.columnWidthsPt, colIndex, span) * scale;
89
- if (cell.background !== void 0 && placement.layoutRotationDeg === void 0) {
90
- const cellFrame = flipY({
91
- xPt: cellXDown,
92
- yPt: cursorYDown,
93
- widthPt: cellWidthPt,
94
- heightPt: rowHeightPt
95
- }, slideHeightPt);
96
- out.push({
97
- kind: "rect",
98
- xPt: cellFrame.xPt,
99
- yPt: cellFrame.yPt,
100
- widthPt: cellFrame.widthPt,
101
- heightPt: cellFrame.heightPt,
102
- fill: cell.background,
103
- sourcePath: table.sourcePath
104
- });
105
- }
90
+ const cellFrame = flipY({
91
+ xPt: cellXDown,
92
+ yPt: cursorYDown,
93
+ widthPt: cellWidthPt,
94
+ heightPt: rowHeightPt
95
+ }, slideHeightPt);
96
+ if (placement.layoutRotationDeg === void 0) stampFrame(cell, pageIndex, cellFrame);
97
+ if (cell.background !== void 0 && placement.layoutRotationDeg === void 0) out.push({
98
+ kind: "rect",
99
+ xPt: cellFrame.xPt,
100
+ yPt: cellFrame.yPt,
101
+ widthPt: cellFrame.widthPt,
102
+ heightPt: cellFrame.heightPt,
103
+ fill: cell.background,
104
+ sourcePath: table.sourcePath
105
+ });
106
106
  let cellCursorYDown = cursorYDown;
107
- for (const block of cell.blocks) if (block.kind === "paragraph") cellCursorYDown = layoutParagraph(block, cellXDown, cellWidthPt, cellCursorYDown, slideHeightPt, placement, 1, 1, measurer, out);
107
+ for (const block of cell.blocks) if (block.kind === "paragraph") cellCursorYDown = layoutParagraph(block, cellXDown, cellWidthPt, cellCursorYDown, slideHeightPt, pageIndex, placement, 1, 1, measurer, out);
108
108
  cellXDown += cellWidthPt;
109
109
  colIndex += span;
110
110
  }
@@ -128,16 +128,18 @@ function layoutShapeFormula(block, flippedFrame, formulaContext) {
128
128
  yPt: flippedFrame.yPt,
129
129
  box
130
130
  });
131
+ stampFrame(block, formulaContext.pageIndex, flippedFrame);
131
132
  }
132
- function convertShape(shape, slideHeightPt, measurer, images, out, formulaContext) {
133
+ function convertShape(shape, slideHeightPt, pageIndex, measurer, images, out, formulaContext) {
133
134
  const flippedFrame = flipY(shape.frame, slideHeightPt);
135
+ stampFrame(shape, pageIndex, flippedFrame);
134
136
  const placement = shapePlacement(flippedFrame, shape.rotationDeg);
135
137
  const contentLeftXDown = shape.frame.xPt + shape.insetLeftPt;
136
138
  const contentWidthPt = Math.max(0, shape.frame.widthPt - shape.insetLeftPt - shape.insetRightPt);
137
139
  const fontScale = shape.fontScale ?? 1;
138
140
  const spacingScale = 1 - (shape.lineSpacingReduction ?? 0);
139
141
  let cursorYDown = shape.frame.yPt + shape.insetTopPt;
140
- for (const block of shape.blocks) if (block.kind === "paragraph") cursorYDown = layoutParagraph(block, contentLeftXDown, contentWidthPt, cursorYDown, slideHeightPt, placement, fontScale, spacingScale, measurer, out);
142
+ for (const block of shape.blocks) if (block.kind === "paragraph") cursorYDown = layoutParagraph(block, contentLeftXDown, contentWidthPt, cursorYDown, slideHeightPt, pageIndex, placement, fontScale, spacingScale, measurer, out);
141
143
  else if (block.kind === "image") {
142
144
  const imageId = registerImage(block, images);
143
145
  const placed = placement.place({
@@ -155,7 +157,13 @@ function convertShape(shape, slideHeightPt, measurer, images, out, formulaContex
155
157
  sourcePath: block.sourcePath
156
158
  };
157
159
  out.push(imageItem);
158
- } else if (block.kind === "table") cursorYDown = layoutTable(block, contentLeftXDown, contentWidthPt, cursorYDown, slideHeightPt, placement, measurer, out);
160
+ stampFrame(block, pageIndex, {
161
+ xPt: placed.x,
162
+ yPt: placed.y,
163
+ widthPt: imageItem.widthPt,
164
+ heightPt: imageItem.heightPt
165
+ });
166
+ } else if (block.kind === "table") cursorYDown = layoutTable(block, contentLeftXDown, contentWidthPt, cursorYDown, slideHeightPt, pageIndex, placement, measurer, out);
159
167
  else if (block.kind === "embeddedObject" && block.objectKind === "formula" && formulaContext !== void 0) layoutShapeFormula(block, flippedFrame, formulaContext);
160
168
  }
161
169
  function convertSlide(slide, slideIndex, measurer, images, positioned, mathMetricsAt) {
@@ -165,7 +173,7 @@ function convertSlide(slide, slideIndex, measurer, images, positioned, mathMetri
165
173
  positioned,
166
174
  mathMetricsAt
167
175
  };
168
- for (const shape of slide.shapes) convertShape(shape, slide.size.heightPt, measurer, images, items, formulaContext);
176
+ for (const shape of slide.shapes) convertShape(shape, slide.size.heightPt, slideIndex, measurer, images, items, formulaContext);
169
177
  return {
170
178
  widthPt: slide.size.widthPt,
171
179
  heightPt: slide.size.heightPt,
@@ -178,13 +186,9 @@ function convertPresentationToLayout(doc, options) {
178
186
  const formulas = [];
179
187
  const pages = doc.slides.map((slide, slideIndex) => convertSlide(slide, slideIndex, options.measurer, images, formulas, options.mathMetricsAt));
180
188
  return {
181
- document: {
182
- formatVersion: LAYOUT_FORMAT_VERSION,
183
- metadata: doc.metadata,
184
- pages,
185
- images
186
- },
187
- formulas
189
+ document: layoutDocumentOf(doc.metadata, pages, images),
190
+ formulas,
191
+ pages: packagePagesOf(pages)
188
192
  };
189
193
  }
190
194
  //#endregion
@@ -38,7 +38,8 @@ function atomizeRuns(runs, measurer) {
38
38
  color: run.color,
39
39
  underline: run.underline,
40
40
  hyperlink: run.hyperlink,
41
- sourcePath: run.sourcePath
41
+ sourcePath: run.sourcePath,
42
+ runIndex: run.runIndex
42
43
  });
43
44
  wordWidth += measurer.widthOfTextAtSize(token, run.font, run.sizePt);
44
45
  }
@@ -1,5 +1,16 @@
1
- import { StyledRun, TextMeasurer, WrapOptions, WrappedLine } from "document-schema.js";
1
+ import { StyledFragment, StyledRun, TextMeasurer, WrapOptions, WrappedLine } from "document-schema.js";
2
2
  //#region src/layout/text-layout.d.ts
3
- declare function wrapRunsToWidth(runs: readonly StyledRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): WrappedLine[];
3
+ interface SourcedRun extends StyledRun {
4
+ readonly runIndex?: number;
5
+ }
6
+ interface SourcedFragment extends StyledFragment {
7
+ readonly runIndex?: number;
8
+ }
9
+ interface SourcedWrappedLine extends Omit<WrappedLine, 'fragments'> {
10
+ readonly fragments: readonly (SourcedFragment & {
11
+ readonly xOffsetPt: number;
12
+ })[];
13
+ }
14
+ declare function wrapRunsToWidth(runs: readonly SourcedRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): SourcedWrappedLine[];
4
15
  //#endregion
5
- export { wrapRunsToWidth };
16
+ export { SourcedFragment, SourcedRun, SourcedWrappedLine, wrapRunsToWidth };
@@ -1,5 +1,16 @@
1
- import { StyledRun, TextMeasurer, WrapOptions, WrappedLine } from "document-schema.js";
1
+ import { StyledFragment, StyledRun, TextMeasurer, WrapOptions, WrappedLine } from "document-schema.js";
2
2
  //#region src/layout/text-layout.d.ts
3
- declare function wrapRunsToWidth(runs: readonly StyledRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): WrappedLine[];
3
+ interface SourcedRun extends StyledRun {
4
+ readonly runIndex?: number;
5
+ }
6
+ interface SourcedFragment extends StyledFragment {
7
+ readonly runIndex?: number;
8
+ }
9
+ interface SourcedWrappedLine extends Omit<WrappedLine, 'fragments'> {
10
+ readonly fragments: readonly (SourcedFragment & {
11
+ readonly xOffsetPt: number;
12
+ })[];
13
+ }
14
+ declare function wrapRunsToWidth(runs: readonly SourcedRun[], measurer: TextMeasurer, maxWidthPt: number, options?: WrapOptions): SourcedWrappedLine[];
4
15
  //#endregion
5
- export { wrapRunsToWidth };
16
+ export { SourcedFragment, SourcedRun, SourcedWrappedLine, wrapRunsToWidth };
@@ -37,7 +37,8 @@ function atomizeRuns(runs, measurer) {
37
37
  color: run.color,
38
38
  underline: run.underline,
39
39
  hyperlink: run.hyperlink,
40
- sourcePath: run.sourcePath
40
+ sourcePath: run.sourcePath,
41
+ runIndex: run.runIndex
41
42
  });
42
43
  wordWidth += measurer.widthOfTextAtSize(token, run.font, run.sizePt);
43
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "documents.js",
3
- "version": "1.102.2",
3
+ "version": "2.0.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": {
@@ -84,11 +84,11 @@
84
84
  "packageManager": "pnpm@11.6.0",
85
85
  "dependencies": {
86
86
  "byte-codec": "^1.1.9",
87
- "document-schema.js": "^2.7.17",
87
+ "document-schema.js": "^3.2.0",
88
88
  "fflate": "^0.8.3",
89
- "markdown-codec": "^1.4.2",
90
- "odf.js": "^2.7.23",
91
- "ooxml.js": "^2.11.31",
89
+ "markdown-codec": "^2.0.0",
90
+ "odf.js": "^3.0.1",
91
+ "ooxml.js": "^2.16.0",
92
92
  "pdf-codec": "^2.2.35",
93
93
  "zod": "^4.4.3"
94
94
  },