@docx4j/core-ts 0.5.0 → 0.7.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 (207) hide show
  1. package/NOTICE +4 -0
  2. package/README.md +92 -4
  3. package/dist/html/convert.mjs +2 -1
  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 +145 -23
  24. package/dist/model/content/Body.mjs +507 -150
  25. package/dist/model/content/Comment.d.mts +23 -5
  26. package/dist/model/content/Comment.mjs +207 -26
  27. package/dist/model/content/ContentControl.d.mts +198 -19
  28. package/dist/model/content/ContentControl.mjs +672 -99
  29. package/dist/model/content/Font.d.mts +70 -17
  30. package/dist/model/content/Font.mjs +119 -36
  31. package/dist/model/content/InlinePicture.d.mts +11 -0
  32. package/dist/model/content/InlinePicture.mjs +21 -1
  33. package/dist/model/content/List.d.mts +6 -3
  34. package/dist/model/content/List.mjs +18 -8
  35. package/dist/model/content/Paragraph.d.mts +200 -14
  36. package/dist/model/content/Paragraph.mjs +898 -82
  37. package/dist/model/content/Range.d.mts +227 -12
  38. package/dist/model/content/Range.mjs +785 -59
  39. package/dist/model/content/ResolvedView.d.mts +104 -0
  40. package/dist/model/content/ResolvedView.mjs +596 -0
  41. package/dist/model/content/Table.d.mts +29 -3
  42. package/dist/model/content/Table.mjs +135 -49
  43. package/dist/model/content/TrackedChange.d.mts +174 -15
  44. package/dist/model/content/TrackedChange.mjs +734 -170
  45. package/dist/model/content/comments.d.mts +20 -6
  46. package/dist/model/content/comments.mjs +67 -57
  47. package/dist/model/content/generalException.d.mts +18 -0
  48. package/dist/model/content/generalException.mjs +24 -0
  49. package/dist/model/content/index.d.mts +10 -3
  50. package/dist/model/content/index.mjs +10 -2
  51. package/dist/model/content/mathText.d.mts +21 -0
  52. package/dist/model/content/mathText.mjs +267 -0
  53. package/dist/model/content/officeText.d.mts +27 -0
  54. package/dist/model/content/officeText.mjs +74 -0
  55. package/dist/model/content/ooxml.mjs +12 -1
  56. package/dist/model/content/outline.d.mts +5 -0
  57. package/dist/model/content/outline.mjs +13 -0
  58. package/dist/model/content/paraIds.d.mts +5 -0
  59. package/dist/model/content/paraIds.mjs +54 -0
  60. package/dist/model/content/placeholders.d.mts +110 -0
  61. package/dist/model/content/placeholders.mjs +253 -0
  62. package/dist/model/content/search.d.mts +74 -0
  63. package/dist/model/content/search.mjs +255 -9
  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 +47 -0
  67. package/dist/model/content/story.mjs +95 -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 +102 -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 +63 -6
  79. package/dist/model/content/tracking.mjs +242 -22
  80. package/dist/model/content/tree.d.mts +172 -24
  81. package/dist/model/content/tree.mjs +328 -54
  82. package/dist/model/content/wordRange.d.mts +48 -0
  83. package/dist/model/content/wordRange.mjs +97 -0
  84. package/dist/model/customxml/CustomXmlPartCollection.d.mts +30 -1
  85. package/dist/model/customxml/CustomXmlPartCollection.mjs +81 -12
  86. package/dist/model/customxml/XmlMapping.d.mts +32 -8
  87. package/dist/model/customxml/XmlMapping.mjs +64 -10
  88. package/dist/model/customxml/bindings.d.mts +33 -4
  89. package/dist/model/customxml/bindings.mjs +171 -45
  90. package/dist/model/customxml/index.d.mts +1 -0
  91. package/dist/model/customxml/index.mjs +1 -0
  92. package/dist/model/customxml/kinds.d.mts +8 -3
  93. package/dist/model/customxml/kinds.mjs +26 -5
  94. package/dist/model/customxml/opendope.d.mts +4 -1
  95. package/dist/model/customxml/opendope.mjs +9 -6
  96. package/dist/model/customxml/picturePlaceholder.d.mts +17 -0
  97. package/dist/model/customxml/picturePlaceholder.mjs +32 -0
  98. package/dist/model/customxml/pictures.d.mts +4 -3
  99. package/dist/model/customxml/pictures.mjs +22 -8
  100. package/dist/model/customxml/storeItems.d.mts +57 -0
  101. package/dist/model/customxml/storeItems.mjs +122 -0
  102. package/dist/model/customxml/xhtml.mjs +23 -22
  103. package/dist/model/dateZone.d.mts +25 -0
  104. package/dist/model/dateZone.mjs +57 -0
  105. package/dist/model/index.d.mts +3 -0
  106. package/dist/model/index.mjs +5 -0
  107. package/dist/model/listnumbering/Emulator.d.mts +37 -5
  108. package/dist/model/listnumbering/Emulator.mjs +63 -9
  109. package/dist/model/properties/PropertyResolver.d.mts +74 -2
  110. package/dist/model/properties/PropertyResolver.mjs +133 -5
  111. package/dist/model/properties/catalogue.d.mts +19 -5
  112. package/dist/model/properties/catalogue.mjs +41 -15
  113. package/dist/model/properties/index.d.mts +1 -1
  114. package/dist/model/properties/log.d.mts +1 -1
  115. package/dist/model/properties/log.mjs +5 -5
  116. package/dist/model/properties/styleUtil.d.mts +3 -1
  117. package/dist/model/properties/styleUtil.mjs +20 -24
  118. package/dist/model/properties/table.mjs +4 -2
  119. package/dist/model/text/CaseMapping.d.mts +38 -0
  120. package/dist/model/text/CaseMapping.mjs +86 -0
  121. package/dist/model/text/Extractor.d.mts +349 -0
  122. package/dist/model/text/Extractor.mjs +2406 -0
  123. package/dist/model/text/LinkTargets.d.mts +45 -0
  124. package/dist/model/text/LinkTargets.mjs +170 -0
  125. package/dist/model/text/MarkdownExporter.d.mts +140 -0
  126. package/dist/model/text/MarkdownExporter.mjs +255 -0
  127. package/dist/model/text/PlainText.d.mts +29 -0
  128. package/dist/model/text/PlainText.mjs +542 -0
  129. package/dist/model/text/TextContext.d.mts +256 -0
  130. package/dist/model/text/TextContext.mjs +600 -0
  131. package/dist/model/text/TextOptions.d.mts +233 -0
  132. package/dist/model/text/TextOptions.mjs +419 -0
  133. package/dist/model/text/TextResult.d.mts +621 -0
  134. package/dist/model/text/TextResult.mjs +629 -0
  135. package/dist/model/text/Texts.d.mts +99 -0
  136. package/dist/model/text/Texts.mjs +187 -0
  137. package/dist/model/text/WmlToMarkdown.d.mts +120 -0
  138. package/dist/model/text/WmlToMarkdown.mjs +936 -0
  139. package/dist/model/text/caseMapping.generated.d.mts +7 -0
  140. package/dist/model/text/caseMapping.generated.mjs +214 -0
  141. package/dist/model/text/commonmark.d.mts +121 -0
  142. package/dist/model/text/commonmark.mjs +655 -0
  143. package/dist/model/text/index.d.mts +8 -0
  144. package/dist/model/text/index.mjs +9 -0
  145. package/dist/model/text/normalize.d.mts +8 -0
  146. package/dist/model/text/normalize.mjs +13 -0
  147. package/dist/model/text/outline.d.mts +4 -0
  148. package/dist/model/text/outline.mjs +71 -0
  149. package/dist/model/wordIntegers.d.mts +29 -0
  150. package/dist/model/wordIntegers.mjs +78 -0
  151. package/dist/office-js/document.mjs +15 -1
  152. package/dist/office-js/fragment.d.mts +7 -5
  153. package/dist/office-js/fragment.mjs +63 -14
  154. package/dist/office-js/proxy.d.mts +8 -0
  155. package/dist/office-js/proxy.mjs +29 -0
  156. package/dist/office-js/run.mjs +2 -0
  157. package/dist/office-js/supported.generated.mjs +16 -0
  158. package/dist/office-js/toApiScript.mjs +29 -12
  159. package/dist/opc/DirectoryPartStore.d.mts +6 -2
  160. package/dist/opc/DirectoryPartStore.mjs +11 -4
  161. package/dist/opc/FlatOpcPartStore.d.mts +4 -2
  162. package/dist/opc/FlatOpcPartStore.mjs +11 -8
  163. package/dist/opc/Load.d.mts +32 -0
  164. package/dist/opc/Load.mjs +115 -5
  165. package/dist/opc/PartStore.d.mts +34 -1
  166. package/dist/opc/PartStore.mjs +71 -8
  167. package/dist/opc/Save.d.mts +32 -0
  168. package/dist/opc/Save.mjs +110 -4
  169. package/dist/opc/ZipPartStore.d.mts +4 -2
  170. package/dist/opc/ZipPartStore.mjs +12 -7
  171. package/dist/opc/exceptions.d.mts +140 -0
  172. package/dist/opc/exceptions.mjs +108 -0
  173. package/dist/opc/index.d.mts +8 -5
  174. package/dist/opc/index.mjs +5 -3
  175. package/dist/opc/mce/preprocessor.d.mts +141 -5
  176. package/dist/opc/mce/preprocessor.mjs +119 -18
  177. package/dist/opc/mce/understood.d.mts +3 -11
  178. package/dist/opc/mce/understood.mjs +27 -23
  179. package/dist/opc/repair/breaks.d.mts +23 -0
  180. package/dist/opc/repair/breaks.mjs +288 -0
  181. package/dist/opc/repair/hosts.d.mts +12 -0
  182. package/dist/opc/repair/hosts.mjs +33 -0
  183. package/dist/opc/repair/mainRoot.d.mts +19 -0
  184. package/dist/opc/repair/mainRoot.mjs +168 -0
  185. package/dist/opc/repair/unknownElements.d.mts +8 -0
  186. package/dist/opc/repair/unknownElements.mjs +180 -0
  187. package/dist/opc/repair/wmlNames.generated.d.mts +2 -0
  188. package/dist/opc/repair/wmlNames.generated.mjs +80 -0
  189. package/dist/opc/skipped.d.mts +50 -0
  190. package/dist/opc/skipped.mjs +140 -0
  191. package/dist/packages/OpcPackage.d.mts +110 -4
  192. package/dist/packages/OpcPackage.mjs +123 -7
  193. package/dist/packages/WordprocessingMLPackage.d.mts +45 -8
  194. package/dist/packages/WordprocessingMLPackage.mjs +158 -21
  195. package/dist/packages/index.d.mts +1 -1
  196. package/dist/parts/DefaultXmlPart.mjs +2 -2
  197. package/dist/parts/Part.d.mts +14 -2
  198. package/dist/parts/RelationshipsPart.d.mts +15 -0
  199. package/dist/parts/RelationshipsPart.mjs +66 -1
  200. package/dist/parts/XmlPart.d.mts +63 -32
  201. package/dist/parts/XmlPart.mjs +240 -96
  202. package/dist/parts/wml/comments.mjs +30 -0
  203. package/dist/parts/wml/index.d.mts +12 -1
  204. package/dist/parts/wml/index.mjs +37 -1
  205. package/dist/xml/dom.d.mts +7 -0
  206. package/dist/xml/dom.mjs +18 -0
  207. package/package.json +2 -2
@@ -0,0 +1,86 @@
1
+ import type * as dml from '@docx4j/generated-objects-ts/modules/org_docx4j_dml';
2
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
3
+ import type * as chart from '@docx4j/generated-objects-ts/modules/org_docx4j_dml_chart';
4
+ import { Part } from '../../parts/Part.mjs';
5
+ import type { XmlPart } from '../../parts/XmlPart.mjs';
6
+ import type { OpcPackage } from '../../packages/OpcPackage.mjs';
7
+ import { type DefaultTheme } from '../fonts/defaultTheme.mjs';
8
+ import { ResolvedColor } from './ResolvedColor.mjs';
9
+ /**
10
+ * A theme's colour scheme and the colour map that leads to it: all a colour reference needs. Immutable; each
11
+ * `with...` returns a new one. Which theme and which map apply depends on the host: {@link ThemeColors.of} takes a
12
+ * package (docx or xlsx) or a part (a slide, layout, master or notes part; a part of a docx or xlsx), and
13
+ * {@link ThemeColors.forChart} a chart in any of them - drawn in its host's theme.
14
+ *
15
+ * The scheme's slots are `dk1`, `lt1`, `dk2`, `lt2`, `accent1` to `accent6`, `hlink` and `folHlink`; the map takes
16
+ * `bg1`, `tx1`, `bg2`, `tx2` (and, in principle, the accents and hyperlinks) to a slot. A slot holding a system
17
+ * colour is the machine's colour, not its `lastClr` (docx4j CR-034 section 11).
18
+ *
19
+ * docx4j's names, but: `of(Theme)` is {@link ThemeColors.ofTheme} here (synchronous), and `of(WordprocessingMLPackage)`,
20
+ * `of(SpreadsheetMLPackage)` and `of(Part)` are one asynchronous {@link ThemeColors.of}; `forChart(Chart)` is
21
+ * asynchronous; `getFormatScheme()` and `getPlaceholder()` are the properties `formatScheme` and `placeholder`.
22
+ */
23
+ export declare class ThemeColors {
24
+ private readonly slots;
25
+ private readonly map;
26
+ /** The theme's format scheme, which style references index into; undefined where the theme has none. */
27
+ readonly formatScheme: dml.CTStyleMatrix | undefined;
28
+ /** `phClr`'s colour, where a style reference supplies one. */
29
+ readonly placeholder: ResolvedColor | undefined;
30
+ private constructor();
31
+ /**
32
+ * A theme with the default colour map (docx4j `of(Theme)`).
33
+ *
34
+ * @param theme undefined for the theme Office supplies where a package has none: the bundled theme `defaultTheme`
35
+ * names, else {@link defaultThemeSetting}'s. Parsing it needs the objects package's context, which is built once
36
+ * anything has been read; {@link ThemeColors.loadDefaultTheme} builds it.
37
+ */
38
+ static ofTheme(theme: dml.Theme | undefined, defaultTheme?: DefaultTheme): ThemeColors;
39
+ /** Parses a bundled theme ahead of a synchronous {@link ThemeColors.ofTheme}(undefined), building the context if need be. */
40
+ static loadDefaultTheme(defaultTheme?: DefaultTheme): Promise<dml.Theme>;
41
+ /**
42
+ * The theme colours of a package or a part:
43
+ * - a docx: the main document part's theme (or the default theme) and `w:clrSchemeMapping` from the settings,
44
+ * which applies to WordprocessingML theme colours and DrawingML scheme colours alike (docx4j CR-034 section 11, P2);
45
+ * - an xlsx: the workbook's theme (or the default theme), with the default map for its drawings;
46
+ * - a slide: its master's theme, its master's `p:clrMap`, then its layout's `p:clrMapOvr`, then its own; a layout,
47
+ * a master, a notes slide, a notes or handout master likewise;
48
+ * - a part of a docx or xlsx: its package's.
49
+ * Anything else, or a part that can't be read, gets the default theme with the default map.
50
+ */
51
+ static of(source: OpcPackage | Part): Promise<ThemeColors>;
52
+ private static themed;
53
+ private static ofPart;
54
+ /** This theme with a DrawingML colour map (`p:clrMap`, `c:clrMapOvr`); undefined leaves it. */
55
+ withMapping(m: dml.CTColorMapping | undefined | null): ThemeColors;
56
+ /** `a:overrideClrMapping` replaces the map; `a:masterClrMapping` (or nothing) keeps it. */
57
+ withOverride(o: dml.CTColorMappingOverride | undefined | null): ThemeColors;
58
+ /** This theme with WordprocessingML's `w:clrSchemeMapping` (whose names differ: dark1, t1, ...). */
59
+ withWordMapping(m: wml.CTColorSchemeMapping | undefined | null): ThemeColors;
60
+ /** This theme with another colour scheme and format scheme (a theme override part's). */
61
+ withScheme(clrScheme: dml.CTColorScheme | undefined | null, fmt?: dml.CTStyleMatrix | null): ThemeColors;
62
+ /**
63
+ * A chart's colours: this (its host's) theme, under the chart's theme override part if it has one, and the
64
+ * chart's `c:clrMapOvr` if it states one.
65
+ */
66
+ forChart(chartPart: XmlPart<chart.CTChartSpace>): Promise<ThemeColors>;
67
+ /** This theme with `phClr` standing for the given colour (a style reference's). */
68
+ withPlaceholder(color: ResolvedColor | undefined): ThemeColors;
69
+ /** A scheme slot's colour (dk1, lt1, ..., folHlink), not through the map. */
70
+ slot(slot: string): ResolvedColor | undefined;
71
+ /**
72
+ * A DrawingML `schemeClr` value's colour: bg1, tx1, bg2, tx2 (and the accents and hyperlinks) through the map,
73
+ * dk1 ... lt2 directly, `phClr` the placeholder.
74
+ */
75
+ schemeColor(val: string | undefined | null): ResolvedColor | undefined;
76
+ /**
77
+ * A WordprocessingML `w:themeColor` value's colour: text1, background1, text2, background2 through the map,
78
+ * dark1 ... followedHyperlink directly; undefined for "none".
79
+ */
80
+ wordThemeColor(themeColor: string | undefined | null): ResolvedColor | undefined;
81
+ /**
82
+ * A SpreadsheetML `theme` index's colour. Excel swaps the first two pairs: 0 is lt1, 1 dk1, 2 lt2, 3 dk2, then
83
+ * accent1 to accent6, hlink, folHlink (docx4j CR-034 section 11, P4).
84
+ */
85
+ sheetThemeColor(index: number): ResolvedColor | undefined;
86
+ }
@@ -0,0 +1,304 @@
1
+ import { getContext, getContextSync } from '@docx4j/generated-objects-ts';
2
+ import { Part } from '../../parts/Part.mjs';
3
+ import { Namespaces } from '../../parts/Namespaces.mjs';
4
+ import { ThemePart, ThemeOverridePart } from '../../parts/dml/index.mjs';
5
+ import { SlidePart, SlideLayoutPart, SlideMasterPart, NotesSlidePart, NotesMasterPart, HandoutMasterPart, } from '../../parts/pml/index.mjs';
6
+ import { Docx4JException } from '../../opc/exceptions.mjs';
7
+ import { themeOfSettings, defaultThemeSetting } from '../fonts/defaultTheme.mjs';
8
+ import { DrawingMLColors } from './DrawingMLColors.mjs';
9
+ /** The scheme's slots. */
10
+ const SLOTS = ['dk1', 'lt1', 'dk2', 'lt2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
11
+ /** What a colour map takes to a slot. */
12
+ const MAPPED = ['bg1', 'tx1', 'bg2', 'tx2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
13
+ /** WordprocessingML's names for the scheme's slots. */
14
+ const WORD_NAMES = new Map([
15
+ ['dark1', 'dk1'], ['light1', 'lt1'], ['dark2', 'dk2'], ['light2', 'lt2'],
16
+ ['accent1', 'accent1'], ['accent2', 'accent2'], ['accent3', 'accent3'], ['accent4', 'accent4'], ['accent5', 'accent5'], ['accent6', 'accent6'],
17
+ ['hyperlink', 'hlink'], ['followedHyperlink', 'folHlink'],
18
+ ]);
19
+ /** Excel's theme indexes: the first two pairs swapped (docx4j CR-034 section 11, P4). */
20
+ const SHEET_ORDER = ['lt1', 'dk1', 'lt2', 'dk2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
21
+ /** The default colour map: bg1 to lt1, tx1 to dk1, bg2 to lt2, tx2 to dk2, the rest to themselves. */
22
+ function defaultMap() {
23
+ const m = new Map([['bg1', 'lt1'], ['tx1', 'dk1'], ['bg2', 'lt2'], ['tx2', 'dk2']]);
24
+ for (let i = 4; i < MAPPED.length; i++)
25
+ m.set(MAPPED[i], MAPPED[i]);
26
+ return m;
27
+ }
28
+ function scheme(cs) {
29
+ const m = new Map();
30
+ if (cs !== undefined && cs !== null) {
31
+ for (const slot of SLOTS) {
32
+ const c = cs[slot];
33
+ const r = c === undefined || c === null ? undefined : DrawingMLColors.resolve(c, undefined);
34
+ if (r !== undefined)
35
+ m.set(slot, r);
36
+ }
37
+ }
38
+ return m;
39
+ }
40
+ // ------------------------------------------------------------------ the bundled themes
41
+ const bundled = new Map();
42
+ function parseTheme(context, xml) {
43
+ const element = context.createUnmarshaller().unmarshalString(xml);
44
+ return element.value;
45
+ }
46
+ /** A bundled theme, parsed; the objects package's context must be built (it is once anything has been read). */
47
+ function bundledThemeSync(theme) {
48
+ let t = bundled.get(theme.value);
49
+ if (t === undefined) {
50
+ let context;
51
+ try {
52
+ context = getContextSync();
53
+ }
54
+ catch (e) {
55
+ throw new Docx4JException(`The default theme ${theme.value} needs the objects context: await ThemeColors.loadDefaultTheme() first`, { cause: e });
56
+ }
57
+ t = parseTheme(context, theme.xml);
58
+ bundled.set(theme.value, t);
59
+ }
60
+ return t;
61
+ }
62
+ async function readQuietly(part) {
63
+ if (part === undefined)
64
+ return undefined;
65
+ try {
66
+ return await part.readContents();
67
+ }
68
+ catch {
69
+ return undefined;
70
+ }
71
+ }
72
+ /** The part a relationship of this type leads to, if it is one of this class. */
73
+ function related(part, type, kind) {
74
+ const rp = part.relationshipsPart;
75
+ const rel = rp === null || rp === void 0 ? void 0 : rp.getRelationshipByType(type);
76
+ const target = rel === undefined ? undefined : rp.getPart(rel);
77
+ return target instanceof kind ? target : undefined;
78
+ }
79
+ const isWord = (pkg) => typeof (pkg === null || pkg === void 0 ? void 0 : pkg.getMainDocumentPart) === 'function';
80
+ const isSpreadsheet = (pkg) => typeof (pkg === null || pkg === void 0 ? void 0 : pkg.getWorkbookPart) === 'function';
81
+ /** The default theme a package names (`pkg.fonts.defaultTheme`), else the process-wide setting. */
82
+ function defaultThemeOfPackage(pkg) {
83
+ return themeOfSettings(pkg === null || pkg === void 0 ? void 0 : pkg.fonts);
84
+ }
85
+ /**
86
+ * A theme's colour scheme and the colour map that leads to it: all a colour reference needs. Immutable; each
87
+ * `with...` returns a new one. Which theme and which map apply depends on the host: {@link ThemeColors.of} takes a
88
+ * package (docx or xlsx) or a part (a slide, layout, master or notes part; a part of a docx or xlsx), and
89
+ * {@link ThemeColors.forChart} a chart in any of them - drawn in its host's theme.
90
+ *
91
+ * The scheme's slots are `dk1`, `lt1`, `dk2`, `lt2`, `accent1` to `accent6`, `hlink` and `folHlink`; the map takes
92
+ * `bg1`, `tx1`, `bg2`, `tx2` (and, in principle, the accents and hyperlinks) to a slot. A slot holding a system
93
+ * colour is the machine's colour, not its `lastClr` (docx4j CR-034 section 11).
94
+ *
95
+ * docx4j's names, but: `of(Theme)` is {@link ThemeColors.ofTheme} here (synchronous), and `of(WordprocessingMLPackage)`,
96
+ * `of(SpreadsheetMLPackage)` and `of(Part)` are one asynchronous {@link ThemeColors.of}; `forChart(Chart)` is
97
+ * asynchronous; `getFormatScheme()` and `getPlaceholder()` are the properties `formatScheme` and `placeholder`.
98
+ */
99
+ export class ThemeColors {
100
+ constructor(slots, map,
101
+ /** The theme's format scheme, which style references index into; undefined where the theme has none. */
102
+ formatScheme,
103
+ /** `phClr`'s colour, where a style reference supplies one. */
104
+ placeholder) {
105
+ this.slots = slots;
106
+ this.map = map;
107
+ this.formatScheme = formatScheme;
108
+ this.placeholder = placeholder;
109
+ }
110
+ // ------------------------------------------------------------------ making one
111
+ /**
112
+ * A theme with the default colour map (docx4j `of(Theme)`).
113
+ *
114
+ * @param theme undefined for the theme Office supplies where a package has none: the bundled theme `defaultTheme`
115
+ * names, else {@link defaultThemeSetting}'s. Parsing it needs the objects package's context, which is built once
116
+ * anything has been read; {@link ThemeColors.loadDefaultTheme} builds it.
117
+ */
118
+ static ofTheme(theme, defaultTheme) {
119
+ var _a;
120
+ theme !== null && theme !== void 0 ? theme : (theme = bundledThemeSync(defaultTheme !== null && defaultTheme !== void 0 ? defaultTheme : defaultThemeSetting()));
121
+ const elements = theme.themeElements;
122
+ return new ThemeColors(scheme(elements === null || elements === void 0 ? void 0 : elements.clrScheme), defaultMap(), (_a = elements === null || elements === void 0 ? void 0 : elements.fmtScheme) !== null && _a !== void 0 ? _a : undefined, undefined);
123
+ }
124
+ /** Parses a bundled theme ahead of a synchronous {@link ThemeColors.ofTheme}(undefined), building the context if need be. */
125
+ static async loadDefaultTheme(defaultTheme = defaultThemeSetting()) {
126
+ let t = bundled.get(defaultTheme.value);
127
+ if (t === undefined) {
128
+ t = parseTheme(await getContext(), defaultTheme.xml);
129
+ bundled.set(defaultTheme.value, t);
130
+ }
131
+ return t;
132
+ }
133
+ /**
134
+ * The theme colours of a package or a part:
135
+ * - a docx: the main document part's theme (or the default theme) and `w:clrSchemeMapping` from the settings,
136
+ * which applies to WordprocessingML theme colours and DrawingML scheme colours alike (docx4j CR-034 section 11, P2);
137
+ * - an xlsx: the workbook's theme (or the default theme), with the default map for its drawings;
138
+ * - a slide: its master's theme, its master's `p:clrMap`, then its layout's `p:clrMapOvr`, then its own; a layout,
139
+ * a master, a notes slide, a notes or handout master likewise;
140
+ * - a part of a docx or xlsx: its package's.
141
+ * Anything else, or a part that can't be read, gets the default theme with the default map.
142
+ */
143
+ static async of(source) {
144
+ if (source instanceof Part)
145
+ return ThemeColors.ofPart(source);
146
+ const fallback = defaultThemeOfPackage(source);
147
+ if (isWord(source)) {
148
+ const main = source.getMainDocumentPart();
149
+ const tc = await ThemeColors.themed(await readQuietly(main.themePart), fallback);
150
+ const settings = await readQuietly(main.documentSettingsPart);
151
+ const m = settings === null || settings === void 0 ? void 0 : settings.clrSchemeMapping;
152
+ return m === undefined || m === null ? tc : tc.withWordMapping(m);
153
+ }
154
+ if (isSpreadsheet(source)) {
155
+ return ThemeColors.themed(await readQuietly(source.getWorkbookPart().themePart), fallback);
156
+ }
157
+ return ThemeColors.themed(undefined, fallback);
158
+ }
159
+ static async themed(theme, fallback) {
160
+ if (theme === undefined)
161
+ await ThemeColors.loadDefaultTheme(fallback);
162
+ return ThemeColors.ofTheme(theme, fallback);
163
+ }
164
+ static async ofPart(part) {
165
+ const fallback = defaultThemeOfPackage(part.package);
166
+ try {
167
+ if (part instanceof SlidePart) {
168
+ const layout = part.slideLayoutPart;
169
+ const tc = layout === undefined ? await ThemeColors.themed(undefined, fallback) : await ThemeColors.ofPart(layout);
170
+ return tc.withOverride((await part.readContents()).clrMapOvr);
171
+ }
172
+ if (part instanceof SlideLayoutPart) {
173
+ const master = part.slideMasterPart;
174
+ const tc = master === undefined ? await ThemeColors.themed(undefined, fallback) : await ThemeColors.ofPart(master);
175
+ return tc.withOverride((await part.readContents()).clrMapOvr);
176
+ }
177
+ if (part instanceof SlideMasterPart || part instanceof NotesMasterPart || part instanceof HandoutMasterPart) {
178
+ const theme = await readQuietly(related(part, Namespaces.THEME, ThemePart));
179
+ return (await ThemeColors.themed(theme, fallback)).withMapping((await part.readContents()).clrMap);
180
+ }
181
+ if (part instanceof NotesSlidePart) {
182
+ const master = related(part, Namespaces.PRESENTATIONML_NOTES_MASTER, NotesMasterPart);
183
+ const tc = master === undefined ? await ThemeColors.themed(undefined, fallback) : await ThemeColors.ofPart(master);
184
+ return tc.withOverride((await part.readContents()).clrMapOvr);
185
+ }
186
+ }
187
+ catch {
188
+ // docx4j logs "Couldn't read the colour map of ..." and takes the default theme
189
+ return ThemeColors.themed(undefined, fallback);
190
+ }
191
+ const pkg = part.package;
192
+ if (isWord(pkg) || isSpreadsheet(pkg))
193
+ return ThemeColors.of(pkg);
194
+ return ThemeColors.themed(undefined, fallback);
195
+ }
196
+ // ------------------------------------------------------------------ deriving one
197
+ /** This theme with a DrawingML colour map (`p:clrMap`, `c:clrMapOvr`); undefined leaves it. */
198
+ withMapping(m) {
199
+ if (m === undefined || m === null)
200
+ return this;
201
+ const mm = new Map(this.map);
202
+ for (const key of MAPPED)
203
+ put(mm, key, m[key]);
204
+ return new ThemeColors(this.slots, mm, this.formatScheme, this.placeholder);
205
+ }
206
+ /** `a:overrideClrMapping` replaces the map; `a:masterClrMapping` (or nothing) keeps it. */
207
+ withOverride(o) {
208
+ return o === undefined || o === null || o.overrideClrMapping === undefined || o.overrideClrMapping === null
209
+ ? this : this.withMapping(o.overrideClrMapping);
210
+ }
211
+ /** This theme with WordprocessingML's `w:clrSchemeMapping` (whose names differ: dark1, t1, ...). */
212
+ withWordMapping(m) {
213
+ if (m === undefined || m === null)
214
+ return this;
215
+ const mm = new Map(this.map);
216
+ put(mm, 'bg1', wordSlot(m.bg1));
217
+ put(mm, 'tx1', wordSlot(m.t1));
218
+ put(mm, 'bg2', wordSlot(m.bg2));
219
+ put(mm, 'tx2', wordSlot(m.t2));
220
+ put(mm, 'accent1', wordSlot(m.accent1));
221
+ put(mm, 'accent2', wordSlot(m.accent2));
222
+ put(mm, 'accent3', wordSlot(m.accent3));
223
+ put(mm, 'accent4', wordSlot(m.accent4));
224
+ put(mm, 'accent5', wordSlot(m.accent5));
225
+ put(mm, 'accent6', wordSlot(m.accent6));
226
+ put(mm, 'hlink', wordSlot(m.hyperlink));
227
+ put(mm, 'folHlink', wordSlot(m.followedHyperlink));
228
+ return new ThemeColors(this.slots, mm, this.formatScheme, this.placeholder);
229
+ }
230
+ /** This theme with another colour scheme and format scheme (a theme override part's). */
231
+ withScheme(clrScheme, fmt) {
232
+ return new ThemeColors(clrScheme === undefined || clrScheme === null ? this.slots : scheme(clrScheme), this.map, fmt === undefined || fmt === null ? this.formatScheme : fmt, this.placeholder);
233
+ }
234
+ /**
235
+ * A chart's colours: this (its host's) theme, under the chart's theme override part if it has one, and the
236
+ * chart's `c:clrMapOvr` if it states one.
237
+ */
238
+ async forChart(chartPart) {
239
+ let tc = this;
240
+ try {
241
+ const override = await readQuietly(related(chartPart, Namespaces.THEME_OVERRIDE, ThemeOverridePart));
242
+ if (override !== undefined)
243
+ tc = tc.withScheme(override.clrScheme, override.fmtScheme);
244
+ tc = tc.withMapping((await chartPart.readContents()).clrMapOvr);
245
+ }
246
+ catch {
247
+ // docx4j logs "Couldn't read ...'s theme override or colour map" and keeps what it has
248
+ }
249
+ return tc;
250
+ }
251
+ /** This theme with `phClr` standing for the given colour (a style reference's). */
252
+ withPlaceholder(color) {
253
+ return new ThemeColors(this.slots, this.map, this.formatScheme, color);
254
+ }
255
+ // ------------------------------------------------------------------ reading it
256
+ /** A scheme slot's colour (dk1, lt1, ..., folHlink), not through the map. */
257
+ slot(slot) {
258
+ return this.slots.get(slot);
259
+ }
260
+ /**
261
+ * A DrawingML `schemeClr` value's colour: bg1, tx1, bg2, tx2 (and the accents and hyperlinks) through the map,
262
+ * dk1 ... lt2 directly, `phClr` the placeholder.
263
+ */
264
+ schemeColor(val) {
265
+ if (val === undefined || val === null)
266
+ return undefined;
267
+ if (val === 'phClr')
268
+ return this.placeholder;
269
+ const slot = this.map.get(val);
270
+ return this.slots.get(slot !== null && slot !== void 0 ? slot : val);
271
+ }
272
+ /**
273
+ * A WordprocessingML `w:themeColor` value's colour: text1, background1, text2, background2 through the map,
274
+ * dark1 ... followedHyperlink directly; undefined for "none".
275
+ */
276
+ wordThemeColor(themeColor) {
277
+ if (themeColor === undefined || themeColor === null)
278
+ return undefined;
279
+ switch (themeColor) {
280
+ case 'text1': return this.schemeColor('tx1');
281
+ case 'background1': return this.schemeColor('bg1');
282
+ case 'text2': return this.schemeColor('tx2');
283
+ case 'background2': return this.schemeColor('bg2');
284
+ default: {
285
+ const slot = WORD_NAMES.get(themeColor);
286
+ return slot === undefined ? undefined : this.slots.get(slot);
287
+ }
288
+ }
289
+ }
290
+ /**
291
+ * A SpreadsheetML `theme` index's colour. Excel swaps the first two pairs: 0 is lt1, 1 dk1, 2 lt2, 3 dk2, then
292
+ * accent1 to accent6, hlink, folHlink (docx4j CR-034 section 11, P4).
293
+ */
294
+ sheetThemeColor(index) {
295
+ return index < 0 || index >= SHEET_ORDER.length ? undefined : this.slots.get(SHEET_ORDER[Math.trunc(index)]);
296
+ }
297
+ }
298
+ function wordSlot(i) {
299
+ return i === undefined || i === null ? undefined : WORD_NAMES.get(i);
300
+ }
301
+ function put(m, key, slot) {
302
+ if (slot !== undefined && slot !== null)
303
+ m.set(key, slot);
304
+ }
@@ -0,0 +1,71 @@
1
+ import type * as wml from '@docx4j/generated-objects-ts/modules/org_docx4j_wml';
2
+ import { ResolvedColor } from './ResolvedColor.mjs';
3
+ import type { ThemeColors } from './ThemeColors.mjs';
4
+ /**
5
+ * WordprocessingML colours (`w:color`, `w:shd`, the borders, `w:u`) resolved as Word draws them (docx4j CR-034
6
+ * section 11, P1).
7
+ *
8
+ * - A theme reference (`w:themeColor`, `w:themeFill`) wins over the value written beside it (`w:val`, `w:color`,
9
+ * `w:fill`), which is a cache Word keeps: Word draws the theme colour even where the value disagrees (an older
10
+ * theme's, or anything else).
11
+ * - `w:themeTint` and `w:themeShade` change the HSL luminance: tint t, L' = L·t + (1 − t); shade t, L' = L·t, t
12
+ * being the byte over 255 (MS-OI29500 2.1.72). Where both are present Word applies the tint (the same note).
13
+ * - Word's own rounding of that arithmetic is not reproduced exactly (within one unit per channel in all 7,700 tints
14
+ * and shades of four corpora), so where the written value is within one unit of the computed one - a current
15
+ * cache - Word's value is returned: exact for every attribute Word itself wrote against the document's theme.
16
+ * - A value is read as Word 365 reads it ({@link WordColors.normalise}, docx4j CR-060 and core-ts CR-015): trimmed,
17
+ * hex in either case with an optional `#`, or one of the 140 classic HTML colour names. One Word rejects is
18
+ * automatic. A fill, a pattern colour and a border's colour are read the same way, as Word reads them (round 5: a
19
+ * name there is drawn): docx4j's `WordColors` since `a9e0303ff` (until then it normalised in `of(Color)` and `of(U)`
20
+ * only; CR-015 section 11.4).
21
+ *
22
+ * docx4j's overloads `of(Color)`, `of(CTBorder)` and `of(U)` are {@link WordColors.of}, {@link WordColors.ofBorder}
23
+ * and {@link WordColors.ofUnderline} here, since the three objects can't be told apart by shape; its `null` (for
24
+ * automatic) is `undefined`.
25
+ */
26
+ export declare const WordColors: {
27
+ /**
28
+ * The colour Word draws for a WordprocessingML colour's attributes.
29
+ *
30
+ * @param val the written value: RRGGBB, "auto", or undefined
31
+ * @param themeColor the theme reference, or undefined (or "none")
32
+ * @param themeTint a byte in hex ("99"), or undefined
33
+ * @param themeShade a byte in hex ("BF"), or undefined
34
+ * @returns undefined for automatic (no theme reference and val "auto" or absent): the caller's default
35
+ */
36
+ resolve(val: string | undefined | null, themeColor: string | undefined | null, themeTint: string | undefined | null, themeShade: string | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
37
+ /**
38
+ * A colour value (`w:color/@w:val`, `w:u/@w:color`, `w:shd/@w:fill`, a border's `w:color`) as Word 365 reads it
39
+ * (docx4j CR-060 section 1, rule 3, and sections 12 and 13): surrounding whitespace trimmed, six hex digits in
40
+ * either case with an optional leading `#`; else a classic HTML colour name, in any case. The rule is the objects
41
+ * package's `wordColor` (its CR-013, held to docx4j's `WordColorValues`).
42
+ *
43
+ * @returns six upper-case hex digits; undefined for `auto` and for a value Word rejects, which Word reads as
44
+ * automatic in a fill or a border colour, and as absent in a text or underline colour ({@link WordColors.stated})
45
+ */
46
+ normalise(val: string | undefined | null): string | undefined;
47
+ /**
48
+ * Whether a `w:color/@w:val` or `w:u/@w:color` value states a colour, as Word reads it (docx4j CR-060 sections 12
49
+ * and 13): one {@link WordColors.normalise} accepts, or exactly `auto` (automatic, which overrides a style's
50
+ * colour). Word reads any other value (`F00`, `bogus`, `""`, `Auto`, `" auto"`) as absent: a style's colour beneath
51
+ * still shows. (In a fill or a border colour it reads such a value as automatic instead.)
52
+ */
53
+ stated(val: string | undefined | null): boolean;
54
+ /** A run's colour (`w:color`); undefined for automatic. */
55
+ of(c: wml.Color | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
56
+ /** A shading's fill (`w:fill`, `w:themeFill`); undefined for automatic. */
57
+ fill(shd: wml.CTShd | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
58
+ /** A shading's pattern colour (`w:color`, `w:themeColor`); undefined for automatic. */
59
+ pattern(shd: wml.CTShd | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
60
+ /** A border's colour; undefined for automatic. docx4j `of(CTBorder)`. */
61
+ ofBorder(border: wml.CTBorder | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
62
+ /** An underline's colour; undefined for automatic (the text's colour). docx4j `of(U)`. */
63
+ ofUnderline(u: wml.U | undefined | null, theme: ThemeColors | undefined): ResolvedColor | undefined;
64
+ /**
65
+ * Word's themeTint (tint true) or themeShade on a colour: float HSL, the channels truncated. That is what Word 365
66
+ * draws (docx4j CR-034 section 11: the three P1 cases with no usable written value, all exact); the values older
67
+ * versions of Word wrote are within one unit of it (all 119 distinct ones in four corpora, 77 exact).
68
+ * Package-private in docx4j; public here for the corpus vectors' test.
69
+ */
70
+ luminance(c: ResolvedColor, t: number, tint: boolean): ResolvedColor;
71
+ };
@@ -0,0 +1,121 @@
1
+ import { wordColor } from '@docx4j/generated-objects-ts/helpers/wml';
2
+ import * as ColorMath from './ColorMath.mjs';
3
+ import { ResolvedColor } from './ResolvedColor.mjs';
4
+ function hexByte(s) {
5
+ if (s === undefined || s === null || s.length === 0)
6
+ return undefined;
7
+ // Java's Integer.parseInt(s, 16): an optional sign, then hex digits
8
+ if (!/^[+-]?[0-9A-Fa-f]+$/.test(s))
9
+ return undefined;
10
+ const v = Number.parseInt(s, 16);
11
+ return v >= 0 && v <= 255 ? v : undefined;
12
+ }
13
+ function truncate(v) {
14
+ return Math.floor(ColorMath.clamp01(v) * 255 + 1e-9);
15
+ }
16
+ /**
17
+ * WordprocessingML colours (`w:color`, `w:shd`, the borders, `w:u`) resolved as Word draws them (docx4j CR-034
18
+ * section 11, P1).
19
+ *
20
+ * - A theme reference (`w:themeColor`, `w:themeFill`) wins over the value written beside it (`w:val`, `w:color`,
21
+ * `w:fill`), which is a cache Word keeps: Word draws the theme colour even where the value disagrees (an older
22
+ * theme's, or anything else).
23
+ * - `w:themeTint` and `w:themeShade` change the HSL luminance: tint t, L' = L·t + (1 − t); shade t, L' = L·t, t
24
+ * being the byte over 255 (MS-OI29500 2.1.72). Where both are present Word applies the tint (the same note).
25
+ * - Word's own rounding of that arithmetic is not reproduced exactly (within one unit per channel in all 7,700 tints
26
+ * and shades of four corpora), so where the written value is within one unit of the computed one - a current
27
+ * cache - Word's value is returned: exact for every attribute Word itself wrote against the document's theme.
28
+ * - A value is read as Word 365 reads it ({@link WordColors.normalise}, docx4j CR-060 and core-ts CR-015): trimmed,
29
+ * hex in either case with an optional `#`, or one of the 140 classic HTML colour names. One Word rejects is
30
+ * automatic. A fill, a pattern colour and a border's colour are read the same way, as Word reads them (round 5: a
31
+ * name there is drawn): docx4j's `WordColors` since `a9e0303ff` (until then it normalised in `of(Color)` and `of(U)`
32
+ * only; CR-015 section 11.4).
33
+ *
34
+ * docx4j's overloads `of(Color)`, `of(CTBorder)` and `of(U)` are {@link WordColors.of}, {@link WordColors.ofBorder}
35
+ * and {@link WordColors.ofUnderline} here, since the three objects can't be told apart by shape; its `null` (for
36
+ * automatic) is `undefined`.
37
+ */
38
+ export const WordColors = {
39
+ /**
40
+ * The colour Word draws for a WordprocessingML colour's attributes.
41
+ *
42
+ * @param val the written value: RRGGBB, "auto", or undefined
43
+ * @param themeColor the theme reference, or undefined (or "none")
44
+ * @param themeTint a byte in hex ("99"), or undefined
45
+ * @param themeShade a byte in hex ("BF"), or undefined
46
+ * @returns undefined for automatic (no theme reference and val "auto" or absent): the caller's default
47
+ */
48
+ resolve(val, themeColor, themeTint, themeShade, theme) {
49
+ const written = ResolvedColor.ofHex(val);
50
+ if (themeColor === undefined || themeColor === null || themeColor === 'none' || theme === undefined)
51
+ return written;
52
+ // Word's value where it is a current cache: Word's own rounding, which the computation below matches for Word 365
53
+ // but not for every older version that wrote the file
54
+ const base = theme.wordThemeColor(themeColor);
55
+ if (base === undefined)
56
+ return written;
57
+ const tint = hexByte(themeTint), shade = hexByte(themeShade);
58
+ const computed = tint !== undefined ? WordColors.luminance(base, tint / 255.0, true)
59
+ : shade !== undefined ? WordColors.luminance(base, shade / 255.0, false) : base;
60
+ return written !== undefined && written.within(computed, 1) ? written : computed;
61
+ },
62
+ /**
63
+ * A colour value (`w:color/@w:val`, `w:u/@w:color`, `w:shd/@w:fill`, a border's `w:color`) as Word 365 reads it
64
+ * (docx4j CR-060 section 1, rule 3, and sections 12 and 13): surrounding whitespace trimmed, six hex digits in
65
+ * either case with an optional leading `#`; else a classic HTML colour name, in any case. The rule is the objects
66
+ * package's `wordColor` (its CR-013, held to docx4j's `WordColorValues`).
67
+ *
68
+ * @returns six upper-case hex digits; undefined for `auto` and for a value Word rejects, which Word reads as
69
+ * automatic in a fill or a border colour, and as absent in a text or underline colour ({@link WordColors.stated})
70
+ */
71
+ normalise(val) {
72
+ const w = typeof val === 'string' ? wordColor(val) : undefined;
73
+ return w === undefined || w === 'auto' ? undefined : w.substring(1);
74
+ },
75
+ /**
76
+ * Whether a `w:color/@w:val` or `w:u/@w:color` value states a colour, as Word reads it (docx4j CR-060 sections 12
77
+ * and 13): one {@link WordColors.normalise} accepts, or exactly `auto` (automatic, which overrides a style's
78
+ * colour). Word reads any other value (`F00`, `bogus`, `""`, `Auto`, `" auto"`) as absent: a style's colour beneath
79
+ * still shows. (In a fill or a border colour it reads such a value as automatic instead.)
80
+ */
81
+ stated(val) {
82
+ return typeof val === 'string' && wordColor(val) !== undefined;
83
+ },
84
+ /** A run's colour (`w:color`); undefined for automatic. */
85
+ of(c, theme) {
86
+ return c === undefined || c === null ? undefined
87
+ : WordColors.resolve(WordColors.normalise(c.val), c.themeColor, c.themeTint, c.themeShade, theme);
88
+ },
89
+ /** A shading's fill (`w:fill`, `w:themeFill`); undefined for automatic. */
90
+ fill(shd, theme) {
91
+ return shd === undefined || shd === null ? undefined
92
+ : WordColors.resolve(WordColors.normalise(shd.fill), shd.themeFill, shd.themeFillTint, shd.themeFillShade, theme);
93
+ },
94
+ /** A shading's pattern colour (`w:color`, `w:themeColor`); undefined for automatic. */
95
+ pattern(shd, theme) {
96
+ return shd === undefined || shd === null ? undefined
97
+ : WordColors.resolve(WordColors.normalise(shd.color), shd.themeColor, shd.themeTint, shd.themeShade, theme);
98
+ },
99
+ /** A border's colour; undefined for automatic. docx4j `of(CTBorder)`. */
100
+ ofBorder(border, theme) {
101
+ return border === undefined || border === null ? undefined
102
+ : WordColors.resolve(WordColors.normalise(border.color), border.themeColor, border.themeTint, border.themeShade, theme);
103
+ },
104
+ /** An underline's colour; undefined for automatic (the text's colour). docx4j `of(U)`. */
105
+ ofUnderline(u, theme) {
106
+ return u === undefined || u === null ? undefined
107
+ : WordColors.resolve(WordColors.normalise(u.color), u.themeColor, u.themeTint, u.themeShade, theme);
108
+ },
109
+ /**
110
+ * Word's themeTint (tint true) or themeShade on a colour: float HSL, the channels truncated. That is what Word 365
111
+ * draws (docx4j CR-034 section 11: the three P1 cases with no usable written value, all exact); the values older
112
+ * versions of Word wrote are within one unit of it (all 119 distinct ones in four corpora, 77 exact).
113
+ * Package-private in docx4j; public here for the corpus vectors' test.
114
+ */
115
+ luminance(c, t, tint) {
116
+ const hsl = ColorMath.rgbToHsl(c.red / 255.0, c.green / 255.0, c.blue / 255.0);
117
+ const l = tint ? hsl[2] * t + (1 - t) : hsl[2] * t;
118
+ const rgb = ColorMath.hslToRgb(hsl[0], hsl[1], ColorMath.clamp01(l));
119
+ return ResolvedColor.rgb(truncate(rgb[0]), truncate(rgb[1]), truncate(rgb[2]));
120
+ },
121
+ };
@@ -0,0 +1,6 @@
1
+ export { ResolvedColor } from './ResolvedColor.mjs';
2
+ export { ThemeColors } from './ThemeColors.mjs';
3
+ export { WordColors } from './WordColors.mjs';
4
+ export { DrawingMLColors } from './DrawingMLColors.mjs';
5
+ export { SpreadsheetColors } from './SpreadsheetColors.mjs';
6
+ export { StyleFill, type StyleFillKind } from './StyleFill.mjs';
@@ -0,0 +1,30 @@
1
+ // CR-008 phase 2: colours as Office draws them (docx4j `org.docx4j.model.color`, its CR-034): any colour reference in
2
+ // a docx, pptx or xlsx resolved to the RGB value (and alpha) Word, PowerPoint or Excel draws for it.
3
+ //
4
+ // A reference resolves against a {@link ThemeColors}: a theme's colour scheme and the colour map that leads to it,
5
+ // made for the reference's host by `await ThemeColors.of(pkg or part)` (a docx: the main document part's theme and
6
+ // the settings' `w:clrSchemeMapping`, which applies to WordprocessingML theme colours and DrawingML scheme colours
7
+ // alike, and is `PropertyResolver.getThemeColors()`; a slide, layout, master, notes slide, notes or handout master:
8
+ // its master's theme with the master's `p:clrMap`, then the layout's and the slide's `p:clrMapOvr`; an xlsx: the
9
+ // workbook's theme; a chart, `forChart` on its host's). A package with no theme part gets the theme Office supplies,
10
+ // the bundled one `pkg.fonts.defaultTheme` names (Office 2023's by default).
11
+ //
12
+ // - {@link WordColors}: `w:color`, `w:shd`, the borders and `w:u`. Word draws the theme reference and keeps the
13
+ // value beside it as a cache, which can be stale; `w:themeTint` and `w:themeShade` change the HSL luminance, the
14
+ // tint winning where both are given.
15
+ // - {@link DrawingMLColors}: the six DrawingML colour kinds and their transforms, applied in document order; a system
16
+ // colour is the machine's, not its `lastClr`. A shape's style references (`a:fillRef`, `a:lnRef`, `a:fontRef`)
17
+ // resolve through the theme's format scheme; an entry that is not a solid fill comes back as a {@link StyleFill} of
18
+ // its kind, not guessed at.
19
+ // - {@link SpreadsheetColors}: `rgb`, `theme` (whose first four indexes Excel reads as lt1, dk1, lt2, dk2),
20
+ // `indexed` (the legacy palette or the workbook's `x:indexedColors`) and `tint`, in Windows' integer HLS.
21
+ //
22
+ // Each returns a {@link ResolvedColor}, or undefined for "automatic", which is the caller's default. Every rule was
23
+ // read from Office's own renderings (docx4j CR-034 section 11); the probes, Office's readings and the corpus tint and
24
+ // shade triples are this package's vectors too (`test/theme-colors/`, CR-008 section 7).
25
+ export { ResolvedColor } from './ResolvedColor.mjs';
26
+ export { ThemeColors } from './ThemeColors.mjs';
27
+ export { WordColors } from './WordColors.mjs';
28
+ export { DrawingMLColors } from './DrawingMLColors.mjs';
29
+ export { SpreadsheetColors } from './SpreadsheetColors.mjs';
30
+ export { StyleFill } from './StyleFill.mjs';