docxmlater 2.3.0 → 2.4.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/core/Document.d.ts +2 -0
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +6 -4
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +2 -2
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +430 -270
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +2 -2
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +39 -39
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts +4 -4
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +50 -47
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/package.json +1 -1
|
@@ -128,7 +128,9 @@ class DocumentParser {
|
|
|
128
128
|
else if (next.type === "tbl") {
|
|
129
129
|
const elementXml = this.extractSingleElement(bodyContent, "w:tbl", next.pos);
|
|
130
130
|
if (elementXml) {
|
|
131
|
-
const parsed = XMLParser_1.XMLParser.parseToObject(elementXml, {
|
|
131
|
+
const parsed = XMLParser_1.XMLParser.parseToObject(elementXml, {
|
|
132
|
+
trimValues: false,
|
|
133
|
+
});
|
|
132
134
|
const table = await this.parseTableFromObject(parsed["w:tbl"], relationshipManager, zipHandler, imageManager);
|
|
133
135
|
if (table)
|
|
134
136
|
bodyElements.push(table);
|
|
@@ -141,7 +143,9 @@ class DocumentParser {
|
|
|
141
143
|
else if (next.type === "sdt") {
|
|
142
144
|
const elementXml = this.extractSingleElement(bodyContent, "w:sdt", next.pos);
|
|
143
145
|
if (elementXml) {
|
|
144
|
-
const parsed = XMLParser_1.XMLParser.parseToObject(elementXml, {
|
|
146
|
+
const parsed = XMLParser_1.XMLParser.parseToObject(elementXml, {
|
|
147
|
+
trimValues: false,
|
|
148
|
+
});
|
|
145
149
|
const sdt = await this.parseSDTFromObject(parsed["w:sdt"], relationshipManager, zipHandler, imageManager);
|
|
146
150
|
if (sdt)
|
|
147
151
|
bodyElements.push(sdt);
|
|
@@ -270,7 +274,7 @@ class DocumentParser {
|
|
|
270
274
|
const elementIndex = childInfo.index;
|
|
271
275
|
if (elementType === "w:r") {
|
|
272
276
|
const runs = pElement["w:r"];
|
|
273
|
-
const runArray = Array.isArray(runs) ? runs :
|
|
277
|
+
const runArray = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
274
278
|
if (elementIndex < runArray.length) {
|
|
275
279
|
const child = runArray[elementIndex];
|
|
276
280
|
if (child["w:drawing"]) {
|
|
@@ -291,7 +295,11 @@ class DocumentParser {
|
|
|
291
295
|
}
|
|
292
296
|
else if (elementType === "w:hyperlink") {
|
|
293
297
|
const hyperlinks = pElement["w:hyperlink"];
|
|
294
|
-
const hyperlinkArray = Array.isArray(hyperlinks)
|
|
298
|
+
const hyperlinkArray = Array.isArray(hyperlinks)
|
|
299
|
+
? hyperlinks
|
|
300
|
+
: hyperlinks
|
|
301
|
+
? [hyperlinks]
|
|
302
|
+
: [];
|
|
295
303
|
if (elementIndex < hyperlinkArray.length) {
|
|
296
304
|
const hyperlink = this.parseHyperlinkFromObject(hyperlinkArray[elementIndex], relationshipManager);
|
|
297
305
|
if (hyperlink) {
|
|
@@ -301,7 +309,11 @@ class DocumentParser {
|
|
|
301
309
|
}
|
|
302
310
|
else if (elementType === "w:fldSimple") {
|
|
303
311
|
const fields = pElement["w:fldSimple"];
|
|
304
|
-
const fieldArray = Array.isArray(fields)
|
|
312
|
+
const fieldArray = Array.isArray(fields)
|
|
313
|
+
? fields
|
|
314
|
+
: fields
|
|
315
|
+
? [fields]
|
|
316
|
+
: [];
|
|
305
317
|
if (elementIndex < fieldArray.length) {
|
|
306
318
|
const field = this.parseSimpleFieldFromObject(fieldArray[elementIndex]);
|
|
307
319
|
if (field) {
|
|
@@ -313,7 +325,7 @@ class DocumentParser {
|
|
|
313
325
|
}
|
|
314
326
|
else {
|
|
315
327
|
const runs = pElement["w:r"];
|
|
316
|
-
const runChildren = Array.isArray(runs) ? runs :
|
|
328
|
+
const runChildren = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
317
329
|
for (const child of runChildren) {
|
|
318
330
|
if (child["w:drawing"]) {
|
|
319
331
|
if (zipHandler && imageManager) {
|
|
@@ -331,7 +343,11 @@ class DocumentParser {
|
|
|
331
343
|
}
|
|
332
344
|
}
|
|
333
345
|
const hyperlinks = pElement["w:hyperlink"];
|
|
334
|
-
const hyperlinkChildren = Array.isArray(hyperlinks)
|
|
346
|
+
const hyperlinkChildren = Array.isArray(hyperlinks)
|
|
347
|
+
? hyperlinks
|
|
348
|
+
: hyperlinks
|
|
349
|
+
? [hyperlinks]
|
|
350
|
+
: [];
|
|
335
351
|
for (const hyperlinkObj of hyperlinkChildren) {
|
|
336
352
|
const hyperlink = this.parseHyperlinkFromObject(hyperlinkObj, relationshipManager);
|
|
337
353
|
if (hyperlink) {
|
|
@@ -339,7 +355,11 @@ class DocumentParser {
|
|
|
339
355
|
}
|
|
340
356
|
}
|
|
341
357
|
const fields = pElement["w:fldSimple"];
|
|
342
|
-
const fieldChildren = Array.isArray(fields)
|
|
358
|
+
const fieldChildren = Array.isArray(fields)
|
|
359
|
+
? fields
|
|
360
|
+
: fields
|
|
361
|
+
? [fields]
|
|
362
|
+
: [];
|
|
343
363
|
for (const fieldObj of fieldChildren) {
|
|
344
364
|
const field = this.parseSimpleFieldFromObject(fieldObj);
|
|
345
365
|
if (field) {
|
|
@@ -349,12 +369,12 @@ class DocumentParser {
|
|
|
349
369
|
}
|
|
350
370
|
this.assembleComplexFields(paragraph);
|
|
351
371
|
const runs = paragraph.getRuns();
|
|
352
|
-
const runData = runs.map(run => ({
|
|
372
|
+
const runData = runs.map((run) => ({
|
|
353
373
|
text: run.getText(),
|
|
354
374
|
rtl: run.getFormatting().rtl,
|
|
355
375
|
}));
|
|
356
376
|
const bidi = paragraph.getFormatting().bidi;
|
|
357
|
-
(0, diagnostics_1.logParagraphContent)(
|
|
377
|
+
(0, diagnostics_1.logParagraphContent)("parsing", -1, runData, bidi);
|
|
358
378
|
if (bidi) {
|
|
359
379
|
(0, diagnostics_1.logTextDirection)(`Paragraph has BiDi enabled`);
|
|
360
380
|
}
|
|
@@ -385,7 +405,7 @@ class DocumentParser {
|
|
|
385
405
|
const elementIndex = childInfo.index;
|
|
386
406
|
if (elementType === "w:r") {
|
|
387
407
|
const runs = paraObj["w:r"];
|
|
388
|
-
const runArray = Array.isArray(runs) ? runs :
|
|
408
|
+
const runArray = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
389
409
|
if (elementIndex < runArray.length) {
|
|
390
410
|
const child = runArray[elementIndex];
|
|
391
411
|
if (child["w:drawing"]) {
|
|
@@ -406,7 +426,11 @@ class DocumentParser {
|
|
|
406
426
|
}
|
|
407
427
|
else if (elementType === "w:hyperlink") {
|
|
408
428
|
const hyperlinks = paraObj["w:hyperlink"];
|
|
409
|
-
const hyperlinkArray = Array.isArray(hyperlinks)
|
|
429
|
+
const hyperlinkArray = Array.isArray(hyperlinks)
|
|
430
|
+
? hyperlinks
|
|
431
|
+
: hyperlinks
|
|
432
|
+
? [hyperlinks]
|
|
433
|
+
: [];
|
|
410
434
|
if (elementIndex < hyperlinkArray.length) {
|
|
411
435
|
const hyperlink = this.parseHyperlinkFromObject(hyperlinkArray[elementIndex], relationshipManager);
|
|
412
436
|
if (hyperlink) {
|
|
@@ -416,7 +440,11 @@ class DocumentParser {
|
|
|
416
440
|
}
|
|
417
441
|
else if (elementType === "w:fldSimple") {
|
|
418
442
|
const fields = paraObj["w:fldSimple"];
|
|
419
|
-
const fieldArray = Array.isArray(fields)
|
|
443
|
+
const fieldArray = Array.isArray(fields)
|
|
444
|
+
? fields
|
|
445
|
+
: fields
|
|
446
|
+
? [fields]
|
|
447
|
+
: [];
|
|
420
448
|
if (elementIndex < fieldArray.length) {
|
|
421
449
|
const field = this.parseSimpleFieldFromObject(fieldArray[elementIndex]);
|
|
422
450
|
if (field) {
|
|
@@ -428,7 +456,7 @@ class DocumentParser {
|
|
|
428
456
|
}
|
|
429
457
|
else {
|
|
430
458
|
const runs = paraObj["w:r"];
|
|
431
|
-
const runChildren = Array.isArray(runs) ? runs :
|
|
459
|
+
const runChildren = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
432
460
|
for (const child of runChildren) {
|
|
433
461
|
if (child["w:drawing"]) {
|
|
434
462
|
if (zipHandler && imageManager) {
|
|
@@ -446,7 +474,11 @@ class DocumentParser {
|
|
|
446
474
|
}
|
|
447
475
|
}
|
|
448
476
|
const hyperlinks = paraObj["w:hyperlink"];
|
|
449
|
-
const hyperlinkChildren = Array.isArray(hyperlinks)
|
|
477
|
+
const hyperlinkChildren = Array.isArray(hyperlinks)
|
|
478
|
+
? hyperlinks
|
|
479
|
+
: hyperlinks
|
|
480
|
+
? [hyperlinks]
|
|
481
|
+
: [];
|
|
450
482
|
for (const hyperlinkObj of hyperlinkChildren) {
|
|
451
483
|
const hyperlink = this.parseHyperlinkFromObject(hyperlinkObj, relationshipManager);
|
|
452
484
|
if (hyperlink) {
|
|
@@ -454,7 +486,11 @@ class DocumentParser {
|
|
|
454
486
|
}
|
|
455
487
|
}
|
|
456
488
|
const fields = paraObj["w:fldSimple"];
|
|
457
|
-
const fieldChildren = Array.isArray(fields)
|
|
489
|
+
const fieldChildren = Array.isArray(fields)
|
|
490
|
+
? fields
|
|
491
|
+
: fields
|
|
492
|
+
? [fields]
|
|
493
|
+
: [];
|
|
458
494
|
for (const fieldObj of fieldChildren) {
|
|
459
495
|
const field = this.parseSimpleFieldFromObject(fieldObj);
|
|
460
496
|
if (field) {
|
|
@@ -574,7 +610,9 @@ class DocumentParser {
|
|
|
574
610
|
const tabs = [];
|
|
575
611
|
const tabElements = Array.isArray(tabsObj["w:tab"])
|
|
576
612
|
? tabsObj["w:tab"]
|
|
577
|
-
: tabsObj["w:tab"]
|
|
613
|
+
: tabsObj["w:tab"]
|
|
614
|
+
? [tabsObj["w:tab"]]
|
|
615
|
+
: [];
|
|
578
616
|
for (const tabObj of tabElements) {
|
|
579
617
|
const tab = {};
|
|
580
618
|
if (tabObj["@_w:pos"])
|
|
@@ -593,14 +631,18 @@ class DocumentParser {
|
|
|
593
631
|
}
|
|
594
632
|
if (pPrObj["w:widowControl"] !== undefined) {
|
|
595
633
|
const widowControlVal = pPrObj["w:widowControl"]?.["@_w:val"];
|
|
596
|
-
if (widowControlVal === "0" ||
|
|
634
|
+
if (widowControlVal === "0" ||
|
|
635
|
+
widowControlVal === "false" ||
|
|
636
|
+
widowControlVal === false ||
|
|
637
|
+
widowControlVal === 0) {
|
|
597
638
|
paragraph.setWidowControl(false);
|
|
598
639
|
}
|
|
599
640
|
else {
|
|
600
641
|
paragraph.setWidowControl(true);
|
|
601
642
|
}
|
|
602
643
|
}
|
|
603
|
-
if (pPrObj["w:outlineLvl"] !== undefined &&
|
|
644
|
+
if (pPrObj["w:outlineLvl"] !== undefined &&
|
|
645
|
+
pPrObj["w:outlineLvl"]["@_w:val"] !== undefined) {
|
|
604
646
|
const level = parseInt(pPrObj["w:outlineLvl"]["@_w:val"], 10);
|
|
605
647
|
if (!isNaN(level) && level >= 0 && level <= 9) {
|
|
606
648
|
paragraph.setOutlineLevel(level);
|
|
@@ -611,7 +653,10 @@ class DocumentParser {
|
|
|
611
653
|
}
|
|
612
654
|
if (pPrObj["w:bidi"] !== undefined) {
|
|
613
655
|
const bidiVal = pPrObj["w:bidi"]?.["@_w:val"];
|
|
614
|
-
if (bidiVal === "0" ||
|
|
656
|
+
if (bidiVal === "0" ||
|
|
657
|
+
bidiVal === "false" ||
|
|
658
|
+
bidiVal === false ||
|
|
659
|
+
bidiVal === 0) {
|
|
615
660
|
paragraph.setBidi(false);
|
|
616
661
|
}
|
|
617
662
|
else {
|
|
@@ -629,7 +674,10 @@ class DocumentParser {
|
|
|
629
674
|
}
|
|
630
675
|
if (pPrObj["w:adjustRightInd"] !== undefined) {
|
|
631
676
|
const adjustRightIndVal = pPrObj["w:adjustRightInd"]?.["@_w:val"];
|
|
632
|
-
if (adjustRightIndVal === "0" ||
|
|
677
|
+
if (adjustRightIndVal === "0" ||
|
|
678
|
+
adjustRightIndVal === "false" ||
|
|
679
|
+
adjustRightIndVal === false ||
|
|
680
|
+
adjustRightIndVal === 0) {
|
|
633
681
|
paragraph.setAdjustRightInd(false);
|
|
634
682
|
}
|
|
635
683
|
else {
|
|
@@ -669,7 +717,11 @@ class DocumentParser {
|
|
|
669
717
|
frameProps.lines = parseInt(framePr["@_w:lines"], 10);
|
|
670
718
|
if (framePr["@_w:anchorLock"] !== undefined) {
|
|
671
719
|
const anchorLockVal = framePr["@_w:anchorLock"];
|
|
672
|
-
frameProps.anchorLock =
|
|
720
|
+
frameProps.anchorLock =
|
|
721
|
+
anchorLockVal === "1" ||
|
|
722
|
+
anchorLockVal === "true" ||
|
|
723
|
+
anchorLockVal === true ||
|
|
724
|
+
anchorLockVal === 1;
|
|
673
725
|
}
|
|
674
726
|
if (Object.keys(frameProps).length > 0) {
|
|
675
727
|
paragraph.setFrameProperties(frameProps);
|
|
@@ -696,7 +748,7 @@ class DocumentParser {
|
|
|
696
748
|
if (pPrObj["w:cnfStyle"]) {
|
|
697
749
|
const cnfStyleVal = pPrObj["w:cnfStyle"]?.["@_w:val"];
|
|
698
750
|
if (cnfStyleVal !== undefined) {
|
|
699
|
-
const bitmask = String(cnfStyleVal).padStart(12,
|
|
751
|
+
const bitmask = String(cnfStyleVal).padStart(12, "0");
|
|
700
752
|
paragraph.setConditionalFormatting(bitmask);
|
|
701
753
|
}
|
|
702
754
|
}
|
|
@@ -726,27 +778,27 @@ class DocumentParser {
|
|
|
726
778
|
const item = content[i];
|
|
727
779
|
if (item instanceof Run_1.Run) {
|
|
728
780
|
const runContent = item.getContent();
|
|
729
|
-
const hasFieldContent = runContent.some((c) => c.type ===
|
|
781
|
+
const hasFieldContent = runContent.some((c) => c.type === "fieldChar" || c.type === "instructionText");
|
|
730
782
|
if (hasFieldContent) {
|
|
731
783
|
fieldRuns.push(item);
|
|
732
|
-
const fieldChar = runContent.find((c) => c.type ===
|
|
784
|
+
const fieldChar = runContent.find((c) => c.type === "fieldChar");
|
|
733
785
|
if (fieldChar) {
|
|
734
786
|
switch (fieldChar.fieldCharType) {
|
|
735
|
-
case
|
|
736
|
-
fieldState =
|
|
787
|
+
case "begin":
|
|
788
|
+
fieldState = "begin";
|
|
737
789
|
break;
|
|
738
|
-
case
|
|
739
|
-
fieldState =
|
|
790
|
+
case "separate":
|
|
791
|
+
fieldState = "separate";
|
|
740
792
|
break;
|
|
741
|
-
case
|
|
742
|
-
fieldState =
|
|
743
|
-
if (fieldState ===
|
|
793
|
+
case "end":
|
|
794
|
+
fieldState = "end";
|
|
795
|
+
if (fieldState === "end" && fieldRuns.length > 0) {
|
|
744
796
|
const complexField = this.createComplexFieldFromRuns(fieldRuns);
|
|
745
797
|
if (complexField) {
|
|
746
798
|
groupedContent.push(complexField);
|
|
747
799
|
}
|
|
748
800
|
else {
|
|
749
|
-
fieldRuns.forEach(run => groupedContent.push(run));
|
|
801
|
+
fieldRuns.forEach((run) => groupedContent.push(run));
|
|
750
802
|
}
|
|
751
803
|
fieldRuns = [];
|
|
752
804
|
fieldState = null;
|
|
@@ -755,14 +807,14 @@ class DocumentParser {
|
|
|
755
807
|
}
|
|
756
808
|
}
|
|
757
809
|
else {
|
|
758
|
-
if (fieldState ===
|
|
759
|
-
fieldState =
|
|
810
|
+
if (fieldState === "begin" || fieldState === "instruction") {
|
|
811
|
+
fieldState = "instruction";
|
|
760
812
|
}
|
|
761
813
|
}
|
|
762
814
|
}
|
|
763
815
|
else {
|
|
764
816
|
if (fieldRuns.length > 0) {
|
|
765
|
-
fieldRuns.forEach(run => groupedContent.push(run));
|
|
817
|
+
fieldRuns.forEach((run) => groupedContent.push(run));
|
|
766
818
|
fieldRuns = [];
|
|
767
819
|
}
|
|
768
820
|
groupedContent.push(item);
|
|
@@ -770,16 +822,16 @@ class DocumentParser {
|
|
|
770
822
|
}
|
|
771
823
|
else {
|
|
772
824
|
if (fieldRuns.length > 0) {
|
|
773
|
-
fieldRuns.forEach(run => groupedContent.push(run));
|
|
825
|
+
fieldRuns.forEach((run) => groupedContent.push(run));
|
|
774
826
|
fieldRuns = [];
|
|
775
827
|
}
|
|
776
828
|
groupedContent.push(item);
|
|
777
829
|
}
|
|
778
830
|
}
|
|
779
831
|
if (fieldRuns.length > 0) {
|
|
780
|
-
fieldRuns.forEach(run => groupedContent.push(run));
|
|
832
|
+
fieldRuns.forEach((run) => groupedContent.push(run));
|
|
781
833
|
}
|
|
782
|
-
if (
|
|
834
|
+
if ("replaceContent" in paragraph) {
|
|
783
835
|
paragraph.replaceContent(groupedContent);
|
|
784
836
|
}
|
|
785
837
|
else {
|
|
@@ -803,11 +855,11 @@ class DocumentParser {
|
|
|
803
855
|
}
|
|
804
856
|
createComplexFieldFromRuns(fieldRuns) {
|
|
805
857
|
if (fieldRuns.length < 2) {
|
|
806
|
-
logger_1.defaultLogger.warn(
|
|
858
|
+
logger_1.defaultLogger.warn("Insufficient runs for ComplexField (minimum 2: begin and instr)");
|
|
807
859
|
return null;
|
|
808
860
|
}
|
|
809
|
-
let instruction =
|
|
810
|
-
let resultText =
|
|
861
|
+
let instruction = "";
|
|
862
|
+
let resultText = "";
|
|
811
863
|
let instructionFormatting;
|
|
812
864
|
let resultFormatting;
|
|
813
865
|
let hasBegin = false;
|
|
@@ -815,33 +867,33 @@ class DocumentParser {
|
|
|
815
867
|
let hasSeparate = false;
|
|
816
868
|
for (const run of fieldRuns) {
|
|
817
869
|
const runContent = run.getContent();
|
|
818
|
-
const fieldCharToken = runContent.find((c) => c.type ===
|
|
870
|
+
const fieldCharToken = runContent.find((c) => c.type === "fieldChar");
|
|
819
871
|
if (fieldCharToken) {
|
|
820
872
|
switch (fieldCharToken.fieldCharType) {
|
|
821
|
-
case
|
|
873
|
+
case "begin":
|
|
822
874
|
hasBegin = true;
|
|
823
875
|
instructionFormatting = run.getFormatting();
|
|
824
876
|
break;
|
|
825
|
-
case
|
|
877
|
+
case "separate":
|
|
826
878
|
hasSeparate = true;
|
|
827
879
|
break;
|
|
828
|
-
case
|
|
880
|
+
case "end":
|
|
829
881
|
hasEnd = true;
|
|
830
882
|
break;
|
|
831
883
|
}
|
|
832
884
|
}
|
|
833
|
-
const instrText = runContent.find((c) => c.type ===
|
|
885
|
+
const instrText = runContent.find((c) => c.type === "instructionText");
|
|
834
886
|
if (instrText) {
|
|
835
|
-
instruction += instrText.value ||
|
|
887
|
+
instruction += instrText.value || "";
|
|
836
888
|
}
|
|
837
|
-
const textContent = runContent.find((c) => c.type ===
|
|
889
|
+
const textContent = runContent.find((c) => c.type === "text");
|
|
838
890
|
if (textContent && hasSeparate) {
|
|
839
|
-
resultText += textContent.value ||
|
|
891
|
+
resultText += textContent.value || "";
|
|
840
892
|
resultFormatting = run.getFormatting();
|
|
841
893
|
}
|
|
842
894
|
}
|
|
843
895
|
if (!hasBegin || !hasEnd || !instruction.trim()) {
|
|
844
|
-
logger_1.defaultLogger.warn(
|
|
896
|
+
logger_1.defaultLogger.warn("Invalid ComplexField structure: missing begin/end or instruction");
|
|
845
897
|
return null;
|
|
846
898
|
}
|
|
847
899
|
instruction = instruction.trim();
|
|
@@ -858,13 +910,17 @@ class DocumentParser {
|
|
|
858
910
|
parseRunFromObject(runObj) {
|
|
859
911
|
try {
|
|
860
912
|
const content = [];
|
|
861
|
-
const toArray = (value) => Array.isArray(value)
|
|
913
|
+
const toArray = (value) => Array.isArray(value)
|
|
914
|
+
? value
|
|
915
|
+
: value !== undefined && value !== null
|
|
916
|
+
? [value]
|
|
917
|
+
: [];
|
|
862
918
|
const extractTextValue = (node) => {
|
|
863
919
|
if (node === undefined || node === null) {
|
|
864
|
-
return
|
|
920
|
+
return "";
|
|
865
921
|
}
|
|
866
|
-
if (typeof node ===
|
|
867
|
-
return XMLBuilder_1.XMLBuilder.unescapeXml(node[
|
|
922
|
+
if (typeof node === "object") {
|
|
923
|
+
return XMLBuilder_1.XMLBuilder.unescapeXml(node["#text"] || "");
|
|
868
924
|
}
|
|
869
925
|
return XMLBuilder_1.XMLBuilder.unescapeXml(String(node));
|
|
870
926
|
};
|
|
@@ -872,69 +928,70 @@ class DocumentParser {
|
|
|
872
928
|
if (value === undefined || value === null) {
|
|
873
929
|
return undefined;
|
|
874
930
|
}
|
|
875
|
-
return value ===
|
|
931
|
+
return (value === "1" || value === 1 || value === true || value === "true");
|
|
876
932
|
};
|
|
877
933
|
if (runObj["_orderedChildren"]) {
|
|
878
934
|
for (const child of runObj["_orderedChildren"]) {
|
|
879
935
|
const elementType = child.type;
|
|
880
936
|
const elementIndex = child.index;
|
|
881
937
|
switch (elementType) {
|
|
882
|
-
case
|
|
938
|
+
case "w:t": {
|
|
883
939
|
const textElements = toArray(runObj["w:t"]);
|
|
884
940
|
const te = textElements[elementIndex];
|
|
885
941
|
if (te !== undefined && te !== null) {
|
|
886
942
|
const text = extractTextValue(te);
|
|
887
943
|
if (text) {
|
|
888
|
-
content.push({ type:
|
|
944
|
+
content.push({ type: "text", value: text });
|
|
889
945
|
}
|
|
890
946
|
}
|
|
891
947
|
break;
|
|
892
948
|
}
|
|
893
|
-
case
|
|
894
|
-
const instrElements = toArray(runObj[
|
|
949
|
+
case "w:instrText": {
|
|
950
|
+
const instrElements = toArray(runObj["w:instrText"]);
|
|
895
951
|
const instr = instrElements[elementIndex];
|
|
896
952
|
if (instr !== undefined && instr !== null) {
|
|
897
953
|
const text = extractTextValue(instr);
|
|
898
|
-
content.push({ type:
|
|
954
|
+
content.push({ type: "instructionText", value: text });
|
|
899
955
|
}
|
|
900
956
|
break;
|
|
901
957
|
}
|
|
902
|
-
case
|
|
903
|
-
const fldChars = toArray(runObj[
|
|
958
|
+
case "w:fldChar": {
|
|
959
|
+
const fldChars = toArray(runObj["w:fldChar"]);
|
|
904
960
|
const fldChar = fldChars[elementIndex];
|
|
905
|
-
if (fldChar && typeof fldChar ===
|
|
906
|
-
const charType = (fldChar[
|
|
961
|
+
if (fldChar && typeof fldChar === "object") {
|
|
962
|
+
const charType = (fldChar["@_w:fldCharType"] ||
|
|
963
|
+
fldChar["@_fldCharType"]);
|
|
907
964
|
if (charType) {
|
|
908
965
|
content.push({
|
|
909
|
-
type:
|
|
966
|
+
type: "fieldChar",
|
|
910
967
|
fieldCharType: charType,
|
|
911
|
-
fieldCharDirty: parseBooleanAttr(fldChar[
|
|
912
|
-
fieldCharLocked: parseBooleanAttr(fldChar[
|
|
968
|
+
fieldCharDirty: parseBooleanAttr(fldChar["@_w:dirty"]),
|
|
969
|
+
fieldCharLocked: parseBooleanAttr(fldChar["@_w:fldLock"] ?? fldChar["@_w:lock"]),
|
|
913
970
|
});
|
|
914
971
|
}
|
|
915
972
|
}
|
|
916
973
|
break;
|
|
917
974
|
}
|
|
918
|
-
case
|
|
919
|
-
content.push({ type:
|
|
975
|
+
case "w:tab":
|
|
976
|
+
content.push({ type: "tab" });
|
|
920
977
|
break;
|
|
921
|
-
case
|
|
922
|
-
const brElements = toArray(runObj[
|
|
978
|
+
case "w:br": {
|
|
979
|
+
const brElements = toArray(runObj["w:br"]);
|
|
923
980
|
const brElement = brElements[elementIndex] || brElements[0];
|
|
924
|
-
const breakType = brElement?.[
|
|
925
|
-
content.push({ type:
|
|
981
|
+
const breakType = brElement?.["@_w:type"];
|
|
982
|
+
content.push({ type: "break", breakType });
|
|
926
983
|
break;
|
|
927
984
|
}
|
|
928
|
-
case
|
|
929
|
-
content.push({ type:
|
|
985
|
+
case "w:cr":
|
|
986
|
+
content.push({ type: "carriageReturn" });
|
|
930
987
|
break;
|
|
931
|
-
case
|
|
932
|
-
content.push({ type:
|
|
988
|
+
case "w:softHyphen":
|
|
989
|
+
content.push({ type: "softHyphen" });
|
|
933
990
|
break;
|
|
934
|
-
case
|
|
935
|
-
content.push({ type:
|
|
991
|
+
case "w:noBreakHyphen":
|
|
992
|
+
content.push({ type: "noBreakHyphen" });
|
|
936
993
|
break;
|
|
937
|
-
case
|
|
994
|
+
case "w:rPr":
|
|
938
995
|
break;
|
|
939
996
|
}
|
|
940
997
|
}
|
|
@@ -946,51 +1003,52 @@ class DocumentParser {
|
|
|
946
1003
|
for (const te of textElements) {
|
|
947
1004
|
const text = extractTextValue(te);
|
|
948
1005
|
if (text) {
|
|
949
|
-
content.push({ type:
|
|
1006
|
+
content.push({ type: "text", value: text });
|
|
950
1007
|
}
|
|
951
1008
|
}
|
|
952
1009
|
}
|
|
953
|
-
const instrTextElement = runObj[
|
|
1010
|
+
const instrTextElement = runObj["w:instrText"];
|
|
954
1011
|
if (instrTextElement !== undefined && instrTextElement !== null) {
|
|
955
1012
|
const instrElements = toArray(instrTextElement);
|
|
956
1013
|
for (const instr of instrElements) {
|
|
957
1014
|
const text = extractTextValue(instr);
|
|
958
|
-
content.push({ type:
|
|
1015
|
+
content.push({ type: "instructionText", value: text });
|
|
959
1016
|
}
|
|
960
1017
|
}
|
|
961
|
-
const fldCharElement = runObj[
|
|
1018
|
+
const fldCharElement = runObj["w:fldChar"];
|
|
962
1019
|
if (fldCharElement !== undefined && fldCharElement !== null) {
|
|
963
1020
|
const fldChars = toArray(fldCharElement);
|
|
964
1021
|
for (const fldChar of fldChars) {
|
|
965
|
-
if (fldChar && typeof fldChar ===
|
|
966
|
-
const charType = (fldChar[
|
|
1022
|
+
if (fldChar && typeof fldChar === "object") {
|
|
1023
|
+
const charType = (fldChar["@_w:fldCharType"] ||
|
|
1024
|
+
fldChar["@_fldCharType"]);
|
|
967
1025
|
if (charType) {
|
|
968
1026
|
content.push({
|
|
969
|
-
type:
|
|
1027
|
+
type: "fieldChar",
|
|
970
1028
|
fieldCharType: charType,
|
|
971
|
-
fieldCharDirty: parseBooleanAttr(fldChar[
|
|
972
|
-
fieldCharLocked: parseBooleanAttr(fldChar[
|
|
1029
|
+
fieldCharDirty: parseBooleanAttr(fldChar["@_w:dirty"]),
|
|
1030
|
+
fieldCharLocked: parseBooleanAttr(fldChar["@_w:fldLock"] ?? fldChar["@_w:lock"]),
|
|
973
1031
|
});
|
|
974
1032
|
}
|
|
975
1033
|
}
|
|
976
1034
|
}
|
|
977
1035
|
}
|
|
978
1036
|
if (runObj["w:tab"] !== undefined) {
|
|
979
|
-
content.push({ type:
|
|
1037
|
+
content.push({ type: "tab" });
|
|
980
1038
|
}
|
|
981
1039
|
if (runObj["w:br"] !== undefined) {
|
|
982
1040
|
const brElement = runObj["w:br"];
|
|
983
|
-
const breakType = brElement?.[
|
|
984
|
-
content.push({ type:
|
|
1041
|
+
const breakType = brElement?.["@_w:type"];
|
|
1042
|
+
content.push({ type: "break", breakType });
|
|
985
1043
|
}
|
|
986
1044
|
if (runObj["w:cr"] !== undefined) {
|
|
987
|
-
content.push({ type:
|
|
1045
|
+
content.push({ type: "carriageReturn" });
|
|
988
1046
|
}
|
|
989
1047
|
if (runObj["w:softHyphen"] !== undefined) {
|
|
990
|
-
content.push({ type:
|
|
1048
|
+
content.push({ type: "softHyphen" });
|
|
991
1049
|
}
|
|
992
1050
|
if (runObj["w:noBreakHyphen"] !== undefined) {
|
|
993
|
-
content.push({ type:
|
|
1051
|
+
content.push({ type: "noBreakHyphen" });
|
|
994
1052
|
}
|
|
995
1053
|
}
|
|
996
1054
|
const run = Run_1.Run.createFromContent(content, { cleanXmlFromText: false });
|
|
@@ -1013,9 +1071,9 @@ class DocumentParser {
|
|
|
1013
1071
|
const anchor = hyperlinkObj["@_w:anchor"];
|
|
1014
1072
|
const tooltip = hyperlinkObj["@_w:tooltip"];
|
|
1015
1073
|
const runs = hyperlinkObj["w:r"];
|
|
1016
|
-
const runChildren = Array.isArray(runs) ? runs :
|
|
1074
|
+
const runChildren = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
1017
1075
|
const parsedRuns = [];
|
|
1018
|
-
let text =
|
|
1076
|
+
let text = "";
|
|
1019
1077
|
let formatting = {};
|
|
1020
1078
|
if (runChildren.length > 0) {
|
|
1021
1079
|
for (const runChild of runChildren) {
|
|
@@ -1037,7 +1095,7 @@ class DocumentParser {
|
|
|
1037
1095
|
url = relationship.getTarget();
|
|
1038
1096
|
}
|
|
1039
1097
|
}
|
|
1040
|
-
let displayText = text || url ||
|
|
1098
|
+
let displayText = text || url || "[Link]";
|
|
1041
1099
|
if (!text && anchor) {
|
|
1042
1100
|
logger_1.defaultLogger.warn(`[DocumentParser] Hyperlink to anchor "${anchor}" has no display text. ` +
|
|
1043
1101
|
`Using placeholder "[Link]" to prevent bookmark ID from appearing as visible text. ` +
|
|
@@ -1057,7 +1115,9 @@ class DocumentParser {
|
|
|
1057
1115
|
return hyperlink;
|
|
1058
1116
|
}
|
|
1059
1117
|
catch (error) {
|
|
1060
|
-
logger_1.defaultLogger.warn(
|
|
1118
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse hyperlink:", error instanceof Error
|
|
1119
|
+
? { message: error.message, stack: error.stack }
|
|
1120
|
+
: { error: String(error) });
|
|
1061
1121
|
return null;
|
|
1062
1122
|
}
|
|
1063
1123
|
}
|
|
@@ -1071,8 +1131,8 @@ class DocumentParser {
|
|
|
1071
1131
|
for (let i = 0; i < content.length; i++) {
|
|
1072
1132
|
const item = content[i];
|
|
1073
1133
|
if (item instanceof Hyperlink_1.Hyperlink) {
|
|
1074
|
-
const url = item.getUrl() ||
|
|
1075
|
-
const anchor = item.getAnchor() ||
|
|
1134
|
+
const url = item.getUrl() || "";
|
|
1135
|
+
const anchor = item.getAnchor() || "";
|
|
1076
1136
|
const key = `${url}|${anchor}`;
|
|
1077
1137
|
if (!hyperlinkGroups.has(key)) {
|
|
1078
1138
|
hyperlinkGroups.set(key, []);
|
|
@@ -1102,17 +1162,19 @@ class DocumentParser {
|
|
|
1102
1162
|
}
|
|
1103
1163
|
const item = content[i];
|
|
1104
1164
|
if (item instanceof Hyperlink_1.Hyperlink) {
|
|
1105
|
-
const url = item.getUrl() ||
|
|
1106
|
-
const anchor = item.getAnchor() ||
|
|
1165
|
+
const url = item.getUrl() || "";
|
|
1166
|
+
const anchor = item.getAnchor() || "";
|
|
1107
1167
|
const key = `${url}|${anchor}`;
|
|
1108
1168
|
const group = hyperlinkGroups.get(key);
|
|
1109
1169
|
if (group.length > 1 && group[0] === item) {
|
|
1110
|
-
const mergedText = group.map(h => h.getText()).join(
|
|
1170
|
+
const mergedText = group.map((h) => h.getText()).join("");
|
|
1111
1171
|
const mergedHyperlink = new Hyperlink_1.Hyperlink({
|
|
1112
1172
|
url: item.getUrl(),
|
|
1113
1173
|
anchor: item.getAnchor(),
|
|
1114
1174
|
text: mergedText,
|
|
1115
|
-
formatting: resetFormatting
|
|
1175
|
+
formatting: resetFormatting
|
|
1176
|
+
? this.getStandardHyperlinkFormatting()
|
|
1177
|
+
: item.getFormatting(),
|
|
1116
1178
|
tooltip: item.getTooltip(),
|
|
1117
1179
|
relationshipId: item.getRelationshipId(),
|
|
1118
1180
|
});
|
|
@@ -1161,9 +1223,9 @@ class DocumentParser {
|
|
|
1161
1223
|
}
|
|
1162
1224
|
getStandardHyperlinkFormatting() {
|
|
1163
1225
|
return {
|
|
1164
|
-
font:
|
|
1165
|
-
color:
|
|
1166
|
-
underline:
|
|
1226
|
+
font: "Verdana",
|
|
1227
|
+
color: "0000FF",
|
|
1228
|
+
underline: "single",
|
|
1167
1229
|
};
|
|
1168
1230
|
}
|
|
1169
1231
|
parseSimpleFieldFromObject(fieldObj) {
|
|
@@ -1173,7 +1235,8 @@ class DocumentParser {
|
|
|
1173
1235
|
return null;
|
|
1174
1236
|
}
|
|
1175
1237
|
const typeMatch = instruction.trim().match(/^(\w+)/);
|
|
1176
|
-
const type = (typeMatch?.[1] ||
|
|
1238
|
+
const type = (typeMatch?.[1] ||
|
|
1239
|
+
"PAGE");
|
|
1177
1240
|
let formatting;
|
|
1178
1241
|
if (fieldObj["w:rPr"]) {
|
|
1179
1242
|
const tempRun = new Run_1.Run("");
|
|
@@ -1188,7 +1251,9 @@ class DocumentParser {
|
|
|
1188
1251
|
return field;
|
|
1189
1252
|
}
|
|
1190
1253
|
catch (error) {
|
|
1191
|
-
logger_1.defaultLogger.warn(
|
|
1254
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse field:", error instanceof Error
|
|
1255
|
+
? { message: error.message, stack: error.stack }
|
|
1256
|
+
: { error: String(error) });
|
|
1192
1257
|
return null;
|
|
1193
1258
|
}
|
|
1194
1259
|
}
|
|
@@ -1444,8 +1509,8 @@ class DocumentParser {
|
|
|
1444
1509
|
logger_1.defaultLogger.warn(`[DocumentParser] Image file not found: ${imagePath}`);
|
|
1445
1510
|
return null;
|
|
1446
1511
|
}
|
|
1447
|
-
const extension = imagePath.split(
|
|
1448
|
-
const { Image: ImageClass } = await Promise.resolve().then(() => __importStar(require(
|
|
1512
|
+
const extension = imagePath.split(".").pop()?.toLowerCase() || "png";
|
|
1513
|
+
const { Image: ImageClass } = await Promise.resolve().then(() => __importStar(require("../elements/Image")));
|
|
1449
1514
|
const image = await ImageClass.create({
|
|
1450
1515
|
source: imageData,
|
|
1451
1516
|
width,
|
|
@@ -1464,7 +1529,9 @@ class DocumentParser {
|
|
|
1464
1529
|
return new ImageRun_1.ImageRun(image);
|
|
1465
1530
|
}
|
|
1466
1531
|
catch (error) {
|
|
1467
|
-
logger_1.defaultLogger.warn(
|
|
1532
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse drawing:", error instanceof Error
|
|
1533
|
+
? { message: error.message, stack: error.stack }
|
|
1534
|
+
: { error: String(error) });
|
|
1468
1535
|
return null;
|
|
1469
1536
|
}
|
|
1470
1537
|
}
|
|
@@ -1478,22 +1545,30 @@ class DocumentParser {
|
|
|
1478
1545
|
if (!wrapObj) {
|
|
1479
1546
|
return undefined;
|
|
1480
1547
|
}
|
|
1481
|
-
let type =
|
|
1548
|
+
let type = "square";
|
|
1482
1549
|
if (wrapTight)
|
|
1483
|
-
type =
|
|
1550
|
+
type = "tight";
|
|
1484
1551
|
else if (wrapThrough)
|
|
1485
|
-
type =
|
|
1552
|
+
type = "through";
|
|
1486
1553
|
else if (wrapTopBottom)
|
|
1487
|
-
type =
|
|
1554
|
+
type = "topAndBottom";
|
|
1488
1555
|
else if (wrapNone)
|
|
1489
|
-
type =
|
|
1556
|
+
type = "none";
|
|
1490
1557
|
return {
|
|
1491
1558
|
type,
|
|
1492
|
-
side: wrapObj["@_wrapText"] ||
|
|
1493
|
-
distanceTop: anchorObj["@_distT"]
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1559
|
+
side: wrapObj["@_wrapText"] || "bothSides",
|
|
1560
|
+
distanceTop: anchorObj["@_distT"]
|
|
1561
|
+
? parseInt(anchorObj["@_distT"], 10)
|
|
1562
|
+
: undefined,
|
|
1563
|
+
distanceBottom: anchorObj["@_distB"]
|
|
1564
|
+
? parseInt(anchorObj["@_distB"], 10)
|
|
1565
|
+
: undefined,
|
|
1566
|
+
distanceLeft: anchorObj["@_distL"]
|
|
1567
|
+
? parseInt(anchorObj["@_distL"], 10)
|
|
1568
|
+
: undefined,
|
|
1569
|
+
distanceRight: anchorObj["@_distR"]
|
|
1570
|
+
? parseInt(anchorObj["@_distR"], 10)
|
|
1571
|
+
: undefined,
|
|
1497
1572
|
};
|
|
1498
1573
|
}
|
|
1499
1574
|
parseImagePosition(anchorObj) {
|
|
@@ -1503,34 +1578,40 @@ class DocumentParser {
|
|
|
1503
1578
|
return undefined;
|
|
1504
1579
|
}
|
|
1505
1580
|
const horizontal = {
|
|
1506
|
-
anchor: posH["@_relativeFrom"] ||
|
|
1581
|
+
anchor: posH["@_relativeFrom"] || "page",
|
|
1507
1582
|
};
|
|
1508
1583
|
if (posH["wp:posOffset"]) {
|
|
1509
1584
|
const offsetText = Array.isArray(posH["wp:posOffset"])
|
|
1510
1585
|
? posH["wp:posOffset"][0]
|
|
1511
1586
|
: posH["wp:posOffset"];
|
|
1512
|
-
horizontal.offset = parseInt(typeof offsetText ===
|
|
1587
|
+
horizontal.offset = parseInt(typeof offsetText === "string"
|
|
1588
|
+
? offsetText
|
|
1589
|
+
: offsetText?.["#text"] || "0", 10);
|
|
1513
1590
|
}
|
|
1514
1591
|
else if (posH["wp:align"]) {
|
|
1515
1592
|
const alignText = Array.isArray(posH["wp:align"])
|
|
1516
1593
|
? posH["wp:align"][0]
|
|
1517
1594
|
: posH["wp:align"];
|
|
1518
|
-
horizontal.alignment =
|
|
1595
|
+
horizontal.alignment =
|
|
1596
|
+
typeof alignText === "string" ? alignText : alignText?.["#text"];
|
|
1519
1597
|
}
|
|
1520
1598
|
const vertical = {
|
|
1521
|
-
anchor: posV["@_relativeFrom"] ||
|
|
1599
|
+
anchor: posV["@_relativeFrom"] || "page",
|
|
1522
1600
|
};
|
|
1523
1601
|
if (posV["wp:posOffset"]) {
|
|
1524
1602
|
const offsetText = Array.isArray(posV["wp:posOffset"])
|
|
1525
1603
|
? posV["wp:posOffset"][0]
|
|
1526
1604
|
: posV["wp:posOffset"];
|
|
1527
|
-
vertical.offset = parseInt(typeof offsetText ===
|
|
1605
|
+
vertical.offset = parseInt(typeof offsetText === "string"
|
|
1606
|
+
? offsetText
|
|
1607
|
+
: offsetText?.["#text"] || "0", 10);
|
|
1528
1608
|
}
|
|
1529
1609
|
else if (posV["wp:align"]) {
|
|
1530
1610
|
const alignText = Array.isArray(posV["wp:align"])
|
|
1531
1611
|
? posV["wp:align"][0]
|
|
1532
1612
|
: posV["wp:align"];
|
|
1533
|
-
vertical.alignment =
|
|
1613
|
+
vertical.alignment =
|
|
1614
|
+
typeof alignText === "string" ? alignText : alignText?.["#text"];
|
|
1534
1615
|
}
|
|
1535
1616
|
return { horizontal, vertical };
|
|
1536
1617
|
}
|
|
@@ -1580,7 +1661,7 @@ class DocumentParser {
|
|
|
1580
1661
|
}
|
|
1581
1662
|
}
|
|
1582
1663
|
const rows = tableObj["w:tr"];
|
|
1583
|
-
const rowChildren = Array.isArray(rows) ? rows :
|
|
1664
|
+
const rowChildren = Array.isArray(rows) ? rows : rows ? [rows] : [];
|
|
1584
1665
|
for (const rowObj of rowChildren) {
|
|
1585
1666
|
const row = await this.parseTableRowFromObject(rowObj, relationshipManager, zipHandler, imageManager);
|
|
1586
1667
|
if (row) {
|
|
@@ -1590,7 +1671,9 @@ class DocumentParser {
|
|
|
1590
1671
|
return table;
|
|
1591
1672
|
}
|
|
1592
1673
|
catch (error) {
|
|
1593
|
-
logger_1.defaultLogger.warn(
|
|
1674
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse table:", error instanceof Error
|
|
1675
|
+
? { message: error.message, stack: error.stack }
|
|
1676
|
+
: { error: String(error) });
|
|
1594
1677
|
return null;
|
|
1595
1678
|
}
|
|
1596
1679
|
}
|
|
@@ -1679,7 +1762,7 @@ class DocumentParser {
|
|
|
1679
1762
|
}
|
|
1680
1763
|
}
|
|
1681
1764
|
const cells = rowObj["w:tc"];
|
|
1682
|
-
const cellChildren = Array.isArray(cells) ? cells :
|
|
1765
|
+
const cellChildren = Array.isArray(cells) ? cells : cells ? [cells] : [];
|
|
1683
1766
|
for (const cellObj of cellChildren) {
|
|
1684
1767
|
const cell = await this.parseTableCellFromObject(cellObj, relationshipManager, zipHandler, imageManager);
|
|
1685
1768
|
if (cell) {
|
|
@@ -1689,7 +1772,9 @@ class DocumentParser {
|
|
|
1689
1772
|
return row;
|
|
1690
1773
|
}
|
|
1691
1774
|
catch (error) {
|
|
1692
|
-
logger_1.defaultLogger.warn(
|
|
1775
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse table row:", error instanceof Error
|
|
1776
|
+
? { message: error.message, stack: error.stack }
|
|
1777
|
+
: { error: String(error) });
|
|
1693
1778
|
return null;
|
|
1694
1779
|
}
|
|
1695
1780
|
}
|
|
@@ -1778,7 +1863,14 @@ class DocumentParser {
|
|
|
1778
1863
|
if (!bordersObj)
|
|
1779
1864
|
return undefined;
|
|
1780
1865
|
const borders = {};
|
|
1781
|
-
const borderNames = [
|
|
1866
|
+
const borderNames = [
|
|
1867
|
+
"top",
|
|
1868
|
+
"bottom",
|
|
1869
|
+
"left",
|
|
1870
|
+
"right",
|
|
1871
|
+
"insideH",
|
|
1872
|
+
"insideV",
|
|
1873
|
+
];
|
|
1782
1874
|
for (const name of borderNames) {
|
|
1783
1875
|
const borderKey = `w:${name}`;
|
|
1784
1876
|
if (bordersObj[borderKey]) {
|
|
@@ -1822,7 +1914,9 @@ class DocumentParser {
|
|
|
1822
1914
|
return undefined;
|
|
1823
1915
|
return {
|
|
1824
1916
|
style: borderObj["@_w:val"] || "single",
|
|
1825
|
-
size: borderObj["@_w:sz"]
|
|
1917
|
+
size: borderObj["@_w:sz"]
|
|
1918
|
+
? parseInt(borderObj["@_w:sz"], 10)
|
|
1919
|
+
: undefined,
|
|
1826
1920
|
color: borderObj["@_w:color"] || undefined,
|
|
1827
1921
|
};
|
|
1828
1922
|
};
|
|
@@ -1870,7 +1964,8 @@ class DocumentParser {
|
|
|
1870
1964
|
}
|
|
1871
1965
|
if (tcPr["w:vAlign"]) {
|
|
1872
1966
|
const valign = tcPr["w:vAlign"]["@_w:val"];
|
|
1873
|
-
if (valign &&
|
|
1967
|
+
if (valign &&
|
|
1968
|
+
(valign === "top" || valign === "center" || valign === "bottom")) {
|
|
1874
1969
|
cell.setVerticalAlignment(valign);
|
|
1875
1970
|
}
|
|
1876
1971
|
}
|
|
@@ -1906,7 +2001,11 @@ class DocumentParser {
|
|
|
1906
2001
|
}
|
|
1907
2002
|
}
|
|
1908
2003
|
const paragraphs = cellObj["w:p"];
|
|
1909
|
-
const paraChildren = Array.isArray(paragraphs)
|
|
2004
|
+
const paraChildren = Array.isArray(paragraphs)
|
|
2005
|
+
? paragraphs
|
|
2006
|
+
: paragraphs
|
|
2007
|
+
? [paragraphs]
|
|
2008
|
+
: [];
|
|
1910
2009
|
for (const paraObj of paraChildren) {
|
|
1911
2010
|
const paragraph = await this.parseParagraphFromObject(paraObj, relationshipManager, zipHandler, imageManager);
|
|
1912
2011
|
if (paragraph) {
|
|
@@ -1916,7 +2015,9 @@ class DocumentParser {
|
|
|
1916
2015
|
return cell;
|
|
1917
2016
|
}
|
|
1918
2017
|
catch (error) {
|
|
1919
|
-
logger_1.defaultLogger.warn(
|
|
2018
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse table cell:", error instanceof Error
|
|
2019
|
+
? { message: error.message, stack: error.stack }
|
|
2020
|
+
: { error: String(error) });
|
|
1920
2021
|
return null;
|
|
1921
2022
|
}
|
|
1922
2023
|
}
|
|
@@ -1925,99 +2026,113 @@ class DocumentParser {
|
|
|
1925
2026
|
if (!sdtObj)
|
|
1926
2027
|
return null;
|
|
1927
2028
|
const properties = {};
|
|
1928
|
-
const sdtPr = sdtObj[
|
|
2029
|
+
const sdtPr = sdtObj["w:sdtPr"];
|
|
1929
2030
|
if (sdtPr) {
|
|
1930
|
-
const idElement = sdtPr[
|
|
1931
|
-
if (idElement && idElement[
|
|
1932
|
-
properties.id = parseInt(idElement[
|
|
2031
|
+
const idElement = sdtPr["w:id"];
|
|
2032
|
+
if (idElement && idElement["@_w:val"]) {
|
|
2033
|
+
properties.id = parseInt(idElement["@_w:val"], 10);
|
|
1933
2034
|
}
|
|
1934
|
-
const tagElement = sdtPr[
|
|
1935
|
-
if (tagElement && tagElement[
|
|
1936
|
-
properties.tag = tagElement[
|
|
2035
|
+
const tagElement = sdtPr["w:tag"];
|
|
2036
|
+
if (tagElement && tagElement["@_w:val"]) {
|
|
2037
|
+
properties.tag = tagElement["@_w:val"];
|
|
1937
2038
|
}
|
|
1938
|
-
const lockElement = sdtPr[
|
|
1939
|
-
if (lockElement && lockElement[
|
|
1940
|
-
properties.lock = lockElement[
|
|
2039
|
+
const lockElement = sdtPr["w:lock"];
|
|
2040
|
+
if (lockElement && lockElement["@_w:val"]) {
|
|
2041
|
+
properties.lock = lockElement["@_w:val"];
|
|
1941
2042
|
}
|
|
1942
|
-
const aliasElement = sdtPr[
|
|
1943
|
-
if (aliasElement && aliasElement[
|
|
1944
|
-
properties.alias = aliasElement[
|
|
2043
|
+
const aliasElement = sdtPr["w:alias"];
|
|
2044
|
+
if (aliasElement && aliasElement["@_w:val"]) {
|
|
2045
|
+
properties.alias = aliasElement["@_w:val"];
|
|
1945
2046
|
}
|
|
1946
|
-
if (sdtPr[
|
|
1947
|
-
properties.controlType =
|
|
2047
|
+
if (sdtPr["w:richText"]) {
|
|
2048
|
+
properties.controlType = "richText";
|
|
1948
2049
|
}
|
|
1949
|
-
else if (sdtPr[
|
|
1950
|
-
properties.controlType =
|
|
1951
|
-
const textElement = sdtPr[
|
|
2050
|
+
else if (sdtPr["w:text"]) {
|
|
2051
|
+
properties.controlType = "plainText";
|
|
2052
|
+
const textElement = sdtPr["w:text"];
|
|
1952
2053
|
properties.plainText = {
|
|
1953
|
-
multiLine: textElement?.[
|
|
2054
|
+
multiLine: textElement?.["@_w:multiLine"] === "1" ||
|
|
2055
|
+
textElement?.["@_w:multiLine"] === "true",
|
|
1954
2056
|
};
|
|
1955
2057
|
}
|
|
1956
|
-
else if (sdtPr[
|
|
1957
|
-
properties.controlType =
|
|
1958
|
-
const comboBoxElement = sdtPr[
|
|
2058
|
+
else if (sdtPr["w:comboBox"]) {
|
|
2059
|
+
properties.controlType = "comboBox";
|
|
2060
|
+
const comboBoxElement = sdtPr["w:comboBox"];
|
|
1959
2061
|
properties.comboBox = this.parseListItems(comboBoxElement);
|
|
1960
2062
|
}
|
|
1961
|
-
else if (sdtPr[
|
|
1962
|
-
properties.controlType =
|
|
1963
|
-
const dropDownElement = sdtPr[
|
|
2063
|
+
else if (sdtPr["w:dropDownList"]) {
|
|
2064
|
+
properties.controlType = "dropDownList";
|
|
2065
|
+
const dropDownElement = sdtPr["w:dropDownList"];
|
|
1964
2066
|
properties.dropDownList = this.parseListItems(dropDownElement);
|
|
1965
2067
|
}
|
|
1966
|
-
else if (sdtPr[
|
|
1967
|
-
properties.controlType =
|
|
1968
|
-
const dateElement = sdtPr[
|
|
2068
|
+
else if (sdtPr["w:date"]) {
|
|
2069
|
+
properties.controlType = "datePicker";
|
|
2070
|
+
const dateElement = sdtPr["w:date"];
|
|
1969
2071
|
properties.datePicker = {
|
|
1970
|
-
dateFormat: dateElement?.[
|
|
1971
|
-
fullDate: dateElement?.[
|
|
1972
|
-
|
|
1973
|
-
|
|
2072
|
+
dateFormat: dateElement?.["w:dateFormat"]?.["@_w:val"],
|
|
2073
|
+
fullDate: dateElement?.["w:fullDate"]?.["@_w:val"]
|
|
2074
|
+
? new Date(dateElement["w:fullDate"]["@_w:val"])
|
|
2075
|
+
: undefined,
|
|
2076
|
+
lid: dateElement?.["w:lid"]?.["@_w:val"],
|
|
2077
|
+
calendar: dateElement?.["w:calendar"]?.["@_w:val"],
|
|
1974
2078
|
};
|
|
1975
2079
|
}
|
|
1976
|
-
else if (sdtPr[
|
|
1977
|
-
properties.controlType =
|
|
1978
|
-
const checkboxElement = sdtPr[
|
|
2080
|
+
else if (sdtPr["w14:checkbox"]) {
|
|
2081
|
+
properties.controlType = "checkbox";
|
|
2082
|
+
const checkboxElement = sdtPr["w14:checkbox"];
|
|
1979
2083
|
properties.checkbox = {
|
|
1980
|
-
checked: checkboxElement?.[
|
|
1981
|
-
|
|
1982
|
-
|
|
2084
|
+
checked: checkboxElement?.["w14:checked"]?.["@_w14:val"] === "1" ||
|
|
2085
|
+
checkboxElement?.["w14:checked"]?.["@_w14:val"] === "true",
|
|
2086
|
+
checkedState: checkboxElement?.["w14:checkedState"]?.["@_w14:val"],
|
|
2087
|
+
uncheckedState: checkboxElement?.["w14:uncheckedState"]?.["@_w14:val"],
|
|
1983
2088
|
};
|
|
1984
2089
|
}
|
|
1985
|
-
else if (sdtPr[
|
|
1986
|
-
properties.controlType =
|
|
2090
|
+
else if (sdtPr["w:picture"]) {
|
|
2091
|
+
properties.controlType = "picture";
|
|
1987
2092
|
}
|
|
1988
|
-
else if (sdtPr[
|
|
1989
|
-
properties.controlType =
|
|
1990
|
-
const docPartObj = sdtPr[
|
|
2093
|
+
else if (sdtPr["w:docPartObj"]) {
|
|
2094
|
+
properties.controlType = "buildingBlock";
|
|
2095
|
+
const docPartObj = sdtPr["w:docPartObj"];
|
|
1991
2096
|
properties.buildingBlock = {
|
|
1992
|
-
gallery: docPartObj?.[
|
|
1993
|
-
category: docPartObj?.[
|
|
2097
|
+
gallery: docPartObj?.["w:docPartGallery"]?.["@_w:val"],
|
|
2098
|
+
category: docPartObj?.["w:docPartCategory"]?.["@_w:val"],
|
|
1994
2099
|
};
|
|
1995
2100
|
}
|
|
1996
|
-
else if (sdtPr[
|
|
1997
|
-
properties.controlType =
|
|
2101
|
+
else if (sdtPr["w:group"]) {
|
|
2102
|
+
properties.controlType = "group";
|
|
1998
2103
|
}
|
|
1999
2104
|
}
|
|
2000
2105
|
const content = [];
|
|
2001
|
-
const sdtContent = sdtObj[
|
|
2106
|
+
const sdtContent = sdtObj["w:sdtContent"];
|
|
2002
2107
|
if (sdtContent) {
|
|
2003
|
-
const orderedChildren = sdtContent[
|
|
2108
|
+
const orderedChildren = sdtContent["_orderedChildren"];
|
|
2004
2109
|
if (orderedChildren && orderedChildren.length > 0) {
|
|
2005
2110
|
for (const childInfo of orderedChildren) {
|
|
2006
2111
|
const elementType = childInfo.type;
|
|
2007
2112
|
const elementIndex = childInfo.index;
|
|
2008
|
-
if (elementType ===
|
|
2009
|
-
const paragraphs = sdtContent[
|
|
2010
|
-
const paraArray = Array.isArray(paragraphs)
|
|
2113
|
+
if (elementType === "w:p") {
|
|
2114
|
+
const paragraphs = sdtContent["w:p"];
|
|
2115
|
+
const paraArray = Array.isArray(paragraphs)
|
|
2116
|
+
? paragraphs
|
|
2117
|
+
: paragraphs
|
|
2118
|
+
? [paragraphs]
|
|
2119
|
+
: [];
|
|
2011
2120
|
if (elementIndex < paraArray.length) {
|
|
2012
|
-
const paraXml = this.objectToXml({
|
|
2121
|
+
const paraXml = this.objectToXml({
|
|
2122
|
+
"w:p": paraArray[elementIndex],
|
|
2123
|
+
});
|
|
2013
2124
|
const para = await this.parseParagraphWithOrder(paraXml, relationshipManager, zipHandler, imageManager);
|
|
2014
2125
|
if (para)
|
|
2015
2126
|
content.push(para);
|
|
2016
2127
|
}
|
|
2017
2128
|
}
|
|
2018
|
-
else if (elementType ===
|
|
2019
|
-
const tables = sdtContent[
|
|
2020
|
-
const tableArray = Array.isArray(tables)
|
|
2129
|
+
else if (elementType === "w:tbl") {
|
|
2130
|
+
const tables = sdtContent["w:tbl"];
|
|
2131
|
+
const tableArray = Array.isArray(tables)
|
|
2132
|
+
? tables
|
|
2133
|
+
: tables
|
|
2134
|
+
? [tables]
|
|
2135
|
+
: [];
|
|
2021
2136
|
if (elementIndex < tableArray.length) {
|
|
2022
2137
|
const tableObj = tableArray[elementIndex];
|
|
2023
2138
|
const table = await this.parseTableFromObject(tableObj, relationshipManager, zipHandler, imageManager);
|
|
@@ -2025,9 +2140,9 @@ class DocumentParser {
|
|
|
2025
2140
|
content.push(table);
|
|
2026
2141
|
}
|
|
2027
2142
|
}
|
|
2028
|
-
else if (elementType ===
|
|
2029
|
-
const sdts = sdtContent[
|
|
2030
|
-
const sdtArray = Array.isArray(sdts) ? sdts :
|
|
2143
|
+
else if (elementType === "w:sdt") {
|
|
2144
|
+
const sdts = sdtContent["w:sdt"];
|
|
2145
|
+
const sdtArray = Array.isArray(sdts) ? sdts : sdts ? [sdts] : [];
|
|
2031
2146
|
if (elementIndex < sdtArray.length) {
|
|
2032
2147
|
const nestedSdt = await this.parseSDTFromObject(sdtArray[elementIndex], relationshipManager, zipHandler, imageManager);
|
|
2033
2148
|
if (nestedSdt)
|
|
@@ -2037,23 +2152,35 @@ class DocumentParser {
|
|
|
2037
2152
|
}
|
|
2038
2153
|
}
|
|
2039
2154
|
else {
|
|
2040
|
-
const paragraphs = sdtContent[
|
|
2041
|
-
const paraArray = Array.isArray(paragraphs)
|
|
2155
|
+
const paragraphs = sdtContent["w:p"];
|
|
2156
|
+
const paraArray = Array.isArray(paragraphs)
|
|
2157
|
+
? paragraphs
|
|
2158
|
+
: paragraphs
|
|
2159
|
+
? [paragraphs]
|
|
2160
|
+
: [];
|
|
2042
2161
|
for (const paraObj of paraArray) {
|
|
2043
|
-
const paraXml = this.objectToXml({
|
|
2162
|
+
const paraXml = this.objectToXml({ "w:p": paraObj });
|
|
2044
2163
|
const para = await this.parseParagraphWithOrder(paraXml, relationshipManager, zipHandler, imageManager);
|
|
2045
2164
|
if (para)
|
|
2046
2165
|
content.push(para);
|
|
2047
2166
|
}
|
|
2048
|
-
const tables = sdtContent[
|
|
2049
|
-
const tableArray = Array.isArray(tables)
|
|
2167
|
+
const tables = sdtContent["w:tbl"];
|
|
2168
|
+
const tableArray = Array.isArray(tables)
|
|
2169
|
+
? tables
|
|
2170
|
+
: tables
|
|
2171
|
+
? [tables]
|
|
2172
|
+
: [];
|
|
2050
2173
|
for (const tableObj of tableArray) {
|
|
2051
2174
|
const table = await this.parseTableFromObject(tableObj, relationshipManager, zipHandler, imageManager);
|
|
2052
2175
|
if (table)
|
|
2053
2176
|
content.push(table);
|
|
2054
2177
|
}
|
|
2055
|
-
const nestedSdts = sdtContent[
|
|
2056
|
-
const sdtArray = Array.isArray(nestedSdts)
|
|
2178
|
+
const nestedSdts = sdtContent["w:sdt"];
|
|
2179
|
+
const sdtArray = Array.isArray(nestedSdts)
|
|
2180
|
+
? nestedSdts
|
|
2181
|
+
: nestedSdts
|
|
2182
|
+
? [nestedSdts]
|
|
2183
|
+
: [];
|
|
2057
2184
|
for (const nestedSdtObj of sdtArray) {
|
|
2058
2185
|
const nestedSdt = await this.parseSDTFromObject(nestedSdtObj, relationshipManager, zipHandler, imageManager);
|
|
2059
2186
|
if (nestedSdt)
|
|
@@ -2061,7 +2188,7 @@ class DocumentParser {
|
|
|
2061
2188
|
}
|
|
2062
2189
|
}
|
|
2063
2190
|
}
|
|
2064
|
-
if (properties.buildingBlock?.gallery ===
|
|
2191
|
+
if (properties.buildingBlock?.gallery === "Table of Contents") {
|
|
2065
2192
|
const toc = this.parseTOCFromSDTContent(content, properties, sdtContent);
|
|
2066
2193
|
if (toc) {
|
|
2067
2194
|
return new TableOfContentsElement_1.TableOfContentsElement(toc);
|
|
@@ -2070,7 +2197,9 @@ class DocumentParser {
|
|
|
2070
2197
|
return new StructuredDocumentTag_1.StructuredDocumentTag(properties, content);
|
|
2071
2198
|
}
|
|
2072
2199
|
catch (error) {
|
|
2073
|
-
logger_1.defaultLogger.warn(
|
|
2200
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse SDT:", error instanceof Error
|
|
2201
|
+
? { message: error.message, stack: error.stack }
|
|
2202
|
+
: { error: String(error) });
|
|
2074
2203
|
return null;
|
|
2075
2204
|
}
|
|
2076
2205
|
}
|
|
@@ -2081,25 +2210,29 @@ class DocumentParser {
|
|
|
2081
2210
|
for (const element of content) {
|
|
2082
2211
|
if (element instanceof Paragraph_1.Paragraph) {
|
|
2083
2212
|
const style = element.getStyle();
|
|
2084
|
-
if (style ===
|
|
2213
|
+
if (style === "TOCHeading") {
|
|
2085
2214
|
const runs = element.getRuns();
|
|
2086
|
-
title = runs.map(r => r.getText()).join(
|
|
2215
|
+
title = runs.map((r) => r.getText()).join("");
|
|
2087
2216
|
}
|
|
2088
2217
|
}
|
|
2089
2218
|
}
|
|
2090
|
-
const paragraphs = sdtContent[
|
|
2091
|
-
const paraArray = Array.isArray(paragraphs)
|
|
2219
|
+
const paragraphs = sdtContent["w:p"];
|
|
2220
|
+
const paraArray = Array.isArray(paragraphs)
|
|
2221
|
+
? paragraphs
|
|
2222
|
+
: paragraphs
|
|
2223
|
+
? [paragraphs]
|
|
2224
|
+
: [];
|
|
2092
2225
|
for (const paraObj of paraArray) {
|
|
2093
|
-
const runs = paraObj[
|
|
2094
|
-
const runArray = Array.isArray(runs) ? runs :
|
|
2226
|
+
const runs = paraObj["w:r"];
|
|
2227
|
+
const runArray = Array.isArray(runs) ? runs : runs ? [runs] : [];
|
|
2095
2228
|
for (const runObj of runArray) {
|
|
2096
|
-
const instrText = runObj[
|
|
2229
|
+
const instrText = runObj["w:instrText"];
|
|
2097
2230
|
if (instrText) {
|
|
2098
|
-
if (typeof instrText ===
|
|
2231
|
+
if (typeof instrText === "string") {
|
|
2099
2232
|
fieldInstruction = instrText.trim();
|
|
2100
2233
|
}
|
|
2101
|
-
else if (instrText[
|
|
2102
|
-
fieldInstruction = instrText[
|
|
2234
|
+
else if (instrText["#text"]) {
|
|
2235
|
+
fieldInstruction = instrText["#text"].trim();
|
|
2103
2236
|
}
|
|
2104
2237
|
if (fieldInstruction)
|
|
2105
2238
|
break;
|
|
@@ -2109,20 +2242,20 @@ class DocumentParser {
|
|
|
2109
2242
|
break;
|
|
2110
2243
|
}
|
|
2111
2244
|
if (!fieldInstruction) {
|
|
2112
|
-
logger_1.defaultLogger.warn(
|
|
2245
|
+
logger_1.defaultLogger.warn("[DocumentParser] No TOC field instruction found in SDT content");
|
|
2113
2246
|
return null;
|
|
2114
2247
|
}
|
|
2115
2248
|
const tocOptions = {
|
|
2116
2249
|
title,
|
|
2117
|
-
originalFieldInstruction: fieldInstruction.trim()
|
|
2250
|
+
originalFieldInstruction: fieldInstruction.trim(),
|
|
2118
2251
|
};
|
|
2119
|
-
if (fieldInstruction.includes(
|
|
2252
|
+
if (fieldInstruction.includes("\\h")) {
|
|
2120
2253
|
tocOptions.useHyperlinks = true;
|
|
2121
2254
|
}
|
|
2122
|
-
if (fieldInstruction.includes(
|
|
2255
|
+
if (fieldInstruction.includes("\\n")) {
|
|
2123
2256
|
tocOptions.showPageNumbers = false;
|
|
2124
2257
|
}
|
|
2125
|
-
if (fieldInstruction.includes(
|
|
2258
|
+
if (fieldInstruction.includes("\\z")) {
|
|
2126
2259
|
tocOptions.hideInWebLayout = true;
|
|
2127
2260
|
}
|
|
2128
2261
|
const outlineMatch = fieldInstruction.match(/\\o\s+"(\d+)-(\d+)"/);
|
|
@@ -2134,14 +2267,14 @@ class DocumentParser {
|
|
|
2134
2267
|
if (stylesMatch && stylesMatch[1]) {
|
|
2135
2268
|
const stylesStr = stylesMatch[1];
|
|
2136
2269
|
const styles = [];
|
|
2137
|
-
const parts = stylesStr.split(
|
|
2270
|
+
const parts = stylesStr.split(",").filter((p) => p.trim());
|
|
2138
2271
|
for (let i = 0; i < parts.length; i += 2) {
|
|
2139
2272
|
const styleName = parts[i];
|
|
2140
2273
|
const levelStr = parts[i + 1];
|
|
2141
2274
|
if (styleName && levelStr) {
|
|
2142
2275
|
styles.push({
|
|
2143
2276
|
styleName: styleName.trim(),
|
|
2144
|
-
level: parseInt(levelStr.trim(), 10)
|
|
2277
|
+
level: parseInt(levelStr.trim(), 10),
|
|
2145
2278
|
});
|
|
2146
2279
|
}
|
|
2147
2280
|
}
|
|
@@ -2152,59 +2285,66 @@ class DocumentParser {
|
|
|
2152
2285
|
return new TableOfContents_1.TableOfContents(tocOptions);
|
|
2153
2286
|
}
|
|
2154
2287
|
catch (error) {
|
|
2155
|
-
logger_1.defaultLogger.warn(
|
|
2288
|
+
logger_1.defaultLogger.warn("[DocumentParser] Failed to parse TOC from SDT content:", error instanceof Error
|
|
2289
|
+
? { message: error.message, stack: error.stack }
|
|
2290
|
+
: { error: String(error) });
|
|
2156
2291
|
return null;
|
|
2157
2292
|
}
|
|
2158
2293
|
}
|
|
2159
2294
|
parseListItems(element) {
|
|
2160
2295
|
const items = [];
|
|
2161
|
-
const listItems = element?.[
|
|
2162
|
-
const itemArray = Array.isArray(listItems)
|
|
2296
|
+
const listItems = element?.["w:listItem"];
|
|
2297
|
+
const itemArray = Array.isArray(listItems)
|
|
2298
|
+
? listItems
|
|
2299
|
+
: listItems
|
|
2300
|
+
? [listItems]
|
|
2301
|
+
: [];
|
|
2163
2302
|
for (const item of itemArray) {
|
|
2164
|
-
if (item[
|
|
2303
|
+
if (item["@_w:displayText"] && item["@_w:value"]) {
|
|
2165
2304
|
items.push({
|
|
2166
|
-
displayText: item[
|
|
2167
|
-
value: item[
|
|
2305
|
+
displayText: item["@_w:displayText"],
|
|
2306
|
+
value: item["@_w:value"],
|
|
2168
2307
|
});
|
|
2169
2308
|
}
|
|
2170
2309
|
}
|
|
2171
2310
|
return {
|
|
2172
2311
|
items,
|
|
2173
|
-
lastValue: element?.[
|
|
2312
|
+
lastValue: element?.["@_w:lastValue"],
|
|
2174
2313
|
};
|
|
2175
2314
|
}
|
|
2176
2315
|
objectToXml(obj) {
|
|
2177
2316
|
const buildXml = (o, name) => {
|
|
2178
|
-
if (typeof o ===
|
|
2317
|
+
if (typeof o === "string")
|
|
2179
2318
|
return o;
|
|
2180
|
-
if (typeof o !==
|
|
2319
|
+
if (typeof o !== "object")
|
|
2181
2320
|
return String(o);
|
|
2182
2321
|
const keys = Object.keys(o);
|
|
2183
2322
|
if (keys.length === 0 && !name)
|
|
2184
|
-
return
|
|
2323
|
+
return "";
|
|
2185
2324
|
const tagName = name || keys[0];
|
|
2186
2325
|
const element = name ? o : o[tagName];
|
|
2187
2326
|
let xml = `<${tagName}`;
|
|
2188
|
-
if (element && typeof element ===
|
|
2327
|
+
if (element && typeof element === "object") {
|
|
2189
2328
|
for (const key of Object.keys(element)) {
|
|
2190
|
-
if (key.startsWith(
|
|
2329
|
+
if (key.startsWith("@_")) {
|
|
2191
2330
|
const attrName = key.substring(2);
|
|
2192
2331
|
xml += ` ${attrName}="${element[key]}"`;
|
|
2193
2332
|
}
|
|
2194
2333
|
}
|
|
2195
2334
|
}
|
|
2196
|
-
const hasChildren = element &&
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2335
|
+
const hasChildren = element &&
|
|
2336
|
+
typeof element === "object" &&
|
|
2337
|
+
Object.keys(element).some((k) => !k.startsWith("@_") && k !== "#text" && k !== "_orderedChildren");
|
|
2338
|
+
if (!hasChildren && (!element || !element["#text"])) {
|
|
2339
|
+
xml += "/>";
|
|
2200
2340
|
}
|
|
2201
2341
|
else {
|
|
2202
|
-
xml +=
|
|
2203
|
-
if (element && element[
|
|
2204
|
-
xml += element[
|
|
2342
|
+
xml += ">";
|
|
2343
|
+
if (element && element["#text"]) {
|
|
2344
|
+
xml += element["#text"];
|
|
2205
2345
|
}
|
|
2206
|
-
if (element && typeof element ===
|
|
2207
|
-
const orderedChildren = element[
|
|
2346
|
+
if (element && typeof element === "object") {
|
|
2347
|
+
const orderedChildren = element["_orderedChildren"];
|
|
2208
2348
|
if (orderedChildren && orderedChildren.length > 0) {
|
|
2209
2349
|
for (const childInfo of orderedChildren) {
|
|
2210
2350
|
const childType = childInfo.type;
|
|
@@ -2228,7 +2368,9 @@ class DocumentParser {
|
|
|
2228
2368
|
}
|
|
2229
2369
|
else {
|
|
2230
2370
|
for (const key of Object.keys(element)) {
|
|
2231
|
-
if (!key.startsWith(
|
|
2371
|
+
if (!key.startsWith("@_") &&
|
|
2372
|
+
key !== "#text" &&
|
|
2373
|
+
key !== "_orderedChildren") {
|
|
2232
2374
|
const children = element[key];
|
|
2233
2375
|
if (Array.isArray(children)) {
|
|
2234
2376
|
for (const child of children) {
|
|
@@ -2636,11 +2778,14 @@ class DocumentParser {
|
|
|
2636
2778
|
runFormatting = this.parseRunFormattingFromXml(rPrXml);
|
|
2637
2779
|
}
|
|
2638
2780
|
const qFormat = styleXml.includes("<w:qFormat/>") || styleXml.includes("<w:qFormat ");
|
|
2639
|
-
const semiHidden = styleXml.includes("<w:semiHidden/>") ||
|
|
2640
|
-
|
|
2781
|
+
const semiHidden = styleXml.includes("<w:semiHidden/>") ||
|
|
2782
|
+
styleXml.includes("<w:semiHidden ");
|
|
2783
|
+
const unhideWhenUsed = styleXml.includes("<w:unhideWhenUsed/>") ||
|
|
2784
|
+
styleXml.includes("<w:unhideWhenUsed ");
|
|
2641
2785
|
const locked = styleXml.includes("<w:locked/>") || styleXml.includes("<w:locked ");
|
|
2642
2786
|
const personal = styleXml.includes("<w:personal/>") || styleXml.includes("<w:personal ");
|
|
2643
|
-
const autoRedefine = styleXml.includes("<w:autoRedefine/>") ||
|
|
2787
|
+
const autoRedefine = styleXml.includes("<w:autoRedefine/>") ||
|
|
2788
|
+
styleXml.includes("<w:autoRedefine ");
|
|
2644
2789
|
let uiPriority;
|
|
2645
2790
|
if (styleXml.includes("<w:uiPriority")) {
|
|
2646
2791
|
const uiPriorityStart = styleXml.indexOf("<w:uiPriority");
|
|
@@ -2672,7 +2817,7 @@ class DocumentParser {
|
|
|
2672
2817
|
}
|
|
2673
2818
|
}
|
|
2674
2819
|
let tableStyle;
|
|
2675
|
-
if (typeAttr ===
|
|
2820
|
+
if (typeAttr === "table") {
|
|
2676
2821
|
tableStyle = this.parseTableStyleProperties(styleXml);
|
|
2677
2822
|
}
|
|
2678
2823
|
const properties = {
|
|
@@ -2875,7 +3020,8 @@ class DocumentParser {
|
|
|
2875
3020
|
if (trPrXml) {
|
|
2876
3021
|
tableStyle.row = this.parseTableRowFormattingFromXml(trPrXml);
|
|
2877
3022
|
}
|
|
2878
|
-
tableStyle.conditionalFormatting =
|
|
3023
|
+
tableStyle.conditionalFormatting =
|
|
3024
|
+
this.parseConditionalFormattingFromXml(styleXml);
|
|
2879
3025
|
return tableStyle;
|
|
2880
3026
|
}
|
|
2881
3027
|
parseTableFormattingFromXml(tblPrXml) {
|
|
@@ -2893,7 +3039,7 @@ class DocumentParser {
|
|
|
2893
3039
|
const tag = XMLParser_1.XMLParser.extractSelfClosingTag(tblPrXml, "w:jc");
|
|
2894
3040
|
if (tag) {
|
|
2895
3041
|
const val = XMLParser_1.XMLParser.extractAttribute(`<w:jc${tag}`, "w:val");
|
|
2896
|
-
if (val ===
|
|
3042
|
+
if (val === "left" || val === "center" || val === "right") {
|
|
2897
3043
|
formatting.alignment = val;
|
|
2898
3044
|
}
|
|
2899
3045
|
}
|
|
@@ -2937,7 +3083,7 @@ class DocumentParser {
|
|
|
2937
3083
|
const tag = XMLParser_1.XMLParser.extractSelfClosingTag(tcPrXml, "w:vAlign");
|
|
2938
3084
|
if (tag) {
|
|
2939
3085
|
const val = XMLParser_1.XMLParser.extractAttribute(`<w:vAlign${tag}`, "w:val");
|
|
2940
|
-
if (val ===
|
|
3086
|
+
if (val === "top" || val === "center" || val === "bottom") {
|
|
2941
3087
|
formatting.verticalAlignment = val;
|
|
2942
3088
|
}
|
|
2943
3089
|
}
|
|
@@ -2954,15 +3100,17 @@ class DocumentParser {
|
|
|
2954
3100
|
if (val) {
|
|
2955
3101
|
formatting.height = parseInt(val, 10);
|
|
2956
3102
|
}
|
|
2957
|
-
if (hRule ===
|
|
3103
|
+
if (hRule === "auto" || hRule === "exact" || hRule === "atLeast") {
|
|
2958
3104
|
formatting.heightRule = hRule;
|
|
2959
3105
|
}
|
|
2960
3106
|
}
|
|
2961
3107
|
}
|
|
2962
|
-
if (trPrXml.includes("<w:cantSplit/>") ||
|
|
3108
|
+
if (trPrXml.includes("<w:cantSplit/>") ||
|
|
3109
|
+
trPrXml.includes("<w:cantSplit ")) {
|
|
2963
3110
|
formatting.cantSplit = true;
|
|
2964
3111
|
}
|
|
2965
|
-
if (trPrXml.includes("<w:tblHeader/>") ||
|
|
3112
|
+
if (trPrXml.includes("<w:tblHeader/>") ||
|
|
3113
|
+
trPrXml.includes("<w:tblHeader ")) {
|
|
2966
3114
|
formatting.isHeader = true;
|
|
2967
3115
|
}
|
|
2968
3116
|
return formatting;
|
|
@@ -2985,7 +3133,8 @@ class DocumentParser {
|
|
|
2985
3133
|
};
|
|
2986
3134
|
const pPrXml = XMLParser_1.XMLParser.extractBetweenTags(tblStylePrXml, "<w:pPr>", "</w:pPr>");
|
|
2987
3135
|
if (pPrXml) {
|
|
2988
|
-
conditional.paragraphFormatting =
|
|
3136
|
+
conditional.paragraphFormatting =
|
|
3137
|
+
this.parseParagraphFormattingFromXml(pPrXml);
|
|
2989
3138
|
}
|
|
2990
3139
|
const rPrXml = XMLParser_1.XMLParser.extractBetweenTags(tblStylePrXml, "<w:rPr>", "</w:rPr>");
|
|
2991
3140
|
if (rPrXml) {
|
|
@@ -2993,15 +3142,18 @@ class DocumentParser {
|
|
|
2993
3142
|
}
|
|
2994
3143
|
const tblPrXml = XMLParser_1.XMLParser.extractBetweenTags(tblStylePrXml, "<w:tblPr>", "</w:tblPr>");
|
|
2995
3144
|
if (tblPrXml) {
|
|
2996
|
-
conditional.tableFormatting =
|
|
3145
|
+
conditional.tableFormatting =
|
|
3146
|
+
this.parseTableFormattingFromXml(tblPrXml);
|
|
2997
3147
|
}
|
|
2998
3148
|
const tcPrXml = XMLParser_1.XMLParser.extractBetweenTags(tblStylePrXml, "<w:tcPr>", "</w:tcPr>");
|
|
2999
3149
|
if (tcPrXml) {
|
|
3000
|
-
conditional.cellFormatting =
|
|
3150
|
+
conditional.cellFormatting =
|
|
3151
|
+
this.parseTableCellFormattingFromXml(tcPrXml);
|
|
3001
3152
|
}
|
|
3002
3153
|
const trPrXml = XMLParser_1.XMLParser.extractBetweenTags(tblStylePrXml, "<w:trPr>", "</w:trPr>");
|
|
3003
3154
|
if (trPrXml) {
|
|
3004
|
-
conditional.rowFormatting =
|
|
3155
|
+
conditional.rowFormatting =
|
|
3156
|
+
this.parseTableRowFormattingFromXml(trPrXml);
|
|
3005
3157
|
}
|
|
3006
3158
|
conditionalFormatting.push(conditional);
|
|
3007
3159
|
}
|
|
@@ -3011,7 +3163,14 @@ class DocumentParser {
|
|
|
3011
3163
|
}
|
|
3012
3164
|
parseBordersFromXml(bordersXml, includeDiagonals) {
|
|
3013
3165
|
const borders = {};
|
|
3014
|
-
const borderTypes = [
|
|
3166
|
+
const borderTypes = [
|
|
3167
|
+
"top",
|
|
3168
|
+
"bottom",
|
|
3169
|
+
"left",
|
|
3170
|
+
"right",
|
|
3171
|
+
"insideH",
|
|
3172
|
+
"insideV",
|
|
3173
|
+
];
|
|
3015
3174
|
for (const type of borderTypes) {
|
|
3016
3175
|
if (bordersXml.includes(`<w:${type}`)) {
|
|
3017
3176
|
const tag = XMLParser_1.XMLParser.extractSelfClosingTag(bordersXml, `w:${type}`);
|
|
@@ -3036,7 +3195,7 @@ class DocumentParser {
|
|
|
3036
3195
|
}
|
|
3037
3196
|
}
|
|
3038
3197
|
if (includeDiagonals) {
|
|
3039
|
-
const diagonalTypes = [
|
|
3198
|
+
const diagonalTypes = ["tl2br", "tr2bl"];
|
|
3040
3199
|
for (const type of diagonalTypes) {
|
|
3041
3200
|
if (bordersXml.includes(`<w:${type}`)) {
|
|
3042
3201
|
const tag = XMLParser_1.XMLParser.extractSelfClosingTag(bordersXml, `w:${type}`);
|
|
@@ -3081,14 +3240,15 @@ class DocumentParser {
|
|
|
3081
3240
|
}
|
|
3082
3241
|
parseCellMarginsFromXml(marginXml) {
|
|
3083
3242
|
const margins = {};
|
|
3084
|
-
const marginTypes = [
|
|
3243
|
+
const marginTypes = ["top", "bottom", "left", "right"];
|
|
3085
3244
|
for (const type of marginTypes) {
|
|
3086
3245
|
if (marginXml.includes(`<w:${type}`)) {
|
|
3087
3246
|
const tag = XMLParser_1.XMLParser.extractSelfClosingTag(marginXml, `w:${type}`);
|
|
3088
3247
|
if (tag) {
|
|
3089
3248
|
const w = XMLParser_1.XMLParser.extractAttribute(`<w:${type}${tag}`, "w:w");
|
|
3090
3249
|
if (w) {
|
|
3091
|
-
margins[type] =
|
|
3250
|
+
margins[type] =
|
|
3251
|
+
parseInt(w, 10);
|
|
3092
3252
|
}
|
|
3093
3253
|
}
|
|
3094
3254
|
}
|
|
@@ -3233,9 +3393,9 @@ class DocumentParser {
|
|
|
3233
3393
|
}
|
|
3234
3394
|
async parseHeader(headerXml, type, zipHandler, relationshipManager, imageManager) {
|
|
3235
3395
|
try {
|
|
3236
|
-
const { Header } = require(
|
|
3396
|
+
const { Header } = require("../elements/Header");
|
|
3237
3397
|
const header = new Header({ type });
|
|
3238
|
-
const hdrContent = XMLParser_1.XMLParser.extractBetweenTags(headerXml,
|
|
3398
|
+
const hdrContent = XMLParser_1.XMLParser.extractBetweenTags(headerXml, "<w:hdr", "</w:hdr>");
|
|
3239
3399
|
if (!hdrContent) {
|
|
3240
3400
|
return header;
|
|
3241
3401
|
}
|
|
@@ -3252,7 +3412,7 @@ class DocumentParser {
|
|
|
3252
3412
|
}
|
|
3253
3413
|
catch (error) {
|
|
3254
3414
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
3255
|
-
this.parseErrors.push({ element:
|
|
3415
|
+
this.parseErrors.push({ element: "header", error: err });
|
|
3256
3416
|
if (this.strictParsing) {
|
|
3257
3417
|
throw new Error(`Failed to parse header: ${err.message}`);
|
|
3258
3418
|
}
|
|
@@ -3261,9 +3421,9 @@ class DocumentParser {
|
|
|
3261
3421
|
}
|
|
3262
3422
|
async parseFooter(footerXml, type, zipHandler, relationshipManager, imageManager) {
|
|
3263
3423
|
try {
|
|
3264
|
-
const { Footer } = require(
|
|
3424
|
+
const { Footer } = require("../elements/Footer");
|
|
3265
3425
|
const footer = new Footer({ type });
|
|
3266
|
-
const ftrContent = XMLParser_1.XMLParser.extractBetweenTags(footerXml,
|
|
3426
|
+
const ftrContent = XMLParser_1.XMLParser.extractBetweenTags(footerXml, "<w:ftr", "</w:ftr>");
|
|
3267
3427
|
if (!ftrContent) {
|
|
3268
3428
|
return footer;
|
|
3269
3429
|
}
|
|
@@ -3280,7 +3440,7 @@ class DocumentParser {
|
|
|
3280
3440
|
}
|
|
3281
3441
|
catch (error) {
|
|
3282
3442
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
3283
|
-
this.parseErrors.push({ element:
|
|
3443
|
+
this.parseErrors.push({ element: "footer", error: err });
|
|
3284
3444
|
if (this.strictParsing) {
|
|
3285
3445
|
throw new Error(`Failed to parse footer: ${err.message}`);
|
|
3286
3446
|
}
|