Compare commits
150 Commits
Author | SHA1 | Date | |
---|---|---|---|
d6f363b275 | |||
118ea57412 | |||
7c8be4c8a7 | |||
fa9021596f | |||
3ccf4bdfe3 | |||
f2480673ec | |||
e93b8032d8 | |||
5de2d8c7fb | |||
e355fd3d2e | |||
d41ef99c85 | |||
5ec18d6e01 | |||
b4cd3a319c | |||
d894bfa167 | |||
d74db948ba | |||
3ef26c747b | |||
38c8220e9e | |||
86f8259b33 | |||
502db14bba | |||
ef12ada5d7 | |||
977b2b302d | |||
17d02a3d1c | |||
6100ff4c4e | |||
8bb73fb25e | |||
d6cce4ae15 | |||
058304d16b | |||
345d34a2e1 | |||
3839a49d47 | |||
0afe0929a3 | |||
a14a1fbd10 | |||
52f0a6958a | |||
8bdde98db1 | |||
19fc900045 | |||
6bdd9b882a | |||
0d97d428fa | |||
a0b42d7bdb | |||
69ba312a96 | |||
a0c13214e6 | |||
4c8829df28 | |||
3ee3e95410 | |||
806deeaf78 | |||
feb121707d | |||
31c7f034ec | |||
30ab92652c | |||
0407548113 | |||
277845626c | |||
b2af8b970e | |||
542866e18b | |||
f54192809f | |||
f3ba62fd88 | |||
8d4a07302b | |||
d504231124 | |||
173b1e118c | |||
ffba276f0d | |||
b210608e56 | |||
74353104dc | |||
825136d1c9 | |||
b2fea471f1 | |||
e9adb8b0ed | |||
5d6bc039d0 | |||
27638063c8 | |||
f6a4d78ab7 | |||
4061e31400 | |||
74db67689f | |||
2213eb28cb | |||
d1b45d416b | |||
f72f7e7514 | |||
0165cfb3e5 | |||
ef747486c0 | |||
e0b2f59c2f | |||
82bdb301f9 | |||
c7ea26e422 | |||
34b2029efe | |||
37e610d2b3 | |||
4882235d20 | |||
1552ebde11 | |||
d263d0c8a5 | |||
610b2388bb | |||
bcb16cef9b | |||
0f3afd94f3 | |||
60eb686d05 | |||
7f5e43fba9 | |||
ed52ef358b | |||
214afab711 | |||
18a1677588 | |||
cae372e9ad | |||
ea5f9a48ab | |||
dcf755e756 | |||
d445c21ea1 | |||
6db0449ed0 | |||
ae37b1980f | |||
96f76906c4 | |||
19d9619785 | |||
5be195fd91 | |||
e36e9e1cf4 | |||
102d6aa55c | |||
daea8d2868 | |||
700a74fd4c | |||
32a84a5ad0 | |||
3c9f9474ce | |||
1e10686315 | |||
cae6405d9a | |||
a884ce94e5 | |||
065c17de74 | |||
09db2c528a | |||
2adfe532dd | |||
6cbe40cecb | |||
6b9467393e | |||
5125e77431 | |||
ab68ae0092 | |||
38079b6171 | |||
d584290f3d | |||
9b9baa9b4a | |||
c258310560 | |||
af0bf5ced5 | |||
57c480a6c6 | |||
25f7423533 | |||
0c068bb03b | |||
1822473abc | |||
93a7d607b2 | |||
d45213636c | |||
e196d9d917 | |||
cf88e50afd | |||
64e5814c31 | |||
37251c84f8 | |||
a576098639 | |||
2450fe83ce | |||
e1004440d2 | |||
491c7abd1c | |||
364ce6d856 | |||
ffb6b73bb7 | |||
6041c39a26 | |||
c54f0a52f6 | |||
6b87d9c038 | |||
1285304f97 | |||
58fae6b201 | |||
dc1f3aebe9 | |||
8a189161f2 | |||
6667595627 | |||
33befaab09 | |||
c91f135c28 | |||
08f9926e60 | |||
f323b293fb | |||
adc91929b0 | |||
c63cba5a0c | |||
7a48da440b | |||
05dda37b71 | |||
ee43585210 | |||
9aab68a8f8 | |||
4f8d435e16 | |||
a1b9be453b |
@ -7,6 +7,7 @@ indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
|
104
.github/workflows/default.yml
vendored
Normal file
104
.github/workflows/default.yml
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
name: Default
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Archive Production Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Test
|
||||
run: npm run test.coverage
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
prettier:
|
||||
name: Prettier
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Prettier
|
||||
run: npm run style
|
||||
demos:
|
||||
name: Run Demos
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
- name: Run demos
|
||||
run: |
|
||||
npm run ts-node -- ./demo/1-basic.ts
|
||||
npm run ts-node -- ./demo/2-declaritive-styles.ts
|
||||
npm run ts-node -- ./demo/3-numbering-and-bullet-points.ts
|
||||
npm run ts-node -- ./demo/4-basic-table.ts
|
||||
npm run ts-node -- ./demo/5-images.ts
|
||||
npm run ts-node -- ./demo/6-page-borders.ts
|
||||
npm run ts-node -- ./demo/7-landscape.ts
|
||||
npm run ts-node -- ./demo/8-header-footer.ts
|
||||
npm run ts-node -- ./demo/9-images-in-header-and-footer.ts
|
||||
npm run ts-node -- ./demo/10-my-cv.ts
|
||||
npm run ts-node -- ./demo/11-declaritive-styles-2.ts
|
||||
npm run ts-node -- ./demo/12-scaling-images.ts
|
||||
npm run ts-node -- ./demo/13-xml-styles.ts
|
||||
npm run ts-node -- ./demo/14-page-numbers.ts
|
||||
npm run ts-node -- ./demo/15-page-break-before.ts
|
||||
npm run ts-node -- ./demo/16-multiple-sections.ts
|
||||
npm run ts-node -- ./demo/17-footnotes.ts
|
||||
npm run ts-node -- ./demo/18-image-from-buffer.ts
|
||||
npm run ts-node -- ./demo/19-export-to-base64.ts
|
||||
npm run ts-node -- ./demo/20-table-cell-borders.ts
|
||||
npm run ts-node -- ./demo/21-bookmarks.ts
|
||||
npm run ts-node -- ./demo/22-right-to-left-text.ts
|
||||
npm run ts-node -- ./demo/23-base64-images.ts
|
||||
npm run ts-node -- ./demo/24-images-to-table-cell.ts
|
||||
npm run ts-node -- ./demo/26-paragraph-borders.ts
|
||||
npm run ts-node -- ./demo/27-declaritive-styles-3.ts
|
||||
npm run ts-node -- ./demo/28-table-of-contents.ts
|
||||
npm run ts-node -- ./demo/29-numbered-lists.ts
|
||||
npm run ts-node -- ./demo/30-template-document.ts
|
||||
npm run ts-node -- ./demo/31-tables.ts
|
||||
npm run ts-node -- ./demo/32-merge-and-shade-table-cells.ts
|
||||
npm run ts-node -- ./demo/33-sequential-captions.ts
|
||||
npm run ts-node -- ./demo/34-floating-tables.ts
|
@ -11,6 +11,7 @@
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![Downloads per month][downloads-image]][downloads-url]
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![GitHub Action Workflow Status][github-actions-workflow-image]][github-actions-workflow-url]
|
||||
[![Dependency Status][daviddm-image]][daviddm-url]
|
||||
[![Known Vulnerabilities][snky-image]][snky-url]
|
||||
[![Chat on Gitter][gitter-image]][gitter-url]
|
||||
@ -67,7 +68,7 @@ Please refer to the [documentation at https://docx.js.org/](https://docx.js.org/
|
||||
|
||||
# Examples
|
||||
|
||||
Check the `examples` section in the [documentation](https://docx.js.org/#/examples) and the [demo folder](https://github.com/dolanmiu/docx/tree/master/demo) for examples.
|
||||
Check the [demo folder](https://github.com/dolanmiu/docx/tree/master/demo) for examples.
|
||||
|
||||
# Contributing
|
||||
|
||||
@ -85,6 +86,7 @@ Read the contribution guidelines [here](https://docx.js.org/#/contribution-guide
|
||||
[<img src="https://i.imgur.com/QEZXU5b.png" alt="drawing" height="50"/>](https://www.beekast.com/)
|
||||
[<img src="https://imgur.com/XVU6aoi.png" alt="drawing" height="50"/>](https://herraizsoto.com/)
|
||||
[<img src="https://i.imgur.com/fn1xccG.png" alt="drawing" height="50"/>](http://www.ativer.com.br/)
|
||||
[<img src="https://i.imgur.com/cmykN7c.png" alt="drawing"/>](https://www.arity.co/)
|
||||
|
||||
|
||||
...and many more!
|
||||
@ -102,6 +104,8 @@ Made with 💖
|
||||
[downloads-url]: https://npmjs.org/package/docx
|
||||
[travis-image]: https://travis-ci.org/dolanmiu/docx.svg?branch=master
|
||||
[travis-url]: https://travis-ci.org/dolanmiu/docx
|
||||
[github-actions-workflow-image]: https://github.com/dolanmiu/docx/workflows/Default/badge.svg
|
||||
[github-actions-workflow-url]: https://github.com/dolanmiu/docx/actions
|
||||
[daviddm-image]: https://david-dm.org/dolanmiu/docx.svg?theme=shields.io
|
||||
[daviddm-url]: https://david-dm.org/dolanmiu/docx
|
||||
[snky-image]: https://snyk.io/test/github/dolanmiu/docx/badge.svg
|
||||
|
@ -204,7 +204,10 @@ class DocumentCreator {
|
||||
alignment: AlignmentType.CENTER,
|
||||
children: [
|
||||
new TextRun(`Mobile: ${phoneNumber} | LinkedIn: ${profileUrl} | Email: ${email}`),
|
||||
new TextRun("Address: 58 Elm Avenue, Kent ME4 6ER, UK").break(),
|
||||
new TextRun({
|
||||
text: "Address: 58 Elm Avenue, Kent ME4 6ER, UK",
|
||||
break: 1,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
AlignmentType,
|
||||
convertInchesToTwip,
|
||||
Document,
|
||||
Footer,
|
||||
HeadingLevel,
|
||||
@ -18,13 +19,8 @@ import {
|
||||
|
||||
const doc = new Document({
|
||||
styles: {
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: "Heading1",
|
||||
name: "Heading 1",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
default: {
|
||||
heading1: {
|
||||
run: {
|
||||
font: "Calibri",
|
||||
size: 52,
|
||||
@ -40,12 +36,7 @@ const doc = new Document({
|
||||
spacing: { line: 340 },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "Heading2",
|
||||
name: "Heading 2",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
heading2: {
|
||||
run: {
|
||||
font: "Calibri",
|
||||
size: 26,
|
||||
@ -55,12 +46,7 @@ const doc = new Document({
|
||||
spacing: { line: 340 },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "Heading3",
|
||||
name: "Heading 3",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
heading3: {
|
||||
run: {
|
||||
font: "Calibri",
|
||||
size: 26,
|
||||
@ -70,12 +56,7 @@ const doc = new Document({
|
||||
spacing: { line: 276 },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "Heading4",
|
||||
name: "Heading 4",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
heading4: {
|
||||
run: {
|
||||
font: "Calibri",
|
||||
size: 26,
|
||||
@ -85,6 +66,8 @@ const doc = new Document({
|
||||
alignment: AlignmentType.JUSTIFIED,
|
||||
},
|
||||
},
|
||||
},
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: "normalPara",
|
||||
name: "Normal Para",
|
||||
@ -128,7 +111,7 @@ const doc = new Document({
|
||||
},
|
||||
paragraph: {
|
||||
spacing: { line: 276 },
|
||||
indent: { left: 720 },
|
||||
indent: { left: convertInchesToTwip(0.5) },
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -139,12 +122,6 @@ const doc = new Document({
|
||||
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "ListParagraph",
|
||||
name: "List Paragraph",
|
||||
basedOn: "Normal",
|
||||
quickFormat: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
@ -1,20 +1,25 @@
|
||||
// Example on how to customise the look at feel using Styles
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType } from "../build";
|
||||
import {
|
||||
AlignmentType,
|
||||
convertInchesToTwip,
|
||||
Document,
|
||||
HeadingLevel,
|
||||
LevelFormat,
|
||||
Packer,
|
||||
Paragraph,
|
||||
TextRun,
|
||||
UnderlineType,
|
||||
} from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
creator: "Clippy",
|
||||
title: "Sample Document",
|
||||
description: "A brief example of using docx",
|
||||
styles: {
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: "Heading1",
|
||||
name: "Heading 1",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
default: {
|
||||
heading1: {
|
||||
run: {
|
||||
size: 28,
|
||||
bold: true,
|
||||
@ -27,12 +32,7 @@ const doc = new Document({
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "Heading2",
|
||||
name: "Heading 2",
|
||||
basedOn: "Normal",
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
heading2: {
|
||||
run: {
|
||||
size: 26,
|
||||
bold: true,
|
||||
@ -48,6 +48,13 @@ const doc = new Document({
|
||||
},
|
||||
},
|
||||
},
|
||||
listParagraph: {
|
||||
run: {
|
||||
color: "#FF0000",
|
||||
},
|
||||
},
|
||||
},
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: "aside",
|
||||
name: "Aside",
|
||||
@ -59,7 +66,7 @@ const doc = new Document({
|
||||
},
|
||||
paragraph: {
|
||||
indent: {
|
||||
left: 720,
|
||||
left: convertInchesToTwip(0.5),
|
||||
},
|
||||
spacing: {
|
||||
line: 276,
|
||||
@ -75,12 +82,6 @@ const doc = new Document({
|
||||
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "ListParagraph",
|
||||
name: "List Paragraph",
|
||||
basedOn: "Normal",
|
||||
quickFormat: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
numbering: {
|
||||
@ -90,7 +91,7 @@ const doc = new Document({
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerLetter",
|
||||
format: LevelFormat.LOWER_LETTER,
|
||||
text: "%1)",
|
||||
alignment: AlignmentType.LEFT,
|
||||
},
|
||||
@ -170,6 +171,17 @@ doc.addSection({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
style: "Strong",
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "Strong Style",
|
||||
}),
|
||||
new TextRun({
|
||||
text: " - Very strong.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Custom styles using JavaScript configuration
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, HeadingLevel, Packer, Paragraph, UnderlineType } from "../build";
|
||||
import { Document, convertInchesToTwip, HeadingLevel, Packer, Paragraph, UnderlineType } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
styles: {
|
||||
@ -17,7 +17,7 @@ const doc = new Document({
|
||||
},
|
||||
paragraph: {
|
||||
indent: {
|
||||
left: 720,
|
||||
left: convertInchesToTwip(0.5),
|
||||
},
|
||||
spacing: {
|
||||
line: 276,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Numbered lists
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
||||
import { AlignmentType, convertInchesToTwip, Document, LevelFormat, Packer, Paragraph } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
numbering: {
|
||||
@ -10,12 +10,12 @@ const doc = new Document({
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: "upperRoman",
|
||||
format: LevelFormat.UPPER_ROMAN,
|
||||
text: "%1",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 720, hanging: 260 },
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -26,18 +26,34 @@ const doc = new Document({
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: "decimal",
|
||||
format: LevelFormat.DECIMAL,
|
||||
text: "%1",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 720, hanging: 260 },
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
reference: "my-number-numbering-reference",
|
||||
},
|
||||
{
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.DECIMAL_ZERO,
|
||||
text: "[%1]",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
reference: "padded-numbering-reference",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@ -109,6 +125,139 @@ doc.addSection({
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "test",
|
||||
numbering: {
|
||||
reference: "padded-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Numbering and bullet points example
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
||||
import { AlignmentType, convertInchesToTwip, Document, LevelFormat, Packer, Paragraph } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
numbering: {
|
||||
@ -11,40 +11,40 @@ const doc = new Document({
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: "upperRoman",
|
||||
format: LevelFormat.UPPER_ROMAN,
|
||||
text: "%1",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 720, hanging: 260 },
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.18) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 1,
|
||||
format: "decimal",
|
||||
format: LevelFormat.DECIMAL,
|
||||
text: "%2.",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 1440, hanging: 980 },
|
||||
indent: { left: convertInchesToTwip(1), hanging: convertInchesToTwip(0.68) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
format: "lowerLetter",
|
||||
format: LevelFormat.LOWER_LETTER,
|
||||
text: "%3)",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 2160, hanging: 1700 },
|
||||
indent: { left: convertInchesToTwip(1.5), hanging: convertInchesToTwip(1.18) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
format: "upperLetter",
|
||||
format: LevelFormat.UPPER_LETTER,
|
||||
text: "%4)",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
|
@ -2,7 +2,20 @@
|
||||
// Also includes an example on how to center tables
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { AlignmentType, BorderStyle, Document, HeadingLevel, Packer, Paragraph, ShadingType, Table, TableCell, TableRow, WidthType } from "../build";
|
||||
import {
|
||||
AlignmentType,
|
||||
BorderStyle,
|
||||
convertInchesToTwip,
|
||||
Document,
|
||||
HeadingLevel,
|
||||
Packer,
|
||||
Paragraph,
|
||||
ShadingType,
|
||||
Table,
|
||||
TableCell,
|
||||
TableRow,
|
||||
WidthType,
|
||||
} from "../build";
|
||||
|
||||
const doc = new Document();
|
||||
|
||||
@ -37,10 +50,10 @@ const table2 = new Table({
|
||||
new TableCell({
|
||||
children: [new Paragraph("World")],
|
||||
margins: {
|
||||
top: 1000,
|
||||
bottom: 1000,
|
||||
left: 1000,
|
||||
right: 1000,
|
||||
top: convertInchesToTwip(0.69),
|
||||
bottom: convertInchesToTwip(0.69),
|
||||
left: convertInchesToTwip(0.69),
|
||||
right: convertInchesToTwip(0.69),
|
||||
},
|
||||
columnSpan: 3,
|
||||
}),
|
||||
@ -64,7 +77,7 @@ const table2 = new Table({
|
||||
size: 100,
|
||||
type: WidthType.AUTO,
|
||||
},
|
||||
columnWidths: [1000, 1000, 1000],
|
||||
columnWidths: [convertInchesToTwip(0.69), convertInchesToTwip(0.69), convertInchesToTwip(0.69)],
|
||||
});
|
||||
|
||||
const table3 = new Table({
|
||||
@ -119,14 +132,14 @@ const table3 = new Table({
|
||||
}),
|
||||
],
|
||||
width: {
|
||||
size: 7000,
|
||||
size: convertInchesToTwip(4.86),
|
||||
type: WidthType.DXA,
|
||||
},
|
||||
margins: {
|
||||
top: 400,
|
||||
bottom: 400,
|
||||
right: 400,
|
||||
left: 400,
|
||||
top: convertInchesToTwip(0.27),
|
||||
bottom: convertInchesToTwip(0.27),
|
||||
right: convertInchesToTwip(0.27),
|
||||
left: convertInchesToTwip(0.27),
|
||||
},
|
||||
});
|
||||
|
||||
@ -355,9 +368,7 @@ const table8 = new Table({
|
||||
],
|
||||
}),
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({ children: [new Paragraph("4,1")] }),
|
||||
],
|
||||
children: [new TableCell({ children: [new Paragraph("4,1")] })],
|
||||
}),
|
||||
],
|
||||
width: {
|
||||
|
@ -28,6 +28,18 @@ doc.addSection({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
shading: {
|
||||
type: ShadingType.DIAGONAL_CROSS,
|
||||
color: "00FFFF",
|
||||
fill: "FF0000",
|
||||
},
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "Hello World for entire paragraph",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
},
|
||||
|
@ -1,7 +1,19 @@
|
||||
// Add custom borders to the table itself
|
||||
// Add custom borders and no-borders to the table itself
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { BorderStyle, Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||
import {
|
||||
BorderStyle,
|
||||
Document,
|
||||
HeadingLevel,
|
||||
Packer,
|
||||
Paragraph,
|
||||
Table,
|
||||
TableBorders,
|
||||
TableCell,
|
||||
TableRow,
|
||||
TextDirection,
|
||||
VerticalAlign,
|
||||
} from "../build";
|
||||
|
||||
const doc = new Document();
|
||||
|
||||
@ -10,6 +22,28 @@ const table = new Table({
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
borders: {
|
||||
top: {
|
||||
style: BorderStyle.DASH_SMALL_GAP,
|
||||
size: 1,
|
||||
color: "red",
|
||||
},
|
||||
bottom: {
|
||||
style: BorderStyle.DASH_SMALL_GAP,
|
||||
size: 1,
|
||||
color: "red",
|
||||
},
|
||||
left: {
|
||||
style: BorderStyle.DASH_SMALL_GAP,
|
||||
size: 1,
|
||||
color: "red",
|
||||
},
|
||||
right: {
|
||||
style: BorderStyle.DASH_SMALL_GAP,
|
||||
size: 1,
|
||||
color: "red",
|
||||
},
|
||||
},
|
||||
children: [new Paragraph("Hello")],
|
||||
}),
|
||||
new TableCell({
|
||||
@ -30,7 +64,103 @@ const table = new Table({
|
||||
],
|
||||
});
|
||||
|
||||
doc.addSection({ children: [table] });
|
||||
// Using the no-border convenience object. It is the same as writing this manually:
|
||||
// const borders = {
|
||||
// top: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// bottom: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// left: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// right: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// insideHorizontal: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// insideVertical: {
|
||||
// style: BorderStyle.NONE,
|
||||
// size: 0,
|
||||
// color: "auto",
|
||||
// },
|
||||
// };
|
||||
const noBorderTable = new Table({
|
||||
borders: TableBorders.NONE,
|
||||
rows: [
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
children: [new Paragraph({}), new Paragraph({})],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({}), new Paragraph({})],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})],
|
||||
textDirection: TextDirection.BOTTOM_TO_TOP_LEFT_TO_RIGHT,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({ text: "top to bottom" }), new Paragraph({})],
|
||||
textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text:
|
||||
"Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "This text should be in the middle of the cell",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "Text above should be vertical from bottom to top",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "Text above should be vertical from top to bottom",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
doc.addSection({ children: [table, new Paragraph("Hello"), noBorderTable] });
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
|
@ -22,6 +22,7 @@ const image4 = Media.addImage(doc, fs.readFileSync("./demo/images/parrots.bmp"))
|
||||
const image5 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||
const image6 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"), 200, 200, {
|
||||
floating: {
|
||||
zIndex: 10,
|
||||
horizontalPosition: {
|
||||
offset: 1014400,
|
||||
},
|
||||
@ -33,6 +34,7 @@ const image6 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"), 2
|
||||
|
||||
const image7 = Media.addImage(doc, fs.readFileSync("./demo/images/cat.jpg"), 200, 200, {
|
||||
floating: {
|
||||
zIndex: 5,
|
||||
horizontalPosition: {
|
||||
relative: HorizontalPositionRelativeFrom.PAGE,
|
||||
align: HorizontalPositionAlign.RIGHT,
|
||||
|
@ -15,6 +15,14 @@ const doc = new Document({
|
||||
italics: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "strong",
|
||||
name: "Strong",
|
||||
basedOn: "Normal",
|
||||
run: {
|
||||
bold: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@ -29,6 +37,18 @@ doc.addSection({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "First Word",
|
||||
style: "strong",
|
||||
}),
|
||||
new TextRun({
|
||||
text:
|
||||
" - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
|
146
demo/54-track-revisions.ts
Normal file
146
demo/54-track-revisions.ts
Normal file
@ -0,0 +1,146 @@
|
||||
// Track Revisions aka. "Track Changes"
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
AlignmentType,
|
||||
DeletedTextRun,
|
||||
Document,
|
||||
Footer,
|
||||
FootnoteReferenceRun,
|
||||
InsertedTextRun,
|
||||
Packer,
|
||||
PageNumber,
|
||||
Paragraph,
|
||||
ShadingType,
|
||||
TextRun,
|
||||
} from "../build";
|
||||
|
||||
/*
|
||||
For reference, see
|
||||
- https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.insertedrun
|
||||
- https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.deletedrun
|
||||
|
||||
The method `addTrackRevisions()` adds an element `<w:trackRevisions />` to the `settings.xml` file. This specifies that the application shall track *new* revisions made to the existing document.
|
||||
See also https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.trackrevisions
|
||||
|
||||
Note that this setting enables to track *new changes* after teh file is generated, so this example will still show inserted and deleted text runs when you remove it.
|
||||
*/
|
||||
|
||||
const doc = new Document({
|
||||
footnotes: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a footnote"),
|
||||
new DeletedTextRun({
|
||||
text: " with some extra text which was deleted",
|
||||
id: 0,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
}),
|
||||
new InsertedTextRun({
|
||||
text: " and new content",
|
||||
id: 1,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
features: {
|
||||
trackRevisions: true,
|
||||
},
|
||||
});
|
||||
|
||||
const paragraph = new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a simple demo "),
|
||||
new TextRun({
|
||||
text: "on how to ",
|
||||
}),
|
||||
new InsertedTextRun({
|
||||
text: "mark a text as an insertion ",
|
||||
id: 0,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
}),
|
||||
new DeletedTextRun({
|
||||
text: "or a deletion.",
|
||||
id: 1,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
doc.addSection({
|
||||
properties: {},
|
||||
children: [
|
||||
paragraph,
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a demo "),
|
||||
new DeletedTextRun({
|
||||
break: 1,
|
||||
text: "in order",
|
||||
color: "red",
|
||||
bold: true,
|
||||
size: 24,
|
||||
font: {
|
||||
name: "Garamond",
|
||||
},
|
||||
shading: {
|
||||
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||
color: "00FFFF",
|
||||
fill: "FF0000",
|
||||
},
|
||||
id: 2,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
}),
|
||||
new InsertedTextRun({
|
||||
text: "to show how to ",
|
||||
bold: false,
|
||||
id: 3,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
}),
|
||||
new TextRun({
|
||||
bold: true,
|
||||
children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
footers: {
|
||||
default: new Footer({
|
||||
children: [
|
||||
new Paragraph({
|
||||
alignment: AlignmentType.CENTER,
|
||||
children: [
|
||||
new TextRun("Awesome LLC"),
|
||||
new TextRun({
|
||||
children: ["Page Number: ", PageNumber.CURRENT],
|
||||
}),
|
||||
new DeletedTextRun({
|
||||
children: [" to ", PageNumber.TOTAL_PAGES],
|
||||
id: 4,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
}),
|
||||
new InsertedTextRun({
|
||||
children: [" from ", PageNumber.TOTAL_PAGES],
|
||||
bold: true,
|
||||
id: 5,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
294
demo/55-math.ts
Normal file
294
demo/55-math.ts
Normal 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);
|
||||
});
|
33
demo/56-background-color.ts
Normal file
33
demo/56-background-color.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// Change background colour of whole document
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
background: {
|
||||
color: "C45911",
|
||||
},
|
||||
});
|
||||
|
||||
doc.addSection({
|
||||
properties: {},
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
88
demo/57-add-parent-numbered-lists.ts
Normal file
88
demo/57-add-parent-numbered-lists.ts
Normal file
@ -0,0 +1,88 @@
|
||||
// Numbered lists - Add parent number in sub number
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { AlignmentType, convertInchesToTwip, Document, HeadingLevel, LevelFormat, Packer, Paragraph } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
numbering: {
|
||||
config: [
|
||||
{
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.DECIMAL,
|
||||
text: "%1",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: 260 },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 1,
|
||||
format: LevelFormat.DECIMAL,
|
||||
text: "%1.%2",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 1.25 * convertInchesToTwip(0.5), hanging: 1.25 * 260 },
|
||||
},
|
||||
run: {
|
||||
bold: true,
|
||||
size: 18,
|
||||
font: "Times New Roman",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
reference: "my-number-numbering-reference",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
doc.addSection({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "How to make cake",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "Step 1 - Add sugar",
|
||||
numbering: {
|
||||
reference: "my-number-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "Step 2 - Add wheat",
|
||||
numbering: {
|
||||
reference: "my-number-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "Step 2a - Stir the wheat in a circle",
|
||||
numbering: {
|
||||
reference: "my-number-numbering-reference",
|
||||
level: 1,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "Step 3 - Put in oven",
|
||||
numbering: {
|
||||
reference: "my-number-numbering-reference",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
new Paragraph({
|
||||
text: "How to make cake",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
@ -53,11 +53,11 @@ Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
||||
|
||||
// Done! A file called 'My First Document.docx' will be in your file system.
|
||||
// Done! A file called 'My Document.docx' will be in your file system.
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img alt="clippy the assistant" src="http://i60.tinypic.com/339pvtt.png">
|
||||
<img alt="clippy the assistant" src="./clippy.png">
|
||||
</p>
|
||||
|
||||
---
|
||||
|
@ -20,12 +20,16 @@
|
||||
* [Tab Stops](usage/tab-stops.md)
|
||||
* [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)
|
||||
* Exporting
|
||||
|
||||
* [Packers](usage/packers.md)
|
||||
* Utility
|
||||
|
||||
* [Convenience functions](usage/convenience-functions.md)
|
||||
|
||||
* [Contribution Guidelines](contribution-guidelines.md)
|
||||
|
||||
|
BIN
docs/clippy.png
Normal file
BIN
docs/clippy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
docs/clippy.psd
Normal file
BIN
docs/clippy.psd
Normal file
Binary file not shown.
BIN
docs/images/math-example.png
Normal file
BIN
docs/images/math-example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -9,7 +9,7 @@ const text = new TextRun("Bullet points");
|
||||
const paragraph = new Paragraph({
|
||||
text: "Bullet points",
|
||||
bullet: {
|
||||
level: 0, // How deep you want the bullet to me
|
||||
level: 0, //How deep you want the bullet to be
|
||||
},
|
||||
});
|
||||
```
|
||||
|
61
docs/usage/change-tracking.md
Normal file
61
docs/usage/change-tracking.md
Normal file
@ -0,0 +1,61 @@
|
||||
# Change Tracking
|
||||
|
||||
> Instead of adding a `TextRun` into a `Paragraph`, you can also add an `InsertedTextRun` or `DeletedTextRun` where you need to supply an `id`, `author` and `date` for the change.
|
||||
|
||||
```ts
|
||||
import { Paragraph, TextRun, InsertedTextRun, DeletedTextRun } from "docx";
|
||||
|
||||
const paragraph = new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a simple demo "),
|
||||
new TextRun({
|
||||
text: "on how to "
|
||||
}),
|
||||
new InsertedTextRun({
|
||||
text: "mark a text as an insertion ",
|
||||
id: 0,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
}),
|
||||
new DeletedTextRun({
|
||||
text: "or a deletion.",
|
||||
id: 1,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
})
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
Note that for a `InsertedTextRun` and `DeletedTextRun`, it is not possible to simply call it with only a text as in `new TextRun("some text")`, since the additonal fields for change tracking need to be provided. Similar to a normal `TextRun` you can add additional text properties.
|
||||
|
||||
```ts
|
||||
import { Paragraph, TextRun, InsertedTextRun, DeletedTextRun } from "docx";
|
||||
|
||||
const paragraph = new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a simple demo"),
|
||||
new DeletedTextRun({
|
||||
text: "with a deletion.",
|
||||
color: "red",
|
||||
bold: true,
|
||||
size: 24,
|
||||
id: 0,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:00:00Z",
|
||||
})
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
In addtion to marking text as inserted or deleted, change tracking can also be added via the document settings. This will enable new changes to be tracked as well.
|
||||
|
||||
```ts
|
||||
import { Document } from "docx";
|
||||
|
||||
const doc = new Document({
|
||||
features: {
|
||||
trackRevisions: true,
|
||||
},
|
||||
});
|
||||
```
|
22
docs/usage/convenience-functions.md
Normal file
22
docs/usage/convenience-functions.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Convenience functions
|
||||
|
||||
OOXML and this library mainly uses a unit called twentieths of a point or `twip` for short. a twip is a typographical measurement, defined as 1/20 of a typographical point. One twip is 1/1440 inch, or 17.64 μm. This unit is not intuitive for many users, so some functions were created to help
|
||||
|
||||
More info here: https://en.wikipedia.org/wiki/Twip
|
||||
|
||||
## Convert Inches to Twip
|
||||
|
||||
```ts
|
||||
import { convertInchesToTwip } from "docx";
|
||||
|
||||
const twip = convertInchesToTwip(1); // returns 1440
|
||||
const twip = convertInchesToTwip(0.5); // returns 720
|
||||
```
|
||||
|
||||
## Convert Millimeters to Twip
|
||||
|
||||
```ts
|
||||
import { convertMillimetersToTwip } from "docx";
|
||||
|
||||
const twip = convertMillimetersToTwip(50); // returns 2834
|
||||
```
|
@ -30,6 +30,24 @@ const doc = new docx.Document({
|
||||
* keywords
|
||||
* lastModifiedBy
|
||||
* revision
|
||||
* externalStyles
|
||||
* styles
|
||||
* numbering
|
||||
* footnotes
|
||||
* hyperlinks
|
||||
* background
|
||||
|
||||
### Change background color of Document
|
||||
|
||||
Set the hex value in the document like so:
|
||||
|
||||
```ts
|
||||
const doc = new docx.Document({
|
||||
background: {
|
||||
color: "C45911",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You can mix and match whatever properties you want, or provide no properties.
|
||||
|
||||
|
@ -125,6 +125,7 @@ Full options you can pass into `floating` are:
|
||||
| lockAnchor | `boolean` | Optional |
|
||||
| behindDocument | `boolean` | Optional |
|
||||
| layoutInCell | `boolean` | Optional |
|
||||
| zIndex | `number` | Optional |
|
||||
|
||||
`HorizontalPositionOptions` are:
|
||||
|
||||
|
265
docs/usage/math.md
Normal file
265
docs/usage/math.md
Normal 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")],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
```
|
@ -142,6 +142,21 @@ const paragraph = new Paragraph({
|
||||
});
|
||||
```
|
||||
|
||||
## Shading
|
||||
|
||||
Add color to an entire paragraph block
|
||||
|
||||
```ts
|
||||
const paragraph = new Paragraph({
|
||||
text: "shading",
|
||||
shading: {
|
||||
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||
color: "00FFFF",
|
||||
fill: "FF0000",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Spacing
|
||||
|
||||
Adding spacing between paragraphs
|
||||
|
@ -51,19 +51,6 @@ const table = new Table({
|
||||
});
|
||||
```
|
||||
|
||||
### Pagination
|
||||
|
||||
#### Prevent row pagination
|
||||
|
||||
To prevent breaking contents of a row across multiple pages, call `cantSplit`:
|
||||
|
||||
```ts
|
||||
const table = new Table({
|
||||
rows: [],
|
||||
cantSplit: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Table Row
|
||||
|
||||
A table consists of multiple `table rows`. Table rows have a list of `children` which accepts a list of `table cells` explained below. You can create a simple `table row` like so:
|
||||
@ -103,7 +90,7 @@ Here is a list of options you can add to the `table row`:
|
||||
| children | `Array<TableCell>` | Required |
|
||||
| cantSplit | `boolean` | Optional |
|
||||
| tableHeader | `boolean` | Optional |
|
||||
| height | `{ value: number, rule: HeightRule }` | Optional |
|
||||
| height | `{ height: number, rule: HeightRule }` | Optional |
|
||||
|
||||
### Repeat row
|
||||
|
||||
@ -116,6 +103,19 @@ const row = new TableRow({
|
||||
});
|
||||
```
|
||||
|
||||
### Pagination
|
||||
|
||||
#### Prevent row pagination
|
||||
|
||||
To prevent breaking contents of a row across multiple pages, call `cantSplit`:
|
||||
|
||||
```ts
|
||||
const row = new Row({
|
||||
...,
|
||||
cantSplit: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Table Cells
|
||||
|
||||
Cells need to be added in the `table row`, you can create a table cell like:
|
||||
|
@ -77,40 +77,78 @@ const text = new TextRun({
|
||||
});
|
||||
```
|
||||
|
||||
### Shading and Highlighting
|
||||
|
||||
```ts
|
||||
const text = new TextRun({
|
||||
text: "shading",
|
||||
shading: {
|
||||
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||
color: "00FFFF",
|
||||
fill: "FF0000",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
const text = new TextRun({
|
||||
text: "highlighting",
|
||||
highlight: "yellow",
|
||||
});
|
||||
```
|
||||
|
||||
### Strike through
|
||||
|
||||
```ts
|
||||
text.strike();
|
||||
const text = new TextRun({
|
||||
text: "strike",
|
||||
strike: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Double strike through
|
||||
|
||||
```ts
|
||||
text.doubleStrike();
|
||||
const text = new TextRun({
|
||||
text: "doubleStrike",
|
||||
doubleStrike: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Superscript
|
||||
|
||||
```ts
|
||||
text.superScript();
|
||||
const text = new TextRun({
|
||||
text: "superScript",
|
||||
superScript: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Subscript
|
||||
|
||||
```ts
|
||||
text.subScript();
|
||||
const text = new TextRun({
|
||||
text: "subScript",
|
||||
subScript: true,
|
||||
});
|
||||
```
|
||||
|
||||
### All Capitals
|
||||
|
||||
```ts
|
||||
text.allCaps();
|
||||
const text = new TextRun({
|
||||
text: "allCaps",
|
||||
allCaps: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Small Capitals
|
||||
|
||||
```ts
|
||||
text.smallCaps();
|
||||
const text = new TextRun({
|
||||
text: "smallCaps",
|
||||
smallCaps: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Break
|
||||
@ -118,13 +156,17 @@ text.smallCaps();
|
||||
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
||||
|
||||
```ts
|
||||
text.break();
|
||||
const text = new TextRun({
|
||||
text: "break",
|
||||
break: 1,
|
||||
});
|
||||
```
|
||||
|
||||
## Chaining
|
||||
|
||||
What if you want to create a paragraph which is **_bold_** and **_italic_**?
|
||||
Adding two breaks:
|
||||
|
||||
```ts
|
||||
paragraph.bold().italics();
|
||||
const text = new TextRun({
|
||||
text: "break",
|
||||
break: 2,
|
||||
});
|
||||
```
|
||||
|
792
package-lock.json
generated
792
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docx",
|
||||
"version": "5.3.0",
|
||||
"version": "5.5.0",
|
||||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
@ -79,7 +79,7 @@
|
||||
"mocha-webpack": "^1.0.1",
|
||||
"nyc": "^15.1.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"prettier": "^2.0.5",
|
||||
"prettier": "^2.1.2",
|
||||
"prompt": "^1.0.0",
|
||||
"replace-in-file": "^3.1.0",
|
||||
"request": "^2.88.0",
|
||||
@ -87,9 +87,9 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"shelljs": "^0.8.4",
|
||||
"sinon": "^9.0.2",
|
||||
"ts-node": "^8.10.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"
|
||||
|
18
src/convenience-functions.spec.ts
Normal file
18
src/convenience-functions.spec.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { expect } from "chai";
|
||||
import { convertInchesToTwip, convertMillimetersToTwip } from "./convenience-functions";
|
||||
|
||||
describe("Utility", () => {
|
||||
describe("#convertMillimetersToTwip", () => {
|
||||
it("should call the underlying header's addChildElement for Paragraph", () => {
|
||||
expect(convertMillimetersToTwip(1000)).to.equal(56692);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#convertInchesToTwip", () => {
|
||||
it("should call the underlying header's addChildElement", () => {
|
||||
expect(convertInchesToTwip(1)).to.equal(1440);
|
||||
expect(convertInchesToTwip(0.5)).to.equal(720);
|
||||
expect(convertInchesToTwip(0.25)).to.equal(360);
|
||||
});
|
||||
});
|
||||
});
|
8
src/convenience-functions.ts
Normal file
8
src/convenience-functions.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// Twip - twentieths of a point
|
||||
export const convertMillimetersToTwip = (millimeters: number): number => {
|
||||
return Math.floor((millimeters / 25.4) * 72 * 20);
|
||||
};
|
||||
|
||||
export const convertInchesToTwip = (inches: number): number => {
|
||||
return Math.floor(inches * 72 * 20);
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
import { XmlComponent } from "file/xml-components";
|
||||
import { IDocumentBackgroundOptions } from "../document";
|
||||
|
||||
import { DocumentAttributes } from "../document/document-attributes";
|
||||
import { INumberingOptions } from "../numbering";
|
||||
@ -32,6 +33,10 @@ export interface IPropertiesOptions {
|
||||
readonly hyperlinks?: {
|
||||
readonly [key: string]: IInternalHyperlinkDefinition | IExternalHyperlinkDefinition;
|
||||
};
|
||||
readonly background?: IDocumentBackgroundOptions;
|
||||
readonly features?: {
|
||||
readonly trackRevisions?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export class CoreProperties extends XmlComponent {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { convertInchesToTwip } from "convenience-functions";
|
||||
import { Formatter } from "export/formatter";
|
||||
import { FooterWrapper } from "file/footer-wrapper";
|
||||
import { HeaderWrapper } from "file/header-wrapper";
|
||||
@ -18,10 +19,10 @@ describe("SectionProperties", () => {
|
||||
const properties = new SectionProperties({
|
||||
width: 11906,
|
||||
height: 16838,
|
||||
top: 1440,
|
||||
right: 1440,
|
||||
bottom: 1440,
|
||||
left: 1440,
|
||||
top: convertInchesToTwip(1),
|
||||
right: convertInchesToTwip(1),
|
||||
bottom: convertInchesToTwip(1),
|
||||
left: convertInchesToTwip(1),
|
||||
header: 708,
|
||||
footer: 708,
|
||||
gutter: 0,
|
||||
@ -30,7 +31,7 @@ describe("SectionProperties", () => {
|
||||
space: 708,
|
||||
count: 1,
|
||||
},
|
||||
linePitch: 360,
|
||||
linePitch: convertInchesToTwip(0.25),
|
||||
headers: {
|
||||
default: new HeaderWrapper(media, 100),
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
// http://officeopenxml.com/WPsection.php
|
||||
import { convertInchesToTwip } from "convenience-functions";
|
||||
import { FooterWrapper } from "file/footer-wrapper";
|
||||
import { HeaderWrapper } from "file/header-wrapper";
|
||||
import { XmlComponent } from "file/xml-components";
|
||||
@ -64,10 +65,10 @@ export class SectionProperties extends XmlComponent {
|
||||
const {
|
||||
width = 11906,
|
||||
height = 16838,
|
||||
top = 1440,
|
||||
right = 1440,
|
||||
bottom = 1440,
|
||||
left = 1440,
|
||||
top = convertInchesToTwip(1),
|
||||
right = convertInchesToTwip(1),
|
||||
bottom = convertInchesToTwip(1),
|
||||
left = convertInchesToTwip(1),
|
||||
header = 708,
|
||||
footer = 708,
|
||||
gutter = 0,
|
||||
|
@ -0,0 +1,53 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { Formatter } from "export/formatter";
|
||||
|
||||
import { DocumentBackground } from "./document-background";
|
||||
|
||||
describe("DocumentBackground", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("should create a DocumentBackground with no options and set color to auto", () => {
|
||||
const documentBackground = new DocumentBackground({});
|
||||
const tree = new Formatter().format(documentBackground);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:background": {
|
||||
_attr: {
|
||||
"w:color": "FFFFFF",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a DocumentBackground with no options and set color to value", () => {
|
||||
const documentBackground = new DocumentBackground({ color: "ffff00" });
|
||||
const tree = new Formatter().format(documentBackground);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:background": {
|
||||
_attr: {
|
||||
"w:color": "ffff00",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a DocumentBackground with no options and set other values", () => {
|
||||
const documentBackground = new DocumentBackground({
|
||||
color: "ffff00",
|
||||
themeColor: "test",
|
||||
themeShade: "test",
|
||||
themeTint: "test",
|
||||
});
|
||||
const tree = new Formatter().format(documentBackground);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:background": {
|
||||
_attr: {
|
||||
"w:color": "ffff00",
|
||||
"w:themeColor": "test",
|
||||
"w:themeShade": "test",
|
||||
"w:themeTint": "test",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
39
src/file/document/document-background/document-background.ts
Normal file
39
src/file/document/document-background/document-background.ts
Normal file
@ -0,0 +1,39 @@
|
||||
// http://officeopenxml.com/WPdocument.php
|
||||
// http://www.datypic.com/sc/ooxml/e-w_background-1.html
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
export class DocumentBackgroundAttributes extends XmlAttributeComponent<{
|
||||
readonly color: string;
|
||||
readonly themeColor?: string;
|
||||
readonly themeShade?: string;
|
||||
readonly themeTint?: string;
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
color: "w:color",
|
||||
themeColor: "w:themeColor",
|
||||
themeShade: "w:themeShade",
|
||||
themeTint: "w:themeTint",
|
||||
};
|
||||
}
|
||||
|
||||
export interface IDocumentBackgroundOptions {
|
||||
readonly color?: string;
|
||||
readonly themeColor?: string;
|
||||
readonly themeShade?: string;
|
||||
readonly themeTint?: string;
|
||||
}
|
||||
|
||||
export class DocumentBackground extends XmlComponent {
|
||||
constructor(options: IDocumentBackgroundOptions) {
|
||||
super("w:background");
|
||||
|
||||
this.root.push(
|
||||
new DocumentBackgroundAttributes({
|
||||
color: options.color ? options.color : "FFFFFF",
|
||||
themeColor: options.themeColor,
|
||||
themeShade: options.themeShade,
|
||||
themeTint: options.themeTint,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
1
src/file/document/document-background/index.ts
Normal file
1
src/file/document/document-background/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./document-background";
|
@ -8,7 +8,7 @@ describe("Document", () => {
|
||||
let document: Document;
|
||||
|
||||
beforeEach(() => {
|
||||
document = new Document();
|
||||
document = new Document({ background: {} });
|
||||
});
|
||||
|
||||
describe("#constructor()", () => {
|
||||
@ -38,6 +38,13 @@ describe("Document", () => {
|
||||
"mc:Ignorable": "w14 w15 wp14",
|
||||
},
|
||||
},
|
||||
{
|
||||
"w:background": {
|
||||
_attr: {
|
||||
"w:color": "FFFFFF",
|
||||
},
|
||||
},
|
||||
},
|
||||
{ "w:body": {} },
|
||||
],
|
||||
});
|
||||
|
@ -5,11 +5,16 @@ import { Table } from "../table";
|
||||
import { TableOfContents } from "../table-of-contents";
|
||||
import { Body } from "./body";
|
||||
import { DocumentAttributes } from "./document-attributes";
|
||||
import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background";
|
||||
|
||||
interface IDocumentOptions {
|
||||
readonly background: IDocumentBackgroundOptions;
|
||||
}
|
||||
|
||||
export class Document extends XmlComponent {
|
||||
private readonly body: Body;
|
||||
|
||||
constructor() {
|
||||
constructor(options: IDocumentOptions) {
|
||||
super("w:document");
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
@ -33,6 +38,7 @@ export class Document extends XmlComponent {
|
||||
}),
|
||||
);
|
||||
this.body = new Body();
|
||||
this.root.push(new DocumentBackground(options.background));
|
||||
this.root.push(this.body);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
export * from "./document";
|
||||
export * from "./document-attributes";
|
||||
export * from "./body";
|
||||
export * from "./document-background";
|
||||
|
@ -218,5 +218,150 @@ describe("Anchor", () => {
|
||||
const textWrap = newJson.root[6];
|
||||
assert.equal(textWrap.rootKey, "wp:wrapTopAndBottom");
|
||||
});
|
||||
|
||||
it("should create a Drawing with a margin", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
margins: {
|
||||
top: 10,
|
||||
left: 10,
|
||||
bottom: 10,
|
||||
right: 10,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
distT: 10,
|
||||
distB: 10,
|
||||
distL: 10,
|
||||
distR: 10,
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with a default margin", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
margins: {},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
distT: 0,
|
||||
distB: 0,
|
||||
distL: 0,
|
||||
distR: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with allowOverlap being false", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
allowOverlap: false,
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
allowOverlap: "0",
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with behindDocument being true", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
behindDocument: true,
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
behindDoc: "1",
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with locked being true", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
lockAnchor: true,
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
locked: "1",
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with locked being false", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
layoutInCell: false,
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
assert.include(anchorAttributes, {
|
||||
layoutInCell: "0",
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a Drawing with a certain z-index", () => {
|
||||
anchor = createAnchor({
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
zIndex: 120,
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
const anchorAttributes = newJson.root[0].root;
|
||||
|
||||
assert.include(anchorAttributes, {
|
||||
relativeHeight: 120,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -11,42 +11,32 @@ import { Extent } from "./../extent/extent";
|
||||
import { GraphicFrameProperties } from "./../graphic-frame/graphic-frame-properties";
|
||||
import { AnchorAttributes } from "./anchor-attributes";
|
||||
|
||||
const defaultOptions: IFloating = {
|
||||
export class Anchor extends XmlComponent {
|
||||
constructor(mediaData: IMediaData, dimensions: IMediaDataDimensions, drawingOptions: IDrawingOptions) {
|
||||
super("wp:anchor");
|
||||
|
||||
const floating: IFloating = {
|
||||
allowOverlap: true,
|
||||
behindDocument: false,
|
||||
lockAnchor: false,
|
||||
layoutInCell: true,
|
||||
verticalPosition: {},
|
||||
horizontalPosition: {},
|
||||
};
|
||||
|
||||
export class Anchor extends XmlComponent {
|
||||
constructor(mediaData: IMediaData, dimensions: IMediaDataDimensions, drawingOptions: IDrawingOptions) {
|
||||
super("wp:anchor");
|
||||
|
||||
const floating = {
|
||||
margins: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
...defaultOptions,
|
||||
...drawingOptions.floating,
|
||||
};
|
||||
|
||||
this.root.push(
|
||||
new AnchorAttributes({
|
||||
distT: floating.margins.top || 0,
|
||||
distB: floating.margins.bottom || 0,
|
||||
distL: floating.margins.left || 0,
|
||||
distR: floating.margins.right || 0,
|
||||
distT: floating.margins ? floating.margins.top || 0 : 0,
|
||||
distB: floating.margins ? floating.margins.bottom || 0 : 0,
|
||||
distL: floating.margins ? floating.margins.left || 0 : 0,
|
||||
distR: floating.margins ? floating.margins.right || 0 : 0,
|
||||
simplePos: "0", // note: word doesn't fully support - so we use 0
|
||||
allowOverlap: floating.allowOverlap === true ? "1" : "0",
|
||||
behindDoc: floating.behindDocument === true ? "1" : "0",
|
||||
locked: floating.lockAnchor === true ? "1" : "0",
|
||||
layoutInCell: floating.layoutInCell === true ? "1" : "0",
|
||||
relativeHeight: dimensions.emus.y,
|
||||
relativeHeight: floating.zIndex ? floating.zIndex : dimensions.emus.y,
|
||||
}),
|
||||
);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// http://officeopenxml.com/drwPicFloating-position.php
|
||||
// http://officeopenxml.com/drwPicFloating.php
|
||||
import { ITextWrapping } from "../text-wrap";
|
||||
|
||||
export enum HorizontalPositionRelativeFrom {
|
||||
@ -67,4 +68,5 @@ export interface IFloating {
|
||||
readonly layoutInCell?: boolean;
|
||||
readonly margins?: IMargins;
|
||||
readonly wrap?: ITextWrapping;
|
||||
readonly zIndex?: number;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -5,7 +5,7 @@ import { Formatter } from "export/formatter";
|
||||
|
||||
import { File } from "./file";
|
||||
import { Footer, Header } from "./header";
|
||||
import { HyperlinkRef, Paragraph } from "./paragraph";
|
||||
import { HyperlinkRef, HyperlinkType, Paragraph } from "./paragraph";
|
||||
import { Table, TableCell, TableRow } from "./table";
|
||||
import { TableOfContents } from "./table-of-contents";
|
||||
|
||||
@ -243,12 +243,40 @@ describe("File", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addTrackRevisionsFeature", () => {
|
||||
it("should call the underlying document's add", () => {
|
||||
const file = new File({
|
||||
features: {
|
||||
trackRevisions: true,
|
||||
},
|
||||
});
|
||||
|
||||
// tslint:disable-next-line: no-unused-expression no-string-literal
|
||||
expect(file.Settings["trackRevisions"]).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe("#HyperlinkCache", () => {
|
||||
it("should initially have empty hyperlink cache", () => {
|
||||
const file = new File();
|
||||
|
||||
expect(file.HyperlinkCache).to.deep.equal({});
|
||||
});
|
||||
|
||||
it("should have hyperlink cache when option is added", () => {
|
||||
const file = new File({
|
||||
hyperlinks: {
|
||||
myCoolLink: {
|
||||
link: "http://www.example.com",
|
||||
text: "Hyperlink",
|
||||
type: HyperlinkType.EXTERNAL,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// tslint:disable-next-line: no-unused-expression no-string-literal
|
||||
expect(file.HyperlinkCache["myCoolLink"]).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe("#createFootnote", () => {
|
||||
|
@ -85,7 +85,7 @@ export class File {
|
||||
this.appProperties = new AppProperties();
|
||||
this.footNotes = new FootNotes();
|
||||
this.contentTypes = new ContentTypes();
|
||||
this.document = new Document();
|
||||
this.document = new Document({ background: options.background || {} });
|
||||
this.settings = new Settings();
|
||||
|
||||
this.media = fileProperties.template && fileProperties.template.media ? fileProperties.template.media : new Media();
|
||||
@ -106,7 +106,7 @@ export class File {
|
||||
this.styles = stylesFactory.newInstance(options.externalStyles);
|
||||
} else if (options.styles) {
|
||||
const stylesFactory = new DefaultStylesFactory();
|
||||
const defaultStyles = stylesFactory.newInstance();
|
||||
const defaultStyles = stylesFactory.newInstance(options.styles.default);
|
||||
this.styles = new Styles({
|
||||
...defaultStyles,
|
||||
...options.styles,
|
||||
@ -170,6 +170,12 @@ export class File {
|
||||
|
||||
this.hyperlinkCache = cache;
|
||||
}
|
||||
|
||||
if (options.features) {
|
||||
if (options.features.trackRevisions) {
|
||||
this.settings.addTrackRevisions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public addSection({
|
||||
|
@ -13,3 +13,4 @@ export * from "./header-wrapper";
|
||||
export * from "./footer-wrapper";
|
||||
export * from "./header";
|
||||
export * from "./footnotes";
|
||||
export * from "./track-revision";
|
||||
|
@ -7,7 +7,7 @@ import { AlignmentType, EmphasisMarkType, TabStopPosition } from "../paragraph";
|
||||
import { UnderlineType } from "../paragraph/run/underline";
|
||||
import { ShadingType } from "../table";
|
||||
import { AbstractNumbering } from "./abstract-numbering";
|
||||
import { LevelSuffix } from "./level";
|
||||
import { LevelFormat, LevelSuffix } from "./level";
|
||||
|
||||
describe("AbstractNumbering", () => {
|
||||
it("stores its ID at its .id property", () => {
|
||||
@ -20,7 +20,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 3,
|
||||
format: "lowerLetter",
|
||||
format: LevelFormat.LOWER_LETTER,
|
||||
text: "%1)",
|
||||
alignment: AlignmentType.END,
|
||||
},
|
||||
@ -29,7 +29,7 @@ describe("AbstractNumbering", () => {
|
||||
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:numFmt": { _attr: { "w:val": LevelFormat.LOWER_LETTER } } });
|
||||
expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
|
||||
});
|
||||
|
||||
@ -37,7 +37,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 3,
|
||||
format: "lowerLetter",
|
||||
format: LevelFormat.LOWER_LETTER,
|
||||
text: "%1)",
|
||||
},
|
||||
]);
|
||||
@ -45,7 +45,7 @@ describe("AbstractNumbering", () => {
|
||||
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:numFmt": { _attr: { "w:val": LevelFormat.LOWER_LETTER } } });
|
||||
expect(tree["w:abstractNum"][2]["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
|
||||
});
|
||||
|
||||
@ -53,7 +53,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 3,
|
||||
format: "lowerLetter",
|
||||
format: LevelFormat.LOWER_LETTER,
|
||||
text: "%1)",
|
||||
alignment: AlignmentType.END,
|
||||
suffix: LevelSuffix.SPACE,
|
||||
@ -68,7 +68,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -87,7 +87,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -106,7 +106,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -125,7 +125,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -144,7 +144,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -163,7 +163,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -182,7 +182,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -216,7 +216,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -239,7 +239,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -262,7 +262,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -281,7 +281,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
paragraph: {
|
||||
@ -324,7 +324,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: { size, sizeComplexScript },
|
||||
@ -340,7 +340,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -359,7 +359,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -378,7 +378,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -398,7 +398,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -417,7 +417,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -436,7 +436,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -455,7 +455,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -485,7 +485,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -533,7 +533,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: { bold, boldComplexScript },
|
||||
@ -566,7 +566,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: { italics, italicsComplexScript },
|
||||
@ -604,7 +604,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: { highlight, highlightComplexScript },
|
||||
@ -682,7 +682,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: { shadow, shading, shadingComplexScript },
|
||||
@ -699,7 +699,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -718,7 +718,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -739,7 +739,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -763,7 +763,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -782,7 +782,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
@ -804,7 +804,7 @@ describe("AbstractNumbering", () => {
|
||||
const abstractNumbering = new AbstractNumbering(1, [
|
||||
{
|
||||
level: 0,
|
||||
format: "lowerRoman",
|
||||
format: LevelFormat.LOWER_ROMAN,
|
||||
text: "%0.",
|
||||
style: {
|
||||
run: {
|
||||
|
@ -1,8 +1,26 @@
|
||||
// http://officeopenxml.com/WPnumbering-numFmt.php
|
||||
import { Attributes, XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
import { AlignmentType } from "../paragraph/formatting";
|
||||
import { IParagraphStylePropertiesOptions, ParagraphProperties } from "../paragraph/properties";
|
||||
import { IRunStylePropertiesOptions, RunProperties } from "../paragraph/run/properties";
|
||||
|
||||
export enum LevelFormat {
|
||||
BULLET = "bullet",
|
||||
CARDINAL_TEXT = "cardinalText",
|
||||
CHICAGO = "chicago",
|
||||
DECIMAL = "decimal",
|
||||
DECIMAL_ENCLOSED_CIRCLE = "decimalEnclosedCircle",
|
||||
DECIMAL_ENCLOSED_FULLSTOP = "decimalEnclosedFullstop",
|
||||
DECIMAL_ENCLOSED_PARENTHESES = "decimalEnclosedParen",
|
||||
DECIMAL_ZERO = "decimalZero",
|
||||
LOWER_LETTER = "lowerLetter",
|
||||
LOWER_ROMAN = "lowerRoman",
|
||||
NONE = "none",
|
||||
ORDINAL_TEXT = "ordinalText",
|
||||
UPPER_LETTER = "upperLetter",
|
||||
UPPER_ROMAN = "upperRoman",
|
||||
}
|
||||
|
||||
interface ILevelAttributesProperties {
|
||||
readonly ilvl?: number;
|
||||
readonly tentative?: number;
|
||||
@ -67,7 +85,7 @@ export enum LevelSuffix {
|
||||
|
||||
export interface ILevelsOptions {
|
||||
readonly level: number;
|
||||
readonly format?: string;
|
||||
readonly format?: LevelFormat;
|
||||
readonly text?: string;
|
||||
readonly alignment?: AlignmentType;
|
||||
readonly start?: number;
|
||||
|
@ -1,10 +1,11 @@
|
||||
// http://officeopenxml.com/WPnumbering.php
|
||||
import { convertInchesToTwip } from "convenience-functions";
|
||||
import { AlignmentType } from "file/paragraph";
|
||||
import { IXmlableObject, XmlComponent } from "file/xml-components";
|
||||
|
||||
import { DocumentAttributes } from "../document/document-attributes";
|
||||
import { AbstractNumbering } from "./abstract-numbering";
|
||||
import { ILevelsOptions } from "./level";
|
||||
import { ILevelsOptions, LevelFormat } from "./level";
|
||||
import { ConcreteNumbering } from "./num";
|
||||
|
||||
export interface INumberingOptions {
|
||||
@ -50,100 +51,100 @@ export class Numbering extends XmlComponent {
|
||||
const abstractNumbering = this.createAbstractNumbering([
|
||||
{
|
||||
level: 0,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CF",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 720, hanging: 360 },
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 1,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CB",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 1440, hanging: 360 },
|
||||
indent: { left: convertInchesToTwip(1), hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25A0",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 2160, hanging: 360 },
|
||||
indent: { left: 2160, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CF",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 2880, hanging: 360 },
|
||||
indent: { left: 2880, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 4,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CB",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 3600, hanging: 360 },
|
||||
indent: { left: 3600, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 5,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25A0",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 4320, hanging: 360 },
|
||||
indent: { left: 4320, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 6,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CF",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 5040, hanging: 360 },
|
||||
indent: { left: 5040, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 7,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CF",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 5760, hanging: 360 },
|
||||
indent: { left: 5760, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
level: 8,
|
||||
format: "bullet",
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u25CF",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 6480, hanging: 360 },
|
||||
indent: { left: 6480, hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3,3 +3,4 @@ export * from "./paragraph";
|
||||
export * from "./properties";
|
||||
export * from "./run";
|
||||
export * from "./links";
|
||||
export * from "./math";
|
||||
|
4
src/file/paragraph/math/brackets/index.ts
Normal file
4
src/file/paragraph/math/brackets/index.ts
Normal 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";
|
@ -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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
20
src/file/paragraph/math/brackets/math-angled-brackets.ts
Normal file
20
src/file/paragraph/math/brackets/math-angled-brackets.ts
Normal 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));
|
||||
}
|
||||
}
|
@ -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": "[",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
14
src/file/paragraph/math/brackets/math-beginning-character.ts
Normal file
14
src/file/paragraph/math/brackets/math-beginning-character.ts
Normal 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 }));
|
||||
}
|
||||
}
|
@ -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": "]",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
16
src/file/paragraph/math/brackets/math-bracket-properties.ts
Normal file
16
src/file/paragraph/math/brackets/math-bracket-properties.ts
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
51
src/file/paragraph/math/brackets/math-curly-brackets.spec.ts
Normal file
51
src/file/paragraph/math/brackets/math-curly-brackets.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
20
src/file/paragraph/math/brackets/math-curly-brackets.ts
Normal file
20
src/file/paragraph/math/brackets/math-curly-brackets.ts
Normal 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));
|
||||
}
|
||||
}
|
14
src/file/paragraph/math/brackets/math-ending-char.ts
Normal file
14
src/file/paragraph/math/brackets/math-ending-char.ts
Normal 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 }));
|
||||
}
|
||||
}
|
@ -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": "]",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
36
src/file/paragraph/math/brackets/math-round-brackets.spec.ts
Normal file
36
src/file/paragraph/math/brackets/math-round-brackets.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
15
src/file/paragraph/math/brackets/math-round-brackets.ts
Normal file
15
src/file/paragraph/math/brackets/math-round-brackets.ts
Normal 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));
|
||||
}
|
||||
}
|
@ -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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
20
src/file/paragraph/math/brackets/math-square-brackets.ts
Normal file
20
src/file/paragraph/math/brackets/math-square-brackets.ts
Normal 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));
|
||||
}
|
||||
}
|
3
src/file/paragraph/math/fraction/index.ts
Normal file
3
src/file/paragraph/math/fraction/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./math-fraction";
|
||||
export * from "./math-denominator";
|
||||
export * from "./math-numerator";
|
26
src/file/paragraph/math/fraction/math-denominator.spec.ts
Normal file
26
src/file/paragraph/math/fraction/math-denominator.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
13
src/file/paragraph/math/fraction/math-denominator.ts
Normal file
13
src/file/paragraph/math/fraction/math-denominator.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
44
src/file/paragraph/math/fraction/math-fraction.spec.ts
Normal file
44
src/file/paragraph/math/fraction/math-fraction.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
19
src/file/paragraph/math/fraction/math-fraction.ts
Normal file
19
src/file/paragraph/math/fraction/math-fraction.ts
Normal 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));
|
||||
}
|
||||
}
|
26
src/file/paragraph/math/fraction/math-numerator.spec.ts
Normal file
26
src/file/paragraph/math/fraction/math-numerator.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
13
src/file/paragraph/math/fraction/math-numerator.ts
Normal file
13
src/file/paragraph/math/fraction/math-numerator.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
3
src/file/paragraph/math/function/index.ts
Normal file
3
src/file/paragraph/math/function/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./math-function";
|
||||
export * from "./math-function-name";
|
||||
export * from "./math-function-properties";
|
27
src/file/paragraph/math/function/math-function-name.spec.ts
Normal file
27
src/file/paragraph/math/function/math-function-name.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
13
src/file/paragraph/math/function/math-function-name.ts
Normal file
13
src/file/paragraph/math/function/math-function-name.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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": {},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -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");
|
||||
}
|
||||
}
|
48
src/file/paragraph/math/function/math-function.spec.ts
Normal file
48
src/file/paragraph/math/function/math-function.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
22
src/file/paragraph/math/function/math-function.ts
Normal file
22
src/file/paragraph/math/function/math-function.ts
Normal 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));
|
||||
}
|
||||
}
|
9
src/file/paragraph/math/index.ts
Normal file
9
src/file/paragraph/math/index.ts
Normal 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";
|
27
src/file/paragraph/math/math-component.ts
Normal file
27
src/file/paragraph/math/math-component.ts
Normal file
@ -0,0 +1,27 @@
|
||||
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;
|
||||
|
||||
// Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
export const WORKAROUND4 = "";
|
21
src/file/paragraph/math/math-run.spec.ts
Normal file
21
src/file/paragraph/math/math-run.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
12
src/file/paragraph/math/math-run.ts
Normal file
12
src/file/paragraph/math/math-run.ts
Normal 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));
|
||||
}
|
||||
}
|
17
src/file/paragraph/math/math-text.spec.ts
Normal file
17
src/file/paragraph/math/math-text.spec.ts
Normal 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"],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
9
src/file/paragraph/math/math-text.ts
Normal file
9
src/file/paragraph/math/math-text.ts
Normal 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);
|
||||
}
|
||||
}
|
38
src/file/paragraph/math/math.spec.ts
Normal file
38
src/file/paragraph/math/math.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
18
src/file/paragraph/math/math.ts
Normal file
18
src/file/paragraph/math/math.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
7
src/file/paragraph/math/n-ary/index.ts
Normal file
7
src/file/paragraph/math/n-ary/index.ts
Normal 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";
|
22
src/file/paragraph/math/n-ary/math-accent-character.spec.ts
Normal file
22
src/file/paragraph/math/n-ary/math-accent-character.spec.ts
Normal 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": "∑",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
14
src/file/paragraph/math/n-ary/math-accent-character.ts
Normal file
14
src/file/paragraph/math/n-ary/math-accent-character.ts
Normal 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 }));
|
||||
}
|
||||
}
|
27
src/file/paragraph/math/n-ary/math-base.spec.ts
Normal file
27
src/file/paragraph/math/n-ary/math-base.spec.ts
Normal 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"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
14
src/file/paragraph/math/n-ary/math-base.ts
Normal file
14
src/file/paragraph/math/n-ary/math-base.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
22
src/file/paragraph/math/n-ary/math-limit-location.spec.ts
Normal file
22
src/file/paragraph/math/n-ary/math-limit-location.spec.ts
Normal 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",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
14
src/file/paragraph/math/n-ary/math-limit-location.ts
Normal file
14
src/file/paragraph/math/n-ary/math-limit-location.ts
Normal 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" }));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user