Merge pull request #12 from felipeochoa/styles

Styles cleanup
This commit is contained in:
Dolan
2017-03-09 15:25:19 +00:00
committed by GitHub
22 changed files with 704 additions and 202 deletions

View File

@ -1,4 +1,4 @@
import { XmlAttributeComponent, XmlComponent } from "../docx/xml-components";
import { XmlAttributeComponent, XmlComponent } from "../xml-components";
interface IndentAttributesProperties {
left: number;
@ -17,7 +17,7 @@ class IndentAttributes extends XmlAttributeComponent {
export class Indent extends XmlComponent {
constructor(left: number, hanging: number) {
constructor(left: number, hanging?: number) {
super("w:ind");
this.root.push(new IndentAttributes({
left: left,

View File

@ -1,9 +1,12 @@
import { Num } from "../../numbering/num";
import { TextRun } from "../run/text-run";
import { Attributes, XmlComponent } from "../xml-components";
import { ThematicBreak } from "./border";
import { Indent } from "./indent";
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";
@ -116,4 +119,19 @@ export class Paragraph extends XmlComponent {
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(start: number, hanging?: number): Paragraph {
this.properties.push(new Indent(start, hanging));
return this;
}
public spacing(params: ISpacingProperties): Paragraph {
this.properties.push(new Spacing(params));
return this;
};
}

View File

@ -0,0 +1,24 @@
import { XmlAttributeComponent, XmlComponent } from "../xml-components";
export interface ISpacingProperties {
after?: number;
before?: number;
line?: number;
}
class SpacingAttributes extends XmlAttributeComponent {
constructor(properties: ISpacingProperties) {
super({
after: "w:after",
before: "w:before",
line: "w:line",
}, properties);
}
}
export class Spacing extends XmlComponent {
constructor(opts: ISpacingProperties) {
super("w:spacing");
this.root.push(new SpacingAttributes(opts));
}
}

View File

@ -1,4 +1,5 @@
import { Attributes, XmlComponent } from "../xml-components";
export { Underline } from './underline';
export class Bold extends XmlComponent {

View File

@ -13,8 +13,8 @@ abstract class BaseUnderline extends XmlComponent {
export class Underline extends BaseUnderline {
constructor() {
super("");
constructor(underlineType: string = "single", color?: string) {
super(underlineType, color);
}
}

View File

@ -1,3 +1,4 @@
export * from "./docx";
export * from "./export";
export { Numbering } from "./numbering";
export { Styles } from "./styles";

View File

@ -1,9 +1,9 @@
import * as _ from "lodash";
import { DocumentAttributes } from "../docx/document/document-attributes";
import { Indent } from "../docx/paragraph/indent";
import { RunFonts } from "../docx/run/run-fonts";
import { MultiPropertyXmlComponent } from "../docx/xml-components";
import { AbstractNumbering } from "./abstract-numbering";
import { Indent } from "./indent";
import { Level } from "./level";
import { Num } from "./num";

View File

@ -1,6 +1,6 @@
import {XmlComponent} from "../../docx/xml-components";
import {ParagraphPropertiesDefaults} from "./paragraph-properties";
import {RunPropertiesDefaults} from "./run-properties";
import { XmlComponent } from "../../docx/xml-components";
import { ParagraphPropertiesDefaults } from "./paragraph-properties";
import { RunPropertiesDefaults } from "./run-properties";
export class DocumentDefaults extends XmlComponent {
@ -15,10 +15,10 @@ export class DocumentDefaults extends XmlComponent {
this.root.push(this.paragraphPropertiesDefaults);
}
clearVariables(): void {
public clearVariables(): void {
this.runPropertiesDefaults.clearVariables();
this.paragraphPropertiesDefaults.clearVariables();
delete this.runPropertiesDefaults;
delete this.paragraphPropertiesDefaults;
}
}
}

View File

@ -1,5 +1,5 @@
import {XmlComponent} from "../../docx/xml-components";
import {ParagraphProperties} from "../../docx/paragraph/properties";
import { ParagraphProperties } from "../../docx/paragraph/properties";
import { XmlComponent } from "../../docx/xml-components";
export class ParagraphPropertiesDefaults extends XmlComponent {
@ -7,4 +7,4 @@ export class ParagraphPropertiesDefaults extends XmlComponent {
super("w:pPrDefault");
this.root.push(new ParagraphProperties());
}
}
}

View File

@ -1,5 +1,5 @@
import {XmlComponent} from "../../docx/xml-components";
import {RunProperties} from "../../docx/run/properties";
import { RunProperties } from "../../docx/run/properties";
import { XmlComponent } from "../../docx/xml-components";
export class RunPropertiesDefaults extends XmlComponent {
@ -7,4 +7,4 @@ export class RunPropertiesDefaults extends XmlComponent {
super("w:rPrDefault");
this.root.push(new RunProperties());
}
}
}

View File

@ -1,56 +1,60 @@
import {Styles} from "./";
import {DocumentDefaults} from "./defaults";
import {ParagraphPropertiesDefaults} from "./defaults/paragraph-properties";
import {RunPropertiesDefaults} from "./defaults/run-properties";
import {Heading1Style, Heading2Style, TitleStyle, Heading3Style, Heading4Style, Heading5Style, Heading6Style, ListParagraph} from "./style";
// import {StyleAttributes} from "./style/attributes";
import {ParagraphProperties} from "../docx/paragraph/properties";
import {RunProperties} from "../docx/run/properties";
import {Color, Size, Italics} from "../docx/run/formatting";
import { ParagraphProperties } from "../docx/paragraph/properties";
import { Color, Italics, Size } from "../docx/run/formatting";
import { RunProperties } from "../docx/run/properties";
import { Styles } from "./";
import { DocumentDefaults } from "./defaults";
import { ParagraphPropertiesDefaults } from "./defaults/paragraph-properties";
import { RunPropertiesDefaults } from "./defaults/run-properties";
import {
Heading1Style, Heading2Style, Heading3Style, Heading4Style, Heading5Style, Heading6Style,
ListParagraph, TitleStyle,
} from "./style";
// import { StyleAttributes } from "./style/attributes";
export class DefaultStylesFactory {
newInstance(): Styles {
let styles = new Styles();
public newInstance(): Styles {
const styles = new Styles();
styles.push(new DocumentDefaults());
let titleStyle = new TitleStyle();
const titleStyle = new TitleStyle();
titleStyle.addRunProperty(new Size(56));
styles.push(titleStyle);
let heading1Style = new Heading1Style();
const heading1Style = new Heading1Style();
heading1Style.addRunProperty(new Color("2E74B5"));
heading1Style.addRunProperty(new Size(32));
styles.push(heading1Style);
let heading2Style = new Heading2Style();
const heading2Style = new Heading2Style();
heading2Style.addRunProperty(new Color("2E74B5"));
heading2Style.addRunProperty(new Size(26));
styles.push(heading2Style);
let heading3Style = new Heading3Style();
const heading3Style = new Heading3Style();
heading3Style.addRunProperty(new Color("1F4D78"));
heading3Style.addRunProperty(new Size(24));
styles.push(heading3Style);
let heading4Style = new Heading4Style();
const heading4Style = new Heading4Style();
heading4Style.addRunProperty(new Color("2E74B5"));
heading4Style.addRunProperty(new Italics());
styles.push(heading4Style);
let heading5Style = new Heading5Style();
const heading5Style = new Heading5Style();
heading5Style.addRunProperty(new Color("2E74B5"));
styles.push(heading5Style);
let heading6Style = new Heading6Style();
const heading6Style = new Heading6Style();
heading6Style.addRunProperty(new Color("1F4D78"));
styles.push(heading6Style);
let listParagraph = new ListParagraph();
const listParagraph = new ListParagraph();
// listParagraph.addParagraphProperty();
styles.push(listParagraph);
// console.log(JSON.stringify(styles, null, " "));
return styles;
}
}
}

View File

@ -1,9 +1,10 @@
import {XmlComponent} from "../docx/xml-components";
import {DocumentAttributes} from "../docx/document/document-attributes";
import {DocumentDefaults} from "./defaults";
import {LatentStyles} from "./latent-styles";
import {LatentStyleException} from "./latent-styles/exceptions";
import {LatentStyleExceptionAttributes} from "./latent-styles/exceptions/attributes";
import { DocumentAttributes } from "../docx/document/document-attributes";
import { XmlComponent } from "../docx/xml-components";
import { DocumentDefaults } from "./defaults";
import { LatentStyles } from "./latent-styles";
import { LatentStyleException } from "./latent-styles/exceptions";
import { LatentStyleExceptionAttributes } from "./latent-styles/exceptions/attributes";
import { ParagraphStyle } from "./style";
export class Styles extends XmlComponent {
@ -15,7 +16,7 @@ export class Styles extends XmlComponent {
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",
Ignorable: "w14 w15"
Ignorable: "w14 w15",
}));
// let latentStyles = new LatentStyles();
// latentStyles.push(new LatentStyleException(new LatentStyleExceptionAttributes({
@ -24,13 +25,20 @@ export class Styles extends XmlComponent {
// this.root.push(latentStyles);
}
push(style: XmlComponent): void {
public push(style: XmlComponent): Styles {
this.root.push(style);
return this;
}
clearVariables() {
this.root.forEach(element => {
public clearVariables(): void {
this.root.forEach((element) => {
element.clearVariables();
});
}
}
public createParagraphStyle(styleId: string, name?: string): ParagraphStyle {
const para = new ParagraphStyle(styleId, name);
this.push(para);
return para;
}
}

View File

@ -1,6 +1,6 @@
import {XmlComponent} from "../../../docx/xml-components";
interface LatentStyleExceptionAttributesProperties {
interface ILatentStyleExceptionAttributesProperties {
name?: string;
uiPriority?: string;
qFormat?: string;
@ -9,23 +9,23 @@ interface LatentStyleExceptionAttributesProperties {
}
export class LatentStyleExceptionAttributes extends XmlComponent {
private _attr: Object;
private _attr: ILatentStyleExceptionAttributesProperties;
xmlKeys = {
private xmlKeys = {
name: "w:name",
uiPriority: "w:uiPriority",
qFormat: "w:qFormat",
semiHidden: "w:semiHidden",
unhideWhenUsed: "w:unhideWhenUsed"
unhideWhenUsed: "w:unhideWhenUsed",
};
constructor(properties?: LatentStyleExceptionAttributesProperties) {
constructor(properties?: ILatentStyleExceptionAttributesProperties) {
super("_attr");
this._attr = properties;
if (!properties) {
this._attr = {};
}
this._attr["xmlKeys"] = this.xmlKeys;
//this._attr.xmlKeys = this.xmlKeys;
}
}
}

View File

@ -1,5 +1,5 @@
import {XmlComponent} from "../../../docx/xml-components";
import {LatentStyleExceptionAttributes} from "./attributes";
import { XmlComponent } from "../../../docx/xml-components";
import { LatentStyleExceptionAttributes } from "./attributes";
export class LatentStyleException extends XmlComponent {
@ -7,4 +7,4 @@ export class LatentStyleException extends XmlComponent {
super("w:lsdException");
this.root.push(attributes);
}
}
}

View File

@ -1,5 +1,5 @@
import {XmlComponent} from "../../docx/xml-components";
import {LatentStyleException} from "./exceptions";
import { XmlComponent } from "../../docx/xml-components";
import { LatentStyleException } from "./exceptions";
export class LatentStyles extends XmlComponent {
@ -7,7 +7,7 @@ export class LatentStyles extends XmlComponent {
super("w:latentStyles");
}
push(latentException: LatentStyleException): void {
public push(latentException: LatentStyleException): void {
this.root.push(latentException);
}
}
}

View File

@ -1,24 +0,0 @@
import {XmlComponent} from "../../docx/xml-components";
import {XmlAttributeComponent} from "../../docx/xml-components";
interface StyleAttributesProperties {
type?: string;
styleId?: string;
default?: string;
customStyle?: string;
val?: string;
}
export class StyleAttributes extends XmlAttributeComponent {
private _attr: Object;
constructor(properties: StyleAttributesProperties) {
super({
type: "w:type",
styleId: "w:styleId",
default: "w:default",
customStyle: "w:customStyle",
val: "w:val"
}, properties);
}
}

View File

@ -1,13 +1,22 @@
import {XmlComponent} from "../../docx/xml-components";
import {StyleAttributes} from "./attributes";
import { XmlAttributeComponent, XmlComponent } from "../../docx/xml-components";
interface IComponentAttributes {
val: string;
}
class ComponentAttributes extends XmlAttributeComponent {
private _attr: IComponentAttributes;
constructor(properties: IComponentAttributes) {
super({val: "w:val"}, properties);
}
}
export class Name extends XmlComponent {
constructor(value: string) {
super("w:name");
this.root.push(new StyleAttributes({
val: value
}));
this.root.push(new ComponentAttributes({val: value}));
}
}
@ -15,9 +24,7 @@ export class BasedOn extends XmlComponent {
constructor(value: string) {
super("w:basedOn");
this.root.push(new StyleAttributes({
val: value
}));
this.root.push(new ComponentAttributes({val: value}));
}
}
@ -25,10 +32,7 @@ export class Next extends XmlComponent {
constructor(value: string) {
super("w:next");
this.root.push(new StyleAttributes({
styleId: "1",
val: value
}));
this.root.push(new ComponentAttributes({val: value}));
}
}
@ -36,9 +40,7 @@ export class Link extends XmlComponent {
constructor(value: string) {
super("w:link");
this.root.push(new StyleAttributes({
val: value
}));
this.root.push(new ComponentAttributes({val: value}));
}
}
@ -46,9 +48,8 @@ export class UiPriority extends XmlComponent {
constructor(value: string) {
super("w:uiPriority");
this.root.push(new StyleAttributes({
val: value
}));
// TODO: this value should be a ST_DecimalNumber
this.root.push(new ComponentAttributes({val: value}));
}
}
@ -73,4 +74,4 @@ export class RsId extends XmlComponent {
export class SemiHidden extends XmlComponent {
}
}

View File

@ -1,17 +1,43 @@
import {XmlComponent} from "../../docx/xml-components";
import {StyleAttributes} from "./attributes";
import {ParagraphProperties} from "../../docx/paragraph/properties";
import {RunProperties} from "../../docx/run/properties";
import {Name, BasedOn, Next, QuickFormat} from "./components";
import { Indent } from "../../docx/paragraph/indent";
import { ParagraphProperties } from "../../docx/paragraph/properties";
import { ISpacingProperties, Spacing } from "../../docx/paragraph/spacing";
import * as formatting from "../../docx/run/formatting";
import { RunProperties } from "../../docx/run/properties";
import { XmlAttributeComponent, XmlComponent } from "../../docx/xml-components";
import { BasedOn, Name, Next, QuickFormat } from "./components";
export interface IStyleAttributes {
type?: string;
styleId?: string;
default?: boolean;
customStyle?: string;
}
class StyleAttributes extends XmlAttributeComponent {
private _attr: IStyleAttributes;
constructor(properties: IStyleAttributes) {
super({
type: "w:type",
styleId: "w:styleId",
default: "w:default",
customStyle: "w:customStyle",
}, properties);
}
}
export class Style extends XmlComponent {
constructor(attributes: StyleAttributes) {
constructor(attributes: IStyleAttributes, name?: string) {
super("w:style");
this.root.push(attributes);
this.root.push(new StyleAttributes(attributes));
if (name) {
this.root.push(new Name(name));
}
}
push(styleSegment: XmlComponent): void {
public push(styleSegment: XmlComponent): void {
this.root.push(styleSegment);
}
}
@ -21,43 +47,87 @@ export class ParagraphStyle extends Style {
private paragraphProperties: ParagraphProperties;
private runProperties: RunProperties;
constructor(styleId: string) {
let attributes = new StyleAttributes({
type: "paragraph",
styleId: styleId
});
super(attributes);
constructor(styleId: string, name?: string) {
super({type: "paragraph", styleId: styleId}, name);
this.paragraphProperties = new ParagraphProperties();
this.runProperties = new RunProperties();
this.root.push(this.paragraphProperties);
this.root.push(this.runProperties);
}
clearVariables(): void {
public clearVariables(): void {
this.paragraphProperties.clearVariables();
this.runProperties.clearVariables();
delete this.paragraphProperties;
delete this.runProperties;
}
addParagraphProperty(property: XmlComponent): void {
public addParagraphProperty(property: XmlComponent): void {
this.paragraphProperties.push(property);
}
addRunProperty(property: XmlComponent): void {
public addRunProperty(property: XmlComponent): void {
this.runProperties.push(property);
}
public basedOn(parentId: string): ParagraphStyle {
this.root.push(new BasedOn(parentId));
return this;
}
public quickFormat(): ParagraphStyle {
this.root.push(new QuickFormat());
return this;
}
public next(nextId: string): ParagraphStyle {
this.root.push(new Next(nextId));
return this;
}
public size(twips: number): ParagraphStyle {
this.addRunProperty(new formatting.Size(twips));
return this;
}
public bold(): ParagraphStyle {
this.addRunProperty(new formatting.Bold());
return this;
}
public italics(): ParagraphStyle {
this.addRunProperty(new formatting.Italics());
return this;
}
public underline(underlineType?: string, color?: string): ParagraphStyle {
this.addRunProperty(new formatting.Underline(underlineType, color));
return this;
}
public color(color: string): ParagraphStyle {
this.addRunProperty(new formatting.Color(color));
return this;
}
public indent(left: number, hanging?: number): ParagraphStyle {
this.addParagraphProperty(new Indent(left, hanging));
return this;
}
public spacing(params: ISpacingProperties): ParagraphStyle {
this.addParagraphProperty(new Spacing(params));
return this;
};
}
export class HeadingStyle extends ParagraphStyle {
constructor(styleId: string, name: string) {
super(styleId);
this.root.push(new Name(name));
this.root.push(new BasedOn("Normal"));
this.root.push(new Next("Normal"));
this.root.push(new QuickFormat());
super(styleId, name);
this.basedOn("Normal");
this.next("Normal");
this.quickFormat();
}
}
@ -118,4 +188,4 @@ export class ListParagraph extends ParagraphStyle {
this.root.push(new BasedOn("Normal"));
this.root.push(new QuickFormat());
}
}
}

View File

@ -1,10 +1,11 @@
import { assert, expect } from "chai";
import * as docx from "../../../docx";
import { Formatter } from "../../../export/formatter";
import { Numbering } from "../../../numbering";
import { assert, expect } from "chai";
function jsonify(obj: Object) {
let stringifiedJson = JSON.stringify(obj);
function jsonify(obj: object) {
const stringifiedJson = JSON.stringify(obj);
return JSON.parse(stringifiedJson);
}
@ -18,7 +19,7 @@ describe("Paragraph", () => {
describe("#constructor()", () => {
it("should create valid JSON", () => {
let stringifiedJson = JSON.stringify(paragraph);
const stringifiedJson = JSON.stringify(paragraph);
let newJson;
try {
@ -30,8 +31,8 @@ describe("Paragraph", () => {
});
it("should create have valid properties", () => {
let stringifiedJson = JSON.stringify(paragraph);
let newJson = JSON.parse(stringifiedJson);
const stringifiedJson = JSON.stringify(paragraph);
const newJson = JSON.parse(stringifiedJson);
assert.equal(newJson.root[0].rootKey, "w:pPr");
});
});
@ -39,7 +40,7 @@ describe("Paragraph", () => {
describe("#heading1()", () => {
it("should add heading style to JSON", () => {
paragraph.heading1();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "Heading1");
});
});
@ -47,7 +48,7 @@ describe("Paragraph", () => {
describe("#heading2()", () => {
it("should add heading style to JSON", () => {
paragraph.heading2();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "Heading2");
});
@ -56,7 +57,7 @@ describe("Paragraph", () => {
describe("#heading3()", () => {
it("should add heading style to JSON", () => {
paragraph.heading3();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "Heading3");
});
@ -65,7 +66,7 @@ describe("Paragraph", () => {
describe("#title()", () => {
it("should add title style to JSON", () => {
paragraph.title();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "Title");
});
@ -74,7 +75,7 @@ describe("Paragraph", () => {
describe("#center()", () => {
it("should add center alignment to JSON", () => {
paragraph.center();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "center");
});
@ -83,7 +84,7 @@ describe("Paragraph", () => {
describe("#thematicBreak()", () => {
it("should add thematic break to JSON", () => {
paragraph.thematicBreak();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].rootKey, "w:pBdr");
});
});
@ -91,13 +92,13 @@ describe("Paragraph", () => {
describe("#pageBreak()", () => {
it("should add page break to JSON", () => {
paragraph.pageBreak();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[1].rootKey, "w:br");
});
it("should add page break with 'page' type", () => {
paragraph.pageBreak();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[1].root[0].root.type, "page");
});
});
@ -105,13 +106,13 @@ describe("Paragraph", () => {
describe("#bullet()", () => {
it("should add list paragraph style to JSON", () => {
paragraph.bullet();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "ListParagraph");
});
it("it should add numbered properties", () => {
paragraph.bullet();
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.isDefined(newJson.root[0].root[2]);
});
});
@ -124,7 +125,7 @@ describe("Paragraph", () => {
const letterNumbering = numbering.createConcreteNumbering(numberedAbstract);
paragraph.setNumbering(letterNumbering, 0);
let newJson = jsonify(paragraph);
const newJson = jsonify(paragraph);
assert.equal(newJson.root[0].root[1].root[0].root.val, "ListParagraph");
});
@ -136,23 +137,73 @@ describe("Paragraph", () => {
paragraph.setNumbering(letterNumbering, 0);
const tree = new Formatter().format(paragraph);
console.log(JSON.stringify(tree, null, 2));
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [
{"_attr": {}},
{"w:pStyle": [{"_attr": {"w:val": "ListParagraph"}}]},
{_attr: {}},
{"w:pStyle": [{_attr: {"w:val": "ListParagraph"}}]},
{
"w:numPr": [
{"w:ilvl": [{"_attr": {"w:val": 0}}]},
{"w:numId": [{"_attr": {"w:val": letterNumbering.id}}]}
]
{"w:ilvl": [{_attr: {"w:val": 0}}]},
{"w:numId": [{_attr: {"w:val": letterNumbering.id}}]},
],
},
],
},
]
})
],
});
});
});
describe("#style", () => {
it("should set the paragraph style to the given styleId", () => {
paragraph.style("myFancyStyle");
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [
{_attr: {}},
{"w:pStyle": [{_attr: {"w:val": "myFancyStyle"}}]},
],
},
],
});
});
});
describe("#indent", () => {
it("should set the paragraph indent to the given values", () => {
paragraph.indent(720);
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [
{_attr: {}},
{"w:ind": [{_attr: {"w:left": 720}}]},
],
},
],
});
});
});
describe("#spacing", () => {
it("should set the paragraph spacing to the given values", () => {
paragraph.spacing({before: 90, line: 50});
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [
{_attr: {}},
{"w:spacing": [{_attr: {"w:before": 90, "w:line": 50}}]},
],
},
],
});
});
});
});

View File

@ -0,0 +1,24 @@
import { expect } from "chai";
import { Spacing } from "../../../docx/paragraph/spacing";
import { Formatter } from "../../../export/formatter";
describe("Spacing", () => {
describe("#constructor", () => {
it("should set the properties given", () => {
const spacing = new Spacing({before: 100, after: 120, line: 150});
const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({
"w:spacing": [{_attr: {"w:after": 120, "w:before": 100, "w:line": 150}}],
});
});
it("should only set the given properties", () => {
const spacing = new Spacing({before: 100});
const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({
"w:spacing": [{_attr: {"w:before": 100}}],
});
});
});
});

View File

@ -1,9 +1,11 @@
import * as u from "../../../docx/run/underline";
import { TextRun } from "../../../docx/run/text-run";
import { assert } from "chai";
import { assert, expect } from "chai";
function jsonify(obj: Object) {
let stringifiedJson = JSON.stringify(obj);
import { TextRun } from "../../../docx/run/text-run";
import * as u from "../../../docx/run/underline";
import { Formatter } from "../../../export/formatter";
function jsonify(obj: object) {
const stringifiedJson = JSON.stringify(obj);
return JSON.parse(stringifiedJson);
}
@ -12,10 +14,26 @@ describe("Underline", () => {
describe("#constructor()", () => {
it("should create a new Underline object with u:u as the rootKey", () => {
let underline = new u.Underline();
let newJson = jsonify(underline);
const underline = new u.Underline();
const newJson = jsonify(underline);
assert.equal(newJson.rootKey, "w:u");
});
it("should default to 'single' and no color", () => {
const underline = new u.Underline();
const tree = new Formatter().format(underline);
expect(tree).to.deep.equal({
"w:u": [{_attr: {"w:val": "single"}}],
});
});
it("should use the given style type and color", () => {
const underline = new u.Underline("double", "FF00CC");
const tree = new Formatter().format(underline);
expect(tree).to.deep.equal({
"w:u": [{_attr: {"w:val": "double", "w:color": "FF00CC"}}],
});
});
});
});
@ -23,14 +41,14 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should have u:u as the rootKey", () => {
let underline = new u.DashDotDotHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.DashDotDotHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.rootKey, "w:u");
});
it("should put value in attribute", () => {
let underline = new u.DashDotDotHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.DashDotDotHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dashDotDotHeavy");
});
});
@ -40,8 +58,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DashDotHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.DashDotHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dashDotHeavy");
});
});
@ -51,8 +69,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DashLongHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.DashLongHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dashLongHeavy");
});
});
@ -62,8 +80,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DashLongUnderline();
let newJson = jsonify(underline);
const underline = new u.DashLongUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dashLong");
});
});
@ -73,8 +91,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DashUnderline();
let newJson = jsonify(underline);
const underline = new u.DashUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dash");
});
});
@ -84,8 +102,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DotDashUnderline();
let newJson = jsonify(underline);
const underline = new u.DotDashUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dotDash");
});
});
@ -95,8 +113,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DotDotDashUnderline();
let newJson = jsonify(underline);
const underline = new u.DotDotDashUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dotDotDash");
});
});
@ -106,8 +124,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DottedHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.DottedHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dottedHeavy");
});
});
@ -117,8 +135,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DottedUnderline();
let newJson = jsonify(underline);
const underline = new u.DottedUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "dotted");
});
});
@ -128,8 +146,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.DoubleUnderline();
let newJson = jsonify(underline);
const underline = new u.DoubleUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "double");
});
});
@ -139,8 +157,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.SingleUnderline();
let newJson = jsonify(underline);
const underline = new u.SingleUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "single");
});
});
@ -150,8 +168,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.ThickUnderline();
let newJson = jsonify(underline);
const underline = new u.ThickUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "thick");
});
});
@ -161,8 +179,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.WaveUnderline();
let newJson = jsonify(underline);
const underline = new u.WaveUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "wave");
});
});
@ -172,8 +190,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.WavyDoubleUnderline();
let newJson = jsonify(underline);
const underline = new u.WavyDoubleUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "wavyDouble");
});
});
@ -183,8 +201,8 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.WavyHeavyUnderline();
let newJson = jsonify(underline);
const underline = new u.WavyHeavyUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "wavyHeavy");
});
});
@ -194,9 +212,9 @@ describe("DashDotDotHeavyUnderline", () => {
describe("#constructor()", () => {
it("should put value in attribute", () => {
let underline = new u.WordsUnderline();
let newJson = jsonify(underline);
const underline = new u.WordsUnderline();
const newJson = jsonify(underline);
assert.equal(newJson.root[0].root.val, "words");
});
});
});
});

View File

@ -1,5 +1,8 @@
import { assert, expect } from "chai";
import { Formatter } from "../export/formatter";
import { Styles } from "../styles";
import { assert } from "chai";
import { ParagraphStyle, Style } from "../styles/style";
import * as components from "../styles/style/components";
describe("Styles", () => {
let styles: Styles;
@ -9,13 +12,316 @@ describe("Styles", () => {
});
describe("#constructor()", () => {
it("should create styles with correct rootKey", () => {
let styles = new Styles();
let stringifiedJson = JSON.stringify(styles);
let newJson = JSON.parse(stringifiedJson);
const newJson = JSON.parse(JSON.stringify(styles));
assert.equal(newJson.rootKey, "w:styles");
});
});
});
describe("#createParagraphStyle", () => {
it("should create a new paragraph style and push it onto this collection", () => {
const ps = styles.createParagraphStyle("pStyleId");
const tree = new Formatter().format(styles)["w:styles"].filter((x) => !x._attr);
expect(tree).to.deep.equal([{
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "pStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
],
}]);
});
it("should set the paragraph name if given", () => {
const ps = styles.createParagraphStyle("pStyleId", "Paragraph Style");
const tree = new Formatter().format(styles)["w:styles"].filter((x) => !x._attr);
expect(tree).to.deep.equal([{
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "pStyleId"}},
{"w:name": [{_attr: {"w:val": "Paragraph Style"}}]},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
],
}]);
});
});
});
describe("Style", () => {
describe("#constructor()", () => {
it("should set the given properties", () => {
const style = new Style({
type: "paragraph",
styleId: "myStyleId",
default: true,
});
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId", "w:default": true}},
],
});
});
it("should set the name of the style, if given", () => {
const style = new Style({
type: "paragraph",
styleId: "myStyleId",
}, "Style Name");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:name": [{_attr: {"w:val": "Style Name"}}]},
],
});
});
});
});
describe("Style components", () => {
it("Name#constructor", () => {
const style = new components.Name("Style Name");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({"w:name": [{_attr: {"w:val": "Style Name"}}]});
});
it("BasedOn#constructor", () => {
const style = new components.BasedOn("otherId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({"w:basedOn": [{_attr: {"w:val": "otherId"}}]});
});
it("Next#constructor", () => {
const style = new components.Next("otherId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({"w:next": [{_attr: {"w:val": "otherId"}}]});
});
it("Link#constructor", () => {
const style = new components.Link("otherId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({"w:link": [{_attr: {"w:val": "otherId"}}]});
});
it("UiPriority#constructor", () => {
const style = new components.UiPriority("123");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({"w:uiPriority": [{_attr: {"w:val": "123"}}]});
});
});
describe("ParagraphStyle", () => {
describe("#constructor", () => {
it("should set the style type to paragraph and use the given style id", () => {
const style = new ParagraphStyle("myStyleId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
],
});
});
it("should set the name of the style, if given", () => {
const style = new ParagraphStyle("myStyleId", "Style Name");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:name": [{_attr: {"w:val": "Style Name"}}]},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
],
});
});
});
describe("formatting methods: style attributes", () => {
it("#basedOn", () => {
const style = new ParagraphStyle("myStyleId")
.basedOn("otherId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
{"w:basedOn": [{_attr: {"w:val": "otherId"}}]},
],
});
});
it("#quickFormat", () => {
const style = new ParagraphStyle("myStyleId")
.quickFormat();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
{"w:qFormat": []},
],
});
});
it("#next", () => {
const style = new ParagraphStyle("myStyleId")
.next("otherId");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": []},
{"w:next": [{_attr: {"w:val": "otherId"}}]},
],
});
});
});
describe("formatting methods: paragraph properties", () => {
it("#indent", () => {
const style = new ParagraphStyle("myStyleId")
.indent(720);
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [
{_attr: {}},
{"w:ind": [{_attr: {"w:left": 720}}]},
]},
{"w:rPr": []},
],
});
});
it("#spacing", () => {
const style = new ParagraphStyle("myStyleId")
.spacing({before: 50, after: 150});
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [
{_attr: {}},
{"w:spacing": [{_attr: {"w:before": 50, "w:after": 150}}]},
]},
{"w:rPr": []},
],
});
});
});
describe("formatting methods: run properties", () => {
it("#size", () => {
const style = new ParagraphStyle("myStyleId")
.size(24);
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:sz": [{_attr: {"w:val": 24}}]},
]},
],
});
});
it("#bold", () => {
const style = new ParagraphStyle("myStyleId")
.bold();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:b": [{_attr: {"w:val": true}}]},
]},
],
});
});
it("#italics", () => {
const style = new ParagraphStyle("myStyleId")
.italics();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:i": [{_attr: {"w:val": true}}]},
]},
],
});
});
describe("#underline", () => {
it("should set underline to 'single' if no arguments are given", () => {
const style = new ParagraphStyle("myStyleId")
.underline();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:u": [{_attr: {"w:val": "single"}}]},
]},
],
});
});
it("should set the style if given", () => {
const style = new ParagraphStyle("myStyleId")
.underline("double");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:u": [{_attr: {"w:val": "double"}}]},
]},
],
});
});
it("should set the style and color if given", () => {
const style = new ParagraphStyle("myStyleId")
.underline("double", "005599");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:u": [{_attr: {"w:val": "double", "w:color": "005599"}}]},
]},
],
});
});
});
it("#color", () => {
const style = new ParagraphStyle("myStyleId")
.color("123456");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{_attr: {"w:type": "paragraph", "w:styleId": "myStyleId"}},
{"w:pPr": [{_attr: {}}]},
{"w:rPr": [
{"w:color": [{_attr: {"w:val": "123456"}}]},
]},
],
});
});
});
});