diff --git a/demo/47-math.ts b/demo/47-math.ts index 7862feac97..5cad1707de 100644 --- a/demo/47-math.ts +++ b/demo/47-math.ts @@ -1,7 +1,7 @@ // Simple example to add text to a document // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { Document, Math, MathDenominator, MathFraction, MathNumerator, MathRun, Packer, Paragraph, TextRun } from "../build"; +import { Document, Math, MathDenominator, MathFraction, MathNumerator, MathRun, MathSum, Packer, Paragraph, TextRun } from "../build"; const doc = new Document(); @@ -25,6 +25,17 @@ doc.addSection({ }), ], }), + new Paragraph({ + children: [ + new Math({ + children: [ + new MathSum({ + child: new MathRun("test"), + }), + ], + }), + ], + }), ], }); diff --git a/src/file/paragraph/math/index.ts b/src/file/paragraph/math/index.ts index 9f3b22b5fa..063678689c 100644 --- a/src/file/paragraph/math/index.ts +++ b/src/file/paragraph/math/index.ts @@ -1,3 +1,4 @@ export * from "./math"; export * from "./math-run"; export * from "./fraction"; +export * from "./n-ary"; diff --git a/src/file/paragraph/math/math-run.ts b/src/file/paragraph/math/math-run.ts index 5b9b9536c4..3b7cceb362 100644 --- a/src/file/paragraph/math/math-run.ts +++ b/src/file/paragraph/math/math-run.ts @@ -1,3 +1,4 @@ +// http://www.datypic.com/sc/ooxml/e-m_r-1.html import { XmlComponent } from "file/xml-components"; import { MathText } from "./math-text"; diff --git a/src/file/paragraph/math/math.ts b/src/file/paragraph/math/math.ts index eee6fdff65..43272ed941 100644 --- a/src/file/paragraph/math/math.ts +++ b/src/file/paragraph/math/math.ts @@ -3,9 +3,10 @@ import { XmlComponent } from "file/xml-components"; import { MathFraction } from "./fraction"; import { MathRun } from "./math-run"; +import { MathSum } from "./n-ary"; export interface IMathOptions { - readonly children: Array; + readonly children: Array; } export class Math extends XmlComponent { diff --git a/src/file/paragraph/math/n-ary/index.ts b/src/file/paragraph/math/n-ary/index.ts new file mode 100644 index 0000000000..6929544152 --- /dev/null +++ b/src/file/paragraph/math/n-ary/index.ts @@ -0,0 +1,7 @@ +export * from "./math-accent-character"; +export * from "./math-base"; +export * from "./math-limit-location"; +export * from "./math-naray-properties"; +export * from "./math-sub-script"; +export * from "./math-sum"; +export * from "./math-super-script"; diff --git a/src/file/paragraph/math/n-ary/math-accent-character.spec.ts b/src/file/paragraph/math/n-ary/math-accent-character.spec.ts new file mode 100644 index 0000000000..b414f4c744 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-accent-character.spec.ts @@ -0,0 +1,22 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathAccentCharacter } from "./math-accent-character"; + +describe("MathAccentCharacter", () => { + describe("#constructor()", () => { + it("should create a MathAccentCharacter with correct root key", () => { + const mathAccentCharacter = new MathAccentCharacter("∑"); + + const tree = new Formatter().format(mathAccentCharacter); + expect(tree).to.deep.equal({ + "m:chr": { + _attr: { + "m:val": "∑", + }, + }, + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-accent-character.ts b/src/file/paragraph/math/n-ary/math-accent-character.ts new file mode 100644 index 0000000000..3a5a10d7d2 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-accent-character.ts @@ -0,0 +1,14 @@ +// http://www.datypic.com/sc/ooxml/e-m_chr-1.html +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +class MathAccentCharacterAttributes extends XmlAttributeComponent<{ readonly accent: string }> { + protected readonly xmlKeys = { accent: "m:val" }; +} + +export class MathAccentCharacter extends XmlComponent { + constructor(readonly accent: string) { + super("m:chr"); + + this.root.push(new MathAccentCharacterAttributes({ accent })); + } +} diff --git a/src/file/paragraph/math/n-ary/math-base.spec.ts b/src/file/paragraph/math/n-ary/math-base.spec.ts new file mode 100644 index 0000000000..012147c4d9 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-base.spec.ts @@ -0,0 +1,27 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathRun } from "../math-run"; +import { MathBase } from "./math-base"; + +describe("MathBase", () => { + describe("#constructor()", () => { + it("should create a MathBase with correct root key", () => { + const mathBase = new MathBase(new MathRun("2+2")); + + const tree = new Formatter().format(mathBase); + expect(tree).to.deep.equal({ + "m:e": [ + { + "m:r": [ + { + "m:t": ["2+2"], + }, + ], + }, + ], + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-base.ts b/src/file/paragraph/math/n-ary/math-base.ts new file mode 100644 index 0000000000..e75231cdb2 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-base.ts @@ -0,0 +1,12 @@ +// http://www.datypic.com/sc/ooxml/e-m_e-1.html +import { XmlComponent } from "file/xml-components"; + +import { MathRun } from "../math-run"; + +export class MathBase extends XmlComponent { + constructor(readonly run: MathRun) { + super("m:e"); + + this.root.push(run); + } +} diff --git a/src/file/paragraph/math/n-ary/math-limit-location.spec.ts b/src/file/paragraph/math/n-ary/math-limit-location.spec.ts new file mode 100644 index 0000000000..426f3d0198 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-limit-location.spec.ts @@ -0,0 +1,22 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathLimitLocation } from "./math-limit-location"; + +describe("MathLimitLocation", () => { + describe("#constructor()", () => { + it("should create a MathLimitLocation with correct root key", () => { + const mathLimitLocation = new MathLimitLocation(); + + const tree = new Formatter().format(mathLimitLocation); + expect(tree).to.deep.equal({ + "m:limLoc": { + _attr: { + "m:val": "undOvr", + }, + }, + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-limit-location.ts b/src/file/paragraph/math/n-ary/math-limit-location.ts new file mode 100644 index 0000000000..5504e1890d --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-limit-location.ts @@ -0,0 +1,14 @@ +// http://www.datypic.com/sc/ooxml/e-m_limLoc-1.html +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +class MathLimitLocationAttributes extends XmlAttributeComponent<{ readonly value: string }> { + protected readonly xmlKeys = { value: "m:val" }; +} + +export class MathLimitLocation extends XmlComponent { + constructor() { + super("m:limLoc"); + + this.root.push(new MathLimitLocationAttributes({ value: "undOvr" })); + } +} diff --git a/src/file/paragraph/math/n-ary/math-naray-properties.spec.ts b/src/file/paragraph/math/n-ary/math-naray-properties.spec.ts new file mode 100644 index 0000000000..01ac55fb03 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-naray-properties.spec.ts @@ -0,0 +1,33 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathNArayProperties } from "./math-naray-properties"; + +describe("MathNArayProperties", () => { + describe("#constructor()", () => { + it("should create a MathNArayProperties with correct root key", () => { + const mathNArayProperties = new MathNArayProperties("∑"); + + const tree = new Formatter().format(mathNArayProperties); + expect(tree).to.deep.equal({ + "m:naryPr": [ + { + "m:chr": { + _attr: { + "m:val": "∑", + }, + }, + }, + { + "m:limLoc": { + _attr: { + "m:val": "undOvr", + }, + }, + }, + ], + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-naray-properties.ts b/src/file/paragraph/math/n-ary/math-naray-properties.ts new file mode 100644 index 0000000000..4b28b58794 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-naray-properties.ts @@ -0,0 +1,14 @@ +// http://www.datypic.com/sc/ooxml/e-m_naryPr-1.html +import { XmlComponent } from "file/xml-components"; + +import { MathAccentCharacter } from "./math-accent-character"; +import { MathLimitLocation } from "./math-limit-location"; + +export class MathNArayProperties extends XmlComponent { + constructor(readonly accent: string) { + super("m:naryPr"); + + this.root.push(new MathAccentCharacter(accent)); + this.root.push(new MathLimitLocation()); + } +} diff --git a/src/file/paragraph/math/n-ary/math-sub-script.spec.ts b/src/file/paragraph/math/n-ary/math-sub-script.spec.ts new file mode 100644 index 0000000000..d09908b192 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-sub-script.spec.ts @@ -0,0 +1,27 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathRun } from "../math-run"; +import { MathSubScript } from "./math-sub-script"; + +describe("MathSubScript", () => { + describe("#constructor()", () => { + it("should create a MathSubScript with correct root key", () => { + const mathSubScript = new MathSubScript(new MathRun("2+2")); + + const tree = new Formatter().format(mathSubScript); + expect(tree).to.deep.equal({ + "m:sub": [ + { + "m:r": [ + { + "m:t": ["2+2"], + }, + ], + }, + ], + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-sub-script.ts b/src/file/paragraph/math/n-ary/math-sub-script.ts new file mode 100644 index 0000000000..25fe8da894 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-sub-script.ts @@ -0,0 +1,12 @@ +// http://www.datypic.com/sc/ooxml/e-m_e-1.html +import { XmlComponent } from "file/xml-components"; + +import { MathRun } from "../math-run"; + +export class MathSubScript extends XmlComponent { + constructor(readonly run: MathRun) { + super("m:sub"); + + this.root.push(run); + } +} diff --git a/src/file/paragraph/math/n-ary/math-sum.spec.ts b/src/file/paragraph/math/n-ary/math-sum.spec.ts new file mode 100644 index 0000000000..e168792b1f --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-sum.spec.ts @@ -0,0 +1,75 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathRun } from "../math-run"; +import { MathSum } from "./math-sum"; + +describe("MathSum", () => { + describe("#constructor()", () => { + it("should create a MathSum with correct root key", () => { + const mathSum = new MathSum({ + child: new MathRun("1"), + subScript: new MathRun("2"), + superScript: new MathRun("3"), + }); + + const tree = new Formatter().format(mathSum); + expect(tree).to.deep.equal({ + "m:nary": [ + { + "m:naryPr": [ + { + "m:chr": { + _attr: { + "m:val": "∑", + }, + }, + }, + { + "m:limLoc": { + _attr: { + "m:val": "undOvr", + }, + }, + }, + ], + }, + { + "m:sub": [ + { + "m:r": [ + { + "m:t": ["1"], + }, + ], + }, + ], + }, + { + "m:sup": [ + { + "m:r": [ + { + "m:t": ["1"], + }, + ], + }, + ], + }, + { + "m:e": [ + { + "m:r": [ + { + "m:t": ["1"], + }, + ], + }, + ], + }, + ], + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-sum.ts b/src/file/paragraph/math/n-ary/math-sum.ts new file mode 100644 index 0000000000..2664b87fad --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-sum.ts @@ -0,0 +1,25 @@ +// http://www.datypic.com/sc/ooxml/e-m_nary-1.html +import { XmlComponent } from "file/xml-components"; + +import { MathRun } from "../math-run"; +import { MathBase } from "./math-base"; +import { MathNArayProperties } from "./math-naray-properties"; +import { MathSubScript } from "./math-sub-script"; +import { MathSuperScript } from "./math-super-script"; + +export interface IMathSumOptions { + readonly child: MathRun; + readonly subScript?: MathRun; + readonly superScript?: MathRun; +} + +export class MathSum extends XmlComponent { + constructor(readonly options: IMathSumOptions) { + super("m:nary"); + + this.root.push(new MathNArayProperties("∑")); + this.root.push(new MathSubScript(options.child)); + this.root.push(new MathSuperScript(options.child)); + this.root.push(new MathBase(options.child)); + } +} diff --git a/src/file/paragraph/math/n-ary/math-super-script.spec.ts b/src/file/paragraph/math/n-ary/math-super-script.spec.ts new file mode 100644 index 0000000000..7270276c28 --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-super-script.spec.ts @@ -0,0 +1,27 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; + +import { MathRun } from "../math-run"; +import { MathSuperScript } from "./math-super-script"; + +describe("MathSuperScript", () => { + describe("#constructor()", () => { + it("should create a MathSuperScript with correct root key", () => { + const mathSuperScript = new MathSuperScript(new MathRun("2+2")); + + const tree = new Formatter().format(mathSuperScript); + expect(tree).to.deep.equal({ + "m:sup": [ + { + "m:r": [ + { + "m:t": ["2+2"], + }, + ], + }, + ], + }); + }); + }); +}); diff --git a/src/file/paragraph/math/n-ary/math-super-script.ts b/src/file/paragraph/math/n-ary/math-super-script.ts new file mode 100644 index 0000000000..8296c59f6a --- /dev/null +++ b/src/file/paragraph/math/n-ary/math-super-script.ts @@ -0,0 +1,12 @@ +// http://www.datypic.com/sc/ooxml/e-m_e-1.html +import { XmlComponent } from "file/xml-components"; + +import { MathRun } from "../math-run"; + +export class MathSuperScript extends XmlComponent { + constructor(readonly run: MathRun) { + super("m:sup"); + + this.root.push(run); + } +}