Merge branch 'master' into image-support

This commit is contained in:
Dolan
2017-03-13 23:37:09 +00:00
7 changed files with 442 additions and 294 deletions

318
README.md
View File

@ -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.
[![NPM](https://nodei.co/npm/docx.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/docx/) [![NPM](https://nodei.co/npm/docx.png?downloads=true&downloadRank=true&stars=true)](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!
![Word 2013 Styles menu](http://content.gcflearnfree.org/topics/233/style_apply_choose.png "Word 2013 Styles menu")
#### 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.
![Word 2013 Tabs](http://www.teachucomp.com/wp-content/uploads/blog-4-22-2015-UsingTabStopsInWord-1024x577.png "Word 2013 Tab Stops")
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

View File

@ -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"
}, },

View File

@ -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;
} }

View File

@ -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));

View File

@ -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;
};
} }

View File

@ -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"]);
}); });

View File

@ -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"}}]},
],
});
});
});
}); });
}); });