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.
Files changed (178) hide show
  1. package/README.md +39 -0
  2. package/dist/codec.cjs +28 -0
  3. package/dist/codec.d.cts +72 -0
  4. package/dist/codec.d.ts +72 -0
  5. package/dist/codec.js +24 -0
  6. package/dist/image/sniff.cjs +28 -0
  7. package/dist/image/sniff.d.cts +5 -0
  8. package/dist/image/sniff.d.ts +5 -0
  9. package/dist/image/sniff.js +27 -0
  10. package/dist/index.cjs +156 -3242
  11. package/dist/index.d.cts +42 -679
  12. package/dist/index.d.ts +42 -679
  13. package/dist/index.js +42 -3129
  14. package/dist/manifest.cjs +252 -0
  15. package/dist/manifest.d.cts +41 -0
  16. package/dist/manifest.d.ts +41 -0
  17. package/dist/manifest.js +242 -0
  18. package/dist/media-type.cjs +27 -0
  19. package/dist/media-type.d.cts +20 -0
  20. package/dist/media-type.d.ts +20 -0
  21. package/dist/media-type.js +25 -0
  22. package/dist/mimetype.cjs +19 -0
  23. package/dist/mimetype.d.cts +7 -0
  24. package/dist/mimetype.d.ts +7 -0
  25. package/dist/mimetype.js +16 -0
  26. package/dist/model/node.cjs +67 -0
  27. package/dist/model/node.d.cts +2 -0
  28. package/dist/model/node.d.ts +2 -0
  29. package/dist/model/node.js +58 -0
  30. package/dist/model/package.cjs +19 -0
  31. package/dist/model/package.d.cts +114 -0
  32. package/dist/model/package.d.ts +114 -0
  33. package/dist/model/package.js +15 -0
  34. package/dist/node-CkBWRjNR.d.cts +83 -0
  35. package/dist/node-CkBWRjNR.d.ts +83 -0
  36. package/dist/ns.cjs +37 -0
  37. package/dist/ns.d.cts +32 -0
  38. package/dist/ns.d.ts +32 -0
  39. package/dist/ns.js +35 -0
  40. package/dist/package-io/read.cjs +35 -0
  41. package/dist/package-io/read.d.cts +5 -0
  42. package/dist/package-io/read.d.ts +5 -0
  43. package/dist/package-io/read.js +34 -0
  44. package/dist/package-io/write.cjs +36 -0
  45. package/dist/package-io/write.d.cts +7 -0
  46. package/dist/package-io/write.d.ts +7 -0
  47. package/dist/package-io/write.js +33 -0
  48. package/dist/styles/properties.cjs +286 -0
  49. package/dist/styles/properties.d.cts +45 -0
  50. package/dist/styles/properties.d.ts +45 -0
  51. package/dist/styles/properties.js +277 -0
  52. package/dist/styles/registry.cjs +212 -0
  53. package/dist/styles/registry.d.cts +37 -0
  54. package/dist/styles/registry.d.ts +37 -0
  55. package/dist/styles/registry.js +209 -0
  56. package/dist/styles/serialize.cjs +23 -0
  57. package/dist/styles/serialize.d.cts +7 -0
  58. package/dist/styles/serialize.d.ts +7 -0
  59. package/dist/styles/serialize.js +21 -0
  60. package/dist/styles/span.cjs +114 -0
  61. package/dist/styles/span.d.cts +5 -0
  62. package/dist/styles/span.d.ts +5 -0
  63. package/dist/styles/span.js +113 -0
  64. package/dist/typed/draw/shapes.cjs +314 -0
  65. package/dist/typed/draw/shapes.d.cts +14 -0
  66. package/dist/typed/draw/shapes.d.ts +14 -0
  67. package/dist/typed/draw/shapes.js +311 -0
  68. package/dist/typed/formula/read.cjs +48 -0
  69. package/dist/typed/formula/read.d.cts +12 -0
  70. package/dist/typed/formula/read.d.ts +12 -0
  71. package/dist/typed/formula/read.js +47 -0
  72. package/dist/typed/odb/read.cjs +112 -0
  73. package/dist/typed/odb/read.d.cts +17 -0
  74. package/dist/typed/odb/read.d.ts +17 -0
  75. package/dist/typed/odb/read.js +111 -0
  76. package/dist/typed/odg/read.cjs +30 -0
  77. package/dist/typed/odg/read.d.cts +10 -0
  78. package/dist/typed/odg/read.d.ts +10 -0
  79. package/dist/typed/odg/read.js +29 -0
  80. package/dist/typed/odm/read.cjs +37 -0
  81. package/dist/typed/odm/read.d.cts +15 -0
  82. package/dist/typed/odm/read.d.ts +15 -0
  83. package/dist/typed/odm/read.js +36 -0
  84. package/dist/typed/odp/read.cjs +39 -0
  85. package/dist/typed/odp/read.d.cts +10 -0
  86. package/dist/typed/odp/read.d.ts +10 -0
  87. package/dist/typed/odp/read.js +38 -0
  88. package/dist/typed/ods/read.cjs +318 -0
  89. package/dist/typed/ods/read.d.cts +10 -0
  90. package/dist/typed/ods/read.d.ts +10 -0
  91. package/dist/typed/ods/read.js +317 -0
  92. package/dist/typed/odt/read.cjs +112 -0
  93. package/dist/typed/odt/read.d.cts +10 -0
  94. package/dist/typed/odt/read.d.ts +10 -0
  95. package/dist/typed/odt/read.js +111 -0
  96. package/dist/typed/shared/a1.cjs +68 -0
  97. package/dist/typed/shared/a1.d.cts +18 -0
  98. package/dist/typed/shared/a1.d.ts +18 -0
  99. package/dist/typed/shared/a1.js +63 -0
  100. package/dist/typed/shared/cascade.cjs +102 -0
  101. package/dist/typed/shared/cascade.d.cts +22 -0
  102. package/dist/typed/shared/cascade.d.ts +22 -0
  103. package/dist/typed/shared/cascade.js +99 -0
  104. package/dist/typed/shared/color.cjs +14 -0
  105. package/dist/typed/shared/color.d.cts +6 -0
  106. package/dist/typed/shared/color.d.ts +6 -0
  107. package/dist/typed/shared/color.js +12 -0
  108. package/dist/typed/shared/geometry.cjs +79 -0
  109. package/dist/typed/shared/geometry.d.cts +12 -0
  110. package/dist/typed/shared/geometry.d.ts +12 -0
  111. package/dist/typed/shared/geometry.js +75 -0
  112. package/dist/typed/shared/masterpage.cjs +39 -0
  113. package/dist/typed/shared/masterpage.d.cts +8 -0
  114. package/dist/typed/shared/masterpage.d.ts +8 -0
  115. package/dist/typed/shared/masterpage.js +37 -0
  116. package/dist/typed/shared/metadata.cjs +42 -0
  117. package/dist/typed/shared/metadata.d.cts +7 -0
  118. package/dist/typed/shared/metadata.d.ts +7 -0
  119. package/dist/typed/shared/metadata.js +40 -0
  120. package/dist/typed/shared/paragraph.cjs +57 -0
  121. package/dist/typed/shared/paragraph.d.cts +7 -0
  122. package/dist/typed/shared/paragraph.d.ts +7 -0
  123. package/dist/typed/shared/paragraph.js +56 -0
  124. package/dist/typed/shared/path.cjs +261 -0
  125. package/dist/typed/shared/path.d.cts +34 -0
  126. package/dist/typed/shared/path.d.ts +34 -0
  127. package/dist/typed/shared/path.js +255 -0
  128. package/dist/typed/shared/style.cjs +8 -0
  129. package/dist/typed/shared/style.d.cts +2 -0
  130. package/dist/typed/shared/style.d.ts +2 -0
  131. package/dist/typed/shared/style.js +2 -0
  132. package/dist/typed/shared/table.cjs +84 -0
  133. package/dist/typed/shared/table.d.cts +7 -0
  134. package/dist/typed/shared/table.d.ts +7 -0
  135. package/dist/typed/shared/table.js +83 -0
  136. package/dist/typed/shared/text.cjs +43 -0
  137. package/dist/typed/shared/text.d.cts +8 -0
  138. package/dist/typed/shared/text.d.ts +8 -0
  139. package/dist/typed/shared/text.js +39 -0
  140. package/dist/typed/shared/transform.cjs +112 -0
  141. package/dist/typed/shared/transform.d.cts +26 -0
  142. package/dist/typed/shared/transform.d.ts +26 -0
  143. package/dist/typed/shared/transform.js +107 -0
  144. package/dist/typed/shared/units.cjs +35 -0
  145. package/dist/typed/shared/units.d.cts +2 -0
  146. package/dist/typed/shared/units.d.ts +2 -0
  147. package/dist/typed/shared/units.js +33 -0
  148. package/dist/units-7pCiECuP.d.cts +6 -0
  149. package/dist/units-7pCiECuP.d.ts +6 -0
  150. package/dist/util/base64.cjs +48 -0
  151. package/dist/util/base64.d.cts +5 -0
  152. package/dist/util/base64.d.ts +5 -0
  153. package/dist/util/base64.js +46 -0
  154. package/dist/xml/build.cjs +46 -0
  155. package/dist/xml/build.d.cts +5 -0
  156. package/dist/xml/build.d.ts +5 -0
  157. package/dist/xml/build.js +46 -0
  158. package/dist/xml/entities.cjs +19 -0
  159. package/dist/xml/entities.d.cts +5 -0
  160. package/dist/xml/entities.d.ts +5 -0
  161. package/dist/xml/entities.js +17 -0
  162. package/dist/xml/fragment.cjs +22 -0
  163. package/dist/xml/fragment.d.cts +6 -0
  164. package/dist/xml/fragment.d.ts +6 -0
  165. package/dist/xml/fragment.js +20 -0
  166. package/dist/xml/parse.cjs +88 -0
  167. package/dist/xml/parse.d.cts +5 -0
  168. package/dist/xml/parse.d.ts +5 -0
  169. package/dist/xml/parse.js +88 -0
  170. package/dist/xml/query.cjs +33 -0
  171. package/dist/xml/query.d.cts +9 -0
  172. package/dist/xml/query.d.ts +9 -0
  173. package/dist/xml/query.js +28 -0
  174. package/dist/zip.cjs +15 -0
  175. package/dist/zip.d.cts +9 -0
  176. package/dist/zip.d.ts +9 -0
  177. package/dist/zip.js +13 -0
  178. package/package.json +9 -1
@@ -0,0 +1,209 @@
1
+ import { el } from "../xml/fragment.js";
2
+ import { encodeXmlText } from "../xml/entities.js";
3
+ import { parseStyleElementProperties } from "./properties.js";
4
+ import { buildStylePropertyElements, canonicalPropertiesString } from "./serialize.js";
5
+ //#region src/styles/registry.ts
6
+ const STYLE_FAMILIES = [
7
+ "paragraph",
8
+ "text",
9
+ "table",
10
+ "table-column",
11
+ "table-row",
12
+ "table-cell",
13
+ "graphic"
14
+ ];
15
+ function isStyleFamily(value) {
16
+ return value === "paragraph" || value === "text" || value === "table" || value === "table-column" || value === "table-row" || value === "table-cell" || value === "graphic";
17
+ }
18
+ const CONTENT_PREFIXES = {
19
+ paragraph: "P",
20
+ text: "T",
21
+ table: "ta",
22
+ "table-column": "co",
23
+ "table-row": "ro",
24
+ "table-cell": "ce",
25
+ graphic: "fr"
26
+ };
27
+ const STYLES_PREFIXES = {
28
+ paragraph: "PS",
29
+ text: "TS",
30
+ table: "taS",
31
+ "table-column": "coS",
32
+ "table-row": "roS",
33
+ "table-cell": "ceS",
34
+ graphic: "frS"
35
+ };
36
+ function prefixesForPart(partPath) {
37
+ const baseName = partPath.slice(partPath.lastIndexOf("/") + 1);
38
+ if (baseName === "content.xml") return CONTENT_PREFIXES;
39
+ if (baseName === "styles.xml") return STYLES_PREFIXES;
40
+ throw new Error(`StyleRegistry.forPart: expected a part named "content.xml" or "styles.xml" (by base name), got "${partPath}"`);
41
+ }
42
+ function emptyFamilySets() {
43
+ return {
44
+ paragraph: /* @__PURE__ */ new Set(),
45
+ text: /* @__PURE__ */ new Set(),
46
+ table: /* @__PURE__ */ new Set(),
47
+ "table-column": /* @__PURE__ */ new Set(),
48
+ "table-row": /* @__PURE__ */ new Set(),
49
+ "table-cell": /* @__PURE__ */ new Set(),
50
+ graphic: /* @__PURE__ */ new Set()
51
+ };
52
+ }
53
+ function attrValue(element, name) {
54
+ return element.attributes.find((attribute) => attribute.name === name)?.value;
55
+ }
56
+ function findDirectChild(nodes, tag) {
57
+ for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
58
+ }
59
+ function findRootElement(nodes) {
60
+ const root = nodes.find((node) => node.type === "element");
61
+ 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");
62
+ return root;
63
+ }
64
+ function ensureAutomaticStyles(root) {
65
+ const existing = findDirectChild(root.children, "office:automatic-styles");
66
+ if (existing !== void 0) return existing;
67
+ const created = el("office:automatic-styles");
68
+ const insertBeforeTags = /* @__PURE__ */ new Set([
69
+ "office:body",
70
+ "office:master-styles",
71
+ "office:settings"
72
+ ]);
73
+ const insertIndex = root.children.findIndex((node) => node.type === "element" && insertBeforeTags.has(node.tag));
74
+ if (insertIndex === -1) root.children.push(created);
75
+ else root.children.splice(insertIndex, 0, created);
76
+ return created;
77
+ }
78
+ function reserveStyleNames(container, reserved) {
79
+ for (const child of container.children) {
80
+ if (child.type !== "element" || child.tag !== "style:style") continue;
81
+ const name = attrValue(child, "style:name");
82
+ const family = attrValue(child, "style:family");
83
+ if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
84
+ reserved[family].add(name);
85
+ }
86
+ }
87
+ const FINGERPRINT_SEPARATOR = "\0";
88
+ const NO_PARENT_SENTINEL = "";
89
+ function computeFingerprint(family, properties, parentStyleName) {
90
+ const parentComponent = parentStyleName ?? NO_PARENT_SENTINEL;
91
+ return [
92
+ family,
93
+ canonicalPropertiesString(properties),
94
+ parentComponent
95
+ ].join(FINGERPRINT_SEPARATOR);
96
+ }
97
+ var StyleRegistry = class StyleRegistry {
98
+ automaticStyles;
99
+ prefixes;
100
+ reservedByFamily;
101
+ knownStyles = /* @__PURE__ */ new Map();
102
+ fingerprintToName = /* @__PURE__ */ new Map();
103
+ nameToFingerprint = /* @__PURE__ */ new Map();
104
+ familyCounters = {
105
+ paragraph: 1,
106
+ text: 1,
107
+ table: 1,
108
+ "table-column": 1,
109
+ "table-row": 1,
110
+ "table-cell": 1,
111
+ graphic: 1
112
+ };
113
+ constructor(automaticStyles, prefixes, reservedByFamily) {
114
+ this.automaticStyles = automaticStyles;
115
+ this.prefixes = prefixes;
116
+ this.reservedByFamily = reservedByFamily;
117
+ }
118
+ static forPart(pkg, partPath, options = {}) {
119
+ const part = pkg.parts[partPath];
120
+ if (part?.kind !== "xml") throw new Error(`StyleRegistry.forPart: "${partPath}" is not an XML part of the given package`);
121
+ const prefixes = prefixesForPart(partPath);
122
+ const root = findRootElement(part.nodes);
123
+ const automaticStyles = ensureAutomaticStyles(root);
124
+ const reservedByFamily = emptyFamilySets();
125
+ const registry = new StyleRegistry(automaticStyles, prefixes, reservedByFamily);
126
+ for (const child of automaticStyles.children) {
127
+ if (child.type !== "element" || child.tag !== "style:style") continue;
128
+ const name = attrValue(child, "style:name");
129
+ const family = attrValue(child, "style:family");
130
+ if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
131
+ registry.knownStyles.set(name, child);
132
+ reservedByFamily[family].add(name);
133
+ const parsed = parseStyleElementProperties(child);
134
+ if (!parsed.hasUnknown) {
135
+ const parentStyleName = attrValue(child, "style:parent-style-name");
136
+ const fingerprint = computeFingerprint(family, parsed.properties, parentStyleName);
137
+ if (!registry.fingerprintToName.has(fingerprint)) {
138
+ registry.fingerprintToName.set(fingerprint, name);
139
+ registry.nameToFingerprint.set(name, fingerprint);
140
+ }
141
+ }
142
+ }
143
+ const ownStyles = findDirectChild(root.children, "office:styles");
144
+ if (ownStyles !== void 0) reserveStyleNames(ownStyles, reservedByFamily);
145
+ if (options.otherPart !== void 0) {
146
+ const otherPart = options.otherPart.pkg.parts[options.otherPart.partPath];
147
+ if (otherPart?.kind === "xml") {
148
+ const otherRoot = findRootElement(otherPart.nodes);
149
+ const otherAutomatic = findDirectChild(otherRoot.children, "office:automatic-styles");
150
+ if (otherAutomatic !== void 0) reserveStyleNames(otherAutomatic, reservedByFamily);
151
+ const otherStyles = findDirectChild(otherRoot.children, "office:styles");
152
+ if (otherStyles !== void 0) reserveStyleNames(otherStyles, reservedByFamily);
153
+ }
154
+ }
155
+ if (options.additionalReservedNames !== void 0) for (const family of STYLE_FAMILIES) for (const name of options.additionalReservedNames) reservedByFamily[family].add(name);
156
+ return registry;
157
+ }
158
+ fingerprint(request) {
159
+ return computeFingerprint(request.family, request.properties, request.parentStyleName);
160
+ }
161
+ intern(request) {
162
+ const fingerprint = this.fingerprint(request);
163
+ const existingName = this.fingerprintToName.get(fingerprint);
164
+ if (existingName !== void 0) return existingName;
165
+ const name = this.mintName(request.family);
166
+ const attributes = {
167
+ "style:name": name,
168
+ "style:family": request.family
169
+ };
170
+ if (request.parentStyleName !== void 0) attributes["style:parent-style-name"] = encodeXmlText(request.parentStyleName);
171
+ const styleElement = el("style:style", attributes, buildStylePropertyElements(request.properties));
172
+ this.automaticStyles.children.push(styleElement);
173
+ this.knownStyles.set(name, styleElement);
174
+ this.reservedByFamily[request.family].add(name);
175
+ this.fingerprintToName.set(fingerprint, name);
176
+ this.nameToFingerprint.set(name, fingerprint);
177
+ return name;
178
+ }
179
+ mintName(family) {
180
+ const prefix = this.prefixes[family];
181
+ const reserved = this.reservedByFamily[family];
182
+ let counter = this.familyCounters[family];
183
+ while (reserved.has(`${prefix}${counter}`)) counter += 1;
184
+ const name = `${prefix}${counter}`;
185
+ this.familyCounters[family] = counter + 1;
186
+ return name;
187
+ }
188
+ names() {
189
+ return [...this.knownStyles.keys()];
190
+ }
191
+ gc(referenced) {
192
+ let removed = 0;
193
+ for (const [name, element] of [...this.knownStyles]) {
194
+ if (referenced.has(name)) continue;
195
+ const index = this.automaticStyles.children.indexOf(element);
196
+ if (index !== -1) this.automaticStyles.children.splice(index, 1);
197
+ this.knownStyles.delete(name);
198
+ const fingerprint = this.nameToFingerprint.get(name);
199
+ if (fingerprint !== void 0) {
200
+ this.fingerprintToName.delete(fingerprint);
201
+ this.nameToFingerprint.delete(name);
202
+ }
203
+ removed += 1;
204
+ }
205
+ return removed;
206
+ }
207
+ };
208
+ //#endregion
209
+ export { STYLE_FAMILIES, StyleRegistry, isStyleFamily };
@@ -0,0 +1,23 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_xml_fragment = require("../xml/fragment.cjs");
3
+ const require_styles_properties = require("./properties.cjs");
4
+ //#region src/styles/serialize.ts
5
+ function attributesToRecord(attributes) {
6
+ const record = {};
7
+ for (const attribute of attributes) record[attribute.name] = attribute.value;
8
+ return record;
9
+ }
10
+ function buildStylePropertyElements(properties) {
11
+ const elements = [];
12
+ const paragraphAttributes = require_styles_properties.paragraphPropertiesToAttributes(properties);
13
+ if (paragraphAttributes.length > 0) elements.push(require_xml_fragment.el("style:paragraph-properties", attributesToRecord(paragraphAttributes)));
14
+ const textAttributes = require_styles_properties.textPropertiesToAttributes(properties);
15
+ if (textAttributes.length > 0) elements.push(require_xml_fragment.el("style:text-properties", attributesToRecord(textAttributes)));
16
+ return elements;
17
+ }
18
+ function canonicalPropertiesString(properties) {
19
+ return [...require_styles_properties.paragraphPropertiesToAttributes(properties), ...require_styles_properties.textPropertiesToAttributes(properties)].map((attribute) => `${attribute.name}=${attribute.value}`).join("|");
20
+ }
21
+ //#endregion
22
+ exports.buildStylePropertyElements = buildStylePropertyElements;
23
+ exports.canonicalPropertiesString = canonicalPropertiesString;
@@ -0,0 +1,7 @@
1
+ import { l as XmlElement } from "../node-CkBWRjNR.cjs";
2
+ import { StyleProperties } from "./properties.cjs";
3
+ //#region src/styles/serialize.d.ts
4
+ declare function buildStylePropertyElements(properties: StyleProperties): XmlElement[];
5
+ declare function canonicalPropertiesString(properties: StyleProperties): string;
6
+ //#endregion
7
+ export { buildStylePropertyElements, canonicalPropertiesString };
@@ -0,0 +1,7 @@
1
+ import { l as XmlElement } from "../node-CkBWRjNR.js";
2
+ import { StyleProperties } from "./properties.js";
3
+ //#region src/styles/serialize.d.ts
4
+ declare function buildStylePropertyElements(properties: StyleProperties): XmlElement[];
5
+ declare function canonicalPropertiesString(properties: StyleProperties): string;
6
+ //#endregion
7
+ export { buildStylePropertyElements, canonicalPropertiesString };
@@ -0,0 +1,21 @@
1
+ import { el } from "../xml/fragment.js";
2
+ import { paragraphPropertiesToAttributes, textPropertiesToAttributes } from "./properties.js";
3
+ //#region src/styles/serialize.ts
4
+ function attributesToRecord(attributes) {
5
+ const record = {};
6
+ for (const attribute of attributes) record[attribute.name] = attribute.value;
7
+ return record;
8
+ }
9
+ function buildStylePropertyElements(properties) {
10
+ const elements = [];
11
+ const paragraphAttributes = paragraphPropertiesToAttributes(properties);
12
+ if (paragraphAttributes.length > 0) elements.push(el("style:paragraph-properties", attributesToRecord(paragraphAttributes)));
13
+ const textAttributes = textPropertiesToAttributes(properties);
14
+ if (textAttributes.length > 0) elements.push(el("style:text-properties", attributesToRecord(textAttributes)));
15
+ return elements;
16
+ }
17
+ function canonicalPropertiesString(properties) {
18
+ return [...paragraphPropertiesToAttributes(properties), ...textPropertiesToAttributes(properties)].map((attribute) => `${attribute.name}=${attribute.value}`).join("|");
19
+ }
20
+ //#endregion
21
+ export { buildStylePropertyElements, canonicalPropertiesString };
@@ -0,0 +1,114 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_xml_fragment = require("../xml/fragment.cjs");
3
+ const require_xml_entities = require("../xml/entities.cjs");
4
+ const require_typed_shared_text = require("../typed/shared/text.cjs");
5
+ //#region src/styles/span.ts
6
+ function ensureSpan(paragraph, start, end, styleName) {
7
+ if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) throw new Error(`ensureSpan: invalid range [${start}, ${end})`);
8
+ const total = require_typed_shared_text.sumOdfNodeLength(paragraph.children);
9
+ if (end > total) throw new Error(`ensureSpan: range end ${end} exceeds the container's total character length ${total}`);
10
+ const { before, after: rest } = splitChildrenAt(paragraph.children, start);
11
+ const { before: middle, after } = splitChildrenAt(rest, end - start);
12
+ let span;
13
+ const soleChild = middle.length === 1 ? middle[0] : void 0;
14
+ if (soleChild?.type === "element" && soleChild.tag === "text:span") {
15
+ span = soleChild;
16
+ setStyleName(span, styleName);
17
+ } else span = require_xml_fragment.el("text:span", { "text:style-name": require_xml_entities.encodeXmlText(styleName) }, middle);
18
+ paragraph.children = [
19
+ ...before,
20
+ span,
21
+ ...after
22
+ ];
23
+ return span;
24
+ }
25
+ function cloneAttributes(attributes) {
26
+ return attributes.map((attribute) => ({ ...attribute }));
27
+ }
28
+ function setStyleName(span, styleName) {
29
+ const encoded = require_xml_entities.encodeXmlText(styleName);
30
+ const existing = span.attributes.find((attribute) => attribute.name === "text:style-name");
31
+ if (existing !== void 0) {
32
+ existing.value = encoded;
33
+ return;
34
+ }
35
+ span.attributes.push({
36
+ name: "text:style-name",
37
+ value: encoded
38
+ });
39
+ }
40
+ function buildSpaceRun(count) {
41
+ return count === 1 ? require_xml_fragment.el("text:s") : require_xml_fragment.el("text:s", { "text:c": String(count) });
42
+ }
43
+ function splitNode(node, offset) {
44
+ if (node.type === "text") return {
45
+ left: {
46
+ type: "text",
47
+ value: node.value.slice(0, offset)
48
+ },
49
+ right: {
50
+ type: "text",
51
+ value: node.value.slice(offset)
52
+ }
53
+ };
54
+ if (node.type === "element" && node.tag === "text:s") {
55
+ const count = require_typed_shared_text.getOdfSpaceCount(node);
56
+ return {
57
+ left: buildSpaceRun(offset),
58
+ right: buildSpaceRun(count - offset)
59
+ };
60
+ }
61
+ if (node.type === "element" && node.tag === "text:span") {
62
+ const inner = splitChildrenAt(node.children, offset);
63
+ return {
64
+ left: inner.before.length === 0 ? void 0 : {
65
+ ...node,
66
+ attributes: cloneAttributes(node.attributes),
67
+ children: inner.before
68
+ },
69
+ right: inner.after.length === 0 ? void 0 : {
70
+ ...node,
71
+ attributes: cloneAttributes(node.attributes),
72
+ children: inner.after
73
+ }
74
+ };
75
+ }
76
+ const label = node.type === "element" ? node.tag : node.type;
77
+ 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`);
78
+ }
79
+ function splitChildrenAt(children, offset) {
80
+ if (offset <= 0) return {
81
+ before: [],
82
+ after: [...children]
83
+ };
84
+ const before = [];
85
+ let remaining = offset;
86
+ for (let index = 0; index < children.length; index += 1) {
87
+ if (remaining === 0) return {
88
+ before,
89
+ after: children.slice(index)
90
+ };
91
+ const node = children[index];
92
+ const length = require_typed_shared_text.measureOdfNodeLength(node);
93
+ if (remaining >= length) {
94
+ before.push(node);
95
+ remaining -= length;
96
+ continue;
97
+ }
98
+ const { left, right } = splitNode(node, remaining);
99
+ const after = [];
100
+ if (left !== void 0) before.push(left);
101
+ if (right !== void 0) after.push(right);
102
+ after.push(...children.slice(index + 1));
103
+ return {
104
+ before,
105
+ after
106
+ };
107
+ }
108
+ return {
109
+ before,
110
+ after: []
111
+ };
112
+ }
113
+ //#endregion
114
+ exports.ensureSpan = ensureSpan;
@@ -0,0 +1,5 @@
1
+ import { l as XmlElement } from "../node-CkBWRjNR.cjs";
2
+ //#region src/styles/span.d.ts
3
+ declare function ensureSpan(paragraph: XmlElement, start: number, end: number, styleName: string): XmlElement;
4
+ //#endregion
5
+ export { ensureSpan };
@@ -0,0 +1,5 @@
1
+ import { l as XmlElement } from "../node-CkBWRjNR.js";
2
+ //#region src/styles/span.d.ts
3
+ declare function ensureSpan(paragraph: XmlElement, start: number, end: number, styleName: string): XmlElement;
4
+ //#endregion
5
+ export { ensureSpan };
@@ -0,0 +1,113 @@
1
+ import { el } from "../xml/fragment.js";
2
+ import { encodeXmlText } from "../xml/entities.js";
3
+ import { getOdfSpaceCount, measureOdfNodeLength, sumOdfNodeLength } from "../typed/shared/text.js";
4
+ //#region src/styles/span.ts
5
+ function ensureSpan(paragraph, start, end, styleName) {
6
+ if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) throw new Error(`ensureSpan: invalid range [${start}, ${end})`);
7
+ const total = sumOdfNodeLength(paragraph.children);
8
+ if (end > total) throw new Error(`ensureSpan: range end ${end} exceeds the container's total character length ${total}`);
9
+ const { before, after: rest } = splitChildrenAt(paragraph.children, start);
10
+ const { before: middle, after } = splitChildrenAt(rest, end - start);
11
+ let span;
12
+ const soleChild = middle.length === 1 ? middle[0] : void 0;
13
+ if (soleChild?.type === "element" && soleChild.tag === "text:span") {
14
+ span = soleChild;
15
+ setStyleName(span, styleName);
16
+ } else span = el("text:span", { "text:style-name": encodeXmlText(styleName) }, middle);
17
+ paragraph.children = [
18
+ ...before,
19
+ span,
20
+ ...after
21
+ ];
22
+ return span;
23
+ }
24
+ function cloneAttributes(attributes) {
25
+ return attributes.map((attribute) => ({ ...attribute }));
26
+ }
27
+ function setStyleName(span, styleName) {
28
+ const encoded = encodeXmlText(styleName);
29
+ const existing = span.attributes.find((attribute) => attribute.name === "text:style-name");
30
+ if (existing !== void 0) {
31
+ existing.value = encoded;
32
+ return;
33
+ }
34
+ span.attributes.push({
35
+ name: "text:style-name",
36
+ value: encoded
37
+ });
38
+ }
39
+ function buildSpaceRun(count) {
40
+ return count === 1 ? el("text:s") : el("text:s", { "text:c": String(count) });
41
+ }
42
+ function splitNode(node, offset) {
43
+ if (node.type === "text") return {
44
+ left: {
45
+ type: "text",
46
+ value: node.value.slice(0, offset)
47
+ },
48
+ right: {
49
+ type: "text",
50
+ value: node.value.slice(offset)
51
+ }
52
+ };
53
+ if (node.type === "element" && node.tag === "text:s") {
54
+ const count = getOdfSpaceCount(node);
55
+ return {
56
+ left: buildSpaceRun(offset),
57
+ right: buildSpaceRun(count - offset)
58
+ };
59
+ }
60
+ if (node.type === "element" && node.tag === "text:span") {
61
+ const inner = splitChildrenAt(node.children, offset);
62
+ return {
63
+ left: inner.before.length === 0 ? void 0 : {
64
+ ...node,
65
+ attributes: cloneAttributes(node.attributes),
66
+ children: inner.before
67
+ },
68
+ right: inner.after.length === 0 ? void 0 : {
69
+ ...node,
70
+ attributes: cloneAttributes(node.attributes),
71
+ children: inner.after
72
+ }
73
+ };
74
+ }
75
+ const label = node.type === "element" ? node.tag : node.type;
76
+ 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`);
77
+ }
78
+ function splitChildrenAt(children, offset) {
79
+ if (offset <= 0) return {
80
+ before: [],
81
+ after: [...children]
82
+ };
83
+ const before = [];
84
+ let remaining = offset;
85
+ for (let index = 0; index < children.length; index += 1) {
86
+ if (remaining === 0) return {
87
+ before,
88
+ after: children.slice(index)
89
+ };
90
+ const node = children[index];
91
+ const length = measureOdfNodeLength(node);
92
+ if (remaining >= length) {
93
+ before.push(node);
94
+ remaining -= length;
95
+ continue;
96
+ }
97
+ const { left, right } = splitNode(node, remaining);
98
+ const after = [];
99
+ if (left !== void 0) before.push(left);
100
+ if (right !== void 0) after.push(right);
101
+ after.push(...children.slice(index + 1));
102
+ return {
103
+ before,
104
+ after
105
+ };
106
+ }
107
+ return {
108
+ before,
109
+ after: []
110
+ };
111
+ }
112
+ //#endregion
113
+ export { ensureSpan };