diff --git a/src/file/document/body/body.spec.ts b/src/file/document/body/body.spec.ts index bae759266c..a65f86b69e 100644 --- a/src/file/document/body/body.spec.ts +++ b/src/file/document/body/body.spec.ts @@ -3,6 +3,7 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; import { Body } from "./body"; +import { sectionMarginDefaults } from "./section-properties"; describe("Body", () => { let body: Body; @@ -32,13 +33,13 @@ describe("Body", () => { { "w:pgMar": { _attr: { - "w:top": 1440, - "w:right": 1440, - "w:bottom": 1440, - "w:left": 1440, - "w:header": 708, - "w:footer": 708, - "w:gutter": 0, + "w:top": sectionMarginDefaults.TOP, + "w:right": sectionMarginDefaults.RIGHT, + "w:bottom": sectionMarginDefaults.BOTTOM, + "w:left": sectionMarginDefaults.LEFT, + "w:header": sectionMarginDefaults.HEADER, + "w:footer": sectionMarginDefaults.FOOTER, + "w:gutter": sectionMarginDefaults.GUTTER, }, }, }, @@ -47,7 +48,7 @@ describe("Body", () => { _attr: {}, }, }, - { "w:cols": { _attr: { "w:space": 708, "w:sep": false, "w:num": 1 } } }, + // { "w:cols": { _attr: { "w:space": 708, "w:sep": false, "w:num": 1 } } }, { "w:docGrid": { _attr: { "w:linePitch": 360 } } }, ], }, diff --git a/src/file/document/body/section-properties/columns/columns-attributes.ts b/src/file/document/body/section-properties/columns/columns-attributes.ts deleted file mode 100644 index 40140bd63f..0000000000 --- a/src/file/document/body/section-properties/columns/columns-attributes.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export class ColumnsAttributes extends XmlAttributeComponent<{ - readonly space?: number; - readonly num?: number; - readonly separate?: boolean; -}> { - protected readonly xmlKeys = { - space: "w:space", - num: "w:num", - separate: "w:sep", - }; -} diff --git a/src/file/document/body/section-properties/columns/columns.ts b/src/file/document/body/section-properties/columns/columns.ts deleted file mode 100644 index c074f189d9..0000000000 --- a/src/file/document/body/section-properties/columns/columns.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { ColumnsAttributes } from "./columns-attributes"; - -export class Columns extends XmlComponent { - constructor(space: number, num: number, separate: boolean) { - super("w:cols"); - this.root.push( - new ColumnsAttributes({ - space: space, - num: num, - separate: separate, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/doc-grid/doc-grid-attributes.ts b/src/file/document/body/section-properties/doc-grid/doc-grid-attributes.ts deleted file mode 100644 index 3fb2a5030f..0000000000 --- a/src/file/document/body/section-properties/doc-grid/doc-grid-attributes.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export interface IDocGridAttributesProperties { - readonly linePitch?: number; -} - -export class DocGridAttributes extends XmlAttributeComponent { - protected readonly xmlKeys = { - linePitch: "w:linePitch", - }; -} diff --git a/src/file/document/body/section-properties/doc-grid/doc-grid.ts b/src/file/document/body/section-properties/doc-grid/doc-grid.ts deleted file mode 100644 index e4df527443..0000000000 --- a/src/file/document/body/section-properties/doc-grid/doc-grid.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { DocGridAttributes } from "./doc-grid-attributes"; - -export class DocumentGrid extends XmlComponent { - constructor(linePitch: number) { - super("w:docGrid"); - this.root.push( - new DocGridAttributes({ - linePitch: linePitch, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/footer-reference/footer-reference-attributes.ts b/src/file/document/body/section-properties/footer-reference/footer-reference-attributes.ts deleted file mode 100644 index 861cc86a11..0000000000 --- a/src/file/document/body/section-properties/footer-reference/footer-reference-attributes.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export enum FooterReferenceType { - DEFAULT = "default", - FIRST = "first", - EVEN = "even", -} - -export class FooterReferenceAttributes extends XmlAttributeComponent<{ - readonly type: string; - readonly id: string; -}> { - protected readonly xmlKeys = { - type: "w:type", - id: "r:id", - }; -} diff --git a/src/file/document/body/section-properties/footer-reference/footer-reference.spec.ts b/src/file/document/body/section-properties/footer-reference/footer-reference.spec.ts deleted file mode 100644 index 50570b4b77..0000000000 --- a/src/file/document/body/section-properties/footer-reference/footer-reference.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { expect } from "chai"; - -import { Formatter } from "export/formatter"; -import { FooterReference } from "./footer-reference"; -import { FooterReferenceType } from "./footer-reference-attributes"; - -describe("footerReference", () => { - it("should create", () => { - const footer = new FooterReference({ - footerType: FooterReferenceType.DEFAULT, - footerId: 1, - }); - - const tree = new Formatter().format(footer); - - expect(tree).to.deep.equal({ - "w:footerReference": { - _attr: { - "r:id": "rId1", - "w:type": "default", - }, - }, - }); - }); - - it("should create without a footer type", () => { - const footer = new FooterReference({ - footerId: 1, - }); - - const tree = new Formatter().format(footer); - - expect(tree).to.deep.equal({ - "w:footerReference": { - _attr: { - "r:id": "rId1", - "w:type": "default", - }, - }, - }); - }); -}); diff --git a/src/file/document/body/section-properties/footer-reference/footer-reference.ts b/src/file/document/body/section-properties/footer-reference/footer-reference.ts deleted file mode 100644 index d23e99aba1..0000000000 --- a/src/file/document/body/section-properties/footer-reference/footer-reference.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { FooterReferenceAttributes, FooterReferenceType } from "./footer-reference-attributes"; - -export interface IFooterOptions { - readonly footerType?: FooterReferenceType; - readonly footerId?: number; -} - -export class FooterReference extends XmlComponent { - constructor(options: IFooterOptions) { - super("w:footerReference"); - - this.root.push( - new FooterReferenceAttributes({ - type: options.footerType || FooterReferenceType.DEFAULT, - id: `rId${options.footerId}`, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/footer-reference/index.ts b/src/file/document/body/section-properties/footer-reference/index.ts deleted file mode 100644 index 9673319fba..0000000000 --- a/src/file/document/body/section-properties/footer-reference/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./footer-reference"; -export * from "./footer-reference-attributes"; diff --git a/src/file/document/body/section-properties/header-reference/header-reference-attributes.ts b/src/file/document/body/section-properties/header-reference/header-reference-attributes.ts deleted file mode 100644 index b46c993999..0000000000 --- a/src/file/document/body/section-properties/header-reference/header-reference-attributes.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export enum HeaderReferenceType { - DEFAULT = "default", - FIRST = "first", - EVEN = "even", -} - -export class HeaderReferenceAttributes extends XmlAttributeComponent<{ - readonly type: string; - readonly id: string; -}> { - protected readonly xmlKeys = { - type: "w:type", - id: "r:id", - }; -} diff --git a/src/file/document/body/section-properties/header-reference/header-reference.spec.ts b/src/file/document/body/section-properties/header-reference/header-reference.spec.ts deleted file mode 100644 index 2d6b39e553..0000000000 --- a/src/file/document/body/section-properties/header-reference/header-reference.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { expect } from "chai"; - -import { Formatter } from "export/formatter"; -import { HeaderReference } from "./header-reference"; -import { HeaderReferenceType } from "./header-reference-attributes"; - -describe("HeaderReference", () => { - it("should create", () => { - const footer = new HeaderReference({ - headerType: HeaderReferenceType.DEFAULT, - headerId: 1, - }); - - const tree = new Formatter().format(footer); - - expect(tree).to.deep.equal({ - "w:headerReference": { - _attr: { - "r:id": "rId1", - "w:type": "default", - }, - }, - }); - }); - - it("should create without a header type", () => { - const footer = new HeaderReference({ - headerId: 1, - }); - - const tree = new Formatter().format(footer); - - expect(tree).to.deep.equal({ - "w:headerReference": { - _attr: { - "r:id": "rId1", - "w:type": "default", - }, - }, - }); - }); -}); diff --git a/src/file/document/body/section-properties/header-reference/header-reference.ts b/src/file/document/body/section-properties/header-reference/header-reference.ts deleted file mode 100644 index b1bc4ef4f4..0000000000 --- a/src/file/document/body/section-properties/header-reference/header-reference.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { HeaderReferenceAttributes, HeaderReferenceType } from "./header-reference-attributes"; - -export interface IHeaderReferenceOptions { - readonly headerType?: HeaderReferenceType; - readonly headerId?: number; -} - -export class HeaderReference extends XmlComponent { - constructor(options: IHeaderReferenceOptions) { - super("w:headerReference"); - this.root.push( - new HeaderReferenceAttributes({ - type: options.headerType || HeaderReferenceType.DEFAULT, - id: `rId${options.headerId}`, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/header-reference/index.ts b/src/file/document/body/section-properties/header-reference/index.ts deleted file mode 100644 index 80239ad98e..0000000000 --- a/src/file/document/body/section-properties/header-reference/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./header-reference"; -export * from "./header-reference-attributes"; diff --git a/src/file/document/body/section-properties/index.ts b/src/file/document/body/section-properties/index.ts index 337bb3b461..bb4ce998e3 100644 --- a/src/file/document/body/section-properties/index.ts +++ b/src/file/document/body/section-properties/index.ts @@ -1,8 +1,2 @@ export * from "./section-properties"; -export * from "./footer-reference"; -export * from "./header-reference"; -export * from "./page-size"; -export * from "./page-number"; -export * from "./page-border"; -export * from "./line-number"; -export * from "./type"; +export * from "./properties"; diff --git a/src/file/document/body/section-properties/line-number/index.ts b/src/file/document/body/section-properties/line-number/index.ts deleted file mode 100644 index 5808fe7f7b..0000000000 --- a/src/file/document/body/section-properties/line-number/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./line-number"; diff --git a/src/file/document/body/section-properties/line-number/line-number.ts b/src/file/document/body/section-properties/line-number/line-number.ts deleted file mode 100644 index 1c053e2e27..0000000000 --- a/src/file/document/body/section-properties/line-number/line-number.ts +++ /dev/null @@ -1,31 +0,0 @@ -// http://officeopenxml.com/WPsectionLineNumbering.php -import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; - -export enum LineNumberRestartFormat { - CONTINUOUS = "continuous", - NEW_SECTION = "newSection", - NEW_PAGE = "newPage", -} - -export interface ILineNumberAttributes { - readonly countBy?: number; - readonly start?: number; - readonly restart?: LineNumberRestartFormat; - readonly distance?: number; -} - -export class LineNumberAttributes extends XmlAttributeComponent { - protected readonly xmlKeys = { - countBy: "w:countBy", - start: "w:start", - restart: "w:restart", - distance: "w:distance", - }; -} - -export class LineNumberType extends XmlComponent { - constructor(options: ILineNumberAttributes) { - super("w:lnNumType"); - this.root.push(new LineNumberAttributes(options)); - } -} diff --git a/src/file/document/body/section-properties/page-border/index.ts b/src/file/document/body/section-properties/page-border/index.ts deleted file mode 100644 index 53d8b8ce4b..0000000000 --- a/src/file/document/body/section-properties/page-border/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./page-borders"; diff --git a/src/file/document/body/section-properties/page-margin/page-margin-attributes.ts b/src/file/document/body/section-properties/page-margin/page-margin-attributes.ts deleted file mode 100644 index 7d7df6565c..0000000000 --- a/src/file/document/body/section-properties/page-margin/page-margin-attributes.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export interface IPageMarginAttributes { - readonly top?: number; - readonly right?: number; - readonly bottom?: number; - readonly left?: number; - readonly header?: number; - readonly footer?: number; - readonly gutter?: number; -} - -export class PageMarginAttributes extends XmlAttributeComponent { - protected readonly xmlKeys = { - top: "w:top", - right: "w:right", - bottom: "w:bottom", - left: "w:left", - header: "w:header", - footer: "w:footer", - gutter: "w:gutter", - }; -} diff --git a/src/file/document/body/section-properties/page-margin/page-margin.ts b/src/file/document/body/section-properties/page-margin/page-margin.ts deleted file mode 100644 index bd9a8e5fa6..0000000000 --- a/src/file/document/body/section-properties/page-margin/page-margin.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { PageMarginAttributes } from "./page-margin-attributes"; - -export class PageMargin extends XmlComponent { - constructor(top: number, right: number, bottom: number, left: number, header: number, footer: number, gutter: number) { - super("w:pgMar"); - this.root.push( - new PageMarginAttributes({ - top: top, - right: right, - bottom: bottom, - left: left, - header: header, - footer: footer, - gutter: gutter, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/page-number/index.ts b/src/file/document/body/section-properties/page-number/index.ts deleted file mode 100644 index 57e81d8724..0000000000 --- a/src/file/document/body/section-properties/page-number/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./page-number"; diff --git a/src/file/document/body/section-properties/page-number/page-number.ts b/src/file/document/body/section-properties/page-number/page-number.ts deleted file mode 100644 index e454afecea..0000000000 --- a/src/file/document/body/section-properties/page-number/page-number.ts +++ /dev/null @@ -1,47 +0,0 @@ -// http://officeopenxml.com/WPSectionPgNumType.php -import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; - -export enum PageNumberFormat { - CARDINAL_TEXT = "cardinalText", - DECIMAL = "decimal", - DECIMAL_ENCLOSED_CIRCLE = "decimalEnclosedCircle", - DECIMAL_ENCLOSED_FULL_STOP = "decimalEnclosedFullstop", - DECIMAL_ENCLOSED_PAREN = "decimalEnclosedParen", - DECIMAL_ZERO = "decimalZero", - LOWER_LETTER = "lowerLetter", - LOWER_ROMAN = "lowerRoman", - NONE = "none", - ORDINAL_TEXT = "ordinalText", - UPPER_LETTER = "upperLetter", - UPPER_ROMAN = "upperRoman", - DECIMAL_FULL_WIDTH = "decimalFullWidth", -} - -export enum PageNumberSeparator { - COLON = "colon", - EM_DASH = "emDash", - EN_DASH = "endash", - HYPHEN = "hyphen", - PERIOD = "period", -} - -export interface IPageNumberTypeAttributes { - readonly start?: number; - readonly formatType?: PageNumberFormat; - readonly separator?: PageNumberSeparator; -} - -export class PageNumberTypeAttributes extends XmlAttributeComponent { - protected readonly xmlKeys = { - start: "w:start", - formatType: "w:fmt", - separator: "w:chapSep", - }; -} - -export class PageNumberType extends XmlComponent { - constructor(options: IPageNumberTypeAttributes) { - super("w:pgNumType"); - this.root.push(new PageNumberTypeAttributes(options)); - } -} diff --git a/src/file/document/body/section-properties/page-size/index.ts b/src/file/document/body/section-properties/page-size/index.ts deleted file mode 100644 index 567f7c2d58..0000000000 --- a/src/file/document/body/section-properties/page-size/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./page-size"; -export * from "./page-size-attributes"; diff --git a/src/file/document/body/section-properties/page-size/page-size-attributes.ts b/src/file/document/body/section-properties/page-size/page-size-attributes.ts deleted file mode 100644 index 9406de635a..0000000000 --- a/src/file/document/body/section-properties/page-size/page-size-attributes.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export enum PageOrientation { - PORTRAIT = "portrait", - LANDSCAPE = "landscape", -} - -export interface IPageSizeAttributes { - readonly width?: number; - readonly height?: number; - readonly orientation?: PageOrientation; -} - -export class PageSizeAttributes extends XmlAttributeComponent { - protected readonly xmlKeys = { - width: "w:w", - height: "w:h", - orientation: "w:orient", - }; -} diff --git a/src/file/document/body/section-properties/page-size/page-size.ts b/src/file/document/body/section-properties/page-size/page-size.ts deleted file mode 100644 index 6aa400bea2..0000000000 --- a/src/file/document/body/section-properties/page-size/page-size.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { PageOrientation, PageSizeAttributes } from "./page-size-attributes"; - -export class PageSize extends XmlComponent { - constructor(width: number, height: number, orientation: PageOrientation) { - super("w:pgSz"); - - const flip = orientation === PageOrientation.LANDSCAPE; - - this.root.push( - new PageSizeAttributes({ - width: flip ? height : width, - height: flip ? width : height, - orientation: orientation, - }), - ); - } -} diff --git a/src/file/document/body/section-properties/properties/columns.ts b/src/file/document/body/section-properties/properties/columns.ts new file mode 100644 index 0000000000..395df4ecae --- /dev/null +++ b/src/file/document/body/section-properties/properties/columns.ts @@ -0,0 +1,41 @@ +import { decimalNumber, twipsMeasureValue } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +// +// +export interface IColumnsAttributes { + readonly space?: number | string; + readonly count?: number; + readonly separate?: boolean; + readonly equalWidth?: boolean; +} + +export class ColumnsAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + space: "w:space", + count: "w:num", + separate: "w:sep", + equalWidth: "w:equalWidth", + }; +} + +export class Columns extends XmlComponent { + constructor({ space, count, separate, equalWidth }: IColumnsAttributes) { + super("w:cols"); + this.root.push( + new ColumnsAttributes({ + space: space === undefined ? undefined : twipsMeasureValue(space), + count: count === undefined ? undefined : decimalNumber(count), + separate, + equalWidth, + }), + ); + } +} diff --git a/src/file/document/body/section-properties/properties/doc-grid.ts b/src/file/document/body/section-properties/properties/doc-grid.ts new file mode 100644 index 0000000000..c8048452b8 --- /dev/null +++ b/src/file/document/body/section-properties/properties/doc-grid.ts @@ -0,0 +1,38 @@ +import { decimalNumber } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// not implemented +// +// +// +// +// +// +// +// + +// +// +// +// +// +export interface IDocGridAttributesProperties { + readonly linePitch?: number; +} + +export class DocGridAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + linePitch: "w:linePitch", + }; +} + +export class DocumentGrid extends XmlComponent { + constructor(linePitch: number) { + super("w:docGrid"); + this.root.push( + new DocGridAttributes({ + linePitch: decimalNumber(linePitch), + }), + ); + } +} diff --git a/src/file/document/body/section-properties/properties/header-footer-reference.spec.ts b/src/file/document/body/section-properties/properties/header-footer-reference.spec.ts new file mode 100644 index 0000000000..adb0bc70b6 --- /dev/null +++ b/src/file/document/body/section-properties/properties/header-footer-reference.spec.ts @@ -0,0 +1,56 @@ +import { expect } from "chai"; + +import { Formatter } from "export/formatter"; +import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./header-footer-reference"; + +describe("HeaderFooterReference", () => { + it("#constructor (footer)", () => { + const footer = new HeaderFooterReference(HeaderFooterType.FOOTER, { + type: HeaderFooterReferenceType.DEFAULT, + id: 1, + }); + + const tree = new Formatter().format(footer); + expect(tree).to.deep.equal({ + "w:footerReference": { + _attr: { + "r:id": "rId1", + "w:type": "default", + }, + }, + }); + }); + + it("#constructor (header)", () => { + const header = new HeaderFooterReference(HeaderFooterType.HEADER, { + type: HeaderFooterReferenceType.DEFAULT, + id: 1, + }); + + const tree = new Formatter().format(header); + expect(tree).to.deep.equal({ + "w:headerReference": { + _attr: { + "r:id": "rId1", + "w:type": "default", + }, + }, + }); + }); + + it("should create without a type", () => { + const footer = new HeaderFooterReference(HeaderFooterType.FOOTER, { + id: 1, + }); + + const tree = new Formatter().format(footer); + expect(tree).to.deep.equal({ + "w:footerReference": { + _attr: { + "r:id": "rId1", + "w:type": "default", + }, + }, + }); + }); +}); diff --git a/src/file/document/body/section-properties/properties/header-footer-reference.ts b/src/file/document/body/section-properties/properties/header-footer-reference.ts new file mode 100644 index 0000000000..1966790da9 --- /dev/null +++ b/src/file/document/body/section-properties/properties/header-footer-reference.ts @@ -0,0 +1,65 @@ +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +export enum HeaderFooterReferenceType { + DEFAULT = "default", + FIRST = "first", + EVEN = "even", +} + +// +// +// +// +// +// +// + +// +// +// +// +// +// + +// +// +// + +export interface IHeaderFooterOptions { + readonly type?: HeaderFooterReferenceType; + readonly id?: number; +} + +class FooterReferenceAttributes extends XmlAttributeComponent<{ + readonly type: HeaderFooterReferenceType; + readonly id: string; +}> { + protected readonly xmlKeys = { + type: "w:type", + id: "r:id", + }; +} + +export enum HeaderFooterType { + HEADER = "w:headerReference", + FOOTER = "w:footerReference", +} +export class HeaderFooterReference extends XmlComponent { + constructor(type: HeaderFooterType, options: IHeaderFooterOptions) { + super(type); + + this.root.push( + new FooterReferenceAttributes({ + type: options.type || HeaderFooterReferenceType.DEFAULT, + id: `rId${options.id}`, + }), + ); + } +} diff --git a/src/file/document/body/section-properties/properties/index.ts b/src/file/document/body/section-properties/properties/index.ts new file mode 100644 index 0000000000..089a005744 --- /dev/null +++ b/src/file/document/body/section-properties/properties/index.ts @@ -0,0 +1,11 @@ +export * from "./columns"; +export * from "./doc-grid"; +// export * from "./header-reference"; +export * from "./page-size"; +export * from "./page-number"; +export * from "./page-borders"; +export * from "./page-margin"; +export * from "./page-borders"; +export * from "./line-number"; +export * from "./section-type"; +export * from "./header-footer-reference"; diff --git a/src/file/document/body/section-properties/properties/line-number.ts b/src/file/document/body/section-properties/properties/line-number.ts new file mode 100644 index 0000000000..0ab1218568 --- /dev/null +++ b/src/file/document/body/section-properties/properties/line-number.ts @@ -0,0 +1,53 @@ +// http://officeopenxml.com/WPsectionLineNumbering.php +import { decimalNumber, twipsMeasureValue } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +export enum LineNumberRestartFormat { + NEW_PAGE = "newPage", + NEW_SECTION = "newSection", + CONTINUOUS = "continuous", +} + +// +// +// +// +// +// + +export interface ILineNumberAttributes { + readonly countBy?: number; + readonly start?: number; + readonly restart?: LineNumberRestartFormat; + readonly distance?: number | string; +} + +export class LineNumberAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + countBy: "w:countBy", + start: "w:start", + restart: "w:restart", + distance: "w:distance", + }; +} + +export class LineNumberType extends XmlComponent { + constructor({ countBy, start, restart, distance }: ILineNumberAttributes) { + super("w:lnNumType"); + this.root.push( + new LineNumberAttributes({ + countBy: countBy === undefined ? undefined : decimalNumber(countBy), + start: start === undefined ? undefined : decimalNumber(start), + restart, + distance: distance === undefined ? undefined : twipsMeasureValue(distance), + }), + ); + } +} diff --git a/src/file/document/body/section-properties/page-border/page-borders.spec.ts b/src/file/document/body/section-properties/properties/page-borders.spec.ts similarity index 100% rename from src/file/document/body/section-properties/page-border/page-borders.spec.ts rename to src/file/document/body/section-properties/properties/page-borders.spec.ts index fef63e81b6..977bcbd1b7 100644 --- a/src/file/document/body/section-properties/page-border/page-borders.spec.ts +++ b/src/file/document/body/section-properties/properties/page-borders.spec.ts @@ -74,8 +74,8 @@ describe("PageBorders", () => { }, }); expect(tree["w:pgBorders"][2]).to.deep.equal({ - "w:right": { - _attr: { "w:color": "223344", "w:sz": 20, "w:val": "double" }, + "w:left": { + _attr: { "w:color": "889900", "w:sz": 40, "w:val": "dotted" }, }, }); expect(tree["w:pgBorders"][3]).to.deep.equal({ @@ -84,8 +84,8 @@ describe("PageBorders", () => { }, }); expect(tree["w:pgBorders"][4]).to.deep.equal({ - "w:left": { - _attr: { "w:color": "889900", "w:sz": 40, "w:val": "dotted" }, + "w:right": { + _attr: { "w:color": "223344", "w:sz": 20, "w:val": "double" }, }, }); }); diff --git a/src/file/document/body/section-properties/page-border/page-borders.ts b/src/file/document/body/section-properties/properties/page-borders.ts similarity index 63% rename from src/file/document/body/section-properties/page-border/page-borders.ts rename to src/file/document/body/section-properties/properties/page-borders.ts index feff190880..d3a8ecbb61 100644 --- a/src/file/document/body/section-properties/page-border/page-borders.ts +++ b/src/file/document/body/section-properties/properties/page-borders.ts @@ -2,17 +2,36 @@ import { BorderElement, IBorderOptions } from "file/border"; import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent } from "file/xml-components"; +// +// +// +// +// +// +// 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", @@ -40,6 +59,17 @@ class PageBordersAttributes extends XmlAttributeComponent }; } +// +// +// +// +// +// +// +// +// +// +// export class PageBorders extends IgnoreIfEmptyXmlComponent { constructor(options?: IPageBordersOptions) { super("w:pgBorders"); @@ -63,14 +93,14 @@ export class PageBorders extends IgnoreIfEmptyXmlComponent { if (options.pageBorderTop) { this.root.push(new BorderElement("w:top", options.pageBorderTop)); } - if (options.pageBorderRight) { - this.root.push(new BorderElement("w:right", options.pageBorderRight)); + if (options.pageBorderLeft) { + this.root.push(new BorderElement("w:left", options.pageBorderLeft)); } if (options.pageBorderBottom) { this.root.push(new BorderElement("w:bottom", options.pageBorderBottom)); } - if (options.pageBorderLeft) { - this.root.push(new BorderElement("w:left", options.pageBorderLeft)); + if (options.pageBorderRight) { + this.root.push(new BorderElement("w:right", options.pageBorderRight)); } } } diff --git a/src/file/document/body/section-properties/properties/page-margin.ts b/src/file/document/body/section-properties/properties/page-margin.ts new file mode 100644 index 0000000000..91df7db51a --- /dev/null +++ b/src/file/document/body/section-properties/properties/page-margin.ts @@ -0,0 +1,58 @@ +import { signedTwipsMeasureValue, twipsMeasureValue } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +// +// +export interface IPageMarginAttributes { + readonly top?: number | string; + readonly right?: number | string; + readonly bottom?: number | string; + readonly left?: number | string; + readonly header?: number | string; + readonly footer?: number | string; + readonly gutter?: number | string; +} + +export class PageMarginAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + top: "w:top", + right: "w:right", + bottom: "w:bottom", + left: "w:left", + header: "w:header", + footer: "w:footer", + gutter: "w:gutter", + }; +} + +export class PageMargin extends XmlComponent { + constructor( + top: number | string, + right: number | string, + bottom: number | string, + left: number | string, + header: number | string, + footer: number | string, + gutter: number | string, + ) { + super("w:pgMar"); + this.root.push( + new PageMarginAttributes({ + top: signedTwipsMeasureValue(top), + right: twipsMeasureValue(right), + bottom: signedTwipsMeasureValue(bottom), + left: twipsMeasureValue(left), + header: twipsMeasureValue(header), + footer: twipsMeasureValue(footer), + gutter: twipsMeasureValue(gutter), + }), + ); + } +} diff --git a/src/file/document/body/section-properties/properties/page-number.ts b/src/file/document/body/section-properties/properties/page-number.ts new file mode 100644 index 0000000000..0bca61ebba --- /dev/null +++ b/src/file/document/body/section-properties/properties/page-number.ts @@ -0,0 +1,54 @@ +// http://officeopenxml.com/WPSectionPgNumType.php +import { NumberFormat } from "file/shared/number-format"; +import { decimalNumber } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +// +// +export enum PageNumberSeparator { + HYPHEN = "hyphen", + PERIOD = "period", + COLON = "colon", + EM_DASH = "emDash", + EN_DASH = "endash", +} + +export interface IPageNumberTypeAttributes { + readonly start?: number; + readonly formatType?: NumberFormat; + readonly separator?: PageNumberSeparator; +} + +// +// +// +// +// +// + +export class PageNumberTypeAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + start: "w:start", + formatType: "w:fmt", + separator: "w:chapSep", + }; +} +export class PageNumberType extends XmlComponent { + constructor({ start, formatType, separator }: IPageNumberTypeAttributes) { + super("w:pgNumType"); + this.root.push( + new PageNumberTypeAttributes({ + start: start === undefined ? undefined : decimalNumber(start), + formatType, + separator, + }), + ); + } +} diff --git a/src/file/document/body/section-properties/page-size/page-size.spec.ts b/src/file/document/body/section-properties/properties/page-size.spec.ts similarity index 90% rename from src/file/document/body/section-properties/page-size/page-size.spec.ts rename to src/file/document/body/section-properties/properties/page-size.spec.ts index 0921006e1e..aa7ca8ae1d 100644 --- a/src/file/document/body/section-properties/page-size/page-size.spec.ts +++ b/src/file/document/body/section-properties/properties/page-size.spec.ts @@ -2,8 +2,7 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; -import { PageSize } from "./page-size"; -import { PageOrientation } from "./page-size-attributes"; +import { PageOrientation, PageSize } from "./page-size"; describe("PageSize", () => { describe("#constructor()", () => { diff --git a/src/file/document/body/section-properties/properties/page-size.ts b/src/file/document/body/section-properties/properties/page-size.ts new file mode 100644 index 0000000000..ff99c52201 --- /dev/null +++ b/src/file/document/body/section-properties/properties/page-size.ts @@ -0,0 +1,52 @@ +import { twipsMeasureValue } from "file/values"; +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +export enum PageOrientation { + PORTRAIT = "portrait", + LANDSCAPE = "landscape", +} + +// +// +// +// +// +// +export interface IPageSizeAttributes { + readonly width?: number | string; + readonly height?: number | string; + readonly orientation?: PageOrientation; +} + +export class PageSizeAttributes extends XmlAttributeComponent { + protected readonly xmlKeys = { + width: "w:w", + height: "w:h", + orientation: "w:orient", + }; +} + +export class PageSize extends XmlComponent { + constructor(width: number | string, height: number | string, orientation: PageOrientation) { + super("w:pgSz"); + + const flip = orientation === PageOrientation.LANDSCAPE; + + const widthTwips = twipsMeasureValue(width); + const heightTwips = twipsMeasureValue(height); + + this.root.push( + new PageSizeAttributes({ + width: flip ? heightTwips : widthTwips, + height: flip ? widthTwips : heightTwips, + orientation: orientation, + }), + ); + } +} diff --git a/src/file/document/body/section-properties/type/section-type.spec.ts b/src/file/document/body/section-properties/properties/section-type.spec.ts similarity index 89% rename from src/file/document/body/section-properties/type/section-type.spec.ts rename to src/file/document/body/section-properties/properties/section-type.spec.ts index 7276825fab..bbf08799f3 100644 --- a/src/file/document/body/section-properties/type/section-type.spec.ts +++ b/src/file/document/body/section-properties/properties/section-type.spec.ts @@ -1,8 +1,7 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; -import { Type } from "./section-type"; -import { SectionType } from "./section-type-attributes"; +import { SectionType, Type } from "./section-type"; describe("Type", () => { it("should create with even page section type", () => { diff --git a/src/file/document/body/section-properties/properties/section-type.ts b/src/file/document/body/section-properties/properties/section-type.ts new file mode 100644 index 0000000000..e09d3c6508 --- /dev/null +++ b/src/file/document/body/section-properties/properties/section-type.ts @@ -0,0 +1,37 @@ +// http://officeopenxml.com/WPsection.php +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; + +// +// +// +// +// +// +// +// +// +export enum SectionType { + NEXT_PAGE = "nextPage", + NEXT_COLUMN = "nextColumn", + CONTINUOUS = "continuous", + EVEN_PAGE = "evenPage", + ODD_PAGE = "oddPage", +} + +// +// +// +export class SectionTypeAttributes extends XmlAttributeComponent<{ + readonly val: SectionType; +}> { + protected readonly xmlKeys = { + val: "w:val", + }; +} + +export class Type extends XmlComponent { + constructor(value: SectionType) { + super("w:type"); + this.root.push(new SectionTypeAttributes({ val: value })); + } +} 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 e118d7c457..d0c7e7fc5a 100644 --- a/src/file/document/body/section-properties/section-properties.spec.ts +++ b/src/file/document/body/section-properties/section-properties.spec.ts @@ -5,13 +5,30 @@ import { Formatter } from "export/formatter"; import { FooterWrapper } from "file/footer-wrapper"; import { HeaderWrapper } from "file/header-wrapper"; import { Media } from "file/media"; +import { NumberFormat } from "file/shared/number-format"; import { VerticalAlign } from "file/vertical-align"; -import { LineNumberRestartFormat } from "./line-number"; -import { PageBorderOffsetFrom } from "./page-border"; -import { PageNumberFormat } from "./page-number"; -import { SectionProperties } from "./section-properties"; -import { SectionType } from "./type/section-type-attributes"; +import { PageOrientation } from "./properties"; +import { LineNumberRestartFormat } from "./properties/line-number"; +import { PageBorderOffsetFrom } from "./properties/page-borders"; +import { SectionType } from "./properties/section-type"; +import { sectionMarginDefaults, sectionPageSizeDefaults, SectionProperties } from "./section-properties"; + +const DEFAULT_MARGINS = { + "w:bottom": sectionMarginDefaults.BOTTOM, + "w:footer": sectionMarginDefaults.FOOTER, + "w:top": sectionMarginDefaults.TOP, + "w:right": sectionMarginDefaults.RIGHT, + "w:left": sectionMarginDefaults.LEFT, + "w:header": sectionMarginDefaults.HEADER, + "w:gutter": sectionMarginDefaults.GUTTER, +}; + +const PAGE_SIZE_DEFAULTS = { + "w:h": sectionPageSizeDefaults.HEIGHT, + "w:orient": sectionPageSizeDefaults.ORIENTATION, + "w:w": sectionPageSizeDefaults.WIDTH, +}; describe("SectionProperties", () => { describe("#constructor()", () => { @@ -21,26 +38,27 @@ describe("SectionProperties", () => { const properties = new SectionProperties({ page: { size: { - width: 11906, - height: 16838, + width: 1190, + height: 1680, + orientation: PageOrientation.PORTRAIT, }, margin: { - top: convertInchesToTwip(1), - right: convertInchesToTwip(1), - bottom: convertInchesToTwip(1), - left: convertInchesToTwip(1), - header: 708, - footer: 708, - gutter: 0, + top: "2in", + right: "2in", + bottom: "2in", + left: "2in", + header: 808, + footer: 808, + gutter: 10, }, pageNumbers: { start: 10, - formatType: PageNumberFormat.CARDINAL_TEXT, + formatType: NumberFormat.CARDINAL_TEXT, }, }, column: { - space: 708, - count: 1, + space: 208, + count: 2, separate: true, }, grid: { @@ -62,25 +80,25 @@ describe("SectionProperties", () => { expect(tree["w:sectPr"]).to.be.an.instanceof(Array); expect(tree["w:sectPr"][0]).to.deep.equal({ "w:headerReference": { _attr: { "r:id": "rId100", "w:type": "default" } } }); expect(tree["w:sectPr"][1]).to.deep.equal({ "w:footerReference": { _attr: { "r:id": "rId200", "w:type": "even" } } }); - expect(tree["w:sectPr"][2]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } }); + expect(tree["w:sectPr"][2]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 1680, "w:w": 1190, "w:orient": "portrait" } } }); expect(tree["w:sectPr"][3]).to.deep.equal({ "w:pgMar": { _attr: { - "w:bottom": 1440, - "w:footer": 708, - "w:top": 1440, - "w:right": 1440, - "w:left": 1440, - "w:header": 708, - "w:gutter": 0, + "w:bottom": "2in", + "w:footer": 808, + "w:top": "2in", + "w:right": "2in", + "w:left": "2in", + "w:header": 808, + "w:gutter": 10, }, }, }); expect(tree["w:sectPr"][4]).to.deep.equal({ "w:pgNumType": { _attr: { "w:fmt": "cardinalText", "w:start": 10 } } }); - expect(tree["w:sectPr"][5]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708, "w:sep": true, "w:num": 1 } } }); + expect(tree["w:sectPr"][5]).to.deep.equal({ "w:cols": { _attr: { "w:space": 208, "w:sep": true, "w:num": 2 } } }); expect(tree["w:sectPr"][6]).to.deep.equal({ "w:vAlign": { _attr: { "w:val": "top" } } }); - expect(tree["w:sectPr"][7]).to.deep.equal({ "w:titlePg": { _attr: { "w:val": "1" } } }); + expect(tree["w:sectPr"][7]).to.deep.equal({ "w:titlePg": {} }); expect(tree["w:sectPr"][8]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } }); }); @@ -89,22 +107,12 @@ describe("SectionProperties", () => { const tree = new Formatter().format(properties); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(tree["w:sectPr"]).to.be.an.instanceof(Array); - expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } }); + expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: PAGE_SIZE_DEFAULTS } }); expect(tree["w:sectPr"][1]).to.deep.equal({ - "w:pgMar": { - _attr: { - "w:bottom": 1440, - "w:footer": 708, - "w:top": 1440, - "w:right": 1440, - "w:left": 1440, - "w:header": 708, - "w:gutter": 0, - }, - }, + "w:pgMar": { _attr: DEFAULT_MARGINS }, }); - expect(tree["w:sectPr"][3]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708, "w:sep": false, "w:num": 1 } } }); - expect(tree["w:sectPr"][4]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } }); + // expect(tree["w:sectPr"][3]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708, "w:sep": false, "w:num": 1 } } }); + expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } }); }); it("should create section properties with changed options", () => { @@ -118,17 +126,12 @@ describe("SectionProperties", () => { const tree = new Formatter().format(properties); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(tree["w:sectPr"]).to.be.an.instanceof(Array); - expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } }); + expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: PAGE_SIZE_DEFAULTS } }); expect(tree["w:sectPr"][1]).to.deep.equal({ "w:pgMar": { _attr: { - "w:bottom": 1440, - "w:footer": 708, + ...DEFAULT_MARGINS, "w:top": 0, - "w:right": 1440, - "w:left": 1440, - "w:header": 708, - "w:gutter": 0, }, }, }); @@ -145,17 +148,12 @@ describe("SectionProperties", () => { const tree = new Formatter().format(properties); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(tree["w:sectPr"]).to.be.an.instanceof(Array); - expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } }); + expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: PAGE_SIZE_DEFAULTS } }); expect(tree["w:sectPr"][1]).to.deep.equal({ "w:pgMar": { _attr: { + ...DEFAULT_MARGINS, "w:bottom": 0, - "w:footer": 708, - "w:top": 1440, - "w:right": 1440, - "w:left": 1440, - "w:header": 708, - "w:gutter": 0, }, }, }); @@ -167,24 +165,25 @@ describe("SectionProperties", () => { size: { width: 0, height: 0, + orientation: PageOrientation.LANDSCAPE, }, }, }); const tree = new Formatter().format(properties); expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]); expect(tree["w:sectPr"]).to.be.an.instanceof(Array); - expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } } }); + expect(tree["w:sectPr"][0]).to.deep.equal({ + "w:pgSz": { + _attr: { + "w:h": 0, + "w:orient": PageOrientation.LANDSCAPE, + "w:w": 0, + }, + }, + }); expect(tree["w:sectPr"][1]).to.deep.equal({ "w:pgMar": { - _attr: { - "w:bottom": 1440, - "w:footer": 708, - "w:top": 1440, - "w:right": 1440, - "w:left": 1440, - "w:header": 708, - "w:gutter": 0, - }, + _attr: DEFAULT_MARGINS, }, }); }); @@ -211,7 +210,7 @@ describe("SectionProperties", () => { const properties = new SectionProperties({ page: { pageNumbers: { - formatType: PageNumberFormat.UPPER_ROMAN, + formatType: NumberFormat.UPPER_ROMAN, }, }, }); diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 96dcad467f..ba155a61c4 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -1,29 +1,21 @@ // http://officeopenxml.com/WPsection.php // tslint:disable: no-unnecessary-initializer -import { convertInchesToTwip } from "convenience-functions"; import { FooterWrapper } from "file/footer-wrapper"; import { HeaderWrapper } from "file/header-wrapper"; import { VerticalAlign, VerticalAlignElement } from "file/vertical-align"; -import { XmlComponent } from "file/xml-components"; +import { OnOffElement, XmlComponent } from "file/xml-components"; -import { Columns } from "./columns/columns"; -import { DocumentGrid } from "./doc-grid/doc-grid"; -import { IDocGridAttributesProperties } from "./doc-grid/doc-grid-attributes"; -import { FooterReferenceType } from "./footer-reference"; -import { FooterReference } from "./footer-reference/footer-reference"; -import { HeaderReferenceType } from "./header-reference"; -import { HeaderReference } from "./header-reference/header-reference"; -import { ILineNumberAttributes, LineNumberType } from "./line-number"; -import { IPageBordersOptions, PageBorders } from "./page-border"; -import { PageMargin } from "./page-margin/page-margin"; -import { IPageMarginAttributes } from "./page-margin/page-margin-attributes"; -import { IPageNumberTypeAttributes, PageNumberType } from "./page-number"; -import { PageSize } from "./page-size/page-size"; -import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes"; -import { TitlePage } from "./title-page/title-page"; -import { Type } from "./type/section-type"; -import { SectionType } from "./type/section-type-attributes"; +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 { 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 { SectionType, Type } from "./properties/section-type"; export interface IHeaderFooterGroup { readonly default?: T; @@ -44,11 +36,7 @@ export interface ISectionPropertiesOptions { readonly lineNumbers?: ILineNumberAttributes; readonly titlePage?: boolean; readonly verticalAlign?: VerticalAlign; - readonly column?: { - readonly space?: number; - readonly count?: number; - readonly separate?: boolean; - }; + readonly column?: IColumnsAttributes; readonly type?: SectionType; } @@ -84,18 +72,39 @@ export interface ISectionPropertiesOptions { // // // + +export const sectionMarginDefaults = { + TOP: "1in", + RIGHT: "1in", + BOTTOM: "1in", + LEFT: "1in", + HEADER: 708, + FOOTER: 708, + GUTTER: 0, +}; + +export const sectionPageSizeDefaults = { + WIDTH: 11906, + HEIGHT: 16838, + ORIENTATION: PageOrientation.PORTRAIT, +}; + export class SectionProperties extends XmlComponent { constructor({ page: { - size: { width = 11906, height = 16838, orientation = PageOrientation.PORTRAIT } = {}, + size: { + width = sectionPageSizeDefaults.WIDTH, + height = sectionPageSizeDefaults.HEIGHT, + orientation = sectionPageSizeDefaults.ORIENTATION, + } = {}, margin: { - top = convertInchesToTwip(1), - right = convertInchesToTwip(1), - bottom = convertInchesToTwip(1), - left = convertInchesToTwip(1), - header = 708, - footer = 708, - gutter = 0, + top = sectionMarginDefaults.TOP, + right = sectionMarginDefaults.RIGHT, + bottom = sectionMarginDefaults.BOTTOM, + left = sectionMarginDefaults.LEFT, + header = sectionMarginDefaults.HEADER, + footer = sectionMarginDefaults.FOOTER, + gutter = sectionMarginDefaults.GUTTER, } = {}, pageNumbers = {}, borders, @@ -104,15 +113,15 @@ export class SectionProperties extends XmlComponent { headerWrapperGroup = {}, footerWrapperGroup = {}, lineNumbers, - titlePage = false, + titlePage, verticalAlign, - column: { space = 708, count = 1, separate = false } = {}, + column, type, }: ISectionPropertiesOptions = {}) { super("w:sectPr"); - this.addHeaders(headerWrapperGroup); - this.addFooters(footerWrapperGroup); + this.addHeaderFooterGroup(HeaderFooterType.HEADER, headerWrapperGroup); + this.addHeaderFooterGroup(HeaderFooterType.FOOTER, footerWrapperGroup); if (type) { this.root.push(new Type(type)); @@ -131,72 +140,48 @@ export class SectionProperties extends XmlComponent { this.root.push(new PageNumberType(pageNumbers)); - this.root.push(new Columns(space, count, separate)); + if (column) { + this.root.push(new Columns(column)); + } if (verticalAlign) { this.root.push(new VerticalAlignElement(verticalAlign)); } - if (titlePage) { - this.root.push(new TitlePage()); + if (titlePage !== undefined) { + this.root.push(new OnOffElement("w:titlePg", titlePage)); } this.root.push(new DocumentGrid(linePitch)); } - private addHeaders(headers: IHeaderFooterGroup): void { - if (headers.default) { + private addHeaderFooterGroup( + type: HeaderFooterType, + group: IHeaderFooterGroup | IHeaderFooterGroup, + ): void { + if (group.default) { this.root.push( - new HeaderReference({ - headerType: HeaderReferenceType.DEFAULT, - headerId: headers.default.View.ReferenceId, + new HeaderFooterReference(type, { + type: HeaderFooterReferenceType.DEFAULT, + id: group.default.View.ReferenceId, }), ); } - if (headers.first) { + if (group.first) { this.root.push( - new HeaderReference({ - headerType: HeaderReferenceType.FIRST, - headerId: headers.first.View.ReferenceId, + new HeaderFooterReference(type, { + type: HeaderFooterReferenceType.FIRST, + id: group.first.View.ReferenceId, }), ); } - if (headers.even) { + if (group.even) { this.root.push( - new HeaderReference({ - headerType: HeaderReferenceType.EVEN, - headerId: headers.even.View.ReferenceId, - }), - ); - } - } - - private addFooters(footers: IHeaderFooterGroup): void { - if (footers.default) { - this.root.push( - new FooterReference({ - footerType: FooterReferenceType.DEFAULT, - footerId: footers.default.View.ReferenceId, - }), - ); - } - - if (footers.first) { - this.root.push( - new FooterReference({ - footerType: FooterReferenceType.FIRST, - footerId: footers.first.View.ReferenceId, - }), - ); - } - - if (footers.even) { - this.root.push( - new FooterReference({ - footerType: FooterReferenceType.EVEN, - footerId: footers.even.View.ReferenceId, + new HeaderFooterReference(type, { + type: HeaderFooterReferenceType.EVEN, + id: group.even.View.ReferenceId, }), ); } diff --git a/src/file/document/body/section-properties/title-page/title-page-attributes.ts b/src/file/document/body/section-properties/title-page/title-page-attributes.ts deleted file mode 100644 index 078b6ed47f..0000000000 --- a/src/file/document/body/section-properties/title-page/title-page-attributes.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export class TitlePageAttributes extends XmlAttributeComponent<{ - readonly value: string; -}> { - protected readonly xmlKeys = { - value: "w:val", - }; -} diff --git a/src/file/document/body/section-properties/title-page/title-page.spec.ts b/src/file/document/body/section-properties/title-page/title-page.spec.ts deleted file mode 100644 index e5eed2a429..0000000000 --- a/src/file/document/body/section-properties/title-page/title-page.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { expect } from "chai"; - -import { Formatter } from "export/formatter"; - -import { TitlePage } from "./title-page"; - -describe("PageSize", () => { - describe("#constructor()", () => { - it("should create title page property for different first page header", () => { - const properties = new TitlePage(); - const tree = new Formatter().format(properties); - - expect(Object.keys(tree)).to.deep.equal(["w:titlePg"]); - expect(tree["w:titlePg"]).to.deep.equal({ _attr: { "w:val": "1" } }); - }); - }); -}); diff --git a/src/file/document/body/section-properties/title-page/title-page.ts b/src/file/document/body/section-properties/title-page/title-page.ts deleted file mode 100644 index 5b11d77581..0000000000 --- a/src/file/document/body/section-properties/title-page/title-page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { XmlComponent } from "file/xml-components"; -import { TitlePageAttributes } from "./title-page-attributes"; - -export class TitlePage extends XmlComponent { - constructor() { - super("w:titlePg"); - this.root.push( - new TitlePageAttributes({ - value: "1", - }), - ); - } -} diff --git a/src/file/document/body/section-properties/type/index.ts b/src/file/document/body/section-properties/type/index.ts deleted file mode 100644 index fd7a8abd9c..0000000000 --- a/src/file/document/body/section-properties/type/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./section-type"; -export * from "./section-type-attributes"; diff --git a/src/file/document/body/section-properties/type/section-type-attributes.ts b/src/file/document/body/section-properties/type/section-type-attributes.ts deleted file mode 100644 index 4ac8dd60b4..0000000000 --- a/src/file/document/body/section-properties/type/section-type-attributes.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export enum SectionType { - CONTINUOUS = "continuous", - EVEN_PAGE = "evenPage", - NEXT_COLUMN = "nextColumn", - NEXT_PAGE = "nextPage", - ODD_PAGE = "oddPage", -} - -export class SectionTypeAttributes extends XmlAttributeComponent<{ - readonly val: SectionType; -}> { - protected readonly xmlKeys = { - val: "w:val", - }; -} diff --git a/src/file/document/body/section-properties/type/section-type.ts b/src/file/document/body/section-properties/type/section-type.ts deleted file mode 100644 index 3a11f2e041..0000000000 --- a/src/file/document/body/section-properties/type/section-type.ts +++ /dev/null @@ -1,10 +0,0 @@ -// http://officeopenxml.com/WPsection.php -import { XmlComponent } from "file/xml-components"; -import { SectionType, SectionTypeAttributes } from "./section-type-attributes"; - -export class Type extends XmlComponent { - constructor(value: SectionType) { - super("w:type"); - this.root.push(new SectionTypeAttributes({ val: value })); - } -} diff --git a/src/file/document/document-background/document-background.spec.ts b/src/file/document/document-background/document-background.spec.ts index 83d1fb36b1..c7d947473d 100644 --- a/src/file/document/document-background/document-background.spec.ts +++ b/src/file/document/document-background/document-background.spec.ts @@ -34,8 +34,8 @@ describe("DocumentBackground", () => { const documentBackground = new DocumentBackground({ color: "ffff00", themeColor: "test", - themeShade: "test", - themeTint: "test", + themeShade: "0A", + themeTint: "0B", }); const tree = new Formatter().format(documentBackground); expect(tree).to.deep.equal({ @@ -43,8 +43,8 @@ describe("DocumentBackground", () => { _attr: { "w:color": "ffff00", "w:themeColor": "test", - "w:themeShade": "test", - "w:themeTint": "test", + "w:themeShade": "0A", + "w:themeTint": "0B", }, }, }); diff --git a/src/file/document/document-background/document-background.ts b/src/file/document/document-background/document-background.ts index 44b04aabe6..bbda932882 100644 --- a/src/file/document/document-background/document-background.ts +++ b/src/file/document/document-background/document-background.ts @@ -1,7 +1,30 @@ // http://officeopenxml.com/WPdocument.php // http://www.datypic.com/sc/ooxml/e-w_background-1.html +import { hexColorValue, uCharHexNumber } from "file/values"; import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + export class DocumentBackgroundAttributes extends XmlAttributeComponent<{ readonly color: string; readonly themeColor?: string; @@ -23,16 +46,32 @@ export interface IDocumentBackgroundOptions { readonly themeTint?: string; } +// +// +// +// +// +// +// +// +// +// +// +// +// + export class DocumentBackground extends XmlComponent { constructor(options: IDocumentBackgroundOptions) { super("w:background"); this.root.push( new DocumentBackgroundAttributes({ - color: options.color ? options.color : "FFFFFF", + color: hexColorValue(options.color ? options.color : "FFFFFF"), themeColor: options.themeColor, - themeShade: options.themeShade, - themeTint: options.themeTint, + themeShade: options.themeShade === undefined ? undefined : uCharHexNumber(options.themeShade), + themeTint: options.themeTint === undefined ? undefined : uCharHexNumber(options.themeTint), }), ); } diff --git a/src/file/file.spec.ts b/src/file/file.spec.ts index a3cd9fbf65..81e2f461a2 100644 --- a/src/file/file.spec.ts +++ b/src/file/file.spec.ts @@ -1,11 +1,18 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; +import { sectionMarginDefaults, sectionPageSizeDefaults } from "./document"; import { File } from "./file"; import { Footer, Header } from "./header"; import { Paragraph } from "./paragraph"; +const PAGE_SIZE_DEFAULTS = { + "w:h": sectionPageSizeDefaults.HEIGHT, + "w:orient": sectionPageSizeDefaults.ORIENTATION, + "w:w": sectionPageSizeDefaults.WIDTH, +}; + describe("File", () => { describe("#constructor", () => { it("should create with correct headers and footers", () => { @@ -114,23 +121,19 @@ describe("File", () => { "w:sectPr": [ { "w:pgSz": { - _attr: { - "w:h": 16838, - "w:orient": "portrait", - "w:w": 11906, - }, + _attr: PAGE_SIZE_DEFAULTS, }, }, { "w:pgMar": { _attr: { - "w:bottom": 1440, - "w:footer": 708, - "w:gutter": 0, - "w:header": 708, - "w:left": 1440, - "w:right": 1440, - "w:top": 1440, + "w:bottom": sectionMarginDefaults.BOTTOM, + "w:footer": sectionMarginDefaults.FOOTER, + "w:gutter": sectionMarginDefaults.GUTTER, + "w:header": sectionMarginDefaults.HEADER, + "w:left": sectionMarginDefaults.LEFT, + "w:right": sectionMarginDefaults.RIGHT, + "w:top": sectionMarginDefaults.TOP, }, }, }, @@ -139,15 +142,15 @@ describe("File", () => { _attr: {}, }, }, - { - "w:cols": { - _attr: { - "w:num": 1, - "w:sep": false, - "w:space": 708, - }, - }, - }, + // { + // "w:cols": { + // _attr: { + // "w:num": 1, + // "w:sep": false, + // "w:space": 708, + // }, + // }, + // }, { "w:docGrid": { _attr: { diff --git a/src/file/file.ts b/src/file/file.ts index 66d4d84b51..38230bdeb1 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -3,7 +3,7 @@ import { ContentTypes } from "./content-types/content-types"; import { CoreProperties, IPropertiesOptions } from "./core-properties"; import { CustomProperties } from "./custom-properties"; import { DocumentWrapper } from "./document-wrapper"; -import { FooterReferenceType, HeaderReferenceType, ISectionPropertiesOptions } from "./document/body/section-properties"; +import { HeaderFooterReferenceType, ISectionPropertiesOptions } from "./document/body/section-properties"; import { IFileProperties } from "./file-properties"; import { FooterWrapper, IDocumentFooter } from "./footer-wrapper"; import { FootnotesWrapper } from "./footnotes-wrapper"; @@ -188,7 +188,7 @@ export class File { return wrapper; } - private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT): void { + private addHeaderToDocument(header: HeaderWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void { this.headers.push({ header, type }); this.documentWrapper.Relationships.createRelationship( header.View.ReferenceId, @@ -198,7 +198,7 @@ export class File { this.contentTypes.addHeader(this.headers.length); } - private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT): void { + private addFooterToDocument(footer: FooterWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void { this.footers.push({ footer, type }); this.documentWrapper.Relationships.createRelationship( footer.View.ReferenceId, diff --git a/src/file/footer-wrapper.ts b/src/file/footer-wrapper.ts index e16a72e974..34162320c0 100644 --- a/src/file/footer-wrapper.ts +++ b/src/file/footer-wrapper.ts @@ -1,6 +1,6 @@ import { XmlComponent } from "file/xml-components"; -import { FooterReferenceType } from "./document"; +import { HeaderFooterReferenceType } from "./document"; import { IViewWrapper } from "./document-wrapper"; import { Footer } from "./footer/footer"; import { Media } from "./media"; @@ -10,7 +10,7 @@ import { Table } from "./table"; export interface IDocumentFooter { readonly footer: FooterWrapper; - readonly type: FooterReferenceType; + readonly type: HeaderFooterReferenceType; } export class FooterWrapper implements IViewWrapper { diff --git a/src/file/header-wrapper.ts b/src/file/header-wrapper.ts index 945a9d674a..40fbd7bb1a 100644 --- a/src/file/header-wrapper.ts +++ b/src/file/header-wrapper.ts @@ -1,6 +1,6 @@ import { XmlComponent } from "file/xml-components"; -import { HeaderReferenceType } from "./document"; +import { HeaderFooterReferenceType } from "./document"; import { IViewWrapper } from "./document-wrapper"; import { Header } from "./header/header"; import { Media } from "./media"; @@ -10,7 +10,7 @@ import { Table } from "./table"; export interface IDocumentHeader { readonly header: HeaderWrapper; - readonly type: HeaderReferenceType; + readonly type: HeaderFooterReferenceType; } export class HeaderWrapper implements IViewWrapper { diff --git a/src/file/shared/number-format.ts b/src/file/shared/number-format.ts new file mode 100644 index 0000000000..8ee5ad10fc --- /dev/null +++ b/src/file/shared/number-format.ts @@ -0,0 +1,133 @@ +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// + +export enum NumberFormat { + DECIMAL = "decimal", + UPPER_ROMAN = "upperRoman", + LOWER_ROMAN = "lowerRoman", + UPPER_LETTER = "upperLetter", + LOWER_LETTER = "lowerLetter", + ORDINAL = "ordinal", + CARDINAL_TEXT = "cardinalText", + ORDINAL_TEXT = "ordinalText", + HEX = "hex", + CHICAGO = "chicago", + IDEOGRAPH_DIGITAL = "ideographDigital", + JAPANESE_COUNTING = "japaneseCounting", + AIUEO = "aiueo", + IROHA = "iroha", + DECIMAL_FULL_WIDTH = "decimalFullWidth", + DECIMAL_HALF_WIDTH = "decimalHalfWidth", + JAPANESE_LEGAL = "japaneseLegal", + JAPANESE_DIGITAL_TEN_THOUSAND = "japaneseDigitalTenThousand", + DECIMAL_ENCLOSED_CIRCLE = "decimalEnclosedCircle", + DECIMAL_FULL_WIDTH_2 = "decimalFullWidth2", + AIUEO_FULL_WIDTH = "aiueoFullWidth", + IROHA_FULL_WIDTH = "irohaFullWidth", + DECIMAL_ZERO = "decimalZero", + BULLET = "bullet", + GANADA = "ganada", + CHOSUNG = "chosung", + DECIMAL_ENCLOSED_FULL_STOP = "decimalEnclosedFullstop", + DECIMAL_ENCLOSED_PAREN = "decimalEnclosedParen", + DECIMAL_ENCLOSED_CIRCLE_CHINESE = "decimalEnclosedCircleChinese", + IDEOGRAPH_ENCLOSED_CIRCLE = "ideographEnclosedCircle", + IDEOGRAPH_TRADITIONAL = "ideographTraditional", + IDEOGRAPH_ZODIAC = "ideographZodiac", + IDEOGRAPH_ZODIAC_TRADITIONAL = "ideographZodiacTraditional", + TAIWANESE_COUNTING = "taiwaneseCounting", + IDEOGRAPH_LEGAL_TRADITIONAL = "ideographLegalTraditional", + TAIWANESE_COUNTING_THOUSAND = "taiwaneseCountingThousand", + TAIWANESE_DIGITAL = "taiwaneseDigital", + CHINESE_COUNTING = "chineseCounting", + CHINESE_LEGAL_SIMPLIFIED = "chineseLegalSimplified", + CHINESE_COUNTING_TEN_THOUSAND = "chineseCountingThousand", + KOREAN_DIGITAL = "koreanDigital", + KOREAN_COUNTING = "koreanCounting", + KOREAN_LEGAL = "koreanLegal", + KOREAN_DIGITAL_2 = "koreanDigital2", + VIETNAMESE_COUNTING = "vietnameseCounting", + RUSSIAN_LOWER = "russianLower", + RUSSIAN_UPPER = "russianUpper", + NONE = "none", + NUMBER_IN_DASH = "numberInDash", + HEBREW_1 = "hebrew1", + HEBREW_2 = "hebrew2", + ARABIC_ALPHA = "arabicAlpha", + ARABIC_ABJAD = "arabicAbjad", + HINDI_VOWELS = "hindiVowels", + HINDI_CONSONANTS = "hindiConsonants", + HINDI_NUMBERS = "hindiNumbers", + HINDI_COUNTING = "hindiCounting", + THAI_LETTERS = "thaiLetters", + THAI_NUMBERS = "thaiNumbers", + THAI_COUNTING = "thaiCounting", + BAHT_TEXT = "bahtText", + DOLLAR_TEXT = "dollarText", + // +} diff --git a/src/import-dotx/import-dotx.ts b/src/import-dotx/import-dotx.ts index 69a1ff0bcc..61340bf79e 100644 --- a/src/import-dotx/import-dotx.ts +++ b/src/import-dotx/import-dotx.ts @@ -1,8 +1,7 @@ import * as JSZip from "jszip"; import { Element as XMLElement, ElementCompact as XMLElementCompact, xml2js } from "xml-js"; -import { FooterReferenceType } from "file/document/body/section-properties/footer-reference"; -import { HeaderReferenceType } from "file/document/body/section-properties/header-reference"; +import { HeaderFooterReferenceType } from "file/document/body/section-properties"; import { FooterWrapper, IDocumentFooter } from "file/footer-wrapper"; import { HeaderWrapper, IDocumentHeader } from "file/header-wrapper"; import { Media } from "file/media"; @@ -17,8 +16,8 @@ const schemeToType = { }; interface IDocumentRefs { - readonly headers: { readonly id: number; readonly type: HeaderReferenceType }[]; - readonly footers: { readonly id: number; readonly type: FooterReferenceType }[]; + readonly headers: { readonly id: number; readonly type: HeaderFooterReferenceType }[]; + readonly footers: { readonly id: number; readonly type: HeaderFooterReferenceType }[]; } enum RelationshipType { @@ -219,7 +218,7 @@ export class ImportDotx { throw Error("header referecne element has no attributes"); } return { - type: item._attributes["w:type"] as HeaderReferenceType, + type: item._attributes["w:type"] as HeaderFooterReferenceType, id: this.parseRefId(item._attributes["r:id"] as string), }; }); @@ -239,7 +238,7 @@ export class ImportDotx { throw Error("footer referecne element has no attributes"); } return { - type: item._attributes["w:type"] as FooterReferenceType, + type: item._attributes["w:type"] as HeaderFooterReferenceType, id: this.parseRefId(item._attributes["r:id"] as string), }; });