@docx4j/core-ts 0.4.0 → 0.6.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 (166) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +34 -3
  3. package/dist/html/convert.mjs +40 -15
  4. package/dist/html/elements.mjs +2 -1
  5. package/dist/model/color/ColorMath.d.mts +29 -0
  6. package/dist/model/color/ColorMath.mjs +146 -0
  7. package/dist/model/color/ColorTables.d.mts +6 -0
  8. package/dist/model/color/ColorTables.mjs +83 -0
  9. package/dist/model/color/DrawingMLColors.d.mts +52 -0
  10. package/dist/model/color/DrawingMLColors.mjs +374 -0
  11. package/dist/model/color/ResolvedColor.d.mts +36 -0
  12. package/dist/model/color/ResolvedColor.mjs +65 -0
  13. package/dist/model/color/SpreadsheetColors.d.mts +36 -0
  14. package/dist/model/color/SpreadsheetColors.mjs +84 -0
  15. package/dist/model/color/StyleFill.d.mts +28 -0
  16. package/dist/model/color/StyleFill.mjs +21 -0
  17. package/dist/model/color/ThemeColors.d.mts +86 -0
  18. package/dist/model/color/ThemeColors.mjs +304 -0
  19. package/dist/model/color/WordColors.d.mts +71 -0
  20. package/dist/model/color/WordColors.mjs +121 -0
  21. package/dist/model/color/index.d.mts +6 -0
  22. package/dist/model/color/index.mjs +30 -0
  23. package/dist/model/content/Body.d.mts +153 -19
  24. package/dist/model/content/Body.mjs +570 -131
  25. package/dist/model/content/Comment.d.mts +21 -3
  26. package/dist/model/content/Comment.mjs +202 -19
  27. package/dist/model/content/ContentControl.d.mts +197 -18
  28. package/dist/model/content/ContentControl.mjs +664 -95
  29. package/dist/model/content/Font.d.mts +67 -17
  30. package/dist/model/content/Font.mjs +114 -35
  31. package/dist/model/content/InlinePicture.d.mts +82 -7
  32. package/dist/model/content/InlinePicture.mjs +221 -28
  33. package/dist/model/content/List.mjs +13 -1
  34. package/dist/model/content/Paragraph.d.mts +213 -14
  35. package/dist/model/content/Paragraph.mjs +936 -100
  36. package/dist/model/content/Range.d.mts +242 -11
  37. package/dist/model/content/Range.mjs +975 -119
  38. package/dist/model/content/ResolvedView.d.mts +104 -0
  39. package/dist/model/content/ResolvedView.mjs +596 -0
  40. package/dist/model/content/Table.d.mts +29 -3
  41. package/dist/model/content/Table.mjs +109 -33
  42. package/dist/model/content/TrackedChange.d.mts +301 -16
  43. package/dist/model/content/TrackedChange.mjs +1284 -158
  44. package/dist/model/content/binder.d.mts +2 -1
  45. package/dist/model/content/binder.mjs +48 -1
  46. package/dist/model/content/comments.d.mts +20 -6
  47. package/dist/model/content/comments.mjs +67 -57
  48. package/dist/model/content/generalException.d.mts +18 -0
  49. package/dist/model/content/generalException.mjs +24 -0
  50. package/dist/model/content/index.d.mts +8 -3
  51. package/dist/model/content/index.mjs +7 -2
  52. package/dist/model/content/mathText.d.mts +21 -0
  53. package/dist/model/content/mathText.mjs +267 -0
  54. package/dist/model/content/officeText.d.mts +27 -0
  55. package/dist/model/content/officeText.mjs +74 -0
  56. package/dist/model/content/outline.d.mts +5 -0
  57. package/dist/model/content/outline.mjs +13 -0
  58. package/dist/model/content/placeholders.d.mts +110 -0
  59. package/dist/model/content/placeholders.mjs +253 -0
  60. package/dist/model/content/relationships.d.mts +30 -0
  61. package/dist/model/content/relationships.mjs +133 -0
  62. package/dist/model/content/search.d.mts +72 -0
  63. package/dist/model/content/search.mjs +204 -2
  64. package/dist/model/content/spanEdits.d.mts +159 -0
  65. package/dist/model/content/spanEdits.mjs +728 -0
  66. package/dist/model/content/story.d.mts +44 -0
  67. package/dist/model/content/story.mjs +92 -0
  68. package/dist/model/content/tableColumns.d.mts +1 -1
  69. package/dist/model/content/tableColumns.mjs +108 -80
  70. package/dist/model/content/tableRevisions.d.mts +11 -3
  71. package/dist/model/content/tableRevisions.mjs +72 -42
  72. package/dist/model/content/tableRules.d.mts +30 -0
  73. package/dist/model/content/tableRules.mjs +100 -0
  74. package/dist/model/content/textBoxes.d.mts +18 -0
  75. package/dist/model/content/textBoxes.mjs +105 -0
  76. package/dist/model/content/trackedChangeFilter.d.mts +39 -0
  77. package/dist/model/content/trackedChangeFilter.mjs +81 -0
  78. package/dist/model/content/tracking.d.mts +28 -0
  79. package/dist/model/content/tracking.mjs +149 -10
  80. package/dist/model/content/tree.d.mts +212 -13
  81. package/dist/model/content/tree.mjs +356 -35
  82. package/dist/model/customxml/CustomXmlPartCollection.d.mts +8 -0
  83. package/dist/model/customxml/CustomXmlPartCollection.mjs +34 -11
  84. package/dist/model/customxml/XmlMapping.d.mts +1 -1
  85. package/dist/model/customxml/XmlMapping.mjs +11 -0
  86. package/dist/model/customxml/bindings.d.mts +21 -2
  87. package/dist/model/customxml/bindings.mjs +76 -32
  88. package/dist/model/customxml/kinds.d.mts +8 -3
  89. package/dist/model/customxml/kinds.mjs +26 -5
  90. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  91. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  92. package/dist/model/customxml/pictures.d.mts +9 -5
  93. package/dist/model/customxml/pictures.mjs +31 -13
  94. package/dist/model/customxml/xhtml.mjs +8 -2
  95. package/dist/model/fonts/families.generated.mjs +2 -2
  96. package/dist/model/fonts/registry.mjs +7 -1
  97. package/dist/model/fonts/substitutions.generated.mjs +2 -2
  98. package/dist/model/fonts/themes.generated.mjs +1 -1
  99. package/dist/model/index.d.mts +2 -0
  100. package/dist/model/index.mjs +4 -0
  101. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  102. package/dist/model/listnumbering/Emulator.mjs +63 -9
  103. package/dist/model/listnumbering/definitions.mjs +18 -0
  104. package/dist/model/properties/PropertyResolver.d.mts +87 -7
  105. package/dist/model/properties/PropertyResolver.mjs +197 -17
  106. package/dist/model/properties/catalogue.d.mts +32 -4
  107. package/dist/model/properties/catalogue.mjs +115 -36
  108. package/dist/model/properties/log.d.mts +1 -1
  109. package/dist/model/properties/log.mjs +5 -5
  110. package/dist/model/properties/table.d.mts +16 -2
  111. package/dist/model/properties/table.mjs +17 -5
  112. package/dist/model/text/Extractor.d.mts +289 -0
  113. package/dist/model/text/Extractor.mjs +2162 -0
  114. package/dist/model/text/LinkTargets.d.mts +45 -0
  115. package/dist/model/text/LinkTargets.mjs +170 -0
  116. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  117. package/dist/model/text/MarkdownExporter.mjs +255 -0
  118. package/dist/model/text/PlainText.d.mts +29 -0
  119. package/dist/model/text/PlainText.mjs +539 -0
  120. package/dist/model/text/TextContext.d.mts +161 -0
  121. package/dist/model/text/TextContext.mjs +425 -0
  122. package/dist/model/text/TextOptions.d.mts +150 -0
  123. package/dist/model/text/TextOptions.mjs +278 -0
  124. package/dist/model/text/TextResult.d.mts +504 -0
  125. package/dist/model/text/TextResult.mjs +526 -0
  126. package/dist/model/text/Texts.d.mts +99 -0
  127. package/dist/model/text/Texts.mjs +187 -0
  128. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  129. package/dist/model/text/WmlToMarkdown.mjs +911 -0
  130. package/dist/model/text/commonmark.d.mts +121 -0
  131. package/dist/model/text/commonmark.mjs +655 -0
  132. package/dist/model/text/index.d.mts +7 -0
  133. package/dist/model/text/index.mjs +8 -0
  134. package/dist/model/text/normalize.d.mts +8 -0
  135. package/dist/model/text/normalize.mjs +13 -0
  136. package/dist/model/text/outline.d.mts +4 -0
  137. package/dist/model/text/outline.mjs +71 -0
  138. package/dist/office-js/fragment.d.mts +7 -5
  139. package/dist/office-js/fragment.mjs +63 -14
  140. package/dist/office-js/proxy.d.mts +8 -0
  141. package/dist/office-js/proxy.mjs +29 -0
  142. package/dist/office-js/run.mjs +2 -0
  143. package/dist/office-js/supported.generated.mjs +16 -0
  144. package/dist/office-js/toApiScript.mjs +21 -5
  145. package/dist/opc/Load.d.mts +9 -2
  146. package/dist/opc/Save.d.mts +17 -0
  147. package/dist/opc/Save.mjs +12 -2
  148. package/dist/opc/index.d.mts +3 -3
  149. package/dist/opc/index.mjs +2 -2
  150. package/dist/opc/mce/preprocessor.d.mts +88 -7
  151. package/dist/opc/mce/preprocessor.mjs +144 -37
  152. package/dist/opc/mce/understood.d.mts +34 -0
  153. package/dist/opc/mce/understood.mjs +55 -3
  154. package/dist/packages/OpcPackage.d.mts +20 -0
  155. package/dist/packages/OpcPackage.mjs +16 -3
  156. package/dist/packages/WordprocessingMLPackage.d.mts +77 -7
  157. package/dist/packages/WordprocessingMLPackage.mjs +242 -11
  158. package/dist/parts/DefaultXmlPart.mjs +2 -2
  159. package/dist/parts/Part.d.mts +10 -2
  160. package/dist/parts/XmlPart.d.mts +35 -32
  161. package/dist/parts/XmlPart.mjs +107 -107
  162. package/dist/parts/wml/comments.mjs +30 -0
  163. package/dist/parts/wml/index.mjs +12 -0
  164. package/dist/xml/dom.d.mts +7 -0
  165. package/dist/xml/dom.mjs +18 -0
  166. package/package.json +2 -2
@@ -0,0 +1,374 @@
1
+ import * as ColorMath from './ColorMath.mjs';
2
+ import { PRESET, SYSTEM } from './ColorTables.mjs';
3
+ import { ResolvedColor } from './ResolvedColor.mjs';
4
+ import { StyleFill } from './StyleFill.mjs';
5
+ const KIND_NAMES = {
6
+ srgbClr: 'org_docx4j_dml.CTSRgbColor', schemeClr: 'org_docx4j_dml.CTSchemeColor', scrgbClr: 'org_docx4j_dml.CTScRgbColor',
7
+ hslClr: 'org_docx4j_dml.CTHslColor', sysClr: 'org_docx4j_dml.CTSystemColor', prstClr: 'org_docx4j_dml.CTPresetColor',
8
+ };
9
+ const HOLDERS = new Set(['org_docx4j_dml.CTColor', 'org_docx4j_dml.CTSolidColorFillProperties',
10
+ 'org_docx4j_dml.CTStyleMatrixReference', 'org_docx4j_dml.CTFontReference']);
11
+ const FILL_NAMES = {
12
+ noFill: 'org_docx4j_dml.CTNoFillProperties', solidFill: 'org_docx4j_dml.CTSolidColorFillProperties',
13
+ gradFill: 'org_docx4j_dml.CTGradientFillProperties', pattFill: 'org_docx4j_dml.CTPatternFillProperties',
14
+ blipFill: 'org_docx4j_dml.CTBlipFillProperties', grpFill: 'org_docx4j_dml.CTGroupFillProperties',
15
+ };
16
+ const typeNameOf = (o) => o === null || o === void 0 ? void 0 : o.TYPE_NAME;
17
+ /** A JAXBElement's counterpart, `{ name, value }`: the value, with the type its element name gives where it has none. */
18
+ function unwrap(o, names) {
19
+ var _a;
20
+ const named = o;
21
+ if (named !== undefined && named !== null && typeof named === 'object' && named.name !== undefined && 'value' in named) {
22
+ const local = typeof named.name === 'string' ? named.name : named.name.localPart;
23
+ return { value: named.value, type: (_a = typeNameOf(named.value)) !== null && _a !== void 0 ? _a : names[local] };
24
+ }
25
+ return { value: o, type: typeNameOf(o) };
26
+ }
27
+ const holds = (o) => ['srgbClr', 'schemeClr', 'scrgbClr', 'hslClr', 'sysClr', 'prstClr'].some((k) => o[k] !== undefined && o[k] !== null);
28
+ /** The colour element inside a holder, or the element itself, with its kind's type name. */
29
+ function kind(o) {
30
+ const { value, type } = unwrap(o, KIND_NAMES);
31
+ if (value === undefined || value === null || typeof value !== 'object')
32
+ return undefined;
33
+ if ((type === undefined || HOLDERS.has(type)) && holds(value)) {
34
+ const h = value;
35
+ for (const [key, name] of [['srgbClr', KIND_NAMES.srgbClr], ['schemeClr', KIND_NAMES.schemeClr], ['scrgbClr', KIND_NAMES.scrgbClr],
36
+ ['hslClr', KIND_NAMES.hslClr], ['sysClr', KIND_NAMES.sysClr], ['prstClr', KIND_NAMES.prstClr]]) {
37
+ const c = h[key];
38
+ if (c !== undefined && c !== null)
39
+ return { value: c, type: name };
40
+ }
41
+ }
42
+ if (type !== undefined && Object.values(KIND_NAMES).includes(type))
43
+ return { value: value, type };
44
+ return undefined;
45
+ }
46
+ /** hexBinary as the objects model has it at run time (byte numbers), or as its declarations say (hex digits). */
47
+ export function bytesOf(v) {
48
+ if (v === undefined || v === null)
49
+ return undefined;
50
+ if (typeof v === 'string') {
51
+ if (!/^([0-9A-Fa-f]{2})*$/.test(v))
52
+ return undefined;
53
+ const out = [];
54
+ for (let i = 0; i < v.length; i += 2)
55
+ out.push(Number.parseInt(v.substring(i, i + 2), 16));
56
+ return out;
57
+ }
58
+ if (Array.isArray(v) || ArrayBuffer.isView(v))
59
+ return Array.from(v, (b) => b & 0xFF);
60
+ return undefined;
61
+ }
62
+ function base(c, type, theme) {
63
+ switch (type) {
64
+ case KIND_NAMES.srgbClr: {
65
+ const val = c.val;
66
+ if (typeof val === 'string')
67
+ return ResolvedColor.ofHex(val);
68
+ const b = bytesOf(val);
69
+ return b !== undefined && b.length === 3 ? ResolvedColor.rgb(b[0], b[1], b[2]) : undefined;
70
+ }
71
+ case KIND_NAMES.schemeClr: {
72
+ const s = c;
73
+ // docx4j logs at debug "Couldn't resolve schemeClr ..."
74
+ return theme === undefined || s.val === undefined || s.val === null ? undefined : theme.schemeColor(s.val);
75
+ }
76
+ case KIND_NAMES.scrgbClr: {
77
+ const s = c;
78
+ return ResolvedColor.rgb(ColorMath.channel(ColorMath.toSrgb(s.r / 100000.0)), ColorMath.channel(ColorMath.toSrgb(s.g / 100000.0)), ColorMath.channel(ColorMath.toSrgb(s.b / 100000.0)));
79
+ }
80
+ case KIND_NAMES.hslClr: {
81
+ const h = c;
82
+ const rgb = ColorMath.hslToRgb(h.hue / 21600000.0, h.sat / 100000.0, h.lum / 100000.0);
83
+ return ResolvedColor.rgb(ColorMath.channel(rgb[0]), ColorMath.channel(rgb[1]), ColorMath.channel(rgb[2]));
84
+ }
85
+ case KIND_NAMES.sysClr: {
86
+ const s = c;
87
+ // Office draws the machine's colour for the name and ignores lastClr (docx4j CR-034 section 11)
88
+ const hex = s.val === undefined || s.val === null ? undefined : SYSTEM.get(s.val);
89
+ if (hex !== undefined)
90
+ return ResolvedColor.ofHex(hex);
91
+ const last = bytesOf(s.lastClr);
92
+ return last !== undefined && last.length === 3 ? ResolvedColor.rgb(last[0], last[1], last[2]) : undefined;
93
+ }
94
+ case KIND_NAMES.prstClr: {
95
+ const p = c;
96
+ return p.val === undefined || p.val === null ? undefined : ResolvedColor.ofHex(PRESET.get(p.val));
97
+ }
98
+ default: return undefined;
99
+ }
100
+ }
101
+ /** The transforms' value, in thousandths of a percent or 60000ths of a degree; 0 for those without one. */
102
+ function value(t) {
103
+ const v = t === null || t === void 0 ? void 0 : t.val;
104
+ return typeof v === 'number' ? v : 0;
105
+ }
106
+ /** A colour with transforms applied in document order. */
107
+ function transform(baseColor, transforms) {
108
+ if (transforms === undefined || transforms === null || transforms.length === 0)
109
+ return baseColor;
110
+ let r = baseColor.red / 255.0, g = baseColor.green / 255.0, b = baseColor.blue / 255.0;
111
+ let alpha = baseColor.alpha / 100000.0;
112
+ let lumLast = false; // the last change to the colour a luminance transform: it rounds half down
113
+ for (const t of transforms) {
114
+ const name = typeof t.name === 'string' ? t.name : t.name.localPart;
115
+ const v = value(t.value) / 100000.0;
116
+ if (!name.startsWith('alpha'))
117
+ lumLast = name.startsWith('lum');
118
+ switch (name) {
119
+ case 'tint':
120
+ r = ColorMath.toSrgb(1 - (1 - ColorMath.toLinear(r)) * v);
121
+ g = ColorMath.toSrgb(1 - (1 - ColorMath.toLinear(g)) * v);
122
+ b = ColorMath.toSrgb(1 - (1 - ColorMath.toLinear(b)) * v);
123
+ break;
124
+ case 'shade':
125
+ r = ColorMath.toSrgb(ColorMath.toLinear(r) * v);
126
+ g = ColorMath.toSrgb(ColorMath.toLinear(g) * v);
127
+ b = ColorMath.toSrgb(ColorMath.toLinear(b) * v);
128
+ break;
129
+ case 'inv':
130
+ r = ColorMath.toSrgb(1 - ColorMath.toLinear(r));
131
+ g = ColorMath.toSrgb(1 - ColorMath.toLinear(g));
132
+ b = ColorMath.toSrgb(1 - ColorMath.toLinear(b));
133
+ break;
134
+ case 'gray': {
135
+ const y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
136
+ r = g = b = ColorMath.clamp01(y);
137
+ break;
138
+ }
139
+ case 'gamma':
140
+ r = ColorMath.toSrgb(r);
141
+ g = ColorMath.toSrgb(g);
142
+ b = ColorMath.toSrgb(b);
143
+ break;
144
+ case 'invGamma':
145
+ r = ColorMath.toLinear(r);
146
+ g = ColorMath.toLinear(g);
147
+ b = ColorMath.toLinear(b);
148
+ break;
149
+ case 'red':
150
+ case 'redOff':
151
+ case 'redMod':
152
+ r = channel(name, r, v);
153
+ break;
154
+ case 'green':
155
+ case 'greenOff':
156
+ case 'greenMod':
157
+ g = channel(name, g, v);
158
+ break;
159
+ case 'blue':
160
+ case 'blueOff':
161
+ case 'blueMod':
162
+ b = channel(name, b, v);
163
+ break;
164
+ case 'alpha':
165
+ alpha = v;
166
+ break;
167
+ case 'alphaOff':
168
+ alpha += v;
169
+ break;
170
+ case 'alphaMod':
171
+ alpha *= v;
172
+ break;
173
+ case 'comp':
174
+ case 'hue':
175
+ case 'hueOff':
176
+ case 'hueMod':
177
+ case 'sat':
178
+ case 'satOff':
179
+ case 'satMod':
180
+ case 'lum':
181
+ case 'lumOff':
182
+ case 'lumMod': {
183
+ let [h, s, l] = ColorMath.rgbToHsl(r, g, b);
184
+ const raw = value(t.value);
185
+ switch (name) {
186
+ case 'comp':
187
+ h += 0.5;
188
+ break;
189
+ case 'hue':
190
+ h = raw / 21600000.0;
191
+ break;
192
+ case 'hueOff':
193
+ h += raw / 21600000.0;
194
+ break;
195
+ case 'hueMod':
196
+ h *= v;
197
+ break;
198
+ case 'sat':
199
+ s = v;
200
+ break;
201
+ case 'satOff':
202
+ s += v;
203
+ break;
204
+ case 'satMod':
205
+ s *= v;
206
+ break;
207
+ case 'lum':
208
+ l = v;
209
+ break;
210
+ case 'lumOff':
211
+ l += v;
212
+ break;
213
+ // l x val / 100000 in this order, not l *= v: with hslToRgbFoley and channelHalfDown, which way an exact
214
+ // half rounds follows this form's floating-point error, as Office's does (docx4j CR-034 section 11, follow-up)
215
+ case 'lumMod':
216
+ l = l * raw / 100000.0;
217
+ break;
218
+ default: break;
219
+ }
220
+ h = h % 1;
221
+ if (h < 0)
222
+ h += 1;
223
+ const rgb = lumLast ? ColorMath.hslToRgbFoley(h, s, ColorMath.clamp01(l)) : ColorMath.hslToRgb(h, s, ColorMath.clamp01(l));
224
+ r = rgb[0];
225
+ g = rgb[1];
226
+ b = rgb[2];
227
+ break;
228
+ }
229
+ default:
230
+ // docx4j logs at debug "Ignoring an unknown colour transform ..."
231
+ break;
232
+ }
233
+ }
234
+ if (lumLast) {
235
+ return ResolvedColor.rgb(ColorMath.channelHalfDown(r), ColorMath.channelHalfDown(g), ColorMath.channelHalfDown(b))
236
+ .withAlpha(Math.round(ColorMath.clamp01(alpha) * 100000));
237
+ }
238
+ return ResolvedColor.rgb(ColorMath.channel(r), ColorMath.channel(g), ColorMath.channel(b))
239
+ .withAlpha(Math.round(ColorMath.clamp01(alpha) * 100000));
240
+ }
241
+ /** red, redOff, redMod (and green, blue): the channel in linear RGB */
242
+ function channel(name, c, v) {
243
+ let l = ColorMath.toLinear(c);
244
+ if (name.endsWith('Off'))
245
+ l += v;
246
+ else if (name.endsWith('Mod'))
247
+ l *= v;
248
+ else
249
+ l = v;
250
+ return ColorMath.toSrgb(l);
251
+ }
252
+ /** The fill's type name: its own, its element name's (`{ name, value }`), or a solid fill's by its colour. */
253
+ function fillOf(o) {
254
+ const { value, type } = unwrap(o, FILL_NAMES);
255
+ if (value === undefined || value === null || typeof value !== 'object')
256
+ return undefined;
257
+ return { value, type: type !== null && type !== void 0 ? type : (holds(value) ? FILL_NAMES.solidFill : undefined) };
258
+ }
259
+ /**
260
+ * DrawingML colours (ISO/IEC 29500-1 section 20.1.2.3) resolved as Office draws them. The six kinds: `srgbClr`,
261
+ * `scrgbClr` (linear percentages), `hslClr`, `sysClr` (the machine's colour by name, not `lastClr`), `prstClr` and
262
+ * `schemeClr` (through {@link ThemeColors}). Their transforms apply in document order, in the spaces Word and
263
+ * PowerPoint use, measured on 403 cases each (docx4j CR-034 section 11, P3):
264
+ * - `tint`, `shade`, `inv`, `red`/`green`/`blue` and their `Off`/`Mod`: linear RGB; `gamma` and `invGamma`: the
265
+ * sRGB transfer function each way;
266
+ * - `hue`, `sat`, `lum` and their `Off`/`Mod`, `comp`: HSL of the sRGB colour, the saturation not clamped (the
267
+ * channels are, afterwards); a colour whose last change is a luminance transform converted back as Foley and van
268
+ * Dam do and rounded half down, as Office rounds it (so `tx1` at `lumMod 50000 lumOff 50000` is 7F7F7F);
269
+ * - `gray`: Rec.709 luma of the sRGB channels;
270
+ * - `alpha`, `alphaOff`, `alphaMod`: the alpha.
271
+ *
272
+ * MS-OI29500 says `lumOff` and `satOff` are not supported by Office; Office 365 applies both as above in every case
273
+ * measured. Known differences from Office: a saturation set on a grey (Office gives a grey's hue about 40 degrees),
274
+ * and some hue, saturation and luminance cases one unit off.
275
+ *
276
+ * An object is known by its `TYPE_NAME` (which the objects package's unmarshal and factories give it), or, wrapped
277
+ * as `{ name, value }`, by its element name; a holder of a colour also by its `srgbClr`, `schemeClr`, ... member.
278
+ * docx4j's `null` is `undefined` here.
279
+ */
280
+ export const DrawingMLColors = {
281
+ /**
282
+ * The colour a DrawingML colour element, or an element holding one, resolves to.
283
+ *
284
+ * @param colour one of the six kinds (`CTSchemeColor`, `CTSRgbColor`, ...), or a holder of one: `CTColor` (a
285
+ * scheme slot), `CTSolidColorFillProperties`, `CTStyleMatrixReference`, `CTFontReference`; `{ name, value }`
286
+ * is unwrapped
287
+ * @param theme the theme and colour map for `schemeClr`; may be undefined where there is none
288
+ * @returns undefined where there is no colour, or a `schemeClr` cannot be resolved
289
+ */
290
+ resolve(colour, theme) {
291
+ const c = kind(colour);
292
+ if (c === undefined)
293
+ return undefined;
294
+ const b = base(c.value, c.type, theme);
295
+ if (b === undefined)
296
+ return undefined;
297
+ return transform(b, c.value.egColorTransform);
298
+ },
299
+ /** A fill: `a:noFill`, `a:solidFill` (its colour resolved), or a gradient, pattern, picture or group fill reported by kind. */
300
+ fill(fillProperties, theme) {
301
+ const f = fillOf(fillProperties);
302
+ return f === undefined ? StyleFill.UNKNOWN : fillOfType(f.type, f.value, theme);
303
+ },
304
+ /** A line's fill: none, solid, gradient or pattern. */
305
+ lineFill(ln, theme) {
306
+ if (ln === undefined || ln === null)
307
+ return StyleFill.UNKNOWN;
308
+ if (ln.noFill !== undefined && ln.noFill !== null)
309
+ return StyleFill.NONE;
310
+ if (ln.solidFill !== undefined && ln.solidFill !== null)
311
+ return fillOfType(FILL_NAMES.solidFill, ln.solidFill, theme);
312
+ if (ln.gradFill !== undefined && ln.gradFill !== null)
313
+ return fillOfType(FILL_NAMES.gradFill, ln.gradFill, theme);
314
+ if (ln.pattFill !== undefined && ln.pattFill !== null)
315
+ return fillOfType(FILL_NAMES.pattFill, ln.pattFill, theme);
316
+ return StyleFill.UNKNOWN;
317
+ },
318
+ /**
319
+ * A shape style's `a:fillRef`: index 0 is no fill, 1 to 999 the theme's `a:fillStyleLst`, 1001 and up its
320
+ * `a:bgFillStyleLst`, with `phClr` the reference's own colour.
321
+ */
322
+ fillReference(ref, theme) {
323
+ var _a, _b;
324
+ if (ref === undefined || ref === null)
325
+ return StyleFill.UNKNOWN;
326
+ const idx = ref.idx;
327
+ if (idx === 0)
328
+ return StyleFill.NONE;
329
+ const fmt = theme === null || theme === void 0 ? void 0 : theme.formatScheme;
330
+ if (theme === undefined || fmt === undefined)
331
+ return StyleFill.UNKNOWN;
332
+ const list = idx >= 1001 ? (_a = fmt.bgFillStyleLst) === null || _a === void 0 ? void 0 : _a.egFillProperties : (_b = fmt.fillStyleLst) === null || _b === void 0 ? void 0 : _b.egFillProperties;
333
+ const i = Math.trunc(idx >= 1001 ? idx - 1001 : idx - 1);
334
+ if (list === undefined || list === null || i < 0 || i >= list.length)
335
+ return StyleFill.UNKNOWN;
336
+ return DrawingMLColors.fill(list[i], theme.withPlaceholder(DrawingMLColors.resolve(holder(ref), theme)));
337
+ },
338
+ /** A shape style's `a:lnRef`: index 0 is no line, else the theme's `a:lnStyleLst` entry's fill. */
339
+ lineReference(ref, theme) {
340
+ var _a;
341
+ if (ref === undefined || ref === null)
342
+ return StyleFill.UNKNOWN;
343
+ const idx = ref.idx;
344
+ if (idx === 0)
345
+ return StyleFill.NONE;
346
+ const fmt = theme === null || theme === void 0 ? void 0 : theme.formatScheme;
347
+ if (theme === undefined || fmt === undefined || fmt.lnStyleLst === undefined || fmt.lnStyleLst === null)
348
+ return StyleFill.UNKNOWN;
349
+ const list = (_a = fmt.lnStyleLst.ln) !== null && _a !== void 0 ? _a : [];
350
+ const i = Math.trunc(idx) - 1;
351
+ if (i < 0 || i >= list.length)
352
+ return StyleFill.UNKNOWN;
353
+ return DrawingMLColors.lineFill(list[i], theme.withPlaceholder(DrawingMLColors.resolve(holder(ref), theme)));
354
+ },
355
+ /** A shape style's `a:fontRef`: its colour, the text's where the text states none. */
356
+ fontReference(ref, theme) {
357
+ return ref === undefined || ref === null ? undefined : DrawingMLColors.resolve(holder(ref), theme);
358
+ },
359
+ };
360
+ function fillOfType(type, f, theme) {
361
+ switch (type) {
362
+ case FILL_NAMES.noFill: return StyleFill.NONE;
363
+ case FILL_NAMES.solidFill: return new StyleFill('SOLID', DrawingMLColors.resolve(holder(f), theme), f);
364
+ case FILL_NAMES.gradFill: return new StyleFill('GRADIENT', undefined, f);
365
+ case FILL_NAMES.pattFill: return new StyleFill('PATTERN', undefined, f);
366
+ case FILL_NAMES.blipFill: return new StyleFill('PICTURE', undefined, f);
367
+ case FILL_NAMES.grpFill: return new StyleFill('GROUP', undefined, f);
368
+ default: return StyleFill.UNKNOWN;
369
+ }
370
+ }
371
+ /** A solid fill, a style or a font reference as a holder of its colour, whatever its TYPE_NAME. */
372
+ function holder(ref) {
373
+ return { srgbClr: ref.srgbClr, schemeClr: ref.schemeClr, scrgbClr: ref.scrgbClr, hslClr: ref.hslClr, sysClr: ref.sysClr, prstClr: ref.prstClr };
374
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * A colour as Office draws it: red, green and blue in sRGB (0 to 255) and an alpha in OOXML's unit
3
+ * (0 to 100000, where 100000 is opaque). Immutable.
4
+ *
5
+ * docx4j's getters are properties here (`getRed()` is `red`); `equals` compares the four values.
6
+ */
7
+ export declare class ResolvedColor {
8
+ /** OOXML's opaque alpha, 100% in thousandths of a percent. */
9
+ static readonly OPAQUE = 100000;
10
+ static readonly BLACK: ResolvedColor;
11
+ static readonly WHITE: ResolvedColor;
12
+ readonly red: number;
13
+ readonly green: number;
14
+ readonly blue: number;
15
+ /** 0 (transparent) to 100000 (opaque). */
16
+ readonly alpha: number;
17
+ private constructor();
18
+ /** An opaque colour; each channel is clamped to 0 to 255. */
19
+ static rgb(red: number, green: number, blue: number): ResolvedColor;
20
+ /**
21
+ * An opaque colour from six hex digits (RRGGBB, either case; a leading '#' is allowed).
22
+ *
23
+ * @returns undefined where the string is not six hex digits ("auto", for instance)
24
+ */
25
+ static ofHex(hex: string | null | undefined): ResolvedColor | undefined;
26
+ /** This colour with another alpha (0 to 100000). */
27
+ withAlpha(alpha: number): ResolvedColor;
28
+ get isOpaque(): boolean;
29
+ /** RRGGBB, upper case, without the alpha. */
30
+ toHex(): string;
31
+ /** Whether each channel is within `units` of the other colour's (alpha not compared). */
32
+ within(other: ResolvedColor | undefined, units: number): boolean;
33
+ equals(other: unknown): boolean;
34
+ /** RRGGBB, or RRGGBB/alpha where not opaque. */
35
+ toString(): string;
36
+ }
@@ -0,0 +1,65 @@
1
+ // A colour as Office draws it: docx4j `org.docx4j.model.color.ResolvedColor` (CR-034).
2
+ function clamp(v, max) {
3
+ return v < 0 ? 0 : v > max ? max : v;
4
+ }
5
+ /**
6
+ * A colour as Office draws it: red, green and blue in sRGB (0 to 255) and an alpha in OOXML's unit
7
+ * (0 to 100000, where 100000 is opaque). Immutable.
8
+ *
9
+ * docx4j's getters are properties here (`getRed()` is `red`); `equals` compares the four values.
10
+ */
11
+ export class ResolvedColor {
12
+ constructor(red, green, blue, alpha) {
13
+ // Java's int arguments: a caller here could pass a fraction
14
+ this.red = clamp(Math.trunc(red), 255);
15
+ this.green = clamp(Math.trunc(green), 255);
16
+ this.blue = clamp(Math.trunc(blue), 255);
17
+ this.alpha = clamp(Math.trunc(alpha), ResolvedColor.OPAQUE);
18
+ }
19
+ /** An opaque colour; each channel is clamped to 0 to 255. */
20
+ static rgb(red, green, blue) {
21
+ return new ResolvedColor(red, green, blue, ResolvedColor.OPAQUE);
22
+ }
23
+ /**
24
+ * An opaque colour from six hex digits (RRGGBB, either case; a leading '#' is allowed).
25
+ *
26
+ * @returns undefined where the string is not six hex digits ("auto", for instance)
27
+ */
28
+ static ofHex(hex) {
29
+ if (hex === undefined || hex === null)
30
+ return undefined;
31
+ const h = hex.startsWith('#') ? hex.substring(1) : hex;
32
+ if (!/^[0-9A-Fa-f]{6}$/.test(h))
33
+ return undefined;
34
+ const v = Number.parseInt(h, 16);
35
+ return ResolvedColor.rgb((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
36
+ }
37
+ /** This colour with another alpha (0 to 100000). */
38
+ withAlpha(alpha) {
39
+ return new ResolvedColor(this.red, this.green, this.blue, alpha);
40
+ }
41
+ get isOpaque() {
42
+ return this.alpha === ResolvedColor.OPAQUE;
43
+ }
44
+ /** RRGGBB, upper case, without the alpha. */
45
+ toHex() {
46
+ return [this.red, this.green, this.blue].map((c) => c.toString(16).toUpperCase().padStart(2, '0')).join('');
47
+ }
48
+ /** Whether each channel is within `units` of the other colour's (alpha not compared). */
49
+ within(other, units) {
50
+ return other !== undefined && Math.abs(this.red - other.red) <= units && Math.abs(this.green - other.green) <= units
51
+ && Math.abs(this.blue - other.blue) <= units;
52
+ }
53
+ equals(other) {
54
+ return other instanceof ResolvedColor && this.red === other.red && this.green === other.green
55
+ && this.blue === other.blue && this.alpha === other.alpha;
56
+ }
57
+ /** RRGGBB, or RRGGBB/alpha where not opaque. */
58
+ toString() {
59
+ return this.isOpaque ? this.toHex() : `${this.toHex()}/${this.alpha}`;
60
+ }
61
+ }
62
+ /** OOXML's opaque alpha, 100% in thousandths of a percent. */
63
+ ResolvedColor.OPAQUE = 100000;
64
+ ResolvedColor.BLACK = new ResolvedColor(0, 0, 0, ResolvedColor.OPAQUE);
65
+ ResolvedColor.WHITE = new ResolvedColor(255, 255, 255, ResolvedColor.OPAQUE);
@@ -0,0 +1,36 @@
1
+ import type * as sml from '@docx4j/generated-objects-ts/modules/org_xlsx4j_sml';
2
+ import { ResolvedColor } from './ResolvedColor.mjs';
3
+ import type { ThemeColors } from './ThemeColors.mjs';
4
+ /**
5
+ * SpreadsheetML colours (`x:color`, `x:fgColor`, `x:bgColor` and the font and border colours, ISO/IEC 29500-1
6
+ * section 18.8) resolved as Excel draws them (docx4j CR-034 section 11, P4).
7
+ *
8
+ * - `theme`: Excel's index swaps the first two pairs (0 lt1, 1 dk1, 2 lt2, 3 dk2, then the accents and hyperlinks),
9
+ * as {@link ThemeColors.sheetThemeColor} does.
10
+ * - `indexed`: the legacy 64-colour palette, or all 64 entries of the workbook's own `x:indexedColors`; 64 and 65
11
+ * the system foreground and background (black, white).
12
+ * - `tint`, −1 to 1: the HLS luminance, L' = L·(1 + tint) below 0, L·(1 − tint) + HLSMAX·tint above, in Windows'
13
+ * integer HLS (HLSMAX 240), the luminance truncated after adding 0.02; a tint of 0 leaves the colour alone. All 90
14
+ * theme-and-tint cells measured exact. (Not POI's per-channel rule.)
15
+ *
16
+ * The `rgb` attributes are hexBinary, which the objects model holds as byte numbers (its declarations say a string;
17
+ * either is read). docx4j's `null` is `undefined` here.
18
+ */
19
+ export declare const SpreadsheetColors: {
20
+ /**
21
+ * @param c the colour element
22
+ * @param theme the workbook's theme
23
+ * @param indexedColors the workbook's `x:indexedColors`, or undefined for the legacy palette
24
+ * @returns undefined for `auto` or nothing stated: the caller's automatic colour
25
+ */
26
+ resolve(c: sml.CTColor | undefined | null, theme: ThemeColors | undefined, indexedColors?: sml.CTIndexedColors | null): ResolvedColor | undefined;
27
+ /** An indexed colour: the workbook's palette for 0 to 63 where it has one, else the legacy one. */
28
+ indexed(i: number, indexedColors?: sml.CTIndexedColors | null): ResolvedColor | undefined;
29
+ /**
30
+ * Excel's tint: Windows' integer HLS, the luminance truncated after adding 0.02. Plain truncation is two cells out
31
+ * of 90 short (both at tint 0.3333, whose luminance comes to just under a whole number and which Excel rounds up);
32
+ * any tolerance from 0.01 to 0.05 gives all 90, presumably the precision Excel keeps a tint at.
33
+ * Package-private in docx4j.
34
+ */
35
+ tint(c: ResolvedColor, tint: number): ResolvedColor;
36
+ };
@@ -0,0 +1,84 @@
1
+ import * as ColorMath from './ColorMath.mjs';
2
+ import { INDEXED } from './ColorTables.mjs';
3
+ import { bytesOf } from './DrawingMLColors.mjs';
4
+ import { ResolvedColor } from './ResolvedColor.mjs';
5
+ /** ARGB (4 bytes) or RGB (3 bytes); the alpha byte is not drawn by Excel and is ignored. */
6
+ function argb(v) {
7
+ const b = bytesOf(v);
8
+ if (b === undefined)
9
+ return undefined;
10
+ if (b.length === 4)
11
+ return ResolvedColor.rgb(b[1], b[2], b[3]);
12
+ if (b.length === 3)
13
+ return ResolvedColor.rgb(b[0], b[1], b[2]);
14
+ return undefined;
15
+ }
16
+ /**
17
+ * SpreadsheetML colours (`x:color`, `x:fgColor`, `x:bgColor` and the font and border colours, ISO/IEC 29500-1
18
+ * section 18.8) resolved as Excel draws them (docx4j CR-034 section 11, P4).
19
+ *
20
+ * - `theme`: Excel's index swaps the first two pairs (0 lt1, 1 dk1, 2 lt2, 3 dk2, then the accents and hyperlinks),
21
+ * as {@link ThemeColors.sheetThemeColor} does.
22
+ * - `indexed`: the legacy 64-colour palette, or all 64 entries of the workbook's own `x:indexedColors`; 64 and 65
23
+ * the system foreground and background (black, white).
24
+ * - `tint`, −1 to 1: the HLS luminance, L' = L·(1 + tint) below 0, L·(1 − tint) + HLSMAX·tint above, in Windows'
25
+ * integer HLS (HLSMAX 240), the luminance truncated after adding 0.02; a tint of 0 leaves the colour alone. All 90
26
+ * theme-and-tint cells measured exact. (Not POI's per-channel rule.)
27
+ *
28
+ * The `rgb` attributes are hexBinary, which the objects model holds as byte numbers (its declarations say a string;
29
+ * either is read). docx4j's `null` is `undefined` here.
30
+ */
31
+ export const SpreadsheetColors = {
32
+ /**
33
+ * @param c the colour element
34
+ * @param theme the workbook's theme
35
+ * @param indexedColors the workbook's `x:indexedColors`, or undefined for the legacy palette
36
+ * @returns undefined for `auto` or nothing stated: the caller's automatic colour
37
+ */
38
+ resolve(c, theme, indexedColors) {
39
+ var _a;
40
+ if (c === undefined || c === null || c.auto === true)
41
+ return undefined;
42
+ let base;
43
+ if (c.rgb !== undefined && c.rgb !== null) {
44
+ base = argb(c.rgb);
45
+ }
46
+ else if (c.theme !== undefined && c.theme !== null) {
47
+ base = theme === undefined ? undefined : theme.sheetThemeColor(Math.trunc(c.theme));
48
+ }
49
+ else if (c.indexed !== undefined && c.indexed !== null) {
50
+ base = SpreadsheetColors.indexed(Math.trunc(c.indexed), indexedColors);
51
+ }
52
+ if (base === undefined)
53
+ return undefined;
54
+ const tint = (_a = c.tint) !== null && _a !== void 0 ? _a : 0;
55
+ return tint === 0 ? base : SpreadsheetColors.tint(base, tint);
56
+ },
57
+ /** An indexed colour: the workbook's palette for 0 to 63 where it has one, else the legacy one. */
58
+ indexed(i, indexedColors) {
59
+ var _a;
60
+ if (indexedColors !== undefined && indexedColors !== null && i >= 0 && i < 64) {
61
+ const custom = (_a = indexedColors.rgbColor) !== null && _a !== void 0 ? _a : [];
62
+ if (i < custom.length && custom[i].rgb !== undefined && custom[i].rgb !== null)
63
+ return argb(custom[i].rgb);
64
+ }
65
+ return i >= 0 && i < INDEXED.length ? ResolvedColor.ofHex(INDEXED[i]) : undefined;
66
+ },
67
+ /**
68
+ * Excel's tint: Windows' integer HLS, the luminance truncated after adding 0.02. Plain truncation is two cells out
69
+ * of 90 short (both at tint 0.3333, whose luminance comes to just under a whole number and which Excel rounds up);
70
+ * any tolerance from 0.01 to 0.05 gives all 90, presumably the precision Excel keeps a tint at.
71
+ * Package-private in docx4j.
72
+ */
73
+ tint(c, tint) {
74
+ const hls = ColorMath.rgbToHls240(c.red, c.green, c.blue);
75
+ const l = tint < 0 ? hls[1] * (1 + tint) : hls[1] * (1 - tint) + (ColorMath.HLSMAX - ColorMath.HLSMAX * (1 - tint));
76
+ let li = Math.trunc(l + 0.02);
77
+ if (li < 0)
78
+ li = 0;
79
+ if (li > ColorMath.HLSMAX)
80
+ li = ColorMath.HLSMAX;
81
+ const rgb = ColorMath.hls240ToRgb(hls[0], li, hls[2]);
82
+ return ResolvedColor.rgb(rgb[0], rgb[1], rgb[2]);
83
+ },
84
+ };
@@ -0,0 +1,28 @@
1
+ import type { ResolvedColor } from './ResolvedColor.mjs';
2
+ /**
3
+ * docx4j's `StyleFill.Kind`, as its names: `NONE` (`a:noFill`, or a style reference with index 0), `SOLID`
4
+ * (`a:solidFill`: `color` is its colour), `GRADIENT` (`a:gradFill`), `PATTERN` (`a:pattFill`), `PICTURE`
5
+ * (`a:blipFill`), `GROUP` (`a:grpFill`: the group's fill), `UNKNOWN` (nothing stated, or a style reference whose
6
+ * index is outside the theme's lists).
7
+ */
8
+ export type StyleFillKind = 'NONE' | 'SOLID' | 'GRADIENT' | 'PATTERN' | 'PICTURE' | 'GROUP' | 'UNKNOWN';
9
+ /**
10
+ * A DrawingML fill as far as colour resolution goes: none, a solid colour (resolved), or a gradient, pattern,
11
+ * picture or group fill, which is reported as such and not guessed at - drawing one is a renderer's business.
12
+ * For a line, the fill is the line's. docx4j's getters are properties here (`getKind()` is `kind`).
13
+ */
14
+ export declare class StyleFill {
15
+ readonly kind: StyleFillKind;
16
+ /** The colour of a `SOLID` fill, else undefined. */
17
+ readonly color: ResolvedColor | undefined;
18
+ /** The fill object (`a:gradFill` and so on), for a renderer; undefined for none. */
19
+ readonly fill: unknown;
20
+ static readonly NONE: StyleFill;
21
+ static readonly UNKNOWN: StyleFill;
22
+ constructor(kind: StyleFillKind,
23
+ /** The colour of a `SOLID` fill, else undefined. */
24
+ color: ResolvedColor | undefined,
25
+ /** The fill object (`a:gradFill` and so on), for a renderer; undefined for none. */
26
+ fill: unknown);
27
+ toString(): string;
28
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * A DrawingML fill as far as colour resolution goes: none, a solid colour (resolved), or a gradient, pattern,
3
+ * picture or group fill, which is reported as such and not guessed at - drawing one is a renderer's business.
4
+ * For a line, the fill is the line's. docx4j's getters are properties here (`getKind()` is `kind`).
5
+ */
6
+ export class StyleFill {
7
+ constructor(kind,
8
+ /** The colour of a `SOLID` fill, else undefined. */
9
+ color,
10
+ /** The fill object (`a:gradFill` and so on), for a renderer; undefined for none. */
11
+ fill) {
12
+ this.kind = kind;
13
+ this.color = color;
14
+ this.fill = fill;
15
+ }
16
+ toString() {
17
+ return this.kind === 'SOLID' ? `solid ${String(this.color)}` : this.kind.toLowerCase();
18
+ }
19
+ }
20
+ StyleFill.NONE = new StyleFill('NONE', undefined, undefined);
21
+ StyleFill.UNKNOWN = new StyleFill('UNKNOWN', undefined, undefined);