@stll/folio-core 0.8.0 → 0.9.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 +39 -0
- package/dist/ai-edits/apply.js +18 -4
- package/dist/ai-edits/headless.d.ts +31 -4
- package/dist/ai-edits/headless.js +148 -35
- package/dist/ai-edits/index.d.ts +3 -3
- package/dist/ai-edits/index.js +2 -1
- package/dist/ai-edits/snapshot.js +40 -3
- package/dist/ai-edits/types.d.ts +2 -1
- package/dist/compat/eigenpal.d.ts +6 -4
- package/dist/compat/eigenpal.js +5 -3
- package/dist/controller/latestRequestGate.d.ts +13 -0
- package/dist/controller/latestRequestGate.js +16 -0
- package/dist/controller/layoutPipeline.js +12 -1
- package/dist/document-operations.d.ts +10 -3
- package/dist/document-operations.js +29 -14
- package/dist/docx/blockContentParser.js +2 -2
- package/dist/docx/commentParser.js +1 -1
- package/dist/docx/compatibility.d.ts +3 -7
- package/dist/docx/compatibility.js +0 -11
- package/dist/docx/encryption/agileDecryption.js +1 -1
- package/dist/docx/encryption/encryptionInfo.js +1 -1
- package/dist/docx/encryption/openEncryptedDocx.js +1 -1
- package/dist/docx/fontTableParser.d.ts +6 -0
- package/dist/docx/fontTableParser.js +72 -0
- package/dist/docx/groupDrawingParser.js +7 -2
- package/dist/docx/headerFooterParser.js +1 -1
- package/dist/docx/normalizeBaseDirection.js +1 -1
- package/dist/docx/numberingParser.js +1 -0
- package/dist/docx/paragraphParser.js +12 -1
- package/dist/docx/parser.d.ts +1 -1
- package/dist/docx/parser.js +12 -9
- package/dist/docx/rezip.js +70 -5
- package/dist/docx/runConsolidator.js +4 -0
- package/dist/docx/runParser.js +19 -1
- package/dist/docx/selectiveSave.js +3 -3
- package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
- package/dist/docx/serializer/fontTableSerializer.js +26 -0
- package/dist/docx/serializer/headerFooterSerializer.js +1 -1
- package/dist/docx/serializer/paragraphSerializer.js +4 -0
- package/dist/docx/serializer/runSerializer.js +7 -0
- package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
- package/dist/docx/serializer/settingsSerializer.js +16 -0
- package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
- package/dist/docx/serializer/stylesSerializer.js +56 -0
- package/dist/docx/serializer/tableSerializer.js +25 -26
- package/dist/docx/serializer/themeSerializer.d.ts +6 -0
- package/dist/docx/serializer/themeSerializer.js +36 -0
- package/dist/docx/settingsParser.js +46 -0
- package/dist/docx/styleParser.js +26 -1
- package/dist/docx/tableParser.js +11 -1
- package/dist/docx/vmlImageParser.js +1 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
- package/dist/i18n/messages/catalogs.gen.js +5910 -5910
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -3
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
- package/dist/layout-bridge/convert/headerFooterLayout.js +6 -1
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +51 -14
- package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
- package/dist/layout-bridge/engine/measuring/index.js +2 -1
- package/dist/layout-engine/index.js +36 -28
- package/dist/layout-engine/measure/cache.js +11 -3
- package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
- package/dist/layout-engine/measure/index.d.ts +2 -1
- package/dist/layout-engine/measure/index.js +2 -1
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
- package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
- package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
- package/dist/layout-engine/measure/lineBreaks.js +11 -18
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
- package/dist/layout-engine/measure/listMarkerWidth.js +12 -6
- package/dist/layout-engine/measure/measureBlocks.d.ts +1 -2
- package/dist/layout-engine/measure/measureBlocks.js +6 -36
- package/dist/layout-engine/measure/measureContainer.js +32 -9
- package/dist/layout-engine/measure/measureHelpers.js +5 -2
- package/dist/layout-engine/measure/measureParagraph.js +335 -72
- package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
- package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
- package/dist/layout-engine/measure/measureWorker.js +8 -19
- package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
- package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
- package/dist/layout-engine/measure/tableCellFloating.js +37 -29
- package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
- package/dist/layout-engine/measure/tableCellFlow.js +73 -0
- package/dist/layout-engine/measure/tableCellGrid.js +1 -1
- package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
- package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
- package/dist/layout-engine/renderedBreakReconciliation.d.ts +6 -1
- package/dist/layout-engine/renderedBreakReconciliation.js +34 -11
- package/dist/layout-engine/tableRowBreak.d.ts +5 -2
- package/dist/layout-engine/tableRowBreak.js +62 -29
- package/dist/layout-engine/types.d.ts +40 -7
- package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
- package/dist/layout-painter/anchoredImagePosition.js +95 -0
- package/dist/layout-painter/borderStroke.d.ts +23 -0
- package/dist/layout-painter/borderStroke.js +39 -0
- package/dist/layout-painter/renderImage.d.ts +5 -4
- package/dist/layout-painter/renderImage.js +18 -4
- package/dist/layout-painter/renderPage.d.ts +2 -27
- package/dist/layout-painter/renderPage.js +13 -99
- package/dist/layout-painter/renderParagraph.js +41 -23
- package/dist/layout-painter/renderTable.d.ts +2 -0
- package/dist/layout-painter/renderTable.js +223 -43
- package/dist/managers/DocumentLoaderManager.d.ts +1 -1
- package/dist/managers/DocumentLoaderManager.js +2 -2
- package/dist/prosemirror/attrs/index.d.ts +4 -2
- package/dist/prosemirror/attrs/index.js +21 -2
- package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
- package/dist/prosemirror/conversion/fromProseDoc.js +33 -18
- package/dist/prosemirror/conversion/toProseDoc.js +50 -18
- package/dist/prosemirror/extensions/StarterKit.js +2 -0
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +7 -2
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
- package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
- package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
- package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
- package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
- package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
- package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
- package/dist/prosemirror/schema/index.d.ts +2 -2
- package/dist/prosemirror/schema/marks.d.ts +6 -1
- package/dist/prosemirror/schema/nodes.d.ts +13 -11
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
- package/dist/prosemirror/utils/tabCalculator.js +12 -10
- package/dist/prosemirror/validation.js +4 -1
- package/dist/redline.js +13 -3
- package/dist/server.d.ts +6 -3
- package/dist/server.js +5 -2
- package/dist/style-sets/extract.d.ts +35 -0
- package/dist/style-sets/extract.js +123 -0
- package/dist/style-sets/stellaStyle.d.ts +13 -0
- package/dist/style-sets/stellaStyle.js +516 -0
- package/dist/style-sets/types.d.ts +31 -0
- package/dist/style-sets/types.js +5 -0
- package/dist/utils/createDocument.d.ts +12 -2
- package/dist/utils/createDocument.js +42 -31
- package/dist/utils/fontResolver.js +6 -6
- package/dist/utils/formatToStyle.js +1 -1
- package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
- package/dist/utils/paragraphFormattingMerge.js +14 -4
- package/package.json +5 -1
- package/dist/docx/capabilities.d.ts +0 -41
- package/dist/docx/capabilities.js +0 -322
package/dist/docx/rezip.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { applyReplyThreadMarkers } from "./commentReplyMarkers.js";
|
|
2
1
|
import { RELATIONSHIP_TYPES, parseRelationships, resolveRelativePath } from "./relsParser.js";
|
|
2
|
+
import { parseNumbering } from "./numberingParser.js";
|
|
3
3
|
import { parseEndnotes, parseFootnotes } from "./footnoteParser.js";
|
|
4
4
|
import { assertValidFolioDocumentModel } from "./modelValidation.js";
|
|
5
|
-
import {
|
|
5
|
+
import { isPreservableDocxEntry } from "./unzip.js";
|
|
6
|
+
import { applyReplyThreadMarkers } from "./commentReplyMarkers.js";
|
|
6
7
|
import { buildPatchedNoteXml, buildPatchedNumberingXml, collectChangedNumberingDefs, collectParaIds, extractParagraphXml } from "./selectiveXmlPatch.js";
|
|
7
8
|
import { escapeXml } from "./serializer/xmlUtils.js";
|
|
8
9
|
import { ensureThreadedCommentParaIds, serializeComments, serializeCommentsExtended } from "./serializer/commentSerializer.js";
|
|
@@ -10,7 +11,10 @@ import { serializeDocument } from "./serializer/documentSerializer.js";
|
|
|
10
11
|
import { serializeHeaderFooter } from "./serializer/headerFooterSerializer.js";
|
|
11
12
|
import { serializeEndnotes, serializeFootnotes } from "./serializer/noteSerializer.js";
|
|
12
13
|
import { serializeNumberingXml } from "./serializer/numberingSerializer.js";
|
|
13
|
-
import {
|
|
14
|
+
import { serializeFontTableXml } from "./serializer/fontTableSerializer.js";
|
|
15
|
+
import { serializeSettingsXml } from "./serializer/settingsSerializer.js";
|
|
16
|
+
import { serializeStylesXml } from "./serializer/stylesSerializer.js";
|
|
17
|
+
import { serializeThemeXml } from "./serializer/themeSerializer.js";
|
|
14
18
|
import { panic } from "better-result";
|
|
15
19
|
import JSZip from "jszip";
|
|
16
20
|
//#region src/docx/rezip.ts
|
|
@@ -1169,7 +1173,7 @@ function createEmptyDocx() {
|
|
|
1169
1173
|
zip.file("docProps/app.xml", `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1170
1174
|
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
|
|
1171
1175
|
<Application>EigenPal DOCX Editor</Application>
|
|
1172
|
-
<AppVersion>1.
|
|
1176
|
+
<AppVersion>1.0000</AppVersion>
|
|
1173
1177
|
</Properties>`);
|
|
1174
1178
|
return zip.generateAsync({
|
|
1175
1179
|
type: "arraybuffer",
|
|
@@ -1184,11 +1188,72 @@ function createEmptyDocx() {
|
|
|
1184
1188
|
* @returns Promise resolving to DOCX as ArrayBuffer
|
|
1185
1189
|
*/
|
|
1186
1190
|
async function createDocx(doc) {
|
|
1187
|
-
const emptyBuffer = await
|
|
1191
|
+
const emptyBuffer = await createDocumentSeedDocx(doc);
|
|
1188
1192
|
return repackDocx({
|
|
1189
1193
|
...doc,
|
|
1190
1194
|
originalBuffer: emptyBuffer
|
|
1191
1195
|
});
|
|
1192
1196
|
}
|
|
1197
|
+
const createDocumentSeedDocx = async (doc) => {
|
|
1198
|
+
const buffer = await createEmptyDocx();
|
|
1199
|
+
const zip = await JSZip.loadAsync(buffer);
|
|
1200
|
+
const relationships = ["<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>"];
|
|
1201
|
+
const overrides = [];
|
|
1202
|
+
let nextRelationshipId = 2;
|
|
1203
|
+
if (doc.package.styles) {
|
|
1204
|
+
assertStyleNumberingReferences(doc);
|
|
1205
|
+
zip.file("word/styles.xml", serializeStylesXml(doc.package.styles));
|
|
1206
|
+
}
|
|
1207
|
+
const numbering = doc.package.numbering;
|
|
1208
|
+
if (numbering && (numbering.abstractNums.length > 0 || numbering.nums.length > 0)) {
|
|
1209
|
+
zip.file("word/numbering.xml", serializeNumberingXml(numbering));
|
|
1210
|
+
relationships.push(relationshipXml(nextRelationshipId, "numbering", "numbering.xml"));
|
|
1211
|
+
overrides.push(overrideXml("/word/numbering.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"));
|
|
1212
|
+
nextRelationshipId += 1;
|
|
1213
|
+
}
|
|
1214
|
+
if (doc.package.theme) {
|
|
1215
|
+
zip.file("word/theme/theme1.xml", serializeThemeXml(doc.package.theme));
|
|
1216
|
+
relationships.push(relationshipXml(nextRelationshipId, "theme", "theme/theme1.xml"));
|
|
1217
|
+
overrides.push(overrideXml("/word/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml"));
|
|
1218
|
+
nextRelationshipId += 1;
|
|
1219
|
+
}
|
|
1220
|
+
if (doc.package.fontTable && doc.package.fontTable.fonts.length > 0) {
|
|
1221
|
+
zip.file("word/fontTable.xml", serializeFontTableXml(doc.package.fontTable));
|
|
1222
|
+
relationships.push(relationshipXml(nextRelationshipId, "fontTable", "fontTable.xml"));
|
|
1223
|
+
overrides.push(overrideXml("/word/fontTable.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"));
|
|
1224
|
+
nextRelationshipId += 1;
|
|
1225
|
+
}
|
|
1226
|
+
if (doc.package.settings) {
|
|
1227
|
+
zip.file("word/settings.xml", serializeSettingsXml(doc.package.settings));
|
|
1228
|
+
relationships.push(relationshipXml(nextRelationshipId, "settings", "settings.xml"));
|
|
1229
|
+
overrides.push(overrideXml("/word/settings.xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"));
|
|
1230
|
+
}
|
|
1231
|
+
zip.file("word/_rels/document.xml.rels", `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${relationships.join("")}</Relationships>`);
|
|
1232
|
+
if (overrides.length > 0) {
|
|
1233
|
+
const contentTypesFile = zip.file("[Content_Types].xml");
|
|
1234
|
+
if (!contentTypesFile) panic("Fresh DOCX seed is missing [Content_Types].xml");
|
|
1235
|
+
const contentTypes = await contentTypesFile.async("string");
|
|
1236
|
+
zip.file("[Content_Types].xml", contentTypes.replace("</Types>", `${overrides.join("")}\n</Types>`));
|
|
1237
|
+
}
|
|
1238
|
+
return zip.generateAsync({
|
|
1239
|
+
type: "arraybuffer",
|
|
1240
|
+
compression: "DEFLATE",
|
|
1241
|
+
compressionOptions: { level: 6 }
|
|
1242
|
+
});
|
|
1243
|
+
};
|
|
1244
|
+
const relationshipXml = (id, type, target) => `<Relationship Id="rId${id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/${type}" Target="${target}"/>`;
|
|
1245
|
+
const overrideXml = (partName, contentType) => `<Override PartName="${partName}" ContentType="${contentType}"/>`;
|
|
1246
|
+
const assertStyleNumberingReferences = (doc) => {
|
|
1247
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
1248
|
+
for (const style of doc.package.styles?.styles ?? []) {
|
|
1249
|
+
const numId = style.pPr?.numPr?.numId;
|
|
1250
|
+
if (numId !== void 0) referenced.add(numId);
|
|
1251
|
+
}
|
|
1252
|
+
if (referenced.size === 0) return;
|
|
1253
|
+
const available = new Set(doc.package.numbering?.nums.map((numbering) => numbering.numId) ?? []);
|
|
1254
|
+
for (const numId of referenced) if (!available.has(numId)) panic(`Style references missing numbering definition ${numId}`);
|
|
1255
|
+
const availableAbstract = new Set(doc.package.numbering?.abstractNums.map((numbering) => numbering.abstractNumId) ?? []);
|
|
1256
|
+
for (const numbering of doc.package.numbering?.nums ?? []) if (!availableAbstract.has(numbering.abstractNumId)) panic(`Numbering definition ${numbering.numId} references missing abstract numbering`);
|
|
1257
|
+
};
|
|
1193
1258
|
//#endregion
|
|
1194
1259
|
export { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_CONTENT_TYPE, COMMENTS_EXTENDED_PART, COMMENTS_EXTENDED_PART_LOWER, DocxPackageFidelityError, addCommentsExtendedOverride, addCommentsExtendedRelationship, addMedia, addRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, createDocx, createEmptyDocx, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, isDocxBuffer, removeCommentsExtendedOverride, removeCommentsExtendedRelationship, repackDocx, repackDocxFromRaw, updateCoreProperties, updateDocumentXml, updateMultipleFiles, updateXmlFile, validateDocx };
|
|
@@ -38,8 +38,12 @@ function formattingEquals(a, b) {
|
|
|
38
38
|
if (!colorEquals(a.color, b.color)) return false;
|
|
39
39
|
if (!shadingEquals(a.shading, b.shading)) return false;
|
|
40
40
|
if (!fontFamilyEquals(a.fontFamily, b.fontFamily)) return false;
|
|
41
|
+
if (!languageEquals(a.language, b.language)) return false;
|
|
41
42
|
return true;
|
|
42
43
|
}
|
|
44
|
+
function languageEquals(a, b) {
|
|
45
|
+
return a?.val === b?.val && a?.eastAsia === b?.eastAsia && a?.bidi === b?.bidi;
|
|
46
|
+
}
|
|
43
47
|
/**
|
|
44
48
|
* Compare underline settings
|
|
45
49
|
*/
|
package/dist/docx/runParser.js
CHANGED
|
@@ -89,6 +89,9 @@ function collectFirstRunPropertyChildren(rPr) {
|
|
|
89
89
|
case "kern":
|
|
90
90
|
children.kern ??= child;
|
|
91
91
|
break;
|
|
92
|
+
case "lang":
|
|
93
|
+
children.lang ??= child;
|
|
94
|
+
break;
|
|
92
95
|
case "outline":
|
|
93
96
|
children.outline ??= child;
|
|
94
97
|
break;
|
|
@@ -262,6 +265,17 @@ function parseRunProperties(rPr, theme, _styles) {
|
|
|
262
265
|
}
|
|
263
266
|
formatting.fontFamily = fontFamily;
|
|
264
267
|
}
|
|
268
|
+
const lang = propertyChildren.lang;
|
|
269
|
+
if (lang) {
|
|
270
|
+
const val = getAttribute(lang, "w", "val") || void 0;
|
|
271
|
+
const eastAsia = getAttribute(lang, "w", "eastAsia") || void 0;
|
|
272
|
+
const bidi = getAttribute(lang, "w", "bidi") || void 0;
|
|
273
|
+
if (val || eastAsia || bidi) formatting.language = {
|
|
274
|
+
...val ? { val } : {},
|
|
275
|
+
...eastAsia ? { eastAsia } : {},
|
|
276
|
+
...bidi ? { bidi } : {}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
265
279
|
const spacing = propertyChildren.spacing;
|
|
266
280
|
if (spacing) {
|
|
267
281
|
const val = parseNumericAttribute(spacing, "w", "val");
|
|
@@ -531,7 +545,11 @@ function parseRunContents(runElement, rels, media, rootXmlns = {}) {
|
|
|
531
545
|
if (vmlDrawing) contents.push(vmlDrawing);
|
|
532
546
|
break;
|
|
533
547
|
}
|
|
534
|
-
case "object":
|
|
548
|
+
case "object": {
|
|
549
|
+
const objectPreview = parseVmlImageContent(child, rels, media, rootXmlns);
|
|
550
|
+
if (objectPreview) contents.push(objectPreview);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
535
553
|
case "rPr": break;
|
|
536
554
|
case "lastRenderedPageBreak": break;
|
|
537
555
|
case "cr":
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { hasUnsynthesizedReplyRanges } from "./commentReplyMarkers.js";
|
|
2
1
|
import { RELATIONSHIP_TYPES } from "./relsParser.js";
|
|
3
|
-
import {
|
|
2
|
+
import { parseCommentsExtended } from "./commentParser.js";
|
|
4
3
|
import { parseNumbering } from "./numberingParser.js";
|
|
4
|
+
import { validateFolioDocumentModel } from "./modelValidation.js";
|
|
5
|
+
import { hasUnsynthesizedReplyRanges } from "./commentReplyMarkers.js";
|
|
5
6
|
import { buildPatchedDocumentXml, buildPatchedNoteXml, buildPatchedNumberingXml, collectChangedNumberingDefs, collectParaIds } from "./selectiveXmlPatch.js";
|
|
6
7
|
import { ensureThreadedCommentParaIds, serializeComments, serializeCommentsExtended } from "./serializer/commentSerializer.js";
|
|
7
8
|
import { serializeDocument } from "./serializer/documentSerializer.js";
|
|
8
9
|
import { serializeEndnotes, serializeFootnotes } from "./serializer/noteSerializer.js";
|
|
9
10
|
import { serializeNumberingXml } from "./serializer/numberingSerializer.js";
|
|
10
11
|
import { COMMENTS_CONTENT_TYPE, COMMENTS_EXTENDED_PART_LOWER, addCommentsExtendedOverride, addCommentsExtendedRelationship, applyUpdatesToZip, collectHeaderFooterUpdates, findMaxRId, hasModelDrivenPictureWatermark, hasUnmaterializedHeaderFooter, updateCoreProperties } from "./rezip.js";
|
|
11
|
-
import { parseCommentsExtended } from "./commentParser.js";
|
|
12
12
|
import "./selectiveSaveFlags.js";
|
|
13
13
|
//#region src/docx/selectiveSave.ts
|
|
14
14
|
const SYNTHETIC_IMAGE_RID_PREFIX = "rId_img_";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { escapeXml } from "./xmlUtils.js";
|
|
2
|
+
//#region src/docx/serializer/fontTableSerializer.ts
|
|
3
|
+
const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
4
|
+
const serializeFontTableXml = (fontTable) => {
|
|
5
|
+
const fonts = fontTable.fonts.map(serializeFont).join("");
|
|
6
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:fonts xmlns:w="${W_NS}">${fonts}</w:fonts>`;
|
|
7
|
+
};
|
|
8
|
+
const serializeFont = (font) => {
|
|
9
|
+
const parts = [];
|
|
10
|
+
if (font.altName) parts.push(`<w:altName w:val="${escapeXml(font.altName)}"/>`);
|
|
11
|
+
if (font.panose1) parts.push(`<w:panose1 w:val="${escapeXml(font.panose1)}"/>`);
|
|
12
|
+
if (font.charset) parts.push(`<w:charset w:val="${escapeXml(font.charset)}"/>`);
|
|
13
|
+
if (font.family) parts.push(`<w:family w:val="${font.family}"/>`);
|
|
14
|
+
if (font.pitch) parts.push(`<w:pitch w:val="${font.pitch}"/>`);
|
|
15
|
+
if (font.sig) {
|
|
16
|
+
const attrs = [];
|
|
17
|
+
for (const [key, value] of Object.entries(font.sig)) {
|
|
18
|
+
if (value === void 0) continue;
|
|
19
|
+
attrs.push(`w:${key}="${escapeXml(value)}"`);
|
|
20
|
+
}
|
|
21
|
+
if (attrs.length > 0) parts.push(`<w:sig ${attrs.join(" ")}/>`);
|
|
22
|
+
}
|
|
23
|
+
return `<w:font w:name="${escapeXml(font.name)}">${parts.join("")}</w:font>`;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { serializeFontTableXml };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { canReplayHeaderFooterVerbatim, getHeaderFooterVerbatimXml } from "../headerFooterVerbatim.js";
|
|
1
2
|
import { escapeXml } from "./xmlUtils.js";
|
|
2
3
|
import { serializeBlockSdt } from "./blockSdtSerializer.js";
|
|
3
4
|
import { serializeParagraph } from "./paragraphSerializer.js";
|
|
4
5
|
import { serializeTable } from "./tableSerializer.js";
|
|
5
|
-
import { canReplayHeaderFooterVerbatim, getHeaderFooterVerbatimXml } from "../headerFooterVerbatim.js";
|
|
6
6
|
//#region src/docx/serializer/headerFooterSerializer.ts
|
|
7
7
|
const NAMESPACES = {
|
|
8
8
|
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
|
@@ -165,6 +165,8 @@ function serializeParagraphFormatting(formatting, propertyChanges, pPrMark) {
|
|
|
165
165
|
if (tabsXml) parts.push(tabsXml);
|
|
166
166
|
pushToggle("suppressLineNumbers", formatting.suppressLineNumbers);
|
|
167
167
|
pushToggle("suppressAutoHyphens", formatting.suppressAutoHyphens);
|
|
168
|
+
pushToggle("kinsoku", formatting.kinsoku);
|
|
169
|
+
pushToggle("overflowPunct", formatting.overflowPunctuation);
|
|
168
170
|
const spacingXml = serializeSpacing(formatting);
|
|
169
171
|
if (spacingXml) parts.push(spacingXml);
|
|
170
172
|
const indXml = serializeIndentation(formatting);
|
|
@@ -350,6 +352,8 @@ function serializeInlineSdt(sdt) {
|
|
|
350
352
|
case "simpleField": return serializeSimpleField(item);
|
|
351
353
|
case "complexField": return serializeComplexField(item);
|
|
352
354
|
case "inlineSdt": return serializeInlineSdt(item);
|
|
355
|
+
case "insertion": return serializeTrackedChange("ins", item);
|
|
356
|
+
case "deletion": return serializeTrackedChange("del", item);
|
|
353
357
|
case "mathEquation": return item.ommlXml || "";
|
|
354
358
|
default: return item;
|
|
355
359
|
}
|
|
@@ -85,6 +85,13 @@ function serializeTextFormatting(formatting) {
|
|
|
85
85
|
if (formatting.fontFamily.csTheme) fontAttrs.push(`w:cstheme="${formatting.fontFamily.csTheme}"`);
|
|
86
86
|
if (fontAttrs.length > 0) parts.push(`<w:rFonts ${fontAttrs.join(" ")}/>`);
|
|
87
87
|
}
|
|
88
|
+
if (formatting.language) {
|
|
89
|
+
const languageAttrs = [];
|
|
90
|
+
if (formatting.language.val) languageAttrs.push(`w:val="${escapeXml(formatting.language.val)}"`);
|
|
91
|
+
if (formatting.language.eastAsia) languageAttrs.push(`w:eastAsia="${escapeXml(formatting.language.eastAsia)}"`);
|
|
92
|
+
if (formatting.language.bidi) languageAttrs.push(`w:bidi="${escapeXml(formatting.language.bidi)}"`);
|
|
93
|
+
if (languageAttrs.length > 0) parts.push(`<w:lang ${languageAttrs.join(" ")}/>`);
|
|
94
|
+
}
|
|
88
95
|
if (formatting.bold === true) parts.push("<w:b/>");
|
|
89
96
|
else if (formatting.bold === false) parts.push("<w:b w:val=\"0\"/>");
|
|
90
97
|
if (formatting.boldCs === true) parts.push("<w:bCs/>");
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { escapeXml, intAttr } from "./xmlUtils.js";
|
|
2
|
+
//#region src/docx/serializer/settingsSerializer.ts
|
|
3
|
+
const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
4
|
+
const serializeSettingsXml = (settings) => {
|
|
5
|
+
const parts = [`<w:defaultTabStop w:val="${intAttr(settings.defaultTabStop)}"/>`];
|
|
6
|
+
if (settings.evenAndOddHeaders) parts.push("<w:evenAndOddHeaders/>");
|
|
7
|
+
if (settings.themeFontLang) {
|
|
8
|
+
const attrs = [];
|
|
9
|
+
if (settings.themeFontLang.eastAsia) attrs.push(`w:eastAsia="${escapeXml(settings.themeFontLang.eastAsia)}"`);
|
|
10
|
+
if (settings.themeFontLang.bidi) attrs.push(`w:bidi="${escapeXml(settings.themeFontLang.bidi)}"`);
|
|
11
|
+
if (attrs.length > 0) parts.push(`<w:themeFontLang ${attrs.join(" ")}/>`);
|
|
12
|
+
}
|
|
13
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:settings xmlns:w="${W_NS}">${parts.join("")}</w:settings>`;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { serializeSettingsXml };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { escapeXml } from "./xmlUtils.js";
|
|
2
|
+
import { serializeTextFormatting } from "./runSerializer.js";
|
|
3
|
+
import { serializeParagraphFormatting } from "./paragraphSerializer.js";
|
|
4
|
+
import { serializeTableCellFormatting, serializeTableFormatting, serializeTableRowFormatting } from "./tableSerializer.js";
|
|
5
|
+
//#region src/docx/serializer/stylesSerializer.ts
|
|
6
|
+
const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
7
|
+
const serializeStylesXml = (definitions) => {
|
|
8
|
+
const docDefaults = serializeDocumentDefaults(definitions);
|
|
9
|
+
const latentStyles = serializeLatentStyles(definitions);
|
|
10
|
+
const styles = definitions.styles.map(serializeStyle).join("");
|
|
11
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<w:styles xmlns:w="${W_NS}">${docDefaults}${latentStyles}${styles}</w:styles>`;
|
|
12
|
+
};
|
|
13
|
+
const serializeDocumentDefaults = (definitions) => {
|
|
14
|
+
return `<w:docDefaults><w:rPrDefault>${serializeTextFormatting(definitions.docDefaults?.rPr) || "<w:rPr/>"}</w:rPrDefault><w:pPrDefault>${serializeParagraphFormatting(definitions.docDefaults?.pPr) || "<w:pPr/>"}</w:pPrDefault></w:docDefaults>`;
|
|
15
|
+
};
|
|
16
|
+
const serializeLatentStyles = (definitions) => {
|
|
17
|
+
const latent = definitions.latentStyles;
|
|
18
|
+
if (!latent) return "";
|
|
19
|
+
const attrs = [];
|
|
20
|
+
pushBooleanAttr(attrs, "w:defLockedState", latent.defLockedState);
|
|
21
|
+
if (latent.defUIPriority !== void 0) attrs.push(`w:defUIPriority="${latent.defUIPriority}"`);
|
|
22
|
+
pushBooleanAttr(attrs, "w:defSemiHidden", latent.defSemiHidden);
|
|
23
|
+
pushBooleanAttr(attrs, "w:defUnhideWhenUsed", latent.defUnhideWhenUsed);
|
|
24
|
+
pushBooleanAttr(attrs, "w:defQFormat", latent.defQFormat);
|
|
25
|
+
return `<w:latentStyles${attrs.length > 0 ? ` ${attrs.join(" ")}` : ""}/>`;
|
|
26
|
+
};
|
|
27
|
+
const serializeStyle = (style) => {
|
|
28
|
+
const attrs = [`w:type="${style.type}"`, `w:styleId="${escapeXml(style.styleId)}"`];
|
|
29
|
+
if (style.default) attrs.push("w:default=\"1\"");
|
|
30
|
+
const parts = [`<w:name w:val="${escapeXml(style.name ?? style.styleId)}"/>`];
|
|
31
|
+
if (style.basedOn) parts.push(`<w:basedOn w:val="${escapeXml(style.basedOn)}"/>`);
|
|
32
|
+
if (style.next) parts.push(`<w:next w:val="${escapeXml(style.next)}"/>`);
|
|
33
|
+
if (style.link) parts.push(`<w:link w:val="${escapeXml(style.link)}"/>`);
|
|
34
|
+
if (style.uiPriority !== void 0) parts.push(`<w:uiPriority w:val="${style.uiPriority}"/>`);
|
|
35
|
+
pushBooleanElement(parts, "hidden", style.hidden);
|
|
36
|
+
pushBooleanElement(parts, "semiHidden", style.semiHidden);
|
|
37
|
+
pushBooleanElement(parts, "unhideWhenUsed", style.unhideWhenUsed);
|
|
38
|
+
pushBooleanElement(parts, "qFormat", style.qFormat);
|
|
39
|
+
pushBooleanElement(parts, "personal", style.personal);
|
|
40
|
+
parts.push(serializeParagraphFormatting(style.pPr));
|
|
41
|
+
parts.push(serializeTextFormatting(style.rPr));
|
|
42
|
+
parts.push(serializeTableFormatting(style.tblPr));
|
|
43
|
+
parts.push(serializeTableRowFormatting(style.trPr));
|
|
44
|
+
parts.push(serializeTableCellFormatting(style.tcPr));
|
|
45
|
+
for (const conditional of style.tblStylePr ?? []) parts.push(`<w:tblStylePr w:type="${conditional.type}">${serializeParagraphFormatting(conditional.pPr)}${serializeTextFormatting(conditional.rPr)}${serializeTableFormatting(conditional.tblPr)}${serializeTableRowFormatting(conditional.trPr)}${serializeTableCellFormatting(conditional.tcPr)}</w:tblStylePr>`);
|
|
46
|
+
return `<w:style ${attrs.join(" ")}>${parts.join("")}</w:style>`;
|
|
47
|
+
};
|
|
48
|
+
const pushBooleanElement = (parts, name, value) => {
|
|
49
|
+
if (value === true) parts.push(`<w:${name}/>`);
|
|
50
|
+
else if (value === false) parts.push(`<w:${name} w:val="0"/>`);
|
|
51
|
+
};
|
|
52
|
+
const pushBooleanAttr = (attrs, name, value) => {
|
|
53
|
+
if (value !== void 0) attrs.push(`${name}="${value ? 1 : 0}"`);
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { serializeStylesXml };
|
|
@@ -30,36 +30,35 @@ function serializeMeasurement(measurement, elementName) {
|
|
|
30
30
|
/**
|
|
31
31
|
* Serialize table borders (w:tblBorders or w:tcBorders)
|
|
32
32
|
*/
|
|
33
|
+
function serializeTableBorderParts(borders) {
|
|
34
|
+
const parts = [];
|
|
35
|
+
const appendBorder = (border, name) => {
|
|
36
|
+
const xml = serializeBorder(border, name);
|
|
37
|
+
if (xml) parts.push(xml);
|
|
38
|
+
};
|
|
39
|
+
appendBorder(borders.top, "top");
|
|
40
|
+
appendBorder(borders.left, "left");
|
|
41
|
+
appendBorder(borders.bottom, "bottom");
|
|
42
|
+
appendBorder(borders.right, "right");
|
|
43
|
+
appendBorder(borders.insideH, "insideH");
|
|
44
|
+
appendBorder(borders.insideV, "insideV");
|
|
45
|
+
return parts;
|
|
46
|
+
}
|
|
33
47
|
function serializeTableBorders(borders, elementName) {
|
|
34
48
|
if (!borders) return "";
|
|
35
|
-
const parts =
|
|
36
|
-
if (borders.top) {
|
|
37
|
-
const topXml = serializeBorder(borders.top, "top");
|
|
38
|
-
if (topXml) parts.push(topXml);
|
|
39
|
-
}
|
|
40
|
-
if (borders.left) {
|
|
41
|
-
const leftXml = serializeBorder(borders.left, "left");
|
|
42
|
-
if (leftXml) parts.push(leftXml);
|
|
43
|
-
}
|
|
44
|
-
if (borders.bottom) {
|
|
45
|
-
const bottomXml = serializeBorder(borders.bottom, "bottom");
|
|
46
|
-
if (bottomXml) parts.push(bottomXml);
|
|
47
|
-
}
|
|
48
|
-
if (borders.right) {
|
|
49
|
-
const rightXml = serializeBorder(borders.right, "right");
|
|
50
|
-
if (rightXml) parts.push(rightXml);
|
|
51
|
-
}
|
|
52
|
-
if (borders.insideH) {
|
|
53
|
-
const insideHXml = serializeBorder(borders.insideH, "insideH");
|
|
54
|
-
if (insideHXml) parts.push(insideHXml);
|
|
55
|
-
}
|
|
56
|
-
if (borders.insideV) {
|
|
57
|
-
const insideVXml = serializeBorder(borders.insideV, "insideV");
|
|
58
|
-
if (insideVXml) parts.push(insideVXml);
|
|
59
|
-
}
|
|
49
|
+
const parts = serializeTableBorderParts(borders);
|
|
60
50
|
if (parts.length === 0) return "";
|
|
61
51
|
return `<w:${elementName}>${parts.join("")}</w:${elementName}>`;
|
|
62
52
|
}
|
|
53
|
+
function serializeTableCellBorders(borders) {
|
|
54
|
+
if (!borders) return "";
|
|
55
|
+
const parts = serializeTableBorderParts(borders);
|
|
56
|
+
const topLeftToBottomRight = serializeBorder(borders.topLeftToBottomRight, "tl2br");
|
|
57
|
+
if (topLeftToBottomRight) parts.push(topLeftToBottomRight);
|
|
58
|
+
const topRightToBottomLeft = serializeBorder(borders.topRightToBottomLeft, "tr2bl");
|
|
59
|
+
if (topRightToBottomLeft) parts.push(topRightToBottomLeft);
|
|
60
|
+
return parts.length > 0 ? `<w:tcBorders>${parts.join("")}</w:tcBorders>` : "";
|
|
61
|
+
}
|
|
63
62
|
/**
|
|
64
63
|
* Serialize cell margins (w:tblCellMar or w:tcMar)
|
|
65
64
|
*/
|
|
@@ -238,7 +237,7 @@ function serializeTableCellFormatting(formatting, propertyChanges, structuralCha
|
|
|
238
237
|
if (formatting.gridSpan && formatting.gridSpan > 1) parts.push(`<w:gridSpan w:val="${intAttr(formatting.gridSpan)}"/>`);
|
|
239
238
|
if (formatting.vMerge) if (formatting.vMerge === "restart") parts.push("<w:vMerge w:val=\"restart\"/>");
|
|
240
239
|
else parts.push("<w:vMerge/>");
|
|
241
|
-
const bordersXml =
|
|
240
|
+
const bordersXml = serializeTableCellBorders(formatting.borders);
|
|
242
241
|
if (bordersXml) parts.push(bordersXml);
|
|
243
242
|
const shadingXml = serializeShading(formatting.shading);
|
|
244
243
|
if (shadingXml) parts.push(shadingXml);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { escapeXml } from "./xmlUtils.js";
|
|
2
|
+
//#region src/docx/serializer/themeSerializer.ts
|
|
3
|
+
const A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
4
|
+
const serializeThemeXml = (theme) => {
|
|
5
|
+
const name = escapeXml(theme.name ?? "Folio Theme");
|
|
6
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<a:theme xmlns:a="${A_NS}" name="${name}"><a:themeElements>${serializeColorScheme(theme.colorScheme)}${serializeFontScheme(theme)}${serializeFormatScheme(theme)}</a:themeElements></a:theme>`;
|
|
7
|
+
};
|
|
8
|
+
const serializeColorScheme = (colors) => {
|
|
9
|
+
const values = {
|
|
10
|
+
dk1: colors?.dk1 ?? "000000",
|
|
11
|
+
lt1: colors?.lt1 ?? "FFFFFF",
|
|
12
|
+
dk2: colors?.dk2 ?? "44546A",
|
|
13
|
+
lt2: colors?.lt2 ?? "E7E6E6",
|
|
14
|
+
accent1: colors?.accent1 ?? "4472C4",
|
|
15
|
+
accent2: colors?.accent2 ?? "ED7D31",
|
|
16
|
+
accent3: colors?.accent3 ?? "A5A5A5",
|
|
17
|
+
accent4: colors?.accent4 ?? "FFC000",
|
|
18
|
+
accent5: colors?.accent5 ?? "5B9BD5",
|
|
19
|
+
accent6: colors?.accent6 ?? "70AD47",
|
|
20
|
+
hlink: colors?.hlink ?? "0563C1",
|
|
21
|
+
folHlink: colors?.folHlink ?? "954F72"
|
|
22
|
+
};
|
|
23
|
+
return `<a:clrScheme name="Folio">${Object.entries(values).map(([slot, value]) => `<a:${slot}><a:srgbClr val="${escapeXml(value)}"/></a:${slot}>`).join("")}</a:clrScheme>`;
|
|
24
|
+
};
|
|
25
|
+
const serializeFontScheme = (theme) => {
|
|
26
|
+
return `<a:fontScheme name="Folio">${serializeThemeFont(theme.fontScheme?.majorFont, "majorFont", "Arial")}${serializeThemeFont(theme.fontScheme?.minorFont, "minorFont", "Arial")}</a:fontScheme>`;
|
|
27
|
+
};
|
|
28
|
+
const serializeThemeFont = (font, element, fallback) => {
|
|
29
|
+
const scriptFonts = Object.entries(font?.fonts ?? {}).map(([script, typeface]) => `<a:font script="${escapeXml(script)}" typeface="${escapeXml(typeface)}"/>`).join("");
|
|
30
|
+
return `<a:${element}><a:latin typeface="${escapeXml(font?.latin ?? fallback)}"/><a:ea typeface="${escapeXml(font?.ea ?? "")}"/><a:cs typeface="${escapeXml(font?.cs ?? "")}"/>${scriptFonts}</a:${element}>`;
|
|
31
|
+
};
|
|
32
|
+
const serializeFormatScheme = (theme) => {
|
|
33
|
+
return `<a:fmtScheme name="${escapeXml(theme.formatScheme?.name ?? "Folio")}"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="6350" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme>`;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { serializeThemeXml };
|
|
@@ -8,6 +8,8 @@ const DEFAULT_TAB_STOP_TWIPS = 720;
|
|
|
8
8
|
* we substitute the OOXML default instead.
|
|
9
9
|
*/
|
|
10
10
|
const MAX_TAB_STOP_TWIPS = 31680;
|
|
11
|
+
const MAX_HYPHENATION_ZONE_TWIPS = 31680;
|
|
12
|
+
const MAX_CONSECUTIVE_HYPHEN_LIMIT = 255;
|
|
11
13
|
function parseSettings(xml) {
|
|
12
14
|
const root = xml ? parseXmlDocument(xml) : null;
|
|
13
15
|
const settings = { defaultTabStop: parseDefaultTabStop(root) };
|
|
@@ -22,8 +24,52 @@ function parseSettings(xml) {
|
|
|
22
24
|
...eastAsiaLang ? { eastAsia: eastAsiaLang } : {},
|
|
23
25
|
...bidiLang ? { bidi: bidiLang } : {}
|
|
24
26
|
};
|
|
27
|
+
const autoHyphenation = parseOnOffSetting(root, "autoHyphenation");
|
|
28
|
+
if (autoHyphenation !== void 0) settings.autoHyphenation = autoHyphenation;
|
|
29
|
+
const doNotHyphenateCaps = parseOnOffSetting(root, "doNotHyphenateCaps");
|
|
30
|
+
if (doNotHyphenateCaps !== void 0) settings.doNotHyphenateCaps = doNotHyphenateCaps;
|
|
31
|
+
const consecutiveHyphenLimit = parseIntegerSetting(root, "consecutiveHyphenLimit", MAX_CONSECUTIVE_HYPHEN_LIMIT);
|
|
32
|
+
if (consecutiveHyphenLimit !== void 0) settings.consecutiveHyphenLimit = consecutiveHyphenLimit;
|
|
33
|
+
const hyphenationZoneTwips = parseIntegerSetting(root, "hyphenationZone", MAX_HYPHENATION_ZONE_TWIPS);
|
|
34
|
+
if (hyphenationZoneTwips !== void 0) settings.hyphenationZoneTwips = hyphenationZoneTwips;
|
|
35
|
+
const noLineBreaksBefore = parseKinsokuOverride(root, "noLineBreaksBefore");
|
|
36
|
+
const noLineBreaksAfter = parseKinsokuOverride(root, "noLineBreaksAfter");
|
|
37
|
+
const compat = root ? findChild(root, "w", "compat") : null;
|
|
38
|
+
const splitPageBreakAndParagraphMark = compat ? findChild(compat, "w", "splitPgBreakAndParaMark") : null;
|
|
39
|
+
if (splitPageBreakAndParagraphMark && parseBooleanElement(splitPageBreakAndParagraphMark)) settings.splitPageBreakAndParagraphMark = true;
|
|
40
|
+
const applyBreakingRules = compat ? findChild(compat, "w", "applyBreakingRules") : null;
|
|
41
|
+
const useLegacyEthiopicAmharicRules = applyBreakingRules !== null && parseBooleanElement(applyBreakingRules);
|
|
42
|
+
if (noLineBreaksBefore || noLineBreaksAfter || useLegacyEthiopicAmharicRules) settings.lineBreakRules = {
|
|
43
|
+
...noLineBreaksBefore ? { noLineBreaksBefore } : {},
|
|
44
|
+
...noLineBreaksAfter ? { noLineBreaksAfter } : {},
|
|
45
|
+
...useLegacyEthiopicAmharicRules ? { useLegacyEthiopicAmharicRules: true } : {}
|
|
46
|
+
};
|
|
25
47
|
return settings;
|
|
26
48
|
}
|
|
49
|
+
function parseOnOffSetting(root, name) {
|
|
50
|
+
if (!root) return;
|
|
51
|
+
const element = findChild(root, "w", name);
|
|
52
|
+
return element ? parseBooleanElement(element) : void 0;
|
|
53
|
+
}
|
|
54
|
+
function parseIntegerSetting(root, name, maximum) {
|
|
55
|
+
if (!root) return;
|
|
56
|
+
const element = findChild(root, "w", name);
|
|
57
|
+
const raw = element ? getAttribute(element, "w", "val") : null;
|
|
58
|
+
if (raw === null || !/^\d+$/u.test(raw)) return;
|
|
59
|
+
const parsed = Number.parseInt(raw, 10);
|
|
60
|
+
return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : void 0;
|
|
61
|
+
}
|
|
62
|
+
function parseKinsokuOverride(root, name) {
|
|
63
|
+
if (!root) return;
|
|
64
|
+
const element = findChild(root, "w", name);
|
|
65
|
+
const characters = element ? getAttribute(element, "w", "val") : null;
|
|
66
|
+
if (!characters) return;
|
|
67
|
+
const language = getAttribute(element, "w", "lang") || void 0;
|
|
68
|
+
return {
|
|
69
|
+
characters,
|
|
70
|
+
...language ? { language } : {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
27
73
|
function parseDefaultTabStop(root) {
|
|
28
74
|
if (!root) return 720;
|
|
29
75
|
const el = findChild(root, "w", "defaultTabStop");
|
package/dist/docx/styleParser.js
CHANGED
|
@@ -110,6 +110,17 @@ function parseRunProperties(rPr, theme) {
|
|
|
110
110
|
}
|
|
111
111
|
formatting.fontFamily = fontFamily;
|
|
112
112
|
}
|
|
113
|
+
const lang = findChild(rPr, "w", "lang");
|
|
114
|
+
if (lang) {
|
|
115
|
+
const val = getAttribute(lang, "w", "val") || void 0;
|
|
116
|
+
const eastAsia = getAttribute(lang, "w", "eastAsia") || void 0;
|
|
117
|
+
const bidi = getAttribute(lang, "w", "bidi") || void 0;
|
|
118
|
+
if (val || eastAsia || bidi) formatting.language = {
|
|
119
|
+
...val ? { val } : {},
|
|
120
|
+
...eastAsia ? { eastAsia } : {},
|
|
121
|
+
...bidi ? { bidi } : {}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
113
124
|
const spacing = findChild(rPr, "w", "spacing");
|
|
114
125
|
if (spacing) {
|
|
115
126
|
const val = parseNumericAttribute(spacing, "w", "val");
|
|
@@ -348,6 +359,10 @@ function parseParagraphProperties(pPr, theme) {
|
|
|
348
359
|
if (suppressLineNumbers) formatting.suppressLineNumbers = parseBooleanElement(suppressLineNumbers);
|
|
349
360
|
const suppressAutoHyphens = findChild(pPr, "w", "suppressAutoHyphens");
|
|
350
361
|
if (suppressAutoHyphens) formatting.suppressAutoHyphens = parseBooleanElement(suppressAutoHyphens);
|
|
362
|
+
const kinsoku = findChild(pPr, "w", "kinsoku");
|
|
363
|
+
if (kinsoku) formatting.kinsoku = parseBooleanElement(kinsoku);
|
|
364
|
+
const overflowPunct = findChild(pPr, "w", "overflowPunct");
|
|
365
|
+
if (overflowPunct) formatting.overflowPunctuation = parseBooleanElement(overflowPunct);
|
|
351
366
|
const rPr = findChild(pPr, "w", "rPr");
|
|
352
367
|
if (rPr) {
|
|
353
368
|
const runProps = parseRunProperties(rPr, theme);
|
|
@@ -388,6 +403,16 @@ function parseTableBorders(tblBorders) {
|
|
|
388
403
|
if (insideV) borders.insideV = insideV;
|
|
389
404
|
return Object.keys(borders).length > 0 ? borders : void 0;
|
|
390
405
|
}
|
|
406
|
+
/** Parse cell-only diagonal borders in addition to the shared table sides. */
|
|
407
|
+
function parseTableCellBorders(tcBorders) {
|
|
408
|
+
if (!tcBorders) return;
|
|
409
|
+
const borders = { ...parseTableBorders(tcBorders) };
|
|
410
|
+
const topLeftToBottomRight = parseBorderSpec(findChild(tcBorders, "w", "tl2br"));
|
|
411
|
+
if (topLeftToBottomRight) borders.topLeftToBottomRight = topLeftToBottomRight;
|
|
412
|
+
const topRightToBottomLeft = parseBorderSpec(findChild(tcBorders, "w", "tr2bl"));
|
|
413
|
+
if (topRightToBottomLeft) borders.topRightToBottomLeft = topRightToBottomLeft;
|
|
414
|
+
return Object.keys(borders).length > 0 ? borders : void 0;
|
|
415
|
+
}
|
|
391
416
|
/**
|
|
392
417
|
* Parse cell margins
|
|
393
418
|
*/
|
|
@@ -535,7 +560,7 @@ function parseTableCellProperties(tcPr, _theme) {
|
|
|
535
560
|
}
|
|
536
561
|
const tcBorders = findChild(tcPr, "w", "tcBorders");
|
|
537
562
|
if (tcBorders) {
|
|
538
|
-
const bordersResult =
|
|
563
|
+
const bordersResult = parseTableCellBorders(tcBorders);
|
|
539
564
|
if (bordersResult) formatting.borders = bordersResult;
|
|
540
565
|
}
|
|
541
566
|
const tcMar = findChild(tcPr, "w", "tcMar");
|
package/dist/docx/tableParser.js
CHANGED
|
@@ -105,6 +105,16 @@ function parseTableBorders(bordersElement) {
|
|
|
105
105
|
if (Object.keys(borders).length === 0) return;
|
|
106
106
|
return borders;
|
|
107
107
|
}
|
|
108
|
+
/** Parse cell-only diagonal borders in addition to the shared table sides. */
|
|
109
|
+
function parseTableCellBorders(bordersElement) {
|
|
110
|
+
if (!bordersElement) return;
|
|
111
|
+
const borders = { ...parseTableBorders(bordersElement) };
|
|
112
|
+
const topLeftToBottomRight = parseBorderSpec(findChild(bordersElement, "w", "tl2br"));
|
|
113
|
+
if (topLeftToBottomRight) borders.topLeftToBottomRight = topLeftToBottomRight;
|
|
114
|
+
const topRightToBottomLeft = parseBorderSpec(findChild(bordersElement, "w", "tr2bl"));
|
|
115
|
+
if (topRightToBottomLeft) borders.topRightToBottomLeft = topRightToBottomLeft;
|
|
116
|
+
return Object.keys(borders).length > 0 ? borders : void 0;
|
|
117
|
+
}
|
|
108
118
|
/**
|
|
109
119
|
* Parse cell margins (w:tblCellMar or w:tcMar)
|
|
110
120
|
*
|
|
@@ -446,7 +456,7 @@ function parseTableCellProperties(tcPrElement) {
|
|
|
446
456
|
const formatting = {};
|
|
447
457
|
const width = parseWidth(findChild(tcPrElement, "w", "tcW"));
|
|
448
458
|
if (width) formatting.width = width;
|
|
449
|
-
const borders =
|
|
459
|
+
const borders = parseTableCellBorders(findChild(tcPrElement, "w", "tcBorders"));
|
|
450
460
|
if (borders) formatting.borders = borders;
|
|
451
461
|
const margins = parseCellMargins(findChild(tcPrElement, "w", "tcMar"));
|
|
452
462
|
if (margins) formatting.margins = margins;
|
|
@@ -206,6 +206,7 @@ function parseVmlImageContent(pictElement, rels, media, rootXmlns = {}) {
|
|
|
206
206
|
const shapeStyle = parseStyleAttr(getAttribute(shape, null, "style"));
|
|
207
207
|
const widthPx = cssLengthToPx(shapeStyle["width"]);
|
|
208
208
|
const heightPx = cssLengthToPx(shapeStyle["height"]);
|
|
209
|
+
if (getLocalName(pictElement.name ?? "") === "object" && (widthPx !== void 0 && !validPreviewDimension(widthPx) || heightPx !== void 0 && !validPreviewDimension(heightPx))) continue;
|
|
209
210
|
const image = {
|
|
210
211
|
type: "image",
|
|
211
212
|
rId,
|