From 89e2129ca4693875611c99ce3afa9fb990ac4642 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Thu, 21 Jun 2018 14:50:50 +0200 Subject: [PATCH 01/19] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a6ec009e3..c46e7b1713 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.2.11", + "version": "3.3.0", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From 9d3b32a8411863510e35ca7a4415d40c8b933b94 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Mon, 25 Jun 2018 12:53:25 +0200 Subject: [PATCH 02/19] fix: fixed wrong import causing exported SectionProperties class to be unusable --- src/file/document/body/body.ts | 2 +- src/file/document/document.ts | 2 +- src/file/file.ts | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/file/document/body/body.ts b/src/file/document/body/body.ts index 691dfd7518..549ba86f97 100644 --- a/src/file/document/body/body.ts +++ b/src/file/document/body/body.ts @@ -1,5 +1,5 @@ import { XmlComponent, IXmlableObject } from "file/xml-components"; -import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties"; +import { SectionProperties, SectionPropertiesOptions } from "./section-properties"; import { Paragraph, ParagraphProperties } from "../.."; export class Body extends XmlComponent { diff --git a/src/file/document/document.ts b/src/file/document/document.ts index a71bcbffe9..6dbb4decdf 100644 --- a/src/file/document/document.ts +++ b/src/file/document/document.ts @@ -4,7 +4,7 @@ import { XmlComponent } from "file/xml-components"; import { Paragraph, PictureRun } from "../paragraph"; import { Table } from "../table"; import { Body } from "./body"; -import { SectionPropertiesOptions } from "./body/section-properties/section-properties"; +import { SectionPropertiesOptions } from "./body/section-properties"; import { DocumentAttributes } from "./document-attributes"; export class Document extends XmlComponent { diff --git a/src/file/file.ts b/src/file/file.ts index a42e542e33..e805b10ade 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -2,7 +2,6 @@ import { AppProperties } from "./app-properties/app-properties"; import { ContentTypes } from "./content-types/content-types"; import { CoreProperties, IPropertiesOptions } from "./core-properties"; import { Document } from "./document"; -import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties"; import { FooterWrapper } from "./footer-wrapper"; import { HeaderWrapper } from "./header-wrapper"; import { Media } from "./media"; @@ -14,7 +13,7 @@ import { DefaultStylesFactory } from "./styles/factory"; import { ExternalStylesFactory } from "./styles/external-styles-factory"; import { Table } from "./table"; import { IMediaData } from "index"; -import { FooterReferenceType, HeaderReferenceType } from "./document/body/section-properties"; +import { FooterReferenceType, HeaderReferenceType, SectionPropertiesOptions } from "./document/body/section-properties"; export class File { private readonly document: Document; From 52007785afdb6f1e718fa6cb120839540231c743 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Mon, 25 Jun 2018 12:54:36 +0200 Subject: [PATCH 03/19] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c46e7b1713..446427e152 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.3.0", + "version": "3.3.1", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From ed72d60951288e03eab5a08c154ea0243eb3b09a Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Wed, 27 Jun 2018 21:55:15 +0200 Subject: [PATCH 04/19] external-styles: create correct XmlComponents from imported style --- .../styles/external-styles-factory.spec.ts | 69 ++++++++++++++++++- src/file/styles/external-styles-factory.ts | 9 ++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/file/styles/external-styles-factory.spec.ts b/src/file/styles/external-styles-factory.spec.ts index 861a6f05d8..e34bfbaa8d 100644 --- a/src/file/styles/external-styles-factory.spec.ts +++ b/src/file/styles/external-styles-factory.spec.ts @@ -10,6 +10,17 @@ describe("External styles factory", () => { + + + + + + + + + + + @@ -52,7 +63,63 @@ describe("External styles factory", () => { expect(importedStyle.root.length).to.equal(5); expect(importedStyle.root[1]).to.eql({ deleted: false, - root: [], + root: [ + { + deleted: false, + root: [ + { + deleted: false, + root: [ + { + _attr: { + "w:ascii": "Arial", + "w:cstheme": "minorHAnsi", + "w:eastAsiaTheme": "minorHAnsi", + "w:hAnsi": "Arial", + }, + deleted: false, + root: [], + rootKey: "w:rFonts", + }, + { + _attr: { + "w:bidi": "ar-SA", + "w:eastAsia": "en-US", + "w:val": "en-US", + }, + deleted: false, + root: [], + rootKey: "w:lang", + }, + ], + rootKey: "w:rPr", + }, + ], + rootKey: "w:rPrDefault", + }, + { + deleted: false, + root: [ + { + deleted: false, + root: [ + { + _attr: { + "w:after": "160", + "w:line": "259", + "w:lineRule": "auto", + }, + deleted: false, + root: [], + rootKey: "w:spacing", + }, + ], + rootKey: "w:pPr", + }, + ], + rootKey: "w:pPrDefault", + }, + ], rootKey: "w:docDefaults", }); expect(importedStyle.root[2]).to.eql({ diff --git a/src/file/styles/external-styles-factory.ts b/src/file/styles/external-styles-factory.ts index 9757faf8d9..7f54f03d4e 100644 --- a/src/file/styles/external-styles-factory.ts +++ b/src/file/styles/external-styles-factory.ts @@ -1,6 +1,6 @@ import { Styles } from "./"; import * as fastXmlParser from "fast-xml-parser"; -import { ImportedXmlComponent, ImportedRootElementAttributes, parseOptions, convertToXmlComponent } from "./../../file/xml-components"; +import { ImportedRootElementAttributes, parseOptions, convertToXmlComponent } from "./../../file/xml-components"; export class ExternalStylesFactory { /** @@ -34,7 +34,12 @@ export class ExternalStylesFactory { Object.keys(xmlStyles) .filter((element) => element !== "_attr" && element !== "w:style") .forEach((element) => { - importedStyle.push(new ImportedXmlComponent(element, xmlStyles[element]._attr)); + const converted = convertToXmlComponent(element, xmlStyles[element]); + if (Array.isArray(converted)) { + converted.forEach((c) => importedStyle.push(c)); + } else { + importedStyle.push(converted); + } }); // convert the styles one by one From 55220c147db53afe3eab7a44e56452743b1fa0f6 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Wed, 27 Jun 2018 22:10:11 +0200 Subject: [PATCH 05/19] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 446427e152..6cb05a6fb8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.3.1", + "version": "3.3.2", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From c797ed9c2570a876a54b251728cc1b8061c23110 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Fri, 29 Jun 2018 00:32:01 +0200 Subject: [PATCH 06/19] media: fixed bug when media size can be decimal - produces invalid docx document --- src/file/media/media.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/file/media/media.ts b/src/file/media/media.ts index 7f384f9f98..99a193e88c 100644 --- a/src/file/media/media.ts +++ b/src/file/media/media.ts @@ -23,8 +23,8 @@ export class Media { y: dimensions.height, }, emus: { - x: dimensions.width * 9525, - y: dimensions.height * 9525, + x: Math.round(dimensions.width * 9525), + y: Math.round(dimensions.height * 9525), }, }, }; From 612a2f90ac3910b17aec2a0afb96f9e45754b6a5 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Fri, 29 Jun 2018 16:31:25 +0200 Subject: [PATCH 07/19] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6cb05a6fb8..1116182ac4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.3.2", + "version": "3.3.3", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From 796e0008261e14f0049e9a599ac0a10f9c2edd22 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Tue, 3 Jul 2018 13:48:31 +0200 Subject: [PATCH 08/19] feature: add support for section page borders --- .../document/body/section-properties/index.ts | 1 + .../section-properties/page-border/index.ts | 1 + .../page-border/page-borders.spec.ts | 91 ++++++++++++++++++ .../page-border/page-borders.ts | 94 +++++++++++++++++++ .../section-properties.spec.ts | 15 ++- .../section-properties/section-properties.ts | 28 +++++- src/file/styles/border/border-style.ts | 29 ++++++ src/file/styles/border/index.ts | 1 + src/file/styles/index.ts | 1 + src/file/table/table-cell.spec.ts | 3 +- src/file/table/table-cell.ts | 31 +----- 11 files changed, 261 insertions(+), 34 deletions(-) create mode 100644 src/file/document/body/section-properties/page-border/index.ts create mode 100644 src/file/document/body/section-properties/page-border/page-borders.spec.ts create mode 100644 src/file/document/body/section-properties/page-border/page-borders.ts create mode 100644 src/file/styles/border/border-style.ts create mode 100644 src/file/styles/border/index.ts diff --git a/src/file/document/body/section-properties/index.ts b/src/file/document/body/section-properties/index.ts index f1b5eabb84..cab88ac7c7 100644 --- a/src/file/document/body/section-properties/index.ts +++ b/src/file/document/body/section-properties/index.ts @@ -3,3 +3,4 @@ export * from "./footer-reference"; export * from "./header-reference"; export * from "./page-size"; export * from "./page-number"; +export * from "./page-border"; diff --git a/src/file/document/body/section-properties/page-border/index.ts b/src/file/document/body/section-properties/page-border/index.ts new file mode 100644 index 0000000000..53d8b8ce4b --- /dev/null +++ b/src/file/document/body/section-properties/page-border/index.ts @@ -0,0 +1 @@ +export * from "./page-borders"; diff --git a/src/file/document/body/section-properties/page-border/page-borders.spec.ts b/src/file/document/body/section-properties/page-border/page-borders.spec.ts new file mode 100644 index 0000000000..782280f292 --- /dev/null +++ b/src/file/document/body/section-properties/page-border/page-borders.spec.ts @@ -0,0 +1,91 @@ +import { expect } from "chai"; + +import { Formatter } from "../../../../../export/formatter"; +import { PageBorders, PageBorderDisplay, PageBorderZOrder } from "./page-borders"; +import { BorderStyle } from "../../../../styles"; + +describe("PageBorders", () => { + describe("#constructor()", () => { + it("should create empty element when no options are passed", () => { + const properties = new PageBorders(); + const tree = new Formatter().format(properties); + + expect(tree).to.equal(""); + }); + + it("should create page borders with some configuration", () => { + const properties = new PageBorders({ + pageBorders: { + display: PageBorderDisplay.FIRST_PAGE, + }, + }); + const tree = new Formatter().format(properties); + + expect(Object.keys(tree)).to.deep.equal(["w:pgBorders"]); + expect(tree["w:pgBorders"]).to.be.an.instanceof(Array); + expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage" } }); + }); + + it("should create page borders with full configuration", () => { + const properties = new PageBorders({ + pageBorders: { + display: PageBorderDisplay.FIRST_PAGE, + zOrder: PageBorderZOrder.BACK, + }, + pageBorderTop: { + style: BorderStyle.DOUBLE_WAVE, + size: 10, + color: "001122", + }, + pageBorderRight: { + style: BorderStyle.DOUBLE, + size: 20, + color: "223344", + }, + pageBorderBottom: { + style: BorderStyle.SINGLE, + size: 30, + color: "556677", + }, + pageBorderLeft: { + style: BorderStyle.DOTTED, + size: 40, + color: "889900", + }, + }); + const tree = new Formatter().format(properties); + + expect(Object.keys(tree)).to.deep.equal(["w:pgBorders"]); + expect(tree["w:pgBorders"]).to.be.an.instanceof(Array); + expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage", "w:zOrder": "back" } }); + expect(tree["w:pgBorders"][1]).to.deep.equal({ + "w:top": [ + { + _attr: { "w:color": "001122", "w:size": 10, "w:val": "doubleWave" }, + }, + ], + }); + expect(tree["w:pgBorders"][2]).to.deep.equal({ + "w:right": [ + { + _attr: { "w:color": "223344", "w:size": 20, "w:val": "double" }, + }, + ], + }); + expect(tree["w:pgBorders"][3]).to.deep.equal({ + "w:bottom": [ + { + _attr: { "w:color": "556677", "w:size": 30, "w:val": "single" }, + }, + ], + }); + expect(tree["w:pgBorders"][4]).to.deep.equal({ + "w:left": [ + { + _attr: { "w:color": "889900", "w:size": 40, "w:val": "dotted" }, + }, + ], + }); + }); + }); +}); diff --git a/src/file/document/body/section-properties/page-border/page-borders.ts b/src/file/document/body/section-properties/page-border/page-borders.ts new file mode 100644 index 0000000000..88b6ce98dd --- /dev/null +++ b/src/file/document/body/section-properties/page-border/page-borders.ts @@ -0,0 +1,94 @@ +// http://officeopenxml.com/WPsectionBorders.php +import { XmlComponent, XmlAttributeComponent, IXmlableObject } from "file/xml-components"; +import { BorderStyle } from "../../../../styles"; + +export enum PageBorderDisplay { + ALL_PAGES = "allPages", + FIRST_PAGE = "firstPage", + NOT_FIRST_PAGE = "notFirstPage", +} + +export enum PageBorderOffsetFrom { + PAGE = "page", + TEXT = "text", +} + +export enum PageBorderZOrder { + BACK = "back", + FRONT = "front", +} + +export interface IPageBorderAttributes { + display?: PageBorderDisplay; + offsetFrom?: PageBorderOffsetFrom; + zOrder?: PageBorderZOrder; +} + +export interface PageBorderConfiguration { + style?: BorderStyle; + size?: number; + color?: string; + space?: number; +} + +export type PageBordersOptions = { + pageBorders?: IPageBorderAttributes; + pageBorderTop?: PageBorderConfiguration; + pageBorderRight?: PageBorderConfiguration; + pageBorderBottom?: PageBorderConfiguration; + pageBorderLeft?: PageBorderConfiguration; +}; + +class PageBordeAttributes extends XmlAttributeComponent { + protected xmlKeys = { + style: "w:val", + size: "w:size", + color: "w:color", + space: "w:space", + }; +} + +class PageBorder extends XmlComponent { + constructor(key: string, options: PageBorderConfiguration) { + super(key); + + this.root.push(new PageBordeAttributes(options)); + } +} + +class PageBordersAttributes extends XmlAttributeComponent { + protected xmlKeys = { + display: "w:display", + offsetFrom: "w:offsetFrom", + zOrder: "w:zOrder", + }; +} + +export class PageBorders extends XmlComponent { + constructor(options?: PageBordersOptions) { + super("w:pgBorders"); + + if (!options) return; + + let pageBordersAttributes = {}; + + if (options.pageBorders) { + pageBordersAttributes = { + display: options.pageBorders.display, + offsetFrom: options.pageBorders.offsetFrom, + zOrder: options.pageBorders.zOrder, + }; + } + + this.root.push(new PageBordersAttributes(pageBordersAttributes)); + + if (options.pageBorderTop) this.root.push(new PageBorder("w:top", options.pageBorderTop)); + if (options.pageBorderRight) this.root.push(new PageBorder("w:right", options.pageBorderRight)); + if (options.pageBorderBottom) this.root.push(new PageBorder("w:bottom", options.pageBorderBottom)); + if (options.pageBorderLeft) this.root.push(new PageBorder("w:left", options.pageBorderLeft)); + } + + public prepForXml(): IXmlableObject { + return this.root.length > 0 ? super.prepForXml() : ""; + } +} diff --git a/src/file/document/body/section-properties/section-properties.spec.ts b/src/file/document/body/section-properties/section-properties.spec.ts index 05a49d09d9..b2499bbd63 100644 --- a/src/file/document/body/section-properties/section-properties.spec.ts +++ b/src/file/document/body/section-properties/section-properties.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { Formatter } from "../../../../export/formatter"; import { SectionProperties } from "./section-properties"; -import { FooterReferenceType, PageNumberFormat } from "."; +import { FooterReferenceType, PageNumberFormat, PageBorderOffsetFrom } from "."; describe("SectionProperties", () => { describe("#constructor()", () => { @@ -155,5 +155,18 @@ describe("SectionProperties", () => { ], }); }); + + it("should create section properties with page borders", () => { + const properties = new SectionProperties({ + pageBorders: { + offsetFrom: PageBorderOffsetFrom.PAGE, + }, + }); + const tree = new Formatter().format(properties); + expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); + expect(tree["w:sectPr"][7]).to.deep.equal({ + "w:pgBorders": [{ _attr: { "w:offsetFrom": "page" } }], + }); + }); }); }); diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 993812bd5e..bb7a36746c 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -10,7 +10,7 @@ import { PageMargin } from "./page-margin/page-margin"; import { IPageMarginAttributes } from "./page-margin/page-margin-attributes"; import { PageSize } from "./page-size/page-size"; import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes"; -import { FooterReferenceType, IPageNumberTypeAttributes, PageNumberType, PageNumberFormat } from "."; +import { FooterReferenceType, IPageNumberTypeAttributes, PageNumberType, PageNumberFormat, PageBordersOptions, PageBorders } from "."; import { HeaderReferenceType } from "./header-reference/header-reference-attributes"; export type SectionPropertiesOptions = IPageSizeAttributes & @@ -19,7 +19,8 @@ export type SectionPropertiesOptions = IPageSizeAttributes & IDocGridAttributesProperties & HeaderOptions & FooterOptions & - IPageNumberTypeAttributes; + IPageNumberTypeAttributes & + PageBordersOptions; export class SectionProperties extends XmlComponent { private options: SectionPropertiesOptions; @@ -45,6 +46,11 @@ export class SectionProperties extends XmlComponent { footerId: 0, pageNumberStart: undefined, pageNumberFormatType: PageNumberFormat.DECIMAL, + pageBorders: undefined, + pageBorderTop: undefined, + pageBorderRight: undefined, + pageBorderBottom: undefined, + pageBorderLeft: undefined, }; const mergedOptions = { @@ -81,6 +87,24 @@ export class SectionProperties extends XmlComponent { this.root.push(new PageNumberType(mergedOptions.pageNumberStart, mergedOptions.pageNumberFormatType)); + if ( + mergedOptions.pageBorders || + mergedOptions.pageBorderTop || + mergedOptions.pageBorderRight || + mergedOptions.pageBorderBottom || + mergedOptions.pageBorderLeft + ) { + this.root.push( + new PageBorders({ + pageBorders: mergedOptions.pageBorders, + pageBorderTop: mergedOptions.pageBorderTop, + pageBorderRight: mergedOptions.pageBorderRight, + pageBorderBottom: mergedOptions.pageBorderBottom, + pageBorderLeft: mergedOptions.pageBorderLeft, + }), + ); + } + this.options = mergedOptions; } diff --git a/src/file/styles/border/border-style.ts b/src/file/styles/border/border-style.ts new file mode 100644 index 0000000000..00f4117d31 --- /dev/null +++ b/src/file/styles/border/border-style.ts @@ -0,0 +1,29 @@ +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", +} diff --git a/src/file/styles/border/index.ts b/src/file/styles/border/index.ts new file mode 100644 index 0000000000..e62e5f7dcc --- /dev/null +++ b/src/file/styles/border/index.ts @@ -0,0 +1 @@ +export * from "./border-style"; diff --git a/src/file/styles/index.ts b/src/file/styles/index.ts index 5b0bd1b063..7c75699adc 100644 --- a/src/file/styles/index.ts +++ b/src/file/styles/index.ts @@ -1,6 +1,7 @@ import { XmlComponent, BaseXmlComponent } from "file/xml-components"; import { DocumentDefaults } from "./defaults"; import { ParagraphStyle } from "./style"; +export * from "./border"; export class Styles extends XmlComponent { constructor(_initialStyles?: BaseXmlComponent) { diff --git a/src/file/table/table-cell.spec.ts b/src/file/table/table-cell.spec.ts index 01c81848bb..4e69e958a8 100644 --- a/src/file/table/table-cell.spec.ts +++ b/src/file/table/table-cell.spec.ts @@ -1,7 +1,8 @@ import { expect } from "chai"; -import { TableCellBorders, BorderStyle, TableCellWidth, WidthType } from "./table-cell"; +import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell"; import { Formatter } from "../../export/formatter"; +import { BorderStyle } from "../styles"; describe("TableCellBorders", () => { describe("#prepForXml", () => { diff --git a/src/file/table/table-cell.ts b/src/file/table/table-cell.ts index 99282f1125..59101b9af3 100644 --- a/src/file/table/table-cell.ts +++ b/src/file/table/table-cell.ts @@ -1,34 +1,5 @@ import { XmlComponent, XmlAttributeComponent, IXmlableObject } from "file/xml-components"; - -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", -} +import { BorderStyle } from "../styles"; interface ICellBorder { style: BorderStyle; From c95e765456ba2b02b468cb0d1447f2be2d8a95a3 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Tue, 3 Jul 2018 14:11:19 +0200 Subject: [PATCH 09/19] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1116182ac4..7caa995140 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.3.3", + "version": "3.3.4", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From a05abd0eea80bcc78e4fd6dc42535e43258de2d9 Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Fri, 6 Jul 2018 18:54:30 +0200 Subject: [PATCH 10/19] numbering: add support to define suffix for numbering level --- src/file/numbering/index.ts | 1 + src/file/numbering/level.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/file/numbering/index.ts b/src/file/numbering/index.ts index a861d336ee..d83cffc61c 100644 --- a/src/file/numbering/index.ts +++ b/src/file/numbering/index.ts @@ -1,2 +1,3 @@ export * from "./numbering"; export * from "./abstract-numbering"; +export * from "./level"; diff --git a/src/file/numbering/level.ts b/src/file/numbering/level.ts index bb50bfb2e2..0df90758fb 100644 --- a/src/file/numbering/level.ts +++ b/src/file/numbering/level.ts @@ -60,6 +60,23 @@ class LevelJc extends XmlComponent { } } +export enum LevelSuffix { + NOTHING = "nothing", + SPACE = "space", + TAB = "tab", +} + +class Suffix extends XmlComponent { + constructor(value: LevelSuffix) { + super("w:suff"); + this.root.push( + new Attributes({ + val: value, + }), + ); + } +} + export class LevelBase extends XmlComponent { private readonly paragraphProperties: ParagraphProperties; private readonly runProperties: RunProperties; @@ -93,6 +110,11 @@ export class LevelBase extends XmlComponent { this.root.push(this.runProperties); } + public setSuffix(value: LevelSuffix) { + this.root.push(new Suffix(value)); + return this; + } + public addParagraphProperty(property: XmlComponent): Level { this.paragraphProperties.push(property); return this; From 3da0bb38df000a47126e212684fb5c348b556f8c Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Fri, 6 Jul 2018 19:01:23 +0200 Subject: [PATCH 11/19] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7caa995140..5d2b6176c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx-h4", - "version": "3.3.4", + "version": "3.3.5", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { From 92da93a16043d1194059026a78fdf96d44ad0706 Mon Sep 17 00:00:00 2001 From: Dolan Date: Tue, 7 Aug 2018 02:47:24 +0100 Subject: [PATCH 12/19] Rename to more readable names --- demo/demo22.js | 4 ++-- .../paragraph/formatting/{bidi.ts => bidirectional.ts} | 2 +- src/file/paragraph/paragraph.spec.ts | 4 ++-- src/file/paragraph/paragraph.ts | 6 +++--- src/file/paragraph/run/formatting.ts | 4 ++-- src/file/paragraph/run/run.spec.ts | 2 +- src/file/paragraph/run/run.ts | 8 ++++---- src/file/styles/defaults/run-properties.ts | 4 ++-- src/file/styles/style/index.ts | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) rename src/file/paragraph/formatting/{bidi.ts => bidirectional.ts} (67%) diff --git a/demo/demo22.js b/demo/demo22.js index ce42f22ccd..4503d6c1c3 100644 --- a/demo/demo22.js +++ b/demo/demo22.js @@ -2,8 +2,8 @@ const docx = require('../build'); var doc = new docx.Document(); -var textRun = new docx.TextRun("שלום עולם").rtl(); -var paragraph = new docx.Paragraph().bidi(); +var textRun = new docx.TextRun("שלום עולם").rightToLeft(); +var paragraph = new docx.Paragraph().bidirectional(); paragraph.addRun(textRun); doc.addParagraph(paragraph); diff --git a/src/file/paragraph/formatting/bidi.ts b/src/file/paragraph/formatting/bidirectional.ts similarity index 67% rename from src/file/paragraph/formatting/bidi.ts rename to src/file/paragraph/formatting/bidirectional.ts index 4a8bbdade9..4083247e78 100644 --- a/src/file/paragraph/formatting/bidi.ts +++ b/src/file/paragraph/formatting/bidirectional.ts @@ -1,6 +1,6 @@ import { XmlComponent } from "file/xml-components"; -export class Bidi extends XmlComponent { +export class Bidirectional extends XmlComponent { constructor() { super("w:bidi"); } diff --git a/src/file/paragraph/paragraph.spec.ts b/src/file/paragraph/paragraph.spec.ts index a2176f3ecf..e00fa6167c 100644 --- a/src/file/paragraph/paragraph.spec.ts +++ b/src/file/paragraph/paragraph.spec.ts @@ -339,9 +339,9 @@ describe("Paragraph", () => { }); }); - describe("#bidi", () => { + describe("#bidirectional", () => { it("set paragraph right to left layout", () => { - paragraph.bidi(); + paragraph.bidirectional(); const tree = new Formatter().format(paragraph); expect(tree).to.deep.equal({ "w:p": [{ "w:pPr": [{ "w:bidi": [] }] }], diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index 22e64fc643..ef298604d7 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -5,7 +5,7 @@ import { Num } from "file/numbering/num"; import { XmlComponent } from "file/xml-components"; import { Alignment } from "./formatting/alignment"; -import { Bidi } from "./formatting/bidi"; +import { Bidirectional } from "./formatting/bidirectional"; import { ThematicBreak } from "./formatting/border"; import { Indent } from "./formatting/indent"; import { KeepLines, KeepNext } from "./formatting/keep"; @@ -217,8 +217,8 @@ export class Paragraph extends XmlComponent { return this; } - public bidi(): Paragraph { - this.properties.push(new Bidi()); + public bidirectional(): Paragraph { + this.properties.push(new Bidirectional()); return this; } } diff --git a/src/file/paragraph/run/formatting.ts b/src/file/paragraph/run/formatting.ts index bd9da1c358..31c64844d0 100644 --- a/src/file/paragraph/run/formatting.ts +++ b/src/file/paragraph/run/formatting.ts @@ -124,7 +124,7 @@ export class Size extends XmlComponent { } } -export class SizeCs extends XmlComponent { +export class SizeComplexScript extends XmlComponent { constructor(size: number) { super("w:szCs"); this.root.push( @@ -135,7 +135,7 @@ export class SizeCs extends XmlComponent { } } -export class RTL extends XmlComponent { +export class RightToLeft extends XmlComponent { constructor() { super("w:rtl"); this.root.push( diff --git a/src/file/paragraph/run/run.spec.ts b/src/file/paragraph/run/run.spec.ts index 5fbe93ee92..f05afaafe0 100644 --- a/src/file/paragraph/run/run.spec.ts +++ b/src/file/paragraph/run/run.spec.ts @@ -145,7 +145,7 @@ describe("Run", () => { describe("#rtl", () => { it("should set the run to the RTL mode", () => { - run.rtl(); + run.rightToLeft(); const tree = new Formatter().format(run); expect(tree).to.deep.equal({ "w:r": [{ "w:rPr": [{ "w:rtl": [{ _attr: { "w:val": true } }] }] }], diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index ea45bbcd34..415364fb2d 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -1,7 +1,7 @@ // http://officeopenxml.com/WPtext.php import { Break } from "./break"; import { Caps, SmallCaps } from "./caps"; -import { Bold, Color, DoubleStrike, Italics, RTL, Size, SizeCs, Strike } from "./formatting"; +import { Bold, Color, DoubleStrike, Italics, RightToLeft, Size, SizeComplexScript, Strike } from "./formatting"; import { Begin, End, Page, Separate } from "./page-number"; import { RunProperties } from "./properties"; import { RunFonts } from "./run-fonts"; @@ -43,12 +43,12 @@ export class Run extends XmlComponent { public size(size: number): Run { this.properties.push(new Size(size)); - this.properties.push(new SizeCs(size)); + this.properties.push(new SizeComplexScript(size)); return this; } - public rtl(): Run { - this.properties.push(new RTL()); + public rightToLeft(): Run { + this.properties.push(new RightToLeft()); return this; } diff --git a/src/file/styles/defaults/run-properties.ts b/src/file/styles/defaults/run-properties.ts index 1f4018dee2..9f30986b84 100644 --- a/src/file/styles/defaults/run-properties.ts +++ b/src/file/styles/defaults/run-properties.ts @@ -1,5 +1,5 @@ import { XmlComponent } from "file/xml-components"; -import { Size, SizeCs } from "../../paragraph/run/formatting"; +import { Size, SizeComplexScript } from "../../paragraph/run/formatting"; import { RunProperties } from "../../paragraph/run/properties"; import { RunFonts } from "../../paragraph/run/run-fonts"; @@ -14,7 +14,7 @@ export class RunPropertiesDefaults extends XmlComponent { public size(size: number): RunPropertiesDefaults { this.properties.push(new Size(size)); - this.properties.push(new SizeCs(size)); + this.properties.push(new SizeComplexScript(size)); return this; } diff --git a/src/file/styles/style/index.ts b/src/file/styles/style/index.ts index 21e60b3d43..655cc28d2a 100644 --- a/src/file/styles/style/index.ts +++ b/src/file/styles/style/index.ts @@ -74,7 +74,7 @@ export class ParagraphStyle extends Style { public size(twips: number): ParagraphStyle { this.addRunProperty(new formatting.Size(twips)); - this.addRunProperty(new formatting.SizeCs(twips)); + this.addRunProperty(new formatting.SizeComplexScript(twips)); return this; } @@ -283,7 +283,7 @@ export class CharacterStyle extends Style { public size(twips: number): CharacterStyle { this.addRunProperty(new formatting.Size(twips)); - this.addRunProperty(new formatting.SizeCs(twips)); + this.addRunProperty(new formatting.SizeComplexScript(twips)); return this; } } From e10c20fa4252436ab63727dd4206d65beca5f478 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 01:55:50 +0100 Subject: [PATCH 13/19] Add image to run --- demo/demo23.js | 3 +++ src/file/file.ts | 10 +++++----- src/file/footer-wrapper.ts | 8 ++++---- src/file/header-wrapper.ts | 8 ++++---- src/file/media/image.ts | 13 +++++++++++++ src/file/media/index.ts | 1 + src/file/media/media.ts | 7 ++++--- src/file/paragraph/image.ts | 6 +++++- src/file/paragraph/paragraph.ts | 7 ++++--- 9 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 src/file/media/image.ts diff --git a/demo/demo23.js b/demo/demo23.js index ec38db901f..7fd5ebb6fb 100644 --- a/demo/demo23.js +++ b/demo/demo23.js @@ -15,6 +15,9 @@ const image5 = docx.Media.addImage(doc, "./demo/images/pizza.gif"); const imageBase64Data = `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` const image6 = docx.Media.addImageFromBuffer(doc, Buffer.from(imageBase64Data, 'base64'), 100, 100); +// I am adding an image to the paragraph rather than the document to make the image inline +paragraph.addImage(image5); + doc.addImage(image); doc.addImage(image2); doc.addImage(image3); diff --git a/src/file/file.ts b/src/file/file.ts index e742e0dd70..d7ef02b520 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -7,9 +7,9 @@ import { SectionPropertiesOptions } from "./document/body/section-properties/sec import { FooterWrapper } from "./footer-wrapper"; import { FootNotes } from "./footnotes"; import { HeaderWrapper } from "./header-wrapper"; -import { Media } from "./media"; +import { Image, Media } from "./media"; import { Numbering } from "./numbering"; -import { Bookmark, Hyperlink, Image, Paragraph } from "./paragraph"; +import { Bookmark, Hyperlink, Paragraph } from "./paragraph"; import { Relationships } from "./relationships"; import { Styles } from "./styles"; import { ExternalStylesFactory } from "./styles/external-styles-factory"; @@ -126,19 +126,19 @@ export class File { public createImage(filePath: string): Image { const image = Media.addImage(this, filePath); - this.document.addParagraph(image); + this.document.addParagraph(image.Paragraph); return image; } public addImage(image: Image): File { - this.document.addParagraph(image); + this.document.addParagraph(image.Paragraph); return this; } public createImageFromBuffer(buffer: Buffer, width?: number, height?: number): Image { const image = Media.addImageFromBuffer(this, buffer, width, height); - this.document.addParagraph(image); + this.document.addParagraph(image.Paragraph); return image; } diff --git a/src/file/footer-wrapper.ts b/src/file/footer-wrapper.ts index b1bd4b534c..c1080bbd4e 100644 --- a/src/file/footer-wrapper.ts +++ b/src/file/footer-wrapper.ts @@ -1,7 +1,7 @@ import { XmlComponent } from "file/xml-components"; import { Footer } from "./footer/footer"; -import { Media } from "./media"; -import { Image, Paragraph } from "./paragraph"; +import { Image, Media } from "./media"; +import { ImageParagraph, Paragraph } from "./paragraph"; import { Relationships } from "./relationships"; import { Table } from "./table"; @@ -43,11 +43,11 @@ export class FooterWrapper { "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`, ); - this.addImage(new Image(mediaData)); + this.addImage(new Image(new ImageParagraph(mediaData))); } public addImage(image: Image): FooterWrapper { - this.footer.addParagraph(image); + this.footer.addParagraph(image.Paragraph); return this; } diff --git a/src/file/header-wrapper.ts b/src/file/header-wrapper.ts index 8970dc2560..1053bc2096 100644 --- a/src/file/header-wrapper.ts +++ b/src/file/header-wrapper.ts @@ -1,7 +1,7 @@ import { XmlComponent } from "file/xml-components"; import { Header } from "./header/header"; -import { Media } from "./media"; -import { Image, Paragraph } from "./paragraph"; +import { Image, Media } from "./media"; +import { ImageParagraph, Paragraph } from "./paragraph"; import { Relationships } from "./relationships"; import { Table } from "./table"; @@ -43,11 +43,11 @@ export class HeaderWrapper { "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`, ); - this.addImage(new Image(mediaData)); + this.addImage(new Image(new ImageParagraph(mediaData))); } public addImage(image: Image): HeaderWrapper { - this.header.addParagraph(image); + this.header.addParagraph(image.Paragraph); return this; } diff --git a/src/file/media/image.ts b/src/file/media/image.ts new file mode 100644 index 0000000000..8255fe7398 --- /dev/null +++ b/src/file/media/image.ts @@ -0,0 +1,13 @@ +import { ImageParagraph, PictureRun } from "../paragraph"; + +export class Image { + constructor(private readonly paragraph: ImageParagraph) {} + + public get Paragraph(): ImageParagraph { + return this.paragraph; + } + + public get Run(): PictureRun { + return this.paragraph.Run; + } +} diff --git a/src/file/media/index.ts b/src/file/media/index.ts index 3575274e26..2ccc436e68 100644 --- a/src/file/media/index.ts +++ b/src/file/media/index.ts @@ -1,2 +1,3 @@ export * from "./media"; export * from "./data"; +export * from "./image"; diff --git a/src/file/media/media.ts b/src/file/media/media.ts index e813a2c051..b0fb4019d8 100644 --- a/src/file/media/media.ts +++ b/src/file/media/media.ts @@ -3,8 +3,9 @@ import * as sizeOf from "image-size"; import * as path from "path"; import { File } from "../file"; -import { Image } from "../paragraph"; +import { ImageParagraph } from "../paragraph"; import { IMediaData } from "./data"; +import { Image } from "./image"; interface IHackedFile { currentRelationshipId: number; @@ -20,7 +21,7 @@ export class Media { "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`, ); - return new Image(mediaData); + return new Image(new ImageParagraph(mediaData)); } public static addImageFromBuffer(file: File, buffer: Buffer, width?: number, height?: number): Image { @@ -39,7 +40,7 @@ export class Media { `media/${mediaData.fileName}`, ); - return new Image(mediaData); + return new Image(new ImageParagraph(mediaData)); } private static generateId(): string { diff --git a/src/file/paragraph/image.ts b/src/file/paragraph/image.ts index 214378853c..634f76e517 100644 --- a/src/file/paragraph/image.ts +++ b/src/file/paragraph/image.ts @@ -3,7 +3,7 @@ import { IMediaData } from "../media"; import { Paragraph } from "./paragraph"; import { PictureRun } from "./run"; -export class Image extends Paragraph { +export class ImageParagraph extends Paragraph { private readonly pictureRun: PictureRun; constructor(imageData: IMediaData, drawingOptions?: IDrawingOptions) { @@ -15,4 +15,8 @@ export class Image extends Paragraph { public scale(factorX: number, factorY?: number): void { this.pictureRun.scale(factorX, factorY); } + + public get Run(): PictureRun { + return this.pictureRun; + } } diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index 22e64fc643..a896044c8e 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -1,6 +1,6 @@ // http://officeopenxml.com/WPparagraph.php import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; -import { IMediaData } from "file/media"; +import { Image } from "file/media"; import { Num } from "file/numbering/num"; import { XmlComponent } from "file/xml-components"; @@ -54,9 +54,10 @@ export class Paragraph extends XmlComponent { return run; } - public createPictureRun(imageData: IMediaData): PictureRun { - const run = new PictureRun(imageData); + public addImage(image: Image): PictureRun { + const run = image.Run; this.addRun(run); + return run; } From bb8c29f4a2bb5a755c61f30aaa2ae31608cf55e7 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 02:53:28 +0100 Subject: [PATCH 14/19] Fix tests --- src/file/paragraph/image.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/file/paragraph/image.spec.ts b/src/file/paragraph/image.spec.ts index 658a99ff81..909a1ca3c3 100644 --- a/src/file/paragraph/image.spec.ts +++ b/src/file/paragraph/image.spec.ts @@ -2,7 +2,7 @@ import { assert, expect } from "chai"; import { Formatter } from "../../export/formatter"; -import { Image } from "./image"; +import { ImageParagraph } from "./image"; describe("Image", () => { let image: Image; From d961721b337cacd6c7f1486936e55fc278caee87 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 02:56:23 +0100 Subject: [PATCH 15/19] Refactor name --- src/file/paragraph/image.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/file/paragraph/image.spec.ts b/src/file/paragraph/image.spec.ts index 909a1ca3c3..45c06b0628 100644 --- a/src/file/paragraph/image.spec.ts +++ b/src/file/paragraph/image.spec.ts @@ -5,10 +5,10 @@ import { Formatter } from "../../export/formatter"; import { ImageParagraph } from "./image"; describe("Image", () => { - let image: Image; + let image: ImageParagraph; beforeEach(() => { - image = new Image({ + image = new ImageParagraph({ referenceId: 0, stream: new Buffer(""), path: "", From f264e4d0f7e053f56a890ba4c611194e4d2b82bd Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 21:58:50 +0100 Subject: [PATCH 16/19] Add scale method to image --- src/file/media/image.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/file/media/image.ts b/src/file/media/image.ts index 8255fe7398..b596f77d9d 100644 --- a/src/file/media/image.ts +++ b/src/file/media/image.ts @@ -10,4 +10,8 @@ export class Image { public get Run(): PictureRun { return this.paragraph.Run; } + + public scale(factorX: number, factorY?: number): void { + this.paragraph.Run.scale(factorX, factorY); + } } From 89df3c48e00f664369321606bb7907b7741c0161 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 23:22:03 +0100 Subject: [PATCH 17/19] Fix linting errors --- src/file/document/body/body.ts | 3 +- .../page-border/page-borders.spec.ts | 2 +- .../page-border/page-borders.ts | 42 ++++++++++++------- .../section-properties/section-properties.ts | 7 +--- src/file/file.ts | 3 +- src/file/media/media.ts | 10 ++--- src/file/numbering/level.ts | 2 +- src/file/styles/external-styles-factory.ts | 4 +- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/file/document/body/body.ts b/src/file/document/body/body.ts index 7fc0e98f38..e274fa359f 100644 --- a/src/file/document/body/body.ts +++ b/src/file/document/body/body.ts @@ -1,7 +1,6 @@ import { IXmlableObject, XmlComponent } from "file/xml-components"; -import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties"; import { Paragraph, ParagraphProperties } from "../.."; -import { SectionProperties, SectionPropertiesOptions } from "./section-properties"; +import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties"; export class Body extends XmlComponent { private readonly defaultSection: SectionProperties; diff --git a/src/file/document/body/section-properties/page-border/page-borders.spec.ts b/src/file/document/body/section-properties/page-border/page-borders.spec.ts index 782280f292..66abb9cc66 100644 --- a/src/file/document/body/section-properties/page-border/page-borders.spec.ts +++ b/src/file/document/body/section-properties/page-border/page-borders.spec.ts @@ -1,8 +1,8 @@ import { expect } from "chai"; import { Formatter } from "../../../../../export/formatter"; -import { PageBorders, PageBorderDisplay, PageBorderZOrder } from "./page-borders"; import { BorderStyle } from "../../../../styles"; +import { PageBorderDisplay, PageBorders, PageBorderZOrder } from "./page-borders"; describe("PageBorders", () => { describe("#constructor()", () => { diff --git a/src/file/document/body/section-properties/page-border/page-borders.ts b/src/file/document/body/section-properties/page-border/page-borders.ts index 88b6ce98dd..0af96cfd41 100644 --- a/src/file/document/body/section-properties/page-border/page-borders.ts +++ b/src/file/document/body/section-properties/page-border/page-borders.ts @@ -1,5 +1,5 @@ // http://officeopenxml.com/WPsectionBorders.php -import { XmlComponent, XmlAttributeComponent, IXmlableObject } from "file/xml-components"; +import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { BorderStyle } from "../../../../styles"; export enum PageBorderDisplay { @@ -24,22 +24,22 @@ export interface IPageBorderAttributes { zOrder?: PageBorderZOrder; } -export interface PageBorderConfiguration { +export interface IPageBorderConfiguration { style?: BorderStyle; size?: number; color?: string; space?: number; } -export type PageBordersOptions = { +export interface IPageBordersOptions { pageBorders?: IPageBorderAttributes; - pageBorderTop?: PageBorderConfiguration; - pageBorderRight?: PageBorderConfiguration; - pageBorderBottom?: PageBorderConfiguration; - pageBorderLeft?: PageBorderConfiguration; -}; + pageBorderTop?: IPageBorderConfiguration; + pageBorderRight?: IPageBorderConfiguration; + pageBorderBottom?: IPageBorderConfiguration; + pageBorderLeft?: IPageBorderConfiguration; +} -class PageBordeAttributes extends XmlAttributeComponent { +class PageBordeAttributes extends XmlAttributeComponent { protected xmlKeys = { style: "w:val", size: "w:size", @@ -49,7 +49,7 @@ class PageBordeAttributes extends XmlAttributeComponent } class PageBorder extends XmlComponent { - constructor(key: string, options: PageBorderConfiguration) { + constructor(key: string, options: IPageBorderConfiguration) { super(key); this.root.push(new PageBordeAttributes(options)); @@ -65,10 +65,12 @@ class PageBordersAttributes extends XmlAttributeComponent } export class PageBorders extends XmlComponent { - constructor(options?: PageBordersOptions) { + constructor(options?: IPageBordersOptions) { super("w:pgBorders"); - if (!options) return; + if (!options) { + return; + } let pageBordersAttributes = {}; @@ -82,10 +84,18 @@ export class PageBorders extends XmlComponent { this.root.push(new PageBordersAttributes(pageBordersAttributes)); - if (options.pageBorderTop) this.root.push(new PageBorder("w:top", options.pageBorderTop)); - if (options.pageBorderRight) this.root.push(new PageBorder("w:right", options.pageBorderRight)); - if (options.pageBorderBottom) this.root.push(new PageBorder("w:bottom", options.pageBorderBottom)); - if (options.pageBorderLeft) this.root.push(new PageBorder("w:left", options.pageBorderLeft)); + if (options.pageBorderTop) { + this.root.push(new PageBorder("w:top", options.pageBorderTop)); + } + if (options.pageBorderRight) { + this.root.push(new PageBorder("w:right", options.pageBorderRight)); + } + if (options.pageBorderBottom) { + this.root.push(new PageBorder("w:bottom", options.pageBorderBottom)); + } + if (options.pageBorderLeft) { + this.root.push(new PageBorder("w:left", options.pageBorderLeft)); + } } public prepForXml(): IXmlableObject { diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 33d0a7a0ae..c23964cd14 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -1,6 +1,6 @@ // http://officeopenxml.com/WPsection.php import { XmlComponent } from "file/xml-components"; -import { FooterReferenceType, IPageNumberTypeAttributes, PageNumberFormat, PageNumberType } from "./"; +import { FooterReferenceType, IPageBordersOptions, IPageNumberTypeAttributes, PageBorders, PageNumberFormat, PageNumberType } from "./"; import { Columns } from "./columns/columns"; import { IColumnsAttributes } from "./columns/columns-attributes"; import { DocumentGrid } from "./doc-grid/doc-grid"; @@ -12,9 +12,6 @@ import { PageMargin } from "./page-margin/page-margin"; import { IPageMarginAttributes } from "./page-margin/page-margin-attributes"; import { PageSize } from "./page-size/page-size"; import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes"; -import { FooterReferenceType, IPageNumberTypeAttributes, PageNumberType, PageNumberFormat } from "."; -// import { TitlePage } from "./title-page/title-page"; -import { FooterReferenceType, IPageNumberTypeAttributes, PageNumberType, PageNumberFormat, PageBordersOptions, PageBorders } from "."; export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & @@ -23,7 +20,7 @@ export type SectionPropertiesOptions = IPageSizeAttributes & IHeaderOptions & IFooterOptions & IPageNumberTypeAttributes & - PageBordersOptions; + IPageBordersOptions; export class SectionProperties extends XmlComponent { private readonly options: SectionPropertiesOptions; diff --git a/src/file/file.ts b/src/file/file.ts index 83d0c8c53b..2482d9b39c 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -2,7 +2,7 @@ import { AppProperties } from "./app-properties/app-properties"; import { ContentTypes } from "./content-types/content-types"; import { CoreProperties, IPropertiesOptions } from "./core-properties"; import { Document } from "./document"; -import { FooterReferenceType, HeaderReference, HeaderReferenceType } from "./document/body/section-properties"; +import { FooterReferenceType, HeaderReference, HeaderReferenceType, SectionPropertiesOptions } from "./document/body/section-properties"; import { FooterWrapper } from "./footer-wrapper"; import { FootNotes } from "./footnotes"; import { HeaderWrapper } from "./header-wrapper"; @@ -14,7 +14,6 @@ import { Styles } from "./styles"; import { ExternalStylesFactory } from "./styles/external-styles-factory"; import { DefaultStylesFactory } from "./styles/factory"; import { Table } from "./table"; -import { FooterReferenceType, HeaderReferenceType, SectionPropertiesOptions } from "./document/body/section-properties"; export class File { private readonly document: Document; diff --git a/src/file/media/media.ts b/src/file/media/media.ts index e8e6044569..aea65777f0 100644 --- a/src/file/media/media.ts +++ b/src/file/media/media.ts @@ -61,8 +61,6 @@ export class Media { this.map = new Map(); } - x: Math.round(dimensions.width * 9525), - y: Math.round(dimensions.height * 9525), public getMedia(key: string): IMediaData { const data = this.map.get(key); @@ -108,12 +106,12 @@ export class Media { fileName: key, dimensions: { pixels: { - x: dimensions.width, - y: dimensions.height, + x: Math.round(dimensions.width), + y: Math.round(dimensions.height), }, emus: { - x: dimensions.width * 9525, - y: dimensions.height * 9525, + x: Math.round(dimensions.width * 9525), + y: Math.round(dimensions.height * 9525), }, }, }; diff --git a/src/file/numbering/level.ts b/src/file/numbering/level.ts index 0df90758fb..8bdc7ff8d7 100644 --- a/src/file/numbering/level.ts +++ b/src/file/numbering/level.ts @@ -110,7 +110,7 @@ export class LevelBase extends XmlComponent { this.root.push(this.runProperties); } - public setSuffix(value: LevelSuffix) { + public setSuffix(value: LevelSuffix): LevelBase { this.root.push(new Suffix(value)); return this; } diff --git a/src/file/styles/external-styles-factory.ts b/src/file/styles/external-styles-factory.ts index 303d563907..301211bdc7 100644 --- a/src/file/styles/external-styles-factory.ts +++ b/src/file/styles/external-styles-factory.ts @@ -1,7 +1,5 @@ import * as fastXmlParser from "fast-xml-parser"; -import { ImportedXmlComponent, ImportedRootElementAttributes, parseOptions, convertToXmlComponent } from "./../../file/xml-components"; -import { convertToXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent, parseOptions } from "file/xml-components"; -import { ImportedRootElementAttributes, parseOptions, convertToXmlComponent } from "./../../file/xml-components"; +import { convertToXmlComponent, ImportedRootElementAttributes, parseOptions } from "file/xml-components"; import { Styles } from "./"; export class ExternalStylesFactory { From 5f594a822fc2b4a89e2c82c5ca255f9ac05eefa7 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 23:29:40 +0100 Subject: [PATCH 18/19] Fix and enable linting on tests --- src/file/content-types/content-types.spec.ts | 3 +++ .../body/section-properties/section-properties.spec.ts | 2 +- src/file/drawing/floating/simple-pos.spec.ts | 2 +- src/file/styles/external-styles-factory.spec.ts | 5 ++++- src/file/table/table-cell.spec.ts | 2 +- src/file/xml-components/imported-xml-component.spec.ts | 6 ++++-- tsconfig.json | 1 - 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/file/content-types/content-types.spec.ts b/src/file/content-types/content-types.spec.ts index 14665df4ee..7e9b62c88f 100644 --- a/src/file/content-types/content-types.spec.ts +++ b/src/file/content-types/content-types.spec.ts @@ -1,6 +1,9 @@ +// tslint:disable:no-string-literal + import { expect } from "chai"; import { Formatter } from "../../export/formatter"; import { ContentTypes } from "./content-types"; + describe("ContentTypes", () => { let contentTypes: ContentTypes; diff --git a/src/file/document/body/section-properties/section-properties.spec.ts b/src/file/document/body/section-properties/section-properties.spec.ts index b2499bbd63..e80facb635 100644 --- a/src/file/document/body/section-properties/section-properties.spec.ts +++ b/src/file/document/body/section-properties/section-properties.spec.ts @@ -1,8 +1,8 @@ import { expect } from "chai"; import { Formatter } from "../../../../export/formatter"; +import { FooterReferenceType, PageBorderOffsetFrom, PageNumberFormat } from "./"; import { SectionProperties } from "./section-properties"; -import { FooterReferenceType, PageNumberFormat, PageBorderOffsetFrom } from "."; describe("SectionProperties", () => { describe("#constructor()", () => { diff --git a/src/file/drawing/floating/simple-pos.spec.ts b/src/file/drawing/floating/simple-pos.spec.ts index a86739b7b0..5eee49f4c1 100644 --- a/src/file/drawing/floating/simple-pos.spec.ts +++ b/src/file/drawing/floating/simple-pos.spec.ts @@ -1,7 +1,7 @@ import { assert } from "chai"; -import { SimplePos } from "./simple-pos"; import { Utility } from "../../../tests/utility"; +import { SimplePos } from "./simple-pos"; describe("SimplePos", () => { describe("#constructor()", () => { diff --git a/src/file/styles/external-styles-factory.spec.ts b/src/file/styles/external-styles-factory.spec.ts index e34bfbaa8d..295c9644f6 100644 --- a/src/file/styles/external-styles-factory.spec.ts +++ b/src/file/styles/external-styles-factory.spec.ts @@ -22,7 +22,7 @@ describe("External styles factory", () => { - + @@ -48,6 +48,7 @@ describe("External styles factory", () => { describe("#parse", () => { it("should parse w:styles attributes", () => { + // tslint:disable-next-line:no-any const importedStyle = new ExternalStylesFactory().newInstance(externalStyles) as any; expect(importedStyle.rootKey).to.equal("w:styles"); @@ -58,6 +59,7 @@ describe("External styles factory", () => { }); it("should parse other child elements of w:styles", () => { + // tslint:disable-next-line:no-any const importedStyle = new ExternalStylesFactory().newInstance(externalStyles) as any; expect(importedStyle.root.length).to.equal(5); @@ -134,6 +136,7 @@ describe("External styles factory", () => { }); it("should parse styles elements", () => { + // tslint:disable-next-line:no-any const importedStyle = new ExternalStylesFactory().newInstance(externalStyles) as any; expect(importedStyle.root.length).to.equal(5); diff --git a/src/file/table/table-cell.spec.ts b/src/file/table/table-cell.spec.ts index 4e69e958a8..7a3072f186 100644 --- a/src/file/table/table-cell.spec.ts +++ b/src/file/table/table-cell.spec.ts @@ -1,8 +1,8 @@ import { expect } from "chai"; -import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell"; import { Formatter } from "../../export/formatter"; import { BorderStyle } from "../styles"; +import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell"; describe("TableCellBorders", () => { describe("#prepForXml", () => { diff --git a/src/file/xml-components/imported-xml-component.spec.ts b/src/file/xml-components/imported-xml-component.spec.ts index e941d3f0ec..beed8cf09a 100644 --- a/src/file/xml-components/imported-xml-component.spec.ts +++ b/src/file/xml-components/imported-xml-component.spec.ts @@ -1,5 +1,5 @@ import { expect } from "chai"; -import { ImportedXmlComponent, convertToXmlComponent } from "./"; +import { convertToXmlComponent, ImportedXmlComponent } from "./"; const xmlString = ` @@ -11,10 +11,11 @@ const xmlString = ` Text 2 - + `; +// tslint:disable:object-literal-key-quotes const importedXmlElement = { "w:p": { _attr: { "w:one": "value 1", "w:two": "value 2" }, @@ -22,6 +23,7 @@ const importedXmlElement = { "w:r": [{ _attr: { active: "true" }, "w:t": "Text 1" }, { _attr: { active: "true" }, "w:t": "Text 2" }], }, }; +// tslint:enable:object-literal-key-quotes const convertedXmlElement = { deleted: false, diff --git a/tsconfig.json b/tsconfig.json index 4ef656d049..53730ebdfd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,6 @@ "exclude": [ "node_modules", "tests", - "**/*.spec.ts", "**/_*" ], "typedocOptions": { From ad356d27596c57d2d0e5a2b8d15c5430a96da3a8 Mon Sep 17 00:00:00 2001 From: Dolan Date: Thu, 9 Aug 2018 23:40:11 +0100 Subject: [PATCH 19/19] Add ignores so it doesnt get generated in documentation --- src/export/packer/packer.ts | 3 +++ src/file/media/data.ts | 3 +++ src/file/xml-components/xmlable-object.ts | 5 ++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/export/packer/packer.ts b/src/export/packer/packer.ts index 64fa05a9aa..848924f457 100644 --- a/src/export/packer/packer.ts +++ b/src/export/packer/packer.ts @@ -3,4 +3,7 @@ export interface IPacker { } // Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432 +/** + * @ignore + */ export const WORKAROUND = ""; diff --git a/src/file/media/data.ts b/src/file/media/data.ts index cbc7d8c5bf..dfc7a664a0 100644 --- a/src/file/media/data.ts +++ b/src/file/media/data.ts @@ -20,4 +20,7 @@ export interface IMediaData { } // Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432 +/** + * @ignore + */ export const WORKAROUND2 = ""; diff --git a/src/file/xml-components/xmlable-object.ts b/src/file/xml-components/xmlable-object.ts index 9fa0d5b600..255df14fc2 100644 --- a/src/file/xml-components/xmlable-object.ts +++ b/src/file/xml-components/xmlable-object.ts @@ -3,4 +3,7 @@ export interface IXmlableObject extends Object { } // Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432 -export const WORKAROUND3 = "workaround"; +/** + * @ignore + */ +export const WORKAROUND3 = "";