Merge pull request #381 from dolanmiu/feat/math

MathML
This commit is contained in:
Dolan
2020-10-13 03:08:43 +01:00
committed by GitHub
101 changed files with 2611 additions and 32 deletions

294
demo/55-math.ts Normal file
View File

@ -0,0 +1,294 @@
// 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,
MathAngledBrackets,
MathCurlyBrackets,
MathFraction,
MathFunction,
MathPreSubSuperScript,
MathRadical,
MathRoundBrackets,
MathRun,
MathSquareBrackets,
MathSubScript,
MathSubSuperScript,
MathSum,
MathSuperScript,
Packer,
Paragraph,
TextRun,
} from "../build";
const doc = new Document();
doc.addSection({
properties: {},
children: [
new Paragraph({
children: [
new Math({
children: [
new MathRun("2+2"),
new MathFraction({
numerator: [new MathRun("hi")],
denominator: [new MathRun("2")],
}),
],
}),
new TextRun({
text: "Foo Bar",
bold: true,
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathFraction({
numerator: [
new MathRun("1"),
new MathRadical({
children: [new MathRun("2")],
}),
],
denominator: [new MathRun("2")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSum({
children: [new MathRun("test")],
}),
new MathSum({
children: [
new MathSuperScript({
children: [new MathRun("e")],
superScript: [new MathRun("2")],
}),
],
subScript: [new MathRun("i")],
}),
new MathSum({
children: [
new MathRadical({
children: [new MathRun("i")],
}),
],
subScript: [new MathRun("i")],
superScript: [new MathRun("10")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSuperScript({
children: [new MathRun("test")],
superScript: [new MathRun("hello")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSubScript({
children: [new MathRun("test")],
subScript: [new MathRun("hello")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSubScript({
children: [new MathRun("x")],
subScript: [
new MathSuperScript({
children: [new MathRun("y")],
superScript: [new MathRun("2")],
}),
],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSubSuperScript({
children: [new MathRun("test")],
superScript: [new MathRun("hello")],
subScript: [new MathRun("world")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathPreSubSuperScript({
children: [new MathRun("test")],
superScript: [new MathRun("hello")],
subScript: [new MathRun("world")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSubScript({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
subScript: [new MathRun("4")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathSubScript({
children: [
new MathRadical({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
degree: [new MathRun("4")],
}),
],
subScript: [new MathRun("x")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathRadical({
children: [new MathRun("4")],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathFunction({
name: [
new MathSuperScript({
children: [new MathRun("cos")],
superScript: [new MathRun("-1")],
}),
],
children: [new MathRun("100")],
}),
new MathRun("×"),
new MathFunction({
name: [new MathRun("sin")],
children: [new MathRun("360")],
}),
new MathRun("= x"),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathRoundBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
new MathSquareBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
new MathCurlyBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
new MathAngledBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
],
}),
],
}),
new Paragraph({
children: [
new Math({
children: [
new MathFraction({
numerator: [
new MathRadical({
children: [new MathRun("4")],
}),
],
denominator: [new MathRun("2a")],
}),
],
}),
],
}),
],
});
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});

View File

@ -21,6 +21,7 @@
* [Table of Contents](usage/table-of-contents.md)
* [Page Numbers](usage/page-numbers.md)
* [Change Tracking](usage/change-tracking.md)
* [Math](usage/math.md)
* Styling
* [Styling with JS](usage/styling-with-js.md)
* [Styling with XML](usage/styling-with-xml.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

265
docs/usage/math.md Normal file
View File

@ -0,0 +1,265 @@
# Math
!> Math requires an understanding of [Sections](usage/sections.md) and [Paragraphs](usage/paragraph.md).
## Intro
1. To add math, create a `Math` object
2. Add `MathComponents` inside `Math`
3. `MathComponents` can have nested `MathComponents` inside. e.g. A fraction where the numerator is a square root, and the demoninator as another fraction. More on `MathComponents` below
4. Make sure to add the `Math` object inside a `Paragraph`
## Example
```ts
new Math({
children: [
new MathRun("2+2"),
new MathFraction({
numerator: [new MathRun("hi")],
denominator: [new MathRun("2")],
}),
],
}),
```
This will produce:
<p align="center">
<img alt="clippy the assistant" src="images/math-example.png" width="200">
</p>
## Math Components
`MathComponents` are the unit sized building blocks of an equation in `docx`. A `MathComponent` takes in more nested `MathComponents` until you reach `MathRun`, which has no children. `MathRun` is similar to a [TextRun](usage/text.md).
### Math Run
`MathRun` is the most basic `MathComponent`.
#### Example
```ts
new MathRun("2+2");
```
```ts
new MathRun("hello");
```
An example of it being used inside `Math`:
```ts
new Math({
children: [
new MathRun("2"),
new MathRun("+"),
new MathRun("2"),
],
}),
```
### Math Fraction
`MathFractions` require a `numerator` and a `demoninator`, which are both a list of `MathComponents`
#### Example
```ts
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
```
```ts
new MathFraction({
numerator: [
new MathRun("1"),
new MathRadical({
children: [new MathRun("2")],
}),
],
denominator: [new MathRun("2")],
}),
```
An example of it being used inside `Math`:
```ts
new Math({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
new MathText("+"),
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
new MathText("= 1"),
],
}),
```
### Sum
A `MathComponent` for `Σ`. It can take a `superScript` and/or `subScript` as arguments to add `MathComponents` (usually limits) on the top and bottom
```ts
new MathSum({
children: [new MathRun("i")],
}),
```
```ts
new MathSum({
children: [
new MathSuperScript({
children: [new MathRun("e")],
superScript: [new MathRun("2")],
})
],
subScript: [new MathRun("i")],
superScript: [new MathRun("10")],
}),
```
### Radicals
A `MathComponent` for the `√` symbol. Examples include, square root, cube root etc. There is an optional `degree` parameter to specify the number of times the radicand is multiplied by itself. For example, `3` for cube root.
```ts
new MathRadical({
children: [new MathRun("2")],
}),
```
Cube root example:
```ts
new MathRadical({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
new MathRun('+ 1'),
],
degree: [new MathRun("3")],
}),
```
### Super Script
`MathSuperScripts` are the little numbers written to the top right of numbers or variables. It means the exponent or power if written by itself with the number or variable.
```ts
new MathSuperScript({
children: [new MathRun("x")],
superScript: [new MathRun("2")],
}),
```
An example with cosine:
```ts
new MathSuperScript({
children: [new MathRun("cos")],
superScript: [new MathRun("-1")],
}),
```
### Sub Script
`MathSubScripts` are similar to `MathSuperScripts`, except the little number is written below.
```ts
new MathSubScript({
children: [new MathRun("F")],
subScript: [new MathRun("n-1")],
}),
```
### Sub-Super Script
`MathSubSuperScripts` are a combination of both `MathSuperScript` and `MathSubScript`.
```ts
new MathSubSuperScript({
children: [new MathRun("test")],
superScript: [new MathRun("hello")],
subScript: [new MathRun("world")],
}),
```
### Function
`MathFunctions` are a way of describing what happens to an input variable, in order to get the output result. It takes a `name` parameter to specify the name of the function.
```ts
new MathFunction({
name: [
new MathSuperScript({
children: [new MathRun("cos")],
superScript: [new MathRun("-1")],
}),
],
children: [new MathRun("100")],
}),
```
### Brackets
#### Square brackets
```ts
new MathSquareBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
```
#### Round brackets
```ts
new MathRoundBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
```
#### Curly brackets
```ts
new MathCurlyBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
```
#### Angled brackets
```ts
new MathAngledBrackets({
children: [
new MathFraction({
numerator: [new MathRun("1")],
denominator: [new MathRun("2")],
}),
],
}),
```

37
package-lock.json generated
View File

@ -1088,7 +1088,7 @@
},
"awesome-typescript-loader": {
"version": "3.5.0",
"resolved": "http://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-3.5.0.tgz",
"resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-3.5.0.tgz",
"integrity": "sha512-qzgm9SEvodVkSi9QY7Me1/rujg+YBNMjayNSAyzNghwTEez++gXoPCwMvpbHRG7wrOkDCiF6dquvv9ESmUBAuw==",
"dev": true,
"requires": {
@ -1665,7 +1665,7 @@
},
"chai": {
"version": "3.5.0",
"resolved": "http://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
"resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
"integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
"dev": true,
"requires": {
@ -2153,7 +2153,7 @@
},
"deep-eql": {
"version": "0.1.3",
"resolved": "http://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
"integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
"dev": true,
"requires": {
@ -4373,7 +4373,7 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"dev": true
},
"is-ci": {
@ -4843,7 +4843,7 @@
},
"jsesc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
"dev": true
},
@ -5098,7 +5098,7 @@
},
"load-json-file": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"requires": {
@ -5395,7 +5395,7 @@
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
@ -5585,7 +5585,7 @@
},
"ncp": {
"version": "1.0.1",
"resolved": "http://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz",
"integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=",
"dev": true
},
@ -5603,7 +5603,7 @@
},
"next-tick": {
"version": "1.0.0",
"resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
@ -7116,7 +7116,7 @@
},
"safe-regex": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
@ -7719,7 +7719,7 @@
},
"strip-eof": {
"version": "1.0.0",
"resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
@ -7996,10 +7996,13 @@
}
},
"tslint-immutable": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-4.9.1.tgz",
"integrity": "sha512-iIFCq08H4YyNIX0bV5N6fGQtAmjc4OQZKQCgBP5WHgQaITyGAHPVmAw+Yf7qe0zbRCvCDZdrdEC/191fLGFiww==",
"dev": true
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-6.0.1.tgz",
"integrity": "sha512-3GQ6HffN64gLmT/N1YzyVMqyf6uBjMvhNaevK8B0K01/QC0OU5AQZrH4TjMHo1IdG3JpqsZvuRy9IW1LA3zjwA==",
"dev": true,
"requires": {
"tsutils": "^2.28.0 || ^3.0.0"
}
},
"tsutils": {
"version": "2.29.0",
@ -8654,7 +8657,7 @@
},
"load-json-file": {
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
@ -8855,7 +8858,7 @@
},
"winston": {
"version": "2.1.1",
"resolved": "http://registry.npmjs.org/winston/-/winston-2.1.1.tgz",
"resolved": "https://registry.npmjs.org/winston/-/winston-2.1.1.tgz",
"integrity": "sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4=",
"dev": true,
"requires": {

View File

@ -89,7 +89,7 @@
"sinon": "^9.0.2",
"ts-node": "^9.0.0",
"tslint": "^6.1.3",
"tslint-immutable": "^4.9.0",
"tslint-immutable": "^6.0.1",
"typedoc": "^0.16.11",
"typescript": "2.9.2",
"webpack": "^3.10.0"

View File

@ -12,7 +12,7 @@ export class Inline extends XmlComponent {
private readonly extent: Extent;
private readonly graphic: Graphic;
constructor(readonly mediaData: IMediaData, private readonly dimensions: IMediaDataDimensions) {
constructor(mediaData: IMediaData, private readonly dimensions: IMediaDataDimensions) {
super("wp:inline");
this.root.push(

View File

@ -3,3 +3,4 @@ export * from "./paragraph";
export * from "./properties";
export * from "./run";
export * from "./links";
export * from "./math";

View File

@ -0,0 +1,4 @@
export * from "./math-round-brackets";
export * from "./math-square-brackets";
export * from "./math-curly-brackets";
export * from "./math-angled-brackets";

View File

@ -0,0 +1,51 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathAngledBrackets } from "./math-angled-brackets";
describe("MathAngledBrackets", () => {
describe("#constructor()", () => {
it("should create a MathAngledBrackets with correct root key", () => {
const mathAngledBrackets = new MathAngledBrackets({
children: [new MathRun("60")],
});
const tree = new Formatter().format(mathAngledBrackets);
expect(tree).to.deep.equal({
"m:d": [
{
"m:dPr": [
{
"m:begChr": {
_attr: {
"m:val": "〈",
},
},
},
{
"m:endChr": {
_attr: {
"m:val": "〉",
},
},
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["60"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,20 @@
// http://www.datypic.com/sc/ooxml/e-m_d-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathBracketProperties } from "./math-bracket-properties";
export class MathAngledBrackets extends XmlComponent {
constructor(options: { readonly children: MathComponent[] }) {
super("m:d");
this.root.push(
new MathBracketProperties({
beginningCharacter: "〈",
endingCharacter: "〉",
}),
);
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathBeginningCharacter } from "./math-beginning-character";
describe("MathBeginningCharacter", () => {
describe("#constructor()", () => {
it("should create a MathBeginningCharacter with correct root key", () => {
const mathBeginningCharacter = new MathBeginningCharacter("[");
const tree = new Formatter().format(mathBeginningCharacter);
expect(tree).to.deep.equal({
"m:begChr": {
_attr: {
"m:val": "[",
},
},
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_begChr-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class MathBeginningCharacterAttributes extends XmlAttributeComponent<{ readonly character: string }> {
protected readonly xmlKeys = { character: "m:val" };
}
export class MathBeginningCharacter extends XmlComponent {
constructor(character: string) {
super("m:begChr");
this.root.push(new MathBeginningCharacterAttributes({ character }));
}
}

View File

@ -0,0 +1,45 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathBracketProperties } from "./math-bracket-properties";
describe("MathBracketProperties", () => {
describe("#constructor()", () => {
it("should create a MathBracketProperties with correct root key", () => {
const mathBracketProperties = new MathBracketProperties();
const tree = new Formatter().format(mathBracketProperties);
expect(tree).to.deep.equal({
"m:dPr": {},
});
});
it("should create a MathBracketProperties with correct root key and add brackets", () => {
const mathBracketProperties = new MathBracketProperties({
beginningCharacter: "[",
endingCharacter: "]",
});
const tree = new Formatter().format(mathBracketProperties);
expect(tree).to.deep.equal({
"m:dPr": [
{
"m:begChr": {
_attr: {
"m:val": "[",
},
},
},
{
"m:endChr": {
_attr: {
"m:val": "]",
},
},
},
],
});
});
});
});

View File

@ -0,0 +1,16 @@
// http://www.datypic.com/sc/ooxml/e-m_dPr-1.html
import { XmlComponent } from "file/xml-components";
import { MathBeginningCharacter } from "./math-beginning-character";
import { MathEndingCharacter } from "./math-ending-char";
export class MathBracketProperties extends XmlComponent {
constructor(options?: { readonly beginningCharacter: string; readonly endingCharacter: string }) {
super("m:dPr");
if (!!options) {
this.root.push(new MathBeginningCharacter(options.beginningCharacter));
this.root.push(new MathEndingCharacter(options.endingCharacter));
}
}
}

View File

@ -0,0 +1,51 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathCurlyBrackets } from "./math-curly-brackets";
describe("MathCurlyBrackets", () => {
describe("#constructor()", () => {
it("should create a MathCurlyBrackets with correct root key", () => {
const mathCurlyBrackets = new MathCurlyBrackets({
children: [new MathRun("60")],
});
const tree = new Formatter().format(mathCurlyBrackets);
expect(tree).to.deep.equal({
"m:d": [
{
"m:dPr": [
{
"m:begChr": {
_attr: {
"m:val": "{",
},
},
},
{
"m:endChr": {
_attr: {
"m:val": "}",
},
},
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["60"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,20 @@
// http://www.datypic.com/sc/ooxml/e-m_d-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathBracketProperties } from "./math-bracket-properties";
export class MathCurlyBrackets extends XmlComponent {
constructor(options: { readonly children: MathComponent[] }) {
super("m:d");
this.root.push(
new MathBracketProperties({
beginningCharacter: "{",
endingCharacter: "}",
}),
);
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_endChr-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class MathEndingCharacterAttributes extends XmlAttributeComponent<{ readonly character: string }> {
protected readonly xmlKeys = { character: "m:val" };
}
export class MathEndingCharacter extends XmlComponent {
constructor(character: string) {
super("m:endChr");
this.root.push(new MathEndingCharacterAttributes({ character }));
}
}

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathEndingCharacter } from "./math-ending-char";
describe("MathEndingCharacter", () => {
describe("#constructor()", () => {
it("should create a MathEndingCharacter with correct root key", () => {
const mathEndingCharacter = new MathEndingCharacter("]");
const tree = new Formatter().format(mathEndingCharacter);
expect(tree).to.deep.equal({
"m:endChr": {
_attr: {
"m:val": "]",
},
},
});
});
});
});

View File

@ -0,0 +1,36 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathRoundBrackets } from "./math-round-brackets";
describe("MathRoundBrackets", () => {
describe("#constructor()", () => {
it("should create a MathRoundBrackets with correct root key", () => {
const mathRoundBrackets = new MathRoundBrackets({
children: [new MathRun("60")],
});
const tree = new Formatter().format(mathRoundBrackets);
expect(tree).to.deep.equal({
"m:d": [
{
"m:dPr": {},
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["60"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,15 @@
// http://www.datypic.com/sc/ooxml/e-m_d-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathBracketProperties } from "./math-bracket-properties";
export class MathRoundBrackets extends XmlComponent {
constructor(options: { readonly children: MathComponent[] }) {
super("m:d");
this.root.push(new MathBracketProperties());
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,51 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathSquareBrackets } from "./math-square-brackets";
describe("MathSquareBrackets", () => {
describe("#constructor()", () => {
it("should create a MathSquareBrackets with correct root key", () => {
const mathSquareBrackets = new MathSquareBrackets({
children: [new MathRun("60")],
});
const tree = new Formatter().format(mathSquareBrackets);
expect(tree).to.deep.equal({
"m:d": [
{
"m:dPr": [
{
"m:begChr": {
_attr: {
"m:val": "[",
},
},
},
{
"m:endChr": {
_attr: {
"m:val": "]",
},
},
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["60"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,20 @@
// http://www.datypic.com/sc/ooxml/e-m_d-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathBracketProperties } from "./math-bracket-properties";
export class MathSquareBrackets extends XmlComponent {
constructor(options: { readonly children: MathComponent[] }) {
super("m:d");
this.root.push(
new MathBracketProperties({
beginningCharacter: "[",
endingCharacter: "]",
}),
);
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,3 @@
export * from "./math-fraction";
export * from "./math-denominator";
export * from "./math-numerator";

View File

@ -0,0 +1,26 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathDenominator } from "./math-denominator";
describe("MathDenominator", () => {
describe("#constructor()", () => {
it("should create a MathDenominator with correct root key", () => {
const mathDenominator = new MathDenominator([new MathRun("2+2")]);
const tree = new Formatter().format(mathDenominator);
expect(tree).to.deep.equal({
"m:den": [
{
"m:r": [
{
"m:t": ["2+2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,13 @@
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathDenominator extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:den");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -0,0 +1,44 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathFraction } from "./math-fraction";
describe("MathFraction", () => {
describe("#constructor()", () => {
it("should create a MathFraction with correct root key", () => {
const mathFraction = new MathFraction({
numerator: [new MathRun("2")],
denominator: [new MathRun("2")],
});
const tree = new Formatter().format(mathFraction);
expect(tree).to.deep.equal({
"m:f": [
{
"m:num": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
{
"m:den": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,19 @@
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathDenominator } from "./math-denominator";
import { MathNumerator } from "./math-numerator";
export interface IMathFractionOptions {
readonly numerator: MathComponent[];
readonly denominator: MathComponent[];
}
export class MathFraction extends XmlComponent {
constructor(options: IMathFractionOptions) {
super("m:f");
this.root.push(new MathNumerator(options.numerator));
this.root.push(new MathDenominator(options.denominator));
}
}

View File

@ -0,0 +1,26 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathNumerator } from "./math-numerator";
describe("MathNumerator", () => {
describe("#constructor()", () => {
it("should create a MathNumerator with correct root key", () => {
const mathNumerator = new MathNumerator([new MathRun("2+2")]);
const tree = new Formatter().format(mathNumerator);
expect(tree).to.deep.equal({
"m:num": [
{
"m:r": [
{
"m:t": ["2+2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,13 @@
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathNumerator extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:num");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -0,0 +1,3 @@
export * from "./math-function";
export * from "./math-function-name";
export * from "./math-function-properties";

View File

@ -0,0 +1,27 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathFunctionName } from "./math-function-name";
describe("MathFunctionName", () => {
describe("#constructor()", () => {
it("should create a MathFunctionName with correct root key", () => {
const mathFunctionName = new MathFunctionName([new MathRun("2")]);
const tree = new Formatter().format(mathFunctionName);
expect(tree).to.deep.equal({
"m:fName": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,13 @@
// http://www.datypic.com/sc/ooxml/e-m_fName-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathFunctionName extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:fName");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -0,0 +1,18 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathFunctionProperties } from "./math-function-properties";
describe("MathFunctionProperties", () => {
describe("#constructor()", () => {
it("should create a MathFunctionProperties with correct root key", () => {
const mathFunctionProperties = new MathFunctionProperties();
const tree = new Formatter().format(mathFunctionProperties);
expect(tree).to.deep.equal({
"m:funcPr": {},
});
});
});
});

View File

@ -0,0 +1,8 @@
// http://www.datypic.com/sc/ooxml/e-m_radPr-1.html
import { XmlComponent } from "file/xml-components";
export class MathFunctionProperties extends XmlComponent {
constructor() {
super("m:funcPr");
}
}

View File

@ -0,0 +1,48 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathFunction } from "./math-function";
describe("MathFunction", () => {
describe("#constructor()", () => {
it("should create a MathFunction with correct root key", () => {
const mathFunction = new MathFunction({
name: [new MathRun("sin")],
children: [new MathRun("60")],
});
const tree = new Formatter().format(mathFunction);
expect(tree).to.deep.equal({
"m:func": [
{
"m:funcPr": {},
},
{
"m:fName": [
{
"m:r": [
{
"m:t": ["sin"],
},
],
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["60"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,22 @@
// http://www.datypic.com/sc/ooxml/e-m_func-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathFunctionName } from "./math-function-name";
import { MathFunctionProperties } from "./math-function-properties";
export interface IMathFunctionOptions {
readonly children: MathComponent[];
readonly name: MathComponent[];
}
export class MathFunction extends XmlComponent {
constructor(options: IMathFunctionOptions) {
super("m:func");
this.root.push(new MathFunctionProperties());
this.root.push(new MathFunctionName(options.name));
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,9 @@
export * from "./math";
export * from "./math-run";
export * from "./fraction";
export * from "./n-ary";
export * from "./script";
export * from "./math-component";
export * from "./radical";
export * from "./function";
export * from "./brackets";

View File

@ -0,0 +1,21 @@
import { MathAngledBrackets, MathCurlyBrackets, MathRoundBrackets, MathSquareBrackets } from "./brackets";
import { MathFraction } from "./fraction";
import { MathFunction } from "./function";
import { MathRun } from "./math-run";
import { MathSum } from "./n-ary";
import { MathRadical } from "./radical";
import { MathSubScript, MathSubSuperScript, MathSuperScript } from "./script";
export type MathComponent =
| MathRun
| MathFraction
| MathSum
| MathSuperScript
| MathSubScript
| MathSubSuperScript
| MathRadical
| MathFunction
| MathRoundBrackets
| MathCurlyBrackets
| MathAngledBrackets
| MathSquareBrackets;

View File

@ -0,0 +1,21 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "./math-run";
describe("MathRun", () => {
describe("#constructor()", () => {
it("should create a MathRun with correct root key", () => {
const mathRun = new MathRun("2+2");
const tree = new Formatter().format(mathRun);
expect(tree).to.deep.equal({
"m:r": [
{
"m:t": ["2+2"],
},
],
});
});
});
});

View File

@ -0,0 +1,12 @@
// http://www.datypic.com/sc/ooxml/e-m_r-1.html
import { XmlComponent } from "file/xml-components";
import { MathText } from "./math-text";
export class MathRun extends XmlComponent {
constructor(text: string) {
super("m:r");
this.root.push(new MathText(text));
}
}

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathText } from "./math-text";
describe("MathText", () => {
describe("#constructor()", () => {
it("should create a MathText with correct root key", () => {
const mathText = new MathText("2+2");
const tree = new Formatter().format(mathText);
expect(tree).to.deep.equal({
"m:t": ["2+2"],
});
});
});
});

View File

@ -0,0 +1,9 @@
import { XmlComponent } from "file/xml-components";
export class MathText extends XmlComponent {
constructor(text: string) {
super("m:t");
this.root.push(text);
}
}

View File

@ -0,0 +1,38 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { Math } from "./math";
import { MathRun } from "./math-run";
describe("Math", () => {
describe("#constructor()", () => {
it("should create a Math with correct root key", () => {
const math = new Math({
children: [],
});
const tree = new Formatter().format(math);
expect(tree).to.deep.equal({
"m:oMath": {},
});
});
it("should be able to add children", () => {
const math = new Math({
children: [new MathRun("2+2")],
});
const tree = new Formatter().format(math);
expect(tree).to.deep.equal({
"m:oMath": [
{
"m:r": [
{
"m:t": ["2+2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,18 @@
// http://www.datypic.com/sc/ooxml/e-m_oMath-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "./math-component";
export interface IMathOptions {
readonly children: MathComponent[];
}
export class Math extends XmlComponent {
constructor(options: IMathOptions) {
super("m:oMath");
for (const child of options.children) {
this.root.push(child);
}
}
}

View File

@ -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";

View File

@ -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": "∑",
},
},
});
});
});
});

View File

@ -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(accent: string) {
super("m:chr");
this.root.push(new MathAccentCharacterAttributes({ accent }));
}
}

View File

@ -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"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_e-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathBase extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:e");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -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",
},
},
});
});
});
});

View File

@ -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" }));
}
}

View File

@ -0,0 +1,133 @@
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("∑", true, true);
const tree = new Formatter().format(mathNArayProperties);
expect(tree).to.deep.equal({
"m:naryPr": [
{
"m:chr": {
_attr: {
"m:val": "∑",
},
},
},
{
"m:limLoc": {
_attr: {
"m:val": "undOvr",
},
},
},
],
});
});
it("should add super-script hide attributes", () => {
const mathNArayProperties = new MathNArayProperties("∑", false, true);
const tree = new Formatter().format(mathNArayProperties);
expect(tree).to.deep.equal({
"m:naryPr": [
{
"m:chr": {
_attr: {
"m:val": "∑",
},
},
},
{
"m:limLoc": {
_attr: {
"m:val": "undOvr",
},
},
},
{
"m:supHide": {
_attr: {
"m:val": 1,
},
},
},
],
});
});
it("should add sub-script hide attributes", () => {
const mathNArayProperties = new MathNArayProperties("∑", true, false);
const tree = new Formatter().format(mathNArayProperties);
expect(tree).to.deep.equal({
"m:naryPr": [
{
"m:chr": {
_attr: {
"m:val": "∑",
},
},
},
{
"m:limLoc": {
_attr: {
"m:val": "undOvr",
},
},
},
{
"m:subHide": {
_attr: {
"m:val": 1,
},
},
},
],
});
});
it("should add both super-script and sub-script hide attributes", () => {
const mathNArayProperties = new MathNArayProperties("∑", false, false);
const tree = new Formatter().format(mathNArayProperties);
expect(tree).to.deep.equal({
"m:naryPr": [
{
"m:chr": {
_attr: {
"m:val": "∑",
},
},
},
{
"m:limLoc": {
_attr: {
"m:val": "undOvr",
},
},
},
{
"m:supHide": {
_attr: {
"m:val": 1,
},
},
},
{
"m:subHide": {
_attr: {
"m:val": 1,
},
},
},
],
});
});
});
});

View File

@ -0,0 +1,24 @@
// 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";
import { MathSubScriptHide } from "./math-sub-script-hide";
import { MathSuperScriptHide } from "./math-super-script-hide";
export class MathNArayProperties extends XmlComponent {
constructor(accent: string, hasSuperScript: boolean, hasSubScript: boolean) {
super("m:naryPr");
this.root.push(new MathAccentCharacter(accent));
this.root.push(new MathLimitLocation());
if (!hasSuperScript) {
this.root.push(new MathSuperScriptHide());
}
if (!hasSubScript) {
this.root.push(new MathSubScriptHide());
}
}
}

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathSubScriptHide } from "./math-sub-script-hide";
describe("MathSubScriptHide", () => {
describe("#constructor()", () => {
it("should create a MathSubScriptHide with correct root key", () => {
const mathSubScriptHide = new MathSubScriptHide();
const tree = new Formatter().format(mathSubScriptHide);
expect(tree).to.deep.equal({
"m:subHide": {
_attr: {
"m:val": 1,
},
},
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_subHide-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class MathSubScriptHideAttributes extends XmlAttributeComponent<{ readonly hide: number }> {
protected readonly xmlKeys = { hide: "m:val" };
}
export class MathSubScriptHide extends XmlComponent {
constructor() {
super("m:subHide");
this.root.push(new MathSubScriptHideAttributes({ hide: 1 }));
}
}

View File

@ -0,0 +1,27 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathSubScriptElement } from "./math-sub-script";
describe("MathSubScriptElement", () => {
describe("#constructor()", () => {
it("should create a MathSubScriptElement with correct root key", () => {
const mathSubScriptElement = new MathSubScriptElement([new MathRun("2+2")]);
const tree = new Formatter().format(mathSubScriptElement);
expect(tree).to.deep.equal({
"m:sub": [
{
"m:r": [
{
"m:t": ["2+2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_sub-3.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathSubScriptElement extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:sub");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -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({
children: [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": ["2"],
},
],
},
],
},
{
"m:sup": [
{
"m:r": [
{
"m:t": ["3"],
},
],
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["1"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,32 @@
// http://www.datypic.com/sc/ooxml/e-m_nary-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "./math-base";
import { MathNArayProperties } from "./math-naray-properties";
import { MathSubScriptElement } from "./math-sub-script";
import { MathSuperScriptElement } from "./math-super-script";
export interface IMathSumOptions {
readonly children: MathComponent[];
readonly subScript?: MathComponent[];
readonly superScript?: MathComponent[];
}
export class MathSum extends XmlComponent {
constructor(options: IMathSumOptions) {
super("m:nary");
this.root.push(new MathNArayProperties("∑", !!options.superScript, !!options.subScript));
if (!!options.subScript) {
this.root.push(new MathSubScriptElement(options.subScript));
}
if (!!options.superScript) {
this.root.push(new MathSuperScriptElement(options.superScript));
}
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathSuperScriptHide } from "./math-super-script-hide";
describe("MathSuperScriptHide", () => {
describe("#constructor()", () => {
it("should create a MathSuperScriptHide with correct root key", () => {
const mathSuperScriptHide = new MathSuperScriptHide();
const tree = new Formatter().format(mathSuperScriptHide);
expect(tree).to.deep.equal({
"m:supHide": {
_attr: {
"m:val": 1,
},
},
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_subHide-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class MathSuperScriptHideAttributes extends XmlAttributeComponent<{ readonly hide: number }> {
protected readonly xmlKeys = { hide: "m:val" };
}
export class MathSuperScriptHide extends XmlComponent {
constructor() {
super("m:supHide");
this.root.push(new MathSuperScriptHideAttributes({ hide: 1 }));
}
}

View File

@ -0,0 +1,27 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathSuperScriptElement } from "./math-super-script";
describe("MathSuperScriptElement", () => {
describe("#constructor()", () => {
it("should create a MathSuperScriptElement with correct root key", () => {
const mathSuperScriptElement = new MathSuperScriptElement([new MathRun("2+2")]);
const tree = new Formatter().format(mathSuperScriptElement);
expect(tree).to.deep.equal({
"m:sup": [
{
"m:r": [
{
"m:t": ["2+2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_sup-3.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathSuperScriptElement extends XmlComponent {
constructor(children: MathComponent[]) {
super("m:sup");
for (const child of children) {
this.root.push(child);
}
}
}

View File

@ -0,0 +1,3 @@
export * from "./math-degree";
export * from "./math-radical";
export * from "./math-radical-properties";

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathDegreeHide } from "./math-degree-hide";
describe("MathDegreeHide", () => {
describe("#constructor()", () => {
it("should create a MathDegreeHide with correct root key", () => {
const mathDegreeHide = new MathDegreeHide();
const tree = new Formatter().format(mathDegreeHide);
expect(tree).to.deep.equal({
"m:degHide": {
_attr: {
"m:val": 1,
},
},
});
});
});
});

View File

@ -0,0 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_degHide-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class MathDegreeHideAttributes extends XmlAttributeComponent<{ readonly hide: number }> {
protected readonly xmlKeys = { hide: "m:val" };
}
export class MathDegreeHide extends XmlComponent {
constructor() {
super("m:degHide");
this.root.push(new MathDegreeHideAttributes({ hide: 1 }));
}
}

View File

@ -0,0 +1,36 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathDegree } from "./math-degree";
describe("MathDegree", () => {
describe("#constructor()", () => {
it("should create a MathDegree with correct root key", () => {
const mathDegree = new MathDegree();
const tree = new Formatter().format(mathDegree);
expect(tree).to.deep.equal({
"m:deg": {},
});
});
it("should create a MathDegree with correct root key with child", () => {
const mathDegree = new MathDegree([new MathRun("2")]);
const tree = new Formatter().format(mathDegree);
expect(tree).to.deep.equal({
"m:deg": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,15 @@
// http://www.datypic.com/sc/ooxml/e-m_deg-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
export class MathDegree extends XmlComponent {
constructor(children?: MathComponent[]) {
super("m:deg");
if (!!children) {
for (const child of children) {
this.root.push(child);
}
}
}
}

View File

@ -0,0 +1,35 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRadicalProperties } from "./math-radical-properties";
describe("MathRadicalProperties", () => {
describe("#constructor()", () => {
it("should create a MathRadicalProperties with correct root key", () => {
const mathRadicalProperties = new MathRadicalProperties(true);
const tree = new Formatter().format(mathRadicalProperties);
expect(tree).to.deep.equal({
"m:radPr": {},
});
});
it("should create a MathRadicalProperties with correct root key with degree hide", () => {
const mathRadicalProperties = new MathRadicalProperties(false);
const tree = new Formatter().format(mathRadicalProperties);
expect(tree).to.deep.equal({
"m:radPr": [
{
"m:degHide": {
_attr: {
"m:val": 1,
},
},
},
],
});
});
});
});

View File

@ -0,0 +1,13 @@
// http://www.datypic.com/sc/ooxml/e-m_radPr-1.html
import { XmlComponent } from "file/xml-components";
import { MathDegreeHide } from "./math-degree-hide";
export class MathRadicalProperties extends XmlComponent {
constructor(hasDegree: boolean) {
super("m:radPr");
if (!hasDegree) {
this.root.push(new MathDegreeHide());
}
}
}

View File

@ -0,0 +1,48 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../math-run";
import { MathRadical } from "./math-radical";
describe("MathRadical", () => {
describe("#constructor()", () => {
it("should create a MathRadical with correct root key", () => {
const mathRadical = new MathRadical({
children: [new MathRun("e")],
degree: [new MathRun("2")],
});
const tree = new Formatter().format(mathRadical);
expect(tree).to.deep.equal({
"m:rad": [
{
"m:radPr": {},
},
{
"m:deg": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["e"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,22 @@
// http://www.datypic.com/sc/ooxml/e-m_rad-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "../n-ary";
import { MathDegree } from "./math-degree";
import { MathRadicalProperties } from "./math-radical-properties";
export interface IMathRadicalOptions {
readonly children: MathComponent[];
readonly degree?: MathComponent[];
}
export class MathRadical extends XmlComponent {
constructor(options: IMathRadicalOptions) {
super("m:rad");
this.root.push(new MathRadicalProperties(!!options.degree));
this.root.push(new MathDegree(options.degree));
this.root.push(new MathBase(options.children));
}
}

View File

@ -0,0 +1,4 @@
export * from "./super-script";
export * from "./sub-script";
export * from "./sub-super-script";
export * from "./pre-sub-super-script";

View File

@ -0,0 +1,2 @@
export * from "./math-pre-sub-super-script-function";
export * from "./math-pre-sub-super-script-function-properties";

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathPreSubSuperScriptProperties } from "./math-pre-sub-super-script-function-properties";
describe("MathPreSubSuperScriptProperties", () => {
describe("#constructor()", () => {
it("should create a MathPreSubSuperScriptProperties with correct root key", () => {
const mathPreSubSuperScriptProperties = new MathPreSubSuperScriptProperties();
const tree = new Formatter().format(mathPreSubSuperScriptProperties);
expect(tree).to.deep.equal({
"m:sPrePr": {},
});
});
});
});

View File

@ -0,0 +1,8 @@
// http://www.datypic.com/sc/ooxml/e-m_sPrePr-1.html
import { XmlComponent } from "file/xml-components";
export class MathPreSubSuperScriptProperties extends XmlComponent {
constructor() {
super("m:sPrePr");
}
}

View File

@ -0,0 +1,60 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../../math-run";
import { MathPreSubSuperScript } from "./math-pre-sub-super-script-function";
describe("MathPreSubScript", () => {
describe("#constructor()", () => {
it("should create a MathPreSubScript with correct root key", () => {
const mathPreSubScript = new MathPreSubSuperScript({
children: [new MathRun("e")],
subScript: [new MathRun("2")],
superScript: [new MathRun("5")],
});
const tree = new Formatter().format(mathPreSubScript);
expect(tree).to.deep.equal({
"m:sPre": [
{
"m:sPrePr": {},
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["e"],
},
],
},
],
},
{
"m:sub": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
{
"m:sup": [
{
"m:r": [
{
"m:t": ["5"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,23 @@
// http://www.datypic.com/sc/ooxml/e-m_sPre-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../../math-component";
import { MathBase, MathSubScriptElement, MathSuperScriptElement } from "../../n-ary";
import { MathPreSubSuperScriptProperties } from "./math-pre-sub-super-script-function-properties";
export interface IMathPreSubSuperScriptOptions {
readonly children: MathComponent[];
readonly subScript: MathComponent[];
readonly superScript: MathComponent[];
}
export class MathPreSubSuperScript extends XmlComponent {
constructor(options: IMathPreSubSuperScriptOptions) {
super("m:sPre");
this.root.push(new MathPreSubSuperScriptProperties());
this.root.push(new MathBase(options.children));
this.root.push(new MathSubScriptElement(options.subScript));
this.root.push(new MathSuperScriptElement(options.superScript));
}
}

View File

@ -0,0 +1,2 @@
export * from "./math-sub-script-function";
export * from "./math-sub-script-function-properties";

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathSubScriptProperties } from "./math-sub-script-function-properties";
describe("MathSubScriptProperties", () => {
describe("#constructor()", () => {
it("should create a MathSubScriptProperties with correct root key", () => {
const mathSubScriptProperties = new MathSubScriptProperties();
const tree = new Formatter().format(mathSubScriptProperties);
expect(tree).to.deep.equal({
"m:sSubPr": {},
});
});
});
});

View File

@ -0,0 +1,8 @@
// http://www.datypic.com/sc/ooxml/e-m_sSubPr-1.html
import { XmlComponent } from "file/xml-components";
export class MathSubScriptProperties extends XmlComponent {
constructor() {
super("m:sSubPr");
}
}

View File

@ -0,0 +1,48 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../../math-run";
import { MathSubScript } from "./math-sub-script-function";
describe("MathSubScript", () => {
describe("#constructor()", () => {
it("should create a MathSubScript with correct root key", () => {
const mathSubScript = new MathSubScript({
children: [new MathRun("e")],
subScript: [new MathRun("2")],
});
const tree = new Formatter().format(mathSubScript);
expect(tree).to.deep.equal({
"m:sSub": [
{
"m:sSubPr": {},
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["e"],
},
],
},
],
},
{
"m:sub": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,21 @@
// http://www.datypic.com/sc/ooxml/e-m_sSub-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../../math-component";
import { MathBase, MathSubScriptElement } from "../../n-ary";
import { MathSubScriptProperties } from "./math-sub-script-function-properties";
export interface IMathSubScriptOptions {
readonly children: MathComponent[];
readonly subScript: MathComponent[];
}
export class MathSubScript extends XmlComponent {
constructor(options: IMathSubScriptOptions) {
super("m:sSub");
this.root.push(new MathSubScriptProperties());
this.root.push(new MathBase(options.children));
this.root.push(new MathSubScriptElement(options.subScript));
}
}

View File

@ -0,0 +1,2 @@
export * from "./math-sub-super-script-function";
export * from "./math-sub-super-script-function-properties";

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathSubSuperScriptProperties } from "./math-sub-super-script-function-properties";
describe("MathSubSuperScriptProperties", () => {
describe("#constructor()", () => {
it("should create a MathSubSuperScriptProperties with correct root key", () => {
const mathSubSuperScriptProperties = new MathSubSuperScriptProperties();
const tree = new Formatter().format(mathSubSuperScriptProperties);
expect(tree).to.deep.equal({
"m:sSubSupPr": {},
});
});
});
});

View File

@ -0,0 +1,8 @@
// http://www.datypic.com/sc/ooxml/e-m_sSubSupPr-1.html
import { XmlComponent } from "file/xml-components";
export class MathSubSuperScriptProperties extends XmlComponent {
constructor() {
super("m:sSubSupPr");
}
}

View File

@ -0,0 +1,60 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../../math-run";
import { MathSubSuperScript } from "./math-sub-super-script-function";
describe("MathSubScript", () => {
describe("#constructor()", () => {
it("should create a MathSubScript with correct root key", () => {
const mathSubScript = new MathSubSuperScript({
children: [new MathRun("e")],
subScript: [new MathRun("2")],
superScript: [new MathRun("5")],
});
const tree = new Formatter().format(mathSubScript);
expect(tree).to.deep.equal({
"m:sSubSup": [
{
"m:sSubSupPr": {},
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["e"],
},
],
},
],
},
{
"m:sub": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
{
"m:sup": [
{
"m:r": [
{
"m:t": ["5"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,23 @@
// http://www.datypic.com/sc/ooxml/e-m_sSubSup-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../../math-component";
import { MathBase, MathSubScriptElement, MathSuperScriptElement } from "../../n-ary";
import { MathSubSuperScriptProperties } from "./math-sub-super-script-function-properties";
export interface IMathSubSuperScriptOptions {
readonly children: MathComponent[];
readonly subScript: MathComponent[];
readonly superScript: MathComponent[];
}
export class MathSubSuperScript extends XmlComponent {
constructor(options: IMathSubSuperScriptOptions) {
super("m:sSubSup");
this.root.push(new MathSubSuperScriptProperties());
this.root.push(new MathBase(options.children));
this.root.push(new MathSubScriptElement(options.subScript));
this.root.push(new MathSuperScriptElement(options.superScript));
}
}

View File

@ -0,0 +1,2 @@
export * from "./math-super-script-function";
export * from "./math-super-script-function-properties";

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathSuperScriptProperties } from "./math-super-script-function-properties";
describe("MathSuperScriptProperties", () => {
describe("#constructor()", () => {
it("should create a MathSuperScriptProperties with correct root key", () => {
const mathSuperScriptProperties = new MathSuperScriptProperties();
const tree = new Formatter().format(mathSuperScriptProperties);
expect(tree).to.deep.equal({
"m:sSupPr": {},
});
});
});
});

View File

@ -0,0 +1,8 @@
// http://www.datypic.com/sc/ooxml/e-m_sSupPr-1.html
import { XmlComponent } from "file/xml-components";
export class MathSuperScriptProperties extends XmlComponent {
constructor() {
super("m:sSupPr");
}
}

View File

@ -0,0 +1,48 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { MathRun } from "../../math-run";
import { MathSuperScript } from "./math-super-script-function";
describe("MathSuperScript", () => {
describe("#constructor()", () => {
it("should create a MathSuperScript with correct root key", () => {
const mathSuperScript = new MathSuperScript({
children: [new MathRun("e")],
superScript: [new MathRun("2")],
});
const tree = new Formatter().format(mathSuperScript);
expect(tree).to.deep.equal({
"m:sSup": [
{
"m:sSupPr": {},
},
{
"m:e": [
{
"m:r": [
{
"m:t": ["e"],
},
],
},
],
},
{
"m:sup": [
{
"m:r": [
{
"m:t": ["2"],
},
],
},
],
},
],
});
});
});
});

View File

@ -0,0 +1,21 @@
// http://www.datypic.com/sc/ooxml/e-m_sSup-1.html
import { XmlComponent } from "file/xml-components";
import { MathComponent } from "../../math-component";
import { MathBase, MathSuperScriptElement } from "../../n-ary";
import { MathSuperScriptProperties } from "./math-super-script-function-properties";
export interface IMathSuperScriptOptions {
readonly children: MathComponent[];
readonly superScript: MathComponent[];
}
export class MathSuperScript extends XmlComponent {
constructor(options: IMathSuperScriptOptions) {
super("m:sSup");
this.root.push(new MathSuperScriptProperties());
this.root.push(new MathBase(options.children));
this.root.push(new MathSuperScriptElement(options.superScript));
}
}

View File

@ -5,8 +5,9 @@ import { stub } from "sinon";
import { Formatter } from "export/formatter";
import { EMPTY_OBJECT } from "file/xml-components";
import { File } from "../file";
import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting";
import { Bookmark } from "./links";
import { Bookmark, HyperlinkRef } from "./links";
import { Paragraph } from "./paragraph";
describe("Paragraph", () => {
@ -759,4 +760,23 @@ describe("Paragraph", () => {
});
});
});
describe("#prepForXml", () => {
it("should set paragraph outline level to the given value", () => {
const paragraph = new Paragraph({
children: [new HyperlinkRef("myAnchorId")],
});
const fileMock = ({
HyperlinkCache: {
myAnchorId: "test",
},
// tslint:disable-next-line: no-any
} as any) as File;
paragraph.prepForXml(fileMock);
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": ["test"],
});
});
});
});

View File

@ -3,9 +3,10 @@ import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"
import { IXmlableObject, XmlComponent } from "file/xml-components";
import { File } from "../file";
import { InsertedTextRun, DeletedTextRun } from "../track-revision";
import { DeletedTextRun, InsertedTextRun } from "../track-revision";
import { PageBreak } from "./formatting/page-break";
import { Bookmark, HyperlinkRef } from "./links";
import { Math } from "./math";
import { IParagraphPropertiesOptions, ParagraphProperties } from "./properties";
import { PictureRun, Run, SequentialIdentifier, SymbolRun, TextRun } from "./run";
@ -22,6 +23,7 @@ export interface IParagraphOptions extends IParagraphPropertiesOptions {
| HyperlinkRef
| InsertedTextRun
| DeletedTextRun
| Math
)[];
}

View File

@ -1,7 +1,7 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { Compatibility } from "./compatibility";
import { UpdateFields } from "./update-fields";
import { TrackRevisions } from "./track-revisions";
import { UpdateFields } from "./update-fields";
export interface ISettingsAttributesProperties {
readonly wpc?: string;
@ -46,8 +46,8 @@ export class SettingsAttributes extends XmlAttributeComponent<ISettingsAttribute
}
export class Settings extends XmlComponent {
private readonly compatibility;
private readonly trackRevisions;
private readonly compatibility: Compatibility;
private readonly trackRevisions: TrackRevisions;
constructor() {
super("w:settings");

View File

@ -1,7 +1,7 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { DeletedTextRun } from "./deleted-text-run";
import { FootnoteReferenceRun, PageNumber } from "../../index";
import { DeletedTextRun } from "./deleted-text-run";
describe("DeletedTextRun", () => {
describe("#constructor", () => {

View File

@ -1,12 +1,11 @@
import { IChangedAttributesProperties, ChangeAttributes } from "../track-revision";
import { XmlComponent } from "file/xml-components";
import { IRunOptions, RunProperties, IRunPropertiesOptions, FootnoteReferenceRun } from "../../index";
import { FootnoteReferenceRun, IRunOptions, IRunPropertiesOptions, RunProperties } from "../../index";
import { Break } from "../../paragraph/run/break";
import { Begin, Separate, End } from "../../paragraph/run/field";
import { Begin, End, Separate } from "../../paragraph/run/field";
import { PageNumber } from "../../paragraph/run/run";
import { DeletedPage, DeletedNumberOfPages, DeletedNumberOfPagesSection } from "./deleted-page-number";
import { ChangeAttributes, IChangedAttributesProperties } from "../track-revision";
import { DeletedNumberOfPages, DeletedNumberOfPagesSection, DeletedPage } from "./deleted-page-number";
import { DeletedText } from "./deleted-text";
interface IDeletedRunOptions extends IRunPropertiesOptions, IChangedAttributesProperties {

View File

@ -1,6 +1,7 @@
import { IChangedAttributesProperties, ChangeAttributes } from "../track-revision";
import { XmlComponent } from "file/xml-components";
import { TextRun, IRunOptions } from "../../index";
import { IRunOptions, TextRun } from "../../index";
import { ChangeAttributes, IChangedAttributesProperties } from "../track-revision";
interface IInsertedRunOptions extends IChangedAttributesProperties, IRunOptions {}

Some files were not shown because too many files have changed in this diff Show More