diff --git a/demo/10-my-cv.ts b/demo/10-my-cv.ts index 75c5d9e8bd..b3e7c55e01 100644 --- a/demo/10-my-cv.ts +++ b/demo/10-my-cv.ts @@ -1,7 +1,7 @@ // Generate a CV // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TextRun } from "../build"; +import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "../build"; // tslint:disable:no-shadowed-variable @@ -226,11 +226,12 @@ class DocumentCreator { public createInstitutionHeader(institutionName: string, dateText: string): Paragraph { return new Paragraph({ - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: TabStopPosition.MAX, }, - }, + ], children: [ new TextRun({ text: institutionName, diff --git a/docs/usage/tab-stops.md b/docs/usage/tab-stops.md index e266c0b310..5c7a99da42 100644 --- a/docs/usage/tab-stops.md +++ b/docs/usage/tab-stops.md @@ -13,11 +13,12 @@ Simply call the relevant methods on the paragraph listed below. Then just add a ```ts const paragraph = new Paragraph({ children: [new TextRun("Hey everyone").bold(), new TextRun("11th November 1999").tab()], - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: TabStopPosition.MAX, }, - }, + ], }); ``` @@ -26,28 +27,49 @@ The example above will create a left aligned text, and a right aligned text on t ```ts const paragraph = new Paragraph({ children: [new TextRun("Second tab stop here I come!").tab().tab()], - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: TabStopPosition.MAX, }, - left: { + { + type: TabStopType.LEFT, position: 1000, }, - }, + ], }); ``` The above shows the use of two tab stops, and how to select/use it. +You can add multiple tab stops of the same `type` too. + +```ts +const paragraph = new Paragraph({ + children: [new TextRun("Multiple tab stops!").tab().tab()], + tabStops: [ + { + type: TabStopType.RIGHT, + position: TabStopPosition.MAX, + }, + { + type: TabStopType.RIGHT, + position: 1000, + }, + ], +}); +``` + ## Left Tab Stop ```ts const paragraph = new Paragraph({ - tabStop: { - left: { + tabStops: [ + { + type: TabStopType.LEFT, position: 2268, }, - }, + ], }); ``` @@ -57,11 +79,12 @@ const paragraph = new Paragraph({ ```ts const paragraph = new Paragraph({ - tabStop: { - center: { + tabStops: [ + { + type: TabStopType.CENTER, position: 2268, }, - }, + ], }); ``` @@ -71,11 +94,12 @@ const paragraph = new Paragraph({ ```ts const paragraph = new Paragraph({ - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: 2268, }, - }, + ], }); ``` @@ -85,11 +109,12 @@ const paragraph = new Paragraph({ ```ts const paragraph = new Paragraph({ - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: TabStopPosition.MAX, }, - }, + ], }); ``` diff --git a/src/file/numbering/level.ts b/src/file/numbering/level.ts index b0fa183f53..bdc65fbba4 100644 --- a/src/file/numbering/level.ts +++ b/src/file/numbering/level.ts @@ -7,9 +7,9 @@ import { ISpacingProperties, KeepLines, KeepNext, - LeftTabStop, - RightTabStop, Spacing, + TabStop, + TabStopType, ThematicBreak, } from "../paragraph/formatting"; import { ParagraphProperties } from "../paragraph/properties"; @@ -237,11 +237,11 @@ export class LevelBase extends XmlComponent { } public rightTabStop(position: number): Level { - return this.addParagraphProperty(new RightTabStop(position)); + return this.addParagraphProperty(new TabStop(TabStopType.RIGHT, position)); } public leftTabStop(position: number): Level { - this.addParagraphProperty(new LeftTabStop(position)); + this.addParagraphProperty(new TabStop(TabStopType.LEFT, position)); return this; } diff --git a/src/file/paragraph/formatting/tab-stop.spec.ts b/src/file/paragraph/formatting/tab-stop.spec.ts index 558289ba8e..377e7bb060 100644 --- a/src/file/paragraph/formatting/tab-stop.spec.ts +++ b/src/file/paragraph/formatting/tab-stop.spec.ts @@ -2,13 +2,13 @@ import { assert } from "chai"; import { Utility } from "tests/utility"; -import { LeaderType, LeftTabStop, RightTabStop } from "./tab-stop"; +import { LeaderType, TabStop, TabStopType } from "./tab-stop"; describe("LeftTabStop", () => { - let tabStop: LeftTabStop; + let tabStop: TabStop; beforeEach(() => { - tabStop = new LeftTabStop(100); + tabStop = new TabStop(TabStopType.LEFT, 100); }); describe("#constructor()", () => { @@ -29,10 +29,10 @@ describe("LeftTabStop", () => { }); describe("RightTabStop", () => { - let tabStop: RightTabStop; + let tabStop: TabStop; beforeEach(() => { - tabStop = new RightTabStop(100, LeaderType.DOT); + tabStop = new TabStop(TabStopType.RIGHT, 100, LeaderType.DOT); }); describe("#constructor()", () => { diff --git a/src/file/paragraph/formatting/tab-stop.ts b/src/file/paragraph/formatting/tab-stop.ts index e934b80c06..cfe121b119 100644 --- a/src/file/paragraph/formatting/tab-stop.ts +++ b/src/file/paragraph/formatting/tab-stop.ts @@ -2,13 +2,13 @@ import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; export class TabStop extends XmlComponent { - constructor(tab: TabStopItem) { + constructor(type: TabStopType, position: number, leader?: LeaderType) { super("w:tabs"); - this.root.push(tab); + this.root.push(new TabStopItem(type, position, leader)); } } -export enum TabValue { +export enum TabStopType { LEFT = "left", RIGHT = "right", CENTER = "center", @@ -33,7 +33,7 @@ export enum TabStopPosition { } export class TabAttributes extends XmlAttributeComponent<{ - readonly val: TabValue; + readonly val: TabStopType; readonly pos: string | number; readonly leader?: LeaderType; }> { @@ -41,7 +41,7 @@ export class TabAttributes extends XmlAttributeComponent<{ } export class TabStopItem extends XmlComponent { - constructor(value: TabValue, position: string | number, leader?: LeaderType) { + constructor(value: TabStopType, position: string | number, leader?: LeaderType) { super("w:tab"); this.root.push( new TabAttributes({ @@ -52,21 +52,3 @@ export class TabStopItem extends XmlComponent { ); } } - -export class LeftTabStop extends TabStop { - constructor(position: number, leader?: LeaderType) { - super(new TabStopItem(TabValue.LEFT, position, leader)); - } -} - -export class RightTabStop extends TabStop { - constructor(position: number, leader?: LeaderType) { - super(new TabStopItem(TabValue.RIGHT, position, leader)); - } -} - -export class CenterTabStop extends TabStop { - constructor(position: number, leader?: LeaderType) { - super(new TabStopItem(TabValue.CENTER, position, leader)); - } -} diff --git a/src/file/paragraph/paragraph.spec.ts b/src/file/paragraph/paragraph.spec.ts index 0536e44505..e8e5f6c8c9 100644 --- a/src/file/paragraph/paragraph.spec.ts +++ b/src/file/paragraph/paragraph.spec.ts @@ -4,7 +4,7 @@ import { Formatter } from "export/formatter"; import { EMPTY_OBJECT } from "file/xml-components"; import { Numbering } from "../numbering"; -import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition } from "./formatting"; +import { AlignmentType, HeadingLevel, LeaderType, PageBreak, TabStopPosition, TabStopType } from "./formatting"; import { Paragraph } from "./paragraph"; describe("Paragraph", () => { @@ -256,11 +256,12 @@ describe("Paragraph", () => { describe("#maxRightTabStop()", () => { it("should add right tab stop to JSON", () => { const paragraph = new Paragraph({ - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: TabStopPosition.MAX, }, - }, + ], }); const tree = new Formatter().format(paragraph); expect(tree).to.deep.equal({ @@ -289,12 +290,13 @@ describe("Paragraph", () => { describe("#leftTabStop()", () => { it("should add leftTabStop to JSON", () => { const paragraph = new Paragraph({ - tabStop: { - left: { + tabStops: [ + { + type: TabStopType.LEFT, position: 100, leader: LeaderType.HYPHEN, }, - }, + ], }); const tree = new Formatter().format(paragraph); expect(tree).to.deep.equal({ @@ -324,12 +326,13 @@ describe("Paragraph", () => { describe("#rightTabStop()", () => { it("should add rightTabStop to JSON", () => { const paragraph = new Paragraph({ - tabStop: { - right: { + tabStops: [ + { + type: TabStopType.RIGHT, position: 100, leader: LeaderType.DOT, }, - }, + ], }); const tree = new Formatter().format(paragraph); expect(tree).to.deep.equal({ @@ -359,12 +362,13 @@ describe("Paragraph", () => { describe("#centerTabStop()", () => { it("should add centerTabStop to JSON", () => { const paragraph = new Paragraph({ - tabStop: { - center: { + tabStops: [ + { + type: TabStopType.CENTER, position: 100, leader: LeaderType.MIDDLE_DOT, }, - }, + ], }); const tree = new Formatter().format(paragraph); expect(tree).to.deep.equal({ diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index cd8f3a1bcd..5d8b4e0ae0 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -11,17 +11,12 @@ import { KeepLines, KeepNext } from "./formatting/keep"; import { PageBreak, PageBreakBefore } from "./formatting/page-break"; import { ContextualSpacing, ISpacingProperties, Spacing } from "./formatting/spacing"; import { HeadingLevel, Style } from "./formatting/style"; -import { CenterTabStop, LeaderType, LeftTabStop, RightTabStop, TabStopPosition } from "./formatting/tab-stop"; +import { LeaderType, TabStop, TabStopPosition, TabStopType } from "./formatting/tab-stop"; import { NumberProperties } from "./formatting/unordered-list"; import { Bookmark, Hyperlink, OutlineLevel } from "./links"; import { ParagraphProperties } from "./properties"; import { PictureRun, Run, SequentialIdentifier, SymbolRun, TextRun } from "./run"; -interface ITabStopOptions { - readonly position: number | TabStopPosition; - readonly leader?: LeaderType; -} - export interface IParagraphOptions { readonly text?: string; readonly border?: IBorderOptions; @@ -36,11 +31,11 @@ export interface IParagraphOptions { readonly indent?: IIndentAttributesProperties; readonly keepLines?: boolean; readonly keepNext?: boolean; - readonly tabStop?: { - readonly left?: ITabStopOptions; - readonly right?: ITabStopOptions; - readonly center?: ITabStopOptions; - }; + readonly tabStops?: Array<{ + readonly position: number | TabStopPosition; + readonly type: TabStopType; + readonly leader?: LeaderType; + }>; readonly style?: string; readonly bullet?: { readonly level: number; @@ -127,17 +122,9 @@ export class Paragraph extends XmlComponent { this.properties.push(new KeepNext()); } - if (options.tabStop) { - if (options.tabStop.left) { - this.properties.push(new LeftTabStop(options.tabStop.left.position, options.tabStop.left.leader)); - } - - if (options.tabStop.right) { - this.properties.push(new RightTabStop(options.tabStop.right.position, options.tabStop.right.leader)); - } - - if (options.tabStop.center) { - this.properties.push(new CenterTabStop(options.tabStop.center.position, options.tabStop.center.leader)); + if (options.tabStops) { + for (const tabStop of options.tabStops) { + this.properties.push(new TabStop(tabStop.type, tabStop.position, tabStop.leader)); } } diff --git a/src/file/styles/style/paragraph-style.ts b/src/file/styles/style/paragraph-style.ts index 077df26292..ab592a9fc6 100644 --- a/src/file/styles/style/paragraph-style.ts +++ b/src/file/styles/style/paragraph-style.ts @@ -5,13 +5,12 @@ import { ISpacingProperties, KeepLines, KeepNext, - LeftTabStop, OutlineLevel, ParagraphProperties, Spacing, ThematicBreak, } from "file/paragraph"; -import { IIndentAttributesProperties, RightTabStop } from "file/paragraph/formatting"; +import { IIndentAttributesProperties, TabStop, TabStopType } from "file/paragraph/formatting"; import * as formatting from "file/paragraph/run/formatting"; import { RunProperties } from "file/paragraph/run/properties"; import { UnderlineType } from "file/paragraph/run/underline"; @@ -181,11 +180,11 @@ export class ParagraphStyle extends Style { } if (options.paragraph.rightTabStop) { - this.paragraphProperties.push(new RightTabStop(options.paragraph.rightTabStop)); + this.paragraphProperties.push(new TabStop(TabStopType.RIGHT, options.paragraph.rightTabStop)); } if (options.paragraph.leftTabStop) { - this.paragraphProperties.push(new LeftTabStop(options.paragraph.leftTabStop)); + this.paragraphProperties.push(new TabStop(TabStopType.LEFT, options.paragraph.leftTabStop)); } if (options.paragraph.indent) {