@cj-tech-master/excelts 9.6.1 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/README_zh.md +18 -3
- package/dist/browser/modules/excel/cell.d.ts +4 -0
- package/dist/browser/modules/excel/note.js +5 -1
- package/dist/browser/modules/excel/row.js +35 -2
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +8 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +22 -2
- package/dist/browser/modules/excel/types.d.ts +81 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +8 -0
- package/dist/browser/modules/excel/utils/drawing-utils.js +19 -2
- package/dist/browser/modules/excel/workbook.browser.d.ts +16 -0
- package/dist/browser/modules/excel/workbook.browser.js +32 -2
- package/dist/browser/modules/excel/worksheet.d.ts +31 -1
- package/dist/browser/modules/excel/worksheet.js +83 -0
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-shape-xform.d.ts +7 -0
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-shape-xform.js +42 -8
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +3 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +5 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +18 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +6 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/blip-xform.js +38 -11
- package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +5 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/pic-xform.d.ts +2 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/pic-xform.js +2 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/shape-xform.d.ts +47 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/shape-xform.js +109 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +10 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +64 -1
- package/dist/browser/modules/pdf/builder/document-builder.js +22 -49
- package/dist/browser/modules/pdf/builder/pdf-editor.js +1 -1
- package/dist/browser/modules/pdf/core/pdf-stream.d.ts +28 -1
- package/dist/browser/modules/pdf/core/pdf-stream.js +38 -2
- package/dist/browser/modules/pdf/font/font-manager.d.ts +26 -0
- package/dist/browser/modules/pdf/font/font-manager.js +35 -18
- package/dist/browser/modules/pdf/render/page-renderer.d.ts +51 -3
- package/dist/browser/modules/pdf/render/page-renderer.js +111 -18
- package/dist/browser/modules/word/advanced/field-engine.js +45 -20
- package/dist/browser/modules/word/advanced/glossary.d.ts +10 -36
- package/dist/browser/modules/word/advanced/glossary.js +8 -9
- package/dist/browser/modules/word/advanced/math-convert.js +94 -12
- package/dist/browser/modules/word/advanced/ole-objects.d.ts +28 -0
- package/dist/browser/modules/word/advanced/ole-objects.js +122 -19
- package/dist/browser/modules/word/advanced/style-map.js +31 -10
- package/dist/browser/modules/word/builder/run-builders.d.ts +7 -1
- package/dist/browser/modules/word/builder/run-builders.js +7 -1
- package/dist/browser/modules/word/constants.d.ts +4 -0
- package/dist/browser/modules/word/constants.js +5 -1
- package/dist/browser/modules/word/convert/docx-to-semantic.d.ts +2 -1
- package/dist/browser/modules/word/convert/docx-to-semantic.js +135 -1
- package/dist/browser/modules/word/convert/html/html-import.d.ts +32 -1
- package/dist/browser/modules/word/convert/html/html-import.js +167 -14
- package/dist/browser/modules/word/convert/html/html.d.ts +2 -2
- package/dist/browser/modules/word/convert/html/html.js +1 -1
- package/dist/browser/modules/word/convert/markdown/markdown-import.d.ts +48 -18
- package/dist/browser/modules/word/convert/markdown/markdown-import.js +279 -69
- package/dist/browser/modules/word/convert/markdown/markdown.d.ts +1 -1
- package/dist/browser/modules/word/convert/odt/odt.js +407 -56
- package/dist/browser/modules/word/html.d.ts +2 -2
- package/dist/browser/modules/word/html.js +1 -1
- package/dist/browser/modules/word/index.base.d.ts +3 -3
- package/dist/browser/modules/word/index.base.js +1 -1
- package/dist/browser/modules/word/layout/layout-full.js +326 -19
- package/dist/browser/modules/word/layout/render-page.js +35 -8
- package/dist/browser/modules/word/markdown.d.ts +1 -1
- package/dist/browser/modules/word/query/compat.d.ts +10 -2
- package/dist/browser/modules/word/query/compat.js +29 -21
- package/dist/browser/modules/word/reader/docx-reader.js +105 -2
- package/dist/browser/modules/word/reader/math-parser.js +8 -2
- package/dist/browser/modules/word/security/cfb-reader.js +5 -5
- package/dist/browser/modules/word/types.d.ts +96 -1
- package/dist/browser/modules/word/writer/docx-packager.js +108 -2
- package/dist/browser/modules/word/writer/glossary-writer.d.ts +28 -0
- package/dist/browser/modules/word/writer/glossary-writer.js +121 -0
- package/dist/browser/modules/word/writer/header-footer-writer.js +105 -20
- package/dist/browser/modules/word/writer/math-writer.js +7 -2
- package/dist/browser/utils/font-metrics.d.ts +8 -0
- package/dist/browser/utils/font-metrics.js +43 -0
- package/dist/browser/utils/theme-colors.js +4 -1
- package/dist/cjs/modules/excel/note.js +5 -1
- package/dist/cjs/modules/excel/row.js +35 -2
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +22 -2
- package/dist/cjs/modules/excel/utils/drawing-utils.js +19 -2
- package/dist/cjs/modules/excel/workbook.browser.js +31 -1
- package/dist/cjs/modules/excel/worksheet.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/comment/vml-shape-xform.js +42 -8
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +3 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +5 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +18 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/blip-xform.js +38 -11
- package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +5 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/pic-xform.js +2 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/shape-xform.js +112 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +10 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +64 -1
- package/dist/cjs/modules/pdf/builder/document-builder.js +21 -48
- package/dist/cjs/modules/pdf/builder/pdf-editor.js +1 -1
- package/dist/cjs/modules/pdf/core/pdf-stream.js +38 -2
- package/dist/cjs/modules/pdf/font/font-manager.js +35 -18
- package/dist/cjs/modules/pdf/render/page-renderer.js +112 -18
- package/dist/cjs/modules/word/advanced/field-engine.js +45 -20
- package/dist/cjs/modules/word/advanced/glossary.js +8 -9
- package/dist/cjs/modules/word/advanced/math-convert.js +94 -12
- package/dist/cjs/modules/word/advanced/ole-objects.js +123 -19
- package/dist/cjs/modules/word/advanced/style-map.js +31 -10
- package/dist/cjs/modules/word/builder/run-builders.js +7 -1
- package/dist/cjs/modules/word/constants.js +5 -1
- package/dist/cjs/modules/word/convert/docx-to-semantic.js +135 -1
- package/dist/cjs/modules/word/convert/html/html-import.js +168 -14
- package/dist/cjs/modules/word/convert/html/html.js +2 -1
- package/dist/cjs/modules/word/convert/markdown/markdown-import.js +279 -69
- package/dist/cjs/modules/word/convert/odt/odt.js +407 -56
- package/dist/cjs/modules/word/html.js +2 -1
- package/dist/cjs/modules/word/index.base.js +4 -3
- package/dist/cjs/modules/word/layout/layout-full.js +325 -18
- package/dist/cjs/modules/word/layout/render-page.js +35 -8
- package/dist/cjs/modules/word/query/compat.js +29 -21
- package/dist/cjs/modules/word/reader/docx-reader.js +104 -1
- package/dist/cjs/modules/word/reader/math-parser.js +8 -2
- package/dist/cjs/modules/word/security/cfb-reader.js +5 -5
- package/dist/cjs/modules/word/writer/docx-packager.js +108 -2
- package/dist/cjs/modules/word/writer/glossary-writer.js +124 -0
- package/dist/cjs/modules/word/writer/header-footer-writer.js +105 -20
- package/dist/cjs/modules/word/writer/math-writer.js +7 -2
- package/dist/cjs/utils/font-metrics.js +44 -0
- package/dist/cjs/utils/theme-colors.js +4 -1
- package/dist/esm/modules/excel/note.js +5 -1
- package/dist/esm/modules/excel/row.js +35 -2
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +22 -2
- package/dist/esm/modules/excel/utils/drawing-utils.js +19 -2
- package/dist/esm/modules/excel/workbook.browser.js +32 -2
- package/dist/esm/modules/excel/worksheet.js +83 -0
- package/dist/esm/modules/excel/xlsx/xform/comment/vml-shape-xform.js +42 -8
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +3 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +5 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +18 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/blip-xform.js +38 -11
- package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +5 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/pic-xform.js +2 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/shape-xform.js +109 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +10 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +64 -1
- package/dist/esm/modules/pdf/builder/document-builder.js +22 -49
- package/dist/esm/modules/pdf/builder/pdf-editor.js +1 -1
- package/dist/esm/modules/pdf/core/pdf-stream.js +38 -2
- package/dist/esm/modules/pdf/font/font-manager.js +35 -18
- package/dist/esm/modules/pdf/render/page-renderer.js +111 -18
- package/dist/esm/modules/word/advanced/field-engine.js +45 -20
- package/dist/esm/modules/word/advanced/glossary.js +8 -9
- package/dist/esm/modules/word/advanced/math-convert.js +94 -12
- package/dist/esm/modules/word/advanced/ole-objects.js +122 -19
- package/dist/esm/modules/word/advanced/style-map.js +31 -10
- package/dist/esm/modules/word/builder/run-builders.js +7 -1
- package/dist/esm/modules/word/constants.js +5 -1
- package/dist/esm/modules/word/convert/docx-to-semantic.js +135 -1
- package/dist/esm/modules/word/convert/html/html-import.js +167 -14
- package/dist/esm/modules/word/convert/html/html.js +1 -1
- package/dist/esm/modules/word/convert/markdown/markdown-import.js +279 -69
- package/dist/esm/modules/word/convert/odt/odt.js +407 -56
- package/dist/esm/modules/word/html.js +1 -1
- package/dist/esm/modules/word/index.base.js +1 -1
- package/dist/esm/modules/word/layout/layout-full.js +326 -19
- package/dist/esm/modules/word/layout/render-page.js +35 -8
- package/dist/esm/modules/word/query/compat.js +29 -21
- package/dist/esm/modules/word/reader/docx-reader.js +105 -2
- package/dist/esm/modules/word/reader/math-parser.js +8 -2
- package/dist/esm/modules/word/security/cfb-reader.js +5 -5
- package/dist/esm/modules/word/writer/docx-packager.js +108 -2
- package/dist/esm/modules/word/writer/glossary-writer.js +121 -0
- package/dist/esm/modules/word/writer/header-footer-writer.js +105 -20
- package/dist/esm/modules/word/writer/math-writer.js +7 -2
- package/dist/esm/utils/font-metrics.js +43 -0
- package/dist/esm/utils/theme-colors.js +4 -1
- package/dist/iife/excelts.iife.js +496 -59
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +39 -39
- package/dist/types/modules/excel/cell.d.ts +4 -0
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +8 -1
- package/dist/types/modules/excel/types.d.ts +81 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +8 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +16 -0
- package/dist/types/modules/excel/worksheet.d.ts +31 -1
- package/dist/types/modules/excel/xlsx/xform/comment/vml-shape-xform.d.ts +7 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +6 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/pic-xform.d.ts +2 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/shape-xform.d.ts +47 -0
- package/dist/types/modules/pdf/core/pdf-stream.d.ts +28 -1
- package/dist/types/modules/pdf/font/font-manager.d.ts +26 -0
- package/dist/types/modules/pdf/render/page-renderer.d.ts +51 -3
- package/dist/types/modules/word/advanced/glossary.d.ts +10 -36
- package/dist/types/modules/word/advanced/ole-objects.d.ts +28 -0
- package/dist/types/modules/word/builder/run-builders.d.ts +7 -1
- package/dist/types/modules/word/constants.d.ts +4 -0
- package/dist/types/modules/word/convert/docx-to-semantic.d.ts +2 -1
- package/dist/types/modules/word/convert/html/html-import.d.ts +32 -1
- package/dist/types/modules/word/convert/html/html.d.ts +2 -2
- package/dist/types/modules/word/convert/markdown/markdown-import.d.ts +48 -18
- package/dist/types/modules/word/convert/markdown/markdown.d.ts +1 -1
- package/dist/types/modules/word/html.d.ts +2 -2
- package/dist/types/modules/word/index.base.d.ts +3 -3
- package/dist/types/modules/word/markdown.d.ts +1 -1
- package/dist/types/modules/word/query/compat.d.ts +10 -2
- package/dist/types/modules/word/types.d.ts +96 -1
- package/dist/types/modules/word/writer/glossary-writer.d.ts +28 -0
- package/dist/types/utils/font-metrics.d.ts +8 -0
- package/package.json +3 -1
|
@@ -426,7 +426,7 @@ function parseParagraph(el, styles, listContext) {
|
|
|
426
426
|
if (listContext) {
|
|
427
427
|
paraProps = {
|
|
428
428
|
...paraProps,
|
|
429
|
-
numbering: { numId:
|
|
429
|
+
numbering: { numId: listContext.numId, level: listContext.level }
|
|
430
430
|
};
|
|
431
431
|
}
|
|
432
432
|
const children = [];
|
|
@@ -555,8 +555,12 @@ function parseDrawFrame(el) {
|
|
|
555
555
|
};
|
|
556
556
|
}
|
|
557
557
|
/** Parse a text:list element. */
|
|
558
|
-
function parseList(el, styles, parentLevel) {
|
|
558
|
+
function parseList(el, styles, parentLevel, registry, parentNumId) {
|
|
559
559
|
const listStyleName = nsAttr(el, "text", "style-name");
|
|
560
|
+
// The outermost list determines the numId; nested lists inherit it so a
|
|
561
|
+
// single multi-level list resolves to one numbering definition. Only the
|
|
562
|
+
// top-level list (no parent numId) consults its own style name.
|
|
563
|
+
const numId = parentNumId ?? registry.numIdFor(listStyleName);
|
|
560
564
|
const paragraphs = [];
|
|
561
565
|
const level = parentLevel;
|
|
562
566
|
const items = findNsChildren(el, "text", "list-item");
|
|
@@ -567,18 +571,19 @@ function parseList(el, styles, parentLevel) {
|
|
|
567
571
|
}
|
|
568
572
|
const local = getLocalName(child.name);
|
|
569
573
|
if (local === "p" || local === "h") {
|
|
570
|
-
|
|
574
|
+
registry.noteLevel(numId, level);
|
|
575
|
+
paragraphs.push(parseParagraph(child, styles, { listStyleName, level, numId }));
|
|
571
576
|
}
|
|
572
577
|
else if (local === "list") {
|
|
573
|
-
// Nested list
|
|
574
|
-
paragraphs.push(...parseList(child, styles, level + 1));
|
|
578
|
+
// Nested list — inherit the enclosing list's numId.
|
|
579
|
+
paragraphs.push(...parseList(child, styles, level + 1, registry, numId));
|
|
575
580
|
}
|
|
576
581
|
}
|
|
577
582
|
}
|
|
578
583
|
return paragraphs;
|
|
579
584
|
}
|
|
580
585
|
/** Parse a table:table element into a Table. */
|
|
581
|
-
function parseTable(el, styles) {
|
|
586
|
+
function parseTable(el, styles, registry) {
|
|
582
587
|
const tableStyleName = nsAttr(el, "table", "style-name");
|
|
583
588
|
const tableStyle = tableStyleName ? styles.get(tableStyleName) : undefined;
|
|
584
589
|
// Parse column definitions for widths
|
|
@@ -629,10 +634,10 @@ function parseTable(el, styles) {
|
|
|
629
634
|
cellContent.push(parseParagraph(cellChild, styles));
|
|
630
635
|
}
|
|
631
636
|
else if (cellChildLocal === "table") {
|
|
632
|
-
cellContent.push(parseTable(cellChild, styles));
|
|
637
|
+
cellContent.push(parseTable(cellChild, styles, registry));
|
|
633
638
|
}
|
|
634
639
|
else if (cellChildLocal === "list") {
|
|
635
|
-
cellContent.push(...parseList(cellChild, styles, 0));
|
|
640
|
+
cellContent.push(...parseList(cellChild, styles, 0, registry));
|
|
636
641
|
}
|
|
637
642
|
}
|
|
638
643
|
// Ensure at least one paragraph per cell
|
|
@@ -663,7 +668,7 @@ function parseTable(el, styles) {
|
|
|
663
668
|
};
|
|
664
669
|
}
|
|
665
670
|
/** Parse document body content from the office:body/office:text element. */
|
|
666
|
-
function parseDocumentBody(bodyEl, styles) {
|
|
671
|
+
function parseDocumentBody(bodyEl, styles, registry) {
|
|
667
672
|
const content = [];
|
|
668
673
|
for (const child of bodyEl.children) {
|
|
669
674
|
if (child.type !== "element") {
|
|
@@ -674,14 +679,14 @@ function parseDocumentBody(bodyEl, styles) {
|
|
|
674
679
|
content.push(parseParagraph(child, styles));
|
|
675
680
|
}
|
|
676
681
|
else if (local === "table") {
|
|
677
|
-
content.push(parseTable(child, styles));
|
|
682
|
+
content.push(parseTable(child, styles, registry));
|
|
678
683
|
}
|
|
679
684
|
else if (local === "list") {
|
|
680
|
-
content.push(...parseList(child, styles, 0));
|
|
685
|
+
content.push(...parseList(child, styles, 0, registry));
|
|
681
686
|
}
|
|
682
687
|
else if (local === "section") {
|
|
683
688
|
// Sections in ODF are logical containers; flatten their content
|
|
684
|
-
content.push(...parseDocumentBody(child, styles));
|
|
689
|
+
content.push(...parseDocumentBody(child, styles, registry));
|
|
685
690
|
}
|
|
686
691
|
}
|
|
687
692
|
return content;
|
|
@@ -819,59 +824,248 @@ function convertStylesToStyleDefs(styles) {
|
|
|
819
824
|
return defs;
|
|
820
825
|
}
|
|
821
826
|
// =============================================================================
|
|
822
|
-
// ODT list numbering
|
|
827
|
+
// ODT list numbering definitions (bullet & numbered, multi-level)
|
|
823
828
|
// =============================================================================
|
|
829
|
+
/** Bullet glyphs per nesting level, cycling every three levels. */
|
|
830
|
+
const ODT_BULLET_CHARS = ["•", "◦", "▪", "•", "◦", "▪", "•", "◦", "▪"];
|
|
831
|
+
/** Default ODF `style:num-format` value emitted for each docx NumberFormat. */
|
|
832
|
+
function numberFormatToOdf(format) {
|
|
833
|
+
switch (format) {
|
|
834
|
+
case "decimal":
|
|
835
|
+
case "decimalZero":
|
|
836
|
+
return "1";
|
|
837
|
+
case "lowerLetter":
|
|
838
|
+
return "a";
|
|
839
|
+
case "upperLetter":
|
|
840
|
+
return "A";
|
|
841
|
+
case "lowerRoman":
|
|
842
|
+
return "i";
|
|
843
|
+
case "upperRoman":
|
|
844
|
+
return "I";
|
|
845
|
+
default:
|
|
846
|
+
// ODF has no equivalent for many Word-specific formats; fall back to
|
|
847
|
+
// decimal so the list still renders as an ordered list (its ordered
|
|
848
|
+
// nature is preserved even when the exact glyph set is not).
|
|
849
|
+
return "1";
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
/** Map an ODF `style:num-format` value to the closest docx NumberFormat. */
|
|
853
|
+
function odfNumFormatToDocx(numFormat) {
|
|
854
|
+
switch (numFormat) {
|
|
855
|
+
case "1":
|
|
856
|
+
return "decimal";
|
|
857
|
+
case "a":
|
|
858
|
+
return "lowerLetter";
|
|
859
|
+
case "A":
|
|
860
|
+
return "upperLetter";
|
|
861
|
+
case "i":
|
|
862
|
+
return "lowerRoman";
|
|
863
|
+
case "I":
|
|
864
|
+
return "upperRoman";
|
|
865
|
+
default:
|
|
866
|
+
return "decimal";
|
|
867
|
+
}
|
|
868
|
+
}
|
|
824
869
|
/**
|
|
825
|
-
*
|
|
826
|
-
* synthesize the corresponding `abstractNumberings` and `numberingInstances`
|
|
827
|
-
* so Word renders bullet/number markers. Without this the list paragraphs
|
|
828
|
-
* carry a `numId` that resolves to nothing in the produced document and the
|
|
829
|
-
* markers are invisible.
|
|
870
|
+
* Parse a single `text:list-style` element into its per-level formats.
|
|
830
871
|
*
|
|
831
|
-
*
|
|
832
|
-
* `
|
|
833
|
-
*
|
|
834
|
-
*
|
|
872
|
+
* Each `text:list-level-style-bullet` becomes a bullet level; each
|
|
873
|
+
* `text:list-level-style-number` becomes a numbered level whose docx format
|
|
874
|
+
* is derived from `style:num-format`. Levels are indexed by `text:level`
|
|
875
|
+
* (1-based in ODF) and stored 0-based.
|
|
835
876
|
*/
|
|
836
|
-
function
|
|
837
|
-
|
|
838
|
-
|
|
877
|
+
function parseOdfListStyle(el) {
|
|
878
|
+
const levels = new Map();
|
|
879
|
+
for (const child of el.children) {
|
|
880
|
+
if (child.type !== "element") {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
const local = getLocalName(child.name);
|
|
884
|
+
const levelAttr = parseInt(nsAttr(child, "text", "level") ?? "1", 10);
|
|
885
|
+
const level = Math.max(0, levelAttr - 1);
|
|
886
|
+
if (local === "list-level-style-bullet") {
|
|
887
|
+
levels.set(level, {
|
|
888
|
+
format: "bullet",
|
|
889
|
+
bulletChar: nsAttr(child, "text", "bullet-char") ?? ODT_BULLET_CHARS[level] ?? "•"
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
else if (local === "list-level-style-number") {
|
|
893
|
+
levels.set(level, {
|
|
894
|
+
format: odfNumFormatToDocx(nsAttr(child, "style", "num-format"))
|
|
895
|
+
});
|
|
896
|
+
}
|
|
839
897
|
}
|
|
898
|
+
return levels;
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Index every `text:list-style` found in the ODF automatic/named styles by
|
|
902
|
+
* name. Used by the reader to recover the original bullet-vs-number format of
|
|
903
|
+
* each list so the produced DOCX renders the correct markers.
|
|
904
|
+
*/
|
|
905
|
+
function collectOdfListStyles(roots) {
|
|
906
|
+
const out = new Map();
|
|
907
|
+
const visit = (el) => {
|
|
908
|
+
for (const child of el.children) {
|
|
909
|
+
if (child.type !== "element") {
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (getLocalName(child.name) === "list-style") {
|
|
913
|
+
const name = nsAttr(child, "style", "name");
|
|
914
|
+
if (name) {
|
|
915
|
+
out.set(name, parseOdfListStyle(child));
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
visit(child);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
for (const root of roots) {
|
|
924
|
+
visit(root);
|
|
925
|
+
}
|
|
926
|
+
return out;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Registry that assigns a stable `numId` to each distinct ODF list-style name
|
|
930
|
+
* encountered while parsing the body, and produces the matching docx
|
|
931
|
+
* `abstractNumberings` / `numberingInstances` on demand.
|
|
932
|
+
*
|
|
933
|
+
* A registry instance is threaded through `parseList` → `parseParagraph` so
|
|
934
|
+
* list paragraphs reference the same `numId` that ultimately resolves to the
|
|
935
|
+
* synthesized numbering definition. Lists without an explicit style name (or
|
|
936
|
+
* referencing an unknown style) fall back to a default bulleted definition.
|
|
937
|
+
*/
|
|
938
|
+
class OdtNumberingRegistry {
|
|
939
|
+
constructor(listStyles) {
|
|
940
|
+
this.numIdByStyle = new Map();
|
|
941
|
+
// The format chosen at each level for a given numId (level 0..8).
|
|
942
|
+
this.levelsByNumId = new Map();
|
|
943
|
+
this.nextNumId = 1;
|
|
944
|
+
this.listStyles = listStyles;
|
|
945
|
+
}
|
|
946
|
+
/** Resolve (and lazily register) the numId for a given list-style name. */
|
|
947
|
+
numIdFor(styleName) {
|
|
948
|
+
const key = styleName ?? "";
|
|
949
|
+
const existing = this.numIdByStyle.get(key);
|
|
950
|
+
if (existing !== undefined) {
|
|
951
|
+
return existing;
|
|
952
|
+
}
|
|
953
|
+
const numId = this.nextNumId++;
|
|
954
|
+
this.numIdByStyle.set(key, numId);
|
|
955
|
+
this.levelsByNumId.set(numId, this.listStyles.get(key) ?? new Map());
|
|
956
|
+
return numId;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Record the level a paragraph used for this numId so the synthesized
|
|
960
|
+
* abstract numbering covers at least the deepest level actually referenced
|
|
961
|
+
* even when the ODF list-style omitted some levels.
|
|
962
|
+
*/
|
|
963
|
+
noteLevel(numId, level) {
|
|
964
|
+
let levels = this.levelsByNumId.get(numId);
|
|
965
|
+
if (!levels) {
|
|
966
|
+
levels = new Map();
|
|
967
|
+
this.levelsByNumId.set(numId, levels);
|
|
968
|
+
}
|
|
969
|
+
if (!levels.has(level)) {
|
|
970
|
+
// Unknown level: default to bullet so the marker is still visible.
|
|
971
|
+
levels.set(level, { format: "bullet", bulletChar: ODT_BULLET_CHARS[level] ?? "•" });
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
/** Whether any list paragraph was registered. */
|
|
975
|
+
get isEmpty() {
|
|
976
|
+
return this.numIdByStyle.size === 0;
|
|
977
|
+
}
|
|
978
|
+
/** Build the docx numbering definitions for every registered list. */
|
|
979
|
+
build() {
|
|
980
|
+
if (this.isEmpty) {
|
|
981
|
+
return {};
|
|
982
|
+
}
|
|
983
|
+
const abstractNumberings = [];
|
|
984
|
+
const numberingInstances = [];
|
|
985
|
+
for (const numId of this.levelsByNumId.keys()) {
|
|
986
|
+
const odfLevels = this.levelsByNumId.get(numId) ?? new Map();
|
|
987
|
+
const levels = [];
|
|
988
|
+
for (let level = 0; level < 9; level++) {
|
|
989
|
+
const info = odfLevels.get(level) ??
|
|
990
|
+
{ format: "bullet", bulletChar: ODT_BULLET_CHARS[level] ?? "•" };
|
|
991
|
+
levels.push(makeNumberingLevel(level, info));
|
|
992
|
+
}
|
|
993
|
+
// abstractNumId mirrors numId for a clean 1:1 mapping.
|
|
994
|
+
abstractNumberings.push({ abstractNumId: numId, levels });
|
|
995
|
+
numberingInstances.push({ numId, abstractNumId: numId });
|
|
996
|
+
}
|
|
997
|
+
return { abstractNumberings, numberingInstances };
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
/** Build a single docx NumberingLevel from a parsed ODF level. */
|
|
1001
|
+
function makeNumberingLevel(level, info) {
|
|
840
1002
|
const tabSuffix = "tab";
|
|
841
|
-
const
|
|
842
|
-
|
|
1003
|
+
const indent = { left: 720 * (level + 1), hanging: 360 };
|
|
1004
|
+
if (info.format === "bullet") {
|
|
1005
|
+
return {
|
|
1006
|
+
level,
|
|
1007
|
+
format: "bullet",
|
|
1008
|
+
text: info.bulletChar ?? ODT_BULLET_CHARS[level] ?? "•",
|
|
1009
|
+
start: 1,
|
|
1010
|
+
paragraphProperties: { indent },
|
|
1011
|
+
suffix: tabSuffix
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
return {
|
|
843
1015
|
level,
|
|
844
|
-
format:
|
|
845
|
-
text
|
|
1016
|
+
format: info.format,
|
|
1017
|
+
// Word level text uses %N placeholders; "%<level+1>." renders "1." etc.
|
|
1018
|
+
text: `%${level + 1}.`,
|
|
846
1019
|
start: 1,
|
|
847
|
-
paragraphProperties: {
|
|
848
|
-
indent: { left: 720 * (level + 1), hanging: 360 }
|
|
849
|
-
},
|
|
1020
|
+
paragraphProperties: { indent },
|
|
850
1021
|
suffix: tabSuffix
|
|
851
|
-
}));
|
|
852
|
-
return {
|
|
853
|
-
abstractNumberings: [{ abstractNumId: 1, levels }],
|
|
854
|
-
numberingInstances: [{ numId: 1, abstractNumId: 1 }]
|
|
855
1022
|
};
|
|
856
1023
|
}
|
|
857
|
-
|
|
1024
|
+
// =============================================================================
|
|
1025
|
+
// Writer-side list numbering helpers
|
|
1026
|
+
// =============================================================================
|
|
1027
|
+
/** Deterministic ODF `text:list-style` name for a given docx numId. */
|
|
1028
|
+
function listStyleNameForNumId(numId) {
|
|
1029
|
+
return `L${numId}`;
|
|
1030
|
+
}
|
|
1031
|
+
/** Collect every distinct numId referenced by list paragraphs in the body. */
|
|
1032
|
+
function collectListNumIds(blocks, out) {
|
|
858
1033
|
for (const block of blocks) {
|
|
859
1034
|
if (block.type === "paragraph") {
|
|
860
|
-
|
|
861
|
-
|
|
1035
|
+
const numId = block.properties?.numbering?.numId;
|
|
1036
|
+
if (typeof numId === "number") {
|
|
1037
|
+
out.add(numId);
|
|
862
1038
|
}
|
|
863
1039
|
}
|
|
864
1040
|
else if (block.type === "table") {
|
|
865
1041
|
for (const row of block.rows) {
|
|
866
1042
|
for (const cell of row.cells) {
|
|
867
|
-
|
|
868
|
-
return true;
|
|
869
|
-
}
|
|
1043
|
+
collectListNumIds(cell.content, out);
|
|
870
1044
|
}
|
|
871
1045
|
}
|
|
872
1046
|
}
|
|
873
1047
|
}
|
|
874
|
-
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Resolve the per-level NumberFormat for a numId from the document's numbering
|
|
1051
|
+
* definitions. Follows numId → numberingInstance → abstractNumbering → levels.
|
|
1052
|
+
* Levels missing a definition default to bullet so a marker is still emitted.
|
|
1053
|
+
*/
|
|
1054
|
+
function resolveNumIdLevelFormats(doc, numId) {
|
|
1055
|
+
const formats = new Array(9).fill("bullet");
|
|
1056
|
+
const inst = doc.numberingInstances?.find(n => n.numId === numId);
|
|
1057
|
+
const abstractId = inst?.abstractNumId;
|
|
1058
|
+
const abstract = abstractId !== undefined
|
|
1059
|
+
? doc.abstractNumberings?.find(a => a.abstractNumId === abstractId)
|
|
1060
|
+
: undefined;
|
|
1061
|
+
if (abstract) {
|
|
1062
|
+
for (const lvl of abstract.levels) {
|
|
1063
|
+
if (lvl.level >= 0 && lvl.level < 9) {
|
|
1064
|
+
formats[lvl.level] = lvl.format;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
return formats;
|
|
875
1069
|
}
|
|
876
1070
|
// =============================================================================
|
|
877
1071
|
// readOdt — Main Entry Point
|
|
@@ -920,10 +1114,12 @@ async function readOdt(buffer) {
|
|
|
920
1114
|
// Collect all styles (from both content.xml and styles.xml)
|
|
921
1115
|
const allStyles = new Map();
|
|
922
1116
|
let pageLayoutProps;
|
|
1117
|
+
let stylesRootEl;
|
|
923
1118
|
// Parse styles from styles.xml
|
|
924
1119
|
if (stylesXml) {
|
|
925
1120
|
const stylesDoc = (0, dom_1.parseXml)(stylesXml);
|
|
926
1121
|
const stylesRoot = stylesDoc.root;
|
|
1122
|
+
stylesRootEl = stylesRoot;
|
|
927
1123
|
// Named styles (office:styles)
|
|
928
1124
|
const officeStylesEl = findNsChild(stylesRoot, "office", "styles");
|
|
929
1125
|
if (officeStylesEl) {
|
|
@@ -1003,7 +1199,16 @@ async function readOdt(buffer) {
|
|
|
1003
1199
|
if (!textEl) {
|
|
1004
1200
|
throw new errors_1.DocxParseError("Invalid ODT: missing office:text element");
|
|
1005
1201
|
}
|
|
1006
|
-
|
|
1202
|
+
// Index every `text:list-style` (from styles.xml and content.xml) so the
|
|
1203
|
+
// body parser can recover each list's bullet-vs-number format. The registry
|
|
1204
|
+
// assigns a stable numId per distinct list style and produces the matching
|
|
1205
|
+
// numbering definitions below.
|
|
1206
|
+
const listStyleRoots = [contentDoc.root];
|
|
1207
|
+
if (stylesRootEl) {
|
|
1208
|
+
listStyleRoots.push(stylesRootEl);
|
|
1209
|
+
}
|
|
1210
|
+
const registry = new OdtNumberingRegistry(collectOdfListStyles(listStyleRoots));
|
|
1211
|
+
const body = parseDocumentBody(textEl, allStyles, registry);
|
|
1007
1212
|
// Convert styles to StyleDef[]
|
|
1008
1213
|
const styleDefs = convertStylesToStyleDefs(allStyles);
|
|
1009
1214
|
// Parse section properties from page layout
|
|
@@ -1059,7 +1264,7 @@ async function readOdt(buffer) {
|
|
|
1059
1264
|
...(styleDefs.length > 0 ? { styles: styleDefs } : {}),
|
|
1060
1265
|
...(coreProperties ? { coreProperties } : {}),
|
|
1061
1266
|
...(images.length > 0 ? { images } : {}),
|
|
1062
|
-
...
|
|
1267
|
+
...registry.build()
|
|
1063
1268
|
};
|
|
1064
1269
|
return doc;
|
|
1065
1270
|
}
|
|
@@ -1288,9 +1493,7 @@ function generateContentXml(doc, imagePaths, imageMap) {
|
|
|
1288
1493
|
const bodyWriter = new writer_1.XmlWriter();
|
|
1289
1494
|
bodyWriter.openNode("office:body");
|
|
1290
1495
|
bodyWriter.openNode("office:text");
|
|
1291
|
-
|
|
1292
|
-
writeBodyContent(bodyWriter, block, doc, imagePaths, ctx);
|
|
1293
|
-
}
|
|
1496
|
+
writeBlocks(bodyWriter, doc.body, doc, imagePaths, ctx);
|
|
1294
1497
|
bodyWriter.closeNode(); // office:text
|
|
1295
1498
|
bodyWriter.closeNode(); // office:body
|
|
1296
1499
|
const bodyXml = bodyWriter.xml;
|
|
@@ -1337,6 +1540,54 @@ function writeAutoStyles(w, doc) {
|
|
|
1337
1540
|
writeStyleDef(w, styleDef);
|
|
1338
1541
|
}
|
|
1339
1542
|
}
|
|
1543
|
+
// Emit one `text:list-style` per distinct numId referenced by the body so
|
|
1544
|
+
// bullet vs numbered (and multi-level mixes) round-trip with the correct
|
|
1545
|
+
// markers. Numbers are sorted for deterministic output.
|
|
1546
|
+
const numIds = new Set();
|
|
1547
|
+
collectListNumIds(doc.body, numIds);
|
|
1548
|
+
for (const numId of [...numIds].sort((a, b) => a - b)) {
|
|
1549
|
+
writeListStyleDef(w, numId, resolveNumIdLevelFormats(doc, numId));
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Write the automatic `text:list-style` for a numId.
|
|
1554
|
+
*
|
|
1555
|
+
* Each of the nine ODF list levels is emitted as either a
|
|
1556
|
+
* `text:list-level-style-bullet` or `text:list-level-style-number` based on
|
|
1557
|
+
* the document's per-level NumberFormat, giving compliant readers (Word,
|
|
1558
|
+
* LibreOffice) the right markers and letting the reader recover the format on
|
|
1559
|
+
* the way back in.
|
|
1560
|
+
*/
|
|
1561
|
+
function writeListStyleDef(w, numId, formats) {
|
|
1562
|
+
w.openNode("text:list-style", { "style:name": listStyleNameForNumId(numId) });
|
|
1563
|
+
for (let idx = 0; idx < 9; idx++) {
|
|
1564
|
+
const level = idx + 1; // ODF list levels are 1-based.
|
|
1565
|
+
const format = formats[idx] ?? "bullet";
|
|
1566
|
+
if (format === "bullet") {
|
|
1567
|
+
w.openNode("text:list-level-style-bullet", {
|
|
1568
|
+
"text:level": String(level),
|
|
1569
|
+
"text:bullet-char": ODT_BULLET_CHARS[idx] ?? "•"
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
else {
|
|
1573
|
+
w.openNode("text:list-level-style-number", {
|
|
1574
|
+
"text:level": String(level),
|
|
1575
|
+
"style:num-format": numberFormatToOdf(format),
|
|
1576
|
+
"style:num-suffix": "."
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
w.openNode("style:list-level-properties", {
|
|
1580
|
+
"text:list-level-position-and-space-mode": "label-alignment"
|
|
1581
|
+
});
|
|
1582
|
+
w.leafNode("style:list-level-label-alignment", {
|
|
1583
|
+
"text:label-followed-by": "listtab",
|
|
1584
|
+
"fo:text-indent": "-0.25in",
|
|
1585
|
+
"fo:margin-left": `${0.25 * level}in`
|
|
1586
|
+
});
|
|
1587
|
+
w.closeNode(); // style:list-level-properties
|
|
1588
|
+
w.closeNode(); // text:list-level-style-{bullet,number}
|
|
1589
|
+
}
|
|
1590
|
+
w.closeNode(); // text:list-style
|
|
1340
1591
|
}
|
|
1341
1592
|
/** Write a single StyleDef as an ODF style. */
|
|
1342
1593
|
function writeStyleDef(w, def) {
|
|
@@ -1476,6 +1727,113 @@ function alignmentToOdf(alignment) {
|
|
|
1476
1727
|
return "start";
|
|
1477
1728
|
}
|
|
1478
1729
|
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Determine whether a body block is a list paragraph (carries numbering).
|
|
1732
|
+
*
|
|
1733
|
+
* The ODT reader maps list-item paragraphs back to `numbering.numId`, so the
|
|
1734
|
+
* writer must round-trip them as `text:list` structures rather than bare
|
|
1735
|
+
* `text:p` (which would silently drop the list semantics).
|
|
1736
|
+
*/
|
|
1737
|
+
function isListParagraph(block) {
|
|
1738
|
+
return block.type === "paragraph" && block.properties?.numbering !== undefined;
|
|
1739
|
+
}
|
|
1740
|
+
/** numId of a list paragraph (falls back to 1 if somehow absent). */
|
|
1741
|
+
function paragraphNumId(block) {
|
|
1742
|
+
return block.type === "paragraph" ? (block.properties?.numbering?.numId ?? 1) : 1;
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Write a sequence of block-level content elements, grouping runs of
|
|
1746
|
+
* consecutive list paragraphs that share a numId into nested `text:list`
|
|
1747
|
+
* structures.
|
|
1748
|
+
*
|
|
1749
|
+
* The ODF list model nests one `text:list` per indentation level, so a
|
|
1750
|
+
* paragraph at `numbering.level === N` is wrapped in `N + 1` nested lists.
|
|
1751
|
+
* Tracking an explicit level stack lets a single run contain mixed levels
|
|
1752
|
+
* (e.g. a sub-bullet between two top-level bullets) and still produce valid,
|
|
1753
|
+
* round-trippable markup that matches what `parseList` expects. Breaking on
|
|
1754
|
+
* numId changes keeps each `text:list` pointed at a single list-style.
|
|
1755
|
+
*/
|
|
1756
|
+
function writeBlocks(w, blocks, doc, imagePaths, ctx) {
|
|
1757
|
+
let i = 0;
|
|
1758
|
+
while (i < blocks.length) {
|
|
1759
|
+
const block = blocks[i];
|
|
1760
|
+
if (isListParagraph(block)) {
|
|
1761
|
+
// Consume the maximal run of consecutive list paragraphs sharing numId.
|
|
1762
|
+
const numId = paragraphNumId(block);
|
|
1763
|
+
let j = i;
|
|
1764
|
+
while (j < blocks.length &&
|
|
1765
|
+
isListParagraph(blocks[j]) &&
|
|
1766
|
+
paragraphNumId(blocks[j]) === numId) {
|
|
1767
|
+
j++;
|
|
1768
|
+
}
|
|
1769
|
+
writeListGroup(w, blocks.slice(i, j), numId, doc, imagePaths, ctx);
|
|
1770
|
+
i = j;
|
|
1771
|
+
}
|
|
1772
|
+
else {
|
|
1773
|
+
writeBodyContent(w, block, doc, imagePaths, ctx);
|
|
1774
|
+
i++;
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Emit a run of list paragraphs (all sharing `numId`) as nested `text:list`
|
|
1780
|
+
* elements.
|
|
1781
|
+
*
|
|
1782
|
+
* ODF nests one `text:list` per indentation level, and every nested list lives
|
|
1783
|
+
* inside a `text:list-item` of its parent. We therefore track, for each open
|
|
1784
|
+
* list level, whether a `text:list-item` is currently open at that level
|
|
1785
|
+
* (`itemOpen[d]`). Raising the level opens wrapper items plus nested lists;
|
|
1786
|
+
* lowering it closes them in the correct order so the markup stays balanced
|
|
1787
|
+
* and matches what `parseList` expects on the way back in.
|
|
1788
|
+
*/
|
|
1789
|
+
function writeListGroup(w, paras, numId, doc, imagePaths, ctx) {
|
|
1790
|
+
const styleName = listStyleNameForNumId(numId);
|
|
1791
|
+
// `itemOpen[d]` is true when a `text:list-item` is open inside the list at
|
|
1792
|
+
// depth `d` (0-based). Its length equals the number of open `text:list`s.
|
|
1793
|
+
const itemOpen = [];
|
|
1794
|
+
const openList = () => {
|
|
1795
|
+
w.openNode("text:list", { "text:style-name": styleName });
|
|
1796
|
+
itemOpen.push(false);
|
|
1797
|
+
};
|
|
1798
|
+
const closeList = () => {
|
|
1799
|
+
const depth = itemOpen.length - 1;
|
|
1800
|
+
if (itemOpen[depth]) {
|
|
1801
|
+
w.closeNode(); // text:list-item
|
|
1802
|
+
}
|
|
1803
|
+
itemOpen.pop();
|
|
1804
|
+
w.closeNode(); // text:list
|
|
1805
|
+
};
|
|
1806
|
+
for (const para of paras) {
|
|
1807
|
+
const level = Math.max(0, para.properties?.numbering?.level ?? 0);
|
|
1808
|
+
const wantLists = level + 1;
|
|
1809
|
+
// Close lists until we are at or below the desired depth.
|
|
1810
|
+
while (itemOpen.length > wantLists) {
|
|
1811
|
+
closeList();
|
|
1812
|
+
}
|
|
1813
|
+
// Open nested lists until we reach the desired depth. Each nested list
|
|
1814
|
+
// must sit inside an open `text:list-item` of its parent list.
|
|
1815
|
+
while (itemOpen.length < wantLists) {
|
|
1816
|
+
const depth = itemOpen.length - 1;
|
|
1817
|
+
if (depth >= 0 && !itemOpen[depth]) {
|
|
1818
|
+
w.openNode("text:list-item");
|
|
1819
|
+
itemOpen[depth] = true;
|
|
1820
|
+
}
|
|
1821
|
+
openList();
|
|
1822
|
+
}
|
|
1823
|
+
// At the target depth start a fresh list-item for this paragraph.
|
|
1824
|
+
const depth = itemOpen.length - 1;
|
|
1825
|
+
if (itemOpen[depth]) {
|
|
1826
|
+
w.closeNode(); // previous text:list-item at this depth
|
|
1827
|
+
}
|
|
1828
|
+
w.openNode("text:list-item");
|
|
1829
|
+
itemOpen[depth] = true;
|
|
1830
|
+
writeParagraph(w, para, doc, imagePaths, ctx);
|
|
1831
|
+
}
|
|
1832
|
+
// Unwind any lists still open.
|
|
1833
|
+
while (itemOpen.length > 0) {
|
|
1834
|
+
closeList();
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1479
1837
|
/** Write a block-level content element to the XML writer. */
|
|
1480
1838
|
function writeBodyContent(w, block, doc, imagePaths, ctx) {
|
|
1481
1839
|
switch (block.type) {
|
|
@@ -1742,14 +2100,7 @@ function writeTableCell(w, cell, doc, imagePaths, ctx) {
|
|
|
1742
2100
|
return;
|
|
1743
2101
|
}
|
|
1744
2102
|
w.openNode("table:table-cell", attrs);
|
|
1745
|
-
|
|
1746
|
-
if (content.type === "paragraph") {
|
|
1747
|
-
writeParagraph(w, content, doc, imagePaths, ctx);
|
|
1748
|
-
}
|
|
1749
|
-
else if (content.type === "table") {
|
|
1750
|
-
writeTable(w, content, doc, imagePaths, ctx);
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
2103
|
+
writeBlocks(w, cell.content, doc, imagePaths, ctx);
|
|
1753
2104
|
w.closeNode();
|
|
1754
2105
|
}
|
|
1755
2106
|
// =============================================================================
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.htmlToDocxBody = exports.renderToHtml = void 0;
|
|
15
|
+
exports.htmlToDocx = exports.htmlToDocxBody = exports.renderToHtml = void 0;
|
|
16
16
|
var html_1 = require("./convert/html/html");
|
|
17
17
|
Object.defineProperty(exports, "renderToHtml", { enumerable: true, get: function () { return html_1.renderToHtml; } });
|
|
18
18
|
Object.defineProperty(exports, "htmlToDocxBody", { enumerable: true, get: function () { return html_1.htmlToDocxBody; } });
|
|
19
|
+
Object.defineProperty(exports, "htmlToDocx", { enumerable: true, get: function () { return html_1.htmlToDocx; } });
|
|
@@ -24,9 +24,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
24
24
|
exports.totalPagesField = exports.pageNumberField = exports.field = exports.softHyphen = exports.noBreakHyphen = exports.carriageReturn = exports.ruby = exports.positionalTab = exports.tab = exports.columnBreak = exports.lineBreak = exports.pageBreak = exports.strikethrough = exports.underline = exports.italic = exports.bold = exports.text = exports.Document = exports.tablePctToPercent = exports.percentToTablePct = exports.spacingToLineMultiplier = exports.lineMultiplierToSpacing = exports.eighthPointToPt = exports.ptToEighthPoint = exports.halfPointToPt = exports.ptToHalfPoint = exports.emuToPx = exports.pxToEmu = exports.ptToEmu = exports.emuToCm = exports.cmToEmu = exports.emuToInches = exports.inchesToEmu = exports.mmToTwips = exports.twipsToPt = exports.ptToTwips = exports.twipsToCm = exports.cmToTwips = exports.twipsToInches = exports.inchesToTwips = exports.isDocxError = exports.DocxLimitExceededError = exports.DocxDecryptionError = exports.DocxEncryptedError = exports.DocxUnsupportedFeatureError = exports.DocxInvalidStructureError = exports.DocxMissingPartError = exports.DocxWriteError = exports.DocxParseError = exports.DocxError = void 0;
|
|
25
25
|
exports.mathBar = exports.mathAccent = exports.mathMatrix = exports.mathLimit = exports.mathFunction = exports.mathNary = exports.mathDelimiter = exports.mathBorderBox = exports.mathGroupChar = exports.mathPhantom = exports.mathPreSubSuperScript = exports.mathSubSuperScript = exports.mathSubScript = exports.mathSuperScript = exports.mathProduct = exports.mathIntegral = exports.mathSum = exports.mathRoot = exports.mathSqrt = exports.mathFraction = exports.mathRun = exports.mathBlock = exports.checkBox = exports.formDropdownField = exports.formCheckboxField = exports.formTextField = exports.includePictureField = exports.includeTextField = exports.ifField = exports.indexField = exports.indexEntryField = exports.tcField = exports.tocField = exports.quoteField = exports.hyperlinkField = exports.noteRefField = exports.pageRefField = exports.refField = exports.styleRefField = exports.fileSizeField = exports.fileNameField = exports.keywordsField = exports.subjectField = exports.titleField = exports.authorField = exports.timeField = exports.sequenceField = exports.dateField = exports.sectionField = exports.sectionPagesField = void 0;
|
|
26
26
|
exports.listRevisions = exports.rejectAllRevisions = exports.acceptAllRevisions = exports.splitDocument = exports.mergeDocuments = exports.mailMerge = exports.replaceText = exports.searchText = exports.extractText = exports.tableCount = exports.listSections = exports.listHyperlinks = exports.listTables = exports.listImages = exports.findComment = exports.findBookmark = exports.getHeadings = exports.countWords = exports.paragraphCount = exports.resolveThemeColor = exports.simpleTable = exports.table = exports.row = exports.cell = exports.gridBorders = exports.border = exports.moveToRangeEnd = exports.moveToRangeStart = exports.moveFromRangeEnd = exports.moveFromRangeStart = exports.movedToRun = exports.movedFromRun = exports.deletedRun = exports.insertedRun = exports.commentReference = exports.commentRangeEnd = exports.commentRangeStart = exports.bookmarkEnd = exports.bookmarkStart = exports.hyperlink = exports.heading = exports.textParagraph = exports.paragraph = exports.structuredDocumentTag = exports.chart = exports.drawingShape = exports.floatingImage = exports.symbol = exports.mathEquationArray = exports.mathBox = void 0;
|
|
27
|
-
exports.
|
|
28
|
-
exports.
|
|
29
|
-
exports.docxToSemantic = exports.createConversionContext = exports.collectTables = exports.collectRuns = exports.collectParagraphs = exports.walkBlocks = exports.walkDocument = exports.mapDocument = exports.createIdGenerators = exports.createRenderContext = exports.resolveSecurityPolicy = exports.STRICT_SECURITY_POLICY = exports.DEFAULT_SECURITY_POLICY = exports.encryptDocx = exports.bindChartData = void 0;
|
|
27
|
+
exports.getQuickParts = exports.getAutoTextEntries = exports.listBuildingBlocks = exports.findBuildingBlock = exports.createGlossaryDocument = exports.createBuildingBlock = exports.addOleObject = exports.createOleEmbedding = exports.getOleObjectData = exports.hasOleObjects = exports.extractOleObjects = exports.subsetFont = exports.addEmbeddedFonts = exports.embedFontFamily = exports.embedFont = exports.validateDocument = exports.createDocxStream = exports.StreamingDocxWriter = exports.toFlatOpc = exports.isFlatOpc = exports.parseFlatOpc = exports.TemplateError = exports.isTemplateChart = exports.listTemplateTags = exports.fillTemplateEnhanced = exports.fillTemplate = exports.diffDocuments = exports.toFlatOpcFromDoc = exports.fillTemplateFromBuffer = exports.patchTemplate = exports.compileTemplate = exports.patchDocument = exports.toBase64 = exports.toBuffer = exports.readDocx = exports.packageDocx = exports.readDocxPart = exports.listDocxParts = exports.editDocxIncremental = exports.fillFormFields = exports.extractFormFields = exports.resolveDataBindings = exports.setCompatibilityMode = exports.getCompatibilityMode = exports.resolveTableStyle = exports.resolveNumberingLevel = exports.resolveRunStyle = exports.resolveStyle = exports.rejectRevision = exports.acceptRevision = void 0;
|
|
28
|
+
exports.CompositeDataSource = exports.CsvDataSource = exports.XmlDataSource = exports.JsonDataSource = exports.renderPageFromLayout = exports.renderDocumentToSvg = exports.renderPageToSvg = exports.writeOdt = exports.readOdt = exports.getUsedFormats = exports.countByFormat = exports.searchByFormat = exports.ENGLISH_US_PATTERNS = exports.hyphenateText = exports.hyphenateWord = exports.createHyphenator = exports.detectDirection = exports.detectScript = exports.shapeText = exports.createStar = exports.createCallout = exports.createFlowchartShape = exports.createArrow = exports.createLine = exports.createEllipse = exports.createRoundRect = exports.createRect = exports.createShape = exports.mathMLToOmml = exports.ommlToMathML = exports.updateTableOfContents = exports.updateFields = exports.layoutDocumentFull = exports.layoutDocument = exports.listVbaParts = exports.removeVbaProject = exports.addVbaProject = exports.getVbaProjectData = exports.getVbaProjectInfo = exports.hasVbaProject = exports.DEFAULT_STYLE_MAP = exports.matchStyleMap = exports.mergeStyleMaps = exports.createStyleMap = exports.parseStyleMap = exports.verifyProtectionPassword = exports.getProtectionState = exports.isDocumentProtected = exports.unprotectDocument = exports.protectDocument = void 0;
|
|
29
|
+
exports.docxToSemantic = exports.createConversionContext = exports.collectTables = exports.collectRuns = exports.collectParagraphs = exports.walkBlocks = exports.walkDocument = exports.mapDocument = exports.createIdGenerators = exports.createRenderContext = exports.resolveSecurityPolicy = exports.STRICT_SECURITY_POLICY = exports.DEFAULT_SECURITY_POLICY = exports.encryptDocx = exports.bindChartData = exports.fillTemplateFromSource = void 0;
|
|
30
30
|
// --- Stable API ---
|
|
31
31
|
/** @stability stable */
|
|
32
32
|
var errors_1 = require("./errors");
|
|
@@ -292,6 +292,7 @@ Object.defineProperty(exports, "extractOleObjects", { enumerable: true, get: fun
|
|
|
292
292
|
Object.defineProperty(exports, "hasOleObjects", { enumerable: true, get: function () { return ole_objects_1.hasOleObjects; } });
|
|
293
293
|
Object.defineProperty(exports, "getOleObjectData", { enumerable: true, get: function () { return ole_objects_1.getOleObjectData; } });
|
|
294
294
|
Object.defineProperty(exports, "createOleEmbedding", { enumerable: true, get: function () { return ole_objects_1.createOleEmbedding; } });
|
|
295
|
+
Object.defineProperty(exports, "addOleObject", { enumerable: true, get: function () { return ole_objects_1.addOleObject; } });
|
|
295
296
|
/** @stability experimental */
|
|
296
297
|
var glossary_1 = require("./advanced/glossary");
|
|
297
298
|
Object.defineProperty(exports, "createBuildingBlock", { enumerable: true, get: function () { return glossary_1.createBuildingBlock; } });
|