diff --git a/src/file/numbering/abstract-numbering.spec.ts b/src/file/numbering/abstract-numbering.spec.ts index 45d7f25f0e..6552775cd5 100644 --- a/src/file/numbering/abstract-numbering.spec.ts +++ b/src/file/numbering/abstract-numbering.spec.ts @@ -8,7 +8,7 @@ import { UnderlineType } from "../paragraph/run/underline"; import { ShadingType } from "../table"; import { AbstractNumbering } from "./abstract-numbering"; -describe.only("AbstractNumbering", () => { +describe("AbstractNumbering", () => { it("stores its ID at its .id property", () => { const abstractNumbering = new AbstractNumbering(5, { levels: [], @@ -29,11 +29,11 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); - expect(tree["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } }); - expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "end" } } }); - expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } }); - expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "end" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } }); }); it("uses 'start' as the default alignment", () => { @@ -47,11 +47,11 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); - expect(tree["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } }); - expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "start" } } }); - expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } }); - expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:start": { _attr: { "w:val": 1 } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "start" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } }); + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } }); }); describe("formatting methods: paragraph properties", () => { @@ -71,7 +71,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }], }); }); @@ -92,7 +92,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:spacing": { _attr: { "w:before": 50, "w:after": 150 } } }], }); }); @@ -113,7 +113,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }], }); }); @@ -134,7 +134,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }], }); }); @@ -155,7 +155,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }], }); }); @@ -176,7 +176,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }], }); }); @@ -197,7 +197,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [ { "w:pBdr": [ @@ -233,7 +233,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [ { "w:tabs": [{ "w:tab": { _attr: { "w:val": "left", "w:pos": 1200 } } }], @@ -258,7 +258,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [ { "w:tabs": [{ "w:tab": { _attr: { "w:val": "right", "w:pos": 9026 } } }], @@ -283,7 +283,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }], }); }); @@ -304,7 +304,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }], }); }); @@ -327,7 +327,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }], }); }); @@ -348,7 +348,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:smallCaps": { _attr: { "w:val": true } } }], }); }); @@ -369,7 +369,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:caps": { _attr: { "w:val": true } } }], }); }); @@ -391,7 +391,7 @@ describe.only("AbstractNumbering", () => { }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:strike": { _attr: { "w:val": true } } }], }); }); @@ -412,7 +412,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:dstrike": { _attr: { "w:val": true } } }], }); }); @@ -433,7 +433,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "subscript" } } }], }); }); @@ -454,7 +454,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "superscript" } } }], }); }); @@ -475,7 +475,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [ { "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } }, ], @@ -498,7 +498,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:b": { _attr: { "w:val": true } } }], }); }); @@ -519,7 +519,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:i": { _attr: { "w:val": true } } }], }); }); @@ -540,7 +540,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:highlight": { _attr: { "w:val": "005599" } } }], }); }); @@ -565,7 +565,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:shd": { _attr: { "w:val": "pct10", "w:fill": "00FFFF", "w:color": "FF0000" } } }], }); }); @@ -587,7 +587,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }], }); }); @@ -610,7 +610,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }], }); }); @@ -634,7 +634,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }], }); }); @@ -656,7 +656,7 @@ describe.only("AbstractNumbering", () => { ], }); const tree = new Formatter().format(abstractNumbering); - expect(tree["w:lvl"]).to.include({ + expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }], }); }); diff --git a/src/file/numbering/concrete-numbering.spec.ts b/src/file/numbering/concrete-numbering.spec.ts index dd15fb5431..42ccc87f2b 100644 --- a/src/file/numbering/concrete-numbering.spec.ts +++ b/src/file/numbering/concrete-numbering.spec.ts @@ -7,7 +7,7 @@ import { ConcreteNumbering } from "./num"; describe("ConcreteNumbering", () => { describe("#overrideLevel", () => { - let concreteNumbering; + let concreteNumbering: ConcreteNumbering; beforeEach(() => { concreteNumbering = new ConcreteNumbering(0, 1); }); @@ -17,18 +17,13 @@ describe("ConcreteNumbering", () => { const tree = new Formatter().format(concreteNumbering); expect(tree["w:num"]).to.include({ "w:lvlOverride": [ + { _attr: { "w:ilvl": 3 } }, { - _attr: { - "w:ilvl": 3, - }, - }, - { - "w:lvl": { - _attr: { - "w:ilvl": 3, - "w15:tentative": 1, - }, - }, + "w:lvl": [ + { _attr: { "w:ilvl": 3, "w15:tentative": 1 } }, + { "w:start": { _attr: { "w:val": 1 } } }, + { "w:lvlJc": { _attr: { "w:val": "start" } } }, + ], }, ], }); @@ -52,12 +47,11 @@ describe("ConcreteNumbering", () => { }, }, { - "w:lvl": { - _attr: { - "w:ilvl": 1, - "w15:tentative": 1, - }, - }, + "w:lvl": [ + { _attr: { "w:ilvl": 1, "w15:tentative": 1 } }, + { "w:start": { _attr: { "w:val": 1 } } }, + { "w:lvlJc": { _attr: { "w:val": "start" } } }, + ], }, ], }); @@ -67,11 +61,16 @@ describe("ConcreteNumbering", () => { const ol = concreteNumbering.overrideLevel(1); expect(ol.Level).to.be.instanceof(LevelForOverride); const tree = new Formatter().format(concreteNumbering); + expect(tree["w:num"]).to.include({ "w:lvlOverride": [ { _attr: { "w:ilvl": 1 } }, { - "w:lvl": { _attr: { "w15:tentative": 1, "w:ilvl": 1 } }, + "w:lvl": [ + { _attr: { "w:ilvl": 1, "w15:tentative": 1 } }, + { "w:start": { _attr: { "w:val": 1 } } }, + { "w:lvlJc": { _attr: { "w:val": "start" } } }, + ], }, ], }); diff --git a/src/file/numbering/level.ts b/src/file/numbering/level.ts index b9f66a89c0..cbef58dfc0 100644 --- a/src/file/numbering/level.ts +++ b/src/file/numbering/level.ts @@ -79,8 +79,8 @@ export enum LevelSuffix { export interface ILevelsOptions { readonly level: number; - readonly format: string; - readonly text: string; + readonly format?: string; + readonly text?: string; readonly alignment?: AlignmentType; readonly start?: number; readonly suffix?: LevelSuffix; @@ -115,10 +115,16 @@ export class LevelBase extends XmlComponent { ); this.root.push(new Start(start)); - this.root.push(new NumberFormat(format)); - this.root.push(new LevelText(text)); this.root.push(new LevelJc(alignment)); + if (format) { + this.root.push(new NumberFormat(format)); + } + + if (text) { + this.root.push(new LevelText(text)); + } + this.paragraphProperties = new ParagraphProperties({}); this.runProperties = new RunProperties(); diff --git a/src/file/numbering/num.ts b/src/file/numbering/num.ts index c19c81a39b..dac54fe668 100644 --- a/src/file/numbering/num.ts +++ b/src/file/numbering/num.ts @@ -55,7 +55,9 @@ export class LevelOverride extends XmlComponent { this.root.push(new StartOverride(start)); } - this.lvl = new LevelForOverride(this.levelNum); + this.lvl = new LevelForOverride({ + level: this.levelNum, + }); this.root.push(this.lvl); } diff --git a/src/file/paragraph/formatting/unordered-list.ts b/src/file/paragraph/formatting/unordered-list.ts index 0b6c4daae0..f7650fc844 100644 --- a/src/file/paragraph/formatting/unordered-list.ts +++ b/src/file/paragraph/formatting/unordered-list.ts @@ -1,7 +1,7 @@ import { Attributes, XmlComponent } from "file/xml-components"; export class NumberProperties extends XmlComponent { - constructor(numberId: number, indentLevel: number) { + constructor(numberId: number | string, indentLevel: number) { super("w:numPr"); this.root.push(new IndentLevel(indentLevel)); this.root.push(new NumberId(numberId)); @@ -20,11 +20,11 @@ class IndentLevel extends XmlComponent { } class NumberId extends XmlComponent { - constructor(id: number) { + constructor(id: number | string) { super("w:numId"); this.root.push( new Attributes({ - val: id, + val: typeof id === "string" ? `__${id}__` : id, }), ); } diff --git a/src/file/paragraph/paragraph.spec.ts b/src/file/paragraph/paragraph.spec.ts index d4c7fc81e9..99c8efb0c0 100644 --- a/src/file/paragraph/paragraph.spec.ts +++ b/src/file/paragraph/paragraph.spec.ts @@ -3,7 +3,6 @@ import { assert, expect } from "chai"; import { Formatter } from "export/formatter"; import { EMPTY_OBJECT } from "file/xml-components"; -import { Numbering } from "../numbering"; import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting"; import { Paragraph } from "./paragraph"; @@ -596,19 +595,9 @@ describe("Paragraph", () => { describe("#setNumbering", () => { it("should add list paragraph style to JSON", () => { - const numbering = new Numbering({ - levels: [ - { - level: 0, - format: "lowerLetter", - text: "%1)", - }, - ], - }); - const paragraph = new Paragraph({ numbering: { - num: letterNumbering, + reference: "test id", level: 0, }, }); @@ -627,19 +616,9 @@ describe("Paragraph", () => { }); it("it should add numbered properties", () => { - const numbering = new Numbering({ - levels: [ - { - level: 0, - format: "lowerLetter", - text: "%1)", - }, - ], - }); - const paragraph = new Paragraph({ numbering: { - num: letterNumbering, + reference: "test id", level: 0, }, }); @@ -650,10 +629,7 @@ describe("Paragraph", () => { "w:pPr": [ { "w:pStyle": { _attr: { "w:val": "ListParagraph" } } }, { - "w:numPr": [ - { "w:ilvl": { _attr: { "w:val": 0 } } }, - { "w:numId": { _attr: { "w:val": letterNumbering.id } } }, - ], + "w:numPr": [{ "w:ilvl": { _attr: { "w:val": 0 } } }, { "w:numId": { _attr: { "w:val": "__test id__" } } }], }, ], }, diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index 1a26a7c666..1defd01779 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -1,6 +1,5 @@ // http://officeopenxml.com/WPparagraph.php import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; -import { ConcreteNumbering } from "file/numbering/num"; import { XmlComponent } from "file/xml-components"; import { Alignment, AlignmentType } from "./formatting/alignment"; @@ -41,7 +40,7 @@ export interface IParagraphOptions { readonly level: number; }; readonly numbering?: { - readonly num: ConcreteNumbering; + readonly reference: string; readonly level: number; readonly custom?: boolean; }; @@ -141,7 +140,7 @@ export class Paragraph extends XmlComponent { if (!options.numbering.custom) { this.properties.push(new Style("ListParagraph")); } - this.properties.push(new NumberProperties(options.numbering.num.id, options.numbering.level)); + this.properties.push(new NumberProperties(options.numbering.reference, options.numbering.level)); } if (options.children) {