Merge branch 'master' into image-support
This commit is contained in:
318
README.md
318
README.md
@ -3,55 +3,24 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Generate .docx files with JS/TS very easily
|
Generate .docx files with JS/TS very easily, written in TS.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
=====
|
=====
|
||||||
|
|
||||||
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Known Vulnerabilities][snky-image]][snky-url]
|
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][gemnasium-image]][gemnasium-url] [![Known Vulnerabilities][snky-image]][snky-url] [![Chat on Gitter][gitter-image]][gitter-url]
|
||||||
|
|
||||||
# docx
|
|
||||||
> A tool to create Word Documents (.docx) with JS or TS, written in TS.
|
|
||||||
|
|
||||||
[](https://nodei.co/npm/docx/)
|
[](https://nodei.co/npm/docx/)
|
||||||
|
|
||||||
# Table of Contents
|
# docx
|
||||||
- [Install](#)
|
|
||||||
- [Usage](#)
|
|
||||||
- [Create simple Word Document](#)
|
|
||||||
- [Create Paragraph](#)
|
|
||||||
- [Styles](#)
|
|
||||||
- [Heading1 - Heading5](#)
|
|
||||||
- [Title](#)
|
|
||||||
- [Text Alignment](#)
|
|
||||||
- [Example](#)
|
|
||||||
- [Thematic Break (Page Break)](#)
|
|
||||||
- [Text](#)
|
|
||||||
- [Typographical Emphasis](#)
|
|
||||||
- [Bold](#)
|
|
||||||
- [Italics](#)
|
|
||||||
- [Underline](#)
|
|
||||||
- [Break](#)
|
|
||||||
- [Chaining](#)
|
|
||||||
- [Bullet Points](#)
|
|
||||||
- [Tab Stops](#)
|
|
||||||
- [Left Tab Stop](#)
|
|
||||||
- [Center Tab Stop](#)
|
|
||||||
- [Right Tab Stop](#)
|
|
||||||
- [Max Right Tab Stop](#)
|
|
||||||
- [Example](#)
|
|
||||||
- [Exporting](#)
|
|
||||||
- [Express](#)
|
|
||||||
- [Standalone .docx file](#)
|
|
||||||
- [Examples](#)
|
|
||||||
|
|
||||||
# Install
|
## Install
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ npm install --save docx
|
$ npm install --save docx
|
||||||
```
|
```
|
||||||
|
|
||||||
# Demo
|
## Demo
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ npm run demo
|
$ npm run demo
|
||||||
@ -59,8 +28,11 @@ $ npm run demo
|
|||||||
|
|
||||||
will run the demo app in the `demo` folder, which creates a file called "My Document.docx" in the root of the project
|
will run the demo app in the `demo` folder, which creates a file called "My Document.docx" in the root of the project
|
||||||
|
|
||||||
|
## Guide
|
||||||
|
|
||||||
# Usage
|
Please refer to [the Wiki](https://github.com/dolanmiu/docx/wiki) for details on how to use this library, examples and much more!
|
||||||
|
|
||||||
|
## Simple Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Used to create docx files
|
// Used to create docx files
|
||||||
@ -69,264 +41,35 @@ var docx = require('docx');
|
|||||||
// Create document
|
// Create document
|
||||||
var doc = new docx.Document();
|
var doc = new docx.Document();
|
||||||
|
|
||||||
|
// Add some content in the document
|
||||||
|
var paragraph = new docx.Paragraph("Some cool text here.");
|
||||||
|
// Add more text into the paragraph if you wish
|
||||||
|
paragraph.addText(new docx.TextRun('Lorem Ipsum Foo Bar'));
|
||||||
|
doc.addParagraph(paragraph);
|
||||||
|
|
||||||
// Used to export the file into a .docx file
|
// Used to export the file into a .docx file
|
||||||
|
var exporter = new docx.LocalPacker(doc);
|
||||||
|
|
||||||
|
// Or use the express packer to make the file downloadable.
|
||||||
// res is express' Response object
|
// res is express' Response object
|
||||||
var exporter = new docx.ExpressPacker(doc, res);
|
var exporter = new docx.ExpressPacker(doc, res);
|
||||||
var exporter = new docx.LocalPacker(doc);
|
|
||||||
```
|
exporter.pack('My First Document');
|
||||||
## Create simple Word Document
|
|
||||||
```js
|
// done! A file called 'My First Document.docx'
|
||||||
var doc = new docx.Document();
|
// will be in your file system if you used LocalPacker
|
||||||
|
// Or it will start downloading if you are using Express
|
||||||
var paragraph = new docx.Paragraph();
|
|
||||||
var text = new docx.TextRun('Hello World');
|
|
||||||
paragraph.addText(text);
|
|
||||||
doc.addParagraph(paragraph);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Document properties
|
## Examples
|
||||||
You can add properties to the Word document by specifying options, for example:
|
Check [the Wiki](https://github.com/dolanmiu/docx/wiki/Examples) for examples.
|
||||||
```js
|
|
||||||
var doc = new docx.Document({
|
|
||||||
creator: 'Dolan Miu',
|
|
||||||
description: 'My extremely interesting document',
|
|
||||||
title: 'My Document'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Full list of options:
|
|
||||||
```
|
|
||||||
creator
|
|
||||||
description
|
|
||||||
title
|
|
||||||
subject
|
|
||||||
keywords
|
|
||||||
lastModifiedBy
|
|
||||||
revision
|
|
||||||
```
|
|
||||||
|
|
||||||
You can mix and match whatever properties you want, or provide no properties.
|
|
||||||
|
|
||||||
## Create Paragraph
|
|
||||||
Every text block in OpenXML is organised in paragraphs. You can add more text to the paragraph by doing this:
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph(),
|
|
||||||
```
|
|
||||||
```js
|
|
||||||
var text = new docx.TextRun('Lorem Ipsum Foo Bar');
|
|
||||||
var paragraph = new docx.Paragraph();
|
|
||||||
paragraph.addText(text);
|
|
||||||
```
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph("Short hand notation for adding text.");
|
|
||||||
```
|
|
||||||
|
|
||||||
After you create the paragraph, you must add the paragraph into the `document`:
|
|
||||||
```js
|
|
||||||
doc.addParagraph(paragraph);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Styles
|
|
||||||
Styles is a very important part of the look of a word document. At the moment, only headings and title is supported, but son the rest will be supported along with custom styles!
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### Heading1 - Heading5
|
|
||||||
```js
|
|
||||||
paragraph.heading1();
|
|
||||||
paragraph.heading2();
|
|
||||||
paragraph.heading3();
|
|
||||||
paragraph.heading4();
|
|
||||||
paragraph.heading5();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Title
|
|
||||||
```js
|
|
||||||
paragraph.title();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Text Alignment
|
|
||||||
To change the text alignment of a paragraph, for center, left, right or justified:
|
|
||||||
```js
|
|
||||||
paragraph.center();
|
|
||||||
```
|
|
||||||
```js
|
|
||||||
paragraph.left();
|
|
||||||
```
|
|
||||||
```js
|
|
||||||
paragraph.right();
|
|
||||||
```
|
|
||||||
```js
|
|
||||||
paragraph.justified();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example
|
|
||||||
```js
|
|
||||||
paragraph.heading1().center();
|
|
||||||
```
|
|
||||||
The above will create a `heading 1` which is `centered`.
|
|
||||||
|
|
||||||
### Thematic Break
|
|
||||||
To add a break in the page, simply add `.thematicBreak()` on a paragraph:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph("Amazing Heading").heading1().thematicBreak();
|
|
||||||
```
|
|
||||||
The above example will create a heading with a page break directly under it.
|
|
||||||
|
|
||||||
### Page Break
|
|
||||||
To move to a new page (insert a page break), simply add `.pageBreak()` on a paragraph:
|
|
||||||
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph("Amazing Heading").heading1().pageBreak();
|
|
||||||
```
|
|
||||||
The above example will create a heading and start a new page immediately afterwards.
|
|
||||||
|
|
||||||
## Text
|
|
||||||
Paragraphs need `text run` objects. To create text:
|
|
||||||
```js
|
|
||||||
var text = new docx.TextRun("My awesome text here for my university dissertation");
|
|
||||||
paragraph.addText(text);
|
|
||||||
```
|
|
||||||
Text objects have methods inside which changes the way the text is displayed.
|
|
||||||
|
|
||||||
### Typographical Emphasis
|
|
||||||
More info [here](https://english.stackexchange.com/questions/97081/what-is-the-typography-term-which-refers-to-the-usage-of-bold-italics-and-unde)
|
|
||||||
#### Bold
|
|
||||||
```js
|
|
||||||
text.bold();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Italics
|
|
||||||
```js
|
|
||||||
text.italic();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Underline
|
|
||||||
```js
|
|
||||||
text.underline();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Strike through
|
|
||||||
```js
|
|
||||||
text.strike();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Double strike through
|
|
||||||
```js
|
|
||||||
text.doubleStrike();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Superscript
|
|
||||||
```js
|
|
||||||
text.superScript();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Subscript
|
|
||||||
```js
|
|
||||||
text.subScript();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### All Capitals
|
|
||||||
```js
|
|
||||||
text.allCaps();
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Small Capitals
|
|
||||||
```js
|
|
||||||
text.smallCaps();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Break
|
|
||||||
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
|
||||||
```js
|
|
||||||
text.break();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Chaining
|
|
||||||
What if you want to create a paragraph which is ***bold*** and ***italic***?
|
|
||||||
```js
|
|
||||||
paragraph.bold().italic();
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bullet Points
|
|
||||||
To make a bullet point, simply make a paragraph into a bullet point:
|
|
||||||
```js
|
|
||||||
var text = new docx.TextRun("Bullet points");
|
|
||||||
var paragraph = new docx.Paragraph(text).bullet();
|
|
||||||
|
|
||||||
var text2 = new docx.TextRun("Are awesome");
|
|
||||||
var paragraph2 = new docx.Paragraph(text2).bullet();
|
|
||||||
|
|
||||||
doc.addParagraph(paragraph);
|
|
||||||
doc.addParagraph(paragraph2);
|
|
||||||
```
|
|
||||||
This will produce:
|
|
||||||
* Bullet points
|
|
||||||
* Are awesome
|
|
||||||
|
|
||||||
## Tab Stops
|
|
||||||
If you do not know why tab stops are useful, then I recommend you do a bit of research. It enables side by side text which is nicely laid out without the need for tables, or constantly pressing space bar.
|
|
||||||
|
|
||||||
**Note**: At the moment, the unit of measurement for a tab stop is counter intuitive for a human. It is using OpenXMLs own measuring system. For example, 2268 roughly translates to 3cm. Therefore in the future, I may consider changing it to percentages or even cm.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Simply call the relevant methods on the paragraph listed below. Then just add a `tab()` method call to a text object. Adding multiple `tabStops` will mean you would have to chain `tab()` until the desired `tabStop` is selected. Example is shown below.
|
|
||||||
|
|
||||||
### Left Tab Stop
|
|
||||||
```js
|
|
||||||
paragraph.leftTabStop(2268);
|
|
||||||
```
|
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
|
||||||
### Center Tab Stop
|
|
||||||
```js
|
|
||||||
paragraph.centerTabStp(2268);
|
|
||||||
```
|
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
|
||||||
### Right Tab Stop
|
|
||||||
```js
|
|
||||||
paragraph.rightTabStop(2268);
|
|
||||||
```
|
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
|
||||||
### Max Right Tab Stop
|
|
||||||
```js
|
|
||||||
paragraph.maxRightTabStop();
|
|
||||||
```
|
|
||||||
This will create a tab stop on the very edge of the right hand side. Handy for right aligning and left aligning text on the same line.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph().maxRightTabStop();
|
|
||||||
var leftText = new docx.TextRun("Hey everyone").bold();
|
|
||||||
var rightText = new docx.TextRun("11th November 2015").tab();
|
|
||||||
paragraph.addText(leftText);
|
|
||||||
paragraph.addText(rightText);
|
|
||||||
```
|
|
||||||
The example above will create a left aligned text, and a right aligned text on the same line. The laymans approach to this problem would be to either use text boxes or tables. YUK!
|
|
||||||
|
|
||||||
```js
|
|
||||||
var paragraph = new docx.Paragraph();
|
|
||||||
paragraph.maxRightTabStop();
|
|
||||||
paragraph.leftTabStop(1000);
|
|
||||||
var text = new docx.TextRun("Second tab stop here I come!").tab().tab();
|
|
||||||
paragraph.addText(text);
|
|
||||||
```
|
|
||||||
The above shows the use of two tab stops, and how to select/use it.
|
|
||||||
|
|
||||||
# Exporting
|
|
||||||
Check the Wiki for exporting guide
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
Check the Wiki for examples
|
|
||||||
|
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Made with 💖
|
Made with 💖
|
||||||
|
|
||||||
|
Huge thanks to [@felipeochoa](https://github.com/felipeochoa) for awesome contributions to this project
|
||||||
|
|
||||||
[npm-image]: https://badge.fury.io/js/docx.svg
|
[npm-image]: https://badge.fury.io/js/docx.svg
|
||||||
[npm-url]: https://npmjs.org/package/docx
|
[npm-url]: https://npmjs.org/package/docx
|
||||||
[travis-image]: https://travis-ci.org/dolanmiu/docx.svg?branch=master
|
[travis-image]: https://travis-ci.org/dolanmiu/docx.svg?branch=master
|
||||||
@ -335,3 +78,8 @@ Made with 💖
|
|||||||
[daviddm-url]: https://david-dm.org/dolanmiu/docx
|
[daviddm-url]: https://david-dm.org/dolanmiu/docx
|
||||||
[snky-image]: https://snyk.io/test/github/dolanmiu/docx/badge.svg
|
[snky-image]: https://snyk.io/test/github/dolanmiu/docx/badge.svg
|
||||||
[snky-url]: https://snyk.io/test/github/dolanmiu/docx
|
[snky-url]: https://snyk.io/test/github/dolanmiu/docx
|
||||||
|
[gitter-image]: https://badges.gitter.im/dolanmiu/docx.svg
|
||||||
|
[gitter-url]: https://gitter.im/docx-lib/Lobby
|
||||||
|
[gemnasium-image]: https://gemnasium.com/badges/github.com/dolanmiu/docx.svg
|
||||||
|
[gemnasium-url]: https://gemnasium.com/github.com/dolanmiu/docx
|
||||||
|
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts",
|
"ts",
|
||||||
"build"
|
"build",
|
||||||
|
"template"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -28,10 +29,8 @@
|
|||||||
"clippy"
|
"clippy"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/app-root-path": "^1.2.4",
|
|
||||||
"@types/archiver": "^0.15.37",
|
"@types/archiver": "^0.15.37",
|
||||||
"@types/express": "^4.0.35",
|
"@types/express": "^4.0.35",
|
||||||
"app-root-path": "^2.0.1",
|
|
||||||
"archiver": "^1.3.0",
|
"archiver": "^1.3.0",
|
||||||
"xml": "^1.0.1"
|
"xml": "^1.0.1"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Num } from "../../numbering/num";
|
import { Num } from "../../numbering/num";
|
||||||
|
import { Run } from "../run";
|
||||||
import { TextRun } from "../run/text-run";
|
import { TextRun } from "../run/text-run";
|
||||||
import { XmlComponent } from "../xml-components";
|
import { XmlComponent } from "../xml-components";
|
||||||
|
|
||||||
@ -24,14 +25,14 @@ export class Paragraph extends XmlComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public addText(run: TextRun): Paragraph {
|
public addRun(run: Run): Paragraph {
|
||||||
this.root.push(run);
|
this.root.push(run);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createTextRun(text: string): TextRun {
|
public createTextRun(text: string): TextRun {
|
||||||
const run = new TextRun(text);
|
const run = new TextRun(text);
|
||||||
this.addText(run);
|
this.addRun(run);
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as appRoot from "app-root-path";
|
|
||||||
import * as archiver from "archiver";
|
import * as archiver from "archiver";
|
||||||
|
import * as path from "path";
|
||||||
import * as xml from "xml";
|
import * as xml from "xml";
|
||||||
import { Document } from "../../docx";
|
import { Document } from "../../docx";
|
||||||
import { Numbering } from "../../numbering";
|
import { Numbering } from "../../numbering";
|
||||||
@ -8,6 +8,8 @@ import { Styles } from "../../styles";
|
|||||||
import { DefaultStylesFactory } from "../../styles/factory";
|
import { DefaultStylesFactory } from "../../styles/factory";
|
||||||
import { Formatter } from "../formatter";
|
import { Formatter } from "../formatter";
|
||||||
|
|
||||||
|
const templatePath = path.resolve(__dirname, "../../../template");
|
||||||
|
|
||||||
export abstract class Packer {
|
export abstract class Packer {
|
||||||
protected archive: any;
|
protected archive: any;
|
||||||
private formatter: Formatter;
|
private formatter: Formatter;
|
||||||
@ -42,12 +44,12 @@ export abstract class Packer {
|
|||||||
this.archive.pipe(output);
|
this.archive.pipe(output);
|
||||||
this.archive.glob("**", {
|
this.archive.glob("**", {
|
||||||
expand: true,
|
expand: true,
|
||||||
cwd: appRoot.path + "/template",
|
cwd: templatePath,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.archive.glob("**/.rels", {
|
this.archive.glob("**/.rels", {
|
||||||
expand: true,
|
expand: true,
|
||||||
cwd: appRoot.path + "/template",
|
cwd: templatePath,
|
||||||
});
|
});
|
||||||
|
|
||||||
const xmlDocument = xml(this.formatter.format(this.document));
|
const xmlDocument = xml(this.formatter.format(this.document));
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import * as paragraph from "../docx/paragraph/formatting";
|
||||||
import { ParagraphProperties } from "../docx/paragraph/properties";
|
import { ParagraphProperties } from "../docx/paragraph/properties";
|
||||||
|
import * as formatting from "../docx/run/formatting";
|
||||||
import { RunProperties } from "../docx/run/properties";
|
import { RunProperties } from "../docx/run/properties";
|
||||||
import { Attributes, XmlAttributeComponent, XmlComponent } from "../docx/xml-components";
|
import { Attributes, XmlAttributeComponent, XmlComponent } from "../docx/xml-components";
|
||||||
|
|
||||||
@ -86,4 +88,113 @@ export class Level extends XmlComponent {
|
|||||||
this.runProperties.push(property);
|
this.runProperties.push(property);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Run formatting ---------------------- //
|
||||||
|
|
||||||
|
public size(twips: number): Level {
|
||||||
|
this.addRunProperty(new formatting.Size(twips));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bold(): Level {
|
||||||
|
this.addRunProperty(new formatting.Bold());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public italics(): Level {
|
||||||
|
this.addRunProperty(new formatting.Italics());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public smallCaps(): Level {
|
||||||
|
this.addRunProperty(new formatting.SmallCaps());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public allCaps(): Level {
|
||||||
|
this.addRunProperty(new formatting.Caps());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public strike(): Level {
|
||||||
|
this.addRunProperty(new formatting.Strike());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public doubleStrike(): Level {
|
||||||
|
this.addRunProperty(new formatting.DoubleStrike());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public subScript(): Level {
|
||||||
|
this.addRunProperty(new formatting.SubScript());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public superScript(): Level {
|
||||||
|
this.addRunProperty(new formatting.SuperScript());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public underline(underlineType?: string, color?: string): Level {
|
||||||
|
this.addRunProperty(new formatting.Underline(underlineType, color));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public color(color: string): Level {
|
||||||
|
this.addRunProperty(new formatting.Color(color));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public font(fontName: string): Level {
|
||||||
|
this.addRunProperty(new formatting.RunFonts(fontName));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------- Paragraph formatting ------------------------ //
|
||||||
|
|
||||||
|
public center(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Alignment("center"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public left(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Alignment("left"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public right(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Alignment("right"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public justified(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Alignment("both"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public thematicBreak(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.ThematicBreak());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public maxRightTabStop(): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.MaxRightTabStop());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public leftTabStop(position: number): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.LeftTabStop(position));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public indent(left: number, hanging?: number): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Indent(left, hanging));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public spacing(params: paragraph.ISpacingProperties): Level {
|
||||||
|
this.addParagraphProperty(new paragraph.Spacing(params));
|
||||||
|
return this;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ describe("Formatter", () => {
|
|||||||
|
|
||||||
it("should format simple paragraph with bold text", () => {
|
it("should format simple paragraph with bold text", () => {
|
||||||
const paragraph = new docx.Paragraph();
|
const paragraph = new docx.Paragraph();
|
||||||
paragraph.addText(new docx.TextRun("test").bold());
|
paragraph.addRun(new docx.TextRun("test").bold());
|
||||||
const newJson = formatter.format(paragraph);
|
const newJson = formatter.format(paragraph);
|
||||||
assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"][0]._attr["w:val"]);
|
assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"][0]._attr["w:val"]);
|
||||||
});
|
});
|
||||||
|
@ -105,5 +105,292 @@ describe("AbstractNumbering", () => {
|
|||||||
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] });
|
expect(tree["w:lvl"]).to.include({ "w:numFmt": [{ _attr: { "w:val": "lowerLetter" } }] });
|
||||||
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] });
|
expect(tree["w:lvl"]).to.include({ "w:lvlText": [{ _attr: { "w:val": "%1)" } }] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("formatting methods: paragraph properties", () => {
|
||||||
|
it("#indent", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.")
|
||||||
|
.indent(720);
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [{"w:ind": [{_attr: {"w:left": 720}}]}],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#spacing", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.")
|
||||||
|
.spacing({before: 50, after: 150});
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:spacing": [{_attr: {"w:before": 50, "w:after": 150}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#center", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.")
|
||||||
|
.center();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:jc": [{_attr: {"w:val": "center"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#left", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.", "left")
|
||||||
|
.left();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:jc": [{_attr: {"w:val": "left"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#right", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.right();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:jc": [{_attr: {"w:val": "right"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#justified", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.justified();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:jc": [{_attr: {"w:val": "both"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#thematicBreak", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.thematicBreak();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:pBdr": [{"w:bottom": [{_attr: {
|
||||||
|
"w:color": "auto",
|
||||||
|
"w:space": "1",
|
||||||
|
"w:val": "single",
|
||||||
|
"w:sz": "6",
|
||||||
|
}}]}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#leftTabStop", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.leftTabStop(1200);
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:tabs": [
|
||||||
|
{"w:tab": [{_attr: {"w:val": "left", "w:pos": 1200}}]},
|
||||||
|
]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#maxRightTabStop", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.maxRightTabStop();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:pPr": [
|
||||||
|
{"w:tabs": [
|
||||||
|
{"w:tab": [{_attr: {"w:val": "right", "w:pos": 9026}}]},
|
||||||
|
]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatting methods: run properties", () => {
|
||||||
|
it("#size", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.size(24);
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:sz": [{_attr: {"w:val": 24}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#smallCaps", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.smallCaps();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:smallCaps": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#allCaps", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.allCaps();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:caps": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#strike", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.strike();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:strike": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#doubleStrike", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.doubleStrike();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:dstrike": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#subScript", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.subScript();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:vertAlign": [{_attr: {"w:val": "subscript"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#superScript", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.superScript();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:vertAlign": [{_attr: {"w:val": "superscript"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#font", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.font("Times");
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [{"w:rFonts": [{_attr: {"w:ascii": "Times", "w:hAnsi": "Times"}}]}],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#bold", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.bold();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:b": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#italics", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.italics();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:i": [{_attr: {"w:val": true}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#underline", () => {
|
||||||
|
it("should set underline to 'single' if no arguments are given", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.underline();
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:u": [{_attr: {"w:val": "single"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set the style if given", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.underline("double");
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:u": [{_attr: {"w:val": "double"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should set the style and color if given", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.underline("double", "005599");
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:u": [{_attr: {"w:val": "double", "w:color": "005599"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("#color", () => {
|
||||||
|
const abstractNumbering = new AbstractNumbering(1);
|
||||||
|
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.")
|
||||||
|
.color("123456");
|
||||||
|
const tree = new Formatter().format(level);
|
||||||
|
expect(tree["w:lvl"]).to.include({
|
||||||
|
"w:rPr": [
|
||||||
|
{"w:color": [{_attr: {"w:val": "123456"}}]},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user