Compare commits

..

29 Commits
3.0.0 ... 3.1.0

Author SHA1 Message Date
cf1689a3c2 Version bump 2017-12-06 01:39:40 +00:00
66d0bab0a5 Add packPdf reference 2017-12-06 01:39:24 +00:00
5889f20f1e Simplify tests and made compile async 2017-12-06 01:32:57 +00:00
ebec10e312 Refactor 2017-12-06 01:03:14 +00:00
ae8a0c7fd0 Edit Tslint 2017-12-05 23:43:19 +00:00
bb49200fad Clean up code using request promise 2017-12-05 02:24:49 +00:00
a6bba0bc6c Enable pdf export 2017-12-05 00:16:21 +00:00
fb08f79344 Add initial conversion 2017-11-10 14:27:57 +00:00
741c74825e Class definition for Pdf converter wrapper 2017-09-30 18:23:02 +01:00
28539cd47b Initial scaffold of pdf convert 2017-09-30 18:15:33 +01:00
8ca7c5a343 Add test 2017-09-30 18:00:06 +01:00
32b56e7071 Move sub components of Paragraph into own folder 2017-09-30 01:52:37 +01:00
7dad717952 Add documentation links 2017-09-22 14:46:19 +01:00
34e928755f Add documentation links 2017-09-21 14:56:46 +01:00
51e0f311fe Refactor numbering into its own file 2017-09-20 13:37:39 +01:00
cc9dff6b94 Version bump 2017-09-19 16:02:32 +01:00
101cc0fdea Add docx keyword to package 2017-09-19 16:02:06 +01:00
d408262fa8 Remove unused class 2017-09-19 15:58:37 +01:00
ed53c30f42 Remove template file and placed in the Wiki
https://github.com/dolanmiu/docx/wiki/Contributing-Guidelines
2017-09-19 15:56:52 +01:00
ebbf6a99c1 Make exporting more consistent 2017-09-19 15:51:55 +01:00
b98c103e45 Export table into own file 2017-09-19 15:49:27 +01:00
518fec0595 Export like standard style 2017-09-19 15:47:29 +01:00
659936f3f0 Refactor xml component into own class 2017-09-19 15:46:20 +01:00
b0febf5054 Refactor run into own file 2017-09-19 15:42:40 +01:00
56b951a2b1 Refactor body into own file 2017-09-19 15:39:14 +01:00
a3a9958a69 Refactor document into own file 2017-09-19 15:36:41 +01:00
4f36bbf426 Refactor paragraph into its own file
Create barrel
2017-09-19 15:21:07 +01:00
357bc7f377 Add documentation reference 2017-09-19 15:17:58 +01:00
da8405b5b9 Add Right and Center tab stops 2017-09-19 12:51:37 +01:00
49 changed files with 856 additions and 741 deletions

View File

@ -57,6 +57,8 @@ var exporter = new docx.LocalPacker(doc);
var exporter = new docx.ExpressPacker(doc, res); var exporter = new docx.ExpressPacker(doc, res);
exporter.pack('My First Document'); exporter.pack('My First Document');
// If you want to export it as a .pdf file instead
exporter.packPdf('My First Document');
// done! A file called 'My First Document.docx' // done! A file called 'My First Document.docx'
// will be in your file system if you used LocalPacker // will be in your file system if you used LocalPacker
@ -66,6 +68,10 @@ exporter.pack('My First Document');
## Examples ## Examples
Check [the Wiki](https://github.com/dolanmiu/docx/wiki/Examples) for examples. Check [the Wiki](https://github.com/dolanmiu/docx/wiki/Examples) for examples.
# Contributing
Read the contribution guidelines [here](https://github.com/dolanmiu/docx/wiki/Contributing-Guidelines).
----- -----
Made with 💖 Made with 💖
@ -84,4 +90,3 @@ Huge thanks to [@felipeochoa](https://github.com/felipeochoa) for awesome contri
[gitter-url]: https://gitter.im/docx-lib/Lobby [gitter-url]: https://gitter.im/docx-lib/Lobby
[gemnasium-image]: https://gemnasium.com/badges/github.com/dolanmiu/docx.svg [gemnasium-image]: https://gemnasium.com/badges/github.com/dolanmiu/docx.svg
[gemnasium-url]: https://gemnasium.com/github.com/dolanmiu/docx [gemnasium-url]: https://gemnasium.com/github.com/dolanmiu/docx

View File

@ -1,6 +1,6 @@
{ {
"name": "docx", "name": "docx",
"version": "3.0.0", "version": "3.1.0",
"description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)",
"main": "build/index.js", "main": "build/index.js",
"scripts": { "scripts": {
@ -22,6 +22,7 @@
"url": "git+https://github.com/dolanmiu/docx.git" "url": "git+https://github.com/dolanmiu/docx.git"
}, },
"keywords": [ "keywords": [
"docx",
"office", "office",
"word", "word",
"generate", "generate",
@ -36,7 +37,11 @@
"dependencies": { "dependencies": {
"@types/archiver": "^1.3.4", "@types/archiver": "^1.3.4",
"@types/express": "^4.0.35", "@types/express": "^4.0.35",
"@types/request": "^2.0.3",
"@types/request-promise": "^4.1.39",
"archiver": "^1.3.0", "archiver": "^1.3.0",
"request": "^2.83.0",
"request-promise": "^4.2.2",
"xml": "^1.0.1" "xml": "^1.0.1"
}, },
"author": "Dolan Miu", "author": "Dolan Miu",

View File

@ -0,0 +1,12 @@
import { XmlComponent } from "../../xml-components";
export class Body extends XmlComponent {
constructor() {
super("w:body");
}
public push(component: XmlComponent): void {
this.root.push(component);
}
}

View File

@ -1,12 +1 @@
import { XmlComponent } from "../../xml-components"; export * from "./body";
export class Body extends XmlComponent {
constructor() {
super("w:body");
}
public push(component: XmlComponent): void {
this.root.push(component);
}
}

View File

@ -0,0 +1,56 @@
// http://officeopenxml.com/WPdocument.php
import { Paragraph } from "../paragraph";
import { Table } from "../table";
import { XmlComponent } from "../xml-components";
import { Body } from "./body";
import { DocumentAttributes } from "./document-attributes";
export class Document extends XmlComponent {
private body: Body;
constructor() {
super("w:document");
this.root.push(new DocumentAttributes({
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
v: "urn:schemas-microsoft-com:vml",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
w10: "urn:schemas-microsoft-com:office:word",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
Ignorable: "w14 w15 wp14",
}));
this.body = new Body();
this.root.push(this.body);
}
public addParagraph(paragraph: Paragraph): void {
this.body.push(paragraph);
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addParagraph(para);
return para;
}
public addTable(table: Table): void {
this.body.push(table);
}
public createTable(rows: number, cols: number): Table {
const table = new Table(rows, cols);
this.addTable(table);
return table;
}
}

View File

@ -1,55 +1 @@
import { Paragraph } from "../paragraph"; export * from "./document";
import { Table } from "../table";
import { XmlComponent } from "../xml-components";
import { Body } from "./body";
import { DocumentAttributes } from "./document-attributes";
export class Document extends XmlComponent {
private body: Body;
constructor() {
super("w:document");
this.root.push(new DocumentAttributes({
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
v: "urn:schemas-microsoft-com:vml",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
w10: "urn:schemas-microsoft-com:office:word",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
Ignorable: "w14 w15 wp14",
}));
this.body = new Body();
this.root.push(this.body);
}
public addParagraph(paragraph: Paragraph): void {
this.body.push(paragraph);
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addParagraph(para);
return para;
}
public addTable(table: Table): void {
this.body.push(table);
}
public createTable(rows: number, cols: number): Table {
const table = new Table(rows, cols);
this.addTable(table);
return table;
}
}

View File

@ -1,7 +1,4 @@
export { Document } from "./document"; export * from "./document";
export * from "./paragraph"; export * from "./paragraph";
export { Run } from "./run"; export * from "./run";
export { TextRun } from "./run/text-run";
export { PictureRun } from "./run/picture-run";
export { Table } from "./table"; export { Table } from "./table";
// Perhaps all run related stuff can be exported from run, instead of exporting Run, TextRun, PictureRun seperately.

View File

@ -1,10 +0,0 @@
export { Alignment } from "./alignment";
export { ThematicBreak } from "./border";
export { Indent } from "./indent";
export { KeepLines, KeepNext } from "./keep";
export { PageBreak } from "./page-break";
export { ParagraphProperties } from "./properties";
export { ISpacingProperties, Spacing } from "./spacing";
export { Style } from "./style";
export { LeftTabStop, MaxRightTabStop } from "./tab-stop";
export { NumberProperties } from "./unordered-list";

View File

@ -1,4 +1,5 @@
import { XmlAttributeComponent, XmlComponent } from "../xml-components"; // http://officeopenxml.com/WPalignment.php
import { XmlAttributeComponent, XmlComponent } from "../../xml-components";
export type AlignmentOptions = "left" | "center" | "right" | "both"; export type AlignmentOptions = "left" | "center" | "right" | "both";

View File

@ -1,6 +1,6 @@
import { assert } from "chai"; import { assert } from "chai";
import { Utility } from "../../tests/utility"; import { Utility } from "../../../tests/utility";
import { ThematicBreak } from "./border"; import { ThematicBreak } from "./border";
describe("Border", () => { describe("Border", () => {
@ -15,6 +15,18 @@ describe("ThematicBreak", () => {
}); });
describe("#constructor()", () => { describe("#constructor()", () => {
it("should create valid JSON", () => {
const stringifiedJson = JSON.stringify(thematicBreak);
let newJson;
try {
newJson = JSON.parse(stringifiedJson);
} catch (e) {
assert.isTrue(false);
}
assert.isTrue(true);
});
it("should create a Thematic Break with correct border properties", () => { it("should create a Thematic Break with correct border properties", () => {
const newJson = Utility.jsonify(thematicBreak); const newJson = Utility.jsonify(thematicBreak);
const attributes = { const attributes = {

View File

@ -1,4 +1,5 @@
import { Attributes, XmlComponent } from "../xml-components"; // http://officeopenxml.com/WPborders.php
import { Attributes, XmlComponent } from "../../xml-components";
class Border extends XmlComponent { class Border extends XmlComponent {

View File

@ -1,4 +1,5 @@
import { XmlAttributeComponent, XmlComponent } from "../xml-components"; // http://officeopenxml.com/WPindentation.php
import { XmlAttributeComponent, XmlComponent } from "../../xml-components";
interface IIndentAttributesProperties { interface IIndentAttributesProperties {
left?: number; left?: number;

View File

@ -0,0 +1,9 @@
export * from "./alignment";
export * from "./border";
export * from "./indent";
export * from "./keep";
export * from "./page-break";
export * from "./spacing";
export * from "./style";
export * from "./tab-stop";
export * from "./unordered-list";

View File

@ -1,4 +1,4 @@
import { XmlComponent } from "../xml-components"; import { XmlComponent } from "../../xml-components";
export class KeepLines extends XmlComponent { export class KeepLines extends XmlComponent {
constructor() { constructor() {

View File

@ -1,6 +1,6 @@
import { assert } from "chai"; import { assert } from "chai";
import { Utility } from "../../tests/utility"; import { Utility } from "../../../tests/utility";
import { PageBreak } from "./page-break"; import { PageBreak } from "./page-break";
describe("PageBreak", () => { describe("PageBreak", () => {

View File

@ -1,5 +1,6 @@
import { Run } from "../run"; // http://officeopenxml.com/WPtextSpecialContent-break.php
import { Attributes, XmlComponent } from "../xml-components"; import { Run } from "../../run";
import { Attributes, XmlComponent } from "../../xml-components";
class Break extends XmlComponent { class Break extends XmlComponent {

View File

@ -1,6 +1,6 @@
import { expect } from "chai"; import { expect } from "chai";
import { Formatter } from "../../export/formatter"; import { Formatter } from "../../../export/formatter";
import { Spacing } from "./spacing"; import { Spacing } from "./spacing";
describe("Spacing", () => { describe("Spacing", () => {

View File

@ -1,4 +1,5 @@
import { XmlAttributeComponent, XmlComponent } from "../xml-components"; // http://officeopenxml.com/WPspacing.php
import { XmlAttributeComponent, XmlComponent } from "../../xml-components";
export interface ISpacingProperties { export interface ISpacingProperties {
after?: number; after?: number;

View File

@ -1,6 +1,6 @@
import { assert } from "chai"; import { assert } from "chai";
import { Utility } from "../../tests/utility"; import { Utility } from "../../../tests/utility";
import { Style } from "./style"; import { Style } from "./style";
describe("ParagraphStyle", () => { describe("ParagraphStyle", () => {

View File

@ -1,4 +1,4 @@
import { Attributes, XmlComponent } from "../xml-components"; import { Attributes, XmlComponent } from "../../xml-components";
export class Style extends XmlComponent { export class Style extends XmlComponent {

View File

@ -1,6 +1,6 @@
import { assert } from "chai"; import { assert } from "chai";
import { Utility } from "../../tests/utility"; import { Utility } from "../../../tests/utility";
import { LeftTabStop, MaxRightTabStop } from "./tab-stop"; import { LeftTabStop, MaxRightTabStop } from "./tab-stop";
describe("LeftTabStop", () => { describe("LeftTabStop", () => {

View File

@ -1,4 +1,5 @@
import { XmlAttributeComponent, XmlComponent } from "../xml-components"; // http://officeopenxml.com/WPtab.php
import { XmlAttributeComponent, XmlComponent } from "../../xml-components";
export class TabStop extends XmlComponent { export class TabStop extends XmlComponent {
@ -8,15 +9,15 @@ export class TabStop extends XmlComponent {
} }
} }
export type TabOptions = "left" | "right"; export type TabValue = "left" | "right" | "center" | "bar" | "clear" | "decimal" | "end" | "num" | "start";
export class TabAttributes extends XmlAttributeComponent<{val: TabOptions, pos: string | number}> { export class TabAttributes extends XmlAttributeComponent<{val: TabValue, pos: string | number}> {
protected xmlKeys = {val: "w:val", pos: "w:pos"}; protected xmlKeys = {val: "w:val", pos: "w:pos"};
} }
export class Tab extends XmlComponent { export class Tab extends XmlComponent {
constructor(value: TabOptions, position: string | number) { constructor(value: TabValue, position: string | number) {
super("w:tab"); super("w:tab");
this.root.push(new TabAttributes({ this.root.push(new TabAttributes({
val: value, val: value,
@ -36,3 +37,15 @@ export class LeftTabStop extends TabStop {
super(new Tab("left", position)); super(new Tab("left", position));
} }
} }
export class RightTabStop extends TabStop {
constructor(position: number) {
super(new Tab("right", position));
}
}
export class CenterTabStop extends TabStop {
constructor(position: number) {
super(new Tab("center", position));
}
}

View File

@ -1,6 +1,6 @@
import { assert } from "chai"; import { assert } from "chai";
import { Utility } from "../../tests/utility"; import { Utility } from "../../../tests/utility";
import { NumberProperties } from "./unordered-list"; import { NumberProperties } from "./unordered-list";
describe("NumberProperties", () => { describe("NumberProperties", () => {

View File

@ -1,4 +1,4 @@
import { Attributes, XmlComponent } from "../xml-components"; import { Attributes, XmlComponent } from "../../xml-components";
export class NumberProperties extends XmlComponent { export class NumberProperties extends XmlComponent {

View File

@ -1,156 +1,3 @@
import { IData } from "../../media/data";
import { Num } from "../../numbering/num";
import { Run } from "../run";
import { PictureRun } from "../run/picture-run";
import { TextRun } from "../run/text-run";
import { XmlComponent } from "../xml-components";
import { Alignment } from "./alignment";
import { ThematicBreak } from "./border";
import { Indent } from "./indent";
import { KeepLines, KeepNext } from "./keep";
import { PageBreak } from "./page-break";
import { ParagraphProperties } from "./properties";
import { ISpacingProperties, Spacing } from "./spacing";
import { Style } from "./style";
import { LeftTabStop, MaxRightTabStop } from "./tab-stop";
import { NumberProperties } from "./unordered-list";
export * from "./formatting"; export * from "./formatting";
export * from "./paragraph";
export class Paragraph extends XmlComponent { export * from "./properties";
private properties: ParagraphProperties;
constructor(text?: string) {
super("w:p");
this.properties = new ParagraphProperties();
this.root.push(this.properties);
if (text !== undefined) {
this.root.push(new TextRun(text));
}
}
public addRun(run: Run): Paragraph {
this.root.push(run);
return this;
}
public createTextRun(text: string): TextRun {
const run = new TextRun(text);
this.addRun(run);
return run;
}
public createPictureRun(imageData: IData): PictureRun {
const run = new PictureRun(imageData);
this.addRun(run);
return run;
}
public heading1(): Paragraph {
this.properties.push(new Style("Heading1"));
return this;
}
public heading2(): Paragraph {
this.properties.push(new Style("Heading2"));
return this;
}
public heading3(): Paragraph {
this.properties.push(new Style("Heading3"));
return this;
}
public heading4(): Paragraph {
this.properties.push(new Style("Heading4"));
return this;
}
public heading5(): Paragraph {
this.properties.push(new Style("Heading5"));
return this;
}
public title(): Paragraph {
this.properties.push(new Style("Title"));
return this;
}
public center(): Paragraph {
this.properties.push(new Alignment("center"));
return this;
}
public left(): Paragraph {
this.properties.push(new Alignment("left"));
return this;
}
public right(): Paragraph {
this.properties.push(new Alignment("right"));
return this;
}
public justified(): Paragraph {
this.properties.push(new Alignment("both"));
return this;
}
public thematicBreak(): Paragraph {
this.properties.push(new ThematicBreak());
return this;
}
public pageBreak(): Paragraph {
this.root.push(new PageBreak());
return this;
}
public maxRightTabStop(): Paragraph {
this.properties.push(new MaxRightTabStop());
return this;
}
public leftTabStop(position: number): Paragraph {
this.properties.push(new LeftTabStop(position));
return this;
}
public bullet(): Paragraph {
this.properties.push(new Style("ListParagraph"));
this.properties.push(new NumberProperties(1, 0));
return this;
}
public setNumbering(numbering: Num, indentLevel: number): Paragraph {
this.properties.push(new Style("ListParagraph"));
this.properties.push(new NumberProperties(numbering.id, indentLevel));
return this;
}
public style(styleId: string): Paragraph {
this.properties.push(new Style(styleId));
return this;
}
public indent(attrs: object): Paragraph {
this.properties.push(new Indent(attrs));
return this;
}
public spacing(params: ISpacingProperties): Paragraph {
this.properties.push(new Spacing(params));
return this;
}
public keepNext(): Paragraph {
this.properties.push(new KeepNext());
return this;
}
public keepLines(): Paragraph {
this.properties.push(new KeepLines());
return this;
}
}

View File

@ -0,0 +1,165 @@
// http://officeopenxml.com/WPparagraph.php
import { IData } from "../../media/data";
import { Num } from "../../numbering/num";
import { Run } from "../run";
import { PictureRun } from "../run/picture-run";
import { TextRun } from "../run/text-run";
import { XmlComponent } from "../xml-components";
import { Alignment } from "./formatting/alignment";
import { ThematicBreak } from "./formatting/border";
import { Indent } from "./formatting/indent";
import { KeepLines, KeepNext } from "./formatting/keep";
import { PageBreak } from "./formatting/page-break";
import { ISpacingProperties, Spacing } from "./formatting/spacing";
import { Style } from "./formatting/style";
import { CenterTabStop, LeftTabStop, MaxRightTabStop, RightTabStop } from "./formatting/tab-stop";
import { NumberProperties } from "./formatting/unordered-list";
import { ParagraphProperties } from "./properties";
export class Paragraph extends XmlComponent {
private properties: ParagraphProperties;
constructor(text?: string) {
super("w:p");
this.properties = new ParagraphProperties();
this.root.push(this.properties);
if (text !== undefined) {
this.root.push(new TextRun(text));
}
}
public addRun(run: Run): Paragraph {
this.root.push(run);
return this;
}
public createTextRun(text: string): TextRun {
const run = new TextRun(text);
this.addRun(run);
return run;
}
public createPictureRun(imageData: IData): PictureRun {
const run = new PictureRun(imageData);
this.addRun(run);
return run;
}
public heading1(): Paragraph {
this.properties.push(new Style("Heading1"));
return this;
}
public heading2(): Paragraph {
this.properties.push(new Style("Heading2"));
return this;
}
public heading3(): Paragraph {
this.properties.push(new Style("Heading3"));
return this;
}
public heading4(): Paragraph {
this.properties.push(new Style("Heading4"));
return this;
}
public heading5(): Paragraph {
this.properties.push(new Style("Heading5"));
return this;
}
public title(): Paragraph {
this.properties.push(new Style("Title"));
return this;
}
public center(): Paragraph {
this.properties.push(new Alignment("center"));
return this;
}
public left(): Paragraph {
this.properties.push(new Alignment("left"));
return this;
}
public right(): Paragraph {
this.properties.push(new Alignment("right"));
return this;
}
public justified(): Paragraph {
this.properties.push(new Alignment("both"));
return this;
}
public thematicBreak(): Paragraph {
this.properties.push(new ThematicBreak());
return this;
}
public pageBreak(): Paragraph {
this.root.push(new PageBreak());
return this;
}
public maxRightTabStop(): Paragraph {
this.properties.push(new MaxRightTabStop());
return this;
}
public leftTabStop(position: number): Paragraph {
this.properties.push(new LeftTabStop(position));
return this;
}
public rightTabStop(position: number): Paragraph {
this.properties.push(new RightTabStop(position));
return this;
}
public centerTabStop(position: number): Paragraph {
this.properties.push(new CenterTabStop(position));
return this;
}
public bullet(): Paragraph {
this.properties.push(new Style("ListParagraph"));
this.properties.push(new NumberProperties(1, 0));
return this;
}
public setNumbering(numbering: Num, indentLevel: number): Paragraph {
this.properties.push(new Style("ListParagraph"));
this.properties.push(new NumberProperties(numbering.id, indentLevel));
return this;
}
public style(styleId: string): Paragraph {
this.properties.push(new Style(styleId));
return this;
}
public indent(attrs: object): Paragraph {
this.properties.push(new Indent(attrs));
return this;
}
public spacing(params: ISpacingProperties): Paragraph {
this.properties.push(new Spacing(params));
return this;
}
public keepNext(): Paragraph {
this.properties.push(new KeepNext());
return this;
}
public keepLines(): Paragraph {
this.properties.push(new KeepLines());
return this;
}
}

View File

@ -1,3 +1,4 @@
// http://officeopenxml.com/WPparagraphProperties.php
import { XmlComponent } from "../xml-components"; import { XmlComponent } from "../xml-components";
export class ParagraphProperties extends XmlComponent { export class ParagraphProperties extends XmlComponent {

View File

@ -1,3 +0,0 @@
export class Row {
}

View File

@ -1,3 +1,4 @@
// http://officeopenxml.com/WPtextSpecialContent-break.php
import { XmlComponent } from "../xml-components"; import { XmlComponent } from "../xml-components";
export class Break extends XmlComponent { export class Break extends XmlComponent {

View File

@ -1,96 +1,3 @@
import { Break } from "./break"; export * from "./run";
import { Caps, SmallCaps } from "./caps"; export * from "./text-run";
import { Bold, Color, DoubleStrike, Italics, Size, Strike } from "./formatting"; export * from "./picture-run";
import { RunProperties } from "./properties";
import { RunFonts } from "./run-fonts";
import { SubScript, SuperScript } from "./script";
import { Style } from "./style";
import { Tab } from "./tab";
import { Underline } from "./underline";
import { XmlComponent } from "../xml-components";
export class Run extends XmlComponent {
private properties: RunProperties;
constructor() {
super("w:r");
this.properties = new RunProperties();
this.root.push(this.properties);
}
public bold(): Run {
this.properties.push(new Bold());
return this;
}
public italic(): Run {
this.properties.push(new Italics());
return this;
}
public underline(underlineType?: string, color?: string): Run {
this.properties.push(new Underline(underlineType, color));
return this;
}
public color(color: string): Run {
this.properties.push(new Color(color));
return this;
}
public size(size: number): Run {
this.properties.push(new Size(size));
return this;
}
public break(): Run {
this.root.splice(1, 0, new Break());
return this;
}
public tab(): Run {
this.root.splice(1, 0, new Tab());
return this;
}
public smallCaps(): Run {
this.properties.push(new SmallCaps());
return this;
}
public allCaps(): Run {
this.properties.push(new Caps());
return this;
}
public strike(): Run {
this.properties.push(new Strike());
return this;
}
public doubleStrike(): Run {
this.properties.push(new DoubleStrike());
return this;
}
public subScript(): Run {
this.properties.push(new SubScript());
return this;
}
public superScript(): Run {
this.properties.push(new SuperScript());
return this;
}
public font(fontName: string): Run {
this.properties.push(new RunFonts(fontName));
return this;
}
public style(styleId: string): Run {
this.properties.push(new Style(styleId));
return this;
}
}

97
ts/docx/run/run.ts Normal file
View File

@ -0,0 +1,97 @@
// http://officeopenxml.com/WPtext.php
import { Break } from "./break";
import { Caps, SmallCaps } from "./caps";
import { Bold, Color, DoubleStrike, Italics, Size, Strike } from "./formatting";
import { RunProperties } from "./properties";
import { RunFonts } from "./run-fonts";
import { SubScript, SuperScript } from "./script";
import { Style } from "./style";
import { Tab } from "./tab";
import { Underline } from "./underline";
import { XmlComponent } from "../xml-components";
export class Run extends XmlComponent {
private properties: RunProperties;
constructor() {
super("w:r");
this.properties = new RunProperties();
this.root.push(this.properties);
}
public bold(): Run {
this.properties.push(new Bold());
return this;
}
public italic(): Run {
this.properties.push(new Italics());
return this;
}
public underline(underlineType?: string, color?: string): Run {
this.properties.push(new Underline(underlineType, color));
return this;
}
public color(color: string): Run {
this.properties.push(new Color(color));
return this;
}
public size(size: number): Run {
this.properties.push(new Size(size));
return this;
}
public break(): Run {
this.root.splice(1, 0, new Break());
return this;
}
public tab(): Run {
this.root.splice(1, 0, new Tab());
return this;
}
public smallCaps(): Run {
this.properties.push(new SmallCaps());
return this;
}
public allCaps(): Run {
this.properties.push(new Caps());
return this;
}
public strike(): Run {
this.properties.push(new Strike());
return this;
}
public doubleStrike(): Run {
this.properties.push(new DoubleStrike());
return this;
}
public subScript(): Run {
this.properties.push(new SubScript());
return this;
}
public superScript(): Run {
this.properties.push(new SuperScript());
return this;
}
public font(fontName: string): Run {
this.properties.push(new RunFonts(fontName));
return this;
}
public style(styleId: string): Run {
this.properties.push(new Style(styleId));
return this;
}
}

View File

@ -1,123 +1 @@
import { Paragraph } from "../paragraph"; export * from "./table";
import { XmlComponent } from "../xml-components";
import { IXmlableObject } from "../xml-components/xmlable-object";
import { TableGrid } from "./grid";
import { TableProperties, WidthTypes } from "./properties";
export class Table extends XmlComponent {
private properties: TableProperties;
private rows: TableRow[];
private grid: TableGrid;
constructor(rows: number, cols: number) {
super("w:tbl");
this.properties = new TableProperties();
this.root.push(this.properties);
const gridCols: number[] = [];
for (let i = 0; i < cols; i++) {
/*
0-width columns don't get rendered correctly, so we need
to give them some value. A reasonable default would be
~6in / numCols, but if we do that it becomes very hard
to resize the table using setWidth, unless the layout
algorithm is set to 'fixed'. Instead, the approach here
means even in 'auto' layout, setting a width on the
table will make it look reasonable, as the layout
algorithm will expand columns to fit its content
*/
gridCols.push(1);
}
this.grid = new TableGrid(gridCols);
this.root.push(this.grid);
this.rows = [];
for (let i = 0; i < rows; i++) {
const cells: TableCell[] = [];
for (let j = 0; j < cols; j++) {
cells.push(new TableCell());
}
const row = new TableRow(cells);
this.rows.push(row);
this.root.push(row);
}
}
public getRow(ix: number): TableRow {
return this.rows[ix];
}
public getCell(row: number, col: number): TableCell {
return this.getRow(row).getCell(col);
}
public setWidth(type: WidthTypes, width: number | string): Table {
this.properties.setWidth(type, width);
return this;
}
public fixedWidthLayout(): Table {
this.properties.fixedWidthLayout();
return this;
}
}
export class TableRow extends XmlComponent {
private properties: TableRowProperties;
private cells: TableCell[];
constructor(cells: TableCell[]) {
super("w:tr");
this.properties = new TableRowProperties();
this.root.push(this.properties);
this.cells = cells;
cells.forEach((c) => this.root.push(c));
}
public getCell(ix: number): TableCell {
return this.cells[ix];
}
}
export class TableRowProperties extends XmlComponent {
constructor() {
super("w:trPr");
}
}
export class TableCell extends XmlComponent {
private properties: TableCellProperties;
constructor() {
super("w:tc");
this.properties = new TableCellProperties();
this.root.push(this.properties);
}
public addContent(content: Paragraph | Table): TableCell {
this.root.push(content);
return this;
}
public prepForXml(): IXmlableObject {
// Cells must end with a paragraph
const retval = super.prepForXml();
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addContent(para);
return para;
}
}
export class TableCellProperties extends XmlComponent {
constructor() {
super("w:tcPr");
}
}

123
ts/docx/table/table.ts Normal file
View File

@ -0,0 +1,123 @@
import { Paragraph } from "../paragraph";
import { XmlComponent } from "../xml-components";
import { IXmlableObject } from "../xml-components/xmlable-object";
import { TableGrid } from "./grid";
import { TableProperties, WidthTypes } from "./properties";
export class Table extends XmlComponent {
private properties: TableProperties;
private rows: TableRow[];
private grid: TableGrid;
constructor(rows: number, cols: number) {
super("w:tbl");
this.properties = new TableProperties();
this.root.push(this.properties);
const gridCols: number[] = [];
for (let i = 0; i < cols; i++) {
/*
0-width columns don't get rendered correctly, so we need
to give them some value. A reasonable default would be
~6in / numCols, but if we do that it becomes very hard
to resize the table using setWidth, unless the layout
algorithm is set to 'fixed'. Instead, the approach here
means even in 'auto' layout, setting a width on the
table will make it look reasonable, as the layout
algorithm will expand columns to fit its content
*/
gridCols.push(1);
}
this.grid = new TableGrid(gridCols);
this.root.push(this.grid);
this.rows = [];
for (let i = 0; i < rows; i++) {
const cells: TableCell[] = [];
for (let j = 0; j < cols; j++) {
cells.push(new TableCell());
}
const row = new TableRow(cells);
this.rows.push(row);
this.root.push(row);
}
}
public getRow(ix: number): TableRow {
return this.rows[ix];
}
public getCell(row: number, col: number): TableCell {
return this.getRow(row).getCell(col);
}
public setWidth(type: WidthTypes, width: number | string): Table {
this.properties.setWidth(type, width);
return this;
}
public fixedWidthLayout(): Table {
this.properties.fixedWidthLayout();
return this;
}
}
export class TableRow extends XmlComponent {
private properties: TableRowProperties;
private cells: TableCell[];
constructor(cells: TableCell[]) {
super("w:tr");
this.properties = new TableRowProperties();
this.root.push(this.properties);
this.cells = cells;
cells.forEach((c) => this.root.push(c));
}
public getCell(ix: number): TableCell {
return this.cells[ix];
}
}
export class TableRowProperties extends XmlComponent {
constructor() {
super("w:trPr");
}
}
export class TableCell extends XmlComponent {
private properties: TableCellProperties;
constructor() {
super("w:tc");
this.properties = new TableCellProperties();
this.root.push(this.properties);
}
public addContent(content: Paragraph | Table): TableCell {
this.root.push(content);
return this;
}
public prepForXml(): IXmlableObject {
// Cells must end with a paragraph
const retval = super.prepForXml();
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addContent(para);
return para;
}
}
export class TableCellProperties extends XmlComponent {
constructor() {
super("w:tcPr");
}
}

View File

@ -1,27 +1,3 @@
import { BaseXmlComponent } from "./base"; export * from "./xml-component";
import { IXmlableObject } from "./xmlable-object";
export { BaseXmlComponent };
export abstract class XmlComponent extends BaseXmlComponent {
protected root: Array<BaseXmlComponent | string>;
constructor(rootKey: string) {
super(rootKey);
this.root = new Array<BaseXmlComponent>();
}
public prepForXml(): IXmlableObject {
const children = this.root.map((comp) => {
if (comp instanceof BaseXmlComponent) {
return comp.prepForXml();
}
return comp;
}).filter((comp) => comp); // Exclude null, undefined, and empty strings
return {
[this.rootKey]: children,
};
}
}
export * from "./attributes"; export * from "./attributes";
export * from "./default-attributes"; export * from "./default-attributes";

View File

@ -0,0 +1,24 @@
import { BaseXmlComponent } from "./base";
import { IXmlableObject } from "./xmlable-object";
export { BaseXmlComponent };
export abstract class XmlComponent extends BaseXmlComponent {
protected root: Array<BaseXmlComponent | string>;
constructor(rootKey: string) {
super(rootKey);
this.root = new Array<BaseXmlComponent>();
}
public prepForXml(): IXmlableObject {
const children = this.root.map((comp) => {
if (comp instanceof BaseXmlComponent) {
return comp.prepForXml();
}
return comp;
}).filter((comp) => comp); // Exclude null, undefined, and empty strings
return {
[this.rootKey]: children,
};
}
}

View File

@ -1,3 +1,3 @@
export { LocalPacker } from "./packer/local"; export * from "./packer/local";
export { ExpressPacker } from "./packer/express"; export * from "./packer/express";
export { Packer } from "./packer/packer"; export * from "./packer/packer";

View File

@ -0,0 +1,99 @@
import * as archiver from "archiver";
import * as express from "express";
import * as fs from "fs";
import * as path from "path";
import * as xml from "xml";
import { Document } from "../../docx";
import { Media } from "../../media";
import { Numbering } from "../../numbering";
import { Properties } from "../../properties";
import { Styles } from "../../styles";
import { DefaultStylesFactory } from "../../styles/factory";
import { Formatter } from "../formatter";
const TEMPLATE_PATH = path.resolve(__dirname, "../../../template");
export class Compiler {
protected archive: archiver.Archiver;
private formatter: Formatter;
private style: Styles;
constructor(
protected document: Document,
style?: Styles,
private properties: Properties = new Properties({
creator: "Un-named",
revision: "1",
lastModifiedBy: "Un-named",
}),
private numbering: Numbering = new Numbering(),
private media: Media = new Media(),
) {
this.formatter = new Formatter();
this.archive = archiver.create("zip", {});
if (style) {
this.style = style;
} else {
const stylesFactory = new DefaultStylesFactory();
this.style = stylesFactory.newInstance();
}
this.archive.on("error", (err) => {
throw err;
});
}
public async compile(output: fs.WriteStream | express.Response): Promise<void> {
this.archive.pipe(output);
this.archive.glob("**", {
cwd: TEMPLATE_PATH,
});
this.archive.glob("**/.rels", {
cwd: TEMPLATE_PATH,
});
const xmlDocument = xml(this.formatter.format(this.document));
const xmlStyles = xml(this.formatter.format(this.style));
const xmlProperties = xml(this.formatter.format(this.properties), {
declaration: {
standalone: "yes",
encoding: "UTF-8",
},
});
const xmlNumbering = xml(this.formatter.format(this.numbering));
this.archive.append(xmlDocument, {
name: "word/document.xml",
});
this.archive.append(xmlStyles, {
name: "word/styles.xml",
});
this.archive.append(xmlProperties, {
name: "docProps/core.xml",
});
this.archive.append(xmlNumbering, {
name: "word/numbering.xml",
});
for (const data of this.media.array) {
this.archive.append(data.stream, {
name: `media/${data.fileName}`,
});
}
this.archive.finalize();
return new Promise<void>((resolve) => {
output.on("close", () => {
resolve();
});
});
}
}

View File

@ -1,16 +1,20 @@
import * as express from "express"; import * as express from "express";
import { Document } from "../../docx/document"; import { Document } from "../../docx/document";
import { Media } from "../../media"; import { Media } from "../../media";
import { Numbering } from "../../numbering"; import { Numbering } from "../../numbering";
import { Properties } from "../../properties"; import { Properties } from "../../properties";
import { Styles } from "../../styles"; import { Styles } from "../../styles";
import { Packer } from "./packer"; import { Compiler } from "./compiler";
import { IPacker } from "./packer";
export class ExpressPacker extends Packer { export class ExpressPacker implements IPacker {
private res: express.Response; private res: express.Response;
private packer: Compiler;
constructor(document: Document, res: express.Response, styles?: Styles, properties?: Properties, numbering?: Numbering, media?: Media) { constructor(document: Document, res: express.Response, styles?: Styles, properties?: Properties, numbering?: Numbering, media?: Media) {
super(document, styles, properties, numbering, media); this.packer = new Compiler(document, styles, properties, numbering, media);
this.res = res; this.res = res;
this.res.on("close", () => { this.res.on("close", () => {
@ -18,8 +22,10 @@ export class ExpressPacker extends Packer {
}); });
} }
public pack(name: string): void { public async pack(name: string): Promise<void> {
name = name.replace(/.docx$/, "");
this.res.attachment(`${name}.docx`); this.res.attachment(`${name}.docx`);
super.compile(this.res); await this.packer.compile(this.res);
} }
} }

View File

@ -1,4 +1,4 @@
import { assert } from "chai"; /* tslint:disable:typedef space-before-function-paren */
import * as fs from "fs"; import * as fs from "fs";
import { Document } from "../../docx/document"; import { Document } from "../../docx/document";
@ -7,7 +7,7 @@ import { LocalPacker } from "../../export/packer/local";
import { Properties } from "../../properties"; import { Properties } from "../../properties";
import { DefaultStylesFactory } from "../../styles/factory"; import { DefaultStylesFactory } from "../../styles/factory";
describe("Packer", () => { describe("LocalPacker", () => {
let packer: LocalPacker; let packer: LocalPacker;
let stylesFactory: DefaultStylesFactory; let stylesFactory: DefaultStylesFactory;
@ -29,27 +29,19 @@ describe("Packer", () => {
}); });
describe("#pack()", () => { describe("#pack()", () => {
/* tslint:disable */ it("should create a standard docx file", async function () {
it("should create a standard docx file", function (done) {
/* tslint:enable */
this.timeout(99999999); this.timeout(99999999);
packer.pack("build-tests/tests/test.docx"); await packer.pack("build-tests/tests/test");
const int = setInterval(() => { fs.statSync("build-tests/tests/test.docx");
const stats = fs.statSync("build-tests/tests/test.docx"); });
if (stats.size > 2000) { });
clearInterval(int);
clearTimeout(out); describe("#packPdf", () => {
done(); it("should create a standard PDF file", async function () {
} this.timeout(99999999);
}, 1000);
const out = setTimeout(() => { await packer.packPdf("build-tests/tests/pdf-test");
clearInterval(int); fs.statSync("build-tests/tests/pdf-test.pdf");
try {
assert(false, "did not create a file within the alloted time");
} catch (e) {
done(e);
}
}, 2000);
}); });
}); });
}); });

View File

@ -1,21 +1,52 @@
import * as fs from "fs"; import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { Document } from "../../docx/document"; import { Document } from "../../docx/document";
import { Media } from "../../media"; import { Media } from "../../media";
import { Numbering } from "../../numbering"; import { Numbering } from "../../numbering";
import { Properties } from "../../properties"; import { Properties } from "../../properties";
import { Styles } from "../../styles"; import { Styles } from "../../styles";
import { Packer } from "./packer"; import { Compiler } from "./compiler";
import { IPacker } from "./packer";
import { PdfConvertWrapper } from "./pdf-convert-wrapper";
export class LocalPacker extends Packer { export class LocalPacker implements IPacker {
private stream: fs.WriteStream; private stream: fs.WriteStream;
private pdfConverter: PdfConvertWrapper;
private packer: Compiler;
constructor(document: Document, styles?: Styles, properties?: Properties, numbering?: Numbering, media?: Media) { constructor(document: Document, styles?: Styles, properties?: Properties, numbering?: Numbering, media?: Media) {
super(document, styles, properties, numbering, media); this.pdfConverter = new PdfConvertWrapper();
this.packer = new Compiler(document, styles, properties, numbering, media);
} }
public pack(path: string): void { public async pack(filePath: string): Promise<void> {
path = path.replace(/.docx$/, ""); filePath = filePath.replace(/.docx$/, "");
this.stream = fs.createWriteStream(`${path}.docx`);
super.compile(this.stream); this.stream = fs.createWriteStream(`${filePath}.docx`);
await this.packer.compile(this.stream);
}
public async packPdf(filePath: string): Promise<void> {
filePath = filePath.replace(/.pdf$/, "");
const fileName = path.basename(filePath, path.extname(filePath));
const tempPath = path.join(os.tmpdir(), `${fileName}.docx`);
this.stream = fs.createWriteStream(tempPath);
await this.packer.compile(this.stream);
const text = await this.pdfConverter.convert(tempPath);
// const writeFile = util.promisify(fs.writeFile); --use this in future, in 3 years time. Only in node 8
// return writeFile(`${filePath}.pdf`, text);
return new Promise<void>((resolve, reject) => {
fs.writeFile(`${filePath}.pdf`, text, (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
} }
} }

View File

@ -1,91 +1,3 @@
import * as archiver from "archiver"; export interface IPacker {
import * as express from "express"; pack(path: string): void;
import * as fs from "fs";
import * as path from "path";
import * as xml from "xml";
import { Document } from "../../docx";
import { Media } from "../../media";
import { Numbering } from "../../numbering";
import { Properties } from "../../properties";
import { Styles } from "../../styles";
import { DefaultStylesFactory } from "../../styles/factory";
import { Formatter } from "../formatter";
const TEMPLATE_PATH = path.resolve(__dirname, "../../../template");
export abstract class Packer {
protected archive: archiver.Archiver;
private formatter: Formatter;
private style: Styles;
constructor(
protected document: Document,
style?: Styles,
private properties: Properties = new Properties({
creator: "Un-named",
revision: "1",
lastModifiedBy: "Un-named",
}),
private numbering: Numbering = new Numbering(),
private media: Media = new Media(),
) {
this.formatter = new Formatter();
this.archive = archiver.create("zip", {});
if (style) {
this.style = style;
} else {
const stylesFactory = new DefaultStylesFactory();
this.style = stylesFactory.newInstance();
}
this.archive.on("error", (err) => {
throw err;
});
}
protected compile(output: fs.WriteStream | express.Response): void {
this.archive.pipe(output);
this.archive.glob("**", {
cwd: TEMPLATE_PATH,
});
this.archive.glob("**/.rels", {
cwd: TEMPLATE_PATH,
});
const xmlDocument = xml(this.formatter.format(this.document));
const xmlStyles = xml(this.formatter.format(this.style));
const xmlProperties = xml(this.formatter.format(this.properties), {
declaration: {
standalone: "yes",
encoding: "UTF-8",
},
});
const xmlNumbering = xml(this.formatter.format(this.numbering));
this.archive.append(xmlDocument, {
name: "word/document.xml",
});
this.archive.append(xmlStyles, {
name: "word/styles.xml",
});
this.archive.append(xmlProperties, {
name: "docProps/core.xml",
});
this.archive.append(xmlNumbering, {
name: "word/numbering.xml",
});
for (const data of this.media.array) {
this.archive.append(data.stream, {
name: `media/${data.fileName}`,
});
}
this.archive.finalize();
}
} }

View File

@ -0,0 +1,34 @@
/* tslint:disable:object-literal-key-quotes */
// This tslint disable is needed, or it simply won't work
import * as fs from "fs";
import * as request from "request-promise";
export interface IConvertOutput {
data: string;
}
export class PdfConvertWrapper {
public convert(filePath: string): request.RequestPromise {
return request.post({
url: "http://mirror1.convertonlinefree.com",
encoding: null,
headers: {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36",
},
formData: {
"__EVENTTARGET": "",
"__EVENTARGUMENT": "",
"__VIEWSTATE": "",
"ctl00$MainContent$fu": {
value: fs.readFileSync(filePath),
options: {
filename: "output.docx",
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
},
},
"ctl00$MainContent$btnConvert": "Convert",
"ctl00$MainContent$fuZip": "",
},
});
}
}

View File

@ -1,87 +1 @@
import { DocumentAttributes } from "../docx/document/document-attributes"; export * from "./numbering";
import { Indent } from "../docx/paragraph/indent";
import { RunFonts } from "../docx/run/run-fonts";
import { XmlComponent } from "../docx/xml-components";
import { AbstractNumbering } from "./abstract-numbering";
import { Num } from "./num";
export class Numbering extends XmlComponent {
private nextId: number;
constructor() {
super("w:numbering");
this.root.push(new DocumentAttributes({
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
v: "urn:schemas-microsoft-com:vml",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
w10: "urn:schemas-microsoft-com:office:word",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
Ignorable: "w14 w15 wp14",
}));
this.nextId = 0;
const abstractNumbering = this.createAbstractNumbering();
abstractNumbering.createLevel(0, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 720, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(1, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 1440, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(2, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 2160, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
abstractNumbering.createLevel(3, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 2880, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(4, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 3600, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(5, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 4320, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
abstractNumbering.createLevel(6, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 5040, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(7, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 5760, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(8, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 6480, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
this.createConcreteNumbering(abstractNumbering);
}
public createAbstractNumbering(): AbstractNumbering {
const num = new AbstractNumbering(this.nextId++);
this.root.push(num);
return num;
}
public createConcreteNumbering(abstractNumbering: AbstractNumbering): Num {
const num = new Num(this.nextId++, abstractNumbering.id);
this.root.push(num);
return num;
}
}

87
ts/numbering/numbering.ts Normal file
View File

@ -0,0 +1,87 @@
import { DocumentAttributes } from "../docx/document/document-attributes";
import { Indent } from "../docx/paragraph/formatting";
import { RunFonts } from "../docx/run/run-fonts";
import { XmlComponent } from "../docx/xml-components";
import { AbstractNumbering } from "./abstract-numbering";
import { Num } from "./num";
export class Numbering extends XmlComponent {
private nextId: number;
constructor() {
super("w:numbering");
this.root.push(new DocumentAttributes({
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
v: "urn:schemas-microsoft-com:vml",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
w10: "urn:schemas-microsoft-com:office:word",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
Ignorable: "w14 w15 wp14",
}));
this.nextId = 0;
const abstractNumbering = this.createAbstractNumbering();
abstractNumbering.createLevel(0, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 720, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(1, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 1440, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(2, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 2160, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
abstractNumbering.createLevel(3, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 2880, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(4, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 3600, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(5, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 4320, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
abstractNumbering.createLevel(6, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 5040, hanging: 360 }))
.addRunProperty(new RunFonts("Symbol", "default"));
abstractNumbering.createLevel(7, "bullet", "o", "left")
.addParagraphProperty(new Indent({ left: 5760, hanging: 360 }))
.addRunProperty(new RunFonts("Courier New", "default"));
abstractNumbering.createLevel(8, "bullet", "•", "left")
.addParagraphProperty(new Indent({ left: 6480, hanging: 360 }))
.addRunProperty(new RunFonts("Wingdings", "default"));
this.createConcreteNumbering(abstractNumbering);
}
public createAbstractNumbering(): AbstractNumbering {
const num = new AbstractNumbering(this.nextId++);
this.root.push(num);
return num;
}
public createConcreteNumbering(abstractNumbering: AbstractNumbering): Num {
const num = new Num(this.nextId++, abstractNumbering.id);
this.root.push(num);
return num;
}
}

View File

@ -1,4 +1,4 @@
import * as paragraph from "../../docx/paragraph/formatting"; import * as paragraph from "../../docx/paragraph";
import * as formatting from "../../docx/run/formatting"; import * as formatting from "../../docx/run/formatting";
import { RunProperties } from "../../docx/run/properties"; import { RunProperties } from "../../docx/run/properties";
import { XmlAttributeComponent, XmlComponent } from "../../docx/xml-components"; import { XmlAttributeComponent, XmlComponent } from "../../docx/xml-components";

View File

@ -8,7 +8,8 @@
"outDir": "../build-tests", "outDir": "../build-tests",
"sourceRoot": "./", "sourceRoot": "./",
"rootDir": "./", "rootDir": "./",
"module": "commonjs" "module": "commonjs",
"noUnusedLocals": true
}, },
"include": [ "include": [
"**/*.spec.ts", "**/*.spec.ts",

View File

@ -1,18 +0,0 @@
/* tslint:disable */
import { assert } from "chai";
import { Utility } from "./utility";
/* tslint:enable */
describe("", () => {
beforeEach(() => {
// TODO
});
describe("#methodName()", () => {
it("should ", () => {
// TODO
});
});
});

View File

@ -9,7 +9,8 @@
"sourceRoot": "./", "sourceRoot": "./",
"rootDir": "./", "rootDir": "./",
"module": "commonjs", "module": "commonjs",
"declaration": true "declaration": true,
"noUnusedLocals": true
}, },
"exclude": [ "exclude": [
"tests", "tests",

View File

@ -33,6 +33,7 @@
], ],
"no-unused-variable": [ "no-unused-variable": [
true true
] ],
"no-implicit-dependencies": false
} }
} }