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.
- package/README.md +330 -4
- package/dist/core/Document.d.ts +66 -28
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +590 -90
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts +15 -13
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +74 -13
- package/dist/core/DocumentGenerator.js.map +1 -1
- package/dist/core/DocumentParser.d.ts +40 -13
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +800 -316
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/DocumentValidator.d.ts +2 -1
- package/dist/core/DocumentValidator.d.ts.map +1 -1
- package/dist/core/DocumentValidator.js.map +1 -1
- package/dist/elements/Bookmark.d.ts +1 -0
- package/dist/elements/Bookmark.d.ts.map +1 -1
- package/dist/elements/Bookmark.js +1 -1
- package/dist/elements/Bookmark.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts +1 -0
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +23 -0
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/ImageManager.d.ts +2 -0
- package/dist/elements/ImageManager.d.ts.map +1 -1
- package/dist/elements/ImageManager.js +22 -0
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/ImageRun.d.ts +10 -0
- package/dist/elements/ImageRun.d.ts.map +1 -0
- package/dist/elements/ImageRun.js +23 -0
- package/dist/elements/ImageRun.js.map +1 -0
- package/dist/elements/Paragraph.d.ts +16 -1
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +146 -2
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Run.d.ts +4 -0
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +27 -1
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.d.ts.map +1 -1
- package/dist/elements/Section.js +3 -8
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/StructuredDocumentTag.d.ts +32 -0
- package/dist/elements/StructuredDocumentTag.d.ts.map +1 -0
- package/dist/elements/StructuredDocumentTag.js +94 -0
- package/dist/elements/StructuredDocumentTag.js.map +1 -0
- package/dist/elements/Table.d.ts +24 -0
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +177 -3
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts +33 -0
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +129 -1
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableRow.d.ts.map +1 -1
- package/dist/elements/TableRow.js +11 -1
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts +1 -0
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +30 -0
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingInstance.d.ts +1 -0
- package/dist/formatting/NumberingInstance.d.ts.map +1 -1
- package/dist/formatting/NumberingInstance.js +16 -0
- package/dist/formatting/NumberingInstance.js.map +1 -1
- package/dist/formatting/NumberingLevel.d.ts +1 -0
- package/dist/formatting/NumberingLevel.d.ts.map +1 -1
- package/dist/formatting/NumberingLevel.js +59 -0
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts +11 -0
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +92 -0
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts +2 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +49 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/xml/XMLBuilder.d.ts +4 -1
- package/dist/xml/XMLBuilder.d.ts.map +1 -1
- package/dist/xml/XMLBuilder.js +134 -31
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/xml/XMLParser.d.ts +1 -0
- package/dist/xml/XMLParser.d.ts.map +1 -1
- package/dist/xml/XMLParser.js +75 -42
- package/dist/xml/XMLParser.js.map +1 -1
- package/dist/zip/ZipHandler.d.ts.map +1 -1
- package/dist/zip/ZipHandler.js +6 -1
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.d.ts.map +1 -1
- package/dist/zip/ZipReader.js +2 -2
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/ZipWriter.d.ts.map +1 -1
- package/dist/zip/ZipWriter.js +13 -8
- package/dist/zip/ZipWriter.js.map +1 -1
- package/package.json +1 -1
package/dist/core/Document.js
CHANGED
|
@@ -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
|
|
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(
|
|
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(
|
|
160
|
-
this.zipHandler.addFile(
|
|
161
|
-
this.zipHandler.addFile(
|
|
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(
|
|
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(
|
|
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 = {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 ===
|
|
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(
|
|
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(
|
|
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 ===
|
|
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
|
|
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(
|
|
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 ===
|
|
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(
|
|
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 !==
|
|
757
|
-
throw new Error(
|
|
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(
|
|
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="[^"]+"/?>`,
|
|
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(
|
|
1196
|
+
contentTypesXml = contentTypesXml.replace("</Types>", ` <Default Extension="${extension}" ContentType="${contentType}"/>\n</Types>`);
|
|
776
1197
|
}
|
|
777
1198
|
}
|
|
778
1199
|
else {
|
|
779
|
-
const partName = partNameOrExtension.startsWith(
|
|
780
|
-
|
|
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(
|
|
1208
|
+
contentTypesXml = contentTypesXml.replace("</Types>", ` <Override PartName="${partName}" ContentType="${contentType}"/>\n</Types>`);
|
|
786
1209
|
}
|
|
787
1210
|
}
|
|
788
|
-
this.zipHandler.updateFile(
|
|
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
|
|
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,
|
|
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,
|
|
807
|
-
const type = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
808
|
-
const target = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
809
|
-
const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
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,
|
|
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,
|
|
843
|
-
const type = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
844
|
-
const target = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
845
|
-
const targetMode = XMLParser_1.XMLParser.extractAttribute(relElement,
|
|
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(
|
|
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,
|
|
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="([^"]+)"`,
|
|
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,
|
|
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
|
|
1373
|
+
const compareText = caseSensitive
|
|
1374
|
+
? runText
|
|
1375
|
+
: runText.toLowerCase();
|
|
949
1376
|
if (wholeWord) {
|
|
950
|
-
const wordPattern = new RegExp(`\\b${searchText.replace(/[.*+?^${}()|[\]\\]/g,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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 ===
|
|
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 ===
|
|
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(
|
|
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
|
-
|
|
1200
|
-
zipHandler.addFile(
|
|
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
|
-
|
|
1204
|
-
zipHandler.addFile(
|
|
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
|
-
|
|
1207
|
-
|
|
1208
|
-
zipHandler.addFile(
|
|
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
|
}
|