diff --git a/demo/1-basic.ts b/demo/1-basic.ts index 7db8870259..eb417f52b4 100644 --- a/demo/1-basic.ts +++ b/demo/1-basic.ts @@ -16,9 +16,9 @@ doc.addSection({ bold: true, }), new TextRun({ - text: "Github is the best", + text: "\tGithub is the best", bold: true, - }).tab(), + }), ], }), ], diff --git a/demo/10-my-cv.ts b/demo/10-my-cv.ts index b3e7c55e01..b91ca318bb 100644 --- a/demo/10-my-cv.ts +++ b/demo/10-my-cv.ts @@ -238,9 +238,9 @@ class DocumentCreator { bold: true, }), new TextRun({ - text: dateText, + text: `\t${dateText}`, bold: true, - }).tab(), + }), ], }); } diff --git a/demo/14-page-numbers.ts b/demo/14-page-numbers.ts index ae34300b5c..00b77cfe31 100644 --- a/demo/14-page-numbers.ts +++ b/demo/14-page-numbers.ts @@ -1,7 +1,7 @@ // Page numbers // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { AlignmentType, Document, Header, Packer, PageBreak, Paragraph, TextRun } from "../build"; +import { AlignmentType, Document, Header, Packer, PageBreak, PageNumber, Paragraph, TextRun } from "../build"; const doc = new Document(); @@ -11,7 +11,12 @@ doc.addSection({ children: [ new Paragraph({ alignment: AlignmentType.RIGHT, - children: [new TextRun("My Title "), new TextRun("Page ").pageNumber()], + children: [ + new TextRun("My Title "), + new TextRun({ + children: ["Page ", PageNumber.CURRENT], + }), + ], }), ], }), @@ -19,7 +24,12 @@ doc.addSection({ children: [ new Paragraph({ alignment: AlignmentType.RIGHT, - children: [new TextRun("First Page Header "), new TextRun("Page ").pageNumber()], + children: [ + new TextRun("First Page Header "), + new TextRun({ + children: ["Page ", PageNumber.CURRENT], + }), + ], }), ], }), diff --git a/demo/16-multiple-sections.ts b/demo/16-multiple-sections.ts index 5518eb5416..6f2e350b23 100644 --- a/demo/16-multiple-sections.ts +++ b/demo/16-multiple-sections.ts @@ -1,7 +1,7 @@ // Multiple sections and headers // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { Document, Footer, Header, Packer, PageNumberFormat, PageOrientation, Paragraph, TextRun } from "../build"; +import { Document, Footer, Header, Packer, PageNumber, PageNumberFormat, PageOrientation, Paragraph, TextRun } from "../build"; const doc = new Document(); @@ -53,7 +53,11 @@ doc.addSection({ default: new Header({ children: [ new Paragraph({ - children: [new TextRun("Page number: ").pageNumber()], + children: [ + new TextRun({ + children: ["Page number: ", PageNumber.CURRENT], + }), + ], }), ], }), @@ -69,7 +73,11 @@ doc.addSection({ default: new Header({ children: [ new Paragraph({ - children: [new TextRun("Page number: ").pageNumber()], + children: [ + new TextRun({ + children: ["Page number: ", PageNumber.CURRENT], + }), + ], }), ], }), @@ -90,7 +98,11 @@ doc.addSection({ default: new Header({ children: [ new Paragraph({ - children: [new TextRun("Page number: ").pageNumber()], + children: [ + new TextRun({ + children: ["Page number: ", PageNumber.CURRENT], + }), + ], }), ], }), diff --git a/demo/17-footnotes.ts b/demo/17-footnotes.ts index bf3f11eb91..3ed1f4ea91 100644 --- a/demo/17-footnotes.ts +++ b/demo/17-footnotes.ts @@ -1,16 +1,25 @@ // Footnotes // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { Document, Packer, Paragraph, TextRun } from "../build"; +import { Document, FootnoteReferenceRun, Packer, Paragraph, TextRun } from "../build"; const doc = new Document(); doc.addSection({ children: [ new Paragraph({ - children: [new TextRun("Hello").referenceFootnote(1), new TextRun(" World!").referenceFootnote(2)], + children: [ + new TextRun({ + children: ["Hello", new FootnoteReferenceRun(1)], + }), + new TextRun({ + children: [" World!", new FootnoteReferenceRun(2)], + }), + ], + }), + new Paragraph({ + children: [new TextRun("Hello World"), new FootnoteReferenceRun(3)], }), - new Paragraph("Hello World").referenceFootnote(3), ], }); diff --git a/demo/19-export-to-base64.ts b/demo/19-export-to-base64.ts index 676d844c8d..1d94cf5ff7 100644 --- a/demo/19-export-to-base64.ts +++ b/demo/19-export-to-base64.ts @@ -15,9 +15,9 @@ doc.addSection({ bold: true, }), new TextRun({ - text: "Bar", + text: "\tBar", bold: true, - }).tab(), + }), ], }), ], diff --git a/demo/39-page-numbers.ts b/demo/39-page-numbers.ts index edc9c411f9..2ab61419ef 100644 --- a/demo/39-page-numbers.ts +++ b/demo/39-page-numbers.ts @@ -1,7 +1,7 @@ // Example how to display page numbers // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { AlignmentType, Document, Footer, Header, Packer, PageNumberFormat, Paragraph, TextRun } from "../build"; +import { AlignmentType, Document, Footer, Header, Packer, PageBreak, PageNumber, PageNumberFormat, Paragraph, TextRun } from "../build"; const doc = new Document({}); @@ -9,9 +9,17 @@ doc.addSection({ headers: { default: new Header({ children: [ - new Paragraph("Foo Bar corp. ") - .addRun(new TextRun("Page Number ").pageNumber()) - .addRun(new TextRun(" to ").numberOfTotalPages()), + new Paragraph({ + children: [ + new TextRun("Foo Bar corp. "), + new TextRun({ + children: ["Page Number ", PageNumber.CURRENT], + }), + new TextRun({ + children: [" to ", PageNumber.TOTAL_PAGES], + }), + ], + }), ], }), }, @@ -19,11 +27,17 @@ doc.addSection({ default: new Footer({ children: [ new Paragraph({ - text: "Foo Bar corp. ", alignment: AlignmentType.CENTER, - }) - .addRun(new TextRun("Page Number: ").pageNumber()) - .addRun(new TextRun(" to ").numberOfTotalPages()), + children: [ + new TextRun("Foo Bar corp. "), + new TextRun({ + children: ["Page Number: ", PageNumber.CURRENT], + }), + new TextRun({ + children: [" to ", PageNumber.TOTAL_PAGES], + }), + ], + }), ], }), }, @@ -32,11 +46,21 @@ doc.addSection({ pageNumberFormatType: PageNumberFormat.DECIMAL, }, children: [ - new Paragraph("Hello World 1").pageBreak(), - new Paragraph("Hello World 2").pageBreak(), - new Paragraph("Hello World 3").pageBreak(), - new Paragraph("Hello World 4").pageBreak(), - new Paragraph("Hello World 5").pageBreak(), + new Paragraph({ + children: [new TextRun("Hello World 1"), new PageBreak()], + }), + new Paragraph({ + children: [new TextRun("Hello World 2"), new PageBreak()], + }), + new Paragraph({ + children: [new TextRun("Hello World 3"), new PageBreak()], + }), + new Paragraph({ + children: [new TextRun("Hello World 4"), new PageBreak()], + }), + new Paragraph({ + children: [new TextRun("Hello World 5"), new PageBreak()], + }), ], }); diff --git a/demo/47-number-of-total-pages-section.ts b/demo/47-number-of-total-pages-section.ts index 988206e524..7e8cf91b2c 100644 --- a/demo/47-number-of-total-pages-section.ts +++ b/demo/47-number-of-total-pages-section.ts @@ -1,7 +1,7 @@ // Multiple sections with total number of pages in each section // Import from 'docx' rather than '../build' if you install from npm import * as fs from "fs"; -import { AlignmentType, Document, Packer, PageNumberFormat, TextRun, Header, Paragraph, Footer, PageBreak } from "../build"; +import { AlignmentType, Document, Footer, Header, Packer, PageBreak, PageNumber, PageNumberFormat, Paragraph, TextRun } from "../build"; const doc = new Document(); @@ -10,8 +10,12 @@ const header = new Header({ new Paragraph({ children: [ new TextRun("Header on another page"), - new TextRun("Page Number: ").pageNumber(), - new TextRun(" to ").numberOfTotalPagesSection(), + new TextRun({ + children: ["Page number: ", PageNumber.CURRENT], + }), + new TextRun({ + children: [" to ", PageNumber.TOTAL_PAGES_IN_SECTION], + }), ], alignment: AlignmentType.CENTER, }), diff --git a/demo/48-vertical-align.ts b/demo/48-vertical-align.ts index a9eb7986da..35181d271c 100644 --- a/demo/48-vertical-align.ts +++ b/demo/48-vertical-align.ts @@ -18,9 +18,9 @@ doc.addSection({ bold: true, }), new TextRun({ - text: "Github is the best", + text: "\tGithub is the best", bold: true, - }).tab(), + }), ], }), ], diff --git a/demo/6-page-borders.ts b/demo/6-page-borders.ts index d54aac9a94..e83f18233b 100644 --- a/demo/6-page-borders.ts +++ b/demo/6-page-borders.ts @@ -21,9 +21,9 @@ doc.addSection({ bold: true, }), new TextRun({ - text: "Github is the best", + text: "\tGithub is the best", bold: true, - }).tab(), + }), ], }), new Paragraph({ diff --git a/demo/browser-demo.html b/demo/browser-demo.html index 82f064deb2..ecd7f47701 100644 --- a/demo/browser-demo.html +++ b/demo/browser-demo.html @@ -24,9 +24,9 @@ bold: true, }), new docx.TextRun({ - text: "Github is the best", + text: "\tGithub is the best", bold: true, - }).tab(), + }), ], }), ], diff --git a/docs/README.md b/docs/README.md index 089c133ac2..dae964d87a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,9 +50,9 @@ doc.addSection({ bold: true, }), new TextRun({ - text: "Github is the best", + text: "\tGithub is the best", bold: true, - }).tab(), + }), ], }), ], diff --git a/docs/usage/tab-stops.md b/docs/usage/tab-stops.md index 5c7a99da42..1a3d1e3b2e 100644 --- a/docs/usage/tab-stops.md +++ b/docs/usage/tab-stops.md @@ -12,7 +12,7 @@ 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()], + children: [new TextRun("Hey everyone").bold(), new TextRun(\t"11th November 1999")], tabStops: [ { type: TabStopType.RIGHT, @@ -26,7 +26,7 @@ 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()], + children: [new TextRun("Second tab stop here I come!")], tabStops: [ { type: TabStopType.RIGHT, @@ -46,7 +46,7 @@ You can add multiple tab stops of the same `type` too. ```ts const paragraph = new Paragraph({ - children: [new TextRun("Multiple tab stops!").tab().tab()], + children: [new TextRun("Multiple tab stops!")], tabStops: [ { type: TabStopType.RIGHT, diff --git a/src/file/footnotes/footnote/index.ts b/src/file/footnotes/footnote/index.ts new file mode 100644 index 0000000000..11d8ba33a9 --- /dev/null +++ b/src/file/footnotes/footnote/index.ts @@ -0,0 +1 @@ +export * from "./run"; diff --git a/src/file/footnotes/footnote/run/index.ts b/src/file/footnotes/footnote/run/index.ts new file mode 100644 index 0000000000..548e717bbd --- /dev/null +++ b/src/file/footnotes/footnote/run/index.ts @@ -0,0 +1 @@ +export * from "./reference-run"; diff --git a/src/file/footnotes/index.ts b/src/file/footnotes/index.ts index 91f3a9948b..1e11cca76a 100644 --- a/src/file/footnotes/index.ts +++ b/src/file/footnotes/index.ts @@ -1 +1,2 @@ export * from "./footnotes"; +export * from "./footnote"; diff --git a/src/file/index.ts b/src/file/index.ts index d14d4d9b1a..c4ce99e345 100644 --- a/src/file/index.ts +++ b/src/file/index.ts @@ -12,3 +12,4 @@ export * from "./xml-components"; export * from "./header-wrapper"; export * from "./footer-wrapper"; export * from "./header"; +export * from "./footnotes"; diff --git a/src/file/paragraph/paragraph.ts b/src/file/paragraph/paragraph.ts index 1defd01779..7de245fab8 100644 --- a/src/file/paragraph/paragraph.ts +++ b/src/file/paragraph/paragraph.ts @@ -44,7 +44,9 @@ export interface IParagraphOptions { readonly level: number; readonly custom?: boolean; }; - readonly children?: Array; + readonly children?: Array< + TextRun | PictureRun | Hyperlink | SymbolRun | Bookmark | PageBreak | SequentialIdentifier | FootnoteReferenceRun + >; } export class Paragraph extends XmlComponent { @@ -157,11 +159,6 @@ export class Paragraph extends XmlComponent { } } - public referenceFootnote(id: number): Paragraph { - this.root.push(new FootnoteReferenceRun(id)); - return this; - } - public addRunToFront(run: Run): Paragraph { this.root.splice(1, 0, run); return this; diff --git a/src/file/paragraph/run/index.ts b/src/file/paragraph/run/index.ts index 353e794c06..21df415f35 100644 --- a/src/file/paragraph/run/index.ts +++ b/src/file/paragraph/run/index.ts @@ -5,3 +5,4 @@ export * from "./picture-run"; export * from "./run-fonts"; export * from "./sequential-identifier"; export * from "./underline"; +export * from "./tab"; diff --git a/src/file/paragraph/run/run-components/text.spec.ts b/src/file/paragraph/run/run-components/text.spec.ts index 57a3a5ede1..6393cebd8b 100644 --- a/src/file/paragraph/run/run-components/text.spec.ts +++ b/src/file/paragraph/run/run-components/text.spec.ts @@ -6,12 +6,6 @@ import { Text } from "./text"; describe("Text", () => { describe("#constructor", () => { - it("creates an empty text run if no text is given", () => { - const t = new Text(""); - const f = new Formatter().format(t); - expect(f).to.deep.equal({ "w:t": { _attr: { "xml:space": "preserve" } } }); - }); - it("adds the passed in text to the component", () => { const t = new Text(" this is\n text"); const f = new Formatter().format(t); diff --git a/src/file/paragraph/run/run-components/text.ts b/src/file/paragraph/run/run-components/text.ts index 5cac4500b4..f730d37d3b 100644 --- a/src/file/paragraph/run/run-components/text.ts +++ b/src/file/paragraph/run/run-components/text.ts @@ -9,8 +9,7 @@ export class Text extends XmlComponent { constructor(text: string) { super("w:t"); this.root.push(new TextAttributes({ space: SpaceType.PRESERVE })); - if (text) { - this.root.push(text); - } + + this.root.push(text); } } diff --git a/src/file/paragraph/run/run.spec.ts b/src/file/paragraph/run/run.spec.ts index c16eb82b03..37aadfb8d8 100644 --- a/src/file/paragraph/run/run.spec.ts +++ b/src/file/paragraph/run/run.spec.ts @@ -1,9 +1,11 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; +// import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; import { ShadingType } from "file/table"; import { Run } from "./"; +import { PageNumber } from "./run"; import { UnderlineType } from "./underline"; describe("Run", () => { @@ -197,17 +199,6 @@ describe("Run", () => { }); }); - describe("#tab()", () => { - it("it should add break to the run", () => { - const run = new Run({}); - run.tab(); - const tree = new Formatter().format(run); - expect(tree).to.deep.equal({ - "w:r": [{ "w:tab": {} }], - }); - }); - }); - describe("#font()", () => { it("should set the font as named", () => { const run = new Run({ @@ -270,8 +261,10 @@ describe("Run", () => { describe("#numberOfTotalPages", () => { it("should set the run to the RTL mode", () => { - const run = new Run({}); - run.numberOfTotalPages(); + const run = new Run({ + children: [PageNumber.TOTAL_PAGES], + }); + const tree = new Formatter().format(run); expect(tree).to.deep.equal({ "w:r": [ @@ -286,8 +279,10 @@ describe("Run", () => { describe("#numberOfTotalPagesSection", () => { it("should set the run to the RTL mode", () => { - const run = new Run({}); - run.numberOfTotalPagesSection(); + const run = new Run({ + children: [PageNumber.TOTAL_PAGES_IN_SECTION], + }); + const tree = new Formatter().format(run); expect(tree).to.deep.equal({ "w:r": [ @@ -302,8 +297,9 @@ describe("Run", () => { describe("#pageNumber", () => { it("should set the run to the RTL mode", () => { - const run = new Run({}); - run.pageNumber(); + const run = new Run({ + children: [PageNumber.CURRENT], + }); const tree = new Formatter().format(run); expect(tree).to.deep.equal({ "w:r": [ diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index e586f8807d..20777b72a2 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -2,6 +2,7 @@ import { ShadingType } from "file/table"; import { XmlComponent } from "file/xml-components"; +import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; import { FieldInstruction } from "file/table-of-contents/field-instruction"; import { Break } from "./break"; import { Caps, SmallCaps } from "./caps"; @@ -24,10 +25,10 @@ import { } from "./formatting"; import { NumberOfPages, NumberOfPagesSection, Page } from "./page-number"; import { RunProperties } from "./properties"; +import { Text } from "./run-components/text"; import { RunFonts } from "./run-fonts"; import { SubScript, SuperScript } from "./script"; import { Style } from "./style"; -import { Tab } from "./tab"; import { Underline, UnderlineType } from "./underline"; export interface IRunOptions { @@ -57,7 +58,14 @@ export interface IRunOptions { readonly fill: string; readonly color: string; }; - readonly children?: Array; + readonly children?: Array; + readonly text?: string; +} + +export enum PageNumber { + CURRENT = "CURRENT", + TOTAL_PAGES = "TOTAL_PAGES", + TOTAL_PAGES_IN_SECTION = "TOTAL_PAGES_IN_SECTION", } export class Run extends XmlComponent { @@ -139,8 +147,37 @@ export class Run extends XmlComponent { if (options.children) { for (const child of options.children) { + if (typeof child === "string") { + switch (child) { + case PageNumber.CURRENT: + this.root.push(new Begin()); + this.root.push(new Page()); + this.root.push(new Separate()); + this.root.push(new End()); + break; + case PageNumber.TOTAL_PAGES: + this.root.push(new Begin()); + this.root.push(new NumberOfPages()); + this.root.push(new Separate()); + this.root.push(new End()); + break; + case PageNumber.TOTAL_PAGES_IN_SECTION: + this.root.push(new Begin()); + this.root.push(new NumberOfPagesSection()); + this.root.push(new Separate()); + this.root.push(new End()); + break; + default: + this.root.push(new Text(child)); + break; + } + continue; + } + this.root.push(child); } + } else if (options.text) { + this.root.push(new Text(options.text)); } } @@ -148,33 +185,4 @@ export class Run extends XmlComponent { this.root.splice(1, 0, new Break()); return this; } - - public tab(): Run { - this.root.splice(1, 0, new Tab()); - return this; - } - - public pageNumber(): Run { - this.root.push(new Begin()); - this.root.push(new Page()); - this.root.push(new Separate()); - this.root.push(new End()); - return this; - } - - public numberOfTotalPages(): Run { - this.root.push(new Begin()); - this.root.push(new NumberOfPages()); - this.root.push(new Separate()); - this.root.push(new End()); - return this; - } - - public numberOfTotalPagesSection(): Run { - this.root.push(new Begin()); - this.root.push(new NumberOfPagesSection()); - this.root.push(new Separate()); - this.root.push(new End()); - return this; - } } diff --git a/src/file/paragraph/run/text-run.spec.ts b/src/file/paragraph/run/text-run.spec.ts index ae8e5bd9b4..b36b3c3139 100644 --- a/src/file/paragraph/run/text-run.spec.ts +++ b/src/file/paragraph/run/text-run.spec.ts @@ -1,6 +1,7 @@ import { expect } from "chai"; import { Formatter } from "export/formatter"; +import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; import { TextRun } from "./text-run"; @@ -19,9 +20,11 @@ describe("TextRun", () => { describe("#referenceFootnote()", () => { it("should add a valid footnote reference", () => { - run = new TextRun("test"); - run.referenceFootnote(1); + run = new TextRun({ + children: ["test", new FootnoteReferenceRun(1)], + }); const tree = new Formatter().format(run); + expect(tree).to.deep.equal({ "w:r": [ { "w:t": [{ _attr: { "xml:space": "preserve" } }, "test"] }, diff --git a/src/file/paragraph/run/text-run.ts b/src/file/paragraph/run/text-run.ts index 2bbf1bae75..200651c9de 100644 --- a/src/file/paragraph/run/text-run.ts +++ b/src/file/paragraph/run/text-run.ts @@ -1,13 +1,8 @@ -import { FootnoteReferenceRun } from "file/footnotes/footnote/run/reference-run"; import { IRunOptions, Run } from "./run"; import { Text } from "./run-components/text"; -export interface ITextRunOptions extends IRunOptions { - readonly text: string; -} - export class TextRun extends Run { - constructor(options: ITextRunOptions | string) { + constructor(options: IRunOptions | string) { if (typeof options === "string") { super({}); this.root.push(new Text(options)); @@ -15,11 +10,5 @@ export class TextRun extends Run { } super(options); - this.root.push(new Text(options.text)); - } - - public referenceFootnote(id: number): TextRun { - this.root.push(new FootnoteReferenceRun(id)); - return this; } }