docxmlater 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +330 -4
  2. package/dist/core/Document.d.ts +66 -28
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +590 -90
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentGenerator.d.ts +15 -13
  7. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  8. package/dist/core/DocumentGenerator.js +74 -13
  9. package/dist/core/DocumentGenerator.js.map +1 -1
  10. package/dist/core/DocumentParser.d.ts +40 -13
  11. package/dist/core/DocumentParser.d.ts.map +1 -1
  12. package/dist/core/DocumentParser.js +800 -316
  13. package/dist/core/DocumentParser.js.map +1 -1
  14. package/dist/core/DocumentValidator.d.ts +2 -1
  15. package/dist/core/DocumentValidator.d.ts.map +1 -1
  16. package/dist/core/DocumentValidator.js.map +1 -1
  17. package/dist/elements/Bookmark.d.ts +1 -0
  18. package/dist/elements/Bookmark.d.ts.map +1 -1
  19. package/dist/elements/Bookmark.js +1 -1
  20. package/dist/elements/Bookmark.js.map +1 -1
  21. package/dist/elements/Hyperlink.d.ts +1 -0
  22. package/dist/elements/Hyperlink.d.ts.map +1 -1
  23. package/dist/elements/Hyperlink.js +23 -0
  24. package/dist/elements/Hyperlink.js.map +1 -1
  25. package/dist/elements/ImageManager.d.ts +2 -0
  26. package/dist/elements/ImageManager.d.ts.map +1 -1
  27. package/dist/elements/ImageManager.js +22 -0
  28. package/dist/elements/ImageManager.js.map +1 -1
  29. package/dist/elements/ImageRun.d.ts +10 -0
  30. package/dist/elements/ImageRun.d.ts.map +1 -0
  31. package/dist/elements/ImageRun.js +23 -0
  32. package/dist/elements/ImageRun.js.map +1 -0
  33. package/dist/elements/Paragraph.d.ts +16 -1
  34. package/dist/elements/Paragraph.d.ts.map +1 -1
  35. package/dist/elements/Paragraph.js +146 -2
  36. package/dist/elements/Paragraph.js.map +1 -1
  37. package/dist/elements/Run.d.ts +4 -0
  38. package/dist/elements/Run.d.ts.map +1 -1
  39. package/dist/elements/Run.js +27 -1
  40. package/dist/elements/Run.js.map +1 -1
  41. package/dist/elements/Section.d.ts.map +1 -1
  42. package/dist/elements/Section.js +3 -8
  43. package/dist/elements/Section.js.map +1 -1
  44. package/dist/elements/StructuredDocumentTag.d.ts +32 -0
  45. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -0
  46. package/dist/elements/StructuredDocumentTag.js +94 -0
  47. package/dist/elements/StructuredDocumentTag.js.map +1 -0
  48. package/dist/elements/Table.d.ts +24 -0
  49. package/dist/elements/Table.d.ts.map +1 -1
  50. package/dist/elements/Table.js +177 -3
  51. package/dist/elements/Table.js.map +1 -1
  52. package/dist/elements/TableOfContents.d.ts +33 -0
  53. package/dist/elements/TableOfContents.d.ts.map +1 -1
  54. package/dist/elements/TableOfContents.js +129 -1
  55. package/dist/elements/TableOfContents.js.map +1 -1
  56. package/dist/elements/TableRow.d.ts.map +1 -1
  57. package/dist/elements/TableRow.js +11 -1
  58. package/dist/elements/TableRow.js.map +1 -1
  59. package/dist/formatting/AbstractNumbering.d.ts +1 -0
  60. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  61. package/dist/formatting/AbstractNumbering.js +30 -0
  62. package/dist/formatting/AbstractNumbering.js.map +1 -1
  63. package/dist/formatting/NumberingInstance.d.ts +1 -0
  64. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  65. package/dist/formatting/NumberingInstance.js +16 -0
  66. package/dist/formatting/NumberingInstance.js.map +1 -1
  67. package/dist/formatting/NumberingLevel.d.ts +1 -0
  68. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  69. package/dist/formatting/NumberingLevel.js +59 -0
  70. package/dist/formatting/NumberingLevel.js.map +1 -1
  71. package/dist/formatting/NumberingManager.d.ts +11 -0
  72. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  73. package/dist/formatting/NumberingManager.js +92 -0
  74. package/dist/formatting/NumberingManager.js.map +1 -1
  75. package/dist/formatting/Style.d.ts +2 -0
  76. package/dist/formatting/Style.d.ts.map +1 -1
  77. package/dist/formatting/Style.js +49 -0
  78. package/dist/formatting/Style.js.map +1 -1
  79. package/dist/index.d.ts +2 -0
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +6 -2
  82. package/dist/index.js.map +1 -1
  83. package/dist/xml/XMLBuilder.d.ts +4 -1
  84. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  85. package/dist/xml/XMLBuilder.js +134 -31
  86. package/dist/xml/XMLBuilder.js.map +1 -1
  87. package/dist/xml/XMLParser.d.ts +1 -0
  88. package/dist/xml/XMLParser.d.ts.map +1 -1
  89. package/dist/xml/XMLParser.js +75 -42
  90. package/dist/xml/XMLParser.js.map +1 -1
  91. package/dist/zip/ZipHandler.d.ts.map +1 -1
  92. package/dist/zip/ZipHandler.js +6 -1
  93. package/dist/zip/ZipHandler.js.map +1 -1
  94. package/dist/zip/ZipReader.d.ts.map +1 -1
  95. package/dist/zip/ZipReader.js +2 -2
  96. package/dist/zip/ZipReader.js.map +1 -1
  97. package/dist/zip/ZipWriter.d.ts.map +1 -1
  98. package/dist/zip/ZipWriter.js +13 -8
  99. package/dist/zip/ZipWriter.js.map +1 -1
  100. package/package.json +1 -1
@@ -41,16 +41,17 @@ const Table_1 = require("../elements/Table");
41
41
  const TableCell_1 = require("../elements/TableCell");
42
42
  const Section_1 = require("../elements/Section");
43
43
  const ImageManager_1 = require("../elements/ImageManager");
44
+ const ImageRun_1 = require("../elements/ImageRun");
44
45
  const HeaderFooterManager_1 = require("../elements/HeaderFooterManager");
45
46
  const TableOfContents_1 = require("../elements/TableOfContents");
46
47
  const TableOfContentsElement_1 = require("../elements/TableOfContentsElement");
48
+ const Bookmark_1 = require("../elements/Bookmark");
47
49
  const BookmarkManager_1 = require("../elements/BookmarkManager");
48
50
  const Revision_1 = require("../elements/Revision");
49
51
  const RevisionManager_1 = require("../elements/RevisionManager");
50
52
  const CommentManager_1 = require("../elements/CommentManager");
51
53
  const FootnoteManager_1 = require("../elements/FootnoteManager");
52
54
  const EndnoteManager_1 = require("../elements/EndnoteManager");
53
- const Run_1 = require("../elements/Run");
54
55
  const Hyperlink_1 = require("../elements/Hyperlink");
55
56
  const XMLParser_1 = require("../xml/XMLParser");
56
57
  const StylesManager_1 = require("../formatting/StylesManager");
@@ -61,24 +62,11 @@ const DocumentParser_1 = require("./DocumentParser");
61
62
  const DocumentGenerator_1 = require("./DocumentGenerator");
62
63
  const DocumentValidator_1 = require("./DocumentValidator");
63
64
  const logger_1 = require("../utils/logger");
64
- class ImageRun extends Run_1.Run {
65
- imageElement;
66
- constructor(image) {
67
- super('');
68
- this.imageElement = image;
69
- }
70
- toXML() {
71
- const drawing = this.imageElement.toXML();
72
- return {
73
- name: 'w:r',
74
- children: [drawing]
75
- };
76
- }
77
- }
78
65
  class Document {
79
66
  zipHandler;
80
67
  bodyElements = [];
81
68
  properties;
69
+ namespaces = {};
82
70
  stylesManager;
83
71
  numberingManager;
84
72
  section;
@@ -106,7 +94,9 @@ class Document {
106
94
  maxRssMB: options.maxRssMB,
107
95
  useAbsoluteLimit: options.useAbsoluteMemoryLimit,
108
96
  });
109
- this.properties = options.properties ? DocumentValidator_1.DocumentValidator.validateProperties(options.properties) : {};
97
+ this.properties = options.properties
98
+ ? DocumentValidator_1.DocumentValidator.validateProperties(options.properties)
99
+ : {};
110
100
  this.stylesManager = StylesManager_1.StylesManager.create();
111
101
  this.numberingManager = NumberingManager_1.NumberingManager.create();
112
102
  this.section = Section_1.Section.createLetter();
@@ -152,21 +142,40 @@ class Document {
152
142
  initializeRequiredFiles() {
153
143
  this.zipHandler.addFile(types_1.DOCX_PATHS.CONTENT_TYPES, this.generator.generateContentTypes());
154
144
  this.zipHandler.addFile(types_1.DOCX_PATHS.RELS, this.generator.generateRels());
155
- this.zipHandler.addFile(types_1.DOCX_PATHS.DOCUMENT, this.generator.generateDocumentXml(this.bodyElements, this.section));
156
- this.zipHandler.addFile('word/_rels/document.xml.rels', this.relationshipManager.generateXml());
145
+ this.zipHandler.addFile(types_1.DOCX_PATHS.DOCUMENT, this.generator.generateDocumentXml(this.bodyElements, this.section, this.namespaces));
146
+ this.zipHandler.addFile("word/_rels/document.xml.rels", this.relationshipManager.generateXml());
157
147
  this.zipHandler.addFile(types_1.DOCX_PATHS.STYLES, this.stylesManager.generateStylesXml());
158
148
  this.zipHandler.addFile(types_1.DOCX_PATHS.NUMBERING, this.numberingManager.generateNumberingXml());
159
- this.zipHandler.addFile('word/fontTable.xml', this.generator.generateFontTable());
160
- this.zipHandler.addFile('word/settings.xml', this.generator.generateSettings());
161
- this.zipHandler.addFile('word/theme/theme1.xml', this.generator.generateTheme());
149
+ this.zipHandler.addFile("word/fontTable.xml", this.generator.generateFontTable());
150
+ this.zipHandler.addFile("word/settings.xml", this.generator.generateSettings());
151
+ this.zipHandler.addFile("word/theme/theme1.xml", this.generator.generateTheme());
162
152
  this.zipHandler.addFile(types_1.DOCX_PATHS.CORE_PROPS, this.generator.generateCoreProps(this.properties));
163
153
  this.zipHandler.addFile(types_1.DOCX_PATHS.APP_PROPS, this.generator.generateAppProps());
164
154
  }
165
155
  async parseDocument() {
166
- const result = await this.parser.parseDocument(this.zipHandler, this.relationshipManager);
156
+ const result = await this.parser.parseDocument(this.zipHandler, this.relationshipManager, this.imageManager);
167
157
  this.bodyElements = result.bodyElements;
168
158
  this.properties = result.properties;
169
159
  this.relationshipManager = result.relationshipManager;
160
+ this.namespaces = result.namespaces;
161
+ if (result.section) {
162
+ this.section = result.section;
163
+ }
164
+ if (result.styles && result.styles.length > 0) {
165
+ for (const style of result.styles) {
166
+ this.stylesManager.addStyle(style);
167
+ }
168
+ }
169
+ if (result.abstractNumberings && result.abstractNumberings.length > 0) {
170
+ for (const abstractNum of result.abstractNumberings) {
171
+ this.numberingManager.addAbstractNumbering(abstractNum);
172
+ }
173
+ }
174
+ if (result.numberingInstances && result.numberingInstances.length > 0) {
175
+ for (const instance of result.numberingInstances) {
176
+ this.numberingManager.addInstance(instance);
177
+ }
178
+ }
170
179
  }
171
180
  addParagraph(paragraph) {
172
181
  this.bodyElements.push(paragraph);
@@ -258,12 +267,12 @@ class Document {
258
267
  this.updateRelationships();
259
268
  this.updateContentTypesWithImagesHeadersFootersAndComments();
260
269
  await this.zipHandler.save(tempPath);
261
- const { promises: fs } = await Promise.resolve().then(() => __importStar(require('fs')));
270
+ const { promises: fs } = await Promise.resolve().then(() => __importStar(require("fs")));
262
271
  await fs.rename(tempPath, filePath);
263
272
  }
264
273
  catch (error) {
265
274
  try {
266
- const { promises: fs } = await Promise.resolve().then(() => __importStar(require('fs')));
275
+ const { promises: fs } = await Promise.resolve().then(() => __importStar(require("fs")));
267
276
  await fs.unlink(tempPath);
268
277
  }
269
278
  catch {
@@ -307,7 +316,7 @@ class Document {
307
316
  }
308
317
  }
309
318
  updateDocumentXml() {
310
- const xml = this.generator.generateDocumentXml(this.bodyElements, this.section);
319
+ const xml = this.generator.generateDocumentXml(this.bodyElements, this.section, this.namespaces);
311
320
  this.zipHandler.updateFile(types_1.DOCX_PATHS.DOCUMENT, xml);
312
321
  }
313
322
  updateCoreProps() {
@@ -348,11 +357,409 @@ class Document {
348
357
  return false;
349
358
  }
350
359
  const currentProps = style.getProperties();
351
- const updatedProps = { ...currentProps, ...properties, styleId };
360
+ const updatedProps = {
361
+ ...currentProps,
362
+ ...properties,
363
+ styleId,
364
+ paragraphFormatting: properties.paragraphFormatting
365
+ ? {
366
+ ...currentProps.paragraphFormatting,
367
+ ...properties.paragraphFormatting,
368
+ spacing: properties.paragraphFormatting.spacing
369
+ ? {
370
+ ...currentProps.paragraphFormatting?.spacing,
371
+ ...properties.paragraphFormatting.spacing,
372
+ }
373
+ : currentProps.paragraphFormatting?.spacing,
374
+ indentation: properties.paragraphFormatting.indentation
375
+ ? {
376
+ ...currentProps.paragraphFormatting?.indentation,
377
+ ...properties.paragraphFormatting.indentation,
378
+ }
379
+ : currentProps.paragraphFormatting?.indentation,
380
+ }
381
+ : currentProps.paragraphFormatting,
382
+ runFormatting: properties.runFormatting
383
+ ? { ...currentProps.runFormatting, ...properties.runFormatting }
384
+ : currentProps.runFormatting,
385
+ };
352
386
  const updatedStyle = Style_1.Style.create(updatedProps);
353
387
  this.stylesManager.addStyle(updatedStyle);
354
388
  return true;
355
389
  }
390
+ applyStyleToAll(styleId, predicate) {
391
+ let count = 0;
392
+ for (const element of this.bodyElements) {
393
+ if (predicate(element)) {
394
+ if (element instanceof Paragraph_1.Paragraph) {
395
+ element.setStyle(styleId);
396
+ count++;
397
+ }
398
+ }
399
+ }
400
+ for (const table of this.getTables()) {
401
+ for (const row of table.getRows()) {
402
+ for (const cell of row.getCells()) {
403
+ for (const para of cell.getParagraphs()) {
404
+ if (predicate(para)) {
405
+ para.setStyle(styleId);
406
+ count++;
407
+ }
408
+ }
409
+ }
410
+ }
411
+ }
412
+ return count;
413
+ }
414
+ findElementsByStyle(styleId) {
415
+ const results = [];
416
+ for (const element of this.bodyElements) {
417
+ if (element instanceof Paragraph_1.Paragraph) {
418
+ const formatting = element.getFormatting();
419
+ if (formatting.style === styleId) {
420
+ results.push(element);
421
+ }
422
+ }
423
+ }
424
+ for (const table of this.getTables()) {
425
+ for (const row of table.getRows()) {
426
+ for (const cell of row.getCells()) {
427
+ for (const para of cell.getParagraphs()) {
428
+ const formatting = para.getFormatting();
429
+ if (formatting.style === styleId) {
430
+ results.push(para);
431
+ }
432
+ }
433
+ const hasStyledParagraph = cell
434
+ .getParagraphs()
435
+ .some((p) => p.getFormatting().style === styleId);
436
+ if (hasStyledParagraph) {
437
+ results.push(cell);
438
+ }
439
+ }
440
+ }
441
+ }
442
+ return results;
443
+ }
444
+ applyStyleToAllParagraphsWithStyle(currentStyleId, newStyleId) {
445
+ let count = 0;
446
+ for (const element of this.bodyElements) {
447
+ if (element instanceof Paragraph_1.Paragraph) {
448
+ const formatting = element.getFormatting();
449
+ if (formatting.style === currentStyleId) {
450
+ element.setStyle(newStyleId);
451
+ count++;
452
+ }
453
+ }
454
+ }
455
+ for (const table of this.getTables()) {
456
+ for (const row of table.getRows()) {
457
+ for (const cell of row.getCells()) {
458
+ for (const para of cell.getParagraphs()) {
459
+ const formatting = para.getFormatting();
460
+ if (formatting.style === currentStyleId) {
461
+ para.setStyle(newStyleId);
462
+ count++;
463
+ }
464
+ }
465
+ }
466
+ }
467
+ }
468
+ return count;
469
+ }
470
+ applyStyleToAllParagraphs(styleId, options) {
471
+ let count = 0;
472
+ const clearFormatting = options?.clearFormatting || false;
473
+ const clearProperties = options?.clearProperties;
474
+ const currentStyleId = options?.currentStyleId;
475
+ const applyToParagraph = (para) => {
476
+ const formatting = para.getFormatting();
477
+ if (currentStyleId !== undefined && formatting.style !== currentStyleId) {
478
+ return;
479
+ }
480
+ if (clearFormatting) {
481
+ para.applyStyleAndClearFormatting(styleId, clearProperties === undefined ? [] : clearProperties);
482
+ }
483
+ else {
484
+ para.setStyle(styleId);
485
+ }
486
+ count++;
487
+ };
488
+ for (const element of this.bodyElements) {
489
+ if (element instanceof Paragraph_1.Paragraph) {
490
+ applyToParagraph(element);
491
+ }
492
+ }
493
+ for (const table of this.getTables()) {
494
+ for (const row of table.getRows()) {
495
+ for (const cell of row.getCells()) {
496
+ for (const para of cell.getParagraphs()) {
497
+ applyToParagraph(para);
498
+ }
499
+ }
500
+ }
501
+ }
502
+ return count;
503
+ }
504
+ updateAllHyperlinkColors(color) {
505
+ const hyperlinks = this.getHyperlinks();
506
+ for (const { hyperlink } of hyperlinks) {
507
+ const currentFormatting = hyperlink.getFormatting();
508
+ hyperlink.setFormatting({
509
+ ...currentFormatting,
510
+ color: color,
511
+ });
512
+ }
513
+ return hyperlinks.length;
514
+ }
515
+ setAllTablesLayout(layout) {
516
+ const tables = this.getTables();
517
+ for (const table of tables) {
518
+ table.setLayout(layout);
519
+ }
520
+ return tables.length;
521
+ }
522
+ applyTableFormattingBySize(singleCellShading, multiCellFirstRowShading) {
523
+ const tables = this.getTables();
524
+ let singleCellCount = 0;
525
+ let multiCellCount = 0;
526
+ for (const table of tables) {
527
+ const rowCount = table.getRowCount();
528
+ const colCount = table.getColumnCount();
529
+ if (rowCount === 1 && colCount === 1) {
530
+ const cell = table.getCell(0, 0);
531
+ if (cell) {
532
+ cell.setShading({ fill: singleCellShading });
533
+ singleCellCount++;
534
+ }
535
+ }
536
+ else {
537
+ const firstRow = table.getRow(0);
538
+ if (firstRow) {
539
+ for (const cell of firstRow.getCells()) {
540
+ cell.setShading({ fill: multiCellFirstRowShading });
541
+ }
542
+ multiCellCount++;
543
+ }
544
+ }
545
+ }
546
+ return { singleCellCount, multiCellCount };
547
+ }
548
+ fixTODHyperlinks() {
549
+ let count = 0;
550
+ if (!this.hasBookmark("_top")) {
551
+ const paragraphs = this.getParagraphs();
552
+ if (paragraphs.length > 0) {
553
+ const firstPara = paragraphs[0];
554
+ if (firstPara) {
555
+ const bookmark = new Bookmark_1.Bookmark({ name: "_top" });
556
+ const registered = this.bookmarkManager.register(bookmark);
557
+ firstPara.addBookmark(registered);
558
+ }
559
+ }
560
+ }
561
+ const hyperlinks = this.getHyperlinks();
562
+ for (const { hyperlink, paragraph } of hyperlinks) {
563
+ const text = hyperlink.getText().toLowerCase();
564
+ if (text.includes("top") && text.includes("document")) {
565
+ hyperlink.setText("Top of the Document");
566
+ hyperlink.setFormatting({
567
+ font: "Verdana",
568
+ size: 12,
569
+ underline: "single",
570
+ color: "0000FF",
571
+ });
572
+ hyperlink.setAnchor("_top");
573
+ paragraph.setAlignment("right");
574
+ count++;
575
+ }
576
+ }
577
+ return count;
578
+ }
579
+ setIfColumnWidth() {
580
+ let count = 0;
581
+ const tables = this.getTables();
582
+ for (const table of tables) {
583
+ const columnCount = table.getColumnCount();
584
+ if (columnCount < 2)
585
+ continue;
586
+ let hasIfColumn = false;
587
+ const rows = table.getRows();
588
+ for (const row of rows) {
589
+ const cells = row.getCells();
590
+ const firstCell = cells[0];
591
+ if (firstCell) {
592
+ const text = firstCell.getText().toLowerCase();
593
+ if (text.includes("if")) {
594
+ hasIfColumn = true;
595
+ break;
596
+ }
597
+ }
598
+ }
599
+ if (hasIfColumn) {
600
+ const tableWidth = table.getFormatting().width || 12960;
601
+ const targetWidth = Math.round(tableWidth * 0.05);
602
+ for (const row of rows) {
603
+ const cells = row.getCells();
604
+ const firstCell = cells[0];
605
+ if (firstCell) {
606
+ firstCell.setWidth(targetWidth);
607
+ count++;
608
+ }
609
+ }
610
+ }
611
+ }
612
+ return count;
613
+ }
614
+ centerLargeImages(minPixels = 100) {
615
+ let count = 0;
616
+ const minEmus = Math.round(minPixels * 9525);
617
+ const images = this.imageManager.getAllImages();
618
+ const largeImageIds = new Set();
619
+ for (const entry of images) {
620
+ const image = entry.image;
621
+ const width = image.getWidth();
622
+ const height = image.getHeight();
623
+ if (width >= minEmus && height >= minEmus) {
624
+ const relId = image.getRelationshipId();
625
+ if (relId) {
626
+ largeImageIds.add(relId);
627
+ }
628
+ }
629
+ }
630
+ for (const paragraph of this.getParagraphs()) {
631
+ const content = paragraph.getContent();
632
+ for (const item of content) {
633
+ if (item instanceof ImageRun_1.ImageRun) {
634
+ const image = item.getImageElement();
635
+ const relId = image.getRelationshipId();
636
+ if (relId && largeImageIds.has(relId)) {
637
+ paragraph.setAlignment("center");
638
+ count++;
639
+ break;
640
+ }
641
+ }
642
+ }
643
+ }
644
+ return count;
645
+ }
646
+ setListLineSpacing(spacingTwips = 240) {
647
+ let count = 0;
648
+ for (const paragraph of this.getParagraphs()) {
649
+ const numbering = paragraph.getNumbering();
650
+ if (numbering) {
651
+ paragraph.setLineSpacing(spacingTwips, "auto");
652
+ count++;
653
+ }
654
+ }
655
+ return count;
656
+ }
657
+ normalizeNumberedLists() {
658
+ let count = 0;
659
+ const standardNumId = this.numberingManager.createNumberedList(3, [
660
+ "decimal",
661
+ "lowerLetter",
662
+ "lowerRoman",
663
+ ]);
664
+ const paragraphs = this.getParagraphs();
665
+ const numberedParas = [];
666
+ for (const para of paragraphs) {
667
+ const numbering = para.getNumbering();
668
+ if (!numbering)
669
+ continue;
670
+ const instance = this.numberingManager.getInstance(numbering.numId);
671
+ if (!instance)
672
+ continue;
673
+ const abstractNum = this.numberingManager.getAbstractNumbering(instance.getAbstractNumId());
674
+ if (!abstractNum)
675
+ continue;
676
+ const level0 = abstractNum.getLevel(0);
677
+ if (!level0)
678
+ continue;
679
+ const format = level0.getFormat();
680
+ if (format !== "bullet") {
681
+ numberedParas.push({ para, level: numbering.level });
682
+ }
683
+ }
684
+ for (const { para, level } of numberedParas) {
685
+ para.setNumbering(standardNumId, level);
686
+ count++;
687
+ }
688
+ this.cleanupUnusedNumbering();
689
+ return count;
690
+ }
691
+ normalizeBulletLists() {
692
+ let count = 0;
693
+ const standardNumId = this.numberingManager.createBulletList(3, [
694
+ "•",
695
+ "○",
696
+ "■",
697
+ ]);
698
+ const paragraphs = this.getParagraphs();
699
+ const bulletParas = [];
700
+ for (const para of paragraphs) {
701
+ const numbering = para.getNumbering();
702
+ if (!numbering)
703
+ continue;
704
+ const instance = this.numberingManager.getInstance(numbering.numId);
705
+ if (!instance)
706
+ continue;
707
+ const abstractNum = this.numberingManager.getAbstractNumbering(instance.getAbstractNumId());
708
+ if (!abstractNum)
709
+ continue;
710
+ const level0 = abstractNum.getLevel(0);
711
+ if (!level0)
712
+ continue;
713
+ const format = level0.getFormat();
714
+ if (format === "bullet") {
715
+ bulletParas.push({ para, level: numbering.level });
716
+ }
717
+ }
718
+ for (const { para, level } of bulletParas) {
719
+ para.setNumbering(standardNumId, level);
720
+ count++;
721
+ }
722
+ this.cleanupUnusedNumbering();
723
+ return count;
724
+ }
725
+ cleanupUnusedNumbering() {
726
+ const usedNumIds = new Set();
727
+ const paragraphs = this.getParagraphs();
728
+ for (const para of paragraphs) {
729
+ const numbering = para.getNumbering();
730
+ if (numbering) {
731
+ usedNumIds.add(numbering.numId);
732
+ }
733
+ }
734
+ this.numberingManager.cleanupUnusedNumbering(usedNumIds);
735
+ }
736
+ removeAllHeadersFooters() {
737
+ let totalCount = 0;
738
+ const headerRels = this.relationshipManager.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
739
+ const footerRels = this.relationshipManager.getRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
740
+ for (const rel of [...headerRels, ...footerRels]) {
741
+ this.relationshipManager.removeRelationship(rel.getId());
742
+ totalCount++;
743
+ }
744
+ const allFiles = this.zipHandler.getFilePaths();
745
+ const headerFooterFiles = allFiles.filter((path) => path.match(/^word\/(header|footer)\d+\.xml$/i));
746
+ for (const filePath of headerFooterFiles) {
747
+ this.zipHandler.removeFile(filePath);
748
+ }
749
+ this.headerFooterManager.clear();
750
+ const section = this.section;
751
+ const sectionProps = section.properties;
752
+ if (sectionProps.headers) {
753
+ sectionProps.headers = {};
754
+ }
755
+ if (sectionProps.footers) {
756
+ sectionProps.footers = {};
757
+ }
758
+ if (sectionProps.titlePage) {
759
+ sectionProps.titlePage = false;
760
+ }
761
+ return totalCount;
762
+ }
356
763
  getStylesXml() {
357
764
  const stylesFile = this.zipHandler.getFileAsString(types_1.DOCX_PATHS.STYLES);
358
765
  return stylesFile || this.stylesManager.generateStylesXml();
@@ -376,6 +783,16 @@ class Document {
376
783
  createMultiLevelList() {
377
784
  return this.numberingManager.createMultiLevelList();
378
785
  }
786
+ getStandardIndentation(level) {
787
+ return this.numberingManager.getStandardIndentation(level);
788
+ }
789
+ setListIndentation(numId, level, leftIndent, hangingIndent) {
790
+ this.numberingManager.setListIndentation(numId, level, leftIndent, hangingIndent);
791
+ return this;
792
+ }
793
+ normalizeAllListIndentation() {
794
+ return this.numberingManager.normalizeAllListIndentation();
795
+ }
379
796
  getSection() {
380
797
  return this.section;
381
798
  }
@@ -398,39 +815,39 @@ class Document {
398
815
  setHeader(header) {
399
816
  const relationship = this.relationshipManager.addHeader(`${header.getFilename(1)}`);
400
817
  this.headerFooterManager.registerHeader(header, relationship.getId());
401
- this.section.setHeaderReference('default', relationship.getId());
818
+ this.section.setHeaderReference("default", relationship.getId());
402
819
  return this;
403
820
  }
404
821
  setFirstPageHeader(header) {
405
822
  this.section.setTitlePage(true);
406
823
  const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
407
824
  this.headerFooterManager.registerHeader(header, relationship.getId());
408
- this.section.setHeaderReference('first', relationship.getId());
825
+ this.section.setHeaderReference("first", relationship.getId());
409
826
  return this;
410
827
  }
411
828
  setEvenPageHeader(header) {
412
829
  const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
413
830
  this.headerFooterManager.registerHeader(header, relationship.getId());
414
- this.section.setHeaderReference('even', relationship.getId());
831
+ this.section.setHeaderReference("even", relationship.getId());
415
832
  return this;
416
833
  }
417
834
  setFooter(footer) {
418
835
  const relationship = this.relationshipManager.addFooter(`${footer.getFilename(1)}`);
419
836
  this.headerFooterManager.registerFooter(footer, relationship.getId());
420
- this.section.setFooterReference('default', relationship.getId());
837
+ this.section.setFooterReference("default", relationship.getId());
421
838
  return this;
422
839
  }
423
840
  setFirstPageFooter(footer) {
424
841
  this.section.setTitlePage(true);
425
842
  const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
426
843
  this.headerFooterManager.registerFooter(footer, relationship.getId());
427
- this.section.setFooterReference('first', relationship.getId());
844
+ this.section.setFooterReference("first", relationship.getId());
428
845
  return this;
429
846
  }
430
847
  setEvenPageFooter(footer) {
431
848
  const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
432
849
  this.headerFooterManager.registerFooter(footer, relationship.getId());
433
- this.section.setFooterReference('even', relationship.getId());
850
+ this.section.setFooterReference("even", relationship.getId());
434
851
  return this;
435
852
  }
436
853
  getHeaderFooterManager() {
@@ -447,7 +864,7 @@ class Document {
447
864
  return this;
448
865
  }
449
866
  createImageRun(image) {
450
- return new ImageRun(image);
867
+ return new ImageRun_1.ImageRun(image);
451
868
  }
452
869
  getImageManager() {
453
870
  return this.imageManager;
@@ -486,17 +903,17 @@ class Document {
486
903
  }
487
904
  updateRelationships() {
488
905
  const xml = this.relationshipManager.generateXml();
489
- this.zipHandler.updateFile('word/_rels/document.xml.rels', xml);
906
+ this.zipHandler.updateFile("word/_rels/document.xml.rels", xml);
490
907
  }
491
908
  saveComments() {
492
909
  if (this.commentManager.getCount() > 0) {
493
910
  const xml = this.commentManager.generateCommentsXml();
494
- this.zipHandler.addFile('word/comments.xml', xml);
911
+ this.zipHandler.addFile("word/comments.xml", xml);
495
912
  this.relationshipManager.addComments();
496
913
  }
497
914
  }
498
915
  updateContentTypesWithImagesHeadersFootersAndComments() {
499
- const contentTypes = this.generator.generateContentTypesWithImagesHeadersFootersAndComments(this.imageManager, this.headerFooterManager, this.commentManager);
916
+ const contentTypes = this.generator.generateContentTypesWithImagesHeadersFootersAndComments(this.imageManager, this.headerFooterManager, this.commentManager, this.zipHandler);
500
917
  this.zipHandler.updateFile(types_1.DOCX_PATHS.CONTENT_TYPES, contentTypes);
501
918
  }
502
919
  getBookmarkManager() {
@@ -515,7 +932,7 @@ class Document {
515
932
  return this.bookmarkManager.hasBookmark(name);
516
933
  }
517
934
  addBookmarkToParagraph(paragraph, bookmarkOrName) {
518
- const bookmark = typeof bookmarkOrName === 'string'
935
+ const bookmark = typeof bookmarkOrName === "string"
519
936
  ? this.createBookmark(bookmarkOrName)
520
937
  : bookmarkOrName;
521
938
  paragraph.addBookmark(bookmark);
@@ -537,12 +954,12 @@ class Document {
537
954
  return this.revisionManager.register(revision);
538
955
  }
539
956
  trackInsertion(paragraph, author, text, date) {
540
- const revision = this.createRevisionFromText('insert', author, text, date);
957
+ const revision = this.createRevisionFromText("insert", author, text, date);
541
958
  paragraph.addRevision(revision);
542
959
  return revision;
543
960
  }
544
961
  trackDeletion(paragraph, author, text, date) {
545
- const revision = this.createRevisionFromText('delete', author, text, date);
962
+ const revision = this.createRevisionFromText("delete", author, text, date);
546
963
  paragraph.addRevision(revision);
547
964
  return revision;
548
965
  }
@@ -568,7 +985,7 @@ class Document {
568
985
  return this.commentManager.getAllComments();
569
986
  }
570
987
  addCommentToParagraph(paragraph, commentOrAuthor, content, initials) {
571
- const comment = typeof commentOrAuthor === 'string'
988
+ const comment = typeof commentOrAuthor === "string"
572
989
  ? this.createComment(commentOrAuthor, content, initials)
573
990
  : commentOrAuthor;
574
991
  paragraph.addComment(comment);
@@ -627,7 +1044,7 @@ class Document {
627
1044
  updates.push({
628
1045
  hyperlink: content,
629
1046
  newUrl,
630
- relationshipId: content.getRelationshipId()
1047
+ relationshipId: content.getRelationshipId(),
631
1048
  });
632
1049
  }
633
1050
  }
@@ -666,9 +1083,13 @@ class Document {
666
1083
  if (!file) {
667
1084
  return null;
668
1085
  }
1086
+ let content = file.content;
1087
+ if (!file.isBinary && Buffer.isBuffer(file.content)) {
1088
+ content = file.content.toString('utf-8');
1089
+ }
669
1090
  return {
670
1091
  name: partName,
671
- content: file.content,
1092
+ content,
672
1093
  contentType: this.getContentTypeForPart(partName),
673
1094
  isBinary: file.isBinary,
674
1095
  size: file.size,
@@ -694,7 +1115,7 @@ class Document {
694
1115
  async getContentTypes() {
695
1116
  const contentTypes = new Map();
696
1117
  try {
697
- const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
1118
+ const contentTypesXml = this.zipHandler.getFileAsString("[Content_Types].xml");
698
1119
  if (!contentTypesXml) {
699
1120
  return contentTypes;
700
1121
  }
@@ -722,11 +1143,11 @@ class Document {
722
1143
  if (!part) {
723
1144
  return null;
724
1145
  }
725
- if (typeof part.content === 'string') {
1146
+ if (typeof part.content === "string") {
726
1147
  return part.content;
727
1148
  }
728
1149
  if (Buffer.isBuffer(part.content)) {
729
- return part.content.toString('utf8');
1150
+ return part.content.toString("utf8");
730
1151
  }
731
1152
  return null;
732
1153
  }
@@ -753,39 +1174,41 @@ class Document {
753
1174
  return xmlMap;
754
1175
  }
755
1176
  async setRawXml(partName, xmlContent) {
756
- if (typeof xmlContent !== 'string') {
757
- throw new Error('XML content must be a string');
1177
+ if (typeof xmlContent !== "string") {
1178
+ throw new Error("XML content must be a string");
758
1179
  }
759
1180
  await this.setPart(partName, xmlContent);
760
1181
  }
761
1182
  async addContentType(partNameOrExtension, contentType) {
762
1183
  try {
763
- let contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
1184
+ let contentTypesXml = this.zipHandler.getFileAsString("[Content_Types].xml");
764
1185
  if (!contentTypesXml) {
765
1186
  return false;
766
1187
  }
767
- const isExtension = partNameOrExtension.startsWith('.');
1188
+ const isExtension = partNameOrExtension.startsWith(".");
768
1189
  if (isExtension) {
769
1190
  const extension = partNameOrExtension.substring(1);
770
- const existingPattern = new RegExp(`<Default\\s+Extension="${extension}"\\s+ContentType="[^"]+"/?>`, 'g');
1191
+ const existingPattern = new RegExp(`<Default\\s+Extension="${extension}"\\s+ContentType="[^"]+"/?>`, "g");
771
1192
  if (existingPattern.test(contentTypesXml)) {
772
1193
  contentTypesXml = contentTypesXml.replace(existingPattern, `<Default Extension="${extension}" ContentType="${contentType}"/>`);
773
1194
  }
774
1195
  else {
775
- contentTypesXml = contentTypesXml.replace('</Types>', ` <Default Extension="${extension}" ContentType="${contentType}"/>\n</Types>`);
1196
+ contentTypesXml = contentTypesXml.replace("</Types>", ` <Default Extension="${extension}" ContentType="${contentType}"/>\n</Types>`);
776
1197
  }
777
1198
  }
778
1199
  else {
779
- const partName = partNameOrExtension.startsWith('/') ? partNameOrExtension : `/${partNameOrExtension}`;
780
- const existingPattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="[^"]+"/?>`, 'g');
1200
+ const partName = partNameOrExtension.startsWith("/")
1201
+ ? partNameOrExtension
1202
+ : `/${partNameOrExtension}`;
1203
+ const existingPattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"\\s+ContentType="[^"]+"/?>`, "g");
781
1204
  if (existingPattern.test(contentTypesXml)) {
782
1205
  contentTypesXml = contentTypesXml.replace(existingPattern, `<Override PartName="${partName}" ContentType="${contentType}"/>`);
783
1206
  }
784
1207
  else {
785
- contentTypesXml = contentTypesXml.replace('</Types>', ` <Override PartName="${partName}" ContentType="${contentType}"/>\n</Types>`);
1208
+ contentTypesXml = contentTypesXml.replace("</Types>", ` <Override PartName="${partName}" ContentType="${contentType}"/>\n</Types>`);
786
1209
  }
787
1210
  }
788
- this.zipHandler.updateFile('[Content_Types].xml', contentTypesXml);
1211
+ this.zipHandler.updateFile("[Content_Types].xml", contentTypesXml);
789
1212
  return true;
790
1213
  }
791
1214
  catch (error) {
@@ -795,18 +1218,20 @@ class Document {
795
1218
  async getAllRelationships() {
796
1219
  const relationships = new Map();
797
1220
  try {
798
- const relsPaths = this.zipHandler.getFilePaths().filter(path => path.endsWith('.rels'));
1221
+ const relsPaths = this.zipHandler
1222
+ .getFilePaths()
1223
+ .filter((path) => path.endsWith(".rels"));
799
1224
  for (const relsPath of relsPaths) {
800
1225
  const relsContent = this.zipHandler.getFileAsString(relsPath);
801
1226
  if (relsContent) {
802
1227
  const rels = [];
803
- const relationshipElements = XMLParser_1.XMLParser.extractElements(relsContent, 'Relationship');
1228
+ const relationshipElements = XMLParser_1.XMLParser.extractElements(relsContent, "Relationship");
804
1229
  for (const relElement of relationshipElements) {
805
1230
  const rel = {};
806
- const id = XMLParser_1.XMLParser.extractAttribute(relElement, 'Id');
807
- const type = XMLParser_1.XMLParser.extractAttribute(relElement, 'Type');
808
- const target = XMLParser_1.XMLParser.extractAttribute(relElement, 'Target');
809
- const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement, 'TargetMode');
1231
+ const id = XMLParser_1.XMLParser.extractAttribute(relElement, "Id");
1232
+ const type = XMLParser_1.XMLParser.extractAttribute(relElement, "Type");
1233
+ const target = XMLParser_1.XMLParser.extractAttribute(relElement, "Target");
1234
+ const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement, "TargetMode");
810
1235
  if (id)
811
1236
  rel.id = id;
812
1237
  if (type)
@@ -827,7 +1252,7 @@ class Document {
827
1252
  }
828
1253
  async getRelationships(partName) {
829
1254
  try {
830
- const lastSlash = partName.lastIndexOf('/');
1255
+ const lastSlash = partName.lastIndexOf("/");
831
1256
  const relsPath = lastSlash === -1
832
1257
  ? `_rels/${partName}.rels`
833
1258
  : `${partName.substring(0, lastSlash)}/_rels/${partName.substring(lastSlash + 1)}.rels`;
@@ -836,13 +1261,13 @@ class Document {
836
1261
  return [];
837
1262
  }
838
1263
  const relationships = [];
839
- const relationshipElements = XMLParser_1.XMLParser.extractElements(relsContent, 'Relationship');
1264
+ const relationshipElements = XMLParser_1.XMLParser.extractElements(relsContent, "Relationship");
840
1265
  for (const relElement of relationshipElements) {
841
1266
  const rel = {};
842
- const id = XMLParser_1.XMLParser.extractAttribute(relElement, 'Id');
843
- const type = XMLParser_1.XMLParser.extractAttribute(relElement, 'Type');
844
- const target = XMLParser_1.XMLParser.extractAttribute(relElement, 'Target');
845
- const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement, 'TargetMode');
1267
+ const id = XMLParser_1.XMLParser.extractAttribute(relElement, "Id");
1268
+ const type = XMLParser_1.XMLParser.extractAttribute(relElement, "Type");
1269
+ const target = XMLParser_1.XMLParser.extractAttribute(relElement, "Target");
1270
+ const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement, "TargetMode");
846
1271
  if (id)
847
1272
  rel.id = id;
848
1273
  if (type)
@@ -861,18 +1286,18 @@ class Document {
861
1286
  }
862
1287
  getContentTypeForPart(partName) {
863
1288
  try {
864
- const contentTypesXml = this.zipHandler.getFileAsString('[Content_Types].xml');
1289
+ const contentTypesXml = this.zipHandler.getFileAsString("[Content_Types].xml");
865
1290
  if (!contentTypesXml) {
866
1291
  return undefined;
867
1292
  }
868
- const overridePattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s+ContentType="([^"]+)"`, 'i');
1293
+ const overridePattern = new RegExp(`<Override\\s+PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"\\s+ContentType="([^"]+)"`, "i");
869
1294
  const overrideMatch = contentTypesXml.match(overridePattern);
870
1295
  if (overrideMatch) {
871
1296
  return overrideMatch[1];
872
1297
  }
873
- const ext = partName.substring(partName.lastIndexOf('.'));
1298
+ const ext = partName.substring(partName.lastIndexOf("."));
874
1299
  if (ext) {
875
- const defaultPattern = new RegExp(`<Default\\s+Extension="${ext.substring(1)}"\\s+ContentType="([^"]+)"`, 'i');
1300
+ const defaultPattern = new RegExp(`<Default\\s+Extension="${ext.substring(1)}"\\s+ContentType="([^"]+)"`, "i");
876
1301
  const defaultMatch = contentTypesXml.match(defaultPattern);
877
1302
  if (defaultMatch) {
878
1303
  return defaultMatch[1];
@@ -901,7 +1326,7 @@ class Document {
901
1326
  const runText = run.getText();
902
1327
  const compareText = caseSensitive ? runText : runText.toLowerCase();
903
1328
  if (wholeWord) {
904
- const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
1329
+ const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, caseSensitive ? "g" : "gi");
905
1330
  let match;
906
1331
  while ((match = wordPattern.exec(runText)) !== null) {
907
1332
  results.push({
@@ -945,9 +1370,11 @@ class Document {
945
1370
  if (!run)
946
1371
  continue;
947
1372
  const runText = run.getText();
948
- const compareText = caseSensitive ? runText : runText.toLowerCase();
1373
+ const compareText = caseSensitive
1374
+ ? runText
1375
+ : runText.toLowerCase();
949
1376
  if (wholeWord) {
950
- const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
1377
+ const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, caseSensitive ? "g" : "gi");
951
1378
  let match;
952
1379
  while ((match = wordPattern.exec(runText)) !== null) {
953
1380
  results.push({
@@ -993,7 +1420,7 @@ class Document {
993
1420
  const originalText = run.getText();
994
1421
  let newText = originalText;
995
1422
  if (wholeWord) {
996
- const wordPattern = new RegExp(`\\b${find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, caseSensitive ? 'g' : 'gi');
1423
+ const wordPattern = new RegExp(`\\b${find.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, caseSensitive ? "g" : "gi");
997
1424
  const matches = originalText.match(wordPattern);
998
1425
  if (matches) {
999
1426
  replacementCount += matches.length;
@@ -1001,7 +1428,7 @@ class Document {
1001
1428
  }
1002
1429
  }
1003
1430
  else {
1004
- const searchPattern = new RegExp(find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), caseSensitive ? 'g' : 'gi');
1431
+ const searchPattern = new RegExp(find.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), caseSensitive ? "g" : "gi");
1005
1432
  const matches = originalText.match(searchPattern);
1006
1433
  if (matches) {
1007
1434
  replacementCount += matches.length;
@@ -1021,7 +1448,7 @@ class Document {
1021
1448
  for (const paragraph of paragraphs) {
1022
1449
  const text = paragraph.getText().trim();
1023
1450
  if (text) {
1024
- const words = text.split(/\s+/).filter(word => word.length > 0);
1451
+ const words = text.split(/\s+/).filter((word) => word.length > 0);
1025
1452
  totalWords += words.length;
1026
1453
  }
1027
1454
  }
@@ -1035,7 +1462,7 @@ class Document {
1035
1462
  for (const para of cellParas) {
1036
1463
  const text = para.getText().trim();
1037
1464
  if (text) {
1038
- const words = text.split(/\s+/).filter(word => word.length > 0);
1465
+ const words = text.split(/\s+/).filter((word) => word.length > 0);
1039
1466
  totalWords += words.length;
1040
1467
  }
1041
1468
  }
@@ -1053,7 +1480,7 @@ class Document {
1053
1480
  totalChars += text.length;
1054
1481
  }
1055
1482
  else {
1056
- totalChars += text.replace(/\s/g, '').length;
1483
+ totalChars += text.replace(/\s/g, "").length;
1057
1484
  }
1058
1485
  }
1059
1486
  const tables = this.getTables();
@@ -1069,7 +1496,7 @@ class Document {
1069
1496
  totalChars += text.length;
1070
1497
  }
1071
1498
  else {
1072
- totalChars += text.replace(/\s/g, '').length;
1499
+ totalChars += text.replace(/\s/g, "").length;
1073
1500
  }
1074
1501
  }
1075
1502
  }
@@ -1079,7 +1506,7 @@ class Document {
1079
1506
  }
1080
1507
  removeParagraph(paragraphOrIndex) {
1081
1508
  let index;
1082
- if (typeof paragraphOrIndex === 'number') {
1509
+ if (typeof paragraphOrIndex === "number") {
1083
1510
  index = paragraphOrIndex;
1084
1511
  }
1085
1512
  else {
@@ -1096,7 +1523,7 @@ class Document {
1096
1523
  }
1097
1524
  removeTable(tableOrIndex) {
1098
1525
  let index;
1099
- if (typeof tableOrIndex === 'number') {
1526
+ if (typeof tableOrIndex === "number") {
1100
1527
  const tables = this.getTables();
1101
1528
  if (tableOrIndex >= 0 && tableOrIndex < tables.length) {
1102
1529
  const table = tables[tableOrIndex];
@@ -1130,6 +1557,79 @@ class Document {
1130
1557
  this.bodyElements.splice(index, 0, paragraph);
1131
1558
  return this;
1132
1559
  }
1560
+ insertTableAt(index, table) {
1561
+ if (index < 0) {
1562
+ index = 0;
1563
+ }
1564
+ else if (index > this.bodyElements.length) {
1565
+ index = this.bodyElements.length;
1566
+ }
1567
+ this.bodyElements.splice(index, 0, table);
1568
+ return this;
1569
+ }
1570
+ insertTocAt(index, toc) {
1571
+ if (index < 0) {
1572
+ index = 0;
1573
+ }
1574
+ else if (index > this.bodyElements.length) {
1575
+ index = this.bodyElements.length;
1576
+ }
1577
+ this.bodyElements.splice(index, 0, toc);
1578
+ return this;
1579
+ }
1580
+ replaceParagraphAt(index, paragraph) {
1581
+ if (index >= 0 && index < this.bodyElements.length) {
1582
+ const element = this.bodyElements[index];
1583
+ if (element instanceof Paragraph_1.Paragraph) {
1584
+ this.bodyElements[index] = paragraph;
1585
+ return true;
1586
+ }
1587
+ }
1588
+ return false;
1589
+ }
1590
+ replaceTableAt(index, table) {
1591
+ if (index >= 0 && index < this.bodyElements.length) {
1592
+ const element = this.bodyElements[index];
1593
+ if (element instanceof Table_1.Table) {
1594
+ this.bodyElements[index] = table;
1595
+ return true;
1596
+ }
1597
+ }
1598
+ return false;
1599
+ }
1600
+ moveElement(fromIndex, toIndex) {
1601
+ if (fromIndex < 0 ||
1602
+ fromIndex >= this.bodyElements.length ||
1603
+ toIndex < 0 ||
1604
+ toIndex >= this.bodyElements.length) {
1605
+ return false;
1606
+ }
1607
+ const [element] = this.bodyElements.splice(fromIndex, 1);
1608
+ this.bodyElements.splice(toIndex, 0, element);
1609
+ return true;
1610
+ }
1611
+ swapElements(index1, index2) {
1612
+ if (index1 < 0 ||
1613
+ index1 >= this.bodyElements.length ||
1614
+ index2 < 0 ||
1615
+ index2 >= this.bodyElements.length) {
1616
+ return false;
1617
+ }
1618
+ const temp = this.bodyElements[index1];
1619
+ this.bodyElements[index1] = this.bodyElements[index2];
1620
+ this.bodyElements[index2] = temp;
1621
+ return true;
1622
+ }
1623
+ removeTocAt(index) {
1624
+ if (index >= 0 && index < this.bodyElements.length) {
1625
+ const element = this.bodyElements[index];
1626
+ if (element instanceof TableOfContentsElement_1.TableOfContentsElement) {
1627
+ this.bodyElements.splice(index, 1);
1628
+ return true;
1629
+ }
1630
+ }
1631
+ return false;
1632
+ }
1133
1633
  getHyperlinks() {
1134
1634
  const hyperlinks = [];
1135
1635
  for (const paragraph of this.getParagraphs()) {
@@ -1191,21 +1691,21 @@ class Document {
1191
1691
  static createEmpty() {
1192
1692
  const doc = new Document(undefined, {}, false);
1193
1693
  const zipHandler = doc.getZipHandler();
1194
- zipHandler.addFile('[Content_Types].xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1694
+ zipHandler.addFile("[Content_Types].xml", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1195
1695
  '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">\n' +
1196
1696
  ' <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>\n' +
1197
1697
  ' <Default Extension="xml" ContentType="application/xml"/>\n' +
1198
1698
  ' <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>\n' +
1199
- '</Types>');
1200
- zipHandler.addFile('_rels/.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1699
+ "</Types>");
1700
+ zipHandler.addFile("_rels/.rels", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1201
1701
  '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\n' +
1202
1702
  ' <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>\n' +
1203
- '</Relationships>');
1204
- zipHandler.addFile('word/document.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1703
+ "</Relationships>");
1704
+ zipHandler.addFile("word/document.xml", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1205
1705
  '<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">\n' +
1206
- ' <w:body/>\n' +
1207
- '</w:document>');
1208
- zipHandler.addFile('word/_rels/document.xml.rels', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1706
+ " <w:body/>\n" +
1707
+ "</w:document>");
1708
+ zipHandler.addFile("word/_rels/document.xml.rels", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n' +
1209
1709
  '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"/>');
1210
1710
  return doc;
1211
1711
  }