@usejunior/docx-core 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/generation/recipes.d.ts +53 -12
- package/dist/generation/recipes.d.ts.map +1 -1
- package/dist/generation/recipes.js +132 -35
- package/dist/generation/recipes.js.map +1 -1
- package/dist/primitives/document.d.ts.map +1 -1
- package/dist/primitives/document.js +4 -198
- package/dist/primitives/document.js.map +1 -1
- package/dist/primitives/document_view-types.d.ts +13 -0
- package/dist/primitives/document_view-types.d.ts.map +1 -1
- package/dist/primitives/document_view.d.ts +48 -1
- package/dist/primitives/document_view.d.ts.map +1 -1
- package/dist/primitives/document_view.js +140 -20
- package/dist/primitives/document_view.js.map +1 -1
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +2 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/locator.d.ts +76 -0
- package/dist/primitives/locator.d.ts.map +1 -0
- package/dist/primitives/locator.js +223 -0
- package/dist/primitives/locator.js.map +1 -0
- package/dist/primitives/table_context.d.ts +19 -0
- package/dist/primitives/table_context.d.ts.map +1 -0
- package/dist/primitives/table_context.js +189 -0
- package/dist/primitives/table_context.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { DocumentViewNode } from './document_view-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic locator primitive over a `DocumentView`.
|
|
4
|
+
*
|
|
5
|
+
* A locator resolves a SINGLE span (raw-text offsets within one node) and never
|
|
6
|
+
* heals, scores, or guesses. Ambiguity — zero matches or more than one — is a
|
|
7
|
+
* drift signal reported as `unresolved`, so a caller updates the selector rather
|
|
8
|
+
* than silently filling the wrong place. Redundant `assertions` corroborate the
|
|
9
|
+
* `primary` match the moment an upstream change makes them disagree.
|
|
10
|
+
*
|
|
11
|
+
* Patterns are authored against the stable, normalized `clean_text`; resolved
|
|
12
|
+
* spans are returned as RAW offsets (`getParagraphText` / `replaceTextAtRange`
|
|
13
|
+
* coordinates) via {@link buildCleanToRawOffsetMap}.
|
|
14
|
+
*/
|
|
15
|
+
export type LocatorStep = {
|
|
16
|
+
kind: 'section';
|
|
17
|
+
/** Exact match against the node's derived heading text. */
|
|
18
|
+
headingText?: string;
|
|
19
|
+
/** Regex (un-anchored) tested against the node's derived heading text. */
|
|
20
|
+
headingRegex?: string;
|
|
21
|
+
/** Exact match against the paragraph's Word style id. */
|
|
22
|
+
headingStyleId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Outline level at which the region ends: the region runs from the matched
|
|
25
|
+
* heading until the next heading whose level is `<= untilLevel`. Defaults
|
|
26
|
+
* to the matched heading's own level (so the region ends at the next
|
|
27
|
+
* sibling-or-higher heading); when the matched heading has no level and no
|
|
28
|
+
* `untilLevel` is given, the region runs to the end of the current scope.
|
|
29
|
+
*/
|
|
30
|
+
untilLevel?: number;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'regex';
|
|
33
|
+
pattern: string;
|
|
34
|
+
flags?: string;
|
|
35
|
+
group?: number;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'contextual';
|
|
38
|
+
contextPattern: string;
|
|
39
|
+
targetPattern: string;
|
|
40
|
+
rowLabelPattern?: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'fingerprint';
|
|
43
|
+
contentFingerprint: string;
|
|
44
|
+
};
|
|
45
|
+
export interface Locator {
|
|
46
|
+
/** Ordered `section` steps narrowing to a region (Scrapy-style nesting). */
|
|
47
|
+
scope?: LocatorStep[];
|
|
48
|
+
/** The deterministic single-span resolver. Must be regex | contextual | fingerprint. */
|
|
49
|
+
primary: LocatorStep;
|
|
50
|
+
/** Corroborators that never select. Must be regex | contextual | fingerprint. */
|
|
51
|
+
assertions?: LocatorStep[];
|
|
52
|
+
}
|
|
53
|
+
export interface LocatorAssertionResult {
|
|
54
|
+
ok: boolean;
|
|
55
|
+
kind: string;
|
|
56
|
+
detail?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LocatorResolution {
|
|
59
|
+
/** RAW-offset span, or null when the primary did not resolve to exactly one span. */
|
|
60
|
+
match: {
|
|
61
|
+
nodeId: string;
|
|
62
|
+
start: number;
|
|
63
|
+
end: number;
|
|
64
|
+
} | null;
|
|
65
|
+
/** True when the primary matched zero or more than one span (a drift signal). */
|
|
66
|
+
unresolved: boolean;
|
|
67
|
+
/** Per-assertion corroboration results (empty when `unresolved`). */
|
|
68
|
+
assertionResults: LocatorAssertionResult[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a {@link Locator} against a document view. Deterministic: the same
|
|
72
|
+
* `(view, locator)` always yields the same result, with no randomness, scoring,
|
|
73
|
+
* or tie-breaking.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveLocator(view: DocumentViewNode[], locator: Locator): LocatorResolution;
|
|
76
|
+
//# sourceMappingURL=locator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.d.ts","sourceRoot":"","sources":["../../src/primitives/locator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAIjE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,wFAAwF;IACxF,OAAO,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7D,iFAAiF;IACjF,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;CAC5C;AAkND;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAe5F"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { buildCleanToRawOffsetMap } from './document_view.js';
|
|
2
|
+
import { computeContentFingerprint } from './content_fingerprint.js';
|
|
3
|
+
const SPAN_KINDS = new Set(['regex', 'contextual', 'fingerprint']);
|
|
4
|
+
/** Raw visible text of a node — the fingerprint basis and offset coordinate space. */
|
|
5
|
+
function rawTextOf(node) {
|
|
6
|
+
return node.raw_text ?? node.text;
|
|
7
|
+
}
|
|
8
|
+
function dedupeFlags(flags) {
|
|
9
|
+
return Array.from(new Set(flags.split(''))).join('');
|
|
10
|
+
}
|
|
11
|
+
function collectRegexSpans(nodes, pattern, flags, group) {
|
|
12
|
+
const needIndices = group > 0;
|
|
13
|
+
const reFlags = dedupeFlags(`${flags ?? ''}g${needIndices ? 'd' : ''}`);
|
|
14
|
+
const spans = [];
|
|
15
|
+
for (const node of nodes) {
|
|
16
|
+
const re = new RegExp(pattern, reFlags);
|
|
17
|
+
const text = node.clean_text;
|
|
18
|
+
let m;
|
|
19
|
+
while ((m = re.exec(text)) !== null) {
|
|
20
|
+
let cs;
|
|
21
|
+
let ce;
|
|
22
|
+
if (needIndices) {
|
|
23
|
+
const idx = m.indices?.[group];
|
|
24
|
+
if (!idx) {
|
|
25
|
+
if (m.index === re.lastIndex)
|
|
26
|
+
re.lastIndex++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
cs = idx[0];
|
|
30
|
+
ce = idx[1];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
cs = m.index;
|
|
34
|
+
ce = m.index + m[0].length;
|
|
35
|
+
}
|
|
36
|
+
spans.push({ node, nodeId: node.id, cleanStart: cs, cleanEnd: ce });
|
|
37
|
+
if (m.index === re.lastIndex)
|
|
38
|
+
re.lastIndex++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return spans;
|
|
42
|
+
}
|
|
43
|
+
function collectContextualSpans(nodes, step) {
|
|
44
|
+
const ctxRe = new RegExp(step.contextPattern);
|
|
45
|
+
const rowRe = step.rowLabelPattern ? new RegExp(step.rowLabelPattern) : null;
|
|
46
|
+
const spans = [];
|
|
47
|
+
for (const node of nodes) {
|
|
48
|
+
if (!ctxRe.test(node.clean_text))
|
|
49
|
+
continue;
|
|
50
|
+
if (rowRe && !rowRe.test(node.table_context?.col_header ?? ''))
|
|
51
|
+
continue;
|
|
52
|
+
const tre = new RegExp(step.targetPattern, 'g');
|
|
53
|
+
const text = node.clean_text;
|
|
54
|
+
let m;
|
|
55
|
+
while ((m = tre.exec(text)) !== null) {
|
|
56
|
+
spans.push({ node, nodeId: node.id, cleanStart: m.index, cleanEnd: m.index + m[0].length });
|
|
57
|
+
if (m.index === tre.lastIndex)
|
|
58
|
+
tre.lastIndex++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return spans;
|
|
62
|
+
}
|
|
63
|
+
function collectFingerprintNodes(nodes, fingerprint) {
|
|
64
|
+
return nodes.filter((n) => computeContentFingerprint(rawTextOf(n)) === fingerprint);
|
|
65
|
+
}
|
|
66
|
+
function headingMatches(node, step) {
|
|
67
|
+
let matched = false;
|
|
68
|
+
if (step.headingStyleId !== undefined) {
|
|
69
|
+
if (node.paragraph_style_id !== step.headingStyleId)
|
|
70
|
+
return false;
|
|
71
|
+
matched = true;
|
|
72
|
+
}
|
|
73
|
+
if (step.headingText !== undefined) {
|
|
74
|
+
if (node.heading?.text !== step.headingText)
|
|
75
|
+
return false;
|
|
76
|
+
matched = true;
|
|
77
|
+
}
|
|
78
|
+
if (step.headingRegex !== undefined) {
|
|
79
|
+
if (!new RegExp(step.headingRegex).test(node.heading?.text ?? ''))
|
|
80
|
+
return false;
|
|
81
|
+
matched = true;
|
|
82
|
+
}
|
|
83
|
+
return matched;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Narrow `nodes` to the region selected by one `section` step. Returns null when
|
|
87
|
+
* the heading does not match EXACTLY one node (zero or many → unresolved).
|
|
88
|
+
*/
|
|
89
|
+
function narrowToSection(nodes, step) {
|
|
90
|
+
const headingIdx = [];
|
|
91
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
92
|
+
if (headingMatches(nodes[i], step))
|
|
93
|
+
headingIdx.push(i);
|
|
94
|
+
}
|
|
95
|
+
if (headingIdx.length !== 1)
|
|
96
|
+
return null;
|
|
97
|
+
const start = headingIdx[0];
|
|
98
|
+
const startLevel = nodes[start].heading?.level ?? null;
|
|
99
|
+
const untilLevel = step.untilLevel ?? startLevel;
|
|
100
|
+
let end = nodes.length;
|
|
101
|
+
if (untilLevel !== null) {
|
|
102
|
+
for (let j = start + 1; j < nodes.length; j++) {
|
|
103
|
+
const lvl = nodes[j].heading?.level;
|
|
104
|
+
if (lvl != null && lvl <= untilLevel) {
|
|
105
|
+
end = j;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return nodes.slice(start, end);
|
|
111
|
+
}
|
|
112
|
+
function narrowScope(view, scope) {
|
|
113
|
+
let nodes = view;
|
|
114
|
+
for (const step of scope) {
|
|
115
|
+
if (step.kind !== 'section') {
|
|
116
|
+
throw new Error(`Locator scope steps must be 'section'; got '${step.kind}'`);
|
|
117
|
+
}
|
|
118
|
+
const narrowed = narrowToSection(nodes, step);
|
|
119
|
+
if (narrowed === null)
|
|
120
|
+
return null;
|
|
121
|
+
nodes = narrowed;
|
|
122
|
+
}
|
|
123
|
+
return nodes;
|
|
124
|
+
}
|
|
125
|
+
function resolvePrimary(nodes, step) {
|
|
126
|
+
if (step.kind === 'fingerprint') {
|
|
127
|
+
const hits = collectFingerprintNodes(nodes, step.contentFingerprint);
|
|
128
|
+
if (hits.length !== 1)
|
|
129
|
+
return null;
|
|
130
|
+
const node = hits[0];
|
|
131
|
+
return { nodeId: node.id, start: 0, end: rawTextOf(node).length };
|
|
132
|
+
}
|
|
133
|
+
let spans;
|
|
134
|
+
if (step.kind === 'regex') {
|
|
135
|
+
spans = collectRegexSpans(nodes, step.pattern, step.flags, step.group ?? 0);
|
|
136
|
+
}
|
|
137
|
+
else if (step.kind === 'contextual') {
|
|
138
|
+
spans = collectContextualSpans(nodes, step);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// 'section' is rejected by validateLocator before we get here.
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
if (spans.length !== 1)
|
|
145
|
+
return null;
|
|
146
|
+
const span = spans[0];
|
|
147
|
+
if (span.cleanEnd <= span.cleanStart)
|
|
148
|
+
return null; // zero-length match is invalid
|
|
149
|
+
const map = buildCleanToRawOffsetMap(span.node);
|
|
150
|
+
return { nodeId: span.nodeId, start: map[span.cleanStart], end: map[span.cleanEnd] };
|
|
151
|
+
}
|
|
152
|
+
function resolveAssertion(nodes, step, primary) {
|
|
153
|
+
if (step.kind === 'fingerprint') {
|
|
154
|
+
const hits = collectFingerprintNodes(nodes, step.contentFingerprint);
|
|
155
|
+
if (hits.length !== 1) {
|
|
156
|
+
return { ok: false, kind: 'fingerprint', detail: `expected exactly 1 node, found ${hits.length}` };
|
|
157
|
+
}
|
|
158
|
+
const ok = hits[0].id === primary.nodeId;
|
|
159
|
+
return { ok, kind: 'fingerprint', detail: ok ? undefined : `node ${hits[0].id} != primary node ${primary.nodeId}` };
|
|
160
|
+
}
|
|
161
|
+
let spans;
|
|
162
|
+
if (step.kind === 'regex') {
|
|
163
|
+
spans = collectRegexSpans(nodes, step.pattern, step.flags, step.group ?? 0);
|
|
164
|
+
}
|
|
165
|
+
else if (step.kind === 'contextual') {
|
|
166
|
+
spans = collectContextualSpans(nodes, step);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
return { ok: false, kind: step.kind, detail: "'section' is not a valid assertion kind" };
|
|
170
|
+
}
|
|
171
|
+
if (spans.length !== 1) {
|
|
172
|
+
return { ok: false, kind: step.kind, detail: `expected exactly 1 span, found ${spans.length}` };
|
|
173
|
+
}
|
|
174
|
+
const span = spans[0];
|
|
175
|
+
if (span.cleanEnd <= span.cleanStart) {
|
|
176
|
+
return { ok: false, kind: step.kind, detail: 'zero-length match' };
|
|
177
|
+
}
|
|
178
|
+
const map = buildCleanToRawOffsetMap(span.node);
|
|
179
|
+
const start = map[span.cleanStart];
|
|
180
|
+
const end = map[span.cleanEnd];
|
|
181
|
+
const ok = span.nodeId === primary.nodeId && start === primary.start && end === primary.end;
|
|
182
|
+
return {
|
|
183
|
+
ok,
|
|
184
|
+
kind: step.kind,
|
|
185
|
+
detail: ok
|
|
186
|
+
? undefined
|
|
187
|
+
: `span {${span.nodeId},${start},${end}} != primary {${primary.nodeId},${primary.start},${primary.end}}`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function validateLocator(locator) {
|
|
191
|
+
if (!SPAN_KINDS.has(locator.primary.kind)) {
|
|
192
|
+
throw new Error(`Locator primary must be regex | contextual | fingerprint; got '${locator.primary.kind}'`);
|
|
193
|
+
}
|
|
194
|
+
for (const a of locator.assertions ?? []) {
|
|
195
|
+
if (!SPAN_KINDS.has(a.kind)) {
|
|
196
|
+
throw new Error(`Locator assertion must be regex | contextual | fingerprint; got '${a.kind}'`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
for (const s of locator.scope ?? []) {
|
|
200
|
+
if (s.kind !== 'section') {
|
|
201
|
+
throw new Error(`Locator scope steps must be 'section'; got '${s.kind}'`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Resolve a {@link Locator} against a document view. Deterministic: the same
|
|
207
|
+
* `(view, locator)` always yields the same result, with no randomness, scoring,
|
|
208
|
+
* or tie-breaking.
|
|
209
|
+
*/
|
|
210
|
+
export function resolveLocator(view, locator) {
|
|
211
|
+
validateLocator(locator);
|
|
212
|
+
const scoped = locator.scope && locator.scope.length > 0 ? narrowScope(view, locator.scope) : view;
|
|
213
|
+
if (scoped === null) {
|
|
214
|
+
return { match: null, unresolved: true, assertionResults: [] };
|
|
215
|
+
}
|
|
216
|
+
const match = resolvePrimary(scoped, locator.primary);
|
|
217
|
+
if (match === null) {
|
|
218
|
+
return { match: null, unresolved: true, assertionResults: [] };
|
|
219
|
+
}
|
|
220
|
+
const assertionResults = (locator.assertions ?? []).map((a) => resolveAssertion(scoped, a, match));
|
|
221
|
+
return { match, unresolved: false, assertionResults };
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.js","sourceRoot":"","sources":["../../src/primitives/locator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TableContext } from './document_view-types.js';
|
|
2
|
+
export type TableMeta = {
|
|
3
|
+
tableIndex: number;
|
|
4
|
+
tableId: string;
|
|
5
|
+
rows: Element[];
|
|
6
|
+
headers: string[];
|
|
7
|
+
totalCols: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Build metadata map for body-level tables.
|
|
11
|
+
* Only indexes direct w:tbl children of w:body (consistent with extractTables).
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildTableMetaMap(body: Element): Map<Element, TableMeta>;
|
|
14
|
+
/**
|
|
15
|
+
* Derive table context for a paragraph by walking up the DOM.
|
|
16
|
+
* Returns undefined if the paragraph is not inside a body-level table.
|
|
17
|
+
*/
|
|
18
|
+
export declare function deriveTableContext(p: Element, tableMetaMap: Map<Element, TableMeta>): TableContext | undefined;
|
|
19
|
+
//# sourceMappingURL=table_context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table_context.d.ts","sourceRoot":"","sources":["../../src/primitives/table_context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQ7D,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAyEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CA2CxE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,YAAY,GAAG,SAAS,CA8D9G"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { OOXML, W } from './namespaces.js';
|
|
2
|
+
import { isW, getDirectChildrenByName } from './dom-helpers.js';
|
|
3
|
+
import { getParagraphText } from './text.js';
|
|
4
|
+
/**
|
|
5
|
+
* Collect all w:tr descendants of a table element, descending through
|
|
6
|
+
* w:ins/w:del/w:sdt wrappers but not into nested w:tbl elements.
|
|
7
|
+
*/
|
|
8
|
+
function collectTableRows(tbl) {
|
|
9
|
+
const rows = [];
|
|
10
|
+
function walk(parent) {
|
|
11
|
+
for (let i = 0; i < parent.childNodes.length; i++) {
|
|
12
|
+
const child = parent.childNodes[i];
|
|
13
|
+
if (child.nodeType !== 1)
|
|
14
|
+
continue;
|
|
15
|
+
const el = child;
|
|
16
|
+
if (isW(el, W.tr)) {
|
|
17
|
+
rows.push(el);
|
|
18
|
+
}
|
|
19
|
+
else if (!isW(el, W.tbl)) {
|
|
20
|
+
walk(el);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
walk(tbl);
|
|
25
|
+
return rows;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Collect all w:tc descendants of a row element, descending through
|
|
29
|
+
* w:ins/w:del/w:sdt wrappers but not into nested w:tr or w:tbl elements.
|
|
30
|
+
*/
|
|
31
|
+
function collectRowCells(tr) {
|
|
32
|
+
const cells = [];
|
|
33
|
+
function walk(parent) {
|
|
34
|
+
for (let i = 0; i < parent.childNodes.length; i++) {
|
|
35
|
+
const child = parent.childNodes[i];
|
|
36
|
+
if (child.nodeType !== 1)
|
|
37
|
+
continue;
|
|
38
|
+
const el = child;
|
|
39
|
+
if (isW(el, W.tc)) {
|
|
40
|
+
cells.push(el);
|
|
41
|
+
}
|
|
42
|
+
else if (!isW(el, W.tr) && !isW(el, W.tbl)) {
|
|
43
|
+
walk(el);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
walk(tr);
|
|
48
|
+
return cells;
|
|
49
|
+
}
|
|
50
|
+
/** Get the gridSpan value for a table cell (default 1). */
|
|
51
|
+
function getCellGridSpan(tc) {
|
|
52
|
+
const tcPrList = getDirectChildrenByName(tc, W.tcPr);
|
|
53
|
+
if (tcPrList.length === 0)
|
|
54
|
+
return 1;
|
|
55
|
+
const gridSpanEls = getDirectChildrenByName(tcPrList[0], 'gridSpan');
|
|
56
|
+
if (gridSpanEls.length === 0)
|
|
57
|
+
return 1;
|
|
58
|
+
const val = gridSpanEls[0].getAttributeNS(OOXML.W_NS, W.val) ??
|
|
59
|
+
gridSpanEls[0].getAttribute('w:val') ??
|
|
60
|
+
gridSpanEls[0].getAttribute(W.val);
|
|
61
|
+
if (!val)
|
|
62
|
+
return 1;
|
|
63
|
+
const n = parseInt(val, 10);
|
|
64
|
+
return n > 0 ? n : 1;
|
|
65
|
+
}
|
|
66
|
+
/** Get visible text from a cell's direct paragraphs (excludes nested tables). */
|
|
67
|
+
function getCellHeaderText(tc) {
|
|
68
|
+
const parts = [];
|
|
69
|
+
for (let i = 0; i < tc.childNodes.length; i++) {
|
|
70
|
+
const child = tc.childNodes[i];
|
|
71
|
+
if (child.nodeType === 1 && isW(child, W.p)) {
|
|
72
|
+
parts.push(getParagraphText(child).trim());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return parts.join(' ').trim();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build metadata map for body-level tables.
|
|
79
|
+
* Only indexes direct w:tbl children of w:body (consistent with extractTables).
|
|
80
|
+
*/
|
|
81
|
+
export function buildTableMetaMap(body) {
|
|
82
|
+
const map = new Map();
|
|
83
|
+
const tables = getDirectChildrenByName(body, W.tbl);
|
|
84
|
+
for (let tableIndex = 0; tableIndex < tables.length; tableIndex++) {
|
|
85
|
+
const tbl = tables[tableIndex];
|
|
86
|
+
const rows = collectTableRows(tbl);
|
|
87
|
+
if (rows.length === 0)
|
|
88
|
+
continue;
|
|
89
|
+
// Compute max grid columns across all rows
|
|
90
|
+
let maxGridCols = 0;
|
|
91
|
+
for (const row of rows) {
|
|
92
|
+
const cells = collectRowCells(row);
|
|
93
|
+
let gridCols = 0;
|
|
94
|
+
for (const cell of cells) {
|
|
95
|
+
gridCols += getCellGridSpan(cell);
|
|
96
|
+
}
|
|
97
|
+
if (gridCols > maxGridCols)
|
|
98
|
+
maxGridCols = gridCols;
|
|
99
|
+
}
|
|
100
|
+
// Extract headers from row 0
|
|
101
|
+
const headerRow = rows[0];
|
|
102
|
+
const headerCells = collectRowCells(headerRow);
|
|
103
|
+
const headers = [];
|
|
104
|
+
for (const cell of headerCells) {
|
|
105
|
+
const span = getCellGridSpan(cell);
|
|
106
|
+
const text = getCellHeaderText(cell);
|
|
107
|
+
headers.push(text);
|
|
108
|
+
for (let s = 1; s < span; s++)
|
|
109
|
+
headers.push('');
|
|
110
|
+
}
|
|
111
|
+
while (headers.length < maxGridCols)
|
|
112
|
+
headers.push('');
|
|
113
|
+
if (headers.length > maxGridCols)
|
|
114
|
+
headers.length = maxGridCols;
|
|
115
|
+
map.set(tbl, {
|
|
116
|
+
tableIndex,
|
|
117
|
+
tableId: `_tbl_${tableIndex}`,
|
|
118
|
+
rows,
|
|
119
|
+
headers,
|
|
120
|
+
totalCols: maxGridCols,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return map;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Derive table context for a paragraph by walking up the DOM.
|
|
127
|
+
* Returns undefined if the paragraph is not inside a body-level table.
|
|
128
|
+
*/
|
|
129
|
+
export function deriveTableContext(p, tableMetaMap) {
|
|
130
|
+
let tc = null;
|
|
131
|
+
let tr = null;
|
|
132
|
+
let tbl = null;
|
|
133
|
+
let current = p.parentNode;
|
|
134
|
+
while (current && current.nodeType === 1) {
|
|
135
|
+
const el = current;
|
|
136
|
+
if (isW(el, W.body))
|
|
137
|
+
break;
|
|
138
|
+
if (isW(el, W.tc))
|
|
139
|
+
tc = el;
|
|
140
|
+
if (isW(el, W.tr))
|
|
141
|
+
tr = el;
|
|
142
|
+
if (isW(el, W.tbl)) {
|
|
143
|
+
if (tableMetaMap.has(el)) {
|
|
144
|
+
tbl = el;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
// Nested table: reset tc/tr, keep walking to find body-level table
|
|
148
|
+
tc = null;
|
|
149
|
+
tr = null;
|
|
150
|
+
}
|
|
151
|
+
current = el.parentNode;
|
|
152
|
+
}
|
|
153
|
+
if (!tbl || !tr || !tc)
|
|
154
|
+
return undefined;
|
|
155
|
+
const meta = tableMetaMap.get(tbl);
|
|
156
|
+
// Compute row_index
|
|
157
|
+
const rowIndex = meta.rows.indexOf(tr);
|
|
158
|
+
if (rowIndex < 0)
|
|
159
|
+
return undefined;
|
|
160
|
+
// Compute grid-aware col_index by summing gridSpan for preceding cells
|
|
161
|
+
const rowCells = collectRowCells(tr);
|
|
162
|
+
let gridCol = 0;
|
|
163
|
+
let cellFound = false;
|
|
164
|
+
for (const cell of rowCells) {
|
|
165
|
+
if (cell === tc) {
|
|
166
|
+
cellFound = true;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
gridCol += getCellGridSpan(cell);
|
|
170
|
+
}
|
|
171
|
+
if (!cellFound)
|
|
172
|
+
return undefined;
|
|
173
|
+
// Compute para_in_cell and cell_para_count
|
|
174
|
+
const allCellPs = Array.from(tc.getElementsByTagNameNS(OOXML.W_NS, W.p));
|
|
175
|
+
const paraInCell = allCellPs.indexOf(p);
|
|
176
|
+
return {
|
|
177
|
+
table_id: meta.tableId,
|
|
178
|
+
table_index: meta.tableIndex,
|
|
179
|
+
row_index: rowIndex,
|
|
180
|
+
col_index: gridCol,
|
|
181
|
+
col_header: meta.headers[gridCol] ?? '',
|
|
182
|
+
total_rows: meta.rows.length,
|
|
183
|
+
total_cols: meta.totalCols,
|
|
184
|
+
is_header_row: rowIndex === 0,
|
|
185
|
+
para_in_cell: paraInCell >= 0 ? paraInCell : 0,
|
|
186
|
+
cell_para_count: allCellPs.length,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=table_context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table_context.js","sourceRoot":"","sources":["../../src/primitives/table_context.ts"],"names":[],"mappings":"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"}
|