Compare commits
291 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
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 | |||
0e818c8d73 | |||
791441ec86 | |||
401de9147c | |||
563e10fa92 | |||
a22c34d8c2 | |||
e549f8ae61 | |||
0ac23d0646 | |||
814d3892f2 | |||
07d1306a35 | |||
5950055cca | |||
d6dd468e84 | |||
9a221a01ab | |||
2a78a29b08 | |||
e90d97b813 | |||
d020d59b11 | |||
5d6d52a465 | |||
ebb3f8137e | |||
af7d275c27 | |||
2b01a6006c | |||
9f3940746a | |||
9f729b3bb3 | |||
2376fb5834 | |||
0a1507599b | |||
42bb01c416 | |||
cfb0ae7428 | |||
6b30f44da0 | |||
a7f89ac58f | |||
38711f04bc | |||
78fd99c26e | |||
cae10d4611 | |||
40233dbf87 | |||
35865e46f0 | |||
ea565d8f71 | |||
859a3f4015 | |||
ebcb37cbed | |||
1bdf9a4987 | |||
d7a9cb2168 | |||
8890e13ccb | |||
87e1844f04 | |||
388030c6ec | |||
d5bd407802 | |||
ba4dc2ed54 | |||
c982e64996 | |||
0425939668 | |||
48b804b765 | |||
246ae6e6bc | |||
efa5b65e45 | |||
f4f6ee5055 | |||
1a630bcb4d | |||
600fef21f6 | |||
b779ee79a5 | |||
08537944ae | |||
004b3641eb | |||
b6be05a931 | |||
191cc071c2 | |||
9e52c46ad3 | |||
21f7662a77 | |||
d4d7f92df8 | |||
a3180fd70d | |||
3dc4f8e87a | |||
64393d92a5 | |||
1fbd405e41 | |||
f711aa1b58 | |||
e2e527ce44 | |||
bb7f48c021 | |||
ad9b64e7ae | |||
ef2ee6d00d | |||
2d259c4edc | |||
b286e3ae09 | |||
ec3e193672 | |||
40a2fcd81e | |||
7e876bad7e | |||
aefa3b102c | |||
4d1f295a26 | |||
56a31faf7e | |||
f3afef01b0 | |||
ea38655c48 | |||
972d06b492 | |||
8538489136 | |||
4f28464b99 | |||
049e111797 | |||
96199c4b12 | |||
cf23789edf | |||
48724e5b08 | |||
40c778d244 | |||
ff0c44ecfc | |||
828cc15ea3 | |||
bbbe55b706 | |||
cd98bdec9b | |||
59767bddfe | |||
035ae40b97 | |||
f7603bfdfc | |||
754201a9a2 | |||
d0af7e4781 | |||
ecf0bf8cdd | |||
85bafb3eef | |||
efe378e94f | |||
614cb74d47 | |||
df4190321e | |||
56c3574a2b | |||
51b11c7035 | |||
564693cf22 | |||
50a6bed92f | |||
ef54b3cf2e | |||
ebf06250b1 | |||
56f9c22ac6 | |||
384242974b | |||
7717d95cab | |||
5b69a32c11 | |||
24abf51c8c | |||
80c5092dc1 | |||
15ffa4d98b | |||
4935878f73 | |||
440782e9cf | |||
f304220463 | |||
02a5aaf5d8 | |||
e84641c13c | |||
278b6b6a20 | |||
d369c0a74c | |||
ab9f97598c | |||
2814841226 | |||
a7d55a52f3 | |||
d436b7b339 | |||
f183d38bb3 | |||
2353b36709 | |||
00db6e7dc1 | |||
eb479c4684 | |||
68413605e9 | |||
02bd5d71d0 | |||
97a851a848 | |||
f503794e09 | |||
d0ee5fa23a | |||
0ccf0f8d7a | |||
719f7c8f9e | |||
828e30a248 | |||
6beb7208af | |||
2d342a2415 | |||
a2017fc353 | |||
709c3d9b55 | |||
950867d032 | |||
65caa531c5 | |||
64addc85ee | |||
aa02261248 | |||
6d447033c9 | |||
c888f589d0 | |||
4697d774f4 |
58
.cspell.json
Normal file
58
.cspell.json
Normal file
@ -0,0 +1,58 @@
|
||||
// cSpell Settings
|
||||
{
|
||||
// Version of the setting file. Always 0.2
|
||||
"version": "0.2",
|
||||
// language - current active spelling language
|
||||
"language": "en_US",
|
||||
"dictionaries": ["en_US", "typescript", "softwareTerms", "fonts", "npm"],
|
||||
// words - list of words to be always considered correct
|
||||
"words": [
|
||||
"Xmlable",
|
||||
"twip",
|
||||
"twips",
|
||||
"jsonify",
|
||||
"falsey",
|
||||
"aiueo",
|
||||
"iroha",
|
||||
"aiueo",
|
||||
"iroha",
|
||||
"chosung",
|
||||
"Abjad",
|
||||
"Initializable",
|
||||
"rels",
|
||||
"dolan",
|
||||
"xmlify",
|
||||
"Xmlifyed",
|
||||
"xmlified",
|
||||
"datas",
|
||||
"jszip",
|
||||
"rsid",
|
||||
"NUMPAGES",
|
||||
"ATLEAST",
|
||||
"ooxml",
|
||||
"clippy",
|
||||
"docsify"
|
||||
],
|
||||
"ignoreRegExpList": [
|
||||
"/\"w:.+\"/",
|
||||
"/\"s:.+\"/",
|
||||
"/\"a:.+\"/",
|
||||
"/\"pic:.+\"/",
|
||||
"/\"xmlns:.+\"/",
|
||||
"/\"vt:.+\"/",
|
||||
"/[^\\s]{40,}/",
|
||||
"/<xsd:.+/>/",
|
||||
"/[A-Z_]+ = \".+\"/",
|
||||
"/XmlAttributeComponent<{[^}]+}>/g",
|
||||
"/xmlKeys = {[^}]+}/g",
|
||||
"/\\.to\\.deep\\.equal\\({[^)]+}\\)/g",
|
||||
"\\.to\\.include\\.members\\(\\[[^\\]]+]\\)",
|
||||
"/new [a-zA-Z]+\\({[^£]+}\\)/g"
|
||||
],
|
||||
"ignorePaths": ["package.json", "docs/api"],
|
||||
"allowCompoundWords": true,
|
||||
// flagWords - list of words to be always considered incorrect
|
||||
// This is useful for offensive words and common spelling errors.
|
||||
// For example "hte" should be "the"
|
||||
"flagWords": ["hte"]
|
||||
}
|
270
.eslintrc.js
Normal file
270
.eslintrc.js
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
|
||||
https://github.com/typescript-eslint/tslint-to-eslint-config
|
||||
|
||||
It represents the closest reasonable ESLint configuration to this
|
||||
project's original TSLint configuration.
|
||||
|
||||
We recommend eventually switching this configuration to extend from
|
||||
the recommended rulesets in typescript-eslint.
|
||||
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
|
||||
|
||||
Happy linting! 💖
|
||||
*/
|
||||
module.exports = {
|
||||
extends: "eslint:recommended",
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: "tsconfig.json",
|
||||
sourceType: "module",
|
||||
},
|
||||
plugins: [
|
||||
"eslint-plugin-import",
|
||||
"eslint-plugin-no-null",
|
||||
"eslint-plugin-unicorn",
|
||||
"eslint-plugin-jsdoc",
|
||||
"eslint-plugin-prefer-arrow",
|
||||
"@typescript-eslint",
|
||||
"functional",
|
||||
],
|
||||
root: true,
|
||||
rules: {
|
||||
"no-undef": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
"no-alert": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-unreachable-loop": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-unused-private-class-members": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-floating-decimal": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-iterator": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-loop-func": "error",
|
||||
"no-new-object": "error",
|
||||
"no-proto": "error",
|
||||
"no-useless-catch": "error",
|
||||
"one-var-declaration-per-line": "error",
|
||||
"prefer-arrow-callback": "error",
|
||||
"prefer-destructuring": "error",
|
||||
"prefer-exponentiation-operator": "error",
|
||||
"prefer-promise-reject-errors": "error",
|
||||
"prefer-regex-literals": "error",
|
||||
"prefer-spread": "error",
|
||||
"prefer-template": "error",
|
||||
"require-await": "error",
|
||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||
"@typescript-eslint/array-type": [
|
||||
"error",
|
||||
{
|
||||
default: "array",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/ban-types": [
|
||||
"error",
|
||||
{
|
||||
types: {
|
||||
Object: {
|
||||
message: "Avoid using the `Object` type. Did you mean `object`?",
|
||||
},
|
||||
Function: {
|
||||
message: "Avoid using the `Function` type. Prefer a specific function type, like `() => void`.",
|
||||
},
|
||||
Boolean: {
|
||||
message: "Avoid using the `Boolean` type. Did you mean `boolean`?",
|
||||
},
|
||||
Number: {
|
||||
message: "Avoid using the `Number` type. Did you mean `number`?",
|
||||
},
|
||||
String: {
|
||||
message: "Avoid using the `String` type. Did you mean `string`?",
|
||||
},
|
||||
Symbol: {
|
||||
message: "Avoid using the `Symbol` type. Did you mean `symbol`?",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/consistent-type-assertions": "error",
|
||||
"@typescript-eslint/dot-notation": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: false,
|
||||
allowTypedFunctionExpressions: false,
|
||||
allowHigherOrderFunctions: false,
|
||||
allowDirectConstAssertionInArrowFunctions: true,
|
||||
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{
|
||||
accessibility: "explicit",
|
||||
overrides: {
|
||||
accessors: "explicit",
|
||||
},
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/explicit-module-boundary-types": [
|
||||
"error",
|
||||
{
|
||||
allowArgumentsExplicitlyTypedAsAny: true,
|
||||
allowDirectConstAssertionInArrowFunctions: true,
|
||||
allowHigherOrderFunctions: false,
|
||||
allowTypedFunctionExpressions: false,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"error",
|
||||
{
|
||||
selector: ["objectLiteralProperty"],
|
||||
leadingUnderscore: "allow",
|
||||
format: ["camelCase", "PascalCase"],
|
||||
filter: {
|
||||
regex: "(^[a-z]+:.+)|_attr|[0-9]",
|
||||
match: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-empty-function": "error",
|
||||
"@typescript-eslint/no-empty-interface": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-parameter-properties": "off",
|
||||
"@typescript-eslint/no-require-imports": "error",
|
||||
"@typescript-eslint/no-shadow": [
|
||||
"error",
|
||||
{
|
||||
hoist: "all",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-this-alias": "error",
|
||||
"@typescript-eslint/no-unused-expressions": "error",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/prefer-for-of": "error",
|
||||
"@typescript-eslint/prefer-function-type": "error",
|
||||
"@typescript-eslint/prefer-namespace-keyword": "error",
|
||||
"@typescript-eslint/prefer-readonly": "error",
|
||||
"@typescript-eslint/triple-slash-reference": [
|
||||
"error",
|
||||
{
|
||||
path: "always",
|
||||
types: "prefer-import",
|
||||
lib: "always",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/typedef": [
|
||||
"error",
|
||||
{
|
||||
parameter: true,
|
||||
propertyDeclaration: true,
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/unified-signatures": "error",
|
||||
"arrow-body-style": "error",
|
||||
complexity: "off",
|
||||
"consistent-return": "error",
|
||||
"constructor-super": "error",
|
||||
curly: "error",
|
||||
"dot-notation": "off",
|
||||
eqeqeq: ["error", "smart"],
|
||||
"guard-for-in": "error",
|
||||
"id-denylist": ["error", "any", "Number", "number", "String", "string", "Boolean", "boolean", "Undefined", "undefined"],
|
||||
"id-match": "error",
|
||||
"import/no-default-export": "error",
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"import/no-internal-modules": "off",
|
||||
"import/order": "error",
|
||||
indent: "off",
|
||||
"jsdoc/check-alignment": "error",
|
||||
"jsdoc/check-indentation": "off",
|
||||
"jsdoc/newline-after-description": "error",
|
||||
"max-classes-per-file": "off",
|
||||
"max-len": "off",
|
||||
"new-parens": "error",
|
||||
"no-bitwise": "error",
|
||||
"no-caller": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-console": "error",
|
||||
"no-debugger": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-empty": "error",
|
||||
"no-empty-function": "off",
|
||||
"no-eval": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-fallthrough": "off",
|
||||
"no-invalid-this": "off",
|
||||
"no-multiple-empty-lines": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-null/no-null": "error",
|
||||
"no-param-reassign": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-return-await": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-underscore-dangle": ["error", { allow: ["_attr"] }],
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unused-expressions": "off",
|
||||
"no-unused-labels": "error",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-constructor": "error",
|
||||
"no-var": "error",
|
||||
"object-shorthand": "off",
|
||||
"one-var": ["error", "never"],
|
||||
"prefer-arrow/prefer-arrow-functions": "error",
|
||||
"prefer-const": "error",
|
||||
"prefer-object-spread": "error",
|
||||
radix: "error",
|
||||
"space-in-parens": ["error", "never"],
|
||||
"spaced-comment": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
markers: ["/"],
|
||||
},
|
||||
],
|
||||
"unicorn/filename-case": "error",
|
||||
"unicorn/prefer-ternary": "error",
|
||||
"use-isnan": "error",
|
||||
"valid-typeof": "off",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"functional/immutable-data": [
|
||||
"error",
|
||||
{
|
||||
assumeTypes: true,
|
||||
ignoreImmediateMutation: true,
|
||||
ignoreAccessorPattern: ["**.root*", "**.numberingReferences*", "**.sections*", "**.properties*"],
|
||||
},
|
||||
],
|
||||
"functional/no-method-signature": "error",
|
||||
"functional/no-mixed-type": "error",
|
||||
"functional/prefer-readonly-type": "error",
|
||||
"no-unused-vars": ["error", { argsIgnorePattern: "^[_]+$" }],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.spec.ts"],
|
||||
rules: {
|
||||
"@typescript-eslint/no-unused-expressions": "off",
|
||||
"@typescript-eslint/dot-notation": "off",
|
||||
"prefer-destructuring": "off",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
10
.github/workflows/default.yml
vendored
10
.github/workflows/default.yml
vendored
@ -58,3 +58,13 @@ jobs:
|
||||
run: npm ci --force
|
||||
- name: Prettier
|
||||
run: npm run style
|
||||
cspell:
|
||||
name: CSpell
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Prettier
|
||||
run: npm run cspell
|
||||
|
27
.github/workflows/demos.yml
vendored
27
.github/workflows/demos.yml
vendored
@ -689,3 +689,30 @@ jobs:
|
||||
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/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
|
||||
|
8
.nycrc
8
.nycrc
@ -1,9 +1,9 @@
|
||||
{
|
||||
"check-coverage": true,
|
||||
"statements": 99.43,
|
||||
"branches": 96.6,
|
||||
"functions": 99.47,
|
||||
"lines": 99.43,
|
||||
"statements": 99.79,
|
||||
"branches": 98.41,
|
||||
"functions": 100,
|
||||
"lines": 99.73,
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
|
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["streetsidesoftware.code-spell-checker", "dbaeumer.vscode-eslint"]
|
||||
}
|
31
README.md
31
README.md
@ -26,21 +26,21 @@
|
||||
|
||||
Here are examples of `docx` being used with basic `HTML/JS` in a browser environment:
|
||||
|
||||
* https://codepen.io/dolanmiu/pen/RwNeObg
|
||||
* https://jsfiddle.net/dolanmiu/onadx1gu/
|
||||
- https://codepen.io/dolanmiu/pen/RwNeObg
|
||||
- https://jsfiddle.net/dolanmiu/onadx1gu/
|
||||
|
||||
Here is an example of `docx` working in `Angular`:
|
||||
|
||||
* https://stackblitz.com/edit/angular-docx
|
||||
- https://stackblitz.com/edit/angular-docx
|
||||
|
||||
Here is an example of `docx` working in `React`:
|
||||
|
||||
* https://stackblitz.com/edit/react-docx
|
||||
* https://stackblitz.com/edit/react-docx-images (adding images to Word Document)
|
||||
- https://stackblitz.com/edit/react-docx
|
||||
- https://stackblitz.com/edit/react-docx-images (adding images to Word Document)
|
||||
|
||||
Here is an example of `docx` working in `Vue.js`:
|
||||
|
||||
* https://stackblitz.com/edit/vuejs-docx
|
||||
- https://stackblitz.com/edit/vuejs-docx
|
||||
|
||||
## Node
|
||||
|
||||
@ -48,15 +48,15 @@ Press `endpoint` on the `RunKit` website:
|
||||
|
||||

|
||||
|
||||
* https://runkit.com/dolanmiu/docx-demo1 - Simple paragraph and text
|
||||
* https://runkit.com/dolanmiu/docx-demo2 - Advanced Paragraphs and text
|
||||
* https://runkit.com/dolanmiu/docx-demo3 - Bullet points
|
||||
* https://runkit.com/dolanmiu/docx-demo4 - Simple table
|
||||
* https://runkit.com/dolanmiu/docx-demo5 - Images
|
||||
* https://runkit.com/dolanmiu/docx-demo6 - Margins
|
||||
* https://runkit.com/dolanmiu/docx-demo7 - Landscape
|
||||
* https://runkit.com/dolanmiu/docx-demo8 - Header and Footer
|
||||
* https://runkit.com/dolanmiu/docx-demo10 - **My CV generated with docx**
|
||||
- https://runkit.com/dolanmiu/docx-demo1 - Simple paragraph and text
|
||||
- https://runkit.com/dolanmiu/docx-demo2 - Advanced Paragraphs and text
|
||||
- https://runkit.com/dolanmiu/docx-demo3 - Bullet points
|
||||
- https://runkit.com/dolanmiu/docx-demo4 - Simple table
|
||||
- https://runkit.com/dolanmiu/docx-demo5 - Images
|
||||
- https://runkit.com/dolanmiu/docx-demo6 - Margins
|
||||
- https://runkit.com/dolanmiu/docx-demo7 - Landscape
|
||||
- https://runkit.com/dolanmiu/docx-demo8 - Header and Footer
|
||||
- https://runkit.com/dolanmiu/docx-demo10 - **My CV generated with docx**
|
||||
|
||||
More [here](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||
|
||||
@ -88,7 +88,6 @@ Read the contribution guidelines [here](https://docx.js.org/#/contribution-guide
|
||||
[<img src="https://i.imgur.com/PXo25um.png" alt="drawing" height="50"/>](https://www.circadianrisk.com/)
|
||||
[<img src="https://i.imgur.com/AKGhtlh.png" alt="drawing"/>](https://lexense.com/)
|
||||
|
||||
|
||||
...and many more!
|
||||
|
||||
---
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Simple example to add text to a document
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
||||
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
@ -16,7 +16,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generate a CV
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
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
|
||||
|
||||
@ -43,7 +43,7 @@ interface Skill {
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
interface Achivement {
|
||||
interface Achievement {
|
||||
readonly issuer: string;
|
||||
readonly name: string;
|
||||
}
|
||||
@ -64,7 +64,7 @@ const experiences: Experience[] = [
|
||||
{
|
||||
isCurrent: false,
|
||||
summary:
|
||||
"Full-stack developer working with Angular, Node and TypeScript. Working for the iShares platform. Emphasis on Dev-ops and developing the continous integration pipeline.",
|
||||
"Full-stack developer working with Angular, Node and TypeScript. Working for the iShares platform. Emphasis on Dev-ops and developing the continuous integration pipeline.",
|
||||
title: "Software Developer",
|
||||
endDate: {
|
||||
month: 11,
|
||||
@ -98,6 +98,7 @@ const experiences: Experience[] = [
|
||||
{
|
||||
isCurrent: false,
|
||||
summary:
|
||||
// cspell:disable-next-line
|
||||
"Develop web commerce platforms for various high profile clients.\n\nCreated a log analysis web application with the Play Framework in Java, incorporating Test Driven Development. It asynchronously uploads and processes large (2 GB) log files, and outputs meaningful results in context with the problem. \n\nAnalysis and development of the payment system infrastructure and user accounts section to be used by several clients of the company such as Waitrose, Tally Weijl, DJ Sports, Debenhams, Ann Summers, John Lewis and others.\n\nTechnologies used include WebSphere Commerce, Java, JavaScript and JSP.",
|
||||
title: "Java Developer",
|
||||
endDate: {
|
||||
@ -118,7 +119,7 @@ const education: Education[] = [
|
||||
{
|
||||
degree: "Master of Science (MSc)",
|
||||
fieldOfStudy: "Computer Science",
|
||||
notes: "Exam Results: 1st Class with Distinction, Dissertation: 1st Class with Distinction\n\nRelevant Courses: Java and C# Programming, Software Engineering, Artificial Intelligence, \nComputational Photography, Algorithmics, Architecture and Hardware.\n\nCreated a Windows 8 game in JavaScript for the dissertation. \n\nCreated an award-winning 3D stereoscopic game in C# using XNA.",
|
||||
notes: "Exam Results: 1st Class with Distinction, Dissertation: 1st Class with Distinction\n\nRelevant Courses: Java and C# Programming, Software Engineering, Artificial Intelligence, \nComputational Photography, Algorithms, Architecture and Hardware.\n\nCreated a Windows 8 game in JavaScript for the dissertation. \n\nCreated an award-winning 3D stereoscopic game in C# using XNA.",
|
||||
schoolName: "University College London",
|
||||
startDate: {
|
||||
year: 2012,
|
||||
@ -156,7 +157,7 @@ const skills: Skill[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const achievements: Achivement[] = [
|
||||
const achievements: Achievement[] = [
|
||||
{
|
||||
issuer: "Oracle",
|
||||
name: "Oracle Certified Expert",
|
||||
@ -165,7 +166,7 @@ const achievements: Achivement[] = [
|
||||
|
||||
class DocumentCreator {
|
||||
// tslint:disable-next-line: typedef
|
||||
public create([experiences, educations, skills, achivements]: [Experience[], Education[], Skill[], Achivement[]]): Document {
|
||||
public create([experiences, educations, skills, achievements]: [Experience[], Education[], Skill[], Achievement[]]): Document {
|
||||
const document = new Document({
|
||||
sections: [
|
||||
{
|
||||
@ -221,7 +222,7 @@ class DocumentCreator {
|
||||
this.createSubHeading("Skills"),
|
||||
this.createSkillList(skills),
|
||||
this.createSubHeading("Achievements"),
|
||||
...this.createAchivementsList(achivements),
|
||||
...this.createAchievementsList(achievements),
|
||||
this.createSubHeading("Interests"),
|
||||
this.createInterests("Programming, Technology, Music Production, Web Design, 3D Modelling, Dancing."),
|
||||
this.createHeading("References"),
|
||||
@ -283,7 +284,7 @@ class DocumentCreator {
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: `\t${dateText}`,
|
||||
children: [new Tab(), dateText],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
@ -318,8 +319,8 @@ class DocumentCreator {
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
public createAchivementsList(achivements: any[]): Paragraph[] {
|
||||
return achivements.map(
|
||||
public createAchievementsList(achievements: any[]): Paragraph[] {
|
||||
return achievements.map(
|
||||
(achievement) =>
|
||||
new Paragraph({
|
||||
text: achievement.name,
|
||||
|
@ -53,17 +53,19 @@ const table = new Table({
|
||||
|
||||
const doc = new Document({
|
||||
numbering: {
|
||||
config:[{
|
||||
reference: 'ref1',
|
||||
config: [
|
||||
{
|
||||
reference: "ref1",
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.DECIMAL,
|
||||
text: '%1)',
|
||||
text: "%1)",
|
||||
start: 50,
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}]
|
||||
},
|
||||
styles: {
|
||||
default: {
|
||||
@ -185,10 +187,10 @@ const doc = new Document({
|
||||
rightTabStop: TabStopPosition.MAX,
|
||||
leftTabStop: 453.543307087,
|
||||
numbering: {
|
||||
reference: 'ref1',
|
||||
reference: "ref1",
|
||||
instance: 0,
|
||||
level: 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -18,10 +18,15 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun({
|
||||
children: ["Hello", new FootnoteReferenceRun(1)],
|
||||
children: ["Hello"],
|
||||
}),
|
||||
new FootnoteReferenceRun(1),
|
||||
new TextRun({
|
||||
children: [" World!", new FootnoteReferenceRun(2)],
|
||||
children: [" World!"],
|
||||
}),
|
||||
new FootnoteReferenceRun(2),
|
||||
new TextRun({
|
||||
children: [" GitHub!"],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
@ -35,15 +40,17 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun({
|
||||
children: ["Hello", new FootnoteReferenceRun(4)],
|
||||
children: ["Hello"],
|
||||
}),
|
||||
new FootnoteReferenceRun(4),
|
||||
new TextRun({
|
||||
children: [" World!", new FootnoteReferenceRun(5)],
|
||||
children: [" World!"],
|
||||
}),
|
||||
new FootnoteReferenceRun(5),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [new TextRun("Hello World"), new FootnoteReferenceRun(6)],
|
||||
children: [new TextRun("Hello World Again"), new FootnoteReferenceRun(6)],
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Export to base64 string - Useful in a browser environment.
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
||||
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
@ -15,7 +15,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tBar",
|
||||
children: [new Tab(), "Bar"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Example on how to customise the look at feel using Styles
|
||||
// Example on how to customize the look at feel using Styles
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
@ -82,6 +82,32 @@ const doc = new Document({
|
||||
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: {
|
||||
@ -169,6 +195,14 @@ const doc = new Document({
|
||||
new TextRun({
|
||||
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({
|
||||
@ -182,6 +216,40 @@ const doc = new Document({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
style: "strikeUnderline",
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "Underline and Strike",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
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,9 +1,21 @@
|
||||
// This demo shows how to create bookmarks then link to them with internal hyperlinks
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Bookmark, Document, Footer, HeadingLevel, InternalHyperlink, Packer, PageBreak, Paragraph, TextRun, PageReference } from "../build";
|
||||
import {
|
||||
Bookmark,
|
||||
Document,
|
||||
Footer,
|
||||
HeadingLevel,
|
||||
InternalHyperlink,
|
||||
Packer,
|
||||
PageBreak,
|
||||
Paragraph,
|
||||
TextRun,
|
||||
PageReference,
|
||||
} from "../build";
|
||||
|
||||
const LOREM_IPSUM =
|
||||
/* cspell:disable-next-line */
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mi velit, convallis convallis scelerisque nec, faucibus nec leo. Phasellus at posuere mauris, tempus dignissim velit. Integer et tortor dolor. Duis auctor efficitur mattis. Vivamus ut metus accumsan tellus auctor sollicitudin venenatis et nibh. Cras quis massa ac metus fringilla venenatis. Proin rutrum mauris purus, ut suscipit magna consectetur id. Integer consectetur sollicitudin ante, vitae faucibus neque efficitur in. Praesent ultricies nibh lectus. Mauris pharetra id odio eget iaculis. Duis dictum, risus id pellentesque rutrum, lorem quam malesuada massa, quis ullamcorper turpis urna a diam. Cras vulputate metus vel massa porta ullamcorper. Etiam porta condimentum nulla nec tristique. Sed nulla urna, pharetra non tortor sed, sollicitudin molestie diam. Maecenas enim leo, feugiat eget vehicula id, sollicitudin vitae ante.";
|
||||
|
||||
const doc = new Document({
|
||||
|
@ -34,8 +34,7 @@ const doc = new Document({
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text:
|
||||
"Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
text: "Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
],
|
||||
|
@ -1,9 +1,15 @@
|
||||
// Add image to table cell
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||
import { Document, ImageRun, Packer, Paragraph, Table, TableCell, TableRow, WidthType } from "../build";
|
||||
|
||||
const imageBase64Data = `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`;
|
||||
|
||||
const table = new Table({
|
||||
width: {
|
||||
size: 8640,
|
||||
type: WidthType.DXA,
|
||||
},
|
||||
rows: [
|
||||
new TableRow({
|
||||
children: [
|
||||
@ -17,7 +23,19 @@ const table = new Table({
|
||||
children: [],
|
||||
}),
|
||||
new TableCell({
|
||||
children: [],
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
data: Buffer.from(imageBase64Data, "base64"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
@ -27,7 +45,19 @@ const table = new Table({
|
||||
children: [],
|
||||
}),
|
||||
new TableCell({
|
||||
children: [],
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
data: fs.readFileSync("./demo/images/image1.jpeg"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new TableCell({
|
||||
children: [],
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Example of making content of section vertically aligned
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
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({
|
||||
sections: [
|
||||
@ -18,7 +18,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -123,8 +123,7 @@ const noBorderTable = new Table({
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text:
|
||||
"Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
text: "Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
],
|
||||
|
@ -25,6 +25,11 @@ const doc = new Document({
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
altText: {
|
||||
title: "This is an ultimate title",
|
||||
description: "This is an ultimate image",
|
||||
name: "My Ultimate Image",
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
@ -43,8 +43,7 @@ const doc = new Document({
|
||||
style: "strong",
|
||||
}),
|
||||
new TextRun({
|
||||
text:
|
||||
" - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
text: " - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
MathSubScript,
|
||||
MathSubSuperScript,
|
||||
MathSum,
|
||||
MathIntegral,
|
||||
MathSuperScript,
|
||||
Packer,
|
||||
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({
|
||||
children: [
|
||||
new Math({
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Change background colour of whole document
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
||||
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
background: {
|
||||
@ -19,7 +19,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Example of how to change page borders
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
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({
|
||||
sections: [
|
||||
@ -25,7 +25,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
PageNumber,
|
||||
Paragraph,
|
||||
ShadingType,
|
||||
Tab,
|
||||
TextRun,
|
||||
} from "../build";
|
||||
|
||||
@ -111,7 +112,7 @@ const doc = new Document({
|
||||
}),
|
||||
new TextRun({
|
||||
bold: true,
|
||||
children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||
children: [new Tab(), "use Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||
}),
|
||||
new TextRun({
|
||||
bold: true,
|
||||
@ -121,7 +122,7 @@ const doc = new Document({
|
||||
author: "Firstname Lastname",
|
||||
date: "2020-10-06T09:05:00Z",
|
||||
bold: false,
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
HorizontalPositionAlign,
|
||||
Packer,
|
||||
Paragraph,
|
||||
Tab,
|
||||
TextRun,
|
||||
VerticalPositionAlign,
|
||||
} from "../build";
|
||||
@ -67,7 +68,7 @@ const doc = new Document({
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -4,7 +4,7 @@ import * as fs from "fs";
|
||||
import { Bookmark, Document, Packer, Paragraph, SimpleField, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
creator: 'Me',
|
||||
creator: "Me",
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
|
@ -13,11 +13,13 @@ const doc = new Document({
|
||||
},
|
||||
},
|
||||
children: [
|
||||
new Paragraph({ children: [
|
||||
new TextRun('This text will be in the first column.'),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("This text will be in the first column."),
|
||||
new ColumnBreak(),
|
||||
new TextRun('This text will be in the second column.'),
|
||||
] }),
|
||||
new TextRun("This text will be in the second column."),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -7,12 +7,31 @@ const doc = new Document({
|
||||
sections: [
|
||||
{
|
||||
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({
|
||||
children: [
|
||||
new TextRun("我今天遛狗去公园"),
|
||||
new TextRun({
|
||||
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||
space: SpaceType.PRESERVE,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
@ -23,7 +42,6 @@ const doc = new Document({
|
||||
),
|
||||
new TextRun({
|
||||
text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345",
|
||||
space: SpaceType.PRESERVE,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
30
demo/74-nodejs-stream.ts
Normal file
30
demo/74-nodejs-stream.ts
Normal file
@ -0,0 +1,30 @@
|
||||
// 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, Tab, TextRun } from "../build";
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const stream = Packer.toStream(doc);
|
||||
stream.pipe(fs.createWriteStream("My Document.docx"));
|
80
demo/75-tab-stops.ts
Normal file
80
demo/75-tab-stops.ts
Normal file
@ -0,0 +1,80 @@
|
||||
// Exporting the document as a stream
|
||||
// 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"));
|
@ -24,7 +24,7 @@
|
||||
bold: true,
|
||||
}),
|
||||
new docx.TextRun({
|
||||
text: "\tGithub is the best",
|
||||
children: [new docx.Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
|
@ -27,7 +27,8 @@ import { Document, Packer, Paragraph, TextRun } from "docx";
|
||||
// Documents contain sections, you can have multiple sections per document, go here to learn more about sections
|
||||
// This simple example will only contain one section
|
||||
const doc = new Document({
|
||||
sections: [{
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [
|
||||
new Paragraph({
|
||||
@ -44,7 +45,8 @@ const doc = new Document({
|
||||
],
|
||||
}),
|
||||
],
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Used to export the file into a .docx file
|
||||
@ -56,6 +58,7 @@ Packer.toBuffer(doc).then((buffer) => {
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<!-- cspell:disable-next-line -->
|
||||
<img alt="clippy the assistant" src="./clippy.png">
|
||||
</p>
|
||||
|
||||
|
@ -1,37 +1,39 @@
|
||||
* [Getting Started](/)
|
||||
- [Getting Started](/)
|
||||
|
||||
* [Examples](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||
- [Examples](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||
|
||||
* API
|
||||
- API
|
||||
|
||||
* [Documentation](https://docx.js.org/api/)
|
||||
- [Documentation](https://docx.js.org/api/)
|
||||
|
||||
* Usage
|
||||
- Usage
|
||||
|
||||
* [Document](usage/document.md)
|
||||
* [Sections](usage/sections.md)
|
||||
* [Paragraph](usage/paragraph.md)
|
||||
* [Text](usage/text.md)
|
||||
* [Image](usage/images.md)
|
||||
* [Headers & Footers](usage/headers-and-footers.md)
|
||||
* [Bullet Points](usage/bullet-points.md)
|
||||
* [Hyperlinks](usage/hyperlinks.md)
|
||||
* [Numbering](usage/numbering.md)
|
||||
* [Tables](usage/tables.md)
|
||||
* [Tab Stops](usage/tab-stops.md)
|
||||
* [Table of Contents](usage/table-of-contents.md)
|
||||
* [Page Numbers](usage/page-numbers.md)
|
||||
* [Change Tracking](usage/change-tracking.md)
|
||||
* [Math](usage/math.md)
|
||||
* [Text Frames](usage/text-frames.md)
|
||||
* Styling
|
||||
* [Styling with JS](usage/styling-with-js.md)
|
||||
* [Styling with XML](usage/styling-with-xml.md)
|
||||
* Exporting
|
||||
- [Document](usage/document.md)
|
||||
- [Sections](usage/sections.md)
|
||||
- [Paragraph](usage/paragraph.md)
|
||||
- [Text](usage/text.md)
|
||||
- [Image](usage/images.md)
|
||||
- [Headers & Footers](usage/headers-and-footers.md)
|
||||
- [Bullet Points](usage/bullet-points.md)
|
||||
- [Hyperlinks](usage/hyperlinks.md)
|
||||
- [Numbering](usage/numbering.md)
|
||||
- [Tables](usage/tables.md)
|
||||
- [Tab Stops](usage/tab-stops.md)
|
||||
- [Table of Contents](usage/table-of-contents.md)
|
||||
- [Page Numbers](usage/page-numbers.md)
|
||||
- [Change Tracking](usage/change-tracking.md)
|
||||
- [Math](usage/math.md)
|
||||
- [Text Frames](usage/text-frames.md)
|
||||
- Styling
|
||||
_ [Styling with JS](usage/styling-with-js.md)
|
||||
_ [Styling with XML](usage/styling-with-xml.md)
|
||||
|
||||
* [Packers](usage/packers.md)
|
||||
* Utility
|
||||
- Exporting
|
||||
|
||||
* [Convenience functions](usage/convenience-functions.md)
|
||||
- [Packers](usage/packers.md)
|
||||
|
||||
* [Contribution Guidelines](contribution-guidelines.md)
|
||||
- Utility
|
||||
|
||||
- [Convenience functions](usage/convenience-functions.md)
|
||||
|
||||
- [Contribution Guidelines](contribution-guidelines.md)
|
||||
|
@ -8,11 +8,11 @@
|
||||
|
||||
- Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
|
||||
|
||||
- Follow the `TSLint` rules
|
||||
- Follow the `ESLint` rules
|
||||
|
||||
## Always think about the user
|
||||
|
||||
Put yourself in their position, and imagine how they would feel about your feature you wrote.
|
||||
Put yourself in their position, and imagine how they would feel about the feature you wrote.
|
||||
|
||||
1. Is it easy to use?
|
||||
2. Has it been documented well?
|
||||
@ -26,13 +26,15 @@ Please write good commit messages when making a commit: https://chris.beams.io/p
|
||||
|
||||
**Do not:**
|
||||
|
||||
<!-- cspell:disable -->
|
||||
```
|
||||
c // What?
|
||||
rtl // Adding acryonyms without explaining anything else is not helpful
|
||||
rtl // Adding acronyms without explaining anything else is not helpful
|
||||
works! // Glad its working, but the message is not helpful
|
||||
demo updated // Getting better, but capitalize the first letter
|
||||
Unesesary coment removed // Make sure to use correct spelling
|
||||
```
|
||||
<!-- cspell:enable -->
|
||||
|
||||
**Do**
|
||||
|
||||
@ -42,9 +44,9 @@ Unesesary coment removed // Make sure to use correct spelling
|
||||
public float(tableFloatOptions: ITableFloatOptions): Table
|
||||
```
|
||||
|
||||
## Delcariative API
|
||||
## Declarative API
|
||||
|
||||
Make sure the API is declarative, so no _method calling_ or _mutation_. This is a design decision, consistent with the rest of the project. There are benefits to delcariative code over other styles of code, explained here: https://dzone.com/articles/why-declarative-coding-makes-you-a-better-programm
|
||||
Make sure the API is declarative, so no _method calling_ or _mutation_. This is a design decision, consistent with the rest of the project. There are benefits to declarative code over other styles of code, explained here: https://dzone.com/articles/why-declarative-coding-makes-you-a-better-programm
|
||||
|
||||
**Do not:**
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-carbon@1/index.min.js"></script>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: "docx",
|
||||
@ -24,6 +25,12 @@
|
||||
subMaxLevel: 2,
|
||||
search: "auto",
|
||||
coverpage: true,
|
||||
plugins: [
|
||||
// Change to your Carbon property ID
|
||||
// cSpell:disable
|
||||
DocsifyCarbon.create("CEAIP237", "docx"),
|
||||
// cSpell:enable
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
|
@ -22,20 +22,19 @@ const doc = new docx.Document({
|
||||
|
||||
### Full list of options:
|
||||
|
||||
|
||||
* creator
|
||||
* description
|
||||
* title
|
||||
* subject
|
||||
* keywords
|
||||
* lastModifiedBy
|
||||
* revision
|
||||
* externalStyles
|
||||
* styles
|
||||
* numbering
|
||||
* footnotes
|
||||
* hyperlinks
|
||||
* background
|
||||
- creator
|
||||
- description
|
||||
- title
|
||||
- subject
|
||||
- keywords
|
||||
- lastModifiedBy
|
||||
- revision
|
||||
- externalStyles
|
||||
- styles
|
||||
- numbering
|
||||
- footnotes
|
||||
- hyperlinks
|
||||
- background
|
||||
|
||||
### 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.
|
||||
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
|
||||
|
||||
### Add image to the document
|
||||
|
||||
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_
|
||||
|
||||
@ -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](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_
|
||||
|
||||
@ -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](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_
|
||||
|
@ -37,7 +37,7 @@ sub-sublists, etc. Each level includes the following properties:
|
||||
numbers from each numbering level before this one. Thus a level
|
||||
text of `%d)` with a number format of `lowerLetter` would result in
|
||||
the sequence "a)", "b)", ...
|
||||
* and a few others, which you can see in the OXML spec section 17.9.6
|
||||
* and a few others, which you can see in the OOXML spec section 17.9.6
|
||||
|
||||
## Document-level bullets/numbering definitions (concrete)
|
||||
|
||||
@ -86,3 +86,34 @@ topLevelP.setNumbering(concrete, 0);
|
||||
subP.setNumbering(concrete, 1);
|
||||
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
|
||||
}]
|
||||
|
||||
```
|
||||
|
@ -111,7 +111,7 @@ const paragraph = new Paragraph({
|
||||
|
||||
## 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
|
||||
|
||||
@ -121,7 +121,7 @@ Add borders to a `Paragraph`. Good for making the `Paragraph` stand out
|
||||
| -------- | -------- | -------- |
|
||||
| color | `string` | Required |
|
||||
| space | `number` | Required |
|
||||
| value | `string` | Required |
|
||||
| style | `string` | Required |
|
||||
| size | `number` | Required |
|
||||
|
||||
**Example:**
|
||||
@ -135,13 +135,13 @@ const paragraph = new Paragraph({
|
||||
top: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
value: "single",
|
||||
style: "single",
|
||||
size: 6,
|
||||
},
|
||||
bottom: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
value: "single",
|
||||
style: "single",
|
||||
size: 6,
|
||||
},
|
||||
},
|
||||
|
@ -146,7 +146,7 @@ const doc = new Document({
|
||||
});
|
||||
```
|
||||
|
||||
**Note**: If you are using the `.headingX` or `.title` methods of paragraphs, you must make sure to define `HeadingX` or `Title` styles for these. Otherwise they'll show up unstyled :(. If you are using the `.bullet` or `.setNumbering` methods, you need to define a `ListParagraph` style or the numbers may not show up.
|
||||
**Note**: If you are using the `.headingX` or `.title` methods of paragraphs, you must make sure to define `HeadingX` or `Title` styles for these. Otherwise they'll show up un-styled :(. If you are using the `.bullet` or `.setNumbering` methods, you need to define a `ListParagraph` style or the numbers may not show up.
|
||||
|
||||
### Document defaults
|
||||
|
||||
@ -199,7 +199,7 @@ For these properties, the rules state the following conflict resolution in case
|
||||
|
||||
## Examples
|
||||
|
||||
### Declaritive styles
|
||||
### Declarative styles
|
||||
|
||||
Importing Images from file system path
|
||||
|
||||
|
@ -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
|
||||
|
||||
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
||||
|
8499
package-lock.json
generated
8499
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docx",
|
||||
"version": "7.4.0",
|
||||
"version": "7.7.0",
|
||||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
@ -9,13 +9,14 @@
|
||||
"test.coverage": "nyc npm test",
|
||||
"test.watch": "npm test -- --watch",
|
||||
"prepublishOnly": "npm run build --production",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "eslint -c .eslintrc.js --ext .ts src",
|
||||
"build": "npm run webpack && npm run fix-types",
|
||||
"webpack": "rimraf ./build && webpack --config ./webpack.config.ts",
|
||||
"demo": "npm run build && npm run ts-node --skip-project ./demo",
|
||||
"typedoc": "rimraf ./build && typedoc src/index.ts --tsconfig tsconfig.typedoc.json",
|
||||
"style": "prettier -l \"src/**/*.ts\"",
|
||||
"style": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
|
||||
"style.fix": "npm run style -- --write",
|
||||
"cspell": "cspell \"{src,demo,docs,scripts}/**/*.{ts,scss,html,md}\" && cspell \"./*.*\"",
|
||||
"fix-types": "ts-node --skip-project scripts/types-absolute-fixer.ts",
|
||||
"e2e": "ts-node scripts/e2e.ts",
|
||||
"serve.docs": "cd docs && docsify serve",
|
||||
@ -63,17 +64,27 @@
|
||||
"homepage": "https://github.com/dolanmiu/docx#readme",
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.2.15",
|
||||
"@types/glob": "^7.1.4",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/glob": "^8.0.0",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/prompt": "^1.1.1",
|
||||
"@types/request-promise": "^4.1.42",
|
||||
"@types/shelljs": "^0.8.9",
|
||||
"@types/sinon": "^10.0.0",
|
||||
"@types/unzipper": "^0.10.4",
|
||||
"@types/webpack": "^5.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||
"@typescript-eslint/parser": "^5.36.1",
|
||||
"buffer": "^6.0.3",
|
||||
"chai": "^3.5.0",
|
||||
"chai": "^4.3.6",
|
||||
"cspell": "^6.2.2",
|
||||
"docsify-cli": "^4.3.0",
|
||||
"eslint": "^8.23.0",
|
||||
"eslint-plugin-functional": "^4.3.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsdoc": "^39.3.6",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"eslint-plugin-unicorn": "^44.0.0",
|
||||
"glob": "^8.0.1",
|
||||
"jszip": "^3.1.5",
|
||||
"mocha": "^10.0.0",
|
||||
@ -92,11 +103,9 @@
|
||||
"ts-loader": "^9.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"tsconfig-paths": "^4.0.0",
|
||||
"tsconfig-paths-webpack-plugin": "^3.5.2",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-immutable": "^6.0.1",
|
||||
"tsconfig-paths-webpack-plugin": "^4.0.0",
|
||||
"typedoc": "^0.23.2",
|
||||
"typescript": "4.7.4",
|
||||
"typescript": "4.8.4",
|
||||
"unzipper": "^0.10.11",
|
||||
"webpack": "^5.28.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IMediaData, Media } from "@file/media";
|
||||
|
||||
export class ImageReplacer {
|
||||
public replace(xmlData: string, mediaData: IMediaData[], offset: number): string {
|
||||
public replace(xmlData: string, mediaData: readonly IMediaData[], offset: number): string {
|
||||
let currentXmlData = xmlData;
|
||||
|
||||
mediaData.forEach((image, i) => {
|
||||
@ -11,7 +11,7 @@ export class ImageReplacer {
|
||||
return currentXmlData;
|
||||
}
|
||||
|
||||
public getMediaData(xmlData: string, media: Media): IMediaData[] {
|
||||
public getMediaData(xmlData: string, media: Media): readonly IMediaData[] {
|
||||
return media.Array.filter((image) => xmlData.search(`{${image.fileName}}`) > 0);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,8 @@ import * as sinon from "sinon";
|
||||
|
||||
import { File } from "@file/file";
|
||||
import { Footer, Header } from "@file/header";
|
||||
import { Paragraph } from "@file/paragraph";
|
||||
import { ImageRun, Paragraph } from "@file/paragraph";
|
||||
import * as convenienceFunctions from "@util/convenience-functions";
|
||||
|
||||
import { Compiler } from "./next-compiler";
|
||||
|
||||
@ -15,8 +16,16 @@ describe("Compiler", () => {
|
||||
compiler = new Compiler();
|
||||
});
|
||||
|
||||
before(() => {
|
||||
sinon.stub(convenienceFunctions, "uniqueId").callsFake(() => "test");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(convenienceFunctions.uniqueId as sinon.SinonStub).restore();
|
||||
});
|
||||
|
||||
describe("#compile()", () => {
|
||||
it("should pack all the content", async function () {
|
||||
it("should pack all the content", function () {
|
||||
this.timeout(99999999);
|
||||
const file = new File({
|
||||
sections: [],
|
||||
@ -44,7 +53,7 @@ describe("Compiler", () => {
|
||||
expect(fileNames).to.include("_rels/.rels");
|
||||
});
|
||||
|
||||
it("should pack all additional headers and footers", async function () {
|
||||
it("should pack all additional headers and footers", function () {
|
||||
const file = new File({
|
||||
sections: [
|
||||
{
|
||||
@ -111,18 +120,38 @@ describe("Compiler", () => {
|
||||
const spy = sinon.spy(compiler["formatter"], "format");
|
||||
|
||||
compiler.compile(file);
|
||||
expect(spy.callCount).to.equal(12);
|
||||
expect(spy.callCount).to.equal(13);
|
||||
});
|
||||
|
||||
it("should work with media datas", () => {
|
||||
// This test is required because before, there was a case where Document was formatted twice, which was inefficient
|
||||
// This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
|
||||
const paragraph = new Paragraph("");
|
||||
const file = new File({
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [paragraph],
|
||||
headers: {
|
||||
default: new Header({
|
||||
children: [new Paragraph("test")],
|
||||
}),
|
||||
},
|
||||
footers: {
|
||||
default: new Footer({
|
||||
children: [new Paragraph("test")],
|
||||
}),
|
||||
},
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
data: Buffer.from("", "base64"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ import { File } from "@file/file";
|
||||
import { Formatter } from "../formatter";
|
||||
import { ImageReplacer } from "./image-replacer";
|
||||
import { NumberingReplacer } from "./numbering-replacer";
|
||||
import { PrettityType } from "./packer";
|
||||
import { PrettifyType } from "./packer";
|
||||
|
||||
interface IXmlifyedFile {
|
||||
readonly data: string;
|
||||
@ -20,10 +20,10 @@ interface IXmlifyedFileMapping {
|
||||
readonly Numbering: IXmlifyedFile;
|
||||
readonly Relationships: IXmlifyedFile;
|
||||
readonly FileRelationships: IXmlifyedFile;
|
||||
readonly Headers: IXmlifyedFile[];
|
||||
readonly Footers: IXmlifyedFile[];
|
||||
readonly HeaderRelationships: IXmlifyedFile[];
|
||||
readonly FooterRelationships: IXmlifyedFile[];
|
||||
readonly Headers: readonly IXmlifyedFile[];
|
||||
readonly Footers: readonly IXmlifyedFile[];
|
||||
readonly HeaderRelationships: readonly IXmlifyedFile[];
|
||||
readonly FooterRelationships: readonly IXmlifyedFile[];
|
||||
readonly ContentTypes: IXmlifyedFile;
|
||||
readonly CustomProperties: IXmlifyedFile;
|
||||
readonly AppProperties: IXmlifyedFile;
|
||||
@ -38,24 +38,24 @@ export class Compiler {
|
||||
private readonly imageReplacer: ImageReplacer;
|
||||
private readonly numberingReplacer: NumberingReplacer;
|
||||
|
||||
constructor() {
|
||||
public constructor() {
|
||||
this.formatter = new Formatter();
|
||||
this.imageReplacer = new ImageReplacer();
|
||||
this.numberingReplacer = new NumberingReplacer();
|
||||
}
|
||||
|
||||
public compile(file: File, prettifyXml?: boolean | PrettityType): JSZip {
|
||||
public compile(file: File, prettifyXml?: boolean | PrettifyType): JSZip {
|
||||
const zip = new JSZip();
|
||||
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
||||
const map = new Map<string, IXmlifyedFile | IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||
const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||
|
||||
for (const [, obj] of map) {
|
||||
if (Array.isArray(obj)) {
|
||||
for (const subFile of obj) {
|
||||
for (const subFile of obj as readonly IXmlifyedFile[]) {
|
||||
zip.file(subFile.path, subFile.data);
|
||||
}
|
||||
} else {
|
||||
zip.file(obj.path, obj.data);
|
||||
zip.file((obj as IXmlifyedFile).path, (obj as IXmlifyedFile).data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ export class Compiler {
|
||||
return zip;
|
||||
}
|
||||
|
||||
private xmlifyFile(file: File, prettify?: boolean | PrettityType): IXmlifyedFileMapping {
|
||||
private xmlifyFile(file: File, prettify?: boolean | PrettifyType): IXmlifyedFileMapping {
|
||||
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
||||
|
||||
const documentXmlData = xml(
|
||||
@ -406,12 +406,7 @@ export class Compiler {
|
||||
path: "word/settings.xml",
|
||||
},
|
||||
Comments: {
|
||||
data: (() => {
|
||||
if (!file.Comments) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = xml(
|
||||
data: xml(
|
||||
this.formatter.format(file.Comments, {
|
||||
viewWrapper: file.Document,
|
||||
file,
|
||||
@ -423,9 +418,7 @@ export class Compiler {
|
||||
encoding: "UTF-8",
|
||||
},
|
||||
},
|
||||
);
|
||||
return data;
|
||||
})(),
|
||||
),
|
||||
path: "word/comments.xml",
|
||||
},
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ConcreteNumbering } from "@file/numbering";
|
||||
|
||||
export class NumberingReplacer {
|
||||
public replace(xmlData: string, concreteNumberings: ConcreteNumbering[]): string {
|
||||
public replace(xmlData: string, concreteNumberings: readonly ConcreteNumbering[]): string {
|
||||
let currentXmlData = xmlData;
|
||||
|
||||
for (const concreteNumbering of concreteNumberings) {
|
||||
|
@ -37,6 +37,14 @@ describe("Packer", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toString()", () => {
|
||||
it("should return a non-empty string", async () => {
|
||||
const result = await Packer.toString(file);
|
||||
|
||||
assert.isAbove(result.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toBuffer()", () => {
|
||||
it("should create a standard docx file", async function () {
|
||||
this.timeout(99999999);
|
||||
@ -47,7 +55,7 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
it("should handle exception if it throws any", () => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const compiler = stub((Packer as any).compiler, "compile");
|
||||
|
||||
compiler.throwsException();
|
||||
@ -57,7 +65,7 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Packer as any).compiler.compile.restore();
|
||||
});
|
||||
});
|
||||
@ -72,7 +80,7 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
it("should handle exception if it throws any", () => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const compiler = stub((Packer as any).compiler, "compile");
|
||||
|
||||
compiler.throwsException();
|
||||
@ -82,14 +90,14 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Packer as any).compiler.compile.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toBlob()", () => {
|
||||
it("should create a standard docx file", async () => {
|
||||
// tslint:disable-next-line: no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
stub((Packer as any).compiler, "compile").callsFake(() => ({
|
||||
// tslint:disable-next-line: no-empty
|
||||
generateAsync: () => mock({}),
|
||||
@ -100,7 +108,7 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
it("should handle exception if it throws any", () => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const compiler = stub((Packer as any).compiler, "compile");
|
||||
|
||||
compiler.throwsException();
|
||||
@ -110,7 +118,57 @@ describe("Packer", () => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// tslint:disable-next-line:no-any
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Packer as any).compiler.compile.restore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toStream()", () => {
|
||||
it("should create a standard docx file", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
stub((Packer as any).compiler, "compile").callsFake(() => ({
|
||||
// tslint:disable-next-line: no-empty
|
||||
generateNodeStream: () => ({
|
||||
on: (event: string, cb: () => void) => {
|
||||
if (event === "end") {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
}),
|
||||
}));
|
||||
const stream = await Packer.toStream(file);
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on("error", () => {
|
||||
reject(new Error());
|
||||
});
|
||||
|
||||
stream.on("end", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle exception if it throws any", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const compiler = stub((Packer as any).compiler, "compile").callsFake(() => ({
|
||||
// tslint:disable-next-line: no-empty
|
||||
on: (event: string, cb: () => void) => {
|
||||
if (event === "error") {
|
||||
cb();
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
compiler.throwsException();
|
||||
try {
|
||||
Packer.toStream(file);
|
||||
} catch (error) {
|
||||
assert.isDefined(error);
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(Packer as any).compiler.compile.restore();
|
||||
});
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Stream } from "stream";
|
||||
import { File } from "@file/file";
|
||||
|
||||
import { Compiler } from "./next-compiler";
|
||||
@ -5,7 +6,7 @@ import { Compiler } from "./next-compiler";
|
||||
/**
|
||||
* Use blanks to prettify
|
||||
*/
|
||||
export enum PrettityType {
|
||||
export enum PrettifyType {
|
||||
NONE = "",
|
||||
WITH_2_BLANKS = " ",
|
||||
WITH_4_BLANKS = " ",
|
||||
@ -13,7 +14,18 @@ export enum PrettityType {
|
||||
}
|
||||
|
||||
export class Packer {
|
||||
public static async toBuffer(file: File, prettify?: boolean | PrettityType): Promise<Buffer> {
|
||||
public static async toString(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||
const zip = this.compiler.compile(file, prettify);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "string",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
compression: "DEFLATE",
|
||||
});
|
||||
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBuffer(file: File, prettify?: boolean | PrettifyType): Promise<Buffer> {
|
||||
const zip = this.compiler.compile(file, prettify);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "nodebuffer",
|
||||
@ -24,7 +36,7 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBase64String(file: File, prettify?: boolean | PrettityType): Promise<string> {
|
||||
public static async toBase64String(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||
const zip = this.compiler.compile(file, prettify);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "base64",
|
||||
@ -35,7 +47,7 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBlob(file: File, prettify?: boolean | PrettityType): Promise<Blob> {
|
||||
public static async toBlob(file: File, prettify?: boolean | PrettifyType): Promise<Blob> {
|
||||
const zip = this.compiler.compile(file, prettify);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "blob",
|
||||
@ -46,5 +58,17 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static toStream(file: File, prettify?: boolean | PrettifyType): Stream {
|
||||
const zip = this.compiler.compile(file, prettify);
|
||||
const zipData = zip.generateNodeStream({
|
||||
type: "nodebuffer",
|
||||
streamFiles: true,
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
compression: "DEFLATE",
|
||||
});
|
||||
|
||||
return zipData;
|
||||
}
|
||||
|
||||
private static readonly compiler = new Compiler();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { AppPropertiesAttributes } from "./app-properties-attributes";
|
||||
|
||||
export class AppProperties extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("Properties");
|
||||
|
||||
this.root.push(
|
||||
|
@ -33,7 +33,7 @@ export interface IBorderOptions {
|
||||
}
|
||||
|
||||
export class BorderElement extends XmlComponent {
|
||||
constructor(elementName: string, { color, size, space, style }: IBorderOptions) {
|
||||
public constructor(elementName: string, { color, size, space, style }: IBorderOptions) {
|
||||
super(elementName);
|
||||
this.root.push(
|
||||
new BordersAttributes({
|
||||
|
@ -4,7 +4,7 @@ import { Default } from "./default/default";
|
||||
import { Override } from "./override/override";
|
||||
|
||||
export class ContentTypes extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("Types");
|
||||
|
||||
this.root.push(
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { DefaultAttributes } from "./default-attributes";
|
||||
|
||||
export class Default extends XmlComponent {
|
||||
constructor(contentType: string, extension?: string) {
|
||||
public constructor(contentType: string, extension?: string) {
|
||||
super("Default");
|
||||
|
||||
this.root.push(
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { OverrideAttributes } from "./override-attributes";
|
||||
|
||||
export class Override extends XmlComponent {
|
||||
constructor(contentType: string, partName?: string) {
|
||||
public constructor(contentType: string, partName?: string) {
|
||||
super("Override");
|
||||
|
||||
this.root.push(
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ICommentsOptions } from "@file/paragraph/run/comment-run";
|
||||
import { ICompatibilityOptions } from "@file/settings/compatibility";
|
||||
import { StringContainer, XmlComponent } from "@file/xml-components";
|
||||
import { dateTimeValue } from "@util/values";
|
||||
|
||||
@ -12,7 +13,7 @@ import { Paragraph } from "../paragraph";
|
||||
import { IStylesOptions } from "../styles";
|
||||
|
||||
export interface IPropertiesOptions {
|
||||
readonly sections: ISectionOptions[];
|
||||
readonly sections: readonly ISectionOptions[];
|
||||
readonly title?: string;
|
||||
readonly subject?: string;
|
||||
readonly creator?: string;
|
||||
@ -26,7 +27,7 @@ export interface IPropertiesOptions {
|
||||
readonly comments?: ICommentsOptions;
|
||||
readonly footnotes?: {
|
||||
readonly [key: string]: {
|
||||
readonly children: Paragraph[];
|
||||
readonly children: readonly Paragraph[];
|
||||
};
|
||||
};
|
||||
readonly background?: IDocumentBackgroundOptions;
|
||||
@ -35,12 +36,14 @@ export interface IPropertiesOptions {
|
||||
readonly updateFields?: boolean;
|
||||
};
|
||||
readonly compatabilityModeVersion?: number;
|
||||
readonly customProperties?: ICustomPropertyOptions[];
|
||||
readonly compatibility?: ICompatibilityOptions;
|
||||
readonly customProperties?: readonly ICustomPropertyOptions[];
|
||||
readonly evenAndOddHeaderAndFooters?: boolean;
|
||||
}
|
||||
|
||||
// <xs:element name="coreProperties" type="CT_CoreProperties"/>
|
||||
|
||||
/* cSpell:disable */
|
||||
// <xs:complexType name="CT_CoreProperties">
|
||||
// <xs:all>
|
||||
// <xs:element name="category" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
@ -60,9 +63,10 @@ export interface IPropertiesOptions {
|
||||
// <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string"/>
|
||||
// </xs:all>
|
||||
// </xs:complexType>
|
||||
/* cSpell:enable */
|
||||
|
||||
export class CoreProperties extends XmlComponent {
|
||||
constructor(options: Omit<IPropertiesOptions, "sections">) {
|
||||
public constructor(options: Omit<IPropertiesOptions, "sections">) {
|
||||
super("cp:coreProperties");
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
@ -100,7 +104,7 @@ export class CoreProperties extends XmlComponent {
|
||||
}
|
||||
|
||||
class TimestampElement extends XmlComponent {
|
||||
constructor(name: string) {
|
||||
public constructor(name: string) {
|
||||
super(name);
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
|
@ -3,11 +3,12 @@ import { CustomPropertiesAttributes } from "./custom-properties-attributes";
|
||||
import { CustomProperty, ICustomPropertyOptions } from "./custom-property";
|
||||
|
||||
export class CustomProperties extends XmlComponent {
|
||||
// tslint:disable-next-line:readonly-keyword
|
||||
// eslint-disable-next-line functional/prefer-readonly-type
|
||||
private nextId: number;
|
||||
// eslint-disable-next-line functional/prefer-readonly-type
|
||||
private readonly properties: CustomProperty[] = [];
|
||||
|
||||
constructor(properties: ICustomPropertyOptions[]) {
|
||||
public constructor(properties: readonly ICustomPropertyOptions[]) {
|
||||
super("Properties");
|
||||
|
||||
this.root.push(
|
||||
@ -32,6 +33,7 @@ export class CustomProperties extends XmlComponent {
|
||||
}
|
||||
|
||||
public addCustomProperty(property: ICustomPropertyOptions): void {
|
||||
// eslint-disable-next-line functional/immutable-data
|
||||
this.properties.push(new CustomProperty(this.nextId++, property));
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ export interface ICustomPropertyOptions {
|
||||
}
|
||||
|
||||
export class CustomProperty extends XmlComponent {
|
||||
constructor(id: number, properties: ICustomPropertyOptions) {
|
||||
public constructor(id: number, properties: ICustomPropertyOptions) {
|
||||
super("property");
|
||||
this.root.push(
|
||||
new CustomPropertyAttributes({
|
||||
@ -21,7 +21,7 @@ export class CustomProperty extends XmlComponent {
|
||||
}
|
||||
|
||||
export class CustomPropertyValue extends XmlComponent {
|
||||
constructor(value: string) {
|
||||
public constructor(value: string) {
|
||||
super("vt:lpwstr");
|
||||
this.root.push(value);
|
||||
}
|
||||
|
@ -7,9 +7,7 @@ describe("DocumentWrapper", () => {
|
||||
it("should create", () => {
|
||||
const file = new DocumentWrapper({ background: {} });
|
||||
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
expect(file.View).to.be.ok;
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
expect(file.Relationships).to.be.ok;
|
||||
});
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ export class DocumentWrapper implements IViewWrapper {
|
||||
private readonly document: Document;
|
||||
private readonly relationships: Relationships;
|
||||
|
||||
constructor(options: IDocumentOptions) {
|
||||
public constructor(options: IDocumentOptions) {
|
||||
this.document = new Document(options);
|
||||
this.relationships = new Relationships();
|
||||
}
|
||||
|
@ -4,9 +4,10 @@ import { IContext, IXmlableObject, XmlComponent } from "@file/xml-components";
|
||||
import { ISectionPropertiesOptions, SectionProperties } from "./section-properties/section-properties";
|
||||
|
||||
export class Body extends XmlComponent {
|
||||
// eslint-disable-next-line functional/prefer-readonly-type
|
||||
private readonly sections: SectionProperties[] = [];
|
||||
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("w:body");
|
||||
}
|
||||
|
||||
@ -16,6 +17,7 @@ export class Body extends XmlComponent {
|
||||
* The spec says:
|
||||
* - section element should be in the last paragraph of the section
|
||||
* - last section should be direct child of body
|
||||
*
|
||||
* @param options new section options
|
||||
*/
|
||||
public addSection(options: ISectionPropertiesOptions): void {
|
||||
|
@ -14,7 +14,7 @@ export class ColumnAttributes extends XmlAttributeComponent<IColumnAttributes> {
|
||||
}
|
||||
|
||||
export class Column extends XmlComponent {
|
||||
constructor({ width, space }: IColumnAttributes) {
|
||||
public constructor({ width, space }: IColumnAttributes) {
|
||||
super("w:col");
|
||||
this.root.push(
|
||||
new ColumnAttributes({
|
||||
|
@ -13,6 +13,13 @@ describe("Columns", () => {
|
||||
expect(tree["w:cols"]).to.deep.equal({ _attr: { "w:num": 3, "w:space": 720 } });
|
||||
});
|
||||
|
||||
it("should create set space and count to undefined if they are undefined", () => {
|
||||
const columns = new Columns({});
|
||||
const tree = new Formatter().format(columns);
|
||||
|
||||
expect(tree["w:cols"]).to.deep.equal({ _attr: {} });
|
||||
});
|
||||
|
||||
it("should ignore individual column attributes if equalWidth is true", () => {
|
||||
const unequalColumns = [new Column({ width: 1000, space: 400 }), new Column({ width: 2000 })];
|
||||
const columns = new Columns({ count: 3, space: 720, equalWidth: true, children: unequalColumns });
|
||||
|
@ -17,7 +17,7 @@ export interface IColumnsAttributes {
|
||||
readonly count?: number;
|
||||
readonly separate?: boolean;
|
||||
readonly equalWidth?: boolean;
|
||||
readonly children?: Column[];
|
||||
readonly children?: readonly Column[];
|
||||
}
|
||||
|
||||
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
||||
@ -30,7 +30,7 @@ export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes>
|
||||
}
|
||||
|
||||
export class Columns extends XmlComponent {
|
||||
constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
|
||||
public constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
|
||||
super("w:cols");
|
||||
this.root.push(
|
||||
new ColumnsAttributes({
|
||||
|
@ -38,7 +38,7 @@ export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesP
|
||||
}
|
||||
|
||||
export class DocumentGrid extends XmlComponent {
|
||||
constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) {
|
||||
public constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) {
|
||||
super("w:docGrid");
|
||||
|
||||
this.root.push(
|
||||
|
@ -52,7 +52,7 @@ export enum HeaderFooterType {
|
||||
FOOTER = "w:footerReference",
|
||||
}
|
||||
export class HeaderFooterReference extends XmlComponent {
|
||||
constructor(type: HeaderFooterType, options: IHeaderFooterOptions) {
|
||||
public constructor(type: HeaderFooterType, options: IHeaderFooterOptions) {
|
||||
super(type);
|
||||
|
||||
this.root.push(
|
||||
|
@ -39,7 +39,7 @@ export class LineNumberAttributes extends XmlAttributeComponent<ILineNumberAttri
|
||||
}
|
||||
|
||||
export class LineNumberType extends XmlComponent {
|
||||
constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
|
||||
public constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
|
||||
super("w:lnNumType");
|
||||
this.root.push(
|
||||
new LineNumberAttributes({
|
||||
|
@ -71,7 +71,7 @@ class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes>
|
||||
// <xsd:attribute name="offsetFrom" type="ST_PageBorderOffset" use="optional" default="text"/>
|
||||
// </xsd:complexType>
|
||||
export class PageBorders extends IgnoreIfEmptyXmlComponent {
|
||||
constructor(options?: IPageBordersOptions) {
|
||||
public constructor(options?: IPageBordersOptions) {
|
||||
super("w:pgBorders");
|
||||
|
||||
if (!options) {
|
||||
|
@ -33,7 +33,7 @@ export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttri
|
||||
}
|
||||
|
||||
export class PageMargin extends XmlComponent {
|
||||
constructor(
|
||||
public constructor(
|
||||
top: number | string,
|
||||
right: number | string,
|
||||
bottom: number | string,
|
||||
|
@ -41,7 +41,7 @@ export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberT
|
||||
};
|
||||
}
|
||||
export class PageNumberType extends XmlComponent {
|
||||
constructor({ start, formatType, separator }: IPageNumberTypeAttributes) {
|
||||
public constructor({ start, formatType, separator }: IPageNumberTypeAttributes) {
|
||||
super("w:pgNumType");
|
||||
this.root.push(
|
||||
new PageNumberTypeAttributes({
|
||||
|
@ -33,7 +33,7 @@ export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttribute
|
||||
}
|
||||
|
||||
export class PageSize extends XmlComponent {
|
||||
constructor(width: number | string, height: number | string, orientation: PageOrientation) {
|
||||
public constructor(width: number | string, height: number | string, orientation: PageOrientation) {
|
||||
super("w:pgSz");
|
||||
|
||||
const flip = orientation === PageOrientation.LANDSCAPE;
|
||||
|
@ -10,7 +10,7 @@ class PageTextDirectionAttributes extends XmlAttributeComponent<{ readonly val:
|
||||
}
|
||||
|
||||
export class PageTextDirection extends XmlComponent {
|
||||
constructor(value: PageTextDirectionType) {
|
||||
public constructor(value: PageTextDirectionType) {
|
||||
super("w:textDirection");
|
||||
|
||||
this.root.push(
|
||||
|
@ -30,7 +30,7 @@ export class SectionTypeAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class Type extends XmlComponent {
|
||||
constructor(value: SectionType) {
|
||||
public constructor(value: SectionType) {
|
||||
super("w:type");
|
||||
this.root.push(new SectionTypeAttributes({ val: value }));
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ export const sectionPageSizeDefaults = {
|
||||
};
|
||||
|
||||
export class SectionProperties extends XmlComponent {
|
||||
constructor({
|
||||
public constructor({
|
||||
page: {
|
||||
size: {
|
||||
width = sectionPageSizeDefaults.WIDTH,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { XmlAttributeComponent } from "@file/xml-components";
|
||||
|
||||
/* cSpell:disable */
|
||||
export interface IDocumentAttributesProperties {
|
||||
readonly wpc?: string;
|
||||
readonly mc?: string;
|
||||
@ -41,6 +42,7 @@ export interface IDocumentAttributesProperties {
|
||||
readonly w16sdtdh?: string;
|
||||
readonly w16se?: string;
|
||||
}
|
||||
/* cSpell:enable */
|
||||
|
||||
export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
|
||||
protected readonly xmlKeys = {
|
||||
|
@ -63,7 +63,7 @@ export interface IDocumentBackgroundOptions {
|
||||
// </xsd:complexType>
|
||||
|
||||
export class DocumentBackground extends XmlComponent {
|
||||
constructor(options: IDocumentBackgroundOptions) {
|
||||
public constructor(options: IDocumentBackgroundOptions) {
|
||||
super("w:background");
|
||||
|
||||
this.root.push(
|
||||
|
@ -33,7 +33,7 @@ export interface IDocumentOptions {
|
||||
export class Document extends XmlComponent {
|
||||
private readonly body: Body;
|
||||
|
||||
constructor(options: IDocumentOptions) {
|
||||
public constructor(options: IDocumentOptions) {
|
||||
super("w:document");
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
|
@ -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";
|
||||
|
||||
@ -6,8 +10,8 @@ import { IDrawingOptions } from "../drawing";
|
||||
import { TextWrappingType } from "../text-wrap";
|
||||
import { Anchor } from "./anchor";
|
||||
|
||||
function createAnchor(drawingOptions: IDrawingOptions): Anchor {
|
||||
return new Anchor(
|
||||
const createAnchor = (drawingOptions: IDrawingOptions): Anchor =>
|
||||
new Anchor(
|
||||
{
|
||||
fileName: "test.png",
|
||||
stream: new Buffer(""),
|
||||
@ -34,9 +38,16 @@ function createAnchor(drawingOptions: IDrawingOptions): Anchor {
|
||||
},
|
||||
drawingOptions,
|
||||
);
|
||||
}
|
||||
|
||||
describe("Anchor", () => {
|
||||
before(() => {
|
||||
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||
});
|
||||
|
||||
let anchor: Anchor;
|
||||
|
||||
describe("#constructor()", () => {
|
||||
@ -363,5 +374,236 @@ describe("Anchor", () => {
|
||||
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": {},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ import { AnchorAttributes } from "./anchor-attributes";
|
||||
// <xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/>
|
||||
// </xsd:complexType>
|
||||
export class Anchor extends XmlComponent {
|
||||
constructor(mediaData: IMediaData, transform: IMediaDataTransformation, drawingOptions: IDrawingOptions) {
|
||||
public constructor(mediaData: IMediaData, transform: IMediaDataTransformation, drawingOptions: IDrawingOptions) {
|
||||
super("wp:anchor");
|
||||
|
||||
const floating: IFloating = {
|
||||
@ -90,7 +90,7 @@ export class Anchor extends XmlComponent {
|
||||
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 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",
|
||||
};
|
||||
}
|
@ -1,15 +1,36 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
import { DocPropertiesAttributes } from "./doc-properties-attributes";
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { uniqueNumericId } from "@util/convenience-functions";
|
||||
|
||||
class DocPropertiesAttributes extends XmlAttributeComponent<{
|
||||
readonly id?: number;
|
||||
readonly name?: string;
|
||||
readonly description?: string;
|
||||
readonly title?: string;
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
id: "id",
|
||||
name: "name",
|
||||
description: "descr",
|
||||
title: "title",
|
||||
};
|
||||
}
|
||||
|
||||
export interface DocPropertiesOptions {
|
||||
readonly name: string;
|
||||
readonly description: string;
|
||||
readonly title: string;
|
||||
}
|
||||
|
||||
export class DocProperties extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor({ name, description, title }: DocPropertiesOptions = { name: "", description: "", title: "" }) {
|
||||
super("wp:docPr");
|
||||
|
||||
this.root.push(
|
||||
new DocPropertiesAttributes({
|
||||
id: 0,
|
||||
name: "",
|
||||
descr: "",
|
||||
id: uniqueNumericId(),
|
||||
name,
|
||||
description,
|
||||
title,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { expect } from "chai";
|
||||
import { SinonStub, stub } from "sinon";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
import * as convenienceFunctions from "@util/convenience-functions";
|
||||
|
||||
import { Drawing, IDrawingOptions } from "./drawing";
|
||||
|
||||
const imageBase64Data = `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`;
|
||||
|
||||
function createDrawing(drawingOptions?: IDrawingOptions): Drawing {
|
||||
return new Drawing(
|
||||
const createDrawing = (drawingOptions?: IDrawingOptions): Drawing =>
|
||||
new Drawing(
|
||||
{
|
||||
fileName: "test.jpg",
|
||||
stream: Buffer.from(imageBase64Data, "base64"),
|
||||
@ -24,9 +26,16 @@ function createDrawing(drawingOptions?: IDrawingOptions): Drawing {
|
||||
},
|
||||
drawingOptions,
|
||||
);
|
||||
}
|
||||
|
||||
describe("Drawing", () => {
|
||||
before(() => {
|
||||
stub(convenienceFunctions, "uniqueNumericId").callsFake(() => 0);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(convenienceFunctions.uniqueNumericId as SinonStub).restore();
|
||||
});
|
||||
|
||||
let currentBreak: Drawing;
|
||||
|
||||
describe("#constructor()", () => {
|
||||
@ -69,6 +78,7 @@ describe("Drawing", () => {
|
||||
descr: "",
|
||||
id: 0,
|
||||
name: "",
|
||||
title: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -299,6 +309,7 @@ describe("Drawing", () => {
|
||||
descr: "",
|
||||
id: 0,
|
||||
name: "",
|
||||
title: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { IMediaData } from "@file/media";
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { Anchor } from "./anchor";
|
||||
import { DocPropertiesOptions } from "./doc-properties/doc-properties";
|
||||
import { IFloating } from "./floating";
|
||||
import { Inline } from "./inline";
|
||||
|
||||
@ -13,6 +15,7 @@ export interface IDistance {
|
||||
|
||||
export interface IDrawingOptions {
|
||||
readonly floating?: IFloating;
|
||||
readonly docProperties?: DocPropertiesOptions;
|
||||
}
|
||||
|
||||
// <xsd:complexType name="CT_Drawing">
|
||||
@ -25,11 +28,15 @@ export interface IDrawingOptions {
|
||||
export class Drawing extends XmlComponent {
|
||||
private readonly inline: Inline;
|
||||
|
||||
constructor(imageData: IMediaData, drawingOptions: IDrawingOptions = {}) {
|
||||
public constructor(imageData: IMediaData, drawingOptions: IDrawingOptions = {}) {
|
||||
super("w:drawing");
|
||||
|
||||
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);
|
||||
} else {
|
||||
this.root.push(new Anchor(imageData, imageData.transformation, drawingOptions));
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { EffectExtentAttributes } from "./effect-extent-attributes";
|
||||
|
||||
export class EffectExtent extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("wp:effectExtent");
|
||||
|
||||
this.root.push(
|
||||
|
@ -5,7 +5,7 @@ import { ExtentAttributes } from "./extent-attributes";
|
||||
export class Extent extends XmlComponent {
|
||||
private readonly attributes: ExtentAttributes;
|
||||
|
||||
constructor(x: number, y: number) {
|
||||
public constructor(x: number, y: number) {
|
||||
super("wp:extent");
|
||||
|
||||
this.attributes = new ExtentAttributes({
|
||||
|
@ -3,7 +3,7 @@ import { HorizontalPositionAlign, VerticalPositionAlign } from "@file/shared/ali
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
export class Align extends XmlComponent {
|
||||
constructor(value: HorizontalPositionAlign | VerticalPositionAlign) {
|
||||
public constructor(value: HorizontalPositionAlign | VerticalPositionAlign) {
|
||||
super("wp:align");
|
||||
this.root.push(value);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class HorizontalPositionAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class HorizontalPosition extends XmlComponent {
|
||||
constructor(horizontalPosition: IHorizontalPositionOptions) {
|
||||
public constructor(horizontalPosition: IHorizontalPositionOptions) {
|
||||
super("wp:positionH");
|
||||
|
||||
this.root.push(
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
export class PositionOffset extends XmlComponent {
|
||||
constructor(offsetValue: number) {
|
||||
public constructor(offsetValue: number) {
|
||||
super("wp:posOffset");
|
||||
this.root.push(offsetValue.toString());
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class SimplePosAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class SimplePos extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("wp:simplePos");
|
||||
|
||||
// NOTE: It's not fully supported in Microsoft Word, but this element is needed anyway
|
||||
|
@ -13,7 +13,7 @@ class VerticalPositionAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class VerticalPosition extends XmlComponent {
|
||||
constructor(verticalPosition: IVerticalPositionOptions) {
|
||||
public constructor(verticalPosition: IVerticalPositionOptions) {
|
||||
super("wp:positionV");
|
||||
|
||||
this.root.push(
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { GraphicFrameLockAttributes } from "./graphic-frame-lock-attributes";
|
||||
|
||||
export class GraphicFrameLocks extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("a:graphicFrameLocks");
|
||||
|
||||
this.root.push(
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { GraphicFrameLocks } from "./graphic-frame-locks/graphic-frame-locks";
|
||||
|
||||
export class GraphicFrameProperties extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("wp:cNvGraphicFramePr");
|
||||
|
||||
this.root.push(new GraphicFrameLocks());
|
||||
|
@ -7,7 +7,7 @@ import { Pic } from "./pic";
|
||||
export class GraphicData extends XmlComponent {
|
||||
private readonly pic: Pic;
|
||||
|
||||
constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
|
||||
public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
|
||||
super("a:graphicData");
|
||||
|
||||
this.root.push(
|
||||
|
@ -6,7 +6,7 @@ import { SourceRectangle } from "./source-rectangle";
|
||||
import { Stretch } from "./stretch";
|
||||
|
||||
export class BlipFill extends XmlComponent {
|
||||
constructor(mediaData: IMediaData) {
|
||||
public constructor(mediaData: IMediaData) {
|
||||
super("pic:blipFill");
|
||||
|
||||
this.root.push(new Blip(mediaData));
|
||||
|
@ -12,7 +12,7 @@ class BlipAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class Blip extends XmlComponent {
|
||||
constructor(mediaData: IMediaData) {
|
||||
public constructor(mediaData: IMediaData) {
|
||||
super("a:blip");
|
||||
this.root.push(
|
||||
new BlipAttributes({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
export class SourceRectangle extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("a:srcRect");
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
class FillRectangle extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("a:fillRect");
|
||||
}
|
||||
}
|
||||
|
||||
export class Stretch extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("a:stretch");
|
||||
this.root.push(new FillRectangle());
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { PicLocks } from "./pic-locks/pic-locks";
|
||||
|
||||
export class ChildNonVisualProperties extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("pic:cNvPicPr");
|
||||
|
||||
this.root.push(new PicLocks());
|
||||
|
@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
|
||||
import { PicLocksAttributes } from "./pic-locks-attributes";
|
||||
|
||||
export class PicLocks extends XmlComponent {
|
||||
constructor() {
|
||||
public constructor() {
|
||||
super("a:picLocks");
|
||||
this.root.push(
|
||||
new PicLocksAttributes({
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user