Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
8583aa0632 | |||
7682745402 | |||
2eb0b537f1 | |||
6d3ebf90c1 | |||
ed8b4180f8 | |||
4ad34920b7 | |||
ede6a32537 | |||
078d4908c2 | |||
c9135953f7 | |||
5259f30752 | |||
2223cfb6b2 | |||
345ce6db6d | |||
7accb91195 | |||
2bb9a78d2f | |||
f303306935 | |||
c82ad9711b | |||
41acda6a06 | |||
5d7ef7ab58 | |||
29f7f1a240 | |||
6b0d777bd7 | |||
455e66f74d | |||
36af1643a4 | |||
3a022c4d2a | |||
e50a6edbed | |||
31728ea253 | |||
5289ea8e1c | |||
d808b287a7 | |||
5ad7fd8a15 | |||
74fbc715e9 | |||
1385a5d702 | |||
e08ad990a8 | |||
35d987430a | |||
bb48068408 | |||
75d62723b6 | |||
02222c8681 | |||
c3800c4559 | |||
e598faad28 |
15
.github/workflows/demos.yml
vendored
15
.github/workflows/demos.yml
vendored
@ -202,13 +202,14 @@ jobs:
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/19-export-to-base64.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
# Base 64 No longer works, abruptly. Node issue?
|
||||
# - name: Extract Word Document
|
||||
# run: npm run extract
|
||||
# - name: Validate XML
|
||||
# uses: ChristophWurst/xmllint-action@v1
|
||||
# with:
|
||||
# xml-file: build/extracted-doc/word/document.xml
|
||||
# xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/20-table-cell-borders.ts
|
||||
- name: Extract Word Document
|
||||
|
6
.nycrc
6
.nycrc
@ -1,9 +1,9 @@
|
||||
{
|
||||
"check-coverage": true,
|
||||
"lines": 99.32,
|
||||
"functions": 99.11,
|
||||
"branches": 96.27,
|
||||
"statements": 99.32,
|
||||
"branches": 96.27,
|
||||
"functions": 99.11,
|
||||
"lines": 99.32,
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
|
@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img alt="clippy the assistant" src="https://i.imgur.com/37uBGhO.gif">
|
||||
<img src="./logo/logo-animate.svg" width="100%" height="300" alt="clippy the assistant">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@ -85,8 +85,9 @@ 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://i.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/)
|
||||
[<img src="https://i.imgur.com/cmykN7c.png" alt="drawing"/>](https://www.arity.co/)
|
||||
[<img src="https://i.imgur.com/PXo25um.png" alt="drawing" height="50"/>](https://www.circadianrisk.com/)
|
||||
[<img src="https://i.imgur.com/AKGhtlh.png" alt="drawing"/>](https://lexense.com/)
|
||||
|
||||
|
||||
...and many more!
|
||||
|
@ -113,6 +113,16 @@ const doc = new Document({
|
||||
bold: true,
|
||||
children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||
}),
|
||||
new TextRun({
|
||||
bold: true,
|
||||
text: "And some style changes",
|
||||
revision: {
|
||||
id: 4,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
bold: false,
|
||||
}
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
@ -12,7 +12,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
text: "Bullet points",
|
||||
bullet: {
|
||||
level: 0 //How deep you want the bullet to be
|
||||
level: 0 // How deep you want the bullet to be. Maximum level is 9
|
||||
}
|
||||
}),
|
||||
new Paragraph({
|
||||
|
@ -59,3 +59,18 @@ const doc = new Document({
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you want to express a style changes, you can add a `revision` to a `TextRun` which need to include all previous style attributes.
|
||||
|
||||
```ts
|
||||
new TextRun({
|
||||
bold: true,
|
||||
text: "This text is now bold and was previously not",
|
||||
revision: {
|
||||
id: 1,
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
bold: false,
|
||||
}
|
||||
}).break()
|
||||
````
|
||||
|
15
logo/logo-animate.svg
Normal file
15
logo/logo-animate.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 1200 600" xml:space="preserve">
|
||||
<style>
|
||||
.st0{fill:#2B579A;}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #fff; }
|
||||
}
|
||||
</style>
|
||||
<path id="X" d="m1009.42 294.26 90.58 216.8h-35.63l-76.09-187.21-75.49 187.21h-35.03l92.4-219.21-85.75-203.52h36.23l70.05 176.34 65.82-176.34h34.42l-81.51 205.93z"/>
|
||||
<path id="C" d="M837.51 426.82c0 60.39-32.61 89.38-96.62 89.38h-1.21c-64.01 0-96.62-28.38-96.62-89.38V173.18c0-57.97 32.61-89.38 96.62-89.38h1.21c64.01 0 96.62 31.4 96.62 89.38v72.47H804.9v-61.6c0-49.52-17.51-70.05-64.62-70.05-47.1 0-64.62 20.53-64.62 70.05v231.89c0 49.52 17.51 70.05 64.62 70.05 47.1 0 64.62-20.53 64.62-70.05v-71.86h32.61v82.74z"/>
|
||||
<path id="O" class="st0" d="M450.95 83.82c2.71.26 5.42.49 8.13.79 15.24 1.66 29.25 6.4 40.96 16.68 10.94 9.62 17.43 21.88 20.97 35.84a76.36 76.36 0 0 1 2.28 18.8c-.03 86.6-.01 173.2-.04 259.8a58.86 58.86 0 0 1-8.11 29.93c-7.35 12.68-18.54 19.97-32.83 22.46-12.27 2.14-24.47 1.56-36.32-2.45-17.14-5.81-27.01-18.1-30.48-35.61-.87-4.4-1.03-8.99-1.1-13.51-.16-10-.05-20.01-.05-30.01V168.27c0-7.04 4.19-10.9 11.29-10.25 1.88.17 3.81.59 5.55 1.31 3.12 1.29 4.69 3.69 4.69 7.22-.03 82.93-.03 165.87-.02 248.8 0 15.01 10.45 28.32 24.92 31.6a38.74 38.74 0 0 0 20.16-.6c10.74-3.27 16.83-10.95 19.56-21.5a35.05 35.05 0 0 0 1.14-8.77c.06-87.53.19-175.06-.07-262.59-.05-17.27-7.1-31.7-21.8-41.66-6.46-4.38-13.78-6.65-21.46-7.74-10.77-1.52-21.49-1.19-31.92 2.09-17.94 5.63-28.41 18.23-32.67 36.19a56.84 56.84 0 0 0-1.45 12.93c-.08 86.6-.13 173.2 0 259.8.03 18.77 4.97 36.32 15.53 52 10.75 15.96 26 25.08 44.85 28.24 15.3 2.56 30.51 1.86 45.37-2.6 24.06-7.22 38.48-23.7 44.77-47.69a92.5 92.5 0 0 0 2.74-28.17c-.05-.87-.04-1.74-.04-2.62V155.51c0-7.45 4.58-11.41 12.11-10.44.81.1 1.61.23 2.4.42 3.53.83 6.05 2.82 7.17 6.37v267.31c-.13.56-.33 1.11-.37 1.68a121.32 121.32 0 0 1-8.14 36.58c-13.92 35.27-39.92 54.47-77.59 58.02l-7.78.74h-8.72l-2.57-.37c-6.55-.84-13.21-1.22-19.65-2.61-23.98-5.2-42.64-18.19-55.3-39.33a114.04 114.04 0 0 1-16.33-59.24c-.13-86.17-.04-172.34-.07-258.52 0-6.38.69-12.63 2.23-18.8 3.53-14.09 10.06-26.46 21.12-36.13 11.73-10.26 25.74-14.98 40.98-16.61 2.65-.28 5.3-.52 7.95-.78 2.66.02 5.33.02 8.01.02z"/>
|
||||
<path id="D" d="M295.06 178.01v243.97c0 59.18-32.61 89.38-96.62 89.38H100V88.64h98.43c64.02 0 96.63 30.19 96.63 89.37zm-99.04-59.18h-63.41v362.34h63.41c47.71 0 66.43-19.93 66.43-70.05V188.88c0-50.12-18.72-70.05-66.43-70.05z"/>
|
||||
<path id="bar" d="M1118.5 25h10v550h-10z">
|
||||
<animate attributeName="visibility" values="hidden;visible" dur="2s" repeatCount="indefinite" />
|
||||
</path>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
12
logo/logo.svg
Normal file
12
logo/logo.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 1200 600" xml:space="preserve">
|
||||
<style>
|
||||
.st0{fill:#2B579A;}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #fff; }
|
||||
}
|
||||
</style>
|
||||
<path id="X" d="m1009.42 294.26 90.58 216.8h-35.63l-76.09-187.21-75.49 187.21h-35.03l92.4-219.21-85.75-203.52h36.23l70.05 176.34 65.82-176.34h34.42l-81.51 205.93z"/>
|
||||
<path id="C" d="M837.51 426.82c0 60.39-32.61 89.38-96.62 89.38h-1.21c-64.01 0-96.62-28.38-96.62-89.38V173.18c0-57.97 32.61-89.38 96.62-89.38h1.21c64.01 0 96.62 31.4 96.62 89.38v72.47H804.9v-61.6c0-49.52-17.51-70.05-64.62-70.05-47.1 0-64.62 20.53-64.62 70.05v231.89c0 49.52 17.51 70.05 64.62 70.05 47.1 0 64.62-20.53 64.62-70.05v-71.86h32.61v82.74z"/>
|
||||
<path id="O" class="st0" d="M450.95 83.82c2.71.26 5.42.49 8.13.79 15.24 1.66 29.25 6.4 40.96 16.68 10.94 9.62 17.43 21.88 20.97 35.84a76.36 76.36 0 0 1 2.28 18.8c-.03 86.6-.01 173.2-.04 259.8a58.86 58.86 0 0 1-8.11 29.93c-7.35 12.68-18.54 19.97-32.83 22.46-12.27 2.14-24.47 1.56-36.32-2.45-17.14-5.81-27.01-18.1-30.48-35.61-.87-4.4-1.03-8.99-1.1-13.51-.16-10-.05-20.01-.05-30.01V168.27c0-7.04 4.19-10.9 11.29-10.25 1.88.17 3.81.59 5.55 1.31 3.12 1.29 4.69 3.69 4.69 7.22-.03 82.93-.03 165.87-.02 248.8 0 15.01 10.45 28.32 24.92 31.6a38.74 38.74 0 0 0 20.16-.6c10.74-3.27 16.83-10.95 19.56-21.5a35.05 35.05 0 0 0 1.14-8.77c.06-87.53.19-175.06-.07-262.59-.05-17.27-7.1-31.7-21.8-41.66-6.46-4.38-13.78-6.65-21.46-7.74-10.77-1.52-21.49-1.19-31.92 2.09-17.94 5.63-28.41 18.23-32.67 36.19a56.84 56.84 0 0 0-1.45 12.93c-.08 86.6-.13 173.2 0 259.8.03 18.77 4.97 36.32 15.53 52 10.75 15.96 26 25.08 44.85 28.24 15.3 2.56 30.51 1.86 45.37-2.6 24.06-7.22 38.48-23.7 44.77-47.69a92.5 92.5 0 0 0 2.74-28.17c-.05-.87-.04-1.74-.04-2.62V155.51c0-7.45 4.58-11.41 12.11-10.44.81.1 1.61.23 2.4.42 3.53.83 6.05 2.82 7.17 6.37v267.31c-.13.56-.33 1.11-.37 1.68a121.32 121.32 0 0 1-8.14 36.58c-13.92 35.27-39.92 54.47-77.59 58.02l-7.78.74h-8.72l-2.57-.37c-6.55-.84-13.21-1.22-19.65-2.61-23.98-5.2-42.64-18.19-55.3-39.33a114.04 114.04 0 0 1-16.33-59.24c-.13-86.17-.04-172.34-.07-258.52 0-6.38.69-12.63 2.23-18.8 3.53-14.09 10.06-26.46 21.12-36.13 11.73-10.26 25.74-14.98 40.98-16.61 2.65-.28 5.3-.52 7.95-.78 2.66.02 5.33.02 8.01.02z"/>
|
||||
<path id="D" d="M295.06 178.01v243.97c0 59.18-32.61 89.38-96.62 89.38H100V88.64h98.43c64.02 0 96.63 30.19 96.63 89.37zm-99.04-59.18h-63.41v362.34h63.41c47.71 0 66.43-19.93 66.43-70.05V188.88c0-50.12-18.72-70.05-66.43-70.05z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
114
package-lock.json
generated
114
package-lock.json
generated
@ -573,9 +573,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.22",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz",
|
||||
"integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
|
||||
"integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/color-name": {
|
||||
@ -585,9 +585,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.0.tgz",
|
||||
"integrity": "sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ==",
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz",
|
||||
"integrity": "sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "*",
|
||||
@ -645,9 +645,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
|
||||
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA=="
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz",
|
||||
"integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw=="
|
||||
},
|
||||
"@types/prompt": {
|
||||
"version": "1.1.2",
|
||||
@ -701,9 +701,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/shelljs": {
|
||||
"version": "0.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.9.tgz",
|
||||
"integrity": "sha512-flVe1dvlrCyQJN/SGrnBxqHG+RzXrVKsmjD8WS/qYHpq5UPjfq7UWFBENP0ZuOl0g6OpAlL6iBoLSvKYUUmyQw==",
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.10.tgz",
|
||||
"integrity": "sha512-nhBdUA/n0nRo1B6E4BuRnUvllYAqal4T9zd91ZDnBh+qQMQTwvxmJHx6xEn/0vdjP2kqEA5eVeLazs4nMxeuFg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/glob": "*",
|
||||
@ -1416,9 +1416,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001283",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz",
|
||||
"integrity": "sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg==",
|
||||
"version": "1.0.30001285",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001285.tgz",
|
||||
"integrity": "sha512-KAOkuUtcQ901MtmvxfKD+ODHH9YVDYnBt+TGYSz2KIfnq22CiArbUxXPN9067gNbgMlnNYRSwho8OPXZPALB9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
@ -1690,6 +1690,52 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
@ -2057,9 +2103,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.3.tgz",
|
||||
"integrity": "sha512-hfpppjYhqIZB8jrNb0rNceQRkSnBN7QJl3W26O1jUv3F3BkQknqy1YTqVXkFnIcFtBc3Qnv5M7r5Lez2iOLgZA==",
|
||||
"version": "1.4.12",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.12.tgz",
|
||||
"integrity": "sha512-zjfhG9Us/hIy8AlQ5OzfbR/C4aBv1Dg/ak4GX35CELYlJ4tDAtoEcQivXvyBdqdNQ+R6PhlgQqV8UNPJmhkJog==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
@ -3156,9 +3202,9 @@
|
||||
}
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "27.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz",
|
||||
"integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==",
|
||||
"version": "27.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.2.tgz",
|
||||
"integrity": "sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
@ -4481,9 +4527,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.0.tgz",
|
||||
"integrity": "sha512-FM/zAKgWTxj40rH03VxzIPdXmj39SwSjwG0heUcNFwI+EMZJnY93yAiKXM3dObIKAM5TA88werc8T/EwhB45eg==",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||
"dev": true
|
||||
},
|
||||
"prismjs": {
|
||||
@ -5668,9 +5714,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
|
||||
"integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
|
||||
"dev": true
|
||||
},
|
||||
"unique-string": {
|
||||
@ -5851,9 +5897,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.0.tgz",
|
||||
"integrity": "sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
||||
"integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
@ -5861,9 +5907,9 @@
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "5.64.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.64.4.tgz",
|
||||
"integrity": "sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw==",
|
||||
"version": "5.65.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz",
|
||||
"integrity": "sha512-Q5or2o6EKs7+oKmJo7LaqZaMOlDWQse9Tm5l1WAfU/ujLGN5Pb0SqGeVkN/4bpPmEqEP5RnVhiqsOtWtUVwGRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/eslint-scope": "^3.7.0",
|
||||
@ -5888,7 +5934,7 @@
|
||||
"schema-utils": "^3.1.0",
|
||||
"tapable": "^2.1.1",
|
||||
"terser-webpack-plugin": "^5.1.3",
|
||||
"watchpack": "^2.3.0",
|
||||
"watchpack": "^2.3.1",
|
||||
"webpack-sources": "^3.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "docx",
|
||||
"version": "7.2.0",
|
||||
"version": "7.3.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": {
|
||||
"pretest": "rimraf ./build",
|
||||
"test": "TS_NODE_PROJECT=\"tsconfig.spec.json\" mocha -r ts-node/register -r tsconfig-paths/register \"src/**/*.ts\"",
|
||||
"test": "cross-env TS_NODE_PROJECT=\"tsconfig.spec.json\" mocha -r ts-node/register -r tsconfig-paths/register \"src/**/*.ts\"",
|
||||
"test.coverage": "nyc npm test",
|
||||
"test.watch": "npm test -- --watch",
|
||||
"prepublishOnly": "npm run build --production",
|
||||
@ -49,7 +49,7 @@
|
||||
],
|
||||
"types": "./build/index.d.ts",
|
||||
"dependencies": {
|
||||
"@types/node": "^16.0.0",
|
||||
"@types/node": "^17.0.0",
|
||||
"jszip": "^3.1.5",
|
||||
"nanoid": "^3.1.20",
|
||||
"xml": "^1.0.1",
|
||||
@ -73,6 +73,7 @@
|
||||
"@types/webpack": "^5.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"chai": "^3.5.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"docsify-cli": "^4.3.0",
|
||||
"glob": "^7.1.2",
|
||||
"jszip": "^3.1.5",
|
||||
@ -95,7 +96,7 @@
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-immutable": "^6.0.1",
|
||||
"typedoc": "^0.22.3",
|
||||
"typescript": "4.5.2",
|
||||
"typescript": "4.5.4",
|
||||
"unzipper": "^0.10.11",
|
||||
"webpack": "^5.28.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
|
@ -44,14 +44,9 @@ export class Compiler {
|
||||
public compile(file: File, prettifyXml?: boolean): JSZip {
|
||||
const zip = new JSZip();
|
||||
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
||||
const map = new Map<string, IXmlifyedFile | IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||
|
||||
for (const key in xmlifiedFileMapping) {
|
||||
if (!xmlifiedFileMapping[key]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const obj = xmlifiedFileMapping[key] as IXmlifyedFile | IXmlifyedFile[];
|
||||
|
||||
for (const [, obj] of map) {
|
||||
if (Array.isArray(obj)) {
|
||||
for (const subFile of obj) {
|
||||
zip.file(subFile.path, subFile.data);
|
||||
|
@ -0,0 +1,30 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { Formatter } from "export/formatter";
|
||||
|
||||
import { DocumentGrid, DocumentGridType } from ".";
|
||||
|
||||
describe("DocumentGrid", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("should create documentGrid with specified linePitch", () => {
|
||||
const docGrid = new DocumentGrid(360);
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 360 } });
|
||||
});
|
||||
|
||||
it("should create documentGrid with specified linePitch and type", () => {
|
||||
const docGrid = new DocumentGrid(360, undefined, DocumentGridType.LINES);
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 360, "w:type": "lines" } });
|
||||
});
|
||||
|
||||
it("should create documentGrid with specified linePitch,charSpace and type", () => {
|
||||
const docGrid = new DocumentGrid(346, -1541, DocumentGridType.LINES_AND_CHARS);
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 346, "w:charSpace": -1541, "w:type": "linesAndChars" } });
|
||||
});
|
||||
});
|
||||
});
|
@ -16,22 +16,36 @@ import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
// <xsd:attribute name="linePitch" type="ST_DecimalNumber"/>
|
||||
// <xsd:attribute name="charSpace" type="ST_DecimalNumber"/>
|
||||
// </xsd:complexType>
|
||||
|
||||
export enum DocumentGridType {
|
||||
DEFAULT = "default",
|
||||
LINES = "lines",
|
||||
LINES_AND_CHARS = "linesAndChars",
|
||||
SNAP_TO_CHARS = "snapToChars",
|
||||
}
|
||||
export interface IDocGridAttributesProperties {
|
||||
readonly type?: DocumentGridType;
|
||||
readonly linePitch?: number;
|
||||
readonly charSpace?: number;
|
||||
}
|
||||
|
||||
export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesProperties> {
|
||||
protected readonly xmlKeys = {
|
||||
type: "w:type",
|
||||
linePitch: "w:linePitch",
|
||||
charSpace: "w:charSpace",
|
||||
};
|
||||
}
|
||||
|
||||
export class DocumentGrid extends XmlComponent {
|
||||
constructor(linePitch: number) {
|
||||
constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) {
|
||||
super("w:docGrid");
|
||||
|
||||
this.root.push(
|
||||
new DocGridAttributes({
|
||||
type: type,
|
||||
linePitch: decimalNumber(linePitch),
|
||||
charSpace: charSpace ? decimalNumber(charSpace) : undefined,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { NumberFormat } from "file/shared/number-format";
|
||||
import { VerticalAlign } from "file/vertical-align";
|
||||
|
||||
import { PageOrientation } from "./properties";
|
||||
import { DocumentGridType } from "./properties/doc-grid";
|
||||
import { LineNumberRestartFormat } from "./properties/line-number";
|
||||
import { PageBorderOffsetFrom } from "./properties/page-borders";
|
||||
import { PageTextDirectionType } from "./properties/page-text-direction";
|
||||
@ -64,6 +65,7 @@ describe("SectionProperties", () => {
|
||||
},
|
||||
grid: {
|
||||
linePitch: convertInchesToTwip(0.25),
|
||||
type: DocumentGridType.LINES,
|
||||
},
|
||||
headerWrapperGroup: {
|
||||
default: new HeaderWrapper(media, 100),
|
||||
@ -100,7 +102,7 @@ describe("SectionProperties", () => {
|
||||
expect(tree["w:sectPr"][5]).to.deep.equal({ "w:cols": { _attr: { "w:space": 208, "w:sep": true, "w:num": 2 } } });
|
||||
expect(tree["w:sectPr"][6]).to.deep.equal({ "w:vAlign": { _attr: { "w:val": "top" } } });
|
||||
expect(tree["w:sectPr"][7]).to.deep.equal({ "w:titlePg": {} });
|
||||
expect(tree["w:sectPr"][8]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } });
|
||||
expect(tree["w:sectPr"][8]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360, "w:type": "lines" } } });
|
||||
});
|
||||
|
||||
it("should create section properties with no options", () => {
|
||||
|
@ -112,7 +112,7 @@ export class SectionProperties extends XmlComponent {
|
||||
borders,
|
||||
textDirection,
|
||||
} = {},
|
||||
grid: { linePitch = 360 } = {},
|
||||
grid: { linePitch = 360, charSpace, type: gridType } = {},
|
||||
headerWrapperGroup = {},
|
||||
footerWrapperGroup = {},
|
||||
lineNumbers,
|
||||
@ -159,7 +159,7 @@ export class SectionProperties extends XmlComponent {
|
||||
this.root.push(new PageTextDirection(textDirection));
|
||||
}
|
||||
|
||||
this.root.push(new DocumentGrid(linePitch));
|
||||
this.root.push(new DocumentGrid(linePitch, charSpace, gridType));
|
||||
}
|
||||
|
||||
private addHeaderFooterGroup(
|
||||
|
25
src/file/numbering/level.spec.ts
Normal file
25
src/file/numbering/level.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { LevelFormat, LevelSuffix } from ".";
|
||||
import { AlignmentType } from "..";
|
||||
|
||||
import { Level } from "./level";
|
||||
|
||||
describe("Level", () => {
|
||||
describe("#constructor", () => {
|
||||
it("should throw an error if level exceeds 9", () => {
|
||||
expect(
|
||||
() =>
|
||||
new Level({
|
||||
level: 10,
|
||||
format: LevelFormat.BULLET,
|
||||
text: "test",
|
||||
alignment: AlignmentType.BOTH,
|
||||
start: 3,
|
||||
style: { run: {}, paragraph: {} },
|
||||
suffix: LevelSuffix.SPACE,
|
||||
}),
|
||||
).to.throw();
|
||||
});
|
||||
});
|
||||
});
|
@ -161,6 +161,12 @@ export class LevelBase extends XmlComponent {
|
||||
this.root.push(this.paragraphProperties);
|
||||
this.root.push(this.runProperties);
|
||||
|
||||
if (level > 9) {
|
||||
throw new Error(
|
||||
"Level cannot be greater than 9. Read more here: https://answers.microsoft.com/en-us/msoffice/forum/all/does-word-support-more-than-9-list-levels/d130fdcd-1781-446d-8c84-c6c79124e4d7",
|
||||
);
|
||||
}
|
||||
|
||||
this.root.push(
|
||||
new LevelAttributes({
|
||||
ilvl: decimalNumber(level),
|
||||
|
@ -5,21 +5,17 @@ import { Formatter } from "export/formatter";
|
||||
import { NumberProperties } from "./unordered-list";
|
||||
|
||||
describe("NumberProperties", () => {
|
||||
let numberProperties: NumberProperties;
|
||||
|
||||
beforeEach(() => {
|
||||
numberProperties = new NumberProperties(5, 10);
|
||||
});
|
||||
|
||||
describe("#constructor()", () => {
|
||||
it("should create a Number Properties with correct root key", () => {
|
||||
const numberProperties = new NumberProperties(5, 9);
|
||||
|
||||
const tree = new Formatter().format(numberProperties);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:numPr": [
|
||||
{
|
||||
"w:ilvl": {
|
||||
_attr: {
|
||||
"w:val": 10,
|
||||
"w:val": 9,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -33,5 +29,9 @@ describe("NumberProperties", () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should throw an error if level exceeds 9", () => {
|
||||
expect(() => new NumberProperties(5, 10)).to.throw();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -11,6 +11,13 @@ export class NumberProperties extends XmlComponent {
|
||||
class IndentLevel extends XmlComponent {
|
||||
constructor(level: number) {
|
||||
super("w:ilvl");
|
||||
|
||||
if (level > 9) {
|
||||
throw new Error(
|
||||
"Level cannot be greater than 9. Read more here: https://answers.microsoft.com/en-us/msoffice/forum/all/does-word-support-more-than-9-list-levels/d130fdcd-1781-446d-8c84-c6c79124e4d7",
|
||||
);
|
||||
}
|
||||
|
||||
this.root.push(
|
||||
new Attributes({
|
||||
val: level,
|
||||
|
@ -70,18 +70,7 @@ describe("ParagraphProperties", () => {
|
||||
const properties = new ParagraphProperties({
|
||||
widowControl: true,
|
||||
});
|
||||
const tree = new Formatter().format(properties, {
|
||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||
file: {
|
||||
Numbering: {
|
||||
createConcreteNumberingInstance: (_: string, __: number) => {
|
||||
return;
|
||||
},
|
||||
},
|
||||
} as File,
|
||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||
viewWrapper: new DocumentWrapper({ background: {} }),
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(tree).to.deep.equal({
|
||||
"w:pPr": [
|
||||
@ -91,5 +80,50 @@ describe("ParagraphProperties", () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should create with the bidirectional property", () => {
|
||||
const properties = new ParagraphProperties({
|
||||
bidirectional: true,
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(tree).to.deep.equal({
|
||||
"w:pPr": [
|
||||
{
|
||||
"w:bidi": {},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should create with the contextualSpacing property", () => {
|
||||
const properties = new ParagraphProperties({
|
||||
contextualSpacing: true,
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(tree).to.deep.equal({
|
||||
"w:pPr": [
|
||||
{
|
||||
"w:contextualSpacing": {},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should create with the suppressLineNumbers property", () => {
|
||||
const properties = new ParagraphProperties({
|
||||
suppressLineNumbers: true,
|
||||
});
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(tree).to.deep.equal({
|
||||
"w:pPr": [
|
||||
{
|
||||
"w:suppressLineNumbers": {},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -146,7 +146,7 @@ export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
|
||||
}
|
||||
|
||||
if (options.bidirectional !== undefined) {
|
||||
this.push(new OnOffElement("w:bidi", options.contextualSpacing));
|
||||
this.push(new OnOffElement("w:bidi", options.bidirectional));
|
||||
}
|
||||
|
||||
if (options.spacing) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { ChangeAttributes, IChangedAttributesProperties } from "../../track-revision/track-revision";
|
||||
|
||||
import { IShadingAttributesProperties, Shading } from "file/shading";
|
||||
import { HpsMeasureElement, IgnoreIfEmptyXmlComponent, OnOffElement, StringValueElement, XmlComponent } from "file/xml-components";
|
||||
import { EmphasisMark, EmphasisMarkType } from "./emphasis-mark";
|
||||
@ -40,12 +42,15 @@ export interface IRunStylePropertiesOptions {
|
||||
readonly shading?: IShadingAttributesProperties;
|
||||
readonly emboss?: boolean;
|
||||
readonly imprint?: boolean;
|
||||
readonly revision?: IRunPropertiesChangeOptions;
|
||||
}
|
||||
|
||||
export interface IRunPropertiesOptions extends IRunStylePropertiesOptions {
|
||||
readonly style?: string;
|
||||
}
|
||||
|
||||
export interface IRunPropertiesChangeOptions extends IRunPropertiesOptions, IChangedAttributesProperties {}
|
||||
|
||||
// <xsd:group name="EG_RPrBase">
|
||||
// <xsd:choice>
|
||||
// <xsd:element name="rStyle" type="CT_String"/>
|
||||
@ -200,9 +205,27 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent {
|
||||
if (options.shading) {
|
||||
this.push(new Shading(options.shading));
|
||||
}
|
||||
|
||||
if (options.revision) {
|
||||
this.push(new RunPropertiesChange(options.revision));
|
||||
}
|
||||
}
|
||||
|
||||
public push(item: XmlComponent): void {
|
||||
this.root.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
export class RunPropertiesChange extends XmlComponent {
|
||||
constructor(options: IRunPropertiesChangeOptions) {
|
||||
super("w:rPrChange");
|
||||
this.root.push(
|
||||
new ChangeAttributes({
|
||||
id: options.id,
|
||||
author: options.author,
|
||||
date: options.date,
|
||||
}),
|
||||
);
|
||||
this.addChildElement(new RunProperties(options as IRunPropertiesOptions));
|
||||
}
|
||||
}
|
||||
|
@ -428,4 +428,64 @@ describe("Run", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#revisions", () => {
|
||||
it("should add style revisions", () => {
|
||||
const run = new Run({
|
||||
bold: true,
|
||||
italics: true,
|
||||
revision: {
|
||||
id: 0,
|
||||
author: "Firstname Lastname",
|
||||
date: "123",
|
||||
bold: false,
|
||||
italics: true,
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(run);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:r": [
|
||||
{
|
||||
"w:rPr": [
|
||||
{ "w:b": {} },
|
||||
{
|
||||
"w:bCs": {},
|
||||
},
|
||||
{ "w:i": {} },
|
||||
{
|
||||
"w:iCs": {},
|
||||
},
|
||||
{
|
||||
"w:rPrChange": [
|
||||
{
|
||||
_attr: {
|
||||
"w:author": "Firstname Lastname",
|
||||
"w:date": "123",
|
||||
"w:id": 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
"w:rPr": [
|
||||
{ "w:b": { _attr: { "w:val": false } } },
|
||||
{
|
||||
"w:bCs": {
|
||||
_attr: {
|
||||
"w:val": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ "w:i": {} },
|
||||
{
|
||||
"w:iCs": {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user