docxmlater 1.5.0 → 1.7.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 +176 -13
- package/dist/core/Document.d.ts +49 -1
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +520 -88
- package/dist/core/Document.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts +1 -0
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +3 -0
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/formatting/Style.d.ts +6 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +13 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/styleConfig.d.ts +47 -0
- package/dist/types/styleConfig.d.ts.map +1 -0
- package/dist/types/styleConfig.js +3 -0
- package/dist/types/styleConfig.js.map +1 -0
- package/package.json +1 -1
package/dist/core/Document.js
CHANGED
|
@@ -753,6 +753,97 @@ class Document {
|
|
|
753
753
|
}
|
|
754
754
|
return count;
|
|
755
755
|
}
|
|
756
|
+
applyStandardTableFormatting(shadingColorOrOptions) {
|
|
757
|
+
const options = typeof shadingColorOrOptions === 'string'
|
|
758
|
+
? { headerRowShading: shadingColorOrOptions }
|
|
759
|
+
: shadingColorOrOptions;
|
|
760
|
+
const autofitToWindow = options?.autofitToWindow !== false;
|
|
761
|
+
const headerRowShading = (options?.headerRowShading || 'E9E9E9').toUpperCase();
|
|
762
|
+
const headerRowFormatting = {
|
|
763
|
+
bold: options?.headerRowFormatting?.bold !== false,
|
|
764
|
+
alignment: options?.headerRowFormatting?.alignment || 'center',
|
|
765
|
+
font: options?.headerRowFormatting?.font || 'Verdana',
|
|
766
|
+
size: options?.headerRowFormatting?.size || 12,
|
|
767
|
+
color: options?.headerRowFormatting?.color || '000000',
|
|
768
|
+
spacingBefore: options?.headerRowFormatting?.spacingBefore ?? 60,
|
|
769
|
+
spacingAfter: options?.headerRowFormatting?.spacingAfter ?? 60,
|
|
770
|
+
};
|
|
771
|
+
const cellMargins = {
|
|
772
|
+
top: options?.cellMargins?.top ?? 0,
|
|
773
|
+
bottom: options?.cellMargins?.bottom ?? 0,
|
|
774
|
+
left: options?.cellMargins?.left ?? 115,
|
|
775
|
+
right: options?.cellMargins?.right ?? 115,
|
|
776
|
+
};
|
|
777
|
+
const skipSingleCellTables = options?.skipSingleCellTables !== false;
|
|
778
|
+
const conditionalReplacementColor = options?.conditionalShading?.replacementColor || headerRowShading;
|
|
779
|
+
let tablesProcessed = 0;
|
|
780
|
+
let headerRowsFormatted = 0;
|
|
781
|
+
let cellsRecolored = 0;
|
|
782
|
+
const tables = this.getAllTables();
|
|
783
|
+
for (const table of tables) {
|
|
784
|
+
const rowCount = table.getRowCount();
|
|
785
|
+
const columnCount = table.getColumnCount();
|
|
786
|
+
if (skipSingleCellTables && rowCount === 1 && columnCount === 1) {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (autofitToWindow) {
|
|
790
|
+
table.setLayout('auto');
|
|
791
|
+
}
|
|
792
|
+
const firstRow = table.getRow(0);
|
|
793
|
+
if (firstRow) {
|
|
794
|
+
for (const cell of firstRow.getCells()) {
|
|
795
|
+
cell.setShading({ fill: headerRowShading });
|
|
796
|
+
cell.setMargins(cellMargins);
|
|
797
|
+
for (const para of cell.getParagraphs()) {
|
|
798
|
+
para.setAlignment(headerRowFormatting.alignment);
|
|
799
|
+
para.setSpaceBefore(headerRowFormatting.spacingBefore);
|
|
800
|
+
para.setSpaceAfter(headerRowFormatting.spacingAfter);
|
|
801
|
+
for (const run of para.getRuns()) {
|
|
802
|
+
if (headerRowFormatting.bold)
|
|
803
|
+
run.setBold(true);
|
|
804
|
+
run.setFont(headerRowFormatting.font, headerRowFormatting.size);
|
|
805
|
+
run.setColor(headerRowFormatting.color);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
headerRowsFormatted++;
|
|
810
|
+
}
|
|
811
|
+
for (let i = 1; i < rowCount; i++) {
|
|
812
|
+
const row = table.getRow(i);
|
|
813
|
+
if (!row)
|
|
814
|
+
continue;
|
|
815
|
+
for (const cell of row.getCells()) {
|
|
816
|
+
cell.setMargins(cellMargins);
|
|
817
|
+
const currentShading = cell.getFormatting().shading;
|
|
818
|
+
const currentColor = currentShading?.fill?.toUpperCase();
|
|
819
|
+
if (currentColor &&
|
|
820
|
+
currentColor !== 'FFFFFF' &&
|
|
821
|
+
currentColor !== headerRowShading) {
|
|
822
|
+
cell.setShading({ fill: conditionalReplacementColor });
|
|
823
|
+
cellsRecolored++;
|
|
824
|
+
const applyFormatting = options?.conditionalShading?.applyFormatting !== false;
|
|
825
|
+
if (applyFormatting) {
|
|
826
|
+
for (const para of cell.getParagraphs()) {
|
|
827
|
+
para.setAlignment('center');
|
|
828
|
+
para.setSpaceBefore(60);
|
|
829
|
+
para.setSpaceAfter(60);
|
|
830
|
+
for (const run of para.getRuns()) {
|
|
831
|
+
run.setBold(true);
|
|
832
|
+
run.setFont('Verdana', 12);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
tablesProcessed++;
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
tablesProcessed,
|
|
843
|
+
headerRowsFormatted,
|
|
844
|
+
cellsRecolored,
|
|
845
|
+
};
|
|
846
|
+
}
|
|
756
847
|
centerLargeImages(minPixels = 100) {
|
|
757
848
|
let count = 0;
|
|
758
849
|
const minEmus = Math.round(minPixels * 9525);
|
|
@@ -962,6 +1053,32 @@ class Document {
|
|
|
962
1053
|
}
|
|
963
1054
|
return count;
|
|
964
1055
|
}
|
|
1056
|
+
applyStandardNumberedListFormatting() {
|
|
1057
|
+
const instances = this.numberingManager.getAllInstances();
|
|
1058
|
+
let count = 0;
|
|
1059
|
+
for (const instance of instances) {
|
|
1060
|
+
const abstractNumId = instance.getAbstractNumId();
|
|
1061
|
+
const abstractNum = this.numberingManager.getAbstractNumbering(abstractNumId);
|
|
1062
|
+
if (!abstractNum)
|
|
1063
|
+
continue;
|
|
1064
|
+
const level0 = abstractNum.getLevel(0);
|
|
1065
|
+
if (!level0 || level0.getFormat() === 'bullet')
|
|
1066
|
+
continue;
|
|
1067
|
+
for (let levelIndex = 0; levelIndex < 9; levelIndex++) {
|
|
1068
|
+
const numLevel = abstractNum.getLevel(levelIndex);
|
|
1069
|
+
if (!numLevel)
|
|
1070
|
+
continue;
|
|
1071
|
+
numLevel.setFont('Verdana');
|
|
1072
|
+
numLevel.setFontSize(24);
|
|
1073
|
+
numLevel.setLeftIndent(720 * (levelIndex + 1));
|
|
1074
|
+
numLevel.setHangingIndent(360);
|
|
1075
|
+
numLevel.setAlignment('left');
|
|
1076
|
+
}
|
|
1077
|
+
this.applyFormattingToListParagraphs(instance.getNumId());
|
|
1078
|
+
count++;
|
|
1079
|
+
}
|
|
1080
|
+
return count;
|
|
1081
|
+
}
|
|
965
1082
|
applyFormattingToListParagraphs(numId) {
|
|
966
1083
|
const paragraphs = this.getAllParagraphs();
|
|
967
1084
|
for (const para of paragraphs) {
|
|
@@ -1132,76 +1249,168 @@ class Document {
|
|
|
1132
1249
|
}
|
|
1133
1250
|
return counts;
|
|
1134
1251
|
}
|
|
1135
|
-
|
|
1252
|
+
static DEFAULT_HEADING1_CONFIG = {
|
|
1253
|
+
run: {
|
|
1254
|
+
font: 'Verdana',
|
|
1255
|
+
size: 18,
|
|
1256
|
+
bold: true,
|
|
1257
|
+
color: '000000',
|
|
1258
|
+
},
|
|
1259
|
+
paragraph: {
|
|
1260
|
+
alignment: 'left',
|
|
1261
|
+
spacing: { before: 0, after: 240, line: 240, lineRule: 'auto' },
|
|
1262
|
+
},
|
|
1263
|
+
};
|
|
1264
|
+
static DEFAULT_HEADING2_CONFIG = {
|
|
1265
|
+
run: {
|
|
1266
|
+
font: 'Verdana',
|
|
1267
|
+
size: 14,
|
|
1268
|
+
bold: true,
|
|
1269
|
+
color: '000000',
|
|
1270
|
+
},
|
|
1271
|
+
paragraph: {
|
|
1272
|
+
alignment: 'left',
|
|
1273
|
+
spacing: { before: 120, after: 120, line: 240, lineRule: 'auto' },
|
|
1274
|
+
},
|
|
1275
|
+
tableOptions: {
|
|
1276
|
+
shading: 'BFBFBF',
|
|
1277
|
+
marginTop: 0,
|
|
1278
|
+
marginBottom: 0,
|
|
1279
|
+
marginLeft: 115,
|
|
1280
|
+
marginRight: 115,
|
|
1281
|
+
tableWidthPercent: 5000,
|
|
1282
|
+
},
|
|
1283
|
+
};
|
|
1284
|
+
static DEFAULT_HEADING3_CONFIG = {
|
|
1285
|
+
run: {
|
|
1286
|
+
font: 'Verdana',
|
|
1287
|
+
size: 12,
|
|
1288
|
+
bold: true,
|
|
1289
|
+
color: '000000',
|
|
1290
|
+
},
|
|
1291
|
+
paragraph: {
|
|
1292
|
+
alignment: 'left',
|
|
1293
|
+
spacing: { before: 60, after: 60, line: 240, lineRule: 'auto' },
|
|
1294
|
+
},
|
|
1295
|
+
};
|
|
1296
|
+
static DEFAULT_NORMAL_CONFIG = {
|
|
1297
|
+
run: {
|
|
1298
|
+
font: 'Verdana',
|
|
1299
|
+
size: 12,
|
|
1300
|
+
color: '000000',
|
|
1301
|
+
},
|
|
1302
|
+
paragraph: {
|
|
1303
|
+
alignment: 'left',
|
|
1304
|
+
spacing: { before: 60, after: 60, line: 240, lineRule: 'auto' },
|
|
1305
|
+
},
|
|
1306
|
+
};
|
|
1307
|
+
static DEFAULT_LIST_PARAGRAPH_CONFIG = {
|
|
1308
|
+
run: {
|
|
1309
|
+
font: 'Verdana',
|
|
1310
|
+
size: 12,
|
|
1311
|
+
color: '000000',
|
|
1312
|
+
},
|
|
1313
|
+
paragraph: {
|
|
1314
|
+
alignment: 'left',
|
|
1315
|
+
spacing: { before: 0, after: 60, line: 240, lineRule: 'auto' },
|
|
1316
|
+
indentation: { left: 360, hanging: 360 },
|
|
1317
|
+
contextualSpacing: true,
|
|
1318
|
+
},
|
|
1319
|
+
};
|
|
1320
|
+
applyCustomFormattingToExistingStyles(options) {
|
|
1136
1321
|
const results = { heading1: false, heading2: false, heading3: false, normal: false, listParagraph: false };
|
|
1137
1322
|
const heading1 = this.stylesManager.getStyle('Heading1');
|
|
1138
1323
|
const heading2 = this.stylesManager.getStyle('Heading2');
|
|
1139
1324
|
const heading3 = this.stylesManager.getStyle('Heading3');
|
|
1140
1325
|
const normal = this.stylesManager.getStyle('Normal');
|
|
1141
1326
|
const listParagraph = this.stylesManager.getStyle('ListParagraph');
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1327
|
+
const h1Config = {
|
|
1328
|
+
run: {
|
|
1329
|
+
...(heading1?.getRunFormatting() || Document.DEFAULT_HEADING1_CONFIG.run),
|
|
1330
|
+
...options?.heading1?.run
|
|
1331
|
+
},
|
|
1332
|
+
paragraph: {
|
|
1333
|
+
...(heading1?.getParagraphFormatting() || Document.DEFAULT_HEADING1_CONFIG.paragraph),
|
|
1334
|
+
...options?.heading1?.paragraph
|
|
1335
|
+
},
|
|
1336
|
+
};
|
|
1337
|
+
const h2Config = {
|
|
1338
|
+
run: {
|
|
1339
|
+
...(heading2?.getRunFormatting() || Document.DEFAULT_HEADING2_CONFIG.run),
|
|
1340
|
+
...options?.heading2?.run
|
|
1341
|
+
},
|
|
1342
|
+
paragraph: {
|
|
1343
|
+
...(heading2?.getParagraphFormatting() || Document.DEFAULT_HEADING2_CONFIG.paragraph),
|
|
1344
|
+
...options?.heading2?.paragraph
|
|
1345
|
+
},
|
|
1346
|
+
tableOptions: {
|
|
1347
|
+
...Document.DEFAULT_HEADING2_CONFIG.tableOptions,
|
|
1348
|
+
...options?.heading2?.tableOptions
|
|
1349
|
+
},
|
|
1350
|
+
};
|
|
1351
|
+
const h3Config = {
|
|
1352
|
+
run: {
|
|
1353
|
+
...(heading3?.getRunFormatting() || Document.DEFAULT_HEADING3_CONFIG.run),
|
|
1354
|
+
...options?.heading3?.run
|
|
1355
|
+
},
|
|
1356
|
+
paragraph: {
|
|
1357
|
+
...(heading3?.getParagraphFormatting() || Document.DEFAULT_HEADING3_CONFIG.paragraph),
|
|
1358
|
+
...options?.heading3?.paragraph
|
|
1359
|
+
},
|
|
1360
|
+
};
|
|
1361
|
+
const normalConfig = {
|
|
1362
|
+
run: {
|
|
1363
|
+
...(normal?.getRunFormatting() || Document.DEFAULT_NORMAL_CONFIG.run),
|
|
1364
|
+
...options?.normal?.run
|
|
1365
|
+
},
|
|
1366
|
+
paragraph: {
|
|
1367
|
+
...(normal?.getParagraphFormatting() || Document.DEFAULT_NORMAL_CONFIG.paragraph),
|
|
1368
|
+
...options?.normal?.paragraph
|
|
1369
|
+
},
|
|
1370
|
+
};
|
|
1371
|
+
const listParaConfig = {
|
|
1372
|
+
run: {
|
|
1373
|
+
...(listParagraph?.getRunFormatting() || Document.DEFAULT_LIST_PARAGRAPH_CONFIG.run),
|
|
1374
|
+
...options?.listParagraph?.run
|
|
1375
|
+
},
|
|
1376
|
+
paragraph: {
|
|
1377
|
+
...(listParagraph?.getParagraphFormatting() || Document.DEFAULT_LIST_PARAGRAPH_CONFIG.paragraph),
|
|
1378
|
+
...options?.listParagraph?.paragraph
|
|
1379
|
+
},
|
|
1380
|
+
};
|
|
1381
|
+
if (heading1 && h1Config.run && h1Config.paragraph) {
|
|
1382
|
+
if (h1Config.run)
|
|
1383
|
+
heading1.setRunFormatting(h1Config.run);
|
|
1384
|
+
if (h1Config.paragraph)
|
|
1385
|
+
heading1.setParagraphFormatting(h1Config.paragraph);
|
|
1153
1386
|
results.heading1 = true;
|
|
1154
1387
|
}
|
|
1155
|
-
if (heading2) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
color: '000000'
|
|
1161
|
-
});
|
|
1162
|
-
heading2.setParagraphFormatting({
|
|
1163
|
-
alignment: 'left',
|
|
1164
|
-
spacing: { before: 120, after: 120, line: 240, lineRule: 'auto' }
|
|
1165
|
-
});
|
|
1388
|
+
if (heading2 && h2Config.run && h2Config.paragraph) {
|
|
1389
|
+
if (h2Config.run)
|
|
1390
|
+
heading2.setRunFormatting(h2Config.run);
|
|
1391
|
+
if (h2Config.paragraph)
|
|
1392
|
+
heading2.setParagraphFormatting(h2Config.paragraph);
|
|
1166
1393
|
results.heading2 = true;
|
|
1167
1394
|
}
|
|
1168
|
-
if (heading3) {
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
color: '000000'
|
|
1174
|
-
});
|
|
1175
|
-
heading3.setParagraphFormatting({
|
|
1176
|
-
alignment: 'left',
|
|
1177
|
-
spacing: { before: 60, after: 60, line: 240, lineRule: 'auto' }
|
|
1178
|
-
});
|
|
1395
|
+
if (heading3 && h3Config.run && h3Config.paragraph) {
|
|
1396
|
+
if (h3Config.run)
|
|
1397
|
+
heading3.setRunFormatting(h3Config.run);
|
|
1398
|
+
if (h3Config.paragraph)
|
|
1399
|
+
heading3.setParagraphFormatting(h3Config.paragraph);
|
|
1179
1400
|
results.heading3 = true;
|
|
1180
1401
|
}
|
|
1181
|
-
if (normal) {
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
});
|
|
1187
|
-
normal.setParagraphFormatting({
|
|
1188
|
-
alignment: 'left',
|
|
1189
|
-
spacing: { before: 60, after: 60, line: 240, lineRule: 'auto' }
|
|
1190
|
-
});
|
|
1402
|
+
if (normal && normalConfig.run && normalConfig.paragraph) {
|
|
1403
|
+
if (normalConfig.run)
|
|
1404
|
+
normal.setRunFormatting(normalConfig.run);
|
|
1405
|
+
if (normalConfig.paragraph)
|
|
1406
|
+
normal.setParagraphFormatting(normalConfig.paragraph);
|
|
1191
1407
|
results.normal = true;
|
|
1192
1408
|
}
|
|
1193
|
-
if (listParagraph) {
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
});
|
|
1199
|
-
listParagraph.setParagraphFormatting({
|
|
1200
|
-
alignment: 'left',
|
|
1201
|
-
spacing: { before: 0, after: 60, line: 240, lineRule: 'auto' },
|
|
1202
|
-
indentation: { left: 360, hanging: 360 },
|
|
1203
|
-
contextualSpacing: true
|
|
1204
|
-
});
|
|
1409
|
+
if (listParagraph && listParaConfig.run && listParaConfig.paragraph) {
|
|
1410
|
+
if (listParaConfig.run)
|
|
1411
|
+
listParagraph.setRunFormatting(listParaConfig.run);
|
|
1412
|
+
if (listParaConfig.paragraph)
|
|
1413
|
+
listParagraph.setParagraphFormatting(listParaConfig.paragraph);
|
|
1205
1414
|
results.listParagraph = true;
|
|
1206
1415
|
}
|
|
1207
1416
|
const processedParagraphs = new Set();
|
|
@@ -1240,30 +1449,42 @@ class Document {
|
|
|
1240
1449
|
}
|
|
1241
1450
|
const { inTable, cell } = this.isParagraphInTable(para);
|
|
1242
1451
|
if (inTable && cell) {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1452
|
+
if (h2Config.tableOptions?.shading) {
|
|
1453
|
+
cell.setShading({ fill: h2Config.tableOptions.shading });
|
|
1454
|
+
}
|
|
1455
|
+
if (h2Config.tableOptions?.marginTop !== undefined || h2Config.tableOptions?.marginBottom !== undefined ||
|
|
1456
|
+
h2Config.tableOptions?.marginLeft !== undefined || h2Config.tableOptions?.marginRight !== undefined) {
|
|
1457
|
+
cell.setMargins({
|
|
1458
|
+
top: h2Config.tableOptions.marginTop ?? 0,
|
|
1459
|
+
bottom: h2Config.tableOptions.marginBottom ?? 0,
|
|
1460
|
+
left: h2Config.tableOptions.marginLeft ?? 115,
|
|
1461
|
+
right: h2Config.tableOptions.marginRight ?? 115,
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
if (h2Config.tableOptions?.tableWidthPercent) {
|
|
1465
|
+
const table = this.getAllTables().find(t => {
|
|
1466
|
+
for (const row of t.getRows()) {
|
|
1467
|
+
for (const c of row.getCells()) {
|
|
1468
|
+
if (c === cell)
|
|
1469
|
+
return true;
|
|
1470
|
+
}
|
|
1250
1471
|
}
|
|
1472
|
+
return false;
|
|
1473
|
+
});
|
|
1474
|
+
if (table) {
|
|
1475
|
+
table.setWidth(h2Config.tableOptions.tableWidthPercent);
|
|
1476
|
+
table.setWidthType('pct');
|
|
1251
1477
|
}
|
|
1252
|
-
return false;
|
|
1253
|
-
});
|
|
1254
|
-
if (table) {
|
|
1255
|
-
table.setWidth(5000);
|
|
1256
|
-
table.setWidthType('pct');
|
|
1257
1478
|
}
|
|
1258
1479
|
}
|
|
1259
1480
|
else {
|
|
1260
1481
|
this.wrapParagraphInTable(para, {
|
|
1261
|
-
shading: 'BFBFBF',
|
|
1262
|
-
marginTop: 0,
|
|
1263
|
-
marginBottom: 0,
|
|
1264
|
-
marginLeft: 115,
|
|
1265
|
-
marginRight: 115,
|
|
1266
|
-
tableWidthPercent: 5000
|
|
1482
|
+
shading: h2Config.tableOptions?.shading ?? 'BFBFBF',
|
|
1483
|
+
marginTop: h2Config.tableOptions?.marginTop ?? 0,
|
|
1484
|
+
marginBottom: h2Config.tableOptions?.marginBottom ?? 0,
|
|
1485
|
+
marginLeft: h2Config.tableOptions?.marginLeft ?? 115,
|
|
1486
|
+
marginRight: h2Config.tableOptions?.marginRight ?? 115,
|
|
1487
|
+
tableWidthPercent: h2Config.tableOptions?.tableWidthPercent ?? 5000,
|
|
1267
1488
|
});
|
|
1268
1489
|
}
|
|
1269
1490
|
processedParagraphs.add(para);
|
|
@@ -1305,23 +1526,234 @@ class Document {
|
|
|
1305
1526
|
processedParagraphs.add(para);
|
|
1306
1527
|
}
|
|
1307
1528
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1529
|
+
return results;
|
|
1530
|
+
}
|
|
1531
|
+
applyStylesFromObjects(...styles) {
|
|
1532
|
+
const options = {};
|
|
1533
|
+
for (const style of styles) {
|
|
1534
|
+
const styleId = style.getStyleId();
|
|
1535
|
+
switch (styleId) {
|
|
1536
|
+
case 'Heading1':
|
|
1537
|
+
options.heading1 = {
|
|
1538
|
+
run: style.getRunFormatting(),
|
|
1539
|
+
paragraph: style.getParagraphFormatting(),
|
|
1540
|
+
};
|
|
1541
|
+
break;
|
|
1542
|
+
case 'Heading2':
|
|
1543
|
+
options.heading2 = {
|
|
1544
|
+
run: style.getRunFormatting(),
|
|
1545
|
+
paragraph: style.getParagraphFormatting(),
|
|
1546
|
+
tableOptions: style.getHeading2TableOptions(),
|
|
1547
|
+
};
|
|
1548
|
+
break;
|
|
1549
|
+
case 'Heading3':
|
|
1550
|
+
options.heading3 = {
|
|
1551
|
+
run: style.getRunFormatting(),
|
|
1552
|
+
paragraph: style.getParagraphFormatting(),
|
|
1553
|
+
};
|
|
1554
|
+
break;
|
|
1555
|
+
case 'Normal':
|
|
1556
|
+
options.normal = {
|
|
1557
|
+
run: style.getRunFormatting(),
|
|
1558
|
+
paragraph: style.getParagraphFormatting(),
|
|
1559
|
+
};
|
|
1560
|
+
break;
|
|
1561
|
+
case 'ListParagraph':
|
|
1562
|
+
options.listParagraph = {
|
|
1563
|
+
run: style.getRunFormatting(),
|
|
1564
|
+
paragraph: style.getParagraphFormatting(),
|
|
1565
|
+
};
|
|
1566
|
+
break;
|
|
1567
|
+
default:
|
|
1568
|
+
break;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
return this.applyCustomFormattingToExistingStyles(options);
|
|
1572
|
+
}
|
|
1573
|
+
parseTOCFieldInstruction(instrText) {
|
|
1574
|
+
const levels = new Set();
|
|
1575
|
+
const outlineMatch = instrText.match(/\\o\s+"(\d+)-(\d+)"/);
|
|
1576
|
+
if (outlineMatch && outlineMatch[1] && outlineMatch[2]) {
|
|
1577
|
+
const start = parseInt(outlineMatch[1], 10);
|
|
1578
|
+
const end = parseInt(outlineMatch[2], 10);
|
|
1579
|
+
for (let i = start; i <= end; i++) {
|
|
1580
|
+
if (i >= 1 && i <= 9) {
|
|
1581
|
+
levels.add(i);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
const styleMatches = instrText.matchAll(/\\t\s+"([^"]+)",(\d+),"/g);
|
|
1586
|
+
for (const match of styleMatches) {
|
|
1587
|
+
const styleName = match[1];
|
|
1588
|
+
const levelStr = match[2];
|
|
1589
|
+
if (!styleName || !levelStr)
|
|
1590
|
+
continue;
|
|
1591
|
+
const level = parseInt(levelStr, 10);
|
|
1592
|
+
const headingMatch = styleName.match(/Heading\s*(\d+)/i);
|
|
1593
|
+
if (headingMatch && headingMatch[1]) {
|
|
1594
|
+
const headingLevel = parseInt(headingMatch[1], 10);
|
|
1595
|
+
if (headingLevel >= 1 && headingLevel <= 9) {
|
|
1596
|
+
levels.add(headingLevel);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
else if (level >= 1 && level <= 9) {
|
|
1600
|
+
levels.add(level);
|
|
1315
1601
|
}
|
|
1316
1602
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
for (const tocElement of tocElements) {
|
|
1320
|
-
const toc = tocElement.getTableOfContents();
|
|
1321
|
-
toc.setShowPageNumbers(false);
|
|
1322
|
-
toc.setHideInWebLayout(true);
|
|
1603
|
+
if (levels.size === 0) {
|
|
1604
|
+
return [1, 2, 3];
|
|
1323
1605
|
}
|
|
1324
|
-
return
|
|
1606
|
+
return Array.from(levels).sort((a, b) => a - b);
|
|
1607
|
+
}
|
|
1608
|
+
findHeadingsForTOC(levels) {
|
|
1609
|
+
const headings = [];
|
|
1610
|
+
const levelSet = new Set(levels);
|
|
1611
|
+
for (const element of this.bodyElements) {
|
|
1612
|
+
if (element instanceof Paragraph_1.Paragraph) {
|
|
1613
|
+
const para = element;
|
|
1614
|
+
const formatting = para.getFormatting();
|
|
1615
|
+
if (formatting.style) {
|
|
1616
|
+
const styleMatch = formatting.style.match(/Heading(\d+)/i);
|
|
1617
|
+
if (styleMatch && styleMatch[1]) {
|
|
1618
|
+
const headingLevel = parseInt(styleMatch[1], 10);
|
|
1619
|
+
if (levelSet.has(headingLevel)) {
|
|
1620
|
+
const text = para.getText().trim();
|
|
1621
|
+
if (text) {
|
|
1622
|
+
const bookmark = this.bookmarkManager.createHeadingBookmark(text);
|
|
1623
|
+
headings.push({
|
|
1624
|
+
level: headingLevel,
|
|
1625
|
+
text: text,
|
|
1626
|
+
bookmark: bookmark.getName()
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
return headings;
|
|
1635
|
+
}
|
|
1636
|
+
generateTOCXML(headings, originalInstrText) {
|
|
1637
|
+
const sdtId = Math.floor(Math.random() * 2000000000) - 1000000000;
|
|
1638
|
+
let tocXml = '<w:sdt>';
|
|
1639
|
+
tocXml += '<w:sdtPr>';
|
|
1640
|
+
tocXml += `<w:id w:val="${sdtId}"/>`;
|
|
1641
|
+
tocXml += '<w:docPartObj>';
|
|
1642
|
+
tocXml += '<w:docPartGallery w:val="Table of Contents"/>';
|
|
1643
|
+
tocXml += '<w:docPartUnique w:val="1"/>';
|
|
1644
|
+
tocXml += '</w:docPartObj>';
|
|
1645
|
+
tocXml += '</w:sdtPr>';
|
|
1646
|
+
tocXml += '<w:sdtContent>';
|
|
1647
|
+
tocXml += '<w:p>';
|
|
1648
|
+
tocXml += '<w:pPr>';
|
|
1649
|
+
tocXml += '<w:spacing w:after="0" w:before="0" w:line="240" w:lineRule="auto"/>';
|
|
1650
|
+
tocXml += '</w:pPr>';
|
|
1651
|
+
tocXml += '<w:r><w:fldChar w:fldCharType="begin"/></w:r>';
|
|
1652
|
+
tocXml += '<w:r>';
|
|
1653
|
+
tocXml += `<w:instrText xml:space="preserve">${this.escapeXml(originalInstrText)}</w:instrText>`;
|
|
1654
|
+
tocXml += '</w:r>';
|
|
1655
|
+
tocXml += '<w:r><w:fldChar w:fldCharType="separate"/></w:r>';
|
|
1656
|
+
if (headings.length > 0 && headings[0]) {
|
|
1657
|
+
tocXml += this.buildTOCEntryXML(headings[0]);
|
|
1658
|
+
}
|
|
1659
|
+
tocXml += '</w:p>';
|
|
1660
|
+
for (let i = 1; i < headings.length; i++) {
|
|
1661
|
+
const heading = headings[i];
|
|
1662
|
+
if (!heading)
|
|
1663
|
+
continue;
|
|
1664
|
+
tocXml += '<w:p>';
|
|
1665
|
+
tocXml += '<w:pPr>';
|
|
1666
|
+
tocXml += '<w:spacing w:after="0" w:before="0" w:line="240" w:lineRule="auto"/>';
|
|
1667
|
+
const indent = (heading.level - 1) * 720;
|
|
1668
|
+
if (indent > 0) {
|
|
1669
|
+
tocXml += `<w:ind w:left="${indent}"/>`;
|
|
1670
|
+
}
|
|
1671
|
+
tocXml += '</w:pPr>';
|
|
1672
|
+
tocXml += this.buildTOCEntryXML(heading);
|
|
1673
|
+
tocXml += '</w:p>';
|
|
1674
|
+
}
|
|
1675
|
+
tocXml += '<w:p>';
|
|
1676
|
+
tocXml += '<w:pPr>';
|
|
1677
|
+
tocXml += '<w:spacing w:after="0" w:before="0" w:line="240" w:lineRule="auto"/>';
|
|
1678
|
+
tocXml += '</w:pPr>';
|
|
1679
|
+
tocXml += '<w:r><w:fldChar w:fldCharType="end"/></w:r>';
|
|
1680
|
+
tocXml += '</w:p>';
|
|
1681
|
+
tocXml += '</w:sdtContent>';
|
|
1682
|
+
tocXml += '</w:sdt>';
|
|
1683
|
+
return tocXml;
|
|
1684
|
+
}
|
|
1685
|
+
buildTOCEntryXML(heading) {
|
|
1686
|
+
const escapedText = this.escapeXml(heading.text);
|
|
1687
|
+
let xml = '';
|
|
1688
|
+
xml += `<w:hyperlink w:anchor="${this.escapeXml(heading.bookmark)}">`;
|
|
1689
|
+
xml += '<w:r>';
|
|
1690
|
+
xml += '<w:rPr>';
|
|
1691
|
+
xml += '<w:rFonts w:ascii="Verdana" w:hAnsi="Verdana" w:cs="Verdana" w:eastAsia="Verdana"/>';
|
|
1692
|
+
xml += '<w:color w:val="0000FF"/>';
|
|
1693
|
+
xml += '<w:sz w:val="24"/>';
|
|
1694
|
+
xml += '<w:szCs w:val="24"/>';
|
|
1695
|
+
xml += '<w:u w:val="single"/>';
|
|
1696
|
+
xml += '</w:rPr>';
|
|
1697
|
+
xml += `<w:t xml:space="preserve">${escapedText}</w:t>`;
|
|
1698
|
+
xml += '</w:r>';
|
|
1699
|
+
xml += '</w:hyperlink>';
|
|
1700
|
+
return xml;
|
|
1701
|
+
}
|
|
1702
|
+
escapeXml(text) {
|
|
1703
|
+
return text
|
|
1704
|
+
.replace(/&/g, '&')
|
|
1705
|
+
.replace(/</g, '<')
|
|
1706
|
+
.replace(/>/g, '>')
|
|
1707
|
+
.replace(/"/g, '"')
|
|
1708
|
+
.replace(/'/g, ''');
|
|
1709
|
+
}
|
|
1710
|
+
async replaceTableOfContents(filePath) {
|
|
1711
|
+
const handler = new ZipHandler_1.ZipHandler();
|
|
1712
|
+
await handler.load(filePath);
|
|
1713
|
+
const docXml = handler.getFileAsString('word/document.xml');
|
|
1714
|
+
if (!docXml) {
|
|
1715
|
+
throw new Error('word/document.xml not found in document');
|
|
1716
|
+
}
|
|
1717
|
+
const tocRegex = /<w:sdt>[\s\S]*?<w:docPartGallery w:val="Table of Contents"[\s\S]*?<\/w:sdt>/g;
|
|
1718
|
+
const tocMatches = Array.from(docXml.matchAll(tocRegex));
|
|
1719
|
+
if (tocMatches.length === 0) {
|
|
1720
|
+
return 0;
|
|
1721
|
+
}
|
|
1722
|
+
let replacedCount = 0;
|
|
1723
|
+
let modifiedXml = docXml;
|
|
1724
|
+
for (const match of tocMatches) {
|
|
1725
|
+
try {
|
|
1726
|
+
const tocXml = match[0];
|
|
1727
|
+
const instrMatch = tocXml.match(/<w:instrText[^>]*>([\s\S]*?)<\/w:instrText>/);
|
|
1728
|
+
if (!instrMatch || !instrMatch[1]) {
|
|
1729
|
+
continue;
|
|
1730
|
+
}
|
|
1731
|
+
let fieldInstruction = instrMatch[1];
|
|
1732
|
+
fieldInstruction = fieldInstruction
|
|
1733
|
+
.replace(/</g, '<')
|
|
1734
|
+
.replace(/>/g, '>')
|
|
1735
|
+
.replace(/"/g, '"')
|
|
1736
|
+
.replace(/'/g, "'")
|
|
1737
|
+
.replace(/&/g, '&');
|
|
1738
|
+
const levels = this.parseTOCFieldInstruction(fieldInstruction);
|
|
1739
|
+
const headings = this.findHeadingsForTOC(levels);
|
|
1740
|
+
if (headings.length === 0) {
|
|
1741
|
+
continue;
|
|
1742
|
+
}
|
|
1743
|
+
const newTocXml = this.generateTOCXML(headings, fieldInstruction);
|
|
1744
|
+
modifiedXml = modifiedXml.replace(tocXml, newTocXml);
|
|
1745
|
+
replacedCount++;
|
|
1746
|
+
}
|
|
1747
|
+
catch (error) {
|
|
1748
|
+
console.error(`Error replacing TOC: ${error}`);
|
|
1749
|
+
continue;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
if (replacedCount > 0) {
|
|
1753
|
+
handler.updateFile('word/document.xml', modifiedXml);
|
|
1754
|
+
await handler.save(filePath);
|
|
1755
|
+
}
|
|
1756
|
+
return replacedCount;
|
|
1325
1757
|
}
|
|
1326
1758
|
getSection() {
|
|
1327
1759
|
return this.section;
|