docx 7.4.0 → 7.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docx",
3
- "version": "7.4.0",
3
+ "version": "7.4.1",
4
4
  "description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -14,8 +14,9 @@
14
14
  "webpack": "rimraf ./build && webpack --config ./webpack.config.ts",
15
15
  "demo": "npm run build && npm run ts-node --skip-project ./demo",
16
16
  "typedoc": "rimraf ./build && typedoc src/index.ts --tsconfig tsconfig.typedoc.json",
17
- "style": "prettier -l \"src/**/*.ts\"",
17
+ "style": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
18
18
  "style.fix": "npm run style -- --write",
19
+ "cspell": "cspell \"{src,demo,docs,scripts}/**/*.{ts,scss,html,md}\" && cspell \"./*.*\"",
19
20
  "fix-types": "ts-node --skip-project scripts/types-absolute-fixer.ts",
20
21
  "e2e": "ts-node scripts/e2e.ts",
21
22
  "serve.docs": "cd docs && docsify serve",
@@ -73,6 +74,7 @@
73
74
  "@types/webpack": "^5.0.0",
74
75
  "buffer": "^6.0.3",
75
76
  "chai": "^3.5.0",
77
+ "cspell": "^6.2.2",
76
78
  "docsify-cli": "^4.3.0",
77
79
  "glob": "^8.0.1",
78
80
  "jszip": "^3.1.5",
@@ -4,7 +4,8 @@ import * as sinon from "sinon";
4
4
 
5
5
  import { File } from "@file/file";
6
6
  import { Footer, Header } from "@file/header";
7
- import { Paragraph } from "@file/paragraph";
7
+ import { ImageRun, Paragraph } from "@file/paragraph";
8
+ import * as convenienceFunctions from "@util/convenience-functions";
8
9
 
9
10
  import { Compiler } from "./next-compiler";
10
11
 
@@ -15,6 +16,14 @@ describe("Compiler", () => {
15
16
  compiler = new Compiler();
16
17
  });
17
18
 
19
+ before(() => {
20
+ sinon.stub(convenienceFunctions, "uniqueId").callsFake(() => "test");
21
+ });
22
+
23
+ after(() => {
24
+ (convenienceFunctions.uniqueId as sinon.SinonStub).restore();
25
+ });
26
+
18
27
  describe("#compile()", () => {
19
28
  it("should pack all the content", async function () {
20
29
  this.timeout(99999999);
@@ -111,18 +120,38 @@ describe("Compiler", () => {
111
120
  const spy = sinon.spy(compiler["formatter"], "format");
112
121
 
113
122
  compiler.compile(file);
114
- expect(spy.callCount).to.equal(12);
123
+ expect(spy.callCount).to.equal(13);
115
124
  });
116
125
 
117
126
  it("should work with media datas", () => {
118
127
  // This test is required because before, there was a case where Document was formatted twice, which was inefficient
119
128
  // This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
120
- const paragraph = new Paragraph("");
121
129
  const file = new File({
122
130
  sections: [
123
131
  {
124
- properties: {},
125
- children: [paragraph],
132
+ headers: {
133
+ default: new Header({
134
+ children: [new Paragraph("test")],
135
+ }),
136
+ },
137
+ footers: {
138
+ default: new Footer({
139
+ children: [new Paragraph("test")],
140
+ }),
141
+ },
142
+ children: [
143
+ new Paragraph({
144
+ children: [
145
+ new ImageRun({
146
+ data: Buffer.from("", "base64"),
147
+ transformation: {
148
+ width: 100,
149
+ height: 100,
150
+ },
151
+ }),
152
+ ],
153
+ }),
154
+ ],
126
155
  },
127
156
  ],
128
157
  });
@@ -6,7 +6,7 @@ import { File } from "@file/file";
6
6
  import { Formatter } from "../formatter";
7
7
  import { ImageReplacer } from "./image-replacer";
8
8
  import { NumberingReplacer } from "./numbering-replacer";
9
- import { PrettityType } from "./packer";
9
+ import { PrettifyType } from "./packer";
10
10
 
11
11
  interface IXmlifyedFile {
12
12
  readonly data: string;
@@ -44,7 +44,7 @@ export class Compiler {
44
44
  this.numberingReplacer = new NumberingReplacer();
45
45
  }
46
46
 
47
- public compile(file: File, prettifyXml?: boolean | PrettityType): JSZip {
47
+ public compile(file: File, prettifyXml?: boolean | PrettifyType): JSZip {
48
48
  const zip = new JSZip();
49
49
  const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
50
50
  const map = new Map<string, IXmlifyedFile | IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
@@ -67,7 +67,7 @@ export class Compiler {
67
67
  return zip;
68
68
  }
69
69
 
70
- private xmlifyFile(file: File, prettify?: boolean | PrettityType): IXmlifyedFileMapping {
70
+ private xmlifyFile(file: File, prettify?: boolean | PrettifyType): IXmlifyedFileMapping {
71
71
  const documentRelationshipCount = file.Document.Relationships.RelationshipCount + 1;
72
72
 
73
73
  const documentXmlData = xml(
@@ -406,26 +406,19 @@ export class Compiler {
406
406
  path: "word/settings.xml",
407
407
  },
408
408
  Comments: {
409
- data: (() => {
410
- if (!file.Comments) {
411
- return;
412
- }
413
-
414
- const data = xml(
415
- this.formatter.format(file.Comments, {
416
- viewWrapper: file.Document,
417
- file,
418
- }),
419
- {
420
- indent: prettify,
421
- declaration: {
422
- standalone: "yes",
423
- encoding: "UTF-8",
424
- },
409
+ data: xml(
410
+ this.formatter.format(file.Comments, {
411
+ viewWrapper: file.Document,
412
+ file,
413
+ }),
414
+ {
415
+ indent: prettify,
416
+ declaration: {
417
+ standalone: "yes",
418
+ encoding: "UTF-8",
425
419
  },
426
- );
427
- return data;
428
- })(),
420
+ },
421
+ ),
429
422
  path: "word/comments.xml",
430
423
  },
431
424
  };
@@ -5,7 +5,7 @@ import { Compiler } from "./next-compiler";
5
5
  /**
6
6
  * Use blanks to prettify
7
7
  */
8
- export enum PrettityType {
8
+ export enum PrettifyType {
9
9
  NONE = "",
10
10
  WITH_2_BLANKS = " ",
11
11
  WITH_4_BLANKS = " ",
@@ -13,7 +13,7 @@ export enum PrettityType {
13
13
  }
14
14
 
15
15
  export class Packer {
16
- public static async toBuffer(file: File, prettify?: boolean | PrettityType): Promise<Buffer> {
16
+ public static async toBuffer(file: File, prettify?: boolean | PrettifyType): Promise<Buffer> {
17
17
  const zip = this.compiler.compile(file, prettify);
18
18
  const zipData = await zip.generateAsync({
19
19
  type: "nodebuffer",
@@ -24,7 +24,7 @@ export class Packer {
24
24
  return zipData;
25
25
  }
26
26
 
27
- public static async toBase64String(file: File, prettify?: boolean | PrettityType): Promise<string> {
27
+ public static async toBase64String(file: File, prettify?: boolean | PrettifyType): Promise<string> {
28
28
  const zip = this.compiler.compile(file, prettify);
29
29
  const zipData = await zip.generateAsync({
30
30
  type: "base64",
@@ -35,7 +35,7 @@ export class Packer {
35
35
  return zipData;
36
36
  }
37
37
 
38
- public static async toBlob(file: File, prettify?: boolean | PrettityType): Promise<Blob> {
38
+ public static async toBlob(file: File, prettify?: boolean | PrettifyType): Promise<Blob> {
39
39
  const zip = this.compiler.compile(file, prettify);
40
40
  const zipData = await zip.generateAsync({
41
41
  type: "blob",
@@ -41,6 +41,7 @@ export interface IPropertiesOptions {
41
41
 
42
42
  // <xs:element name="coreProperties" type="CT_CoreProperties"/>
43
43
 
44
+ /* cSpell:disable */
44
45
  // <xs:complexType name="CT_CoreProperties">
45
46
  // <xs:all>
46
47
  // <xs:element name="category" minOccurs="0" maxOccurs="1" type="xs:string"/>
@@ -60,6 +61,7 @@ export interface IPropertiesOptions {
60
61
  // <xs:element name="version" minOccurs="0" maxOccurs="1" type="xs:string"/>
61
62
  // </xs:all>
62
63
  // </xs:complexType>
64
+ /* cSpell:enable */
63
65
 
64
66
  export class CoreProperties extends XmlComponent {
65
67
  constructor(options: Omit<IPropertiesOptions, "sections">) {
@@ -1,5 +1,6 @@
1
1
  import { XmlAttributeComponent } from "@file/xml-components";
2
2
 
3
+ /* cSpell:disable */
3
4
  export interface IDocumentAttributesProperties {
4
5
  readonly wpc?: string;
5
6
  readonly mc?: string;
@@ -41,6 +42,7 @@ export interface IDocumentAttributesProperties {
41
42
  readonly w16sdtdh?: string;
42
43
  readonly w16se?: string;
43
44
  }
45
+ /* cSpell:enable */
44
46
 
45
47
  export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
46
48
  protected readonly xmlKeys = {
package/src/file/file.ts CHANGED
@@ -71,10 +71,7 @@ export class File {
71
71
  },
72
72
  );
73
73
 
74
- if (options.comments) {
75
- this.comments = new Comments(options.comments);
76
- }
77
-
74
+ this.comments = new Comments(options.comments ?? { children: [] });
78
75
  this.fileRelationships = new Relationships();
79
76
  this.customProperties = new CustomProperties(options.customProperties ?? []);
80
77
  this.appProperties = new AppProperties();
@@ -1,7 +1,7 @@
1
1
  export * from "./math-accent-character";
2
2
  export * from "./math-base";
3
3
  export * from "./math-limit-location";
4
- export * from "./math-naray-properties";
4
+ export * from "./math-n-ary-properties";
5
5
  export * from "./math-sub-script";
6
6
  export * from "./math-sum";
7
7
  export * from "./math-super-script";
@@ -2,14 +2,14 @@ import { expect } from "chai";
2
2
 
3
3
  import { Formatter } from "@export/formatter";
4
4
 
5
- import { MathNArayProperties } from "./math-naray-properties";
5
+ import { MathNAryProperties } from "./math-n-ary-properties";
6
6
 
7
- describe("MathNArayProperties", () => {
7
+ describe("MathNAryProperties", () => {
8
8
  describe("#constructor()", () => {
9
- it("should create a MathNArayProperties with correct root key", () => {
10
- const mathNArayProperties = new MathNArayProperties("∑", true, true);
9
+ it("should create a MathNAryProperties with correct root key", () => {
10
+ const mathNAryProperties = new MathNAryProperties("∑", true, true);
11
11
 
12
- const tree = new Formatter().format(mathNArayProperties);
12
+ const tree = new Formatter().format(mathNAryProperties);
13
13
  expect(tree).to.deep.equal({
14
14
  "m:naryPr": [
15
15
  {
@@ -31,9 +31,9 @@ describe("MathNArayProperties", () => {
31
31
  });
32
32
 
33
33
  it("should add super-script hide attributes", () => {
34
- const mathNArayProperties = new MathNArayProperties("∑", false, true);
34
+ const mathNAryProperties = new MathNAryProperties("∑", false, true);
35
35
 
36
- const tree = new Formatter().format(mathNArayProperties);
36
+ const tree = new Formatter().format(mathNAryProperties);
37
37
  expect(tree).to.deep.equal({
38
38
  "m:naryPr": [
39
39
  {
@@ -62,9 +62,9 @@ describe("MathNArayProperties", () => {
62
62
  });
63
63
 
64
64
  it("should add sub-script hide attributes", () => {
65
- const mathNArayProperties = new MathNArayProperties("∑", true, false);
65
+ const mathNAryProperties = new MathNAryProperties("∑", true, false);
66
66
 
67
- const tree = new Formatter().format(mathNArayProperties);
67
+ const tree = new Formatter().format(mathNAryProperties);
68
68
  expect(tree).to.deep.equal({
69
69
  "m:naryPr": [
70
70
  {
@@ -93,9 +93,9 @@ describe("MathNArayProperties", () => {
93
93
  });
94
94
 
95
95
  it("should add both super-script and sub-script hide attributes", () => {
96
- const mathNArayProperties = new MathNArayProperties("∑", false, false);
96
+ const mathNAryProperties = new MathNAryProperties("∑", false, false);
97
97
 
98
- const tree = new Formatter().format(mathNArayProperties);
98
+ const tree = new Formatter().format(mathNAryProperties);
99
99
  expect(tree).to.deep.equal({
100
100
  "m:naryPr": [
101
101
  {
@@ -6,7 +6,7 @@ import { MathLimitLocation } from "./math-limit-location";
6
6
  import { MathSubScriptHide } from "./math-sub-script-hide";
7
7
  import { MathSuperScriptHide } from "./math-super-script-hide";
8
8
 
9
- export class MathNArayProperties extends XmlComponent {
9
+ export class MathNAryProperties extends XmlComponent {
10
10
  constructor(accent: string, hasSuperScript: boolean, hasSubScript: boolean) {
11
11
  super("m:naryPr");
12
12
 
@@ -3,7 +3,7 @@ import { XmlComponent } from "@file/xml-components";
3
3
 
4
4
  import { MathComponent } from "../math-component";
5
5
  import { MathBase } from "./math-base";
6
- import { MathNArayProperties } from "./math-naray-properties";
6
+ import { MathNAryProperties } from "./math-n-ary-properties";
7
7
  import { MathSubScriptElement } from "./math-sub-script";
8
8
  import { MathSuperScriptElement } from "./math-super-script";
9
9
 
@@ -17,7 +17,7 @@ export class MathSum extends XmlComponent {
17
17
  constructor(options: IMathSumOptions) {
18
18
  super("m:nary");
19
19
 
20
- this.root.push(new MathNArayProperties("∑", !!options.superScript, !!options.subScript));
20
+ this.root.push(new MathNAryProperties("∑", !!options.superScript, !!options.subScript));
21
21
 
22
22
  if (!!options.subScript) {
23
23
  this.root.push(new MathSubScriptElement(options.subScript));
@@ -27,6 +27,7 @@ export enum RelativeVerticalPosition {
27
27
  }
28
28
 
29
29
  export interface ITableFloatOptions {
30
+ /* cSpell:disable */
30
31
  /**
31
32
  * Specifies the horizontal anchor or the base object from which the horizontal positioning in the
32
33
  * tblpX or tblpXSpec attribute should be determined.
@@ -35,6 +36,7 @@ export interface ITableFloatOptions {
35
36
  * text - relative to the vertical edge of the text margin for the column in which the anchor paragraph is located
36
37
  * If omitted, the value is assumed to be page.
37
38
  */
39
+ /* cSpell:enable */
38
40
  readonly horizontalAnchor?: TableAnchorType;
39
41
 
40
42
  /**
@@ -90,25 +92,25 @@ export interface ITableFloatOptions {
90
92
  readonly relativeVerticalPosition?: RelativeVerticalPosition;
91
93
 
92
94
  /**
93
- * Specifies the minimun distance to be maintained between the table and the top of text in the paragraph
95
+ * Specifies the minimum distance to be maintained between the table and the top of text in the paragraph
94
96
  * below the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
95
97
  */
96
98
  readonly bottomFromText?: number | string;
97
99
 
98
100
  /**
99
- * Specifies the minimun distance to be maintained between the table and the bottom edge of text in the paragraph
101
+ * Specifies the minimum distance to be maintained between the table and the bottom edge of text in the paragraph
100
102
  * above the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
101
103
  */
102
104
  readonly topFromText?: number | string;
103
105
 
104
106
  /**
105
- * Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
107
+ * Specifies the minimum distance to be maintained between the table and the edge of text in the paragraph
106
108
  * to the left of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
107
109
  */
108
110
  readonly leftFromText?: number | string;
109
111
 
110
112
  /**
111
- * Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
113
+ * Specifies the minimum distance to be maintained between the table and the edge of text in the paragraph
112
114
  * to the right of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
113
115
  */
114
116
  readonly rightFromText?: number | string;
@@ -13,7 +13,7 @@ describe("Deleted Page", () => {
13
13
  });
14
14
  });
15
15
 
16
- describe("Delted NumberOfPages", () => {
16
+ describe("Deleted NumberOfPages", () => {
17
17
  describe("#constructor()", () => {
18
18
  it("uses the font name for both ascii and hAnsi", () => {
19
19
  const tree = new Formatter().format(new DeletedNumberOfPages());
@@ -13,8 +13,8 @@ export function convertToXmlComponent(element: XmlElement): ImportedXmlComponent
13
13
  case undefined:
14
14
  case "element":
15
15
  const xmlComponent = new ImportedXmlComponent(element.name as string, element.attributes);
16
- const childElments = element.elements || [];
17
- for (const childElm of childElments) {
16
+ const childElements = element.elements || [];
17
+ for (const childElm of childElements) {
18
18
  const child = convertToXmlComponent(childElm);
19
19
  if (child !== undefined) {
20
20
  xmlComponent.push(child);
@@ -141,12 +141,12 @@ export class ImportDotx {
141
141
  }
142
142
 
143
143
  private async addRelationshipToWrapper(
144
- relationhipFile: IRelationshipFileInfo,
144
+ relationshipFile: IRelationshipFileInfo,
145
145
  zipContent: JSZip,
146
146
  wrapper: HeaderWrapper | FooterWrapper,
147
147
  media: Media,
148
148
  ): Promise<void> {
149
- const refFile = zipContent.files[`word/_rels/${relationhipFile.target}.rels`];
149
+ const refFile = zipContent.files[`word/_rels/${relationshipFile.target}.rels`];
150
150
 
151
151
  if (!refFile) {
152
152
  return;
@@ -4,13 +4,13 @@ import { convertInchesToTwip, convertMillimetersToTwip, uniqueId, uniqueNumericI
4
4
 
5
5
  describe("Utility", () => {
6
6
  describe("#convertMillimetersToTwip", () => {
7
- it("should call the underlying header's addChildElement for Paragraph", () => {
7
+ it("should convert millimeters to TWIP", () => {
8
8
  expect(convertMillimetersToTwip(1000)).to.equal(56692);
9
9
  });
10
10
  });
11
11
 
12
12
  describe("#convertInchesToTwip", () => {
13
- it("should call the underlying header's addChildElement", () => {
13
+ it("should convert inches to TWIP", () => {
14
14
  expect(convertInchesToTwip(1)).to.equal(1440);
15
15
  expect(convertInchesToTwip(0.5)).to.equal(720);
16
16
  expect(convertInchesToTwip(0.25)).to.equal(360);
@@ -73,6 +73,7 @@ describe("values", () => {
73
73
  it("should throw on invalid values", () => {
74
74
  expect(() => shortHexNumber("11")).to.throw();
75
75
  expect(() => shortHexNumber("112233")).to.throw();
76
+ /* cspell:disable-next-line */
76
77
  expect(() => shortHexNumber("FFFG")).to.throw();
77
78
  });
78
79
  });
@@ -208,6 +208,7 @@ export const pointMeasureValue = unsignedDecimalNumber;
208
208
  //
209
209
  // http://www.datypic.com/sc/xsd/t-xsd_dateTime.html
210
210
  // The type xsd:dateTime represents a specific date and time in the format
211
+ /* cspell:disable-next-line */
211
212
  // CCYY-MM-DDThh:mm:ss.sss, which is a concatenation of the date and time forms,
212
213
  // separated by a literal letter "T". All of the same rules that apply to the date
213
214
  // and time types are applicable to xsd:dateTime as well.