Compare commits
303 Commits
Author | SHA1 | Date | |
---|---|---|---|
1403ac664b | |||
ba0a502d27 | |||
44d4b93d06 | |||
72abd4b7ac | |||
a473a98f17 | |||
f649dac62c | |||
ba7f937a7a | |||
1c8e6ae1db | |||
e09e201c45 | |||
409ea028cb | |||
fc86e1842d | |||
b614b74a2a | |||
e7eb415376 | |||
77c5a736dd | |||
a241a51cfd | |||
4e0468d978 | |||
cfe5970e54 | |||
27977edf82 | |||
7405a19ae8 | |||
ce32375d47 | |||
b33b7d2ebd | |||
b2b23bdc1c | |||
7f26badbc9 | |||
b19025881b | |||
5af1045a59 | |||
4d1a351649 | |||
8ba9a448d3 | |||
a708475539 | |||
9c60cfcbc7 | |||
a5454edc61 | |||
7152abfe48 | |||
075eeb7e3c | |||
f0acb3f3fb | |||
ae048833a1 | |||
ebae72004c | |||
13744abff5 | |||
492ef29d7f | |||
a6e6463a36 | |||
2ef596543b | |||
85005c3c07 | |||
0d2b433446 | |||
b1f67652e9 | |||
4e2befb7ef | |||
a887927968 | |||
ee6db1429a | |||
170309a7ed | |||
05fcf6edd4 | |||
eb2174e566 | |||
2a56360875 | |||
ba862766a6 | |||
71291dab8f | |||
974ba7b450 | |||
8f7df39c07 | |||
ca3d8f0121 | |||
46c517d195 | |||
ff37f3b460 | |||
7b9b474484 | |||
e80a50d36c | |||
df99f96469 | |||
f87ad6a43c | |||
8bf5220e31 | |||
da8148251a | |||
01183ac34d | |||
d553e4763a | |||
213c3d29f3 | |||
697c1d91c6 | |||
b22de4ac4f | |||
0af9d27dcc | |||
b89b571c4e | |||
64505a295f | |||
c247bbf409 | |||
4c60e6a0c0 | |||
086e5ef184 | |||
7e81f7b368 | |||
defa431aa9 | |||
17eb4fe8c4 | |||
3997ce538d | |||
3654eb0800 | |||
c6bb255641 | |||
05a3cf5b43 | |||
dece0f58e1 | |||
7f3c5615c9 | |||
56d23176b7 | |||
958538c96a | |||
9fa6d5392b | |||
d7fdbf9736 | |||
0af1279b1d | |||
2bb2333cb9 | |||
78c511cab9 | |||
4016e961a9 | |||
9f3888d94f | |||
316891a1f2 | |||
0a9d844dcc | |||
15b8d85562 | |||
d1f3df5600 | |||
0fc0921aa9 | |||
7ad4c5409c | |||
a645accf5d | |||
b64cb2d448 | |||
cfcea6c863 | |||
d1cd17ff6e | |||
408869fa96 | |||
ed146fbffd | |||
e49e1cc7b9 | |||
2c9233c021 | |||
b2ad04e4e7 | |||
2381ba8a05 | |||
9cff0b2a57 | |||
a4754ebcfe | |||
8988f471c3 | |||
5f4ff94e26 | |||
6f531c5abc | |||
c761a362d1 | |||
2e155ddebc | |||
9c8a07eadc | |||
9cb9c8c462 | |||
4268c9d466 | |||
26f77eb45f | |||
dea23e4349 | |||
0ade4b1557 | |||
165d48323b | |||
179598cc07 | |||
a8656ca3fe | |||
020e0eb669 | |||
e5dfce523a | |||
b53b4a77b4 | |||
dd86cf3d27 | |||
32953b3696 | |||
cfec058c9d | |||
a1c07d5a8e | |||
5be745b081 | |||
b4fcfd6386 | |||
6e371d42a7 | |||
e8564d58c6 | |||
368aa431a0 | |||
afcd1ae060 | |||
244d2b8904 | |||
6dae62e1ab | |||
5810cb5f02 | |||
11c26af3a9 | |||
1b9b815214 | |||
c342137c6f | |||
eefc8bd8a5 | |||
9873861210 | |||
cf7a05e05d | |||
6eb11d8842 | |||
3ad68337e7 | |||
07f363fcb7 | |||
2d2e4cdab2 | |||
0cadec7f58 | |||
e86dbd3398 | |||
021f1b0c4d | |||
5aa2027252 | |||
2fc297ef3c | |||
3fe216846c | |||
649a50f7c5 | |||
dc14123a5a | |||
048a035a5d | |||
f212cf0251 | |||
1f2f5988e1 | |||
f1359a4750 | |||
f2775ed13c | |||
3ae749278e | |||
0bcc6910f4 | |||
c15951550c | |||
8308b6413e | |||
5b75875684 | |||
28029f4c1c | |||
824d7f9893 | |||
b3aea4b9a0 | |||
32377d187d | |||
a80815822d | |||
c198154fdc | |||
618c7a8578 | |||
ef7b930d4d | |||
8296895cc6 | |||
1dce6fee15 | |||
444e7771b4 | |||
962795743c | |||
f98f852a55 | |||
e379a7fe04 | |||
022b25cfcd | |||
e20bd66663 | |||
6b8e22368b | |||
4304e82751 | |||
75715fde37 | |||
e779f6ea62 | |||
9280cdba50 | |||
8410d0c06d | |||
d47d85bdcf | |||
6ae45327fe | |||
464cd946dc | |||
cbff540b6e | |||
a8e6ba4c49 | |||
efc1ceaf1a | |||
c4ed19e589 | |||
13cf3eee5a | |||
24c159de37 | |||
7570fc2bf5 | |||
6929dee846 | |||
d4ac2a08ee | |||
010ef05ce3 | |||
fa401297da | |||
ce0e9936c3 | |||
c13e9938cf | |||
b8f97553b3 | |||
2550da199d | |||
682b679bdb | |||
e0fd7e751c | |||
9b57db4716 | |||
d23f453d28 | |||
6c28f8bab0 | |||
10b87b5a70 | |||
6b6f9d7ed4 | |||
0434d00ff7 | |||
7e3acc25b9 | |||
62ad8f12b7 | |||
a6a656f1a0 | |||
1bf36009e8 | |||
86bdf3e199 | |||
a3c796aae3 | |||
dbe0586f70 | |||
7e2538dffc | |||
c3080ff9d9 | |||
772fc8462a | |||
e194780cd1 | |||
5b80ea32d7 | |||
31b7e07ab3 | |||
939d418af1 | |||
4258dd2a2e | |||
b7334a1ab5 | |||
9229f45d59 | |||
2bd4aacdd5 | |||
abbd695a8f | |||
f7b98bcde8 | |||
a756a7697c | |||
fd1ea5b4dc | |||
d83e089cd3 | |||
33715cc50c | |||
f3f1f2d0b1 | |||
c35e706fa8 | |||
35cebfe1a2 | |||
d04c42cbe8 | |||
8744e613ac | |||
cbeecbf3e1 | |||
f8ab2d1701 | |||
adc5c6f594 | |||
c9524cc497 | |||
90de6ba7e1 | |||
78d74ae60b | |||
579593a467 | |||
b5393dadae | |||
528ab1933e | |||
36181f8c91 | |||
45af681db1 | |||
ad6b482136 | |||
a6e1c2b019 | |||
3eb98533ae | |||
f5f021834e | |||
35702c3f77 | |||
8fbbd571ad | |||
2dd228be69 | |||
562835cfe7 | |||
6bac06e84d | |||
88436168ee | |||
0c3206d2e2 | |||
033debd339 | |||
d4f160732a | |||
4238fc9ab4 | |||
0d042b8dd1 | |||
afdd5f2d8f | |||
70c7b3d1b3 | |||
7b1cd5fe86 | |||
09ab169ffd | |||
35a82cf12e | |||
8d33cb01dd | |||
438d11dd86 | |||
d23b0d0789 | |||
1fa8c7ac82 | |||
3d6ead0359 | |||
379050dccd | |||
f9d1c197cf | |||
a89ee463e6 | |||
036caaacc8 | |||
80c37afe2b | |||
3a36d912fe | |||
c741d5d8ac | |||
0fa7dd13ad | |||
d5d80550e7 | |||
23a0a59454 | |||
066aa56f6a | |||
3997b7a5d6 | |||
ccc391607a | |||
9577192d41 | |||
968c3aed0f | |||
9c7a80729b | |||
5f26ca1c94 | |||
f2b1587bff | |||
3b9f80fb1a | |||
8da57bec51 | |||
63db9f290c | |||
e8bd4bd6c6 | |||
28d93b0c42 |
@ -8,18 +8,23 @@
|
||||
// words - list of words to be always considered correct
|
||||
"words": [
|
||||
"Abjad",
|
||||
"aink",
|
||||
"aiueo",
|
||||
"ATLEAST",
|
||||
"chosung",
|
||||
"clippy",
|
||||
"datas",
|
||||
"dcmitype",
|
||||
"dcterms",
|
||||
"docsify",
|
||||
"dolan",
|
||||
"execa",
|
||||
"falsey",
|
||||
"horz",
|
||||
"iife",
|
||||
"Initializable",
|
||||
"iroha",
|
||||
"JOHAB",
|
||||
"jsonify",
|
||||
"jszip",
|
||||
"NUMPAGES",
|
||||
@ -30,6 +35,7 @@
|
||||
"panose",
|
||||
"rels",
|
||||
"rsid",
|
||||
"sdtdh",
|
||||
"twip",
|
||||
"twips",
|
||||
"Xmlable",
|
||||
@ -53,7 +59,8 @@
|
||||
"\\.to\\.include\\.members\\(\\[[^\\]]+]\\)",
|
||||
"/new [a-zA-Z]+\\({[^£]+}\\)/g",
|
||||
"/<element name=\"[a-z]+\"/gi",
|
||||
"/<attribute name=\"[a-z]+\"/gi"
|
||||
"/<attribute name=\"[a-z]+\"/gi",
|
||||
"/key: \".+\"/"
|
||||
],
|
||||
"ignorePaths": ["package.json", "docs/api", "*.docx", "build"],
|
||||
"allowCompoundWords": true,
|
||||
|
239
.eslintrc.yml
239
.eslintrc.yml
@ -1,239 +0,0 @@
|
||||
extends: eslint:recommended
|
||||
env:
|
||||
browser: true
|
||||
es6: true
|
||||
node: true
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
project:
|
||||
- tsconfig.json
|
||||
- demo/tsconfig.json
|
||||
sourceType: module
|
||||
plugins:
|
||||
- eslint-plugin-import
|
||||
- eslint-plugin-no-null
|
||||
- eslint-plugin-unicorn
|
||||
- eslint-plugin-jsdoc
|
||||
- eslint-plugin-prefer-arrow
|
||||
- "@typescript-eslint"
|
||||
- eslint-plugin-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: true
|
||||
allowTypedFunctionExpressions: true
|
||||
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"
|
||||
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-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"
|
||||
functional/immutable-data:
|
||||
- error
|
||||
- assumeTypes: true
|
||||
ignoreImmediateMutation: true
|
||||
ignoreAccessorPattern:
|
||||
- "**.root*"
|
||||
- "**.numberingReferences*"
|
||||
- "**.sections*"
|
||||
- "**.properties*"
|
||||
functional/prefer-property-signatures: error
|
||||
functional/no-mixed-types: error
|
||||
functional/prefer-readonly-type: error
|
||||
no-unused-vars:
|
||||
- error
|
||||
- argsIgnorePattern: ^[_]+$
|
||||
ignorePatterns:
|
||||
- vite.config.ts
|
||||
overrides:
|
||||
- files:
|
||||
- "*.spec.ts"
|
||||
rules:
|
||||
"@typescript-eslint/no-unused-expressions": "off"
|
||||
"@typescript-eslint/dot-notation": "off"
|
||||
prefer-destructuring: "off"
|
||||
"@typescript-eslint/explicit-function-return-type": "off"
|
12
.github/actions/install-and-build/action.yml
vendored
Normal file
12
.github/actions/install-and-build/action.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
name: Install dependencies and build ⚙️
|
||||
description: Install dependencies and build
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: npm ci --force
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: npm run build
|
14
.github/actions/validate-docx/action.yml
vendored
Normal file
14
.github/actions/validate-docx/action.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
name: Extract and Validate Document ⚙️
|
||||
description: Extract the document and validate the XML against the schema.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Extract Word Document
|
||||
shell: bash
|
||||
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
|
27
.github/workflows/default.yml
vendored
27
.github/workflows/default.yml
vendored
@ -13,13 +13,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Build
|
||||
run: npm run build
|
||||
uses: actions/checkout@v4
|
||||
- uses: "./.github/actions/install-and-build"
|
||||
- name: Archive Production Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
@ -28,22 +25,24 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Test
|
||||
run: npm run test.ci
|
||||
run: npm run test:ci
|
||||
- name: Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Lint
|
||||
@ -53,18 +52,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Prettier
|
||||
run: npm run style
|
||||
run: npm run prettier
|
||||
cspell:
|
||||
name: CSpell
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Prettier
|
||||
- name: CSpell
|
||||
run: npm run cspell
|
||||
|
943
.github/workflows/demos.yml
vendored
943
.github/workflows/demos.yml
vendored
@ -8,792 +8,189 @@ on:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Archive Production Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
demos:
|
||||
name: Run Demos and Validate
|
||||
needs: [build]
|
||||
name: Demos
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: build
|
||||
path: build
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/1-basic.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/2-declaritive-styles.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/3-numbering-and-bullet-points.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/4-basic-table.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/5-images.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/6-page-borders.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/7-landscape.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/8-header-footer.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/9-images-in-header-and-footer.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/10-my-cv.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/11-declaritive-styles-2.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/12-scaling-images.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/13-xml-styles.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/14-page-numbers.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/15-page-break-before.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/16-multiple-sections.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/17-footnotes.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- uses: actions/checkout@v4
|
||||
- uses: "./.github/actions/install-and-build"
|
||||
- name: Run Demos
|
||||
run: npm run run-ts -- ./demo/1-basic.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/2-declaritive-styles.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/3-numbering-and-bullet-points.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/4-basic-table.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/5-images.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/6-page-borders.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/7-landscape.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/8-header-footer.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/9-images-in-header-and-footer.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/10-my-cv.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/11-declaritive-styles-2.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/12-scaling-images.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/13-xml-styles.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/14-page-numbers.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/15-page-break-before.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/16-multiple-sections.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/17-footnotes.ts
|
||||
# element r: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}r': This element is not expected.
|
||||
# - 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/18-image-from-buffer.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/19-export-to-base64.ts
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/18-image-from-buffer.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/19-export-to-base64.ts
|
||||
# Base 64 No longer works, abruptly. Node issue?
|
||||
# - name: Extract Word Document
|
||||
# run: npm run extract
|
||||
# - name: Validate XML
|
||||
# uses: ChristophWurst/xmllint-action@v1
|
||||
# with:
|
||||
# xml-file: build/extracted-doc/word/document.xml
|
||||
# xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/20-table-cell-borders.ts
|
||||
- name: Extract Word Document
|
||||
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/21-bookmarks.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/20-table-cell-borders.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/21-bookmarks.ts
|
||||
# Bad ID - need numeric ID
|
||||
# - 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/22-right-to-left-text.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/23-base64-images.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/24-images-to-table-cell.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/25-table-xml-styles.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/26-paragraph-borders.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/27-declaritive-styles-3.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/28-table-of-contents.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/29-numbered-lists.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/31-tables.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/32-merge-and-shade-table-cells.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/33-sequential-captions.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/34-floating-tables.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/22-right-to-left-text.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/23-base64-images.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/24-images-to-table-cell.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/25-table-xml-styles.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/26-paragraph-borders.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/27-declaritive-styles-3.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/28-table-of-contents.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/29-numbered-lists.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/31-tables.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/32-merge-and-shade-table-cells.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/33-sequential-captions.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/34-floating-tables.ts
|
||||
# element tblpPr: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tblpPr', attribute 'overlap': The attribute 'overlap' is not allowed.
|
||||
# element tblpPr: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tblpPr': Element content is not allowed, because the content type is empty.
|
||||
# - 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/35-hyperlinks.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/36-image-to-table-cell.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/37-images-to-header-and-footer.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/38-text-wrapping.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/39-page-numbers.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/40-line-numbers.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/41-merge-table-cells-2.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/42-restart-page-numbers.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/43-images-to-table-cell-2.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/44-multiple-columns.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/45-highlighting-text.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/46-shading-text.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/47-number-of-total-pages-section.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/48-vertical-align.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/49-table-borders.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/50-readme-demo.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/51-character-styles.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/52-japanese.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/53-chinese.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/54-custom-properties.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/55-math.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/35-hyperlinks.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/36-image-to-table-cell.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/37-images-to-header-and-footer.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/38-text-wrapping.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/39-page-numbers.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/40-line-numbers.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/41-merge-table-cells-2.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/42-restart-page-numbers.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/43-images-to-table-cell-2.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/44-multiple-columns.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/45-highlighting-text.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/46-shading-text.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/47-number-of-total-pages-section.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/48-vertical-align.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/49-table-borders.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/50-readme-demo.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/51-character-styles.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/52-japanese.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/53-chinese.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/54-custom-properties.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/55-math.ts
|
||||
#: element subHide: Schemas validity error : Element '{http://schemas.openxmlformats.org/officeDocument/2006/math}subHide': This element is not expected. Expected is ( {http://schemas.openxmlformats.org/officeDocument/2006/math}ctrlPr ).
|
||||
#: element e: Schemas validity error : Element '{http://schemas.openxmlformats.org/officeDocument/2006/math}e': This element is not expected. Expected is ( {http://schemas.openxmlformats.org/officeDocument/2006/math}sub ).
|
||||
#: element e: Schemas validity error : Element '{http://schemas.openxmlformats.org/officeDocument/2006/math}e': This element is not expected. Expected is ( {http://schemas.openxmlformats.org/officeDocument/2006/math}sup ).
|
||||
#: element e: Schemas validity error : Element '{http://schemas.openxmlformats.org/officeDocument/2006/math}e': This element is not expected. Expected is ( {http://schemas.openxmlformats.org/officeDocument/2006/math}sub ).
|
||||
# - 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/56-background-color.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/57-add-parent-numbered-lists.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/58-section-types.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/59-header-footer-margins.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/60-track-revisions.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/56-background-color.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/57-add-parent-numbered-lists.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/58-section-types.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/59-header-footer-margins.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/60-track-revisions.ts
|
||||
# element r: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}r': This element is not expected.
|
||||
# - 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/61-text-frame.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/61-text-frame.ts
|
||||
# element left: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}left': This element is not expected. Expected is one of ( {http://schemas.openxmlformats.org/wordprocessingml/2006/main}right, {http://schemas.openxmlformats.org/wordprocessingml/2006/main}between, {http://schemas.openxmlformats.org/wordprocessingml/2006/main}bar ).
|
||||
# - 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/62-paragraph-spacing.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/63-odd-even-header-footer.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/64-complex-numbering-text.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/65-page-sizes.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/66-fields.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/62-paragraph-spacing.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/63-odd-even-header-footer.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/64-complex-numbering-text.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/65-page-sizes.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/66-fields.ts
|
||||
# element bookmarkStart: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}bookmarkStart', attribute '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}id': '-irrswq-ln94j4fdgdjxs' is not a valid value of the atomic type '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}ST_DecimalNumber'.
|
||||
# element bookmarkEnd: Schemas validity error : Element '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}bookmarkEnd', attribute '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}id': '-irrswq-ln94j4fdgdjxs' is not a valid value of the atomic type '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}ST_DecimalNumber'.
|
||||
# - 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/67-column-break.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/68-numbering-instances-and-starting-number.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/69-different-width-columns.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/70-line-numbers-suppression.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/71-page-borders-2.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/72-word-wrap.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/73-comments.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/73-comments.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
# - name: Run Demo
|
||||
# run: npm run ts-node -- ./demo/75-tab-stops.ts
|
||||
# - name: Extract Word Document
|
||||
# run: npm run extract
|
||||
# - name: Validate XML
|
||||
# uses: ChristophWurst/xmllint-action@v1
|
||||
# with:
|
||||
# xml-file: build/extracted-doc/word/document.xml
|
||||
# xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/76-compatibility.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/77-side-by-side-tables.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/78-thai-distributed.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/79-table-from-data-source.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/80-thai-distributed.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/81-continuous-header.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/82-new-headers-new-section.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/83-setting-languages.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
- name: Run Demo
|
||||
run: npm run ts-node -- ./demo/84-positional-tabs.ts
|
||||
- name: Extract Word Document
|
||||
run: npm run extract
|
||||
- name: Validate XML
|
||||
uses: ChristophWurst/xmllint-action@v1
|
||||
with:
|
||||
xml-file: build/extracted-doc/word/document.xml
|
||||
xml-schema-file: ooxml-schemas/microsoft/wml-2010.xsd
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/67-column-break.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/68-numbering-instances-and-starting-number.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/69-different-width-columns.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/70-line-numbers-suppression.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/71-page-borders-2.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/72-word-wrap.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/73-comments.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/74-nodejs-stream.ts
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
# run: npm run run-ts -- ./demo/75-tab-stops.ts
|
||||
# - uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/76-compatibility.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/77-side-by-side-tables.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/78-thai-distributed.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/79-table-from-data-source.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/80-thai-distributed.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/81-continuous-header.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/82-new-headers-new-section.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/83-setting-languages.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
- run: npm run run-ts -- ./demo/84-positional-tabs.ts
|
||||
- uses: "./.github/actions/validate-docx"
|
||||
|
8
.github/workflows/github-pages.yml
vendored
8
.github/workflows/github-pages.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Build 🔧
|
||||
@ -19,7 +19,7 @@ jobs:
|
||||
echo "docx.js.org" > docs/.nojekyll
|
||||
echo "docx.js.org" > docs/CNAME
|
||||
- name: Archive Production Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: docs
|
||||
@ -28,11 +28,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo 🛎️
|
||||
uses: actions/checkout@master
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: npm ci --force
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@master
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docs
|
||||
path: docs
|
||||
|
46
.github/workflows/npm-publish.yml
vendored
Normal file
46
.github/workflows/npm-publish.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
||||
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
||||
|
||||
name: Node.js Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20.x"
|
||||
- run: npm ci --force
|
||||
- run: npm run cspell
|
||||
- run: npm run prettier
|
||||
- run: npm run lint
|
||||
- run: npm run test:ci
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20.x"
|
||||
- run: npm ci --force
|
||||
- run: npm run build
|
||||
|
||||
publish-npm:
|
||||
needs: [test, build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20.x"
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- run: npm ci --force
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -33,8 +33,7 @@ node_modules
|
||||
.node_repl_history
|
||||
|
||||
# build
|
||||
build
|
||||
build-tests
|
||||
dist
|
||||
|
||||
# Documentation
|
||||
docs/api/
|
||||
|
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@ -1,18 +1,4 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Demo",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeArgs": [
|
||||
"-r",
|
||||
"${workspaceFolder}/node_modules/ts-node/register",
|
||||
"-r",
|
||||
"${workspaceFolder}/node_modules/tsconfig-paths/register"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"program": "${workspaceFolder}/demo/85-template-document.ts"
|
||||
}
|
||||
]
|
||||
"configurations": []
|
||||
}
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -5,5 +5,6 @@
|
||||
"editor.formatOnSave": false,
|
||||
"prettier.tabWidth": 4,
|
||||
"prettier.arrowParens": "always",
|
||||
"prettier.bracketSpacing": true
|
||||
"prettier.bracketSpacing": true,
|
||||
"eslint.useFlatConfig": true
|
||||
}
|
||||
|
20
.vscode/tasks.json
vendored
20
.vscode/tasks.json
vendored
@ -2,23 +2,5 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "ts-node",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
"tasks": []
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
[![Known Vulnerabilities][snky-image]][snky-url]
|
||||
[![PRs Welcome][pr-image]][pr-url]
|
||||
[![codecov][codecov-image]][codecov-url]
|
||||
[![Docx.js Editor][docxjs-editor-image]][docxjs-editor-url]
|
||||
|
||||
<p align="center">
|
||||
<img src="https://i.imgur.com/QeL1HuU.png" alt="drawing"/>
|
||||
@ -64,6 +65,10 @@ More [here](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||
|
||||
Please refer to the [documentation at https://docx.js.org/](https://docx.js.org/) for details on how to use this library, examples and much more!
|
||||
|
||||
# Playground
|
||||
|
||||
Experience `docx` in action through [Docx.js Editor][docxjs-editor-url], an interactive playground where you can code and preview the results in real-time.
|
||||
|
||||
# Examples
|
||||
|
||||
Check the [demo folder](https://github.com/dolanmiu/docx/tree/master/demo) for examples.
|
||||
@ -88,6 +93,7 @@ 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/)
|
||||
[<img src="https://i.imgur.com/9tqJaHw.png" alt="drawing" height="50"/>](https://novelpad.co/)
|
||||
[<img src="https://i.imgur.com/5bLKFeP.png" alt="drawing" height="50"/>](https://proton.me/)
|
||||
|
||||
...and many more!
|
||||
|
||||
@ -114,3 +120,5 @@ Made with 💖
|
||||
[patreon-url]: https://www.patreon.com/dolanmiu
|
||||
[browserstack-image]: https://user-images.githubusercontent.com/2917613/54233552-128e9d00-4505-11e9-88fb-025a4e04007c.png
|
||||
[browserstack-url]: https://www.browserstack.com
|
||||
[docxjs-editor-image]: https://img.shields.io/badge/Docx.js%20Editor-2b579a.svg?style=flat&logo=javascript&logoColor=white
|
||||
[docxjs-editor-url]: https://docxjs-editor.vercel.app/
|
||||
|
24
SECURITY.md
Normal file
24
SECURITY.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Use this section to tell people about which versions of your project are
|
||||
currently being supported with security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 9.0.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We encourage responsible disclosure of security vulnerabilities. If you believe you have found a security vulnerability in this project, please report it via the [Security Tab](https://github.com/dolanmiu/docx/security/advisories)
|
||||
|
||||
Please include the following information in your report:
|
||||
|
||||
* A description of the vulnerability
|
||||
* Steps to reproduce the vulnerability
|
||||
* Impact of the vulnerability
|
||||
|
||||
We will investigate all reported vulnerabilities and take appropriate action.
|
||||
|
||||
We appreciate your help in keeping this project secure.
|
@ -45,7 +45,7 @@ const doc = new Document({
|
||||
children: [
|
||||
new TextRun("My Title "),
|
||||
new TextRun({
|
||||
children: ["Footer - Page ", PageNumber.CURRENT],
|
||||
children: ["Footer - Page ", PageNumber.CURRENT, " of ", PageNumber.TOTAL_PAGES],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
convertMillimetersToTwip,
|
||||
Document,
|
||||
HorizontalPositionAlign,
|
||||
HorizontalPositionRelativeFrom,
|
||||
@ -20,6 +21,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/image1.jpeg"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
@ -36,17 +38,24 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "png",
|
||||
data: fs.readFileSync("./demo/images/dog.png").toString("base64"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
outline: {
|
||||
type: "solidFill",
|
||||
solidFillType: "rgb",
|
||||
value: "FF0000",
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/cat.jpg"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
@ -55,12 +64,19 @@ const doc = new Document({
|
||||
vertical: true,
|
||||
},
|
||||
},
|
||||
outline: {
|
||||
type: "solidFill",
|
||||
solidFillType: "rgb",
|
||||
value: "0000FF",
|
||||
width: convertMillimetersToTwip(600),
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "bmp",
|
||||
data: fs.readFileSync("./demo/images/parrots.bmp"),
|
||||
transformation: {
|
||||
width: 150,
|
||||
@ -76,6 +92,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "gif",
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -91,6 +108,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "gif",
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -112,6 +130,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/cat.jpg"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -131,6 +150,22 @@ const doc = new Document({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "svg",
|
||||
data: fs.readFileSync("./demo/images/linux-svg.svg"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
},
|
||||
fallback: {
|
||||
type: "png",
|
||||
data: fs.readFileSync("./demo/images/linux-png.png"),
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -21,6 +21,8 @@ import {
|
||||
Packer,
|
||||
Paragraph,
|
||||
TextRun,
|
||||
MathLimitLower,
|
||||
MathLimitUpper,
|
||||
} from "docx";
|
||||
|
||||
const doc = new Document({
|
||||
@ -316,6 +318,23 @@ const doc = new Document({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new Math({
|
||||
children: [
|
||||
new MathLimitUpper({
|
||||
children: [new MathRun("x")],
|
||||
limit: [new MathRun("-")],
|
||||
}),
|
||||
new MathRun("="),
|
||||
new MathLimitLower({
|
||||
children: [new MathRun("lim")],
|
||||
limit: [new MathRun("x→0")],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
AlignmentType,
|
||||
BorderStyle,
|
||||
Document,
|
||||
FrameAnchorType,
|
||||
@ -20,6 +21,7 @@ const doc = new Document({
|
||||
children: [
|
||||
new Paragraph({
|
||||
frame: {
|
||||
type: "absolute",
|
||||
position: {
|
||||
x: 1000,
|
||||
y: 3000,
|
||||
@ -30,6 +32,54 @@ const doc = new Document({
|
||||
horizontal: FrameAnchorType.MARGIN,
|
||||
vertical: FrameAnchorType.MARGIN,
|
||||
},
|
||||
},
|
||||
border: {
|
||||
top: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
bottom: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
left: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
right: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
},
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
frame: {
|
||||
type: "alignment",
|
||||
width: 4000,
|
||||
height: 1000,
|
||||
anchor: {
|
||||
horizontal: FrameAnchorType.MARGIN,
|
||||
vertical: FrameAnchorType.MARGIN,
|
||||
},
|
||||
alignment: {
|
||||
x: HorizontalPositionAlign.CENTER,
|
||||
y: VerticalPositionAlign.TOP,
|
||||
@ -73,6 +123,59 @@ const doc = new Document({
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new Paragraph({
|
||||
frame: {
|
||||
type: "alignment",
|
||||
width: 4000,
|
||||
height: 1000,
|
||||
anchor: {
|
||||
horizontal: FrameAnchorType.MARGIN,
|
||||
vertical: FrameAnchorType.MARGIN,
|
||||
},
|
||||
alignment: {
|
||||
x: HorizontalPositionAlign.CENTER,
|
||||
y: VerticalPositionAlign.BOTTOM,
|
||||
},
|
||||
},
|
||||
border: {
|
||||
top: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
bottom: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
left: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
right: {
|
||||
color: "auto",
|
||||
space: 1,
|
||||
style: BorderStyle.SINGLE,
|
||||
size: 6,
|
||||
},
|
||||
},
|
||||
alignment: AlignmentType.RIGHT,
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
}),
|
||||
new TextRun({
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -107,5 +107,5 @@ const doc = new Document({
|
||||
|
||||
// Used to export the file into a .docx file
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("6-numbering.docx", buffer);
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Example demonstrating page borders with style, colors and size
|
||||
|
||||
import { BorderStyle, Document, Packer, PageBorderDisplay, PageBorderOffsetFrom, PageBorderZOrder, Paragraph, TextRun } from "docx";
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, TextRun, Paragraph, BorderStyle, PageBorderDisplay, PageBorderOffsetFrom, PageBorderZOrder } from "docx";
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Simple example to add comments to a document
|
||||
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, TextRun, CommentRangeStart, CommentRangeEnd, CommentReference } from "docx";
|
||||
import { Document, Packer, Paragraph, TextRun, CommentRangeStart, CommentRangeEnd, CommentReference, ImageRun } from "docx";
|
||||
|
||||
const doc = new Document({
|
||||
comments: {
|
||||
@ -20,6 +20,14 @@ const doc = new Document({
|
||||
}),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/cat.jpg"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
}),
|
||||
new TextRun({
|
||||
text: "comment text content",
|
||||
}),
|
||||
|
@ -18,6 +18,7 @@ const receiptTabStops = [
|
||||
const twoTabStops = [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }];
|
||||
|
||||
const doc = new Document({
|
||||
defaultTabStop: 0,
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
|
@ -16,7 +16,9 @@ import {
|
||||
VerticalAlign,
|
||||
} from "docx";
|
||||
|
||||
patchDocument(fs.readFileSync("demo/assets/simple-template.docx"), {
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/simple-template.docx"),
|
||||
patches: {
|
||||
name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
@ -56,7 +58,11 @@ patchDocument(fs.readFileSync("demo/assets/simple-template.docx"), {
|
||||
],
|
||||
link: "https://www.google.co.uk",
|
||||
}),
|
||||
new ImageRun({ data: fs.readFileSync("./demo/images/dog.png"), transformation: { width: 100, height: 100 } }),
|
||||
new ImageRun({
|
||||
type: "png",
|
||||
data: fs.readFileSync("./demo/images/dog.png"),
|
||||
transformation: { width: 100, height: 100 },
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
@ -82,7 +88,13 @@ patchDocument(fs.readFileSync("demo/assets/simple-template.docx"), {
|
||||
},
|
||||
image_test: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new ImageRun({ data: fs.readFileSync("./demo/images/image1.jpeg"), transformation: { width: 100, height: 100 } })],
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/image1.jpeg"),
|
||||
transformation: { width: 100, height: 100 },
|
||||
}),
|
||||
],
|
||||
},
|
||||
table: {
|
||||
type: PatchType.DOCUMENT,
|
||||
|
@ -3,7 +3,9 @@
|
||||
import * as fs from "fs";
|
||||
import { patchDocument, PatchType, TextRun } from "docx";
|
||||
|
||||
patchDocument(fs.readFileSync("demo/assets/simple-template-2.docx"), {
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/simple-template-2.docx"),
|
||||
patches: {
|
||||
name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
|
@ -24,7 +24,9 @@ const patches = getPatches({
|
||||
paragraph_replace: "Lorem ipsum paragraph",
|
||||
});
|
||||
|
||||
patchDocument(fs.readFileSync("demo/assets/simple-template.docx"), {
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/simple-template.docx"),
|
||||
patches,
|
||||
}).then((doc) => {
|
||||
fs.writeFileSync("My Document.docx", doc);
|
||||
|
@ -22,8 +22,11 @@ const patches = getPatches({
|
||||
"first-name": "John",
|
||||
});
|
||||
|
||||
patchDocument(fs.readFileSync("demo/assets/simple-template-3.docx"), {
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/simple-template-3.docx"),
|
||||
patches,
|
||||
keepOriginalStyles: true,
|
||||
}).then((doc) => {
|
||||
fs.writeFileSync("My Document.docx", doc);
|
||||
});
|
||||
|
40
demo/91-custom-fonts.ts
Normal file
40
demo/91-custom-fonts.ts
Normal file
@ -0,0 +1,40 @@
|
||||
// Simple example to add text to a document
|
||||
|
||||
import * as fs from "fs";
|
||||
import { CharacterSet, Document, Packer, Paragraph, Tab, TextRun } from "docx";
|
||||
|
||||
const font = fs.readFileSync("./demo/assets/Pacifico.ttf");
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [
|
||||
new Paragraph({
|
||||
run: {
|
||||
font: "Pacifico",
|
||||
},
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
size: 40,
|
||||
font: "Pacifico",
|
||||
}),
|
||||
new TextRun({
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
font: "Pacifico",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
fonts: [{ name: "Pacifico", data: font, characterSet: CharacterSet.ANSI }],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
44
demo/92-declarative-custom-fonts.ts
Normal file
44
demo/92-declarative-custom-fonts.ts
Normal file
@ -0,0 +1,44 @@
|
||||
// Simple example to add text to a document
|
||||
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, Paragraph, Tab, TextRun } from "docx";
|
||||
|
||||
const font = fs.readFileSync("./demo/assets/Pacifico.ttf");
|
||||
|
||||
const doc = new Document({
|
||||
styles: {
|
||||
default: {
|
||||
document: {
|
||||
run: {
|
||||
font: "Pacifico",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("Hello World"),
|
||||
new TextRun({
|
||||
text: "Foo Bar",
|
||||
bold: true,
|
||||
size: 40,
|
||||
}),
|
||||
new TextRun({
|
||||
children: [new Tab(), "Github is the best"],
|
||||
bold: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
fonts: [{ name: "Pacifico", data: font, characterSet: "00" }],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
72
demo/93-template-document.ts
Normal file
72
demo/93-template-document.ts
Normal file
@ -0,0 +1,72 @@
|
||||
// Patch a document with patches
|
||||
|
||||
import * as fs from "fs";
|
||||
import { patchDocument, PatchType, TextRun } from "docx";
|
||||
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/field-trip.docx"),
|
||||
patches: {
|
||||
todays_date: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: new Date().toLocaleDateString() })],
|
||||
},
|
||||
|
||||
school_name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
address: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "blah blah" })],
|
||||
},
|
||||
|
||||
city: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
state: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
zip: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
phone: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
first_name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
last_name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
email_address: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
ft_dates: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
|
||||
grade: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun({ text: "test" })],
|
||||
},
|
||||
},
|
||||
}).then((doc) => {
|
||||
fs.writeFileSync("My Document.docx", doc);
|
||||
});
|
43
demo/94-texbox.ts
Normal file
43
demo/94-texbox.ts
Normal file
@ -0,0 +1,43 @@
|
||||
// Simple example to add textbox to a document
|
||||
import { Document, Packer, Paragraph, Textbox, TextRun } from "docx";
|
||||
import * as fs from "fs";
|
||||
|
||||
const doc = new Document({
|
||||
sections: [
|
||||
{
|
||||
properties: {},
|
||||
children: [
|
||||
new Textbox({
|
||||
alignment: "center",
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [new TextRun("Hi i'm a textbox!")],
|
||||
}),
|
||||
],
|
||||
style: {
|
||||
width: "200pt",
|
||||
height: "auto",
|
||||
},
|
||||
}),
|
||||
new Textbox({
|
||||
alignment: "center",
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [new TextRun("Hi i'm a textbox with a hidden box!")],
|
||||
}),
|
||||
],
|
||||
style: {
|
||||
width: "300pt",
|
||||
height: 400,
|
||||
visibility: "hidden",
|
||||
zIndex: "auto",
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
60
demo/95-paragraph-style-with-shading-and-borders.ts
Normal file
60
demo/95-paragraph-style-with-shading-and-borders.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import * as fs from "fs";
|
||||
import { BorderStyle, Document, Packer, Paragraph, TextRun } from "docx";
|
||||
|
||||
const doc = new Document({
|
||||
styles: {
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: "withSingleBlackBordersAndYellowShading",
|
||||
name: "Paragraph Style with Black Borders and Yellow Shading",
|
||||
basedOn: "Normal",
|
||||
paragraph: {
|
||||
shading: {
|
||||
color: "#fff000",
|
||||
type: "solid",
|
||||
},
|
||||
border: {
|
||||
top: {
|
||||
style: BorderStyle.SINGLE,
|
||||
color: "#000000",
|
||||
size: 4,
|
||||
},
|
||||
bottom: {
|
||||
style: BorderStyle.SINGLE,
|
||||
color: "#000000",
|
||||
size: 4,
|
||||
},
|
||||
left: {
|
||||
style: BorderStyle.SINGLE,
|
||||
color: "#000000",
|
||||
size: 4,
|
||||
},
|
||||
right: {
|
||||
style: BorderStyle.SINGLE,
|
||||
color: "#000000",
|
||||
size: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
sections: [
|
||||
{
|
||||
children: [
|
||||
new Paragraph({
|
||||
style: "withSingleBlackBordersAndYellowShading",
|
||||
children: [
|
||||
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.",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
168
demo/96-template-document.ts
Normal file
168
demo/96-template-document.ts
Normal file
@ -0,0 +1,168 @@
|
||||
// Patch a document with patches
|
||||
|
||||
import * as fs from "fs";
|
||||
import {
|
||||
ExternalHyperlink,
|
||||
HeadingLevel,
|
||||
ImageRun,
|
||||
Paragraph,
|
||||
patchDocument,
|
||||
PatchType,
|
||||
Table,
|
||||
TableCell,
|
||||
TableRow,
|
||||
TextDirection,
|
||||
TextRun,
|
||||
VerticalAlign,
|
||||
} from "docx";
|
||||
|
||||
patchDocument({
|
||||
outputType: "nodebuffer",
|
||||
data: fs.readFileSync("demo/assets/simple-template-4.docx"),
|
||||
patches: {
|
||||
name: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun("Sir. "), new TextRun("John Doe"), new TextRun("(The Conqueror)")],
|
||||
},
|
||||
table_heading_1: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun("Heading wow!")],
|
||||
},
|
||||
item_1: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [
|
||||
new TextRun("#657"),
|
||||
new ExternalHyperlink({
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "BBC News Link",
|
||||
}),
|
||||
],
|
||||
link: "https://www.bbc.co.uk/news",
|
||||
}),
|
||||
],
|
||||
},
|
||||
paragraph_replace: {
|
||||
type: PatchType.DOCUMENT,
|
||||
children: [
|
||||
new Paragraph("Lorem ipsum paragraph"),
|
||||
new Paragraph("Another paragraph"),
|
||||
new Paragraph({
|
||||
children: [
|
||||
new TextRun("This is a "),
|
||||
new ExternalHyperlink({
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "Google Link",
|
||||
}),
|
||||
],
|
||||
link: "https://www.google.co.uk",
|
||||
}),
|
||||
new ImageRun({
|
||||
type: "png",
|
||||
data: fs.readFileSync("./demo/images/dog.png"),
|
||||
transformation: { width: 100, height: 100 },
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
header_adjective: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [new TextRun("Delightful Header")],
|
||||
},
|
||||
footer_text: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [
|
||||
new TextRun("replaced just as"),
|
||||
new TextRun(" well"),
|
||||
new ExternalHyperlink({
|
||||
children: [
|
||||
new TextRun({
|
||||
text: "BBC News Link",
|
||||
}),
|
||||
],
|
||||
link: "https://www.bbc.co.uk/news",
|
||||
}),
|
||||
],
|
||||
},
|
||||
image_test: {
|
||||
type: PatchType.PARAGRAPH,
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "jpg",
|
||||
data: fs.readFileSync("./demo/images/image1.jpeg"),
|
||||
transformation: { width: 100, height: 100 },
|
||||
}),
|
||||
],
|
||||
},
|
||||
table: {
|
||||
type: PatchType.DOCUMENT,
|
||||
children: [
|
||||
new Table({
|
||||
rows: [
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
children: [new Paragraph({}), new Paragraph({})],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({}), new Paragraph({})],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})],
|
||||
textDirection: TextDirection.BOTTOM_TO_TOP_LEFT_TO_RIGHT,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [new Paragraph({ text: "top to bottom" }), new Paragraph({})],
|
||||
textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new TableRow({
|
||||
children: [
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||
heading: HeadingLevel.HEADING_1,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "This text should be in the middle of the cell",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "Text above should be vertical from bottom to top",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
new TableCell({
|
||||
children: [
|
||||
new Paragraph({
|
||||
text: "Text above should be vertical from top to bottom",
|
||||
}),
|
||||
],
|
||||
verticalAlign: VerticalAlign.CENTER,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
placeholderDelimiters: { start: "<<", end: ">>" },
|
||||
}).then((doc) => {
|
||||
fs.writeFileSync("My Document.docx", doc);
|
||||
});
|
BIN
demo/assets/Pacifico.ttf
Normal file
BIN
demo/assets/Pacifico.ttf
Normal file
Binary file not shown.
BIN
demo/assets/field-trip.docx
Normal file
BIN
demo/assets/field-trip.docx
Normal file
Binary file not shown.
Binary file not shown.
BIN
demo/assets/simple-template-4.docx
Normal file
BIN
demo/assets/simple-template-4.docx
Normal file
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="../build/index.umd.js"></script>
|
||||
|
BIN
demo/images/linux-png.png
Normal file
BIN
demo/images/linux-png.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
183
demo/images/linux-svg.svg
Normal file
183
demo/images/linux-svg.svg
Normal file
@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="500pt" height="600pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/">
|
||||
|
||||
<defs>
|
||||
|
||||
<linearGradient id="linearGradient172">
|
||||
|
||||
<stop style="stop-color:#3f2600;stop-opacity:0.6;" offset="0" id="stop173" />
|
||||
|
||||
<stop style="stop-color:#3f2600;stop-opacity:0;" offset="1" id="stop174" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient167">
|
||||
|
||||
<stop style="stop-color:#ffffff;stop-opacity:0.65;" offset="0" id="stop168" />
|
||||
|
||||
<stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop169" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient162">
|
||||
|
||||
<stop style="stop-color:#ffa63f;stop-opacity:1;" offset="0" id="stop163" />
|
||||
|
||||
<stop style="stop-color:#ffff00;stop-opacity:1;" offset="1" id="stop164" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient153">
|
||||
|
||||
<stop style="stop-color:#ffeed7;stop-opacity:1;" offset="0" id="stop154" />
|
||||
|
||||
<stop style="stop-color:#bdbfc2;stop-opacity:1;" offset="1" id="stop155" /></linearGradient>
|
||||
|
||||
<linearGradient id="linearGradient138">
|
||||
|
||||
<stop style="stop-color:#ffffff;stop-opacity:0.8;" offset="0" id="stop139" />
|
||||
|
||||
<stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop140" />
|
||||
</linearGradient>
|
||||
<linearGradient xlink:href="#linearGradient138" id="linearGradient141" x1="0.47424799" y1="0.020191999" x2="0.417539" y2="0.90125799" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient142" x1="0.55880702" y1="0.031192999" x2="0.553922" y2="0.94531101" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient143" x1="0.46557701" y1="0.028819799" x2="0.41365999" y2="0.93366498" gradientUnits="objectBoundingBox"/>
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient144" x1="0.70346397" y1="0.059404202" x2="0.64553201" y2="0.94063401" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient145" x1="0.46741399" y1="-0.036155298" x2="0.86741799" y2="0.75857902" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient146" x1="0.57152498" y1="0.023441499" x2="0.57143003" y2="0.71875" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient147" x1="0.5" y1="0.0234362" x2="0.5" y2="0.8125" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient148" x1="0.50799799" y1="0.37435901" x2="0.51599997" y2="0.92820501" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient138" id="linearGradient149" x1="0.5" y1="0.131707" x2="0.50400001" y2="0.94634098" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient150" x1="-0.30509499" y1="0.099496603" x2="0.156323" y2="0.94191301" gradientUnits="objectBoundingBox" gradientTransform="matrix(-0.928523,0.283938,0.435332,0.943857,-1.91327e-7,5.49908e-8)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient151" x1="0.433979" y1="0.022184599" x2="0.487055" y2="1.02569" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient152" x1="0.5" y1="0.89842999" x2="0.5" y2="0.40625" gradientUnits="objectBoundingBox" spreadMethod="reflect" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient156" x1="0.43568701" y1="0.98882002" x2="0.453989" y2="0.23093501" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient157" x1="0.49180499" y1="1.15284" x2="0.49482101" y2="0.41252401" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient158" x1="0.51730198" y1="0.85418499" x2="0.49843901" y2="0.136172" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient159" x1="0.46201" y1="0.87917101" x2="0.49215299" y2="0.096282303" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient161" x1="0.50086302" y1="0.34872901" x2="0.41209599" y2="0.98558098" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient165" x1="0.60399801" y1="0.51020199" x2="0.46399999" y2="0.98367399" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient166" x1="0.50000501" y1="0.191616" x2="0.50800002" y2="0.97005898" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<radialGradient xlink:href="#linearGradient172" id="radialGradient171" cx="0.5" cy="0.5" fx="0.5" fy="0.5" r="0.5" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<radialGradient xlink:href="#linearGradient172" id="radialGradient176" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient178" x1="0.94027299" y1="1.2934099" x2="0.19452" y2="-0.675295" gradientUnits="objectBoundingBox" />
|
||||
|
||||
<radialGradient xlink:href="#linearGradient172" id="radialGradient1399" gradientTransform="scale(1.045233,0.956725)" cx="446.77762" cy="1219.4125" fx="446.77762" fy="1219.4125" r="195.07191" gradientUnits="userSpaceOnUse" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1401" gradientUnits="userSpaceOnUse" x1="400.57785" y1="369.53015" x2="400.84448" y2="304.07886" gradientTransform="scale(0.575262,1.738339)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient138" id="linearGradient1403" gradientUnits="userSpaceOnUse" x1="303.01761" y1="237.93179" x2="297.0856" y2="330.09561" gradientTransform="scale(1.116071,0.896001)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1405" gradientUnits="userSpaceOnUse" gradientTransform="scale(0.816497,1.224744)" x1="378.93771" y1="278.60202" x2="380.27319" y2="243.91606" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1407" gradientUnits="userSpaceOnUse" x1="381.38742" y1="277.495" x2="380.5517" y2="245.68338" gradientTransform="scale(0.816497,1.224744)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1409" gradientUnits="userSpaceOnUse" gradientTransform="scale(0.816497,1.224744)" x1="379.09573" y1="240.92712" x2="376.79556" y2="281.01636" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1411" gradientUnits="userSpaceOnUse" x1="389.63535" y1="242.28218" x2="387.06866" y2="281.32513" gradientTransform="scale(0.816497,1.224744)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1413" gradientUnits="userSpaceOnUse" spreadMethod="reflect" x1="437.57941" y1="528.87177" x2="437.57941" y2="394.10361" gradientTransform="scale(0.812855,1.230232)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1415" gradientUnits="userSpaceOnUse" x1="375.17325" y1="419.78485" x2="377.48541" y2="324.03815" gradientTransform="scale(0.649784,1.538974)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient138" id="linearGradient1417" gradientUnits="userSpaceOnUse" x1="320.75104" y1="498.17776" x2="321.32224" y2="614.50439" gradientTransform="scale(1.074798,0.930408)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1419" gradientUnits="userSpaceOnUse" x1="322.48257" y1="435.26761" x2="323.2514" y2="488.48251" gradientTransform="scale(1.077001,0.928504)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1421" gradientUnits="userSpaceOnUse" x1="411.2215" y1="242.94365" x2="411.2215" y2="331.44858" gradientTransform="scale(0.571707,1.749147)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1423" gradientUnits="userSpaceOnUse" x1="867.34546" y1="234.73897" x2="867.33453" y2="314.83911" gradientTransform="scale(0.572667,1.746214)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient1425" gradientUnits="userSpaceOnUse" x1="236.25362" y1="657.11133" x2="212.5099" y2="737.41229" gradientTransform="scale(1.011514,0.988617)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient153" id="linearGradient1427" gradientUnits="userSpaceOnUse" x1="381.56607" y1="655.73102" x2="279.64313" y2="386.66583" gradientTransform="scale(1.065499,0.938527)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient1429" gradientUnits="userSpaceOnUse" x1="218.11714" y1="630.30475" x2="203.12654" y2="737.8537" gradientTransform="scale(1.009851,0.990245)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1431" gradientUnits="userSpaceOnUse" gradientTransform="scale(1.007724,0.992335)" x1="117.88966" y1="587.23602" x2="182.24524" y2="704.73077" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1433" gradientUnits="userSpaceOnUse" x1="223.10072" y1="570.41809" x2="230.53499" y2="710.97723" gradientTransform="scale(0.999504,1.000496)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1435" gradientUnits="userSpaceOnUse" x1="316.93988" y1="474.01779" x2="371.60889" y2="582.63507" gradientTransform="scale(1.065499,0.938527)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient162" id="linearGradient1437" gradientUnits="userSpaceOnUse" x1="284.68652" y1="410.46326" x2="285.45923" y2="485.69934" gradientTransform="scale(1.218684,0.820557)" />
|
||||
|
||||
<linearGradient xlink:href="#linearGradient167" id="linearGradient1439" gradientUnits="userSpaceOnUse" x1="288.82358" y1="398.85422" x2="288.37628" y2="482.55939" gradientTransform="scale(1.221941,0.81837)" />
|
||||
</defs>
|
||||
|
||||
<g id="g1369" transform="translate(-310.7524,-64.25268)">
|
||||
|
||||
<path transform="matrix(1.4177,0,0,0.414745,-38.7944,222.194)" d="M 670.88202 1166.6423 A 203.89551 186.63016 0 1 1 263.091,1166.6423 A 203.89551 186.63016 0 1 1 670.88202 1166.6423 z" id="path175" style="fill:url(#radialGradient1399);stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path106" d="M 223.627,632.24 C 201.239,600.017 196.873,495.256 249.114,430.81 C 275,399.892 281.604,378.345 283.645,349.417 C 285.034,316.438 260.32,217.975 353.528,210.473 C 447.934,202.941 442.864,296.133 442.321,345.448 C 441.87,387.088 472.895,410.689 494.117,443.143 C 533.396,502.773 530.074,605.443 486.718,661.015 C 431.801,730.583 384.765,700.413 353.528,702.945 C 295.035,706.147 293.101,737.336 223.627,632.24 z " style="fill:#000000;stroke:none;stroke-width:1.25;" />
|
||||
|
||||
<path transform="matrix(-1.67739,-2.24516e-2,-2.11236e-2,1.4709,1173.58,-293.017)" id="path113" d="M 246.571,470.864 C 234.332,483.36 202.175,539.956 251.44,576.224 C 268.809,588.857 235.063,635.719 219.435,612.532 C 191.865,570.914 210.604,505.591 227.75,482.344 C 239.402,465.857 256.98,459.668 246.571,470.864 z " style="fill:url(#linearGradient1401);stroke:none;stroke-width:0.99464899;" />
|
||||
|
||||
<path transform="matrix(-1.67755,0,0,1.52374,1174.62,-318.082)" id="path111" d="M 256.513,459.837 C 236.598,477.554 200.337,539.928 253.225,580.443 C 270.595,593.075 237.832,632.906 219.435,612.532 C 155.472,541.712 221.104,460.278 243.697,432.282 C 263.889,407.935 281.775,438.034 256.513,459.837 z " style="fill:#000000;stroke:#000000;stroke-width:0.97729802;" />
|
||||
|
||||
<path transform="matrix(1.26626,-7.13667e-2,-4.59795e-2,1.19574,202.143,-125.761)" d="M 399.56879 258.15753 A 58.37323 46.863022 0 1 1 282.82233,258.15753 A 58.37323 46.863022 0 1 1 399.56879 258.15753 z" id="path114" style="fill:url(#linearGradient1403);stroke:none;stroke-width:1.26498997;" />
|
||||
|
||||
<path transform="matrix(1.30445,-7.55326e-2,7.71251e-2,1.34257,144.757,-177.617)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path115" style="fill:url(#linearGradient1405);stroke:none;stroke-width:1.17873001;" />
|
||||
|
||||
<path transform="matrix(-1.81082,4.95107e-2,3.17324e-2,1.55333,1207.46,-284.777)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path116" style="fill:url(#linearGradient1407);stroke:none;stroke-width:0.93138498;" />
|
||||
|
||||
<path transform="matrix(-0.823196,-1.76123e-3,-1.82321e-2,0.852662,913.674,-37.9902)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path117" style="fill:#000000;stroke:none;stroke-width:1.86495996;" />
|
||||
|
||||
<path transform="matrix(0.59438,-7.22959e-2,6.88176e-2,0.705838,367.448,32.4186)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path118" style="fill:#000000;stroke:none;stroke-width:2.39814997;" />
|
||||
|
||||
<path transform="matrix(-0.480323,-3.6454e-2,-4.67935e-2,0.475606,813.496,87.0124)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path121" style="fill:url(#linearGradient1409);stroke:none;stroke-width:3.1916101;" />
|
||||
|
||||
<path transform="matrix(0.35691,-4.08211e-2,4.13232e-2,0.398544,449.334,114.991)" d="M 328.86324 320.64151 A 18.087479 27.131195 0 1 1 292.68828,320.64151 A 18.087479 27.131195 0 1 1 328.86324 320.64151 z" id="path122" style="fill:url(#linearGradient1411);stroke:none;stroke-width:4.12025976;" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-168.23)" id="path128" d="M 258.702,495.425 C 271.538,466.322 298.816,415.199 299.397,375.667 C 299.397,344.225 393.576,336.716 401.134,368.109 C 408.692,399.502 427.875,446.592 440.084,469.265 C 452.292,491.937 487.893,563.96 449.968,626.811 C 415.811,682.455 312.243,726.477 256.958,619.254 C 238.355,582.047 241.673,535.939 258.702,495.425 z " style="fill:url(#linearGradient1413);stroke:none;stroke-width:1.25;" />
|
||||
|
||||
<path transform="matrix(1.38936,-0.111074,0.102211,1.30214,108.413,-165.938)" id="path112" d="M 242.905,473.815 C 231.642,492.782 207.405,543.124 255.042,575.862 C 306.353,610.682 301.515,672.924 239.435,637.817 C 182.658,606.028 216.59,500.039 234.925,475.551 C 247.032,458.337 264.822,437.52 242.905,473.815 z " style="fill:url(#linearGradient1415);stroke:none;stroke-width:1.15804005;" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path109" d="M 256.513,449.72 C 239.048,478.228 197.136,545.533 253.225,580.443 C 328.794,626.798 307.398,673.154 238.426,631.417 C 141.317,573.153 226.601,455.801 265.557,411.079 C 310.001,360.879 274.111,420.166 256.513,449.72 z " style="fill:#000000;stroke:#000000;stroke-width:1.25;" />
|
||||
|
||||
<path id="path125" d="M 421.481,504.727 C 421.481,537.139 392.209,579.243 341.953,578.865 C 290.125,579.32 268.004,537.139 268.004,504.727 C 268.004,472.315 302.383,446.01 344.743,446.01 C 387.102,446.01 421.481,472.315 421.481,504.727 z " style="font-size:12px;fill:url(#linearGradient1417);stroke:none;stroke-width:1.23705006;stroke-dasharray:none" transform="matrix(1.30209,0,0,1.22525,170.042,-153.557)" />
|
||||
|
||||
<path id="path127" d="M 398.227,412.292 C 397.615,450.864 375.047,459.963 346.487,459.963 C 317.926,459.963 297.195,454.269 294.746,412.292 C 294.746,385.978 317.926,370.75 346.487,370.75 C 375.047,370.75 398.227,385.978 398.227,412.292 z " style="font-size:12px;fill:url(#linearGradient1419);stroke:none;stroke-width:1.38846004;stroke-dasharray:none" transform="matrix(1.1868,0,0,1.06708,210.623,-100.078)" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path129" d="M 234.285,456.475 C 252.001,429.479 289.3,388.111 241.262,462.288 C 202.311,523.331 226.859,562.561 239.518,573.327 C 276.045,605.889 274.484,627.676 245.913,610.533 C 184.288,573.907 197.078,512.285 234.285,456.475 z " style="fill:url(#linearGradient1421);stroke:none;stroke-width:1.25;" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path131" d="M 490.662,467.52 C 475.343,435.819 426.528,355.618 492.988,448.917 C 553.449,533.214 511.01,591.93 503.452,597.744 C 495.895,603.557 470.315,615.184 477.873,594.837 C 485.43,574.49 523.107,535.864 490.662,467.52 z " style="fill:url(#linearGradient1423);stroke:none;stroke-width:1.25;" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path132" d="M 220.915,716.921 C 180.473,695.505 121.663,721.045 143.013,662.855 C 147.289,649.617 136.638,629.847 143.594,616.929 C 151.733,601.231 169.174,604.72 179.639,594.255 C 189.957,583.364 196.498,564.606 215.683,567.513 C 234.867,570.42 247.628,593.974 261.027,622.742 C 270.91,643.38 305.968,672.406 303.677,695.5 C 300.981,731 260.65,737.69 220.915,716.921 z " style="fill:url(#linearGradient1425);stroke:#e68c3f;stroke-width:6.25;" />
|
||||
|
||||
<path id="path177" d="M 415.072,495.764 C 412.065,520.67 379.259,572.391 345.554,577.298 C 311.294,582.634 279.122,543.238 271.407,506.184 C 261.518,464.978 293.994,448.584 343.345,449.557 C 396.646,451.211 417.466,463.448 415.072,495.764 z " style="font-size:12px;fill:url(#linearGradient1427);stroke:none;stroke-width:2.85509992;stroke-dasharray:none" transform="matrix(0.598206,0.268584,-0.239623,0.617213,700.568,140.464)" />
|
||||
|
||||
<path transform="matrix(-1.1685,0.423145,0.475283,1.16478,728.343,-213.821)" id="path133" d="M 220.274,718.402 C 178.947,694.812 120.38,724.007 143.013,662.855 C 147.749,649.787 136.417,629.303 143.373,616.385 C 151.512,600.687 169.174,604.72 179.639,594.255 C 189.957,583.364 198.466,566.387 217.651,569.294 C 236.835,572.201 247.628,593.974 261.027,622.742 C 270.91,643.38 304.442,671.713 302.151,694.807 C 299.455,730.307 259.427,740.278 220.274,718.402 z " style="fill:url(#linearGradient1429);stroke:#e68c3f;stroke-width:6.25067997;" />
|
||||
|
||||
<path transform="matrix(-0.945096,0.343745,0.424076,0.956058,714.328,-64.342)" id="path134" d="M 216.482,675.68 C 129.951,618.177 169.174,604.72 179.639,594.255 C 189.957,583.364 198.466,566.387 217.651,569.294 C 236.835,572.201 247.628,593.974 261.027,622.742 C 270.91,643.38 304.087,671.66 302.151,694.807 C 299.535,721.917 253.961,700.294 216.482,675.68 z " style="fill:url(#linearGradient1431);stroke:none;stroke-width:1.52532005;" />
|
||||
|
||||
<path transform="matrix(1.00431,-5.2286e-2,-1.74e-2,1.04575,244.191,-28.4653)" id="path135" d="M 216.506,677.071 C 129.975,619.568 169.709,603.501 182.56,595.791 C 197.959,585.849 197.718,564.96 216.903,567.867 C 236.087,570.774 247.628,593.974 261.027,622.742 C 270.91,643.38 304.087,671.66 302.151,694.807 C 299.535,721.917 253.985,701.685 216.506,677.071 z " style="fill:url(#linearGradient1433);stroke:none;stroke-width:1.52532005;" />
|
||||
|
||||
<path id="path136" d="M 415.072,495.764 C 412.065,520.67 379.259,572.391 345.554,577.298 C 311.294,582.634 279.122,543.238 271.407,506.184 C 261.518,464.978 293.994,448.584 343.345,449.557 C 396.646,451.211 417.466,463.448 415.072,495.764 z " style="font-size:12px;fill:#000000;stroke:none;stroke-width:2.85509992;" transform="matrix(0.515584,0.215259,-0.206526,0.49467,713.3,222.559)" />
|
||||
|
||||
<path id="path137" d="M 415.072,495.764 C 412.065,520.67 379.259,572.391 345.554,577.298 C 311.294,582.634 279.122,543.238 271.407,506.184 C 261.518,464.978 293.994,448.584 343.345,449.557 C 396.646,451.211 417.466,463.448 415.072,495.764 z " style="font-size:12px;fill:url(#linearGradient1435);stroke:none;stroke-width:2.85509992;" transform="matrix(0.351231,0.149463,-0.128856,0.343469,724.522,318.291)" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path119" d="M 309.954,338.729 C 317.101,331.959 334.765,311.663 367.915,332.974 C 374.077,336.984 379.077,337.351 390.936,342.429 C 414.662,352.178 403.318,375.688 378.192,383.537 C 367.434,387.026 357.656,400.093 338.063,398.976 C 321.329,397.999 316.944,387.102 306.665,381.07 C 288.396,370.759 285.7,356.816 295.565,349.417 C 305.431,342.018 309.29,339.358 309.954,338.729 z " style="fill:url(#linearGradient1437);stroke:#e68c3f;stroke-width:3.75;" />
|
||||
|
||||
<path transform="matrix(1.25,0,0,1.25,185.454,-167.505)" id="path120" d="M 391.251,357.645 C 381.368,358.226 359.858,379.736 337.185,379.736 C 314.512,379.736 301.141,358.807 297.653,358.807" style="fill:none;stroke:#e68c3f;stroke-width:2.5;" />
|
||||
|
||||
<path transform="matrix(0.627885,0,0,0.595666,392.366,51.8173)" id="path123" d="M 309.954,338.729 C 317.101,331.959 339.645,313.381 369.542,332.401 C 375.841,336.167 382.346,340.266 392.02,345.865 C 411.182,357.613 401.691,374.543 378.734,385.255 C 368.316,389.75 351.141,399.67 338.063,398.976 C 323.53,397.568 314.128,387.577 304.496,381.07 C 286.826,368.767 287.899,358.833 296.107,350.562 C 302.312,344.883 309.29,339.358 309.954,338.729 z " style="fill:url(#linearGradient1439);stroke:none;" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 21 KiB |
@ -55,7 +55,7 @@ if (files.length === 0) {
|
||||
const filePath = path.join(dir, files[0]);
|
||||
|
||||
console.log(`Running demo ${demoNumber}: ${files[0]}`);
|
||||
const { stdout } = await $`ts-node --project demo/tsconfig.json ${filePath}`;
|
||||
const { stdout } = await $`tsx ${filePath}`;
|
||||
console.log(stdout);
|
||||
console.log("Successfully created document!");
|
||||
}
|
||||
|
@ -7,4 +7,4 @@
|
||||
}
|
||||
},
|
||||
"include": ["../demo"]
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
- Simple, declarative API
|
||||
- 80+ usage examples
|
||||
- Battle tested, mature, 99.9%+ coverage
|
||||
- Battle tested, mature, 100% coverage (yes, every line is tested)
|
||||
|
||||
[GitHub](https://github.com/dolanmiu/docx)
|
||||
[Get Started](#Welcome)
|
||||
|
@ -1,24 +1,25 @@
|
||||
# Contribution Guidelines
|
||||
|
||||
- Include documentation reference(s) at the top of each file as a comment. For example:
|
||||
- Include documentation reference(s) at the top of each file as a comment. For example:
|
||||
|
||||
```ts
|
||||
// http://officeopenxml.com/WPdocument.php
|
||||
```
|
||||
|
||||
<!-- cSpell:ignore datypic -->
|
||||
|
||||
It can be a link to `officeopenxml.com` or `datypic.com` etc.
|
||||
It could also be a reference to the official ECMA-376 standard: https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
|
||||
|
||||
- Include a portion of the schema as a comment for cross reference. For example:
|
||||
- Include a portion of the schema as a comment for cross reference. For example:
|
||||
|
||||
```ts
|
||||
// <xsd:element name="tbl" type="CT_Tbl" minOccurs="0" maxOccurs="1"/>
|
||||
```
|
||||
|
||||
- Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
|
||||
- Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
|
||||
|
||||
- Follow the `ESLint` rules
|
||||
- Follow the `ESLint` rules
|
||||
|
||||
## Always think about the user
|
||||
|
||||
@ -37,6 +38,7 @@ Please write good commit messages when making a commit: https://chris.beams.io/p
|
||||
**Do not:**
|
||||
|
||||
<!-- cspell:disable -->
|
||||
|
||||
```
|
||||
c // What?
|
||||
rtl // Adding acronyms without explaining anything else is not helpful
|
||||
@ -44,6 +46,7 @@ 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**
|
||||
@ -104,22 +107,25 @@ private get _level: string;
|
||||
private get level: string;
|
||||
```
|
||||
|
||||
## Interfaces over type alias
|
||||
## Types over interfaces
|
||||
|
||||
Do not use `type`, but rather use `Interfaces`. `type` cannot be extended, and a class cannot implement it.
|
||||
Using `type` aliases in TypeScript offers several advantages over `interfaces`:
|
||||
|
||||
> "In general, use what you want ( type alias / interface ) just be consistent"
|
||||
> "always use interface for public API's definition when authoring a library or 3rd party ambient type definitions"
|
||||
>
|
||||
> - https://medium.com/@martin_hotell/interface-vs-type-alias-in-typescript-2-7-2a8f1777af4c
|
||||
- **Flexibility with Complex Types**: `type` supports defining unions, intersections, and other complex type constructs that `interfaces` cannot handle. For example:
|
||||
|
||||
`Interface` is generally preferred over `type`: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
|
||||
```typescript
|
||||
type StringOrNumber = string | number;
|
||||
type Combined = TypeA & TypeB;
|
||||
```
|
||||
|
||||
**Do not:**
|
||||
- **Support for Primitive Types**: `type` can alias primitive types (e.g., `type ID = string`), while `interfaces` are limited to object shapes.
|
||||
- **Tuple and Array Types**: `type` allows defining tuples and specific array types easily (e.g., `type Point = [number, number]`), which `interfaces` cannot represent.
|
||||
- **Utility Types Compatibility**: `type` works seamlessly with TypeScript's utility types (e.g., `Partial<T>`, `Pick<T, K>`), enabling more expressive type transformations.
|
||||
- **Functional Programming**: `type` is ideal for functional programming patterns, such as defining function signatures or mapped types, due to its versatility.
|
||||
- **No Declaration Merging**: Unlike `interfaces`, type does not support declaration merging, which can prevent accidental type extensions and ensure predictable type definitions.
|
||||
- **Consistent Pattern**: This project uses `type` for all type definitions, so using `type` for all type definitions maintains consistency and readability across the codebase.
|
||||
|
||||
```ts
|
||||
type RelationshipFileInfo = { id: number; target: string };
|
||||
```
|
||||
Detailed discussion: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
|
||||
|
||||
**Do:**
|
||||
|
||||
@ -130,6 +136,12 @@ interface IRelationshipFileInfo {
|
||||
}
|
||||
```
|
||||
|
||||
**Do not:**
|
||||
|
||||
```ts
|
||||
type RelationshipFileInfo = { id: number; target: string };
|
||||
```
|
||||
|
||||
## String enums vs type
|
||||
|
||||
To take full advantage of TypeScript's typing system, its best to use `string enums`:
|
||||
|
@ -22,7 +22,7 @@ const doc = new Document({
|
||||
}
|
||||
})
|
||||
],
|
||||
}];
|
||||
}]
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -22,19 +22,30 @@ const doc = new docx.Document({
|
||||
|
||||
### Full list of options:
|
||||
|
||||
- creator
|
||||
- description
|
||||
- title
|
||||
- subject
|
||||
- keywords
|
||||
- lastModifiedBy
|
||||
- revision
|
||||
- externalStyles
|
||||
- styles
|
||||
- numbering
|
||||
- footnotes
|
||||
- hyperlinks
|
||||
- background
|
||||
| Property | Type | Notes |
|
||||
| -------------------------- | -------------------------------------------------------- | -------- |
|
||||
| sections | `ISectionOptions[]` | Optional |
|
||||
| title | `string` | Optional |
|
||||
| subject | `string` | Optional |
|
||||
| creator | `string` | Optional |
|
||||
| keywords | `string` | Optional |
|
||||
| description | `string` | Optional |
|
||||
| lastModifiedBy | `string` | Optional |
|
||||
| revision | `number` | Optional |
|
||||
| externalStyles | `string` | Optional |
|
||||
| styles | `IStylesOptions` | Optional |
|
||||
| numbering | `INumberingOptions` | Optional |
|
||||
| comments | `ICommentsOptions` | Optional |
|
||||
| footnotes | `Record<string, { children: Paragraph[] }>` | Optional |
|
||||
| background | `IDocumentBackgroundOptions` | Optional |
|
||||
| features | `{ trackRevisions?: boolean; updateFields?: boolean; }` | Optional |
|
||||
| compatabilityModeVersion | `number` | Optional |
|
||||
| compatibility | `ICompatibilityOptions` | Optional |
|
||||
| customProperties | ` ICustomPropertyOptions`[] | Optional |
|
||||
| evenAndOddHeaderAndFooters | `boolean` | Optional |
|
||||
| defaultTabStop | `number` | Optional |
|
||||
| fonts | ` FontOptions[]` | Optional |
|
||||
| hyphenation | `IHyphenationOptions` | Optional |
|
||||
|
||||
### Change background color of Document
|
||||
|
||||
|
@ -16,12 +16,10 @@ const chapter1 = new Paragraph({
|
||||
children: [
|
||||
new Bookmark({
|
||||
id: "anchorForChapter1",
|
||||
children: [
|
||||
new TextRun("Chapter 1"),
|
||||
],
|
||||
children: [new TextRun("Chapter 1")],
|
||||
}),
|
||||
],
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
Then you can create an hyperlink pointing to that bookmark with an `InternalHyperLink`:
|
||||
@ -35,20 +33,32 @@ const link = new InternalHyperlink({
|
||||
}),
|
||||
],
|
||||
anchor: "anchorForChapter1",
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
### Page reference
|
||||
|
||||
You can also get the page number of the bookmark by creating a page reference to it:
|
||||
|
||||
```ts
|
||||
const paragraph = new Paragraph({
|
||||
children: [
|
||||
new TextRun("Chapter 1 can be seen on page "),
|
||||
new PageReference("anchorForChapter1"),
|
||||
],
|
||||
children: [new TextRun("Chapter 1 can be seen on page "), new PageReference("anchorForChapter1")],
|
||||
});
|
||||
```
|
||||
|
||||
### Numbered item reference
|
||||
|
||||
You can also create cross references for numbered items with `NumberedItemReference`.
|
||||
|
||||
```ts
|
||||
const paragraph = new Paragraph({
|
||||
children: [new TextRun("See Paragraph "), new NumberedItemReference("anchorForParagraph1", "1.1")],
|
||||
});
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The `NumberedItemReference` currently needs a cached value (in this case `1.1`)
|
||||
|
||||
## External
|
||||
|
||||
To create an external hyperlink you just need to specify the url and the text of the link, then add it to a paragraph:
|
||||
@ -69,7 +79,6 @@ const paragraph = new Paragraph({
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Styling hyperlinks
|
||||
|
||||
It is possible to set the style of the text of both internal and external hyperlinks. This can be done applying run formatting on any of the `TextRun` children of the hyperlink. Use the `style: "Hyperlink"` property to show the default link styles, which can be combined with any other style.
|
||||
|
@ -6,6 +6,7 @@ To create a `floating` image on top of text:
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'gif',
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -26,6 +27,7 @@ By default with no arguments, its an `inline` image:
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'gif',
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
@ -59,6 +61,7 @@ const doc = new Document({
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: [IMAGE_TYPE],
|
||||
data: [IMAGE_BUFFER],
|
||||
transformation: {
|
||||
width: [IMAGE_SIZE],
|
||||
@ -97,6 +100,7 @@ To change the position the image to be on top of the text, simply add the `float
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'png',
|
||||
data: buffer,
|
||||
transformation: {
|
||||
width: 903,
|
||||
@ -115,6 +119,7 @@ const image = new ImageRun({
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'png',
|
||||
data: buffer,
|
||||
transformation: {
|
||||
width: 903,
|
||||
@ -180,6 +185,7 @@ For example:
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'gif',
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -228,6 +234,7 @@ For example:
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'gif',
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
transformation: {
|
||||
width: 200,
|
||||
@ -258,6 +265,7 @@ Specifies common non-visual DrawingML properties. A name, title and description
|
||||
|
||||
```ts
|
||||
const image = new ImageRun({
|
||||
type: 'gif',
|
||||
data: fs.readFileSync("./demo/images/pizza.gif"),
|
||||
altText: {
|
||||
title: "This is an ultimate title",
|
||||
|
@ -263,3 +263,23 @@ new MathAngledBrackets({
|
||||
],
|
||||
}),
|
||||
```
|
||||
|
||||
### Limit
|
||||
|
||||
#### Limit Upper
|
||||
|
||||
```ts
|
||||
new MathLimitUpper({
|
||||
children: [new MathRun("x")],
|
||||
limit: [new MathRun("-")],
|
||||
}),
|
||||
```
|
||||
|
||||
#### Limit Lower
|
||||
|
||||
```ts
|
||||
new MathLimitLower({
|
||||
children: [new MathRun("lim")],
|
||||
limit: [new MathRun("x→0")],
|
||||
}),
|
||||
```
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Bullets and Numbering
|
||||
|
||||
!> Bullets and Numbering requires an understanding of [Sections](usage/sections.md) and [Paragraphs](usage/paragraph.md).
|
||||
|
||||
`docx` is quite flexible in its bullets and numbering system, allowing
|
||||
the user great freedom in how bullets and numbers are to be styled and
|
||||
displayed. E.g., numbers can be shown using Arabic numerals, roman
|
||||
@ -8,112 +10,184 @@ format also supports re-using bullets/numbering styles throughout the
|
||||
document, so that different lists using the same style need not
|
||||
redefine them.
|
||||
|
||||
Because of this flexibility, bullets and numbering in DOCX involves a
|
||||
couple of moving pieces:
|
||||
## Configuration
|
||||
|
||||
1. Document-level bullets/numbering definitions (abstract)
|
||||
2. Document-level bullets/numbering definitions (concrete)
|
||||
3. Paragraph-level bullets/numbering selection
|
||||
|
||||
## Document-level bullets/numbering definitions (abstract)
|
||||
|
||||
Every document contains a set of abstract bullets/numbering
|
||||
definitions which define the formatting and layout of paragraphs using
|
||||
those bullets/numbering. An abstract numbering system defines how
|
||||
bullets/numbers are to be shown for lists, including any sublists that
|
||||
may be used. Thus each abstract definition includes a series of
|
||||
_levels_ which form a sequence starting at 0 indicating the top-level
|
||||
list look and increasing from there to describe the sublists, then
|
||||
sub-sublists, etc. Each level includes the following properties:
|
||||
|
||||
* **level**: This is its 0-based index in the definition stack
|
||||
* **numberFormat**: This indicates how the bullet or number should be
|
||||
generated. Options include `bullet` (meaning don't count), `decimal`
|
||||
(arabic numerals), `upperRoman`, `lowerRoman`, `hex`, and many
|
||||
more.
|
||||
* **levelText**: This is a format string using the output of the
|
||||
`numberFormat` function and generating a string to insert before
|
||||
every item in the list. You may use `%1`, `%2`, ... to reference the
|
||||
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 OOXML spec section 17.9.6
|
||||
|
||||
## Document-level bullets/numbering definitions (concrete)
|
||||
|
||||
Concrete definitions are sort of like concrete subclasses of the
|
||||
abstract definitions. They indicate their parent and are allowed to
|
||||
override certain level definitions. Thus two lists that differ only in
|
||||
how sub-sub-lists are to be displayed can share the same abstract
|
||||
numbering definition and have slightly different concrete definitions.
|
||||
|
||||
## Paragraph-level bullets/numbering selection
|
||||
|
||||
In order to use a bullets/numbering definition (which must be
|
||||
concrete), paragraphs need to select it, similar to applying a CSS
|
||||
class to an element, using both the concrete numbering definition ID
|
||||
and the level number that the paragraph should be at. Additionally, MS
|
||||
Word and LibreOffice typically apply a "ListParagraph" style to
|
||||
paragraphs that are being numbered.
|
||||
|
||||
## Using bullets/numbering in `docx`
|
||||
|
||||
`docx` includes a pre-defined bullet style which you can add to your
|
||||
paragraphs using `para.bullets()`. If you require different bullet
|
||||
styles or numbering of any kind, you'll have to use the
|
||||
`docx.Numbering` class.
|
||||
|
||||
First you need to create a new numbering container class and use it to
|
||||
create your abstract numbering style, define your levels, and create
|
||||
your concrete numbering style:
|
||||
Numbering is configured by adding config into `Document`:
|
||||
|
||||
```ts
|
||||
const numbering = new docx.Numbering();
|
||||
|
||||
const abstractNum = numbering.createAbstractNumbering();
|
||||
abstractNum.createLevel(0, "upperRoman", "%1", "start").addParagraphProperty(new Indent(720, 260));
|
||||
abstractNum.createLevel(1, "decimal", "%2.", "start").addParagraphProperty(new Indent(1440, 980));
|
||||
abstractNum.createLevel(2, "lowerLetter", "%3)", "start").addParagraphProperty(new Indent(2160, 1700));
|
||||
|
||||
const concrete = numbering.createConcreteNumbering(abstractNum);
|
||||
new Document({
|
||||
numbering: {
|
||||
config: [...]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
You can then apply your concrete style to paragraphs using the
|
||||
`setNumbering` method:
|
||||
Each `config` entry includes the following properties:
|
||||
|
||||
. Each level includes the following properties:
|
||||
|
||||
| Property | Type | Notes | Possible Values |
|
||||
| --------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| reference | `string` | Required | A unique `string` |
|
||||
| levels | `ILevelOptions[]` | Required | a series of _levels_ which form a sequence starting at 0 indicating the top-level list look and increasing from there to describe the sublists, then sub-sublists, etc |
|
||||
|
||||
### Level Options
|
||||
|
||||
Levels define the numbering definition itself, what it looks like, the indention, the alignment and the style. The reason why it is an array is because it allows the ability to create sub-lists. A sub list will have a different configuration because you may want the sub-list to have a different indentation or different bullet.
|
||||
|
||||
| Property | Type | Notes | Possible Values |
|
||||
| --------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| level | `number` | Required | The list level this definition is for. `0` is for the root level, `1` is for a sub list, `2` is for a sub-sub-list etc. |
|
||||
| format | `LevelFormat` | Optional | `DECIMAL`, `UPPER_ROMAN`, `LOWER_ROMAN`, `UPPER_LETTER`, `LOWER_LETTER`, `ORDINAL`, `CARDINAL_TEXT`, `ORDINAL_TEXT`, `HEX`, `CHICAGO`, `IDEOGRAPH__DIGITAL`, `JAPANESE_COUNTING`, `AIUEO`, `IROHA`, `DECIMAL_FULL_WIDTH`, `DECIMAL_HALF_WIDTH`, `JAPANESE_LEGAL`, `JAPANESE_DIGITAL_TEN_THOUSAND`, `DECIMAL_ENCLOSED_CIRCLE`, `DECIMAL_FULL_WIDTH2`, `AIUEO_FULL_WIDTH`, `IROHA_FULL_WIDTH`, `DECIMAL_ZERO`, `BULLET`, `GANADA`, `CHOSUNG`, `DECIMAL_ENCLOSED_FULLSTOP`, `DECIMAL_ENCLOSED_PARENTHESES`, `DECIMAL_ENCLOSED_CIRCLE_CHINESE`, `IDEOGRAPH_ENCLOSED_CIRCLE`, `IDEOGRAPH_TRADITIONAL`, `IDEOGRAPH_ZODIAC`, `IDEOGRAPH_ZODIAC_TRADITIONAL`, `TAIWANESE_COUNTING`, `IDEOGRAPH_LEGAL_TRADITIONAL`, `TAIWANESE_COUNTING_THOUSAND`, `TAIWANESE_DIGITAL`, `CHINESE_COUNTING`, `CHINESE_LEGAL_SIMPLIFIED`, `CHINESE_COUNTING_THOUSAND`, `KOREAN_DIGITAL`, `KOREAN_COUNTING`, `KOREAN_LEGAL`, `KOREAN_DIGITAL2`, `VIETNAMESE_COUNTING`, `RUSSIAN_LOWER`, `RUSSIAN_UPPER`, `NONE`, `NUMBER_IN_DASH`, `HEBREW1`, `HEBREW2`, `ARABIC_ALPHA`, `ARABIC_ABJAD`, `HINDI_VOWELS`, `HINDI_CONSONANTS`, `HINDI_NUMBERS`, `HINDI_COUNTING`, `THAI_LETTERS`, `THAI_NUMBERS`, `THAI_COUNTING`, `BAHT_TEXT`, `DOLLAR_TEXT`, `CUSTOM` |
|
||||
| text | `string` | Optional | A unique `string` to describe the shape of the bullet |
|
||||
| alignment | `string` | Required | `START`, `CENTER`, `END`, `BOTH`, `MEDIUM_KASHIDA`, `DISTRIBUTE`, `NUM_TAB`, `HIGH_KASHIDA`, `LOW_KASHIDA`, `THAI_DISTRIBUTE`, `LEFT`, `RIGHT`, `JUSTIFIED` |
|
||||
| style | `string` | Optional | [Sections](usage/styling-with-js.md) |
|
||||
|
||||
## Using ordered lists in `docx`
|
||||
|
||||
Add a `numbering` section to the `Document` to numbering style, define your levels. Use `LevelFormat.UPPER_ROMAN` for the `format` in `levels`:
|
||||
|
||||
```ts
|
||||
topLevelP.setNumbering(concrete, 0);
|
||||
subP.setNumbering(concrete, 1);
|
||||
subSubP.setNumbering(concrete, 2);
|
||||
const doc = new Document({
|
||||
...
|
||||
numbering: {
|
||||
config: [
|
||||
{
|
||||
reference: "my-numbering",
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.UPPER_ROMAN,
|
||||
text: "%1",
|
||||
alignment: AlignmentType.START,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: 2880, hanging: 2420 },
|
||||
},
|
||||
},
|
||||
},
|
||||
...
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
## 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
|
||||
And then on a `Paragraph`, we can add use the numbering created:
|
||||
|
||||
```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
|
||||
}]
|
||||
|
||||
new Paragraph({
|
||||
text: "Hey you!",
|
||||
numbering: {
|
||||
reference: "my-numbering",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
```
|
||||
|
||||
## Un-ordered lists / Bullet points
|
||||
|
||||
Add a `numbering` section to the `Document` to numbering style, define your levels. Use `LevelFormat.BULLET` for the `format` in `levels`:
|
||||
|
||||
```ts
|
||||
const doc = new Document({
|
||||
...
|
||||
numbering: {
|
||||
config: [
|
||||
{
|
||||
reference: "my-bullet-points",
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u1F60",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
And then on a `Paragraph`, we can add use the numbering created:
|
||||
|
||||
```ts
|
||||
new Paragraph({
|
||||
text: "Hey you!",
|
||||
numbering: {
|
||||
reference: "my-bullet-points",
|
||||
level: 0,
|
||||
},
|
||||
}),
|
||||
```
|
||||
|
||||
## Disabling numbering inherited from paragraph style
|
||||
|
||||
If the numbering is set on a paragraph style, you may wish to disable it for a specific paragraph:
|
||||
|
||||
```ts
|
||||
const doc = new Document({
|
||||
...
|
||||
numbering: {
|
||||
config: [
|
||||
{
|
||||
reference: "my-bullet-points",
|
||||
levels: [
|
||||
{
|
||||
level: 0,
|
||||
format: LevelFormat.BULLET,
|
||||
text: "\u1F60",
|
||||
alignment: AlignmentType.LEFT,
|
||||
style: {
|
||||
paragraph: {
|
||||
indent: { left: convertInchesToTwip(0.5), hanging: convertInchesToTwip(0.25) },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
styles: {
|
||||
paragraphStyles: [
|
||||
{
|
||||
id: 'bullet',
|
||||
name: 'Bullet',
|
||||
basedOn: 'Normal',
|
||||
next: 'Normal',
|
||||
run: {},
|
||||
paragraph: {
|
||||
numbering: {
|
||||
reference: 'my-bullet-points',
|
||||
level: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
new Paragraph({
|
||||
text: "No bullet points!",
|
||||
style: "Bullet",
|
||||
numbering: false,
|
||||
}),
|
||||
```
|
||||
|
||||
## Full Example
|
||||
|
||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/3-numbering-and-bullet-points.ts ":include")
|
||||
|
||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/3-numbering-and-bullet-points.ts_
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
> Packers are the way in which `docx` turns your code into `.docx` format. It is completely decoupled from the `docx.Document`.
|
||||
|
||||
Packers works in both a node and browser environment (Angular etc). Now, the packer returns a `Buffer`, `Blob` or `base64 string`. It is up to you to take that and persist it with node's `fs`, send it down as a downloadable file, or anything else you wish. As of `version 4+`, this library will not have options to export to PDF.
|
||||
Packers works in both a node and browser environment (Angular etc). Now, the packer returns a `Buffer`, `Blob`, `string`, `base64 string`, `ArrayBuffer`, or `Stream`. It is up to you to take that and persist it with node's `fs`, send it down as a downloadable file, or anything else you wish. As of `version 4+`, this library will not have options to export to PDF.
|
||||
|
||||
### Export as Buffer
|
||||
|
||||
@ -14,6 +14,14 @@ Packer.toBuffer(doc).then((buffer) => {
|
||||
});
|
||||
```
|
||||
|
||||
### Export as string
|
||||
|
||||
```ts
|
||||
Packer.toString(doc).then((string) => {
|
||||
console.log(string);
|
||||
});
|
||||
```
|
||||
|
||||
### Export as a `base64` string
|
||||
|
||||
```ts
|
||||
@ -32,3 +40,46 @@ Packer.toBlob(doc).then((blob) => {
|
||||
saveAs(blob, "example.docx");
|
||||
});
|
||||
```
|
||||
|
||||
### Export as ArrayBuffer
|
||||
|
||||
This may be useful when working in a Node.js worker.
|
||||
|
||||
```ts
|
||||
Packer.toArrayBuffer(doc).then((arrayBuffer) => {
|
||||
port.postMessage(arrayBuffer, [arrayBuffer]);
|
||||
});
|
||||
```
|
||||
|
||||
### Export as a Stream
|
||||
|
||||
```ts
|
||||
Packer.toStream(doc).then((stream) => {
|
||||
// read from stream
|
||||
});
|
||||
```
|
||||
|
||||
### Export using optional arguments
|
||||
|
||||
The `Packer` methods support 2 optional arguments.
|
||||
|
||||
The first is for controlling the indentation of the xml and should be a `boolean` or `keyof typeof PrettifyType`.
|
||||
|
||||
The second is an array of subfile overrides (`{path: string, data: string}[]`). These overrides can be used to write additional subfiles to the result or even override default subfiles in the case that the default handling of these subfiles does not meet your needs.
|
||||
|
||||
```ts
|
||||
const overrides = [{ path: "word/commentsExtended.xml", data: "string_data" }];
|
||||
Packer.toString(doc, true, overrides).then((string) => {
|
||||
console.log(string);
|
||||
});
|
||||
```
|
||||
|
||||
### Export to arbitrary formats
|
||||
|
||||
You can also use the lower-level `Packer.pack` method to export to any specified type.
|
||||
|
||||
```ts
|
||||
Packer.pack(doc, 'string').then((string) => {
|
||||
console.log(string);
|
||||
});
|
||||
```
|
||||
|
@ -35,6 +35,9 @@ interface Patch {
|
||||
| type | `PatchType` | Required | `DOCUMENT`, `PARAGRAPH` |
|
||||
| children | `FileChild[] or ParagraphChild[]` | Required | The contents to replace with. A `FileChild` is a `Paragraph` or `Table`, whereas a `ParagraphChild` is typical `Paragraph` children. |
|
||||
|
||||
|
||||
The patcher also takes in a `keepOriginalStyles` boolean, which will preserve the styles of the patched text when set to true.
|
||||
|
||||
### How to patch existing document
|
||||
|
||||
1. Open your existing word document in your favorite Word Processor
|
||||
@ -76,7 +79,7 @@ patchDocument(fs.readFileSync("My Document.docx"), {
|
||||
],
|
||||
link: "https://www.google.co.uk",
|
||||
}),
|
||||
new ImageRun({ data: fs.readFileSync("./demo/images/dog.png"), transformation: { width: 100, height: 100 } }),
|
||||
new ImageRun({ type: 'png', data: fs.readFileSync("./demo/images/dog.png"), transformation: { width: 100, height: 100 } }),
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
@ -126,10 +126,10 @@ const doc = new Document({
|
||||
next: "Normal",
|
||||
quickFormat: true,
|
||||
run: {
|
||||
size: 26
|
||||
size: 26,
|
||||
bold: true,
|
||||
color: "999999",
|
||||
{
|
||||
underline: {
|
||||
type: UnderlineType.DOUBLE,
|
||||
color: "FF0000",
|
||||
},
|
||||
|
@ -9,11 +9,16 @@
|
||||

|
||||

|
||||
|
||||
*Note*: Font and color selection from the theme are currently not supported.
|
||||
|
||||
3. You can even create a totally new `Style`:
|
||||
|
||||

|
||||

|
||||
|
||||
*Note*: When selecting the style type, it is important to consider the component being used.
|
||||
|
||||
|
||||
4. Save
|
||||
5. Re-name the saved `.docx` file to `.zip` and un-zip
|
||||
6. Find `styles.xml`
|
||||
|
@ -22,7 +22,7 @@ Then add the table in the `section`
|
||||
const doc = new Document({
|
||||
sections: [{
|
||||
children: [table],
|
||||
}];
|
||||
}],
|
||||
});
|
||||
```
|
||||
|
||||
|
26
docs/usage/text-box.md
Normal file
26
docs/usage/text-box.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Text Box
|
||||
|
||||
Similar `Text Frames`, but the difference being that it is `VML` `Shape` based.
|
||||
|
||||
!> `Text Boxes` requires an understanding of [Paragraphs](usage/paragraph.md).
|
||||
|
||||
> `Text boxes` are paragraphs of text in a document which are positioned in a separate region or frame in the document, and can be positioned with a specific size and position relative to non-frame paragraphs in the current document.
|
||||
|
||||
## Intro
|
||||
|
||||
To make a `Text Box`, simply create a `Textbox` object inside the `Document`:
|
||||
|
||||
```ts
|
||||
new Textbox({
|
||||
alignment: "center",
|
||||
children: [
|
||||
new Paragraph({
|
||||
children: [new TextRun("Hi i'm a textbox!")],
|
||||
}),
|
||||
],
|
||||
style: {
|
||||
width: "200pt",
|
||||
height: "auto",
|
||||
},
|
||||
});
|
||||
```
|
@ -1,6 +1,6 @@
|
||||
# Text Frames
|
||||
|
||||
Also known as `Text Boxes`
|
||||
> Similar to `Text Boxes`!
|
||||
|
||||
!> Text Frames requires an understanding of [Paragraphs](usage/paragraph.md).
|
||||
|
||||
|
370
eslint.config.ts
Normal file
370
eslint.config.ts
Normal file
@ -0,0 +1,370 @@
|
||||
import eslint from "@eslint/js";
|
||||
import type { Linter } from "eslint";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
import unicorn from "eslint-plugin-unicorn";
|
||||
import jsdoc from "eslint-plugin-jsdoc";
|
||||
import preferArrow from "eslint-plugin-prefer-arrow";
|
||||
import functional from "eslint-plugin-functional";
|
||||
import globals from "globals";
|
||||
import tsEslint from "typescript-eslint";
|
||||
|
||||
const config: Linter.Config<Linter.RulesRecord>[] = [
|
||||
{
|
||||
ignores: ["**/vite.config.ts", "**/dist/**", "**/coverage/**", "**/*.js", "eslint.config.ts", "**/demo/**", "**/scripts/**"],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
importPlugin.flatConfigs.recommended,
|
||||
...tsEslint.configs.recommended,
|
||||
...tsEslint.configs.stylistic,
|
||||
{
|
||||
files: ["**/src/**/*.ts"],
|
||||
plugins: {
|
||||
unicorn,
|
||||
jsdoc,
|
||||
"prefer-arrow": preferArrow,
|
||||
functional,
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
typescript: true,
|
||||
node: 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/no-restricted-types": [
|
||||
"error",
|
||||
{
|
||||
types: {
|
||||
Object: {
|
||||
message: "Avoid using the `Object` type. Did you mean `object`?",
|
||||
fixWith: "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`?",
|
||||
fixWith: "boolean",
|
||||
},
|
||||
|
||||
Number: {
|
||||
message: "Avoid using the `Number` type. Did you mean `number`?",
|
||||
fixWith: "number",
|
||||
},
|
||||
|
||||
String: {
|
||||
message: "Avoid using the `String` type. Did you mean `string`?",
|
||||
fixWith: "string",
|
||||
},
|
||||
|
||||
Symbol: {
|
||||
message: "Avoid using the `Symbol` type. Did you mean `symbol`?",
|
||||
fixWith: "symbol",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
"@typescript-eslint/consistent-type-assertions": "error",
|
||||
"@typescript-eslint/dot-notation": "error",
|
||||
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: true,
|
||||
allowTypedFunctionExpressions: true,
|
||||
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", "UPPER_CASE"],
|
||||
|
||||
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/consistent-type-definitions": ["error", "type"],
|
||||
|
||||
"@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/no-inferrable-types": "off",
|
||||
|
||||
"@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",
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
allowSeparatedGroups: true,
|
||||
ignoreDeclarationSort: true,
|
||||
},
|
||||
],
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
groups: [["external", "builtin"], "internal", ["sibling", "parent", "index"]],
|
||||
"newlines-between": "always",
|
||||
pathGroups: [
|
||||
{ pattern: "@file/**/*", group: "internal" },
|
||||
{ pattern: "@file/**", group: "internal" },
|
||||
{ pattern: "@export/**", group: "internal" },
|
||||
],
|
||||
pathGroupsExcludedImportTypes: ["internal"],
|
||||
alphabetize: {
|
||||
order: "asc",
|
||||
caseInsensitive: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
indent: "off",
|
||||
"jsdoc/check-alignment": "error",
|
||||
"jsdoc/check-indentation": "off",
|
||||
"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-param-reassign": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-return-await": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
"no-sparse-arrays": "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",
|
||||
|
||||
"functional/immutable-data": [
|
||||
"error",
|
||||
{
|
||||
ignoreImmediateMutation: true,
|
||||
ignoreAccessorPattern: ["**.root*", "**.numberingReferences*", "**.sections*", "**.properties*"],
|
||||
},
|
||||
],
|
||||
|
||||
"functional/prefer-property-signatures": "error",
|
||||
"functional/no-mixed-types": "error",
|
||||
"functional/prefer-readonly-type": "error",
|
||||
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^[_]+$",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.spec.ts"],
|
||||
plugins: {
|
||||
unicorn,
|
||||
jsdoc,
|
||||
"prefer-arrow": preferArrow,
|
||||
functional,
|
||||
},
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
},
|
||||
|
||||
sourceType: "module",
|
||||
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
project: ["tsconfig.json"],
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/no-unused-expressions": "off",
|
||||
"@typescript-eslint/dot-notation": "off",
|
||||
"prefer-destructuring": "off",
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^[_]+$",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default config;
|
17953
package-lock.json
generated
17953
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
95
package.json
95
package.json
@ -1,43 +1,44 @@
|
||||
{
|
||||
"name": "docx",
|
||||
"version": "8.2.1",
|
||||
"version": "9.4.0",
|
||||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||
"type": "module",
|
||||
"main": "build/index.umd.js",
|
||||
"module": "./build/index.js",
|
||||
"types": "./build/index.d.ts",
|
||||
"main": "dist/index.umd.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"browser": {
|
||||
"default": "./build/index.umd.js"
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": "./build/index.cjs",
|
||||
"types": "./build/index.d.ts",
|
||||
"import": "./build/index.js",
|
||||
"default": "./build/index.js"
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"build"
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc && vite build",
|
||||
"test": "vitest --ui --coverage",
|
||||
"test.ci": "vitest run --coverage",
|
||||
"test:ci": "vitest run --coverage",
|
||||
"prepublishOnly": "npm run build --omit=dev",
|
||||
"lint": "eslint --ext .ts src",
|
||||
"lint": "eslint --flag unstable_ts_config --config eslint.config.ts",
|
||||
"predemo": "npm run build",
|
||||
"demo": "ts-node --project demo/tsconfig.json ./demo/index.ts",
|
||||
"demo": "tsx ./demo/index.ts",
|
||||
"typedoc": "typedoc src/index.ts --tsconfig tsconfig.typedoc.json",
|
||||
"style": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
|
||||
"style.fix": "npm run style -- --write",
|
||||
"prettier": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
|
||||
"prettier:fix": "npm run prettier -- --write",
|
||||
"cspell": "cspell \"{src,demo,docs,scripts}/**/*.{ts,scss,html,md}\" && cspell \"./*.*\"",
|
||||
"serve.docs": "cd docs && docsify serve",
|
||||
"extract": "ts-node scripts/extract-document.ts",
|
||||
"ts-node": "ts-node --project demo/tsconfig.json"
|
||||
"extract": "tsx scripts/extract-document.ts",
|
||||
"run-ts": "tsx"
|
||||
},
|
||||
"pre-commit": [
|
||||
"style",
|
||||
"prettier",
|
||||
"lint"
|
||||
],
|
||||
"repository": {
|
||||
@ -57,9 +58,10 @@
|
||||
"clippy"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/node": "^22.7.5",
|
||||
"hash.js": "^1.1.7",
|
||||
"jszip": "^3.10.1",
|
||||
"nanoid": "^4.0.2",
|
||||
"nanoid": "^5.1.3",
|
||||
"xml": "^1.0.1",
|
||||
"xml-js": "^1.6.8"
|
||||
},
|
||||
@ -70,40 +72,43 @@
|
||||
},
|
||||
"homepage": "https://docx.js.org",
|
||||
"devDependencies": {
|
||||
"@esbuild/win32-x64": "^0.18.3",
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
"@types/inquirer": "^9.0.3",
|
||||
"@types/prompt": "^1.1.1",
|
||||
"@types/unzipper": "^0.10.4",
|
||||
"@types/xml": "^1.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||
"@typescript-eslint/parser": "^5.36.1",
|
||||
"@vitest/coverage-v8": "^0.33.0",
|
||||
"@vitest/ui": "^0.33.0",
|
||||
"cspell": "^6.2.2",
|
||||
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
||||
"@typescript-eslint/parser": "^8.8.1",
|
||||
"@vitest/coverage-v8": "^3.0.8",
|
||||
"@vitest/ui": "^3.0.8",
|
||||
"cspell": "^8.2.3",
|
||||
"docsify-cli": "^4.3.0",
|
||||
"eslint": "^8.23.0",
|
||||
"eslint-plugin-functional": "^5.0.8",
|
||||
"eslint": "^9.13.0",
|
||||
"eslint-import-resolver-typescript": "^4.3.2",
|
||||
"eslint-plugin-functional": "^7.0.2",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsdoc": "^46.2.6",
|
||||
"eslint-plugin-jsdoc": "^50.3.1",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.3",
|
||||
"eslint-plugin-unicorn": "^47.0.0",
|
||||
"execa": "^7.1.1",
|
||||
"glob": "^10.2.7",
|
||||
"inquirer": "^9.2.7",
|
||||
"jsdom": "^22.1.0",
|
||||
"eslint-plugin-unicorn": "^58.0.0",
|
||||
"execa": "^9.4.0",
|
||||
"glob": "^11.0.0",
|
||||
"inquirer": "^12.0.0",
|
||||
"jiti": "^2.3.3",
|
||||
"jsdom": "^26.0.0",
|
||||
"pre-commit": "^1.2.2",
|
||||
"prettier": "^2.3.1",
|
||||
"ts-node": "^10.2.1",
|
||||
"prettier": "^3.1.1",
|
||||
"tsconfig-paths": "^4.0.0",
|
||||
"typedoc": "^0.24.8",
|
||||
"typescript": "5.1.6",
|
||||
"unzipper": "^0.10.11",
|
||||
"vite": "^4.3.2",
|
||||
"vite-plugin-dts": "^3.3.1",
|
||||
"vite-plugin-node-polyfills": "^0.9.0",
|
||||
"vite-tsconfig-paths": "^4.2.0",
|
||||
"vitest": "^0.33.0"
|
||||
"tsx": "^4.7.0",
|
||||
"typedoc": "^0.28.2",
|
||||
"typescript": "5.3.3",
|
||||
"typescript-eslint": "^8.10.0",
|
||||
"unzipper": "^0.12.3",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^4.2.4",
|
||||
"vite-plugin-node-polyfills": "^0.23.0",
|
||||
"vite-tsconfig-paths": "^5.0.1",
|
||||
"vitest": "^3.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { BaseXmlComponent, IContext, IXmlableObject } from "@file/xml-components";
|
||||
|
||||
export class Formatter {
|
||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||
public format(input: BaseXmlComponent, context: IContext = { stack: [] } as unknown as IContext): IXmlableObject {
|
||||
const output = input.prepForXml(context);
|
||||
|
||||
|
@ -12,7 +12,8 @@ describe("ImageReplacer", () => {
|
||||
"test {test-image.png} test",
|
||||
[
|
||||
{
|
||||
stream: Buffer.from(""),
|
||||
type: "png",
|
||||
data: Buffer.from(""),
|
||||
fileName: "test-image.png",
|
||||
transformation: {
|
||||
pixels: {
|
||||
|
@ -36,7 +36,7 @@ describe("Compiler", () => {
|
||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||
|
||||
expect(fileNames).is.an.instanceof(Array);
|
||||
expect(fileNames).has.length(17);
|
||||
expect(fileNames).has.length(20);
|
||||
expect(fileNames).to.include("word/document.xml");
|
||||
expect(fileNames).to.include("word/styles.xml");
|
||||
expect(fileNames).to.include("docProps/core.xml");
|
||||
@ -47,7 +47,9 @@ describe("Compiler", () => {
|
||||
expect(fileNames).to.include("word/_rels/footnotes.xml.rels");
|
||||
expect(fileNames).to.include("word/settings.xml");
|
||||
expect(fileNames).to.include("word/comments.xml");
|
||||
expect(fileNames).to.include("word/fontTable.xml");
|
||||
expect(fileNames).to.include("word/_rels/document.xml.rels");
|
||||
expect(fileNames).to.include("word/_rels/fontTable.xml.rels");
|
||||
expect(fileNames).to.include("[Content_Types].xml");
|
||||
expect(fileNames).to.include("_rels/.rels");
|
||||
},
|
||||
@ -94,7 +96,7 @@ describe("Compiler", () => {
|
||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||
|
||||
expect(fileNames).is.an.instanceof(Array);
|
||||
expect(fileNames).has.length(25);
|
||||
expect(fileNames).has.length(28);
|
||||
|
||||
expect(fileNames).to.include("word/header1.xml");
|
||||
expect(fileNames).to.include("word/_rels/header1.xml.rels");
|
||||
@ -110,6 +112,41 @@ describe("Compiler", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it(
|
||||
"should pack subfile overrides",
|
||||
async () => {
|
||||
const file = new File({
|
||||
sections: [],
|
||||
comments: {
|
||||
children: [],
|
||||
},
|
||||
});
|
||||
const subfileData1 = "comments";
|
||||
const subfileData2 = "commentsExtended";
|
||||
const overrides = [
|
||||
{ path: "word/comments.xml", data: subfileData1 },
|
||||
{ path: "word/commentsExtended.xml", data: subfileData2 },
|
||||
];
|
||||
const zipFile = compiler.compile(file, "", overrides);
|
||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||
|
||||
expect(fileNames).is.an.instanceof(Array);
|
||||
expect(fileNames).has.length(21);
|
||||
|
||||
expect(fileNames).to.include("word/comments.xml");
|
||||
expect(fileNames).to.include("word/commentsExtended.xml");
|
||||
|
||||
const commentsText = await zipFile.file("word/comments.xml")?.async("text");
|
||||
const commentsExtendedText = await zipFile.file("word/commentsExtended.xml")?.async("text");
|
||||
|
||||
expect(commentsText).toBe(subfileData1);
|
||||
expect(commentsExtendedText).toBe(subfileData2);
|
||||
},
|
||||
{
|
||||
timeout: 99999999,
|
||||
},
|
||||
);
|
||||
|
||||
it("should call the format method X times equalling X files to be formatted", () => {
|
||||
// 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.
|
||||
@ -123,16 +160,13 @@ describe("Compiler", () => {
|
||||
],
|
||||
});
|
||||
|
||||
// tslint:disable-next-line: no-string-literal
|
||||
const spy = vi.spyOn(compiler["formatter"], "format");
|
||||
|
||||
compiler.compile(file);
|
||||
expect(spy).toBeCalledTimes(13);
|
||||
expect(spy).toBeCalledTimes(16);
|
||||
});
|
||||
|
||||
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 file = new File({
|
||||
sections: [
|
||||
{
|
||||
@ -150,12 +184,25 @@ describe("Compiler", () => {
|
||||
new Paragraph({
|
||||
children: [
|
||||
new ImageRun({
|
||||
type: "png",
|
||||
data: Buffer.from("", "base64"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
}),
|
||||
new ImageRun({
|
||||
type: "svg",
|
||||
data: Buffer.from("", "base64"),
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
fallback: {
|
||||
type: "png",
|
||||
data: Buffer.from("", "base64"),
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
@ -165,7 +212,8 @@ describe("Compiler", () => {
|
||||
|
||||
vi.spyOn(compiler["imageReplacer"], "getMediaData").mockReturnValue([
|
||||
{
|
||||
stream: Buffer.from(""),
|
||||
type: "png",
|
||||
data: Buffer.from(""),
|
||||
fileName: "test",
|
||||
transformation: {
|
||||
pixels: {
|
||||
@ -178,9 +226,48 @@ describe("Compiler", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "svg",
|
||||
data: Buffer.from(""),
|
||||
fileName: "test",
|
||||
transformation: {
|
||||
pixels: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
emus: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
},
|
||||
fallback: {
|
||||
type: "png",
|
||||
data: Buffer.from(""),
|
||||
fileName: "test",
|
||||
transformation: {
|
||||
pixels: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
emus: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
compiler.compile(file);
|
||||
});
|
||||
|
||||
it("should work with fonts", () => {
|
||||
const file = new File({
|
||||
sections: [],
|
||||
fonts: [{ name: "Pacifico", data: Buffer.from("") }],
|
||||
});
|
||||
|
||||
compiler.compile(file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,18 +2,19 @@ import JSZip from "jszip";
|
||||
import xml from "xml";
|
||||
|
||||
import { File } from "@file/file";
|
||||
import { obfuscate } from "@file/fonts/obfuscate-ttf-to-odttf";
|
||||
|
||||
import { Formatter } from "../formatter";
|
||||
import { ImageReplacer } from "./image-replacer";
|
||||
import { NumberingReplacer } from "./numbering-replacer";
|
||||
import { PrettifyType } from "./packer";
|
||||
|
||||
interface IXmlifyedFile {
|
||||
export type IXmlifyedFile = {
|
||||
readonly data: string;
|
||||
readonly path: string;
|
||||
}
|
||||
};
|
||||
|
||||
interface IXmlifyedFileMapping {
|
||||
type IXmlifyedFileMapping = {
|
||||
readonly Document: IXmlifyedFile;
|
||||
readonly Styles: IXmlifyedFile;
|
||||
readonly Properties: IXmlifyedFile;
|
||||
@ -31,7 +32,10 @@ interface IXmlifyedFileMapping {
|
||||
readonly FootNotesRelationships: IXmlifyedFile;
|
||||
readonly Settings: IXmlifyedFile;
|
||||
readonly Comments?: IXmlifyedFile;
|
||||
}
|
||||
readonly CommentsRelationships?: IXmlifyedFile;
|
||||
readonly FontTable?: IXmlifyedFile;
|
||||
readonly FontTableRelationships?: IXmlifyedFile;
|
||||
};
|
||||
|
||||
export class Compiler {
|
||||
private readonly formatter: Formatter;
|
||||
@ -44,7 +48,11 @@ export class Compiler {
|
||||
this.numberingReplacer = new NumberingReplacer();
|
||||
}
|
||||
|
||||
public compile(file: File, prettifyXml?: PrettifyType): JSZip {
|
||||
public compile(
|
||||
file: File,
|
||||
prettifyXml?: (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): JSZip {
|
||||
const zip = new JSZip();
|
||||
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
||||
const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||
@ -59,14 +67,28 @@ export class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
for (const { stream, fileName } of file.Media.Array) {
|
||||
zip.file(`word/media/${fileName}`, stream);
|
||||
for (const subFile of overrides) {
|
||||
zip.file(subFile.path, subFile.data);
|
||||
}
|
||||
|
||||
for (const data of file.Media.Array) {
|
||||
if (data.type !== "svg") {
|
||||
zip.file(`word/media/${data.fileName}`, data.data);
|
||||
} else {
|
||||
zip.file(`word/media/${data.fileName}`, data.data);
|
||||
zip.file(`word/media/${data.fallback.fileName}`, data.fallback.data);
|
||||
}
|
||||
}
|
||||
|
||||
for (const { data: buffer, name, fontKey } of file.FontTable.fontOptionsWithKey) {
|
||||
const [nameWithoutExtension] = name.split(".");
|
||||
zip.file(`word/fonts/${nameWithoutExtension}.odttf`, obfuscate(buffer, fontKey));
|
||||
}
|
||||
|
||||
return zip;
|
||||
}
|
||||
|
||||
private xmlifyFile(file: File, prettify?: PrettifyType): IXmlifyedFileMapping {
|
||||
private xmlifyFile(file: File, prettify?: (typeof PrettifyType)[keyof typeof PrettifyType]): IXmlifyedFileMapping {
|
||||
const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
|
||||
|
||||
const documentXmlData = xml(
|
||||
@ -83,7 +105,28 @@ export class Compiler {
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const commentRelationshipCount = file.Comments.Relationships.RelationshipCount + 1;
|
||||
const commentXmlData = xml(
|
||||
this.formatter.format(file.Comments, {
|
||||
viewWrapper: {
|
||||
View: file.Comments,
|
||||
Relationships: file.Comments.Relationships,
|
||||
},
|
||||
file,
|
||||
stack: [],
|
||||
}),
|
||||
{
|
||||
indent: prettify,
|
||||
declaration: {
|
||||
standalone: "yes",
|
||||
encoding: "UTF-8",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
|
||||
const commentMediaDatas = this.imageReplacer.getMediaData(commentXmlData, file.Media);
|
||||
|
||||
return {
|
||||
Relationships: {
|
||||
@ -96,6 +139,12 @@ export class Compiler {
|
||||
);
|
||||
});
|
||||
|
||||
file.Document.Relationships.createRelationship(
|
||||
file.Document.Relationships.RelationshipCount + 1,
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
|
||||
"fontTable.xml",
|
||||
);
|
||||
|
||||
return xml(
|
||||
this.formatter.format(file.Document.Relationships, {
|
||||
viewWrapper: file.Document,
|
||||
@ -423,8 +472,44 @@ export class Compiler {
|
||||
path: "word/settings.xml",
|
||||
},
|
||||
Comments: {
|
||||
data: (() => {
|
||||
const xmlData = this.imageReplacer.replace(commentXmlData, commentMediaDatas, commentRelationshipCount);
|
||||
const referenedXmlData = this.numberingReplacer.replace(xmlData, file.Numbering.ConcreteNumbering);
|
||||
return referenedXmlData;
|
||||
})(),
|
||||
path: "word/comments.xml",
|
||||
},
|
||||
CommentsRelationships: {
|
||||
data: (() => {
|
||||
commentMediaDatas.forEach((mediaData, i) => {
|
||||
file.Comments.Relationships.createRelationship(
|
||||
commentRelationshipCount + i,
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
`media/${mediaData.fileName}`,
|
||||
);
|
||||
});
|
||||
return xml(
|
||||
this.formatter.format(file.Comments.Relationships, {
|
||||
viewWrapper: {
|
||||
View: file.Comments,
|
||||
Relationships: file.Comments.Relationships,
|
||||
},
|
||||
file,
|
||||
stack: [],
|
||||
}),
|
||||
{
|
||||
indent: prettify,
|
||||
declaration: {
|
||||
encoding: "UTF-8",
|
||||
},
|
||||
},
|
||||
);
|
||||
})(),
|
||||
path: "word/_rels/comments.xml.rels",
|
||||
},
|
||||
FontTable: {
|
||||
data: xml(
|
||||
this.formatter.format(file.Comments, {
|
||||
this.formatter.format(file.FontTable.View, {
|
||||
viewWrapper: file.Document,
|
||||
file,
|
||||
stack: [],
|
||||
@ -437,7 +522,24 @@ export class Compiler {
|
||||
},
|
||||
},
|
||||
),
|
||||
path: "word/comments.xml",
|
||||
path: "word/fontTable.xml",
|
||||
},
|
||||
FontTableRelationships: {
|
||||
data: (() =>
|
||||
xml(
|
||||
this.formatter.format(file.FontTable.Relationships, {
|
||||
viewWrapper: file.Document,
|
||||
file,
|
||||
stack: [],
|
||||
}),
|
||||
{
|
||||
indent: prettify,
|
||||
declaration: {
|
||||
encoding: "UTF-8",
|
||||
},
|
||||
},
|
||||
))(),
|
||||
path: "word/_rels/fontTable.xml.rels",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, true);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_2_BLANKS);
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_2_BLANKS, expect.anything());
|
||||
});
|
||||
|
||||
it("should use a prettify value", async () => {
|
||||
@ -55,7 +55,7 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, PrettifyType.WITH_4_BLANKS);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_4_BLANKS);
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_4_BLANKS, expect.anything());
|
||||
});
|
||||
|
||||
it("should use an undefined prettify value", async () => {
|
||||
@ -64,7 +64,32 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, false);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined);
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined, expect.anything());
|
||||
});
|
||||
});
|
||||
|
||||
describe("overrides", () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should use an overrides value", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const spy = vi.spyOn((Packer as any).compiler, "compile");
|
||||
const overrides = [{ path: "word/comments.xml", data: "comments" }];
|
||||
|
||||
await Packer.toString(file, true, overrides);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), expect.anything(), overrides);
|
||||
});
|
||||
|
||||
it("should use a default overrides value", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const spy = vi.spyOn((Packer as any).compiler, "compile");
|
||||
|
||||
await Packer.toString(file);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined, []);
|
||||
});
|
||||
});
|
||||
|
||||
@ -139,7 +164,6 @@ describe("Packer", () => {
|
||||
it("should create a standard docx file", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
vi.spyOn((Packer as any).compiler, "compile").mockReturnValue({
|
||||
// tslint:disable-next-line: no-empty
|
||||
generateAsync: () => vi.fn(),
|
||||
});
|
||||
const str = await Packer.toBlob(file);
|
||||
@ -163,11 +187,37 @@ describe("Packer", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toArrayBuffer()", () => {
|
||||
it("should create a standard docx file", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
vi.spyOn((Packer as any).compiler, "compile").mockReturnValue({
|
||||
generateAsync: () => vi.fn(),
|
||||
});
|
||||
const str = await Packer.toArrayBuffer(file);
|
||||
|
||||
assert.isDefined(str);
|
||||
});
|
||||
|
||||
it("should handle exception if it throws any", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
vi.spyOn((Packer as any).compiler, "compile").mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
return Packer.toArrayBuffer(file).catch((error) => {
|
||||
assert.isDefined(error);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
});
|
||||
|
||||
describe("#toStream()", () => {
|
||||
it("should create a standard docx file", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
vi.spyOn((Packer as any).compiler, "compile").mockReturnValue({
|
||||
// tslint:disable-next-line: no-empty
|
||||
generateAsync: () => Promise.resolve(vi.fn()),
|
||||
});
|
||||
const stream = Packer.toStream(file);
|
||||
|
@ -1,69 +1,89 @@
|
||||
import { Stream } from "stream";
|
||||
import { File } from "@file/file";
|
||||
|
||||
import { Compiler } from "./next-compiler";
|
||||
import { File } from "@file/file";
|
||||
import { OutputByType, OutputType } from "@util/output-type";
|
||||
|
||||
import { Compiler, IXmlifyedFile } from "./next-compiler";
|
||||
|
||||
/**
|
||||
* Use blanks to prettify
|
||||
*/
|
||||
export enum PrettifyType {
|
||||
NONE = "",
|
||||
WITH_2_BLANKS = " ",
|
||||
WITH_4_BLANKS = " ",
|
||||
WITH_TAB = "\t",
|
||||
}
|
||||
export const PrettifyType = {
|
||||
NONE: "",
|
||||
WITH_2_BLANKS: " ",
|
||||
WITH_4_BLANKS: " ",
|
||||
|
||||
const convertPrettifyType = (prettify?: boolean | PrettifyType): PrettifyType | undefined =>
|
||||
WITH_TAB: "\t",
|
||||
} as const;
|
||||
|
||||
const convertPrettifyType = (
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
): (typeof PrettifyType)[keyof typeof PrettifyType] | undefined =>
|
||||
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify;
|
||||
|
||||
export class Packer {
|
||||
public static async toString(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "string",
|
||||
// eslint-disable-next-line require-await
|
||||
public static async pack<T extends OutputType>(
|
||||
file: File,
|
||||
type: T,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<OutputByType[T]> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
return zip.generateAsync({
|
||||
type,
|
||||
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, convertPrettifyType(prettify));
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "nodebuffer",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
compression: "DEFLATE",
|
||||
});
|
||||
|
||||
return zipData;
|
||||
public static toString(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<string> {
|
||||
return Packer.pack(file, "string", prettify, overrides);
|
||||
}
|
||||
|
||||
public static async toBase64String(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "base64",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
compression: "DEFLATE",
|
||||
});
|
||||
|
||||
return zipData;
|
||||
public static toBuffer(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<Buffer> {
|
||||
return Packer.pack(file, "nodebuffer", prettify, overrides);
|
||||
}
|
||||
|
||||
public static async toBlob(file: File, prettify?: boolean | PrettifyType): Promise<Blob> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "blob",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
compression: "DEFLATE",
|
||||
});
|
||||
|
||||
return zipData;
|
||||
public static toBase64String(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<string> {
|
||||
return Packer.pack(file, "base64", prettify, overrides);
|
||||
}
|
||||
|
||||
public static toStream(file: File, prettify?: boolean | PrettifyType): Stream {
|
||||
public static toBlob(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<Blob> {
|
||||
return Packer.pack(file, "blob", prettify, overrides);
|
||||
}
|
||||
|
||||
public static toArrayBuffer(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<ArrayBuffer> {
|
||||
return Packer.pack(file, "arraybuffer", prettify, overrides);
|
||||
}
|
||||
|
||||
public static toStream(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Stream {
|
||||
const stream = new Stream();
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
|
||||
zip.generateAsync({
|
||||
type: "nodebuffer",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { AppPropertiesAttributes } from "./app-properties-attributes";
|
||||
|
||||
export class AppProperties extends XmlComponent {
|
||||
|
@ -22,15 +22,15 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { eighthPointMeasureValue, hexColorValue, pointMeasureValue } from "@util/values";
|
||||
|
||||
export interface IBorderOptions {
|
||||
readonly style: BorderStyle;
|
||||
export type IBorderOptions = {
|
||||
readonly style: (typeof BorderStyle)[keyof typeof BorderStyle];
|
||||
/** Border color, in hex (eg 'FF00AA') */
|
||||
readonly color?: string;
|
||||
/** Size of the border in 1/8 pt */
|
||||
readonly size?: number;
|
||||
/** Spacing offset. Values are specified in pt */
|
||||
readonly space?: number;
|
||||
}
|
||||
};
|
||||
|
||||
export class BorderElement extends XmlComponent {
|
||||
public constructor(elementName: string, { color, size, space, style }: IBorderOptions) {
|
||||
@ -55,32 +55,101 @@ class BordersAttributes extends XmlAttributeComponent<IBorderOptions> {
|
||||
};
|
||||
}
|
||||
|
||||
export enum BorderStyle {
|
||||
SINGLE = "single",
|
||||
DASH_DOT_STROKED = "dashDotStroked",
|
||||
DASHED = "dashed",
|
||||
DASH_SMALL_GAP = "dashSmallGap",
|
||||
DOT_DASH = "dotDash",
|
||||
DOT_DOT_DASH = "dotDotDash",
|
||||
DOTTED = "dotted",
|
||||
DOUBLE = "double",
|
||||
DOUBLE_WAVE = "doubleWave",
|
||||
INSET = "inset",
|
||||
NIL = "nil",
|
||||
NONE = "none",
|
||||
OUTSET = "outset",
|
||||
THICK = "thick",
|
||||
THICK_THIN_LARGE_GAP = "thickThinLargeGap",
|
||||
THICK_THIN_MEDIUM_GAP = "thickThinMediumGap",
|
||||
THICK_THIN_SMALL_GAP = "thickThinSmallGap",
|
||||
THIN_THICK_LARGE_GAP = "thinThickLargeGap",
|
||||
THIN_THICK_MEDIUM_GAP = "thinThickMediumGap",
|
||||
THIN_THICK_SMALL_GAP = "thinThickSmallGap",
|
||||
THIN_THICK_THIN_LARGE_GAP = "thinThickThinLargeGap",
|
||||
THIN_THICK_THIN_MEDIUM_GAP = "thinThickThinMediumGap",
|
||||
THIN_THICK_THIN_SMALL_GAP = "thinThickThinSmallGap",
|
||||
THREE_D_EMBOSS = "threeDEmboss",
|
||||
THREE_D_ENGRAVE = "threeDEngrave",
|
||||
TRIPLE = "triple",
|
||||
WAVE = "wave",
|
||||
}
|
||||
/**
|
||||
* Table borders are defined with the <w:tblBorders> element. Child elements of this element specify the kinds of `border`:
|
||||
*
|
||||
* `bottom`, `end` (`right` in the previous version of the standard), `insideH`, `insideV`, `start` (`left` in the previous version of the standard), and `top`.
|
||||
*
|
||||
* Reference: http://officeopenxml.com/WPtableBorders.php
|
||||
*
|
||||
* ## XSD Schema
|
||||
* ```xml
|
||||
* <xsd:simpleType name="ST_Border">
|
||||
* <xsd:restriction base="xsd:string">
|
||||
* <xsd:enumeration value="single"/>
|
||||
* <xsd:enumeration value="dashDotStroked"/>
|
||||
* <xsd:enumeration value="dashed"/>
|
||||
* <xsd:enumeration value="dashSmallGap"/>
|
||||
* <xsd:enumeration value="dotDash"/>
|
||||
* <xsd:enumeration value="dotDotDash"/>
|
||||
* <xsd:enumeration value="dotted"/>
|
||||
* <xsd:enumeration value="double"/>
|
||||
* <xsd:enumeration value="doubleWave"/>
|
||||
* <xsd:enumeration value="inset"/>
|
||||
* <xsd:enumeration value="nil"/>
|
||||
* <xsd:enumeration value="none"/>
|
||||
* <xsd:enumeration value="outset"/>
|
||||
* <xsd:enumeration value="thick"/>
|
||||
* <xsd:enumeration value="thickThinLargeGap"/>
|
||||
* <xsd:enumeration value="thickThinMediumGap"/>
|
||||
* <xsd:enumeration value="thickThinSmallGap"/>
|
||||
* <xsd:enumeration value="thinThickLargeGap"/>
|
||||
* <xsd:enumeration value="thinThickMediumGap"/>
|
||||
* <xsd:enumeration value="thinThickSmallGap"/>
|
||||
* <xsd:enumeration value="thinThickThinLargeGap"/>
|
||||
* <xsd:enumeration value="thinThickThinMediumGap"/>
|
||||
* <xsd:enumeration value="thinThickThinSmallGap"/>
|
||||
* <xsd:enumeration value="threeDEmboss"/>
|
||||
* <xsd:enumeration value="threeDEngrave"/>
|
||||
* <xsd:enumeration value="triple"/>
|
||||
* <xsd:enumeration value="wave"/>
|
||||
* </xsd:restriction>
|
||||
* </xsd:simpleType>
|
||||
* ```
|
||||
*/
|
||||
export const BorderStyle = {
|
||||
/** a single line */
|
||||
SINGLE: "single",
|
||||
/** a line with a series of alternating thin and thick strokes */
|
||||
DASH_DOT_STROKED: "dashDotStroked",
|
||||
/** a dashed line */
|
||||
DASHED: "dashed",
|
||||
/** a dashed line with small gaps */
|
||||
DASH_SMALL_GAP: "dashSmallGap",
|
||||
/** a line with alternating dots and dashes */
|
||||
DOT_DASH: "dotDash",
|
||||
/** a line with a repeating dot - dot - dash sequence */
|
||||
DOT_DOT_DASH: "dotDotDash",
|
||||
/** a dotted line */
|
||||
DOTTED: "dotted",
|
||||
/** a double line */
|
||||
DOUBLE: "double",
|
||||
/** a double wavy line */
|
||||
DOUBLE_WAVE: "doubleWave",
|
||||
/** an inset set of lines */
|
||||
INSET: "inset",
|
||||
/** no border */
|
||||
NIL: "nil",
|
||||
/** no border */
|
||||
NONE: "none",
|
||||
/** an outset set of lines */
|
||||
OUTSET: "outset",
|
||||
/** a single line */
|
||||
THICK: "thick",
|
||||
/** a thick line contained within a thin line with a large-sized intermediate gap */
|
||||
THICK_THIN_LARGE_GAP: "thickThinLargeGap",
|
||||
/** a thick line contained within a thin line with a medium-sized intermediate gap */
|
||||
THICK_THIN_MEDIUM_GAP: "thickThinMediumGap",
|
||||
/** a thick line contained within a thin line with a small intermediate gap */
|
||||
THICK_THIN_SMALL_GAP: "thickThinSmallGap",
|
||||
/** a thin line contained within a thick line with a large-sized intermediate gap */
|
||||
THIN_THICK_LARGE_GAP: "thinThickLargeGap",
|
||||
/** a thick line contained within a thin line with a medium-sized intermediate gap */
|
||||
THIN_THICK_MEDIUM_GAP: "thinThickMediumGap",
|
||||
/** a thick line contained within a thin line with a small intermediate gap */
|
||||
THIN_THICK_SMALL_GAP: "thinThickSmallGap",
|
||||
/** a thin-thick-thin line with a large gap */
|
||||
THIN_THICK_THIN_LARGE_GAP: "thinThickThinLargeGap",
|
||||
/** a thin-thick-thin line with a medium gap */
|
||||
THIN_THICK_THIN_MEDIUM_GAP: "thinThickThinMediumGap",
|
||||
/** a thin-thick-thin line with a small gap */
|
||||
THIN_THICK_THIN_SMALL_GAP: "thinThickThinSmallGap",
|
||||
/** a three-staged gradient line, getting darker towards the paragraph */
|
||||
THREE_D_EMBOSS: "threeDEmboss",
|
||||
/** a three-staged gradient like, getting darker away from the paragraph */
|
||||
THREE_D_ENGRAVE: "threeDEngrave",
|
||||
/** a triple line */
|
||||
TRIPLE: "triple",
|
||||
/** a wavy line */
|
||||
WAVE: "wave",
|
||||
} as const;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { CheckBoxUtil } from ".";
|
||||
|
||||
describe("CheckBoxUtil", () => {
|
||||
|
@ -7,20 +7,20 @@
|
||||
// </xsd:complexType>
|
||||
// <xsd:element name="checkbox" type="CT_SdtCheckbox"/>
|
||||
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
import { CheckBoxSymbolElement } from "@file/checkbox/checkbox-symbol";
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
export interface ICheckboxSymbolProperties {
|
||||
export type ICheckboxSymbolProperties = {
|
||||
readonly value?: string;
|
||||
readonly font?: string;
|
||||
}
|
||||
};
|
||||
|
||||
export interface ICheckboxSymbolOptions {
|
||||
export type ICheckboxSymbolOptions = {
|
||||
readonly alias?: string;
|
||||
readonly checked?: boolean;
|
||||
readonly checkedState?: ICheckboxSymbolProperties;
|
||||
readonly uncheckedState?: ICheckboxSymbolProperties;
|
||||
}
|
||||
};
|
||||
|
||||
export class CheckBoxUtil extends XmlComponent {
|
||||
private readonly DEFAULT_UNCHECKED_SYMBOL: string = "2610";
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { CheckBox } from "./checkbox";
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { SymbolRun } from "@file/paragraph/run/symbol-run";
|
||||
import { StructuredDocumentTagProperties } from "@file/table-of-contents/sdt-properties";
|
||||
import { StructuredDocumentTagContent } from "@file/table-of-contents/sdt-content";
|
||||
import { StructuredDocumentTagProperties } from "@file/table-of-contents/sdt-properties";
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { CheckBoxUtil, ICheckboxSymbolOptions } from "./checkbox-util";
|
||||
|
||||
export class CheckBox extends XmlComponent {
|
||||
|
@ -1,5 +1,3 @@
|
||||
// tslint:disable:no-string-literal
|
||||
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
@ -25,11 +23,21 @@ describe("ContentTypes", () => {
|
||||
expect(tree["Types"][3]).to.deep.equal({ Default: { _attr: { ContentType: "image/jpeg", Extension: "jpg" } } });
|
||||
expect(tree["Types"][4]).to.deep.equal({ Default: { _attr: { ContentType: "image/bmp", Extension: "bmp" } } });
|
||||
expect(tree["Types"][5]).to.deep.equal({ Default: { _attr: { ContentType: "image/gif", Extension: "gif" } } });
|
||||
expect(tree["Types"][6]).to.deep.equal({
|
||||
expect(tree["Types"][6]).to.deep.equal({ Default: { _attr: { ContentType: "image/svg+xml", Extension: "svg" } } });
|
||||
expect(tree["Types"][7]).to.deep.equal({
|
||||
Default: { _attr: { ContentType: "application/vnd.openxmlformats-package.relationships+xml", Extension: "rels" } },
|
||||
});
|
||||
expect(tree["Types"][7]).to.deep.equal({ Default: { _attr: { ContentType: "application/xml", Extension: "xml" } } });
|
||||
expect(tree["Types"][8]).to.deep.equal({
|
||||
expect(tree["Types"][8]).to.deep.equal({ Default: { _attr: { ContentType: "application/xml", Extension: "xml" } } });
|
||||
|
||||
expect(tree["Types"][9]).to.deep.equal({
|
||||
Default: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.obfuscatedFont",
|
||||
Extension: "odttf",
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][10]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
|
||||
@ -37,7 +45,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][9]).to.deep.equal({
|
||||
expect(tree["Types"][11]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
|
||||
@ -45,7 +53,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][10]).to.deep.equal({
|
||||
expect(tree["Types"][12]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-package.core-properties+xml",
|
||||
@ -53,7 +61,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][11]).to.deep.equal({
|
||||
expect(tree["Types"][13]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.custom-properties+xml",
|
||||
@ -61,7 +69,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][12]).to.deep.equal({
|
||||
expect(tree["Types"][14]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml",
|
||||
@ -69,7 +77,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][13]).to.deep.equal({
|
||||
expect(tree["Types"][15]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
|
||||
@ -77,7 +85,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][14]).to.deep.equal({
|
||||
expect(tree["Types"][16]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
|
||||
@ -85,7 +93,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(tree["Types"][15]).to.deep.equal({
|
||||
expect(tree["Types"][17]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
|
||||
@ -102,7 +110,7 @@ describe("ContentTypes", () => {
|
||||
contentTypes.addFooter(102);
|
||||
const tree = new Formatter().format(contentTypes);
|
||||
|
||||
expect(tree["Types"][17]).to.deep.equal({
|
||||
expect(tree["Types"][20]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
|
||||
@ -111,7 +119,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(tree["Types"][18]).to.deep.equal({
|
||||
expect(tree["Types"][21]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
|
||||
@ -128,7 +136,7 @@ describe("ContentTypes", () => {
|
||||
contentTypes.addHeader(202);
|
||||
const tree = new Formatter().format(contentTypes);
|
||||
|
||||
expect(tree["Types"][17]).to.deep.equal({
|
||||
expect(tree["Types"][20]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
|
||||
@ -137,7 +145,7 @@ describe("ContentTypes", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(tree["Types"][18]).to.deep.equal({
|
||||
expect(tree["Types"][21]).to.deep.equal({
|
||||
Override: {
|
||||
_attr: {
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { ContentTypeAttributes } from "./content-types-attributes";
|
||||
import { Default } from "./default/default";
|
||||
import { Override } from "./override/override";
|
||||
@ -18,8 +19,10 @@ export class ContentTypes extends XmlComponent {
|
||||
this.root.push(new Default("image/jpeg", "jpg"));
|
||||
this.root.push(new Default("image/bmp", "bmp"));
|
||||
this.root.push(new Default("image/gif", "gif"));
|
||||
this.root.push(new Default("image/svg+xml", "svg"));
|
||||
this.root.push(new Default("application/vnd.openxmlformats-package.relationships+xml", "rels"));
|
||||
this.root.push(new Default("application/xml", "xml"));
|
||||
this.root.push(new Default("application/vnd.openxmlformats-officedocument.obfuscatedFont", "odttf"));
|
||||
|
||||
this.root.push(
|
||||
new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "/word/document.xml"),
|
||||
@ -33,6 +36,7 @@ export class ContentTypes extends XmlComponent {
|
||||
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml", "/word/footnotes.xml"));
|
||||
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml", "/word/settings.xml"));
|
||||
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml", "/word/comments.xml"));
|
||||
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml", "/word/fontTable.xml"));
|
||||
}
|
||||
|
||||
public addFooter(index: number): void {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { DefaultAttributes } from "./default-attributes";
|
||||
|
||||
export class Default extends XmlComponent {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { OverrideAttributes } from "./override-attributes";
|
||||
|
||||
export class Override extends XmlComponent {
|
||||
|
@ -45,7 +45,7 @@ describe("Properties", () => {
|
||||
expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const key = (obj: { readonly [key: string]: any }) => Object.keys(obj)[0];
|
||||
const key = (obj: Readonly<Record<string, any>>) => Object.keys(obj)[0];
|
||||
expect(tree["cp:coreProperties"].map(key)).to.include.members([
|
||||
"_attr",
|
||||
"cp:keywords",
|
||||
|
@ -1,18 +1,19 @@
|
||||
import { FontOptions } from "@file/fonts/font-table";
|
||||
import { ICommentsOptions } from "@file/paragraph/run/comment-run";
|
||||
import { IHyphenationOptions } from "@file/settings";
|
||||
import { ICompatibilityOptions } from "@file/settings/compatibility";
|
||||
import { StringContainer, XmlComponent } from "@file/xml-components";
|
||||
import { StringContainer, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { dateTimeValue } from "@util/values";
|
||||
|
||||
import { ICustomPropertyOptions } from "../custom-properties";
|
||||
import { IDocumentBackgroundOptions } from "../document";
|
||||
|
||||
import { DocumentAttributes } from "../document/document-attributes";
|
||||
import { ISectionOptions } from "../file";
|
||||
import { INumberingOptions } from "../numbering";
|
||||
import { Paragraph } from "../paragraph";
|
||||
import { IStylesOptions } from "../styles";
|
||||
|
||||
export interface IPropertiesOptions {
|
||||
export type IPropertiesOptions = {
|
||||
readonly sections: readonly ISectionOptions[];
|
||||
readonly title?: string;
|
||||
readonly subject?: string;
|
||||
@ -25,11 +26,14 @@ export interface IPropertiesOptions {
|
||||
readonly styles?: IStylesOptions;
|
||||
readonly numbering?: INumberingOptions;
|
||||
readonly comments?: ICommentsOptions;
|
||||
readonly footnotes?: {
|
||||
readonly [key: string]: {
|
||||
readonly children: readonly Paragraph[];
|
||||
};
|
||||
};
|
||||
readonly footnotes?: Readonly<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
readonly children: readonly Paragraph[];
|
||||
}
|
||||
>
|
||||
>;
|
||||
readonly background?: IDocumentBackgroundOptions;
|
||||
readonly features?: {
|
||||
readonly trackRevisions?: boolean;
|
||||
@ -39,7 +43,10 @@ export interface IPropertiesOptions {
|
||||
readonly compatibility?: ICompatibilityOptions;
|
||||
readonly customProperties?: readonly ICustomPropertyOptions[];
|
||||
readonly evenAndOddHeaderAndFooters?: boolean;
|
||||
}
|
||||
readonly defaultTabStop?: number;
|
||||
readonly fonts?: readonly FontOptions[];
|
||||
readonly hyphenation?: IHyphenationOptions;
|
||||
};
|
||||
|
||||
// <xs:element name="coreProperties" type="CT_CoreProperties"/>
|
||||
|
||||
@ -68,15 +75,7 @@ export interface IPropertiesOptions {
|
||||
export class CoreProperties extends XmlComponent {
|
||||
public constructor(options: Omit<IPropertiesOptions, "sections">) {
|
||||
super("cp:coreProperties");
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
|
||||
dc: "http://purl.org/dc/elements/1.1/",
|
||||
dcterms: "http://purl.org/dc/terms/",
|
||||
dcmitype: "http://purl.org/dc/dcmitype/",
|
||||
xsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
}),
|
||||
);
|
||||
this.root.push(new DocumentAttributes(["cp", "dc", "dcterms", "dcmitype", "xsi"]));
|
||||
if (options.title) {
|
||||
this.root.push(new StringContainer("dc:title", options.title));
|
||||
}
|
||||
@ -103,11 +102,15 @@ export class CoreProperties extends XmlComponent {
|
||||
}
|
||||
}
|
||||
|
||||
class TimestampElementProperties extends XmlAttributeComponent<{ readonly type: string }> {
|
||||
protected readonly xmlKeys = { type: "xsi:type" };
|
||||
}
|
||||
|
||||
class TimestampElement extends XmlComponent {
|
||||
public constructor(name: string) {
|
||||
super(name);
|
||||
this.root.push(
|
||||
new DocumentAttributes({
|
||||
new TimestampElementProperties({
|
||||
type: "dcterms:W3CDTF",
|
||||
}),
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { IContext, IXmlableObject, XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { CustomPropertiesAttributes } from "./custom-properties-attributes";
|
||||
import { CustomProperty, ICustomPropertyOptions } from "./custom-property";
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { CustomPropertyAttributes } from "./custom-property-attributes";
|
||||
|
||||
export interface ICustomPropertyOptions {
|
||||
export type ICustomPropertyOptions = {
|
||||
readonly name: string;
|
||||
readonly value: string;
|
||||
}
|
||||
};
|
||||
|
||||
export class CustomProperty extends XmlComponent {
|
||||
public constructor(id: number, properties: ICustomPropertyOptions) {
|
||||
|
@ -3,11 +3,12 @@ import { Footer } from "./footer/footer";
|
||||
import { FootNotes } from "./footnotes";
|
||||
import { Header } from "./header/header";
|
||||
import { Relationships } from "./relationships";
|
||||
import { XmlComponent } from "./xml-components";
|
||||
|
||||
export interface IViewWrapper {
|
||||
readonly View: Document | Footer | Header | FootNotes;
|
||||
export type IViewWrapper = {
|
||||
readonly View: Document | Footer | Header | FootNotes | XmlComponent;
|
||||
readonly Relationships: Relationships;
|
||||
}
|
||||
};
|
||||
|
||||
export class DocumentWrapper implements IViewWrapper {
|
||||
private readonly document: Document;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { decimalNumber, PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||
import { PositiveUniversalMeasure, decimalNumber, twipsMeasureValue } from "@util/values";
|
||||
|
||||
import { Column } from "./column";
|
||||
|
||||
|
@ -2,26 +2,26 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { DocumentGrid, DocumentGridType } from ".";
|
||||
import { DocumentGridType, createDocumentGrid } from ".";
|
||||
|
||||
describe("DocumentGrid", () => {
|
||||
describe("createDocumentGrid", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("should create documentGrid with specified linePitch", () => {
|
||||
const docGrid = new DocumentGrid(360);
|
||||
const docGrid = createDocumentGrid({ linePitch: 360 });
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 360 } });
|
||||
});
|
||||
|
||||
it("should create documentGrid with specified linePitch and type", () => {
|
||||
const docGrid = new DocumentGrid(360, undefined, DocumentGridType.LINES);
|
||||
const docGrid = createDocumentGrid({ linePitch: 360, type: DocumentGridType.LINES });
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 360, "w:type": "lines" } });
|
||||
});
|
||||
|
||||
it("should create documentGrid with specified linePitch,charSpace and type", () => {
|
||||
const docGrid = new DocumentGrid(346, -1541, DocumentGridType.LINES_AND_CHARS);
|
||||
const docGrid = createDocumentGrid({ linePitch: 346, charSpace: -1541, type: DocumentGridType.LINES_AND_CHARS });
|
||||
const tree = new Formatter().format(docGrid);
|
||||
|
||||
expect(tree["w:docGrid"]).to.deep.equal({ _attr: { "w:linePitch": 346, "w:charSpace": -1541, "w:type": "linesAndChars" } });
|
||||
|
@ -1,52 +1,113 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { BuilderElement, XmlComponent } from "@file/xml-components";
|
||||
import { decimalNumber } from "@util/values";
|
||||
|
||||
// not implemented
|
||||
// <xsd:simpleType name="ST_DocGrid">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:enumeration value="default"/>
|
||||
// <xsd:enumeration value="lines"/>
|
||||
// <xsd:enumeration value="linesAndChars"/>
|
||||
// <xsd:enumeration value="snapToChars"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
/**
|
||||
* Specifies the type of the current document grid, which defines the grid behavior.
|
||||
*
|
||||
* The grid can define a grid which snaps all East Asian characters to grid positions, but leaves Latin text with its default spacing; a grid which adds the specified character pitch to all characters on each row; or a grid which affects only the line pitch for the current section.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_ST_DocGrid_topic_ID0ELYP2.html
|
||||
*
|
||||
* ## XSD Schema
|
||||
* ```xml
|
||||
* <xsd:simpleType name="ST_DocGrid">
|
||||
* <xsd:restriction base="xsd:string">
|
||||
* <xsd:enumeration value="default"/>
|
||||
* <xsd:enumeration value="lines"/>
|
||||
* <xsd:enumeration value="linesAndChars"/>
|
||||
* <xsd:enumeration value="snapToChars"/>
|
||||
* </xsd:restriction>
|
||||
* </xsd:simpleType>
|
||||
* ```
|
||||
*/
|
||||
export const DocumentGridType = {
|
||||
/**
|
||||
* Specifies that no document grid shall be applied to the contents of the current section in the document.
|
||||
*/
|
||||
DEFAULT: "default",
|
||||
/**
|
||||
* Specifies that the parent section shall have additional line pitch added to each line within it (as specified on the <docGrid> element (§2.6.5)) in order to maintain the specified number of lines per page.
|
||||
*/
|
||||
LINES: "lines",
|
||||
/**
|
||||
* Specifies that the parent section shall have both the additional line pitch and character pitch added to each line and character within it (as specified on the <docGrid> element (§2.6.5)) in order to maintain a specific number of lines per page and characters per line.
|
||||
*
|
||||
* When this value is set, the input specified via the user interface may be allowed in exact number of line/character pitch units. */
|
||||
LINES_AND_CHARS: "linesAndChars",
|
||||
/**
|
||||
* Specifies that the parent section shall have both the additional line pitch and character pitch added to each line and character within it (as specified on the <docGrid> element (§2.6.5)) in order to maintain a specific number of lines per page and characters per line.
|
||||
*
|
||||
* When this value is set, the input specified via the user interface may be restricted to the number of lines per page and characters per line, with the consumer or producer translating this information based on the current font data to get the resulting line and character pitch values
|
||||
*/
|
||||
SNAP_TO_CHARS: "snapToChars",
|
||||
} as const;
|
||||
|
||||
// <xsd:complexType name="CT_DocGrid">
|
||||
// <xsd:attribute name="type" type="ST_DocGrid"/>
|
||||
// <xsd:attribute name="linePitch" type="ST_DecimalNumber"/>
|
||||
// <xsd:attribute name="charSpace" type="ST_DecimalNumber"/>
|
||||
// </xsd:complexType>
|
||||
|
||||
export enum DocumentGridType {
|
||||
DEFAULT = "default",
|
||||
LINES = "lines",
|
||||
LINES_AND_CHARS = "linesAndChars",
|
||||
SNAP_TO_CHARS = "snapToChars",
|
||||
}
|
||||
export interface IDocGridAttributesProperties {
|
||||
readonly type?: DocumentGridType;
|
||||
readonly linePitch?: number;
|
||||
export type IDocGridAttributesProperties = {
|
||||
/**
|
||||
* Specifies the type of the current document grid, which defines the grid behavior.
|
||||
*
|
||||
* The grid can define a grid which snaps all East Asian characters to grid positions, but leaves Latin text with its default spacing; a grid which adds the specified character pitch to each character on each row; or a grid which affects only the line pitch for the current section.
|
||||
*/
|
||||
readonly type?: (typeof DocumentGridType)[keyof typeof DocumentGridType];
|
||||
/**
|
||||
* Specifies the number of lines to be allowed on the document grid for the current page assuming all lines have equal line pitch applied to them. This line pitch shall not be added to any line which appears within a table cell unless the <adjustLineHeightInTable> element (§2.15.3.1) is present in the document's compatibility settings.
|
||||
*
|
||||
* This attribute is specified in twentieths of a point, and defines the pitch for each line of text on this page such that the desired number of single spaced lines of text fits on the current page.
|
||||
*
|
||||
* ```xml
|
||||
* <w:docGrid w:linePitch="684" …/>
|
||||
* ```
|
||||
*
|
||||
* The `linePitch` attribute specifies that 34.2 points is to the amount of pitch allowed for each line on this page in order to maintain the specific document grid. ]
|
||||
*
|
||||
* Individual paragraphs can override the line pitch information specified for the document grid by either:
|
||||
*
|
||||
* Specifying an exact line spacing value using the `lineRule` attribute of value exact on the <spacing> element (§2.3.1.33).
|
||||
*
|
||||
* Specifying that the paragraph text shall not snap to the document grid via the <snapToGrid> element (§2.3.1.32).
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_DecimalNumber simple type (§2.18.16).
|
||||
*/
|
||||
readonly linePitch: number;
|
||||
/**
|
||||
* Specifies the number of characters to be allowed on the document grid for each line in this section.
|
||||
*
|
||||
* This attribute's value shall be specified by multiplying the difference between the desired character pitch and the character pitch for that character in the font size of the Normal font by 4096.
|
||||
*
|
||||
* This value shall then be used to add the character pitch for the specified point size to each character in the section [: This results in text in the Normal style having a specific number of characters per line. ]
|
||||
*
|
||||
* ```xml
|
||||
* <w:docGrid w:charSize="40960" …/>
|
||||
* ```
|
||||
* The `charSpace` attribute specifies a value of 40960, which means that the delta between the character pitch of each character in the grid and the Normal font is 10 points, resulting in a character pitch of 11+10 = 21 points for all characters in this section. ]
|
||||
*
|
||||
* Individual runs of text can override the line pitch information specified for the document grid by specifying that the run text shall not snap to the document grid via the <snapToGrid> element (§2.3.2.32).
|
||||
*
|
||||
* The possible values for this attribute are defined by the `ST_DecimalNumber` simple type (§2.18.16).
|
||||
*/
|
||||
readonly charSpace?: number;
|
||||
}
|
||||
};
|
||||
|
||||
export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesProperties> {
|
||||
protected readonly xmlKeys = {
|
||||
type: "w:type",
|
||||
linePitch: "w:linePitch",
|
||||
charSpace: "w:charSpace",
|
||||
};
|
||||
}
|
||||
|
||||
export class DocumentGrid extends XmlComponent {
|
||||
public constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) {
|
||||
super("w:docGrid");
|
||||
|
||||
this.root.push(
|
||||
new DocGridAttributes({
|
||||
type: type,
|
||||
linePitch: decimalNumber(linePitch),
|
||||
charSpace: charSpace ? decimalNumber(charSpace) : undefined,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This element specifies the settings for the document grid, which enables precise layout of full-width East Asian language characters within a document by specifying the desired number of characters per line and lines per page for all East Asian text content in this section.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_docGrid_topic_ID0EHU5S.html
|
||||
*
|
||||
* ```xml
|
||||
* <xsd:complexType name="CT_DocGrid">
|
||||
* <xsd:attribute name="type" type="ST_DocGrid"/>
|
||||
* <xsd:attribute name="linePitch" type="ST_DecimalNumber"/>
|
||||
* <xsd:attribute name="charSpace" type="ST_DecimalNumber"/>
|
||||
* </xsd:complexType>
|
||||
* ```
|
||||
* @returns
|
||||
*/
|
||||
export const createDocumentGrid = ({ type, linePitch, charSpace }: IDocGridAttributesProperties): XmlComponent =>
|
||||
new BuilderElement<IDocGridAttributesProperties>({
|
||||
name: "w:docGrid",
|
||||
attributes: {
|
||||
type: { key: "w:type", value: type },
|
||||
linePitch: { key: "w:linePitch", value: decimalNumber(linePitch) },
|
||||
charSpace: { key: "w:charSpace", value: charSpace ? decimalNumber(charSpace) : undefined },
|
||||
},
|
||||
});
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./header-footer-reference";
|
||||
|
||||
describe("HeaderFooterReference", () => {
|
||||
|
@ -1,19 +1,30 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
|
||||
// <xsd:simpleType name="ST_HdrFtr">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:enumeration value="even"/>
|
||||
// <xsd:enumeration value="default"/>
|
||||
// <xsd:enumeration value="first"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum HeaderFooterReferenceType {
|
||||
DEFAULT = "default",
|
||||
FIRST = "first",
|
||||
EVEN = "even",
|
||||
}
|
||||
/**
|
||||
* This simple type specifies the possible types of headers and footers which may be specified for a given header or footer reference in a document. This value determines the page(s) on which the current header or footer shall be displayed.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_ST_HdrFtr_topic_ID0E2UW2.html
|
||||
*
|
||||
* ## XSD Schema
|
||||
* ```xml
|
||||
* <xsd:simpleType name="ST_HdrFtr">
|
||||
* <xsd:restriction base="xsd:string">
|
||||
* <xsd:enumeration value="even"/>
|
||||
* <xsd:enumeration value="default"/>
|
||||
* <xsd:enumeration value="first"/>
|
||||
* </xsd:restriction>
|
||||
* </xsd:simpleType>
|
||||
* ```
|
||||
*/
|
||||
export const HeaderFooterReferenceType = {
|
||||
/** Specifies that this header or footer shall appear on every page in this section which is not overridden with a specific `even` or `first` page header/footer. In a section with all three types specified, this type shall be used on all odd numbered pages (counting from the `first` page in the section, not the section numbering). */
|
||||
DEFAULT: "default",
|
||||
/** Specifies that this header or footer shall appear on the first page in this section. The appearance of this header or footer is contingent on the setting of the `titlePg` element (§2.10.6). */
|
||||
FIRST: "first",
|
||||
/** Specifies that this header or footer shall appear on all even numbered pages in this section (counting from the first page in the section, not the section numbering). The appearance of this header or footer is contingent on the setting of the `evenAndOddHeaders` element (§2.10.1). */
|
||||
EVEN: "even",
|
||||
} as const;
|
||||
|
||||
// </xsd:complexType>
|
||||
// <xsd:group name="EG_HdrFtrReferences">
|
||||
// <xsd:choice>
|
||||
// <xsd:element name="headerReference" type="CT_HdrFtrRef" minOccurs="0"/>
|
||||
@ -32,13 +43,13 @@ export enum HeaderFooterReferenceType {
|
||||
// <xsd:attribute ref="r:id" use="required"/>
|
||||
// </xsd:complexType>
|
||||
|
||||
export interface IHeaderFooterOptions {
|
||||
readonly type?: HeaderFooterReferenceType;
|
||||
export type IHeaderFooterOptions = {
|
||||
readonly type?: (typeof HeaderFooterReferenceType)[keyof typeof HeaderFooterReferenceType];
|
||||
readonly id?: number;
|
||||
}
|
||||
};
|
||||
|
||||
class FooterReferenceAttributes extends XmlAttributeComponent<{
|
||||
readonly type: HeaderFooterReferenceType;
|
||||
readonly type: (typeof HeaderFooterReferenceType)[keyof typeof HeaderFooterReferenceType];
|
||||
readonly id: string;
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
@ -47,12 +58,13 @@ class FooterReferenceAttributes extends XmlAttributeComponent<{
|
||||
};
|
||||
}
|
||||
|
||||
export enum HeaderFooterType {
|
||||
HEADER = "w:headerReference",
|
||||
FOOTER = "w:footerReference",
|
||||
}
|
||||
export const HeaderFooterType = {
|
||||
HEADER: "w:headerReference",
|
||||
FOOTER: "w:footerReference",
|
||||
} as const;
|
||||
|
||||
export class HeaderFooterReference extends XmlComponent {
|
||||
public constructor(type: HeaderFooterType, options: IHeaderFooterOptions) {
|
||||
public constructor(type: (typeof HeaderFooterType)[keyof typeof HeaderFooterType], options: IHeaderFooterOptions) {
|
||||
super(type);
|
||||
|
||||
this.root.push(
|
||||
|
@ -0,0 +1,34 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { createLineNumberType } from "./line-number";
|
||||
|
||||
describe("createLineNumberType", () => {
|
||||
it("should work", () => {
|
||||
const textDirection = createLineNumberType({ countBy: 0, start: 0, restart: "newPage", distance: 10 });
|
||||
|
||||
const tree = new Formatter().format(textDirection);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:lnNumType": { _attr: { "w:countBy": 0, "w:start": 0, "w:restart": "newPage", "w:distance": 10 } },
|
||||
});
|
||||
});
|
||||
|
||||
it("should work with string measures for distance", () => {
|
||||
const textDirection = createLineNumberType({ countBy: 0, start: 0, restart: "newPage", distance: "10mm" });
|
||||
|
||||
const tree = new Formatter().format(textDirection);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:lnNumType": { _attr: { "w:countBy": 0, "w:start": 0, "w:restart": "newPage", "w:distance": "10mm" } },
|
||||
});
|
||||
});
|
||||
|
||||
it("should work with blank entries", () => {
|
||||
const textDirection = createLineNumberType({});
|
||||
|
||||
const tree = new Formatter().format(textDirection);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:lnNumType": { _attr: {} },
|
||||
});
|
||||
});
|
||||
});
|
@ -1,49 +1,138 @@
|
||||
// http://officeopenxml.com/WPsectionLineNumbering.php
|
||||
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { decimalNumber, PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||
import { BuilderElement, XmlComponent } from "@file/xml-components";
|
||||
import { PositiveUniversalMeasure, decimalNumber, twipsMeasureValue } from "@util/values";
|
||||
|
||||
// <xsd:simpleType name="ST_LineNumberRestart">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:enumeration value="newPage"/>
|
||||
// <xsd:enumeration value="newSection"/>
|
||||
// <xsd:enumeration value="continuous"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum LineNumberRestartFormat {
|
||||
NEW_PAGE = "newPage",
|
||||
NEW_SECTION = "newSection",
|
||||
CONTINUOUS = "continuous",
|
||||
}
|
||||
/**
|
||||
* This simple type specifies when the line numbering in the parent section shall be reset to its restart value. The line numbering increments for each line (even if the line number itself is not displayed) until it reaches the restart point specified by this element.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_ST_LineNumberRestart_topic_ID0EUS42.html
|
||||
*
|
||||
* ## XSD Schema
|
||||
*
|
||||
* ```xml
|
||||
* <xsd:simpleType name="ST_LineNumberRestart">
|
||||
* <xsd:restriction base="xsd:string">
|
||||
* <xsd:enumeration value="newPage"/>
|
||||
* <xsd:enumeration value="newSection"/>
|
||||
* <xsd:enumeration value="continuous"/>
|
||||
* </xsd:restriction>
|
||||
* </xsd:simpleType>
|
||||
* ```
|
||||
*/
|
||||
export const LineNumberRestartFormat = {
|
||||
/**
|
||||
* ## Restart Line Numbering on Each Page
|
||||
*
|
||||
* Specifies that line numbering for the parent section shall restart to the starting value whenever a new page is displayed.
|
||||
*/
|
||||
NEW_PAGE: "newPage",
|
||||
/**
|
||||
* ## Restart Line Numbering for Each Section
|
||||
*
|
||||
* Specifies that line numbering for the parent section shall restart to the starting value whenever the parent begins.
|
||||
*/
|
||||
NEW_SECTION: "newSection",
|
||||
/**
|
||||
* ## Continue Line Numbering From Previous Section
|
||||
*
|
||||
* Specifies that line numbering for the parent section shall continue from the line numbering from the end of the previous section, if any.
|
||||
*/
|
||||
CONTINUOUS: "continuous",
|
||||
} as const;
|
||||
|
||||
// <xsd:complexType name="CT_LineNumber">
|
||||
// <xsd:attribute name="countBy" type="ST_DecimalNumber" use="optional"/>
|
||||
// <xsd:attribute name="start" type="ST_DecimalNumber" use="optional" default="1"/>
|
||||
// <xsd:attribute name="distance" type="s:ST_TwipsMeasure" use="optional"/>
|
||||
// <xsd:attribute name="restart" type="ST_LineNumberRestart" use="optional" default="newPage"/>
|
||||
// </xsd:complexType>
|
||||
|
||||
export interface ILineNumberAttributes {
|
||||
export type ILineNumberAttributes = {
|
||||
/**
|
||||
* Specifies the line number increments to be displayed in the current document.
|
||||
*
|
||||
* Although each line has an associated line number, only lines which are an even multiple of this value shall be displayed.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:lnNumType … w:countBy="5"/>
|
||||
* ```
|
||||
*
|
||||
* This setting ensures that only lines whose number is a multiple of (e.g. 5, 10, and 15) will have a line number displayed. ]
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_DecimalNumber simple type (§2.18.16).
|
||||
*/
|
||||
readonly countBy?: number;
|
||||
/**
|
||||
* ## Line Numbering Starting Value
|
||||
*
|
||||
* Specifies the starting value used for the first line whenever the line numbering is restarted by use of the `restart` attribute.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:lnNumType w:start="3" w:countBy="5"/>
|
||||
* ```
|
||||
*
|
||||
* The `start` attribute specifies that line numbers shall be counted starting from the number 3.
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_DecimalNumber simple type (§2.18.16).
|
||||
*/
|
||||
readonly start?: number;
|
||||
readonly restart?: LineNumberRestartFormat;
|
||||
/**
|
||||
* ## Line Numbering Restart Setting
|
||||
*
|
||||
* Specifies when the line numbering in this section shall be reset to the line number specified by the `start` attribute's value.
|
||||
*
|
||||
* The line numbering increments for each line (even if it is not displayed) until it reaches the restart point specified by this element.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:sectPr>
|
||||
* ...
|
||||
* <w:lnNumType w:restart="newPage" ... />
|
||||
* </w:sectPr>
|
||||
* ```
|
||||
*
|
||||
* The value of `newPage` specifies that the line numbers shall restart at the top of each page to the value specified by the `start` attribute. In this case, `newPage` is the default, so this value could have been omitted entirely.
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_LineNumberRestart simple type (§2.18.54).
|
||||
*/
|
||||
readonly restart?: (typeof LineNumberRestartFormat)[keyof typeof LineNumberRestartFormat];
|
||||
/**
|
||||
* Specifies the distance between the text margin and the edge of any line numbers appearing in that section.
|
||||
*
|
||||
* ```.xml
|
||||
* <w:lnNumType ... w:distance="720"/>
|
||||
* ```
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_TwipsMeasure simple type (§2.18.105).
|
||||
*/
|
||||
readonly distance?: number | PositiveUniversalMeasure;
|
||||
}
|
||||
};
|
||||
|
||||
export class LineNumberType extends XmlComponent {
|
||||
public constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
|
||||
super("w:lnNumType");
|
||||
this.root.push(
|
||||
new NextAttributeComponent<{
|
||||
readonly countBy?: number;
|
||||
readonly start?: number;
|
||||
readonly restart?: LineNumberRestartFormat;
|
||||
readonly distance?: number | PositiveUniversalMeasure;
|
||||
}>({
|
||||
countBy: { key: "w:countBy", value: countBy === undefined ? undefined : decimalNumber(countBy) },
|
||||
start: { key: "w:start", value: start === undefined ? undefined : decimalNumber(start) },
|
||||
restart: { key: "w:restart", value: restart },
|
||||
distance: { key: "w:distance", value: distance === undefined ? undefined : twipsMeasureValue(distance) },
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This element specifies the settings for line numbering to be displayed before each column of text in this section in the document.
|
||||
*
|
||||
* References:
|
||||
* - https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_lnNumType_topic_ID0EVRAT.html
|
||||
* - http://officeopenxml.com/WPsectionLineNumbering.php
|
||||
*
|
||||
* ## XSD Schema
|
||||
*
|
||||
* ```xml
|
||||
* <xsd:complexType name="CT_LineNumber">
|
||||
* <xsd:attribute name="countBy" type="ST_DecimalNumber" use="optional"/>
|
||||
* <xsd:attribute name="start" type="ST_DecimalNumber" use="optional" default="1"/>
|
||||
* <xsd:attribute name="distance" type="s:ST_TwipsMeasure" use="optional"/>
|
||||
* <xsd:attribute name="restart" type="ST_LineNumberRestart" use="optional" default="newPage"/>
|
||||
* </xsd:complexType>
|
||||
* ```
|
||||
*/
|
||||
export const createLineNumberType = ({ countBy, start, restart, distance }: ILineNumberAttributes): XmlComponent =>
|
||||
new BuilderElement<ILineNumberAttributes>({
|
||||
name: "w:lnNumType",
|
||||
attributes: {
|
||||
countBy: { key: "w:countBy", value: countBy === undefined ? undefined : decimalNumber(countBy) },
|
||||
start: { key: "w:start", value: start === undefined ? undefined : decimalNumber(start) },
|
||||
restart: { key: "w:restart", value: restart },
|
||||
distance: {
|
||||
key: "w:distance",
|
||||
value: distance === undefined ? undefined : twipsMeasureValue(distance),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { Formatter } from "@export/formatter";
|
||||
import { BorderStyle } from "@file/border";
|
||||
|
||||
import { PageBorderDisplay, PageBorders, PageBorderZOrder } from "./page-borders";
|
||||
import { PageBorderDisplay, PageBorderZOrder, PageBorders } from "./page-borders";
|
||||
|
||||
describe("PageBorders", () => {
|
||||
describe("#constructor()", () => {
|
||||
|
@ -9,11 +9,12 @@ import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent } from "@file/xml-comp
|
||||
// <xsd:enumeration value="notFirstPage"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum PageBorderDisplay {
|
||||
ALL_PAGES = "allPages",
|
||||
FIRST_PAGE = "firstPage",
|
||||
NOT_FIRST_PAGE = "notFirstPage",
|
||||
}
|
||||
|
||||
export const PageBorderDisplay = {
|
||||
ALL_PAGES: "allPages",
|
||||
FIRST_PAGE: "firstPage",
|
||||
NOT_FIRST_PAGE: "notFirstPage",
|
||||
} as const;
|
||||
|
||||
// <xsd:simpleType name="ST_PageBorderOffset">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
@ -21,10 +22,10 @@ export enum PageBorderDisplay {
|
||||
// <xsd:enumeration value="text"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum PageBorderOffsetFrom {
|
||||
PAGE = "page",
|
||||
TEXT = "text",
|
||||
}
|
||||
export const PageBorderOffsetFrom = {
|
||||
PAGE: "page",
|
||||
TEXT: "text",
|
||||
} as const;
|
||||
|
||||
// <xsd:simpleType name="ST_PageBorderZOrder">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
@ -32,24 +33,24 @@ export enum PageBorderOffsetFrom {
|
||||
// <xsd:enumeration value="back"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum PageBorderZOrder {
|
||||
BACK = "back",
|
||||
FRONT = "front",
|
||||
}
|
||||
export const PageBorderZOrder = {
|
||||
BACK: "back",
|
||||
FRONT: "front",
|
||||
} as const;
|
||||
|
||||
export interface IPageBorderAttributes {
|
||||
readonly display?: PageBorderDisplay;
|
||||
readonly offsetFrom?: PageBorderOffsetFrom;
|
||||
readonly zOrder?: PageBorderZOrder;
|
||||
}
|
||||
export type IPageBorderAttributes = {
|
||||
readonly display?: (typeof PageBorderDisplay)[keyof typeof PageBorderDisplay];
|
||||
readonly offsetFrom?: (typeof PageBorderOffsetFrom)[keyof typeof PageBorderOffsetFrom];
|
||||
readonly zOrder?: (typeof PageBorderZOrder)[keyof typeof PageBorderZOrder];
|
||||
};
|
||||
|
||||
export interface IPageBordersOptions {
|
||||
export type IPageBordersOptions = {
|
||||
readonly pageBorders?: IPageBorderAttributes;
|
||||
readonly pageBorderTop?: IBorderOptions;
|
||||
readonly pageBorderRight?: IBorderOptions;
|
||||
readonly pageBorderBottom?: IBorderOptions;
|
||||
readonly pageBorderLeft?: IBorderOptions;
|
||||
}
|
||||
};
|
||||
|
||||
class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes> {
|
||||
protected readonly xmlKeys = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { PositiveUniversalMeasure, signedTwipsMeasureValue, twipsMeasureValue, UniversalMeasure } from "@util/values";
|
||||
import { PositiveUniversalMeasure, UniversalMeasure, signedTwipsMeasureValue, twipsMeasureValue } from "@util/values";
|
||||
|
||||
// <xsd:complexType name="CT_PageMar">
|
||||
// <xsd:attribute name="top" type="ST_SignedTwipsMeasure" use="required"/>
|
||||
|
@ -12,19 +12,20 @@ import { decimalNumber } from "@util/values";
|
||||
// <xsd:enumeration value="enDash"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum PageNumberSeparator {
|
||||
HYPHEN = "hyphen",
|
||||
PERIOD = "period",
|
||||
COLON = "colon",
|
||||
EM_DASH = "emDash",
|
||||
EN_DASH = "endash",
|
||||
}
|
||||
|
||||
export interface IPageNumberTypeAttributes {
|
||||
export const PageNumberSeparator = {
|
||||
HYPHEN: "hyphen",
|
||||
PERIOD: "period",
|
||||
COLON: "colon",
|
||||
EM_DASH: "emDash",
|
||||
EN_DASH: "endash",
|
||||
} as const;
|
||||
|
||||
export type IPageNumberTypeAttributes = {
|
||||
readonly start?: number;
|
||||
readonly formatType?: NumberFormat;
|
||||
readonly separator?: PageNumberSeparator;
|
||||
}
|
||||
readonly formatType?: (typeof NumberFormat)[keyof typeof NumberFormat];
|
||||
readonly separator?: (typeof PageNumberSeparator)[keyof typeof PageNumberSeparator];
|
||||
};
|
||||
|
||||
// <xsd:complexType name="CT_PageNumber">
|
||||
// <xsd:attribute name="fmt" type="ST_NumberFormat" use="optional" default="decimal"/>
|
||||
@ -40,6 +41,7 @@ export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberT
|
||||
separator: "w:chapSep",
|
||||
};
|
||||
}
|
||||
|
||||
export class PageNumberType extends XmlComponent {
|
||||
public constructor({ start, formatType, separator }: IPageNumberTypeAttributes) {
|
||||
super("w:pgNumType");
|
||||
|
@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { PageOrientation, PageSize } from "./page-size";
|
||||
import { PageOrientation, createPageSize } from "./page-size";
|
||||
|
||||
describe("PageSize", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("should create page size with portrait", () => {
|
||||
const properties = new PageSize(100, 200, PageOrientation.PORTRAIT);
|
||||
const properties = createPageSize({ width: 100, height: 200, orientation: PageOrientation.PORTRAIT });
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
|
||||
@ -15,7 +15,7 @@ describe("PageSize", () => {
|
||||
});
|
||||
|
||||
it("should create page size with horizontal and invert the lengths", () => {
|
||||
const properties = new PageSize(100, 200, PageOrientation.LANDSCAPE);
|
||||
const properties = createPageSize({ width: 100, height: 200, orientation: PageOrientation.LANDSCAPE });
|
||||
const tree = new Formatter().format(properties);
|
||||
|
||||
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
|
||||
|
@ -1,44 +1,132 @@
|
||||
import { NextAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { BuilderElement, XmlComponent } from "@file/xml-components";
|
||||
import { PositiveUniversalMeasure, twipsMeasureValue } from "@util/values";
|
||||
|
||||
// <xsd:simpleType name="ST_PageOrientation">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:enumeration value="portrait"/>
|
||||
// <xsd:enumeration value="landscape"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum PageOrientation {
|
||||
PORTRAIT = "portrait",
|
||||
LANDSCAPE = "landscape",
|
||||
}
|
||||
/**
|
||||
* This simple type specifies the orientation of all pages in the parent section. This information is used to determine the actual paper size to use when printing the file.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_ST_PageOrientation_topic_ID0EKBK3.html
|
||||
*
|
||||
* ## XSD Schema
|
||||
*
|
||||
* ```xml
|
||||
* <xsd:simpleType name="ST_PageOrientation">
|
||||
* <xsd:restriction base="xsd:string">
|
||||
* <xsd:enumeration value="portrait"/>
|
||||
* <xsd:enumeration value="landscape"/>
|
||||
* </xsd:restriction>
|
||||
* </xsd:simpleType>
|
||||
* ```
|
||||
*/
|
||||
export const PageOrientation = {
|
||||
/**
|
||||
* ## Portrait Mode
|
||||
*
|
||||
* Specifies that pages in this section shall be printed in portrait mode.
|
||||
*/
|
||||
PORTRAIT: "portrait",
|
||||
/**
|
||||
* ## Landscape Mode
|
||||
*
|
||||
* Specifies that pages in this section shall be printed in landscape mode, which prints the page contents with a 90 degree rotation with respect to the normal page orientation.
|
||||
*/
|
||||
LANDSCAPE: "landscape",
|
||||
} as const;
|
||||
|
||||
// <xsd:complexType name="CT_PageSz">
|
||||
// <xsd:attribute name="w" type="s:ST_TwipsMeasure"/>
|
||||
// <xsd:attribute name="h" type="s:ST_TwipsMeasure"/>
|
||||
// <xsd:attribute name="orient" type="ST_PageOrientation" use="optional"/>
|
||||
// <xsd:attribute name="code" type="ST_DecimalNumber" use="optional"/>
|
||||
// </xsd:complexType>
|
||||
export type IPageSizeAttributes = {
|
||||
readonly width?: number | PositiveUniversalMeasure;
|
||||
readonly height?: number | PositiveUniversalMeasure;
|
||||
readonly orientation?: PageOrientation;
|
||||
/**
|
||||
* ## Page Width
|
||||
*
|
||||
* This attribute indicates the width (in twentieths of a point) for all pages in the current section.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:pgSz w:w="15840" w:h="12240" />
|
||||
* ```
|
||||
*
|
||||
* All pages in this section are displayed on a page that is 15840 twentieths of a point (11") wide.
|
||||
*
|
||||
* The possible values for this attribute are defined by the ST_TwipsMeasure simple type (§2.18.105).
|
||||
*/
|
||||
readonly width: number | PositiveUniversalMeasure;
|
||||
/**
|
||||
* ## Page Height
|
||||
*
|
||||
* Specifies the height (in twentieths of a point) for all pages in the current section.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:pgSz w:w="15840" w:h="12240" />
|
||||
* ```
|
||||
*
|
||||
* All pages in this section are displayed on a page that is `12240` twentieths of a point (`8.5"`) tall.
|
||||
*
|
||||
* The possible values for this attribute are defined by the `ST_TwipsMeasure` simple type (§2.18.105).
|
||||
*/
|
||||
readonly height: number | PositiveUniversalMeasure;
|
||||
/**
|
||||
* ## Page Orientation
|
||||
*
|
||||
* Specifies the orientation of all pages in this section.
|
||||
*
|
||||
* This information is used to determine the actual paper size to use on the printer.
|
||||
*
|
||||
* This implies that the actual paper size width and height are reversed for pages in this section. If this attribute is omitted, then portrait shall be implied.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* ```xml
|
||||
* <w:pgSz w:w="15840" w:h="12240" w:orient="landscape" />
|
||||
* ```
|
||||
*
|
||||
* Although the page width is 11", and page height is 8.5", according to the `w` and `h` attributes, because the `orient` attribute is set to landscape, pages in this section are printed on 8.5x11" paper in landscape mode.
|
||||
*
|
||||
* The possible values for this attribute are defined by the `ST_PageOrientation` simple type (§2.18.71).
|
||||
*/
|
||||
readonly orientation?: (typeof PageOrientation)[keyof typeof PageOrientation];
|
||||
/**
|
||||
* ## Printer Paper Code
|
||||
*
|
||||
* Specifies a printer-specific paper code for the paper type, which shall be used by the printer for pages in this section.
|
||||
*
|
||||
* This code is stored to ensure the proper paper type is chosen if the specified paper size matches the sizes of multiple paper types supported by the current printer.
|
||||
*
|
||||
* It will be sent to the printer and used by the printer to determine the appropriate paper type to use when printing.
|
||||
*
|
||||
* This value is not interpreted or modified other than storing it as specified by the printer.
|
||||
*
|
||||
* The possible values for this attribute are defined by the `ST_DecimalNumber` simple type (§2.18.16).
|
||||
*/
|
||||
readonly code?: number;
|
||||
};
|
||||
|
||||
export class PageSize extends XmlComponent {
|
||||
public constructor(width: number | PositiveUniversalMeasure, height: number | PositiveUniversalMeasure, orientation: PageOrientation) {
|
||||
super("w:pgSz");
|
||||
|
||||
const flip = orientation === PageOrientation.LANDSCAPE;
|
||||
|
||||
const widthTwips = twipsMeasureValue(width);
|
||||
const heightTwips = twipsMeasureValue(height);
|
||||
|
||||
this.root.push(
|
||||
new NextAttributeComponent<IPageSizeAttributes>({
|
||||
width: { key: "w:w", value: flip ? heightTwips : widthTwips },
|
||||
height: { key: "w:h", value: flip ? widthTwips : heightTwips },
|
||||
orientation: { key: "w:orient", value: orientation },
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This element specifies the properties (size and orientation) for all pages in the current section.
|
||||
*
|
||||
* Reference: https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_pgSz_topic_ID0ENEDT.html?hl=pgsz%2Cpage%2Csize
|
||||
*
|
||||
* ## XSD Schema
|
||||
*
|
||||
* ```xml
|
||||
* <xsd:complexType name="CT_PageSz">
|
||||
* <xsd:attribute name="w" type="s:ST_TwipsMeasure"/>
|
||||
* <xsd:attribute name="h" type="s:ST_TwipsMeasure"/>
|
||||
* <xsd:attribute name="orient" type="ST_PageOrientation" use="optional"/>
|
||||
* <xsd:attribute name="code" type="ST_DecimalNumber" use="optional"/>
|
||||
* </xsd:complexType>
|
||||
* ```
|
||||
*/
|
||||
export const createPageSize = ({ width, height, orientation, code }: IPageSizeAttributes): XmlComponent => {
|
||||
const widthTwips = twipsMeasureValue(width);
|
||||
const heightTwips = twipsMeasureValue(height);
|
||||
return new BuilderElement<IPageSizeAttributes>({
|
||||
name: "w:pgSz",
|
||||
attributes: {
|
||||
width: { key: "w:w", value: orientation === PageOrientation.LANDSCAPE ? heightTwips : widthTwips },
|
||||
height: { key: "w:h", value: orientation === PageOrientation.LANDSCAPE ? widthTwips : heightTwips },
|
||||
orientation: { key: "w:orient", value: orientation },
|
||||
code: { key: "w:code", value: code },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { PageTextDirection, PageTextDirectionType } from "./page-text-direction";
|
||||
|
||||
describe("PageTextDirection", () => {
|
||||
|
@ -1,16 +1,18 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
|
||||
export enum PageTextDirectionType {
|
||||
LEFT_TO_RIGHT_TOP_TO_BOTTOM = "lrTb",
|
||||
TOP_TO_BOTTOM_RIGHT_TO_LEFT = "tbRl",
|
||||
}
|
||||
export const PageTextDirectionType = {
|
||||
LEFT_TO_RIGHT_TOP_TO_BOTTOM: "lrTb",
|
||||
TOP_TO_BOTTOM_RIGHT_TO_LEFT: "tbRl",
|
||||
} as const;
|
||||
|
||||
class PageTextDirectionAttributes extends XmlAttributeComponent<{ readonly val: PageTextDirectionType }> {
|
||||
class PageTextDirectionAttributes extends XmlAttributeComponent<{
|
||||
readonly val: (typeof PageTextDirectionType)[keyof typeof PageTextDirectionType];
|
||||
}> {
|
||||
protected readonly xmlKeys = { val: "w:val" };
|
||||
}
|
||||
|
||||
export class PageTextDirection extends XmlComponent {
|
||||
public constructor(value: PageTextDirectionType) {
|
||||
public constructor(value: (typeof PageTextDirectionType)[keyof typeof PageTextDirectionType]) {
|
||||
super("w:textDirection");
|
||||
|
||||
this.root.push(
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { Formatter } from "@export/formatter";
|
||||
|
||||
import { SectionType, Type } from "./section-type";
|
||||
|
||||
describe("Type", () => {
|
||||
|
@ -10,19 +10,20 @@ import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
// <xsd:enumeration value="oddPage"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export enum SectionType {
|
||||
NEXT_PAGE = "nextPage",
|
||||
NEXT_COLUMN = "nextColumn",
|
||||
CONTINUOUS = "continuous",
|
||||
EVEN_PAGE = "evenPage",
|
||||
ODD_PAGE = "oddPage",
|
||||
}
|
||||
|
||||
export const SectionType = {
|
||||
NEXT_PAGE: "nextPage",
|
||||
NEXT_COLUMN: "nextColumn",
|
||||
CONTINUOUS: "continuous",
|
||||
EVEN_PAGE: "evenPage",
|
||||
ODD_PAGE: "oddPage",
|
||||
} as const;
|
||||
|
||||
// <xsd:complexType name="CT_SectType">
|
||||
// <xsd:attribute name="val" type="ST_SectionMark"/>
|
||||
// </xsd:complexType>
|
||||
export class SectionTypeAttributes extends XmlAttributeComponent<{
|
||||
readonly val: SectionType;
|
||||
readonly val: (typeof SectionType)[keyof typeof SectionType];
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
val: "w:val",
|
||||
@ -30,7 +31,7 @@ export class SectionTypeAttributes extends XmlAttributeComponent<{
|
||||
}
|
||||
|
||||
export class Type extends XmlComponent {
|
||||
public constructor(value: SectionType) {
|
||||
public constructor(value: (typeof SectionType)[keyof typeof SectionType]) {
|
||||
super("w:type");
|
||||
this.root.push(new SectionTypeAttributes({ val: value }));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import { LineNumberRestartFormat } from "./properties/line-number";
|
||||
import { PageBorderOffsetFrom } from "./properties/page-borders";
|
||||
import { PageTextDirectionType } from "./properties/page-text-direction";
|
||||
import { SectionType } from "./properties/section-type";
|
||||
import { sectionMarginDefaults, sectionPageSizeDefaults, SectionProperties } from "./section-properties";
|
||||
import { SectionProperties, sectionMarginDefaults, sectionPageSizeDefaults } from "./section-properties";
|
||||
|
||||
const DEFAULT_MARGINS = {
|
||||
"w:bottom": sectionMarginDefaults.BOTTOM,
|
||||
|
@ -1,46 +1,44 @@
|
||||
// http://officeopenxml.com/WPsection.php
|
||||
// tslint:disable: no-unnecessary-initializer
|
||||
|
||||
import { FooterWrapper } from "@file/footer-wrapper";
|
||||
import { HeaderWrapper } from "@file/header-wrapper";
|
||||
import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align";
|
||||
import { OnOffElement, XmlComponent } from "@file/xml-components";
|
||||
import { PositiveUniversalMeasure, UniversalMeasure } from "@util/values";
|
||||
|
||||
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./properties/header-footer-reference";
|
||||
import { Columns, IColumnsAttributes } from "./properties/columns";
|
||||
import { DocumentGrid, IDocGridAttributesProperties } from "./properties/doc-grid";
|
||||
import { ILineNumberAttributes, LineNumberType } from "./properties/line-number";
|
||||
import { IDocGridAttributesProperties, createDocumentGrid } from "./properties/doc-grid";
|
||||
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./properties/header-footer-reference";
|
||||
import { ILineNumberAttributes, createLineNumberType } from "./properties/line-number";
|
||||
import { IPageBordersOptions, PageBorders } from "./properties/page-borders";
|
||||
import { IPageMarginAttributes, PageMargin } from "./properties/page-margin";
|
||||
import { IPageNumberTypeAttributes, PageNumberType } from "./properties/page-number";
|
||||
import { IPageSizeAttributes, PageOrientation, PageSize } from "./properties/page-size";
|
||||
import { IPageSizeAttributes, PageOrientation, createPageSize } from "./properties/page-size";
|
||||
import { PageTextDirection, PageTextDirectionType } from "./properties/page-text-direction";
|
||||
import { SectionType, Type } from "./properties/section-type";
|
||||
|
||||
export interface IHeaderFooterGroup<T> {
|
||||
export type IHeaderFooterGroup<T> = {
|
||||
readonly default?: T;
|
||||
readonly first?: T;
|
||||
readonly even?: T;
|
||||
}
|
||||
};
|
||||
|
||||
export interface ISectionPropertiesOptions {
|
||||
export type ISectionPropertiesOptions = {
|
||||
readonly page?: {
|
||||
readonly size?: IPageSizeAttributes;
|
||||
readonly size?: Partial<IPageSizeAttributes>;
|
||||
readonly margin?: IPageMarginAttributes;
|
||||
readonly pageNumbers?: IPageNumberTypeAttributes;
|
||||
readonly borders?: IPageBordersOptions;
|
||||
readonly textDirection?: PageTextDirectionType;
|
||||
readonly textDirection?: (typeof PageTextDirectionType)[keyof typeof PageTextDirectionType];
|
||||
};
|
||||
readonly grid?: IDocGridAttributesProperties;
|
||||
readonly grid?: Partial<IDocGridAttributesProperties>;
|
||||
readonly headerWrapperGroup?: IHeaderFooterGroup<HeaderWrapper>;
|
||||
readonly footerWrapperGroup?: IHeaderFooterGroup<FooterWrapper>;
|
||||
readonly lineNumbers?: ILineNumberAttributes;
|
||||
readonly titlePage?: boolean;
|
||||
readonly verticalAlign?: VerticalAlign;
|
||||
readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign];
|
||||
readonly column?: IColumnsAttributes;
|
||||
readonly type?: SectionType;
|
||||
}
|
||||
readonly type?: (typeof SectionType)[keyof typeof SectionType];
|
||||
};
|
||||
|
||||
// <xsd:complexType name="CT_SectPr">
|
||||
// <xsd:sequence>
|
||||
@ -76,10 +74,10 @@ export interface ISectionPropertiesOptions {
|
||||
// </xsd:group>
|
||||
|
||||
export const sectionMarginDefaults = {
|
||||
TOP: "1in" as UniversalMeasure,
|
||||
RIGHT: "1in" as PositiveUniversalMeasure,
|
||||
BOTTOM: "1in" as UniversalMeasure,
|
||||
LEFT: "1in" as PositiveUniversalMeasure,
|
||||
TOP: 1440,
|
||||
RIGHT: 1440,
|
||||
BOTTOM: 1440,
|
||||
LEFT: 1440,
|
||||
HEADER: 708,
|
||||
FOOTER: 708,
|
||||
GUTTER: 0,
|
||||
@ -130,7 +128,7 @@ export class SectionProperties extends XmlComponent {
|
||||
this.root.push(new Type(type));
|
||||
}
|
||||
|
||||
this.root.push(new PageSize(width, height, orientation));
|
||||
this.root.push(createPageSize({ width, height, orientation }));
|
||||
this.root.push(new PageMargin(top, right, bottom, left, header, footer, gutter));
|
||||
|
||||
if (borders) {
|
||||
@ -138,7 +136,7 @@ export class SectionProperties extends XmlComponent {
|
||||
}
|
||||
|
||||
if (lineNumbers) {
|
||||
this.root.push(new LineNumberType(lineNumbers));
|
||||
this.root.push(createLineNumberType(lineNumbers));
|
||||
}
|
||||
|
||||
this.root.push(new PageNumberType(pageNumbers));
|
||||
@ -159,11 +157,11 @@ export class SectionProperties extends XmlComponent {
|
||||
this.root.push(new PageTextDirection(textDirection));
|
||||
}
|
||||
|
||||
this.root.push(new DocumentGrid(linePitch, charSpace, gridType));
|
||||
this.root.push(createDocumentGrid({ linePitch, charSpace, type: gridType }));
|
||||
}
|
||||
|
||||
private addHeaderFooterGroup(
|
||||
type: HeaderFooterType,
|
||||
type: (typeof HeaderFooterType)[keyof typeof HeaderFooterType],
|
||||
group: IHeaderFooterGroup<HeaderWrapper> | IHeaderFooterGroup<FooterWrapper>,
|
||||
): void {
|
||||
if (group.default) {
|
||||
|
@ -1,89 +1,60 @@
|
||||
import { XmlAttributeComponent } from "@file/xml-components";
|
||||
import { AttributeMap, XmlAttributeComponent } from "@file/xml-components";
|
||||
|
||||
/* cSpell:disable */
|
||||
export interface IDocumentAttributesProperties {
|
||||
readonly wpc?: string;
|
||||
readonly mc?: string;
|
||||
readonly o?: string;
|
||||
readonly r?: string;
|
||||
readonly m?: string;
|
||||
readonly v?: string;
|
||||
readonly wp14?: string;
|
||||
readonly wp?: string;
|
||||
readonly w10?: string;
|
||||
readonly w?: string;
|
||||
readonly w14?: string;
|
||||
readonly w15?: string;
|
||||
readonly wpg?: string;
|
||||
readonly wpi?: string;
|
||||
readonly wne?: string;
|
||||
readonly wps?: string;
|
||||
readonly Ignorable?: string;
|
||||
readonly cp?: string;
|
||||
readonly dc?: string;
|
||||
readonly dcterms?: string;
|
||||
readonly dcmitype?: string;
|
||||
readonly xsi?: string;
|
||||
readonly type?: string;
|
||||
readonly cx?: string;
|
||||
readonly cx1?: string;
|
||||
readonly cx2?: string;
|
||||
readonly cx3?: string;
|
||||
readonly cx4?: string;
|
||||
readonly cx5?: string;
|
||||
readonly cx6?: string;
|
||||
readonly cx7?: string;
|
||||
readonly cx8?: string;
|
||||
readonly aink?: string;
|
||||
readonly am3d?: string;
|
||||
readonly w16cex?: string;
|
||||
readonly w16cid?: string;
|
||||
readonly w16?: string;
|
||||
readonly w16sdtdh?: string;
|
||||
readonly w16se?: string;
|
||||
}
|
||||
export const DocumentAttributeNamespaces = {
|
||||
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
||||
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
|
||||
o: "urn:schemas-microsoft-com:office:office",
|
||||
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
||||
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
|
||||
v: "urn:schemas-microsoft-com:vml",
|
||||
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
|
||||
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
|
||||
w10: "urn:schemas-microsoft-com:office:word",
|
||||
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
||||
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
|
||||
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
|
||||
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
|
||||
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
|
||||
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
|
||||
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
||||
cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
|
||||
dc: "http://purl.org/dc/elements/1.1/",
|
||||
dcterms: "http://purl.org/dc/terms/",
|
||||
dcmitype: "http://purl.org/dc/dcmitype/",
|
||||
xsi: "http://www.w3.org/2001/XMLSchema-instance",
|
||||
cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
||||
cx1: "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
||||
cx2: "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
||||
cx3: "http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",
|
||||
cx4: "http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",
|
||||
cx5: "http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",
|
||||
cx6: "http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",
|
||||
cx7: "http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
|
||||
cx8: "http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
|
||||
aink: "http://schemas.microsoft.com/office/drawing/2016/ink",
|
||||
am3d: "http://schemas.microsoft.com/office/drawing/2017/model3d",
|
||||
w16cex: "http://schemas.microsoft.com/office/word/2018/wordml/cex",
|
||||
w16cid: "http://schemas.microsoft.com/office/word/2016/wordml/cid",
|
||||
w16: "http://schemas.microsoft.com/office/word/2018/wordml",
|
||||
w16sdtdh: "http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash",
|
||||
w16se: "http://schemas.microsoft.com/office/word/2015/wordml/symex",
|
||||
};
|
||||
/* cSpell:enable */
|
||||
|
||||
export type DocumentAttributeNamespace = keyof typeof DocumentAttributeNamespaces;
|
||||
|
||||
export type IDocumentAttributesProperties = Partial<Record<DocumentAttributeNamespace, string>> & {
|
||||
readonly Ignorable?: string;
|
||||
};
|
||||
|
||||
export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
|
||||
protected readonly xmlKeys = {
|
||||
wpc: "xmlns:wpc",
|
||||
mc: "xmlns:mc",
|
||||
o: "xmlns:o",
|
||||
r: "xmlns:r",
|
||||
m: "xmlns:m",
|
||||
v: "xmlns:v",
|
||||
wp14: "xmlns:wp14",
|
||||
wp: "xmlns:wp",
|
||||
w10: "xmlns:w10",
|
||||
w: "xmlns:w",
|
||||
w14: "xmlns:w14",
|
||||
w15: "xmlns:w15",
|
||||
wpg: "xmlns:wpg",
|
||||
wpi: "xmlns:wpi",
|
||||
wne: "xmlns:wne",
|
||||
wps: "xmlns:wps",
|
||||
Ignorable: "mc:Ignorable",
|
||||
cp: "xmlns:cp",
|
||||
dc: "xmlns:dc",
|
||||
dcterms: "xmlns:dcterms",
|
||||
dcmitype: "xmlns:dcmitype",
|
||||
xsi: "xmlns:xsi",
|
||||
type: "xsi:type",
|
||||
cx: "xmlns:cx",
|
||||
cx1: "xmlns:cx1",
|
||||
cx2: "xmlns:cx2",
|
||||
cx3: "xmlns:cx3",
|
||||
cx4: "xmlns:cx4",
|
||||
cx5: "xmlns:cx5",
|
||||
cx6: "xmlns:cx6",
|
||||
cx7: "xmlns:cx7",
|
||||
cx8: "xmlns:cx8",
|
||||
aink: "xmlns:aink",
|
||||
am3d: "xmlns:am3d",
|
||||
w16cex: "xmlns:w16cex",
|
||||
w16cid: "xmlns:w16cid",
|
||||
w16: "xmlns:w16",
|
||||
w16sdtdh: "xmlns:w16sdtdh",
|
||||
w16se: "xmlns:w16se",
|
||||
};
|
||||
...Object.fromEntries(Object.keys(DocumentAttributeNamespaces).map((key) => [key, `xmlns:${key}`])),
|
||||
} as AttributeMap<IDocumentAttributesProperties>;
|
||||
|
||||
public constructor(ns: readonly DocumentAttributeNamespace[], Ignorable?: string) {
|
||||
super({ Ignorable, ...Object.fromEntries(ns.map((n) => [n, DocumentAttributeNamespaces[n]])) });
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user