Compare commits
393 Commits
7.5.0
...
feature/pa
Author | SHA1 | Date | |
---|---|---|---|
c5a2c1c0cb | |||
d505281a7e | |||
58575342e0 | |||
60ad6d6ab5 | |||
f9dec1cb3c | |||
c713e6f371 | |||
3c55f9fc1f | |||
c9a8a99278 | |||
b309d327f0 | |||
58bad10bfe | |||
26ea6c518f | |||
d4594a97a2 | |||
68f951ef79 | |||
12e29c6a75 | |||
05eedb2ac1 | |||
46ded68369 | |||
b3a53d341d | |||
afcd5e70a1 | |||
ae48999e38 | |||
4c38e45455 | |||
ec847dccf9 | |||
ca47a1dc3f | |||
cc53ff417b | |||
fcba817a4a | |||
bcd8249d17 | |||
bc0a197ba1 | |||
2e16279d7b | |||
87590aedbd | |||
0fef7763d5 | |||
e55698d221 | |||
d410b5e96f | |||
8587601411 | |||
5b67cb21c6 | |||
42fd9d06de | |||
1e0b74fd27 | |||
21934ec85b | |||
b4f01fb6ec | |||
fbf6329500 | |||
41549443c3 | |||
92630af4e1 | |||
4db633da16 | |||
dac02f13ae | |||
1a52dec1c2 | |||
be1ca51162 | |||
768e20bb79 | |||
26b9b15de8 | |||
42713095b6 | |||
3acafeca38 | |||
7ca75c8c5a | |||
c00ad454a9 | |||
16d04eb4d3 | |||
816845f271 | |||
12eeda8d33 | |||
3d622c2ef1 | |||
21a6767c6f | |||
7a7326ec09 | |||
9b3af4e217 | |||
cee0114f81 | |||
03399aedf0 | |||
2739b94bd8 | |||
c720441d62 | |||
00b5898fe0 | |||
0d0940b7a5 | |||
f28c949ac6 | |||
63317d6ac8 | |||
6406ba831f | |||
7a7575964a | |||
d75c833717 | |||
40344b57d9 | |||
6fc26d1da3 | |||
a012a0e418 | |||
bf1a2f3059 | |||
ca316b4e6d | |||
1fb5c581c9 | |||
efa64b451a | |||
38059ea6b9 | |||
c2110622ca | |||
0452959b85 | |||
0eca8389b6 | |||
66e043137b | |||
d684654625 | |||
7749f6b20f | |||
15c9c0ae3e | |||
74fddc2ada | |||
cff866ecdc | |||
e952c02c83 | |||
546983c6ba | |||
c7134564a3 | |||
984a3573eb | |||
defe94a2b2 | |||
e23c8c4b46 | |||
7941ff487a | |||
7b7df33a0f | |||
68b04f2511 | |||
db3e017a7d | |||
c21d45a79e | |||
6defb686bb | |||
f68796dae1 | |||
b1872bcb95 | |||
3006f4d2c1 | |||
7f88a38219 | |||
aeb2487c70 | |||
e42e50dd39 | |||
f4572b9720 | |||
7646f3a845 | |||
e4e5b1e4f6 | |||
a481518470 | |||
2435ebf16e | |||
414fa70e5d | |||
f255d4c141 | |||
4513bb529b | |||
5907132062 | |||
69bf313f18 | |||
fe8b0a6b2b | |||
abcfd79f2f | |||
41e3b078ec | |||
4eb2f92c1f | |||
9bfb5bf681 | |||
473ad2947c | |||
ee28f6ad84 | |||
11bebd42ac | |||
49b4ca67e0 | |||
3282f762df | |||
d335106b46 | |||
cefa01f7ec | |||
b7ba2b3306 | |||
03d5152e7c | |||
af3b7f2613 | |||
1405841565 | |||
211d2dc0d6 | |||
82f431465f | |||
247afe56ce | |||
91e874eee5 | |||
ff67c3660b | |||
58c580b9ca | |||
a9da151026 | |||
83c72d0dbb | |||
2c31367851 | |||
3b618f3a2c | |||
4c5bc6232d | |||
694835bdac | |||
c8b75c19da | |||
c0181aa83a | |||
c5b615ae2a | |||
54cbd56f42 | |||
c8914a109e | |||
62d0767ceb | |||
8509bccc4f | |||
4ce53a3d76 | |||
8024c01a82 | |||
1b380c3fdb | |||
06b67bd292 | |||
8a1087f601 | |||
ff09d6515c | |||
ebe85d8e14 | |||
5dc27ac46a | |||
1dcc8ee761 | |||
ec69f9ac07 | |||
f789f60e22 | |||
32e3f07d57 | |||
9ea41ab3ce | |||
4b8d062862 | |||
d9408029f3 | |||
9fe0406078 | |||
5a4fe5d5da | |||
e6af9b4b73 | |||
361f9231d8 | |||
4215932550 | |||
29da523579 | |||
fbb4d7cfde | |||
3ea453a07f | |||
984e762a53 | |||
1592aa7117 | |||
62b4522c94 | |||
8b86751c95 | |||
afa380e336 | |||
feebff9077 | |||
028b50ff99 | |||
559e81c3fe | |||
4da6b98437 | |||
5b2409c76f | |||
ff027d172e | |||
3f23290a46 | |||
f1a10d32e6 | |||
a71f40e873 | |||
7f449319cd | |||
ab5c8ea698 | |||
68cfa9360b | |||
f627e3d994 | |||
7c870548d9 | |||
57ccc41547 | |||
988ba45197 | |||
df6606041b | |||
3ae27b466f | |||
69f5e21435 | |||
6da73c612a | |||
e1b1c1492f | |||
6ca13c4fce | |||
b474567d20 | |||
c07170902e | |||
0f201d2f4b | |||
b875d6f183 | |||
831b92239d | |||
66b91c22dd | |||
1242c0689f | |||
4386d02526 | |||
3ba521f8cc | |||
85bb818ae6 | |||
be7e2aa8fe | |||
7f71f6e3f1 | |||
a94d23e2ae | |||
133c255ce2 | |||
863e27ff9b | |||
5c63e6ae12 | |||
10dd36569d | |||
be5985fb6a | |||
0d7f169613 | |||
eaddcb83ab | |||
9a6885f124 | |||
7284ee818b | |||
20964454c4 | |||
d7670929d1 | |||
58f0761423 | |||
3f28bc09bc | |||
323895f0ab | |||
6efa734e81 | |||
47d64af737 | |||
4a2b91ce07 | |||
080a77cc73 | |||
9b874b0061 | |||
ff8a2ed538 | |||
251eafe103 | |||
64b604c9ac | |||
72fc5f9874 | |||
71dcdf0ca2 | |||
e23fc987a7 | |||
36dba1a36f | |||
1b1547d4b6 | |||
8008482592 | |||
6d1a7fe438 | |||
90c58b0498 | |||
c91bb71700 | |||
3d09c45205 | |||
f1e41d883c | |||
4f783ec8e4 | |||
3d35e84953 | |||
e80bc8b584 | |||
2848b39479 | |||
7ee9be200c | |||
94cdd740ad | |||
9130687164 | |||
2f52f47463 | |||
01866f4802 | |||
fa8ac0f2e4 | |||
e9a909ed20 | |||
8808447963 | |||
056b496189 | |||
11b374ea75 | |||
f8f9744786 | |||
6f6888d638 | |||
995430b76f | |||
d4a5ec4e14 | |||
c7dce059f8 | |||
2f4e3f2153 | |||
a37c5646b6 | |||
ddc9c8f62f | |||
1b06fc71cf | |||
e65a3bfeab | |||
b9ceabcc07 | |||
35be3bfb9b | |||
572c8efbc7 | |||
b1b3e2369b | |||
dc72bb629e | |||
a724706817 | |||
84989116ef | |||
6c4efe4a1c | |||
8596d70b79 | |||
db6c9b2700 | |||
a33602ccf6 | |||
988987ddbe | |||
309e66a6de | |||
7d8cfc0382 | |||
5cbae5d3f7 | |||
9b630c4ef7 | |||
befcbabe27 | |||
4cfb0ade88 | |||
a6f528537b | |||
dfc82a517d | |||
29f421686f | |||
c11299076f | |||
1cb2ef565e | |||
2de07d04a8 | |||
75e064dd1d | |||
5f0091ee25 | |||
d2c0e656d0 | |||
522b21862b | |||
ccf66dbd50 | |||
6e30ab0355 | |||
568c764e3c | |||
d508e8ae31 | |||
ded346e34a | |||
edb8eddce1 | |||
abd3641da4 | |||
7e1165d012 | |||
461754e591 | |||
e649330dbc | |||
baec324811 | |||
91c430d9e2 | |||
efd853d519 | |||
f717b0eae4 | |||
d76d21a1f2 | |||
712450d717 | |||
b9d93c9d33 | |||
c7ca51cd65 | |||
20b793620a | |||
9bed303d34 | |||
f4ed171f85 | |||
8a3ccdb196 | |||
41765d133f | |||
482ea1b186 | |||
3bba7f9d23 | |||
7e5e2baf92 | |||
53c70e6cd1 | |||
4bfb87ea74 | |||
86e12c7d40 | |||
eb5449adf8 | |||
19eeec9fc8 | |||
449f5f5be3 | |||
bc5a1b52b7 | |||
fc7f37767f | |||
38dbdd02ae | |||
7bb3fa74ce | |||
a33660d32c | |||
ef842d1f3f | |||
e5c2a0a87b | |||
817ffe8fd0 | |||
5b582d45ba | |||
6a303532f4 | |||
c75abb7cb9 | |||
8282d76b87 | |||
79f3866c4c | |||
6dcf3f25e9 | |||
e80acea63f | |||
640639264d | |||
3ccdd2585c | |||
2c4b55c692 | |||
70a3b25d54 | |||
d053baef03 | |||
629c586014 | |||
32a5cca878 | |||
911c705b59 | |||
594c8d72b8 | |||
7ea5232b22 | |||
be12d61795 | |||
925340eb3d | |||
e4b03b3f71 | |||
9ab6df99b1 | |||
51519a55ef | |||
059455929b | |||
8a1df4438e | |||
cbf6e46e35 | |||
727b1bd63b | |||
363b8d74ae | |||
b31ecd6583 | |||
563914a0ef | |||
1e8adbb240 | |||
4b1f89a561 | |||
1a4a0ea5b8 | |||
f781028b08 | |||
56e8ad4f17 | |||
62c34ae612 | |||
26123b0a93 | |||
4023464a13 | |||
0c92f354c5 | |||
676723c8bd | |||
2f4d5afaea | |||
d0abceb08d | |||
8b165e93e1 | |||
321969eb85 | |||
85ec90849e | |||
96451bc5b7 | |||
311cbf55ef | |||
0258b256f2 | |||
c615de97c4 | |||
e29a7bf146 | |||
b665c243f0 | |||
bea1c9ed61 | |||
0e6bdaa9c9 | |||
7925689618 | |||
791441ec86 | |||
601a4038f4 | |||
e0576c889b | |||
4ff7f0a7bd |
@ -47,7 +47,9 @@
|
|||||||
"/xmlKeys = {[^}]+}/g",
|
"/xmlKeys = {[^}]+}/g",
|
||||||
"/\\.to\\.deep\\.equal\\({[^)]+}\\)/g",
|
"/\\.to\\.deep\\.equal\\({[^)]+}\\)/g",
|
||||||
"\\.to\\.include\\.members\\(\\[[^\\]]+]\\)",
|
"\\.to\\.include\\.members\\(\\[[^\\]]+]\\)",
|
||||||
"/new [a-zA-Z]+\\({[^£]+}\\)/g"
|
"/new [a-zA-Z]+\\({[^£]+}\\)/g",
|
||||||
|
"/<element name=\"[a-z]+\"/gi",
|
||||||
|
"/<attribute name=\"[a-z]+\"/gi"
|
||||||
],
|
],
|
||||||
"ignorePaths": ["package.json", "docs/api"],
|
"ignorePaths": ["package.json", "docs/api"],
|
||||||
"allowCompoundWords": true,
|
"allowCompoundWords": true,
|
||||||
|
14
.eslintrc.js
14
.eslintrc.js
@ -96,8 +96,8 @@ module.exports = {
|
|||||||
"@typescript-eslint/explicit-function-return-type": [
|
"@typescript-eslint/explicit-function-return-type": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
allowExpressions: false,
|
allowExpressions: true,
|
||||||
allowTypedFunctionExpressions: false,
|
allowTypedFunctionExpressions: true,
|
||||||
allowHigherOrderFunctions: false,
|
allowHigherOrderFunctions: false,
|
||||||
allowDirectConstAssertionInArrowFunctions: true,
|
allowDirectConstAssertionInArrowFunctions: true,
|
||||||
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
|
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
|
||||||
@ -214,7 +214,6 @@ module.exports = {
|
|||||||
"no-sequences": "error",
|
"no-sequences": "error",
|
||||||
"no-shadow": "off",
|
"no-shadow": "off",
|
||||||
"no-sparse-arrays": "error",
|
"no-sparse-arrays": "error",
|
||||||
"no-template-curly-in-string": "error",
|
|
||||||
"no-throw-literal": "error",
|
"no-throw-literal": "error",
|
||||||
"no-trailing-spaces": "error",
|
"no-trailing-spaces": "error",
|
||||||
"no-undef-init": "error",
|
"no-undef-init": "error",
|
||||||
@ -243,7 +242,6 @@ module.exports = {
|
|||||||
"unicorn/prefer-ternary": "error",
|
"unicorn/prefer-ternary": "error",
|
||||||
"use-isnan": "error",
|
"use-isnan": "error",
|
||||||
"valid-typeof": "off",
|
"valid-typeof": "off",
|
||||||
"@typescript-eslint/explicit-function-return-type": "off",
|
|
||||||
"functional/immutable-data": [
|
"functional/immutable-data": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
@ -252,9 +250,12 @@ module.exports = {
|
|||||||
ignoreAccessorPattern: ["**.root*", "**.numberingReferences*", "**.sections*", "**.properties*"],
|
ignoreAccessorPattern: ["**.root*", "**.numberingReferences*", "**.sections*", "**.properties*"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"functional/no-method-signature": "error",
|
"functional/prefer-property-signatures": "error",
|
||||||
"functional/no-mixed-type": "error",
|
"functional/no-mixed-types": "error",
|
||||||
|
// TODO: Deprecated. Use prefer-immutable-types and type-declaration-immutability instead
|
||||||
"functional/prefer-readonly-type": "error",
|
"functional/prefer-readonly-type": "error",
|
||||||
|
// "functional/prefer-immutable-types": "error",
|
||||||
|
// "functional/type-declaration-immutability": "error",
|
||||||
"no-unused-vars": ["error", { argsIgnorePattern: "^[_]+$" }],
|
"no-unused-vars": ["error", { argsIgnorePattern: "^[_]+$" }],
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
@ -264,6 +265,7 @@ module.exports = {
|
|||||||
"@typescript-eslint/no-unused-expressions": "off",
|
"@typescript-eslint/no-unused-expressions": "off",
|
||||||
"@typescript-eslint/dot-notation": "off",
|
"@typescript-eslint/dot-notation": "off",
|
||||||
"prefer-destructuring": "off",
|
"prefer-destructuring": "off",
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
2
.github/workflows/default.yml
vendored
2
.github/workflows/default.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: npm run test.coverage
|
run: npm run test.coverage
|
||||||
- name: Codecov
|
- name: Codecov
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
verbose: true
|
verbose: true
|
||||||
|
117
.github/workflows/demos.yml
vendored
117
.github/workflows/demos.yml
vendored
@ -689,3 +689,120 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
xml-file: build/extracted-doc/word/document.xml
|
xml-file: build/extracted-doc/word/document.xml
|
||||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/72-word-wrap.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/73-comments.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/73-comments.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
|
||||||
|
# - name: Run Demo
|
||||||
|
# run: npm run ts-node -- ./demo/75-tab-stops.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/76-compatibility.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/77-side-by-side-tables.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/78-thai-distributed.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/79-table-from-data-source.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/80-thai-distributed.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/81-continuous-header.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/82-new-headers-new-section.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/83-setting-languages.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
|
||||||
|
- name: Run Demo
|
||||||
|
run: npm run ts-node -- ./demo/84-positional-tabs.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
|
||||||
|
8
.nycrc
8
.nycrc
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"check-coverage": true,
|
"check-coverage": true,
|
||||||
"statements": 99.72,
|
"statements": 99.79,
|
||||||
"branches": 97.95,
|
"branches": 98.41,
|
||||||
"functions": 99.82,
|
"functions": 100,
|
||||||
"lines": 99.71,
|
"lines": 99.73,
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts"
|
||||||
],
|
],
|
||||||
|
@ -29,11 +29,12 @@ Here are examples of `docx` being used with basic `HTML/JS` in a browser environ
|
|||||||
- https://codepen.io/dolanmiu/pen/RwNeObg
|
- https://codepen.io/dolanmiu/pen/RwNeObg
|
||||||
- https://jsfiddle.net/dolanmiu/onadx1gu/
|
- https://jsfiddle.net/dolanmiu/onadx1gu/
|
||||||
|
|
||||||
Here is an example of `docx` working in `Angular`:
|
Here are examples of `docx` working in `Angular`:
|
||||||
|
|
||||||
- https://stackblitz.com/edit/angular-docx
|
- https://stackblitz.com/edit/angular-docx
|
||||||
|
- https://stackblitz.com/edit/angular-wmd6k3
|
||||||
|
|
||||||
Here is an example of `docx` working in `React`:
|
Here are examples of `docx` working in `React`:
|
||||||
|
|
||||||
- https://stackblitz.com/edit/react-docx
|
- https://stackblitz.com/edit/react-docx
|
||||||
- https://stackblitz.com/edit/react-docx-images (adding images to Word Document)
|
- https://stackblitz.com/edit/react-docx-images (adding images to Word Document)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Simple example to add text to a document
|
// Simple example to add text to a document
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -14,9 +14,10 @@ const doc = new Document({
|
|||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Foo Bar",
|
text: "Foo Bar",
|
||||||
bold: true,
|
bold: true,
|
||||||
|
size: 40,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Generate a CV
|
// Generate a CV
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "../build";
|
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, Tab, TabStopPosition, TabStopType, TextRun } from "../build";
|
||||||
|
|
||||||
// tslint:disable:no-shadowed-variable
|
// tslint:disable:no-shadowed-variable
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ class DocumentCreator {
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: `\t${dateText}`,
|
children: [new Tab(), dateText],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Export to base64 string - Useful in a browser environment.
|
// Export to base64 string - Useful in a browser environment.
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -15,7 +15,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tBar",
|
children: [new Tab(), "Bar"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -82,6 +82,32 @@ const doc = new Document({
|
|||||||
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "strikeUnderline",
|
||||||
|
name: "Strike Underline",
|
||||||
|
basedOn: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
strike: true,
|
||||||
|
underline: {
|
||||||
|
type: UnderlineType.SINGLE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
characterStyles: [
|
||||||
|
{
|
||||||
|
id: "strikeUnderlineCharacter",
|
||||||
|
name: "Strike Underline",
|
||||||
|
basedOn: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
strike: true,
|
||||||
|
underline: {
|
||||||
|
type: UnderlineType.SINGLE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
numbering: {
|
numbering: {
|
||||||
@ -169,6 +195,14 @@ const doc = new Document({
|
|||||||
new TextRun({
|
new TextRun({
|
||||||
text: "and back to normal.",
|
text: "and back to normal.",
|
||||||
}),
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "This text will be invisible!",
|
||||||
|
vanish: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "This text will be VERY invisible! Word processors cannot override this!",
|
||||||
|
specVanish: true,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
@ -182,6 +216,49 @@ const doc = new Document({
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
style: "strikeUnderline",
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Underline and Strike",
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: " Override Underline ",
|
||||||
|
underline: {
|
||||||
|
type: UnderlineType.NONE,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "Strike and Underline",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Hello World ",
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
style: "strikeUnderlineCharacter",
|
||||||
|
text: "Underline and Strike",
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: " Another Hello World",
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
scale: 50,
|
||||||
|
text: " Scaled text",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
scale: 200,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Scaled paragraph",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Example of making content of section vertically aligned
|
// Example of making content of section vertically aligned
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, VerticalAlign, TextRun } from "../build";
|
import { Document, Packer, Paragraph, VerticalAlign, TextRun, Tab } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -18,7 +18,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -25,6 +25,11 @@ const doc = new Document({
|
|||||||
width: 100,
|
width: 100,
|
||||||
height: 100,
|
height: 100,
|
||||||
},
|
},
|
||||||
|
altText: {
|
||||||
|
title: "This is an ultimate title",
|
||||||
|
description: "This is an ultimate image",
|
||||||
|
name: "My Ultimate Image",
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
MathSubScript,
|
MathSubScript,
|
||||||
MathSubSuperScript,
|
MathSubSuperScript,
|
||||||
MathSum,
|
MathSum,
|
||||||
|
MathIntegral,
|
||||||
MathSuperScript,
|
MathSuperScript,
|
||||||
Packer,
|
Packer,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
@ -90,6 +91,35 @@ const doc = new Document({
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathIntegral({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
}),
|
||||||
|
new MathIntegral({
|
||||||
|
children: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("e")],
|
||||||
|
superScript: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("i")],
|
||||||
|
}),
|
||||||
|
new MathIntegral({
|
||||||
|
children: [
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("i")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("i")],
|
||||||
|
superScript: [new MathRun("10")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [
|
children: [
|
||||||
new Math({
|
new Math({
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Change background colour of whole document
|
// Change background colour of whole document
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
background: {
|
background: {
|
||||||
@ -19,7 +19,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Example of how to change page borders
|
// Example of how to change page borders
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, TextRun } from "../build";
|
import { Document, HeadingLevel, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -25,7 +25,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
PageNumber,
|
PageNumber,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
ShadingType,
|
ShadingType,
|
||||||
|
Tab,
|
||||||
TextRun,
|
TextRun,
|
||||||
} from "../build";
|
} from "../build";
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ const doc = new Document({
|
|||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
bold: true,
|
bold: true,
|
||||||
children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
children: [new Tab(), "use Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
bold: true,
|
bold: true,
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
HorizontalPositionAlign,
|
HorizontalPositionAlign,
|
||||||
Packer,
|
Packer,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
|
Tab,
|
||||||
TextRun,
|
TextRun,
|
||||||
VerticalPositionAlign,
|
VerticalPositionAlign,
|
||||||
} from "../build";
|
} from "../build";
|
||||||
@ -67,7 +68,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -7,12 +7,31 @@ const doc = new Document({
|
|||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
children: [
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
wordWrap: true,
|
||||||
|
children: [
|
||||||
|
new TextRun("我今天遛狗去公园"),
|
||||||
|
new TextRun({
|
||||||
|
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
wordWrap: true,
|
||||||
|
children: [
|
||||||
|
new TextRun(
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
|
||||||
|
),
|
||||||
|
new TextRun({
|
||||||
|
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [
|
children: [
|
||||||
new TextRun("我今天遛狗去公园"),
|
new TextRun("我今天遛狗去公园"),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||||
space: SpaceType.PRESERVE,
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -23,7 +42,6 @@ const doc = new Document({
|
|||||||
),
|
),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||||
space: SpaceType.PRESERVE,
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Exporting the document as a stream
|
// Exporting the document as a stream
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
@ -16,7 +16,7 @@ const doc = new Document({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
80
demo/75-tab-stops.ts
Normal file
80
demo/75-tab-stops.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Example of using tab stops
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "../build";
|
||||||
|
|
||||||
|
const columnWidth = TabStopPosition.MAX / 4;
|
||||||
|
const receiptTabStops = [
|
||||||
|
// no need to define first left tab column
|
||||||
|
// the right aligned tab column position should point to the end of column
|
||||||
|
// i.e. in this case
|
||||||
|
// (end position of 1st) + (end position of current)
|
||||||
|
// columnWidth + columnWidth = columnWidth * 2
|
||||||
|
|
||||||
|
{ type: TabStopType.RIGHT, position: columnWidth * 2 },
|
||||||
|
{ type: TabStopType.RIGHT, position: columnWidth * 3 },
|
||||||
|
{ type: TabStopType.RIGHT, position: TabStopPosition.MAX },
|
||||||
|
],
|
||||||
|
twoTabStops = [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }];
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
children: [new TextRun("Receipt 001")],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: twoTabStops,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "To Bob.\tBy Alice.",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: twoTabStops,
|
||||||
|
children: [new TextRun("Foo Inc\tBar Inc")],
|
||||||
|
}),
|
||||||
|
new Paragraph({ text: "" }),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: receiptTabStops,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Item\tPrice\tQuantity\tSub-total",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: receiptTabStops,
|
||||||
|
text: "Item 3\t10\t5\t50",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: receiptTabStops,
|
||||||
|
text: "Item 3\t10\t5\t50",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: receiptTabStops,
|
||||||
|
text: "Item 3\t10\t5\t50",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
tabStops: receiptTabStops,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "\t\t\tTotal: 200",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const stream = Packer.toStream(doc);
|
||||||
|
stream.pipe(fs.createWriteStream("My Document.docx"));
|
87
demo/76-compatibility.ts
Normal file
87
demo/76-compatibility.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Add compatibility options
|
||||||
|
// 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({
|
||||||
|
compatibility: {
|
||||||
|
useSingleBorderforContiguousCells: true,
|
||||||
|
wordPerfectJustification: true,
|
||||||
|
noTabStopForHangingIndent: true,
|
||||||
|
noLeading: true,
|
||||||
|
spaceForUnderline: true,
|
||||||
|
noColumnBalance: true,
|
||||||
|
balanceSingleByteDoubleByteWidth: true,
|
||||||
|
noExtraLineSpacing: true,
|
||||||
|
doNotLeaveBackslashAlone: true,
|
||||||
|
underlineTrailingSpaces: true,
|
||||||
|
doNotExpandShiftReturn: true,
|
||||||
|
spacingInWholePoints: true,
|
||||||
|
lineWrapLikeWord6: true,
|
||||||
|
printBodyTextBeforeHeader: true,
|
||||||
|
printColorsBlack: true,
|
||||||
|
spaceWidth: true,
|
||||||
|
showBreaksInFrames: true,
|
||||||
|
subFontBySize: true,
|
||||||
|
suppressBottomSpacing: true,
|
||||||
|
suppressTopSpacing: true,
|
||||||
|
suppressSpacingAtTopOfPage: true,
|
||||||
|
suppressTopSpacingWP: true,
|
||||||
|
suppressSpBfAfterPgBrk: true,
|
||||||
|
swapBordersFacingPages: true,
|
||||||
|
convertMailMergeEsc: true,
|
||||||
|
truncateFontHeightsLikeWP6: true,
|
||||||
|
macWordSmallCaps: true,
|
||||||
|
usePrinterMetrics: true,
|
||||||
|
doNotSuppressParagraphBorders: true,
|
||||||
|
wrapTrailSpaces: true,
|
||||||
|
footnoteLayoutLikeWW8: true,
|
||||||
|
shapeLayoutLikeWW8: true,
|
||||||
|
alignTablesRowByRow: true,
|
||||||
|
forgetLastTabAlignment: true,
|
||||||
|
adjustLineHeightInTable: true,
|
||||||
|
autoSpaceLikeWord95: true,
|
||||||
|
noSpaceRaiseLower: true,
|
||||||
|
doNotUseHTMLParagraphAutoSpacing: true,
|
||||||
|
layoutRawTableWidth: true,
|
||||||
|
layoutTableRowsApart: true,
|
||||||
|
useWord97LineBreakRules: true,
|
||||||
|
doNotBreakWrappedTables: true,
|
||||||
|
doNotSnapToGridInCell: true,
|
||||||
|
selectFieldWithFirstOrLastCharacter: true,
|
||||||
|
applyBreakingRules: true,
|
||||||
|
doNotWrapTextWithPunctuation: true,
|
||||||
|
doNotUseEastAsianBreakRules: true,
|
||||||
|
useWord2002TableStyleRules: true,
|
||||||
|
growAutofit: true,
|
||||||
|
useFELayout: true,
|
||||||
|
useNormalStyleForList: true,
|
||||||
|
doNotUseIndentAsNumberingTabStop: true,
|
||||||
|
useAlternateEastAsianLineBreakRules: true,
|
||||||
|
allowSpaceOfSameStyleInTable: true,
|
||||||
|
doNotSuppressIndentation: true,
|
||||||
|
doNotAutofitConstrainedTables: true,
|
||||||
|
autofitToFirstFixedWidthCell: true,
|
||||||
|
underlineTabInNumberingList: true,
|
||||||
|
displayHangulFixedWidth: true,
|
||||||
|
splitPgBreakAndParaMark: true,
|
||||||
|
doNotVerticallyAlignCellWithSp: true,
|
||||||
|
doNotBreakConstrainedForcedTable: true,
|
||||||
|
ignoreVerticalAlignmentInTextboxes: true,
|
||||||
|
useAnsiKerningPairs: true,
|
||||||
|
cachedColumnBalance: true,
|
||||||
|
},
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
116
demo/77-side-by-side-tables.ts
Normal file
116
demo/77-side-by-side-tables.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Exporting the document as a stream
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Packer, Paragraph, Table, TableBorders, TableCell, TableRow, WidthType } from "../build";
|
||||||
|
|
||||||
|
const table1 = new Table({
|
||||||
|
columnWidths: [3505, 5505],
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 3505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 5505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 3505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 5505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [new Paragraph("World")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const table2 = new Table({
|
||||||
|
columnWidths: [3505, 5505],
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 3505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [new Paragraph("Foo")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 5505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 3505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
width: {
|
||||||
|
size: 5505,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
children: [new Paragraph("Bar")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const noBorderTable = new Table({
|
||||||
|
borders: TableBorders.NONE,
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [table1],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [table2],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {},
|
||||||
|
children: [noBorderTable],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const stream = Packer.toStream(doc);
|
||||||
|
stream.pipe(fs.createWriteStream("My Document.docx"));
|
27
demo/78-thai-distributed.ts
Normal file
27
demo/78-thai-distributed.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// 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 { AlignmentType, Document, Packer, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
alignment: AlignmentType.THAI_DISTRIBUTE,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "บริษัท บิสกิด จำกัด (บริษัทฯ) ได้จดทะเบียนจัดตั้งขึ้นเป็นบริษัทจำกัดตามประมวลกฎหมายแพ่งและพาณิชย์ของประเทศไทย เมื่อวันที่ 30 พฤษภาคม 2561 ทะเบียนนิติบุคคลเลขที่ 0845561005665",
|
||||||
|
size: 36,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
193
demo/79-table-from-data-source.ts
Normal file
193
demo/79-table-from-data-source.ts
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// Example of how you would create a table and add data to it from a data source
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {
|
||||||
|
Document,
|
||||||
|
HeadingLevel,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
VerticalAlign,
|
||||||
|
TextDirection,
|
||||||
|
TextRun,
|
||||||
|
WidthType,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
|
interface StockPrice {
|
||||||
|
readonly date: Date;
|
||||||
|
readonly ticker: string;
|
||||||
|
readonly price: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DATA: StockPrice[] = [
|
||||||
|
{
|
||||||
|
date: new Date("2007-08-28"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 18.12,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-08-29"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.15,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-08-30"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.46,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-08-31"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.78,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-04"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 20.59,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-05"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.54,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-06"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.29,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-07"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 18.82,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-10"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.53,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-11"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.36,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-12"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.55,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-13"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-14"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.83,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
date: new Date("2007-09-17"),
|
||||||
|
ticker: "Apple",
|
||||||
|
price: 19.77,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const generateRows = (prices: StockPrice[]): TableRow[] =>
|
||||||
|
prices.map(
|
||||||
|
({ date, ticker, price }) =>
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(date.toString())],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(ticker)],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(price.toString())],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
children: [
|
||||||
|
new Table({
|
||||||
|
width: {
|
||||||
|
size: 9070,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Date",
|
||||||
|
bold: true,
|
||||||
|
size: 40,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Ticker",
|
||||||
|
bold: true,
|
||||||
|
size: 40,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.LEFT_TO_RIGHT_TOP_TO_BOTTOM,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Price",
|
||||||
|
bold: true,
|
||||||
|
size: 40,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
...generateRows(DATA),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
49
demo/80-thai-distributed.ts
Normal file
49
demo/80-thai-distributed.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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 { AlignmentType, convertMillimetersToTwip, Document, Packer, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: "test",
|
||||||
|
name: "Test",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: convertMillimetersToTwip(6.4) },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
page: {
|
||||||
|
margin: {
|
||||||
|
top: 0,
|
||||||
|
right: convertMillimetersToTwip(24),
|
||||||
|
bottom: convertMillimetersToTwip(24),
|
||||||
|
left: convertMillimetersToTwip(24),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
alignment: AlignmentType.THAI_DISTRIBUTE,
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "บริษัทฯ มีเงินสด 41,985.00 บาท และ 25,855.66 บาทตามลำดับ เงินสดทั้งจำนวนอยู่ในความดูแลและรับผิดชอบของกรรมการ บริษัทฯบันทึกการรับชำระเงินและการจ่ายชำระเงินผ่านบัญชีเงินสดเพียงเท่านั้น ซึ่งอาจกระทบต่อความถูกต้องครบถ้วนของการบันทึกบัญชี ทั้งนี้ขึ้นอยู่กับระบบการควบคุมภายในของบริษัท",
|
||||||
|
size: 28,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
148
demo/81-continuous-header.ts
Normal file
148
demo/81-continuous-header.ts
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Example of a continuous header
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Footer, Header, Packer, Paragraph, SectionType, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
creator: "Creator",
|
||||||
|
title: "Title",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: { titlePage: true },
|
||||||
|
headers: {
|
||||||
|
first: new Header({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "HEADER PAGE ONE",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
default: new Header({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "HEADER PAGE TWO AND FOLLOWING PAGES",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
first: new Footer({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "FOOTER PAGE ONE",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
default: new Footer({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "FOOTER PAGE TWO AND FOLLOWING PAGES",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac suscipit orci, in lobortis risus. Nulla vehicula rutrum finibus. Nullam consequat, magna in vehicula commodo, enim massa consectetur nisl, sit amet rutrum nunc ante vel lorem. Sed sit amet scelerisque velit. Proin non quam eget mauris aliquet posuere a sed orci. Proin posuere ante suscipit neque dignissim hendrerit. Pellentesque eget dapibus metus. Donec at mollis mauris. Vestibulum sit amet scelerisque nulla. Vivamus ipsum erat, tempor sed volutpat non, molestie at odio. Vivamus lectus ligula, finibus at mattis vitae, euismod sed tellus. Etiam neque massa, faucibus a fringilla nec, mollis at ex. Aliquam eget nibh tortor. Sed ut viverra libero. Nulla facilisis bibendum quam eget porttitor.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed eget nunc ac turpis facilisis volutpat. Duis eget arcu vitae neque porta hendrerit. Proin vel ante nulla. Duis congue efficitur dui. Suspendisse potenti. Aliquam aliquam nibh eu ipsum sagittis efficitur. Quisque sagittis metus dui, vitae suscipit tortor sollicitudin at. Suspendisse convallis, sem ac ornare condimentum, odio ipsum dapibus justo, a aliquam risus massa ut enim. Mauris vel placerat nibh. Ut iaculis vitae nibh at elementum. Quisque hendrerit et magna vitae mollis. Duis dictum euismod leo, at cursus risus sodales sed.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
spacing: {
|
||||||
|
after: 500,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "The first section ends after this paragraph.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
type: SectionType.CONTINUOUS,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac suscipit orci, in lobortis risus. Nulla vehicula rutrum finibus. Nullam consequat, magna in vehicula commodo, enim massa consectetur nisl, sit amet rutrum nunc ante vel lorem. Sed sit amet scelerisque velit. Proin non quam eget mauris aliquet posuere a sed orci. Proin posuere ante suscipit neque dignissim hendrerit. Pellentesque eget dapibus metus. Donec at mollis mauris. Vestibulum sit amet scelerisque nulla. Vivamus ipsum erat, tempor sed volutpat non, molestie at odio. Vivamus lectus ligula, finibus at mattis vitae, euismod sed tellus. Etiam neque massa, faucibus a fringilla nec, mollis at ex. Aliquam eget nibh tortor. Sed ut viverra libero. Nulla facilisis bibendum quam eget porttitor.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed eget nunc ac turpis facilisis volutpat. Duis eget arcu vitae neque porta hendrerit. Proin vel ante nulla. Duis congue efficitur dui. Suspendisse potenti. Aliquam aliquam nibh eu ipsum sagittis efficitur. Quisque sagittis metus dui, vitae suscipit tortor sollicitudin at. Suspendisse convallis, sem ac ornare condimentum, odio ipsum dapibus justo, a aliquam risus massa ut enim. Mauris vel placerat nibh. Ut iaculis vitae nibh at elementum. Quisque hendrerit et magna vitae mollis. Duis dictum euismod leo, at cursus risus sodales sed.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "The second section starts with the headline above. Move cursor to the end of this text and press enter until next page is generated in continuous section break mode.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
148
demo/82-new-headers-new-section.ts
Normal file
148
demo/82-new-headers-new-section.ts
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
// Example of using headers and footers in a new section
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Footer, Header, Packer, Paragraph, SectionType, Tab, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
creator: "Creator",
|
||||||
|
title: "Title",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
default: new Header({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "HEADER PAGE ONE",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: new Footer({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "FOOTER PAGE ONE",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac suscipit orci, in lobortis risus. Nulla vehicula rutrum finibus. Nullam consequat, magna in vehicula commodo, enim massa consectetur nisl, sit amet rutrum nunc ante vel lorem. Sed sit amet scelerisque velit. Proin non quam eget mauris aliquet posuere a sed orci. Proin posuere ante suscipit neque dignissim hendrerit. Pellentesque eget dapibus metus. Donec at mollis mauris. Vestibulum sit amet scelerisque nulla. Vivamus ipsum erat, tempor sed volutpat non, molestie at odio. Vivamus lectus ligula, finibus at mattis vitae, euismod sed tellus. Etiam neque massa, faucibus a fringilla nec, mollis at ex. Aliquam eget nibh tortor. Sed ut viverra libero. Nulla facilisis bibendum quam eget porttitor.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed eget nunc ac turpis facilisis volutpat. Duis eget arcu vitae neque porta hendrerit. Proin vel ante nulla. Duis congue efficitur dui. Suspendisse potenti. Aliquam aliquam nibh eu ipsum sagittis efficitur. Quisque sagittis metus dui, vitae suscipit tortor sollicitudin at. Suspendisse convallis, sem ac ornare condimentum, odio ipsum dapibus justo, a aliquam risus massa ut enim. Mauris vel placerat nibh. Ut iaculis vitae nibh at elementum. Quisque hendrerit et magna vitae mollis. Duis dictum euismod leo, at cursus risus sodales sed.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
spacing: {
|
||||||
|
after: 500,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "The first section ends after this paragraph.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
default: new Header({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "HEADER PAGE TWO AND FOLLOWING PAGES",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: new Footer({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "FOOTER PAGE TWO AND FOLLOWING PAGES",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac suscipit orci, in lobortis risus. Nulla vehicula rutrum finibus. Nullam consequat, magna in vehicula commodo, enim massa consectetur nisl, sit amet rutrum nunc ante vel lorem. Sed sit amet scelerisque velit. Proin non quam eget mauris aliquet posuere a sed orci. Proin posuere ante suscipit neque dignissim hendrerit. Pellentesque eget dapibus metus. Donec at mollis mauris. Vestibulum sit amet scelerisque nulla. Vivamus ipsum erat, tempor sed volutpat non, molestie at odio. Vivamus lectus ligula, finibus at mattis vitae, euismod sed tellus. Etiam neque massa, faucibus a fringilla nec, mollis at ex. Aliquam eget nibh tortor. Sed ut viverra libero. Nulla facilisis bibendum quam eget porttitor.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed eget nunc ac turpis facilisis volutpat. Duis eget arcu vitae neque porta hendrerit. Proin vel ante nulla. Duis congue efficitur dui. Suspendisse potenti. Aliquam aliquam nibh eu ipsum sagittis efficitur. Quisque sagittis metus dui, vitae suscipit tortor sollicitudin at. Suspendisse convallis, sem ac ornare condimentum, odio ipsum dapibus justo, a aliquam risus massa ut enim. Mauris vel placerat nibh. Ut iaculis vitae nibh at elementum. Quisque hendrerit et magna vitae mollis. Duis dictum euismod leo, at cursus risus sodales sed.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Sed gravida commodo felis, at aliquet risus volutpat ut. Nam nec ex eleifend tellus sodales volutpat nec ac nibh. Vestibulum pretium, leo vitae lobortis accumsan, urna libero euismod ante, consequat aliquam enim risus id nisl. Donec sagittis, justo eu luctus posuere, leo purus pellentesque turpis, eget volutpat mi leo vitae lacus. Etiam ante ante, posuere at augue non, lacinia ornare purus. Praesent vitae velit in enim congue maximus. Vivamus tincidunt fringilla neque. Curabitur fermentum justo nec sapien porttitor, ac ullamcorper nisi imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed non orci vel eros egestas eleifend sit amet a diam. Duis mattis at ligula quis faucibus. Donec elementum lacus velit, a vehicula nunc gravida a. Phasellus eget nunc vehicula, varius velit a, maximus velit. Sed a suscipit nisi, non hendrerit felis. Proin mattis facilisis massa, quis elementum neque fringilla non.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "The second section starts with the headline above. Move cursor to the end of this text and press enter until next page is generated in continuous section break mode.",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
69
demo/83-setting-languages.ts
Normal file
69
demo/83-setting-languages.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// 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, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
|
default: {
|
||||||
|
document: {
|
||||||
|
run: {
|
||||||
|
color: "ff0000",
|
||||||
|
language: {
|
||||||
|
value: "es-ES",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: "frenchNormal",
|
||||||
|
name: "French Normal",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
run: {
|
||||||
|
color: "999999",
|
||||||
|
italics: true,
|
||||||
|
language: {
|
||||||
|
value: "fr-FR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "koreanNormal",
|
||||||
|
name: "Korean Normal",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
run: {
|
||||||
|
color: "0000ff",
|
||||||
|
bold: true,
|
||||||
|
language: {
|
||||||
|
value: "ko-KR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "Yo vivo en Granada, una ciudad pequeña que tiene monumentos muy importantes como la Alhambra. Aquí la comida es deliciosa y son famosos el gazpacho, el rebujito y el salmorejo.",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "Toute personne a droit à l'éducation. L'éducation doit être gratuite, au moins en ce qui concerne l'enseignement élémentaire et fondamental. L'enseignement élémentaire est obligatoire. L'enseignement technique et professionnel doit être généralisé; l'accès aux études supérieures doit être ouvert en pleine égalité à tous en fonction de leur mérite.",
|
||||||
|
style: "frenchNormal",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "대법관은 대법원장의 제청으로 국회의 동의를 얻어 대통령이 임명한다. 강화조약. 국가는 국민 모두의 생산 및 생활의 기반이 되는 국토의 효율적이고 균형있는 이용·개발과 보전을 위하여 법률이 정하는 바에 의하여 그에 관한 필요한 제한과 의무를 과할 수 있다, 국가는 청원에 대하여 심사할 의무를 진다.",
|
||||||
|
style: "koreanNormal",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
60
demo/84-positional-tabs.ts
Normal file
60
demo/84-positional-tabs.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// Simple example apply positional tabs to a document
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {
|
||||||
|
Document,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
PositionalTab,
|
||||||
|
Tab,
|
||||||
|
TextRun,
|
||||||
|
PositionalTabAlignment,
|
||||||
|
PositionalTabRelativeTo,
|
||||||
|
PositionalTabLeader,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Full name"),
|
||||||
|
new TextRun({
|
||||||
|
children: [
|
||||||
|
new PositionalTab({
|
||||||
|
alignment: PositionalTabAlignment.RIGHT,
|
||||||
|
relativeTo: PositionalTabRelativeTo.MARGIN,
|
||||||
|
leader: PositionalTabLeader.DOT,
|
||||||
|
}),
|
||||||
|
"John Doe",
|
||||||
|
],
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World"),
|
||||||
|
new TextRun({
|
||||||
|
children: [
|
||||||
|
new PositionalTab({
|
||||||
|
alignment: PositionalTabAlignment.CENTER,
|
||||||
|
relativeTo: PositionalTabRelativeTo.INDENT,
|
||||||
|
leader: PositionalTabLeader.HYPHEN,
|
||||||
|
}),
|
||||||
|
"Foo bar",
|
||||||
|
],
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
@ -24,7 +24,7 @@
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new docx.TextRun({
|
new docx.TextRun({
|
||||||
text: "\tGithub is the best",
|
children: [new docx.Tab(), "Github is the best"],
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -11,22 +11,26 @@
|
|||||||
- [Document](usage/document.md)
|
- [Document](usage/document.md)
|
||||||
- [Sections](usage/sections.md)
|
- [Sections](usage/sections.md)
|
||||||
- [Paragraph](usage/paragraph.md)
|
- [Paragraph](usage/paragraph.md)
|
||||||
|
- [Text Frames](usage/text-frames.md)
|
||||||
|
- [Symbols](usage/symbols.md)
|
||||||
- [Text](usage/text.md)
|
- [Text](usage/text.md)
|
||||||
- [Image](usage/images.md)
|
- [Images](usage/images.md)
|
||||||
- [Headers & Footers](usage/headers-and-footers.md)
|
- [Headers & Footers](usage/headers-and-footers.md)
|
||||||
- [Bullet Points](usage/bullet-points.md)
|
- [Bullet Points](usage/bullet-points.md)
|
||||||
- [Hyperlinks](usage/hyperlinks.md)
|
- [Hyperlinks](usage/hyperlinks.md)
|
||||||
- [Numbering](usage/numbering.md)
|
- [Numbering](usage/numbering.md)
|
||||||
- [Tables](usage/tables.md)
|
- [Tables](usage/tables.md)
|
||||||
- [Tab Stops](usage/tab-stops.md)
|
- [Tabs](usage/tabs.md)
|
||||||
- [Table of Contents](usage/table-of-contents.md)
|
- [Table of Contents](usage/table-of-contents.md)
|
||||||
- [Page Numbers](usage/page-numbers.md)
|
- [Page Numbers](usage/page-numbers.md)
|
||||||
- [Change Tracking](usage/change-tracking.md)
|
- [Change Tracking](usage/change-tracking.md)
|
||||||
- [Math](usage/math.md)
|
- [Math](usage/math.md)
|
||||||
- [Text Frames](usage/text-frames.md)
|
- [Comments](usage/comments.md)
|
||||||
|
- [Footnotes](usage/footnotes.md)
|
||||||
|
- [Fields](usage/fields.md)
|
||||||
- Styling
|
- Styling
|
||||||
_ [Styling with JS](usage/styling-with-js.md)
|
- [Styling with JS](usage/styling-with-js.md)
|
||||||
_ [Styling with XML](usage/styling-with-xml.md)
|
- [Styling with XML](usage/styling-with-xml.md)
|
||||||
|
|
||||||
- Exporting
|
- Exporting
|
||||||
|
|
||||||
|
@ -22,20 +22,19 @@ const doc = new docx.Document({
|
|||||||
|
|
||||||
### Full list of options:
|
### Full list of options:
|
||||||
|
|
||||||
|
- creator
|
||||||
* creator
|
- description
|
||||||
* description
|
- title
|
||||||
* title
|
- subject
|
||||||
* subject
|
- keywords
|
||||||
* keywords
|
- lastModifiedBy
|
||||||
* lastModifiedBy
|
- revision
|
||||||
* revision
|
- externalStyles
|
||||||
* externalStyles
|
- styles
|
||||||
* styles
|
- numbering
|
||||||
* numbering
|
- footnotes
|
||||||
* footnotes
|
- hyperlinks
|
||||||
* hyperlinks
|
- background
|
||||||
* background
|
|
||||||
|
|
||||||
### Change background color of Document
|
### Change background color of Document
|
||||||
|
|
||||||
@ -55,3 +54,87 @@ You can mix and match whatever properties you want, or provide no properties.
|
|||||||
|
|
||||||
Various parts of the API require positioning arguments. The units are "20ths of a point" from the [OOXML](http://officeopenxml.com/index.php) specification.
|
Various parts of the API require positioning arguments. The units are "20ths of a point" from the [OOXML](http://officeopenxml.com/index.php) specification.
|
||||||
See [Lars Corneliussen's blog post](https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/) for more information and how to convert units.
|
See [Lars Corneliussen's blog post](https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/) for more information and how to convert units.
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
Compatibility Settings are optional settings used to preserve visual fidelity of documents created in earlier word processing applications. Some of these settings provide ability for specific behaviors, described in detail below; and others simply instruct applications to mimic the behavior of an existing word processing application.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const doc = new docx.Document({
|
||||||
|
compatibility: {
|
||||||
|
version: 15,
|
||||||
|
doNotExpandShiftReturn: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compatibility Options
|
||||||
|
|
||||||
|
| Property | Type | Notes | Possible Values |
|
||||||
|
| ----------------------------------- | --------- | -------- | ---------------------------- |
|
||||||
|
| version | `number` | Optional | `15`, `16`, `17` |
|
||||||
|
| useSingleBorderforContiguousCells | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| wordPerfectJustification | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| noTabStopForHangingIndent | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| noLeading | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| spaceForUnderline | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| noColumnBalance | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| balanceSingleByteDoubleByteWidth | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| noExtraLineSpacing | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotLeaveBackslashAlone | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| underlineTrailingSpaces | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotExpandShiftReturn | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| spacingInWholePoints | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| lineWrapLikeWord6 | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| printBodyTextBeforeHeader | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| printColorsBlack | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| spaceWidth | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| showBreaksInFrames | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| subFontBySize | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| suppressBottomSpacing | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| suppressTopSpacing | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| suppressSpacingAtTopOfPage | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| suppressTopSpacingWP | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| suppressSpBfAfterPgBrk | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| swapBordersFacingPages | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| convertMailMergeEsc | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| truncateFontHeightsLikeWP6 | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| macWordSmallCaps | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| usePrinterMetrics | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotSuppressParagraphBorders | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| wrapTrailSpaces | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| footnoteLayoutLikeWW8 | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| shapeLayoutLikeWW8 | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| alignTablesRowByRow | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| forgetLastTabAlignment | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| adjustLineHeightInTable | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| autoSpaceLikeWord95 | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| noSpaceRaiseLower | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotUseHTMLParagraphAutoSpacing | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| layoutRawTableWidth | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| layoutTableRowsApart | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useWord97LineBreakRules | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotBreakWrappedTables | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotSnapToGridInCell | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| selectFieldWithFirstOrLastCharacter | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| applyBreakingRules | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotWrapTextWithPunctuation | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotUseEastAsianBreakRules | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useWord2002TableStyleRules | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| growAutofit | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useFELayout | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useNormalStyleForList | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotUseIndentAsNumberingTabStop | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useAlternateEastAsianLineBreakRules | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| allowSpaceOfSameStyleInTable | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotSuppressIndentation | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotAutofitConstrainedTables | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| autofitToFirstFixedWidthCell | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| underlineTabInNumberingList | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| displayHangulFixedWidth | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| splitPgBreakAndParaMark | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotVerticallyAlignCellWithSp | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| doNotBreakConstrainedForcedTable | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| ignoreVerticalAlignmentInTextboxes | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| useAnsiKerningPairs | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
| cachedColumnBalance | `boolean` | Optional | `true`, `false`, `undefined` |
|
||||||
|
@ -252,13 +252,36 @@ const image = new ImageRun({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Alternative Text
|
||||||
|
|
||||||
|
Specifies common non-visual DrawingML properties. A name, title and description for a picture can be specified.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const image = new ImageRun({
|
||||||
|
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||||
|
altText: {
|
||||||
|
title: "This is an ultimate title",
|
||||||
|
description: "This is an ultimate image",
|
||||||
|
name: "My Ultimate Image",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Property | Type | Notes | Possible Values |
|
||||||
|
| ----------- | -------- | -------- | ------------------------------------ |
|
||||||
|
| name | `string` | Required | `Specimen A` |
|
||||||
|
| title | `string` | Required | `My awesome title of my image` |
|
||||||
|
| description | `string` | Required | `My awesome description of my image` |
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Add image to the document
|
### Add image to the document
|
||||||
|
|
||||||
Importing Images from file system path
|
Importing Images from file system path
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/5-images.ts ':include')
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/5-images.ts ":include")
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/5-images.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/5-images.ts_
|
||||||
|
|
||||||
@ -266,7 +289,7 @@ _Source: https://github.com/dolanmiu/docx/blob/master/demo/5-images.ts_
|
|||||||
|
|
||||||
Example showing how to add image to headers and footers
|
Example showing how to add image to headers and footers
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/9-images-in-header-and-footer.ts ':include')
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/9-images-in-header-and-footer.ts ":include")
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/9-images-in-header-and-footer.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/9-images-in-header-and-footer.ts_
|
||||||
|
|
||||||
@ -274,6 +297,6 @@ _Source: https://github.com/dolanmiu/docx/blob/master/demo/9-images-in-header-an
|
|||||||
|
|
||||||
Example showing how to float images on top of text and optimally give a `margin`
|
Example showing how to float images on top of text and optimally give a `margin`
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/38-text-wrapping.ts ':include')
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/38-text-wrapping.ts ":include")
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/38-text-wrapping.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/38-text-wrapping.ts_
|
||||||
|
@ -86,3 +86,34 @@ topLevelP.setNumbering(concrete, 0);
|
|||||||
subP.setNumbering(concrete, 1);
|
subP.setNumbering(concrete, 1);
|
||||||
subSubP.setNumbering(concrete, 2);
|
subSubP.setNumbering(concrete, 2);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Unindent numbering
|
||||||
|
|
||||||
|
Default:1. test
|
||||||
|
|
||||||
|
After:1.test
|
||||||
|
|
||||||
|
Use default numbering have indent,If you want unindent numbering
|
||||||
|
|
||||||
|
How to custom number see the demo:
|
||||||
|
https://runkit.com/dolanmiu/docx-demo3
|
||||||
|
|
||||||
|
```ts
|
||||||
|
|
||||||
|
enum LevelSuffix {
|
||||||
|
NOTHING = "nothing",
|
||||||
|
SPACE = "space",
|
||||||
|
TAB = "tab"
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom numbering
|
||||||
|
const levels=[
|
||||||
|
{
|
||||||
|
level: 0,
|
||||||
|
format: "decimal",
|
||||||
|
text: "%1.",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
suffix: LevelSuffix.NOTHING, // Cancel intent
|
||||||
|
}]
|
||||||
|
|
||||||
|
```
|
||||||
|
@ -61,13 +61,13 @@ const doc = new Document({
|
|||||||
This is the list of options for a paragraph. A detailed explanation is below:
|
This is the list of options for a paragraph. A detailed explanation is below:
|
||||||
|
|
||||||
| Property | Type | Mandatory? | Possible Values |
|
| Property | Type | Mandatory? | Possible Values |
|
||||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
|
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [text](#text) | `string` | Optional | |
|
| [text](#text) | `string` | Optional | |
|
||||||
| [heading](#heading) | `HeadingLevel` | Optional | `HEADING_1`, `HEADING_2`, `HEADING_3`, `HEADING_4`, `HEADING_5`, `HEADING_6`, `TITLE` |
|
| [heading](#heading) | `HeadingLevel` | Optional | `HEADING_1`, `HEADING_2`, `HEADING_3`, `HEADING_4`, `HEADING_5`, `HEADING_6`, `TITLE` |
|
||||||
| [border](#border) | `IBorderOptions` | Optional | `top`, `bottom`, `left`, `right`. Each of these are of type IBorderPropertyOptions. Click here for Example |
|
| [border](#border) | `IBorderOptions` | Optional | `top`, `bottom`, `left`, `right`. Each of these are of type IBorderPropertyOptions. Click here for Example |
|
||||||
| [spacing](#spacing) | `ISpacingProperties` | Optional | See below for ISpacingProperties |
|
| [spacing](#spacing) | `ISpacingProperties` | Optional | See below for ISpacingProperties |
|
||||||
| [outlineLevel](#outline-level) | `number` | Optional | |
|
| [outlineLevel](#outline-level) | `number` | Optional | |
|
||||||
| alignment | `AlignmentType` | Optional | |
|
| alignment | `AlignmentType` | Optional | `START`, `CENTER`, `END`, `BOTH`, `MEDIUM_KASHIDA`, `DISTRIBUTE`, `NUM_TAB`, `HIGH_KASHIDA`, `LOW_KASHIDA`, `THAI_DISTRIBUTE`, `LEFT`, `RIGHT`, `JUSTIFIED` |
|
||||||
| heading | `HeadingLevel` | Optional | |
|
| heading | `HeadingLevel` | Optional | |
|
||||||
| bidirectional | `boolean` | Optional | |
|
| bidirectional | `boolean` | Optional | |
|
||||||
| thematicBreak | `boolean` | Optional | |
|
| thematicBreak | `boolean` | Optional | |
|
||||||
@ -111,7 +111,7 @@ const paragraph = new Paragraph({
|
|||||||
|
|
||||||
## Border
|
## Border
|
||||||
|
|
||||||
Add borders to a `Paragraph`. Good for making the `Paragraph` stand out
|
Add borders to a `Paragraph`. Good for making the `Paragraph` stand out. Border top and border bottom can be used as a horizontal rule (also known as horizontal line).
|
||||||
|
|
||||||
#### IBorderPropertyOptions
|
#### IBorderPropertyOptions
|
||||||
|
|
||||||
@ -181,11 +181,13 @@ Adding spacing between paragraphs
|
|||||||
### ISpacingProperties
|
### ISpacingProperties
|
||||||
|
|
||||||
| Property | Type | Notes | Possible Values |
|
| Property | Type | Notes | Possible Values |
|
||||||
| -------- | -------------- | -------- | ----------------------------- |
|
| -------- | -------------- | -------- | -------------------------------------- |
|
||||||
| after | `number` | Optional | |
|
| after | `number` | Optional | |
|
||||||
| before | `number` | Optional | |
|
| before | `number` | Optional | |
|
||||||
| line | `number` | Optional | |
|
| line | `number` | Optional | |
|
||||||
| lineRule | `LineRuleType` | Optional | `AT_LEAST`, `EXACTLY`, `AUTO` |
|
| lineRule | `LineRuleType` | Optional | `AT_LEAST`, `EXACTLY`, `EXACT`, `AUTO` |
|
||||||
|
|
||||||
|
Note: The `lineRule` property has different values depending on the version of Word you are using. The `EXACTLY` value is only available in Word 2016 and above. Use `EXACT` for greater support, including LibreOffice etc. Read this issue for more information: https://github.com/dolanmiu/docx/issues/1773.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
# Tab Stops
|
|
||||||
|
|
||||||
> Tab stops are useful, if you are unclear of what they are, [here is a link explaining](https://en.wikipedia.org/wiki/Tab_stop). It enables side by side text which is nicely laid out without the need for tables, or constantly pressing space bar.
|
|
||||||
|
|
||||||
!> **Note**: The unit of measurement for a tab stop is in [DXA](https://stackoverflow.com/questions/14360183/default-wordml-unit-measurement-pixel-or-point-or-inches)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Simply declare the tab stops on the paragraph, as shown below. Use the tab character `\t` to indicate the tab position within the `text` property of a `TextRun`. Adding multiple `tabStops` will mean you can add additional `\t` characters until the desired `tabStop` is selected. Example is shown below.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
children: [new TextRun({ text: "Hey everyone", bold: true}), new TextRun("\t11th November 1999")],
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: TabStopPosition.MAX,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
The example above will create a left aligned text, and a right aligned text on the same line. The laymans approach to this problem would be to either use text boxes or tables. Not ideal!
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
children: [new TextRun("\t\tSecond tab stop here I come!")],
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: TabStopPosition.MAX,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: TabStopType.LEFT,
|
|
||||||
position: 1000,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
The above shows the use of two tab stops, and how to select/use it.
|
|
||||||
|
|
||||||
You can add multiple tab stops of the same `type` too.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
children: [new TextRun("Multiple \ttab \tstops!")],
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: TabStopPosition.MAX,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: 1000,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Left Tab Stop
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.LEFT,
|
|
||||||
position: 2268,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
|
||||||
## Center Tab Stop
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.CENTER,
|
|
||||||
position: 2268,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
2268 is the distance from the center.
|
|
||||||
|
|
||||||
## Right Tab Stop
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: 2268,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
|
||||||
## Max Right Tab Stop
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const paragraph = new Paragraph({
|
|
||||||
tabStops: [
|
|
||||||
{
|
|
||||||
type: TabStopType.RIGHT,
|
|
||||||
position: TabStopPosition.MAX,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create a tab stop on the very edge of the right hand side. Handy for right aligning and left aligning text on the same line.
|
|
184
docs/usage/tabs.md
Normal file
184
docs/usage/tabs.md
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
# Tabs and Tab Stops
|
||||||
|
|
||||||
|
## Tab Stops
|
||||||
|
|
||||||
|
> Tab stops are useful, if you are unclear of what they are, [here is a link explaining](https://en.wikipedia.org/wiki/Tab_stop). It enables side by side text which is nicely laid out without the need for tables, or constantly pressing space bar.
|
||||||
|
|
||||||
|
!> **Note**: The unit of measurement for a tab stop is in [DXA](https://stackoverflow.com/questions/14360183/default-wordml-unit-measurement-pixel-or-point-or-inches)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Simply declare the tab stops on the paragraph, as shown below. Use the tab character `\t` or add the `new Tab()` child to indicate the tab position within the `text` property of a `TextRun`. Adding multiple `tabStops` will mean you can add additional `\t` characters until the desired `tabStop` is selected. Example is shown below.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({ text: "Hey everyone", bold: true }),
|
||||||
|
new TextRun("\t11th November 1999"),
|
||||||
|
new TextRun({
|
||||||
|
children: [new Tab(), "11th November 1999"],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The example above will create a left aligned text, and a right aligned text on the same line. The laymans approach to this problem would be to either use text boxes or tables. Not ideal!
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [new TextRun("\t\tSecond tab stop here I come!")],
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: TabStopType.LEFT,
|
||||||
|
position: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The above shows the use of two tab stops, and how to select/use it.
|
||||||
|
|
||||||
|
You can add multiple tab stops of the same `type` too.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [new TextRun("Multiple \ttab \tstops!")],
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Multiple ", new Tab(), "tab ", new Tab(), "stops!"],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Left Tab Stop
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.LEFT,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
2268 is the distance from the left side.
|
||||||
|
|
||||||
|
### Center Tab Stop
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.CENTER,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
2268 is the distance from the center.
|
||||||
|
|
||||||
|
### Right Tab Stop
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
2268 is the distance from the left side.
|
||||||
|
|
||||||
|
### Max Right Tab Stop
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a tab stop on the very edge of the right hand side. Handy for right aligning and left aligning text on the same line.
|
||||||
|
|
||||||
|
## Positional Tabs
|
||||||
|
|
||||||
|
> Positional tab allow you to create a tab stop that is relative to the margin, or the page. This is useful if you want to create a table of contents, or a table of figures.
|
||||||
|
|
||||||
|
They are easier to use than the normal tab stops, as you can use the `PositionalTab` class to create a tab stop, and then add the text to the `TextRun` children. Useful for most cases.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Full name"),
|
||||||
|
new TextRun({
|
||||||
|
children: [
|
||||||
|
new PositionalTab({
|
||||||
|
alignment: PositionalTabAlignment.RIGHT,
|
||||||
|
relativeTo: PositionalTabRelativeTo.MARGIN,
|
||||||
|
leader: PositionalTabLeader.DOT,
|
||||||
|
}),
|
||||||
|
"John Doe",
|
||||||
|
],
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Option | Type | Description | Possible Values |
|
||||||
|
| ---------- | ------------------------- | ------------------------------------- | ------------------------------------------------------------- |
|
||||||
|
| alignment | `PositionalTabAlignment` | The alignment of the tab stop | `LEFT`, `RIGHT`, `CENTER` |
|
||||||
|
| relativeTo | `PositionalTabRelativeTo` | The relative position of the tab stop | `MARGIN`, `INDENT` |
|
||||||
|
| leader | `PositionalTabLeader` | The leader of the tab stop | `NONE`, `DOT`, `HYPHEN`, `UNDERSCORE`, `MIDDLE_DOT`, `EQUALS` |
|
@ -151,6 +151,28 @@ const text = new TextRun({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Vanish and SpecVanish
|
||||||
|
|
||||||
|
You may want to hide your text in your document.
|
||||||
|
|
||||||
|
`Vanish` should affect the normal display of text, but an application may have settings to force hidden text to be displayed.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const text = new TextRun({
|
||||||
|
text: "This text will be hidden",
|
||||||
|
vanish: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
`SpecVanish` was typically used to ensure that a paragraph style can be applied to a part of a paragraph, and still appear as in the Table of Contents (which in previous word processors would ignore the use of the style if it were being used as a character style).
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const text = new TextRun({
|
||||||
|
text: "This text will be hidden forever.",
|
||||||
|
specVanish: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## Break
|
## Break
|
||||||
|
|
||||||
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
||||||
|
4591
package-lock.json
generated
4591
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "docx",
|
"name": "docx",
|
||||||
"version": "7.5.0",
|
"version": "7.8.2",
|
||||||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -52,7 +52,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^18.0.0",
|
"@types/node": "^18.0.0",
|
||||||
"jszip": "^3.1.5",
|
"jszip": "^3.1.5",
|
||||||
"nanoid": "^3.1.20",
|
"nanoid": "^3.3.4",
|
||||||
"xml": "^1.0.1",
|
"xml": "^1.0.1",
|
||||||
"xml-js": "^1.6.8"
|
"xml-js": "^1.6.8"
|
||||||
},
|
},
|
||||||
@ -65,7 +65,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^4.2.15",
|
"@types/chai": "^4.2.15",
|
||||||
"@types/glob": "^8.0.0",
|
"@types/glob": "^8.0.0",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^10.0.0",
|
||||||
"@types/prompt": "^1.1.1",
|
"@types/prompt": "^1.1.1",
|
||||||
"@types/request-promise": "^4.1.42",
|
"@types/request-promise": "^4.1.42",
|
||||||
"@types/shelljs": "^0.8.9",
|
"@types/shelljs": "^0.8.9",
|
||||||
@ -75,16 +75,16 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||||
"@typescript-eslint/parser": "^5.36.1",
|
"@typescript-eslint/parser": "^5.36.1",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"chai": "^3.5.0",
|
"chai": "^4.3.6",
|
||||||
"cspell": "^6.2.2",
|
"cspell": "^6.2.2",
|
||||||
"docsify-cli": "^4.3.0",
|
"docsify-cli": "^4.3.0",
|
||||||
"eslint": "^8.23.0",
|
"eslint": "^8.23.0",
|
||||||
"eslint-plugin-functional": "^4.3.1",
|
"eslint-plugin-functional": "^5.0.1",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-jsdoc": "^39.3.6",
|
"eslint-plugin-jsdoc": "^39.3.6",
|
||||||
"eslint-plugin-no-null": "^1.0.2",
|
"eslint-plugin-no-null": "^1.0.2",
|
||||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||||
"eslint-plugin-unicorn": "^43.0.2",
|
"eslint-plugin-unicorn": "^45.0.0",
|
||||||
"glob": "^8.0.1",
|
"glob": "^8.0.1",
|
||||||
"jszip": "^3.1.5",
|
"jszip": "^3.1.5",
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.0.0",
|
||||||
@ -96,19 +96,19 @@
|
|||||||
"replace-in-file": "^6.2.0",
|
"replace-in-file": "^6.2.0",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^4.0.4",
|
||||||
"shelljs": "^0.8.4",
|
"shelljs": "^0.8.4",
|
||||||
"sinon": "^14.0.0",
|
"sinon": "^15.0.0",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"ts-loader": "^9.0.0",
|
"ts-loader": "^9.0.0",
|
||||||
"ts-node": "^10.2.1",
|
"ts-node": "^10.2.1",
|
||||||
"tsconfig-paths": "^4.0.0",
|
"tsconfig-paths": "^4.0.0",
|
||||||
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
||||||
"typedoc": "^0.23.2",
|
"typedoc": "^0.23.2",
|
||||||
"typescript": "4.7.4",
|
"typescript": "4.9.5",
|
||||||
"unzipper": "^0.10.11",
|
"unzipper": "^0.10.11",
|
||||||
"webpack": "^5.28.0",
|
"webpack": "^5.28.0",
|
||||||
"webpack-cli": "^4.6.0"
|
"webpack-cli": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
|
@ -2,7 +2,7 @@ import { BaseXmlComponent, IContext, IXmlableObject } from "@file/xml-components
|
|||||||
|
|
||||||
export class Formatter {
|
export class Formatter {
|
||||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||||
public format(input: BaseXmlComponent, context: IContext = {} as IContext): IXmlableObject {
|
public format(input: BaseXmlComponent, context: IContext = { stack: [] } as unknown as IContext): IXmlableObject {
|
||||||
const output = input.prepForXml(context);
|
const output = input.prepForXml(context);
|
||||||
|
|
||||||
if (output) {
|
if (output) {
|
||||||
|
@ -74,6 +74,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Document.View, {
|
this.formatter.format(file.Document.View, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -100,6 +101,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Document.Relationships, {
|
this.formatter.format(file.Document.Relationships, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -125,6 +127,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Styles, {
|
this.formatter.format(file.Styles, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -144,6 +147,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.CoreProperties, {
|
this.formatter.format(file.CoreProperties, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -160,6 +164,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Numbering, {
|
this.formatter.format(file.Numbering, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -176,6 +181,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.FileRelationships, {
|
this.formatter.format(file.FileRelationships, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -191,6 +197,7 @@ export class Compiler {
|
|||||||
this.formatter.format(headerWrapper.View, {
|
this.formatter.format(headerWrapper.View, {
|
||||||
viewWrapper: headerWrapper,
|
viewWrapper: headerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -214,6 +221,7 @@ export class Compiler {
|
|||||||
this.formatter.format(headerWrapper.Relationships, {
|
this.formatter.format(headerWrapper.Relationships, {
|
||||||
viewWrapper: headerWrapper,
|
viewWrapper: headerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -230,6 +238,7 @@ export class Compiler {
|
|||||||
this.formatter.format(footerWrapper.View, {
|
this.formatter.format(footerWrapper.View, {
|
||||||
viewWrapper: footerWrapper,
|
viewWrapper: footerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -253,6 +262,7 @@ export class Compiler {
|
|||||||
this.formatter.format(footerWrapper.Relationships, {
|
this.formatter.format(footerWrapper.Relationships, {
|
||||||
viewWrapper: footerWrapper,
|
viewWrapper: footerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -269,6 +279,7 @@ export class Compiler {
|
|||||||
this.formatter.format(headerWrapper.View, {
|
this.formatter.format(headerWrapper.View, {
|
||||||
viewWrapper: headerWrapper,
|
viewWrapper: headerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -293,6 +304,7 @@ export class Compiler {
|
|||||||
this.formatter.format(footerWrapper.View, {
|
this.formatter.format(footerWrapper.View, {
|
||||||
viewWrapper: footerWrapper,
|
viewWrapper: footerWrapper,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -317,6 +329,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.ContentTypes, {
|
this.formatter.format(file.ContentTypes, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -332,6 +345,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.CustomProperties, {
|
this.formatter.format(file.CustomProperties, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -348,6 +362,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.AppProperties, {
|
this.formatter.format(file.AppProperties, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -363,7 +378,8 @@ export class Compiler {
|
|||||||
data: xml(
|
data: xml(
|
||||||
this.formatter.format(file.FootNotes.View, {
|
this.formatter.format(file.FootNotes.View, {
|
||||||
viewWrapper: file.FootNotes,
|
viewWrapper: file.FootNotes,
|
||||||
file: file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -378,7 +394,8 @@ export class Compiler {
|
|||||||
data: xml(
|
data: xml(
|
||||||
this.formatter.format(file.FootNotes.Relationships, {
|
this.formatter.format(file.FootNotes.Relationships, {
|
||||||
viewWrapper: file.FootNotes,
|
viewWrapper: file.FootNotes,
|
||||||
file: file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -394,6 +411,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Settings, {
|
this.formatter.format(file.Settings, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
@ -410,6 +428,7 @@ export class Compiler {
|
|||||||
this.formatter.format(file.Comments, {
|
this.formatter.format(file.Comments, {
|
||||||
viewWrapper: file.Document,
|
viewWrapper: file.Document,
|
||||||
file,
|
file,
|
||||||
|
stack: [],
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
indent: prettify,
|
indent: prettify,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { ICommentsOptions } from "@file/paragraph/run/comment-run";
|
import { ICommentsOptions } from "@file/paragraph/run/comment-run";
|
||||||
|
import { ICompatibilityOptions } from "@file/settings/compatibility";
|
||||||
import { StringContainer, XmlComponent } from "@file/xml-components";
|
import { StringContainer, XmlComponent } from "@file/xml-components";
|
||||||
import { dateTimeValue } from "@util/values";
|
import { dateTimeValue } from "@util/values";
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ export interface IPropertiesOptions {
|
|||||||
readonly updateFields?: boolean;
|
readonly updateFields?: boolean;
|
||||||
};
|
};
|
||||||
readonly compatabilityModeVersion?: number;
|
readonly compatabilityModeVersion?: number;
|
||||||
|
readonly compatibility?: ICompatibilityOptions;
|
||||||
readonly customProperties?: readonly ICustomPropertyOptions[];
|
readonly customProperties?: readonly ICustomPropertyOptions[];
|
||||||
readonly evenAndOddHeaderAndFooters?: boolean;
|
readonly evenAndOddHeaderAndFooters?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,23 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { twipsMeasureValue } from "@util/values";
|
import { PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||||
|
|
||||||
export interface IColumnAttributes {
|
// <xsd:complexType name="CT_Column">
|
||||||
readonly width: number | string;
|
// <xsd:attribute name="w" type="s:ST_TwipsMeasure" use="optional" />
|
||||||
readonly space?: number | string;
|
// <xsd:attribute name="space" type="s:ST_TwipsMeasure" use="optional" default="0" />
|
||||||
}
|
// </xsd:complexType>
|
||||||
|
|
||||||
export class ColumnAttributes extends XmlAttributeComponent<IColumnAttributes> {
|
type IColumnAttributes = {
|
||||||
protected readonly xmlKeys = {
|
readonly width: number | PositiveUniversalMeasure;
|
||||||
width: "w:w",
|
readonly space?: number | PositiveUniversalMeasure;
|
||||||
space: "w:space",
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Column extends XmlComponent {
|
export class Column extends XmlComponent {
|
||||||
public constructor({ width, space }: IColumnAttributes) {
|
public constructor({ width, space }: IColumnAttributes) {
|
||||||
super("w:col");
|
super("w:col");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new ColumnAttributes({
|
new NextAttributeComponent<IColumnAttributes>({
|
||||||
width: twipsMeasureValue(width),
|
width: { key: "w:w", value: twipsMeasureValue(width) },
|
||||||
space: space === undefined ? undefined : twipsMeasureValue(space),
|
space: { key: "w:space", value: space === undefined ? undefined : twipsMeasureValue(space) },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { decimalNumber, twipsMeasureValue } from "@util/values";
|
import { decimalNumber, PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||||
|
|
||||||
import { Column } from "./column";
|
import { Column } from "./column";
|
||||||
|
|
||||||
@ -12,32 +12,23 @@ import { Column } from "./column";
|
|||||||
// <xsd:attribute name="num" type="ST_DecimalNumber" use="optional" default="1"/>
|
// <xsd:attribute name="num" type="ST_DecimalNumber" use="optional" default="1"/>
|
||||||
// <xsd:attribute name="sep" type="s:ST_OnOff" use="optional"/>
|
// <xsd:attribute name="sep" type="s:ST_OnOff" use="optional"/>
|
||||||
// </xsd:complexType>
|
// </xsd:complexType>
|
||||||
export interface IColumnsAttributes {
|
export type IColumnsAttributes = {
|
||||||
readonly space?: number | string;
|
readonly space?: number | PositiveUniversalMeasure;
|
||||||
readonly count?: number;
|
readonly count?: number;
|
||||||
readonly separate?: boolean;
|
readonly separate?: boolean;
|
||||||
readonly equalWidth?: boolean;
|
readonly equalWidth?: boolean;
|
||||||
readonly children?: readonly Column[];
|
readonly children?: readonly Column[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
space: "w:space",
|
|
||||||
count: "w:num",
|
|
||||||
separate: "w:sep",
|
|
||||||
equalWidth: "w:equalWidth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Columns extends XmlComponent {
|
export class Columns extends XmlComponent {
|
||||||
public constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
|
public constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
|
||||||
super("w:cols");
|
super("w:cols");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new ColumnsAttributes({
|
new NextAttributeComponent<Omit<IColumnsAttributes, "children">>({
|
||||||
space: space === undefined ? undefined : twipsMeasureValue(space),
|
space: { key: "w:space", value: space === undefined ? undefined : twipsMeasureValue(space) },
|
||||||
count: count === undefined ? undefined : decimalNumber(count),
|
count: { key: "w:num", value: count === undefined ? undefined : decimalNumber(count) },
|
||||||
separate,
|
separate: { key: "w:sep", value: separate },
|
||||||
equalWidth,
|
equalWidth: { key: "w:equalWidth", value: equalWidth },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// http://officeopenxml.com/WPsectionLineNumbering.php
|
// http://officeopenxml.com/WPsectionLineNumbering.php
|
||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { decimalNumber, twipsMeasureValue } from "@util/values";
|
import { decimalNumber, PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||||
|
|
||||||
// <xsd:simpleType name="ST_LineNumberRestart">
|
// <xsd:simpleType name="ST_LineNumberRestart">
|
||||||
// <xsd:restriction base="xsd:string">
|
// <xsd:restriction base="xsd:string">
|
||||||
@ -26,27 +26,23 @@ export interface ILineNumberAttributes {
|
|||||||
readonly countBy?: number;
|
readonly countBy?: number;
|
||||||
readonly start?: number;
|
readonly start?: number;
|
||||||
readonly restart?: LineNumberRestartFormat;
|
readonly restart?: LineNumberRestartFormat;
|
||||||
readonly distance?: number | string;
|
readonly distance?: number | PositiveUniversalMeasure;
|
||||||
}
|
|
||||||
|
|
||||||
export class LineNumberAttributes extends XmlAttributeComponent<ILineNumberAttributes> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
countBy: "w:countBy",
|
|
||||||
start: "w:start",
|
|
||||||
restart: "w:restart",
|
|
||||||
distance: "w:distance",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LineNumberType extends XmlComponent {
|
export class LineNumberType extends XmlComponent {
|
||||||
public constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
|
public constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
|
||||||
super("w:lnNumType");
|
super("w:lnNumType");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new LineNumberAttributes({
|
new NextAttributeComponent<{
|
||||||
countBy: countBy === undefined ? undefined : decimalNumber(countBy),
|
readonly countBy?: number;
|
||||||
start: start === undefined ? undefined : decimalNumber(start),
|
readonly start?: number;
|
||||||
restart,
|
readonly restart?: LineNumberRestartFormat;
|
||||||
distance: distance === undefined ? undefined : twipsMeasureValue(distance),
|
readonly distance?: number | PositiveUniversalMeasure;
|
||||||
|
}>({
|
||||||
|
countBy: { key: "w:countBy", value: countBy === undefined ? undefined : decimalNumber(countBy) },
|
||||||
|
start: { key: "w:start", value: start === undefined ? undefined : decimalNumber(start) },
|
||||||
|
restart: { key: "w:restart", value: restart },
|
||||||
|
distance: { key: "w:distance", value: distance === undefined ? undefined : twipsMeasureValue(distance) },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ export class PageBorders extends IgnoreIfEmptyXmlComponent {
|
|||||||
super("w:pgBorders");
|
super("w:pgBorders");
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
return;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.pageBorders) {
|
if (options.pageBorders) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { signedTwipsMeasureValue, twipsMeasureValue } from "@util/values";
|
import { PositiveUniversalMeasure, signedTwipsMeasureValue, twipsMeasureValue, UniversalMeasure } from "@util/values";
|
||||||
|
|
||||||
// <xsd:complexType name="CT_PageMar">
|
// <xsd:complexType name="CT_PageMar">
|
||||||
// <xsd:attribute name="top" type="ST_SignedTwipsMeasure" use="required"/>
|
// <xsd:attribute name="top" type="ST_SignedTwipsMeasure" use="required"/>
|
||||||
@ -10,48 +10,36 @@ import { signedTwipsMeasureValue, twipsMeasureValue } from "@util/values";
|
|||||||
// <xsd:attribute name="footer" type="s:ST_TwipsMeasure" use="required"/>
|
// <xsd:attribute name="footer" type="s:ST_TwipsMeasure" use="required"/>
|
||||||
// <xsd:attribute name="gutter" type="s:ST_TwipsMeasure" use="required"/>
|
// <xsd:attribute name="gutter" type="s:ST_TwipsMeasure" use="required"/>
|
||||||
// </xsd:complexType>
|
// </xsd:complexType>
|
||||||
export interface IPageMarginAttributes {
|
export type IPageMarginAttributes = {
|
||||||
readonly top?: number | string;
|
readonly top?: number | UniversalMeasure;
|
||||||
readonly right?: number | string;
|
readonly right?: number | PositiveUniversalMeasure;
|
||||||
readonly bottom?: number | string;
|
readonly bottom?: number | UniversalMeasure;
|
||||||
readonly left?: number | string;
|
readonly left?: number | PositiveUniversalMeasure;
|
||||||
readonly header?: number | string;
|
readonly header?: number | PositiveUniversalMeasure;
|
||||||
readonly footer?: number | string;
|
readonly footer?: number | PositiveUniversalMeasure;
|
||||||
readonly gutter?: number | string;
|
readonly gutter?: number | PositiveUniversalMeasure;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttributes> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
top: "w:top",
|
|
||||||
right: "w:right",
|
|
||||||
bottom: "w:bottom",
|
|
||||||
left: "w:left",
|
|
||||||
header: "w:header",
|
|
||||||
footer: "w:footer",
|
|
||||||
gutter: "w:gutter",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PageMargin extends XmlComponent {
|
export class PageMargin extends XmlComponent {
|
||||||
public constructor(
|
public constructor(
|
||||||
top: number | string,
|
top: number | UniversalMeasure,
|
||||||
right: number | string,
|
right: number | PositiveUniversalMeasure,
|
||||||
bottom: number | string,
|
bottom: number | UniversalMeasure,
|
||||||
left: number | string,
|
left: number | PositiveUniversalMeasure,
|
||||||
header: number | string,
|
header: number | PositiveUniversalMeasure,
|
||||||
footer: number | string,
|
footer: number | PositiveUniversalMeasure,
|
||||||
gutter: number | string,
|
gutter: number | PositiveUniversalMeasure,
|
||||||
) {
|
) {
|
||||||
super("w:pgMar");
|
super("w:pgMar");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new PageMarginAttributes({
|
new NextAttributeComponent<IPageMarginAttributes>({
|
||||||
top: signedTwipsMeasureValue(top),
|
top: { key: "w:top", value: signedTwipsMeasureValue(top) },
|
||||||
right: twipsMeasureValue(right),
|
right: { key: "w:right", value: twipsMeasureValue(right) },
|
||||||
bottom: signedTwipsMeasureValue(bottom),
|
bottom: { key: "w:bottom", value: signedTwipsMeasureValue(bottom) },
|
||||||
left: twipsMeasureValue(left),
|
left: { key: "w:left", value: twipsMeasureValue(left) },
|
||||||
header: twipsMeasureValue(header),
|
header: { key: "w:header", value: twipsMeasureValue(header) },
|
||||||
footer: twipsMeasureValue(footer),
|
footer: { key: "w:footer", value: twipsMeasureValue(footer) },
|
||||||
gutter: twipsMeasureValue(gutter),
|
gutter: { key: "w:gutter", value: twipsMeasureValue(gutter) },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { twipsMeasureValue } from "@util/values";
|
import { PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||||
|
|
||||||
// <xsd:simpleType name="ST_PageOrientation">
|
// <xsd:simpleType name="ST_PageOrientation">
|
||||||
// <xsd:restriction base="xsd:string">
|
// <xsd:restriction base="xsd:string">
|
||||||
@ -18,22 +18,14 @@ export enum PageOrientation {
|
|||||||
// <xsd:attribute name="orient" type="ST_PageOrientation" use="optional"/>
|
// <xsd:attribute name="orient" type="ST_PageOrientation" use="optional"/>
|
||||||
// <xsd:attribute name="code" type="ST_DecimalNumber" use="optional"/>
|
// <xsd:attribute name="code" type="ST_DecimalNumber" use="optional"/>
|
||||||
// </xsd:complexType>
|
// </xsd:complexType>
|
||||||
export interface IPageSizeAttributes {
|
export type IPageSizeAttributes = {
|
||||||
readonly width?: number | string;
|
readonly width?: number | PositiveUniversalMeasure;
|
||||||
readonly height?: number | string;
|
readonly height?: number | PositiveUniversalMeasure;
|
||||||
readonly orientation?: PageOrientation;
|
readonly orientation?: PageOrientation;
|
||||||
}
|
};
|
||||||
|
|
||||||
export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttributes> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
width: "w:w",
|
|
||||||
height: "w:h",
|
|
||||||
orientation: "w:orient",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PageSize extends XmlComponent {
|
export class PageSize extends XmlComponent {
|
||||||
public constructor(width: number | string, height: number | string, orientation: PageOrientation) {
|
public constructor(width: number | PositiveUniversalMeasure, height: number | PositiveUniversalMeasure, orientation: PageOrientation) {
|
||||||
super("w:pgSz");
|
super("w:pgSz");
|
||||||
|
|
||||||
const flip = orientation === PageOrientation.LANDSCAPE;
|
const flip = orientation === PageOrientation.LANDSCAPE;
|
||||||
@ -42,10 +34,10 @@ export class PageSize extends XmlComponent {
|
|||||||
const heightTwips = twipsMeasureValue(height);
|
const heightTwips = twipsMeasureValue(height);
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new PageSizeAttributes({
|
new NextAttributeComponent<IPageSizeAttributes>({
|
||||||
width: flip ? heightTwips : widthTwips,
|
width: { key: "w:w", value: flip ? heightTwips : widthTwips },
|
||||||
height: flip ? widthTwips : heightTwips,
|
height: { key: "w:h", value: flip ? widthTwips : heightTwips },
|
||||||
orientation: orientation,
|
orientation: { key: "w:orient", value: orientation },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import { FooterWrapper } from "@file/footer-wrapper";
|
|||||||
import { HeaderWrapper } from "@file/header-wrapper";
|
import { HeaderWrapper } from "@file/header-wrapper";
|
||||||
import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align";
|
import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align";
|
||||||
import { OnOffElement, XmlComponent } from "@file/xml-components";
|
import { OnOffElement, XmlComponent } from "@file/xml-components";
|
||||||
|
import { PositiveUniversalMeasure, UniversalMeasure } from "@util/values";
|
||||||
|
|
||||||
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./properties/header-footer-reference";
|
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./properties/header-footer-reference";
|
||||||
|
|
||||||
import { Columns, IColumnsAttributes } from "./properties/columns";
|
import { Columns, IColumnsAttributes } from "./properties/columns";
|
||||||
import { DocumentGrid, IDocGridAttributesProperties } from "./properties/doc-grid";
|
import { DocumentGrid, IDocGridAttributesProperties } from "./properties/doc-grid";
|
||||||
import { ILineNumberAttributes, LineNumberType } from "./properties/line-number";
|
import { ILineNumberAttributes, LineNumberType } from "./properties/line-number";
|
||||||
@ -76,10 +76,10 @@ export interface ISectionPropertiesOptions {
|
|||||||
// </xsd:group>
|
// </xsd:group>
|
||||||
|
|
||||||
export const sectionMarginDefaults = {
|
export const sectionMarginDefaults = {
|
||||||
TOP: "1in",
|
TOP: "1in" as UniversalMeasure,
|
||||||
RIGHT: "1in",
|
RIGHT: "1in" as PositiveUniversalMeasure,
|
||||||
BOTTOM: "1in",
|
BOTTOM: "1in" as UniversalMeasure,
|
||||||
LEFT: "1in",
|
LEFT: "1in" as PositiveUniversalMeasure,
|
||||||
HEADER: 708,
|
HEADER: 708,
|
||||||
FOOTER: 708,
|
FOOTER: 708,
|
||||||
GUTTER: 0,
|
GUTTER: 0,
|
||||||
|
@ -8,7 +8,7 @@ import { DocumentAttributes } from "./document-attributes";
|
|||||||
import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background";
|
import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background";
|
||||||
|
|
||||||
export interface IDocumentOptions {
|
export interface IDocumentOptions {
|
||||||
readonly background: IDocumentBackgroundOptions;
|
readonly background?: IDocumentBackgroundOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <xsd:element name="document" type="CT_Document"/>
|
// <xsd:element name="document" type="CT_Document"/>
|
||||||
@ -73,7 +73,9 @@ export class Document extends XmlComponent {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
this.body = new Body();
|
this.body = new Body();
|
||||||
|
if (options.background) {
|
||||||
this.root.push(new DocumentBackground(options.background));
|
this.root.push(new DocumentBackground(options.background));
|
||||||
|
}
|
||||||
this.root.push(this.body);
|
this.root.push(this.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { assert } from "chai";
|
import { assert, expect } from "chai";
|
||||||
|
import { SinonStub, stub } from "sinon";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
import * as convenienceFunctions from "@util/convenience-functions";
|
||||||
|
|
||||||
import { Utility } from "tests/utility";
|
import { Utility } from "tests/utility";
|
||||||
|
|
||||||
@ -36,6 +40,14 @@ const createAnchor = (drawingOptions: IDrawingOptions): Anchor =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
describe("Anchor", () => {
|
describe("Anchor", () => {
|
||||||
|
before(() => {
|
||||||
|
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||||
|
});
|
||||||
|
|
||||||
let anchor: Anchor;
|
let anchor: Anchor;
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -362,5 +374,236 @@ describe("Anchor", () => {
|
|||||||
relativeHeight: 120,
|
relativeHeight: 120,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should create a Drawing with doc properties", () => {
|
||||||
|
anchor = createAnchor({
|
||||||
|
floating: {
|
||||||
|
verticalPosition: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
horizontalPosition: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
zIndex: 120,
|
||||||
|
},
|
||||||
|
docProperties: {
|
||||||
|
name: "test",
|
||||||
|
description: "test",
|
||||||
|
title: "test",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(anchor);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"wp:anchor": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
allowOverlap: "1",
|
||||||
|
behindDoc: "0",
|
||||||
|
distB: 0,
|
||||||
|
distL: 0,
|
||||||
|
distR: 0,
|
||||||
|
distT: 0,
|
||||||
|
layoutInCell: "1",
|
||||||
|
locked: "0",
|
||||||
|
relativeHeight: 120,
|
||||||
|
simplePos: "0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:simplePos": {
|
||||||
|
_attr: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:positionH": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
relativeFrom: "page",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:posOffset": ["0"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:positionV": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
relativeFrom: "page",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:posOffset": ["0"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:extent": {
|
||||||
|
_attr: {
|
||||||
|
cx: 952500,
|
||||||
|
cy: 952500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:effectExtent": {
|
||||||
|
_attr: {
|
||||||
|
b: 0,
|
||||||
|
l: 0,
|
||||||
|
r: 0,
|
||||||
|
t: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:wrapNone": {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:docPr": {
|
||||||
|
_attr: {
|
||||||
|
descr: "test",
|
||||||
|
id: 0,
|
||||||
|
name: "test",
|
||||||
|
title: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:cNvGraphicFramePr": [
|
||||||
|
{
|
||||||
|
"a:graphicFrameLocks": {
|
||||||
|
_attr: {
|
||||||
|
noChangeAspect: 1,
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:graphic": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:graphicData": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
uri: "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:pic": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xmlns:pic": "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:nvPicPr": [
|
||||||
|
{
|
||||||
|
"pic:cNvPr": {
|
||||||
|
_attr: {
|
||||||
|
descr: "",
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:cNvPicPr": [
|
||||||
|
{
|
||||||
|
"a:picLocks": {
|
||||||
|
_attr: {
|
||||||
|
noChangeArrowheads: 1,
|
||||||
|
noChangeAspect: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:blipFill": [
|
||||||
|
{
|
||||||
|
"a:blip": {
|
||||||
|
_attr: {
|
||||||
|
cstate: "none",
|
||||||
|
"r:embed": "rId{test.png}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:srcRect": {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:stretch": [
|
||||||
|
{
|
||||||
|
"a:fillRect": {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:spPr": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
bwMode: "auto",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:xfrm": [
|
||||||
|
{
|
||||||
|
_attr: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:off": {
|
||||||
|
_attr: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:ext": {
|
||||||
|
_attr: {
|
||||||
|
cx: 952500,
|
||||||
|
cy: 952500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:prstGeom": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
prst: "rect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:avLst": {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -90,7 +90,7 @@ export class Anchor extends XmlComponent {
|
|||||||
this.root.push(new WrapNone());
|
this.root.push(new WrapNone());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.root.push(new DocProperties());
|
this.root.push(new DocProperties(drawingOptions.docProperties));
|
||||||
this.root.push(new GraphicFrameProperties());
|
this.root.push(new GraphicFrameProperties());
|
||||||
this.root.push(new Graphic(mediaData, transform));
|
this.root.push(new Graphic(mediaData, transform));
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { XmlAttributeComponent } from "@file/xml-components";
|
|
||||||
|
|
||||||
export class DocPropertiesAttributes extends XmlAttributeComponent<{
|
|
||||||
readonly id?: number;
|
|
||||||
readonly name?: string;
|
|
||||||
readonly descr?: string;
|
|
||||||
}> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
id: "id",
|
|
||||||
name: "name",
|
|
||||||
descr: "descr",
|
|
||||||
};
|
|
||||||
}
|
|
@ -0,0 +1,61 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
|
||||||
|
import { createHyperlinkClick, createHyperlinkHover } from "./doc-properties-children";
|
||||||
|
|
||||||
|
describe("Document Properties Children", () => {
|
||||||
|
describe("#createHyperlinkClick", () => {
|
||||||
|
it("should create a Hyperlink Click component", () => {
|
||||||
|
const tree = new Formatter().format(createHyperlinkClick("1", false));
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"a:hlinkClick": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a Hyperlink Click component with xmlns:a", () => {
|
||||||
|
const tree = new Formatter().format(createHyperlinkClick("1", true));
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"a:hlinkClick": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#createHyperlinkHover", () => {
|
||||||
|
it("should create a Hyperlink Hover component", () => {
|
||||||
|
const tree = new Formatter().format(createHyperlinkHover("1", false));
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"a:hlinkHover": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a Hyperlink Hover component with xmlns:a", () => {
|
||||||
|
const tree = new Formatter().format(createHyperlinkHover("1", true));
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"a:hlinkHover": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
57
src/file/drawing/doc-properties/doc-properties-children.ts
Normal file
57
src/file/drawing/doc-properties/doc-properties-children.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// <sequence>
|
||||||
|
// <element name="hlinkClick" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="hlinkHover" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1" />
|
||||||
|
// </sequence>
|
||||||
|
|
||||||
|
import { BuilderElement, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
// <xsd:complexType name="CT_Hyperlink">
|
||||||
|
// <xsd:group ref="EG_PContent" minOccurs="0" maxOccurs="unbounded" />
|
||||||
|
// <xsd:attribute name="tgtFrame" type="s:ST_String" use="optional" />
|
||||||
|
// <xsd:attribute name="tooltip" type="s:ST_String" use="optional" />
|
||||||
|
// <xsd:attribute name="docLocation" type="s:ST_String" use="optional" />
|
||||||
|
// <xsd:attribute name="history" type="s:ST_OnOff" use="optional" />
|
||||||
|
// <xsd:attribute name="anchor" type="s:ST_String" use="optional" />
|
||||||
|
// <xsd:attribute ref="r:id" />
|
||||||
|
// </xsd:complexType>
|
||||||
|
|
||||||
|
// TODO: Implement the rest of the attributes
|
||||||
|
|
||||||
|
export const createHyperlinkClick = (linkId: string, hasXmlNs: boolean): XmlComponent =>
|
||||||
|
new BuilderElement({
|
||||||
|
name: "a:hlinkClick",
|
||||||
|
attributes: {
|
||||||
|
...(hasXmlNs
|
||||||
|
? {
|
||||||
|
xmlns: {
|
||||||
|
key: "xmlns:a",
|
||||||
|
value: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
id: {
|
||||||
|
key: "r:id",
|
||||||
|
value: `rId${linkId}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createHyperlinkHover = (linkId: string, hasXmlNs: boolean): XmlComponent =>
|
||||||
|
new BuilderElement({
|
||||||
|
name: "a:hlinkHover",
|
||||||
|
attributes: {
|
||||||
|
...(hasXmlNs
|
||||||
|
? {
|
||||||
|
xmlns: {
|
||||||
|
key: "xmlns:a",
|
||||||
|
value: "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
id: {
|
||||||
|
key: "r:id",
|
||||||
|
value: `rId${linkId}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
@ -1,16 +1,67 @@
|
|||||||
import { XmlComponent } from "@file/xml-components";
|
// https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_docPr_topic_ID0ES32OB.html
|
||||||
import { DocPropertiesAttributes } from "./doc-properties-attributes";
|
import { IContext, IXmlableObject, NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
|
import { ConcreteHyperlink } from "@file/paragraph";
|
||||||
|
|
||||||
|
import { uniqueNumericId } from "@util/convenience-functions";
|
||||||
|
|
||||||
|
import { createHyperlinkClick } from "./doc-properties-children";
|
||||||
|
|
||||||
|
// <complexType name="CT_NonVisualDrawingProps">
|
||||||
|
// <sequence>
|
||||||
|
// <element name="hlinkClick" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="hlinkHover" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1" />
|
||||||
|
// </sequence>
|
||||||
|
// <attribute name="id" type="ST_DrawingElementId" use="required" />
|
||||||
|
// <attribute name="name" type="xsd:string" use="required" />
|
||||||
|
// <attribute name="descr" type="xsd:string" use="optional" default="" />
|
||||||
|
// <attribute name="hidden" type="xsd:boolean" use="optional" default="false" />
|
||||||
|
// </complexType>
|
||||||
|
|
||||||
|
export interface DocPropertiesOptions {
|
||||||
|
readonly name: string;
|
||||||
|
readonly description: string;
|
||||||
|
readonly title: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class DocProperties extends XmlComponent {
|
export class DocProperties extends XmlComponent {
|
||||||
public constructor() {
|
public constructor({ name, description, title }: DocPropertiesOptions = { name: "", description: "", title: "" }) {
|
||||||
super("wp:docPr");
|
super("wp:docPr");
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new DocPropertiesAttributes({
|
new NextAttributeComponent({
|
||||||
id: 0,
|
id: {
|
||||||
name: "",
|
key: "id",
|
||||||
descr: "",
|
value: uniqueNumericId(),
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
key: "name",
|
||||||
|
value: name,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
key: "descr",
|
||||||
|
value: description,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
key: "title",
|
||||||
|
value: title,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public prepForXml(context: IContext): IXmlableObject | undefined {
|
||||||
|
for (let i = context.stack.length - 1; i >= 0; i--) {
|
||||||
|
const element = context.stack[i];
|
||||||
|
if (!(element instanceof ConcreteHyperlink)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.root.push(createHyperlinkClick(element.linkId, true));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.prepForXml(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
import { SinonStub, stub } from "sinon";
|
||||||
|
|
||||||
|
import { IContext } from "@file/xml-components";
|
||||||
import { Formatter } from "@export/formatter";
|
import { Formatter } from "@export/formatter";
|
||||||
|
import * as convenienceFunctions from "@util/convenience-functions";
|
||||||
|
|
||||||
|
import { ConcreteHyperlink, TextRun } from "../";
|
||||||
import { Drawing, IDrawingOptions } from "./drawing";
|
import { Drawing, IDrawingOptions } from "./drawing";
|
||||||
|
|
||||||
const imageBase64Data = `iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAACzVBMVEUAAAAAAAAAAAAAAAA/AD8zMzMqKiokJCQfHx8cHBwZGRkuFxcqFSonJyckJCQiIiIfHx8eHh4cHBwoGhomGSYkJCQhISEfHx8eHh4nHR0lHBwkGyQjIyMiIiIgICAfHx8mHh4lHh4kHR0jHCMiGyIhISEgICAfHx8lHx8kHh4jHR0hHCEhISEgICAlHx8kHx8jHh4jHh4iHSIhHCEhISElICAkHx8jHx8jHh4iHh4iHSIhHSElICAkICAjHx8jHx8iHh4iHh4hHiEhHSEkICAjHx8iHx8iHx8hHh4hHiEkHSEjHSAjHx8iHx8iHx8hHh4kHiEkHiEjHSAiHx8hHx8hHh4kHiEjHiAjHSAiHx8iHx8hHx8kHh4jHiEjHiAjHiAiICAiHx8kHx8jHh4jHiEjHiAiHiAiHSAiHx8jHx8jHx8jHiAiHiAiHiAiHSAiHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8iHx8iHSAiHiAjHiAjHx8jHx8hHx8iHx8iHyAiHiAjHiAjHiAjHh4hHx8iHx8iHx8iHyAjHSAjHiAjHiAjHh4hHx8iHx8iHx8jHyAjHiAhHh4iHx8iHx8jHyAjHSAjHSAhHiAhHh4iHx8iHx8jHx8jHyAjHSAjHSAiHh4iHh4jHx8jHx8jHyAjHyAhHSAhHSAiHh4iHh4jHx8jHx8jHyAhHyAhHSAiHSAiHh4jHh4jHx8jHx8jHyAhHyAhHSAiHSAjHR4jHh4jHx8jHx8hHyAhHyAiHSAjHSAjHR4jHh4jHx8hHx8hHyAhHyAiHyAjHSAjHR4jHR4hHh4hHx8hHyAiHyAjHyAjHSAjHR4jHR4hHh4hHx8hHyAjHyAjHyAjHSAjHR4hHR4hHR4hHx8iHyAjHyAjHyAjHSAhHR4hHR4hHR4hHx8jHyAjHyAjHyAjHyC9S2xeAAAA7nRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFxgZGhscHR4fICEiIyQlJicoKSorLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZISUpLTE1OUFFSU1RVVllaW1xdXmBhYmNkZWZnaGprbG1ub3Byc3R1dnd4eXp8fn+AgYKDhIWGiImKi4yNj5CRkpOUlZaXmJmam5ydnp+goaKjpKaoqqusra6vsLGys7S1tri5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+fkZpVQAABcBJREFUGBntwftjlQMcBvDnnLNL22qzJjWlKLHFVogyty3SiFq6EZliqZGyhnSxsLlMRahYoZKRFcul5dKFCatYqWZaNKvWtrPz/A2+7/b27qRzec/lPfvl/XxgMplMJpPJZDKZAtA9HJ3ppnIez0KnSdtC0RCNznHdJrbrh85wdSlVVRaEXuoGamYi5K5430HNiTiEWHKJg05eRWgNfKeV7RxbqUhGKPV/207VupQ8is0IoX5vtFC18SqEHaK4GyHTZ2kzVR8PBTCO4oANIZL4ShNVZcOhKKeYg9DoWdhI1ec3os2VFI0JCIUez5+i6st0qJZRrEAIJCw+QdW223BG/EmKwTBc/IJ/qfp2FDrkUnwFo8U9dZyqnaPhxLqfYjyM1S3vb6p+GGOBszsojoTDSDFz6qj66R4LzvYJxVMwUNRjf1H1ywQr/megg2RzLximy8waqvbda8M5iijegVEiHjlM1W/3h+FcXesphsMY4dMOUnUgOxyuPEzxPQwRNvV3qg5Nj4BreyimwADWe/dRVTMjEm6MoGLzGwtystL6RyOY3qSqdlYU3FpLZw1VW0sK5943MvUCKwJ1noNtjs6Ohge76Zq9ZkfpigU5WWkDYuCfbs1U5HWFR8/Qq4a9W0uK5k4ZmdrTCl8spGIePLPlbqqsc1Afe83O0hULc8alDYiBd7ZyitYMeBfR55rR2fOKP6ioPk2dGvZ+UVI0d8rtqT2tcCexlqK2F3wRn5Q+YVbBqrLKOupkr9lZujAOrmS0UpTb4JeIPkNHZ+cXr6uoPk2vyuBSPhWLEKj45PQJuQWryyqP0Z14uGLdROHIRNBEXDR09EP5r62rOHCazhrD4VKPwxTH+sIA3ZPTJ+YuWV22n+IruHFDC8X2CBjnPoolcGc2FYUwzmsUWXDHsoGKLBhmN0VvuBVfTVE/AAbpaid5CB4MbaLY1QXGuIViLTyZQcVyGGMuxWPwaA0Vk2GI9RRp8Ci2iuLkIBjhT5LNUfAspZFiTwyC72KK7+DNg1SsRvCNp3gZXq2k4iEEXSHFJHgVXUlxejCCbTvFAHiXdIJiXxyCK7KJ5FHoMZGK9xBcwyg2QpdlVMxEUM2iyIMuXXZQNF+HswxMsSAAJRQjoE//eoqDCXBSTO6f1xd+O0iyNRY6jaWi1ALNYCocZROj4JdEikroVkjFk9DcStXxpdfCD2MoXodu4RUU9ptxxmXssOfxnvDVcxRTod9FxyhqLoAqis5aPhwTDp9spRgEH2Q6KLbYoKqlaKTm6Isp0C/sJMnjFvhiERXPQvUNRe9p29lhR04CdBpC8Sl8YiuncIxEuzUUg4Dkgj+paVozygY9plPMh28SaymO9kabAopREGF3vt9MzeFFl8G7lRSZ8FFGK8XX4VA8QjEd7XrM3M0OXz8YCy+qKBLgq3wqnofiTorF0Ax56Rg1J1elW+BBAsVe+My6iYq7IK6keBdOIseV2qn5Pb8f3MqkWAXf9ThM8c8lAOIotuFsF875lRrH5klRcG0+xcPwQ1oLxfeRAP4heQTnGL78X2rqlw2DK59SXAV/zKaiGMAuko5InCt68mcOan5+ohf+z1pP8lQY/GHZQMV4YD3FpXDp4qerqbF/lBWBswyi+AL+ia+maLgcRRQj4IYlY/UpauqKBsPJAxQF8NM1TRQ/RudSPAD34rK3scOuR8/HGcspxsJfOVS8NZbiGXiUtPgINU3v3WFDmx8pEuG3EiqKKVbCC1vm2iZqap5LAtCtleQf8F9sFYWDohzeJczYyQ4V2bEZFGsQgJRGqqqhS2phHTWn9lDkIhBTqWqxQZ+IsRvtdHY9AvI2VX2hW68nfqGmuQsCEl3JdjfCF8OW1bPdtwhQ0gm2mQzfRE3a7KCYj0BNZJs8+Kxf/r6WtTEI2FIqlsMfFgRB5A6KUnSe/vUkX0AnuvUIt8SjM1m6wWQymUwmk8lkMgXRf5vi8rLQxtUhAAAAAElFTkSuQmCC`;
|
const imageBase64Data = `iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAACzVBMVEUAAAAAAAAAAAAAAAA/AD8zMzMqKiokJCQfHx8cHBwZGRkuFxcqFSonJyckJCQiIiIfHx8eHh4cHBwoGhomGSYkJCQhISEfHx8eHh4nHR0lHBwkGyQjIyMiIiIgICAfHx8mHh4lHh4kHR0jHCMiGyIhISEgICAfHx8lHx8kHh4jHR0hHCEhISEgICAlHx8kHx8jHh4jHh4iHSIhHCEhISElICAkHx8jHx8jHh4iHh4iHSIhHSElICAkICAjHx8jHx8iHh4iHh4hHiEhHSEkICAjHx8iHx8iHx8hHh4hHiEkHSEjHSAjHx8iHx8iHx8hHh4kHiEkHiEjHSAiHx8hHx8hHh4kHiEjHiAjHSAiHx8iHx8hHx8kHh4jHiEjHiAjHiAiICAiHx8kHx8jHh4jHiEjHiAiHiAiHSAiHx8jHx8jHx8jHiAiHiAiHiAiHSAiHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8iHx8iHSAiHiAjHiAjHx8jHx8hHx8iHx8iHyAiHiAjHiAjHiAjHh4hHx8iHx8iHx8iHyAjHSAjHiAjHiAjHh4hHx8iHx8iHx8jHyAjHiAhHh4iHx8iHx8jHyAjHSAjHSAhHiAhHh4iHx8iHx8jHx8jHyAjHSAjHSAiHh4iHh4jHx8jHx8jHyAjHyAhHSAhHSAiHh4iHh4jHx8jHx8jHyAhHyAhHSAiHSAiHh4jHh4jHx8jHx8jHyAhHyAhHSAiHSAjHR4jHh4jHx8jHx8hHyAhHyAiHSAjHSAjHR4jHh4jHx8hHx8hHyAhHyAiHyAjHSAjHR4jHR4hHh4hHx8hHyAiHyAjHyAjHSAjHR4jHR4hHh4hHx8hHyAjHyAjHyAjHSAjHR4hHR4hHR4hHx8iHyAjHyAjHyAjHSAhHR4hHR4hHR4hHx8jHyAjHyAjHyAjHyC9S2xeAAAA7nRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFxgZGhscHR4fICEiIyQlJicoKSorLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZISUpLTE1OUFFSU1RVVllaW1xdXmBhYmNkZWZnaGprbG1ub3Byc3R1dnd4eXp8fn+AgYKDhIWGiImKi4yNj5CRkpOUlZaXmJmam5ydnp+goaKjpKaoqqusra6vsLGys7S1tri5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+fkZpVQAABcBJREFUGBntwftjlQMcBvDnnLNL22qzJjWlKLHFVogyty3SiFq6EZliqZGyhnSxsLlMRahYoZKRFcul5dKFCatYqWZaNKvWtrPz/A2+7/b27qRzec/lPfvl/XxgMplMJpPJZDKZAtA9HJ3ppnIez0KnSdtC0RCNznHdJrbrh85wdSlVVRaEXuoGamYi5K5430HNiTiEWHKJg05eRWgNfKeV7RxbqUhGKPV/207VupQ8is0IoX5vtFC18SqEHaK4GyHTZ2kzVR8PBTCO4oANIZL4ShNVZcOhKKeYg9DoWdhI1ec3os2VFI0JCIUez5+i6st0qJZRrEAIJCw+QdW223BG/EmKwTBc/IJ/qfp2FDrkUnwFo8U9dZyqnaPhxLqfYjyM1S3vb6p+GGOBszsojoTDSDFz6qj66R4LzvYJxVMwUNRjf1H1ywQr/megg2RzLximy8waqvbda8M5iijegVEiHjlM1W/3h+FcXesphsMY4dMOUnUgOxyuPEzxPQwRNvV3qg5Nj4BreyimwADWe/dRVTMjEm6MoGLzGwtystL6RyOY3qSqdlYU3FpLZw1VW0sK5943MvUCKwJ1noNtjs6Ohge76Zq9ZkfpigU5WWkDYuCfbs1U5HWFR8/Qq4a9W0uK5k4ZmdrTCl8spGIePLPlbqqsc1Afe83O0hULc8alDYiBd7ZyitYMeBfR55rR2fOKP6ioPk2dGvZ+UVI0d8rtqT2tcCexlqK2F3wRn5Q+YVbBqrLKOupkr9lZujAOrmS0UpTb4JeIPkNHZ+cXr6uoPk2vyuBSPhWLEKj45PQJuQWryyqP0Z14uGLdROHIRNBEXDR09EP5r62rOHCazhrD4VKPwxTH+sIA3ZPTJ+YuWV22n+IruHFDC8X2CBjnPoolcGc2FYUwzmsUWXDHsoGKLBhmN0VvuBVfTVE/AAbpaid5CB4MbaLY1QXGuIViLTyZQcVyGGMuxWPwaA0Vk2GI9RRp8Ci2iuLkIBjhT5LNUfAspZFiTwyC72KK7+DNg1SsRvCNp3gZXq2k4iEEXSHFJHgVXUlxejCCbTvFAHiXdIJiXxyCK7KJ5FHoMZGK9xBcwyg2QpdlVMxEUM2iyIMuXXZQNF+HswxMsSAAJRQjoE//eoqDCXBSTO6f1xd+O0iyNRY6jaWi1ALNYCocZROj4JdEikroVkjFk9DcStXxpdfCD2MoXodu4RUU9ptxxmXssOfxnvDVcxRTod9FxyhqLoAqis5aPhwTDp9spRgEH2Q6KLbYoKqlaKTm6Isp0C/sJMnjFvhiERXPQvUNRe9p29lhR04CdBpC8Sl8YiuncIxEuzUUg4Dkgj+paVozygY9plPMh28SaymO9kabAopREGF3vt9MzeFFl8G7lRSZ8FFGK8XX4VA8QjEd7XrM3M0OXz8YCy+qKBLgq3wqnofiTorF0Ax56Rg1J1elW+BBAsVe+My6iYq7IK6keBdOIseV2qn5Pb8f3MqkWAXf9ThM8c8lAOIotuFsF875lRrH5klRcG0+xcPwQ1oLxfeRAP4heQTnGL78X2rqlw2DK59SXAV/zKaiGMAuko5InCt68mcOan5+ohf+z1pP8lQY/GHZQMV4YD3FpXDp4qerqbF/lBWBswyi+AL+ia+maLgcRRQj4IYlY/UpauqKBsPJAxQF8NM1TRQ/RudSPAD34rK3scOuR8/HGcspxsJfOVS8NZbiGXiUtPgINU3v3WFDmx8pEuG3EiqKKVbCC1vm2iZqap5LAtCtleQf8F9sFYWDohzeJczYyQ4V2bEZFGsQgJRGqqqhS2phHTWn9lDkIhBTqWqxQZ+IsRvtdHY9AvI2VX2hW68nfqGmuQsCEl3JdjfCF8OW1bPdtwhQ0gm2mQzfRE3a7KCYj0BNZJs8+Kxf/r6WtTEI2FIqlsMfFgRB5A6KUnSe/vUkX0AnuvUIt8SjM1m6wWQymUwmk8lkMgXRf5vi8rLQxtUhAAAAAElFTkSuQmCC`;
|
||||||
@ -26,6 +30,14 @@ const createDrawing = (drawingOptions?: IDrawingOptions): Drawing =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
describe("Drawing", () => {
|
describe("Drawing", () => {
|
||||||
|
before(() => {
|
||||||
|
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||||
|
});
|
||||||
|
|
||||||
let currentBreak: Drawing;
|
let currentBreak: Drawing;
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -68,6 +80,7 @@ describe("Drawing", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -298,6 +311,7 @@ describe("Drawing", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -438,5 +452,257 @@ describe("Drawing", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should create a drawing with a hyperlink", () => {
|
||||||
|
currentBreak = createDrawing({
|
||||||
|
floating: {
|
||||||
|
horizontalPosition: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
verticalPosition: {
|
||||||
|
offset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(currentBreak, {
|
||||||
|
stack: [new ConcreteHyperlink([new TextRun("Test")], "1")],
|
||||||
|
} as unknown as IContext);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:drawing": [
|
||||||
|
{
|
||||||
|
"wp:anchor": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
allowOverlap: "1",
|
||||||
|
behindDoc: "0",
|
||||||
|
distB: 0,
|
||||||
|
distL: 0,
|
||||||
|
distR: 0,
|
||||||
|
distT: 0,
|
||||||
|
layoutInCell: "1",
|
||||||
|
locked: "0",
|
||||||
|
relativeHeight: 952500,
|
||||||
|
simplePos: "0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:simplePos": {
|
||||||
|
_attr: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:positionH": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
relativeFrom: "page",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:posOffset": ["0"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:positionV": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
relativeFrom: "page",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:posOffset": ["0"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:extent": {
|
||||||
|
_attr: {
|
||||||
|
cx: 952500,
|
||||||
|
cy: 952500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:effectExtent": {
|
||||||
|
_attr: {
|
||||||
|
b: 0,
|
||||||
|
l: 0,
|
||||||
|
r: 0,
|
||||||
|
t: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:wrapNone": {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:docPr": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
descr: "",
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
title: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:hlinkClick": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"wp:cNvGraphicFramePr": [
|
||||||
|
{
|
||||||
|
"a:graphicFrameLocks": {
|
||||||
|
_attr: {
|
||||||
|
// tslint:disable-next-line:object-literal-key-quotes
|
||||||
|
noChangeAspect: 1,
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:graphic": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:graphicData": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
uri: "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:pic": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xmlns:pic": "http://schemas.openxmlformats.org/drawingml/2006/picture",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:nvPicPr": [
|
||||||
|
{
|
||||||
|
"pic:cNvPr": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
descr: "",
|
||||||
|
id: 0,
|
||||||
|
name: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:hlinkClick": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:cNvPicPr": [
|
||||||
|
{
|
||||||
|
"a:picLocks": {
|
||||||
|
_attr: {
|
||||||
|
noChangeArrowheads: 1,
|
||||||
|
noChangeAspect: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:blipFill": [
|
||||||
|
{
|
||||||
|
"a:blip": {
|
||||||
|
_attr: {
|
||||||
|
// tslint:disable-next-line:object-literal-key-quotes
|
||||||
|
cstate: "none",
|
||||||
|
"r:embed": "rId{test.jpg}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:srcRect": {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:stretch": [
|
||||||
|
{
|
||||||
|
"a:fillRect": {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pic:spPr": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
bwMode: "auto",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:xfrm": [
|
||||||
|
{
|
||||||
|
_attr: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:off": {
|
||||||
|
_attr: {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:ext": {
|
||||||
|
_attr: {
|
||||||
|
cx: 952500,
|
||||||
|
cy: 952500,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:prstGeom": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
prst: "rect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:avLst": {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { IMediaData } from "@file/media";
|
import { IMediaData } from "@file/media";
|
||||||
import { XmlComponent } from "@file/xml-components";
|
import { XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
import { Anchor } from "./anchor";
|
import { Anchor } from "./anchor";
|
||||||
|
import { DocPropertiesOptions } from "./doc-properties/doc-properties";
|
||||||
import { IFloating } from "./floating";
|
import { IFloating } from "./floating";
|
||||||
import { Inline } from "./inline";
|
import { Inline } from "./inline";
|
||||||
|
|
||||||
@ -13,6 +15,7 @@ export interface IDistance {
|
|||||||
|
|
||||||
export interface IDrawingOptions {
|
export interface IDrawingOptions {
|
||||||
readonly floating?: IFloating;
|
readonly floating?: IFloating;
|
||||||
|
readonly docProperties?: DocPropertiesOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <xsd:complexType name="CT_Drawing">
|
// <xsd:complexType name="CT_Drawing">
|
||||||
@ -29,7 +32,11 @@ export class Drawing extends XmlComponent {
|
|||||||
super("w:drawing");
|
super("w:drawing");
|
||||||
|
|
||||||
if (!drawingOptions.floating) {
|
if (!drawingOptions.floating) {
|
||||||
this.inline = new Inline(imageData, imageData.transformation);
|
this.inline = new Inline({
|
||||||
|
mediaData: imageData,
|
||||||
|
transform: imageData.transformation,
|
||||||
|
docProperties: drawingOptions.docProperties,
|
||||||
|
});
|
||||||
this.root.push(this.inline);
|
this.root.push(this.inline);
|
||||||
} else {
|
} else {
|
||||||
this.root.push(new Anchor(imageData, imageData.transformation, drawingOptions));
|
this.root.push(new Anchor(imageData, imageData.transformation, drawingOptions));
|
||||||
|
@ -1,6 +1,21 @@
|
|||||||
import { XmlComponent } from "@file/xml-components";
|
import { IContext, IXmlableObject, XmlComponent } from "@file/xml-components";
|
||||||
|
import { createHyperlinkClick } from "@file/drawing/doc-properties/doc-properties-children";
|
||||||
|
import { ConcreteHyperlink } from "@file/paragraph";
|
||||||
|
|
||||||
import { NonVisualPropertiesAttributes } from "./non-visual-properties-attributes";
|
import { NonVisualPropertiesAttributes } from "./non-visual-properties-attributes";
|
||||||
|
|
||||||
|
// <complexType name="CT_NonVisualDrawingProps">
|
||||||
|
// <sequence>
|
||||||
|
// <element name="hlinkClick" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="hlinkHover" type="CT_Hyperlink" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1" />
|
||||||
|
// </sequence>
|
||||||
|
// <attribute name="id" type="ST_DrawingElementId" use="required" />
|
||||||
|
// <attribute name="name" type="xsd:string" use="required" />
|
||||||
|
// <attribute name="descr" type="xsd:string" use="optional" default="" />
|
||||||
|
// <attribute name="hidden" type="xsd:boolean" use="optional" default="false" />
|
||||||
|
// </complexType>
|
||||||
|
|
||||||
export class NonVisualProperties extends XmlComponent {
|
export class NonVisualProperties extends XmlComponent {
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super("pic:cNvPr");
|
super("pic:cNvPr");
|
||||||
@ -13,4 +28,19 @@ export class NonVisualProperties extends XmlComponent {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public prepForXml(context: IContext): IXmlableObject | undefined {
|
||||||
|
for (let i = context.stack.length - 1; i >= 0; i--) {
|
||||||
|
const element = context.stack[i];
|
||||||
|
if (!(element instanceof ConcreteHyperlink)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.root.push(createHyperlinkClick(element.linkId, false));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.prepForXml(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
// http://officeopenxml.com/drwPicInline.php
|
// http://officeopenxml.com/drwPicInline.php
|
||||||
import { IMediaData, IMediaDataTransformation } from "@file/media";
|
import { IMediaData, IMediaDataTransformation } from "@file/media";
|
||||||
import { XmlComponent } from "@file/xml-components";
|
import { XmlComponent } from "@file/xml-components";
|
||||||
import { DocProperties } from "./../doc-properties/doc-properties";
|
import { DocProperties, DocPropertiesOptions } from "./../doc-properties/doc-properties";
|
||||||
import { EffectExtent } from "./../effect-extent/effect-extent";
|
import { EffectExtent } from "./../effect-extent/effect-extent";
|
||||||
import { Extent } from "./../extent/extent";
|
import { Extent } from "./../extent/extent";
|
||||||
import { GraphicFrameProperties } from "./../graphic-frame/graphic-frame-properties";
|
import { GraphicFrameProperties } from "./../graphic-frame/graphic-frame-properties";
|
||||||
import { Graphic } from "./../inline/graphic";
|
import { Graphic } from "./../inline/graphic";
|
||||||
import { InlineAttributes } from "./inline-attributes";
|
import { InlineAttributes } from "./inline-attributes";
|
||||||
|
|
||||||
|
interface InlineOptions {
|
||||||
|
readonly mediaData: IMediaData;
|
||||||
|
readonly transform: IMediaDataTransformation;
|
||||||
|
readonly docProperties?: DocPropertiesOptions;
|
||||||
|
}
|
||||||
|
|
||||||
// <xsd:complexType name="CT_Inline">
|
// <xsd:complexType name="CT_Inline">
|
||||||
// <xsd:sequence>
|
// <xsd:sequence>
|
||||||
// <xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
// <xsd:element name="extent" type="a:CT_PositiveSize2D"/>
|
||||||
@ -26,7 +32,7 @@ export class Inline extends XmlComponent {
|
|||||||
private readonly extent: Extent;
|
private readonly extent: Extent;
|
||||||
private readonly graphic: Graphic;
|
private readonly graphic: Graphic;
|
||||||
|
|
||||||
public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
|
public constructor({ mediaData, transform, docProperties }: InlineOptions) {
|
||||||
super("wp:inline");
|
super("wp:inline");
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
@ -43,7 +49,7 @@ export class Inline extends XmlComponent {
|
|||||||
|
|
||||||
this.root.push(this.extent);
|
this.root.push(this.extent);
|
||||||
this.root.push(new EffectExtent());
|
this.root.push(new EffectExtent());
|
||||||
this.root.push(new DocProperties());
|
this.root.push(new DocProperties(docProperties));
|
||||||
this.root.push(new GraphicFrameProperties());
|
this.root.push(new GraphicFrameProperties());
|
||||||
this.root.push(this.graphic);
|
this.root.push(this.graphic);
|
||||||
}
|
}
|
||||||
|
5
src/file/file-child.ts
Normal file
5
src/file/file-child.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
export class FileChild extends XmlComponent {
|
||||||
|
public readonly fileChild = Symbol();
|
||||||
|
}
|
@ -11,15 +11,13 @@ import { Footer, Header } from "./header";
|
|||||||
import { HeaderWrapper, IDocumentHeader } from "./header-wrapper";
|
import { HeaderWrapper, IDocumentHeader } from "./header-wrapper";
|
||||||
import { Media } from "./media";
|
import { Media } from "./media";
|
||||||
import { Numbering } from "./numbering";
|
import { Numbering } from "./numbering";
|
||||||
import { Paragraph } from "./paragraph";
|
|
||||||
import { Comments } from "./paragraph/run/comment-run";
|
import { Comments } from "./paragraph/run/comment-run";
|
||||||
import { Relationships } from "./relationships";
|
import { Relationships } from "./relationships";
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
import { Styles } from "./styles";
|
import { Styles } from "./styles";
|
||||||
import { ExternalStylesFactory } from "./styles/external-styles-factory";
|
import { ExternalStylesFactory } from "./styles/external-styles-factory";
|
||||||
import { DefaultStylesFactory } from "./styles/factory";
|
import { DefaultStylesFactory } from "./styles/factory";
|
||||||
import { Table } from "./table";
|
import { FileChild } from "./file-child";
|
||||||
import { TableOfContents } from "./table-of-contents";
|
|
||||||
|
|
||||||
export interface ISectionOptions {
|
export interface ISectionOptions {
|
||||||
readonly headers?: {
|
readonly headers?: {
|
||||||
@ -33,7 +31,7 @@ export interface ISectionOptions {
|
|||||||
readonly even?: Footer;
|
readonly even?: Footer;
|
||||||
};
|
};
|
||||||
readonly properties?: ISectionPropertiesOptions;
|
readonly properties?: ISectionPropertiesOptions;
|
||||||
readonly children: readonly (Paragraph | Table | TableOfContents)[];
|
readonly children: readonly FileChild[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class File {
|
export class File {
|
||||||
@ -73,9 +71,10 @@ export class File {
|
|||||||
this.appProperties = new AppProperties();
|
this.appProperties = new AppProperties();
|
||||||
this.footnotesWrapper = new FootnotesWrapper();
|
this.footnotesWrapper = new FootnotesWrapper();
|
||||||
this.contentTypes = new ContentTypes();
|
this.contentTypes = new ContentTypes();
|
||||||
this.documentWrapper = new DocumentWrapper({ background: options.background || {} });
|
this.documentWrapper = new DocumentWrapper({ background: options.background });
|
||||||
this.settings = new Settings({
|
this.settings = new Settings({
|
||||||
compatabilityModeVersion: options.compatabilityModeVersion,
|
compatibilityModeVersion: options.compatabilityModeVersion,
|
||||||
|
compatibility: options.compatibility,
|
||||||
evenAndOddHeaders: options.evenAndOddHeaderAndFooters ? true : false,
|
evenAndOddHeaders: options.evenAndOddHeaderAndFooters ? true : false,
|
||||||
trackRevisions: options.features?.trackRevisions,
|
trackRevisions: options.features?.trackRevisions,
|
||||||
updateFields: options.features?.updateFields,
|
updateFields: options.features?.updateFields,
|
||||||
|
@ -18,4 +18,3 @@ export * from "./track-revision";
|
|||||||
export * from "./shared";
|
export * from "./shared";
|
||||||
export * from "./border";
|
export * from "./border";
|
||||||
export * from "./vertical-align";
|
export * from "./vertical-align";
|
||||||
export * from "./space-type";
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,9 +12,11 @@ describe("ConcreteNumbering", () => {
|
|||||||
abstractNumId: 1,
|
abstractNumId: 1,
|
||||||
reference: "1",
|
reference: "1",
|
||||||
instance: 0,
|
instance: 0,
|
||||||
overrideLevel: {
|
overrideLevels: [
|
||||||
|
{
|
||||||
num: 3,
|
num: 3,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const tree = new Formatter().format(concreteNumbering);
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
@ -44,19 +46,78 @@ describe("ConcreteNumbering", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sets a new override level for two different level numbers", () => {
|
||||||
|
const concreteNumbering = new ConcreteNumbering({
|
||||||
|
numId: 0,
|
||||||
|
abstractNumId: 1,
|
||||||
|
reference: "1",
|
||||||
|
instance: 0,
|
||||||
|
overrideLevels: [{ num: 3 }, { num: 5 }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:num": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:numId": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:abstractNumId": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("sets the startOverride element if start is given", () => {
|
it("sets the startOverride element if start is given", () => {
|
||||||
const concreteNumbering = new ConcreteNumbering({
|
const concreteNumbering = new ConcreteNumbering({
|
||||||
numId: 0,
|
numId: 0,
|
||||||
abstractNumId: 1,
|
abstractNumId: 1,
|
||||||
reference: "1",
|
reference: "1",
|
||||||
instance: 0,
|
instance: 0,
|
||||||
overrideLevel: {
|
overrideLevels: [
|
||||||
|
{
|
||||||
num: 1,
|
num: 1,
|
||||||
start: 9,
|
start: 9,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const tree = new Formatter().format(concreteNumbering);
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
expect(tree["w:num"]).to.include({
|
expect(tree).to.deep.equal({
|
||||||
|
"w:num": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:numId": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:abstractNumId": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
"w:lvlOverride": [
|
"w:lvlOverride": [
|
||||||
{
|
{
|
||||||
_attr: {
|
_attr: {
|
||||||
@ -71,6 +132,134 @@ describe("ConcreteNumbering", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets the startOverride element for several levels if start is given", () => {
|
||||||
|
const concreteNumbering = new ConcreteNumbering({
|
||||||
|
numId: 0,
|
||||||
|
abstractNumId: 1,
|
||||||
|
reference: "1",
|
||||||
|
instance: 0,
|
||||||
|
overrideLevels: [
|
||||||
|
{
|
||||||
|
num: 1,
|
||||||
|
start: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
num: 3,
|
||||||
|
start: 10,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:num": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:numId": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:abstractNumId": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:startOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:startOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Mix of overrideLevels with start and without", () => {
|
||||||
|
const concreteNumbering = new ConcreteNumbering({
|
||||||
|
numId: 0,
|
||||||
|
abstractNumId: 1,
|
||||||
|
reference: "1",
|
||||||
|
instance: 0,
|
||||||
|
overrideLevels: [
|
||||||
|
{
|
||||||
|
num: 1,
|
||||||
|
start: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
num: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:num": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:numId": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:abstractNumId": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:startOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:lvlOverride": {
|
||||||
|
_attr: {
|
||||||
|
"w:ilvl": 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,9 +269,11 @@ describe("ConcreteNumbering", () => {
|
|||||||
abstractNumId: 1,
|
abstractNumId: 1,
|
||||||
reference: "1",
|
reference: "1",
|
||||||
instance: 0,
|
instance: 0,
|
||||||
overrideLevel: {
|
overrideLevels: [
|
||||||
|
{
|
||||||
num: 1,
|
num: 1,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const tree = new Formatter().format(concreteNumbering);
|
const tree = new Formatter().format(concreteNumbering);
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// http://officeopenxml.com/WPnumbering-numFmt.php
|
// http://officeopenxml.com/WPnumbering-numFmt.php
|
||||||
|
// http://www.datypic.com/sc/ooxml/a-w_val-57.html
|
||||||
import { Attributes, NumberValueElement, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { Attributes, NumberValueElement, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { decimalNumber } from "@util/values";
|
import { decimalNumber } from "@util/values";
|
||||||
|
|
||||||
@ -6,21 +7,138 @@ import { AlignmentType } from "../paragraph/formatting";
|
|||||||
import { ILevelParagraphStylePropertiesOptions, ParagraphProperties } from "../paragraph/properties";
|
import { ILevelParagraphStylePropertiesOptions, ParagraphProperties } from "../paragraph/properties";
|
||||||
import { IRunStylePropertiesOptions, RunProperties } from "../paragraph/run/properties";
|
import { IRunStylePropertiesOptions, RunProperties } from "../paragraph/run/properties";
|
||||||
|
|
||||||
|
// TODO: Breaking change - consolidate with number-format
|
||||||
|
// <xsd:simpleType name="ST_NumberFormat">
|
||||||
|
// <xsd:restriction base="xsd:string">
|
||||||
|
// <xsd:enumeration value="decimal"/>
|
||||||
|
// <xsd:enumeration value="upperRoman"/>
|
||||||
|
// <xsd:enumeration value="lowerRoman"/>
|
||||||
|
// <xsd:enumeration value="upperLetter"/>
|
||||||
|
// <xsd:enumeration value="lowerLetter"/>
|
||||||
|
// <xsd:enumeration value="ordinal"/>
|
||||||
|
// <xsd:enumeration value="cardinalText"/>
|
||||||
|
// <xsd:enumeration value="ordinalText"/>
|
||||||
|
// <xsd:enumeration value="hex"/>
|
||||||
|
// <xsd:enumeration value="chicago"/>
|
||||||
|
// <xsd:enumeration value="ideographDigital"/>
|
||||||
|
// <xsd:enumeration value="japaneseCounting"/>
|
||||||
|
// <xsd:enumeration value="aiueo"/>
|
||||||
|
// <xsd:enumeration value="iroha"/>
|
||||||
|
// <xsd:enumeration value="decimalFullWidth"/>
|
||||||
|
// <xsd:enumeration value="decimalHalfWidth"/>
|
||||||
|
// <xsd:enumeration value="japaneseLegal"/>
|
||||||
|
// <xsd:enumeration value="japaneseDigitalTenThousand"/>
|
||||||
|
// <xsd:enumeration value="decimalEnclosedCircle"/>
|
||||||
|
// <xsd:enumeration value="decimalFullWidth2"/>
|
||||||
|
// <xsd:enumeration value="aiueoFullWidth"/>
|
||||||
|
// <xsd:enumeration value="irohaFullWidth"/>
|
||||||
|
// <xsd:enumeration value="decimalZero"/>
|
||||||
|
// <xsd:enumeration value="bullet"/>
|
||||||
|
// <xsd:enumeration value="ganada"/>
|
||||||
|
// <xsd:enumeration value="chosung"/>
|
||||||
|
// <xsd:enumeration value="decimalEnclosedFullstop"/>
|
||||||
|
// <xsd:enumeration value="decimalEnclosedParen"/>
|
||||||
|
// <xsd:enumeration value="decimalEnclosedCircleChinese"/>
|
||||||
|
// <xsd:enumeration value="ideographEnclosedCircle"/>
|
||||||
|
// <xsd:enumeration value="ideographTraditional"/>
|
||||||
|
// <xsd:enumeration value="ideographZodiac"/>
|
||||||
|
// <xsd:enumeration value="ideographZodiacTraditional"/>
|
||||||
|
// <xsd:enumeration value="taiwaneseCounting"/>
|
||||||
|
// <xsd:enumeration value="ideographLegalTraditional"/>
|
||||||
|
// <xsd:enumeration value="taiwaneseCountingThousand"/>
|
||||||
|
// <xsd:enumeration value="taiwaneseDigital"/>
|
||||||
|
// <xsd:enumeration value="chineseCounting"/>
|
||||||
|
// <xsd:enumeration value="chineseLegalSimplified"/>
|
||||||
|
// <xsd:enumeration value="chineseCountingThousand"/>
|
||||||
|
// <xsd:enumeration value="koreanDigital"/>
|
||||||
|
// <xsd:enumeration value="koreanCounting"/>
|
||||||
|
// <xsd:enumeration value="koreanLegal"/>
|
||||||
|
// <xsd:enumeration value="koreanDigital2"/>
|
||||||
|
// <xsd:enumeration value="vietnameseCounting"/>
|
||||||
|
// <xsd:enumeration value="russianLower"/>
|
||||||
|
// <xsd:enumeration value="russianUpper"/>
|
||||||
|
// <xsd:enumeration value="none"/>
|
||||||
|
// <xsd:enumeration value="numberInDash"/>
|
||||||
|
// <xsd:enumeration value="hebrew1"/>
|
||||||
|
// <xsd:enumeration value="hebrew2"/>
|
||||||
|
// <xsd:enumeration value="arabicAlpha"/>
|
||||||
|
// <xsd:enumeration value="arabicAbjad"/>
|
||||||
|
// <xsd:enumeration value="hindiVowels"/>
|
||||||
|
// <xsd:enumeration value="hindiConsonants"/>
|
||||||
|
// <xsd:enumeration value="hindiNumbers"/>
|
||||||
|
// <xsd:enumeration value="hindiCounting"/>
|
||||||
|
// <xsd:enumeration value="thaiLetters"/>
|
||||||
|
// <xsd:enumeration value="thaiNumbers"/>
|
||||||
|
// <xsd:enumeration value="thaiCounting"/>
|
||||||
|
// <xsd:enumeration value="bahtText"/>
|
||||||
|
// <xsd:enumeration value="dollarText"/>
|
||||||
|
// <xsd:enumeration value="custom"/>
|
||||||
|
// </xsd:restriction>
|
||||||
|
// </xsd:simpleType>
|
||||||
export enum LevelFormat {
|
export enum LevelFormat {
|
||||||
BULLET = "bullet",
|
|
||||||
CARDINAL_TEXT = "cardinalText",
|
|
||||||
CHICAGO = "chicago",
|
|
||||||
DECIMAL = "decimal",
|
DECIMAL = "decimal",
|
||||||
|
UPPER_ROMAN = "upperRoman",
|
||||||
|
LOWER_ROMAN = "lowerRoman",
|
||||||
|
UPPER_LETTER = "upperLetter",
|
||||||
|
LOWER_LETTER = "lowerLetter",
|
||||||
|
ORDINAL = "ordinal",
|
||||||
|
CARDINAL_TEXT = "cardinalText",
|
||||||
|
ORDINAL_TEXT = "ordinalText",
|
||||||
|
HEX = "hex",
|
||||||
|
CHICAGO = "chicago",
|
||||||
|
IDEOGRAPH__DIGITAL = "ideographDigital",
|
||||||
|
JAPANESE_COUNTING = "japaneseCounting",
|
||||||
|
AIUEO = "aiueo",
|
||||||
|
IROHA = "iroha",
|
||||||
|
DECIMAL_FULL_WIDTH = "decimalFullWidth",
|
||||||
|
DECIMAL_HALF_WIDTH = "decimalHalfWidth",
|
||||||
|
JAPANESE_LEGAL = "japaneseLegal",
|
||||||
|
JAPANESE_DIGITAL_TEN_THOUSAND = "japaneseDigitalTenThousand",
|
||||||
DECIMAL_ENCLOSED_CIRCLE = "decimalEnclosedCircle",
|
DECIMAL_ENCLOSED_CIRCLE = "decimalEnclosedCircle",
|
||||||
|
DECIMAL_FULL_WIDTH2 = "decimalFullWidth2",
|
||||||
|
AIUEO_FULL_WIDTH = "aiueoFullWidth",
|
||||||
|
IROHA_FULL_WIDTH = "irohaFullWidth",
|
||||||
|
DECIMAL_ZERO = "decimalZero",
|
||||||
|
BULLET = "bullet",
|
||||||
|
GANADA = "ganada",
|
||||||
|
CHOSUNG = "chosung",
|
||||||
DECIMAL_ENCLOSED_FULLSTOP = "decimalEnclosedFullstop",
|
DECIMAL_ENCLOSED_FULLSTOP = "decimalEnclosedFullstop",
|
||||||
DECIMAL_ENCLOSED_PARENTHESES = "decimalEnclosedParen",
|
DECIMAL_ENCLOSED_PARENTHESES = "decimalEnclosedParen",
|
||||||
DECIMAL_ZERO = "decimalZero",
|
DECIMAL_ENCLOSED_CIRCLE_CHINESE = "decimalEnclosedCircleChinese",
|
||||||
LOWER_LETTER = "lowerLetter",
|
IDEOGRAPH_ENCLOSED_CIRCLE = "ideographEnclosedCircle",
|
||||||
LOWER_ROMAN = "lowerRoman",
|
IDEOGRAPH_TRADITIONAL = "ideographTraditional",
|
||||||
|
IDEOGRAPH_ZODIAC = "ideographZodiac",
|
||||||
|
IDEOGRAPH_ZODIAC_TRADITIONAL = "ideographZodiacTraditional",
|
||||||
|
TAIWANESE_COUNTING = "taiwaneseCounting",
|
||||||
|
IDEOGRAPH_LEGAL_TRADITIONAL = "ideographLegalTraditional",
|
||||||
|
TAIWANESE_COUNTING_THOUSAND = "taiwaneseCountingThousand",
|
||||||
|
TAIWANESE_DIGITAL = "taiwaneseDigital",
|
||||||
|
CHINESE_COUNTING = "chineseCounting",
|
||||||
|
CHINESE_LEGAL_SIMPLIFIED = "chineseLegalSimplified",
|
||||||
|
CHINESE_COUNTING_THOUSAND = "chineseCountingThousand",
|
||||||
|
KOREAN_DIGITAL = "koreanDigital",
|
||||||
|
KOREAN_COUNTING = "koreanCounting",
|
||||||
|
KOREAN_LEGAL = "koreanLegal",
|
||||||
|
KOREAN_DIGITAL2 = "koreanDigital2",
|
||||||
|
VIETNAMESE_COUNTING = "vietnameseCounting",
|
||||||
|
RUSSIAN_LOWER = "russianLower",
|
||||||
|
RUSSIAN_UPPER = "russianUpper",
|
||||||
NONE = "none",
|
NONE = "none",
|
||||||
ORDINAL_TEXT = "ordinalText",
|
NUMBER_IN_DASH = "numberInDash",
|
||||||
UPPER_LETTER = "upperLetter",
|
HEBREW1 = "hebrew1",
|
||||||
UPPER_ROMAN = "upperRoman",
|
HEBREW2 = "hebrew2",
|
||||||
|
ARABIC_ALPHA = "arabicAlpha",
|
||||||
|
ARABIC_ABJAD = "arabicAbjad",
|
||||||
|
HINDI_VOWELS = "hindiVowels",
|
||||||
|
HINDI_CONSONANTS = "hindiConsonants",
|
||||||
|
HINDI_NUMBERS = "hindiNumbers",
|
||||||
|
HINDI_COUNTING = "hindiCounting",
|
||||||
|
THAI_LETTERS = "thaiLetters",
|
||||||
|
THAI_NUMBERS = "thaiNumbers",
|
||||||
|
THAI_COUNTING = "thaiCounting",
|
||||||
|
BAHT_TEXT = "bahtText",
|
||||||
|
DOLLAR_TEXT = "dollarText",
|
||||||
|
CUSTOM = "custom",
|
||||||
}
|
}
|
||||||
|
|
||||||
class LevelAttributes extends XmlAttributeComponent<{
|
class LevelAttributes extends XmlAttributeComponent<{
|
||||||
|
@ -18,15 +18,17 @@ class NumAttributes extends XmlAttributeComponent<{
|
|||||||
protected readonly xmlKeys = { numId: "w:numId" };
|
protected readonly xmlKeys = { numId: "w:numId" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IOverrideLevel {
|
||||||
|
readonly num: number;
|
||||||
|
readonly start?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IConcreteNumberingOptions {
|
export interface IConcreteNumberingOptions {
|
||||||
readonly numId: number;
|
readonly numId: number;
|
||||||
readonly abstractNumId: number;
|
readonly abstractNumId: number;
|
||||||
readonly reference: string;
|
readonly reference: string;
|
||||||
readonly instance: number;
|
readonly instance: number;
|
||||||
readonly overrideLevel?: {
|
readonly overrideLevels?: readonly IOverrideLevel[];
|
||||||
readonly num: number;
|
|
||||||
readonly start?: number;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// <xsd:complexType name="CT_Numbering">
|
// <xsd:complexType name="CT_Numbering">
|
||||||
@ -60,8 +62,10 @@ export class ConcreteNumbering extends XmlComponent {
|
|||||||
|
|
||||||
this.root.push(new AbstractNumId(decimalNumber(options.abstractNumId)));
|
this.root.push(new AbstractNumId(decimalNumber(options.abstractNumId)));
|
||||||
|
|
||||||
if (options.overrideLevel) {
|
if (options.overrideLevels && options.overrideLevels.length) {
|
||||||
this.root.push(new LevelOverride(options.overrideLevel.num, options.overrideLevel.start));
|
for (const level of options.overrideLevels) {
|
||||||
|
this.root.push(new LevelOverride(level.num, level.start));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,10 +164,12 @@ export class Numbering extends XmlComponent {
|
|||||||
abstractNumId: abstractNumbering.id,
|
abstractNumId: abstractNumbering.id,
|
||||||
reference: "default-bullet-numbering",
|
reference: "default-bullet-numbering",
|
||||||
instance: 0,
|
instance: 0,
|
||||||
overrideLevel: {
|
overrideLevels: [
|
||||||
|
{
|
||||||
num: 0,
|
num: 0,
|
||||||
start: 1,
|
start: 1,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,16 +1,51 @@
|
|||||||
// http://officeopenxml.com/WPalignment.php
|
// http://officeopenxml.com/WPalignment.php
|
||||||
// http://officeopenxml.com/WPtableAlignment.php
|
// http://officeopenxml.com/WPtableAlignment.php
|
||||||
|
// http://www.datypic.com/sc/ooxml/t-w_ST_Jc.html
|
||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
// <xsd:simpleType name="ST_Jc">
|
||||||
|
// <xsd:restriction base="xsd:string">
|
||||||
|
// <xsd:enumeration value="start"/>
|
||||||
|
// <xsd:enumeration value="center"/>
|
||||||
|
// <xsd:enumeration value="end"/>
|
||||||
|
// <xsd:enumeration value="both"/>
|
||||||
|
// <xsd:enumeration value="mediumKashida"/>
|
||||||
|
// <xsd:enumeration value="distribute"/>
|
||||||
|
// <xsd:enumeration value="numTab"/>
|
||||||
|
// <xsd:enumeration value="highKashida"/>
|
||||||
|
// <xsd:enumeration value="lowKashida"/>
|
||||||
|
// <xsd:enumeration value="thaiDistribute"/>
|
||||||
|
// <xsd:enumeration value="left"/>
|
||||||
|
// <xsd:enumeration value="right"/>
|
||||||
|
// </xsd:restriction>
|
||||||
|
// </xsd:simpleType>
|
||||||
export enum AlignmentType {
|
export enum AlignmentType {
|
||||||
|
/** Align Start */
|
||||||
START = "start",
|
START = "start",
|
||||||
END = "end",
|
/** Align Center */
|
||||||
CENTER = "center",
|
CENTER = "center",
|
||||||
|
/** End */
|
||||||
|
END = "end",
|
||||||
|
/** Justified */
|
||||||
BOTH = "both",
|
BOTH = "both",
|
||||||
JUSTIFIED = "both",
|
/** Medium Kashida Length */
|
||||||
|
MEDIUM_KASHIDA = "mediumKashida",
|
||||||
|
/** Distribute All Characters Equally */
|
||||||
DISTRIBUTE = "distribute",
|
DISTRIBUTE = "distribute",
|
||||||
|
/** Align to List Tab */
|
||||||
|
NUM_TAB = "numTab",
|
||||||
|
/** Widest Kashida Length */
|
||||||
|
HIGH_KASHIDA = "highKashida",
|
||||||
|
/** Low Kashida Length */
|
||||||
|
LOW_KASHIDA = "lowKashida",
|
||||||
|
/** Thai Language Justification */
|
||||||
|
THAI_DISTRIBUTE = "thaiDistribute",
|
||||||
|
/** Align Left */
|
||||||
LEFT = "left",
|
LEFT = "left",
|
||||||
|
/** Align Right */
|
||||||
RIGHT = "right",
|
RIGHT = "right",
|
||||||
|
/** Justified */
|
||||||
|
JUSTIFIED = "both",
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AlignmentAttributes extends XmlAttributeComponent<{ readonly val: AlignmentType }> {
|
export class AlignmentAttributes extends XmlAttributeComponent<{ readonly val: AlignmentType }> {
|
||||||
|
@ -1,39 +1,14 @@
|
|||||||
// http://officeopenxml.com/WPindentation.php
|
// http://officeopenxml.com/WPindentation.php
|
||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
import { signedTwipsMeasureValue, twipsMeasureValue } from "@util/values";
|
import { PositiveUniversalMeasure, signedTwipsMeasureValue, twipsMeasureValue, UniversalMeasure } from "@util/values";
|
||||||
|
|
||||||
export interface IIndentAttributesProperties {
|
export interface IIndentAttributesProperties {
|
||||||
readonly start?: number | string;
|
readonly start?: number | UniversalMeasure;
|
||||||
readonly end?: number | string;
|
readonly end?: number | UniversalMeasure;
|
||||||
readonly left?: number | string;
|
readonly left?: number | UniversalMeasure;
|
||||||
readonly right?: number | string;
|
readonly right?: number | UniversalMeasure;
|
||||||
readonly hanging?: number | string;
|
readonly hanging?: number | PositiveUniversalMeasure;
|
||||||
readonly firstLine?: number | string;
|
readonly firstLine?: number | PositiveUniversalMeasure;
|
||||||
}
|
|
||||||
|
|
||||||
// <xsd:complexType name="CT_Ind">
|
|
||||||
// <xsd:attribute name="start" type="ST_SignedTwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="startChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// <xsd:attribute name="end" type="ST_SignedTwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="endChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// <xsd:attribute name="left" type="ST_SignedTwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="leftChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// <xsd:attribute name="right" type="ST_SignedTwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="rightChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// <xsd:attribute name="hanging" type="s:ST_TwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="hangingChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// <xsd:attribute name="firstLine" type="s:ST_TwipsMeasure" use="optional"/>
|
|
||||||
// <xsd:attribute name="firstLineChars" type="ST_DecimalNumber" use="optional"/>
|
|
||||||
// </xsd:complexType>
|
|
||||||
class IndentAttributes extends XmlAttributeComponent<IIndentAttributesProperties> {
|
|
||||||
protected readonly xmlKeys = {
|
|
||||||
start: "w:start",
|
|
||||||
end: "w:end",
|
|
||||||
left: "w:left",
|
|
||||||
right: "w:right",
|
|
||||||
hanging: "w:hanging",
|
|
||||||
firstLine: "w:firstLine",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// <xsd:complexType name="CT_PPrBase">
|
// <xsd:complexType name="CT_PPrBase">
|
||||||
@ -43,14 +18,53 @@ class IndentAttributes extends XmlAttributeComponent<IIndentAttributesProperties
|
|||||||
export class Indent extends XmlComponent {
|
export class Indent extends XmlComponent {
|
||||||
public constructor({ start, end, left, right, hanging, firstLine }: IIndentAttributesProperties) {
|
public constructor({ start, end, left, right, hanging, firstLine }: IIndentAttributesProperties) {
|
||||||
super("w:ind");
|
super("w:ind");
|
||||||
|
// <xsd:complexType name="CT_Ind">
|
||||||
|
// <xsd:attribute name="start" type="ST_SignedTwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="startChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// <xsd:attribute name="end" type="ST_SignedTwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="endChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// <xsd:attribute name="left" type="ST_SignedTwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="leftChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// <xsd:attribute name="right" type="ST_SignedTwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="rightChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// <xsd:attribute name="hanging" type="s:ST_TwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="hangingChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// <xsd:attribute name="firstLine" type="s:ST_TwipsMeasure" use="optional"/>
|
||||||
|
// <xsd:attribute name="firstLineChars" type="ST_DecimalNumber" use="optional"/>
|
||||||
|
// </xsd:complexType>
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new IndentAttributes({
|
new NextAttributeComponent<{
|
||||||
start: start === undefined ? undefined : signedTwipsMeasureValue(start),
|
readonly start?: number | UniversalMeasure;
|
||||||
end: end === undefined ? undefined : signedTwipsMeasureValue(end),
|
readonly end?: number | UniversalMeasure;
|
||||||
left: left === undefined ? undefined : signedTwipsMeasureValue(left),
|
readonly left?: number | UniversalMeasure;
|
||||||
right: right === undefined ? undefined : signedTwipsMeasureValue(right),
|
readonly right?: number | UniversalMeasure;
|
||||||
hanging: hanging === undefined ? undefined : twipsMeasureValue(hanging),
|
readonly hanging?: number | PositiveUniversalMeasure;
|
||||||
firstLine: firstLine === undefined ? undefined : twipsMeasureValue(firstLine),
|
readonly firstLine?: number | PositiveUniversalMeasure;
|
||||||
|
}>({
|
||||||
|
start: {
|
||||||
|
key: "w:start",
|
||||||
|
value: start === undefined ? undefined : signedTwipsMeasureValue(start),
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
key: "w:end",
|
||||||
|
value: end === undefined ? undefined : signedTwipsMeasureValue(end),
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
key: "w:left",
|
||||||
|
value: left === undefined ? undefined : signedTwipsMeasureValue(left),
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
key: "w:right",
|
||||||
|
value: right === undefined ? undefined : signedTwipsMeasureValue(right),
|
||||||
|
},
|
||||||
|
hanging: {
|
||||||
|
key: "w:hanging",
|
||||||
|
value: hanging === undefined ? undefined : twipsMeasureValue(hanging),
|
||||||
|
},
|
||||||
|
firstLine: {
|
||||||
|
key: "w:firstLine",
|
||||||
|
value: firstLine === undefined ? undefined : twipsMeasureValue(firstLine),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
|||||||
export enum LineRuleType {
|
export enum LineRuleType {
|
||||||
AT_LEAST = "atLeast",
|
AT_LEAST = "atLeast",
|
||||||
EXACTLY = "exactly",
|
EXACTLY = "exactly",
|
||||||
|
EXACT = "exact",
|
||||||
AUTO = "auto",
|
AUTO = "auto",
|
||||||
}
|
}
|
||||||
export interface ISpacingProperties {
|
export interface ISpacingProperties {
|
||||||
|
@ -8,7 +8,7 @@ describe("LeftTabStop", () => {
|
|||||||
let tabStop: TabStop;
|
let tabStop: TabStop;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tabStop = new TabStop(TabStopType.LEFT, 100);
|
tabStop = new TabStop([{ type: TabStopType.LEFT, position: 100 }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -32,7 +32,7 @@ describe("RightTabStop", () => {
|
|||||||
let tabStop: TabStop;
|
let tabStop: TabStop;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
tabStop = new TabStop(TabStopType.RIGHT, 100, LeaderType.DOT);
|
tabStop = new TabStop([{ type: TabStopType.RIGHT, position: 100, leader: LeaderType.DOT }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
|
@ -1,10 +1,19 @@
|
|||||||
// http://officeopenxml.com/WPtab.php
|
// http://officeopenxml.com/WPtab.php
|
||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
export interface TabStopDefinition {
|
||||||
|
readonly type: TabStopType;
|
||||||
|
readonly position: number | TabStopPosition;
|
||||||
|
readonly leader?: LeaderType;
|
||||||
|
}
|
||||||
|
|
||||||
export class TabStop extends XmlComponent {
|
export class TabStop extends XmlComponent {
|
||||||
public constructor(type: TabStopType, position: number, leader?: LeaderType) {
|
public constructor(tabDefinitions: readonly TabStopDefinition[]) {
|
||||||
super("w:tabs");
|
super("w:tabs");
|
||||||
this.root.push(new TabStopItem(type, position, leader));
|
|
||||||
|
for (const tabDefinition of tabDefinitions) {
|
||||||
|
this.root.push(new TabStopItem(tabDefinition));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,13 +50,13 @@ export class TabAttributes extends XmlAttributeComponent<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TabStopItem extends XmlComponent {
|
export class TabStopItem extends XmlComponent {
|
||||||
public constructor(value: TabStopType, position: string | number, leader?: LeaderType) {
|
public constructor({ type, position, leader }: TabStopDefinition) {
|
||||||
super("w:tab");
|
super("w:tab");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new TabAttributes({
|
new TabAttributes({
|
||||||
val: value,
|
val: type,
|
||||||
pos: position,
|
pos: position,
|
||||||
leader,
|
leader: leader,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
0
src/file/paragraph/formatting/width.ts
Normal file
0
src/file/paragraph/formatting/width.ts
Normal file
20
src/file/paragraph/formatting/word-wrap.spec.ts
Normal file
20
src/file/paragraph/formatting/word-wrap.spec.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
|
||||||
|
import { WordWrap } from "./word-wrap";
|
||||||
|
|
||||||
|
describe("WordWrap", () => {
|
||||||
|
it("should create", () => {
|
||||||
|
const wordWrap = new WordWrap();
|
||||||
|
const tree = new Formatter().format(wordWrap);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:wordWrap": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
14
src/file/paragraph/formatting/word-wrap.ts
Normal file
14
src/file/paragraph/formatting/word-wrap.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// http://officeopenxml.com/WPalignment.php
|
||||||
|
// http://officeopenxml.com/WPtableAlignment.php
|
||||||
|
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
export class WordWrapAttributes extends XmlAttributeComponent<{ readonly val: 0 }> {
|
||||||
|
protected readonly xmlKeys = { val: "w:val" };
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WordWrap extends XmlComponent {
|
||||||
|
public constructor() {
|
||||||
|
super("w:wordWrap");
|
||||||
|
this.root.push(new WordWrapAttributes({ val: 0 }));
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { SpaceType } from "@file/space-type";
|
import { SpaceType } from "@file/shared";
|
||||||
import { XmlComponent } from "@file/xml-components";
|
import { XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
import { TextAttributes } from "../run/text-attributes";
|
import { TextAttributes } from "../run/text-attributes";
|
||||||
|
@ -2,7 +2,7 @@ import { MathAngledBrackets, MathCurlyBrackets, MathRoundBrackets, MathSquareBra
|
|||||||
import { MathFraction } from "./fraction";
|
import { MathFraction } from "./fraction";
|
||||||
import { MathFunction } from "./function";
|
import { MathFunction } from "./function";
|
||||||
import { MathRun } from "./math-run";
|
import { MathRun } from "./math-run";
|
||||||
import { MathSum } from "./n-ary";
|
import { MathSum, MathIntegral } from "./n-ary";
|
||||||
import { MathRadical } from "./radical";
|
import { MathRadical } from "./radical";
|
||||||
import { MathSubScript, MathSubSuperScript, MathSuperScript } from "./script";
|
import { MathSubScript, MathSubSuperScript, MathSuperScript } from "./script";
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ export type MathComponent =
|
|||||||
| MathRun
|
| MathRun
|
||||||
| MathFraction
|
| MathFraction
|
||||||
| MathSum
|
| MathSum
|
||||||
|
| MathIntegral
|
||||||
| MathSuperScript
|
| MathSuperScript
|
||||||
| MathSubScript
|
| MathSubScript
|
||||||
| MathSubSuperScript
|
| MathSubSuperScript
|
||||||
|
@ -4,4 +4,5 @@ export * from "./math-limit-location";
|
|||||||
export * from "./math-n-ary-properties";
|
export * from "./math-n-ary-properties";
|
||||||
export * from "./math-sub-script";
|
export * from "./math-sub-script";
|
||||||
export * from "./math-sum";
|
export * from "./math-sum";
|
||||||
|
export * from "./math-integral";
|
||||||
export * from "./math-super-script";
|
export * from "./math-super-script";
|
||||||
|
116
src/file/paragraph/math/n-ary/math-integral.spec.ts
Normal file
116
src/file/paragraph/math/n-ary/math-integral.spec.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
|
||||||
|
import { MathRun } from "../math-run";
|
||||||
|
import { MathIntegral } from "./math-integral";
|
||||||
|
|
||||||
|
describe("MathIntegral", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a MathIntegral with correct root key", () => {
|
||||||
|
const mathIntegral = new MathIntegral({
|
||||||
|
children: [new MathRun("1")],
|
||||||
|
subScript: [new MathRun("2")],
|
||||||
|
superScript: [new MathRun("3")],
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(mathIntegral);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"m:nary": [
|
||||||
|
{
|
||||||
|
"m:naryPr": [
|
||||||
|
{
|
||||||
|
"m:limLoc": {
|
||||||
|
_attr: {
|
||||||
|
"m:val": "undOvr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:sub": [
|
||||||
|
{
|
||||||
|
"m:r": [
|
||||||
|
{
|
||||||
|
"m:t": ["2"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:sup": [
|
||||||
|
{
|
||||||
|
"m:r": [
|
||||||
|
{
|
||||||
|
"m:t": ["3"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:e": [
|
||||||
|
{
|
||||||
|
"m:r": [
|
||||||
|
{
|
||||||
|
"m:t": ["1"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a MathIntegral with correct root key without sub-script and super-scripts", () => {
|
||||||
|
const mathIntegral = new MathIntegral({
|
||||||
|
children: [new MathRun("1")],
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(mathIntegral);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"m:nary": [
|
||||||
|
{
|
||||||
|
"m:naryPr": [
|
||||||
|
{
|
||||||
|
"m:limLoc": {
|
||||||
|
_attr: {
|
||||||
|
"m:val": "undOvr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:supHide": {
|
||||||
|
_attr: {
|
||||||
|
"m:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:subHide": {
|
||||||
|
_attr: {
|
||||||
|
"m:val": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"m:e": [
|
||||||
|
{
|
||||||
|
"m:r": [
|
||||||
|
{
|
||||||
|
"m:t": ["1"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
31
src/file/paragraph/math/n-ary/math-integral.ts
Normal file
31
src/file/paragraph/math/n-ary/math-integral.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
import { MathComponent } from "../math-component";
|
||||||
|
import { MathBase } from "./math-base";
|
||||||
|
import { MathNAryProperties } from "./math-n-ary-properties";
|
||||||
|
import { MathSubScriptElement } from "./math-sub-script";
|
||||||
|
import { MathSuperScriptElement } from "./math-super-script";
|
||||||
|
|
||||||
|
export interface IMathIntegralOptions {
|
||||||
|
readonly children: readonly MathComponent[];
|
||||||
|
readonly subScript?: readonly MathComponent[];
|
||||||
|
readonly superScript?: readonly MathComponent[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MathIntegral extends XmlComponent {
|
||||||
|
public constructor(options: IMathIntegralOptions) {
|
||||||
|
super("m:nary");
|
||||||
|
|
||||||
|
this.root.push(new MathNAryProperties("", !!options.superScript, !!options.subScript));
|
||||||
|
|
||||||
|
if (!!options.subScript) {
|
||||||
|
this.root.push(new MathSubScriptElement(options.subScript));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!options.superScript) {
|
||||||
|
this.root.push(new MathSuperScriptElement(options.superScript));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.root.push(new MathBase(options.children));
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,9 @@ export class MathNAryProperties extends XmlComponent {
|
|||||||
public constructor(accent: string, hasSuperScript: boolean, hasSubScript: boolean) {
|
public constructor(accent: string, hasSuperScript: boolean, hasSubScript: boolean) {
|
||||||
super("m:naryPr");
|
super("m:naryPr");
|
||||||
|
|
||||||
|
if (!!accent) {
|
||||||
this.root.push(new MathAccentCharacter(accent));
|
this.root.push(new MathAccentCharacter(accent));
|
||||||
|
}
|
||||||
this.root.push(new MathLimitLocation());
|
this.root.push(new MathLimitLocation());
|
||||||
|
|
||||||
if (!hasSuperScript) {
|
if (!hasSuperScript) {
|
||||||
|
@ -3,6 +3,7 @@ import { SinonStub, stub } from "sinon";
|
|||||||
|
|
||||||
import * as convenienceFunctions from "@util/convenience-functions";
|
import * as convenienceFunctions from "@util/convenience-functions";
|
||||||
|
|
||||||
|
import { HorizontalPositionAlign, VerticalPositionAlign } from "@file/shared";
|
||||||
import { Formatter } from "@export/formatter";
|
import { Formatter } from "@export/formatter";
|
||||||
import { BorderStyle } from "@file/border";
|
import { BorderStyle } from "@file/border";
|
||||||
import { EMPTY_OBJECT } from "@file/xml-components";
|
import { EMPTY_OBJECT } from "@file/xml-components";
|
||||||
@ -10,7 +11,6 @@ import { EMPTY_OBJECT } from "@file/xml-components";
|
|||||||
import { IViewWrapper } from "../document-wrapper";
|
import { IViewWrapper } from "../document-wrapper";
|
||||||
import { File } from "../file";
|
import { File } from "../file";
|
||||||
import { ShadingType } from "../shading";
|
import { ShadingType } from "../shading";
|
||||||
import { HorizontalPositionAlign, VerticalPositionAlign } from "../shared";
|
|
||||||
import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting";
|
import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting";
|
||||||
import { FrameAnchorType } from "./frame";
|
import { FrameAnchorType } from "./frame";
|
||||||
import { Bookmark, ExternalHyperlink } from "./links";
|
import { Bookmark, ExternalHyperlink } from "./links";
|
||||||
@ -25,6 +25,7 @@ describe("Paragraph", () => {
|
|||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
(convenienceFunctions.uniqueId as SinonStub).restore();
|
(convenienceFunctions.uniqueId as SinonStub).restore();
|
||||||
|
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -953,6 +954,7 @@ describe("Paragraph", () => {
|
|||||||
paragraph.prepForXml({
|
paragraph.prepForXml({
|
||||||
viewWrapper: viewWrapperMock,
|
viewWrapper: viewWrapperMock,
|
||||||
file: file,
|
file: file,
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
const tree = new Formatter().format(paragraph);
|
const tree = new Formatter().format(paragraph);
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// http://officeopenxml.com/WPparagraph.php
|
// http://officeopenxml.com/WPparagraph.php
|
||||||
import { FootnoteReferenceRun } from "@file/footnotes";
|
import { FootnoteReferenceRun } from "@file/footnotes";
|
||||||
import { IContext, IXmlableObject, XmlComponent } from "@file/xml-components";
|
import { IContext, IXmlableObject } from "@file/xml-components";
|
||||||
import { uniqueId } from "@util/convenience-functions";
|
import { uniqueId } from "@util/convenience-functions";
|
||||||
|
import { FileChild } from "@file/file-child";
|
||||||
|
|
||||||
import { TargetModeType } from "../relationships/relationship/relationship";
|
import { TargetModeType } from "../relationships/relationship/relationship";
|
||||||
import { DeletedTextRun, InsertedTextRun } from "../track-revision";
|
import { DeletedTextRun, InsertedTextRun } from "../track-revision";
|
||||||
@ -9,8 +10,10 @@ import { ColumnBreak, PageBreak } from "./formatting/break";
|
|||||||
import { Bookmark, ConcreteHyperlink, ExternalHyperlink, InternalHyperlink } from "./links";
|
import { Bookmark, ConcreteHyperlink, ExternalHyperlink, InternalHyperlink } from "./links";
|
||||||
import { Math } from "./math";
|
import { Math } from "./math";
|
||||||
import { IParagraphPropertiesOptions, ParagraphProperties } from "./properties";
|
import { IParagraphPropertiesOptions, ParagraphProperties } from "./properties";
|
||||||
import { ImageRun, Run, SequentialIdentifier, SimpleField, SimpleMailMergeField, SymbolRun, TextRun } from "./run";
|
import { ImageRun, PageNumber, Run, SequentialIdentifier, SimpleField, SimpleMailMergeField, SymbolRun, TextRun } from "./run";
|
||||||
import { Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments } from "./run/comment-run";
|
import { Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments } from "./run/comment-run";
|
||||||
|
import { Begin, End, Separate } from "./run/field";
|
||||||
|
import { NumberOfPages, NumberOfPagesSection, Page } from "./run/page-number";
|
||||||
|
|
||||||
export type ParagraphChild =
|
export type ParagraphChild =
|
||||||
| TextRun
|
| TextRun
|
||||||
@ -32,14 +35,15 @@ export type ParagraphChild =
|
|||||||
| Comment
|
| Comment
|
||||||
| CommentRangeStart
|
| CommentRangeStart
|
||||||
| CommentRangeEnd
|
| CommentRangeEnd
|
||||||
| CommentReference;
|
| CommentReference
|
||||||
|
| PageNumber;
|
||||||
|
|
||||||
export interface IParagraphOptions extends IParagraphPropertiesOptions {
|
export interface IParagraphOptions extends IParagraphPropertiesOptions {
|
||||||
readonly text?: string;
|
readonly text?: string;
|
||||||
readonly children?: readonly ParagraphChild[];
|
readonly children?: readonly ParagraphChild[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Paragraph extends XmlComponent {
|
export class Paragraph extends FileChild {
|
||||||
private readonly properties: ParagraphProperties;
|
private readonly properties: ParagraphProperties;
|
||||||
|
|
||||||
public constructor(options: string | IParagraphOptions) {
|
public constructor(options: string | IParagraphOptions) {
|
||||||
@ -62,6 +66,34 @@ export class Paragraph extends XmlComponent {
|
|||||||
|
|
||||||
if (options.children) {
|
if (options.children) {
|
||||||
for (const child of options.children) {
|
for (const child of options.children) {
|
||||||
|
if (typeof child === "string") {
|
||||||
|
switch (child) {
|
||||||
|
case PageNumber.CURRENT:
|
||||||
|
this.root.push(new TextRun({ children: [new Begin()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new Page()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new Separate()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new End()] }));
|
||||||
|
break;
|
||||||
|
case PageNumber.TOTAL_PAGES:
|
||||||
|
this.root.push(new TextRun({ children: [new Begin()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new NumberOfPages()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new Separate()] }));
|
||||||
|
this.root.push(new TextRun("0"));
|
||||||
|
this.root.push(new TextRun({ children: [new End()] }));
|
||||||
|
break;
|
||||||
|
case PageNumber.TOTAL_PAGES_IN_SECTION:
|
||||||
|
this.root.push(new TextRun({ children: [new Begin()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new NumberOfPagesSection()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new Separate()] }));
|
||||||
|
this.root.push(new TextRun({ children: [new End()] }));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.root.push(new TextRun(child));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (child instanceof Bookmark) {
|
if (child instanceof Bookmark) {
|
||||||
this.root.push(child.start);
|
this.root.push(child.start);
|
||||||
for (const textRun of child.children) {
|
for (const textRun of child.children) {
|
||||||
|
@ -31,6 +31,7 @@ describe("ParagraphProperties", () => {
|
|||||||
} as File,
|
} as File,
|
||||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||||
viewWrapper: new DocumentWrapper({ background: {} }),
|
viewWrapper: new DocumentWrapper({ background: {} }),
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
@ -123,5 +124,24 @@ describe("ParagraphProperties", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should create with the wordWrap property", () => {
|
||||||
|
const properties = new ParagraphProperties({
|
||||||
|
wordWrap: true,
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(properties);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:pPr": [
|
||||||
|
{
|
||||||
|
"w:wordWrap": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,8 +9,9 @@ import { PageBreakBefore } from "./formatting/break";
|
|||||||
import { IIndentAttributesProperties, Indent } from "./formatting/indent";
|
import { IIndentAttributesProperties, Indent } from "./formatting/indent";
|
||||||
import { ISpacingProperties, Spacing } from "./formatting/spacing";
|
import { ISpacingProperties, Spacing } from "./formatting/spacing";
|
||||||
import { HeadingLevel, Style } from "./formatting/style";
|
import { HeadingLevel, Style } from "./formatting/style";
|
||||||
import { LeaderType, TabStop, TabStopPosition, TabStopType } from "./formatting/tab-stop";
|
import { TabStop, TabStopDefinition, TabStopType } from "./formatting/tab-stop";
|
||||||
import { NumberProperties } from "./formatting/unordered-list";
|
import { NumberProperties } from "./formatting/unordered-list";
|
||||||
|
import { WordWrap } from "./formatting/word-wrap";
|
||||||
import { FrameProperties, IFrameOptions } from "./frame/frame-properties";
|
import { FrameProperties, IFrameOptions } from "./frame/frame-properties";
|
||||||
import { OutlineLevel } from "./links";
|
import { OutlineLevel } from "./links";
|
||||||
|
|
||||||
@ -41,11 +42,7 @@ export interface IParagraphPropertiesOptions extends IParagraphStylePropertiesOp
|
|||||||
readonly heading?: HeadingLevel;
|
readonly heading?: HeadingLevel;
|
||||||
readonly bidirectional?: boolean;
|
readonly bidirectional?: boolean;
|
||||||
readonly pageBreakBefore?: boolean;
|
readonly pageBreakBefore?: boolean;
|
||||||
readonly tabStops?: readonly {
|
readonly tabStops?: readonly TabStopDefinition[];
|
||||||
readonly position: number | TabStopPosition;
|
|
||||||
readonly type: TabStopType;
|
|
||||||
readonly leader?: LeaderType;
|
|
||||||
}[];
|
|
||||||
readonly style?: string;
|
readonly style?: string;
|
||||||
readonly bullet?: {
|
readonly bullet?: {
|
||||||
readonly level: number;
|
readonly level: number;
|
||||||
@ -54,6 +51,8 @@ export interface IParagraphPropertiesOptions extends IParagraphStylePropertiesOp
|
|||||||
readonly widowControl?: boolean;
|
readonly widowControl?: boolean;
|
||||||
readonly frame?: IFrameOptions;
|
readonly frame?: IFrameOptions;
|
||||||
readonly suppressLineNumbers?: boolean;
|
readonly suppressLineNumbers?: boolean;
|
||||||
|
readonly wordWrap?: boolean;
|
||||||
|
readonly scale?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
|
export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
|
||||||
@ -132,19 +131,26 @@ export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
|
|||||||
this.push(new Shading(options.shading));
|
this.push(new Shading(options.shading));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rightTabStop) {
|
if (options.wordWrap) {
|
||||||
this.push(new TabStop(TabStopType.RIGHT, options.rightTabStop));
|
this.push(new WordWrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.tabStops) {
|
/**
|
||||||
for (const tabStop of options.tabStops) {
|
* FIX: Multitab support for Libre Writer
|
||||||
this.push(new TabStop(tabStop.type, tabStop.position, tabStop.leader));
|
* Ensure there is only one w:tabs tag with multiple w:tab
|
||||||
}
|
*/
|
||||||
}
|
const tabDefinitions: readonly TabStopDefinition[] = [
|
||||||
|
...(options.rightTabStop ? [{ type: TabStopType.RIGHT, position: options.rightTabStop }] : []),
|
||||||
|
...(options.tabStops ? options.tabStops : []),
|
||||||
|
...(options.leftTabStop ? [{ type: TabStopType.LEFT, position: options.leftTabStop }] : []),
|
||||||
|
];
|
||||||
|
|
||||||
if (options.leftTabStop) {
|
if (tabDefinitions.length > 0) {
|
||||||
this.push(new TabStop(TabStopType.LEFT, options.leftTabStop));
|
this.push(new TabStop(tabDefinitions));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* FIX - END
|
||||||
|
*/
|
||||||
|
|
||||||
if (options.bidirectional !== undefined) {
|
if (options.bidirectional !== undefined) {
|
||||||
this.push(new OnOffElement("w:bidi", options.bidirectional));
|
this.push(new OnOffElement("w:bidi", options.bidirectional));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
import { Formatter } from "@export/formatter";
|
import { Formatter } from "@export/formatter";
|
||||||
import { Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments } from "./comment-run";
|
import { Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments } from "./comment-run";
|
||||||
@ -40,12 +41,54 @@ describe("CommentReference", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("Comment", () => {
|
describe("Comment", () => {
|
||||||
|
let clock: sinon.SinonFakeTimers;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const now = new Date("1999-01-01T00:00:00.000Z");
|
||||||
|
clock = sinon.useFakeTimers(now.getTime());
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
it("should create", () => {
|
it("should create", () => {
|
||||||
const component = new Comment({
|
const component = new Comment({
|
||||||
id: 0,
|
id: 0,
|
||||||
text: "test-comment",
|
text: "test-comment",
|
||||||
date: new Date(1999, 0, 1),
|
date: new Date("1999-01-01T00:00:00.000Z"),
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(component);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:comment": [
|
||||||
|
{ _attr: { "w:id": 0, "w:date": "1999-01-01T00:00:00.000Z" } },
|
||||||
|
{
|
||||||
|
"w:p": [
|
||||||
|
{
|
||||||
|
"w:r": [
|
||||||
|
{
|
||||||
|
"w:t": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xml:space": "preserve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"test-comment",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create by using default date", () => {
|
||||||
|
const component = new Comment({
|
||||||
|
id: 0,
|
||||||
|
text: "test-comment",
|
||||||
});
|
});
|
||||||
const tree = new Formatter().format(component);
|
const tree = new Formatter().format(component);
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
@ -83,12 +126,12 @@ describe("Comments", () => {
|
|||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
text: "test-comment",
|
text: "test-comment",
|
||||||
date: new Date(1999, 0, 1),
|
date: new Date("1999-01-01T00:00:00.000Z"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
text: "test-comment-2",
|
text: "test-comment-2",
|
||||||
date: new Date(1999, 0, 1),
|
date: new Date("1999-01-01T00:00:00.000Z"),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
229
src/file/paragraph/run/empty-children.spec.ts
Normal file
229
src/file/paragraph/run/empty-children.spec.ts
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
import {
|
||||||
|
AnnotationReference,
|
||||||
|
CarriageReturn,
|
||||||
|
ContinuationSeparator,
|
||||||
|
DayLong,
|
||||||
|
DayShort,
|
||||||
|
EndnoteReference,
|
||||||
|
FootnoteReferenceElement,
|
||||||
|
LastRenderedPageBreak,
|
||||||
|
MonthLong,
|
||||||
|
MonthShort,
|
||||||
|
NoBreakHyphen,
|
||||||
|
PageNumberElement,
|
||||||
|
Separator,
|
||||||
|
SoftHyphen,
|
||||||
|
Tab,
|
||||||
|
YearLong,
|
||||||
|
YearShort,
|
||||||
|
} from "./empty-children";
|
||||||
|
|
||||||
|
// <xsd:element name="noBreakHyphen" type="CT_Empty"/>
|
||||||
|
// <xsd:element name="softHyphen" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="dayShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="monthShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="yearShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="dayLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="monthLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="yearLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="annotationRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="footnoteRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="endnoteRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="separator" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="continuationSeparator" type="CT_Empty" minOccurs="0" />
|
||||||
|
// ...
|
||||||
|
// <xsd:element name="pgNum" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="cr" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="tab" type="CT_Empty" minOccurs="0" />
|
||||||
|
// ...
|
||||||
|
// <xsd:element name="lastRenderedPageBreak" type="CT_Empty" minOccurs="0" maxOccurs="1" />
|
||||||
|
|
||||||
|
describe("NoBreakHyphen", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a NoBreakHyphen with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new NoBreakHyphen());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:noBreakHyphen": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("SoftHyphen", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a SoftHyphen with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new SoftHyphen());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:softHyphen": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("DayShort", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a DayShort with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new DayShort());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:dayShort": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("MonthShort", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a MonthShort with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new MonthShort());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:monthShort": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("YearShort", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a YearShort with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new YearShort());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:yearShort": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("DayLong", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a DayLong with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new DayLong());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:dayLong": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("MonthLong", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a MonthLong with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new MonthLong());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:monthLong": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("YearLong", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a YearLong with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new YearLong());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:yearLong": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("AnnotationReference", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a AnnotationReference with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new AnnotationReference());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:annotationRef": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("FootnoteReferenceElement", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a FootnoteReferenceElement with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new FootnoteReferenceElement());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:footnoteRef": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("EndnoteReference", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a EndnoteReference with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new EndnoteReference());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:endnoteRef": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Separator", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a Separator with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new Separator());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:separator": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("ContinuationSeparator", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a ContinuationSeparator with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new ContinuationSeparator());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:continuationSeparator": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("PageNumberElement", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a PageNumberElement with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new PageNumberElement());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:pgNum": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("CarriageReturn", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a CarriageReturn with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new CarriageReturn());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:cr": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Tab", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a Tab with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new Tab());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:tab": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("LastRenderedPageBreak", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a LastRenderedPageBreak with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(new LastRenderedPageBreak());
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:lastRenderedPageBreak": {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
127
src/file/paragraph/run/empty-children.ts
Normal file
127
src/file/paragraph/run/empty-children.ts
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import { EmptyElement } from "@file/xml-components";
|
||||||
|
|
||||||
|
// <xsd:group name="EG_RunInnerContent">
|
||||||
|
// ...
|
||||||
|
// <xsd:element name="noBreakHyphen" type="CT_Empty"/>
|
||||||
|
// <xsd:element name="softHyphen" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="dayShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="monthShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="yearShort" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="dayLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="monthLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="yearLong" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="annotationRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="footnoteRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="endnoteRef" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="separator" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="continuationSeparator" type="CT_Empty" minOccurs="0" />
|
||||||
|
// ...
|
||||||
|
// <xsd:element name="pgNum" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="cr" type="CT_Empty" minOccurs="0" />
|
||||||
|
// <xsd:element name="tab" type="CT_Empty" minOccurs="0" />
|
||||||
|
// ...
|
||||||
|
// <xsd:element name="lastRenderedPageBreak" type="CT_Empty" minOccurs="0" maxOccurs="1" />
|
||||||
|
// </xsd:choice>
|
||||||
|
// </xsd:group>
|
||||||
|
|
||||||
|
export class NoBreakHyphen extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:noBreakHyphen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SoftHyphen extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:softHyphen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DayShort extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:dayShort");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MonthShort extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:monthShort");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class YearShort extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:yearShort");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DayLong extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:dayLong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MonthLong extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:monthLong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class YearLong extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:yearLong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AnnotationReference extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:annotationRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FootnoteReferenceElement extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:footnoteRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class EndnoteReference extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:endnoteRef");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Separator extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:separator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ContinuationSeparator extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:continuationSeparator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PageNumberElement extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:pgNum");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CarriageReturn extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:cr");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Tab extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:tab");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LastRenderedPageBreak extends EmptyElement {
|
||||||
|
public constructor() {
|
||||||
|
super("w:lastRenderedPageBreak");
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,29 @@
|
|||||||
|
// http://www.datypic.com/sc/ooxml/e-w_fldChar-1.html
|
||||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
// <xsd:complexType name="CT_FldChar">
|
||||||
|
// <xsd:choice>
|
||||||
|
// <xsd:element name="fldData" type="CT_Text" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <xsd:element name="ffData" type="CT_FFData" minOccurs="0" maxOccurs="1" />
|
||||||
|
// <xsd:element name="numberingChange" type="CT_TrackChangeNumbering" minOccurs="0" />
|
||||||
|
// </xsd:choice>
|
||||||
|
// <xsd:attribute name="fldCharType" type="ST_FldCharType" use="required" />
|
||||||
|
// <xsd:attribute name="fldLock" type="s:ST_OnOff" />
|
||||||
|
// <xsd:attribute name="dirty" type="s:ST_OnOff" />
|
||||||
|
// </xsd:complexType>
|
||||||
|
|
||||||
enum FieldCharacterType {
|
enum FieldCharacterType {
|
||||||
BEGIN = "begin",
|
BEGIN = "begin",
|
||||||
END = "end",
|
END = "end",
|
||||||
SEPARATE = "separate",
|
SEPARATE = "separate",
|
||||||
}
|
}
|
||||||
|
|
||||||
class FidCharAttrs extends XmlAttributeComponent<{ readonly type: FieldCharacterType; readonly dirty?: boolean }> {
|
class FidCharAttrs extends XmlAttributeComponent<{
|
||||||
protected readonly xmlKeys = { type: "w:fldCharType", dirty: "w:dirty" };
|
readonly type: FieldCharacterType;
|
||||||
|
readonly dirty?: boolean;
|
||||||
|
readonly fieldLock?: boolean;
|
||||||
|
}> {
|
||||||
|
protected readonly xmlKeys = { type: "w:fldCharType", dirty: "w:dirty", fieldLock: "w:fldLock" };
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Begin extends XmlComponent {
|
export class Begin extends XmlComponent {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Attributes, XmlComponent } from "@file/xml-components";
|
import { Attributes, XmlComponent } from "@file/xml-components";
|
||||||
import { hexColorValue, signedTwipsMeasureValue } from "@util/values";
|
import { hexColorValue, signedTwipsMeasureValue, UniversalMeasure } from "@util/values";
|
||||||
|
|
||||||
export class CharacterSpacing extends XmlComponent {
|
export class CharacterSpacing extends XmlComponent {
|
||||||
public constructor(value: number | string) {
|
public constructor(value: number | UniversalMeasure) {
|
||||||
super("w:spacing");
|
super("w:spacing");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new Attributes({
|
new Attributes({
|
||||||
|
@ -11,10 +11,12 @@ import { ImageRun } from "./image-run";
|
|||||||
describe("ImageRun", () => {
|
describe("ImageRun", () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
stub(convenienceFunctions, "uniqueId").callsFake(() => "test-unique-id");
|
stub(convenienceFunctions, "uniqueId").callsFake(() => "test-unique-id");
|
||||||
|
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
(convenienceFunctions.uniqueId as SinonStub).restore();
|
(convenienceFunctions.uniqueId as SinonStub).restore();
|
||||||
|
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -45,6 +47,7 @@ describe("ImageRun", () => {
|
|||||||
},
|
},
|
||||||
} as unknown as File,
|
} as unknown as File,
|
||||||
viewWrapper: {} as unknown as IViewWrapper,
|
viewWrapper: {} as unknown as IViewWrapper,
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
"w:r": [
|
"w:r": [
|
||||||
@ -125,6 +128,7 @@ describe("ImageRun", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -295,6 +299,7 @@ describe("ImageRun", () => {
|
|||||||
},
|
},
|
||||||
} as unknown as File,
|
} as unknown as File,
|
||||||
viewWrapper: {} as unknown as IViewWrapper,
|
viewWrapper: {} as unknown as IViewWrapper,
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
"w:r": [
|
"w:r": [
|
||||||
@ -375,6 +380,7 @@ describe("ImageRun", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -548,6 +554,7 @@ describe("ImageRun", () => {
|
|||||||
},
|
},
|
||||||
} as unknown as File,
|
} as unknown as File,
|
||||||
viewWrapper: {} as unknown as IViewWrapper,
|
viewWrapper: {} as unknown as IViewWrapper,
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
@ -629,6 +636,7 @@ describe("ImageRun", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -805,6 +813,7 @@ describe("ImageRun", () => {
|
|||||||
},
|
},
|
||||||
} as unknown as File,
|
} as unknown as File,
|
||||||
viewWrapper: {} as unknown as IViewWrapper,
|
viewWrapper: {} as unknown as IViewWrapper,
|
||||||
|
stack: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
@ -886,6 +895,7 @@ describe("ImageRun", () => {
|
|||||||
descr: "",
|
descr: "",
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "",
|
name: "",
|
||||||
|
title: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { uniqueId } from "@util/convenience-functions";
|
import { uniqueId } from "@util/convenience-functions";
|
||||||
|
|
||||||
import { IContext, IXmlableObject } from "@file/xml-components";
|
import { IContext, IXmlableObject } from "@file/xml-components";
|
||||||
|
import { DocPropertiesOptions } from "@file/drawing/doc-properties/doc-properties";
|
||||||
|
|
||||||
import { Drawing, IFloating } from "../../drawing";
|
import { Drawing, IFloating } from "../../drawing";
|
||||||
import { IMediaTransformation } from "../../media";
|
import { IMediaTransformation } from "../../media";
|
||||||
@ -11,6 +12,7 @@ export interface IImageOptions {
|
|||||||
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
||||||
readonly transformation: IMediaTransformation;
|
readonly transformation: IMediaTransformation;
|
||||||
readonly floating?: IFloating;
|
readonly floating?: IFloating;
|
||||||
|
readonly altText?: DocPropertiesOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ImageRun extends Run {
|
export class ImageRun extends Run {
|
||||||
@ -37,7 +39,7 @@ export class ImageRun extends Run {
|
|||||||
rotation: options.transformation.rotation ? options.transformation.rotation * 60000 : undefined,
|
rotation: options.transformation.rotation ? options.transformation.rotation * 60000 : undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const drawing = new Drawing(this.imageData, { floating: options.floating });
|
const drawing = new Drawing(this.imageData, { floating: options.floating, docProperties: options.altText });
|
||||||
|
|
||||||
this.root.push(drawing);
|
this.root.push(drawing);
|
||||||
}
|
}
|
||||||
@ -49,15 +51,16 @@ export class ImageRun extends Run {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private convertDataURIToBinary(dataURI: string): Uint8Array {
|
private convertDataURIToBinary(dataURI: string): Uint8Array {
|
||||||
|
if (typeof atob === "function") {
|
||||||
// https://gist.github.com/borismus/1032746
|
// https://gist.github.com/borismus/1032746
|
||||||
// https://github.com/mafintosh/base64-to-uint8array
|
// https://github.com/mafintosh/base64-to-uint8array
|
||||||
const BASE64_MARKER = ";base64,";
|
const BASE64_MARKER = ";base64,";
|
||||||
|
const base64Index = dataURI.indexOf(BASE64_MARKER);
|
||||||
|
|
||||||
const base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
|
const base64IndexWithOffset = base64Index === -1 ? 0 : base64Index + BASE64_MARKER.length;
|
||||||
|
|
||||||
if (typeof atob === "function") {
|
|
||||||
return new Uint8Array(
|
return new Uint8Array(
|
||||||
atob(dataURI.substring(base64Index))
|
atob(dataURI.substring(base64IndexWithOffset))
|
||||||
.split("")
|
.split("")
|
||||||
.map((c) => c.charCodeAt(0)),
|
.map((c) => c.charCodeAt(0)),
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,7 @@ export * from "./run-fonts";
|
|||||||
export * from "./sequential-identifier";
|
export * from "./sequential-identifier";
|
||||||
export * from "./underline";
|
export * from "./underline";
|
||||||
export * from "./emphasis-mark";
|
export * from "./emphasis-mark";
|
||||||
export * from "./tab";
|
|
||||||
export * from "./simple-field";
|
export * from "./simple-field";
|
||||||
export * from "./comment-run";
|
export * from "./comment-run";
|
||||||
|
export * from "./empty-children";
|
||||||
|
export * from "./positional-tab";
|
||||||
|
29
src/file/paragraph/run/language.spec.ts
Normal file
29
src/file/paragraph/run/language.spec.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
|
||||||
|
import { createLanguageComponent } from "./language";
|
||||||
|
|
||||||
|
describe("Language", () => {
|
||||||
|
describe("#createLanguageComponent", () => {
|
||||||
|
it("should create a language component", () => {
|
||||||
|
const tree = new Formatter().format(
|
||||||
|
createLanguageComponent({
|
||||||
|
value: "en-US",
|
||||||
|
eastAsia: "zh-CN",
|
||||||
|
bidirectional: "ar-SA",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:lang": {
|
||||||
|
_attr: {
|
||||||
|
"w:bidi": "ar-SA",
|
||||||
|
"w:eastAsia": "zh-CN",
|
||||||
|
"w:val": "en-US",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
35
src/file/paragraph/run/language.ts
Normal file
35
src/file/paragraph/run/language.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { BuilderElement, XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
|
// <xsd:complexType name="CT_Language">
|
||||||
|
// <xsd:attribute name="val" type="s:ST_Lang" use="optional"/>
|
||||||
|
// <xsd:attribute name="eastAsia" type="s:ST_Lang" use="optional"/>
|
||||||
|
// <xsd:attribute name="bidi" type="s:ST_Lang" use="optional"/>
|
||||||
|
// </xsd:complexType>
|
||||||
|
export interface ILanguageOptions {
|
||||||
|
readonly value?: string;
|
||||||
|
readonly eastAsia?: string;
|
||||||
|
readonly bidirectional?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createLanguageComponent = (options: ILanguageOptions): XmlComponent =>
|
||||||
|
new BuilderElement<{
|
||||||
|
readonly value?: string;
|
||||||
|
readonly eastAsia?: string;
|
||||||
|
readonly bidirectional?: string;
|
||||||
|
}>({
|
||||||
|
name: "w:lang",
|
||||||
|
attributes: {
|
||||||
|
value: {
|
||||||
|
key: "w:val",
|
||||||
|
value: options.value,
|
||||||
|
},
|
||||||
|
eastAsia: {
|
||||||
|
key: "w:eastAsia",
|
||||||
|
value: options.eastAsia,
|
||||||
|
},
|
||||||
|
bidirectional: {
|
||||||
|
key: "w:bidi",
|
||||||
|
value: options.bidirectional,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
@ -1,4 +1,4 @@
|
|||||||
import { SpaceType } from "@file/space-type";
|
import { SpaceType } from "@file/shared";
|
||||||
import { XmlComponent } from "@file/xml-components";
|
import { XmlComponent } from "@file/xml-components";
|
||||||
|
|
||||||
import { TextAttributes } from "./text-attributes";
|
import { TextAttributes } from "./text-attributes";
|
||||||
|
27
src/file/paragraph/run/positional-tab.spec.ts
Normal file
27
src/file/paragraph/run/positional-tab.spec.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "@export/formatter";
|
||||||
|
|
||||||
|
import { PositionalTab, PositionalTabAlignment, PositionalTabLeader, PositionalTabRelativeTo } from "./positional-tab";
|
||||||
|
|
||||||
|
describe("PositionalTab", () => {
|
||||||
|
it("should create a PositionalTab with correct root key", () => {
|
||||||
|
const tree = new Formatter().format(
|
||||||
|
new PositionalTab({
|
||||||
|
alignment: PositionalTabAlignment.CENTER,
|
||||||
|
relativeTo: PositionalTabRelativeTo.MARGIN,
|
||||||
|
leader: PositionalTabLeader.DOT,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:ptab": {
|
||||||
|
_attr: {
|
||||||
|
"w:alignment": "center",
|
||||||
|
"w:relativeTo": "margin",
|
||||||
|
"w:leader": "dot",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user