reamkit 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/esm/bidi/algorithm.d.ts +9 -0
- package/dist/esm/bidi/algorithm.js +458 -0
- package/dist/esm/bidi/char-types.d.ts +2 -0
- package/dist/esm/bidi/char-types.js +439 -0
- package/dist/esm/bidi/index.d.ts +14 -0
- package/dist/esm/bidi/index.js +25 -0
- package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
- package/dist/esm/converter/docx-to-pdf.js +227 -0
- package/dist/esm/converter/index.d.ts +4 -0
- package/dist/esm/converter/index.js +2 -0
- package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
- package/dist/esm/converter/xlsx-to-pdf.js +515 -0
- package/dist/esm/crypto/asn1.d.ts +23 -0
- package/dist/esm/crypto/asn1.js +123 -0
- package/dist/esm/crypto/cms.d.ts +9 -0
- package/dist/esm/crypto/cms.js +34 -0
- package/dist/esm/crypto/index.d.ts +2 -0
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/document-model/index.d.ts +1 -0
- package/dist/esm/document-model/index.js +0 -0
- package/dist/esm/document-model/types.d.ts +403 -0
- package/dist/esm/font/arabic-joining.d.ts +4 -0
- package/dist/esm/font/arabic-joining.js +97 -0
- package/dist/esm/font/binary-reader.d.ts +13 -0
- package/dist/esm/font/binary-reader.js +44 -0
- package/dist/esm/font/font-registry.d.ts +19 -0
- package/dist/esm/font/font-registry.js +39 -0
- package/dist/esm/font/index.d.ts +7 -0
- package/dist/esm/font/opentype-layout.d.ts +21 -0
- package/dist/esm/font/opentype-layout.js +329 -0
- package/dist/esm/font/ttf-parser.d.ts +29 -0
- package/dist/esm/font/ttf-parser.js +290 -0
- package/dist/esm/font/ttf-subset.d.ts +3 -0
- package/dist/esm/font/ttf-subset.js +201 -0
- package/dist/esm/fonts/index.d.ts +2 -0
- package/dist/esm/fonts/remote-fonts.d.ts +13 -0
- package/dist/esm/fonts/remote-fonts.js +94 -0
- package/dist/esm/hyphenation/index.d.ts +10 -0
- package/dist/esm/hyphenation/index.js +38 -0
- package/dist/esm/hyphenation/liang.d.ts +10 -0
- package/dist/esm/hyphenation/liang.js +79 -0
- package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-en-us.js +5 -0
- package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-ru.js +5 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/line-breaker/index.d.ts +2 -0
- package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
- package/dist/esm/line-breaker/knuth-plass.js +172 -0
- package/dist/esm/numbering/index.d.ts +1 -0
- package/dist/esm/numbering/state.d.ts +6 -0
- package/dist/esm/numbering/state.js +83 -0
- package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
- package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
- package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
- package/dist/esm/ooxml/drawingml/colors.js +125 -0
- package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
- package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
- package/dist/esm/ooxml/index.d.ts +1 -0
- package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
- package/dist/esm/ooxml/math/omml-parser.js +217 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
- package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
- package/dist/esm/ooxml/spreadsheet/index.js +7 -0
- package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
- package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
- package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
- package/dist/esm/ooxml/wordproc/font-table.js +82 -0
- package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
- package/dist/esm/ooxml/wordproc/index.js +9 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
- package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
- package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
- package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
- package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
- package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
- package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
- package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
- package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
- package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
- package/dist/esm/opc/core-properties.d.ts +11 -0
- package/dist/esm/opc/core-properties.js +51 -0
- package/dist/esm/opc/index.d.ts +5 -0
- package/dist/esm/opc/index.js +3 -0
- package/dist/esm/opc/package.d.ts +26 -0
- package/dist/esm/opc/package.js +113 -0
- package/dist/esm/opc/relationship-types.d.ts +3 -0
- package/dist/esm/opc/relationship-types.js +4 -0
- package/dist/esm/opc/relationships.d.ts +7 -0
- package/dist/esm/opc/relationships.js +28 -0
- package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
- package/dist/esm/pdf/arc-to-bezier.js +58 -0
- package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
- package/dist/esm/pdf/chart-geometry.d.ts +64 -0
- package/dist/esm/pdf/chart-geometry.js +674 -0
- package/dist/esm/pdf/cid-font.d.ts +15 -0
- package/dist/esm/pdf/cid-font.js +174 -0
- package/dist/esm/pdf/embedded-file.d.ts +11 -0
- package/dist/esm/pdf/embedded-file.js +23 -0
- package/dist/esm/pdf/icc-profile.d.ts +1 -0
- package/dist/esm/pdf/icc-profile.js +166 -0
- package/dist/esm/pdf/image-xobject.d.ts +13 -0
- package/dist/esm/pdf/image-xobject.js +335 -0
- package/dist/esm/pdf/index.d.ts +11 -0
- package/dist/esm/pdf/index.js +5 -0
- package/dist/esm/pdf/math-layout.d.ts +45 -0
- package/dist/esm/pdf/math-layout.js +1138 -0
- package/dist/esm/pdf/objects.d.ts +32 -0
- package/dist/esm/pdf/objects.js +54 -0
- package/dist/esm/pdf/preset-geometry.d.ts +6 -0
- package/dist/esm/pdf/preset-geometry.js +199 -0
- package/dist/esm/pdf/serialize.d.ts +3 -0
- package/dist/esm/pdf/serialize.js +54 -0
- package/dist/esm/pdf/signature.d.ts +25 -0
- package/dist/esm/pdf/signature.js +126 -0
- package/dist/esm/pdf/struct-tree.d.ts +31 -0
- package/dist/esm/pdf/struct-tree.js +109 -0
- package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
- package/dist/esm/pdf/styled-page-renderer.js +2317 -0
- package/dist/esm/pdf/text-encoding.d.ts +2 -0
- package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
- package/dist/esm/pdf/text-page-renderer.js +4 -0
- package/dist/esm/pdf/vector-graphics.d.ts +46 -0
- package/dist/esm/pdf/vector-graphics.js +103 -0
- package/dist/esm/pdf/writer.d.ts +10 -0
- package/dist/esm/pdf/writer.js +81 -0
- package/dist/esm/pdf/xmp.d.ts +13 -0
- package/dist/esm/pdf/xmp.js +38 -0
- package/dist/esm/style-cascade/index.d.ts +3 -0
- package/dist/esm/style-cascade/resolver.d.ts +4 -0
- package/dist/esm/style-cascade/resolver.js +96 -0
- package/dist/esm/style-cascade/types.d.ts +29 -0
- package/dist/esm/style-cascade/types.js +26 -0
- package/package.json +90 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
//#region src/line-breaker/knuth-plass.ts
|
|
2
|
+
var FORCED_BREAK = -1e4;
|
|
3
|
+
var FORBIDDEN_BREAK = 1e4;
|
|
4
|
+
var LINE_PENALTY = 10;
|
|
5
|
+
var FITNESS_PENALTY = 100;
|
|
6
|
+
var FLAGGED_PENALTY = 100;
|
|
7
|
+
var TOLERANCE_RATIO = 4;
|
|
8
|
+
var MAX_ACTIVE_NODES = 200;
|
|
9
|
+
var FIT_VERY_TIGHT = 0;
|
|
10
|
+
var FIT_TIGHT = 1;
|
|
11
|
+
var FIT_LOOSE = 2;
|
|
12
|
+
var FIT_VERY_LOOSE = 3;
|
|
13
|
+
function fitnessClass(r) {
|
|
14
|
+
if (r < -.5) return FIT_VERY_TIGHT;
|
|
15
|
+
if (r <= .5) return FIT_TIGHT;
|
|
16
|
+
if (r <= 1) return FIT_LOOSE;
|
|
17
|
+
return FIT_VERY_LOOSE;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Break a paragraph into lines using the Knuth-Plass total-fit algorithm.
|
|
21
|
+
*
|
|
22
|
+
* `lineWidths`: either a number (uniform width) or an array indexed by line
|
|
23
|
+
* (0-based). When the array is shorter than the paragraph the last entry is
|
|
24
|
+
* reused for trailing lines — this matches the common case of "first line
|
|
25
|
+
* different, rest the same".
|
|
26
|
+
*/
|
|
27
|
+
function breakLines(items, lineWidths) {
|
|
28
|
+
if (items.length === 0) return {
|
|
29
|
+
breaks: [],
|
|
30
|
+
ratios: []
|
|
31
|
+
};
|
|
32
|
+
const widthFor = (line) => {
|
|
33
|
+
if (typeof lineWidths === "number") return lineWidths;
|
|
34
|
+
if (line < lineWidths.length) return lineWidths[line];
|
|
35
|
+
return lineWidths[lineWidths.length - 1];
|
|
36
|
+
};
|
|
37
|
+
const startNode = {
|
|
38
|
+
itemIndex: -1,
|
|
39
|
+
line: 0,
|
|
40
|
+
fitness: FIT_TIGHT,
|
|
41
|
+
totalWidth: 0,
|
|
42
|
+
totalStretch: 0,
|
|
43
|
+
totalShrink: 0,
|
|
44
|
+
totalDemerits: 0,
|
|
45
|
+
previous: null
|
|
46
|
+
};
|
|
47
|
+
let active = [startNode];
|
|
48
|
+
const isFeasibleBreakpoint = (i) => {
|
|
49
|
+
const item = items[i];
|
|
50
|
+
if (item.type === "penalty" && item.penalty < FORBIDDEN_BREAK) return true;
|
|
51
|
+
if (item.type === "glue") {
|
|
52
|
+
const prev = items[i - 1];
|
|
53
|
+
return !!prev && prev.type === "box";
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
const widthBeforeItem = new Array(items.length + 1);
|
|
58
|
+
const stretchBeforeItem = new Array(items.length + 1);
|
|
59
|
+
const shrinkBeforeItem = new Array(items.length + 1);
|
|
60
|
+
widthBeforeItem[0] = 0;
|
|
61
|
+
stretchBeforeItem[0] = 0;
|
|
62
|
+
shrinkBeforeItem[0] = 0;
|
|
63
|
+
for (let i = 0; i < items.length; i++) {
|
|
64
|
+
const it = items[i];
|
|
65
|
+
const addW = it.type === "penalty" ? 0 : it.width;
|
|
66
|
+
const addSt = it.type === "glue" ? it.stretch : 0;
|
|
67
|
+
const addSh = it.type === "glue" ? it.shrink : 0;
|
|
68
|
+
widthBeforeItem[i + 1] = widthBeforeItem[i] + addW;
|
|
69
|
+
stretchBeforeItem[i + 1] = stretchBeforeItem[i] + addSt;
|
|
70
|
+
shrinkBeforeItem[i + 1] = shrinkBeforeItem[i] + addSh;
|
|
71
|
+
}
|
|
72
|
+
const measureLine = (a, b) => {
|
|
73
|
+
const startIdx = a.itemIndex + 1;
|
|
74
|
+
let width = widthBeforeItem[b] - widthBeforeItem[startIdx];
|
|
75
|
+
const stretch = stretchBeforeItem[b] - stretchBeforeItem[startIdx];
|
|
76
|
+
const shrink = shrinkBeforeItem[b] - shrinkBeforeItem[startIdx];
|
|
77
|
+
const item = items[b];
|
|
78
|
+
if (item.type === "penalty") width += item.width;
|
|
79
|
+
return {
|
|
80
|
+
width,
|
|
81
|
+
stretch,
|
|
82
|
+
shrink
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const computeRatio = (line, target) => {
|
|
86
|
+
if (line.width < target) return line.stretch > 0 ? (target - line.width) / line.stretch : Infinity;
|
|
87
|
+
if (line.width > target) return line.shrink > 0 ? (target - line.width) / line.shrink : -Infinity;
|
|
88
|
+
return 0;
|
|
89
|
+
};
|
|
90
|
+
const lineDemerits = (r, penaltyAtBreak, lastItemPenalty) => {
|
|
91
|
+
const badness = 100 * Math.pow(Math.abs(r), 3);
|
|
92
|
+
let d;
|
|
93
|
+
if (penaltyAtBreak >= 0 && penaltyAtBreak < FORBIDDEN_BREAK) d = Math.pow(LINE_PENALTY + badness + penaltyAtBreak, 2);
|
|
94
|
+
else if (penaltyAtBreak > FORCED_BREAK && penaltyAtBreak < 0) d = Math.pow(LINE_PENALTY + badness, 2) - penaltyAtBreak * penaltyAtBreak;
|
|
95
|
+
else d = Math.pow(LINE_PENALTY + badness, 2);
|
|
96
|
+
return d;
|
|
97
|
+
};
|
|
98
|
+
for (let i = 0; i < items.length; i++) {
|
|
99
|
+
if (!isFeasibleBreakpoint(i)) continue;
|
|
100
|
+
const item = items[i];
|
|
101
|
+
const penaltyAtBreak = item.type === "penalty" ? item.penalty : 0;
|
|
102
|
+
const survivingActive = [];
|
|
103
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const a of active) {
|
|
105
|
+
const target = widthFor(a.line);
|
|
106
|
+
const r = computeRatio(measureLine(a, i), target);
|
|
107
|
+
const isForced = penaltyAtBreak <= FORCED_BREAK;
|
|
108
|
+
if (r < -1 && !isForced) continue;
|
|
109
|
+
if (!isForced) survivingActive.push(a);
|
|
110
|
+
const effectiveR = r < -1 ? -1 : isForced && r > TOLERANCE_RATIO ? TOLERANCE_RATIO : r;
|
|
111
|
+
const fc = fitnessClass(effectiveR);
|
|
112
|
+
let demerits = lineDemerits(effectiveR, penaltyAtBreak, null);
|
|
113
|
+
if (Math.abs(fc - a.fitness) > 1) demerits += FITNESS_PENALTY;
|
|
114
|
+
if (item.type === "penalty" && item.flagged) {
|
|
115
|
+
const prevItem = a.itemIndex >= 0 ? items[a.itemIndex] : null;
|
|
116
|
+
if (prevItem && prevItem.type === "penalty" && prevItem.flagged) demerits += FLAGGED_PENALTY;
|
|
117
|
+
}
|
|
118
|
+
demerits += a.totalDemerits;
|
|
119
|
+
const key = `${a.line + 1}:${fc}`;
|
|
120
|
+
const existing = candidates.get(key);
|
|
121
|
+
if (!existing || demerits < existing.totalDemerits) candidates.set(key, {
|
|
122
|
+
itemIndex: i,
|
|
123
|
+
line: a.line + 1,
|
|
124
|
+
fitness: fc,
|
|
125
|
+
totalWidth: widthBeforeItem[i + 1],
|
|
126
|
+
totalStretch: stretchBeforeItem[i + 1],
|
|
127
|
+
totalShrink: shrinkBeforeItem[i + 1],
|
|
128
|
+
totalDemerits: demerits,
|
|
129
|
+
previous: a
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
active = survivingActive;
|
|
133
|
+
for (const c of candidates.values()) active.push(c);
|
|
134
|
+
if (active.length === 0) active = [{
|
|
135
|
+
itemIndex: i,
|
|
136
|
+
line: 1,
|
|
137
|
+
fitness: FIT_TIGHT,
|
|
138
|
+
totalWidth: widthBeforeItem[i + 1],
|
|
139
|
+
totalStretch: stretchBeforeItem[i + 1],
|
|
140
|
+
totalShrink: shrinkBeforeItem[i + 1],
|
|
141
|
+
totalDemerits: 0,
|
|
142
|
+
previous: startNode
|
|
143
|
+
}];
|
|
144
|
+
else if (active.length > MAX_ACTIVE_NODES) {
|
|
145
|
+
active.sort((p, q) => p.totalDemerits - q.totalDemerits);
|
|
146
|
+
active.length = MAX_ACTIVE_NODES;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
let best = null;
|
|
150
|
+
for (const a of active) if (!best || a.totalDemerits < best.totalDemerits) best = a;
|
|
151
|
+
if (!best) return {
|
|
152
|
+
breaks: [],
|
|
153
|
+
ratios: []
|
|
154
|
+
};
|
|
155
|
+
const breaks = [];
|
|
156
|
+
const ratios = [];
|
|
157
|
+
let node = best;
|
|
158
|
+
while (node.previous) {
|
|
159
|
+
breaks.unshift(node.itemIndex);
|
|
160
|
+
const prev = node.previous;
|
|
161
|
+
const target = widthFor(prev.line);
|
|
162
|
+
const r = computeRatio(measureLine(prev, node.itemIndex), target);
|
|
163
|
+
ratios.unshift(r < -1 ? -1 : r);
|
|
164
|
+
node = prev;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
breaks,
|
|
168
|
+
ratios
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
export { breakLines };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NumberingState, formatLevelMarker } from './state.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AbstractNumbering, Numbering, NumberingLevel, NumberingReference } from '../document-model/index.js';
|
|
2
|
+
export declare class NumberingState {
|
|
3
|
+
private readonly counters;
|
|
4
|
+
resolveMarker(numbering: Numbering, ref: NumberingReference): string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function formatLevelMarker(abstractNum: AbstractNumbering, currentLevel: NumberingLevel, counters: ReadonlyArray<number>): string;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//#region src/numbering/state.ts
|
|
2
|
+
var NumberingState = class {
|
|
3
|
+
counters = /* @__PURE__ */ new Map();
|
|
4
|
+
resolveMarker(numbering, ref) {
|
|
5
|
+
const instance = numbering.numInstances.get(ref.numId);
|
|
6
|
+
if (!instance) return null;
|
|
7
|
+
const abstractNum = numbering.abstractNums.get(instance.abstractNumId);
|
|
8
|
+
if (!abstractNum) return null;
|
|
9
|
+
const level = abstractNum.levels.get(ref.ilvl);
|
|
10
|
+
if (!level) return null;
|
|
11
|
+
let arr = this.counters.get(ref.numId);
|
|
12
|
+
if (!arr) {
|
|
13
|
+
arr = new Array(9).fill(0);
|
|
14
|
+
this.counters.set(ref.numId, arr);
|
|
15
|
+
}
|
|
16
|
+
for (let k = ref.ilvl + 1; k < arr.length; k++) arr[k] = 0;
|
|
17
|
+
if (arr[ref.ilvl] === 0) arr[ref.ilvl] = level.start;
|
|
18
|
+
else arr[ref.ilvl] += 1;
|
|
19
|
+
return formatLevelMarker(abstractNum, level, arr);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function formatLevelMarker(abstractNum, currentLevel, counters) {
|
|
23
|
+
if (currentLevel.format === "bullet") return normalizeBullet(currentLevel.lvlText);
|
|
24
|
+
return currentLevel.lvlText.replace(/%(\d)/g, (_match, n) => {
|
|
25
|
+
const lvlIdx = Number(n) - 1;
|
|
26
|
+
const level = abstractNum.levels.get(lvlIdx);
|
|
27
|
+
const counter = counters[lvlIdx] ?? 0;
|
|
28
|
+
return formatCounter(level?.format ?? "decimal", counter);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function formatCounter(format, n) {
|
|
32
|
+
if (n <= 0) return "";
|
|
33
|
+
switch (format) {
|
|
34
|
+
case "decimal": return String(n);
|
|
35
|
+
case "lowerLetter": return toLetters(n).toLowerCase();
|
|
36
|
+
case "upperLetter": return toLetters(n);
|
|
37
|
+
case "lowerRoman": return toRoman(n).toLowerCase();
|
|
38
|
+
case "upperRoman": return toRoman(n);
|
|
39
|
+
default: return "";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function toLetters(n) {
|
|
43
|
+
let s = "";
|
|
44
|
+
let v = n;
|
|
45
|
+
while (v > 0) {
|
|
46
|
+
v--;
|
|
47
|
+
s = String.fromCharCode(65 + v % 26) + s;
|
|
48
|
+
v = Math.floor(v / 26);
|
|
49
|
+
}
|
|
50
|
+
return s;
|
|
51
|
+
}
|
|
52
|
+
function toRoman(n) {
|
|
53
|
+
const map = [
|
|
54
|
+
[1e3, "M"],
|
|
55
|
+
[900, "CM"],
|
|
56
|
+
[500, "D"],
|
|
57
|
+
[400, "CD"],
|
|
58
|
+
[100, "C"],
|
|
59
|
+
[90, "XC"],
|
|
60
|
+
[50, "L"],
|
|
61
|
+
[40, "XL"],
|
|
62
|
+
[10, "X"],
|
|
63
|
+
[9, "IX"],
|
|
64
|
+
[5, "V"],
|
|
65
|
+
[4, "IV"],
|
|
66
|
+
[1, "I"]
|
|
67
|
+
];
|
|
68
|
+
let s = "";
|
|
69
|
+
let v = n;
|
|
70
|
+
for (const [value, ch] of map) while (v >= value) {
|
|
71
|
+
s += ch;
|
|
72
|
+
v -= value;
|
|
73
|
+
}
|
|
74
|
+
return s;
|
|
75
|
+
}
|
|
76
|
+
function normalizeBullet(lvlText) {
|
|
77
|
+
if (lvlText.length === 0) return "•";
|
|
78
|
+
const cp = lvlText.codePointAt(0);
|
|
79
|
+
if (cp >= 57344 && cp <= 63743) return "•";
|
|
80
|
+
return lvlText;
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { NumberingState };
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { poAttr, poChildren, poFindByPath, poFindDescendant, poIntAttr, poIs, poTag, poText, poVal } from "../wordproc/po-helpers.js";
|
|
2
|
+
import { XMLParser } from "fast-xml-parser";
|
|
3
|
+
//#region src/ooxml/drawingml/chart-parser.ts
|
|
4
|
+
var decoder = new TextDecoder("utf-8");
|
|
5
|
+
var parser = new XMLParser({
|
|
6
|
+
ignoreAttributes: false,
|
|
7
|
+
attributeNamePrefix: "@_",
|
|
8
|
+
preserveOrder: true,
|
|
9
|
+
parseAttributeValue: false,
|
|
10
|
+
parseTagValue: false,
|
|
11
|
+
trimValues: false
|
|
12
|
+
});
|
|
13
|
+
var TYPE_OF_TAG = {
|
|
14
|
+
"c:barChart": "bar",
|
|
15
|
+
"c:bar3DChart": "bar",
|
|
16
|
+
"c:lineChart": "line",
|
|
17
|
+
"c:line3DChart": "line",
|
|
18
|
+
"c:pieChart": "pie",
|
|
19
|
+
"c:pie3DChart": "pie",
|
|
20
|
+
"c:doughnutChart": "pie",
|
|
21
|
+
"c:areaChart": "area",
|
|
22
|
+
"c:area3DChart": "area",
|
|
23
|
+
"c:scatterChart": "scatter"
|
|
24
|
+
};
|
|
25
|
+
function parseChart(chartXml, resolveColor) {
|
|
26
|
+
const chart = poFindByPath(parser.parse(decoder.decode(chartXml)), ["c:chartSpace", "c:chart"]);
|
|
27
|
+
if (!chart) return null;
|
|
28
|
+
const plotArea = poChildren(chart).find((c) => poIs(c, "c:plotArea"));
|
|
29
|
+
if (!plotArea) return null;
|
|
30
|
+
const group = poChildren(plotArea).find((c) => (poTag(c) ?? "") in TYPE_OF_TAG);
|
|
31
|
+
const type = group ? TYPE_OF_TAG[poTag(group)] ?? "unknown" : "unknown";
|
|
32
|
+
const serNodes = group ? poChildren(group).filter((c) => poIs(c, "c:ser")) : [];
|
|
33
|
+
const series = serNodes.map((s) => parseSeries(s, resolveColor));
|
|
34
|
+
let categories = [];
|
|
35
|
+
for (const s of serNodes) {
|
|
36
|
+
const cat = poChildren(s).find((c) => poIs(c, "c:cat"));
|
|
37
|
+
if (cat) {
|
|
38
|
+
categories = denseStrings(cat);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const barDir = group ? poVal(poChildren(group).find((c) => poIs(c, "c:barDir"))) : void 0;
|
|
43
|
+
const grouping = group ? poVal(poChildren(group).find((c) => poIs(c, "c:grouping"))) : void 0;
|
|
44
|
+
const doughnut = group ? poIs(group, "c:doughnutChart") : false;
|
|
45
|
+
const showValues = group ? chartShowsValues(group) : false;
|
|
46
|
+
const catAxisTitle = axisTitle(plotArea, "c:catAx");
|
|
47
|
+
const valAxisTitle = axisTitle(plotArea, "c:valAx");
|
|
48
|
+
const legend = poChildren(chart).find((c) => poIs(c, "c:legend"));
|
|
49
|
+
const legendPos = legend ? poVal(poChildren(legend).find((c) => poIs(c, "c:legendPos"))) : void 0;
|
|
50
|
+
const title = chartTitle(chart);
|
|
51
|
+
return {
|
|
52
|
+
type,
|
|
53
|
+
...title ? { title } : {},
|
|
54
|
+
categories,
|
|
55
|
+
series,
|
|
56
|
+
hasLegend: legend !== void 0,
|
|
57
|
+
...isLegendPos(legendPos) ? { legendPos } : {},
|
|
58
|
+
...barDir === "col" || barDir === "bar" ? { barDir } : {},
|
|
59
|
+
...isGrouping(grouping) ? { grouping } : {},
|
|
60
|
+
...doughnut ? { doughnut: true } : {},
|
|
61
|
+
...showValues ? { showValues: true } : {},
|
|
62
|
+
...catAxisTitle ? { catAxisTitle } : {},
|
|
63
|
+
...valAxisTitle ? { valAxisTitle } : {}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function parseSeries(ser, resolveColor) {
|
|
67
|
+
const valNode = poChildren(ser).find((c) => poIs(c, "c:val")) ?? poChildren(ser).find((c) => poIs(c, "c:yVal"));
|
|
68
|
+
const values = valNode ? denseNumbers(valNode) : [];
|
|
69
|
+
const xValNode = poChildren(ser).find((c) => poIs(c, "c:xVal"));
|
|
70
|
+
const xValues = xValNode ? denseNumbers(xValNode) : void 0;
|
|
71
|
+
const name = seriesName(ser);
|
|
72
|
+
const colorHex = fillColorOf(poChildren(ser).find((c) => poIs(c, "c:spPr")), resolveColor);
|
|
73
|
+
const pointColors = dataPointColors(ser, resolveColor);
|
|
74
|
+
return {
|
|
75
|
+
values,
|
|
76
|
+
...xValues && xValues.length > 0 ? { xValues } : {},
|
|
77
|
+
...name ? { name } : {},
|
|
78
|
+
...colorHex ? { colorHex } : {},
|
|
79
|
+
...pointColors.length > 0 ? { pointColors } : {}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function seriesName(ser) {
|
|
83
|
+
const tx = poChildren(ser).find((c) => poIs(c, "c:tx"));
|
|
84
|
+
if (!tx) return void 0;
|
|
85
|
+
const direct = poChildren(tx).find((c) => poIs(c, "c:v"));
|
|
86
|
+
if (direct) return poText(direct) || void 0;
|
|
87
|
+
return readPts(tx)[0]?.v || void 0;
|
|
88
|
+
}
|
|
89
|
+
function dataPointColors(ser, resolveColor) {
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const dPt of poChildren(ser)) {
|
|
92
|
+
if (!poIs(dPt, "c:dPt")) continue;
|
|
93
|
+
const idxNode = poChildren(dPt).find((c) => poIs(c, "c:idx"));
|
|
94
|
+
const idx = idxNode ? poIntAttr(idxNode, "val") ?? 0 : 0;
|
|
95
|
+
const colorHex = fillColorOf(poChildren(dPt).find((c) => poIs(c, "c:spPr")), resolveColor);
|
|
96
|
+
if (colorHex) out.push({
|
|
97
|
+
idx,
|
|
98
|
+
colorHex
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
function fillColorOf(spPr, resolveColor) {
|
|
104
|
+
if (!spPr) return void 0;
|
|
105
|
+
const directFill = poChildren(spPr).find((c) => poIs(c, "a:solidFill"));
|
|
106
|
+
const fromFill = directFill ? colorFromSolidFill(directFill, resolveColor) : void 0;
|
|
107
|
+
if (fromFill) return fromFill;
|
|
108
|
+
const ln = poChildren(spPr).find((c) => poIs(c, "a:ln"));
|
|
109
|
+
const lnFill = ln ? poChildren(ln).find((c) => poIs(c, "a:solidFill")) : void 0;
|
|
110
|
+
return lnFill ? colorFromSolidFill(lnFill, resolveColor) : void 0;
|
|
111
|
+
}
|
|
112
|
+
function colorMods(colorNode) {
|
|
113
|
+
const mods = [];
|
|
114
|
+
for (const c of poChildren(colorNode)) for (const kind of [
|
|
115
|
+
"lumMod",
|
|
116
|
+
"lumOff",
|
|
117
|
+
"shade",
|
|
118
|
+
"tint",
|
|
119
|
+
"alpha"
|
|
120
|
+
]) if (poIs(c, `a:${kind}`)) {
|
|
121
|
+
const v = poIntAttr(c, "val");
|
|
122
|
+
if (v !== void 0) mods.push({
|
|
123
|
+
kind,
|
|
124
|
+
val: v / 1e5
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return mods;
|
|
128
|
+
}
|
|
129
|
+
function colorFromSolidFill(solid, resolveColor) {
|
|
130
|
+
for (const c of poChildren(solid)) {
|
|
131
|
+
const isSrgb = poIs(c, "a:srgbClr");
|
|
132
|
+
if (!isSrgb && !poIs(c, "a:schemeClr")) continue;
|
|
133
|
+
const v = poAttr(c, "val");
|
|
134
|
+
if (!v) continue;
|
|
135
|
+
const mods = colorMods(c);
|
|
136
|
+
const raw = isSrgb ? { srgb: v } : { scheme: v };
|
|
137
|
+
return resolveColor(mods.length > 0 ? {
|
|
138
|
+
...raw,
|
|
139
|
+
mods
|
|
140
|
+
} : raw);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function collectAT(node) {
|
|
144
|
+
let text = "";
|
|
145
|
+
const walk = (n) => {
|
|
146
|
+
for (const c of poChildren(n)) if (poIs(c, "a:t")) text += poText(c);
|
|
147
|
+
else walk(c);
|
|
148
|
+
};
|
|
149
|
+
walk(node);
|
|
150
|
+
return text;
|
|
151
|
+
}
|
|
152
|
+
function chartTitle(chart) {
|
|
153
|
+
const title = poChildren(chart).find((c) => poIs(c, "c:title"));
|
|
154
|
+
return title ? collectAT(title) || void 0 : void 0;
|
|
155
|
+
}
|
|
156
|
+
function axisTitle(plotArea, axTag) {
|
|
157
|
+
const ax = poChildren(plotArea).find((c) => poIs(c, axTag));
|
|
158
|
+
const title = ax ? poChildren(ax).find((c) => poIs(c, "c:title")) : void 0;
|
|
159
|
+
return title ? collectAT(title) || void 0 : void 0;
|
|
160
|
+
}
|
|
161
|
+
function dLblsShowVal(dLbls) {
|
|
162
|
+
if (!dLbls) return false;
|
|
163
|
+
const v = poVal(poChildren(dLbls).find((c) => poIs(c, "c:showVal")));
|
|
164
|
+
return v === "1" || v === "true";
|
|
165
|
+
}
|
|
166
|
+
function chartShowsValues(group) {
|
|
167
|
+
if (dLblsShowVal(poChildren(group).find((c) => poIs(c, "c:dLbls")))) return true;
|
|
168
|
+
for (const ser of poChildren(group)) if (poIs(ser, "c:ser") && dLblsShowVal(poChildren(ser).find((c) => poIs(c, "c:dLbls")))) return true;
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
function readPts(container) {
|
|
172
|
+
const cache = poFindDescendant(container, "c:numCache") ?? poFindDescendant(container, "c:strCache");
|
|
173
|
+
if (!cache) return [];
|
|
174
|
+
const out = [];
|
|
175
|
+
for (const pt of poChildren(cache)) {
|
|
176
|
+
if (!poIs(pt, "c:pt")) continue;
|
|
177
|
+
const idx = poIntAttr(pt, "idx") ?? 0;
|
|
178
|
+
const vNode = poChildren(pt).find((c) => poIs(c, "c:v"));
|
|
179
|
+
out.push({
|
|
180
|
+
idx,
|
|
181
|
+
v: vNode ? poText(vNode) : ""
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
function ptCountOf(container) {
|
|
187
|
+
const cache = poFindDescendant(container, "c:numCache") ?? poFindDescendant(container, "c:strCache");
|
|
188
|
+
const pc = cache ? poChildren(cache).find((c) => poIs(c, "c:ptCount")) : void 0;
|
|
189
|
+
return pc ? poIntAttr(pc, "val") ?? 0 : 0;
|
|
190
|
+
}
|
|
191
|
+
function denseLength(container, pts) {
|
|
192
|
+
let max = ptCountOf(container);
|
|
193
|
+
for (const p of pts) max = Math.max(max, p.idx + 1);
|
|
194
|
+
return max;
|
|
195
|
+
}
|
|
196
|
+
function denseNumbers(container) {
|
|
197
|
+
const pts = readPts(container);
|
|
198
|
+
const arr = new Array(denseLength(container, pts)).fill(0);
|
|
199
|
+
for (const p of pts) {
|
|
200
|
+
const n = Number(p.v);
|
|
201
|
+
if (Number.isFinite(n)) arr[p.idx] = n;
|
|
202
|
+
}
|
|
203
|
+
return arr;
|
|
204
|
+
}
|
|
205
|
+
function denseStrings(container) {
|
|
206
|
+
const pts = readPts(container);
|
|
207
|
+
const arr = new Array(denseLength(container, pts)).fill("");
|
|
208
|
+
for (const p of pts) arr[p.idx] = p.v;
|
|
209
|
+
return arr;
|
|
210
|
+
}
|
|
211
|
+
function isLegendPos(v) {
|
|
212
|
+
return v === "r" || v === "l" || v === "t" || v === "b";
|
|
213
|
+
}
|
|
214
|
+
function isGrouping(v) {
|
|
215
|
+
return v === "clustered" || v === "stacked" || v === "percentStacked" || v === "standard";
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
export { parseChart };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ColorMod {
|
|
2
|
+
readonly kind: 'lumMod' | 'lumOff' | 'shade' | 'tint' | 'alpha';
|
|
3
|
+
readonly val: number;
|
|
4
|
+
}
|
|
5
|
+
export type RawColor = {
|
|
6
|
+
readonly srgb: string;
|
|
7
|
+
readonly mods?: ReadonlyArray<ColorMod>;
|
|
8
|
+
} | {
|
|
9
|
+
readonly scheme: string;
|
|
10
|
+
readonly mods?: ReadonlyArray<ColorMod>;
|
|
11
|
+
};
|
|
12
|
+
export type ColorResolver = (raw: RawColor) => string | undefined;
|
|
13
|
+
export declare function applyColorMods(hex: string, mods: ReadonlyArray<ColorMod>): string;
|
|
14
|
+
export declare const DEFAULT_THEME_PALETTE: ReadonlyMap<string, string>;
|
|
15
|
+
export declare function resolveSchemeName(name: string): string;
|
|
16
|
+
export declare function makeColorResolver(palette: ReadonlyMap<string, string>): ColorResolver;
|
|
17
|
+
export declare const defaultColorResolver: ColorResolver;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//#region src/ooxml/drawingml/colors.ts
|
|
2
|
+
function clamp01(x) {
|
|
3
|
+
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
4
|
+
}
|
|
5
|
+
function rgbToHsl(r, g, b) {
|
|
6
|
+
const max = Math.max(r, g, b);
|
|
7
|
+
const min = Math.min(r, g, b);
|
|
8
|
+
const l = (max + min) / 2;
|
|
9
|
+
const d = max - min;
|
|
10
|
+
if (d === 0) return [
|
|
11
|
+
0,
|
|
12
|
+
0,
|
|
13
|
+
l
|
|
14
|
+
];
|
|
15
|
+
const s = d / (1 - Math.abs(2 * l - 1));
|
|
16
|
+
let h;
|
|
17
|
+
if (max === r) h = (g - b) / d % 6;
|
|
18
|
+
else if (max === g) h = (b - r) / d + 2;
|
|
19
|
+
else h = (r - g) / d + 4;
|
|
20
|
+
h *= 60;
|
|
21
|
+
if (h < 0) h += 360;
|
|
22
|
+
return [
|
|
23
|
+
h,
|
|
24
|
+
s,
|
|
25
|
+
l
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
function hslToRgb(h, s, l) {
|
|
29
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
30
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
31
|
+
const m = l - c / 2;
|
|
32
|
+
let r = 0;
|
|
33
|
+
let g = 0;
|
|
34
|
+
let b = 0;
|
|
35
|
+
if (h < 60) [r, g, b] = [
|
|
36
|
+
c,
|
|
37
|
+
x,
|
|
38
|
+
0
|
|
39
|
+
];
|
|
40
|
+
else if (h < 120) [r, g, b] = [
|
|
41
|
+
x,
|
|
42
|
+
c,
|
|
43
|
+
0
|
|
44
|
+
];
|
|
45
|
+
else if (h < 180) [r, g, b] = [
|
|
46
|
+
0,
|
|
47
|
+
c,
|
|
48
|
+
x
|
|
49
|
+
];
|
|
50
|
+
else if (h < 240) [r, g, b] = [
|
|
51
|
+
0,
|
|
52
|
+
x,
|
|
53
|
+
c
|
|
54
|
+
];
|
|
55
|
+
else if (h < 300) [r, g, b] = [
|
|
56
|
+
x,
|
|
57
|
+
0,
|
|
58
|
+
c
|
|
59
|
+
];
|
|
60
|
+
else [r, g, b] = [
|
|
61
|
+
c,
|
|
62
|
+
0,
|
|
63
|
+
x
|
|
64
|
+
];
|
|
65
|
+
return [
|
|
66
|
+
r + m,
|
|
67
|
+
g + m,
|
|
68
|
+
b + m
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
function applyColorMods(hex, mods) {
|
|
72
|
+
if (mods.length === 0) return hex;
|
|
73
|
+
const n = parseInt(hex, 16);
|
|
74
|
+
let r = (n >> 16 & 255) / 255;
|
|
75
|
+
let g = (n >> 8 & 255) / 255;
|
|
76
|
+
let b = (n & 255) / 255;
|
|
77
|
+
for (const m of mods) if (m.kind === "shade") {
|
|
78
|
+
r *= m.val;
|
|
79
|
+
g *= m.val;
|
|
80
|
+
b *= m.val;
|
|
81
|
+
} else if (m.kind === "tint") {
|
|
82
|
+
r = r * m.val + (1 - m.val);
|
|
83
|
+
g = g * m.val + (1 - m.val);
|
|
84
|
+
b = b * m.val + (1 - m.val);
|
|
85
|
+
} else if (m.kind === "lumMod" || m.kind === "lumOff") {
|
|
86
|
+
const [h, s, l] = rgbToHsl(r, g, b);
|
|
87
|
+
const l2 = m.kind === "lumMod" ? l * m.val : clamp01(l + m.val);
|
|
88
|
+
[r, g, b] = hslToRgb(h, s, l2);
|
|
89
|
+
}
|
|
90
|
+
const toHex = (x) => Math.round(clamp01(x) * 255).toString(16).padStart(2, "0");
|
|
91
|
+
return (toHex(r) + toHex(g) + toHex(b)).toUpperCase();
|
|
92
|
+
}
|
|
93
|
+
var DEFAULT_THEME_PALETTE = new Map([
|
|
94
|
+
["dk1", "000000"],
|
|
95
|
+
["lt1", "FFFFFF"],
|
|
96
|
+
["dk2", "44546A"],
|
|
97
|
+
["lt2", "E7E6E6"],
|
|
98
|
+
["accent1", "4472C4"],
|
|
99
|
+
["accent2", "ED7D31"],
|
|
100
|
+
["accent3", "A5A5A5"],
|
|
101
|
+
["accent4", "FFC000"],
|
|
102
|
+
["accent5", "5B9BD5"],
|
|
103
|
+
["accent6", "70AD47"],
|
|
104
|
+
["hlink", "0563C1"],
|
|
105
|
+
["folHlink", "954F72"]
|
|
106
|
+
]);
|
|
107
|
+
var SCHEME_ALIAS = {
|
|
108
|
+
tx1: "dk1",
|
|
109
|
+
bg1: "lt1",
|
|
110
|
+
tx2: "dk2",
|
|
111
|
+
bg2: "lt2"
|
|
112
|
+
};
|
|
113
|
+
function resolveSchemeName(name) {
|
|
114
|
+
return SCHEME_ALIAS[name] ?? name;
|
|
115
|
+
}
|
|
116
|
+
function makeColorResolver(palette) {
|
|
117
|
+
return (raw) => {
|
|
118
|
+
const base = "srgb" in raw ? raw.srgb.toUpperCase() : palette.get(resolveSchemeName(raw.scheme));
|
|
119
|
+
if (base === void 0) return void 0;
|
|
120
|
+
return raw.mods && raw.mods.length > 0 ? applyColorMods(base, raw.mods) : base;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
var defaultColorResolver = makeColorResolver(DEFAULT_THEME_PALETTE);
|
|
124
|
+
//#endregion
|
|
125
|
+
export { DEFAULT_THEME_PALETTE, defaultColorResolver, makeColorResolver };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseTheme(themeXml: Uint8Array): Map<string, string>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { poAttr, poChildren, poFindByPath, poIs, poTag } from "../wordproc/po-helpers.js";
|
|
2
|
+
import { XMLParser } from "fast-xml-parser";
|
|
3
|
+
//#region src/ooxml/drawingml/theme-parser.ts
|
|
4
|
+
var decoder = new TextDecoder("utf-8");
|
|
5
|
+
var parser = new XMLParser({
|
|
6
|
+
ignoreAttributes: false,
|
|
7
|
+
attributeNamePrefix: "@_",
|
|
8
|
+
preserveOrder: true,
|
|
9
|
+
parseAttributeValue: false,
|
|
10
|
+
parseTagValue: false,
|
|
11
|
+
trimValues: false
|
|
12
|
+
});
|
|
13
|
+
var SCHEME_SLOTS = new Set([
|
|
14
|
+
"dk1",
|
|
15
|
+
"lt1",
|
|
16
|
+
"dk2",
|
|
17
|
+
"lt2",
|
|
18
|
+
"accent1",
|
|
19
|
+
"accent2",
|
|
20
|
+
"accent3",
|
|
21
|
+
"accent4",
|
|
22
|
+
"accent5",
|
|
23
|
+
"accent6",
|
|
24
|
+
"hlink",
|
|
25
|
+
"folHlink"
|
|
26
|
+
]);
|
|
27
|
+
function parseTheme(themeXml) {
|
|
28
|
+
const out = /* @__PURE__ */ new Map();
|
|
29
|
+
const clrScheme = poFindByPath(parser.parse(decoder.decode(themeXml)), [
|
|
30
|
+
"a:theme",
|
|
31
|
+
"a:themeElements",
|
|
32
|
+
"a:clrScheme"
|
|
33
|
+
]);
|
|
34
|
+
if (!clrScheme) return out;
|
|
35
|
+
for (const slot of poChildren(clrScheme)) {
|
|
36
|
+
const tag = poTag(slot);
|
|
37
|
+
if (!tag || !tag.startsWith("a:")) continue;
|
|
38
|
+
const name = tag.slice(2);
|
|
39
|
+
if (!SCHEME_SLOTS.has(name)) continue;
|
|
40
|
+
const hex = colorOf(slot);
|
|
41
|
+
if (hex) out.set(name, hex);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
function colorOf(slot) {
|
|
46
|
+
for (const c of poChildren(slot)) if (poIs(c, "a:srgbClr")) {
|
|
47
|
+
const v = poAttr(c, "val");
|
|
48
|
+
if (v) return v.toUpperCase();
|
|
49
|
+
} else if (poIs(c, "a:sysClr")) {
|
|
50
|
+
const v = poAttr(c, "lastClr");
|
|
51
|
+
if (v) return v.toUpperCase();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { parseTheme };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as wordproc from './wordproc/index.js';
|