odf.js 1.13.2 → 2.1.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 (44) hide show
  1. package/README.md +19 -4
  2. package/dist/index.cjs +10 -0
  3. package/dist/index.d.cts +7 -3
  4. package/dist/index.d.ts +7 -3
  5. package/dist/index.js +7 -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/embedded.cjs +42 -0
  11. package/dist/typed/draw/embedded.d.cts +13 -0
  12. package/dist/typed/draw/embedded.d.ts +13 -0
  13. package/dist/typed/draw/embedded.js +41 -0
  14. package/dist/typed/draw/shapes.cjs +86 -30
  15. package/dist/typed/draw/shapes.d.cts +4 -1
  16. package/dist/typed/draw/shapes.d.ts +4 -1
  17. package/dist/typed/draw/shapes.js +86 -30
  18. package/dist/typed/formula/read.cjs +14 -0
  19. package/dist/typed/formula/read.d.cts +3 -2
  20. package/dist/typed/formula/read.d.ts +3 -2
  21. package/dist/typed/formula/read.js +14 -1
  22. package/dist/typed/odb/form.cjs +85 -0
  23. package/dist/typed/odb/form.d.cts +31 -0
  24. package/dist/typed/odb/form.d.ts +31 -0
  25. package/dist/typed/odb/form.js +84 -0
  26. package/dist/typed/odb/read.cjs +60 -23
  27. package/dist/typed/odb/read.d.cts +15 -4
  28. package/dist/typed/odb/read.d.ts +15 -4
  29. package/dist/typed/odb/read.js +60 -24
  30. package/dist/typed/odb/report.cjs +161 -0
  31. package/dist/typed/odb/report.d.cts +48 -0
  32. package/dist/typed/odb/report.d.ts +48 -0
  33. package/dist/typed/odb/report.js +160 -0
  34. package/dist/typed/odb/subdocument.cjs +16 -0
  35. package/dist/typed/odb/subdocument.d.cts +8 -0
  36. package/dist/typed/odb/subdocument.d.ts +8 -0
  37. package/dist/typed/odb/subdocument.js +15 -0
  38. package/dist/typed/ods/read.cjs +98 -4
  39. package/dist/typed/ods/read.js +100 -6
  40. package/dist/typed/shared/table.cjs +94 -7
  41. package/dist/typed/shared/table.d.cts +9 -2
  42. package/dist/typed/shared/table.d.ts +9 -2
  43. package/dist/typed/shared/table.js +94 -8
  44. package/package.json +1 -1
@@ -2,11 +2,18 @@ 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";
9
+ import { parseOdfTransform } from "../shared/transform.js";
8
10
  import { resolvePageLayoutProperties } from "../shared/masterpage.js";
9
- import { PAGE_SIZE_A4 } from "document-schema.js";
11
+ import { readDrawFrame } from "../draw/shapes.js";
12
+ import { readDrawObjectReference } from "../draw/embedded.js";
13
+ import { readOdp } from "../odp/read.js";
14
+ import { readOdt } from "../odt/read.js";
15
+ import { readOdg } from "../odg/read.js";
16
+ import { CONTENT_FORMAT_VERSION, PAGE_SIZE_A4 } from "document-schema.js";
10
17
  //#region src/typed/ods/read.ts
11
18
  const CONTENT_PART = "content.xml";
12
19
  function parseKnownOdfLength(value) {
@@ -154,10 +161,84 @@ function parseNonNegativeInteger(value) {
154
161
  const parsed = Number.parseInt(value, 10);
155
162
  return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
156
163
  }
164
+ function readEmbeddedObjectDocument(reference) {
165
+ switch (reference.objectKind) {
166
+ case "wordprocessing": {
167
+ const { metadata, sections } = readOdt(reference.package);
168
+ return {
169
+ kind: "wordprocessing",
170
+ formatVersion: CONTENT_FORMAT_VERSION,
171
+ metadata,
172
+ sections
173
+ };
174
+ }
175
+ case "presentation": {
176
+ const { metadata, slides } = readOdp(reference.package);
177
+ return {
178
+ kind: "presentation",
179
+ formatVersion: CONTENT_FORMAT_VERSION,
180
+ metadata,
181
+ slides
182
+ };
183
+ }
184
+ case "drawing": {
185
+ const { metadata, pages } = readOdg(reference.package);
186
+ return {
187
+ kind: "drawing",
188
+ formatVersion: CONTENT_FORMAT_VERSION,
189
+ metadata,
190
+ pages
191
+ };
192
+ }
193
+ case "spreadsheet": {
194
+ const { metadata, sheets } = readOds(reference.package);
195
+ return {
196
+ kind: "spreadsheet",
197
+ formatVersion: CONTENT_FORMAT_VERSION,
198
+ metadata,
199
+ sheets
200
+ };
201
+ }
202
+ }
203
+ }
204
+ function collectAnchoredFrame(frameElement, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
205
+ const shape = readDrawFrame(frameElement, groupFunctions, pkg);
206
+ if (shape === void 0) return;
207
+ const reference = readDrawObjectReference(frameElement, pkg);
208
+ if (reference !== void 0) {
209
+ embeddedObjects.push({
210
+ objectKind: reference.objectKind,
211
+ document: readEmbeddedObjectDocument(reference),
212
+ frame: shape.frame
213
+ });
214
+ return;
215
+ }
216
+ for (const block of shape.blocks) if (block.kind === "image") images.push({
217
+ ...block,
218
+ anchorRow,
219
+ anchorColumn,
220
+ offsetXPt: shape.frame.xPt,
221
+ offsetYPt: shape.frame.yPt
222
+ });
223
+ }
224
+ function collectAnchoredFrames(children, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
225
+ for (const child of children) {
226
+ if (child.type !== "element") continue;
227
+ if (child.tag === "draw:frame") collectAnchoredFrame(child, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects);
228
+ else if (child.tag === "draw:g") {
229
+ const ownValue = attrValue(child, "draw:transform");
230
+ const ownFunctions = ownValue === void 0 ? [] : parseOdfTransform(ownValue);
231
+ const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
232
+ collectAnchoredFrames(child.children, nested, pkg, anchorRow, anchorColumn, images, embeddedObjects);
233
+ }
234
+ }
235
+ }
157
236
  function readTable(tableElement, pkg) {
158
237
  const columns = [];
159
238
  const rows = [];
160
239
  const cells = [];
240
+ const images = [];
241
+ const embeddedObjects = [];
161
242
  const manualBreakRows = [];
162
243
  const manualBreakColumns = [];
163
244
  let repeatColumns;
@@ -182,6 +263,7 @@ function readTable(tableElement, pkg) {
182
263
  const columnIndex = cursor.columnIndex;
183
264
  const rowIndex = cursor.rowIndex;
184
265
  cursor.nextCell(readRepeatCount(child, "table:number-columns-repeated"));
266
+ collectAnchoredFrames(child.children, [], pkg, rowIndex, columnIndex, images, embeddedObjects);
185
267
  const formula = attrValue(child, "table:formula");
186
268
  const { runs, displayText } = readCellText(child, pkg);
187
269
  if (!(attrValue(child, "office:value-type") !== void 0) && formula === void 0 && displayText.length === 0) continue;
@@ -198,6 +280,13 @@ function readTable(tableElement, pkg) {
198
280
  if (runs.length > 0) cell.runs = runs;
199
281
  if (colSpan !== void 0) cell.colSpan = colSpan;
200
282
  if (rowSpan !== void 0) cell.rowSpan = rowSpan;
283
+ const cellStyleName = attrValue(child, "table:style-name");
284
+ const { elements: cellStyleChain } = resolveStyleElementChain(cellStyleName, "table-cell", pkg);
285
+ const decoration = readCellStyleDecoration(cellStyleChain);
286
+ if (decoration.background !== void 0) cell.background = decoration.background;
287
+ if (decoration.borders !== void 0) cell.borders = decoration.borders;
288
+ if (decoration.alignment !== void 0) cell.alignment = decoration.alignment;
289
+ if (decoration.verticalAlignment !== void 0) cell.verticalAlignment = decoration.verticalAlignment;
201
290
  cells.push(cell);
202
291
  }
203
292
  }
@@ -216,7 +305,8 @@ function readTable(tableElement, pkg) {
216
305
  }
217
306
  for (const child of tableElement.children) {
218
307
  if (child.type !== "element") continue;
219
- if (child.tag === "table:table-column") processColumn(child);
308
+ if (child.tag === "table:shapes") collectAnchoredFrames(child.children, [], pkg, 0, 0, images, embeddedObjects);
309
+ else if (child.tag === "table:table-column") processColumn(child);
220
310
  else if (child.tag === "table:table-header-columns") {
221
311
  const startIndex = columnCursor;
222
312
  for (const headerChild of child.children) if (headerChild.type === "element" && headerChild.tag === "table:table-column") processColumn(headerChild);
@@ -238,6 +328,8 @@ function readTable(tableElement, pkg) {
238
328
  columns,
239
329
  rows,
240
330
  cells,
331
+ images,
332
+ embeddedObjects,
241
333
  repeatColumns,
242
334
  repeatRows,
243
335
  manualBreakRows,
@@ -287,15 +379,17 @@ function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualB
287
379
  function readSheet(tableElement, pkg) {
288
380
  const name = attrValue(tableElement, "table:name");
289
381
  if (name === void 0) return;
290
- const { columns, rows, cells, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
291
- return {
382
+ const { columns, rows, cells, images, embeddedObjects, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
383
+ const sheet = {
292
384
  name,
293
385
  cells,
294
386
  columns,
295
387
  rows,
296
- images: [],
388
+ images,
297
389
  printSettings: readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns)
298
390
  };
391
+ if (embeddedObjects.length > 0) sheet.embeddedObjects = embeddedObjects;
392
+ return sheet;
299
393
  }
300
394
  function readOds(pkg) {
301
395
  const contentPart = pkg.parts[CONTENT_PART];
@@ -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.2",
3
+ "version": "2.1.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": {