odf.js 1.12.0 → 1.13.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/README.md +39 -0
- package/dist/codec.cjs +28 -0
- package/dist/codec.d.cts +72 -0
- package/dist/codec.d.ts +72 -0
- package/dist/codec.js +24 -0
- package/dist/image/sniff.cjs +28 -0
- package/dist/image/sniff.d.cts +5 -0
- package/dist/image/sniff.d.ts +5 -0
- package/dist/image/sniff.js +27 -0
- package/dist/index.cjs +156 -3242
- package/dist/index.d.cts +42 -679
- package/dist/index.d.ts +42 -679
- package/dist/index.js +42 -3129
- package/dist/manifest.cjs +252 -0
- package/dist/manifest.d.cts +41 -0
- package/dist/manifest.d.ts +41 -0
- package/dist/manifest.js +242 -0
- package/dist/media-type.cjs +27 -0
- package/dist/media-type.d.cts +20 -0
- package/dist/media-type.d.ts +20 -0
- package/dist/media-type.js +25 -0
- package/dist/mimetype.cjs +19 -0
- package/dist/mimetype.d.cts +7 -0
- package/dist/mimetype.d.ts +7 -0
- package/dist/mimetype.js +16 -0
- package/dist/model/node.cjs +67 -0
- package/dist/model/node.d.cts +2 -0
- package/dist/model/node.d.ts +2 -0
- package/dist/model/node.js +58 -0
- package/dist/model/package.cjs +19 -0
- package/dist/model/package.d.cts +114 -0
- package/dist/model/package.d.ts +114 -0
- package/dist/model/package.js +15 -0
- package/dist/node-CkBWRjNR.d.cts +83 -0
- package/dist/node-CkBWRjNR.d.ts +83 -0
- package/dist/ns.cjs +37 -0
- package/dist/ns.d.cts +32 -0
- package/dist/ns.d.ts +32 -0
- package/dist/ns.js +35 -0
- package/dist/package-io/read.cjs +35 -0
- package/dist/package-io/read.d.cts +5 -0
- package/dist/package-io/read.d.ts +5 -0
- package/dist/package-io/read.js +34 -0
- package/dist/package-io/write.cjs +36 -0
- package/dist/package-io/write.d.cts +7 -0
- package/dist/package-io/write.d.ts +7 -0
- package/dist/package-io/write.js +33 -0
- package/dist/styles/properties.cjs +286 -0
- package/dist/styles/properties.d.cts +45 -0
- package/dist/styles/properties.d.ts +45 -0
- package/dist/styles/properties.js +277 -0
- package/dist/styles/registry.cjs +212 -0
- package/dist/styles/registry.d.cts +37 -0
- package/dist/styles/registry.d.ts +37 -0
- package/dist/styles/registry.js +209 -0
- package/dist/styles/serialize.cjs +23 -0
- package/dist/styles/serialize.d.cts +7 -0
- package/dist/styles/serialize.d.ts +7 -0
- package/dist/styles/serialize.js +21 -0
- package/dist/styles/span.cjs +114 -0
- package/dist/styles/span.d.cts +5 -0
- package/dist/styles/span.d.ts +5 -0
- package/dist/styles/span.js +113 -0
- package/dist/typed/draw/shapes.cjs +314 -0
- package/dist/typed/draw/shapes.d.cts +14 -0
- package/dist/typed/draw/shapes.d.ts +14 -0
- package/dist/typed/draw/shapes.js +311 -0
- package/dist/typed/formula/read.cjs +48 -0
- package/dist/typed/formula/read.d.cts +12 -0
- package/dist/typed/formula/read.d.ts +12 -0
- package/dist/typed/formula/read.js +47 -0
- package/dist/typed/odb/read.cjs +112 -0
- package/dist/typed/odb/read.d.cts +17 -0
- package/dist/typed/odb/read.d.ts +17 -0
- package/dist/typed/odb/read.js +111 -0
- package/dist/typed/odg/read.cjs +30 -0
- package/dist/typed/odg/read.d.cts +10 -0
- package/dist/typed/odg/read.d.ts +10 -0
- package/dist/typed/odg/read.js +29 -0
- package/dist/typed/odm/read.cjs +37 -0
- package/dist/typed/odm/read.d.cts +15 -0
- package/dist/typed/odm/read.d.ts +15 -0
- package/dist/typed/odm/read.js +36 -0
- package/dist/typed/odp/read.cjs +39 -0
- package/dist/typed/odp/read.d.cts +10 -0
- package/dist/typed/odp/read.d.ts +10 -0
- package/dist/typed/odp/read.js +38 -0
- package/dist/typed/ods/read.cjs +318 -0
- package/dist/typed/ods/read.d.cts +10 -0
- package/dist/typed/ods/read.d.ts +10 -0
- package/dist/typed/ods/read.js +317 -0
- package/dist/typed/odt/read.cjs +112 -0
- package/dist/typed/odt/read.d.cts +10 -0
- package/dist/typed/odt/read.d.ts +10 -0
- package/dist/typed/odt/read.js +111 -0
- package/dist/typed/shared/a1.cjs +68 -0
- package/dist/typed/shared/a1.d.cts +18 -0
- package/dist/typed/shared/a1.d.ts +18 -0
- package/dist/typed/shared/a1.js +63 -0
- package/dist/typed/shared/cascade.cjs +102 -0
- package/dist/typed/shared/cascade.d.cts +22 -0
- package/dist/typed/shared/cascade.d.ts +22 -0
- package/dist/typed/shared/cascade.js +99 -0
- package/dist/typed/shared/color.cjs +14 -0
- package/dist/typed/shared/color.d.cts +6 -0
- package/dist/typed/shared/color.d.ts +6 -0
- package/dist/typed/shared/color.js +12 -0
- package/dist/typed/shared/geometry.cjs +79 -0
- package/dist/typed/shared/geometry.d.cts +12 -0
- package/dist/typed/shared/geometry.d.ts +12 -0
- package/dist/typed/shared/geometry.js +75 -0
- package/dist/typed/shared/masterpage.cjs +39 -0
- package/dist/typed/shared/masterpage.d.cts +8 -0
- package/dist/typed/shared/masterpage.d.ts +8 -0
- package/dist/typed/shared/masterpage.js +37 -0
- package/dist/typed/shared/metadata.cjs +42 -0
- package/dist/typed/shared/metadata.d.cts +7 -0
- package/dist/typed/shared/metadata.d.ts +7 -0
- package/dist/typed/shared/metadata.js +40 -0
- package/dist/typed/shared/paragraph.cjs +57 -0
- package/dist/typed/shared/paragraph.d.cts +7 -0
- package/dist/typed/shared/paragraph.d.ts +7 -0
- package/dist/typed/shared/paragraph.js +56 -0
- package/dist/typed/shared/path.cjs +261 -0
- package/dist/typed/shared/path.d.cts +34 -0
- package/dist/typed/shared/path.d.ts +34 -0
- package/dist/typed/shared/path.js +255 -0
- package/dist/typed/shared/style.cjs +8 -0
- package/dist/typed/shared/style.d.cts +2 -0
- package/dist/typed/shared/style.d.ts +2 -0
- package/dist/typed/shared/style.js +2 -0
- package/dist/typed/shared/table.cjs +84 -0
- package/dist/typed/shared/table.d.cts +7 -0
- package/dist/typed/shared/table.d.ts +7 -0
- package/dist/typed/shared/table.js +83 -0
- package/dist/typed/shared/text.cjs +43 -0
- package/dist/typed/shared/text.d.cts +8 -0
- package/dist/typed/shared/text.d.ts +8 -0
- package/dist/typed/shared/text.js +39 -0
- package/dist/typed/shared/transform.cjs +112 -0
- package/dist/typed/shared/transform.d.cts +26 -0
- package/dist/typed/shared/transform.d.ts +26 -0
- package/dist/typed/shared/transform.js +107 -0
- package/dist/typed/shared/units.cjs +35 -0
- package/dist/typed/shared/units.d.cts +2 -0
- package/dist/typed/shared/units.d.ts +2 -0
- package/dist/typed/shared/units.js +33 -0
- package/dist/units-7pCiECuP.d.cts +6 -0
- package/dist/units-7pCiECuP.d.ts +6 -0
- package/dist/util/base64.cjs +48 -0
- package/dist/util/base64.d.cts +5 -0
- package/dist/util/base64.d.ts +5 -0
- package/dist/util/base64.js +46 -0
- package/dist/xml/build.cjs +46 -0
- package/dist/xml/build.d.cts +5 -0
- package/dist/xml/build.d.ts +5 -0
- package/dist/xml/build.js +46 -0
- package/dist/xml/entities.cjs +19 -0
- package/dist/xml/entities.d.cts +5 -0
- package/dist/xml/entities.d.ts +5 -0
- package/dist/xml/entities.js +17 -0
- package/dist/xml/fragment.cjs +22 -0
- package/dist/xml/fragment.d.cts +6 -0
- package/dist/xml/fragment.d.ts +6 -0
- package/dist/xml/fragment.js +20 -0
- package/dist/xml/parse.cjs +88 -0
- package/dist/xml/parse.d.cts +5 -0
- package/dist/xml/parse.d.ts +5 -0
- package/dist/xml/parse.js +88 -0
- package/dist/xml/query.cjs +33 -0
- package/dist/xml/query.d.cts +9 -0
- package/dist/xml/query.d.ts +9 -0
- package/dist/xml/query.js +28 -0
- package/dist/zip.cjs +15 -0
- package/dist/zip.d.cts +9 -0
- package/dist/zip.d.ts +9 -0
- package/dist/zip.js +13 -0
- package/package.json +9 -1
package/dist/index.cjs
CHANGED
|
@@ -1,3250 +1,164 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const require_model_node = require("./model/node.cjs");
|
|
3
|
+
const require_model_package = require("./model/package.cjs");
|
|
4
|
+
const require_util_base64 = require("./util/base64.cjs");
|
|
5
|
+
const require_xml_parse = require("./xml/parse.cjs");
|
|
6
|
+
const require_zip = require("./zip.cjs");
|
|
7
|
+
const require_package_io_read = require("./package-io/read.cjs");
|
|
8
|
+
const require_xml_build = require("./xml/build.cjs");
|
|
9
|
+
const require_package_io_write = require("./package-io/write.cjs");
|
|
10
|
+
const require_codec = require("./codec.cjs");
|
|
11
|
+
const require_ns = require("./ns.cjs");
|
|
12
|
+
const require_media_type = require("./media-type.cjs");
|
|
13
|
+
const require_image_sniff = require("./image/sniff.cjs");
|
|
14
|
+
const require_mimetype = require("./mimetype.cjs");
|
|
15
|
+
const require_xml_fragment = require("./xml/fragment.cjs");
|
|
16
|
+
const require_xml_entities = require("./xml/entities.cjs");
|
|
17
|
+
const require_manifest = require("./manifest.cjs");
|
|
18
|
+
const require_typed_shared_units = require("./typed/shared/units.cjs");
|
|
19
|
+
const require_typed_shared_color = require("./typed/shared/color.cjs");
|
|
20
|
+
const require_styles_properties = require("./styles/properties.cjs");
|
|
21
|
+
const require_styles_serialize = require("./styles/serialize.cjs");
|
|
22
|
+
const require_styles_registry = require("./styles/registry.cjs");
|
|
23
|
+
const require_xml_query = require("./xml/query.cjs");
|
|
24
|
+
const require_typed_shared_text = require("./typed/shared/text.cjs");
|
|
25
|
+
const require_styles_span = require("./styles/span.cjs");
|
|
26
|
+
const require_typed_shared_a1 = require("./typed/shared/a1.cjs");
|
|
27
|
+
const require_typed_shared_geometry = require("./typed/shared/geometry.cjs");
|
|
28
|
+
require("./typed/shared/style.cjs");
|
|
29
|
+
const require_typed_shared_cascade = require("./typed/shared/cascade.cjs");
|
|
30
|
+
const require_typed_shared_metadata = require("./typed/shared/metadata.cjs");
|
|
31
|
+
const require_typed_shared_paragraph = require("./typed/shared/paragraph.cjs");
|
|
32
|
+
const require_typed_shared_table = require("./typed/shared/table.cjs");
|
|
33
|
+
const require_typed_shared_transform = require("./typed/shared/transform.cjs");
|
|
34
|
+
const require_typed_shared_masterpage = require("./typed/shared/masterpage.cjs");
|
|
35
|
+
const require_typed_shared_path = require("./typed/shared/path.cjs");
|
|
36
|
+
const require_typed_draw_shapes = require("./typed/draw/shapes.cjs");
|
|
37
|
+
const require_typed_odp_read = require("./typed/odp/read.cjs");
|
|
38
|
+
const require_typed_odt_read = require("./typed/odt/read.cjs");
|
|
39
|
+
const require_typed_odg_read = require("./typed/odg/read.cjs");
|
|
40
|
+
const require_typed_ods_read = require("./typed/ods/read.cjs");
|
|
41
|
+
const require_typed_formula_read = require("./typed/formula/read.cjs");
|
|
42
|
+
const require_typed_odm_read = require("./typed/odm/read.cjs");
|
|
43
|
+
const require_typed_odb_read = require("./typed/odb/read.cjs");
|
|
5
44
|
let document_schema_js = require("document-schema.js");
|
|
6
|
-
//#region src/model/node.ts
|
|
7
|
-
const AttributeSchema = zod.z.object({
|
|
8
|
-
name: zod.z.string(),
|
|
9
|
-
value: zod.z.string()
|
|
10
|
-
});
|
|
11
|
-
const XmlTextSchema = zod.z.object({
|
|
12
|
-
type: zod.z.literal("text"),
|
|
13
|
-
value: zod.z.string()
|
|
14
|
-
});
|
|
15
|
-
const XmlCdataSchema = zod.z.object({
|
|
16
|
-
type: zod.z.literal("cdata"),
|
|
17
|
-
value: zod.z.string()
|
|
18
|
-
});
|
|
19
|
-
const XmlCommentSchema = zod.z.object({
|
|
20
|
-
type: zod.z.literal("comment"),
|
|
21
|
-
value: zod.z.string()
|
|
22
|
-
});
|
|
23
|
-
const XmlDeclarationSchema = zod.z.object({
|
|
24
|
-
type: zod.z.literal("declaration"),
|
|
25
|
-
attributes: zod.z.array(AttributeSchema)
|
|
26
|
-
});
|
|
27
|
-
const XmlPiSchema = zod.z.object({
|
|
28
|
-
type: zod.z.literal("pi"),
|
|
29
|
-
target: zod.z.string(),
|
|
30
|
-
content: zod.z.string()
|
|
31
|
-
});
|
|
32
|
-
function isRecord$1(value) {
|
|
33
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
|
-
}
|
|
35
|
-
function isAttribute(value) {
|
|
36
|
-
return isRecord$1(value) && typeof value.name === "string" && typeof value.value === "string";
|
|
37
|
-
}
|
|
38
|
-
function isXmlNode(value) {
|
|
39
|
-
if (!isRecord$1(value)) return false;
|
|
40
|
-
const t = value.type;
|
|
41
|
-
if (t === "text" || t === "cdata" || t === "comment") return typeof value.value === "string";
|
|
42
|
-
if (t === "declaration") return Array.isArray(value.attributes) && value.attributes.every(isAttribute);
|
|
43
|
-
if (t === "pi") return typeof value.target === "string" && typeof value.content === "string";
|
|
44
|
-
if (t === "element") return typeof value.tag === "string" && Array.isArray(value.attributes) && value.attributes.every(isAttribute) && Array.isArray(value.children) && value.children.every(isXmlNode);
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
const XmlElementSchema = zod.z.object({
|
|
48
|
-
type: zod.z.literal("element"),
|
|
49
|
-
tag: zod.z.string(),
|
|
50
|
-
attributes: zod.z.array(AttributeSchema),
|
|
51
|
-
children: zod.z.array(zod.z.custom(isXmlNode))
|
|
52
|
-
});
|
|
53
|
-
const XmlNodeSchema = zod.z.discriminatedUnion("type", [
|
|
54
|
-
XmlTextSchema,
|
|
55
|
-
XmlCdataSchema,
|
|
56
|
-
XmlCommentSchema,
|
|
57
|
-
XmlDeclarationSchema,
|
|
58
|
-
XmlPiSchema,
|
|
59
|
-
XmlElementSchema
|
|
60
|
-
]);
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/model/package.ts
|
|
63
|
-
const XmlPartSchema = zod.z.object({
|
|
64
|
-
kind: zod.z.literal("xml"),
|
|
65
|
-
nodes: zod.z.array(XmlNodeSchema)
|
|
66
|
-
});
|
|
67
|
-
const BinaryPartSchema = zod.z.object({
|
|
68
|
-
kind: zod.z.literal("binary"),
|
|
69
|
-
base64: zod.z.string()
|
|
70
|
-
});
|
|
71
|
-
const PartSchema = zod.z.discriminatedUnion("kind", [XmlPartSchema, BinaryPartSchema]);
|
|
72
|
-
const PackageSchema = zod.z.object({ parts: zod.z.record(zod.z.string(), PartSchema) });
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/util/base64.ts
|
|
75
|
-
const TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
76
|
-
const DECODE = (() => {
|
|
77
|
-
const map = (/* @__PURE__ */ new Uint8Array(256)).fill(255);
|
|
78
|
-
for (let i = 0; i < 64; i = i + 1) map[TABLE.charCodeAt(i)] = i;
|
|
79
|
-
return map;
|
|
80
|
-
})();
|
|
81
|
-
function bytesToBase64(bytes) {
|
|
82
|
-
let out = "";
|
|
83
|
-
const len = bytes.length;
|
|
84
|
-
for (let i = 0; i < len; i = i + 3) {
|
|
85
|
-
const b0 = bytes[i];
|
|
86
|
-
const b1 = i + 1 < len ? bytes[i + 1] : 0;
|
|
87
|
-
const b2 = i + 2 < len ? bytes[i + 2] : 0;
|
|
88
|
-
out += TABLE[b0 >> 2];
|
|
89
|
-
out += TABLE[(b0 & 3) << 4 | b1 >> 4];
|
|
90
|
-
out += i + 1 < len ? TABLE[(b1 & 15) << 2 | b2 >> 6] : "=";
|
|
91
|
-
out += i + 2 < len ? TABLE[b2 & 63] : "=";
|
|
92
|
-
}
|
|
93
|
-
return out;
|
|
94
|
-
}
|
|
95
|
-
function base64ToBytes(b64) {
|
|
96
|
-
const clean = b64.replace(/[^A-Za-z0-9+/=]/g, "");
|
|
97
|
-
const len = clean.length;
|
|
98
|
-
const out = new Uint8Array(len * 3 / 4 | 0);
|
|
99
|
-
let p = 0;
|
|
100
|
-
for (let i = 0; i < len; i = i + 4) {
|
|
101
|
-
const c0 = DECODE[clean.charCodeAt(i)];
|
|
102
|
-
const c1 = DECODE[clean.charCodeAt(i + 1)];
|
|
103
|
-
const c2 = clean.charCodeAt(i + 2);
|
|
104
|
-
const c3 = clean.charCodeAt(i + 3);
|
|
105
|
-
if (c0 === 255 || c1 === 255) throw new Error("invalid base64 input");
|
|
106
|
-
out[p++] = c0 << 2 | c1 >> 4;
|
|
107
|
-
if (c2 !== 61) {
|
|
108
|
-
const d2 = DECODE[c2];
|
|
109
|
-
out[p++] = (c1 & 15) << 4 | d2 >> 2;
|
|
110
|
-
if (c3 !== 61) {
|
|
111
|
-
const d3 = DECODE[c3];
|
|
112
|
-
out[p++] = (d2 & 3) << 6 | d3;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return out.subarray(0, p);
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
|
-
//#region src/xml/parse.ts
|
|
120
|
-
const PARSER = new fast_xml_parser.XMLParser({
|
|
121
|
-
preserveOrder: true,
|
|
122
|
-
attributeNamePrefix: "@_",
|
|
123
|
-
ignoreAttributes: false,
|
|
124
|
-
textNodeName: "#text",
|
|
125
|
-
cdataPropName: "__cdata",
|
|
126
|
-
commentPropName: "__comment",
|
|
127
|
-
processEntities: false,
|
|
128
|
-
parseTagValue: false,
|
|
129
|
-
trimValues: false
|
|
130
|
-
});
|
|
131
|
-
function parseXml(xml) {
|
|
132
|
-
return parseNodes(PARSER.parse(xml));
|
|
133
|
-
}
|
|
134
|
-
function isRecord(value) {
|
|
135
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
136
|
-
}
|
|
137
|
-
function isUnknownArray(value) {
|
|
138
|
-
return Array.isArray(value);
|
|
139
|
-
}
|
|
140
|
-
function asString(value) {
|
|
141
|
-
if (typeof value !== "string") throw new Error(`expected string while parsing XML, got ${typeof value}`);
|
|
142
|
-
return value;
|
|
143
|
-
}
|
|
144
|
-
function parseNodes(raw) {
|
|
145
|
-
if (!isUnknownArray(raw)) throw new Error("fast-xml-parser output was not an ordered array");
|
|
146
|
-
return raw.map(parseNode);
|
|
147
|
-
}
|
|
148
|
-
function parseNode(raw) {
|
|
149
|
-
if (!isRecord(raw)) throw new Error("fast-xml-parser node was not an object");
|
|
150
|
-
let tagKey;
|
|
151
|
-
for (const key of Object.keys(raw)) if (key !== ":@") {
|
|
152
|
-
if (tagKey !== void 0) throw new Error("XML node had multiple tag keys");
|
|
153
|
-
tagKey = key;
|
|
154
|
-
}
|
|
155
|
-
if (tagKey === void 0) throw new Error("XML node had no tag key");
|
|
156
|
-
const attributes = parseAttributes(raw[":@"]);
|
|
157
|
-
if (tagKey === "#text") return {
|
|
158
|
-
type: "text",
|
|
159
|
-
value: asString(raw["#text"])
|
|
160
|
-
};
|
|
161
|
-
if (tagKey === "__comment") return {
|
|
162
|
-
type: "comment",
|
|
163
|
-
value: scalarText(raw.__comment)
|
|
164
|
-
};
|
|
165
|
-
if (tagKey === "__cdata") return {
|
|
166
|
-
type: "cdata",
|
|
167
|
-
value: scalarText(raw.__cdata)
|
|
168
|
-
};
|
|
169
|
-
if (tagKey === "?xml") return {
|
|
170
|
-
type: "declaration",
|
|
171
|
-
attributes
|
|
172
|
-
};
|
|
173
|
-
if (tagKey.startsWith("?")) return {
|
|
174
|
-
type: "pi",
|
|
175
|
-
target: tagKey.slice(1),
|
|
176
|
-
content: scalarText(raw[tagKey])
|
|
177
|
-
};
|
|
178
|
-
return {
|
|
179
|
-
type: "element",
|
|
180
|
-
tag: tagKey,
|
|
181
|
-
attributes,
|
|
182
|
-
children: parseNodes(raw[tagKey])
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
function parseAttributes(raw) {
|
|
186
|
-
if (raw === void 0) return [];
|
|
187
|
-
if (!isRecord(raw)) throw new Error("XML attributes were not an object");
|
|
188
|
-
const attrs = [];
|
|
189
|
-
for (const key of Object.keys(raw)) {
|
|
190
|
-
if (!key.startsWith("@_")) throw new Error(`unexpected attribute key without @_ prefix: ${key}`);
|
|
191
|
-
attrs.push({
|
|
192
|
-
name: key.slice(2),
|
|
193
|
-
value: asString(raw[key])
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
return attrs;
|
|
197
|
-
}
|
|
198
|
-
function scalarText(raw) {
|
|
199
|
-
if (!isUnknownArray(raw) || raw.length === 0) throw new Error("expected a scalar-text wrapper array");
|
|
200
|
-
const first = raw[0];
|
|
201
|
-
if (!isRecord(first)) throw new Error("scalar-text wrapper was not an object");
|
|
202
|
-
return asString(first["#text"]);
|
|
203
|
-
}
|
|
204
|
-
//#endregion
|
|
205
|
-
//#region src/zip.ts
|
|
206
|
-
function unzipPackage(bytes) {
|
|
207
|
-
return (0, fflate.unzipSync)(bytes);
|
|
208
|
-
}
|
|
209
|
-
function zipPackage(entries) {
|
|
210
|
-
const data = {};
|
|
211
|
-
for (const [path, entry] of entries) if (entry.stored === true) data[path] = [entry.bytes, { level: 0 }];
|
|
212
|
-
else data[path] = entry.bytes;
|
|
213
|
-
return (0, fflate.zipSync)(data);
|
|
214
|
-
}
|
|
215
|
-
//#endregion
|
|
216
|
-
//#region src/package-io/read.ts
|
|
217
|
-
function parsePackage(bytes) {
|
|
218
|
-
const entries = unzipPackage(bytes);
|
|
219
|
-
const parts = {};
|
|
220
|
-
for (const [path, partBytes] of Object.entries(entries)) if (looksLikeXml(partBytes)) parts[path] = {
|
|
221
|
-
kind: "xml",
|
|
222
|
-
nodes: parseXml(new TextDecoder("utf-8").decode(partBytes))
|
|
223
|
-
};
|
|
224
|
-
else parts[path] = {
|
|
225
|
-
kind: "binary",
|
|
226
|
-
base64: bytesToBase64(partBytes)
|
|
227
|
-
};
|
|
228
|
-
return { parts };
|
|
229
|
-
}
|
|
230
|
-
function looksLikeXml(bytes) {
|
|
231
|
-
let i = 0;
|
|
232
|
-
if (bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191) i = 3;
|
|
233
|
-
while (i < bytes.length) {
|
|
234
|
-
const b = bytes[i];
|
|
235
|
-
if (b === 32 || b === 9 || b === 10 || b === 13) {
|
|
236
|
-
i = i + 1;
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
return b === 60;
|
|
240
|
-
}
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
//#endregion
|
|
244
|
-
//#region src/xml/build.ts
|
|
245
|
-
const BUILDER = new fast_xml_parser.XMLBuilder({
|
|
246
|
-
preserveOrder: true,
|
|
247
|
-
attributeNamePrefix: "@_",
|
|
248
|
-
ignoreAttributes: false,
|
|
249
|
-
textNodeName: "#text",
|
|
250
|
-
cdataPropName: "__cdata",
|
|
251
|
-
commentPropName: "__comment",
|
|
252
|
-
processEntities: false,
|
|
253
|
-
format: false,
|
|
254
|
-
suppressEmptyNode: false
|
|
255
|
-
});
|
|
256
|
-
function buildXml(nodes) {
|
|
257
|
-
const out = BUILDER.build(toOrdered(nodes));
|
|
258
|
-
if (typeof out !== "string") throw new Error("XMLBuilder did not return a string");
|
|
259
|
-
return out;
|
|
260
|
-
}
|
|
261
|
-
function toOrdered(nodes) {
|
|
262
|
-
return nodes.map(toOrderedNode);
|
|
263
|
-
}
|
|
264
|
-
function attrsObject(attributes) {
|
|
265
|
-
const obj = {};
|
|
266
|
-
for (const a of attributes) obj[`@_${a.name}`] = a.value;
|
|
267
|
-
return obj;
|
|
268
|
-
}
|
|
269
|
-
function toOrderedNode(node) {
|
|
270
|
-
switch (node.type) {
|
|
271
|
-
case "text": return { "#text": node.value };
|
|
272
|
-
case "comment": return { __comment: [{ "#text": node.value }] };
|
|
273
|
-
case "cdata": return { __cdata: [{ "#text": node.value }] };
|
|
274
|
-
case "pi": return { [`?${node.target}`]: [{ "#text": node.content }] };
|
|
275
|
-
case "declaration": return {
|
|
276
|
-
"?xml": [{ "#text": "" }],
|
|
277
|
-
":@": attrsObject(node.attributes)
|
|
278
|
-
};
|
|
279
|
-
case "element": {
|
|
280
|
-
const obj = { [node.tag]: toOrdered(node.children) };
|
|
281
|
-
const attrs = attrsObject(node.attributes);
|
|
282
|
-
if (Object.keys(attrs).length > 0) obj[":@"] = attrs;
|
|
283
|
-
return obj;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
//#endregion
|
|
288
|
-
//#region src/package-io/write.ts
|
|
289
|
-
const MIMETYPE_PART = "mimetype";
|
|
290
|
-
const MANIFEST_PART = "META-INF/manifest.xml";
|
|
291
|
-
function serializePackage(pkg) {
|
|
292
|
-
const remaining = new Map(Object.entries(pkg.parts));
|
|
293
|
-
const entries = [];
|
|
294
|
-
const mimetype = remaining.get(MIMETYPE_PART);
|
|
295
|
-
if (mimetype !== void 0) {
|
|
296
|
-
entries.push([MIMETYPE_PART, {
|
|
297
|
-
bytes: partToBytes(mimetype),
|
|
298
|
-
stored: true
|
|
299
|
-
}]);
|
|
300
|
-
remaining.delete(MIMETYPE_PART);
|
|
301
|
-
}
|
|
302
|
-
const manifest = remaining.get(MANIFEST_PART);
|
|
303
|
-
if (manifest !== void 0) {
|
|
304
|
-
entries.push([MANIFEST_PART, { bytes: partToBytes(manifest) }]);
|
|
305
|
-
remaining.delete(MANIFEST_PART);
|
|
306
|
-
}
|
|
307
|
-
for (const [path, part] of remaining) entries.push([path, { bytes: partToBytes(part) }]);
|
|
308
|
-
return zipPackage(entries);
|
|
309
|
-
}
|
|
310
|
-
function partToBytes(part) {
|
|
311
|
-
switch (part.kind) {
|
|
312
|
-
case "xml": return new TextEncoder().encode(buildXml(part.nodes));
|
|
313
|
-
case "binary": return base64ToBytes(part.base64);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
//#endregion
|
|
317
|
-
//#region src/codec.ts
|
|
318
|
-
const xmlCodec = zod.z.codec(zod.z.string(), zod.z.array(XmlNodeSchema), {
|
|
319
|
-
decode: (xml) => parseXml(xml),
|
|
320
|
-
encode: (nodes) => buildXml(nodes)
|
|
321
|
-
});
|
|
322
|
-
const packageCodec = zod.z.codec(zod.z.instanceof(Uint8Array), PackageSchema, {
|
|
323
|
-
decode: (bytes) => parsePackage(bytes),
|
|
324
|
-
encode: (pkg) => serializePackage(pkg)
|
|
325
|
-
});
|
|
326
|
-
function decodePackage(bytes) {
|
|
327
|
-
return zod.z.decode(packageCodec, bytes);
|
|
328
|
-
}
|
|
329
|
-
function encodePackage(pkg) {
|
|
330
|
-
return zod.z.encode(packageCodec, pkg);
|
|
331
|
-
}
|
|
332
|
-
//#endregion
|
|
333
|
-
//#region src/ns.ts
|
|
334
|
-
const ODF_NAMESPACES = Object.freeze({
|
|
335
|
-
office: "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
|
336
|
-
style: "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
|
|
337
|
-
text: "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
|
|
338
|
-
table: "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
|
|
339
|
-
draw: "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
|
|
340
|
-
fo: "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
|
341
|
-
svg: "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
|
|
342
|
-
xlink: "http://www.w3.org/1999/xlink",
|
|
343
|
-
dc: "http://purl.org/dc/elements/1.1/",
|
|
344
|
-
meta: "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
|
|
345
|
-
number: "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
|
|
346
|
-
chart: "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
|
|
347
|
-
dr3d: "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
|
|
348
|
-
math: "http://www.w3.org/1998/Math/MathML",
|
|
349
|
-
form: "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
|
|
350
|
-
script: "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
|
|
351
|
-
config: "urn:oasis:names:tc:opendocument:xmlns:config:1.0",
|
|
352
|
-
presentation: "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",
|
|
353
|
-
smil: "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0",
|
|
354
|
-
anim: "urn:oasis:names:tc:opendocument:xmlns:animation:1.0",
|
|
355
|
-
xforms: "http://www.w3.org/2002/xforms",
|
|
356
|
-
xsd: "http://www.w3.org/2001/XMLSchema",
|
|
357
|
-
xsi: "http://www.w3.org/2001/XMLSchema-instance",
|
|
358
|
-
manifest: "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0",
|
|
359
|
-
db: "urn:oasis:names:tc:opendocument:xmlns:database:1.0"
|
|
360
|
-
});
|
|
361
|
-
function xmlnsAttributes(prefixes) {
|
|
362
|
-
const attrs = {};
|
|
363
|
-
for (const prefix of prefixes) attrs[`xmlns:${prefix}`] = ODF_NAMESPACES[prefix];
|
|
364
|
-
return attrs;
|
|
365
|
-
}
|
|
366
|
-
//#endregion
|
|
367
|
-
//#region src/media-type.ts
|
|
368
|
-
const ODF_MEDIA_TYPES = Object.freeze({
|
|
369
|
-
odt: "application/vnd.oasis.opendocument.text",
|
|
370
|
-
ott: "application/vnd.oasis.opendocument.text-template",
|
|
371
|
-
ods: "application/vnd.oasis.opendocument.spreadsheet",
|
|
372
|
-
ots: "application/vnd.oasis.opendocument.spreadsheet-template",
|
|
373
|
-
odp: "application/vnd.oasis.opendocument.presentation",
|
|
374
|
-
otp: "application/vnd.oasis.opendocument.presentation-template",
|
|
375
|
-
odg: "application/vnd.oasis.opendocument.graphics",
|
|
376
|
-
otg: "application/vnd.oasis.opendocument.graphics-template",
|
|
377
|
-
odf: "application/vnd.oasis.opendocument.formula",
|
|
378
|
-
otf: "application/vnd.oasis.opendocument.formula-template",
|
|
379
|
-
odm: "application/vnd.oasis.opendocument.text-master",
|
|
380
|
-
otm: "application/vnd.oasis.opendocument.text-master-template",
|
|
381
|
-
odb: "application/vnd.oasis.opendocument.base"
|
|
382
|
-
});
|
|
383
|
-
function isOdfExtension(extension) {
|
|
384
|
-
return Object.hasOwn(ODF_MEDIA_TYPES, extension);
|
|
385
|
-
}
|
|
386
|
-
function mediaTypeForExtension(extension) {
|
|
387
|
-
const lower = extension.toLowerCase();
|
|
388
|
-
return isOdfExtension(lower) ? ODF_MEDIA_TYPES[lower] : void 0;
|
|
389
|
-
}
|
|
390
|
-
//#endregion
|
|
391
|
-
//#region src/image/sniff.ts
|
|
392
|
-
const PNG_SIGNATURE = [
|
|
393
|
-
137,
|
|
394
|
-
80,
|
|
395
|
-
78,
|
|
396
|
-
71,
|
|
397
|
-
13,
|
|
398
|
-
10,
|
|
399
|
-
26,
|
|
400
|
-
10
|
|
401
|
-
];
|
|
402
|
-
const JPEG_SIGNATURE = [
|
|
403
|
-
255,
|
|
404
|
-
216,
|
|
405
|
-
255
|
|
406
|
-
];
|
|
407
|
-
function startsWith(bytes, signature) {
|
|
408
|
-
if (bytes.length < signature.length) return false;
|
|
409
|
-
for (let i = 0; i < signature.length; i++) if (bytes[i] !== signature[i]) return false;
|
|
410
|
-
return true;
|
|
411
|
-
}
|
|
412
|
-
function sniffImageFormat(bytes) {
|
|
413
|
-
if (startsWith(bytes, PNG_SIGNATURE)) return "png";
|
|
414
|
-
if (startsWith(bytes, JPEG_SIGNATURE)) return "jpeg";
|
|
415
|
-
}
|
|
416
|
-
//#endregion
|
|
417
|
-
//#region src/mimetype.ts
|
|
418
|
-
function readMimetype(pkg) {
|
|
419
|
-
const part = pkg.parts[MIMETYPE_PART];
|
|
420
|
-
if (part?.kind !== "binary") return;
|
|
421
|
-
return new TextDecoder("utf-8").decode(base64ToBytes(part.base64));
|
|
422
|
-
}
|
|
423
|
-
function writeMimetype(pkg, mediaType) {
|
|
424
|
-
pkg.parts[MIMETYPE_PART] = {
|
|
425
|
-
kind: "binary",
|
|
426
|
-
base64: bytesToBase64(new TextEncoder().encode(mediaType))
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
//#endregion
|
|
430
|
-
//#region src/xml/fragment.ts
|
|
431
|
-
function el(tag, attrs = {}, children = []) {
|
|
432
|
-
return {
|
|
433
|
-
type: "element",
|
|
434
|
-
tag,
|
|
435
|
-
attributes: Object.entries(attrs).map(([name, value]) => ({
|
|
436
|
-
name,
|
|
437
|
-
value
|
|
438
|
-
})),
|
|
439
|
-
children
|
|
440
|
-
};
|
|
441
|
-
}
|
|
442
|
-
function txt(value) {
|
|
443
|
-
return {
|
|
444
|
-
type: "text",
|
|
445
|
-
value
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
//#endregion
|
|
449
|
-
//#region src/xml/entities.ts
|
|
450
|
-
function encodeXmlText(value) {
|
|
451
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
452
|
-
}
|
|
453
|
-
const XML_ENTITY_PATTERN = /&(?:amp|lt|gt|quot|apos);/g;
|
|
454
|
-
const XML_ENTITY_DECODE = {
|
|
455
|
-
"&": "&",
|
|
456
|
-
"<": "<",
|
|
457
|
-
">": ">",
|
|
458
|
-
""": "\"",
|
|
459
|
-
"'": "'"
|
|
460
|
-
};
|
|
461
|
-
function decodeXmlText(value) {
|
|
462
|
-
return value.replace(XML_ENTITY_PATTERN, (entity) => XML_ENTITY_DECODE[entity]);
|
|
463
|
-
}
|
|
464
|
-
//#endregion
|
|
465
|
-
//#region src/manifest.ts
|
|
466
|
-
const ManifestEntrySchema = zod.z.object({
|
|
467
|
-
fullPath: zod.z.string(),
|
|
468
|
-
mediaType: zod.z.string(),
|
|
469
|
-
version: zod.z.string().optional()
|
|
470
|
-
});
|
|
471
|
-
const ManifestSchema = zod.z.object({
|
|
472
|
-
version: zod.z.string(),
|
|
473
|
-
entries: zod.z.array(ManifestEntrySchema)
|
|
474
|
-
});
|
|
475
|
-
const ManifestProblemSchema = zod.z.object({
|
|
476
|
-
severity: zod.z.enum(["error", "warning"]),
|
|
477
|
-
message: zod.z.string(),
|
|
478
|
-
path: zod.z.string().optional()
|
|
479
|
-
});
|
|
480
|
-
const DEFAULT_MANIFEST_VERSION = "1.3";
|
|
481
|
-
const STANDARD_XML_PART_NAMES = /* @__PURE__ */ new Set([
|
|
482
|
-
"content.xml",
|
|
483
|
-
"styles.xml",
|
|
484
|
-
"meta.xml",
|
|
485
|
-
"settings.xml"
|
|
486
|
-
]);
|
|
487
|
-
function findChildElement$1(nodes, tag) {
|
|
488
|
-
for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
|
|
489
|
-
}
|
|
490
|
-
function attrValue$2(element, name) {
|
|
491
|
-
return element.attributes.find((attribute) => attribute.name === name)?.value;
|
|
492
|
-
}
|
|
493
|
-
function readManifest(pkg) {
|
|
494
|
-
const part = pkg.parts[MANIFEST_PART];
|
|
495
|
-
if (part?.kind !== "xml") throw new Error(`package has no ${MANIFEST_PART} XML part to read`);
|
|
496
|
-
const root = findChildElement$1(part.nodes, "manifest:manifest");
|
|
497
|
-
if (root === void 0) throw new Error(`${MANIFEST_PART} has no manifest:manifest root element`);
|
|
498
|
-
const version = attrValue$2(root, "manifest:version");
|
|
499
|
-
if (version === void 0) throw new Error(`${MANIFEST_PART}'s manifest:manifest root is missing the required manifest:version attribute`);
|
|
500
|
-
const entries = [];
|
|
501
|
-
for (const child of root.children) {
|
|
502
|
-
if (child.type !== "element" || child.tag !== "manifest:file-entry") continue;
|
|
503
|
-
const fullPath = attrValue$2(child, "manifest:full-path");
|
|
504
|
-
const mediaType = attrValue$2(child, "manifest:media-type");
|
|
505
|
-
if (fullPath === void 0 || mediaType === void 0) throw new Error(`${MANIFEST_PART} has a manifest:file-entry missing manifest:full-path or manifest:media-type`);
|
|
506
|
-
const entryVersion = attrValue$2(child, "manifest:version");
|
|
507
|
-
entries.push(entryVersion === void 0 ? {
|
|
508
|
-
fullPath,
|
|
509
|
-
mediaType
|
|
510
|
-
} : {
|
|
511
|
-
fullPath,
|
|
512
|
-
mediaType,
|
|
513
|
-
version: entryVersion
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
return {
|
|
517
|
-
version,
|
|
518
|
-
entries
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
function subdocumentDirectories(partPaths) {
|
|
522
|
-
const dirs = [];
|
|
523
|
-
for (const path of partPaths) if (path.endsWith("/content.xml")) dirs.push(path.slice(0, path.length - 11));
|
|
524
|
-
return dirs;
|
|
525
|
-
}
|
|
526
|
-
function resolvePartMediaType(path, bytes, overrides) {
|
|
527
|
-
const override = overrides?.[path];
|
|
528
|
-
if (override !== void 0) return override;
|
|
529
|
-
const baseName = path.slice(path.lastIndexOf("/") + 1);
|
|
530
|
-
if (STANDARD_XML_PART_NAMES.has(baseName)) return "text/xml";
|
|
531
|
-
const dotIndex = baseName.lastIndexOf(".");
|
|
532
|
-
const extension = dotIndex === -1 ? "" : baseName.slice(dotIndex + 1);
|
|
533
|
-
const byExtension = extension === "" ? void 0 : mediaTypeForExtension(extension);
|
|
534
|
-
if (byExtension !== void 0) return byExtension;
|
|
535
|
-
if (bytes !== void 0) {
|
|
536
|
-
const sniffed = sniffImageFormat(bytes);
|
|
537
|
-
if (sniffed === "png") return "image/png";
|
|
538
|
-
if (sniffed === "jpeg") return "image/jpeg";
|
|
539
|
-
}
|
|
540
|
-
return "";
|
|
541
|
-
}
|
|
542
|
-
function buildManifest(pkg, options = {}) {
|
|
543
|
-
const version = options.version ?? DEFAULT_MANIFEST_VERSION;
|
|
544
|
-
const documentMediaType = options.documentMediaType ?? readMimetype(pkg);
|
|
545
|
-
if (documentMediaType === void 0) throw new Error("buildManifest: package has no \"mimetype\" part and no documentMediaType override was supplied -- the manifest root entry requires a known document media type");
|
|
546
|
-
const entries = [{
|
|
547
|
-
fullPath: "/",
|
|
548
|
-
mediaType: documentMediaType,
|
|
549
|
-
version
|
|
550
|
-
}];
|
|
551
|
-
const partPaths = Object.keys(pkg.parts);
|
|
552
|
-
for (const dir of new Set(subdocumentDirectories(partPaths))) entries.push({
|
|
553
|
-
fullPath: dir,
|
|
554
|
-
mediaType: resolvePartMediaType(dir, void 0, options.mediaTypeOverrides)
|
|
555
|
-
});
|
|
556
|
-
for (const [path, part] of Object.entries(pkg.parts)) {
|
|
557
|
-
if (path === "mimetype" || path === "META-INF/manifest.xml") continue;
|
|
558
|
-
const bytes = part.kind === "binary" ? base64ToBytes(part.base64) : void 0;
|
|
559
|
-
entries.push({
|
|
560
|
-
fullPath: path,
|
|
561
|
-
mediaType: resolvePartMediaType(path, bytes, options.mediaTypeOverrides)
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
return {
|
|
565
|
-
version,
|
|
566
|
-
entries
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
function buildManifestNodes(manifest) {
|
|
570
|
-
const fileEntries = manifest.entries.map((entry) => {
|
|
571
|
-
const attrs = { "manifest:full-path": encodeXmlText(entry.fullPath) };
|
|
572
|
-
if (entry.version !== void 0) attrs["manifest:version"] = encodeXmlText(entry.version);
|
|
573
|
-
attrs["manifest:media-type"] = encodeXmlText(entry.mediaType);
|
|
574
|
-
return el("manifest:file-entry", attrs);
|
|
575
|
-
});
|
|
576
|
-
return [{
|
|
577
|
-
type: "declaration",
|
|
578
|
-
attributes: [{
|
|
579
|
-
name: "version",
|
|
580
|
-
value: "1.0"
|
|
581
|
-
}, {
|
|
582
|
-
name: "encoding",
|
|
583
|
-
value: "UTF-8"
|
|
584
|
-
}]
|
|
585
|
-
}, el("manifest:manifest", {
|
|
586
|
-
...xmlnsAttributes(["manifest"]),
|
|
587
|
-
"manifest:version": encodeXmlText(manifest.version)
|
|
588
|
-
}, fileEntries)];
|
|
589
|
-
}
|
|
590
|
-
function writeManifest(pkg, manifest) {
|
|
591
|
-
pkg.parts[MANIFEST_PART] = {
|
|
592
|
-
kind: "xml",
|
|
593
|
-
nodes: buildManifestNodes(manifest)
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
function syncManifest(pkg, options) {
|
|
597
|
-
writeManifest(pkg, buildManifest(pkg, options));
|
|
598
|
-
}
|
|
599
|
-
function validateManifest(pkg) {
|
|
600
|
-
const problems = [];
|
|
601
|
-
const manifestPart = pkg.parts[MANIFEST_PART];
|
|
602
|
-
if (manifestPart === void 0) {
|
|
603
|
-
problems.push({
|
|
604
|
-
severity: "error",
|
|
605
|
-
message: `package has no ${MANIFEST_PART} part`
|
|
606
|
-
});
|
|
607
|
-
return problems;
|
|
608
|
-
}
|
|
609
|
-
if (manifestPart.kind !== "xml") {
|
|
610
|
-
problems.push({
|
|
611
|
-
severity: "error",
|
|
612
|
-
message: `${MANIFEST_PART} part is not XML`
|
|
613
|
-
});
|
|
614
|
-
return problems;
|
|
615
|
-
}
|
|
616
|
-
const root = findChildElement$1(manifestPart.nodes, "manifest:manifest");
|
|
617
|
-
if (root === void 0) {
|
|
618
|
-
problems.push({
|
|
619
|
-
severity: "error",
|
|
620
|
-
message: `${MANIFEST_PART} has no manifest:manifest root element`
|
|
621
|
-
});
|
|
622
|
-
return problems;
|
|
623
|
-
}
|
|
624
|
-
let manifest;
|
|
625
|
-
try {
|
|
626
|
-
manifest = readManifest(pkg);
|
|
627
|
-
} catch (error) {
|
|
628
|
-
problems.push({
|
|
629
|
-
severity: "error",
|
|
630
|
-
message: `failed to parse ${MANIFEST_PART}: ${error instanceof Error ? error.message : String(error)}`
|
|
631
|
-
});
|
|
632
|
-
return problems;
|
|
633
|
-
}
|
|
634
|
-
const rootEntry = manifest.entries.find((entry) => entry.fullPath === "/");
|
|
635
|
-
if (rootEntry === void 0) problems.push({
|
|
636
|
-
severity: "error",
|
|
637
|
-
message: "manifest has no root (\"/\") entry"
|
|
638
|
-
});
|
|
639
|
-
else {
|
|
640
|
-
const documentMediaType = readMimetype(pkg);
|
|
641
|
-
if (documentMediaType !== void 0 && documentMediaType !== rootEntry.mediaType) problems.push({
|
|
642
|
-
severity: "error",
|
|
643
|
-
message: `manifest root entry media type "${rootEntry.mediaType}" does not match the mimetype part's media type "${documentMediaType}"`,
|
|
644
|
-
path: "/"
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
const partPaths = new Set(Object.keys(pkg.parts).filter((path) => path !== "mimetype" && path !== "META-INF/manifest.xml"));
|
|
648
|
-
const manifestPaths = new Set(manifest.entries.map((entry) => entry.fullPath));
|
|
649
|
-
for (const entry of manifest.entries) {
|
|
650
|
-
if (entry.fullPath === "/" || entry.fullPath.endsWith("/")) continue;
|
|
651
|
-
if (!partPaths.has(entry.fullPath)) problems.push({
|
|
652
|
-
severity: "warning",
|
|
653
|
-
message: `manifest lists "${entry.fullPath}" but the package has no such part`,
|
|
654
|
-
path: entry.fullPath
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
for (const path of partPaths) if (!manifestPaths.has(path)) problems.push({
|
|
658
|
-
severity: "warning",
|
|
659
|
-
message: `package has part "${path}" not listed in the manifest`,
|
|
660
|
-
path
|
|
661
|
-
});
|
|
662
|
-
for (const child of root.children) {
|
|
663
|
-
if (child.type !== "element" || child.tag !== "manifest:file-entry") continue;
|
|
664
|
-
if (!child.children.some((grandchild) => grandchild.type === "element" && grandchild.tag === "manifest:encryption-data")) continue;
|
|
665
|
-
const fullPath = attrValue$2(child, "manifest:full-path");
|
|
666
|
-
if (fullPath === void 0) continue;
|
|
667
|
-
problems.push({
|
|
668
|
-
severity: "warning",
|
|
669
|
-
message: `entry "${fullPath}" carries manifest:encryption-data -- odf.js does not implement ODF encryption/decryption`,
|
|
670
|
-
path: fullPath
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
return problems;
|
|
674
|
-
}
|
|
675
|
-
function setDocumentMediaType(pkg, mediaType, version = DEFAULT_MANIFEST_VERSION) {
|
|
676
|
-
writeMimetype(pkg, mediaType);
|
|
677
|
-
const rootEntry = {
|
|
678
|
-
fullPath: "/",
|
|
679
|
-
mediaType,
|
|
680
|
-
version
|
|
681
|
-
};
|
|
682
|
-
if (pkg.parts["META-INF/manifest.xml"] === void 0) {
|
|
683
|
-
writeManifest(pkg, {
|
|
684
|
-
version,
|
|
685
|
-
entries: [rootEntry]
|
|
686
|
-
});
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
const existing = readManifest(pkg);
|
|
690
|
-
const rootIndex = existing.entries.findIndex((entry) => entry.fullPath === "/");
|
|
691
|
-
writeManifest(pkg, {
|
|
692
|
-
version,
|
|
693
|
-
entries: rootIndex === -1 ? [rootEntry, ...existing.entries] : existing.entries.map((entry, index) => index === rootIndex ? rootEntry : entry)
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
//#endregion
|
|
697
|
-
//#region src/typed/shared/units.ts
|
|
698
|
-
const LENGTH_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(cm|mm|in|pt|pc|px)$/;
|
|
699
|
-
const POINTS_PER_INCH = 72;
|
|
700
|
-
const POINTS_PER_PICA = 12;
|
|
701
|
-
const CM_PER_INCH = 2.54;
|
|
702
|
-
const MM_PER_INCH = 25.4;
|
|
703
|
-
const CSS_REFERENCE_PIXELS_PER_INCH = 96;
|
|
704
|
-
function unitToPtFactor(unit) {
|
|
705
|
-
switch (unit) {
|
|
706
|
-
case "pt": return 1;
|
|
707
|
-
case "in": return POINTS_PER_INCH;
|
|
708
|
-
case "cm": return POINTS_PER_INCH / CM_PER_INCH;
|
|
709
|
-
case "mm": return POINTS_PER_INCH / MM_PER_INCH;
|
|
710
|
-
case "pc": return POINTS_PER_PICA;
|
|
711
|
-
case "px": return POINTS_PER_INCH / CSS_REFERENCE_PIXELS_PER_INCH;
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
function isLengthUnit(value) {
|
|
715
|
-
return value === "cm" || value === "mm" || value === "in" || value === "pt" || value === "pc" || value === "px";
|
|
716
|
-
}
|
|
717
|
-
function parseOdfLength(value) {
|
|
718
|
-
const match = LENGTH_PATTERN.exec(value);
|
|
719
|
-
if (match === null) return;
|
|
720
|
-
const numeric = match[1];
|
|
721
|
-
const unit = match[2];
|
|
722
|
-
if (numeric === void 0 || unit === void 0 || !isLengthUnit(unit)) return;
|
|
723
|
-
return Number(numeric) * unitToPtFactor(unit);
|
|
724
|
-
}
|
|
725
|
-
function formatOdfLength(pt, unit = "pt") {
|
|
726
|
-
return `${pt / unitToPtFactor(unit)}${unit}`;
|
|
727
|
-
}
|
|
728
|
-
//#endregion
|
|
729
|
-
//#region src/typed/shared/color.ts
|
|
730
|
-
const ODF_COLOR_PATTERN = /^#[0-9a-fA-F]{6}$/;
|
|
731
|
-
function parseOdfColor(value) {
|
|
732
|
-
if (!ODF_COLOR_PATTERN.test(value)) return;
|
|
733
|
-
return (0, document_schema_js.rgbHexToColor)(value);
|
|
734
|
-
}
|
|
735
|
-
function formatOdfColor(color) {
|
|
736
|
-
return `#${(0, document_schema_js.colorToRgbHex)(color)}`;
|
|
737
|
-
}
|
|
738
|
-
//#endregion
|
|
739
|
-
//#region src/styles/properties.ts
|
|
740
|
-
const StylePropertiesSchema = zod.z.object({
|
|
741
|
-
bold: zod.z.boolean().optional(),
|
|
742
|
-
italic: zod.z.boolean().optional(),
|
|
743
|
-
underline: zod.z.boolean().optional(),
|
|
744
|
-
strike: zod.z.boolean().optional(),
|
|
745
|
-
fontFamily: zod.z.string().optional(),
|
|
746
|
-
sizePt: zod.z.number().optional(),
|
|
747
|
-
color: document_schema_js.ColorSchema.optional(),
|
|
748
|
-
alignment: document_schema_js.AlignmentSchema.optional(),
|
|
749
|
-
spacingBeforePt: zod.z.number().optional(),
|
|
750
|
-
spacingAfterPt: zod.z.number().optional(),
|
|
751
|
-
lineSpacing: zod.z.number().optional(),
|
|
752
|
-
indentLeftPt: zod.z.number().optional(),
|
|
753
|
-
indentFirstLinePt: zod.z.number().optional()
|
|
754
|
-
});
|
|
755
|
-
const ATTR = {
|
|
756
|
-
fontWeight: "fo:font-weight",
|
|
757
|
-
fontStyle: "fo:font-style",
|
|
758
|
-
underlineStyle: "style:text-underline-style",
|
|
759
|
-
underlineWidth: "style:text-underline-width",
|
|
760
|
-
underlineColor: "style:text-underline-color",
|
|
761
|
-
lineThroughStyle: "style:text-line-through-style",
|
|
762
|
-
lineThroughType: "style:text-line-through-type",
|
|
763
|
-
fontFamily: "fo:font-family",
|
|
764
|
-
fontSize: "fo:font-size",
|
|
765
|
-
color: "fo:color",
|
|
766
|
-
textAlign: "fo:text-align",
|
|
767
|
-
marginTop: "fo:margin-top",
|
|
768
|
-
marginBottom: "fo:margin-bottom",
|
|
769
|
-
lineHeight: "fo:line-height",
|
|
770
|
-
marginLeft: "fo:margin-left",
|
|
771
|
-
textIndent: "fo:text-indent"
|
|
772
|
-
};
|
|
773
|
-
const TEXT_ATTR_NAMES = /* @__PURE__ */ new Set([
|
|
774
|
-
ATTR.fontWeight,
|
|
775
|
-
ATTR.fontStyle,
|
|
776
|
-
ATTR.underlineStyle,
|
|
777
|
-
ATTR.underlineWidth,
|
|
778
|
-
ATTR.underlineColor,
|
|
779
|
-
ATTR.lineThroughStyle,
|
|
780
|
-
ATTR.lineThroughType,
|
|
781
|
-
ATTR.fontFamily,
|
|
782
|
-
ATTR.fontSize,
|
|
783
|
-
ATTR.color
|
|
784
|
-
]);
|
|
785
|
-
const PARAGRAPH_ATTR_NAMES = /* @__PURE__ */ new Set([
|
|
786
|
-
ATTR.textAlign,
|
|
787
|
-
ATTR.marginTop,
|
|
788
|
-
ATTR.marginBottom,
|
|
789
|
-
ATTR.lineHeight,
|
|
790
|
-
ATTR.marginLeft,
|
|
791
|
-
ATTR.textIndent
|
|
792
|
-
]);
|
|
793
|
-
function attributeMap(element) {
|
|
794
|
-
const map = /* @__PURE__ */ new Map();
|
|
795
|
-
for (const attribute of element.attributes) map.set(attribute.name, attribute.value);
|
|
796
|
-
return map;
|
|
797
|
-
}
|
|
798
|
-
function formatPt(valuePt) {
|
|
799
|
-
return formatOdfLength(valuePt, "pt");
|
|
800
|
-
}
|
|
801
|
-
const PERCENTAGE_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))%$/;
|
|
802
|
-
function parsePercentageMultiplier(value) {
|
|
803
|
-
const match = PERCENTAGE_PATTERN.exec(value);
|
|
804
|
-
if (match === null) return;
|
|
805
|
-
const numeric = match[1];
|
|
806
|
-
if (numeric === void 0) return;
|
|
807
|
-
return Number(numeric) / 100;
|
|
808
|
-
}
|
|
809
|
-
function formatPercentageMultiplier(multiplier) {
|
|
810
|
-
return `${multiplier * 100}%`;
|
|
811
|
-
}
|
|
812
|
-
function parseLineDecoration(style, companionA, companionAOnValue, companionB, companionBOnValue) {
|
|
813
|
-
if (style === void 0 && companionA === void 0 && companionB === void 0) return;
|
|
814
|
-
if (style === "solid" && (companionA === void 0 || companionA === companionAOnValue) && (companionB === void 0 || companionB === companionBOnValue)) return true;
|
|
815
|
-
if (style === "none" && companionA === void 0 && companionB === void 0) return false;
|
|
816
|
-
return "unknown";
|
|
817
|
-
}
|
|
818
|
-
const RISKY_STYLE_ELEMENT_ATTRS = /* @__PURE__ */ new Set(["style:master-page-name", "style:next-style-name"]);
|
|
819
|
-
function parseTextProperties(element) {
|
|
820
|
-
const attrs = attributeMap(element);
|
|
821
|
-
const properties = {};
|
|
822
|
-
let hasUnknown = false;
|
|
823
|
-
for (const name of attrs.keys()) if (!TEXT_ATTR_NAMES.has(name)) hasUnknown = true;
|
|
824
|
-
const fontWeight = attrs.get(ATTR.fontWeight);
|
|
825
|
-
if (fontWeight === "bold") properties.bold = true;
|
|
826
|
-
else if (fontWeight === "normal") properties.bold = false;
|
|
827
|
-
else if (fontWeight !== void 0) hasUnknown = true;
|
|
828
|
-
const fontStyle = attrs.get(ATTR.fontStyle);
|
|
829
|
-
if (fontStyle === "italic") properties.italic = true;
|
|
830
|
-
else if (fontStyle === "normal") properties.italic = false;
|
|
831
|
-
else if (fontStyle !== void 0) hasUnknown = true;
|
|
832
|
-
const underline = parseLineDecoration(attrs.get(ATTR.underlineStyle), attrs.get(ATTR.underlineWidth), "auto", attrs.get(ATTR.underlineColor), "font-color");
|
|
833
|
-
if (underline === "unknown") hasUnknown = true;
|
|
834
|
-
else if (underline !== void 0) properties.underline = underline;
|
|
835
|
-
const strike = parseLineDecoration(attrs.get(ATTR.lineThroughStyle), attrs.get(ATTR.lineThroughType), "single", void 0, "");
|
|
836
|
-
if (strike === "unknown") hasUnknown = true;
|
|
837
|
-
else if (strike !== void 0) properties.strike = strike;
|
|
838
|
-
const fontFamily = attrs.get(ATTR.fontFamily);
|
|
839
|
-
if (fontFamily !== void 0) properties.fontFamily = fontFamily;
|
|
840
|
-
const fontSize = attrs.get(ATTR.fontSize);
|
|
841
|
-
if (fontSize !== void 0) {
|
|
842
|
-
const pt = parseOdfLength(fontSize);
|
|
843
|
-
if (pt === void 0) hasUnknown = true;
|
|
844
|
-
else properties.sizePt = pt;
|
|
845
|
-
}
|
|
846
|
-
const color = attrs.get(ATTR.color);
|
|
847
|
-
if (color !== void 0) {
|
|
848
|
-
const parsed = parseOdfColor(color);
|
|
849
|
-
if (parsed === void 0) hasUnknown = true;
|
|
850
|
-
else properties.color = parsed;
|
|
851
|
-
}
|
|
852
|
-
return {
|
|
853
|
-
properties,
|
|
854
|
-
hasUnknown
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
function parseParagraphProperties(element) {
|
|
858
|
-
const attrs = attributeMap(element);
|
|
859
|
-
const properties = {};
|
|
860
|
-
let hasUnknown = false;
|
|
861
|
-
for (const name of attrs.keys()) if (!PARAGRAPH_ATTR_NAMES.has(name)) hasUnknown = true;
|
|
862
|
-
const textAlign = attrs.get(ATTR.textAlign);
|
|
863
|
-
if (textAlign === "left" || textAlign === "center" || textAlign === "right" || textAlign === "justify") properties.alignment = textAlign;
|
|
864
|
-
else if (textAlign !== void 0) hasUnknown = true;
|
|
865
|
-
const marginTop = attrs.get(ATTR.marginTop);
|
|
866
|
-
if (marginTop !== void 0) {
|
|
867
|
-
const pt = parseOdfLength(marginTop);
|
|
868
|
-
if (pt === void 0) hasUnknown = true;
|
|
869
|
-
else properties.spacingBeforePt = pt;
|
|
870
|
-
}
|
|
871
|
-
const marginBottom = attrs.get(ATTR.marginBottom);
|
|
872
|
-
if (marginBottom !== void 0) {
|
|
873
|
-
const pt = parseOdfLength(marginBottom);
|
|
874
|
-
if (pt === void 0) hasUnknown = true;
|
|
875
|
-
else properties.spacingAfterPt = pt;
|
|
876
|
-
}
|
|
877
|
-
const marginLeft = attrs.get(ATTR.marginLeft);
|
|
878
|
-
if (marginLeft !== void 0) {
|
|
879
|
-
const pt = parseOdfLength(marginLeft);
|
|
880
|
-
if (pt === void 0) hasUnknown = true;
|
|
881
|
-
else properties.indentLeftPt = pt;
|
|
882
|
-
}
|
|
883
|
-
const textIndent = attrs.get(ATTR.textIndent);
|
|
884
|
-
if (textIndent !== void 0) {
|
|
885
|
-
const pt = parseOdfLength(textIndent);
|
|
886
|
-
if (pt === void 0) hasUnknown = true;
|
|
887
|
-
else properties.indentFirstLinePt = pt;
|
|
888
|
-
}
|
|
889
|
-
const lineHeight = attrs.get(ATTR.lineHeight);
|
|
890
|
-
if (lineHeight !== void 0) {
|
|
891
|
-
const multiplier = parsePercentageMultiplier(lineHeight);
|
|
892
|
-
if (multiplier === void 0) hasUnknown = true;
|
|
893
|
-
else properties.lineSpacing = multiplier;
|
|
894
|
-
}
|
|
895
|
-
return {
|
|
896
|
-
properties,
|
|
897
|
-
hasUnknown
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
function parseStyleElementProperties(styleElement) {
|
|
901
|
-
let properties = {};
|
|
902
|
-
let hasUnknown = false;
|
|
903
|
-
for (const attribute of styleElement.attributes) if (RISKY_STYLE_ELEMENT_ATTRS.has(attribute.name)) hasUnknown = true;
|
|
904
|
-
for (const child of styleElement.children) {
|
|
905
|
-
if (child.type !== "element") continue;
|
|
906
|
-
if (child.tag === "style:text-properties") {
|
|
907
|
-
const result = parseTextProperties(child);
|
|
908
|
-
properties = {
|
|
909
|
-
...properties,
|
|
910
|
-
...result.properties
|
|
911
|
-
};
|
|
912
|
-
if (result.hasUnknown) hasUnknown = true;
|
|
913
|
-
} else if (child.tag === "style:paragraph-properties") {
|
|
914
|
-
const result = parseParagraphProperties(child);
|
|
915
|
-
properties = {
|
|
916
|
-
...properties,
|
|
917
|
-
...result.properties
|
|
918
|
-
};
|
|
919
|
-
if (result.hasUnknown) hasUnknown = true;
|
|
920
|
-
} else hasUnknown = true;
|
|
921
|
-
}
|
|
922
|
-
return {
|
|
923
|
-
properties,
|
|
924
|
-
hasUnknown
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
function textPropertiesToAttributes(properties) {
|
|
928
|
-
const attributes = [];
|
|
929
|
-
if (properties.bold !== void 0) attributes.push({
|
|
930
|
-
name: ATTR.fontWeight,
|
|
931
|
-
value: properties.bold ? "bold" : "normal"
|
|
932
|
-
});
|
|
933
|
-
if (properties.italic !== void 0) attributes.push({
|
|
934
|
-
name: ATTR.fontStyle,
|
|
935
|
-
value: properties.italic ? "italic" : "normal"
|
|
936
|
-
});
|
|
937
|
-
if (properties.underline !== void 0) if (properties.underline) {
|
|
938
|
-
attributes.push({
|
|
939
|
-
name: ATTR.underlineStyle,
|
|
940
|
-
value: "solid"
|
|
941
|
-
});
|
|
942
|
-
attributes.push({
|
|
943
|
-
name: ATTR.underlineWidth,
|
|
944
|
-
value: "auto"
|
|
945
|
-
});
|
|
946
|
-
attributes.push({
|
|
947
|
-
name: ATTR.underlineColor,
|
|
948
|
-
value: "font-color"
|
|
949
|
-
});
|
|
950
|
-
} else attributes.push({
|
|
951
|
-
name: ATTR.underlineStyle,
|
|
952
|
-
value: "none"
|
|
953
|
-
});
|
|
954
|
-
if (properties.strike !== void 0) if (properties.strike) {
|
|
955
|
-
attributes.push({
|
|
956
|
-
name: ATTR.lineThroughStyle,
|
|
957
|
-
value: "solid"
|
|
958
|
-
});
|
|
959
|
-
attributes.push({
|
|
960
|
-
name: ATTR.lineThroughType,
|
|
961
|
-
value: "single"
|
|
962
|
-
});
|
|
963
|
-
} else attributes.push({
|
|
964
|
-
name: ATTR.lineThroughStyle,
|
|
965
|
-
value: "none"
|
|
966
|
-
});
|
|
967
|
-
if (properties.fontFamily !== void 0) attributes.push({
|
|
968
|
-
name: ATTR.fontFamily,
|
|
969
|
-
value: encodeXmlText(properties.fontFamily)
|
|
970
|
-
});
|
|
971
|
-
if (properties.sizePt !== void 0) attributes.push({
|
|
972
|
-
name: ATTR.fontSize,
|
|
973
|
-
value: formatPt(properties.sizePt)
|
|
974
|
-
});
|
|
975
|
-
if (properties.color !== void 0) attributes.push({
|
|
976
|
-
name: ATTR.color,
|
|
977
|
-
value: formatOdfColor(properties.color)
|
|
978
|
-
});
|
|
979
|
-
return attributes;
|
|
980
|
-
}
|
|
981
|
-
function paragraphPropertiesToAttributes(properties) {
|
|
982
|
-
const attributes = [];
|
|
983
|
-
if (properties.alignment !== void 0) attributes.push({
|
|
984
|
-
name: ATTR.textAlign,
|
|
985
|
-
value: properties.alignment
|
|
986
|
-
});
|
|
987
|
-
if (properties.spacingBeforePt !== void 0) attributes.push({
|
|
988
|
-
name: ATTR.marginTop,
|
|
989
|
-
value: formatPt(properties.spacingBeforePt)
|
|
990
|
-
});
|
|
991
|
-
if (properties.spacingAfterPt !== void 0) attributes.push({
|
|
992
|
-
name: ATTR.marginBottom,
|
|
993
|
-
value: formatPt(properties.spacingAfterPt)
|
|
994
|
-
});
|
|
995
|
-
if (properties.lineSpacing !== void 0) attributes.push({
|
|
996
|
-
name: ATTR.lineHeight,
|
|
997
|
-
value: formatPercentageMultiplier(properties.lineSpacing)
|
|
998
|
-
});
|
|
999
|
-
if (properties.indentLeftPt !== void 0) attributes.push({
|
|
1000
|
-
name: ATTR.marginLeft,
|
|
1001
|
-
value: formatPt(properties.indentLeftPt)
|
|
1002
|
-
});
|
|
1003
|
-
if (properties.indentFirstLinePt !== void 0) attributes.push({
|
|
1004
|
-
name: ATTR.textIndent,
|
|
1005
|
-
value: formatPt(properties.indentFirstLinePt)
|
|
1006
|
-
});
|
|
1007
|
-
return attributes;
|
|
1008
|
-
}
|
|
1009
|
-
//#endregion
|
|
1010
|
-
//#region src/styles/serialize.ts
|
|
1011
|
-
function attributesToRecord(attributes) {
|
|
1012
|
-
const record = {};
|
|
1013
|
-
for (const attribute of attributes) record[attribute.name] = attribute.value;
|
|
1014
|
-
return record;
|
|
1015
|
-
}
|
|
1016
|
-
function buildStylePropertyElements(properties) {
|
|
1017
|
-
const elements = [];
|
|
1018
|
-
const paragraphAttributes = paragraphPropertiesToAttributes(properties);
|
|
1019
|
-
if (paragraphAttributes.length > 0) elements.push(el("style:paragraph-properties", attributesToRecord(paragraphAttributes)));
|
|
1020
|
-
const textAttributes = textPropertiesToAttributes(properties);
|
|
1021
|
-
if (textAttributes.length > 0) elements.push(el("style:text-properties", attributesToRecord(textAttributes)));
|
|
1022
|
-
return elements;
|
|
1023
|
-
}
|
|
1024
|
-
function canonicalPropertiesString(properties) {
|
|
1025
|
-
return [...paragraphPropertiesToAttributes(properties), ...textPropertiesToAttributes(properties)].map((attribute) => `${attribute.name}=${attribute.value}`).join("|");
|
|
1026
|
-
}
|
|
1027
|
-
//#endregion
|
|
1028
|
-
//#region src/styles/registry.ts
|
|
1029
|
-
const STYLE_FAMILIES = [
|
|
1030
|
-
"paragraph",
|
|
1031
|
-
"text",
|
|
1032
|
-
"table",
|
|
1033
|
-
"table-column",
|
|
1034
|
-
"table-row",
|
|
1035
|
-
"table-cell",
|
|
1036
|
-
"graphic"
|
|
1037
|
-
];
|
|
1038
|
-
function isStyleFamily(value) {
|
|
1039
|
-
return value === "paragraph" || value === "text" || value === "table" || value === "table-column" || value === "table-row" || value === "table-cell" || value === "graphic";
|
|
1040
|
-
}
|
|
1041
|
-
const CONTENT_PREFIXES = {
|
|
1042
|
-
paragraph: "P",
|
|
1043
|
-
text: "T",
|
|
1044
|
-
table: "ta",
|
|
1045
|
-
"table-column": "co",
|
|
1046
|
-
"table-row": "ro",
|
|
1047
|
-
"table-cell": "ce",
|
|
1048
|
-
graphic: "fr"
|
|
1049
|
-
};
|
|
1050
|
-
const STYLES_PREFIXES = {
|
|
1051
|
-
paragraph: "PS",
|
|
1052
|
-
text: "TS",
|
|
1053
|
-
table: "taS",
|
|
1054
|
-
"table-column": "coS",
|
|
1055
|
-
"table-row": "roS",
|
|
1056
|
-
"table-cell": "ceS",
|
|
1057
|
-
graphic: "frS"
|
|
1058
|
-
};
|
|
1059
|
-
function prefixesForPart(partPath) {
|
|
1060
|
-
const baseName = partPath.slice(partPath.lastIndexOf("/") + 1);
|
|
1061
|
-
if (baseName === "content.xml") return CONTENT_PREFIXES;
|
|
1062
|
-
if (baseName === "styles.xml") return STYLES_PREFIXES;
|
|
1063
|
-
throw new Error(`StyleRegistry.forPart: expected a part named "content.xml" or "styles.xml" (by base name), got "${partPath}"`);
|
|
1064
|
-
}
|
|
1065
|
-
function emptyFamilySets() {
|
|
1066
|
-
return {
|
|
1067
|
-
paragraph: /* @__PURE__ */ new Set(),
|
|
1068
|
-
text: /* @__PURE__ */ new Set(),
|
|
1069
|
-
table: /* @__PURE__ */ new Set(),
|
|
1070
|
-
"table-column": /* @__PURE__ */ new Set(),
|
|
1071
|
-
"table-row": /* @__PURE__ */ new Set(),
|
|
1072
|
-
"table-cell": /* @__PURE__ */ new Set(),
|
|
1073
|
-
graphic: /* @__PURE__ */ new Set()
|
|
1074
|
-
};
|
|
1075
|
-
}
|
|
1076
|
-
function attrValue$1(element, name) {
|
|
1077
|
-
return element.attributes.find((attribute) => attribute.name === name)?.value;
|
|
1078
|
-
}
|
|
1079
|
-
function findDirectChild(nodes, tag) {
|
|
1080
|
-
for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
|
|
1081
|
-
}
|
|
1082
|
-
function findRootElement(nodes) {
|
|
1083
|
-
const root = nodes.find((node) => node.type === "element");
|
|
1084
|
-
if (root === void 0) throw new Error("StyleRegistry: part has no root XML element -- construct the part's minimal root (office:document-content/office:document-styles) before building a StyleRegistry for it");
|
|
1085
|
-
return root;
|
|
1086
|
-
}
|
|
1087
|
-
function ensureAutomaticStyles(root) {
|
|
1088
|
-
const existing = findDirectChild(root.children, "office:automatic-styles");
|
|
1089
|
-
if (existing !== void 0) return existing;
|
|
1090
|
-
const created = el("office:automatic-styles");
|
|
1091
|
-
const insertBeforeTags = /* @__PURE__ */ new Set([
|
|
1092
|
-
"office:body",
|
|
1093
|
-
"office:master-styles",
|
|
1094
|
-
"office:settings"
|
|
1095
|
-
]);
|
|
1096
|
-
const insertIndex = root.children.findIndex((node) => node.type === "element" && insertBeforeTags.has(node.tag));
|
|
1097
|
-
if (insertIndex === -1) root.children.push(created);
|
|
1098
|
-
else root.children.splice(insertIndex, 0, created);
|
|
1099
|
-
return created;
|
|
1100
|
-
}
|
|
1101
|
-
function reserveStyleNames(container, reserved) {
|
|
1102
|
-
for (const child of container.children) {
|
|
1103
|
-
if (child.type !== "element" || child.tag !== "style:style") continue;
|
|
1104
|
-
const name = attrValue$1(child, "style:name");
|
|
1105
|
-
const family = attrValue$1(child, "style:family");
|
|
1106
|
-
if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
|
|
1107
|
-
reserved[family].add(name);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
const FINGERPRINT_SEPARATOR = "\0";
|
|
1111
|
-
const NO_PARENT_SENTINEL = "";
|
|
1112
|
-
function computeFingerprint(family, properties, parentStyleName) {
|
|
1113
|
-
const parentComponent = parentStyleName ?? NO_PARENT_SENTINEL;
|
|
1114
|
-
return [
|
|
1115
|
-
family,
|
|
1116
|
-
canonicalPropertiesString(properties),
|
|
1117
|
-
parentComponent
|
|
1118
|
-
].join(FINGERPRINT_SEPARATOR);
|
|
1119
|
-
}
|
|
1120
|
-
var StyleRegistry = class StyleRegistry {
|
|
1121
|
-
automaticStyles;
|
|
1122
|
-
prefixes;
|
|
1123
|
-
reservedByFamily;
|
|
1124
|
-
knownStyles = /* @__PURE__ */ new Map();
|
|
1125
|
-
fingerprintToName = /* @__PURE__ */ new Map();
|
|
1126
|
-
nameToFingerprint = /* @__PURE__ */ new Map();
|
|
1127
|
-
familyCounters = {
|
|
1128
|
-
paragraph: 1,
|
|
1129
|
-
text: 1,
|
|
1130
|
-
table: 1,
|
|
1131
|
-
"table-column": 1,
|
|
1132
|
-
"table-row": 1,
|
|
1133
|
-
"table-cell": 1,
|
|
1134
|
-
graphic: 1
|
|
1135
|
-
};
|
|
1136
|
-
constructor(automaticStyles, prefixes, reservedByFamily) {
|
|
1137
|
-
this.automaticStyles = automaticStyles;
|
|
1138
|
-
this.prefixes = prefixes;
|
|
1139
|
-
this.reservedByFamily = reservedByFamily;
|
|
1140
|
-
}
|
|
1141
|
-
static forPart(pkg, partPath, options = {}) {
|
|
1142
|
-
const part = pkg.parts[partPath];
|
|
1143
|
-
if (part?.kind !== "xml") throw new Error(`StyleRegistry.forPart: "${partPath}" is not an XML part of the given package`);
|
|
1144
|
-
const prefixes = prefixesForPart(partPath);
|
|
1145
|
-
const root = findRootElement(part.nodes);
|
|
1146
|
-
const automaticStyles = ensureAutomaticStyles(root);
|
|
1147
|
-
const reservedByFamily = emptyFamilySets();
|
|
1148
|
-
const registry = new StyleRegistry(automaticStyles, prefixes, reservedByFamily);
|
|
1149
|
-
for (const child of automaticStyles.children) {
|
|
1150
|
-
if (child.type !== "element" || child.tag !== "style:style") continue;
|
|
1151
|
-
const name = attrValue$1(child, "style:name");
|
|
1152
|
-
const family = attrValue$1(child, "style:family");
|
|
1153
|
-
if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
|
|
1154
|
-
registry.knownStyles.set(name, child);
|
|
1155
|
-
reservedByFamily[family].add(name);
|
|
1156
|
-
const parsed = parseStyleElementProperties(child);
|
|
1157
|
-
if (!parsed.hasUnknown) {
|
|
1158
|
-
const parentStyleName = attrValue$1(child, "style:parent-style-name");
|
|
1159
|
-
const fingerprint = computeFingerprint(family, parsed.properties, parentStyleName);
|
|
1160
|
-
if (!registry.fingerprintToName.has(fingerprint)) {
|
|
1161
|
-
registry.fingerprintToName.set(fingerprint, name);
|
|
1162
|
-
registry.nameToFingerprint.set(name, fingerprint);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
const ownStyles = findDirectChild(root.children, "office:styles");
|
|
1167
|
-
if (ownStyles !== void 0) reserveStyleNames(ownStyles, reservedByFamily);
|
|
1168
|
-
if (options.otherPart !== void 0) {
|
|
1169
|
-
const otherPart = options.otherPart.pkg.parts[options.otherPart.partPath];
|
|
1170
|
-
if (otherPart?.kind === "xml") {
|
|
1171
|
-
const otherRoot = findRootElement(otherPart.nodes);
|
|
1172
|
-
const otherAutomatic = findDirectChild(otherRoot.children, "office:automatic-styles");
|
|
1173
|
-
if (otherAutomatic !== void 0) reserveStyleNames(otherAutomatic, reservedByFamily);
|
|
1174
|
-
const otherStyles = findDirectChild(otherRoot.children, "office:styles");
|
|
1175
|
-
if (otherStyles !== void 0) reserveStyleNames(otherStyles, reservedByFamily);
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
if (options.additionalReservedNames !== void 0) for (const family of STYLE_FAMILIES) for (const name of options.additionalReservedNames) reservedByFamily[family].add(name);
|
|
1179
|
-
return registry;
|
|
1180
|
-
}
|
|
1181
|
-
fingerprint(request) {
|
|
1182
|
-
return computeFingerprint(request.family, request.properties, request.parentStyleName);
|
|
1183
|
-
}
|
|
1184
|
-
intern(request) {
|
|
1185
|
-
const fingerprint = this.fingerprint(request);
|
|
1186
|
-
const existingName = this.fingerprintToName.get(fingerprint);
|
|
1187
|
-
if (existingName !== void 0) return existingName;
|
|
1188
|
-
const name = this.mintName(request.family);
|
|
1189
|
-
const attributes = {
|
|
1190
|
-
"style:name": name,
|
|
1191
|
-
"style:family": request.family
|
|
1192
|
-
};
|
|
1193
|
-
if (request.parentStyleName !== void 0) attributes["style:parent-style-name"] = encodeXmlText(request.parentStyleName);
|
|
1194
|
-
const styleElement = el("style:style", attributes, buildStylePropertyElements(request.properties));
|
|
1195
|
-
this.automaticStyles.children.push(styleElement);
|
|
1196
|
-
this.knownStyles.set(name, styleElement);
|
|
1197
|
-
this.reservedByFamily[request.family].add(name);
|
|
1198
|
-
this.fingerprintToName.set(fingerprint, name);
|
|
1199
|
-
this.nameToFingerprint.set(name, fingerprint);
|
|
1200
|
-
return name;
|
|
1201
|
-
}
|
|
1202
|
-
mintName(family) {
|
|
1203
|
-
const prefix = this.prefixes[family];
|
|
1204
|
-
const reserved = this.reservedByFamily[family];
|
|
1205
|
-
let counter = this.familyCounters[family];
|
|
1206
|
-
while (reserved.has(`${prefix}${counter}`)) counter += 1;
|
|
1207
|
-
const name = `${prefix}${counter}`;
|
|
1208
|
-
this.familyCounters[family] = counter + 1;
|
|
1209
|
-
return name;
|
|
1210
|
-
}
|
|
1211
|
-
names() {
|
|
1212
|
-
return [...this.knownStyles.keys()];
|
|
1213
|
-
}
|
|
1214
|
-
gc(referenced) {
|
|
1215
|
-
let removed = 0;
|
|
1216
|
-
for (const [name, element] of [...this.knownStyles]) {
|
|
1217
|
-
if (referenced.has(name)) continue;
|
|
1218
|
-
const index = this.automaticStyles.children.indexOf(element);
|
|
1219
|
-
if (index !== -1) this.automaticStyles.children.splice(index, 1);
|
|
1220
|
-
this.knownStyles.delete(name);
|
|
1221
|
-
const fingerprint = this.nameToFingerprint.get(name);
|
|
1222
|
-
if (fingerprint !== void 0) {
|
|
1223
|
-
this.fingerprintToName.delete(fingerprint);
|
|
1224
|
-
this.nameToFingerprint.delete(name);
|
|
1225
|
-
}
|
|
1226
|
-
removed += 1;
|
|
1227
|
-
}
|
|
1228
|
-
return removed;
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
//#endregion
|
|
1232
|
-
//#region src/xml/query.ts
|
|
1233
|
-
function rootElement(nodes) {
|
|
1234
|
-
for (const node of nodes) if (node.type === "element") return node;
|
|
1235
|
-
}
|
|
1236
|
-
function findChildElement(nodes, tag) {
|
|
1237
|
-
for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
|
|
1238
|
-
}
|
|
1239
|
-
function childrenWithTag(element, tag) {
|
|
1240
|
-
const out = [];
|
|
1241
|
-
for (const child of element.children) if (child.type === "element" && child.tag === tag) out.push(child);
|
|
1242
|
-
return out;
|
|
1243
|
-
}
|
|
1244
|
-
function* walk(nodes) {
|
|
1245
|
-
for (const node of nodes) {
|
|
1246
|
-
yield node;
|
|
1247
|
-
if (node.type === "element") yield* walk(node.children);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
function elementsWithTag(nodes, tag) {
|
|
1251
|
-
const out = [];
|
|
1252
|
-
for (const node of walk(nodes)) if (node.type === "element" && node.tag === tag) out.push(node);
|
|
1253
|
-
return out;
|
|
1254
|
-
}
|
|
1255
|
-
function attrValue(element, name) {
|
|
1256
|
-
return element.attributes.find((attribute) => attribute.name === name)?.value;
|
|
1257
|
-
}
|
|
1258
|
-
//#endregion
|
|
1259
|
-
//#region src/typed/shared/text.ts
|
|
1260
|
-
function getOdfSpaceCount(element) {
|
|
1261
|
-
const raw = attrValue(element, "text:c");
|
|
1262
|
-
if (raw === void 0) return 1;
|
|
1263
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1264
|
-
if (!Number.isInteger(parsed) || parsed < 0 || String(parsed) !== raw) throw new Error(`getOdfSpaceCount: text:s has a malformed text:c attribute: "${raw}"`);
|
|
1265
|
-
return parsed;
|
|
1266
|
-
}
|
|
1267
|
-
function measureOdfNodeLength(node) {
|
|
1268
|
-
if (node.type === "text") return node.value.length;
|
|
1269
|
-
if (node.type !== "element") return 0;
|
|
1270
|
-
if (node.tag === "text:s") return getOdfSpaceCount(node);
|
|
1271
|
-
if (node.tag === "text:tab" || node.tag === "text:line-break") return 1;
|
|
1272
|
-
if (node.tag === "text:span") return sumOdfNodeLength(node.children);
|
|
1273
|
-
return 0;
|
|
1274
|
-
}
|
|
1275
|
-
function sumOdfNodeLength(nodes) {
|
|
1276
|
-
let total = 0;
|
|
1277
|
-
for (const node of nodes) total += measureOdfNodeLength(node);
|
|
1278
|
-
return total;
|
|
1279
|
-
}
|
|
1280
|
-
function decodeOdfNode(node) {
|
|
1281
|
-
if (node.type === "text") return decodeXmlText(node.value);
|
|
1282
|
-
if (node.type !== "element") return "";
|
|
1283
|
-
if (node.tag === "text:s") return " ".repeat(getOdfSpaceCount(node));
|
|
1284
|
-
if (node.tag === "text:tab") return " ";
|
|
1285
|
-
if (node.tag === "text:line-break") return "\n";
|
|
1286
|
-
if (node.tag === "text:span") return decodeOdfText(node);
|
|
1287
|
-
return "";
|
|
1288
|
-
}
|
|
1289
|
-
function decodeOdfText(container) {
|
|
1290
|
-
let text = "";
|
|
1291
|
-
for (const child of container.children) text += decodeOdfNode(child);
|
|
1292
|
-
return text;
|
|
1293
|
-
}
|
|
1294
|
-
//#endregion
|
|
1295
|
-
//#region src/styles/span.ts
|
|
1296
|
-
function ensureSpan(paragraph, start, end, styleName) {
|
|
1297
|
-
if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) throw new Error(`ensureSpan: invalid range [${start}, ${end})`);
|
|
1298
|
-
const total = sumOdfNodeLength(paragraph.children);
|
|
1299
|
-
if (end > total) throw new Error(`ensureSpan: range end ${end} exceeds the container's total character length ${total}`);
|
|
1300
|
-
const { before, after: rest } = splitChildrenAt(paragraph.children, start);
|
|
1301
|
-
const { before: middle, after } = splitChildrenAt(rest, end - start);
|
|
1302
|
-
let span;
|
|
1303
|
-
const soleChild = middle.length === 1 ? middle[0] : void 0;
|
|
1304
|
-
if (soleChild?.type === "element" && soleChild.tag === "text:span") {
|
|
1305
|
-
span = soleChild;
|
|
1306
|
-
setStyleName(span, styleName);
|
|
1307
|
-
} else span = el("text:span", { "text:style-name": encodeXmlText(styleName) }, middle);
|
|
1308
|
-
paragraph.children = [
|
|
1309
|
-
...before,
|
|
1310
|
-
span,
|
|
1311
|
-
...after
|
|
1312
|
-
];
|
|
1313
|
-
return span;
|
|
1314
|
-
}
|
|
1315
|
-
function cloneAttributes(attributes) {
|
|
1316
|
-
return attributes.map((attribute) => ({ ...attribute }));
|
|
1317
|
-
}
|
|
1318
|
-
function setStyleName(span, styleName) {
|
|
1319
|
-
const encoded = encodeXmlText(styleName);
|
|
1320
|
-
const existing = span.attributes.find((attribute) => attribute.name === "text:style-name");
|
|
1321
|
-
if (existing !== void 0) {
|
|
1322
|
-
existing.value = encoded;
|
|
1323
|
-
return;
|
|
1324
|
-
}
|
|
1325
|
-
span.attributes.push({
|
|
1326
|
-
name: "text:style-name",
|
|
1327
|
-
value: encoded
|
|
1328
|
-
});
|
|
1329
|
-
}
|
|
1330
|
-
function buildSpaceRun(count) {
|
|
1331
|
-
return count === 1 ? el("text:s") : el("text:s", { "text:c": String(count) });
|
|
1332
|
-
}
|
|
1333
|
-
function splitNode(node, offset) {
|
|
1334
|
-
if (node.type === "text") return {
|
|
1335
|
-
left: {
|
|
1336
|
-
type: "text",
|
|
1337
|
-
value: node.value.slice(0, offset)
|
|
1338
|
-
},
|
|
1339
|
-
right: {
|
|
1340
|
-
type: "text",
|
|
1341
|
-
value: node.value.slice(offset)
|
|
1342
|
-
}
|
|
1343
|
-
};
|
|
1344
|
-
if (node.type === "element" && node.tag === "text:s") {
|
|
1345
|
-
const count = getOdfSpaceCount(node);
|
|
1346
|
-
return {
|
|
1347
|
-
left: buildSpaceRun(offset),
|
|
1348
|
-
right: buildSpaceRun(count - offset)
|
|
1349
|
-
};
|
|
1350
|
-
}
|
|
1351
|
-
if (node.type === "element" && node.tag === "text:span") {
|
|
1352
|
-
const inner = splitChildrenAt(node.children, offset);
|
|
1353
|
-
return {
|
|
1354
|
-
left: inner.before.length === 0 ? void 0 : {
|
|
1355
|
-
...node,
|
|
1356
|
-
attributes: cloneAttributes(node.attributes),
|
|
1357
|
-
children: inner.before
|
|
1358
|
-
},
|
|
1359
|
-
right: inner.after.length === 0 ? void 0 : {
|
|
1360
|
-
...node,
|
|
1361
|
-
attributes: cloneAttributes(node.attributes),
|
|
1362
|
-
children: inner.after
|
|
1363
|
-
}
|
|
1364
|
-
};
|
|
1365
|
-
}
|
|
1366
|
-
const label = node.type === "element" ? node.tag : node.type;
|
|
1367
|
-
throw new Error(`ensureSpan: cannot split "${label}" at a fractional offset -- this indicates a character-length computation bug, since every node type with length 1 or 0 should never reach this branch`);
|
|
1368
|
-
}
|
|
1369
|
-
function splitChildrenAt(children, offset) {
|
|
1370
|
-
if (offset <= 0) return {
|
|
1371
|
-
before: [],
|
|
1372
|
-
after: [...children]
|
|
1373
|
-
};
|
|
1374
|
-
const before = [];
|
|
1375
|
-
let remaining = offset;
|
|
1376
|
-
for (let index = 0; index < children.length; index += 1) {
|
|
1377
|
-
if (remaining === 0) return {
|
|
1378
|
-
before,
|
|
1379
|
-
after: children.slice(index)
|
|
1380
|
-
};
|
|
1381
|
-
const node = children[index];
|
|
1382
|
-
const length = measureOdfNodeLength(node);
|
|
1383
|
-
if (remaining >= length) {
|
|
1384
|
-
before.push(node);
|
|
1385
|
-
remaining -= length;
|
|
1386
|
-
continue;
|
|
1387
|
-
}
|
|
1388
|
-
const { left, right } = splitNode(node, remaining);
|
|
1389
|
-
const after = [];
|
|
1390
|
-
if (left !== void 0) before.push(left);
|
|
1391
|
-
if (right !== void 0) after.push(right);
|
|
1392
|
-
after.push(...children.slice(index + 1));
|
|
1393
|
-
return {
|
|
1394
|
-
before,
|
|
1395
|
-
after
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
return {
|
|
1399
|
-
before,
|
|
1400
|
-
after: []
|
|
1401
|
-
};
|
|
1402
|
-
}
|
|
1403
|
-
//#endregion
|
|
1404
|
-
//#region src/typed/shared/a1.ts
|
|
1405
|
-
const ALPHABET_SIZE = 26;
|
|
1406
|
-
const ALPHABET_START_CODE = "A".charCodeAt(0);
|
|
1407
|
-
function columnIndexToLetters(index) {
|
|
1408
|
-
if (!Number.isInteger(index) || index < 0) throw new Error(`columnIndexToLetters: index must be a non-negative integer, got ${index}`);
|
|
1409
|
-
let remaining = index + 1;
|
|
1410
|
-
let letters = "";
|
|
1411
|
-
while (remaining > 0) {
|
|
1412
|
-
const digit = (remaining - 1) % ALPHABET_SIZE;
|
|
1413
|
-
letters = String.fromCharCode(ALPHABET_START_CODE + digit) + letters;
|
|
1414
|
-
remaining = Math.floor((remaining - 1) / ALPHABET_SIZE);
|
|
1415
|
-
}
|
|
1416
|
-
return letters;
|
|
1417
|
-
}
|
|
1418
|
-
function cellReference(columnIndex, rowIndex) {
|
|
1419
|
-
if (!Number.isInteger(rowIndex) || rowIndex < 0) throw new Error(`cellReference: rowIndex must be a non-negative integer, got ${rowIndex}`);
|
|
1420
|
-
return `${columnIndexToLetters(columnIndex)}${rowIndex + 1}`;
|
|
1421
|
-
}
|
|
1422
|
-
function columnLettersToIndex(letters) {
|
|
1423
|
-
if (!/^[A-Z]+$/.test(letters)) return;
|
|
1424
|
-
let index = 0;
|
|
1425
|
-
for (const char of letters) index = index * ALPHABET_SIZE + (char.charCodeAt(0) - ALPHABET_START_CODE + 1);
|
|
1426
|
-
return index - 1;
|
|
1427
|
-
}
|
|
1428
|
-
function parseCellReference(reference) {
|
|
1429
|
-
const match = /^([A-Z]+)(\d+)$/.exec(reference);
|
|
1430
|
-
if (match === null) return;
|
|
1431
|
-
const [, letters, digits] = match;
|
|
1432
|
-
if (letters === void 0 || digits === void 0) return;
|
|
1433
|
-
const column = columnLettersToIndex(letters);
|
|
1434
|
-
const row = Number.parseInt(digits, 10) - 1;
|
|
1435
|
-
if (column === void 0 || row < 0) return;
|
|
1436
|
-
return {
|
|
1437
|
-
column,
|
|
1438
|
-
row
|
|
1439
|
-
};
|
|
1440
|
-
}
|
|
1441
|
-
function validateRepeatCount(repeatCount, caller) {
|
|
1442
|
-
if (!Number.isInteger(repeatCount) || repeatCount < 1) throw new Error(`${caller}: repeatCount must be a positive integer, got ${repeatCount}`);
|
|
1443
|
-
}
|
|
1444
|
-
var TableCursor = class {
|
|
1445
|
-
columnCursor = 0;
|
|
1446
|
-
rowCursor = 0;
|
|
1447
|
-
get columnIndex() {
|
|
1448
|
-
return this.columnCursor;
|
|
1449
|
-
}
|
|
1450
|
-
get rowIndex() {
|
|
1451
|
-
return this.rowCursor;
|
|
1452
|
-
}
|
|
1453
|
-
nextCell(repeatCount = 1) {
|
|
1454
|
-
validateRepeatCount(repeatCount, "TableCursor.nextCell");
|
|
1455
|
-
const reference = cellReference(this.columnCursor, this.rowCursor);
|
|
1456
|
-
this.columnCursor += repeatCount;
|
|
1457
|
-
return reference;
|
|
1458
|
-
}
|
|
1459
|
-
nextRow(repeatCount = 1) {
|
|
1460
|
-
validateRepeatCount(repeatCount, "TableCursor.nextRow");
|
|
1461
|
-
this.rowCursor += repeatCount;
|
|
1462
|
-
this.columnCursor = 0;
|
|
1463
|
-
}
|
|
1464
|
-
};
|
|
1465
|
-
//#endregion
|
|
1466
|
-
//#region src/typed/shared/geometry.ts
|
|
1467
|
-
function parsePageSize(pageLayoutProperties) {
|
|
1468
|
-
const widthValue = attrValue(pageLayoutProperties, "fo:page-width");
|
|
1469
|
-
const heightValue = attrValue(pageLayoutProperties, "fo:page-height");
|
|
1470
|
-
if (widthValue === void 0 || heightValue === void 0) return;
|
|
1471
|
-
const widthPt = parseOdfLength(widthValue);
|
|
1472
|
-
const heightPt = parseOdfLength(heightValue);
|
|
1473
|
-
if (widthPt === void 0 || heightPt === void 0) return;
|
|
1474
|
-
return {
|
|
1475
|
-
widthPt,
|
|
1476
|
-
heightPt
|
|
1477
|
-
};
|
|
1478
|
-
}
|
|
1479
|
-
function parseMargins(pageLayoutProperties) {
|
|
1480
|
-
const topValue = attrValue(pageLayoutProperties, "fo:margin-top");
|
|
1481
|
-
const rightValue = attrValue(pageLayoutProperties, "fo:margin-right");
|
|
1482
|
-
const bottomValue = attrValue(pageLayoutProperties, "fo:margin-bottom");
|
|
1483
|
-
const leftValue = attrValue(pageLayoutProperties, "fo:margin-left");
|
|
1484
|
-
if (topValue === void 0 || rightValue === void 0 || bottomValue === void 0 || leftValue === void 0) return;
|
|
1485
|
-
const topPt = parseOdfLength(topValue);
|
|
1486
|
-
const rightPt = parseOdfLength(rightValue);
|
|
1487
|
-
const bottomPt = parseOdfLength(bottomValue);
|
|
1488
|
-
const leftPt = parseOdfLength(leftValue);
|
|
1489
|
-
if (topPt === void 0 || rightPt === void 0 || bottomPt === void 0 || leftPt === void 0) return;
|
|
1490
|
-
return {
|
|
1491
|
-
topPt,
|
|
1492
|
-
rightPt,
|
|
1493
|
-
bottomPt,
|
|
1494
|
-
leftPt
|
|
1495
|
-
};
|
|
1496
|
-
}
|
|
1497
|
-
function parseBox(element) {
|
|
1498
|
-
const xValue = attrValue(element, "svg:x");
|
|
1499
|
-
const yValue = attrValue(element, "svg:y");
|
|
1500
|
-
const widthValue = attrValue(element, "svg:width");
|
|
1501
|
-
const heightValue = attrValue(element, "svg:height");
|
|
1502
|
-
if (xValue === void 0 || yValue === void 0 || widthValue === void 0 || heightValue === void 0) return;
|
|
1503
|
-
const xPt = parseOdfLength(xValue);
|
|
1504
|
-
const yPt = parseOdfLength(yValue);
|
|
1505
|
-
const widthPt = parseOdfLength(widthValue);
|
|
1506
|
-
const heightPt = parseOdfLength(heightValue);
|
|
1507
|
-
if (xPt === void 0 || yPt === void 0 || widthPt === void 0 || heightPt === void 0) return;
|
|
1508
|
-
return {
|
|
1509
|
-
xPt,
|
|
1510
|
-
yPt,
|
|
1511
|
-
widthPt,
|
|
1512
|
-
heightPt
|
|
1513
|
-
};
|
|
1514
|
-
}
|
|
1515
|
-
function parseLinePoints(element) {
|
|
1516
|
-
const x1Value = attrValue(element, "svg:x1");
|
|
1517
|
-
const y1Value = attrValue(element, "svg:y1");
|
|
1518
|
-
const x2Value = attrValue(element, "svg:x2");
|
|
1519
|
-
const y2Value = attrValue(element, "svg:y2");
|
|
1520
|
-
if (x1Value === void 0 || y1Value === void 0 || x2Value === void 0 || y2Value === void 0) return;
|
|
1521
|
-
const x1Pt = parseOdfLength(x1Value);
|
|
1522
|
-
const y1Pt = parseOdfLength(y1Value);
|
|
1523
|
-
const x2Pt = parseOdfLength(x2Value);
|
|
1524
|
-
const y2Pt = parseOdfLength(y2Value);
|
|
1525
|
-
if (x1Pt === void 0 || y1Pt === void 0 || x2Pt === void 0 || y2Pt === void 0) return;
|
|
1526
|
-
return {
|
|
1527
|
-
from: {
|
|
1528
|
-
xPt: x1Pt,
|
|
1529
|
-
yPt: y1Pt
|
|
1530
|
-
},
|
|
1531
|
-
to: {
|
|
1532
|
-
xPt: x2Pt,
|
|
1533
|
-
yPt: y2Pt
|
|
1534
|
-
}
|
|
1535
|
-
};
|
|
1536
|
-
}
|
|
1537
|
-
//#endregion
|
|
1538
|
-
//#region src/typed/shared/cascade.ts
|
|
1539
|
-
const STYLE_PARTS = ["content.xml", "styles.xml"];
|
|
1540
|
-
const NAME_KEY_SEPARATOR = "\0";
|
|
1541
|
-
function nameKey(family, name) {
|
|
1542
|
-
return `${family}${NAME_KEY_SEPARATOR}${name}`;
|
|
1543
|
-
}
|
|
1544
|
-
function collectStyles(pkg) {
|
|
1545
|
-
const byName = /* @__PURE__ */ new Map();
|
|
1546
|
-
const defaultByFamily = /* @__PURE__ */ new Map();
|
|
1547
|
-
for (const partPath of STYLE_PARTS) {
|
|
1548
|
-
const part = pkg.parts[partPath];
|
|
1549
|
-
if (part?.kind !== "xml") continue;
|
|
1550
|
-
const root = rootElement(part.nodes);
|
|
1551
|
-
if (root === void 0) continue;
|
|
1552
|
-
for (const containerTag of ["office:automatic-styles", "office:styles"]) {
|
|
1553
|
-
const container = findChildElement(root.children, containerTag);
|
|
1554
|
-
if (container === void 0) continue;
|
|
1555
|
-
for (const child of container.children) {
|
|
1556
|
-
if (child.type !== "element") continue;
|
|
1557
|
-
if (child.tag === "style:style") {
|
|
1558
|
-
const name = attrValue(child, "style:name");
|
|
1559
|
-
const family = attrValue(child, "style:family");
|
|
1560
|
-
if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
|
|
1561
|
-
byName.set(nameKey(family, name), child);
|
|
1562
|
-
} else if (child.tag === "style:default-style") {
|
|
1563
|
-
const family = attrValue(child, "style:family");
|
|
1564
|
-
if (family === void 0 || !isStyleFamily(family)) continue;
|
|
1565
|
-
if (!defaultByFamily.has(family)) defaultByFamily.set(family, child);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
return {
|
|
1571
|
-
byName,
|
|
1572
|
-
defaultByFamily
|
|
1573
|
-
};
|
|
1574
|
-
}
|
|
1575
|
-
function resolveStyleElementChain(styleName, family, pkg) {
|
|
1576
|
-
const { byName, defaultByFamily } = collectStyles(pkg);
|
|
1577
|
-
const diagnostics = [];
|
|
1578
|
-
const elements = [];
|
|
1579
|
-
const defaultElement = defaultByFamily.get(family);
|
|
1580
|
-
if (defaultElement !== void 0) elements.push(defaultElement);
|
|
1581
|
-
if (styleName === void 0) return {
|
|
1582
|
-
elements,
|
|
1583
|
-
diagnostics
|
|
1584
|
-
};
|
|
1585
|
-
const chain = [];
|
|
1586
|
-
const visited = /* @__PURE__ */ new Set();
|
|
1587
|
-
let currentName = styleName;
|
|
1588
|
-
while (currentName !== void 0) {
|
|
1589
|
-
const key = nameKey(family, currentName);
|
|
1590
|
-
if (visited.has(key)) {
|
|
1591
|
-
diagnostics.push({
|
|
1592
|
-
severity: "warning",
|
|
1593
|
-
message: `cyclic style:parent-style-name chain detected at style "${currentName}" (family "${family}") -- breaking the cycle and stopping cascade resolution at this point`
|
|
1594
|
-
});
|
|
1595
|
-
break;
|
|
1596
|
-
}
|
|
1597
|
-
visited.add(key);
|
|
1598
|
-
const element = byName.get(key);
|
|
1599
|
-
if (element === void 0) {
|
|
1600
|
-
diagnostics.push({
|
|
1601
|
-
severity: "warning",
|
|
1602
|
-
message: `style "${currentName}" (family "${family}") was not found in content.xml or styles.xml -- stopping cascade resolution at this point`
|
|
1603
|
-
});
|
|
1604
|
-
break;
|
|
1605
|
-
}
|
|
1606
|
-
chain.push(element);
|
|
1607
|
-
currentName = attrValue(element, "style:parent-style-name");
|
|
1608
|
-
}
|
|
1609
|
-
chain.reverse();
|
|
1610
|
-
elements.push(...chain);
|
|
1611
|
-
return {
|
|
1612
|
-
elements,
|
|
1613
|
-
diagnostics
|
|
1614
|
-
};
|
|
1615
|
-
}
|
|
1616
|
-
function resolveStyle(styleName, family, pkg) {
|
|
1617
|
-
const { elements, diagnostics } = resolveStyleElementChain(styleName, family, pkg);
|
|
1618
|
-
let properties = {};
|
|
1619
|
-
for (const element of elements) properties = {
|
|
1620
|
-
...properties,
|
|
1621
|
-
...parseStyleElementProperties(element).properties
|
|
1622
|
-
};
|
|
1623
|
-
return {
|
|
1624
|
-
properties,
|
|
1625
|
-
diagnostics
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
function findStyleElement(styleName, family, pkg) {
|
|
1629
|
-
const { byName } = collectStyles(pkg);
|
|
1630
|
-
return byName.get(nameKey(family, styleName));
|
|
1631
|
-
}
|
|
1632
|
-
//#endregion
|
|
1633
|
-
//#region src/typed/shared/metadata.ts
|
|
1634
|
-
const META_PART = "meta.xml";
|
|
1635
|
-
function elementText(element) {
|
|
1636
|
-
let text = "";
|
|
1637
|
-
for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
|
|
1638
|
-
return text;
|
|
1639
|
-
}
|
|
1640
|
-
function firstElementText(container, tag) {
|
|
1641
|
-
const element = childrenWithTag(container, tag)[0];
|
|
1642
|
-
if (element === void 0) return;
|
|
1643
|
-
const text = elementText(element);
|
|
1644
|
-
return text.length > 0 ? text : void 0;
|
|
1645
|
-
}
|
|
1646
|
-
function readOdfMetadata(pkg) {
|
|
1647
|
-
const part = pkg.parts[META_PART];
|
|
1648
|
-
if (part?.kind !== "xml") return {};
|
|
1649
|
-
const root = rootElement(part.nodes);
|
|
1650
|
-
const meta = root === void 0 ? void 0 : findChildElement(root.children, "office:meta");
|
|
1651
|
-
if (meta === void 0) return {};
|
|
1652
|
-
const metadata = {};
|
|
1653
|
-
const title = firstElementText(meta, "dc:title");
|
|
1654
|
-
if (title !== void 0) metadata.title = title;
|
|
1655
|
-
const author = firstElementText(meta, "meta:initial-creator");
|
|
1656
|
-
if (author !== void 0) metadata.author = author;
|
|
1657
|
-
const subject = firstElementText(meta, "dc:subject");
|
|
1658
|
-
if (subject !== void 0) metadata.subject = subject;
|
|
1659
|
-
const keywords = childrenWithTag(meta, "meta:keyword").map(elementText).filter((keyword) => keyword.length > 0);
|
|
1660
|
-
if (keywords.length > 0) metadata.keywords = keywords;
|
|
1661
|
-
const creator = firstElementText(meta, "meta:generator");
|
|
1662
|
-
if (creator !== void 0) metadata.creator = creator;
|
|
1663
|
-
const createdIso = firstElementText(meta, "meta:creation-date");
|
|
1664
|
-
if (createdIso !== void 0) metadata.createdIso = createdIso;
|
|
1665
|
-
const modifiedIso = firstElementText(meta, "dc:date");
|
|
1666
|
-
if (modifiedIso !== void 0) metadata.modifiedIso = modifiedIso;
|
|
1667
|
-
return metadata;
|
|
1668
|
-
}
|
|
1669
|
-
//#endregion
|
|
1670
|
-
//#region src/typed/shared/paragraph.ts
|
|
1671
|
-
function collectRuns(nodes, baseProperties, pkg, out) {
|
|
1672
|
-
for (const node of nodes) {
|
|
1673
|
-
if (node.type === "text") {
|
|
1674
|
-
if (node.value.length > 0) out.push(runFromText(decodeXmlText(node.value), baseProperties));
|
|
1675
|
-
continue;
|
|
1676
|
-
}
|
|
1677
|
-
if (node.type !== "element") continue;
|
|
1678
|
-
if (node.tag === "text:s") out.push(runFromText(" ".repeat(getOdfSpaceCount(node)), baseProperties));
|
|
1679
|
-
else if (node.tag === "text:tab") out.push(runFromText(" ", baseProperties));
|
|
1680
|
-
else if (node.tag === "text:line-break") out.push(runFromText("\n", baseProperties));
|
|
1681
|
-
else if (node.tag === "text:span") {
|
|
1682
|
-
const styleName = attrValue(node, "text:style-name");
|
|
1683
|
-
const spanProperties = {
|
|
1684
|
-
...baseProperties,
|
|
1685
|
-
...resolveStyle(styleName, "text", pkg).properties
|
|
1686
|
-
};
|
|
1687
|
-
collectRuns(node.children, spanProperties, pkg, out);
|
|
1688
|
-
}
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
function runFromText(text, properties) {
|
|
1692
|
-
return {
|
|
1693
|
-
text,
|
|
1694
|
-
bold: properties.bold,
|
|
1695
|
-
italic: properties.italic,
|
|
1696
|
-
underline: properties.underline,
|
|
1697
|
-
strike: properties.strike,
|
|
1698
|
-
fontFamily: properties.fontFamily,
|
|
1699
|
-
sizePt: properties.sizePt,
|
|
1700
|
-
color: properties.color
|
|
1701
|
-
};
|
|
1702
|
-
}
|
|
1703
|
-
function readOdfParagraph(pElement, pkg) {
|
|
1704
|
-
const styleName = attrValue(pElement, "text:style-name");
|
|
1705
|
-
const paragraphProperties = resolveStyle(styleName, "paragraph", pkg).properties;
|
|
1706
|
-
const runs = [];
|
|
1707
|
-
collectRuns(pElement.children, paragraphProperties, pkg, runs);
|
|
1708
|
-
return {
|
|
1709
|
-
kind: "paragraph",
|
|
1710
|
-
runs,
|
|
1711
|
-
styleId: styleName,
|
|
1712
|
-
alignment: paragraphProperties.alignment,
|
|
1713
|
-
spacingBeforePt: paragraphProperties.spacingBeforePt,
|
|
1714
|
-
spacingAfterPt: paragraphProperties.spacingAfterPt,
|
|
1715
|
-
lineSpacing: paragraphProperties.lineSpacing,
|
|
1716
|
-
indentLeftPt: paragraphProperties.indentLeftPt,
|
|
1717
|
-
indentFirstLinePt: paragraphProperties.indentFirstLinePt
|
|
1718
|
-
};
|
|
1719
|
-
}
|
|
1720
|
-
//#endregion
|
|
1721
|
-
//#region src/typed/shared/table.ts
|
|
1722
|
-
function readRepeatCount$1(element, attrName) {
|
|
1723
|
-
const raw = attrValue(element, attrName);
|
|
1724
|
-
if (raw === void 0) return 1;
|
|
1725
|
-
const parsed = Number.parseInt(raw, 10);
|
|
1726
|
-
return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
|
|
1727
|
-
}
|
|
1728
|
-
function resolveColumnWidthPt(columnElement, pkg) {
|
|
1729
|
-
const styleName = attrValue(columnElement, "table:style-name");
|
|
1730
|
-
const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-column", pkg);
|
|
1731
|
-
const props = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-column-properties")[0];
|
|
1732
|
-
const widthValue = props === void 0 ? void 0 : attrValue(props, "style:column-width");
|
|
1733
|
-
return widthValue === void 0 ? 0 : parseOdfLength(widthValue) ?? 0;
|
|
1734
|
-
}
|
|
1735
|
-
function resolveRowHeightPt(rowElement, pkg) {
|
|
1736
|
-
const styleName = attrValue(rowElement, "table:style-name");
|
|
1737
|
-
const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-row", pkg);
|
|
1738
|
-
const props = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-row-properties")[0];
|
|
1739
|
-
const heightValue = props === void 0 ? void 0 : attrValue(props, "style:row-height");
|
|
1740
|
-
return heightValue === void 0 ? void 0 : parseOdfLength(heightValue);
|
|
1741
|
-
}
|
|
1742
|
-
function readTableCellBackground(cellElement, pkg) {
|
|
1743
|
-
const styleName = attrValue(cellElement, "table:style-name");
|
|
1744
|
-
const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-cell", pkg);
|
|
1745
|
-
const props = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-cell-properties")[0];
|
|
1746
|
-
const value = props === void 0 ? void 0 : attrValue(props, "fo:background-color");
|
|
1747
|
-
return value === void 0 ? void 0 : parseOdfColor(value);
|
|
1748
|
-
}
|
|
1749
|
-
function readTableCell(cellElement, pkg) {
|
|
1750
|
-
const blocks = childrenWithTag(cellElement, "text:p").map((p) => readOdfParagraph(p, pkg));
|
|
1751
|
-
const colSpanRaw = attrValue(cellElement, "table:number-columns-spanned");
|
|
1752
|
-
const rowSpanRaw = attrValue(cellElement, "table:number-rows-spanned");
|
|
1753
|
-
return {
|
|
1754
|
-
blocks,
|
|
1755
|
-
colSpan: colSpanRaw === void 0 ? void 0 : Number.parseInt(colSpanRaw, 10),
|
|
1756
|
-
rowSpan: rowSpanRaw === void 0 ? void 0 : Number.parseInt(rowSpanRaw, 10),
|
|
1757
|
-
background: readTableCellBackground(cellElement, pkg)
|
|
1758
|
-
};
|
|
1759
|
-
}
|
|
1760
|
-
function readTableRow(rowElement, pkg) {
|
|
1761
|
-
const cells = [];
|
|
1762
|
-
for (const child of rowElement.children) {
|
|
1763
|
-
if (child.type !== "element") continue;
|
|
1764
|
-
if (child.tag === "table:covered-table-cell") {
|
|
1765
|
-
const repeat = readRepeatCount$1(child, "table:number-columns-repeated");
|
|
1766
|
-
for (let i = 0; i < repeat; i++) cells.push({ blocks: [] });
|
|
1767
|
-
} else if (child.tag === "table:table-cell") {
|
|
1768
|
-
const cell = readTableCell(child, pkg);
|
|
1769
|
-
const repeat = readRepeatCount$1(child, "table:number-columns-repeated");
|
|
1770
|
-
for (let i = 0; i < repeat; i++) cells.push(cell);
|
|
1771
|
-
}
|
|
1772
|
-
}
|
|
1773
|
-
return {
|
|
1774
|
-
cells,
|
|
1775
|
-
heightPt: resolveRowHeightPt(rowElement, pkg)
|
|
1776
|
-
};
|
|
1777
|
-
}
|
|
1778
|
-
function readOdfTable(tableElement, pkg) {
|
|
1779
|
-
const columnWidthsPt = [];
|
|
1780
|
-
for (const column of childrenWithTag(tableElement, "table:table-column")) {
|
|
1781
|
-
const widthPt = resolveColumnWidthPt(column, pkg);
|
|
1782
|
-
const repeat = readRepeatCount$1(column, "table:number-columns-repeated");
|
|
1783
|
-
for (let i = 0; i < repeat; i++) columnWidthsPt.push(widthPt);
|
|
1784
|
-
}
|
|
1785
|
-
const rows = [];
|
|
1786
|
-
for (const rowElement of childrenWithTag(tableElement, "table:table-row")) {
|
|
1787
|
-
const row = readTableRow(rowElement, pkg);
|
|
1788
|
-
const repeat = readRepeatCount$1(rowElement, "table:number-rows-repeated");
|
|
1789
|
-
for (let i = 0; i < repeat; i++) rows.push(row);
|
|
1790
|
-
}
|
|
1791
|
-
return {
|
|
1792
|
-
kind: "table",
|
|
1793
|
-
rows,
|
|
1794
|
-
columnWidthsPt
|
|
1795
|
-
};
|
|
1796
|
-
}
|
|
1797
|
-
//#endregion
|
|
1798
|
-
//#region src/typed/shared/transform.ts
|
|
1799
|
-
const FUNCTION_PATTERN = /([a-zA-Z]+)\s*\(\s*([^)]*?)\s*\)/g;
|
|
1800
|
-
function parseOdfTransform(value) {
|
|
1801
|
-
const functions = [];
|
|
1802
|
-
for (const match of value.matchAll(FUNCTION_PATTERN)) {
|
|
1803
|
-
const name = match[1];
|
|
1804
|
-
const argsRaw = match[2];
|
|
1805
|
-
if (name === void 0 || argsRaw === void 0) continue;
|
|
1806
|
-
const args = argsRaw.split(/\s+/).filter((arg) => arg.length > 0);
|
|
1807
|
-
if (name === "rotate") {
|
|
1808
|
-
const angleArg = args[0];
|
|
1809
|
-
if (angleArg === void 0) continue;
|
|
1810
|
-
const angleRad = Number(angleArg);
|
|
1811
|
-
if (!Number.isFinite(angleRad)) continue;
|
|
1812
|
-
functions.push({
|
|
1813
|
-
kind: "rotate",
|
|
1814
|
-
angleRad
|
|
1815
|
-
});
|
|
1816
|
-
} else if (name === "translate") {
|
|
1817
|
-
const xArg = args[0];
|
|
1818
|
-
if (xArg === void 0) continue;
|
|
1819
|
-
const yArg = args[1];
|
|
1820
|
-
const xPt = parseOdfLength(xArg);
|
|
1821
|
-
const yPt = yArg === void 0 ? 0 : parseOdfLength(yArg);
|
|
1822
|
-
if (xPt === void 0 || yPt === void 0) continue;
|
|
1823
|
-
functions.push({
|
|
1824
|
-
kind: "translate",
|
|
1825
|
-
xPt,
|
|
1826
|
-
yPt
|
|
1827
|
-
});
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
return functions;
|
|
1831
|
-
}
|
|
1832
|
-
function applyOdfTransform(functions, point) {
|
|
1833
|
-
let current = point;
|
|
1834
|
-
for (const fn of functions) if (fn.kind === "rotate") {
|
|
1835
|
-
const cos = Math.cos(fn.angleRad);
|
|
1836
|
-
const sin = Math.sin(fn.angleRad);
|
|
1837
|
-
current = {
|
|
1838
|
-
xPt: current.xPt * cos + current.yPt * sin,
|
|
1839
|
-
yPt: current.yPt * cos - current.xPt * sin
|
|
1840
|
-
};
|
|
1841
|
-
} else current = {
|
|
1842
|
-
xPt: current.xPt + fn.xPt,
|
|
1843
|
-
yPt: current.yPt + fn.yPt
|
|
1844
|
-
};
|
|
1845
|
-
return current;
|
|
1846
|
-
}
|
|
1847
|
-
function netRotationDeg(functions) {
|
|
1848
|
-
let totalRad = 0;
|
|
1849
|
-
for (const fn of functions) if (fn.kind === "rotate") totalRad += fn.angleRad;
|
|
1850
|
-
return -totalRad * 180 / Math.PI;
|
|
1851
|
-
}
|
|
1852
|
-
function resolveOdfShapeGeometry(element) {
|
|
1853
|
-
const transformValue = attrValue(element, "draw:transform");
|
|
1854
|
-
if (transformValue === void 0) {
|
|
1855
|
-
const box = parseBox(element);
|
|
1856
|
-
return box === void 0 ? void 0 : {
|
|
1857
|
-
frame: box,
|
|
1858
|
-
rotationDeg: void 0
|
|
1859
|
-
};
|
|
1860
|
-
}
|
|
1861
|
-
const widthValue = attrValue(element, "svg:width");
|
|
1862
|
-
const heightValue = attrValue(element, "svg:height");
|
|
1863
|
-
if (widthValue === void 0 || heightValue === void 0) return;
|
|
1864
|
-
const widthPt = parseOdfLength(widthValue);
|
|
1865
|
-
const heightPt = parseOdfLength(heightValue);
|
|
1866
|
-
if (widthPt === void 0 || heightPt === void 0) return;
|
|
1867
|
-
const functions = parseOdfTransform(transformValue);
|
|
1868
|
-
const center = applyOdfTransform(functions, {
|
|
1869
|
-
xPt: widthPt / 2,
|
|
1870
|
-
yPt: heightPt / 2
|
|
1871
|
-
});
|
|
1872
|
-
const rotationDeg = netRotationDeg(functions);
|
|
1873
|
-
return {
|
|
1874
|
-
frame: {
|
|
1875
|
-
xPt: center.xPt - widthPt / 2,
|
|
1876
|
-
yPt: center.yPt - heightPt / 2,
|
|
1877
|
-
widthPt,
|
|
1878
|
-
heightPt
|
|
1879
|
-
},
|
|
1880
|
-
rotationDeg: rotationDeg === 0 ? void 0 : rotationDeg
|
|
1881
|
-
};
|
|
1882
|
-
}
|
|
1883
|
-
function composeOdfGroupTransform(groupFunctions, child) {
|
|
1884
|
-
if (groupFunctions.length === 0) return child;
|
|
1885
|
-
const newCenter = applyOdfTransform(groupFunctions, {
|
|
1886
|
-
xPt: child.frame.xPt + child.frame.widthPt / 2,
|
|
1887
|
-
yPt: child.frame.yPt + child.frame.heightPt / 2
|
|
1888
|
-
});
|
|
1889
|
-
const newRotationDeg = (child.rotationDeg ?? 0) + netRotationDeg(groupFunctions);
|
|
1890
|
-
return {
|
|
1891
|
-
frame: {
|
|
1892
|
-
xPt: newCenter.xPt - child.frame.widthPt / 2,
|
|
1893
|
-
yPt: newCenter.yPt - child.frame.heightPt / 2,
|
|
1894
|
-
widthPt: child.frame.widthPt,
|
|
1895
|
-
heightPt: child.frame.heightPt
|
|
1896
|
-
},
|
|
1897
|
-
rotationDeg: newRotationDeg === 0 ? void 0 : newRotationDeg
|
|
1898
|
-
};
|
|
1899
|
-
}
|
|
1900
|
-
//#endregion
|
|
1901
|
-
//#region src/typed/shared/masterpage.ts
|
|
1902
|
-
const STYLES_PART$1 = "styles.xml";
|
|
1903
|
-
const AUTOMATIC_STYLE_PARTS$1 = ["content.xml", STYLES_PART$1];
|
|
1904
|
-
function findMasterPageElement(pkg, masterPageName) {
|
|
1905
|
-
if (masterPageName === void 0) return;
|
|
1906
|
-
const stylesPart = pkg.parts[STYLES_PART$1];
|
|
1907
|
-
if (stylesPart?.kind !== "xml") return;
|
|
1908
|
-
const root = rootElement(stylesPart.nodes);
|
|
1909
|
-
const masterStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:master-styles");
|
|
1910
|
-
if (masterStyles === void 0) return;
|
|
1911
|
-
return childrenWithTag(masterStyles, "style:master-page").find((element) => attrValue(element, "style:name") === masterPageName);
|
|
1912
|
-
}
|
|
1913
|
-
function findPageLayoutElement$1(pkg, pageLayoutName) {
|
|
1914
|
-
if (pageLayoutName === void 0) return;
|
|
1915
|
-
for (const partPath of AUTOMATIC_STYLE_PARTS$1) {
|
|
1916
|
-
const part = pkg.parts[partPath];
|
|
1917
|
-
if (part?.kind !== "xml") continue;
|
|
1918
|
-
const root = rootElement(part.nodes);
|
|
1919
|
-
const automaticStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:automatic-styles");
|
|
1920
|
-
if (automaticStyles === void 0) continue;
|
|
1921
|
-
const found = childrenWithTag(automaticStyles, "style:page-layout").find((element) => attrValue(element, "style:name") === pageLayoutName);
|
|
1922
|
-
if (found !== void 0) return found;
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
function resolvePageLayoutProperties(pkg, masterPageName) {
|
|
1926
|
-
const masterPage = findMasterPageElement(pkg, masterPageName);
|
|
1927
|
-
const pageLayout = findPageLayoutElement$1(pkg, masterPage === void 0 ? void 0 : attrValue(masterPage, "style:page-layout-name"));
|
|
1928
|
-
return pageLayout === void 0 ? void 0 : childrenWithTag(pageLayout, "style:page-layout-properties")[0];
|
|
1929
|
-
}
|
|
1930
|
-
function resolveDrawPageSize(page, pkg) {
|
|
1931
|
-
const properties = resolvePageLayoutProperties(pkg, attrValue(page, "draw:master-page-name"));
|
|
1932
|
-
return properties === void 0 ? void 0 : parsePageSize(properties);
|
|
1933
|
-
}
|
|
1934
|
-
//#endregion
|
|
1935
|
-
//#region src/typed/shared/path.ts
|
|
1936
|
-
const VIEW_BOX_PATTERN = /^(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)$/;
|
|
1937
|
-
function parseOdfViewBox(value) {
|
|
1938
|
-
const match = VIEW_BOX_PATTERN.exec(value.trim());
|
|
1939
|
-
if (match === null) return;
|
|
1940
|
-
const minX = Number(match[1]);
|
|
1941
|
-
const minY = Number(match[2]);
|
|
1942
|
-
const width = Number(match[3]);
|
|
1943
|
-
const height = Number(match[4]);
|
|
1944
|
-
if (width <= 0 || height <= 0) return;
|
|
1945
|
-
return {
|
|
1946
|
-
minX,
|
|
1947
|
-
minY,
|
|
1948
|
-
width,
|
|
1949
|
-
height
|
|
1950
|
-
};
|
|
1951
|
-
}
|
|
1952
|
-
function parseOdfPointsList(value) {
|
|
1953
|
-
const points = [];
|
|
1954
|
-
for (const pair of value.trim().split(/\s+/)) {
|
|
1955
|
-
if (pair.length === 0) continue;
|
|
1956
|
-
const [xRaw, yRaw] = pair.split(",");
|
|
1957
|
-
if (xRaw === void 0 || yRaw === void 0) continue;
|
|
1958
|
-
const x = Number(xRaw);
|
|
1959
|
-
const y = Number(yRaw);
|
|
1960
|
-
if (!Number.isFinite(x) || !Number.isFinite(y)) continue;
|
|
1961
|
-
points.push({
|
|
1962
|
-
x,
|
|
1963
|
-
y
|
|
1964
|
-
});
|
|
1965
|
-
}
|
|
1966
|
-
return points;
|
|
1967
|
-
}
|
|
1968
|
-
function rawSubpathFromPoints(points, closed) {
|
|
1969
|
-
const start = points[0];
|
|
1970
|
-
if (start === void 0) return;
|
|
1971
|
-
return {
|
|
1972
|
-
start,
|
|
1973
|
-
segments: points.slice(1).map((to) => ({
|
|
1974
|
-
kind: "line",
|
|
1975
|
-
to
|
|
1976
|
-
})),
|
|
1977
|
-
closed
|
|
1978
|
-
};
|
|
1979
|
-
}
|
|
1980
|
-
const COMMAND_LETTERS = /* @__PURE__ */ new Set([
|
|
1981
|
-
"M",
|
|
1982
|
-
"m",
|
|
1983
|
-
"L",
|
|
1984
|
-
"l",
|
|
1985
|
-
"H",
|
|
1986
|
-
"h",
|
|
1987
|
-
"V",
|
|
1988
|
-
"v",
|
|
1989
|
-
"C",
|
|
1990
|
-
"c",
|
|
1991
|
-
"S",
|
|
1992
|
-
"s",
|
|
1993
|
-
"Q",
|
|
1994
|
-
"q",
|
|
1995
|
-
"T",
|
|
1996
|
-
"t",
|
|
1997
|
-
"A",
|
|
1998
|
-
"a",
|
|
1999
|
-
"Z",
|
|
2000
|
-
"z"
|
|
2001
|
-
]);
|
|
2002
|
-
function isCommandLetter(token) {
|
|
2003
|
-
return COMMAND_LETTERS.has(token);
|
|
2004
|
-
}
|
|
2005
|
-
const PATH_TOKEN_PATTERN = /[MmLlHhVvCcSsQqTtAaZz]|-?(?:\d+\.\d+|\.\d+|\d+)(?:[eE][-+]?\d+)?/g;
|
|
2006
|
-
function tokenizePathData(d) {
|
|
2007
|
-
return d.match(PATH_TOKEN_PATTERN) ?? [];
|
|
2008
|
-
}
|
|
2009
|
-
function parseOdfPathData(d) {
|
|
2010
|
-
const tokens = tokenizePathData(d);
|
|
2011
|
-
const subpaths = [];
|
|
2012
|
-
let current = {
|
|
2013
|
-
x: 0,
|
|
2014
|
-
y: 0
|
|
2015
|
-
};
|
|
2016
|
-
let subpathStart = {
|
|
2017
|
-
x: 0,
|
|
2018
|
-
y: 0
|
|
2019
|
-
};
|
|
2020
|
-
let activeSubpath;
|
|
2021
|
-
let command;
|
|
2022
|
-
let firstMInCommand = true;
|
|
2023
|
-
function startSubpath(point) {
|
|
2024
|
-
activeSubpath = {
|
|
2025
|
-
start: point,
|
|
2026
|
-
segments: [],
|
|
2027
|
-
closed: false
|
|
2028
|
-
};
|
|
2029
|
-
subpaths.push(activeSubpath);
|
|
2030
|
-
subpathStart = point;
|
|
2031
|
-
current = point;
|
|
2032
|
-
}
|
|
2033
|
-
function pushSegment(segment, to) {
|
|
2034
|
-
if (activeSubpath !== void 0) activeSubpath.segments.push(segment);
|
|
2035
|
-
current = to;
|
|
2036
|
-
}
|
|
2037
|
-
let i = 0;
|
|
2038
|
-
while (i < tokens.length) {
|
|
2039
|
-
const token = tokens[i];
|
|
2040
|
-
if (token === void 0) break;
|
|
2041
|
-
if (isCommandLetter(token)) {
|
|
2042
|
-
if (token === "Z" || token === "z") {
|
|
2043
|
-
if (activeSubpath !== void 0) {
|
|
2044
|
-
activeSubpath.closed = true;
|
|
2045
|
-
current = subpathStart;
|
|
2046
|
-
}
|
|
2047
|
-
command = void 0;
|
|
2048
|
-
i += 1;
|
|
2049
|
-
continue;
|
|
2050
|
-
}
|
|
2051
|
-
command = token;
|
|
2052
|
-
firstMInCommand = true;
|
|
2053
|
-
i += 1;
|
|
2054
|
-
continue;
|
|
2055
|
-
}
|
|
2056
|
-
if (command === void 0) {
|
|
2057
|
-
i += 1;
|
|
2058
|
-
continue;
|
|
2059
|
-
}
|
|
2060
|
-
const upper = command.toUpperCase();
|
|
2061
|
-
const relative = command !== upper;
|
|
2062
|
-
if (upper === "M" || upper === "L") {
|
|
2063
|
-
const xTok = tokens[i];
|
|
2064
|
-
const yTok = tokens[i + 1];
|
|
2065
|
-
i += 2;
|
|
2066
|
-
if (xTok === void 0 || yTok === void 0) break;
|
|
2067
|
-
const x = Number(xTok);
|
|
2068
|
-
const y = Number(yTok);
|
|
2069
|
-
if (!Number.isFinite(x) || !Number.isFinite(y)) continue;
|
|
2070
|
-
const point = relative ? {
|
|
2071
|
-
x: current.x + x,
|
|
2072
|
-
y: current.y + y
|
|
2073
|
-
} : {
|
|
2074
|
-
x,
|
|
2075
|
-
y
|
|
2076
|
-
};
|
|
2077
|
-
if (upper === "M" && firstMInCommand) {
|
|
2078
|
-
startSubpath(point);
|
|
2079
|
-
firstMInCommand = false;
|
|
2080
|
-
} else pushSegment({
|
|
2081
|
-
kind: "line",
|
|
2082
|
-
to: point
|
|
2083
|
-
}, point);
|
|
2084
|
-
} else if (upper === "H") {
|
|
2085
|
-
const xTok = tokens[i];
|
|
2086
|
-
i += 1;
|
|
2087
|
-
if (xTok === void 0) break;
|
|
2088
|
-
const x = Number(xTok);
|
|
2089
|
-
if (!Number.isFinite(x)) continue;
|
|
2090
|
-
const point = relative ? {
|
|
2091
|
-
x: current.x + x,
|
|
2092
|
-
y: current.y
|
|
2093
|
-
} : {
|
|
2094
|
-
x,
|
|
2095
|
-
y: current.y
|
|
2096
|
-
};
|
|
2097
|
-
pushSegment({
|
|
2098
|
-
kind: "line",
|
|
2099
|
-
to: point
|
|
2100
|
-
}, point);
|
|
2101
|
-
} else if (upper === "V") {
|
|
2102
|
-
const yTok = tokens[i];
|
|
2103
|
-
i += 1;
|
|
2104
|
-
if (yTok === void 0) break;
|
|
2105
|
-
const y = Number(yTok);
|
|
2106
|
-
if (!Number.isFinite(y)) continue;
|
|
2107
|
-
const point = relative ? {
|
|
2108
|
-
x: current.x,
|
|
2109
|
-
y: current.y + y
|
|
2110
|
-
} : {
|
|
2111
|
-
x: current.x,
|
|
2112
|
-
y
|
|
2113
|
-
};
|
|
2114
|
-
pushSegment({
|
|
2115
|
-
kind: "line",
|
|
2116
|
-
to: point
|
|
2117
|
-
}, point);
|
|
2118
|
-
} else if (upper === "C") {
|
|
2119
|
-
const rawArgs = tokens.slice(i, i + 6);
|
|
2120
|
-
i += 6;
|
|
2121
|
-
if (rawArgs.length < 6) break;
|
|
2122
|
-
const x1 = Number(rawArgs[0]);
|
|
2123
|
-
const y1 = Number(rawArgs[1]);
|
|
2124
|
-
const x2 = Number(rawArgs[2]);
|
|
2125
|
-
const y2 = Number(rawArgs[3]);
|
|
2126
|
-
const x = Number(rawArgs[4]);
|
|
2127
|
-
const y = Number(rawArgs[5]);
|
|
2128
|
-
if (![
|
|
2129
|
-
x1,
|
|
2130
|
-
y1,
|
|
2131
|
-
x2,
|
|
2132
|
-
y2,
|
|
2133
|
-
x,
|
|
2134
|
-
y
|
|
2135
|
-
].every(Number.isFinite)) continue;
|
|
2136
|
-
const control1 = relative ? {
|
|
2137
|
-
x: current.x + x1,
|
|
2138
|
-
y: current.y + y1
|
|
2139
|
-
} : {
|
|
2140
|
-
x: x1,
|
|
2141
|
-
y: y1
|
|
2142
|
-
};
|
|
2143
|
-
const control2 = relative ? {
|
|
2144
|
-
x: current.x + x2,
|
|
2145
|
-
y: current.y + y2
|
|
2146
|
-
} : {
|
|
2147
|
-
x: x2,
|
|
2148
|
-
y: y2
|
|
2149
|
-
};
|
|
2150
|
-
const to = relative ? {
|
|
2151
|
-
x: current.x + x,
|
|
2152
|
-
y: current.y + y
|
|
2153
|
-
} : {
|
|
2154
|
-
x,
|
|
2155
|
-
y
|
|
2156
|
-
};
|
|
2157
|
-
pushSegment({
|
|
2158
|
-
kind: "cubic",
|
|
2159
|
-
control1,
|
|
2160
|
-
control2,
|
|
2161
|
-
to
|
|
2162
|
-
}, to);
|
|
2163
|
-
} else i += 1;
|
|
2164
|
-
}
|
|
2165
|
-
return subpaths;
|
|
2166
|
-
}
|
|
2167
|
-
function scaleOdfRawPoint(point, viewBox, frame) {
|
|
2168
|
-
return {
|
|
2169
|
-
xPt: (point.x - viewBox.minX) * (frame.widthPt / viewBox.width),
|
|
2170
|
-
yPt: (point.y - viewBox.minY) * (frame.heightPt / viewBox.height)
|
|
2171
|
-
};
|
|
2172
|
-
}
|
|
2173
|
-
function buildOdfSubpaths(rawSubpaths, viewBox, frame) {
|
|
2174
|
-
return rawSubpaths.map((raw) => ({
|
|
2175
|
-
start: scaleOdfRawPoint(raw.start, viewBox, frame),
|
|
2176
|
-
closed: raw.closed,
|
|
2177
|
-
segments: raw.segments.map((segment) => segment.kind === "line" ? {
|
|
2178
|
-
kind: "line",
|
|
2179
|
-
to: scaleOdfRawPoint(segment.to, viewBox, frame)
|
|
2180
|
-
} : {
|
|
2181
|
-
kind: "cubic",
|
|
2182
|
-
control1: scaleOdfRawPoint(segment.control1, viewBox, frame),
|
|
2183
|
-
control2: scaleOdfRawPoint(segment.control2, viewBox, frame),
|
|
2184
|
-
to: scaleOdfRawPoint(segment.to, viewBox, frame)
|
|
2185
|
-
})
|
|
2186
|
-
}));
|
|
2187
|
-
}
|
|
2188
|
-
//#endregion
|
|
2189
|
-
//#region src/typed/draw/shapes.ts
|
|
2190
|
-
const ZERO_INSETS = {
|
|
2191
|
-
insetLeftPt: 0,
|
|
2192
|
-
insetTopPt: 0,
|
|
2193
|
-
insetRightPt: 0,
|
|
2194
|
-
insetBottomPt: 0
|
|
2195
|
-
};
|
|
2196
|
-
function readPaddingPt(props, attrName) {
|
|
2197
|
-
const value = attrValue(props, attrName);
|
|
2198
|
-
return value === void 0 ? void 0 : parseOdfLength(value);
|
|
2199
|
-
}
|
|
2200
|
-
function readFrameInsets(frame, pkg) {
|
|
2201
|
-
const { elements } = resolveStyleElementChain(attrValue(frame, "draw:style-name"), "graphic", pkg);
|
|
2202
|
-
let insets = ZERO_INSETS;
|
|
2203
|
-
for (const element of elements) {
|
|
2204
|
-
const props = childrenWithTag(element, "style:graphic-properties")[0];
|
|
2205
|
-
if (props === void 0) continue;
|
|
2206
|
-
insets = {
|
|
2207
|
-
insetLeftPt: readPaddingPt(props, "fo:padding-left") ?? insets.insetLeftPt,
|
|
2208
|
-
insetTopPt: readPaddingPt(props, "fo:padding-top") ?? insets.insetTopPt,
|
|
2209
|
-
insetRightPt: readPaddingPt(props, "fo:padding-right") ?? insets.insetRightPt,
|
|
2210
|
-
insetBottomPt: readPaddingPt(props, "fo:padding-bottom") ?? insets.insetBottomPt
|
|
2211
|
-
};
|
|
2212
|
-
}
|
|
2213
|
-
return insets;
|
|
2214
|
-
}
|
|
2215
|
-
function readDrawImageBlock(image, frameBox, pkg) {
|
|
2216
|
-
const href = attrValue(image, "xlink:href");
|
|
2217
|
-
const part = href === void 0 ? void 0 : pkg.parts[href];
|
|
2218
|
-
if (part?.kind !== "binary") return;
|
|
2219
|
-
const format = sniffImageFormat(base64ToBytes(part.base64));
|
|
2220
|
-
if (format === void 0) return;
|
|
2221
|
-
return {
|
|
2222
|
-
kind: "image",
|
|
2223
|
-
format,
|
|
2224
|
-
base64: part.base64,
|
|
2225
|
-
widthPt: frameBox.widthPt,
|
|
2226
|
-
heightPt: frameBox.heightPt
|
|
2227
|
-
};
|
|
2228
|
-
}
|
|
2229
|
-
function readDrawFrameContent(frame, frameBox, pkg) {
|
|
2230
|
-
const table = childrenWithTag(frame, "table:table")[0];
|
|
2231
|
-
if (table !== void 0) return [readOdfTable(table, pkg)];
|
|
2232
|
-
const textBox = childrenWithTag(frame, "draw:text-box")[0];
|
|
2233
|
-
if (textBox !== void 0) return elementsWithTag(textBox.children, "text:p").map((p) => readOdfParagraph(p, pkg));
|
|
2234
|
-
const image = childrenWithTag(frame, "draw:image")[0];
|
|
2235
|
-
if (image !== void 0) {
|
|
2236
|
-
const block = readDrawImageBlock(image, frameBox, pkg);
|
|
2237
|
-
return block === void 0 ? [] : [block];
|
|
2238
|
-
}
|
|
2239
|
-
return [];
|
|
2240
|
-
}
|
|
2241
|
-
function readDrawFrame(frame, groupFunctions, pkg) {
|
|
2242
|
-
const ownGeometry = resolveOdfShapeGeometry(frame);
|
|
2243
|
-
if (ownGeometry === void 0) return;
|
|
2244
|
-
const geometry = composeOdfGroupTransform(groupFunctions, ownGeometry);
|
|
2245
|
-
return {
|
|
2246
|
-
name: attrValue(frame, "draw:name"),
|
|
2247
|
-
frame: geometry.frame,
|
|
2248
|
-
rotationDeg: geometry.rotationDeg,
|
|
2249
|
-
...readFrameInsets(frame, pkg),
|
|
2250
|
-
blocks: readDrawFrameContent(frame, geometry.frame, pkg)
|
|
2251
|
-
};
|
|
2252
|
-
}
|
|
2253
|
-
function readOwnTransformFunctions(element) {
|
|
2254
|
-
const value = attrValue(element, "draw:transform");
|
|
2255
|
-
return value === void 0 ? [] : parseOdfTransform(value);
|
|
2256
|
-
}
|
|
2257
|
-
function walkDrawShapes(children, groupFunctions, pkg, out) {
|
|
2258
|
-
for (const node of children) {
|
|
2259
|
-
if (node.type !== "element") continue;
|
|
2260
|
-
if (node.tag === "draw:frame") {
|
|
2261
|
-
const shape = readDrawFrame(node, groupFunctions, pkg);
|
|
2262
|
-
if (shape !== void 0) out.push(shape);
|
|
2263
|
-
} else if (node.tag === "draw:g") {
|
|
2264
|
-
const ownFunctions = readOwnTransformFunctions(node);
|
|
2265
|
-
const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
|
|
2266
|
-
walkDrawShapes(node.children, nested, pkg, out);
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
}
|
|
2270
|
-
function readOdfFillAndStroke(element, pkg) {
|
|
2271
|
-
const { elements } = resolveStyleElementChain(attrValue(element, "draw:style-name"), "graphic", pkg);
|
|
2272
|
-
let fill;
|
|
2273
|
-
let stroke;
|
|
2274
|
-
for (const styleElement of elements) {
|
|
2275
|
-
const props = childrenWithTag(styleElement, "style:graphic-properties")[0];
|
|
2276
|
-
if (props === void 0) continue;
|
|
2277
|
-
if (attrValue(props, "draw:fill") === "none") fill = void 0;
|
|
2278
|
-
else {
|
|
2279
|
-
const fillColorValue = attrValue(props, "draw:fill-color");
|
|
2280
|
-
const parsedFill = fillColorValue === void 0 ? void 0 : parseOdfColor(fillColorValue);
|
|
2281
|
-
if (parsedFill !== void 0) fill = parsedFill;
|
|
2282
|
-
}
|
|
2283
|
-
if (attrValue(props, "draw:stroke") === "none") stroke = void 0;
|
|
2284
|
-
else {
|
|
2285
|
-
const strokeColorValue = attrValue(props, "svg:stroke-color");
|
|
2286
|
-
const strokeWidthValue = attrValue(props, "svg:stroke-width");
|
|
2287
|
-
const strokeColor = strokeColorValue === void 0 ? void 0 : parseOdfColor(strokeColorValue);
|
|
2288
|
-
const strokeWidthPt = strokeWidthValue === void 0 ? void 0 : parseOdfLength(strokeWidthValue);
|
|
2289
|
-
if (strokeColor !== void 0 && strokeWidthPt !== void 0 && strokeWidthPt > 0) stroke = {
|
|
2290
|
-
color: strokeColor,
|
|
2291
|
-
widthPt: strokeWidthPt
|
|
2292
|
-
};
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
return {
|
|
2296
|
-
fill,
|
|
2297
|
-
stroke
|
|
2298
|
-
};
|
|
2299
|
-
}
|
|
2300
|
-
function resolveVectorFrame(element, groupFunctions) {
|
|
2301
|
-
const geometry = resolveOdfShapeGeometry(element);
|
|
2302
|
-
if (geometry === void 0) return;
|
|
2303
|
-
return composeOdfGroupTransform(groupFunctions, geometry).frame;
|
|
2304
|
-
}
|
|
2305
|
-
function readDrawRectVector(element, groupFunctions, pkg) {
|
|
2306
|
-
const frame = resolveVectorFrame(element, groupFunctions);
|
|
2307
|
-
if (frame === void 0) return;
|
|
2308
|
-
const { fill, stroke } = readOdfFillAndStroke(element, pkg);
|
|
2309
|
-
return {
|
|
2310
|
-
kind: "rect",
|
|
2311
|
-
frame,
|
|
2312
|
-
fill,
|
|
2313
|
-
stroke
|
|
2314
|
-
};
|
|
2315
|
-
}
|
|
2316
|
-
function readDrawEllipseVector(element, groupFunctions, pkg) {
|
|
2317
|
-
const frame = resolveVectorFrame(element, groupFunctions);
|
|
2318
|
-
if (frame === void 0) return;
|
|
2319
|
-
const { fill, stroke } = readOdfFillAndStroke(element, pkg);
|
|
2320
|
-
return {
|
|
2321
|
-
kind: "ellipse",
|
|
2322
|
-
frame,
|
|
2323
|
-
fill,
|
|
2324
|
-
stroke
|
|
2325
|
-
};
|
|
2326
|
-
}
|
|
2327
|
-
function readDrawLineVector(element, groupFunctions, pkg) {
|
|
2328
|
-
const raw = parseLinePoints(element);
|
|
2329
|
-
if (raw === void 0) return;
|
|
2330
|
-
const from = groupFunctions.length === 0 ? raw.from : applyOdfTransform(groupFunctions, raw.from);
|
|
2331
|
-
const to = groupFunctions.length === 0 ? raw.to : applyOdfTransform(groupFunctions, raw.to);
|
|
2332
|
-
const { stroke } = readOdfFillAndStroke(element, pkg);
|
|
2333
|
-
if (stroke === void 0) return;
|
|
2334
|
-
return {
|
|
2335
|
-
kind: "line",
|
|
2336
|
-
from,
|
|
2337
|
-
to,
|
|
2338
|
-
stroke
|
|
2339
|
-
};
|
|
2340
|
-
}
|
|
2341
|
-
function readDrawPathVector(element, groupFunctions, pkg) {
|
|
2342
|
-
const frame = resolveVectorFrame(element, groupFunctions);
|
|
2343
|
-
if (frame === void 0) return;
|
|
2344
|
-
const viewBoxValue = attrValue(element, "svg:viewBox");
|
|
2345
|
-
const viewBox = viewBoxValue === void 0 ? void 0 : parseOdfViewBox(viewBoxValue);
|
|
2346
|
-
if (viewBox === void 0) return;
|
|
2347
|
-
let rawSubpaths;
|
|
2348
|
-
if (element.tag === "draw:path") {
|
|
2349
|
-
const d = attrValue(element, "svg:d");
|
|
2350
|
-
rawSubpaths = d === void 0 ? [] : parseOdfPathData(d);
|
|
2351
|
-
} else {
|
|
2352
|
-
const pointsValue = attrValue(element, "draw:points");
|
|
2353
|
-
const subpath = rawSubpathFromPoints(pointsValue === void 0 ? [] : parseOdfPointsList(pointsValue), element.tag === "draw:polygon");
|
|
2354
|
-
rawSubpaths = subpath === void 0 ? [] : [subpath];
|
|
2355
|
-
}
|
|
2356
|
-
if (rawSubpaths.length === 0) return;
|
|
2357
|
-
const subpaths = buildOdfSubpaths(rawSubpaths, viewBox, frame);
|
|
2358
|
-
const { fill, stroke } = readOdfFillAndStroke(element, pkg);
|
|
2359
|
-
return {
|
|
2360
|
-
kind: "path",
|
|
2361
|
-
frame,
|
|
2362
|
-
subpaths,
|
|
2363
|
-
fill,
|
|
2364
|
-
stroke
|
|
2365
|
-
};
|
|
2366
|
-
}
|
|
2367
|
-
const RECOGNIZED_CUSTOM_SHAPE_PRESETS = /* @__PURE__ */ new Set([
|
|
2368
|
-
"rectangle",
|
|
2369
|
-
"round-rectangle",
|
|
2370
|
-
"ellipse"
|
|
2371
|
-
]);
|
|
2372
|
-
function readCustomShapeVector(element, groupFunctions, pkg) {
|
|
2373
|
-
const geometryElement = childrenWithTag(element, "draw:enhanced-geometry")[0];
|
|
2374
|
-
const type = geometryElement === void 0 ? void 0 : attrValue(geometryElement, "draw:type");
|
|
2375
|
-
if (type === void 0 || !RECOGNIZED_CUSTOM_SHAPE_PRESETS.has(type)) return;
|
|
2376
|
-
const frame = resolveVectorFrame(element, groupFunctions);
|
|
2377
|
-
if (frame === void 0) return;
|
|
2378
|
-
const { fill, stroke } = readOdfFillAndStroke(element, pkg);
|
|
2379
|
-
return {
|
|
2380
|
-
kind: type === "ellipse" ? "ellipse" : "rect",
|
|
2381
|
-
frame,
|
|
2382
|
-
fill,
|
|
2383
|
-
stroke
|
|
2384
|
-
};
|
|
2385
|
-
}
|
|
2386
|
-
function readCustomShapeAsTextShape(element, groupFunctions, pkg) {
|
|
2387
|
-
const paragraphs = elementsWithTag(element.children, "text:p").map((p) => readOdfParagraph(p, pkg));
|
|
2388
|
-
if (!paragraphs.some((paragraph) => paragraph.runs.some((run) => run.text.length > 0))) return;
|
|
2389
|
-
const ownGeometry = resolveOdfShapeGeometry(element);
|
|
2390
|
-
if (ownGeometry === void 0) return;
|
|
2391
|
-
const geometry = composeOdfGroupTransform(groupFunctions, ownGeometry);
|
|
2392
|
-
return {
|
|
2393
|
-
name: attrValue(element, "draw:name"),
|
|
2394
|
-
frame: geometry.frame,
|
|
2395
|
-
rotationDeg: geometry.rotationDeg,
|
|
2396
|
-
...readFrameInsets(element, pkg),
|
|
2397
|
-
blocks: paragraphs
|
|
2398
|
-
};
|
|
2399
|
-
}
|
|
2400
|
-
function nextDocumentIndex(state) {
|
|
2401
|
-
const value = state.next;
|
|
2402
|
-
state.next += 1;
|
|
2403
|
-
return value;
|
|
2404
|
-
}
|
|
2405
|
-
function paintOrderKey(element, state) {
|
|
2406
|
-
const documentIndex = nextDocumentIndex(state);
|
|
2407
|
-
const raw = attrValue(element, "draw:z-index");
|
|
2408
|
-
if (raw === void 0) return documentIndex;
|
|
2409
|
-
const parsed = Number.parseInt(raw, 10);
|
|
2410
|
-
return Number.isInteger(parsed) && parsed >= 0 ? parsed : documentIndex;
|
|
2411
|
-
}
|
|
2412
|
-
function byPaintOrder(items) {
|
|
2413
|
-
return items.slice().sort((a, b) => a.zIndex - b.zIndex).map((item) => item.value);
|
|
2414
|
-
}
|
|
2415
|
-
function walkDrawPageContent(children, groupFunctions, pkg, indexState, shapesOut, vectorsOut) {
|
|
2416
|
-
for (const node of children) {
|
|
2417
|
-
if (node.type !== "element") continue;
|
|
2418
|
-
if (node.tag === "draw:frame") {
|
|
2419
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2420
|
-
const shape = readDrawFrame(node, groupFunctions, pkg);
|
|
2421
|
-
if (shape !== void 0) shapesOut.push({
|
|
2422
|
-
value: shape,
|
|
2423
|
-
zIndex
|
|
2424
|
-
});
|
|
2425
|
-
} else if (node.tag === "draw:g") {
|
|
2426
|
-
const ownFunctions = readOwnTransformFunctions(node);
|
|
2427
|
-
const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
|
|
2428
|
-
walkDrawPageContent(node.children, nested, pkg, indexState, shapesOut, vectorsOut);
|
|
2429
|
-
} else if (node.tag === "draw:rect") {
|
|
2430
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2431
|
-
const vector = readDrawRectVector(node, groupFunctions, pkg);
|
|
2432
|
-
if (vector !== void 0) vectorsOut.push({
|
|
2433
|
-
value: vector,
|
|
2434
|
-
zIndex
|
|
2435
|
-
});
|
|
2436
|
-
} else if (node.tag === "draw:ellipse" || node.tag === "draw:circle") {
|
|
2437
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2438
|
-
const vector = readDrawEllipseVector(node, groupFunctions, pkg);
|
|
2439
|
-
if (vector !== void 0) vectorsOut.push({
|
|
2440
|
-
value: vector,
|
|
2441
|
-
zIndex
|
|
2442
|
-
});
|
|
2443
|
-
} else if (node.tag === "draw:line") {
|
|
2444
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2445
|
-
const vector = readDrawLineVector(node, groupFunctions, pkg);
|
|
2446
|
-
if (vector !== void 0) vectorsOut.push({
|
|
2447
|
-
value: vector,
|
|
2448
|
-
zIndex
|
|
2449
|
-
});
|
|
2450
|
-
} else if (node.tag === "draw:path" || node.tag === "draw:polygon" || node.tag === "draw:polyline") {
|
|
2451
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2452
|
-
const vector = readDrawPathVector(node, groupFunctions, pkg);
|
|
2453
|
-
if (vector !== void 0) vectorsOut.push({
|
|
2454
|
-
value: vector,
|
|
2455
|
-
zIndex
|
|
2456
|
-
});
|
|
2457
|
-
} else if (node.tag === "draw:custom-shape") {
|
|
2458
|
-
const zIndex = paintOrderKey(node, indexState);
|
|
2459
|
-
const vector = readCustomShapeVector(node, groupFunctions, pkg);
|
|
2460
|
-
if (vector !== void 0) vectorsOut.push({
|
|
2461
|
-
value: vector,
|
|
2462
|
-
zIndex
|
|
2463
|
-
});
|
|
2464
|
-
else {
|
|
2465
|
-
const shape = readCustomShapeAsTextShape(node, groupFunctions, pkg);
|
|
2466
|
-
if (shape !== void 0) shapesOut.push({
|
|
2467
|
-
value: shape,
|
|
2468
|
-
zIndex
|
|
2469
|
-
});
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
}
|
|
2473
|
-
}
|
|
2474
|
-
function readDrawPageContent(children, pkg) {
|
|
2475
|
-
const shapesOut = [];
|
|
2476
|
-
const vectorsOut = [];
|
|
2477
|
-
walkDrawPageContent(children, [], pkg, { next: 0 }, shapesOut, vectorsOut);
|
|
2478
|
-
return {
|
|
2479
|
-
shapes: byPaintOrder(shapesOut),
|
|
2480
|
-
vectors: byPaintOrder(vectorsOut)
|
|
2481
|
-
};
|
|
2482
|
-
}
|
|
2483
|
-
//#endregion
|
|
2484
|
-
//#region src/typed/odp/read.ts
|
|
2485
|
-
const CONTENT_PART$6 = "content.xml";
|
|
2486
|
-
function readSlideSize(page, pkg) {
|
|
2487
|
-
return resolveDrawPageSize(page, pkg) ?? document_schema_js.SLIDE_SIZE_WIDESCREEN;
|
|
2488
|
-
}
|
|
2489
|
-
function readSlideNotes(page) {
|
|
2490
|
-
const notes = childrenWithTag(page, "presentation:notes")[0];
|
|
2491
|
-
if (notes === void 0) return "";
|
|
2492
|
-
return elementsWithTag(notes.children, "text:p").map(decodeOdfText).join("\n");
|
|
2493
|
-
}
|
|
2494
|
-
function readSlide(page, pkg) {
|
|
2495
|
-
const shapes = [];
|
|
2496
|
-
walkDrawShapes(page.children, [], pkg, shapes);
|
|
2497
|
-
return {
|
|
2498
|
-
size: readSlideSize(page, pkg),
|
|
2499
|
-
shapes,
|
|
2500
|
-
notes: readSlideNotes(page)
|
|
2501
|
-
};
|
|
2502
|
-
}
|
|
2503
|
-
function readOdp(pkg) {
|
|
2504
|
-
const contentPart = pkg.parts[CONTENT_PART$6];
|
|
2505
|
-
const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
|
|
2506
|
-
const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
|
|
2507
|
-
const presentation = body === void 0 ? void 0 : findChildElement(body.children, "office:presentation");
|
|
2508
|
-
const pages = presentation === void 0 ? [] : childrenWithTag(presentation, "draw:page");
|
|
2509
|
-
return {
|
|
2510
|
-
metadata: readOdfMetadata(pkg),
|
|
2511
|
-
slides: pages.map((page) => readSlide(page, pkg))
|
|
2512
|
-
};
|
|
2513
|
-
}
|
|
2514
|
-
//#endregion
|
|
2515
|
-
//#region src/typed/odt/read.ts
|
|
2516
|
-
const CONTENT_PART$5 = "content.xml";
|
|
2517
|
-
const STYLES_PART = "styles.xml";
|
|
2518
|
-
const AUTOMATIC_STYLE_PARTS = [CONTENT_PART$5, STYLES_PART];
|
|
2519
|
-
function readOutlineLevel(headingElement) {
|
|
2520
|
-
const raw = attrValue(headingElement, "text:outline-level");
|
|
2521
|
-
if (raw === void 0) return 1;
|
|
2522
|
-
const parsed = Number.parseInt(raw, 10);
|
|
2523
|
-
return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
|
|
2524
|
-
}
|
|
2525
|
-
function readParagraphOrHeading(element, pkg, list) {
|
|
2526
|
-
const paragraph = readOdfParagraph(element, pkg);
|
|
2527
|
-
if (element.tag === "text:h") paragraph.styleId = `Heading${readOutlineLevel(element)}`;
|
|
2528
|
-
if (list !== void 0) paragraph.list = list;
|
|
2529
|
-
return paragraph;
|
|
2530
|
-
}
|
|
2531
|
-
function readListItems(listElement, context, pkg, blocks) {
|
|
2532
|
-
for (const item of listElement.children) {
|
|
2533
|
-
if (item.type !== "element" || item.tag !== "text:list-item") continue;
|
|
2534
|
-
for (const itemChild of item.children) {
|
|
2535
|
-
if (itemChild.type !== "element") continue;
|
|
2536
|
-
if (itemChild.tag === "text:p" || itemChild.tag === "text:h") blocks.push(readParagraphOrHeading(itemChild, pkg, context));
|
|
2537
|
-
else if (itemChild.tag === "text:list") readListItems(itemChild, {
|
|
2538
|
-
numId: context.numId,
|
|
2539
|
-
level: context.level + 1
|
|
2540
|
-
}, pkg, blocks);
|
|
2541
|
-
}
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
function readBlocks(nodes, pkg, listIdState) {
|
|
2545
|
-
const blocks = [];
|
|
2546
|
-
for (const node of nodes) {
|
|
2547
|
-
if (node.type !== "element") continue;
|
|
2548
|
-
if (node.tag === "text:p" || node.tag === "text:h") blocks.push(readParagraphOrHeading(node, pkg, void 0));
|
|
2549
|
-
else if (node.tag === "text:list") {
|
|
2550
|
-
const numId = `list${listIdState.next}`;
|
|
2551
|
-
listIdState.next += 1;
|
|
2552
|
-
readListItems(node, {
|
|
2553
|
-
numId,
|
|
2554
|
-
level: 0
|
|
2555
|
-
}, pkg, blocks);
|
|
2556
|
-
} else if (node.tag === "table:table") blocks.push(readOdfTable(node, pkg));
|
|
2557
|
-
else if (node.tag === "text:section") blocks.push(...readBlocks(node.children, pkg, listIdState));
|
|
2558
|
-
}
|
|
2559
|
-
return blocks;
|
|
2560
|
-
}
|
|
2561
|
-
function parseKnownOdfLength$1(value) {
|
|
2562
|
-
const parsed = parseOdfLength(value);
|
|
2563
|
-
if (parsed === void 0) throw new Error(`readOdt: internal error -- "${value}" is not a valid ODF length literal`);
|
|
2564
|
-
return parsed;
|
|
2565
|
-
}
|
|
2566
|
-
const DEFAULT_MARGIN_PT$1 = parseKnownOdfLength$1("2cm");
|
|
2567
|
-
const DEFAULT_MARGINS$1 = {
|
|
2568
|
-
topPt: DEFAULT_MARGIN_PT$1,
|
|
2569
|
-
rightPt: DEFAULT_MARGIN_PT$1,
|
|
2570
|
-
bottomPt: DEFAULT_MARGIN_PT$1,
|
|
2571
|
-
leftPt: DEFAULT_MARGIN_PT$1
|
|
2572
|
-
};
|
|
2573
|
-
function findPageLayoutElement(pkg, pageLayoutName) {
|
|
2574
|
-
if (pageLayoutName === void 0) return;
|
|
2575
|
-
for (const partPath of AUTOMATIC_STYLE_PARTS) {
|
|
2576
|
-
const part = pkg.parts[partPath];
|
|
2577
|
-
if (part?.kind !== "xml") continue;
|
|
2578
|
-
const root = rootElement(part.nodes);
|
|
2579
|
-
const automaticStyles = root === void 0 ? void 0 : findChildElement(root.children, "office:automatic-styles");
|
|
2580
|
-
if (automaticStyles === void 0) continue;
|
|
2581
|
-
const found = childrenWithTag(automaticStyles, "style:page-layout").find((element) => attrValue(element, "style:name") === pageLayoutName);
|
|
2582
|
-
if (found !== void 0) return found;
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
function readFirstMasterPageGeometry(pkg) {
|
|
2586
|
-
const stylesPart = pkg.parts[STYLES_PART];
|
|
2587
|
-
const stylesRoot = stylesPart?.kind === "xml" ? rootElement(stylesPart.nodes) : void 0;
|
|
2588
|
-
const masterStyles = stylesRoot === void 0 ? void 0 : findChildElement(stylesRoot.children, "office:master-styles");
|
|
2589
|
-
const masterPage = masterStyles === void 0 ? void 0 : findChildElement(masterStyles.children, "style:master-page");
|
|
2590
|
-
const layout = findPageLayoutElement(pkg, masterPage === void 0 ? void 0 : attrValue(masterPage, "style:page-layout-name"));
|
|
2591
|
-
const properties = layout === void 0 ? void 0 : findChildElement(layout.children, "style:page-layout-properties");
|
|
2592
|
-
const pageSize = properties === void 0 ? void 0 : parsePageSize(properties);
|
|
2593
|
-
const margins = properties === void 0 ? void 0 : parseMargins(properties);
|
|
2594
|
-
return {
|
|
2595
|
-
pageSize: pageSize ?? document_schema_js.PAGE_SIZE_A4,
|
|
2596
|
-
margins: margins ?? DEFAULT_MARGINS$1
|
|
2597
|
-
};
|
|
2598
|
-
}
|
|
2599
|
-
function readOdt(pkg) {
|
|
2600
|
-
const contentPart = pkg.parts[CONTENT_PART$5];
|
|
2601
|
-
if (contentPart?.kind !== "xml") throw new Error(`readOdt: package has no ${CONTENT_PART$5} part`);
|
|
2602
|
-
const contentRoot = rootElement(contentPart.nodes);
|
|
2603
|
-
const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
|
|
2604
|
-
const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
|
|
2605
|
-
if (textElement === void 0) throw new Error(`readOdt: ${CONTENT_PART$5} has no office:body/office:text element`);
|
|
2606
|
-
const metadata = readOdfMetadata(pkg);
|
|
2607
|
-
const { pageSize, margins } = readFirstMasterPageGeometry(pkg);
|
|
2608
|
-
return {
|
|
2609
|
-
metadata,
|
|
2610
|
-
sections: [{
|
|
2611
|
-
pageSize,
|
|
2612
|
-
margins,
|
|
2613
|
-
blocks: readBlocks(textElement.children, pkg, { next: 1 })
|
|
2614
|
-
}]
|
|
2615
|
-
};
|
|
2616
|
-
}
|
|
2617
|
-
//#endregion
|
|
2618
|
-
//#region src/typed/odg/read.ts
|
|
2619
|
-
const CONTENT_PART$4 = "content.xml";
|
|
2620
|
-
function readPage(page, pkg) {
|
|
2621
|
-
const size = resolveDrawPageSize(page, pkg) ?? document_schema_js.PAGE_SIZE_A4;
|
|
2622
|
-
const { shapes, vectors } = readDrawPageContent(page.children, pkg);
|
|
2623
|
-
return {
|
|
2624
|
-
size,
|
|
2625
|
-
shapes,
|
|
2626
|
-
vectors
|
|
2627
|
-
};
|
|
2628
|
-
}
|
|
2629
|
-
function readOdg(pkg) {
|
|
2630
|
-
const contentPart = pkg.parts[CONTENT_PART$4];
|
|
2631
|
-
const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
|
|
2632
|
-
const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
|
|
2633
|
-
const drawing = body === void 0 ? void 0 : findChildElement(body.children, "office:drawing");
|
|
2634
|
-
const pages = drawing === void 0 ? [] : childrenWithTag(drawing, "draw:page");
|
|
2635
|
-
return {
|
|
2636
|
-
metadata: readOdfMetadata(pkg),
|
|
2637
|
-
pages: pages.map((page) => readPage(page, pkg))
|
|
2638
|
-
};
|
|
2639
|
-
}
|
|
2640
|
-
//#endregion
|
|
2641
|
-
//#region src/typed/ods/read.ts
|
|
2642
|
-
const CONTENT_PART$3 = "content.xml";
|
|
2643
|
-
function parseKnownOdfLength(value) {
|
|
2644
|
-
const parsed = parseOdfLength(value);
|
|
2645
|
-
if (parsed === void 0) throw new Error(`readOds: internal error -- "${value}" is not a valid ODF length literal`);
|
|
2646
|
-
return parsed;
|
|
2647
|
-
}
|
|
2648
|
-
const DEFAULT_MARGIN_PT = parseKnownOdfLength("2cm");
|
|
2649
|
-
const DEFAULT_MARGINS = {
|
|
2650
|
-
topPt: DEFAULT_MARGIN_PT,
|
|
2651
|
-
rightPt: DEFAULT_MARGIN_PT,
|
|
2652
|
-
bottomPt: DEFAULT_MARGIN_PT,
|
|
2653
|
-
leftPt: DEFAULT_MARGIN_PT
|
|
2654
|
-
};
|
|
2655
|
-
function readRepeatCount(element, attrName) {
|
|
2656
|
-
const raw = attrValue(element, attrName);
|
|
2657
|
-
if (raw === void 0) return 1;
|
|
2658
|
-
const parsed = Number.parseInt(raw, 10);
|
|
2659
|
-
return Number.isInteger(parsed) && parsed > 0 ? parsed : 1;
|
|
2660
|
-
}
|
|
2661
|
-
function isHidden(element) {
|
|
2662
|
-
return attrValue(element, "table:visibility") === "collapse";
|
|
2663
|
-
}
|
|
2664
|
-
function readColumnLayout(columnElement, pkg) {
|
|
2665
|
-
const styleName = attrValue(columnElement, "table:style-name");
|
|
2666
|
-
const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-column", pkg);
|
|
2667
|
-
const properties = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-column-properties")[0];
|
|
2668
|
-
const widthValue = properties === void 0 ? void 0 : attrValue(properties, "style:column-width");
|
|
2669
|
-
return {
|
|
2670
|
-
widthPt: widthValue === void 0 ? 0 : parseOdfLength(widthValue) ?? 0,
|
|
2671
|
-
manualBreak: (properties === void 0 ? void 0 : attrValue(properties, "fo:break-before")) === "page"
|
|
2672
|
-
};
|
|
2673
|
-
}
|
|
2674
|
-
function readRowLayout(rowElement, pkg) {
|
|
2675
|
-
const styleName = attrValue(rowElement, "table:style-name");
|
|
2676
|
-
const styleElement = styleName === void 0 ? void 0 : findStyleElement(styleName, "table-row", pkg);
|
|
2677
|
-
const properties = styleElement === void 0 ? void 0 : childrenWithTag(styleElement, "style:table-row-properties")[0];
|
|
2678
|
-
const heightValue = properties === void 0 ? void 0 : attrValue(properties, "style:row-height");
|
|
2679
|
-
return {
|
|
2680
|
-
heightPt: heightValue === void 0 ? 0 : parseOdfLength(heightValue) ?? 0,
|
|
2681
|
-
manualBreak: (properties === void 0 ? void 0 : attrValue(properties, "fo:break-before")) === "page"
|
|
2682
|
-
};
|
|
2683
|
-
}
|
|
2684
|
-
function readCellText(cellElement, pkg) {
|
|
2685
|
-
const paragraphs = childrenWithTag(cellElement, "text:p");
|
|
2686
|
-
const runs = [];
|
|
2687
|
-
paragraphs.forEach((paragraph, index) => {
|
|
2688
|
-
if (index > 0) runs.push({ text: "\n" });
|
|
2689
|
-
runs.push(...readOdfParagraph(paragraph, pkg).runs);
|
|
2690
|
-
});
|
|
2691
|
-
return {
|
|
2692
|
-
runs,
|
|
2693
|
-
displayText: runs.map((run) => run.text).join("")
|
|
2694
|
-
};
|
|
2695
|
-
}
|
|
2696
|
-
function readCellValue(cellElement, displayText) {
|
|
2697
|
-
const valueType = attrValue(cellElement, "office:value-type");
|
|
2698
|
-
const stringFallback = {
|
|
2699
|
-
kind: "string",
|
|
2700
|
-
value: displayText
|
|
2701
|
-
};
|
|
2702
|
-
switch (valueType) {
|
|
2703
|
-
case "float": {
|
|
2704
|
-
const value = parseRequiredNumber(attrValue(cellElement, "office:value"));
|
|
2705
|
-
return value === void 0 ? stringFallback : {
|
|
2706
|
-
kind: "number",
|
|
2707
|
-
value
|
|
2708
|
-
};
|
|
2709
|
-
}
|
|
2710
|
-
case "percentage": {
|
|
2711
|
-
const value = parseRequiredNumber(attrValue(cellElement, "office:value"));
|
|
2712
|
-
return value === void 0 ? stringFallback : {
|
|
2713
|
-
kind: "percentage",
|
|
2714
|
-
value
|
|
2715
|
-
};
|
|
2716
|
-
}
|
|
2717
|
-
case "currency": {
|
|
2718
|
-
const value = parseRequiredNumber(attrValue(cellElement, "office:value"));
|
|
2719
|
-
if (value === void 0) return stringFallback;
|
|
2720
|
-
const currency = attrValue(cellElement, "office:currency");
|
|
2721
|
-
return currency === void 0 ? {
|
|
2722
|
-
kind: "currency",
|
|
2723
|
-
value
|
|
2724
|
-
} : {
|
|
2725
|
-
kind: "currency",
|
|
2726
|
-
value,
|
|
2727
|
-
currency
|
|
2728
|
-
};
|
|
2729
|
-
}
|
|
2730
|
-
case "boolean": {
|
|
2731
|
-
const raw = attrValue(cellElement, "office:boolean-value");
|
|
2732
|
-
return raw === void 0 ? stringFallback : {
|
|
2733
|
-
kind: "boolean",
|
|
2734
|
-
value: raw === "true"
|
|
2735
|
-
};
|
|
2736
|
-
}
|
|
2737
|
-
case "date": return {
|
|
2738
|
-
kind: "date",
|
|
2739
|
-
value: attrValue(cellElement, "office:date-value") ?? displayText
|
|
2740
|
-
};
|
|
2741
|
-
case "time": return {
|
|
2742
|
-
kind: "time",
|
|
2743
|
-
value: attrValue(cellElement, "office:time-value") ?? displayText
|
|
2744
|
-
};
|
|
2745
|
-
case "string": return {
|
|
2746
|
-
kind: "string",
|
|
2747
|
-
value: attrValue(cellElement, "office:string-value") ?? displayText
|
|
2748
|
-
};
|
|
2749
|
-
default: return { kind: "empty" };
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2752
|
-
function parseRequiredNumber(raw) {
|
|
2753
|
-
if (raw === void 0) return;
|
|
2754
|
-
const value = Number(raw);
|
|
2755
|
-
return Number.isNaN(value) ? void 0 : value;
|
|
2756
|
-
}
|
|
2757
|
-
function parsePrintRanges(value) {
|
|
2758
|
-
const first = value.split(" ").find((part) => part.length > 0);
|
|
2759
|
-
if (first === void 0) return;
|
|
2760
|
-
const separatorIndex = first.indexOf(":");
|
|
2761
|
-
if (separatorIndex === -1) return;
|
|
2762
|
-
const start = parseA1WithOptionalSheetPrefix(first.slice(0, separatorIndex));
|
|
2763
|
-
const end = parseA1WithOptionalSheetPrefix(first.slice(separatorIndex + 1));
|
|
2764
|
-
if (start === void 0 || end === void 0) return;
|
|
2765
|
-
return {
|
|
2766
|
-
startRow: start.row,
|
|
2767
|
-
startColumn: start.column,
|
|
2768
|
-
endRow: end.row,
|
|
2769
|
-
endColumn: end.column
|
|
2770
|
-
};
|
|
2771
|
-
}
|
|
2772
|
-
function parseA1WithOptionalSheetPrefix(cellPart) {
|
|
2773
|
-
const dotIndex = cellPart.lastIndexOf(".");
|
|
2774
|
-
return parseCellReference(dotIndex === -1 ? cellPart : cellPart.slice(dotIndex + 1));
|
|
2775
|
-
}
|
|
2776
|
-
function parseScalePercentage(value) {
|
|
2777
|
-
const match = /^(\d+(?:\.\d+)?)%$/.exec(value);
|
|
2778
|
-
if (match === null) return;
|
|
2779
|
-
const numeric = match[1];
|
|
2780
|
-
return numeric === void 0 ? void 0 : Number(numeric);
|
|
2781
|
-
}
|
|
2782
|
-
function parseNonNegativeInteger(value) {
|
|
2783
|
-
if (value === void 0) return;
|
|
2784
|
-
const parsed = Number.parseInt(value, 10);
|
|
2785
|
-
return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
2786
|
-
}
|
|
2787
|
-
function readTable(tableElement, pkg) {
|
|
2788
|
-
const columns = [];
|
|
2789
|
-
const rows = [];
|
|
2790
|
-
const cells = [];
|
|
2791
|
-
const manualBreakRows = [];
|
|
2792
|
-
const manualBreakColumns = [];
|
|
2793
|
-
let repeatColumns;
|
|
2794
|
-
let repeatRows;
|
|
2795
|
-
let columnCursor = 0;
|
|
2796
|
-
const cursor = new TableCursor();
|
|
2797
|
-
function processColumn(columnElement) {
|
|
2798
|
-
const { widthPt, manualBreak } = readColumnLayout(columnElement, pkg);
|
|
2799
|
-
columns.push({
|
|
2800
|
-
index: columnCursor,
|
|
2801
|
-
widthPt,
|
|
2802
|
-
hidden: isHidden(columnElement) ? true : void 0
|
|
2803
|
-
});
|
|
2804
|
-
if (manualBreak) manualBreakColumns.push(columnCursor);
|
|
2805
|
-
columnCursor += readRepeatCount(columnElement, "table:number-columns-repeated");
|
|
2806
|
-
}
|
|
2807
|
-
function processRowCells(rowElement) {
|
|
2808
|
-
for (const child of rowElement.children) {
|
|
2809
|
-
if (child.type !== "element") continue;
|
|
2810
|
-
if (child.tag === "table:covered-table-cell") cursor.nextCell(readRepeatCount(child, "table:number-columns-repeated"));
|
|
2811
|
-
else if (child.tag === "table:table-cell") {
|
|
2812
|
-
const columnIndex = cursor.columnIndex;
|
|
2813
|
-
const rowIndex = cursor.rowIndex;
|
|
2814
|
-
cursor.nextCell(readRepeatCount(child, "table:number-columns-repeated"));
|
|
2815
|
-
const formula = attrValue(child, "table:formula");
|
|
2816
|
-
const { runs, displayText } = readCellText(child, pkg);
|
|
2817
|
-
if (!(attrValue(child, "office:value-type") !== void 0) && formula === void 0 && displayText.length === 0) continue;
|
|
2818
|
-
const value = readCellValue(child, displayText);
|
|
2819
|
-
const colSpan = parseNonNegativeInteger(attrValue(child, "table:number-columns-spanned"));
|
|
2820
|
-
const rowSpan = parseNonNegativeInteger(attrValue(child, "table:number-rows-spanned"));
|
|
2821
|
-
const cell = {
|
|
2822
|
-
row: rowIndex,
|
|
2823
|
-
column: columnIndex,
|
|
2824
|
-
value,
|
|
2825
|
-
displayText
|
|
2826
|
-
};
|
|
2827
|
-
if (formula !== void 0) cell.formula = formula;
|
|
2828
|
-
if (runs.length > 0) cell.runs = runs;
|
|
2829
|
-
if (colSpan !== void 0) cell.colSpan = colSpan;
|
|
2830
|
-
if (rowSpan !== void 0) cell.rowSpan = rowSpan;
|
|
2831
|
-
cells.push(cell);
|
|
2832
|
-
}
|
|
2833
|
-
}
|
|
2834
|
-
}
|
|
2835
|
-
function processRow(rowElement) {
|
|
2836
|
-
const startIndex = cursor.rowIndex;
|
|
2837
|
-
processRowCells(rowElement);
|
|
2838
|
-
const { heightPt, manualBreak } = readRowLayout(rowElement, pkg);
|
|
2839
|
-
rows.push({
|
|
2840
|
-
index: startIndex,
|
|
2841
|
-
heightPt,
|
|
2842
|
-
hidden: isHidden(rowElement) ? true : void 0
|
|
2843
|
-
});
|
|
2844
|
-
if (manualBreak) manualBreakRows.push(startIndex);
|
|
2845
|
-
cursor.nextRow(readRepeatCount(rowElement, "table:number-rows-repeated"));
|
|
2846
|
-
}
|
|
2847
|
-
for (const child of tableElement.children) {
|
|
2848
|
-
if (child.type !== "element") continue;
|
|
2849
|
-
if (child.tag === "table:table-column") processColumn(child);
|
|
2850
|
-
else if (child.tag === "table:table-header-columns") {
|
|
2851
|
-
const startIndex = columnCursor;
|
|
2852
|
-
for (const headerChild of child.children) if (headerChild.type === "element" && headerChild.tag === "table:table-column") processColumn(headerChild);
|
|
2853
|
-
if (columnCursor > startIndex) repeatColumns = {
|
|
2854
|
-
start: startIndex,
|
|
2855
|
-
end: columnCursor - 1
|
|
2856
|
-
};
|
|
2857
|
-
} else if (child.tag === "table:table-row") processRow(child);
|
|
2858
|
-
else if (child.tag === "table:table-header-rows") {
|
|
2859
|
-
const startIndex = cursor.rowIndex;
|
|
2860
|
-
for (const headerChild of child.children) if (headerChild.type === "element" && headerChild.tag === "table:table-row") processRow(headerChild);
|
|
2861
|
-
if (cursor.rowIndex > startIndex) repeatRows = {
|
|
2862
|
-
start: startIndex,
|
|
2863
|
-
end: cursor.rowIndex - 1
|
|
2864
|
-
};
|
|
2865
|
-
}
|
|
2866
|
-
}
|
|
2867
|
-
return {
|
|
2868
|
-
columns,
|
|
2869
|
-
rows,
|
|
2870
|
-
cells,
|
|
2871
|
-
repeatColumns,
|
|
2872
|
-
repeatRows,
|
|
2873
|
-
manualBreakRows,
|
|
2874
|
-
manualBreakColumns
|
|
2875
|
-
};
|
|
2876
|
-
}
|
|
2877
|
-
function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns) {
|
|
2878
|
-
const tableStyleName = attrValue(tableElement, "table:style-name");
|
|
2879
|
-
const tableStyleElement = tableStyleName === void 0 ? void 0 : findStyleElement(tableStyleName, "table", pkg);
|
|
2880
|
-
const layoutProperties = resolvePageLayoutProperties(pkg, tableStyleElement === void 0 ? void 0 : attrValue(tableStyleElement, "style:master-page-name"));
|
|
2881
|
-
const pageSize = layoutProperties === void 0 ? void 0 : parsePageSize(layoutProperties);
|
|
2882
|
-
const margins = layoutProperties === void 0 ? void 0 : parseMargins(layoutProperties);
|
|
2883
|
-
const printTokens = new Set((layoutProperties === void 0 ? void 0 : attrValue(layoutProperties, "style:print"))?.split(" ").filter((token) => token.length > 0));
|
|
2884
|
-
const pageOrder = (layoutProperties === void 0 ? void 0 : attrValue(layoutProperties, "style:print-page-order")) === "ltr" ? "overThenDown" : "downThenOver";
|
|
2885
|
-
const scaleToRaw = layoutProperties === void 0 ? void 0 : attrValue(layoutProperties, "style:scale-to");
|
|
2886
|
-
const scale = scaleToRaw === void 0 ? void 0 : parseScalePercentage(scaleToRaw);
|
|
2887
|
-
const scaleToXRaw = layoutProperties === void 0 ? void 0 : attrValue(layoutProperties, "style:scale-to-X");
|
|
2888
|
-
const scaleToYRaw = layoutProperties === void 0 ? void 0 : attrValue(layoutProperties, "style:scale-to-Y");
|
|
2889
|
-
const fitWidth = parseNonNegativeInteger(scaleToXRaw);
|
|
2890
|
-
const fitHeight = parseNonNegativeInteger(scaleToYRaw);
|
|
2891
|
-
const fitToPages = fitWidth === void 0 || fitHeight === void 0 ? void 0 : {
|
|
2892
|
-
width: fitWidth,
|
|
2893
|
-
height: fitHeight
|
|
2894
|
-
};
|
|
2895
|
-
const printRangesRaw = attrValue(tableElement, "table:print-ranges");
|
|
2896
|
-
const printRange = printRangesRaw === void 0 ? void 0 : parsePrintRanges(printRangesRaw);
|
|
2897
|
-
const manualBreaks = manualBreakRows.length > 0 || manualBreakColumns.length > 0 ? {
|
|
2898
|
-
rows: manualBreakRows,
|
|
2899
|
-
columns: manualBreakColumns
|
|
2900
|
-
} : void 0;
|
|
2901
|
-
const settings = {
|
|
2902
|
-
pageSize: pageSize ?? document_schema_js.PAGE_SIZE_A4,
|
|
2903
|
-
margins: margins ?? DEFAULT_MARGINS,
|
|
2904
|
-
gridlines: printTokens.has("grid"),
|
|
2905
|
-
headers: printTokens.has("headers"),
|
|
2906
|
-
pageOrder
|
|
2907
|
-
};
|
|
2908
|
-
if (printRange !== void 0) settings.printRange = printRange;
|
|
2909
|
-
if (scale !== void 0) settings.scale = scale;
|
|
2910
|
-
if (fitToPages !== void 0) settings.fitToPages = fitToPages;
|
|
2911
|
-
if (repeatRows !== void 0) settings.repeatRows = repeatRows;
|
|
2912
|
-
if (repeatColumns !== void 0) settings.repeatColumns = repeatColumns;
|
|
2913
|
-
if (manualBreaks !== void 0) settings.manualBreaks = manualBreaks;
|
|
2914
|
-
return settings;
|
|
2915
|
-
}
|
|
2916
|
-
function readSheet(tableElement, pkg) {
|
|
2917
|
-
const name = attrValue(tableElement, "table:name");
|
|
2918
|
-
if (name === void 0) return;
|
|
2919
|
-
const { columns, rows, cells, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
|
|
2920
|
-
return {
|
|
2921
|
-
name,
|
|
2922
|
-
cells,
|
|
2923
|
-
columns,
|
|
2924
|
-
rows,
|
|
2925
|
-
images: [],
|
|
2926
|
-
printSettings: readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns)
|
|
2927
|
-
};
|
|
2928
|
-
}
|
|
2929
|
-
function readOds(pkg) {
|
|
2930
|
-
const contentPart = pkg.parts[CONTENT_PART$3];
|
|
2931
|
-
const root = contentPart?.kind === "xml" ? rootElement(contentPart.nodes) : void 0;
|
|
2932
|
-
const body = root === void 0 ? void 0 : findChildElement(root.children, "office:body");
|
|
2933
|
-
const spreadsheet = body === void 0 ? void 0 : findChildElement(body.children, "office:spreadsheet");
|
|
2934
|
-
const tables = spreadsheet === void 0 ? [] : childrenWithTag(spreadsheet, "table:table");
|
|
2935
|
-
const sheets = [];
|
|
2936
|
-
for (const table of tables) {
|
|
2937
|
-
const sheet = readSheet(table, pkg);
|
|
2938
|
-
if (sheet !== void 0) sheets.push(sheet);
|
|
2939
|
-
}
|
|
2940
|
-
return {
|
|
2941
|
-
metadata: readOdfMetadata(pkg),
|
|
2942
|
-
sheets
|
|
2943
|
-
};
|
|
2944
|
-
}
|
|
2945
|
-
//#endregion
|
|
2946
|
-
//#region src/typed/formula/read.ts
|
|
2947
|
-
const CONTENT_PART$2 = "content.xml";
|
|
2948
|
-
const MATH_ROOT_TAGS = ["math", "math:math"];
|
|
2949
|
-
const ANNOTATION_TAGS = ["annotation", "math:annotation"];
|
|
2950
|
-
const STARMATH_ENCODING_PREFIX = "StarMath";
|
|
2951
|
-
function findMathRoot(nodes) {
|
|
2952
|
-
const root = rootElement(nodes);
|
|
2953
|
-
if (root === void 0) return;
|
|
2954
|
-
if (MATH_ROOT_TAGS.includes(root.tag)) return root;
|
|
2955
|
-
for (const tag of MATH_ROOT_TAGS) {
|
|
2956
|
-
const [found] = elementsWithTag(root.children, tag);
|
|
2957
|
-
if (found !== void 0) return found;
|
|
2958
|
-
}
|
|
2959
|
-
}
|
|
2960
|
-
function annotationText(element) {
|
|
2961
|
-
let text = "";
|
|
2962
|
-
for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
|
|
2963
|
-
return text;
|
|
2964
|
-
}
|
|
2965
|
-
function findStarMathAnnotation(mathRoot) {
|
|
2966
|
-
for (const tag of ANNOTATION_TAGS) for (const annotation of elementsWithTag(mathRoot.children, tag)) {
|
|
2967
|
-
if (!attrValue(annotation, "encoding")?.startsWith(STARMATH_ENCODING_PREFIX)) continue;
|
|
2968
|
-
const text = annotationText(annotation);
|
|
2969
|
-
if (text.length > 0) return text;
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
function readOdfFormula(pkg) {
|
|
2973
|
-
const contentPart = pkg.parts[CONTENT_PART$2];
|
|
2974
|
-
if (contentPart?.kind !== "xml") throw new Error(`readOdfFormula: package has no ${CONTENT_PART$2} part`);
|
|
2975
|
-
const mathRoot = findMathRoot(contentPart.nodes);
|
|
2976
|
-
if (mathRoot === void 0) throw new Error(`readOdfFormula: ${CONTENT_PART$2} has no MathML root element`);
|
|
2977
|
-
const metadata = readOdfMetadata(pkg);
|
|
2978
|
-
const starMath = findStarMathAnnotation(mathRoot);
|
|
2979
|
-
return starMath === void 0 ? {
|
|
2980
|
-
mathml: mathRoot.children,
|
|
2981
|
-
metadata
|
|
2982
|
-
} : {
|
|
2983
|
-
starMath,
|
|
2984
|
-
mathml: mathRoot.children,
|
|
2985
|
-
metadata
|
|
2986
|
-
};
|
|
2987
|
-
}
|
|
2988
|
-
//#endregion
|
|
2989
|
-
//#region src/typed/odm/read.ts
|
|
2990
|
-
const CONTENT_PART$1 = "content.xml";
|
|
2991
|
-
function readSection(element) {
|
|
2992
|
-
const sourceElement = findChildElement(element.children, "text:section-source");
|
|
2993
|
-
if (sourceElement === void 0) return;
|
|
2994
|
-
const name = attrValue(element, "text:name");
|
|
2995
|
-
const href = attrValue(sourceElement, "xlink:href");
|
|
2996
|
-
if (name === void 0 || href === void 0) return;
|
|
2997
|
-
const filterName = attrValue(sourceElement, "text:filter-name");
|
|
2998
|
-
return filterName === void 0 ? {
|
|
2999
|
-
name,
|
|
3000
|
-
href
|
|
3001
|
-
} : {
|
|
3002
|
-
name,
|
|
3003
|
-
href,
|
|
3004
|
-
filterName
|
|
3005
|
-
};
|
|
3006
|
-
}
|
|
3007
|
-
function readOdm(pkg) {
|
|
3008
|
-
const contentPart = pkg.parts[CONTENT_PART$1];
|
|
3009
|
-
if (contentPart?.kind !== "xml") throw new Error(`readOdm: package has no ${CONTENT_PART$1} part`);
|
|
3010
|
-
const contentRoot = rootElement(contentPart.nodes);
|
|
3011
|
-
const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
|
|
3012
|
-
const textElement = body === void 0 ? void 0 : findChildElement(body.children, "office:text");
|
|
3013
|
-
if (textElement === void 0) throw new Error(`readOdm: ${CONTENT_PART$1} has no office:body/office:text element`);
|
|
3014
|
-
const sections = [];
|
|
3015
|
-
for (const node of textElement.children) {
|
|
3016
|
-
if (node.type !== "element" || node.tag !== "text:section") continue;
|
|
3017
|
-
const section = readSection(node);
|
|
3018
|
-
if (section !== void 0) sections.push(section);
|
|
3019
|
-
}
|
|
3020
|
-
return { sections };
|
|
3021
|
-
}
|
|
3022
|
-
//#endregion
|
|
3023
|
-
//#region src/typed/odb/read.ts
|
|
3024
|
-
const CONTENT_PART = "content.xml";
|
|
3025
|
-
const EMBEDDED_URL_PREFIX = "sdbc:embedded:";
|
|
3026
|
-
const SUBDOCUMENT_CONTENT_SUFFIX = "/content.xml";
|
|
3027
|
-
function isXmlMediaType(mediaType) {
|
|
3028
|
-
return mediaType === "text/xml" || mediaType === "application/xml" || mediaType.endsWith("+xml");
|
|
3029
|
-
}
|
|
3030
|
-
function formatServerDatabaseUrl(serverDatabase) {
|
|
3031
|
-
const dbType = attrValue(serverDatabase, "db:type");
|
|
3032
|
-
if (dbType === void 0) return;
|
|
3033
|
-
const hostname = attrValue(serverDatabase, "db:hostname");
|
|
3034
|
-
const port = attrValue(serverDatabase, "db:port");
|
|
3035
|
-
const localSocketName = attrValue(serverDatabase, "db:local-socket-name");
|
|
3036
|
-
const databaseName = attrValue(serverDatabase, "db:database-name");
|
|
3037
|
-
const host = hostname === void 0 ? localSocketName : `${hostname}${port === void 0 ? "" : `:${port}`}`;
|
|
3038
|
-
if (host === void 0) return databaseName === void 0 ? `${dbType}://` : `${dbType}:///${databaseName}`;
|
|
3039
|
-
return databaseName === void 0 ? `${dbType}://${host}` : `${dbType}://${host}/${databaseName}`;
|
|
3040
|
-
}
|
|
3041
|
-
function readConnectionInfo(databaseElement) {
|
|
3042
|
-
const dataSource = findChildElement(databaseElement.children, "db:data-source");
|
|
3043
|
-
const connectionData = dataSource === void 0 ? void 0 : findChildElement(dataSource.children, "db:connection-data");
|
|
3044
|
-
if (connectionData === void 0) return;
|
|
3045
|
-
const resource = findChildElement(connectionData.children, "db:connection-resource");
|
|
3046
|
-
if (resource !== void 0) {
|
|
3047
|
-
const url = attrValue(resource, "xlink:href");
|
|
3048
|
-
if (url === void 0) return;
|
|
3049
|
-
return {
|
|
3050
|
-
type: url.startsWith(EMBEDDED_URL_PREFIX) ? "embedded" : "external",
|
|
3051
|
-
url
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
const description = findChildElement(connectionData.children, "db:database-description");
|
|
3055
|
-
if (description === void 0) return;
|
|
3056
|
-
const fileBased = findChildElement(description.children, "db:file-based-database");
|
|
3057
|
-
if (fileBased !== void 0) {
|
|
3058
|
-
const url = attrValue(fileBased, "xlink:href");
|
|
3059
|
-
return url === void 0 ? { type: "external" } : {
|
|
3060
|
-
type: "external",
|
|
3061
|
-
url
|
|
3062
|
-
};
|
|
3063
|
-
}
|
|
3064
|
-
const serverDatabase = findChildElement(description.children, "db:server-database");
|
|
3065
|
-
if (serverDatabase !== void 0) {
|
|
3066
|
-
const url = formatServerDatabaseUrl(serverDatabase);
|
|
3067
|
-
return url === void 0 ? { type: "external" } : {
|
|
3068
|
-
type: "external",
|
|
3069
|
-
url
|
|
3070
|
-
};
|
|
3071
|
-
}
|
|
3072
|
-
}
|
|
3073
|
-
function collectQueryNames(container, names) {
|
|
3074
|
-
for (const child of container.children) {
|
|
3075
|
-
if (child.type !== "element") continue;
|
|
3076
|
-
if (child.tag === "db:query") {
|
|
3077
|
-
const name = attrValue(child, "db:name");
|
|
3078
|
-
if (name !== void 0) names.push(name);
|
|
3079
|
-
} else if (child.tag === "db:query-collection") collectQueryNames(child, names);
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3082
|
-
function collectTableNames(databaseElement) {
|
|
3083
|
-
const names = [];
|
|
3084
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3085
|
-
const pushName = (name) => {
|
|
3086
|
-
if (name !== void 0 && !seen.has(name)) {
|
|
3087
|
-
seen.add(name);
|
|
3088
|
-
names.push(name);
|
|
3089
|
-
}
|
|
3090
|
-
};
|
|
3091
|
-
const representations = findChildElement(databaseElement.children, "db:table-representations");
|
|
3092
|
-
if (representations !== void 0) for (const representation of childrenWithTag(representations, "db:table-representation")) pushName(attrValue(representation, "db:name"));
|
|
3093
|
-
const schemaDefinition = findChildElement(databaseElement.children, "db:schema-definition");
|
|
3094
|
-
const tableDefinitions = schemaDefinition === void 0 ? void 0 : findChildElement(schemaDefinition.children, "db:table-definitions");
|
|
3095
|
-
if (tableDefinitions !== void 0) for (const definition of childrenWithTag(tableDefinitions, "db:table-definition")) pushName(attrValue(definition, "db:name"));
|
|
3096
|
-
return names;
|
|
3097
|
-
}
|
|
3098
|
-
function subdocumentNamesUnderPrefix(entries, prefix) {
|
|
3099
|
-
const names = [];
|
|
3100
|
-
for (const entry of entries) {
|
|
3101
|
-
if (!entry.fullPath.startsWith(prefix) || !entry.fullPath.endsWith(SUBDOCUMENT_CONTENT_SUFFIX) || !isXmlMediaType(entry.mediaType)) continue;
|
|
3102
|
-
const withoutSuffix = entry.fullPath.slice(0, entry.fullPath.length - 12);
|
|
3103
|
-
const lastSlash = withoutSuffix.lastIndexOf("/");
|
|
3104
|
-
const name = lastSlash === -1 ? withoutSuffix.slice(prefix.length) : withoutSuffix.slice(lastSlash + 1);
|
|
3105
|
-
if (name.length > 0) names.push(name);
|
|
3106
|
-
}
|
|
3107
|
-
return names;
|
|
3108
|
-
}
|
|
3109
|
-
function readOdbInventory(pkg) {
|
|
3110
|
-
const contentPart = pkg.parts[CONTENT_PART];
|
|
3111
|
-
if (contentPart?.kind !== "xml") throw new Error(`readOdbInventory: package has no ${CONTENT_PART} part`);
|
|
3112
|
-
const contentRoot = rootElement(contentPart.nodes);
|
|
3113
|
-
const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
|
|
3114
|
-
const databaseElement = body === void 0 ? void 0 : findChildElement(body.children, "office:database");
|
|
3115
|
-
if (databaseElement === void 0) throw new Error(`readOdbInventory: ${CONTENT_PART} has no office:body/office:database element`);
|
|
3116
|
-
const connection = readConnectionInfo(databaseElement);
|
|
3117
|
-
const queries = [];
|
|
3118
|
-
const queriesElement = findChildElement(databaseElement.children, "db:queries");
|
|
3119
|
-
if (queriesElement !== void 0) collectQueryNames(queriesElement, queries);
|
|
3120
|
-
const tables = collectTableNames(databaseElement);
|
|
3121
|
-
const manifest = readManifest(pkg);
|
|
3122
|
-
return {
|
|
3123
|
-
connection,
|
|
3124
|
-
tables,
|
|
3125
|
-
queries,
|
|
3126
|
-
forms: subdocumentNamesUnderPrefix(manifest.entries, "forms/"),
|
|
3127
|
-
reports: subdocumentNamesUnderPrefix(manifest.entries, "reports/")
|
|
3128
|
-
};
|
|
3129
|
-
}
|
|
3130
|
-
//#endregion
|
|
3131
45
|
Object.defineProperty(exports, "AlignmentSchema", {
|
|
3132
46
|
enumerable: true,
|
|
3133
47
|
get: function() {
|
|
3134
48
|
return document_schema_js.AlignmentSchema;
|
|
3135
49
|
}
|
|
3136
50
|
});
|
|
3137
|
-
exports.AttributeSchema = AttributeSchema;
|
|
3138
|
-
exports.BinaryPartSchema = BinaryPartSchema;
|
|
3139
|
-
exports.MANIFEST_PART = MANIFEST_PART;
|
|
3140
|
-
exports.META_PART = META_PART;
|
|
3141
|
-
exports.MIMETYPE_PART = MIMETYPE_PART;
|
|
3142
|
-
exports.ManifestEntrySchema = ManifestEntrySchema;
|
|
3143
|
-
exports.ManifestProblemSchema = ManifestProblemSchema;
|
|
3144
|
-
exports.ManifestSchema = ManifestSchema;
|
|
3145
|
-
exports.ODF_MEDIA_TYPES = ODF_MEDIA_TYPES;
|
|
3146
|
-
exports.ODF_NAMESPACES = ODF_NAMESPACES;
|
|
3147
|
-
exports.PackageSchema = PackageSchema;
|
|
3148
|
-
exports.PartSchema = PartSchema;
|
|
3149
|
-
exports.STYLE_FAMILIES = STYLE_FAMILIES;
|
|
3150
|
-
exports.StylePropertiesSchema = StylePropertiesSchema;
|
|
3151
|
-
exports.StyleRegistry = StyleRegistry;
|
|
3152
|
-
exports.TableCursor = TableCursor;
|
|
3153
|
-
exports.XmlCdataSchema = XmlCdataSchema;
|
|
3154
|
-
exports.XmlCommentSchema = XmlCommentSchema;
|
|
3155
|
-
exports.XmlDeclarationSchema = XmlDeclarationSchema;
|
|
3156
|
-
exports.XmlElementSchema = XmlElementSchema;
|
|
3157
|
-
exports.XmlNodeSchema = XmlNodeSchema;
|
|
3158
|
-
exports.XmlPartSchema = XmlPartSchema;
|
|
3159
|
-
exports.XmlPiSchema = XmlPiSchema;
|
|
3160
|
-
exports.XmlTextSchema = XmlTextSchema;
|
|
3161
|
-
exports.applyOdfTransform = applyOdfTransform;
|
|
3162
|
-
exports.attrValue = attrValue;
|
|
3163
|
-
exports.base64ToBytes = base64ToBytes;
|
|
3164
|
-
exports.buildManifest = buildManifest;
|
|
3165
|
-
exports.buildOdfSubpaths = buildOdfSubpaths;
|
|
3166
|
-
exports.buildStylePropertyElements = buildStylePropertyElements;
|
|
3167
|
-
exports.buildXml = buildXml;
|
|
3168
|
-
exports.bytesToBase64 = bytesToBase64;
|
|
3169
|
-
exports.canonicalPropertiesString = canonicalPropertiesString;
|
|
3170
|
-
exports.cellReference = cellReference;
|
|
3171
|
-
exports.childrenWithTag = childrenWithTag;
|
|
3172
|
-
exports.columnIndexToLetters = columnIndexToLetters;
|
|
3173
|
-
exports.columnLettersToIndex = columnLettersToIndex;
|
|
3174
|
-
exports.composeOdfGroupTransform = composeOdfGroupTransform;
|
|
3175
|
-
exports.decodeOdfText = decodeOdfText;
|
|
3176
|
-
exports.decodePackage = decodePackage;
|
|
3177
|
-
exports.decodeXmlText = decodeXmlText;
|
|
3178
|
-
exports.el = el;
|
|
3179
|
-
exports.elementsWithTag = elementsWithTag;
|
|
3180
|
-
exports.encodePackage = encodePackage;
|
|
3181
|
-
exports.encodeXmlText = encodeXmlText;
|
|
3182
|
-
exports.ensureSpan = ensureSpan;
|
|
3183
|
-
exports.findChildElement = findChildElement;
|
|
3184
|
-
exports.findStyleElement = findStyleElement;
|
|
3185
|
-
exports.formatOdfColor = formatOdfColor;
|
|
3186
|
-
exports.formatOdfLength = formatOdfLength;
|
|
3187
|
-
exports.formatPercentageMultiplier = formatPercentageMultiplier;
|
|
3188
|
-
exports.formatPt = formatPt;
|
|
3189
|
-
exports.getOdfSpaceCount = getOdfSpaceCount;
|
|
3190
|
-
exports.isStyleFamily = isStyleFamily;
|
|
3191
|
-
exports.isXmlNode = isXmlNode;
|
|
3192
|
-
exports.measureOdfNodeLength = measureOdfNodeLength;
|
|
3193
|
-
exports.mediaTypeForExtension = mediaTypeForExtension;
|
|
3194
|
-
exports.netRotationDeg = netRotationDeg;
|
|
3195
|
-
exports.packageCodec = packageCodec;
|
|
3196
|
-
exports.paragraphPropertiesToAttributes = paragraphPropertiesToAttributes;
|
|
3197
|
-
exports.parseBox = parseBox;
|
|
3198
|
-
exports.parseCellReference = parseCellReference;
|
|
3199
|
-
exports.parseLength = parseOdfLength;
|
|
3200
|
-
exports.parseLinePoints = parseLinePoints;
|
|
3201
|
-
exports.parseMargins = parseMargins;
|
|
3202
|
-
exports.parseOdfColor = parseOdfColor;
|
|
3203
|
-
exports.parseOdfLength = parseOdfLength;
|
|
3204
|
-
exports.parseOdfPathData = parseOdfPathData;
|
|
3205
|
-
exports.parseOdfPointsList = parseOdfPointsList;
|
|
3206
|
-
exports.parseOdfTransform = parseOdfTransform;
|
|
3207
|
-
exports.parseOdfViewBox = parseOdfViewBox;
|
|
3208
|
-
exports.parsePackage = parsePackage;
|
|
3209
|
-
exports.parsePageSize = parsePageSize;
|
|
3210
|
-
exports.parseParagraphProperties = parseParagraphProperties;
|
|
3211
|
-
exports.parseStyleElementProperties = parseStyleElementProperties;
|
|
3212
|
-
exports.parseTextProperties = parseTextProperties;
|
|
3213
|
-
exports.parseXml = parseXml;
|
|
3214
|
-
exports.rawSubpathFromPoints = rawSubpathFromPoints;
|
|
3215
|
-
exports.readDrawFrame = readDrawFrame;
|
|
3216
|
-
exports.readDrawPageContent = readDrawPageContent;
|
|
3217
|
-
exports.readManifest = readManifest;
|
|
3218
|
-
exports.readMimetype = readMimetype;
|
|
3219
|
-
exports.readOdbInventory = readOdbInventory;
|
|
3220
|
-
exports.readOdfFormula = readOdfFormula;
|
|
3221
|
-
exports.readOdfMetadata = readOdfMetadata;
|
|
3222
|
-
exports.readOdfParagraph = readOdfParagraph;
|
|
3223
|
-
exports.readOdfTable = readOdfTable;
|
|
3224
|
-
exports.readOdg = readOdg;
|
|
3225
|
-
exports.readOdm = readOdm;
|
|
3226
|
-
exports.readOdp = readOdp;
|
|
3227
|
-
exports.readOds = readOds;
|
|
3228
|
-
exports.readOdt = readOdt;
|
|
3229
|
-
exports.resolveDrawPageSize = resolveDrawPageSize;
|
|
3230
|
-
exports.resolveOdfShapeGeometry = resolveOdfShapeGeometry;
|
|
3231
|
-
exports.resolvePageLayoutProperties = resolvePageLayoutProperties;
|
|
3232
|
-
exports.resolveStyle = resolveStyle;
|
|
3233
|
-
exports.resolveStyleElementChain = resolveStyleElementChain;
|
|
3234
|
-
exports.rootElement = rootElement;
|
|
3235
|
-
exports.scaleOdfRawPoint = scaleOdfRawPoint;
|
|
3236
|
-
exports.serializePackage = serializePackage;
|
|
3237
|
-
exports.setDocumentMediaType = setDocumentMediaType;
|
|
3238
|
-
exports.sniffImageFormat = sniffImageFormat;
|
|
3239
|
-
exports.sumOdfNodeLength = sumOdfNodeLength;
|
|
3240
|
-
exports.syncManifest = syncManifest;
|
|
3241
|
-
exports.textPropertiesToAttributes = textPropertiesToAttributes;
|
|
3242
|
-
exports.txt = txt;
|
|
3243
|
-
exports.unzipPackage = unzipPackage;
|
|
3244
|
-
exports.validateManifest = validateManifest;
|
|
3245
|
-
exports.walkDrawShapes = walkDrawShapes;
|
|
3246
|
-
exports.writeManifest = writeManifest;
|
|
3247
|
-
exports.writeMimetype = writeMimetype;
|
|
3248
|
-
exports.xmlCodec = xmlCodec;
|
|
3249
|
-
exports.xmlnsAttributes = xmlnsAttributes;
|
|
3250
|
-
exports.zipPackage = zipPackage;
|
|
51
|
+
exports.AttributeSchema = require_model_node.AttributeSchema;
|
|
52
|
+
exports.BinaryPartSchema = require_model_package.BinaryPartSchema;
|
|
53
|
+
exports.MANIFEST_PART = require_package_io_write.MANIFEST_PART;
|
|
54
|
+
exports.META_PART = require_typed_shared_metadata.META_PART;
|
|
55
|
+
exports.MIMETYPE_PART = require_package_io_write.MIMETYPE_PART;
|
|
56
|
+
exports.ManifestEntrySchema = require_manifest.ManifestEntrySchema;
|
|
57
|
+
exports.ManifestProblemSchema = require_manifest.ManifestProblemSchema;
|
|
58
|
+
exports.ManifestSchema = require_manifest.ManifestSchema;
|
|
59
|
+
exports.ODF_MEDIA_TYPES = require_media_type.ODF_MEDIA_TYPES;
|
|
60
|
+
exports.ODF_NAMESPACES = require_ns.ODF_NAMESPACES;
|
|
61
|
+
exports.PackageSchema = require_model_package.PackageSchema;
|
|
62
|
+
exports.PartSchema = require_model_package.PartSchema;
|
|
63
|
+
exports.STYLE_FAMILIES = require_styles_registry.STYLE_FAMILIES;
|
|
64
|
+
exports.StylePropertiesSchema = require_styles_properties.StylePropertiesSchema;
|
|
65
|
+
exports.StyleRegistry = require_styles_registry.StyleRegistry;
|
|
66
|
+
exports.TableCursor = require_typed_shared_a1.TableCursor;
|
|
67
|
+
exports.XmlCdataSchema = require_model_node.XmlCdataSchema;
|
|
68
|
+
exports.XmlCommentSchema = require_model_node.XmlCommentSchema;
|
|
69
|
+
exports.XmlDeclarationSchema = require_model_node.XmlDeclarationSchema;
|
|
70
|
+
exports.XmlElementSchema = require_model_node.XmlElementSchema;
|
|
71
|
+
exports.XmlNodeSchema = require_model_node.XmlNodeSchema;
|
|
72
|
+
exports.XmlPartSchema = require_model_package.XmlPartSchema;
|
|
73
|
+
exports.XmlPiSchema = require_model_node.XmlPiSchema;
|
|
74
|
+
exports.XmlTextSchema = require_model_node.XmlTextSchema;
|
|
75
|
+
exports.applyOdfTransform = require_typed_shared_transform.applyOdfTransform;
|
|
76
|
+
exports.attrValue = require_xml_query.attrValue;
|
|
77
|
+
exports.base64ToBytes = require_util_base64.base64ToBytes;
|
|
78
|
+
exports.buildManifest = require_manifest.buildManifest;
|
|
79
|
+
exports.buildOdfSubpaths = require_typed_shared_path.buildOdfSubpaths;
|
|
80
|
+
exports.buildStylePropertyElements = require_styles_serialize.buildStylePropertyElements;
|
|
81
|
+
exports.buildXml = require_xml_build.buildXml;
|
|
82
|
+
exports.bytesToBase64 = require_util_base64.bytesToBase64;
|
|
83
|
+
exports.canonicalPropertiesString = require_styles_serialize.canonicalPropertiesString;
|
|
84
|
+
exports.cellReference = require_typed_shared_a1.cellReference;
|
|
85
|
+
exports.childrenWithTag = require_xml_query.childrenWithTag;
|
|
86
|
+
exports.columnIndexToLetters = require_typed_shared_a1.columnIndexToLetters;
|
|
87
|
+
exports.columnLettersToIndex = require_typed_shared_a1.columnLettersToIndex;
|
|
88
|
+
exports.composeOdfGroupTransform = require_typed_shared_transform.composeOdfGroupTransform;
|
|
89
|
+
exports.decodeOdfText = require_typed_shared_text.decodeOdfText;
|
|
90
|
+
exports.decodePackage = require_codec.decodePackage;
|
|
91
|
+
exports.decodeXmlText = require_xml_entities.decodeXmlText;
|
|
92
|
+
exports.el = require_xml_fragment.el;
|
|
93
|
+
exports.elementsWithTag = require_xml_query.elementsWithTag;
|
|
94
|
+
exports.encodePackage = require_codec.encodePackage;
|
|
95
|
+
exports.encodeXmlText = require_xml_entities.encodeXmlText;
|
|
96
|
+
exports.ensureSpan = require_styles_span.ensureSpan;
|
|
97
|
+
exports.findChildElement = require_xml_query.findChildElement;
|
|
98
|
+
exports.findStyleElement = require_typed_shared_cascade.findStyleElement;
|
|
99
|
+
exports.formatOdfColor = require_typed_shared_color.formatOdfColor;
|
|
100
|
+
exports.formatOdfLength = require_typed_shared_units.formatOdfLength;
|
|
101
|
+
exports.formatPercentageMultiplier = require_styles_properties.formatPercentageMultiplier;
|
|
102
|
+
exports.formatPt = require_styles_properties.formatPt;
|
|
103
|
+
exports.getOdfSpaceCount = require_typed_shared_text.getOdfSpaceCount;
|
|
104
|
+
exports.isStyleFamily = require_styles_registry.isStyleFamily;
|
|
105
|
+
exports.isXmlNode = require_model_node.isXmlNode;
|
|
106
|
+
exports.measureOdfNodeLength = require_typed_shared_text.measureOdfNodeLength;
|
|
107
|
+
exports.mediaTypeForExtension = require_media_type.mediaTypeForExtension;
|
|
108
|
+
exports.netRotationDeg = require_typed_shared_transform.netRotationDeg;
|
|
109
|
+
exports.packageCodec = require_codec.packageCodec;
|
|
110
|
+
exports.paragraphPropertiesToAttributes = require_styles_properties.paragraphPropertiesToAttributes;
|
|
111
|
+
exports.parseBox = require_typed_shared_geometry.parseBox;
|
|
112
|
+
exports.parseCellReference = require_typed_shared_a1.parseCellReference;
|
|
113
|
+
exports.parseLength = require_typed_shared_units.parseOdfLength;
|
|
114
|
+
exports.parseLinePoints = require_typed_shared_geometry.parseLinePoints;
|
|
115
|
+
exports.parseMargins = require_typed_shared_geometry.parseMargins;
|
|
116
|
+
exports.parseOdfColor = require_typed_shared_color.parseOdfColor;
|
|
117
|
+
exports.parseOdfLength = require_typed_shared_units.parseOdfLength;
|
|
118
|
+
exports.parseOdfPathData = require_typed_shared_path.parseOdfPathData;
|
|
119
|
+
exports.parseOdfPointsList = require_typed_shared_path.parseOdfPointsList;
|
|
120
|
+
exports.parseOdfTransform = require_typed_shared_transform.parseOdfTransform;
|
|
121
|
+
exports.parseOdfViewBox = require_typed_shared_path.parseOdfViewBox;
|
|
122
|
+
exports.parsePackage = require_package_io_read.parsePackage;
|
|
123
|
+
exports.parsePageSize = require_typed_shared_geometry.parsePageSize;
|
|
124
|
+
exports.parseParagraphProperties = require_styles_properties.parseParagraphProperties;
|
|
125
|
+
exports.parseStyleElementProperties = require_styles_properties.parseStyleElementProperties;
|
|
126
|
+
exports.parseTextProperties = require_styles_properties.parseTextProperties;
|
|
127
|
+
exports.parseXml = require_xml_parse.parseXml;
|
|
128
|
+
exports.rawSubpathFromPoints = require_typed_shared_path.rawSubpathFromPoints;
|
|
129
|
+
exports.readDrawFrame = require_typed_draw_shapes.readDrawFrame;
|
|
130
|
+
exports.readDrawPageContent = require_typed_draw_shapes.readDrawPageContent;
|
|
131
|
+
exports.readManifest = require_manifest.readManifest;
|
|
132
|
+
exports.readMimetype = require_mimetype.readMimetype;
|
|
133
|
+
exports.readOdbInventory = require_typed_odb_read.readOdbInventory;
|
|
134
|
+
exports.readOdfFormula = require_typed_formula_read.readOdfFormula;
|
|
135
|
+
exports.readOdfMetadata = require_typed_shared_metadata.readOdfMetadata;
|
|
136
|
+
exports.readOdfParagraph = require_typed_shared_paragraph.readOdfParagraph;
|
|
137
|
+
exports.readOdfTable = require_typed_shared_table.readOdfTable;
|
|
138
|
+
exports.readOdg = require_typed_odg_read.readOdg;
|
|
139
|
+
exports.readOdm = require_typed_odm_read.readOdm;
|
|
140
|
+
exports.readOdp = require_typed_odp_read.readOdp;
|
|
141
|
+
exports.readOds = require_typed_ods_read.readOds;
|
|
142
|
+
exports.readOdt = require_typed_odt_read.readOdt;
|
|
143
|
+
exports.resolveDrawPageSize = require_typed_shared_masterpage.resolveDrawPageSize;
|
|
144
|
+
exports.resolveOdfShapeGeometry = require_typed_shared_transform.resolveOdfShapeGeometry;
|
|
145
|
+
exports.resolvePageLayoutProperties = require_typed_shared_masterpage.resolvePageLayoutProperties;
|
|
146
|
+
exports.resolveStyle = require_typed_shared_cascade.resolveStyle;
|
|
147
|
+
exports.resolveStyleElementChain = require_typed_shared_cascade.resolveStyleElementChain;
|
|
148
|
+
exports.rootElement = require_xml_query.rootElement;
|
|
149
|
+
exports.scaleOdfRawPoint = require_typed_shared_path.scaleOdfRawPoint;
|
|
150
|
+
exports.serializePackage = require_package_io_write.serializePackage;
|
|
151
|
+
exports.setDocumentMediaType = require_manifest.setDocumentMediaType;
|
|
152
|
+
exports.sniffImageFormat = require_image_sniff.sniffImageFormat;
|
|
153
|
+
exports.sumOdfNodeLength = require_typed_shared_text.sumOdfNodeLength;
|
|
154
|
+
exports.syncManifest = require_manifest.syncManifest;
|
|
155
|
+
exports.textPropertiesToAttributes = require_styles_properties.textPropertiesToAttributes;
|
|
156
|
+
exports.txt = require_xml_fragment.txt;
|
|
157
|
+
exports.unzipPackage = require_zip.unzipPackage;
|
|
158
|
+
exports.validateManifest = require_manifest.validateManifest;
|
|
159
|
+
exports.walkDrawShapes = require_typed_draw_shapes.walkDrawShapes;
|
|
160
|
+
exports.writeManifest = require_manifest.writeManifest;
|
|
161
|
+
exports.writeMimetype = require_mimetype.writeMimetype;
|
|
162
|
+
exports.xmlCodec = require_codec.xmlCodec;
|
|
163
|
+
exports.xmlnsAttributes = require_ns.xmlnsAttributes;
|
|
164
|
+
exports.zipPackage = require_zip.zipPackage;
|