@office-open/docx 0.10.10 → 0.10.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/dist/{context-YVFle0J6.mjs → context-CiyAhqTX.mjs} +21 -5
- package/dist/context-CiyAhqTX.mjs.map +1 -0
- package/dist/{core-properties-C510YJhg.d.mts → core-properties-CIG9ZnsW.d.mts} +19 -2
- package/dist/core-properties-CIG9ZnsW.d.mts.map +1 -0
- package/dist/{generate-fsy5ESN0.mjs → generate-DjODfjQ1.mjs} +41 -37
- package/dist/generate-DjODfjQ1.mjs.map +1 -0
- package/dist/generate.d.mts +1 -1
- package/dist/generate.mjs +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -73
- package/dist/index.mjs.map +1 -1
- package/dist/{parse-BcxcUGsx.mjs → parse-DDWWDGbX.mjs} +5 -8
- package/dist/parse-DDWWDGbX.mjs.map +1 -0
- package/dist/parse.d.mts +1 -1
- package/dist/parse.mjs +1 -1
- package/dist/{parts-7TLJ0TNR.mjs → parts-B7Sfx_F0.mjs} +365 -119
- package/dist/parts-B7Sfx_F0.mjs.map +1 -0
- package/dist/patch/index.d.mts +1 -1
- package/dist/patch/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/context-YVFle0J6.mjs.map +0 -1
- package/dist/core-properties-C510YJhg.d.mts.map +0 -1
- package/dist/generate-fsy5ESN0.mjs.map +0 -1
- package/dist/parse-BcxcUGsx.mjs.map +0 -1
- package/dist/parts-7TLJ0TNR.mjs.map +0 -1
|
@@ -179,6 +179,32 @@ function breakXml(breakOpt) {
|
|
|
179
179
|
return count === 1 ? one : one.repeat(count);
|
|
180
180
|
}
|
|
181
181
|
/**
|
|
182
|
+
* Empty EG_RunInnerContent elements — self-closing XML with no attributes.
|
|
183
|
+
* Shared by the body run stringifier and the inline (footnote/endnote) run
|
|
184
|
+
* stringifier so both emit them identically. Keyed by the RunOptions child
|
|
185
|
+
* property name (e.g. `{ separator: true }` → `separator`).
|
|
186
|
+
*
|
|
187
|
+
* XSD reference: EG_RunInnerContent group in wml.xsd.
|
|
188
|
+
*/
|
|
189
|
+
const EMPTY_RUN_ELEMENTS = {
|
|
190
|
+
noBreakHyphen: "<w:noBreakHyphen/>",
|
|
191
|
+
softHyphen: "<w:softHyphen/>",
|
|
192
|
+
dayShort: "<w:dayShort/>",
|
|
193
|
+
monthShort: "<w:monthShort/>",
|
|
194
|
+
yearShort: "<w:yearShort/>",
|
|
195
|
+
dayLong: "<w:dayLong/>",
|
|
196
|
+
monthLong: "<w:monthLong/>",
|
|
197
|
+
yearLong: "<w:yearLong/>",
|
|
198
|
+
annotationRef: "<w:annotationRef/>",
|
|
199
|
+
footnoteRef: "<w:footnoteRef/>",
|
|
200
|
+
endnoteRef: "<w:endnoteRef/>",
|
|
201
|
+
separator: "<w:separator/>",
|
|
202
|
+
continuationSeparator: "<w:continuationSeparator/>",
|
|
203
|
+
pgNum: "<w:pgNum/>",
|
|
204
|
+
carriageReturn: "<w:cr/>",
|
|
205
|
+
lastRenderedPageBreak: "<w:lastRenderedPageBreak/>"
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
182
208
|
* Constants for page number field types.
|
|
183
209
|
*
|
|
184
210
|
* These values are used to insert dynamic page number fields into a document.
|
|
@@ -1431,6 +1457,133 @@ function parseEmbed(el) {
|
|
|
1431
1457
|
return opts;
|
|
1432
1458
|
}
|
|
1433
1459
|
//#endregion
|
|
1460
|
+
//#region src/shared/shading.ts
|
|
1461
|
+
/**
|
|
1462
|
+
* Shading module for WordprocessingML documents.
|
|
1463
|
+
*
|
|
1464
|
+
* Shading is used to apply background colors and patterns to paragraphs,
|
|
1465
|
+
* table cells, and text runs. The shading type is identical in all places.
|
|
1466
|
+
*
|
|
1467
|
+
* Reference: http://officeopenxml.com/WPshading.php
|
|
1468
|
+
*
|
|
1469
|
+
* @see http://officeopenxml.com/WPtableShading.php
|
|
1470
|
+
* @see http://officeopenxml.com/WPtableCellProperties-Shading.php
|
|
1471
|
+
*
|
|
1472
|
+
* ## XSD Schema
|
|
1473
|
+
* ```xml
|
|
1474
|
+
* <xsd:complexType name="CT_Shd">
|
|
1475
|
+
* <xsd:attribute name="val" type="ST_Shd" use="required"/>
|
|
1476
|
+
* <xsd:attribute name="color" type="ST_HexColor" use="optional"/>
|
|
1477
|
+
* <xsd:attribute name="themeColor" type="ST_ThemeColor" use="optional"/>
|
|
1478
|
+
* <xsd:attribute name="themeTint" type="ST_UcharHexNumber" use="optional"/>
|
|
1479
|
+
* <xsd:attribute name="themeShade" type="ST_UcharHexNumber" use="optional"/>
|
|
1480
|
+
* <xsd:attribute name="fill" type="ST_HexColor" use="optional"/>
|
|
1481
|
+
* <xsd:attribute name="themeFill" type="ST_ThemeColor" use="optional"/>
|
|
1482
|
+
* <xsd:attribute name="themeFillTint" type="ST_UcharHexNumber" use="optional"/>
|
|
1483
|
+
* <xsd:attribute name="themeFillShade" type="ST_UcharHexNumber" use="optional"/>
|
|
1484
|
+
* </xsd:complexType>
|
|
1485
|
+
* ```
|
|
1486
|
+
*
|
|
1487
|
+
* @module
|
|
1488
|
+
*/
|
|
1489
|
+
/**
|
|
1490
|
+
* Shading pattern types.
|
|
1491
|
+
*
|
|
1492
|
+
* Specifies the pattern used for shading. The pattern combines the fill
|
|
1493
|
+
* color and the pattern color.
|
|
1494
|
+
*
|
|
1495
|
+
* ## XSD Schema
|
|
1496
|
+
* ```xml
|
|
1497
|
+
* <xsd:simpleType name="ST_Shd">
|
|
1498
|
+
* <xsd:restriction base="xsd:string">
|
|
1499
|
+
* <xsd:enumeration value="nil"/>
|
|
1500
|
+
* <xsd:enumeration value="clear"/>
|
|
1501
|
+
* <xsd:enumeration value="solid"/>
|
|
1502
|
+
* <xsd:enumeration value="horzStripe"/>
|
|
1503
|
+
* <xsd:enumeration value="vertStripe"/>
|
|
1504
|
+
* <xsd:enumeration value="reverseDiagStripe"/>
|
|
1505
|
+
* <xsd:enumeration value="diagStripe"/>
|
|
1506
|
+
* <xsd:enumeration value="horzCross"/>
|
|
1507
|
+
* <xsd:enumeration value="diagCross"/>
|
|
1508
|
+
* <!-- ... percent values ... -->
|
|
1509
|
+
* </xsd:restriction>
|
|
1510
|
+
* </xsd:simpleType>
|
|
1511
|
+
* ```
|
|
1512
|
+
*
|
|
1513
|
+
* @publicApi
|
|
1514
|
+
*/
|
|
1515
|
+
const ShadingType = {
|
|
1516
|
+
/** Clear shading - no pattern, fill color only */
|
|
1517
|
+
CLEAR: "clear",
|
|
1518
|
+
DIAGONAL_CROSS: "diagCross",
|
|
1519
|
+
DIAGONAL_STRIPE: "diagStripe",
|
|
1520
|
+
HORIZONTAL_CROSS: "horzCross",
|
|
1521
|
+
HORIZONTAL_STRIPE: "horzStripe",
|
|
1522
|
+
NIL: "nil",
|
|
1523
|
+
PERCENT_10: "pct10",
|
|
1524
|
+
PERCENT_12: "pct12",
|
|
1525
|
+
PERCENT_15: "pct15",
|
|
1526
|
+
PERCENT_20: "pct20",
|
|
1527
|
+
PERCENT_25: "pct25",
|
|
1528
|
+
PERCENT_30: "pct30",
|
|
1529
|
+
PERCENT_35: "pct35",
|
|
1530
|
+
PERCENT_37: "pct37",
|
|
1531
|
+
PERCENT_40: "pct40",
|
|
1532
|
+
PERCENT_45: "pct45",
|
|
1533
|
+
PERCENT_5: "pct5",
|
|
1534
|
+
PERCENT_50: "pct50",
|
|
1535
|
+
PERCENT_55: "pct55",
|
|
1536
|
+
PERCENT_60: "pct60",
|
|
1537
|
+
PERCENT_62: "pct62",
|
|
1538
|
+
PERCENT_65: "pct65",
|
|
1539
|
+
PERCENT_70: "pct70",
|
|
1540
|
+
PERCENT_75: "pct75",
|
|
1541
|
+
PERCENT_80: "pct80",
|
|
1542
|
+
PERCENT_85: "pct85",
|
|
1543
|
+
PERCENT_87: "pct87",
|
|
1544
|
+
PERCENT_90: "pct90",
|
|
1545
|
+
PERCENT_95: "pct95",
|
|
1546
|
+
REVERSE_DIAGONAL_STRIPE: "reverseDiagStripe",
|
|
1547
|
+
SOLID: "solid",
|
|
1548
|
+
THIN_DIAGONAL_CROSS: "thinDiagCross",
|
|
1549
|
+
THIN_DIAGONAL_STRIPE: "thinDiagStripe",
|
|
1550
|
+
THIN_HORIZONTAL_CROSS: "thinHorzCross",
|
|
1551
|
+
THIN_REVERSE_DIAGONAL_STRIPE: "thinReverseDiagStripe",
|
|
1552
|
+
THIN_VERTICAL_STRIPE: "thinVertStripe",
|
|
1553
|
+
VERTICAL_STRIPE: "vertStripe"
|
|
1554
|
+
};
|
|
1555
|
+
const THEME_COLORS$2 = Object.values(ThemeColor);
|
|
1556
|
+
/**
|
|
1557
|
+
* Parse a w:shd (CT_Shd) element into ShadingAttributesProperties.
|
|
1558
|
+
*
|
|
1559
|
+
* Reads every CT_Shd attribute (fill/color/val plus the theme* family), so the
|
|
1560
|
+
* result round-trips losslessly — paragraph, table-cell, and run shading all
|
|
1561
|
+
* share this single reader. Returns undefined when the element carries no data.
|
|
1562
|
+
*/
|
|
1563
|
+
function parseShading(shd) {
|
|
1564
|
+
const shading = {};
|
|
1565
|
+
const fill = attr(shd, "w:fill");
|
|
1566
|
+
if (fill) shading.fill = fill;
|
|
1567
|
+
const color = attr(shd, "w:color");
|
|
1568
|
+
if (color) shading.color = color;
|
|
1569
|
+
const val = attr(shd, "w:val");
|
|
1570
|
+
if (val) shading.type = val;
|
|
1571
|
+
const themeColor = attr(shd, "w:themeColor");
|
|
1572
|
+
if (themeColor && THEME_COLORS$2.includes(themeColor)) shading.themeColor = themeColor;
|
|
1573
|
+
const themeTint = attr(shd, "w:themeTint");
|
|
1574
|
+
if (themeTint) shading.themeTint = themeTint;
|
|
1575
|
+
const themeShade = attr(shd, "w:themeShade");
|
|
1576
|
+
if (themeShade) shading.themeShade = themeShade;
|
|
1577
|
+
const themeFill = attr(shd, "w:themeFill");
|
|
1578
|
+
if (themeFill && THEME_COLORS$2.includes(themeFill)) shading.themeFill = themeFill;
|
|
1579
|
+
const themeFillTint = attr(shd, "w:themeFillTint");
|
|
1580
|
+
if (themeFillTint) shading.themeFillTint = themeFillTint;
|
|
1581
|
+
const themeFillShade = attr(shd, "w:themeFillShade");
|
|
1582
|
+
if (themeFillShade) shading.themeFillShade = themeFillShade;
|
|
1583
|
+
if (Object.keys(shading).length === 0) return void 0;
|
|
1584
|
+
return shading;
|
|
1585
|
+
}
|
|
1586
|
+
//#endregion
|
|
1434
1587
|
//#region src/util/stringify-element.ts
|
|
1435
1588
|
/**
|
|
1436
1589
|
* Element-to-XML serialization helpers shared across the parse layer.
|
|
@@ -1629,7 +1782,7 @@ function parseRunProperties(el) {
|
|
|
1629
1782
|
const bdr = findChild(el, "w:bdr");
|
|
1630
1783
|
if (bdr) opts.border = parseBorder(bdr);
|
|
1631
1784
|
const shd = findChild(el, "w:shd");
|
|
1632
|
-
if (shd) opts.shading = parseShading
|
|
1785
|
+
if (shd) opts.shading = parseShading(shd);
|
|
1633
1786
|
const eastAsianLayout = findChild(el, "w:eastAsianLayout");
|
|
1634
1787
|
if (eastAsianLayout) opts.eastAsianLayout = parseEastAsianLayout(eastAsianLayout);
|
|
1635
1788
|
const contentPart = findChild(el, "w:contentPart");
|
|
@@ -1675,19 +1828,6 @@ function parseBorder(el) {
|
|
|
1675
1828
|
return opts;
|
|
1676
1829
|
}
|
|
1677
1830
|
/**
|
|
1678
|
-
* Parse a w:shd element into ShadingAttributesProperties.
|
|
1679
|
-
*/
|
|
1680
|
-
function parseShading$1(el) {
|
|
1681
|
-
const opts = {};
|
|
1682
|
-
const fill = colorAttr(el, "w:fill");
|
|
1683
|
-
if (fill) opts.fill = fill;
|
|
1684
|
-
const color = colorAttr(el, "w:color");
|
|
1685
|
-
if (color) opts.color = color;
|
|
1686
|
-
const type = attr(el, "w:val");
|
|
1687
|
-
if (type) opts.type = type;
|
|
1688
|
-
return opts;
|
|
1689
|
-
}
|
|
1690
|
-
/**
|
|
1691
1831
|
* Parse a w:eastAsianLayout element into EastAsianLayoutOptions.
|
|
1692
1832
|
*/
|
|
1693
1833
|
function parseEastAsianLayout(el) {
|
|
@@ -2220,7 +2360,7 @@ function stringifyParagraphProperties(options) {
|
|
|
2220
2360
|
if (options.suppressAutoHyphens !== void 0) parts.push(onOff$1("w:suppressAutoHyphens", options.suppressAutoHyphens));
|
|
2221
2361
|
if (options.kinsoku !== void 0) parts.push(onOff$1("w:kinsoku", options.kinsoku));
|
|
2222
2362
|
if (options.wordWrap !== void 0) parts.push(onOff$1("w:wordWrap", options.wordWrap));
|
|
2223
|
-
if (options.overflowPunctuation) parts.push(onOff$1("w:overflowPunct", options.overflowPunctuation));
|
|
2363
|
+
if (options.overflowPunctuation !== void 0) parts.push(onOff$1("w:overflowPunct", options.overflowPunctuation));
|
|
2224
2364
|
if (options.topLinePunct !== void 0) parts.push(onOff$1("w:topLinePunct", options.topLinePunct));
|
|
2225
2365
|
if (options.autoSpaceDE !== void 0) parts.push(onOff$1("w:autoSpaceDE", options.autoSpaceDE));
|
|
2226
2366
|
if (options.autoSpaceEastAsianText !== void 0) parts.push(onOff$1("w:autoSpaceDN", options.autoSpaceEastAsianText));
|
|
@@ -4128,8 +4268,39 @@ function tocInstructionStr(opts) {
|
|
|
4128
4268
|
function stringifyTableOfContents(alias = "Table of Contents", options = {}, entriesXml = "") {
|
|
4129
4269
|
const instr = tocInstructionStr(options);
|
|
4130
4270
|
const aliasAttr = alias ? ` w:val="${escapeXml(alias)}"` : "";
|
|
4131
|
-
const
|
|
4132
|
-
|
|
4271
|
+
const headRuns = `<w:r><w:rPr><w:rFonts w:asciiTheme="majorHAnsi" w:cstheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cs="Times New Roman"/></w:rPr><w:fldChar w:fldCharType="begin"${entriesXml.length > 0 ? "" : " w:dirty=\"1\""}/></w:r><w:r><w:instrText xml:space="preserve"> ${instr} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r>`;
|
|
4272
|
+
const endRun = `<w:r><w:fldChar w:fldCharType="end"/></w:r>`;
|
|
4273
|
+
const endParagraph = `<w:p>${endRun}</w:p>`;
|
|
4274
|
+
const body = entriesXml ? injectFieldEnd(injectFieldHead(entriesXml, headRuns), endRun) : `<w:p>${headRuns}</w:p>` + endParagraph;
|
|
4275
|
+
return `<w:sdt>${`<w:sdtPr><w:alias${aliasAttr}/><w:docPartObj><w:docPartGallery w:val="Table of Contents"/></w:docPartObj></w:sdtPr>`}${`<w:sdtContent>${body}</w:sdtContent>`}</w:sdt>`;
|
|
4276
|
+
}
|
|
4277
|
+
/**
|
|
4278
|
+
* Inject the field-head runs into the first `<w:p>` of `entriesXml`, placing
|
|
4279
|
+
* them after the opening tag (and after `<w:pPr>` when present) so the head
|
|
4280
|
+
* shares the first entry's paragraph. Returns `entriesXml` unchanged when no
|
|
4281
|
+
* `<w:p>` is found.
|
|
4282
|
+
*/
|
|
4283
|
+
function injectFieldHead(entriesXml, headRuns) {
|
|
4284
|
+
const pTagStart = entriesXml.search(/<w:p[ >]/);
|
|
4285
|
+
if (pTagStart < 0) return entriesXml;
|
|
4286
|
+
const pTagEnd = entriesXml.indexOf(">", pTagStart) + 1;
|
|
4287
|
+
let injectAt = pTagEnd;
|
|
4288
|
+
if (entriesXml.slice(pTagEnd, pTagEnd + 7) === "<w:pPr>") {
|
|
4289
|
+
const pPrEnd = entriesXml.indexOf("</w:pPr>", pTagEnd);
|
|
4290
|
+
if (pPrEnd >= 0) injectAt = pPrEnd + 8;
|
|
4291
|
+
}
|
|
4292
|
+
return entriesXml.slice(0, injectAt) + headRuns + entriesXml.slice(injectAt);
|
|
4293
|
+
}
|
|
4294
|
+
/**
|
|
4295
|
+
* Inject the field-end run into the last `<w:p>` of `entriesXml` (before its
|
|
4296
|
+
* closing `</w:p>`) so the end shares the last entry's paragraph instead of
|
|
4297
|
+
* occupying a standalone control-only paragraph that renders as a blank line.
|
|
4298
|
+
* Returns `entriesXml` unchanged when no `</w:p>` is found.
|
|
4299
|
+
*/
|
|
4300
|
+
function injectFieldEnd(entriesXml, endRun) {
|
|
4301
|
+
const lastClose = entriesXml.lastIndexOf("</w:p>");
|
|
4302
|
+
if (lastClose < 0) return entriesXml;
|
|
4303
|
+
return entriesXml.slice(0, lastClose) + endRun + entriesXml.slice(lastClose);
|
|
4133
4304
|
}
|
|
4134
4305
|
//#endregion
|
|
4135
4306
|
//#region src/parts/textbox/shape/shape.ts
|
|
@@ -4648,32 +4819,6 @@ function replaceRelsWithPlaceholders(xml, ctx, prefix) {
|
|
|
4648
4819
|
* @module
|
|
4649
4820
|
*/
|
|
4650
4821
|
/**
|
|
4651
|
-
* Mapping from empty child property name to self-closing XML element.
|
|
4652
|
-
*
|
|
4653
|
-
* These are single-key objects like `{ noBreakHyphen: true }` that map to
|
|
4654
|
-
* self-closing XML elements with no attributes.
|
|
4655
|
-
*
|
|
4656
|
-
* XSD reference: EG_RunInnerContent group in wml.xsd.
|
|
4657
|
-
*/
|
|
4658
|
-
const EMPTY_RUN_ELEMENTS = {
|
|
4659
|
-
noBreakHyphen: "<w:noBreakHyphen/>",
|
|
4660
|
-
softHyphen: "<w:softHyphen/>",
|
|
4661
|
-
dayShort: "<w:dayShort/>",
|
|
4662
|
-
monthShort: "<w:monthShort/>",
|
|
4663
|
-
yearShort: "<w:yearShort/>",
|
|
4664
|
-
dayLong: "<w:dayLong/>",
|
|
4665
|
-
monthLong: "<w:monthLong/>",
|
|
4666
|
-
yearLong: "<w:yearLong/>",
|
|
4667
|
-
annotationRef: "<w:annotationRef/>",
|
|
4668
|
-
footnoteRef: "<w:footnoteRef/>",
|
|
4669
|
-
endnoteRef: "<w:endnoteRef/>",
|
|
4670
|
-
separator: "<w:separator/>",
|
|
4671
|
-
continuationSeparator: "<w:continuationSeparator/>",
|
|
4672
|
-
pgNum: "<w:pgNum/>",
|
|
4673
|
-
carriageReturn: "<w:cr/>",
|
|
4674
|
-
lastRenderedPageBreak: "<w:lastRenderedPageBreak/>"
|
|
4675
|
-
};
|
|
4676
|
-
/**
|
|
4677
4822
|
* Stringify a run (w:r) from pure JSON options.
|
|
4678
4823
|
*
|
|
4679
4824
|
* Handles text, children, breaks, and run properties.
|
|
@@ -4780,8 +4925,8 @@ function stringifyParagraph(opts, ctx, sectionPropertiesXml) {
|
|
|
4780
4925
|
* Dispatches to the appropriate stringifier based on the child type.
|
|
4781
4926
|
* Pure JSON API — no class instance support.
|
|
4782
4927
|
*/
|
|
4783
|
-
function stringifyBodyChild(child, ctx) {
|
|
4784
|
-
if ("paragraph" in child) return stringifyParagraph(child.paragraph, ctx);
|
|
4928
|
+
function stringifyBodyChild(child, ctx, sectionPropertiesXml) {
|
|
4929
|
+
if ("paragraph" in child) return stringifyParagraph(child.paragraph, ctx, sectionPropertiesXml);
|
|
4785
4930
|
if ("table" in child) return tableDesc.stringify(child.table, ctx) ?? "";
|
|
4786
4931
|
if ("toc" in child) {
|
|
4787
4932
|
const { alias, ...options } = child.toc;
|
|
@@ -4895,14 +5040,18 @@ function stringifyDocumentXml(ctx, docCtx) {
|
|
|
4895
5040
|
if (ctx._options.background) parts.push(stringifyDocumentBackground(ctx._options.background, docCtx));
|
|
4896
5041
|
const bodyParts = [];
|
|
4897
5042
|
for (let si = 0; si < sections.length; si++) {
|
|
4898
|
-
const
|
|
4899
|
-
if (section.children) for (const child of section.children) bodyParts.push(stringifyBodyChild(child, docCtx));
|
|
5043
|
+
const children = sections[si].children ?? [];
|
|
4900
5044
|
const sectPrOpts = bodySections[si];
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
5045
|
+
const sectPrXml = sectPrOpts ? sectionPropertiesDesc.stringify(sectPrOpts, docCtx) ?? "" : "";
|
|
5046
|
+
const isLast = si === sections.length - 1;
|
|
5047
|
+
let sectPrHosted = isLast || !sectPrXml;
|
|
5048
|
+
for (let ci = 0; ci < children.length; ci++) {
|
|
5049
|
+
const inject = !isLast && sectPrXml && ci === children.length - 1 && "paragraph" in children[ci];
|
|
5050
|
+
if (inject) sectPrHosted = true;
|
|
5051
|
+
bodyParts.push(stringifyBodyChild(children[ci], docCtx, inject ? sectPrXml : void 0));
|
|
4905
5052
|
}
|
|
5053
|
+
if (!isLast && sectPrXml && !sectPrHosted) bodyParts.push(`<w:p><w:pPr>${sectPrXml}</w:pPr></w:p>`);
|
|
5054
|
+
if (isLast && sectPrXml) bodyParts.push(sectPrXml);
|
|
4906
5055
|
}
|
|
4907
5056
|
parts.push(`<w:body>${bodyParts.join("")}</w:body>`);
|
|
4908
5057
|
parts.push("</w:document>");
|
|
@@ -5005,7 +5154,8 @@ function parseParagraphProperties(el, ctx) {
|
|
|
5005
5154
|
const level = ilvl ? attrNum(ilvl, "w:val") ?? 0 : 0;
|
|
5006
5155
|
const numIdEl = findChild(numPr, "w:numId");
|
|
5007
5156
|
const numId = numIdEl ? attr(numIdEl, "w:val") : void 0;
|
|
5008
|
-
if (numId
|
|
5157
|
+
if (numId === "0") opts.numbering = false;
|
|
5158
|
+
else if (numId !== void 0 && ctx.numberingCache.size > 0) {
|
|
5009
5159
|
const numEl = ctx.docx.numbering;
|
|
5010
5160
|
if (numEl) {
|
|
5011
5161
|
let abstractNumId;
|
|
@@ -5116,14 +5266,8 @@ function parseParagraphProperties(el, ctx) {
|
|
|
5116
5266
|
}
|
|
5117
5267
|
const shd = findChild(el, "w:shd");
|
|
5118
5268
|
if (shd) {
|
|
5119
|
-
const
|
|
5120
|
-
|
|
5121
|
-
if (fill) shdObj.fill = fill;
|
|
5122
|
-
const color = attr(shd, "w:color");
|
|
5123
|
-
if (color) shdObj.color = color;
|
|
5124
|
-
const val = attr(shd, "w:val");
|
|
5125
|
-
if (val) shdObj.type = val;
|
|
5126
|
-
if (Object.keys(shdObj).length > 0) opts.shading = shdObj;
|
|
5269
|
+
const shading = parseShading(shd);
|
|
5270
|
+
if (shading) opts.shading = shading;
|
|
5127
5271
|
}
|
|
5128
5272
|
const textAlignment = findChild(el, "w:textAlignment");
|
|
5129
5273
|
if (textAlignment) {
|
|
@@ -5985,8 +6129,9 @@ function parseImageRun(el, ctx) {
|
|
|
5985
6129
|
if (!mediaPath) return void 0;
|
|
5986
6130
|
const imageData = ctx.docx.doc.getRaw(mediaPath);
|
|
5987
6131
|
if (!imageData) return void 0;
|
|
6132
|
+
const type = imageTypeFromPath(mediaPath);
|
|
5988
6133
|
const imageOpts = {
|
|
5989
|
-
type
|
|
6134
|
+
type,
|
|
5990
6135
|
data: imageData,
|
|
5991
6136
|
transformation: {
|
|
5992
6137
|
...info.width !== void 0 ? { width: info.width } : {},
|
|
@@ -6017,6 +6162,15 @@ function parseImageRun(el, ctx) {
|
|
|
6017
6162
|
if (blipResult.blipEffects) imageOpts.blipEffects = blipResult.blipEffects;
|
|
6018
6163
|
const useLocalDpi = readBlipUseLocalDpi(blip);
|
|
6019
6164
|
if (useLocalDpi !== void 0) imageOpts.useLocalDpi = useLocalDpi;
|
|
6165
|
+
const svg = readBlipSvg(blip, ctx);
|
|
6166
|
+
if (svg) {
|
|
6167
|
+
imageOpts.fallback = {
|
|
6168
|
+
type,
|
|
6169
|
+
data: imageData
|
|
6170
|
+
};
|
|
6171
|
+
imageOpts.type = "svg";
|
|
6172
|
+
imageOpts.data = svg.data;
|
|
6173
|
+
}
|
|
6020
6174
|
return { image: imageOpts };
|
|
6021
6175
|
}
|
|
6022
6176
|
/**
|
|
@@ -6033,6 +6187,33 @@ function readBlipUseLocalDpi(blip) {
|
|
|
6033
6187
|
}
|
|
6034
6188
|
}
|
|
6035
6189
|
/**
|
|
6190
|
+
* Read the `asvg:svgBlip` blip extension. When present, the surrounding
|
|
6191
|
+
* `a:blip` r:embed carries the raster fallback and this extension targets the
|
|
6192
|
+
* vector SVG part. Returns the SVG bytes so the picture round-trips as an
|
|
6193
|
+
* SvgMediaOptions (vector primary + raster fallback); undefined when no SVG
|
|
6194
|
+
* extension exists.
|
|
6195
|
+
*/
|
|
6196
|
+
function readBlipSvg(blip, ctx) {
|
|
6197
|
+
const extLst = findChild(blip, "a:extLst");
|
|
6198
|
+
if (!extLst) return void 0;
|
|
6199
|
+
for (const ext of extLst.elements ?? []) {
|
|
6200
|
+
if (ext.type !== "element" || ext.name !== "a:ext") continue;
|
|
6201
|
+
const svgBlip = findChild(ext, "asvg:svgBlip");
|
|
6202
|
+
if (svgBlip) {
|
|
6203
|
+
const rEmbed = attr(svgBlip, "r:embed");
|
|
6204
|
+
if (!rEmbed) return void 0;
|
|
6205
|
+
const svgPath = ctx.resolveRelationship(rEmbed);
|
|
6206
|
+
if (!svgPath) return void 0;
|
|
6207
|
+
const data = ctx.docx.doc.getRaw(svgPath);
|
|
6208
|
+
if (!data) return void 0;
|
|
6209
|
+
return {
|
|
6210
|
+
data,
|
|
6211
|
+
fileName: svgPath.split("/").pop() ?? svgPath
|
|
6212
|
+
};
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
/**
|
|
6036
6217
|
* Read the blip-fill crop rectangle (`a:srcRect`, l/t/r/b percentage insets)
|
|
6037
6218
|
* from a `pic:blipFill` parent. Returns undefined when there is no crop.
|
|
6038
6219
|
*/
|
|
@@ -6273,6 +6454,19 @@ function parsePicChildMediaData(picEl, ctx) {
|
|
|
6273
6454
|
const ln = findChild(spPr, "a:ln");
|
|
6274
6455
|
if (ln) result.outline = outlineDesc.parse(ln, ctx);
|
|
6275
6456
|
}
|
|
6457
|
+
const svg = readBlipSvg(blip, ctx);
|
|
6458
|
+
if (svg) return {
|
|
6459
|
+
...result,
|
|
6460
|
+
type: "svg",
|
|
6461
|
+
data: svg.data,
|
|
6462
|
+
fileName: svg.fileName,
|
|
6463
|
+
fallback: {
|
|
6464
|
+
type: result.type,
|
|
6465
|
+
fileName: result.fileName,
|
|
6466
|
+
data,
|
|
6467
|
+
transformation: result.transformation
|
|
6468
|
+
}
|
|
6469
|
+
};
|
|
6276
6470
|
return result;
|
|
6277
6471
|
}
|
|
6278
6472
|
/**
|
|
@@ -6409,6 +6603,26 @@ function readPosition(posEl) {
|
|
|
6409
6603
|
}
|
|
6410
6604
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
6411
6605
|
}
|
|
6606
|
+
/** Read wp:wrapPolygon (start + lineTo points) into a WrapPolygon, if present. */
|
|
6607
|
+
function readWrapPolygon(el) {
|
|
6608
|
+
const poly = findChild(el, "wp:wrapPolygon");
|
|
6609
|
+
if (!poly) return void 0;
|
|
6610
|
+
const points = [];
|
|
6611
|
+
const start = findChild(poly, "wp:start");
|
|
6612
|
+
if (start) points.push({
|
|
6613
|
+
x: attrNum(start, "x") ?? 0,
|
|
6614
|
+
y: attrNum(start, "y") ?? 0
|
|
6615
|
+
});
|
|
6616
|
+
for (const child of poly.elements ?? []) if (child.name === "wp:lineTo") points.push({
|
|
6617
|
+
x: attrNum(child, "x") ?? 0,
|
|
6618
|
+
y: attrNum(child, "y") ?? 0
|
|
6619
|
+
});
|
|
6620
|
+
if (points.length === 0) return void 0;
|
|
6621
|
+
return {
|
|
6622
|
+
edited: attrBool(poly, "edited"),
|
|
6623
|
+
points
|
|
6624
|
+
};
|
|
6625
|
+
}
|
|
6412
6626
|
/** Map the wp:anchor wrap child element into a TextWrapping ({ type, side? }). */
|
|
6413
6627
|
function readWrap(anchor) {
|
|
6414
6628
|
const WRAP_TYPE = [
|
|
@@ -6424,6 +6638,10 @@ function readWrap(anchor) {
|
|
|
6424
6638
|
const wrap = { type };
|
|
6425
6639
|
const side = attr(el, "wrapText");
|
|
6426
6640
|
if (side) wrap.side = side;
|
|
6641
|
+
if (name === "wrapTight" || name === "wrapThrough") {
|
|
6642
|
+
const polygon = readWrapPolygon(el);
|
|
6643
|
+
if (polygon) wrap.polygon = polygon;
|
|
6644
|
+
}
|
|
6427
6645
|
return wrap;
|
|
6428
6646
|
}
|
|
6429
6647
|
}
|
|
@@ -6895,11 +7113,17 @@ function stringifyGroupChild(child, ctx) {
|
|
|
6895
7113
|
}
|
|
6896
7114
|
if (child.type === "wpg") return stringifyNestedGroup(child, ctx);
|
|
6897
7115
|
const picData = child;
|
|
7116
|
+
const isSvg = picData.type === "svg";
|
|
7117
|
+
const blipTarget = isSvg && "fallback" in picData ? picData.fallback.fileName : picData.fileName;
|
|
6898
7118
|
const picParts = [];
|
|
6899
7119
|
picParts.push(stringifyNvPicPr({}, picData.nonVisualProperties));
|
|
6900
7120
|
const groupBlipParts = [];
|
|
7121
|
+
const extParts = [];
|
|
6901
7122
|
const useLocalDpiExt = buildUseLocalDpiExt(picData.useLocalDpi);
|
|
6902
|
-
|
|
7123
|
+
if (useLocalDpiExt) extParts.push(useLocalDpiExt);
|
|
7124
|
+
if (isSvg) extParts.push(`<a:ext uri="${SVG_BLIP_EXT_URI}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="{${escapeXml(picData.fileName)}}"/></a:ext>`);
|
|
7125
|
+
const extLst = extParts.length > 0 ? `<a:extLst>${extParts.join("")}</a:extLst>` : "";
|
|
7126
|
+
groupBlipParts.push(extLst ? `<a:blip r:embed="{${escapeXml(blipTarget)}}">${extLst}</a:blip>` : `<a:blip r:embed="{${escapeXml(blipTarget)}}"/>`);
|
|
6903
7127
|
const groupSrcRectXml = buildSrcRectXml(picData.sourceRectangle);
|
|
6904
7128
|
if (groupSrcRectXml) groupBlipParts.push(groupSrcRectXml);
|
|
6905
7129
|
groupBlipParts.push("<a:stretch><a:fillRect/></a:stretch>");
|
|
@@ -6953,7 +7177,12 @@ function stringifyPositionH(opts) {
|
|
|
6953
7177
|
function stringifyPositionV(opts) {
|
|
6954
7178
|
return `<wp:positionV relativeFrom="${opts.relative ?? VerticalPositionRelativeFrom.PAGE}">${opts.align ? `<wp:align>${opts.align}</wp:align>` : opts.offset !== void 0 ? `<wp:posOffset>${convertToEmu(opts.offset)}</wp:posOffset>` : "<wp:align>top</wp:align>"}</wp:positionV>`;
|
|
6955
7179
|
}
|
|
6956
|
-
function wrapPolygonStr(cx, cy) {
|
|
7180
|
+
function wrapPolygonStr(cx, cy, polygon) {
|
|
7181
|
+
if (polygon?.points.length) {
|
|
7182
|
+
const editedAttr = polygon.edited !== void 0 ? ` edited="${polygon.edited ? 1 : 0}"` : "";
|
|
7183
|
+
const [start, ...rest] = polygon.points;
|
|
7184
|
+
return `<wp:wrapPolygon${editedAttr}>${`<wp:start x="${start.x}" y="${start.y}"/>`}${rest.map((p) => `<wp:lineTo x="${p.x}" y="${p.y}"/>`).join("")}</wp:wrapPolygon>`;
|
|
7185
|
+
}
|
|
6957
7186
|
return `<wp:wrapPolygon edited="0"><wp:start x="0" y="0"/><wp:lineTo x="0" y="${-cy}"/><wp:lineTo x="${cx}" y="${-cy}"/><wp:lineTo x="${cx}" y="0"/><wp:lineTo x="0" y="0"/></wp:wrapPolygon>`;
|
|
6958
7187
|
}
|
|
6959
7188
|
function wrapSquareStr(textWrapping, margins) {
|
|
@@ -6971,13 +7200,13 @@ function wrapTightStr(textWrapping, margins, cx, cy) {
|
|
|
6971
7200
|
const a = [`wrapText="${textWrapping.side ?? TextWrappingSide.BOTH_SIDES}"`];
|
|
6972
7201
|
if (margins.left != null) a.push(`distL="${convertToEmu(margins.left)}"`);
|
|
6973
7202
|
if (margins.right != null) a.push(`distR="${convertToEmu(margins.right)}"`);
|
|
6974
|
-
return `<wp:wrapTight ${a.join(" ")}>${wrapPolygonStr(cx, cy)}</wp:wrapTight>`;
|
|
7203
|
+
return `<wp:wrapTight ${a.join(" ")}>${wrapPolygonStr(cx, cy, textWrapping.polygon)}</wp:wrapTight>`;
|
|
6975
7204
|
}
|
|
6976
7205
|
function wrapThroughStr(textWrapping, margins, cx, cy) {
|
|
6977
7206
|
const a = [`wrapText="${textWrapping.side ?? TextWrappingSide.BOTH_SIDES}"`];
|
|
6978
7207
|
if (margins.left != null) a.push(`distL="${convertToEmu(margins.left)}"`);
|
|
6979
7208
|
if (margins.right != null) a.push(`distR="${convertToEmu(margins.right)}"`);
|
|
6980
|
-
return `<wp:wrapThrough ${a.join(" ")}>${wrapPolygonStr(cx, cy)}</wp:wrapThrough>`;
|
|
7209
|
+
return `<wp:wrapThrough ${a.join(" ")}>${wrapPolygonStr(cx, cy, textWrapping.polygon)}</wp:wrapThrough>`;
|
|
6981
7210
|
}
|
|
6982
7211
|
function wrapTopAndBottomStr(margins) {
|
|
6983
7212
|
const m = margins ?? {};
|
|
@@ -7216,14 +7445,36 @@ function stringifyRunInline(opts, ctx) {
|
|
|
7216
7445
|
const rPr = stringifyRunProperties(opts);
|
|
7217
7446
|
if (rPr) parts.push(rPr);
|
|
7218
7447
|
if (opts.break) parts.push(breakXml(opts.break));
|
|
7219
|
-
if (opts.children)
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7448
|
+
if (opts.children) {
|
|
7449
|
+
for (const child of opts.children) if (typeof child === "string") parts.push(`<w:t xml:space="preserve">${escapeXml(child)}</w:t>`);
|
|
7450
|
+
else if (typeof child === "object" && child !== null) {
|
|
7451
|
+
if ("tab" in child) {
|
|
7452
|
+
parts.push("<w:tab/>");
|
|
7453
|
+
continue;
|
|
7454
|
+
}
|
|
7455
|
+
if ("pageBreak" in child) {
|
|
7456
|
+
parts.push("<w:br w:type=\"page\"/>");
|
|
7457
|
+
continue;
|
|
7458
|
+
}
|
|
7459
|
+
if ("columnBreak" in child) {
|
|
7460
|
+
parts.push("<w:br w:type=\"column\"/>");
|
|
7461
|
+
continue;
|
|
7462
|
+
}
|
|
7463
|
+
if ("break" in child) {
|
|
7464
|
+
parts.push(breakXml(child.break));
|
|
7465
|
+
continue;
|
|
7466
|
+
}
|
|
7467
|
+
const emptyXml = EMPTY_RUN_ELEMENTS[Object.keys(child)[0]];
|
|
7468
|
+
if (emptyXml) {
|
|
7469
|
+
parts.push(emptyXml);
|
|
7470
|
+
continue;
|
|
7471
|
+
}
|
|
7472
|
+
const jsonResult = stringifyChildDispatch(child, ctx);
|
|
7473
|
+
if (jsonResult !== void 0) if (Array.isArray(jsonResult)) parts.push(...jsonResult);
|
|
7474
|
+
else parts.push(jsonResult);
|
|
7475
|
+
else if ("text" in child || "children" in child || "break" in child) parts.push(stringifyRunInline(child, ctx));
|
|
7476
|
+
}
|
|
7477
|
+
} else if (opts.text !== void 0) parts.push(`<w:t xml:space="preserve">${escapeXml(String(opts.text))}</w:t>`);
|
|
7227
7478
|
const rsidAttrs = [];
|
|
7228
7479
|
if (opts.rsid) rsidAttrs.push(` w:rsidR="${opts.rsid}"`);
|
|
7229
7480
|
if (opts.runPropertiesRsid) rsidAttrs.push(` w:rsidRPr="${opts.runPropertiesRsid}"`);
|
|
@@ -7563,7 +7814,13 @@ function stringifyChildDispatch(child, ctx) {
|
|
|
7563
7814
|
registerMedia(c.children);
|
|
7564
7815
|
continue;
|
|
7565
7816
|
}
|
|
7566
|
-
|
|
7817
|
+
if (c.type === "svg") {
|
|
7818
|
+
const fb = c.fallback;
|
|
7819
|
+
fb.fileName = ctx.file.media.addMedia(fb.data, fb.type, () => fb, fb.fileName).fileName;
|
|
7820
|
+
c.fileName = ctx.file.media.addMedia(c.data, "svg", () => c, c.fileName).fileName;
|
|
7821
|
+
continue;
|
|
7822
|
+
}
|
|
7823
|
+
c.fileName = ctx.file.media.addMedia(c.data, c.type, () => c, c.fileName).fileName;
|
|
7567
7824
|
}
|
|
7568
7825
|
};
|
|
7569
7826
|
registerMedia(opts.children);
|
|
@@ -8267,30 +8524,6 @@ function parseCellMargins(marginEl) {
|
|
|
8267
8524
|
if (Object.keys(margins).length === 0) return void 0;
|
|
8268
8525
|
return margins;
|
|
8269
8526
|
}
|
|
8270
|
-
/** Parse a w:shd (CT_Shd) element into ShadingAttributesProperties. */
|
|
8271
|
-
function parseShading(shd) {
|
|
8272
|
-
const shading = {};
|
|
8273
|
-
const fill = attr(shd, "w:fill");
|
|
8274
|
-
if (fill) shading.fill = fill;
|
|
8275
|
-
const color = attr(shd, "w:color");
|
|
8276
|
-
if (color) shading.color = color;
|
|
8277
|
-
const val = attr(shd, "w:val");
|
|
8278
|
-
if (val) shading.type = val;
|
|
8279
|
-
const themeColor = attr(shd, "w:themeColor");
|
|
8280
|
-
if (themeColor && THEME_COLORS.includes(themeColor)) shading.themeColor = themeColor;
|
|
8281
|
-
const themeTint = attr(shd, "w:themeTint");
|
|
8282
|
-
if (themeTint) shading.themeTint = themeTint;
|
|
8283
|
-
const themeShade = attr(shd, "w:themeShade");
|
|
8284
|
-
if (themeShade) shading.themeShade = themeShade;
|
|
8285
|
-
const themeFill = attr(shd, "w:themeFill");
|
|
8286
|
-
if (themeFill && THEME_COLORS.includes(themeFill)) shading.themeFill = themeFill;
|
|
8287
|
-
const themeFillTint = attr(shd, "w:themeFillTint");
|
|
8288
|
-
if (themeFillTint) shading.themeFillTint = themeFillTint;
|
|
8289
|
-
const themeFillShade = attr(shd, "w:themeFillShade");
|
|
8290
|
-
if (themeFillShade) shading.themeFillShade = themeFillShade;
|
|
8291
|
-
if (Object.keys(shading).length === 0) return void 0;
|
|
8292
|
-
return shading;
|
|
8293
|
-
}
|
|
8294
8527
|
/** Parse a w:cnfStyle (CT_Cnf) element into CnfStyleOptions. */
|
|
8295
8528
|
function parseCnfStyle(cnfEl) {
|
|
8296
8529
|
const cnf = {};
|
|
@@ -10009,7 +10242,7 @@ function stringifyDocDefaults(opts) {
|
|
|
10009
10242
|
else children.push("<w:rPrDefault><w:rPr><w:rFonts w:asciiTheme=\"minorHAnsi\" w:eastAsiaTheme=\"minorEastAsia\" w:hAnsiTheme=\"minorHAnsi\" w:cstheme=\"minorBidi\"/><w:kern w:val=\"2\"/><w:sz w:val=\"22\"/><w:szCs w:val=\"24\"/><w:lang w:val=\"en-US\" w:eastAsia=\"zh-CN\" w:bidi=\"ar-SA\"/><w14:ligatures w14:val=\"standardContextual\"/></w:rPr></w:rPrDefault>");
|
|
10010
10243
|
const pPr = stringifyParagraphProperties(opts.paragraph).xml;
|
|
10011
10244
|
if (pPr) children.push(`<w:pPrDefault>${pPr}</w:pPrDefault>`);
|
|
10012
|
-
else children.push("<w:pPrDefault><w:pPr><w:spacing w:after=\"160\" w:line=\"278\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>");
|
|
10245
|
+
else children.push("<w:pPrDefault><w:pPr><w:widowControl/><w:spacing w:after=\"160\" w:line=\"278\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>");
|
|
10013
10246
|
return `<w:docDefaults>${children.join("")}</w:docDefaults>`;
|
|
10014
10247
|
}
|
|
10015
10248
|
let cachedDefaultStyles = null;
|
|
@@ -10047,8 +10280,7 @@ var DefaultStylesFactory = class {
|
|
|
10047
10280
|
id: "Normal",
|
|
10048
10281
|
name: "Normal",
|
|
10049
10282
|
default: true,
|
|
10050
|
-
quickFormat: true
|
|
10051
|
-
paragraph: { widowControl: false }
|
|
10283
|
+
quickFormat: true
|
|
10052
10284
|
});
|
|
10053
10285
|
const headings = [
|
|
10054
10286
|
{
|
|
@@ -11664,8 +11896,8 @@ const settingsDesc = {
|
|
|
11664
11896
|
}));
|
|
11665
11897
|
p.push(onOff("w:removePersonalInformation", opts.removePersonalInformation));
|
|
11666
11898
|
p.push(onOff("w:removeDateAndTime", opts.removeDateAndTime));
|
|
11667
|
-
p.push(onOff("w:displayBackgroundShape", opts.displayBackgroundShape));
|
|
11668
11899
|
p.push(onOff("w:doNotDisplayPageBoundaries", opts.doNotDisplayPageBoundaries));
|
|
11900
|
+
p.push(onOff("w:displayBackgroundShape", opts.displayBackgroundShape));
|
|
11669
11901
|
p.push(onOff("w:printPostScriptOverText", opts.printPostScriptOverText));
|
|
11670
11902
|
p.push(onOff("w:printFractionalCharacterWidth", opts.printFractionalCharacterWidth));
|
|
11671
11903
|
p.push(onOff("w:printFormsData", opts.printFormsData));
|
|
@@ -11750,12 +11982,12 @@ const settingsDesc = {
|
|
|
11750
11982
|
p.push(numVal("w:drawingGridVerticalSpacing", opts.drawingGridVerticalSpacing));
|
|
11751
11983
|
p.push(numVal("w:displayHorizontalDrawingGridEvery", opts.displayHorizontalDrawingGridEvery));
|
|
11752
11984
|
p.push(numVal("w:displayVerticalDrawingGridEvery", opts.displayVerticalDrawingGridEvery));
|
|
11985
|
+
p.push(onOff("w:doNotUseMarginsForDrawingGridOrigin", opts.doNotUseMarginsForDrawingGridOrigin));
|
|
11753
11986
|
p.push(numVal("w:drawingGridHorizontalOrigin", opts.drawingGridHorizontalOrigin));
|
|
11754
11987
|
p.push(numVal("w:drawingGridVerticalOrigin", opts.drawingGridVerticalOrigin));
|
|
11755
|
-
p.push(onOff("w:doNotUseMarginsForDrawingGridOrigin", opts.doNotUseMarginsForDrawingGridOrigin));
|
|
11756
11988
|
p.push(onOff("w:doNotShadeFormData", opts.doNotShadeFormData));
|
|
11757
|
-
if (opts.characterSpacingControl !== void 0) p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl));
|
|
11758
11989
|
p.push(onOff("w:noPunctuationKerning", opts.noPunctuationKerning));
|
|
11990
|
+
if (opts.characterSpacingControl !== void 0) p.push(strVal("w:characterSpacingControl", opts.characterSpacingControl));
|
|
11759
11991
|
p.push(onOff("w:printTwoOnOne", opts.printTwoOnOne));
|
|
11760
11992
|
p.push(onOff("w:strictFirstAndLastChars", opts.strictFirstAndLastChars));
|
|
11761
11993
|
if (opts.noLineBreaksAfter !== void 0) {
|
|
@@ -11806,7 +12038,6 @@ const settingsDesc = {
|
|
|
11806
12038
|
if (opts.rsids !== void 0) p.push(stringifyRsids(opts.rsids));
|
|
11807
12039
|
if (opts.mathPr !== void 0) p.push(stringifyMathPr(opts.mathPr));
|
|
11808
12040
|
if (opts.attachedSchema !== void 0) for (const schema of opts.attachedSchema) p.push(strVal("w:attachedSchema", schema));
|
|
11809
|
-
if (opts.colorSchemeMapping !== void 0) p.push(stringifyColorSchemeMapping(opts.colorSchemeMapping));
|
|
11810
12041
|
if (opts.themeFontLang !== void 0) {
|
|
11811
12042
|
const a = {};
|
|
11812
12043
|
if (opts.themeFontLang.val !== void 0) a["w:val"] = opts.themeFontLang.val;
|
|
@@ -11814,6 +12045,7 @@ const settingsDesc = {
|
|
|
11814
12045
|
if (opts.themeFontLang.bidi !== void 0) a["w:bidi"] = opts.themeFontLang.bidi;
|
|
11815
12046
|
p.push(attrEl("w:themeFontLang", a));
|
|
11816
12047
|
}
|
|
12048
|
+
if (opts.colorSchemeMapping !== void 0) p.push(stringifyColorSchemeMapping(opts.colorSchemeMapping));
|
|
11817
12049
|
p.push(onOff("w:doNotIncludeSubdocsInStats", opts.doNotIncludeSubdocsInStats));
|
|
11818
12050
|
p.push(onOff("w:doNotAutoCompressPictures", opts.doNotAutoCompressPictures));
|
|
11819
12051
|
if (opts.forceUpgrade !== void 0) p.push("<w:forceUpgrade/>");
|
|
@@ -11827,8 +12059,8 @@ const settingsDesc = {
|
|
|
11827
12059
|
if (st.url !== void 0) attrs["w:url"] = st.url;
|
|
11828
12060
|
p.push(attrEl("w:smartTagType", attrs));
|
|
11829
12061
|
}
|
|
11830
|
-
p.push(onOff("w:doNotEmbedSmartTags", opts.doNotEmbedSmartTags));
|
|
11831
12062
|
if (opts.shapeDefaults !== void 0) p.push(`<w:shapeDefaults>${opts.shapeDefaults}</w:shapeDefaults>`);
|
|
12063
|
+
p.push(onOff("w:doNotEmbedSmartTags", opts.doNotEmbedSmartTags));
|
|
11832
12064
|
p.push(strVal("w:decimalSymbol", opts.decimalSymbol));
|
|
11833
12065
|
p.push(strVal("w:listSeparator", opts.listSeparator));
|
|
11834
12066
|
return `<w:settings ${SETTINGS_NS}>${p.join("")}</w:settings>`;
|
|
@@ -12990,8 +13222,20 @@ const contentTypesDesc = {
|
|
|
12990
13222
|
kind: "custom",
|
|
12991
13223
|
stringify(opts, _ctx) {
|
|
12992
13224
|
const p = ["<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"];
|
|
12993
|
-
|
|
12994
|
-
for (const
|
|
13225
|
+
const seenDefault = /* @__PURE__ */ new Set();
|
|
13226
|
+
for (const d of opts.defaults) {
|
|
13227
|
+
const key = d.extension.toLowerCase();
|
|
13228
|
+
if (seenDefault.has(key)) continue;
|
|
13229
|
+
seenDefault.add(key);
|
|
13230
|
+
p.push(defaultXml(d.extension, d.contentType));
|
|
13231
|
+
}
|
|
13232
|
+
const seenOverride = /* @__PURE__ */ new Set();
|
|
13233
|
+
for (const o of opts.overrides) {
|
|
13234
|
+
const key = o.partName.toLowerCase();
|
|
13235
|
+
if (seenOverride.has(key)) continue;
|
|
13236
|
+
seenOverride.add(key);
|
|
13237
|
+
p.push(overrideXml(o.partName, o.contentType));
|
|
13238
|
+
}
|
|
12995
13239
|
p.push("</Types>");
|
|
12996
13240
|
return p.join("");
|
|
12997
13241
|
},
|
|
@@ -13087,25 +13331,27 @@ const STANDARD_DEFAULTS = [
|
|
|
13087
13331
|
*
|
|
13088
13332
|
* Round-tripped packages pass through the source's [Content_Types], which may
|
|
13089
13333
|
* declare an uppercase extension (e.g. `JPG`) while the media is named `.jpg`.
|
|
13090
|
-
* OPC extension matching is case-
|
|
13091
|
-
*
|
|
13092
|
-
*
|
|
13093
|
-
* the media
|
|
13334
|
+
* OPC extension matching is **case-insensitive** (ECMA-376-2 §10.1.2), so `JPG`
|
|
13335
|
+
* and `jpg` are one key — emitting both yields a duplicate default that Word
|
|
13336
|
+
* rejects as unreadable content. Match existing defaults case-insensitively so
|
|
13337
|
+
* we never add a colliding extension; the media then resolves through the
|
|
13338
|
+
* source's already-declared default.
|
|
13094
13339
|
*/
|
|
13095
13340
|
function withMediaDefaults(input, mediaFileNames) {
|
|
13096
|
-
const have = new Set(input.defaults.map((d) => d.extension));
|
|
13341
|
+
const have = new Set(input.defaults.map((d) => d.extension.toLowerCase()));
|
|
13097
13342
|
const standard = new Map(STANDARD_DEFAULTS.map((d) => [d.extension, d.contentType]));
|
|
13098
13343
|
const defaults = [...input.defaults];
|
|
13099
13344
|
for (const fileName of mediaFileNames) {
|
|
13100
13345
|
const ext = fileName.slice(fileName.lastIndexOf(".") + 1);
|
|
13101
|
-
|
|
13102
|
-
|
|
13346
|
+
const key = ext.toLowerCase();
|
|
13347
|
+
if (!ext || have.has(key)) continue;
|
|
13348
|
+
const contentType = standard.get(key);
|
|
13103
13349
|
if (contentType) {
|
|
13104
13350
|
defaults.push({
|
|
13105
13351
|
extension: ext,
|
|
13106
13352
|
contentType
|
|
13107
13353
|
});
|
|
13108
|
-
have.add(
|
|
13354
|
+
have.add(key);
|
|
13109
13355
|
}
|
|
13110
13356
|
}
|
|
13111
13357
|
return {
|
|
@@ -13129,7 +13375,7 @@ const ALTCHUNK_DEFAULTS = {
|
|
|
13129
13375
|
*/
|
|
13130
13376
|
function withAltChunkOverrides(input, altChunks) {
|
|
13131
13377
|
const defaults = [...input.defaults];
|
|
13132
|
-
const haveExt = new Set(defaults.map((d) => d.extension));
|
|
13378
|
+
const haveExt = new Set(defaults.map((d) => d.extension.toLowerCase()));
|
|
13133
13379
|
for (const ac of altChunks) {
|
|
13134
13380
|
const ext = (ac.path.split(".").pop() ?? "").toLowerCase();
|
|
13135
13381
|
if (ext && !haveExt.has(ext) && ALTCHUNK_DEFAULTS[ext]) {
|
|
@@ -13619,6 +13865,6 @@ const webSettingsDesc = {
|
|
|
13619
13865
|
}
|
|
13620
13866
|
};
|
|
13621
13867
|
//#endregion
|
|
13622
|
-
export { PageBorderZOrder as $, stringifyCustomXmlShell as $t, StyleLevel as A,
|
|
13868
|
+
export { PageBorderZOrder as $, stringifyCustomXmlShell as $t, StyleLevel as A, TextHorzOverflowType as An, sectionPageSizeDefaults as At, stringifyNumberingStyle as B, TextEffect as Bn, NumberFormat as Bt, footnotesDesc as C, RubyAlign as Cn, parseSdtBlock as Ct, selectTocEntryElements as D, EmphasisMarkType as Dn, sectionPropertiesDesc as Dt, parseTocFieldInstruction as E, PositionalTabRelativeTo as En, parseSectionPropertiesEl as Et, extractStyleId as F, parseBodyProperties as Fn, createVerticalPosition as Ft, createHeaderFooterReference as G, TextboxTightWrapType as Gn, TextWrappingSide as Gt, stringifyTableStyle as H, PageNumber as Hn, VerticalPositionAlign as Ht, parseStyleDefinitions as I, createImageData$1 as In, createHorizontalPosition as It, LineNumberRestartFormat as J, AlignmentType as Jn, checkboxSymbolRunInner as Jt, SectionType as K, HeadingLevel as Kn, TextWrappingType as Kt, DefaultStylesFactory as L, Media as Ln, HorizontalPositionRelativeFrom as Lt, Styles as M, TextVerticalType as Mn, PageOrientation as Mt, buildNumberingCache as N, VerticalAnchor as Nn, PageNumberSeparator as Nt, SdtDateMappingType as O, UnderlineType as On, stringifySectionPropertiesXml as Ot, buildStyleCache as P, createBodyProperties as Pn, createPageNumberType as Pt, PageBorderOffsetFrom as Q, setBodyParseChild as Qt, stringifyCharacterStyle as R, createTransformation as Rn, VerticalPositionRelativeFrom as Rt, endnotesDesc as S, parseFormFieldData as Sn, stringifyTableOfContents as St, parseTocFieldFromElements as T, PositionalTabLeader as Tn, FontWrapper as Tt, HeaderFooterReferenceType as U, breakXml as Un, createWrapThrough as Ut, stringifyParagraphStyle as V, EMPTY_RUN_ELEMENTS as Vn, SpaceType as Vt, HeaderFooterType as W, TextAlignmentType as Wn, createWrapTight as Wt, createPageMargin as X, parseCustomXmlProperties as Xt, createLineNumberType as Y, customXmlBlockDesc as Yt, PageBorderDisplay as Z, sdtBlockDesc as Zt, glossaryDesc as _, TextDirection as _n, parseParagraph as _t, appPropertiesDesc as a, parseShading as an, LevelFormat as at, CharacterSet as b, FormFieldTextType as bn, stringifyDocumentXml as bt, relationshipsDesc as c, widthFiftiethsToPct as cn, parseTablePropertiesEl as ct, withAltChunkOverrides as d, BorderStyle as dn, tableDesc as dt, stringifySdtPr as en, DocumentGridType as et, withMediaDefaults as f, TableLayoutType as fn, stringifyChildDispatch as ft, DocPartType as g, TableAnchorType as gn, resetDrawingIdGen as gt, DocPartGallery as h, RelativeVerticalPosition as hn, drawingDesc as ht, webSettingsDesc as i, ShadingType as in, parseNumberingDefinitions as it, settingsDesc as j, TextVertOverflowType as jn, PageTextDirectionType as jt, SdtLock as k, TextBodyWrappingType as kn, sectionMarginDefaults as kt, buildContentTypesFromRegistry as l, widthPctToFiftieths as ln, parseTableRowPropertiesEl as lt, DocPartBehavior as m, RelativeHorizontalPosition as mn, stringifyRunInline as mt, frameXml as n, subDocDesc as nn, DocumentAttributeNamespaces as nt, customPropertiesDesc as o, objectDesc as on, LevelSuffix as ot, commentsDesc as p, OverlapType as pn, stringifyParagraphInline as pt, createSectionType as q, LineRuleType as qn, altChunkDesc as qt, framesetXml as r, stringifyElement as rn, Numbering as rt, corePropertiesDesc as s, WidthType as sn, parseTableCellPropertiesEl as st, TargetScreenSize as t, stringifySdtShell as tn, createDocumentGrid as tt, contentTypesDesc as u, TABLE_BORDERS_NONE as un, setTableParseChild as ut, bibliographyDesc as v, VerticalMergeType as vn, parseParagraphProperties as vt, parseToc as w, PositionalTabAlignment as wn, parseSdtProperties as wt, EditGroupType as x, createFormFieldData as xn, replaceRelsWithPlaceholders as xt, fontTableDesc as y, ProofErrorType as yn, stringifyBodyChild as yt, stringifyConditionalTableStyle as z, HighlightColor as zn, HorizontalPositionAlign as zt };
|
|
13623
13869
|
|
|
13624
|
-
//# sourceMappingURL=parts-
|
|
13870
|
+
//# sourceMappingURL=parts-B7Sfx_F0.mjs.map
|