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
@@ -0,0 +1,161 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_xml_entities = require("../../xml/entities.cjs");
3
+ const require_xml_query = require("../../xml/query.cjs");
4
+ const require_typed_odb_subdocument = require("./subdocument.cjs");
5
+ const require_typed_odb_read = require("./read.cjs");
6
+ //#region src/typed/odb/report.ts
7
+ const CONTENT_PART = "content.xml";
8
+ const GROUP_TAG = "rpt:group";
9
+ const FUNCTION_TAG = "rpt:function";
10
+ const REPORT_ELEMENT_TAG = "rpt:report-element";
11
+ const REPORT_COMPONENT_TAG = "rpt:report-component";
12
+ const RPT_TAG_PREFIX = "rpt:";
13
+ const FIELD_FORMULA_PREFIX = "field:[";
14
+ const FIELD_FORMULA_SUFFIX = "]";
15
+ function reportAttr(element, name) {
16
+ const raw = require_xml_query.attrValue(element, name);
17
+ return raw === void 0 ? void 0 : require_xml_entities.decodeXmlText(raw);
18
+ }
19
+ function parseOptionalBoolean(raw) {
20
+ return raw === void 0 ? void 0 : raw === "true";
21
+ }
22
+ function boundFieldName(formula) {
23
+ if (formula === void 0 || !formula.startsWith(FIELD_FORMULA_PREFIX) || !formula.endsWith(FIELD_FORMULA_SUFFIX)) return;
24
+ const inner = formula.slice(7, formula.length - 1);
25
+ return inner.length === 0 ? void 0 : inner;
26
+ }
27
+ function elementText(element) {
28
+ let text = "";
29
+ for (const child of element.children) if (child.type === "text") text += require_xml_entities.decodeXmlText(child.value);
30
+ else if (child.type === "element") text += elementText(child);
31
+ return text;
32
+ }
33
+ function reportElementChild(element) {
34
+ return require_xml_query.findChildElement(element.children, REPORT_ELEMENT_TAG);
35
+ }
36
+ function readReportElement(element, reportElement) {
37
+ const control = { tag: element.tag };
38
+ const component = require_xml_query.findChildElement(reportElement.children, REPORT_COMPONENT_TAG);
39
+ const name = component === void 0 ? void 0 : reportAttr(component, "draw:name");
40
+ if (name !== void 0) control.name = name;
41
+ const formula = reportAttr(element, "rpt:formula");
42
+ if (formula !== void 0) control.formula = formula;
43
+ let text = "";
44
+ for (const child of element.children) if (child.type === "text") text += require_xml_entities.decodeXmlText(child.value);
45
+ else if (child.type === "element" && !child.tag.startsWith(RPT_TAG_PREFIX)) text += elementText(child);
46
+ if (text.length > 0) control.text = text;
47
+ const dataField = boundFieldName(formula);
48
+ if (dataField !== void 0) control.dataField = dataField;
49
+ return control;
50
+ }
51
+ function collectControls(nodes, controls) {
52
+ for (const node of nodes) {
53
+ if (node.type !== "element") continue;
54
+ if (node.tag.startsWith(RPT_TAG_PREFIX)) {
55
+ const reportElement = reportElementChild(node);
56
+ if (reportElement !== void 0) {
57
+ controls.push(readReportElement(node, reportElement));
58
+ continue;
59
+ }
60
+ }
61
+ collectControls(node.children, controls);
62
+ }
63
+ }
64
+ function readBand(element, kind) {
65
+ const elements = [];
66
+ collectControls(element.children, elements);
67
+ const band = {
68
+ kind,
69
+ elements
70
+ };
71
+ const table = require_xml_query.findChildElement(element.children, "table:table");
72
+ const name = table === void 0 ? void 0 : reportAttr(table, "table:name");
73
+ if (name !== void 0) band.name = name;
74
+ return band;
75
+ }
76
+ function readBandIfPresent(container, tag, kind) {
77
+ const element = require_xml_query.findChildElement(container.children, tag);
78
+ return element === void 0 ? void 0 : readBand(element, kind);
79
+ }
80
+ function readFunctions(container) {
81
+ const functions = [];
82
+ for (const child of container.children) {
83
+ if (child.type !== "element" || child.tag !== FUNCTION_TAG) continue;
84
+ const name = reportAttr(child, "rpt:name");
85
+ const formula = reportAttr(child, "rpt:formula");
86
+ if (name === void 0 || formula === void 0) continue;
87
+ functions.push({
88
+ name,
89
+ formula
90
+ });
91
+ }
92
+ return functions;
93
+ }
94
+ function readGroup(element) {
95
+ const group = {
96
+ functions: readFunctions(element),
97
+ groups: []
98
+ };
99
+ const groupExpression = reportAttr(element, "rpt:group-expression");
100
+ if (groupExpression !== void 0) group.groupExpression = groupExpression;
101
+ const sortExpression = reportAttr(element, "rpt:sort-expression");
102
+ if (sortExpression !== void 0) group.sortExpression = sortExpression;
103
+ const sortAscending = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:sort-ascending"));
104
+ if (sortAscending !== void 0) group.sortAscending = sortAscending;
105
+ const startNewColumn = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:start-new-column"));
106
+ if (startNewColumn !== void 0) group.startNewColumn = startNewColumn;
107
+ const resetPageNumber = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:reset-page-number"));
108
+ if (resetPageNumber !== void 0) group.resetPageNumber = resetPageNumber;
109
+ const keepTogether = reportAttr(element, "rpt:keep-together");
110
+ if (keepTogether !== void 0) group.keepTogether = keepTogether;
111
+ const header = readBandIfPresent(element, "rpt:group-header", "group-header");
112
+ if (header !== void 0) group.header = header;
113
+ const footer = readBandIfPresent(element, "rpt:group-footer", "group-footer");
114
+ if (footer !== void 0) group.footer = footer;
115
+ for (const child of element.children) if (child.type === "element" && child.tag === GROUP_TAG) group.groups.push(readGroup(child));
116
+ return group;
117
+ }
118
+ function findDetail(container) {
119
+ const detail = require_xml_query.findChildElement(container.children, "rpt:detail");
120
+ if (detail !== void 0) return readBand(detail, "detail");
121
+ const group = require_xml_query.findChildElement(container.children, GROUP_TAG);
122
+ return group === void 0 ? void 0 : findDetail(group);
123
+ }
124
+ function readOdbReport(pkg, reportName) {
125
+ const component = require_typed_odb_read.resolveOdbComponent(pkg, "report", reportName);
126
+ const contentPart = require_typed_odb_subdocument.subDocumentPackage(pkg, component.href).parts[CONTENT_PART];
127
+ if (contentPart?.kind !== "xml") throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} is not an XML part`);
128
+ const contentRoot = require_xml_query.rootElement(contentPart.nodes);
129
+ const body = contentRoot === void 0 ? void 0 : require_xml_query.findChildElement(contentRoot.children, "office:body");
130
+ const reportElement = body === void 0 ? void 0 : require_xml_query.findChildElement(body.children, "office:report");
131
+ if (reportElement === void 0) throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} has no office:body/office:report element`);
132
+ const groups = [];
133
+ for (const child of reportElement.children) if (child.type === "element" && child.tag === GROUP_TAG) groups.push(readGroup(child));
134
+ const report = {
135
+ name: component.name,
136
+ href: component.href,
137
+ groups,
138
+ functions: readFunctions(reportElement)
139
+ };
140
+ const command = reportAttr(reportElement, "rpt:command");
141
+ if (command !== void 0) report.command = command;
142
+ const commandType = reportAttr(reportElement, "rpt:command-type");
143
+ if (commandType !== void 0) report.commandType = commandType;
144
+ const caption = reportAttr(reportElement, "office:caption");
145
+ if (caption !== void 0) report.caption = caption;
146
+ const mimeType = reportAttr(reportElement, "office:mimetype");
147
+ if (mimeType !== void 0) report.mimeType = mimeType;
148
+ const reportHeader = readBandIfPresent(reportElement, "rpt:report-header", "report-header");
149
+ if (reportHeader !== void 0) report.reportHeader = reportHeader;
150
+ const pageHeader = readBandIfPresent(reportElement, "rpt:page-header", "page-header");
151
+ if (pageHeader !== void 0) report.pageHeader = pageHeader;
152
+ const detail = findDetail(reportElement);
153
+ if (detail !== void 0) report.detail = detail;
154
+ const pageFooter = readBandIfPresent(reportElement, "rpt:page-footer", "page-footer");
155
+ if (pageFooter !== void 0) report.pageFooter = pageFooter;
156
+ const reportFooter = readBandIfPresent(reportElement, "rpt:report-footer", "report-footer");
157
+ if (reportFooter !== void 0) report.reportFooter = reportFooter;
158
+ return report;
159
+ }
160
+ //#endregion
161
+ exports.readOdbReport = readOdbReport;
@@ -0,0 +1,48 @@
1
+ import { Package } from "../../model/package.cjs";
2
+ //#region src/typed/odb/report.d.ts
3
+ interface OdbReportElement {
4
+ tag: string;
5
+ name?: string;
6
+ text?: string;
7
+ formula?: string;
8
+ dataField?: string;
9
+ }
10
+ interface OdbReportBand {
11
+ kind: 'report-header' | 'page-header' | 'group-header' | 'detail' | 'group-footer' | 'page-footer' | 'report-footer';
12
+ name?: string;
13
+ elements: OdbReportElement[];
14
+ }
15
+ interface OdbReportFunction {
16
+ name: string;
17
+ formula: string;
18
+ }
19
+ interface OdbReportGroup {
20
+ groupExpression?: string;
21
+ sortExpression?: string;
22
+ sortAscending?: boolean;
23
+ startNewColumn?: boolean;
24
+ resetPageNumber?: boolean;
25
+ keepTogether?: string;
26
+ header?: OdbReportBand;
27
+ footer?: OdbReportBand;
28
+ functions: OdbReportFunction[];
29
+ groups: OdbReportGroup[];
30
+ }
31
+ interface OdbReport {
32
+ name: string;
33
+ href: string;
34
+ command?: string;
35
+ commandType?: string;
36
+ caption?: string;
37
+ mimeType?: string;
38
+ reportHeader?: OdbReportBand;
39
+ pageHeader?: OdbReportBand;
40
+ groups: OdbReportGroup[];
41
+ detail?: OdbReportBand;
42
+ pageFooter?: OdbReportBand;
43
+ reportFooter?: OdbReportBand;
44
+ functions: OdbReportFunction[];
45
+ }
46
+ declare function readOdbReport(pkg: Package, reportName: string): OdbReport;
47
+ //#endregion
48
+ export { OdbReport, OdbReportBand, OdbReportElement, OdbReportFunction, OdbReportGroup, readOdbReport };
@@ -0,0 +1,48 @@
1
+ import { Package } from "../../model/package.js";
2
+ //#region src/typed/odb/report.d.ts
3
+ interface OdbReportElement {
4
+ tag: string;
5
+ name?: string;
6
+ text?: string;
7
+ formula?: string;
8
+ dataField?: string;
9
+ }
10
+ interface OdbReportBand {
11
+ kind: 'report-header' | 'page-header' | 'group-header' | 'detail' | 'group-footer' | 'page-footer' | 'report-footer';
12
+ name?: string;
13
+ elements: OdbReportElement[];
14
+ }
15
+ interface OdbReportFunction {
16
+ name: string;
17
+ formula: string;
18
+ }
19
+ interface OdbReportGroup {
20
+ groupExpression?: string;
21
+ sortExpression?: string;
22
+ sortAscending?: boolean;
23
+ startNewColumn?: boolean;
24
+ resetPageNumber?: boolean;
25
+ keepTogether?: string;
26
+ header?: OdbReportBand;
27
+ footer?: OdbReportBand;
28
+ functions: OdbReportFunction[];
29
+ groups: OdbReportGroup[];
30
+ }
31
+ interface OdbReport {
32
+ name: string;
33
+ href: string;
34
+ command?: string;
35
+ commandType?: string;
36
+ caption?: string;
37
+ mimeType?: string;
38
+ reportHeader?: OdbReportBand;
39
+ pageHeader?: OdbReportBand;
40
+ groups: OdbReportGroup[];
41
+ detail?: OdbReportBand;
42
+ pageFooter?: OdbReportBand;
43
+ reportFooter?: OdbReportBand;
44
+ functions: OdbReportFunction[];
45
+ }
46
+ declare function readOdbReport(pkg: Package, reportName: string): OdbReport;
47
+ //#endregion
48
+ export { OdbReport, OdbReportBand, OdbReportElement, OdbReportFunction, OdbReportGroup, readOdbReport };
@@ -0,0 +1,160 @@
1
+ import { decodeXmlText } from "../../xml/entities.js";
2
+ import { attrValue, findChildElement, rootElement } from "../../xml/query.js";
3
+ import { subDocumentPackage } from "./subdocument.js";
4
+ import { resolveOdbComponent } from "./read.js";
5
+ //#region src/typed/odb/report.ts
6
+ const CONTENT_PART = "content.xml";
7
+ const GROUP_TAG = "rpt:group";
8
+ const FUNCTION_TAG = "rpt:function";
9
+ const REPORT_ELEMENT_TAG = "rpt:report-element";
10
+ const REPORT_COMPONENT_TAG = "rpt:report-component";
11
+ const RPT_TAG_PREFIX = "rpt:";
12
+ const FIELD_FORMULA_PREFIX = "field:[";
13
+ const FIELD_FORMULA_SUFFIX = "]";
14
+ function reportAttr(element, name) {
15
+ const raw = attrValue(element, name);
16
+ return raw === void 0 ? void 0 : decodeXmlText(raw);
17
+ }
18
+ function parseOptionalBoolean(raw) {
19
+ return raw === void 0 ? void 0 : raw === "true";
20
+ }
21
+ function boundFieldName(formula) {
22
+ if (formula === void 0 || !formula.startsWith(FIELD_FORMULA_PREFIX) || !formula.endsWith(FIELD_FORMULA_SUFFIX)) return;
23
+ const inner = formula.slice(7, formula.length - 1);
24
+ return inner.length === 0 ? void 0 : inner;
25
+ }
26
+ function elementText(element) {
27
+ let text = "";
28
+ for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
29
+ else if (child.type === "element") text += elementText(child);
30
+ return text;
31
+ }
32
+ function reportElementChild(element) {
33
+ return findChildElement(element.children, REPORT_ELEMENT_TAG);
34
+ }
35
+ function readReportElement(element, reportElement) {
36
+ const control = { tag: element.tag };
37
+ const component = findChildElement(reportElement.children, REPORT_COMPONENT_TAG);
38
+ const name = component === void 0 ? void 0 : reportAttr(component, "draw:name");
39
+ if (name !== void 0) control.name = name;
40
+ const formula = reportAttr(element, "rpt:formula");
41
+ if (formula !== void 0) control.formula = formula;
42
+ let text = "";
43
+ for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
44
+ else if (child.type === "element" && !child.tag.startsWith(RPT_TAG_PREFIX)) text += elementText(child);
45
+ if (text.length > 0) control.text = text;
46
+ const dataField = boundFieldName(formula);
47
+ if (dataField !== void 0) control.dataField = dataField;
48
+ return control;
49
+ }
50
+ function collectControls(nodes, controls) {
51
+ for (const node of nodes) {
52
+ if (node.type !== "element") continue;
53
+ if (node.tag.startsWith(RPT_TAG_PREFIX)) {
54
+ const reportElement = reportElementChild(node);
55
+ if (reportElement !== void 0) {
56
+ controls.push(readReportElement(node, reportElement));
57
+ continue;
58
+ }
59
+ }
60
+ collectControls(node.children, controls);
61
+ }
62
+ }
63
+ function readBand(element, kind) {
64
+ const elements = [];
65
+ collectControls(element.children, elements);
66
+ const band = {
67
+ kind,
68
+ elements
69
+ };
70
+ const table = findChildElement(element.children, "table:table");
71
+ const name = table === void 0 ? void 0 : reportAttr(table, "table:name");
72
+ if (name !== void 0) band.name = name;
73
+ return band;
74
+ }
75
+ function readBandIfPresent(container, tag, kind) {
76
+ const element = findChildElement(container.children, tag);
77
+ return element === void 0 ? void 0 : readBand(element, kind);
78
+ }
79
+ function readFunctions(container) {
80
+ const functions = [];
81
+ for (const child of container.children) {
82
+ if (child.type !== "element" || child.tag !== FUNCTION_TAG) continue;
83
+ const name = reportAttr(child, "rpt:name");
84
+ const formula = reportAttr(child, "rpt:formula");
85
+ if (name === void 0 || formula === void 0) continue;
86
+ functions.push({
87
+ name,
88
+ formula
89
+ });
90
+ }
91
+ return functions;
92
+ }
93
+ function readGroup(element) {
94
+ const group = {
95
+ functions: readFunctions(element),
96
+ groups: []
97
+ };
98
+ const groupExpression = reportAttr(element, "rpt:group-expression");
99
+ if (groupExpression !== void 0) group.groupExpression = groupExpression;
100
+ const sortExpression = reportAttr(element, "rpt:sort-expression");
101
+ if (sortExpression !== void 0) group.sortExpression = sortExpression;
102
+ const sortAscending = parseOptionalBoolean(attrValue(element, "rpt:sort-ascending"));
103
+ if (sortAscending !== void 0) group.sortAscending = sortAscending;
104
+ const startNewColumn = parseOptionalBoolean(attrValue(element, "rpt:start-new-column"));
105
+ if (startNewColumn !== void 0) group.startNewColumn = startNewColumn;
106
+ const resetPageNumber = parseOptionalBoolean(attrValue(element, "rpt:reset-page-number"));
107
+ if (resetPageNumber !== void 0) group.resetPageNumber = resetPageNumber;
108
+ const keepTogether = reportAttr(element, "rpt:keep-together");
109
+ if (keepTogether !== void 0) group.keepTogether = keepTogether;
110
+ const header = readBandIfPresent(element, "rpt:group-header", "group-header");
111
+ if (header !== void 0) group.header = header;
112
+ const footer = readBandIfPresent(element, "rpt:group-footer", "group-footer");
113
+ if (footer !== void 0) group.footer = footer;
114
+ for (const child of element.children) if (child.type === "element" && child.tag === GROUP_TAG) group.groups.push(readGroup(child));
115
+ return group;
116
+ }
117
+ function findDetail(container) {
118
+ const detail = findChildElement(container.children, "rpt:detail");
119
+ if (detail !== void 0) return readBand(detail, "detail");
120
+ const group = findChildElement(container.children, GROUP_TAG);
121
+ return group === void 0 ? void 0 : findDetail(group);
122
+ }
123
+ function readOdbReport(pkg, reportName) {
124
+ const component = resolveOdbComponent(pkg, "report", reportName);
125
+ const contentPart = subDocumentPackage(pkg, component.href).parts[CONTENT_PART];
126
+ if (contentPart?.kind !== "xml") throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} is not an XML part`);
127
+ const contentRoot = rootElement(contentPart.nodes);
128
+ const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
129
+ const reportElement = body === void 0 ? void 0 : findChildElement(body.children, "office:report");
130
+ if (reportElement === void 0) throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} has no office:body/office:report element`);
131
+ const groups = [];
132
+ for (const child of reportElement.children) if (child.type === "element" && child.tag === GROUP_TAG) groups.push(readGroup(child));
133
+ const report = {
134
+ name: component.name,
135
+ href: component.href,
136
+ groups,
137
+ functions: readFunctions(reportElement)
138
+ };
139
+ const command = reportAttr(reportElement, "rpt:command");
140
+ if (command !== void 0) report.command = command;
141
+ const commandType = reportAttr(reportElement, "rpt:command-type");
142
+ if (commandType !== void 0) report.commandType = commandType;
143
+ const caption = reportAttr(reportElement, "office:caption");
144
+ if (caption !== void 0) report.caption = caption;
145
+ const mimeType = reportAttr(reportElement, "office:mimetype");
146
+ if (mimeType !== void 0) report.mimeType = mimeType;
147
+ const reportHeader = readBandIfPresent(reportElement, "rpt:report-header", "report-header");
148
+ if (reportHeader !== void 0) report.reportHeader = reportHeader;
149
+ const pageHeader = readBandIfPresent(reportElement, "rpt:page-header", "page-header");
150
+ if (pageHeader !== void 0) report.pageHeader = pageHeader;
151
+ const detail = findDetail(reportElement);
152
+ if (detail !== void 0) report.detail = detail;
153
+ const pageFooter = readBandIfPresent(reportElement, "rpt:page-footer", "page-footer");
154
+ if (pageFooter !== void 0) report.pageFooter = pageFooter;
155
+ const reportFooter = readBandIfPresent(reportElement, "rpt:report-footer", "report-footer");
156
+ if (reportFooter !== void 0) report.reportFooter = reportFooter;
157
+ return report;
158
+ }
159
+ //#endregion
160
+ export { readOdbReport };
@@ -0,0 +1,16 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/typed/odb/subdocument.ts
3
+ const CONTENT_PART = "content.xml";
4
+ function subDocumentPackage(pkg, prefix, options = {}) {
5
+ const normalised = prefix.endsWith("/") ? prefix : `${prefix}/`;
6
+ const parts = {};
7
+ for (const [path, part] of Object.entries(pkg.parts)) {
8
+ if (!path.startsWith(normalised)) continue;
9
+ const relative = path.slice(normalised.length);
10
+ if (relative.length > 0) parts[relative] = part;
11
+ }
12
+ if (options.allowMissingContent !== true && parts[CONTENT_PART] === void 0) throw new Error(`subDocumentPackage: package has no ${normalised}${CONTENT_PART} part`);
13
+ return { parts };
14
+ }
15
+ //#endregion
16
+ exports.subDocumentPackage = subDocumentPackage;
@@ -0,0 +1,8 @@
1
+ import { Package } from "../../model/package.cjs";
2
+ //#region src/typed/odb/subdocument.d.ts
3
+ interface SubDocumentPackageOptions {
4
+ allowMissingContent?: boolean;
5
+ }
6
+ declare function subDocumentPackage(pkg: Package, prefix: string, options?: SubDocumentPackageOptions): Package;
7
+ //#endregion
8
+ export { SubDocumentPackageOptions, subDocumentPackage };
@@ -0,0 +1,8 @@
1
+ import { Package } from "../../model/package.js";
2
+ //#region src/typed/odb/subdocument.d.ts
3
+ interface SubDocumentPackageOptions {
4
+ allowMissingContent?: boolean;
5
+ }
6
+ declare function subDocumentPackage(pkg: Package, prefix: string, options?: SubDocumentPackageOptions): Package;
7
+ //#endregion
8
+ export { SubDocumentPackageOptions, subDocumentPackage };
@@ -0,0 +1,15 @@
1
+ //#region src/typed/odb/subdocument.ts
2
+ const CONTENT_PART = "content.xml";
3
+ function subDocumentPackage(pkg, prefix, options = {}) {
4
+ const normalised = prefix.endsWith("/") ? prefix : `${prefix}/`;
5
+ const parts = {};
6
+ for (const [path, part] of Object.entries(pkg.parts)) {
7
+ if (!path.startsWith(normalised)) continue;
8
+ const relative = path.slice(normalised.length);
9
+ if (relative.length > 0) parts[relative] = part;
10
+ }
11
+ if (options.allowMissingContent !== true && parts[CONTENT_PART] === void 0) throw new Error(`subDocumentPackage: package has no ${normalised}${CONTENT_PART} part`);
12
+ return { parts };
13
+ }
14
+ //#endregion
15
+ export { subDocumentPackage };
@@ -6,7 +6,14 @@ 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");
10
+ const require_typed_shared_transform = require("../shared/transform.cjs");
9
11
  const require_typed_shared_masterpage = require("../shared/masterpage.cjs");
12
+ const require_typed_draw_shapes = require("../draw/shapes.cjs");
13
+ const require_typed_draw_embedded = require("../draw/embedded.cjs");
14
+ const require_typed_odp_read = require("../odp/read.cjs");
15
+ const require_typed_odt_read = require("../odt/read.cjs");
16
+ const require_typed_odg_read = require("../odg/read.cjs");
10
17
  let document_schema_js = require("document-schema.js");
11
18
  //#region src/typed/ods/read.ts
12
19
  const CONTENT_PART = "content.xml";
@@ -155,10 +162,84 @@ function parseNonNegativeInteger(value) {
155
162
  const parsed = Number.parseInt(value, 10);
156
163
  return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
157
164
  }
165
+ function readEmbeddedObjectDocument(reference) {
166
+ switch (reference.objectKind) {
167
+ case "wordprocessing": {
168
+ const { metadata, sections } = require_typed_odt_read.readOdt(reference.package);
169
+ return {
170
+ kind: "wordprocessing",
171
+ formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
172
+ metadata,
173
+ sections
174
+ };
175
+ }
176
+ case "presentation": {
177
+ const { metadata, slides } = require_typed_odp_read.readOdp(reference.package);
178
+ return {
179
+ kind: "presentation",
180
+ formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
181
+ metadata,
182
+ slides
183
+ };
184
+ }
185
+ case "drawing": {
186
+ const { metadata, pages } = require_typed_odg_read.readOdg(reference.package);
187
+ return {
188
+ kind: "drawing",
189
+ formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
190
+ metadata,
191
+ pages
192
+ };
193
+ }
194
+ case "spreadsheet": {
195
+ const { metadata, sheets } = readOds(reference.package);
196
+ return {
197
+ kind: "spreadsheet",
198
+ formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
199
+ metadata,
200
+ sheets
201
+ };
202
+ }
203
+ }
204
+ }
205
+ function collectAnchoredFrame(frameElement, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
206
+ const shape = require_typed_draw_shapes.readDrawFrame(frameElement, groupFunctions, pkg);
207
+ if (shape === void 0) return;
208
+ const reference = require_typed_draw_embedded.readDrawObjectReference(frameElement, pkg);
209
+ if (reference !== void 0) {
210
+ embeddedObjects.push({
211
+ objectKind: reference.objectKind,
212
+ document: readEmbeddedObjectDocument(reference),
213
+ frame: shape.frame
214
+ });
215
+ return;
216
+ }
217
+ for (const block of shape.blocks) if (block.kind === "image") images.push({
218
+ ...block,
219
+ anchorRow,
220
+ anchorColumn,
221
+ offsetXPt: shape.frame.xPt,
222
+ offsetYPt: shape.frame.yPt
223
+ });
224
+ }
225
+ function collectAnchoredFrames(children, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
226
+ for (const child of children) {
227
+ if (child.type !== "element") continue;
228
+ if (child.tag === "draw:frame") collectAnchoredFrame(child, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects);
229
+ else if (child.tag === "draw:g") {
230
+ const ownValue = require_xml_query.attrValue(child, "draw:transform");
231
+ const ownFunctions = ownValue === void 0 ? [] : require_typed_shared_transform.parseOdfTransform(ownValue);
232
+ const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
233
+ collectAnchoredFrames(child.children, nested, pkg, anchorRow, anchorColumn, images, embeddedObjects);
234
+ }
235
+ }
236
+ }
158
237
  function readTable(tableElement, pkg) {
159
238
  const columns = [];
160
239
  const rows = [];
161
240
  const cells = [];
241
+ const images = [];
242
+ const embeddedObjects = [];
162
243
  const manualBreakRows = [];
163
244
  const manualBreakColumns = [];
164
245
  let repeatColumns;
@@ -183,6 +264,7 @@ function readTable(tableElement, pkg) {
183
264
  const columnIndex = cursor.columnIndex;
184
265
  const rowIndex = cursor.rowIndex;
185
266
  cursor.nextCell(readRepeatCount(child, "table:number-columns-repeated"));
267
+ collectAnchoredFrames(child.children, [], pkg, rowIndex, columnIndex, images, embeddedObjects);
186
268
  const formula = require_xml_query.attrValue(child, "table:formula");
187
269
  const { runs, displayText } = readCellText(child, pkg);
188
270
  if (!(require_xml_query.attrValue(child, "office:value-type") !== void 0) && formula === void 0 && displayText.length === 0) continue;
@@ -199,6 +281,13 @@ function readTable(tableElement, pkg) {
199
281
  if (runs.length > 0) cell.runs = runs;
200
282
  if (colSpan !== void 0) cell.colSpan = colSpan;
201
283
  if (rowSpan !== void 0) cell.rowSpan = rowSpan;
284
+ const cellStyleName = require_xml_query.attrValue(child, "table:style-name");
285
+ const { elements: cellStyleChain } = require_typed_shared_cascade.resolveStyleElementChain(cellStyleName, "table-cell", pkg);
286
+ const decoration = require_typed_shared_table.readCellStyleDecoration(cellStyleChain);
287
+ if (decoration.background !== void 0) cell.background = decoration.background;
288
+ if (decoration.borders !== void 0) cell.borders = decoration.borders;
289
+ if (decoration.alignment !== void 0) cell.alignment = decoration.alignment;
290
+ if (decoration.verticalAlignment !== void 0) cell.verticalAlignment = decoration.verticalAlignment;
202
291
  cells.push(cell);
203
292
  }
204
293
  }
@@ -217,7 +306,8 @@ function readTable(tableElement, pkg) {
217
306
  }
218
307
  for (const child of tableElement.children) {
219
308
  if (child.type !== "element") continue;
220
- if (child.tag === "table:table-column") processColumn(child);
309
+ if (child.tag === "table:shapes") collectAnchoredFrames(child.children, [], pkg, 0, 0, images, embeddedObjects);
310
+ else if (child.tag === "table:table-column") processColumn(child);
221
311
  else if (child.tag === "table:table-header-columns") {
222
312
  const startIndex = columnCursor;
223
313
  for (const headerChild of child.children) if (headerChild.type === "element" && headerChild.tag === "table:table-column") processColumn(headerChild);
@@ -239,6 +329,8 @@ function readTable(tableElement, pkg) {
239
329
  columns,
240
330
  rows,
241
331
  cells,
332
+ images,
333
+ embeddedObjects,
242
334
  repeatColumns,
243
335
  repeatRows,
244
336
  manualBreakRows,
@@ -288,15 +380,17 @@ function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualB
288
380
  function readSheet(tableElement, pkg) {
289
381
  const name = require_xml_query.attrValue(tableElement, "table:name");
290
382
  if (name === void 0) return;
291
- const { columns, rows, cells, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
292
- return {
383
+ const { columns, rows, cells, images, embeddedObjects, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
384
+ const sheet = {
293
385
  name,
294
386
  cells,
295
387
  columns,
296
388
  rows,
297
- images: [],
389
+ images,
298
390
  printSettings: readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns)
299
391
  };
392
+ if (embeddedObjects.length > 0) sheet.embeddedObjects = embeddedObjects;
393
+ return sheet;
300
394
  }
301
395
  function readOds(pkg) {
302
396
  const contentPart = pkg.parts[CONTENT_PART];