@office-open/docx 0.9.3 → 0.9.5

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.
@@ -1,6 +1,6 @@
1
- import { A as stringifyParagraphProperties, D as stringifyChildDispatch, E as tableDesc, F as parseDrawingRun, M as parseMathChildren, O as stringifyParagraphInline, Y as BorderStyle, ct as Media, et as parseFormFieldData, j as stringifyRunProperties, lt as createTransformation, n as sectionPropertiesDesc } from "./document-D8HDkCHs.mjs";
2
- import { Relationships, convertInchesToTwip, decimalNumber, derivePasswordHash, hexColorValue, toUint8Array, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
3
- import { attr, attrBool, attrNum, children, colorAttr, escapeXml, findChild, js2xml, textOf, xml2js } from "@office-open/xml";
1
+ import { A as stringifyParagraphInline, Ct as Media, E as tableDesc, F as parseDrawingRun, J as altChunkDesc, M as parseMathChildren, O as parseSdtProperties, Q as sdtBlockDesc, X as customXmlBlockDesc, Z as parseCustomXmlPr, at as stringifyRunProperties, ct as parsedRunToOptions, ht as parseFormFieldData, it as stringifyParagraphProperties, k as stringifyChildDispatch, n as sectionPropertiesDesc, ot as parseRun, rt as subDocDesc, st as parseRunProperties, ut as BorderStyle, wt as createTransformation } from "./document-DYH7tGnw.mjs";
2
+ import { Relationships, ThemeColor, convertInchesToTwip, decimalNumber, derivePasswordHash, hexColorValue, toUint8Array, uCharHexNumber, uniqueId, uniqueNumericIdCreator, uniqueUuid } from "@office-open/core";
3
+ import { attr, attrBool, attrNum, children, escapeXml, findChild, js2xml, textOf, xml2js } from "@office-open/xml";
4
4
  import { ChartCollection } from "@office-open/core/chart";
5
5
  import { SmartArtCollection } from "@office-open/core/smartart";
6
6
  //#region src/parts/paragraph/formatting/alignment.ts
@@ -74,6 +74,35 @@ const AlignmentType = {
74
74
  JUSTIFIED: "both"
75
75
  };
76
76
  //#endregion
77
+ //#region src/parts/paragraph/formatting/spacing.ts
78
+ /**
79
+ * Paragraph spacing module for WordprocessingML documents.
80
+ *
81
+ * This module provides spacing options for paragraphs including space before,
82
+ * space after, and line spacing.
83
+ *
84
+ * Reference: http://officeopenxml.com/WPspacing.php
85
+ *
86
+ * @module
87
+ */
88
+ /**
89
+ * Line spacing rule types.
90
+ *
91
+ * Specifies how the line height is calculated.
92
+ *
93
+ * @publicApi
94
+ */
95
+ const LineRuleType = {
96
+ /** Line spacing is at least the specified value */
97
+ AT_LEAST: "atLeast",
98
+ /** Line spacing is exactly the specified value */
99
+ EXACTLY: "exactly",
100
+ /** Line spacing is exactly the specified value (alias for EXACTLY) */
101
+ EXACT: "exact",
102
+ /** Line spacing is automatically determined based on content */
103
+ AUTO: "auto"
104
+ };
105
+ //#endregion
77
106
  //#region src/parts/paragraph/formatting/style.ts
78
107
  /**
79
108
  * Paragraph style module for WordprocessingML documents.
@@ -965,7 +994,7 @@ function stringifyLevel(opts) {
965
994
  /**
966
995
  * Parse w:numbering element into NumberingOptions.
967
996
  */
968
- function parseNumberingDefinitions(el) {
997
+ function parseNumberingDefinitions(el, parseParagraphProperties, ctx) {
969
998
  const abstractNums = /* @__PURE__ */ new Map();
970
999
  for (const child of el.elements ?? []) {
971
1000
  if (child.name !== "w:abstractNum") continue;
@@ -987,7 +1016,7 @@ function parseNumberingDefinitions(el) {
987
1016
  const levels = [];
988
1017
  for (const child of abstractEl.elements ?? []) {
989
1018
  if (child.name !== "w:lvl") continue;
990
- const levelOpts = parseLevelEl(child);
1019
+ const levelOpts = parseLevelEl(child, parseParagraphProperties, ctx);
991
1020
  if (levelOpts) levels.push(levelOpts);
992
1021
  }
993
1022
  if (levels.length > 0 && levels.every((l) => l.format === LevelFormat.BULLET)) continue;
@@ -999,7 +1028,7 @@ function parseNumberingDefinitions(el) {
999
1028
  if (configs.length === 0) return void 0;
1000
1029
  return { config: configs };
1001
1030
  }
1002
- function parseLevelEl(el) {
1031
+ function parseLevelEl(el, parseParagraphProperties, ctx) {
1003
1032
  const opts = {};
1004
1033
  const level = attrNum(el, "w:ilvl");
1005
1034
  if (level !== void 0) opts.level = level;
@@ -1008,478 +1037,65 @@ function parseLevelEl(el) {
1008
1037
  const val = attrNum(start, "w:val");
1009
1038
  if (val !== void 0) opts.start = val;
1010
1039
  }
1040
+ const lvlRestart = findChild(el, "w:lvlRestart");
1041
+ if (lvlRestart) {
1042
+ const val = attrNum(lvlRestart, "w:val");
1043
+ if (val !== void 0) opts.lvlRestart = val;
1044
+ }
1011
1045
  const numFmt = findChild(el, "w:numFmt");
1012
1046
  if (numFmt) {
1013
1047
  const val = attr(numFmt, "w:val");
1014
1048
  if (val) opts.format = val;
1015
1049
  }
1050
+ const suff = findChild(el, "w:suff");
1051
+ if (suff) {
1052
+ const val = attr(suff, "w:val");
1053
+ if (val) opts.suffix = val;
1054
+ }
1055
+ if (findChild(el, "w:isLgl")) opts.isLegalNumberingStyle = true;
1016
1056
  const lvlText = findChild(el, "w:lvlText");
1017
1057
  if (lvlText) {
1018
1058
  const val = attr(lvlText, "w:val");
1019
1059
  if (val) opts.text = val;
1020
1060
  }
1061
+ const lvlPicBulletId = findChild(el, "w:lvlPicBulletId");
1062
+ if (lvlPicBulletId) {
1063
+ const val = attrNum(lvlPicBulletId, "w:val");
1064
+ if (val !== void 0) opts.lvlPicBulletId = val;
1065
+ }
1066
+ const legacyEl = findChild(el, "w:legacy");
1067
+ if (legacyEl) {
1068
+ const legacy = {};
1069
+ const space = attrNum(legacyEl, "w:legacySpace");
1070
+ if (space !== void 0) legacy.space = space;
1071
+ const indent = attrNum(legacyEl, "w:legacyIndent");
1072
+ if (indent !== void 0) legacy.indent = indent;
1073
+ if (Object.keys(legacy).length > 0) opts.legacy = legacy;
1074
+ }
1021
1075
  const lvlJc = findChild(el, "w:lvlJc");
1022
1076
  if (lvlJc) {
1023
1077
  const val = attr(lvlJc, "w:val");
1024
1078
  if (val) opts.alignment = val;
1025
1079
  }
1026
- const suff = findChild(el, "w:suff");
1027
- if (suff) {
1028
- const val = attr(suff, "w:val");
1029
- if (val) opts.suffix = val;
1030
- }
1031
- if (findChild(el, "w:isLgl")) opts.isLegalNumberingStyle = true;
1080
+ const tplc = attr(el, "w:tplc");
1081
+ if (tplc) opts.templateCode = tplc;
1082
+ const tentative = attrBool(el, "w:tentative");
1083
+ if (tentative !== void 0) opts.tentative = tentative;
1084
+ const style = {};
1032
1085
  const rPr = findChild(el, "w:rPr");
1033
1086
  if (rPr) {
1034
- const style = {};
1035
- const sz = findChild(rPr, "w:sz");
1036
- if (sz) {
1037
- const val = attrNum(sz, "w:val");
1038
- if (val !== void 0) {
1039
- if (!style.run) style.run = {};
1040
- style.run.size = val;
1041
- }
1042
- }
1043
- const rFonts = findChild(rPr, "w:rFonts");
1044
- if (rFonts) {
1045
- const ascii = attr(rFonts, "w:ascii");
1046
- if (ascii) {
1047
- if (!style.run) style.run = {};
1048
- style.run.font = ascii;
1049
- }
1050
- }
1051
- if (Object.keys(style).length > 0) opts.style = style;
1087
+ const runOpts = parseRunProperties(rPr);
1088
+ if (Object.keys(runOpts).length > 0) style.run = runOpts;
1052
1089
  }
1053
1090
  const pPr = findChild(el, "w:pPr");
1054
1091
  if (pPr) {
1055
- const style = opts.style ?? {};
1056
- const paraStyle = {};
1057
- const ind = findChild(pPr, "w:ind");
1058
- if (ind) {
1059
- const indent = {};
1060
- const left = attrNum(ind, "w:left");
1061
- if (left !== void 0) indent.left = left;
1062
- const hanging = attrNum(ind, "w:hanging");
1063
- if (hanging !== void 0) indent.hanging = hanging;
1064
- if (Object.keys(indent).length > 0) paraStyle.indent = indent;
1065
- }
1066
- if (Object.keys(paraStyle).length > 0) {
1067
- style.paragraph = paraStyle;
1068
- opts.style = style;
1069
- }
1092
+ const paraOpts = parseParagraphProperties(pPr, ctx);
1093
+ if (Object.keys(paraOpts).length > 0) style.paragraph = paraOpts;
1070
1094
  }
1095
+ if (Object.keys(style).length > 0) opts.style = style;
1071
1096
  return Object.keys(opts).length > 0 ? opts : void 0;
1072
1097
  }
1073
1098
  //#endregion
1074
- //#region src/parts/paragraph/run/run-parse.ts
1075
- /**
1076
- * Run properties parser for DOCX documents.
1077
- *
1078
- * Parses w:rPr Element trees into RunPropertiesOptions objects.
1079
- *
1080
- * @module
1081
- */
1082
- /**
1083
- * Parse a w:rPr element into RunPropertiesOptions.
1084
- */
1085
- function parseRunProperties(el) {
1086
- const opts = {};
1087
- const rStyle = findChild(el, "w:rStyle");
1088
- if (rStyle) opts.style = attr(rStyle, "w:val");
1089
- const font = findChild(el, "w:rFonts");
1090
- if (font) {
1091
- const ascii = attr(font, "w:ascii");
1092
- const eastAsia = attr(font, "w:eastAsia");
1093
- const hAnsi = attr(font, "w:hAnsi");
1094
- const cs = attr(font, "w:cs");
1095
- const hint = attr(font, "w:hint");
1096
- if (ascii && !eastAsia && !hAnsi && !cs) opts.font = hint ? {
1097
- name: ascii,
1098
- hint
1099
- } : ascii;
1100
- else {
1101
- const fontObj = {};
1102
- if (ascii) fontObj.ascii = ascii;
1103
- if (eastAsia) fontObj.eastAsia = eastAsia;
1104
- if (hAnsi) fontObj.hAnsi = hAnsi;
1105
- if (cs) fontObj.cs = cs;
1106
- if (hint) fontObj.hint = hint;
1107
- opts.font = fontObj;
1108
- }
1109
- }
1110
- const bold = findChild(el, "w:b");
1111
- if (bold) opts.bold = attrBool(bold, "w:val") ?? true;
1112
- const boldCs = findChild(el, "w:bCs");
1113
- if (boldCs) opts.boldComplexScript = attrBool(boldCs, "w:val") ?? true;
1114
- const italic = findChild(el, "w:i");
1115
- if (italic) opts.italic = attrBool(italic, "w:val") ?? true;
1116
- const italicCs = findChild(el, "w:iCs");
1117
- if (italicCs) opts.italicComplexScript = attrBool(italicCs, "w:val") ?? true;
1118
- const underline = findChild(el, "w:u");
1119
- if (underline) {
1120
- const ul = {};
1121
- const uType = attr(underline, "w:val");
1122
- if (uType) ul.type = uType;
1123
- const uColor = colorAttr(underline, "w:color");
1124
- if (uColor) ul.color = uColor;
1125
- opts.underline = ul;
1126
- }
1127
- for (const [name, optKey] of [
1128
- ["w:strike", "strike"],
1129
- ["w:dstrike", "doubleStrike"],
1130
- ["w:outline", "outline"],
1131
- ["w:shadow", "shadow"],
1132
- ["w:emboss", "emboss"],
1133
- ["w:imprint", "imprint"],
1134
- ["w:vanish", "vanish"],
1135
- ["w:webHidden", "webHidden"],
1136
- ["w:noProof", "noProof"],
1137
- ["w:snapToGrid", "snapToGrid"],
1138
- ["w:smallCaps", "smallCaps"],
1139
- ["w:caps", "allCaps"],
1140
- ["w:rtl", "rightToLeft"],
1141
- ["w:cs", "complexScript"],
1142
- ["w:specVanish", "specVanish"],
1143
- ["w:math", "math"]
1144
- ]) {
1145
- const child = findChild(el, name);
1146
- if (child) opts[optKey] = attrBool(child, "w:val") ?? true;
1147
- }
1148
- const color = findChild(el, "w:color");
1149
- if (color) {
1150
- const c = colorAttr(color, "w:val");
1151
- if (c) opts.color = c;
1152
- }
1153
- const sz = findChild(el, "w:sz");
1154
- if (sz) {
1155
- const halfPts = attrNum(sz, "w:val");
1156
- if (halfPts !== void 0) opts.size = halfPts / 2;
1157
- }
1158
- const szCs = findChild(el, "w:szCs");
1159
- if (szCs) {
1160
- const halfPts = attrNum(szCs, "w:val");
1161
- if (halfPts !== void 0) opts.sizeComplexScript = halfPts / 2;
1162
- }
1163
- const highlight = findChild(el, "w:highlight");
1164
- if (highlight) {
1165
- const val = attr(highlight, "w:val");
1166
- if (val) opts.highlight = val;
1167
- }
1168
- const highlightCs = findChild(el, "w:highlightCs");
1169
- if (highlightCs) {
1170
- const val = attr(highlightCs, "w:val");
1171
- if (val) opts.highlightComplexScript = val;
1172
- }
1173
- const vertAlign = findChild(el, "w:vertAlign");
1174
- if (vertAlign) {
1175
- const val = attr(vertAlign, "w:val");
1176
- if (val === "subscript") opts.subScript = true;
1177
- else if (val === "superscript") opts.superScript = true;
1178
- }
1179
- const effect = findChild(el, "w:effect");
1180
- if (effect) {
1181
- const val = attr(effect, "w:val");
1182
- if (val) opts.effect = val;
1183
- }
1184
- const emphasisMark = findChild(el, "w:em");
1185
- if (emphasisMark) {
1186
- const val = attr(emphasisMark, "w:val");
1187
- if (val) opts.emphasisMark = { type: val };
1188
- }
1189
- const spacing = findChild(el, "w:spacing");
1190
- if (spacing) {
1191
- const val = attrNum(spacing, "w:val");
1192
- if (val !== void 0) opts.characterSpacing = val;
1193
- }
1194
- const scale = findChild(el, "w:w");
1195
- if (scale) {
1196
- const val = attrNum(scale, "w:val");
1197
- if (val !== void 0) opts.scale = val;
1198
- }
1199
- const kern = findChild(el, "w:kern");
1200
- if (kern) {
1201
- const val = attrNum(kern, "w:val");
1202
- if (val !== void 0) opts.kern = val;
1203
- }
1204
- const position = findChild(el, "w:position");
1205
- if (position) {
1206
- const val = attr(position, "w:val");
1207
- if (val !== void 0) opts.position = val;
1208
- }
1209
- const fitText = findChild(el, "w:fitText");
1210
- if (fitText) {
1211
- const val = attrNum(fitText, "w:val");
1212
- if (val !== void 0) opts.fitText = val;
1213
- }
1214
- const lang = findChild(el, "w:lang");
1215
- if (lang) {
1216
- const langObj = {};
1217
- const val = attr(lang, "w:val");
1218
- if (val) langObj.val = val;
1219
- const eastAsia = attr(lang, "w:eastAsia");
1220
- if (eastAsia) langObj.eastAsia = eastAsia;
1221
- const bidi = attr(lang, "w:bidi");
1222
- if (bidi) langObj.bidi = bidi;
1223
- if (Object.keys(langObj).length > 0) opts.language = langObj;
1224
- }
1225
- const bdr = findChild(el, "w:bdr");
1226
- if (bdr) opts.border = parseBorder(bdr);
1227
- const shd = findChild(el, "w:shd");
1228
- if (shd) opts.shading = parseShading(shd);
1229
- return opts;
1230
- }
1231
- /**
1232
- * Parse a w:bdr element into BorderOptions.
1233
- */
1234
- function parseBorder(el) {
1235
- const opts = {};
1236
- const style = attr(el, "w:val");
1237
- if (style) opts.style = style;
1238
- const color = colorAttr(el, "w:color");
1239
- if (color) opts.color = color;
1240
- const size = attrNum(el, "w:sz");
1241
- if (size !== void 0) opts.size = size;
1242
- const space = attrNum(el, "w:space");
1243
- if (space !== void 0) opts.space = space;
1244
- const shadow = attrBool(el, "w:shadow");
1245
- if (shadow !== void 0) opts.shadow = shadow;
1246
- const frame = attrBool(el, "w:frame");
1247
- if (frame !== void 0) opts.frame = frame;
1248
- return opts;
1249
- }
1250
- /**
1251
- * Parse a w:shd element into ShadingAttributesProperties.
1252
- */
1253
- function parseShading(el) {
1254
- const opts = {};
1255
- const fill = colorAttr(el, "w:fill");
1256
- if (fill) opts.fill = fill;
1257
- const color = colorAttr(el, "w:color");
1258
- if (color) opts.color = color;
1259
- const type = attr(el, "w:val");
1260
- if (type) opts.type = type;
1261
- return opts;
1262
- }
1263
- /** Matches w:br[@w:type="page"] → PageBreak */
1264
- const PARSED_PAGE_BREAK = Symbol("PageBreak");
1265
- /** Matches w:br (line break) */
1266
- const PARSED_LINE_BREAK = Symbol("LineBreak");
1267
- /** Matches w:tab */
1268
- const PARSED_TAB = Symbol("Tab");
1269
- /** Matches w:cr */
1270
- const PARSED_CR = Symbol("CarriageReturn");
1271
- /** Matches w:noBreakHyphen */
1272
- const PARSED_NO_BREAK_HYPHEN = Symbol("NoBreakHyphen");
1273
- /** Matches w:softHyphen */
1274
- const PARSED_SOFT_HYPHEN = Symbol("SoftHyphen");
1275
- /** Matches w:footnoteRef — auto-generated by Footnote class */
1276
- const PARSED_FOOTNOTE_REF = Symbol("FootnoteRef");
1277
- /** Matches w:br[@w:type="column"] */
1278
- const PARSED_COLUMN_BREAK = Symbol("ColumnBreak");
1279
- /** Matches w:dayShort */
1280
- const PARSED_DAY_SHORT = Symbol("DayShort");
1281
- /** Matches w:monthShort */
1282
- const PARSED_MONTH_SHORT = Symbol("MonthShort");
1283
- /** Matches w:yearShort */
1284
- const PARSED_YEAR_SHORT = Symbol("YearShort");
1285
- /** Matches w:dayLong */
1286
- const PARSED_DAY_LONG = Symbol("DayLong");
1287
- /** Matches w:monthLong */
1288
- const PARSED_MONTH_LONG = Symbol("MonthLong");
1289
- /** Matches w:yearLong */
1290
- const PARSED_YEAR_LONG = Symbol("YearLong");
1291
- /** Matches w:annotationRef */
1292
- const PARSED_ANNOTATION_REF = Symbol("AnnotationRef");
1293
- /** Matches w:separator */
1294
- const PARSED_SEPARATOR = Symbol("Separator");
1295
- /** Matches w:continuationSeparator */
1296
- const PARSED_CONTINUATION_SEPARATOR = Symbol("ContinuationSeparator");
1297
- /** Matches w:pgNum */
1298
- const PARSED_PG_NUM = Symbol("PgNum");
1299
- /** Matches w:lastRenderedPageBreak */
1300
- const PARSED_LAST_RENDERED_PAGE_BREAK = Symbol("LastRenderedPageBreak");
1301
- /**
1302
- * Parse a w:r element into run data.
1303
- * Returns { properties, children } where children are parsed run content items.
1304
- */
1305
- function parseRun(el, _ctx) {
1306
- const rPr = findChild(el, "w:rPr");
1307
- const properties = rPr ? parseRunProperties(rPr) : void 0;
1308
- const children = [];
1309
- for (const child of el.elements ?? []) switch (child.name) {
1310
- case "w:rPr": break;
1311
- case "w:t": {
1312
- const preserveSpace = attrBool(child, "xml:space");
1313
- let text = textOf(child);
1314
- if (preserveSpace && text) {}
1315
- children.push(text);
1316
- break;
1317
- }
1318
- case "w:delText": {
1319
- const text = textOf(child);
1320
- if (text) children.push(text);
1321
- break;
1322
- }
1323
- case "w:br": {
1324
- const brType = attr(child, "w:type");
1325
- if (brType === "page") children.push(PARSED_PAGE_BREAK);
1326
- else if (brType === "column") children.push(PARSED_COLUMN_BREAK);
1327
- else children.push(PARSED_LINE_BREAK);
1328
- break;
1329
- }
1330
- case "w:tab":
1331
- children.push(PARSED_TAB);
1332
- break;
1333
- case "w:cr":
1334
- children.push(PARSED_CR);
1335
- break;
1336
- case "w:noBreakHyphen":
1337
- children.push(PARSED_NO_BREAK_HYPHEN);
1338
- break;
1339
- case "w:softHyphen":
1340
- children.push(PARSED_SOFT_HYPHEN);
1341
- break;
1342
- case "w:commentReference": {
1343
- const id = attrNum(child, "w:id");
1344
- if (id !== void 0) children.push({ commentReference: id });
1345
- break;
1346
- }
1347
- case "w:drawing":
1348
- case "w:pict": break;
1349
- case "w:sym": {
1350
- const charVal = attr(child, "w:char");
1351
- const fontVal = attr(child, "w:font");
1352
- if (charVal) children.push({ symbolRun: {
1353
- char: charVal,
1354
- symbolfont: fontVal ?? "Wingdings"
1355
- } });
1356
- break;
1357
- }
1358
- case "w:footnoteReference": {
1359
- const id = attrNum(child, "w:id");
1360
- if (id !== void 0) children.push({ footnoteReference: id });
1361
- break;
1362
- }
1363
- case "w:endnoteReference": {
1364
- const id = attrNum(child, "w:id");
1365
- if (id !== void 0) children.push({ endnoteReference: id });
1366
- break;
1367
- }
1368
- case "w:footnoteRef":
1369
- case "w:endnoteRef":
1370
- children.push(PARSED_FOOTNOTE_REF);
1371
- break;
1372
- case "w:dayShort":
1373
- children.push(PARSED_DAY_SHORT);
1374
- break;
1375
- case "w:monthShort":
1376
- children.push(PARSED_MONTH_SHORT);
1377
- break;
1378
- case "w:yearShort":
1379
- children.push(PARSED_YEAR_SHORT);
1380
- break;
1381
- case "w:dayLong":
1382
- children.push(PARSED_DAY_LONG);
1383
- break;
1384
- case "w:monthLong":
1385
- children.push(PARSED_MONTH_LONG);
1386
- break;
1387
- case "w:yearLong":
1388
- children.push(PARSED_YEAR_LONG);
1389
- break;
1390
- case "w:annotationRef":
1391
- children.push(PARSED_ANNOTATION_REF);
1392
- break;
1393
- case "w:separator":
1394
- children.push(PARSED_SEPARATOR);
1395
- break;
1396
- case "w:continuationSeparator":
1397
- children.push(PARSED_CONTINUATION_SEPARATOR);
1398
- break;
1399
- case "w:pgNum":
1400
- children.push(PARSED_PG_NUM);
1401
- break;
1402
- case "w:lastRenderedPageBreak":
1403
- children.push(PARSED_LAST_RENDERED_PAGE_BREAK);
1404
- break;
1405
- default: break;
1406
- }
1407
- return {
1408
- properties,
1409
- children
1410
- };
1411
- }
1412
- /**
1413
- * Convert parsed run data into an RunOptions suitable for the Document constructor.
1414
- * Simplifies the parsed children into text + break format.
1415
- * If the run contains only a commentReference, returns { commentReference: id } instead.
1416
- * If the run only contains footnoteRef/endnoteRef (auto-generated), returns empty options.
1417
- *
1418
- * When empty run elements (tab, noBreakHyphen, date fields, etc.) are present,
1419
- * uses children[] format to preserve them for round-trip fidelity.
1420
- */
1421
- /** Mapping from parse symbols to RunOptions child objects for empty elements. */
1422
- const SYMBOL_TO_CHILD = new Map([
1423
- [PARSED_TAB, { tab: true }],
1424
- [PARSED_CR, { carriageReturn: true }],
1425
- [PARSED_NO_BREAK_HYPHEN, { noBreakHyphen: true }],
1426
- [PARSED_SOFT_HYPHEN, { softHyphen: true }],
1427
- [PARSED_DAY_SHORT, { dayShort: true }],
1428
- [PARSED_MONTH_SHORT, { monthShort: true }],
1429
- [PARSED_YEAR_SHORT, { yearShort: true }],
1430
- [PARSED_DAY_LONG, { dayLong: true }],
1431
- [PARSED_MONTH_LONG, { monthLong: true }],
1432
- [PARSED_YEAR_LONG, { yearLong: true }],
1433
- [PARSED_ANNOTATION_REF, { annotationRef: true }],
1434
- [PARSED_SEPARATOR, { separator: true }],
1435
- [PARSED_CONTINUATION_SEPARATOR, { continuationSeparator: true }],
1436
- [PARSED_PG_NUM, { pgNum: true }],
1437
- [PARSED_LAST_RENDERED_PAGE_BREAK, { lastRenderedPageBreak: true }]
1438
- ]);
1439
- function parsedRunToOptions(parsed) {
1440
- const contentChildren = parsed.children.filter((c) => c !== PARSED_FOOTNOTE_REF);
1441
- if (contentChildren.length === 0 && parsed.children.some((c) => c === PARSED_FOOTNOTE_REF)) return null;
1442
- const opts = { ...parsed.properties };
1443
- const isRefChild = (c) => typeof c === "object" && c !== null && ("commentReference" in c || "footnoteReference" in c || "endnoteReference" in c);
1444
- const refChildren = contentChildren.filter(isRefChild);
1445
- const nonRefChildren = contentChildren.filter((c) => !isRefChild(c));
1446
- if (refChildren.length > 0 && nonRefChildren.length === 0) return refChildren[0];
1447
- const symbolIdx = nonRefChildren.findIndex((c) => typeof c === "object" && c !== null && "symbolRun" in c);
1448
- if (symbolIdx >= 0 && nonRefChildren.length === 1 && !parsed.properties) return nonRefChildren[symbolIdx];
1449
- const textParts = [];
1450
- let breakCount = 0;
1451
- let hasPageBreak = false;
1452
- let hasColumnBreak = false;
1453
- const extraChildren = [];
1454
- for (const child of nonRefChildren) if (typeof child === "string") textParts.push(child);
1455
- else if (child === PARSED_LINE_BREAK) breakCount++;
1456
- else if (child === PARSED_PAGE_BREAK) hasPageBreak = true;
1457
- else if (child === PARSED_COLUMN_BREAK) hasColumnBreak = true;
1458
- else {
1459
- const mapped = SYMBOL_TO_CHILD.get(child);
1460
- if (mapped) extraChildren.push(mapped);
1461
- }
1462
- if (extraChildren.length > 0) {
1463
- const children = [];
1464
- for (const child of nonRefChildren) if (typeof child === "string") children.push(child);
1465
- else if (child === PARSED_LINE_BREAK) children.push({ break: 1 });
1466
- else if (child === PARSED_PAGE_BREAK) children.push({ pageBreak: true });
1467
- else if (child === PARSED_COLUMN_BREAK) children.push({ columnBreak: true });
1468
- else {
1469
- const mapped = SYMBOL_TO_CHILD.get(child);
1470
- if (mapped) children.push(mapped);
1471
- }
1472
- opts.children = children;
1473
- } else {
1474
- if (textParts.length > 0) opts.text = textParts.join("");
1475
- if (breakCount > 0) opts.break = breakCount;
1476
- if (hasPageBreak) opts.pageBreak = true;
1477
- if (hasColumnBreak) opts.columnBreak = true;
1478
- }
1479
- if (Object.keys(opts).length === 0 && textParts.length === 0 && breakCount === 0 && !hasPageBreak && !hasColumnBreak && extraChildren.length === 0) return null;
1480
- return opts;
1481
- }
1482
- //#endregion
1483
1099
  //#region src/parts/styles/factory.ts
1484
1100
  /** Escape special XML characters. */
1485
1101
  function esc(s) {
@@ -1886,7 +1502,7 @@ function buildNumberingCache(numberingEl) {
1886
1502
  return cache;
1887
1503
  }
1888
1504
  /**
1889
- * Parse w:styles element into StylesOptions-like structure.
1505
+ * Parse w:styles element into StylesOptions.
1890
1506
  *
1891
1507
  * Skips built-in styles that DefaultStylesFactory already generates,
1892
1508
  * keeping only user-defined custom styles for round-trip fidelity.
@@ -1896,13 +1512,12 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
1896
1512
  const paragraphStyles = [];
1897
1513
  const characterStyles = [];
1898
1514
  for (const child of el.elements ?? []) if (child.name === "w:docDefaults") {
1899
- const defOpts = parseDocDefaults(child);
1515
+ const defOpts = parseDocDefaults(child, parseParagraphProperties, ctx);
1900
1516
  if (defOpts) opts.default = defOpts;
1901
1517
  } else if (child.name === "w:style") {
1902
1518
  const styleOpts = parseStyleElement(child, parseParagraphProperties, ctx);
1903
- if (!styleOpts) continue;
1904
- const styleId = styleOpts.id;
1905
- if (styleId && BUILTIN_STYLE_IDS.has(styleId)) continue;
1519
+ if (!styleOpts?._type || !styleOpts.id) continue;
1520
+ if (BUILTIN_STYLE_IDS.has(styleOpts.id)) continue;
1906
1521
  const type = styleOpts._type;
1907
1522
  delete styleOpts._type;
1908
1523
  if (type === "paragraph") paragraphStyles.push(styleOpts);
@@ -1912,38 +1527,25 @@ function parseStyleDefinitions(el, parseParagraphProperties, ctx) {
1912
1527
  if (characterStyles.length > 0) opts.characterStyles = characterStyles;
1913
1528
  return Object.keys(opts).length > 0 ? opts : void 0;
1914
1529
  }
1915
- function parseDocDefaults(el) {
1916
- const result = {};
1917
- const docDefaults = {};
1530
+ function parseDocDefaults(el, parseParagraphProperties, ctx) {
1531
+ const document = {};
1918
1532
  const rPrDefault = findChild(el, "w:rPrDefault");
1919
1533
  if (rPrDefault) {
1920
1534
  const rPr = findChild(rPrDefault, "w:rPr");
1921
1535
  if (rPr) {
1922
1536
  const runDefaults = parseRunProperties(rPr);
1923
- if (Object.keys(runDefaults).length > 0) docDefaults.run = runDefaults;
1537
+ if (Object.keys(runDefaults).length > 0) document.run = runDefaults;
1924
1538
  }
1925
1539
  }
1926
1540
  const pPrDefault = findChild(el, "w:pPrDefault");
1927
1541
  if (pPrDefault) {
1928
1542
  const pPr = findChild(pPrDefault, "w:pPr");
1929
1543
  if (pPr) {
1930
- const paraDefaults = {};
1931
- const spacing = findChild(pPr, "w:spacing");
1932
- if (spacing) {
1933
- const sp = {};
1934
- const before = attrNum(spacing, "w:before");
1935
- if (before !== void 0) sp.before = before;
1936
- const after = attrNum(spacing, "w:after");
1937
- if (after !== void 0) sp.after = after;
1938
- const line = attrNum(spacing, "w:line");
1939
- if (line !== void 0) sp.line = line;
1940
- if (Object.keys(sp).length > 0) paraDefaults.spacing = sp;
1941
- }
1942
- if (Object.keys(paraDefaults).length > 0) docDefaults.paragraph = paraDefaults;
1544
+ const paraDefaults = parseParagraphProperties(pPr, ctx);
1545
+ if (Object.keys(paraDefaults).length > 0) document.paragraph = paraDefaults;
1943
1546
  }
1944
1547
  }
1945
- if (Object.keys(docDefaults).length > 0) result.document = docDefaults;
1946
- return Object.keys(result).length > 0 ? result : void 0;
1548
+ return Object.keys(document).length > 0 ? { document } : void 0;
1947
1549
  }
1948
1550
  function parseStyleElement(el, parseParagraphProperties, ctx) {
1949
1551
  const opts = {};
@@ -2014,7 +1616,7 @@ function parseStyleElement(el, parseParagraphProperties, ctx) {
2014
1616
  *
2015
1617
  * @module
2016
1618
  */
2017
- function escapeAttr$2(s) {
1619
+ function escapeAttr$1(s) {
2018
1620
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2019
1621
  }
2020
1622
  /** Derive the namespace-prefixed val attribute from the element tag. */
@@ -2028,12 +1630,12 @@ function numVal(tag, val) {
2028
1630
  return val !== void 0 ? `<${tag} ${valAttr(tag)}="${val}"/>` : "";
2029
1631
  }
2030
1632
  function strVal(tag, val) {
2031
- return val !== void 0 ? `<${tag} ${valAttr(tag)}="${escapeAttr$2(val)}"/>` : "";
1633
+ return val !== void 0 ? `<${tag} ${valAttr(tag)}="${escapeAttr$1(val)}"/>` : "";
2032
1634
  }
2033
1635
  /** Build attribute string from key-value pairs, skipping undefined. */
2034
1636
  function attrStr(attrs) {
2035
1637
  const parts = [];
2036
- for (const [k, v] of Object.entries(attrs)) if (v !== void 0) parts.push(`${k}="${escapeAttr$2(String(v))}"`);
1638
+ for (const [k, v] of Object.entries(attrs)) if (v !== void 0) parts.push(`${k}="${escapeAttr$1(String(v))}"`);
2037
1639
  return parts.join(" ");
2038
1640
  }
2039
1641
  /** Self-closing element with attributes only. */
@@ -2042,11 +1644,19 @@ function attrEl(tag, attrs) {
2042
1644
  return a ? `<${tag} ${a}/>` : `<${tag}/>`;
2043
1645
  }
2044
1646
  function compatSetting(name, val) {
2045
- return `<w:compatSetting w:name="${escapeAttr$2(name)}" w:uri="http://schemas.microsoft.com/office/word" w:val="${val}"/>`;
1647
+ return `<w:compatSetting w:name="${escapeAttr$1(name)}" w:uri="http://schemas.microsoft.com/office/word" w:val="${val}"/>`;
2046
1648
  }
2047
1649
  function maybeDerive(password, hashValue) {
2048
1650
  return password !== void 0 && hashValue === void 0 ? derivePasswordHash(password) : void 0;
2049
1651
  }
1652
+ /** Valid w:documentProtection/@w:edit values (ST_DocProtect). */
1653
+ const DOC_PROTECT_EDITS = [
1654
+ "none",
1655
+ "readOnly",
1656
+ "comments",
1657
+ "trackedChanges",
1658
+ "forms"
1659
+ ];
2050
1660
  function stringifyDocProtect(opts) {
2051
1661
  const derived = maybeDerive(opts.password, opts.hashValue);
2052
1662
  const attrs = { "w:enforcement": "1" };
@@ -2392,7 +2002,7 @@ const settingsDesc = {
2392
2002
  p.push(onOff("w:autoFormatOverride", opts.autoFormatOverride));
2393
2003
  p.push(onOff("w:styleLockTheme", opts.styleLockTheme));
2394
2004
  p.push(onOff("w:styleLockQFSet", opts.styleLockQFSet));
2395
- p.push(numVal("w:defaultTabStop", opts.defaultTabStop ?? 420));
2005
+ if (opts.defaultTabStop !== void 0) p.push(numVal("w:defaultTabStop", opts.defaultTabStop));
2396
2006
  p.push(onOff("w:autoHyphenation", opts.hyphenation?.autoHyphenation));
2397
2007
  p.push(numVal("w:consecutiveHyphenLimit", opts.hyphenation?.consecutiveHyphenLimit));
2398
2008
  p.push(numVal("w:hyphenationZone", opts.hyphenation?.hyphenationZone));
@@ -2413,7 +2023,7 @@ const settingsDesc = {
2413
2023
  p.push(numVal("w:drawingGridVerticalOrigin", opts.drawingGridVerticalOrigin));
2414
2024
  p.push(onOff("w:doNotUseMarginsForDrawingGridOrigin", opts.doNotUseMarginsForDrawingGridOrigin));
2415
2025
  p.push(onOff("w:doNotShadeFormData", opts.doNotShadeFormData));
2416
- p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl ?? "compressPunctuation"));
2026
+ if (opts.characterSpacingControl !== void 0) p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl));
2417
2027
  p.push(onOff("w:noPunctuationKerning", opts.noPunctuationKerning));
2418
2028
  p.push(onOff("w:printTwoOnOne", opts.printTwoOnOne));
2419
2029
  p.push(onOff("w:strictFirstAndLastChars", opts.strictFirstAndLastChars));
@@ -2450,20 +2060,11 @@ const settingsDesc = {
2450
2060
  if (opts.hdrShapeDefaults !== void 0) p.push("<w:hdrShapeDefaults/>");
2451
2061
  if (opts.footnotePr !== void 0) p.push(stringifyFootnotePr(opts.footnotePr));
2452
2062
  if (opts.endnotePr !== void 0) p.push(stringifyEndnotePr(opts.endnotePr));
2453
- p.push(stringifyCompatibility({
2063
+ const compatXml = stringifyCompatibility({
2454
2064
  ...opts.compatibility,
2455
- version: opts.compatibility?.version ?? opts.compatibilityModeVersion ?? 15,
2456
- spaceForUnderline: opts.compatibility?.spaceForUnderline ?? true,
2457
- balanceSingleByteDoubleByteWidth: opts.compatibility?.balanceSingleByteDoubleByteWidth ?? true,
2458
- doNotLeaveBackslashAlone: opts.compatibility?.doNotLeaveBackslashAlone ?? true,
2459
- underlineTrailingSpaces: opts.compatibility?.underlineTrailingSpaces ?? true,
2460
- doNotExpandShiftReturn: opts.compatibility?.doNotExpandShiftReturn ?? true,
2461
- adjustLineHeightInTable: opts.compatibility?.adjustLineHeightInTable ?? true,
2462
- useFELayout: opts.compatibility?.useFELayout ?? true,
2463
- overrideTableStyleFontSizeAndJustification: opts.compatibility?.overrideTableStyleFontSizeAndJustification ?? true,
2464
- enableOpenTypeFeatures: opts.compatibility?.enableOpenTypeFeatures ?? true,
2465
- doNotFlipMirrorIndents: opts.compatibility?.doNotFlipMirrorIndents ?? true
2466
- }));
2065
+ version: opts.compatibility?.version ?? opts.compatibilityModeVersion
2066
+ });
2067
+ if (compatXml) p.push(compatXml);
2467
2068
  if (opts.docVars?.length) {
2468
2069
  const vars = opts.docVars.map((v) => attrEl("w:docVar", {
2469
2070
  "w:name": v.name,
@@ -2521,14 +2122,16 @@ const settingsDesc = {
2521
2122
  const val = attr(tabStopEl, "w:val");
2522
2123
  if (val) opts.defaultTabStop = parseInt(val, 10);
2523
2124
  }
2524
- if (findChild(el, "w:trackRevisions")) {
2125
+ const trackRevEl = findChild(el, "w:trackRevisions");
2126
+ if (trackRevEl) {
2525
2127
  const features = opts.features ?? {};
2526
- features.trackRevisions = true;
2128
+ features.trackRevisions = attrBool(trackRevEl, "w:val") ?? true;
2527
2129
  opts.features = features;
2528
2130
  }
2529
- if (findChild(el, "w:updateFields")) {
2131
+ const updateFieldsEl = findChild(el, "w:updateFields");
2132
+ if (updateFieldsEl) {
2530
2133
  const features = opts.features ?? {};
2531
- features.updateFields = true;
2134
+ features.updateFields = attrBool(updateFieldsEl, "w:val") ?? true;
2532
2135
  opts.features = features;
2533
2136
  }
2534
2137
  const compatEl = findChild(el, "w:compat");
@@ -2685,7 +2288,7 @@ const settingsDesc = {
2685
2288
  if (docProtEl) {
2686
2289
  const prot = {};
2687
2290
  const edit = attr(docProtEl, "w:edit");
2688
- if (edit) prot.edit = edit;
2291
+ if (edit && DOC_PROTECT_EDITS.includes(edit)) prot.edit = edit;
2689
2292
  if (attr(docProtEl, "w:enforcement") !== void 0) {
2690
2293
  const hash = attr(docProtEl, "w:hash");
2691
2294
  if (hash) prot.hash = hash;
@@ -2712,10 +2315,16 @@ const settingsDesc = {
2712
2315
  const formatting = attr(docProtEl, "w:formatting");
2713
2316
  if (formatting !== void 0) prot.formatting = formatting === "1" || formatting === "true";
2714
2317
  }
2715
- if (Object.keys(prot).length > 0) opts.documentProtection = prot;
2318
+ if (Object.keys(prot).length > 0) {
2319
+ const features = opts.features ?? {};
2320
+ features.documentProtection = prot;
2321
+ opts.features = features;
2322
+ }
2716
2323
  }
2717
- if (findChild(el, "w:doNotTrackMoves")) opts.doNotTrackMoves = true;
2718
- if (findChild(el, "w:doNotTrackFormatting")) opts.doNotTrackFormatting = true;
2324
+ const noMovesEl = findChild(el, "w:doNotTrackMoves");
2325
+ if (noMovesEl) opts.doNotTrackMoves = attrBool(noMovesEl, "w:val") ?? true;
2326
+ const noFmtEl = findChild(el, "w:doNotTrackFormatting");
2327
+ if (noFmtEl) opts.doNotTrackFormatting = attrBool(noFmtEl, "w:val") ?? true;
2719
2328
  return opts;
2720
2329
  }
2721
2330
  };
@@ -2853,6 +2462,19 @@ function parseTocFieldInstruction(instruction, opts) {
2853
2462
  if (switches["o"]) opts.headingStyleRange = switches["o"];
2854
2463
  if (switches["p"]) opts.entryAndPageNumberSeparator = switches["p"];
2855
2464
  if (switches["s"]) opts.seqFieldIdentifierForPrefix = switches["s"];
2465
+ if (switches["t"]) {
2466
+ const parts = switches["t"].split(",");
2467
+ const stylesWithLevels = [];
2468
+ for (let i = 0; i + 1 < parts.length; i += 2) {
2469
+ const styleName = parts[i];
2470
+ const level = parseInt(parts[i + 1], 10);
2471
+ if (styleName && !Number.isNaN(level)) stylesWithLevels.push({
2472
+ styleName,
2473
+ level
2474
+ });
2475
+ }
2476
+ if (stylesWithLevels.length > 0) opts.stylesWithLevels = stylesWithLevels;
2477
+ }
2856
2478
  if ("u" in switches) opts.useAppliedParagraphOutlineLevel = true;
2857
2479
  if ("w" in switches) opts.preserveTabInEntries = true;
2858
2480
  if ("x" in switches) opts.preserveNewLineInEntries = true;
@@ -3217,6 +2839,22 @@ const HEADING_MAP = {
3217
2839
  Heading6: HeadingLevel.HEADING_6,
3218
2840
  Title: HeadingLevel.TITLE
3219
2841
  };
2842
+ /** Valid w:spacing/@w:lineRule values (ST_LineSpacingRule). */
2843
+ const LINE_RULES = Object.values(LineRuleType);
2844
+ /** Valid border @w:val values (ST_Border). */
2845
+ const BORDER_STYLES = Object.values(BorderStyle);
2846
+ /** Valid border @w:themeColor values (ST_ThemeColor). */
2847
+ const THEME_COLORS = Object.values(ThemeColor);
2848
+ /**
2849
+ * Reverse of inline.ts's deleted-page-number field map: maps a w:delInstrText
2850
+ * field code to the PageNumber placeholder a deletion run uses on the stringify
2851
+ * side, so deleted page-number fields round-trip instead of being dropped.
2852
+ */
2853
+ const DELETED_PAGE_FIELD = {
2854
+ PAGE: "CURRENT",
2855
+ NUMPAGES: "TOTAL_PAGES",
2856
+ SECTIONPAGES: "TOTAL_PAGES_IN_SECTION"
2857
+ };
3220
2858
  /**
3221
2859
  * Parse w:pPr element into paragraph properties (without children).
3222
2860
  */
@@ -3243,11 +2881,15 @@ function parseParagraphProperties(el, ctx) {
3243
2881
  const line = attrNum(spacing, "w:line");
3244
2882
  if (line !== void 0) sp.line = line;
3245
2883
  const lineRule = attr(spacing, "w:lineRule");
3246
- if (lineRule) sp.lineRule = lineRule;
3247
- const beforeAuto = attrBool(spacing, "w:beforeAutospacing") ?? attrBool(spacing, "w:beforeLines");
3248
- if (beforeAuto !== void 0) sp.beforeAutoSpacing = beforeAuto;
3249
- const afterAuto = attrBool(spacing, "w:afterAutospacing") ?? attrBool(spacing, "w:afterLines");
3250
- if (afterAuto !== void 0) sp.afterAutoSpacing = afterAuto;
2884
+ if (lineRule && LINE_RULES.includes(lineRule)) sp.lineRule = lineRule;
2885
+ const beforeAutoSpacing = attrBool(spacing, "w:beforeAutospacing");
2886
+ if (beforeAutoSpacing !== void 0) sp.beforeAutoSpacing = beforeAutoSpacing;
2887
+ const afterAutoSpacing = attrBool(spacing, "w:afterAutospacing");
2888
+ if (afterAutoSpacing !== void 0) sp.afterAutoSpacing = afterAutoSpacing;
2889
+ const beforeLines = attrNum(spacing, "w:beforeLines");
2890
+ if (beforeLines !== void 0) sp.beforeLines = beforeLines;
2891
+ const afterLines = attrNum(spacing, "w:afterLines");
2892
+ if (afterLines !== void 0) sp.afterLines = afterLines;
3251
2893
  if (Object.keys(sp).length > 0) opts.spacing = sp;
3252
2894
  }
3253
2895
  const ind = findChild(el, "w:ind");
@@ -3255,16 +2897,28 @@ function parseParagraphProperties(el, ctx) {
3255
2897
  const indentObj = {};
3256
2898
  const left = attrNum(ind, "w:left");
3257
2899
  if (left !== void 0) indentObj.left = left;
2900
+ const leftChars = attrNum(ind, "w:leftChars");
2901
+ if (leftChars !== void 0) indentObj.leftChars = leftChars;
3258
2902
  const right = attrNum(ind, "w:right");
3259
2903
  if (right !== void 0) indentObj.right = right;
2904
+ const rightChars = attrNum(ind, "w:rightChars");
2905
+ if (rightChars !== void 0) indentObj.rightChars = rightChars;
3260
2906
  const start = attrNum(ind, "w:start");
3261
2907
  if (start !== void 0) indentObj.start = start;
2908
+ const startChars = attrNum(ind, "w:startChars");
2909
+ if (startChars !== void 0) indentObj.startChars = startChars;
3262
2910
  const end = attrNum(ind, "w:end");
3263
2911
  if (end !== void 0) indentObj.end = end;
2912
+ const endChars = attrNum(ind, "w:endChars");
2913
+ if (endChars !== void 0) indentObj.endChars = endChars;
3264
2914
  const hanging = attrNum(ind, "w:hanging");
3265
2915
  if (hanging !== void 0) indentObj.hanging = hanging;
2916
+ const hangingChars = attrNum(ind, "w:hangingChars");
2917
+ if (hangingChars !== void 0) indentObj.hangingChars = hangingChars;
3266
2918
  const firstLine = attrNum(ind, "w:firstLine");
3267
2919
  if (firstLine !== void 0) indentObj.firstLine = firstLine;
2920
+ const firstLineChars = attrNum(ind, "w:firstLineChars");
2921
+ if (firstLineChars !== void 0) indentObj.firstLineChars = firstLineChars;
3268
2922
  if (Object.keys(indentObj).length > 0) opts.indent = indentObj;
3269
2923
  }
3270
2924
  const numPr = findChild(el, "w:numPr");
@@ -3325,6 +2979,7 @@ function parseParagraphProperties(el, ctx) {
3325
2979
  ["w:kinsoku", "kinsoku"],
3326
2980
  ["w:topLinePunct", "topLinePunct"],
3327
2981
  ["w:autoSpaceDE", "autoSpaceDE"],
2982
+ ["w:autoSpaceDN", "autoSpaceEastAsianText"],
3328
2983
  ["w:overflowPunct", "overflowPunctuation"],
3329
2984
  ["w:suppressOverlap", "suppressOverlap"]
3330
2985
  ]) {
@@ -3338,21 +2993,32 @@ function parseParagraphProperties(el, ctx) {
3338
2993
  "top",
3339
2994
  "bottom",
3340
2995
  "left",
3341
- "right"
2996
+ "right",
2997
+ "between",
2998
+ "bar"
3342
2999
  ]) {
3343
3000
  const sideEl = findChild(pBdr, `w:${side}`);
3344
- if (sideEl) {
3345
- const sideOpts = {};
3346
- const style = attr(sideEl, "w:val");
3347
- if (style) sideOpts.style = style;
3348
- const color = attr(sideEl, "w:color");
3349
- if (color) sideOpts.color = color;
3350
- const size = attrNum(sideEl, "w:sz");
3351
- if (size !== void 0) sideOpts.size = size;
3352
- const space = attrNum(sideEl, "w:space");
3353
- if (space !== void 0) sideOpts.space = space;
3354
- border[side] = sideOpts;
3355
- }
3001
+ if (!sideEl) continue;
3002
+ const style = attr(sideEl, "w:val");
3003
+ if (!style || !BORDER_STYLES.includes(style)) continue;
3004
+ const sideOpts = { style };
3005
+ const color = attr(sideEl, "w:color");
3006
+ if (color) sideOpts.color = color;
3007
+ const size = attrNum(sideEl, "w:sz");
3008
+ if (size !== void 0) sideOpts.size = size;
3009
+ const space = attrNum(sideEl, "w:space");
3010
+ if (space !== void 0) sideOpts.space = space;
3011
+ const themeColor = attr(sideEl, "w:themeColor");
3012
+ if (themeColor && THEME_COLORS.includes(themeColor)) sideOpts.themeColor = themeColor;
3013
+ const themeTint = attr(sideEl, "w:themeTint");
3014
+ if (themeTint) sideOpts.themeTint = themeTint;
3015
+ const themeShade = attr(sideEl, "w:themeShade");
3016
+ if (themeShade) sideOpts.themeShade = themeShade;
3017
+ const shadow = attrBool(sideEl, "w:shadow");
3018
+ if (shadow !== void 0) sideOpts.shadow = shadow;
3019
+ const frame = attrBool(sideEl, "w:frame");
3020
+ if (frame !== void 0) sideOpts.frame = frame;
3021
+ border[side] = sideOpts;
3356
3022
  }
3357
3023
  if (Object.keys(border).length > 0) opts.border = border;
3358
3024
  }
@@ -3397,6 +3063,24 @@ function parseParagraphProperties(el, ctx) {
3397
3063
  const val = attr(framePr, attrName);
3398
3064
  if (val !== void 0) frame[optName] = val;
3399
3065
  }
3066
+ const xAlign = attr(framePr, "w:xAlign");
3067
+ const yAlign = attr(framePr, "w:yAlign");
3068
+ if (xAlign || yAlign) {
3069
+ const alignment = {};
3070
+ if (xAlign) alignment.x = xAlign;
3071
+ if (yAlign) alignment.y = yAlign;
3072
+ frame.alignment = alignment;
3073
+ }
3074
+ const hAnchor = attr(framePr, "w:hAnchor");
3075
+ const vAnchor = attr(framePr, "w:vAnchor");
3076
+ if (hAnchor || vAnchor) {
3077
+ const anchor = {};
3078
+ if (hAnchor) anchor.horizontal = hAnchor;
3079
+ if (vAnchor) anchor.vertical = vAnchor;
3080
+ frame.anchor = anchor;
3081
+ }
3082
+ const anchorLock = attrBool(framePr, "w:anchorLock");
3083
+ if (anchorLock !== void 0) frame.anchorLock = anchorLock;
3400
3084
  const w = attrNum(framePr, "w:w");
3401
3085
  if (w !== void 0) frame.width = w;
3402
3086
  const h = attrNum(framePr, "w:h");
@@ -3417,17 +3101,119 @@ function collectRunText(el) {
3417
3101
  for (const c of el.elements ?? []) if (c.name === "w:t") text += textOf(c);
3418
3102
  return text;
3419
3103
  }
3104
+ /** Concatenate `<w:t>` text across all `<w:r>` children of a container (rt/rubyBase). */
3105
+ function collectRunsText(el) {
3106
+ let text = "";
3107
+ for (const r of el.elements ?? []) if (r.name === "w:r") text += collectRunText(r);
3108
+ return text;
3109
+ }
3110
+ /**
3111
+ * Parse the inline children of a smartTag/customXml container (recursive).
3112
+ *
3113
+ * Handles runs and nested smartTag/customXml. Form fields, hyperlinks and
3114
+ * other paragraph-level constructs are rare inside these containers and are
3115
+ * not handled here.
3116
+ */
3117
+ function parseContainerChildren(el, ctx) {
3118
+ const children = [];
3119
+ for (const sub of el.elements ?? []) switch (sub.name) {
3120
+ case "w:r": {
3121
+ const runOpts = parsedRunToOptions(parseRun(sub, ctx));
3122
+ if (runOpts !== null) children.push(runOpts);
3123
+ break;
3124
+ }
3125
+ case "w:smartTag":
3126
+ children.push({ smartTag: parseSmartTagInline(sub, ctx) });
3127
+ break;
3128
+ case "w:customXml":
3129
+ children.push({ customXml: parseCustomXmlInline(sub, ctx) });
3130
+ break;
3131
+ default: break;
3132
+ }
3133
+ return children;
3134
+ }
3135
+ /** Parse a w:smartTag element into its ParagraphChild form. */
3136
+ function parseSmartTagInline(el, ctx) {
3137
+ const st = {};
3138
+ const element = attr(el, "w:element");
3139
+ if (element) st.element = element;
3140
+ const uri = attr(el, "w:uri");
3141
+ if (uri) st.uri = uri;
3142
+ const pr = findChild(el, "w:smartTagPr");
3143
+ if (pr) {
3144
+ const props = [];
3145
+ for (const a of pr.elements ?? []) {
3146
+ if (a.name !== "w:attr") continue;
3147
+ const prop = {
3148
+ name: attr(a, "w:name") ?? "",
3149
+ val: attr(a, "w:val") ?? ""
3150
+ };
3151
+ const auri = attr(a, "w:uri");
3152
+ if (auri) prop.uri = auri;
3153
+ props.push(prop);
3154
+ }
3155
+ if (props.length > 0) st.properties = props;
3156
+ }
3157
+ const content = parseContainerChildren(el, ctx);
3158
+ if (content.length > 0) st.children = content;
3159
+ return st;
3160
+ }
3161
+ /** Parse an inline w:customXml element into its ParagraphChild form. */
3162
+ function parseCustomXmlInline(el, ctx) {
3163
+ const cx = {};
3164
+ const element = attr(el, "w:element");
3165
+ if (element) cx.element = element;
3166
+ const uri = attr(el, "w:uri");
3167
+ if (uri) cx.uri = uri;
3168
+ const pr = findChild(el, "w:customXmlPr");
3169
+ if (pr) {
3170
+ const parsed = parseCustomXmlPr(pr);
3171
+ if (parsed.placeholder !== void 0 || parsed.attributes !== void 0) cx.customXmlPr = parsed;
3172
+ }
3173
+ const content = parseContainerChildren(el, ctx);
3174
+ if (content.length > 0) cx.children = content;
3175
+ return cx;
3176
+ }
3177
+ /** Parse a move-revision range start (w:moveFromRangeStart / w:moveToRangeStart). */
3178
+ function parseMoveRangeStart(el) {
3179
+ const id = attrNum(el, "w:id");
3180
+ if (id === void 0) return null;
3181
+ const m = { id };
3182
+ const name = attr(el, "w:name");
3183
+ if (name !== void 0) m.name = name;
3184
+ const author = attr(el, "w:author");
3185
+ if (author !== void 0) m.author = author;
3186
+ const date = attr(el, "w:date");
3187
+ if (date !== void 0) m.date = date;
3188
+ return m;
3189
+ }
3190
+ /** Parse a customXml range start (Ins/Del/MoveFrom/MoveTo). */
3191
+ function parseCustomXmlRangeStart(el) {
3192
+ const id = attrNum(el, "w:id");
3193
+ if (id === void 0) return null;
3194
+ const m = { id };
3195
+ const author = attr(el, "w:author");
3196
+ if (author !== void 0) m.author = author;
3197
+ const date = attr(el, "w:date");
3198
+ if (date !== void 0) m.date = date;
3199
+ return m;
3200
+ }
3420
3201
  /**
3421
3202
  * Parse a w:p element into ParagraphOptions.
3422
3203
  */
3423
- function parseParagraph(el, ctx) {
3424
- const opts = {};
3425
- const pPr = findChild(el, "w:pPr");
3426
- if (pPr) Object.assign(opts, parseParagraphProperties(pPr, ctx));
3204
+ /**
3205
+ * Parse run-level children shared by paragraphs and inline-SDT content.
3206
+ * Includes the field accumulator that collapses form/complex fields spanning
3207
+ * multiple w:r runs into a single child.
3208
+ */
3209
+ function parseRunLevelChildren(elements, ctx) {
3427
3210
  const childList = [];
3211
+ let fieldKind = null;
3428
3212
  let pendingFormField = null;
3213
+ let pendingInstruction = "";
3214
+ let pendingResult = "";
3429
3215
  let collectingResult = false;
3430
- for (const child of el.elements ?? []) switch (child.name) {
3216
+ for (const child of elements ?? []) switch (child.name) {
3431
3217
  case "w:pPr": break;
3432
3218
  case "w:r": {
3433
3219
  const fldCharEl = findChild(child, "w:fldChar");
@@ -3435,17 +3221,36 @@ function parseParagraph(el, ctx) {
3435
3221
  const fctype = attr(fldCharEl, "w:fldCharType");
3436
3222
  if (fctype === "begin") {
3437
3223
  const ffDataEl = findChild(fldCharEl, "w:ffData");
3438
- if (ffDataEl) pendingFormField = parseFormFieldData(ffDataEl);
3224
+ if (ffDataEl) {
3225
+ fieldKind = "form";
3226
+ pendingFormField = parseFormFieldData(ffDataEl);
3227
+ } else {
3228
+ fieldKind = "complex";
3229
+ pendingInstruction = "";
3230
+ pendingResult = "";
3231
+ }
3232
+ collectingResult = false;
3439
3233
  } else if (fctype === "separate") collectingResult = true;
3440
- else if (fctype === "end" && pendingFormField) {
3441
- childList.push({ formField: pendingFormField });
3234
+ else if (fctype === "end" && fieldKind) {
3235
+ if (fieldKind === "form" && pendingFormField) childList.push({ formField: pendingFormField });
3236
+ else if (fieldKind === "complex") {
3237
+ const cf = { instruction: pendingInstruction };
3238
+ if (pendingResult) cf.result = pendingResult;
3239
+ childList.push({ complexField: cf });
3240
+ }
3241
+ fieldKind = null;
3442
3242
  pendingFormField = null;
3443
3243
  collectingResult = false;
3444
3244
  }
3445
3245
  break;
3446
3246
  }
3447
- if (pendingFormField) {
3448
- if (collectingResult && pendingFormField.textInput) {
3247
+ if (fieldKind) {
3248
+ if (fieldKind === "complex") if (collectingResult) pendingResult += collectRunText(child);
3249
+ else {
3250
+ const instrEl = findChild(child, "w:instrText");
3251
+ if (instrEl) pendingInstruction += textOf(instrEl);
3252
+ }
3253
+ else if (collectingResult && pendingFormField?.textInput) {
3449
3254
  const text = collectRunText(child);
3450
3255
  if (text) {
3451
3256
  const ti = pendingFormField.textInput;
@@ -3536,6 +3341,24 @@ function parseParagraph(el, ctx) {
3536
3341
  break;
3537
3342
  }
3538
3343
  case "w:del": {
3344
+ let delFieldPlaceholder;
3345
+ for (const sub of child.elements ?? []) {
3346
+ if (sub.name !== "w:r") continue;
3347
+ const delInstrEl = findChild(sub, "w:delInstrText");
3348
+ if (delInstrEl) {
3349
+ delFieldPlaceholder = DELETED_PAGE_FIELD[(textOf(delInstrEl) ?? "").trim()];
3350
+ if (delFieldPlaceholder) break;
3351
+ }
3352
+ }
3353
+ if (delFieldPlaceholder) {
3354
+ childList.push({ deletion: {
3355
+ id: attrNum(child, "w:id") ?? 0,
3356
+ author: attr(child, "w:author") ?? "",
3357
+ date: attr(child, "w:date") ?? "",
3358
+ children: [delFieldPlaceholder]
3359
+ } });
3360
+ break;
3361
+ }
3539
3362
  const delRun = findChild(child, "w:r");
3540
3363
  if (delRun) {
3541
3364
  const runOpts = parsedRunToOptions(parseRun(delRun, ctx));
@@ -3548,8 +3371,229 @@ function parseParagraph(el, ctx) {
3548
3371
  }
3549
3372
  break;
3550
3373
  }
3374
+ case "w:moveFrom": {
3375
+ const runEl = findChild(child, "w:r");
3376
+ if (runEl) {
3377
+ const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
3378
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedFrom: {
3379
+ id: attrNum(child, "w:id") ?? 0,
3380
+ author: attr(child, "w:author") ?? "",
3381
+ date: attr(child, "w:date") ?? "",
3382
+ ...runOpts
3383
+ } });
3384
+ }
3385
+ break;
3386
+ }
3387
+ case "w:moveTo": {
3388
+ const runEl = findChild(child, "w:r");
3389
+ if (runEl) {
3390
+ const runOpts = parsedRunToOptions(parseRun(runEl, ctx));
3391
+ if (runOpts !== null && typeof runOpts === "object" && !("commentReference" in runOpts)) childList.push({ movedTo: {
3392
+ id: attrNum(child, "w:id") ?? 0,
3393
+ author: attr(child, "w:author") ?? "",
3394
+ date: attr(child, "w:date") ?? "",
3395
+ ...runOpts
3396
+ } });
3397
+ }
3398
+ break;
3399
+ }
3400
+ case "w:fldSimple": {
3401
+ const instruction = attr(child, "w:instr");
3402
+ if (instruction) {
3403
+ const sf = { instruction };
3404
+ let cachedValue = "";
3405
+ for (const sub of child.elements ?? []) if (sub.name === "w:r") cachedValue += collectRunText(sub);
3406
+ if (cachedValue) sf.cachedValue = cachedValue;
3407
+ childList.push({ simpleField: sf });
3408
+ }
3409
+ break;
3410
+ }
3411
+ case "w:smartTag": {
3412
+ const st = parseSmartTagInline(child, ctx);
3413
+ if (st.element) childList.push({ smartTag: st });
3414
+ break;
3415
+ }
3416
+ case "w:customXml": {
3417
+ const cx = parseCustomXmlInline(child, ctx);
3418
+ if (cx.element) childList.push({ customXml: cx });
3419
+ break;
3420
+ }
3421
+ case "w:dir": {
3422
+ const val = attr(child, "w:val");
3423
+ if (val) {
3424
+ const dir = { val };
3425
+ const content = parseContainerChildren(child, ctx);
3426
+ if (content.length > 0) dir.children = content;
3427
+ childList.push({ dir });
3428
+ }
3429
+ break;
3430
+ }
3431
+ case "w:bdo": {
3432
+ const val = attr(child, "w:val");
3433
+ if (val) {
3434
+ const bdo = { val };
3435
+ const content = parseContainerChildren(child, ctx);
3436
+ if (content.length > 0) bdo.children = content;
3437
+ childList.push({ bdo });
3438
+ }
3439
+ break;
3440
+ }
3441
+ case "w:ruby": {
3442
+ const ruby = {};
3443
+ const pr = findChild(child, "w:rubyPr");
3444
+ if (pr) {
3445
+ const alignEl = findChild(pr, "w:rubyAlign");
3446
+ if (alignEl) {
3447
+ const v = attr(alignEl, "w:val");
3448
+ if (v) ruby.alignment = v;
3449
+ }
3450
+ const hpsEl = findChild(pr, "w:hps");
3451
+ if (hpsEl) {
3452
+ const v = attrNum(hpsEl, "w:val");
3453
+ if (v !== void 0) ruby.fontSize = v / 2;
3454
+ }
3455
+ const hpsRaiseEl = findChild(pr, "w:hpsRaise");
3456
+ if (hpsRaiseEl) {
3457
+ const v = attrNum(hpsRaiseEl, "w:val");
3458
+ if (v !== void 0) ruby.raise = v / 2;
3459
+ }
3460
+ const hpsBaseEl = findChild(pr, "w:hpsBaseText");
3461
+ if (hpsBaseEl) {
3462
+ const v = attrNum(hpsBaseEl, "w:val");
3463
+ if (v !== void 0) ruby.baseFontSize = v / 2;
3464
+ }
3465
+ const lidEl = findChild(pr, "w:lid");
3466
+ if (lidEl) {
3467
+ const v = attr(lidEl, "w:val");
3468
+ if (v) ruby.languageId = v;
3469
+ }
3470
+ if (findChild(pr, "w:dirty")) ruby.dirty = true;
3471
+ }
3472
+ const rt = findChild(child, "w:rt");
3473
+ if (rt) ruby.text = collectRunsText(rt);
3474
+ const rubyBase = findChild(child, "w:rubyBase");
3475
+ if (rubyBase) ruby.base = collectRunsText(rubyBase);
3476
+ if (ruby.text !== void 0 && ruby.base !== void 0) childList.push({ ruby });
3477
+ break;
3478
+ }
3479
+ case "w:proofErr": {
3480
+ const type = attr(child, "w:type");
3481
+ if (type) childList.push({ proofErr: type });
3482
+ break;
3483
+ }
3484
+ case "w:ptab": {
3485
+ const alignment = attr(child, "w:alignment");
3486
+ const leader = attr(child, "w:leader");
3487
+ const relativeTo = attr(child, "w:relativeTo");
3488
+ if (alignment !== void 0 && leader !== void 0 && relativeTo !== void 0) childList.push({ positionalTab: {
3489
+ alignment,
3490
+ leader,
3491
+ relativeTo
3492
+ } });
3493
+ break;
3494
+ }
3495
+ case "w:permStart": {
3496
+ const id = attr(child, "w:id");
3497
+ if (id !== void 0) {
3498
+ const ps = { id };
3499
+ const ed = attr(child, "w:ed");
3500
+ if (ed !== void 0) ps.ed = ed;
3501
+ const editGroup = attr(child, "w:edGrp");
3502
+ if (editGroup !== void 0) ps.editGroup = editGroup;
3503
+ const colFirst = attrNum(child, "w:colFirst");
3504
+ if (colFirst !== void 0) ps.colFirst = colFirst;
3505
+ const colLast = attrNum(child, "w:colLast");
3506
+ if (colLast !== void 0) ps.colLast = colLast;
3507
+ childList.push({ permStart: ps });
3508
+ }
3509
+ break;
3510
+ }
3511
+ case "w:permEnd": {
3512
+ const id = attr(child, "w:id");
3513
+ if (id !== void 0) childList.push({ permEnd: id });
3514
+ break;
3515
+ }
3516
+ case "w:moveFromRangeStart": {
3517
+ const m = parseMoveRangeStart(child);
3518
+ if (m) childList.push({ moveFromRangeStart: m });
3519
+ break;
3520
+ }
3521
+ case "w:moveFromRangeEnd": {
3522
+ const id = attrNum(child, "w:id");
3523
+ if (id !== void 0) childList.push({ moveFromRangeEnd: id });
3524
+ break;
3525
+ }
3526
+ case "w:moveToRangeStart": {
3527
+ const m = parseMoveRangeStart(child);
3528
+ if (m) childList.push({ moveToRangeStart: m });
3529
+ break;
3530
+ }
3531
+ case "w:moveToRangeEnd": {
3532
+ const id = attrNum(child, "w:id");
3533
+ if (id !== void 0) childList.push({ moveToRangeEnd: id });
3534
+ break;
3535
+ }
3536
+ case "w:customXmlInsRangeStart": {
3537
+ const m = parseCustomXmlRangeStart(child);
3538
+ if (m) childList.push({ customXmlInsRangeStart: m });
3539
+ break;
3540
+ }
3541
+ case "w:customXmlInsRangeEnd": {
3542
+ const id = attrNum(child, "w:id");
3543
+ if (id !== void 0) childList.push({ customXmlInsRangeEnd: id });
3544
+ break;
3545
+ }
3546
+ case "w:customXmlDelRangeStart": {
3547
+ const m = parseCustomXmlRangeStart(child);
3548
+ if (m) childList.push({ customXmlDelRangeStart: m });
3549
+ break;
3550
+ }
3551
+ case "w:customXmlDelRangeEnd": {
3552
+ const id = attrNum(child, "w:id");
3553
+ if (id !== void 0) childList.push({ customXmlDelRangeEnd: id });
3554
+ break;
3555
+ }
3556
+ case "w:customXmlMoveFromRangeStart": {
3557
+ const m = parseCustomXmlRangeStart(child);
3558
+ if (m) childList.push({ customXmlMoveFromRangeStart: m });
3559
+ break;
3560
+ }
3561
+ case "w:customXmlMoveFromRangeEnd": {
3562
+ const id = attrNum(child, "w:id");
3563
+ if (id !== void 0) childList.push({ customXmlMoveFromRangeEnd: id });
3564
+ break;
3565
+ }
3566
+ case "w:customXmlMoveToRangeStart": {
3567
+ const m = parseCustomXmlRangeStart(child);
3568
+ if (m) childList.push({ customXmlMoveToRangeStart: m });
3569
+ break;
3570
+ }
3571
+ case "w:customXmlMoveToRangeEnd": {
3572
+ const id = attrNum(child, "w:id");
3573
+ if (id !== void 0) childList.push({ customXmlMoveToRangeEnd: id });
3574
+ break;
3575
+ }
3576
+ case "w:sdt": {
3577
+ const sdtPr = findChild(child, "w:sdtPr");
3578
+ const properties = sdtPr ? parseSdtProperties(sdtPr) : {};
3579
+ const sdtEndPr = findChild(child, "w:sdtEndPr");
3580
+ const endProperties = sdtEndPr ? parseRunProperties(sdtEndPr) : void 0;
3581
+ const sdtChildren = parseRunLevelChildren(findChild(child, "w:sdtContent")?.elements, ctx);
3582
+ const sdt = { properties };
3583
+ if (sdtChildren.length > 0) sdt.children = sdtChildren;
3584
+ if (endProperties) sdt.endProperties = endProperties;
3585
+ childList.push({ sdt });
3586
+ break;
3587
+ }
3551
3588
  default: break;
3552
3589
  }
3590
+ return childList;
3591
+ }
3592
+ function parseParagraph(el, ctx) {
3593
+ const opts = {};
3594
+ const pPr = findChild(el, "w:pPr");
3595
+ if (pPr) Object.assign(opts, parseParagraphProperties(pPr, ctx));
3596
+ const childList = parseRunLevelChildren(el.elements, ctx);
3553
3597
  if (childList.length > 0) {
3554
3598
  if (childList.every((c) => typeof c === "object" && c !== null && "text" in c && Object.keys(c).length === 1)) {
3555
3599
  const combined = childList.map((c) => c.text).join("");
@@ -3656,151 +3700,6 @@ const endnotesDesc = {
3656
3700
  }
3657
3701
  };
3658
3702
  //#endregion
3659
- //#region src/parts/sdt/sdt-parse.ts
3660
- /**
3661
- * Structured Document Tag parser for DOCX documents.
3662
- *
3663
- * Parses w:sdt elements into SdtPropertiesOptions + children.
3664
- *
3665
- * @module
3666
- */
3667
- /**
3668
- * Parse w:sdtPr element into SdtPropertiesOptions.
3669
- */
3670
- function parseSdtProperties(el) {
3671
- const opts = {};
3672
- const alias = findChild(el, "w:alias");
3673
- if (alias) opts.alias = attr(alias, "w:val");
3674
- const tag = findChild(el, "w:tag");
3675
- if (tag) {
3676
- const val = attr(tag, "w:val");
3677
- if (val) opts.tag = val;
3678
- }
3679
- const id = findChild(el, "w:id");
3680
- if (id) {
3681
- const val = attrNum(id, "w:val");
3682
- if (val !== void 0) opts.id = val;
3683
- }
3684
- const lock = findChild(el, "w:lock");
3685
- if (lock) {
3686
- const val = attr(lock, "w:val");
3687
- if (val) opts.lock = val;
3688
- }
3689
- const temporary = findChild(el, "w:temporary");
3690
- if (temporary) opts.temporary = attrBool(temporary, "w:val") ?? true;
3691
- const showingPlcHdr = findChild(el, "w:showingPlcHdr");
3692
- if (showingPlcHdr) opts.showingPlaceholder = attrBool(showingPlcHdr, "w:val") ?? true;
3693
- const label = findChild(el, "w:label");
3694
- if (label) {
3695
- const val = attrNum(label, "w:val");
3696
- if (val !== void 0) opts.label = val;
3697
- }
3698
- const tabIndex = findChild(el, "w:tabIndex");
3699
- if (tabIndex) {
3700
- const val = attrNum(tabIndex, "w:val");
3701
- if (val !== void 0) opts.tabIndex = val;
3702
- }
3703
- const dataBinding = findChild(el, "w:dataBinding");
3704
- if (dataBinding) opts.dataBinding = {
3705
- xpath: attr(dataBinding, "w:xpath") ?? "",
3706
- storeItemID: attr(dataBinding, "w:storeItemID") ?? "",
3707
- prefixMappings: attr(dataBinding, "w:prefixMappings")
3708
- };
3709
- if (findChild(el, "w:equation")) opts.equation = true;
3710
- else if (findChild(el, "w:comboBox")) {
3711
- const comboBox = findChild(el, "w:comboBox");
3712
- const items = [];
3713
- for (const li of children(comboBox, "w:listItem")) items.push({
3714
- displayText: attr(li, "w:displayText"),
3715
- value: attr(li, "w:value")
3716
- });
3717
- opts.comboBox = {
3718
- items: items.length > 0 ? items : void 0,
3719
- lastValue: attr(comboBox, "w:lastValue")
3720
- };
3721
- } else if (findChild(el, "w:date")) {
3722
- const date = findChild(el, "w:date");
3723
- const dateOpts = {};
3724
- const dateFormat = findChild(date, "w:dateFormat");
3725
- if (dateFormat) dateOpts.dateFormat = textOf(dateFormat);
3726
- const lid = findChild(date, "w:lid");
3727
- if (lid) dateOpts.languageId = textOf(lid);
3728
- const storeMapped = findChild(date, "w:storeMappedDataAs");
3729
- if (storeMapped) dateOpts.storeMappedDataAs = attr(storeMapped, "w:val");
3730
- const calendar = findChild(date, "w:calendar");
3731
- if (calendar) dateOpts.calendar = attr(calendar, "w:val");
3732
- const fullDate = attr(date, "w:fullDate");
3733
- if (fullDate) dateOpts.fullDate = fullDate;
3734
- opts.date = dateOpts;
3735
- } else if (findChild(el, "w:dropDownList")) {
3736
- const ddl = findChild(el, "w:dropDownList");
3737
- const items = [];
3738
- for (const li of children(ddl, "w:listItem")) items.push({
3739
- displayText: attr(li, "w:displayText"),
3740
- value: attr(li, "w:value")
3741
- });
3742
- opts.dropDownList = {
3743
- items: items.length > 0 ? items : void 0,
3744
- lastValue: attr(ddl, "w:lastValue")
3745
- };
3746
- } else if (findChild(el, "w:picture")) opts.picture = true;
3747
- else if (findChild(el, "w:richText")) opts.richText = true;
3748
- else if (findChild(el, "w:text")) opts.text = { multiLine: attrBool(findChild(el, "w:text"), "w:multiLine") };
3749
- else if (findChild(el, "w:citation")) opts.citation = true;
3750
- else if (findChild(el, "w:group")) opts.group = true;
3751
- else if (findChild(el, "w:bibliography")) opts.bibliography = true;
3752
- else if (findChild(el, "w:docPartObj")) {
3753
- const dp = findChild(el, "w:docPartObj");
3754
- opts.docPartObj = {};
3755
- const gallery = findChild(dp, "w:docPartGallery");
3756
- if (gallery) opts.docPartObj.gallery = attr(gallery, "w:val");
3757
- const category = findChild(dp, "w:docPartCategory");
3758
- if (category) opts.docPartObj.category = attr(category, "w:val");
3759
- } else if (findChild(el, "w:docPartList")) {
3760
- const dp = findChild(el, "w:docPartList");
3761
- opts.docPartList = {};
3762
- const gallery = findChild(dp, "w:docPartGallery");
3763
- if (gallery) opts.docPartList.gallery = attr(gallery, "w:val");
3764
- const category = findChild(dp, "w:docPartCategory");
3765
- if (category) opts.docPartList.category = attr(category, "w:val");
3766
- } else if (findChild(el, "w14:checkbox")) {
3767
- const cb = findChild(el, "w14:checkbox");
3768
- const cbObj = {};
3769
- const checked = findChild(cb, "w14:checked");
3770
- if (checked) cbObj.checked = attrBool(checked, "w14:val") ?? true;
3771
- const checkedState = findChild(cb, "w14:checkedState");
3772
- if (checkedState) cbObj.checkedState = {
3773
- val: attr(checkedState, "w14:val") ?? "",
3774
- font: attr(checkedState, "w14:font")
3775
- };
3776
- const uncheckedState = findChild(cb, "w14:uncheckedState");
3777
- if (uncheckedState) cbObj.uncheckedState = {
3778
- val: attr(uncheckedState, "w14:val") ?? "",
3779
- font: attr(uncheckedState, "w14:font")
3780
- };
3781
- opts.checkbox = cbObj;
3782
- }
3783
- return opts;
3784
- }
3785
- /**
3786
- * Parse a block-level w:sdt element.
3787
- * Returns an object suitable for the { sdt: ... } SectionChild variant.
3788
- */
3789
- function parseSdtBlock(el, ctx, parseChildren) {
3790
- const sdtPr = findChild(el, "w:sdtPr");
3791
- const properties = sdtPr ? parseSdtProperties(sdtPr) : {};
3792
- const sdtContent = findChild(el, "w:sdtContent");
3793
- let childList;
3794
- if (sdtContent) {
3795
- childList = parseChildren(sdtContent.elements ?? [], ctx);
3796
- if (childList.length === 0) childList = void 0;
3797
- }
3798
- return {
3799
- properties,
3800
- children: childList
3801
- };
3802
- }
3803
- //#endregion
3804
3703
  //#region src/parts/perm-start.ts
3805
3704
  /**
3806
3705
  * Permission range markers for WordprocessingML document protection.
@@ -3981,7 +3880,7 @@ const fontTableDesc = {
3981
3880
  };
3982
3881
  //#endregion
3983
3882
  //#region src/parts/bibliography.ts
3984
- function escapeXml$2(s) {
3883
+ function escapeXml$1(s) {
3985
3884
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3986
3885
  }
3987
3886
  const SOURCE_FIELDS = [
@@ -4006,13 +3905,13 @@ const bibliographyDesc = {
4006
3905
  kind: "custom",
4007
3906
  stringify(opts, _ctx) {
4008
3907
  const attrParts = ["xmlns:b=\"http://schemas.openxmlformats.org/officeDocument/2006/bibliography\""];
4009
- if (opts.styleName !== void 0) attrParts.push(`StyleName="${escapeXml$2(opts.styleName)}"`);
3908
+ if (opts.styleName !== void 0) attrParts.push(`StyleName="${escapeXml$1(opts.styleName)}"`);
4010
3909
  const parts = [`<b:Sources ${attrParts.join(" ")}>`];
4011
3910
  for (const source of opts.sources) {
4012
3911
  const sourceParts = [];
4013
3912
  for (const [tagName, key] of SOURCE_FIELDS) {
4014
3913
  const value = source[key];
4015
- if (value !== void 0) sourceParts.push(`<b:${tagName}>${escapeXml$2(value)}</b:${tagName}>`);
3914
+ if (value !== void 0) sourceParts.push(`<b:${tagName}>${escapeXml$1(value)}</b:${tagName}>`);
4016
3915
  }
4017
3916
  parts.push(`<b:Source>${sourceParts.join("")}</b:Source>`);
4018
3917
  }
@@ -4197,15 +4096,15 @@ const glossaryDesc = {
4197
4096
  };
4198
4097
  //#endregion
4199
4098
  //#region src/parts/comments.ts
4200
- function escapeAttr$1(s) {
4099
+ function escapeAttr(s) {
4201
4100
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
4202
4101
  }
4203
4102
  const COMMENTS_NS = "xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:w16=\"http://schemas.microsoft.com/office/word/2018/wordml\" xmlns:w16cex=\"http://schemas.microsoft.com/office/word/2018/wordml/cex\" xmlns:w16cid=\"http://schemas.microsoft.com/office/word/2016/wordml/cid\" xmlns:w16sdtdh=\"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash\" xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wne=\"http://schemas.openxmlformats.org/office/word/2006/wordml\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\"";
4204
4103
  function stringifyComment(opts, ctx) {
4205
4104
  const dateStr = typeof opts.date === "string" ? opts.date : (opts.date ?? /* @__PURE__ */ new Date()).toISOString();
4206
- const attrs = [`w:id="${opts.id}"`, `w:date="${escapeAttr$1(dateStr)}"`];
4207
- if (opts.author !== void 0) attrs.push(`w:author="${escapeAttr$1(opts.author)}"`);
4208
- if (opts.initials !== void 0) attrs.push(`w:initials="${escapeAttr$1(opts.initials)}"`);
4105
+ const attrs = [`w:id="${opts.id}"`, `w:date="${escapeAttr(dateStr)}"`];
4106
+ if (opts.author !== void 0) attrs.push(`w:author="${escapeAttr(opts.author)}"`);
4107
+ if (opts.initials !== void 0) attrs.push(`w:initials="${escapeAttr(opts.initials)}"`);
4209
4108
  const parts = [];
4210
4109
  for (const child of opts.children) parts.push(stringifyParagraphInline(child, ctx));
4211
4110
  return `<w:comment ${attrs.join(" ")}>${parts.join("")}</w:comment>`;
@@ -4480,433 +4379,6 @@ const relationshipsDesc = {
4480
4379
  }
4481
4380
  };
4482
4381
  //#endregion
4483
- //#region src/parts/bodychildren.ts
4484
- /**
4485
- * Body-level child descriptors for DOCX.
4486
- *
4487
- * Provides descriptor-based stringification for section children.
4488
- * All types use pure string builders — zero class instantiation, zero toXml().
4489
- *
4490
- * @module
4491
- */
4492
- function escapeAttr(s) {
4493
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
4494
- }
4495
- const ALTCHUNK_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
4496
- function wrapHtmlDocument(fragment) {
4497
- if (/<(!DOCTYPE|html|HTML)/i.test(fragment)) return fragment;
4498
- return `<!DOCTYPE html>\n<html><head><meta charset="utf-8"></head>\n<body>${fragment}</body></html>`;
4499
- }
4500
- const altChunkDesc = {
4501
- kind: "custom",
4502
- stringify(opts, ctx) {
4503
- const relId = uniqueId();
4504
- const extension = opts.extension;
4505
- const partPath = `afchunks/afchunk${relId}.${extension}`;
4506
- const rawData = typeof opts.data === "string" ? new TextEncoder().encode(opts.data) : opts.data;
4507
- const data = opts.contentType === "text/html" && typeof opts.data === "string" ? new TextEncoder().encode(wrapHtmlDocument(opts.data)) : rawData;
4508
- ctx.fileData.document.relationships.addRelationship(relId, ALTCHUNK_REL_TYPE, partPath);
4509
- ctx.fileData.altChunks.addAltChunk(relId, {
4510
- key: relId,
4511
- data,
4512
- path: partPath,
4513
- extension,
4514
- contentType: opts.contentType
4515
- });
4516
- const rId = `rId${relId}`;
4517
- if (opts.matchSrc) return `<w:altChunk r:id="${rId}"><w:altChunkPr><w:matchSrc/></w:altChunkPr></w:altChunk>`;
4518
- return `<w:altChunk r:id="${rId}"/>`;
4519
- },
4520
- parse(el, ctx) {
4521
- const rId = attr(el, "r:id");
4522
- const opts = {};
4523
- const altChunkPr = findChild(el, "w:altChunkPr");
4524
- if (altChunkPr && findChild(altChunkPr, "w:matchSrc")) opts.matchSrc = true;
4525
- const dctx = ctx;
4526
- if (rId) {
4527
- const path = dctx.resolveRelationship(rId);
4528
- if (path) {
4529
- const data = dctx.getRaw(path);
4530
- if (data) {
4531
- opts.data = data;
4532
- switch (path.split(".").pop() ?? "txt") {
4533
- case "html":
4534
- opts.contentType = "text/html";
4535
- opts.extension = "html";
4536
- break;
4537
- case "rtf":
4538
- opts.contentType = "application/rtf";
4539
- opts.extension = "rtf";
4540
- break;
4541
- default:
4542
- opts.contentType = "text/plain";
4543
- opts.extension = "txt";
4544
- break;
4545
- }
4546
- }
4547
- }
4548
- }
4549
- return opts;
4550
- }
4551
- };
4552
- const SUBDOC_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/subDocument";
4553
- const subDocDesc = {
4554
- kind: "custom",
4555
- stringify(opts, ctx) {
4556
- const relId = uniqueId();
4557
- const partPath = `subdocs/subdoc${relId}.docx`;
4558
- const data = typeof opts.data === "string" ? new TextEncoder().encode(opts.data) : opts.data;
4559
- ctx.fileData.document.relationships.addRelationship(relId, SUBDOC_REL_TYPE, partPath);
4560
- ctx.fileData.subDocs.addSubDoc(relId, {
4561
- data,
4562
- path: partPath
4563
- });
4564
- return `<w:subDoc r:id="rId${relId}"/>`;
4565
- },
4566
- parse(el, ctx) {
4567
- const rId = attr(el, "r:id");
4568
- const dctx = ctx;
4569
- if (rId) {
4570
- const path = dctx.resolveRelationship(rId);
4571
- if (path) {
4572
- const data = dctx.getRaw(path);
4573
- if (data) return { data };
4574
- }
4575
- }
4576
- return { data: new Uint8Array(0) };
4577
- }
4578
- };
4579
- function escapeXml$1(s) {
4580
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
4581
- }
4582
- function sdtListItemXml(item, forceValue) {
4583
- const attrs = [];
4584
- if (item.displayText !== void 0) attrs.push(`w:displayText="${escapeXml$1(item.displayText)}"`);
4585
- const value = item.value ?? (forceValue ? item.displayText : void 0);
4586
- if (value !== void 0) attrs.push(`w:value="${escapeXml$1(value)}"`);
4587
- return `<w:listItem ${attrs.join(" ")}/>`;
4588
- }
4589
- function sdtListTypeXml(name, options) {
4590
- const parts = [];
4591
- if (options.items) for (const item of options.items) parts.push(sdtListItemXml(item, name === "w:dropDownList"));
4592
- const attrs = [];
4593
- if (options.lastValue !== void 0) attrs.push(`w:lastValue="${escapeXml$1(options.lastValue)}"`);
4594
- const attrStr = attrs.length ? " " + attrs.join(" ") : "";
4595
- return parts.length ? `<${name}${attrStr}>${parts.join("")}</${name}>` : `<${name}${attrStr}/>`;
4596
- }
4597
- function sdtDateXml(options) {
4598
- const parts = [];
4599
- if (options.dateFormat !== void 0) parts.push(`<w:dateFormat w:val="${escapeXml$1(options.dateFormat)}"/>`);
4600
- if (options.languageId !== void 0) parts.push(`<w:lid w:val="${escapeXml$1(options.languageId)}"/>`);
4601
- if (options.storeMappedDataAs !== void 0) parts.push(`<w:storeMappedDataAs w:val="${options.storeMappedDataAs}"/>`);
4602
- if (options.calendar !== void 0) parts.push(`<w:calendar w:val="${options.calendar}"/>`);
4603
- const attrs = [];
4604
- if (options.fullDate !== void 0) attrs.push(`w:fullDate="${options.fullDate}"`);
4605
- const attrStr = attrs.length ? " " + attrs.join(" ") : "";
4606
- return parts.length ? `<w:date${attrStr}>${parts.join("")}</w:date>` : `<w:date${attrStr}/>`;
4607
- }
4608
- function sdtDataBindingXml(options) {
4609
- const attrs = [`w:xpath="${escapeXml$1(options.xpath)}"`, `w:storeItemID="${escapeXml$1(options.storeItemID)}"`];
4610
- if (options.prefixMappings !== void 0) attrs.push(`w:prefixMappings="${escapeXml$1(options.prefixMappings)}"`);
4611
- return `<w:dataBinding ${attrs.join(" ")}/>`;
4612
- }
4613
- function sdtDocPartXml(name, options) {
4614
- const parts = [];
4615
- if (options.gallery !== void 0) parts.push(`<w:docPartGallery w:val="${escapeXml$1(options.gallery)}"/>`);
4616
- if (options.category !== void 0) parts.push(`<w:docPartCategory w:val="${escapeXml$1(options.category)}"/>`);
4617
- if (options.unique !== void 0) parts.push(options.unique ? "<w:docPartUnique/>" : "<w:docPartUnique w:val=\"0\"/>");
4618
- return parts.length ? `<${name}>${parts.join("")}</${name}>` : `<${name}/>`;
4619
- }
4620
- function onOffAttr(name, val) {
4621
- return val ? `<${name}/>` : `<${name} w:val="0"/>`;
4622
- }
4623
- const W14_NS = "xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\"";
4624
- /** Default symbol font for checkbox content controls (CT_SdtCheckboxSymbol). */
4625
- const CHECKBOX_FONT = "MS Gothic";
4626
- const DEFAULT_CHECKED = {
4627
- val: "2612",
4628
- font: CHECKBOX_FONT
4629
- };
4630
- const DEFAULT_UNCHECKED = {
4631
- val: "2610",
4632
- font: CHECKBOX_FONT
4633
- };
4634
- /**
4635
- * Build a w14:checkbox element (Word 2010+ content control checkbox).
4636
- *
4637
- * Lives in the w14 extension namespace; emitted with an inline xmlns:w14 so it
4638
- * is valid wherever w:sdtPr appears. validate.ts tolerates the w14 namespace.
4639
- */
4640
- function sdtCheckboxXml(opts) {
4641
- const checked = opts.checkedState ?? DEFAULT_CHECKED;
4642
- const unchecked = opts.uncheckedState ?? DEFAULT_UNCHECKED;
4643
- return `<w14:checkbox ${W14_NS}>${(opts.checked ? "<w14:checked/>" : "<w14:checked w14:val=\"0\"/>") + `<w14:checkedState w14:val="${escapeXml$1(checked.val)}" w14:font="${escapeXml$1(checked.font ?? CHECKBOX_FONT)}"/><w14:uncheckedState w14:val="${escapeXml$1(unchecked.val)}" w14:font="${escapeXml$1(unchecked.font ?? CHECKBOX_FONT)}"/>`}</w14:checkbox>`;
4644
- }
4645
- function stringifySdtPr(opts) {
4646
- const parts = [];
4647
- if (opts.alias !== void 0) parts.push(`<w:alias w:val="${escapeXml$1(opts.alias)}"/>`);
4648
- if (opts.tag !== void 0) parts.push(`<w:tag w:val="${escapeXml$1(opts.tag)}"/>`);
4649
- if (opts.id !== void 0) parts.push(`<w:id w:val="${opts.id}"/>`);
4650
- if (opts.lock !== void 0) parts.push(`<w:lock w:val="${opts.lock}"/>`);
4651
- if (opts.temporary !== void 0) parts.push(onOffAttr("w:temporary", opts.temporary));
4652
- const effectiveShowingPlcHdr = opts.showingPlaceholder ?? false;
4653
- if (opts.showingPlaceholder !== void 0 || effectiveShowingPlcHdr) parts.push(onOffAttr("w:showingPlcHdr", effectiveShowingPlcHdr));
4654
- if (opts.dataBinding) parts.push(sdtDataBindingXml(opts.dataBinding));
4655
- if (opts.label !== void 0) parts.push(`<w:label w:val="${opts.label}"/>`);
4656
- if (opts.tabIndex !== void 0) parts.push(`<w:tabIndex w:val="${opts.tabIndex}"/>`);
4657
- if (opts.equation) parts.push("<w:equation/>");
4658
- else if (opts.comboBox) parts.push(sdtListTypeXml("w:comboBox", opts.comboBox));
4659
- else if (opts.date) parts.push(sdtDateXml(opts.date));
4660
- else if (opts.docPartObj) parts.push(sdtDocPartXml("w:docPartObj", opts.docPartObj));
4661
- else if (opts.docPartList) parts.push(sdtDocPartXml("w:docPartList", opts.docPartList));
4662
- else if (opts.dropDownList) parts.push(sdtListTypeXml("w:dropDownList", opts.dropDownList));
4663
- else if (opts.picture) parts.push("<w:picture/>");
4664
- else if (opts.richText) parts.push("<w:richText/>");
4665
- else if (opts.text !== void 0) {
4666
- const multiLine = opts.text.multiLine ?? false;
4667
- parts.push(`<w:text w:multiLine="${multiLine}"/>`);
4668
- } else if (opts.citation) parts.push("<w:citation/>");
4669
- else if (opts.group) parts.push("<w:group/>");
4670
- else if (opts.bibliography) parts.push("<w:bibliography/>");
4671
- else if (opts.checkbox) parts.push(sdtCheckboxXml(opts.checkbox));
4672
- return parts.length ? `<w:sdtPr>${parts.join("")}</w:sdtPr>` : "<w:sdtPr/>";
4673
- }
4674
- /** Parse w:sdtPr element into SdtPropertiesOptions. */
4675
- function parseSdtPr(el) {
4676
- const opts = {};
4677
- const alias = findChild(el, "w:alias");
4678
- if (alias) opts.alias = attr(alias, "w:val");
4679
- const tag = findChild(el, "w:tag");
4680
- if (tag) {
4681
- const val = attr(tag, "w:val");
4682
- if (val) opts.tag = val;
4683
- }
4684
- const id = findChild(el, "w:id");
4685
- if (id) {
4686
- const val = attrNum(id, "w:val");
4687
- if (val !== void 0) opts.id = val;
4688
- }
4689
- const lock = findChild(el, "w:lock");
4690
- if (lock) {
4691
- const val = attr(lock, "w:val");
4692
- if (val) opts.lock = val;
4693
- }
4694
- const temporary = findChild(el, "w:temporary");
4695
- if (temporary) opts.temporary = attrBool(temporary, "w:val") ?? true;
4696
- const showingPlcHdr = findChild(el, "w:showingPlcHdr");
4697
- if (showingPlcHdr) opts.showingPlaceholder = attrBool(showingPlcHdr, "w:val") ?? true;
4698
- const label = findChild(el, "w:label");
4699
- if (label) {
4700
- const val = attrNum(label, "w:val");
4701
- if (val !== void 0) opts.label = val;
4702
- }
4703
- const tabIndex = findChild(el, "w:tabIndex");
4704
- if (tabIndex) {
4705
- const val = attrNum(tabIndex, "w:val");
4706
- if (val !== void 0) opts.tabIndex = val;
4707
- }
4708
- const dataBinding = findChild(el, "w:dataBinding");
4709
- if (dataBinding) opts.dataBinding = {
4710
- xpath: attr(dataBinding, "w:xpath") ?? "",
4711
- storeItemID: attr(dataBinding, "w:storeItemID") ?? "",
4712
- prefixMappings: attr(dataBinding, "w:prefixMappings")
4713
- };
4714
- if (findChild(el, "w:equation")) opts.equation = true;
4715
- else if (findChild(el, "w:comboBox")) {
4716
- const comboBox = findChild(el, "w:comboBox");
4717
- const items = [];
4718
- for (const li of children(comboBox, "w:listItem")) items.push({
4719
- displayText: attr(li, "w:displayText"),
4720
- value: attr(li, "w:value")
4721
- });
4722
- opts.comboBox = {
4723
- items: items.length > 0 ? items : void 0,
4724
- lastValue: attr(comboBox, "w:lastValue")
4725
- };
4726
- } else if (findChild(el, "w:date")) {
4727
- const date = findChild(el, "w:date");
4728
- const dateOpts = {};
4729
- const dateFormat = findChild(date, "w:dateFormat");
4730
- if (dateFormat) dateOpts.dateFormat = textOf(dateFormat);
4731
- const lid = findChild(date, "w:lid");
4732
- if (lid) dateOpts.languageId = textOf(lid);
4733
- const storeMapped = findChild(date, "w:storeMappedDataAs");
4734
- if (storeMapped) dateOpts.storeMappedDataAs = attr(storeMapped, "w:val");
4735
- const calendar = findChild(date, "w:calendar");
4736
- if (calendar) dateOpts.calendar = attr(calendar, "w:val");
4737
- const fullDate = attr(date, "w:fullDate");
4738
- if (fullDate) dateOpts.fullDate = fullDate;
4739
- opts.date = dateOpts;
4740
- } else if (findChild(el, "w:docPartObj")) {
4741
- const dp = findChild(el, "w:docPartObj");
4742
- const dpObj = {};
4743
- const gallery = findChild(dp, "w:docPartGallery");
4744
- if (gallery) dpObj.gallery = attr(gallery, "w:val");
4745
- const category = findChild(dp, "w:docPartCategory");
4746
- if (category) dpObj.category = attr(category, "w:val");
4747
- if (findChild(dp, "w:docPartUnique")) dpObj.unique = true;
4748
- opts.docPartObj = dpObj;
4749
- } else if (findChild(el, "w:docPartList")) {
4750
- const dp = findChild(el, "w:docPartList");
4751
- const dpObj = {};
4752
- const gallery = findChild(dp, "w:docPartGallery");
4753
- if (gallery) dpObj.gallery = attr(gallery, "w:val");
4754
- const category = findChild(dp, "w:docPartCategory");
4755
- if (category) dpObj.category = attr(category, "w:val");
4756
- if (findChild(dp, "w:docPartUnique")) dpObj.unique = true;
4757
- opts.docPartList = dpObj;
4758
- } else if (findChild(el, "w:dropDownList")) {
4759
- const ddl = findChild(el, "w:dropDownList");
4760
- const items = [];
4761
- for (const li of children(ddl, "w:listItem")) items.push({
4762
- displayText: attr(li, "w:displayText"),
4763
- value: attr(li, "w:value")
4764
- });
4765
- opts.dropDownList = {
4766
- items: items.length > 0 ? items : void 0,
4767
- lastValue: attr(ddl, "w:lastValue")
4768
- };
4769
- } else if (findChild(el, "w:picture")) opts.picture = true;
4770
- else if (findChild(el, "w:richText")) opts.richText = true;
4771
- else if (findChild(el, "w:text")) opts.text = { multiLine: attrBool(findChild(el, "w:text"), "w:multiLine") };
4772
- else if (findChild(el, "w:citation")) opts.citation = true;
4773
- else if (findChild(el, "w:group")) opts.group = true;
4774
- else if (findChild(el, "w:bibliography")) opts.bibliography = true;
4775
- else if (findChild(el, "w14:checkbox")) {
4776
- const cb = findChild(el, "w14:checkbox");
4777
- const cbObj = {};
4778
- const checked = findChild(cb, "w14:checked");
4779
- if (checked) cbObj.checked = attrBool(checked, "w14:val") ?? true;
4780
- const checkedState = findChild(cb, "w14:checkedState");
4781
- if (checkedState) cbObj.checkedState = {
4782
- val: attr(checkedState, "w14:val") ?? "",
4783
- font: attr(checkedState, "w14:font")
4784
- };
4785
- const uncheckedState = findChild(cb, "w14:uncheckedState");
4786
- if (uncheckedState) cbObj.uncheckedState = {
4787
- val: attr(uncheckedState, "w14:val") ?? "",
4788
- font: attr(uncheckedState, "w14:font")
4789
- };
4790
- opts.checkbox = cbObj;
4791
- }
4792
- return opts;
4793
- }
4794
- /** Parse w:customXmlPr element into CustomXmlPrOptions. */
4795
- function parseCustomXmlPr(el) {
4796
- const opts = {};
4797
- const placeholder = findChild(el, "w:placeholder");
4798
- if (placeholder) {
4799
- const val = attr(placeholder, "w:val");
4800
- if (val) opts.placeholder = val;
4801
- }
4802
- const attributes = [];
4803
- for (const child of el.elements ?? []) {
4804
- if (child.name !== "w:attr") continue;
4805
- const name = attr(child, "w:name");
4806
- const val = attr(child, "w:val");
4807
- if (name && val) {
4808
- const attrOpts = {
4809
- name,
4810
- val
4811
- };
4812
- const uriVal = attr(child, "w:uri");
4813
- if (uriVal) attrOpts.uri = uriVal;
4814
- attributes.push(attrOpts);
4815
- }
4816
- }
4817
- if (attributes.length > 0) opts.attributes = attributes;
4818
- return opts;
4819
- }
4820
- /** Body child element parsing callback for SDT/customXml content. */
4821
- let _parseBodyChild;
4822
- /** Register the body child parser (called from parse/body.ts to break circular dependency). */
4823
- function setBodyParseChild(parser) {
4824
- _parseBodyChild = parser;
4825
- }
4826
- function parseBodyChildren(elements, ctx) {
4827
- if (!_parseBodyChild) return [];
4828
- const result = [];
4829
- for (const el of elements) result.push(_parseBodyChild(el, ctx));
4830
- return result;
4831
- }
4832
- const sdtBlockDesc = {
4833
- kind: "custom",
4834
- stringify(opts, ctx) {
4835
- const parts = ["<w:sdt>"];
4836
- parts.push(stringifySdtPr(opts.properties));
4837
- parts.push("<w:sdtEndPr/>");
4838
- if (opts.properties.checkbox) {
4839
- const cb = opts.properties.checkbox;
4840
- const symbol = cb.checked ?? false ? cb.checkedState ?? DEFAULT_CHECKED : cb.uncheckedState ?? DEFAULT_UNCHECKED;
4841
- const font = escapeXml$1(symbol.font ?? CHECKBOX_FONT);
4842
- const char = escapeXml$1(String.fromCodePoint(parseInt(symbol.val, 16)));
4843
- parts.push(`<w:sdtContent><w:p><w:r><w:rPr><w:rFonts w:ascii="${font}" w:hAnsi="${font}"/></w:rPr><w:t>${char}</w:t></w:r></w:p></w:sdtContent>`);
4844
- } else if (opts.children && opts.children.length > 0) {
4845
- const contentParts = [];
4846
- for (const child of opts.children) contentParts.push(ctx.stringifyChild(child, ctx));
4847
- const contentBody = contentParts.join("");
4848
- parts.push(contentBody ? `<w:sdtContent>${contentBody}</w:sdtContent>` : "<w:sdtContent/>");
4849
- }
4850
- parts.push("</w:sdt>");
4851
- return parts.join("");
4852
- },
4853
- parse(el, ctx) {
4854
- const dctx = ctx;
4855
- const sdtPr = findChild(el, "w:sdtPr");
4856
- const properties = sdtPr ? parseSdtPr(sdtPr) : {};
4857
- const sdtContent = findChild(el, "w:sdtContent");
4858
- let childList;
4859
- if (sdtContent && sdtContent.elements?.length) {
4860
- childList = parseBodyChildren(sdtContent.elements, dctx);
4861
- if (childList.length === 0) childList = void 0;
4862
- }
4863
- return {
4864
- properties,
4865
- children: childList
4866
- };
4867
- }
4868
- };
4869
- function buildCustomXmlPrXml(pr) {
4870
- const parts = ["<w:customXmlPr>"];
4871
- if (pr.placeholder !== void 0) parts.push(`<w:placeholder w:val="${escapeAttr(pr.placeholder)}"/>`);
4872
- if (pr.attributes) for (const attr of pr.attributes) {
4873
- const attrParts = [`w:name="${escapeAttr(attr.name)}"`, `w:val="${escapeAttr(attr.val)}"`];
4874
- if (attr.uri !== void 0) attrParts.push(`w:uri="${escapeAttr(attr.uri)}"`);
4875
- parts.push(`<w:attr ${attrParts.join(" ")}/>`);
4876
- }
4877
- parts.push("</w:customXmlPr>");
4878
- return parts.join("");
4879
- }
4880
- const customXmlBlockDesc = {
4881
- kind: "custom",
4882
- stringify(opts, ctx) {
4883
- const attrs = [`w:element="${escapeAttr(opts.element)}"`];
4884
- if (opts.uri !== void 0) attrs.push(`w:uri="${escapeAttr(opts.uri)}"`);
4885
- const parts = [`<w:customXml ${attrs.join(" ")}>`];
4886
- if (opts.customXmlPr) parts.push(buildCustomXmlPrXml(opts.customXmlPr));
4887
- if (opts.children) for (const child of opts.children) parts.push(ctx.stringifyChild(child, ctx));
4888
- parts.push("</w:customXml>");
4889
- return parts.join("");
4890
- },
4891
- parse(el, ctx) {
4892
- const dctx = ctx;
4893
- const opts = {};
4894
- const element = attr(el, "w:element");
4895
- if (element) opts.element = element;
4896
- const uri = attr(el, "w:uri");
4897
- if (uri) opts.uri = uri;
4898
- const xmlPr = findChild(el, "w:customXmlPr");
4899
- if (xmlPr) opts.customXmlPr = parseCustomXmlPr(xmlPr);
4900
- const childList = [];
4901
- for (const child of el.elements ?? []) {
4902
- if (child.name === "w:customXmlPr") continue;
4903
- if (_parseBodyChild) childList.push(_parseBodyChild(child, dctx));
4904
- }
4905
- if (childList.length > 0) opts.children = childList;
4906
- return opts;
4907
- }
4908
- };
4909
- //#endregion
4910
4382
  //#region src/parts/core-properties.ts
4911
4383
  const corePropertiesDesc = {
4912
4384
  kind: "custom",
@@ -4989,6 +4461,114 @@ const customPropertiesDesc = {
4989
4461
  }
4990
4462
  };
4991
4463
  //#endregion
4464
+ //#region src/parts/app-properties.ts
4465
+ const appPropertiesDesc = {
4466
+ kind: "custom",
4467
+ stringify(opts, _ctx) {
4468
+ const p = ["<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"];
4469
+ if (opts.template !== void 0) p.push(`<Template>${escapeXml(opts.template)}</Template>`);
4470
+ if (opts.manager !== void 0) p.push(`<Manager>${escapeXml(opts.manager)}</Manager>`);
4471
+ if (opts.company !== void 0) p.push(`<Company>${escapeXml(opts.company)}</Company>`);
4472
+ if (opts.pages !== void 0) p.push(`<Pages>${opts.pages}</Pages>`);
4473
+ if (opts.words !== void 0) p.push(`<Words>${opts.words}</Words>`);
4474
+ if (opts.characters !== void 0) p.push(`<Characters>${opts.characters}</Characters>`);
4475
+ if (opts.lines !== void 0) p.push(`<Lines>${opts.lines}</Lines>`);
4476
+ if (opts.paragraphs !== void 0) p.push(`<Paragraphs>${opts.paragraphs}</Paragraphs>`);
4477
+ if (opts.slides !== void 0) p.push(`<Slides>${opts.slides}</Slides>`);
4478
+ if (opts.notes !== void 0) p.push(`<Notes>${opts.notes}</Notes>`);
4479
+ if (opts.totalTime !== void 0) p.push(`<TotalTime>${opts.totalTime}</TotalTime>`);
4480
+ if (opts.hiddenSlides !== void 0) p.push(`<HiddenSlides>${opts.hiddenSlides}</HiddenSlides>`);
4481
+ if (opts.mmClips !== void 0) p.push(`<MMClips>${opts.mmClips}</MMClips>`);
4482
+ if (opts.scaleCrop !== void 0) p.push(`<ScaleCrop>${opts.scaleCrop ? 1 : 0}</ScaleCrop>`);
4483
+ if (opts.linksUpToDate !== void 0) p.push(`<LinksUpToDate>${opts.linksUpToDate ? 1 : 0}</LinksUpToDate>`);
4484
+ if (opts.charactersWithSpaces !== void 0) p.push(`<CharactersWithSpaces>${opts.charactersWithSpaces}</CharactersWithSpaces>`);
4485
+ if (opts.sharedDoc !== void 0) p.push(`<SharedDoc>${opts.sharedDoc ? 1 : 0}</SharedDoc>`);
4486
+ if (opts.hyperlinkBase !== void 0) p.push(`<HyperlinkBase>${escapeXml(opts.hyperlinkBase)}</HyperlinkBase>`);
4487
+ if (opts.hyperlinksChanged !== void 0) p.push(`<HyperlinksChanged>${opts.hyperlinksChanged ? 1 : 0}</HyperlinksChanged>`);
4488
+ if (opts.application !== void 0) p.push(`<Application>${escapeXml(opts.application)}</Application>`);
4489
+ if (opts.appVersion !== void 0) p.push(`<AppVersion>${escapeXml(opts.appVersion)}</AppVersion>`);
4490
+ if (opts.docSecurity !== void 0) p.push(`<DocSecurity>${opts.docSecurity}</DocSecurity>`);
4491
+ p.push("</Properties>");
4492
+ return p.join("");
4493
+ },
4494
+ parse(el, _ctx) {
4495
+ const result = {};
4496
+ for (const child of el.elements ?? []) {
4497
+ if (typeof child.name !== "string") continue;
4498
+ const text = child.elements?.[0]?.text;
4499
+ switch (child.name) {
4500
+ case "Template":
4501
+ if (typeof text === "string") result.template = text;
4502
+ break;
4503
+ case "Manager":
4504
+ if (typeof text === "string") result.manager = text;
4505
+ break;
4506
+ case "Company":
4507
+ if (typeof text === "string") result.company = text;
4508
+ break;
4509
+ case "Pages":
4510
+ if (typeof text === "string") result.pages = Number(text);
4511
+ break;
4512
+ case "Words":
4513
+ if (typeof text === "string") result.words = Number(text);
4514
+ break;
4515
+ case "Characters":
4516
+ if (typeof text === "string") result.characters = Number(text);
4517
+ break;
4518
+ case "Lines":
4519
+ if (typeof text === "string") result.lines = Number(text);
4520
+ break;
4521
+ case "Paragraphs":
4522
+ if (typeof text === "string") result.paragraphs = Number(text);
4523
+ break;
4524
+ case "Slides":
4525
+ if (typeof text === "string") result.slides = Number(text);
4526
+ break;
4527
+ case "Notes":
4528
+ if (typeof text === "string") result.notes = Number(text);
4529
+ break;
4530
+ case "TotalTime":
4531
+ if (typeof text === "string") result.totalTime = Number(text);
4532
+ break;
4533
+ case "HiddenSlides":
4534
+ if (typeof text === "string") result.hiddenSlides = Number(text);
4535
+ break;
4536
+ case "MMClips":
4537
+ if (typeof text === "string") result.mmClips = Number(text);
4538
+ break;
4539
+ case "ScaleCrop":
4540
+ if (typeof text === "string") result.scaleCrop = text === "1" || text === "true";
4541
+ break;
4542
+ case "LinksUpToDate":
4543
+ if (typeof text === "string") result.linksUpToDate = text === "1" || text === "true";
4544
+ break;
4545
+ case "CharactersWithSpaces":
4546
+ if (typeof text === "string") result.charactersWithSpaces = Number(text);
4547
+ break;
4548
+ case "SharedDoc":
4549
+ if (typeof text === "string") result.sharedDoc = text === "1" || text === "true";
4550
+ break;
4551
+ case "HyperlinkBase":
4552
+ if (typeof text === "string") result.hyperlinkBase = text;
4553
+ break;
4554
+ case "HyperlinksChanged":
4555
+ if (typeof text === "string") result.hyperlinksChanged = text === "1" || text === "true";
4556
+ break;
4557
+ case "Application":
4558
+ if (typeof text === "string") result.application = text;
4559
+ break;
4560
+ case "AppVersion":
4561
+ if (typeof text === "string") result.appVersion = text;
4562
+ break;
4563
+ case "DocSecurity":
4564
+ if (typeof text === "string") result.docSecurity = Number(text);
4565
+ break;
4566
+ }
4567
+ }
4568
+ return result;
4569
+ }
4570
+ };
4571
+ //#endregion
4992
4572
  //#region src/parts/web-settings.ts
4993
4573
  /**
4994
4574
  * Screen size types for web settings target.
@@ -5531,6 +5111,6 @@ var DocxReadContext = class {
5531
5111
  }
5532
5112
  };
5533
5113
  //#endregion
5534
- export { RelativeVerticalPosition as $, footnotesDesc as A, settingsDesc as B, fontTableDesc as C, EditGroupType as D, AltChunkCollection as E, stringifyTableOfContents as F, Numbering as G, buildNumberingCache as H, parseToc as I, LevelSuffix as J, parseNumberingDefinitions as K, SdtDateMappingType as L, parseParagraphProperties as M, stringifyBodyChild as N, parseSdtBlock as O, stringifyDocumentXml as P, RelativeHorizontalPosition as Q, SdtLock as R, bibliographyDesc as S, SubDocCollection as T, buildStyleCache as U, Styles as V, parseStyleDefinitions as W, TableLayoutType as X, TABLE_BORDERS_NONE as Y, OverlapType as Z, commentsDesc as _, framesetXml as a, PositionalTabRelativeTo as at, DocPartType as b, corePropertiesDesc as c, createImageData as ct, sdtBlockDesc as d, PageNumber as dt, TableAnchorType as et, setBodyParseChild as f, TextAlignmentType as ft, contentTypesDesc as g, buildContentTypes as h, AlignmentType as ht, frameXml as i, PositionalTabLeader as it, parseParagraph as j, endnotesDesc as k, altChunkDesc as l, HighlightColor as lt, relationshipsDesc as m, HeadingLevel as mt, DocxWriteContext as n, RubyAlign as nt, webSettingsDesc as o, EmphasisMarkType as ot, subDocDesc as p, TextboxTightWrapType as pt, LevelFormat as q, TargetScreenSize as r, PositionalTabAlignment as rt, customPropertiesDesc as s, UnderlineType as st, DocxReadContext as t, ProofErrorType as tt, customXmlBlockDesc as u, TextEffect as ut, DocPartBehavior as v, CharacterSet as w, glossaryDesc as x, DocPartGallery as y, StyleLevel as z };
5114
+ export { PositionalTabLeader as $, stringifyTableOfContents as A, Numbering as B, EditGroupType as C, parseParagraphProperties as D, parseParagraph as E, settingsDesc as F, TableLayoutType as G, LevelFormat as H, Styles as I, RelativeVerticalPosition as J, OverlapType as K, buildNumberingCache as L, SdtDateMappingType as M, SdtLock as N, stringifyBodyChild as O, StyleLevel as P, PositionalTabAlignment as Q, buildStyleCache as R, AltChunkCollection as S, footnotesDesc as T, LevelSuffix as U, parseNumberingDefinitions as V, TABLE_BORDERS_NONE as W, ProofErrorType as X, TableAnchorType as Y, RubyAlign as Z, glossaryDesc as _, framesetXml as a, TextEffect as at, CharacterSet as b, customPropertiesDesc as c, TextboxTightWrapType as ct, buildContentTypes as d, AlignmentType as dt, PositionalTabRelativeTo as et, contentTypesDesc as f, DocPartType as g, DocPartGallery as h, frameXml as i, HighlightColor as it, parseToc as j, stringifyDocumentXml as k, corePropertiesDesc as l, HeadingLevel as lt, DocPartBehavior as m, DocxWriteContext as n, UnderlineType as nt, webSettingsDesc as o, PageNumber as ot, commentsDesc as p, RelativeHorizontalPosition as q, TargetScreenSize as r, createImageData as rt, appPropertiesDesc as s, TextAlignmentType as st, DocxReadContext as t, EmphasisMarkType as tt, relationshipsDesc as u, LineRuleType as ut, bibliographyDesc as v, endnotesDesc as w, SubDocCollection as x, fontTableDesc as y, parseStyleDefinitions as z };
5535
5115
 
5536
- //# sourceMappingURL=context-DeKZoZem.mjs.map
5116
+ //# sourceMappingURL=context-CSBntKXD.mjs.map