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,277 @@
1
+ import { encodeXmlText } from "../xml/entities.js";
2
+ import { formatOdfLength, parseOdfLength } from "../typed/shared/units.js";
3
+ import { formatOdfColor, parseOdfColor } from "../typed/shared/color.js";
4
+ import { z } from "zod";
5
+ import { AlignmentSchema, ColorSchema } from "document-schema.js";
6
+ //#region src/styles/properties.ts
7
+ const StylePropertiesSchema = z.object({
8
+ bold: z.boolean().optional(),
9
+ italic: z.boolean().optional(),
10
+ underline: z.boolean().optional(),
11
+ strike: z.boolean().optional(),
12
+ fontFamily: z.string().optional(),
13
+ sizePt: z.number().optional(),
14
+ color: ColorSchema.optional(),
15
+ alignment: AlignmentSchema.optional(),
16
+ spacingBeforePt: z.number().optional(),
17
+ spacingAfterPt: z.number().optional(),
18
+ lineSpacing: z.number().optional(),
19
+ indentLeftPt: z.number().optional(),
20
+ indentFirstLinePt: z.number().optional()
21
+ });
22
+ const ATTR = {
23
+ fontWeight: "fo:font-weight",
24
+ fontStyle: "fo:font-style",
25
+ underlineStyle: "style:text-underline-style",
26
+ underlineWidth: "style:text-underline-width",
27
+ underlineColor: "style:text-underline-color",
28
+ lineThroughStyle: "style:text-line-through-style",
29
+ lineThroughType: "style:text-line-through-type",
30
+ fontFamily: "fo:font-family",
31
+ fontSize: "fo:font-size",
32
+ color: "fo:color",
33
+ textAlign: "fo:text-align",
34
+ marginTop: "fo:margin-top",
35
+ marginBottom: "fo:margin-bottom",
36
+ lineHeight: "fo:line-height",
37
+ marginLeft: "fo:margin-left",
38
+ textIndent: "fo:text-indent"
39
+ };
40
+ const TEXT_ATTR_NAMES = /* @__PURE__ */ new Set([
41
+ ATTR.fontWeight,
42
+ ATTR.fontStyle,
43
+ ATTR.underlineStyle,
44
+ ATTR.underlineWidth,
45
+ ATTR.underlineColor,
46
+ ATTR.lineThroughStyle,
47
+ ATTR.lineThroughType,
48
+ ATTR.fontFamily,
49
+ ATTR.fontSize,
50
+ ATTR.color
51
+ ]);
52
+ const PARAGRAPH_ATTR_NAMES = /* @__PURE__ */ new Set([
53
+ ATTR.textAlign,
54
+ ATTR.marginTop,
55
+ ATTR.marginBottom,
56
+ ATTR.lineHeight,
57
+ ATTR.marginLeft,
58
+ ATTR.textIndent
59
+ ]);
60
+ function attributeMap(element) {
61
+ const map = /* @__PURE__ */ new Map();
62
+ for (const attribute of element.attributes) map.set(attribute.name, attribute.value);
63
+ return map;
64
+ }
65
+ function formatPt(valuePt) {
66
+ return formatOdfLength(valuePt, "pt");
67
+ }
68
+ const PERCENTAGE_PATTERN = /^(-?(?:\d+(?:\.\d+)?|\.\d+))%$/;
69
+ function parsePercentageMultiplier(value) {
70
+ const match = PERCENTAGE_PATTERN.exec(value);
71
+ if (match === null) return;
72
+ const numeric = match[1];
73
+ if (numeric === void 0) return;
74
+ return Number(numeric) / 100;
75
+ }
76
+ function formatPercentageMultiplier(multiplier) {
77
+ return `${multiplier * 100}%`;
78
+ }
79
+ function parseLineDecoration(style, companionA, companionAOnValue, companionB, companionBOnValue) {
80
+ if (style === void 0 && companionA === void 0 && companionB === void 0) return;
81
+ if (style === "solid" && (companionA === void 0 || companionA === companionAOnValue) && (companionB === void 0 || companionB === companionBOnValue)) return true;
82
+ if (style === "none" && companionA === void 0 && companionB === void 0) return false;
83
+ return "unknown";
84
+ }
85
+ const RISKY_STYLE_ELEMENT_ATTRS = /* @__PURE__ */ new Set(["style:master-page-name", "style:next-style-name"]);
86
+ function parseTextProperties(element) {
87
+ const attrs = attributeMap(element);
88
+ const properties = {};
89
+ let hasUnknown = false;
90
+ for (const name of attrs.keys()) if (!TEXT_ATTR_NAMES.has(name)) hasUnknown = true;
91
+ const fontWeight = attrs.get(ATTR.fontWeight);
92
+ if (fontWeight === "bold") properties.bold = true;
93
+ else if (fontWeight === "normal") properties.bold = false;
94
+ else if (fontWeight !== void 0) hasUnknown = true;
95
+ const fontStyle = attrs.get(ATTR.fontStyle);
96
+ if (fontStyle === "italic") properties.italic = true;
97
+ else if (fontStyle === "normal") properties.italic = false;
98
+ else if (fontStyle !== void 0) hasUnknown = true;
99
+ const underline = parseLineDecoration(attrs.get(ATTR.underlineStyle), attrs.get(ATTR.underlineWidth), "auto", attrs.get(ATTR.underlineColor), "font-color");
100
+ if (underline === "unknown") hasUnknown = true;
101
+ else if (underline !== void 0) properties.underline = underline;
102
+ const strike = parseLineDecoration(attrs.get(ATTR.lineThroughStyle), attrs.get(ATTR.lineThroughType), "single", void 0, "");
103
+ if (strike === "unknown") hasUnknown = true;
104
+ else if (strike !== void 0) properties.strike = strike;
105
+ const fontFamily = attrs.get(ATTR.fontFamily);
106
+ if (fontFamily !== void 0) properties.fontFamily = fontFamily;
107
+ const fontSize = attrs.get(ATTR.fontSize);
108
+ if (fontSize !== void 0) {
109
+ const pt = parseOdfLength(fontSize);
110
+ if (pt === void 0) hasUnknown = true;
111
+ else properties.sizePt = pt;
112
+ }
113
+ const color = attrs.get(ATTR.color);
114
+ if (color !== void 0) {
115
+ const parsed = parseOdfColor(color);
116
+ if (parsed === void 0) hasUnknown = true;
117
+ else properties.color = parsed;
118
+ }
119
+ return {
120
+ properties,
121
+ hasUnknown
122
+ };
123
+ }
124
+ function parseParagraphProperties(element) {
125
+ const attrs = attributeMap(element);
126
+ const properties = {};
127
+ let hasUnknown = false;
128
+ for (const name of attrs.keys()) if (!PARAGRAPH_ATTR_NAMES.has(name)) hasUnknown = true;
129
+ const textAlign = attrs.get(ATTR.textAlign);
130
+ if (textAlign === "left" || textAlign === "center" || textAlign === "right" || textAlign === "justify") properties.alignment = textAlign;
131
+ else if (textAlign !== void 0) hasUnknown = true;
132
+ const marginTop = attrs.get(ATTR.marginTop);
133
+ if (marginTop !== void 0) {
134
+ const pt = parseOdfLength(marginTop);
135
+ if (pt === void 0) hasUnknown = true;
136
+ else properties.spacingBeforePt = pt;
137
+ }
138
+ const marginBottom = attrs.get(ATTR.marginBottom);
139
+ if (marginBottom !== void 0) {
140
+ const pt = parseOdfLength(marginBottom);
141
+ if (pt === void 0) hasUnknown = true;
142
+ else properties.spacingAfterPt = pt;
143
+ }
144
+ const marginLeft = attrs.get(ATTR.marginLeft);
145
+ if (marginLeft !== void 0) {
146
+ const pt = parseOdfLength(marginLeft);
147
+ if (pt === void 0) hasUnknown = true;
148
+ else properties.indentLeftPt = pt;
149
+ }
150
+ const textIndent = attrs.get(ATTR.textIndent);
151
+ if (textIndent !== void 0) {
152
+ const pt = parseOdfLength(textIndent);
153
+ if (pt === void 0) hasUnknown = true;
154
+ else properties.indentFirstLinePt = pt;
155
+ }
156
+ const lineHeight = attrs.get(ATTR.lineHeight);
157
+ if (lineHeight !== void 0) {
158
+ const multiplier = parsePercentageMultiplier(lineHeight);
159
+ if (multiplier === void 0) hasUnknown = true;
160
+ else properties.lineSpacing = multiplier;
161
+ }
162
+ return {
163
+ properties,
164
+ hasUnknown
165
+ };
166
+ }
167
+ function parseStyleElementProperties(styleElement) {
168
+ let properties = {};
169
+ let hasUnknown = false;
170
+ for (const attribute of styleElement.attributes) if (RISKY_STYLE_ELEMENT_ATTRS.has(attribute.name)) hasUnknown = true;
171
+ for (const child of styleElement.children) {
172
+ if (child.type !== "element") continue;
173
+ if (child.tag === "style:text-properties") {
174
+ const result = parseTextProperties(child);
175
+ properties = {
176
+ ...properties,
177
+ ...result.properties
178
+ };
179
+ if (result.hasUnknown) hasUnknown = true;
180
+ } else if (child.tag === "style:paragraph-properties") {
181
+ const result = parseParagraphProperties(child);
182
+ properties = {
183
+ ...properties,
184
+ ...result.properties
185
+ };
186
+ if (result.hasUnknown) hasUnknown = true;
187
+ } else hasUnknown = true;
188
+ }
189
+ return {
190
+ properties,
191
+ hasUnknown
192
+ };
193
+ }
194
+ function textPropertiesToAttributes(properties) {
195
+ const attributes = [];
196
+ if (properties.bold !== void 0) attributes.push({
197
+ name: ATTR.fontWeight,
198
+ value: properties.bold ? "bold" : "normal"
199
+ });
200
+ if (properties.italic !== void 0) attributes.push({
201
+ name: ATTR.fontStyle,
202
+ value: properties.italic ? "italic" : "normal"
203
+ });
204
+ if (properties.underline !== void 0) if (properties.underline) {
205
+ attributes.push({
206
+ name: ATTR.underlineStyle,
207
+ value: "solid"
208
+ });
209
+ attributes.push({
210
+ name: ATTR.underlineWidth,
211
+ value: "auto"
212
+ });
213
+ attributes.push({
214
+ name: ATTR.underlineColor,
215
+ value: "font-color"
216
+ });
217
+ } else attributes.push({
218
+ name: ATTR.underlineStyle,
219
+ value: "none"
220
+ });
221
+ if (properties.strike !== void 0) if (properties.strike) {
222
+ attributes.push({
223
+ name: ATTR.lineThroughStyle,
224
+ value: "solid"
225
+ });
226
+ attributes.push({
227
+ name: ATTR.lineThroughType,
228
+ value: "single"
229
+ });
230
+ } else attributes.push({
231
+ name: ATTR.lineThroughStyle,
232
+ value: "none"
233
+ });
234
+ if (properties.fontFamily !== void 0) attributes.push({
235
+ name: ATTR.fontFamily,
236
+ value: encodeXmlText(properties.fontFamily)
237
+ });
238
+ if (properties.sizePt !== void 0) attributes.push({
239
+ name: ATTR.fontSize,
240
+ value: formatPt(properties.sizePt)
241
+ });
242
+ if (properties.color !== void 0) attributes.push({
243
+ name: ATTR.color,
244
+ value: formatOdfColor(properties.color)
245
+ });
246
+ return attributes;
247
+ }
248
+ function paragraphPropertiesToAttributes(properties) {
249
+ const attributes = [];
250
+ if (properties.alignment !== void 0) attributes.push({
251
+ name: ATTR.textAlign,
252
+ value: properties.alignment
253
+ });
254
+ if (properties.spacingBeforePt !== void 0) attributes.push({
255
+ name: ATTR.marginTop,
256
+ value: formatPt(properties.spacingBeforePt)
257
+ });
258
+ if (properties.spacingAfterPt !== void 0) attributes.push({
259
+ name: ATTR.marginBottom,
260
+ value: formatPt(properties.spacingAfterPt)
261
+ });
262
+ if (properties.lineSpacing !== void 0) attributes.push({
263
+ name: ATTR.lineHeight,
264
+ value: formatPercentageMultiplier(properties.lineSpacing)
265
+ });
266
+ if (properties.indentLeftPt !== void 0) attributes.push({
267
+ name: ATTR.marginLeft,
268
+ value: formatPt(properties.indentLeftPt)
269
+ });
270
+ if (properties.indentFirstLinePt !== void 0) attributes.push({
271
+ name: ATTR.textIndent,
272
+ value: formatPt(properties.indentFirstLinePt)
273
+ });
274
+ return attributes;
275
+ }
276
+ //#endregion
277
+ export { StylePropertiesSchema, formatPercentageMultiplier, formatPt, paragraphPropertiesToAttributes, parseOdfLength as parseLength, parseParagraphProperties, parseStyleElementProperties, parseTextProperties, textPropertiesToAttributes };
@@ -0,0 +1,212 @@
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_styles_properties = require("./properties.cjs");
5
+ const require_styles_serialize = require("./serialize.cjs");
6
+ //#region src/styles/registry.ts
7
+ const STYLE_FAMILIES = [
8
+ "paragraph",
9
+ "text",
10
+ "table",
11
+ "table-column",
12
+ "table-row",
13
+ "table-cell",
14
+ "graphic"
15
+ ];
16
+ function isStyleFamily(value) {
17
+ return value === "paragraph" || value === "text" || value === "table" || value === "table-column" || value === "table-row" || value === "table-cell" || value === "graphic";
18
+ }
19
+ const CONTENT_PREFIXES = {
20
+ paragraph: "P",
21
+ text: "T",
22
+ table: "ta",
23
+ "table-column": "co",
24
+ "table-row": "ro",
25
+ "table-cell": "ce",
26
+ graphic: "fr"
27
+ };
28
+ const STYLES_PREFIXES = {
29
+ paragraph: "PS",
30
+ text: "TS",
31
+ table: "taS",
32
+ "table-column": "coS",
33
+ "table-row": "roS",
34
+ "table-cell": "ceS",
35
+ graphic: "frS"
36
+ };
37
+ function prefixesForPart(partPath) {
38
+ const baseName = partPath.slice(partPath.lastIndexOf("/") + 1);
39
+ if (baseName === "content.xml") return CONTENT_PREFIXES;
40
+ if (baseName === "styles.xml") return STYLES_PREFIXES;
41
+ throw new Error(`StyleRegistry.forPart: expected a part named "content.xml" or "styles.xml" (by base name), got "${partPath}"`);
42
+ }
43
+ function emptyFamilySets() {
44
+ return {
45
+ paragraph: /* @__PURE__ */ new Set(),
46
+ text: /* @__PURE__ */ new Set(),
47
+ table: /* @__PURE__ */ new Set(),
48
+ "table-column": /* @__PURE__ */ new Set(),
49
+ "table-row": /* @__PURE__ */ new Set(),
50
+ "table-cell": /* @__PURE__ */ new Set(),
51
+ graphic: /* @__PURE__ */ new Set()
52
+ };
53
+ }
54
+ function attrValue(element, name) {
55
+ return element.attributes.find((attribute) => attribute.name === name)?.value;
56
+ }
57
+ function findDirectChild(nodes, tag) {
58
+ for (const node of nodes) if (node.type === "element" && node.tag === tag) return node;
59
+ }
60
+ function findRootElement(nodes) {
61
+ const root = nodes.find((node) => node.type === "element");
62
+ 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");
63
+ return root;
64
+ }
65
+ function ensureAutomaticStyles(root) {
66
+ const existing = findDirectChild(root.children, "office:automatic-styles");
67
+ if (existing !== void 0) return existing;
68
+ const created = require_xml_fragment.el("office:automatic-styles");
69
+ const insertBeforeTags = /* @__PURE__ */ new Set([
70
+ "office:body",
71
+ "office:master-styles",
72
+ "office:settings"
73
+ ]);
74
+ const insertIndex = root.children.findIndex((node) => node.type === "element" && insertBeforeTags.has(node.tag));
75
+ if (insertIndex === -1) root.children.push(created);
76
+ else root.children.splice(insertIndex, 0, created);
77
+ return created;
78
+ }
79
+ function reserveStyleNames(container, reserved) {
80
+ for (const child of container.children) {
81
+ if (child.type !== "element" || child.tag !== "style:style") continue;
82
+ const name = attrValue(child, "style:name");
83
+ const family = attrValue(child, "style:family");
84
+ if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
85
+ reserved[family].add(name);
86
+ }
87
+ }
88
+ const FINGERPRINT_SEPARATOR = "\0";
89
+ const NO_PARENT_SENTINEL = "";
90
+ function computeFingerprint(family, properties, parentStyleName) {
91
+ const parentComponent = parentStyleName ?? NO_PARENT_SENTINEL;
92
+ return [
93
+ family,
94
+ require_styles_serialize.canonicalPropertiesString(properties),
95
+ parentComponent
96
+ ].join(FINGERPRINT_SEPARATOR);
97
+ }
98
+ var StyleRegistry = class StyleRegistry {
99
+ automaticStyles;
100
+ prefixes;
101
+ reservedByFamily;
102
+ knownStyles = /* @__PURE__ */ new Map();
103
+ fingerprintToName = /* @__PURE__ */ new Map();
104
+ nameToFingerprint = /* @__PURE__ */ new Map();
105
+ familyCounters = {
106
+ paragraph: 1,
107
+ text: 1,
108
+ table: 1,
109
+ "table-column": 1,
110
+ "table-row": 1,
111
+ "table-cell": 1,
112
+ graphic: 1
113
+ };
114
+ constructor(automaticStyles, prefixes, reservedByFamily) {
115
+ this.automaticStyles = automaticStyles;
116
+ this.prefixes = prefixes;
117
+ this.reservedByFamily = reservedByFamily;
118
+ }
119
+ static forPart(pkg, partPath, options = {}) {
120
+ const part = pkg.parts[partPath];
121
+ if (part?.kind !== "xml") throw new Error(`StyleRegistry.forPart: "${partPath}" is not an XML part of the given package`);
122
+ const prefixes = prefixesForPart(partPath);
123
+ const root = findRootElement(part.nodes);
124
+ const automaticStyles = ensureAutomaticStyles(root);
125
+ const reservedByFamily = emptyFamilySets();
126
+ const registry = new StyleRegistry(automaticStyles, prefixes, reservedByFamily);
127
+ for (const child of automaticStyles.children) {
128
+ if (child.type !== "element" || child.tag !== "style:style") continue;
129
+ const name = attrValue(child, "style:name");
130
+ const family = attrValue(child, "style:family");
131
+ if (name === void 0 || family === void 0 || !isStyleFamily(family)) continue;
132
+ registry.knownStyles.set(name, child);
133
+ reservedByFamily[family].add(name);
134
+ const parsed = require_styles_properties.parseStyleElementProperties(child);
135
+ if (!parsed.hasUnknown) {
136
+ const parentStyleName = attrValue(child, "style:parent-style-name");
137
+ const fingerprint = computeFingerprint(family, parsed.properties, parentStyleName);
138
+ if (!registry.fingerprintToName.has(fingerprint)) {
139
+ registry.fingerprintToName.set(fingerprint, name);
140
+ registry.nameToFingerprint.set(name, fingerprint);
141
+ }
142
+ }
143
+ }
144
+ const ownStyles = findDirectChild(root.children, "office:styles");
145
+ if (ownStyles !== void 0) reserveStyleNames(ownStyles, reservedByFamily);
146
+ if (options.otherPart !== void 0) {
147
+ const otherPart = options.otherPart.pkg.parts[options.otherPart.partPath];
148
+ if (otherPart?.kind === "xml") {
149
+ const otherRoot = findRootElement(otherPart.nodes);
150
+ const otherAutomatic = findDirectChild(otherRoot.children, "office:automatic-styles");
151
+ if (otherAutomatic !== void 0) reserveStyleNames(otherAutomatic, reservedByFamily);
152
+ const otherStyles = findDirectChild(otherRoot.children, "office:styles");
153
+ if (otherStyles !== void 0) reserveStyleNames(otherStyles, reservedByFamily);
154
+ }
155
+ }
156
+ if (options.additionalReservedNames !== void 0) for (const family of STYLE_FAMILIES) for (const name of options.additionalReservedNames) reservedByFamily[family].add(name);
157
+ return registry;
158
+ }
159
+ fingerprint(request) {
160
+ return computeFingerprint(request.family, request.properties, request.parentStyleName);
161
+ }
162
+ intern(request) {
163
+ const fingerprint = this.fingerprint(request);
164
+ const existingName = this.fingerprintToName.get(fingerprint);
165
+ if (existingName !== void 0) return existingName;
166
+ const name = this.mintName(request.family);
167
+ const attributes = {
168
+ "style:name": name,
169
+ "style:family": request.family
170
+ };
171
+ if (request.parentStyleName !== void 0) attributes["style:parent-style-name"] = require_xml_entities.encodeXmlText(request.parentStyleName);
172
+ const styleElement = require_xml_fragment.el("style:style", attributes, require_styles_serialize.buildStylePropertyElements(request.properties));
173
+ this.automaticStyles.children.push(styleElement);
174
+ this.knownStyles.set(name, styleElement);
175
+ this.reservedByFamily[request.family].add(name);
176
+ this.fingerprintToName.set(fingerprint, name);
177
+ this.nameToFingerprint.set(name, fingerprint);
178
+ return name;
179
+ }
180
+ mintName(family) {
181
+ const prefix = this.prefixes[family];
182
+ const reserved = this.reservedByFamily[family];
183
+ let counter = this.familyCounters[family];
184
+ while (reserved.has(`${prefix}${counter}`)) counter += 1;
185
+ const name = `${prefix}${counter}`;
186
+ this.familyCounters[family] = counter + 1;
187
+ return name;
188
+ }
189
+ names() {
190
+ return [...this.knownStyles.keys()];
191
+ }
192
+ gc(referenced) {
193
+ let removed = 0;
194
+ for (const [name, element] of [...this.knownStyles]) {
195
+ if (referenced.has(name)) continue;
196
+ const index = this.automaticStyles.children.indexOf(element);
197
+ if (index !== -1) this.automaticStyles.children.splice(index, 1);
198
+ this.knownStyles.delete(name);
199
+ const fingerprint = this.nameToFingerprint.get(name);
200
+ if (fingerprint !== void 0) {
201
+ this.fingerprintToName.delete(fingerprint);
202
+ this.nameToFingerprint.delete(name);
203
+ }
204
+ removed += 1;
205
+ }
206
+ return removed;
207
+ }
208
+ };
209
+ //#endregion
210
+ exports.STYLE_FAMILIES = STYLE_FAMILIES;
211
+ exports.StyleRegistry = StyleRegistry;
212
+ exports.isStyleFamily = isStyleFamily;
@@ -0,0 +1,37 @@
1
+ import { Package } from "../model/package.cjs";
2
+ import { StyleProperties } from "./properties.cjs";
3
+ //#region src/styles/registry.d.ts
4
+ declare const STYLE_FAMILIES: readonly ["paragraph", "text", "table", "table-column", "table-row", "table-cell", "graphic"];
5
+ type StyleFamily = (typeof STYLE_FAMILIES)[number];
6
+ declare function isStyleFamily(value: string): value is StyleFamily;
7
+ interface InternRequest {
8
+ properties: StyleProperties;
9
+ family: StyleFamily;
10
+ parentStyleName?: string;
11
+ }
12
+ interface OtherPartRef {
13
+ pkg: Package;
14
+ partPath: string;
15
+ }
16
+ interface StyleRegistryOptions {
17
+ otherPart?: OtherPartRef;
18
+ additionalReservedNames?: readonly string[];
19
+ }
20
+ declare class StyleRegistry {
21
+ private readonly automaticStyles;
22
+ private readonly prefixes;
23
+ private readonly reservedByFamily;
24
+ private readonly knownStyles;
25
+ private readonly fingerprintToName;
26
+ private readonly nameToFingerprint;
27
+ private readonly familyCounters;
28
+ private constructor();
29
+ static forPart(pkg: Package, partPath: string, options?: StyleRegistryOptions): StyleRegistry;
30
+ fingerprint(request: InternRequest): string;
31
+ intern(request: InternRequest): string;
32
+ private mintName;
33
+ names(): readonly string[];
34
+ gc(referenced: ReadonlySet<string>): number;
35
+ }
36
+ //#endregion
37
+ export { InternRequest, OtherPartRef, STYLE_FAMILIES, StyleFamily, StyleRegistry, StyleRegistryOptions, isStyleFamily };
@@ -0,0 +1,37 @@
1
+ import { Package } from "../model/package.js";
2
+ import { StyleProperties } from "./properties.js";
3
+ //#region src/styles/registry.d.ts
4
+ declare const STYLE_FAMILIES: readonly ["paragraph", "text", "table", "table-column", "table-row", "table-cell", "graphic"];
5
+ type StyleFamily = (typeof STYLE_FAMILIES)[number];
6
+ declare function isStyleFamily(value: string): value is StyleFamily;
7
+ interface InternRequest {
8
+ properties: StyleProperties;
9
+ family: StyleFamily;
10
+ parentStyleName?: string;
11
+ }
12
+ interface OtherPartRef {
13
+ pkg: Package;
14
+ partPath: string;
15
+ }
16
+ interface StyleRegistryOptions {
17
+ otherPart?: OtherPartRef;
18
+ additionalReservedNames?: readonly string[];
19
+ }
20
+ declare class StyleRegistry {
21
+ private readonly automaticStyles;
22
+ private readonly prefixes;
23
+ private readonly reservedByFamily;
24
+ private readonly knownStyles;
25
+ private readonly fingerprintToName;
26
+ private readonly nameToFingerprint;
27
+ private readonly familyCounters;
28
+ private constructor();
29
+ static forPart(pkg: Package, partPath: string, options?: StyleRegistryOptions): StyleRegistry;
30
+ fingerprint(request: InternRequest): string;
31
+ intern(request: InternRequest): string;
32
+ private mintName;
33
+ names(): readonly string[];
34
+ gc(referenced: ReadonlySet<string>): number;
35
+ }
36
+ //#endregion
37
+ export { InternRequest, OtherPartRef, STYLE_FAMILIES, StyleFamily, StyleRegistry, StyleRegistryOptions, isStyleFamily };