odf.js 1.13.1 → 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 +15 -3
  2. package/dist/index.cjs +8 -0
  3. package/dist/index.d.cts +6 -3
  4. package/dist/index.d.ts +6 -3
  5. package/dist/index.js +6 -3
  6. package/dist/ns.cjs +2 -1
  7. package/dist/ns.d.cts +1 -0
  8. package/dist/ns.d.ts +1 -0
  9. package/dist/ns.js +2 -1
  10. package/dist/typed/draw/shapes.cjs +71 -27
  11. package/dist/typed/draw/shapes.d.cts +4 -1
  12. package/dist/typed/draw/shapes.d.ts +4 -1
  13. package/dist/typed/draw/shapes.js +71 -27
  14. package/dist/typed/formula/read.cjs +14 -0
  15. package/dist/typed/formula/read.d.cts +3 -2
  16. package/dist/typed/formula/read.d.ts +3 -2
  17. package/dist/typed/formula/read.js +14 -1
  18. package/dist/typed/odb/form.cjs +85 -0
  19. package/dist/typed/odb/form.d.cts +31 -0
  20. package/dist/typed/odb/form.d.ts +31 -0
  21. package/dist/typed/odb/form.js +84 -0
  22. package/dist/typed/odb/read.cjs +60 -23
  23. package/dist/typed/odb/read.d.cts +15 -4
  24. package/dist/typed/odb/read.d.ts +15 -4
  25. package/dist/typed/odb/read.js +60 -24
  26. package/dist/typed/odb/report.cjs +161 -0
  27. package/dist/typed/odb/report.d.cts +48 -0
  28. package/dist/typed/odb/report.d.ts +48 -0
  29. package/dist/typed/odb/report.js +160 -0
  30. package/dist/typed/odb/subdocument.cjs +16 -0
  31. package/dist/typed/odb/subdocument.d.cts +8 -0
  32. package/dist/typed/odb/subdocument.d.ts +8 -0
  33. package/dist/typed/odb/subdocument.js +15 -0
  34. package/dist/typed/ods/read.cjs +9 -1
  35. package/dist/typed/ods/read.js +10 -2
  36. package/dist/typed/shared/table.cjs +94 -7
  37. package/dist/typed/shared/table.d.cts +9 -2
  38. package/dist/typed/shared/table.d.ts +9 -2
  39. package/dist/typed/shared/table.js +94 -8
  40. package/package.json +2 -2
@@ -6,6 +6,7 @@ const require_typed_shared_geometry = require("../shared/geometry.cjs");
6
6
  const require_typed_shared_cascade = require("../shared/cascade.cjs");
7
7
  const require_typed_shared_metadata = require("../shared/metadata.cjs");
8
8
  const require_typed_shared_paragraph = require("../shared/paragraph.cjs");
9
+ const require_typed_shared_table = require("../shared/table.cjs");
9
10
  const require_typed_shared_masterpage = require("../shared/masterpage.cjs");
10
11
  let document_schema_js = require("document-schema.js");
11
12
  //#region src/typed/ods/read.ts
@@ -199,6 +200,13 @@ function readTable(tableElement, pkg) {
199
200
  if (runs.length > 0) cell.runs = runs;
200
201
  if (colSpan !== void 0) cell.colSpan = colSpan;
201
202
  if (rowSpan !== void 0) cell.rowSpan = rowSpan;
203
+ const cellStyleName = require_xml_query.attrValue(child, "table:style-name");
204
+ const { elements: cellStyleChain } = require_typed_shared_cascade.resolveStyleElementChain(cellStyleName, "table-cell", pkg);
205
+ const decoration = require_typed_shared_table.readCellStyleDecoration(cellStyleChain);
206
+ if (decoration.background !== void 0) cell.background = decoration.background;
207
+ if (decoration.borders !== void 0) cell.borders = decoration.borders;
208
+ if (decoration.alignment !== void 0) cell.alignment = decoration.alignment;
209
+ if (decoration.verticalAlignment !== void 0) cell.verticalAlignment = decoration.verticalAlignment;
202
210
  cells.push(cell);
203
211
  }
204
212
  }
@@ -278,7 +286,7 @@ function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualB
278
286
  pageOrder
279
287
  };
280
288
  if (printRange !== void 0) settings.printRange = printRange;
281
- if (scale !== void 0) settings.scale = scale;
289
+ if (scale !== void 0) settings.scalePercent = scale;
282
290
  if (fitToPages !== void 0) settings.fitToPages = fitToPages;
283
291
  if (repeatRows !== void 0) settings.repeatRows = repeatRows;
284
292
  if (repeatColumns !== void 0) settings.repeatColumns = repeatColumns;
@@ -2,9 +2,10 @@ import { parseOdfLength } from "../shared/units.js";
2
2
  import { attrValue, childrenWithTag, findChildElement, rootElement } from "../../xml/query.js";
3
3
  import { TableCursor, parseCellReference } from "../shared/a1.js";
4
4
  import { parseMargins, parsePageSize } from "../shared/geometry.js";
5
- import { findStyleElement } from "../shared/cascade.js";
5
+ import { findStyleElement, resolveStyleElementChain } from "../shared/cascade.js";
6
6
  import { readOdfMetadata } from "../shared/metadata.js";
7
7
  import { readOdfParagraph } from "../shared/paragraph.js";
8
+ import { readCellStyleDecoration } from "../shared/table.js";
8
9
  import { resolvePageLayoutProperties } from "../shared/masterpage.js";
9
10
  import { PAGE_SIZE_A4 } from "document-schema.js";
10
11
  //#region src/typed/ods/read.ts
@@ -198,6 +199,13 @@ function readTable(tableElement, pkg) {
198
199
  if (runs.length > 0) cell.runs = runs;
199
200
  if (colSpan !== void 0) cell.colSpan = colSpan;
200
201
  if (rowSpan !== void 0) cell.rowSpan = rowSpan;
202
+ const cellStyleName = attrValue(child, "table:style-name");
203
+ const { elements: cellStyleChain } = resolveStyleElementChain(cellStyleName, "table-cell", pkg);
204
+ const decoration = readCellStyleDecoration(cellStyleChain);
205
+ if (decoration.background !== void 0) cell.background = decoration.background;
206
+ if (decoration.borders !== void 0) cell.borders = decoration.borders;
207
+ if (decoration.alignment !== void 0) cell.alignment = decoration.alignment;
208
+ if (decoration.verticalAlignment !== void 0) cell.verticalAlignment = decoration.verticalAlignment;
201
209
  cells.push(cell);
202
210
  }
203
211
  }
@@ -277,7 +285,7 @@ function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualB
277
285
  pageOrder
278
286
  };
279
287
  if (printRange !== void 0) settings.printRange = printRange;
280
- if (scale !== void 0) settings.scale = scale;
288
+ if (scale !== void 0) settings.scalePercent = scale;
281
289
  if (fitToPages !== void 0) settings.fitToPages = fitToPages;
282
290
  if (repeatRows !== void 0) settings.repeatRows = repeatRows;
283
291
  if (repeatColumns !== void 0) settings.repeatColumns = repeatColumns;
@@ -25,22 +25,108 @@ function resolveRowHeightPt(rowElement, pkg) {
25
25
  const heightValue = props === void 0 ? void 0 : require_xml_query.attrValue(props, "style:row-height");
26
26
  return heightValue === void 0 ? void 0 : require_typed_shared_units.parseOdfLength(heightValue);
27
27
  }
28
- function readTableCellBackground(cellElement, pkg) {
29
- const styleName = require_xml_query.attrValue(cellElement, "table:style-name");
30
- const styleElement = styleName === void 0 ? void 0 : require_typed_shared_cascade.findStyleElement(styleName, "table-cell", pkg);
31
- const props = styleElement === void 0 ? void 0 : require_xml_query.childrenWithTag(styleElement, "style:table-cell-properties")[0];
32
- const value = props === void 0 ? void 0 : require_xml_query.attrValue(props, "fo:background-color");
33
- return value === void 0 ? void 0 : require_typed_shared_color.parseOdfColor(value);
28
+ const BORDER_STYLE_MAP = {
29
+ solid: "solid",
30
+ dashed: "dashed",
31
+ dotted: "dotted",
32
+ double: "double"
33
+ };
34
+ const BORDER_EDGE_KEYS = [
35
+ "left",
36
+ "right",
37
+ "top",
38
+ "bottom"
39
+ ];
40
+ const BORDER_EDGE_ATTRS = {
41
+ left: "fo:border-left",
42
+ right: "fo:border-right",
43
+ top: "fo:border-top",
44
+ bottom: "fo:border-bottom"
45
+ };
46
+ function isVerticalAlign(value) {
47
+ return value === "top" || value === "middle" || value === "bottom";
48
+ }
49
+ function parseBorderEdge(value) {
50
+ const tokens = value.trim().split(/\s+/);
51
+ if (tokens.length !== 3) return;
52
+ const [widthToken, styleToken, colorToken] = tokens;
53
+ if (widthToken === void 0 || styleToken === void 0 || colorToken === void 0) return;
54
+ if (styleToken === "none" || styleToken === "hidden") return { none: true };
55
+ const widthPt = require_typed_shared_units.parseOdfLength(widthToken);
56
+ const color = require_typed_shared_color.parseOdfColor(colorToken);
57
+ if (widthPt === void 0 || widthPt <= 0 || color === void 0) return;
58
+ const style = BORDER_STYLE_MAP[styleToken];
59
+ return { border: style === void 0 ? {
60
+ color,
61
+ widthPt
62
+ } : {
63
+ color,
64
+ widthPt,
65
+ style
66
+ } };
67
+ }
68
+ function applyBorderEdgeUpdates(accumulated, cellProperties) {
69
+ const shorthandValue = require_xml_query.attrValue(cellProperties, "fo:border");
70
+ const shorthandUpdate = shorthandValue === void 0 ? void 0 : parseBorderEdge(shorthandValue);
71
+ if (shorthandUpdate !== void 0) for (const edge of BORDER_EDGE_KEYS) applyBorderEdgeUpdate(accumulated, edge, shorthandUpdate);
72
+ for (const edge of BORDER_EDGE_KEYS) {
73
+ const rawValue = require_xml_query.attrValue(cellProperties, BORDER_EDGE_ATTRS[edge]);
74
+ const update = rawValue === void 0 ? void 0 : parseBorderEdge(rawValue);
75
+ if (update !== void 0) applyBorderEdgeUpdate(accumulated, edge, update);
76
+ }
77
+ }
78
+ function applyBorderEdgeUpdate(accumulated, edge, update) {
79
+ if ("none" in update) delete accumulated[edge];
80
+ else accumulated[edge] = update.border;
81
+ }
82
+ function bordersFromAccumulated(accumulated) {
83
+ if (accumulated.left === void 0 && accumulated.right === void 0 && accumulated.top === void 0 && accumulated.bottom === void 0) return;
84
+ const borders = {};
85
+ if (accumulated.left !== void 0) borders.left = accumulated.left;
86
+ if (accumulated.right !== void 0) borders.right = accumulated.right;
87
+ if (accumulated.top !== void 0) borders.top = accumulated.top;
88
+ if (accumulated.bottom !== void 0) borders.bottom = accumulated.bottom;
89
+ return borders;
90
+ }
91
+ function readCellStyleDecoration(elements) {
92
+ let background;
93
+ let alignment;
94
+ let verticalAlignment;
95
+ const borderAccumulator = {};
96
+ for (const styleElement of elements) {
97
+ const cellProperties = require_xml_query.childrenWithTag(styleElement, "style:table-cell-properties")[0];
98
+ if (cellProperties !== void 0) {
99
+ const backgroundValue = require_xml_query.attrValue(cellProperties, "fo:background-color");
100
+ const parsedBackground = backgroundValue === void 0 ? void 0 : require_typed_shared_color.parseOdfColor(backgroundValue);
101
+ if (parsedBackground !== void 0) background = parsedBackground;
102
+ applyBorderEdgeUpdates(borderAccumulator, cellProperties);
103
+ const verticalAlignValue = require_xml_query.attrValue(cellProperties, "style:vertical-align");
104
+ if (verticalAlignValue !== void 0 && isVerticalAlign(verticalAlignValue)) verticalAlignment = verticalAlignValue;
105
+ }
106
+ const paragraphProperties = require_xml_query.childrenWithTag(styleElement, "style:paragraph-properties")[0];
107
+ const textAlignValue = paragraphProperties === void 0 ? void 0 : require_xml_query.attrValue(paragraphProperties, "fo:text-align");
108
+ if (textAlignValue === "left" || textAlignValue === "center" || textAlignValue === "right" || textAlignValue === "justify") alignment = textAlignValue;
109
+ }
110
+ return {
111
+ background,
112
+ borders: bordersFromAccumulated(borderAccumulator),
113
+ alignment,
114
+ verticalAlignment
115
+ };
34
116
  }
35
117
  function readTableCell(cellElement, pkg) {
36
118
  const blocks = require_xml_query.childrenWithTag(cellElement, "text:p").map((p) => require_typed_shared_paragraph.readOdfParagraph(p, pkg));
37
119
  const colSpanRaw = require_xml_query.attrValue(cellElement, "table:number-columns-spanned");
38
120
  const rowSpanRaw = require_xml_query.attrValue(cellElement, "table:number-rows-spanned");
121
+ const styleName = require_xml_query.attrValue(cellElement, "table:style-name");
122
+ const styleElement = styleName === void 0 ? void 0 : require_typed_shared_cascade.findStyleElement(styleName, "table-cell", pkg);
123
+ const { background, borders } = readCellStyleDecoration(styleElement === void 0 ? [] : [styleElement]);
39
124
  return {
40
125
  blocks,
41
126
  colSpan: colSpanRaw === void 0 ? void 0 : Number.parseInt(colSpanRaw, 10),
42
127
  rowSpan: rowSpanRaw === void 0 ? void 0 : Number.parseInt(rowSpanRaw, 10),
43
- background: readTableCellBackground(cellElement, pkg)
128
+ background,
129
+ borders
44
130
  };
45
131
  }
46
132
  function readTableRow(rowElement, pkg) {
@@ -81,4 +167,5 @@ function readOdfTable(tableElement, pkg) {
81
167
  };
82
168
  }
83
169
  //#endregion
170
+ exports.readCellStyleDecoration = readCellStyleDecoration;
84
171
  exports.readOdfTable = readOdfTable;
@@ -1,7 +1,14 @@
1
1
  import { l as XmlElement } from "../../node-CkBWRjNR.cjs";
2
2
  import { Package } from "../../model/package.cjs";
3
- import { ContentTable } from "document-schema.js";
3
+ import { Alignment, Color, ContentCellBorders, ContentTable } from "document-schema.js";
4
4
  //#region src/typed/shared/table.d.ts
5
+ interface CellStyleDecoration {
6
+ background?: Color;
7
+ borders?: ContentCellBorders;
8
+ alignment?: Alignment;
9
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
10
+ }
11
+ declare function readCellStyleDecoration(elements: readonly XmlElement[]): CellStyleDecoration;
5
12
  declare function readOdfTable(tableElement: XmlElement, pkg: Package): ContentTable;
6
13
  //#endregion
7
- export { readOdfTable };
14
+ export { CellStyleDecoration, readCellStyleDecoration, readOdfTable };
@@ -1,7 +1,14 @@
1
1
  import { l as XmlElement } from "../../node-CkBWRjNR.js";
2
2
  import { Package } from "../../model/package.js";
3
- import { ContentTable } from "document-schema.js";
3
+ import { Alignment, Color, ContentCellBorders, ContentTable } from "document-schema.js";
4
4
  //#region src/typed/shared/table.d.ts
5
+ interface CellStyleDecoration {
6
+ background?: Color;
7
+ borders?: ContentCellBorders;
8
+ alignment?: Alignment;
9
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
10
+ }
11
+ declare function readCellStyleDecoration(elements: readonly XmlElement[]): CellStyleDecoration;
5
12
  declare function readOdfTable(tableElement: XmlElement, pkg: Package): ContentTable;
6
13
  //#endregion
7
- export { readOdfTable };
14
+ export { CellStyleDecoration, readCellStyleDecoration, readOdfTable };
@@ -24,22 +24,108 @@ function resolveRowHeightPt(rowElement, pkg) {
24
24
  const heightValue = props === void 0 ? void 0 : attrValue(props, "style:row-height");
25
25
  return heightValue === void 0 ? void 0 : parseOdfLength(heightValue);
26
26
  }
27
- function readTableCellBackground(cellElement, pkg) {
28
- const styleName = attrValue(cellElement, "table:style-name");
29
- const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-cell", pkg);
30
- const props = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-cell-properties")[0];
31
- const value = props === void 0 ? void 0 : attrValue(props, "fo:background-color");
32
- return value === void 0 ? void 0 : parseOdfColor(value);
27
+ const BORDER_STYLE_MAP = {
28
+ solid: "solid",
29
+ dashed: "dashed",
30
+ dotted: "dotted",
31
+ double: "double"
32
+ };
33
+ const BORDER_EDGE_KEYS = [
34
+ "left",
35
+ "right",
36
+ "top",
37
+ "bottom"
38
+ ];
39
+ const BORDER_EDGE_ATTRS = {
40
+ left: "fo:border-left",
41
+ right: "fo:border-right",
42
+ top: "fo:border-top",
43
+ bottom: "fo:border-bottom"
44
+ };
45
+ function isVerticalAlign(value) {
46
+ return value === "top" || value === "middle" || value === "bottom";
47
+ }
48
+ function parseBorderEdge(value) {
49
+ const tokens = value.trim().split(/\s+/);
50
+ if (tokens.length !== 3) return;
51
+ const [widthToken, styleToken, colorToken] = tokens;
52
+ if (widthToken === void 0 || styleToken === void 0 || colorToken === void 0) return;
53
+ if (styleToken === "none" || styleToken === "hidden") return { none: true };
54
+ const widthPt = parseOdfLength(widthToken);
55
+ const color = parseOdfColor(colorToken);
56
+ if (widthPt === void 0 || widthPt <= 0 || color === void 0) return;
57
+ const style = BORDER_STYLE_MAP[styleToken];
58
+ return { border: style === void 0 ? {
59
+ color,
60
+ widthPt
61
+ } : {
62
+ color,
63
+ widthPt,
64
+ style
65
+ } };
66
+ }
67
+ function applyBorderEdgeUpdates(accumulated, cellProperties) {
68
+ const shorthandValue = attrValue(cellProperties, "fo:border");
69
+ const shorthandUpdate = shorthandValue === void 0 ? void 0 : parseBorderEdge(shorthandValue);
70
+ if (shorthandUpdate !== void 0) for (const edge of BORDER_EDGE_KEYS) applyBorderEdgeUpdate(accumulated, edge, shorthandUpdate);
71
+ for (const edge of BORDER_EDGE_KEYS) {
72
+ const rawValue = attrValue(cellProperties, BORDER_EDGE_ATTRS[edge]);
73
+ const update = rawValue === void 0 ? void 0 : parseBorderEdge(rawValue);
74
+ if (update !== void 0) applyBorderEdgeUpdate(accumulated, edge, update);
75
+ }
76
+ }
77
+ function applyBorderEdgeUpdate(accumulated, edge, update) {
78
+ if ("none" in update) delete accumulated[edge];
79
+ else accumulated[edge] = update.border;
80
+ }
81
+ function bordersFromAccumulated(accumulated) {
82
+ if (accumulated.left === void 0 && accumulated.right === void 0 && accumulated.top === void 0 && accumulated.bottom === void 0) return;
83
+ const borders = {};
84
+ if (accumulated.left !== void 0) borders.left = accumulated.left;
85
+ if (accumulated.right !== void 0) borders.right = accumulated.right;
86
+ if (accumulated.top !== void 0) borders.top = accumulated.top;
87
+ if (accumulated.bottom !== void 0) borders.bottom = accumulated.bottom;
88
+ return borders;
89
+ }
90
+ function readCellStyleDecoration(elements) {
91
+ let background;
92
+ let alignment;
93
+ let verticalAlignment;
94
+ const borderAccumulator = {};
95
+ for (const styleElement of elements) {
96
+ const cellProperties = childrenWithTag(styleElement, "style:table-cell-properties")[0];
97
+ if (cellProperties !== void 0) {
98
+ const backgroundValue = attrValue(cellProperties, "fo:background-color");
99
+ const parsedBackground = backgroundValue === void 0 ? void 0 : parseOdfColor(backgroundValue);
100
+ if (parsedBackground !== void 0) background = parsedBackground;
101
+ applyBorderEdgeUpdates(borderAccumulator, cellProperties);
102
+ const verticalAlignValue = attrValue(cellProperties, "style:vertical-align");
103
+ if (verticalAlignValue !== void 0 && isVerticalAlign(verticalAlignValue)) verticalAlignment = verticalAlignValue;
104
+ }
105
+ const paragraphProperties = childrenWithTag(styleElement, "style:paragraph-properties")[0];
106
+ const textAlignValue = paragraphProperties === void 0 ? void 0 : attrValue(paragraphProperties, "fo:text-align");
107
+ if (textAlignValue === "left" || textAlignValue === "center" || textAlignValue === "right" || textAlignValue === "justify") alignment = textAlignValue;
108
+ }
109
+ return {
110
+ background,
111
+ borders: bordersFromAccumulated(borderAccumulator),
112
+ alignment,
113
+ verticalAlignment
114
+ };
33
115
  }
34
116
  function readTableCell(cellElement, pkg) {
35
117
  const blocks = childrenWithTag(cellElement, "text:p").map((p) => readOdfParagraph(p, pkg));
36
118
  const colSpanRaw = attrValue(cellElement, "table:number-columns-spanned");
37
119
  const rowSpanRaw = attrValue(cellElement, "table:number-rows-spanned");
120
+ const styleName = attrValue(cellElement, "table:style-name");
121
+ const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-cell", pkg);
122
+ const { background, borders } = readCellStyleDecoration(styleElement === void 0 ? [] : [styleElement]);
38
123
  return {
39
124
  blocks,
40
125
  colSpan: colSpanRaw === void 0 ? void 0 : Number.parseInt(colSpanRaw, 10),
41
126
  rowSpan: rowSpanRaw === void 0 ? void 0 : Number.parseInt(rowSpanRaw, 10),
42
- background: readTableCellBackground(cellElement, pkg)
127
+ background,
128
+ borders
43
129
  };
44
130
  }
45
131
  function readTableRow(rowElement, pkg) {
@@ -80,4 +166,4 @@ function readOdfTable(tableElement, pkg) {
80
166
  };
81
167
  }
82
168
  //#endregion
83
- export { readOdfTable };
169
+ export { readCellStyleDecoration, readOdfTable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "odf.js",
3
- "version": "1.13.1",
3
+ "version": "2.0.0",
4
4
  "description": "Type-safe, lossless round-trip conversion between OpenDocument Format packages (odt, ods, odp) and JSON, hand-written and dependency-minimal, built on Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -69,7 +69,7 @@
69
69
  "license": "MIT",
70
70
  "packageManager": "pnpm@11.6.0",
71
71
  "dependencies": {
72
- "document-schema.js": "^1.5.2",
72
+ "document-schema.js": "^2.0.0",
73
73
  "fast-xml-parser": "^5.10.1",
74
74
  "fflate": "^0.8.3",
75
75
  "zod": "^4.4.3"