Merge pull request #307 from brucehappy/features/xml_optimization

Optimize XML output
This commit is contained in:
Dolan
2019-04-11 22:50:10 +01:00
committed by GitHub
62 changed files with 1242 additions and 1608 deletions

View File

@ -31,7 +31,7 @@ describe("Formatter", () => {
const paragraph = new file.Paragraph();
paragraph.addRun(new file.TextRun("test").bold());
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"][0]["w:r"][0]["w:rPr"][0]["w:b"]._attr["w:val"]);
});
it("should format attributes (rsidSect)", () => {

View File

@ -191,13 +191,4 @@ export class Compiler {
},
};
}
/* By default docx collapse empty tags. <a></a> -> <a/>. this function mimic it
so comparing (diff) original docx file and the library output is easier
Currently not used, so commenting out */
// private collapseEmptyTags(xmlData: string): string {
// const regEx = /<(([^ <>]+)[^<>]*)><\/\2>/g;
// const collapsed = xmlData.replace(regEx, "<$1/>");
// return collapsed;
// }
}

View File

@ -20,84 +20,70 @@ describe("ContentTypes", () => {
expect(tree["Types"]).to.be.an.instanceof(Array);
expect(tree["Types"][0]).to.deep.equal({ _attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" } });
expect(tree["Types"][1]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/png", Extension: "png" } }] });
expect(tree["Types"][2]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/jpeg", Extension: "jpeg" } }] });
expect(tree["Types"][3]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/jpeg", Extension: "jpg" } }] });
expect(tree["Types"][4]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/bmp", Extension: "bmp" } }] });
expect(tree["Types"][5]).to.deep.equal({ Default: [{ _attr: { ContentType: "image/gif", Extension: "gif" } }] });
expect(tree["Types"][1]).to.deep.equal({ Default: { _attr: { ContentType: "image/png", Extension: "png" } } });
expect(tree["Types"][2]).to.deep.equal({ Default: { _attr: { ContentType: "image/jpeg", Extension: "jpeg" } } });
expect(tree["Types"][3]).to.deep.equal({ Default: { _attr: { ContentType: "image/jpeg", Extension: "jpg" } } });
expect(tree["Types"][4]).to.deep.equal({ Default: { _attr: { ContentType: "image/bmp", Extension: "bmp" } } });
expect(tree["Types"][5]).to.deep.equal({ Default: { _attr: { ContentType: "image/gif", Extension: "gif" } } });
expect(tree["Types"][6]).to.deep.equal({
Default: [{ _attr: { ContentType: "application/vnd.openxmlformats-package.relationships+xml", Extension: "rels" } }],
Default: { _attr: { ContentType: "application/vnd.openxmlformats-package.relationships+xml", Extension: "rels" } },
});
expect(tree["Types"][7]).to.deep.equal({ Default: [{ _attr: { ContentType: "application/xml", Extension: "xml" } }] });
expect(tree["Types"][7]).to.deep.equal({ Default: { _attr: { ContentType: "application/xml", Extension: "xml" } } });
expect(tree["Types"][8]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
PartName: "/word/document.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
PartName: "/word/document.xml",
},
],
},
});
expect(tree["Types"][9]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
PartName: "/word/styles.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
PartName: "/word/styles.xml",
},
],
},
});
expect(tree["Types"][10]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-package.core-properties+xml",
PartName: "/docProps/core.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-package.core-properties+xml",
PartName: "/docProps/core.xml",
},
],
},
});
expect(tree["Types"][11]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml",
PartName: "/docProps/app.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml",
PartName: "/docProps/app.xml",
},
],
},
});
expect(tree["Types"][12]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
PartName: "/word/numbering.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
PartName: "/word/numbering.xml",
},
],
},
});
expect(tree["Types"][13]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
PartName: "/word/footnotes.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
PartName: "/word/footnotes.xml",
},
],
},
});
expect(tree["Types"][14]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
PartName: "/word/settings.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
PartName: "/word/settings.xml",
},
],
},
});
});
});
@ -109,25 +95,21 @@ describe("ContentTypes", () => {
const tree = new Formatter().format(contentTypes);
expect(tree["Types"][15]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
PartName: "/word/footer101.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
PartName: "/word/footer101.xml",
},
],
},
});
expect(tree["Types"][16]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
PartName: "/word/footer102.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
PartName: "/word/footer102.xml",
},
],
},
});
});
});
@ -139,25 +121,21 @@ describe("ContentTypes", () => {
const tree = new Formatter().format(contentTypes);
expect(tree["Types"][15]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
PartName: "/word/header201.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
PartName: "/word/header201.xml",
},
],
},
});
expect(tree["Types"][16]).to.deep.equal({
Override: [
{
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
PartName: "/word/header202.xml",
},
Override: {
_attr: {
ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
PartName: "/word/header202.xml",
},
],
},
});
});
});

View File

@ -30,14 +30,14 @@ describe("Body", () => {
const formatted = new Formatter().format(body)["w:body"];
expect(formatted).to.be.an.instanceof(Array);
const defaultSectionPr = formatted[0]["w:p"][1]["w:pPr"][0]["w:sectPr"];
const defaultSectionPr = formatted[0]["w:p"][0]["w:pPr"][0]["w:sectPr"];
// check that this is the default section and added first in paragraph
expect(defaultSectionPr[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(defaultSectionPr[0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
// check for new section (since it's the last one, it's direct child of body)
const newSection = formatted[1]["w:sectPr"];
expect(newSection[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } }] });
expect(newSection[0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } } });
});
it("should add section with default parameters", () => {
@ -52,30 +52,27 @@ describe("Body", () => {
"w:body": [
{
"w:p": [
{ "w:pPr": [] },
{
"w:pPr": [
{
"w:sectPr": [
{ "w:pgSz": [{ _attr: { "w:w": 11906, "w:h": 16838, "w:orient": "portrait" } }] },
{ "w:pgSz": { _attr: { "w:w": 11906, "w:h": 16838, "w:orient": "portrait" } } },
{
"w:pgMar": [
{
_attr: {
"w:top": 1440,
"w:right": 1440,
"w:bottom": 1440,
"w:left": 1440,
"w:header": 708,
"w:footer": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:top": 1440,
"w:right": 1440,
"w:bottom": 1440,
"w:left": 1440,
"w:header": 708,
"w:footer": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
},
{ "w:cols": [{ _attr: { "w:space": 708 } }] },
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] },
{ "w:cols": { _attr: { "w:space": 708 } } },
{ "w:docGrid": { _attr: { "w:linePitch": 360 } } },
],
},
],
@ -84,25 +81,23 @@ describe("Body", () => {
},
{
"w:sectPr": [
{ "w:pgSz": [{ _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } }] },
{ "w:pgSz": { _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } } },
{
"w:pgMar": [
{
_attr: {
"w:top": 1440,
"w:right": 1440,
"w:bottom": 1440,
"w:left": 1440,
"w:header": 708,
"w:footer": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:top": 1440,
"w:right": 1440,
"w:bottom": 1440,
"w:left": 1440,
"w:header": 708,
"w:footer": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
},
{ "w:cols": [{ _attr: { "w:space": 708 } }] },
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] },
{ "w:cols": { _attr: { "w:space": 708 } } },
{ "w:docGrid": { _attr: { "w:linePitch": 360 } } },
],
},
],

View File

@ -21,8 +21,7 @@ describe("PageBorders", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgBorders"]);
expect(tree["w:pgBorders"]).to.be.an.instanceof(Array);
expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage" } });
expect(tree["w:pgBorders"]).to.deep.equal({ _attr: { "w:display": "firstPage" } });
});
it("should create page borders with full configuration", () => {
@ -58,32 +57,24 @@ describe("PageBorders", () => {
expect(tree["w:pgBorders"]).to.be.an.instanceof(Array);
expect(tree["w:pgBorders"][0]).to.deep.equal({ _attr: { "w:display": "firstPage", "w:zOrder": "back" } });
expect(tree["w:pgBorders"][1]).to.deep.equal({
"w:top": [
{
_attr: { "w:color": "001122", "w:size": 10, "w:val": "doubleWave" },
},
],
"w:top": {
_attr: { "w:color": "001122", "w:size": 10, "w:val": "doubleWave" },
},
});
expect(tree["w:pgBorders"][2]).to.deep.equal({
"w:right": [
{
_attr: { "w:color": "223344", "w:size": 20, "w:val": "double" },
},
],
"w:right": {
_attr: { "w:color": "223344", "w:size": 20, "w:val": "double" },
},
});
expect(tree["w:pgBorders"][3]).to.deep.equal({
"w:bottom": [
{
_attr: { "w:color": "556677", "w:size": 30, "w:val": "single" },
},
],
"w:bottom": {
_attr: { "w:color": "556677", "w:size": 30, "w:val": "single" },
},
});
expect(tree["w:pgBorders"][4]).to.deep.equal({
"w:left": [
{
_attr: { "w:color": "889900", "w:size": 40, "w:val": "dotted" },
},
],
"w:left": {
_attr: { "w:color": "889900", "w:size": 40, "w:val": "dotted" },
},
});
});
});

View File

@ -1,6 +1,6 @@
// http://officeopenxml.com/WPsectionBorders.php
import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
export enum PageBorderDisplay {
ALL_PAGES = "allPages",
@ -64,7 +64,7 @@ class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes>
};
}
export class PageBorders extends XmlComponent {
export class PageBorders extends IgnoreIfEmptyXmlComponent {
constructor(options?: IPageBordersOptions) {
super("w:pgBorders");
@ -97,10 +97,4 @@ export class PageBorders extends XmlComponent {
this.root.push(new PageBorder("w:left", options.pageBorderLeft));
}
}
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
}

View File

@ -12,8 +12,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array);
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 200, "w:w": 100, "w:orient": "portrait" } });
expect(tree["w:pgSz"]).to.deep.equal({ _attr: { "w:h": 200, "w:w": 100, "w:orient": "portrait" } });
});
it("should create page size with horizontal and invert the lengths", () => {
@ -21,8 +20,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array);
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 100, "w:w": 200, "w:orient": "landscape" } });
expect(tree["w:pgSz"]).to.deep.equal({ _attr: { "w:h": 100, "w:w": 200, "w:orient": "landscape" } });
});
});
});

View File

@ -39,29 +39,27 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
});
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] });
expect(tree["w:sectPr"][4]).to.deep.equal({ "w:headerReference": [{ _attr: { "r:id": "rId100", "w:type": "default" } }] });
expect(tree["w:sectPr"][5]).to.deep.equal({ "w:footerReference": [{ _attr: { "r:id": "rId200", "w:type": "even" } }] });
expect(tree["w:sectPr"][6]).to.deep.equal({ "w:pgNumType": [{ _attr: { "w:fmt": "cardinalText", "w:start": 10 } }] });
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708 } } });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } });
expect(tree["w:sectPr"][4]).to.deep.equal({ "w:headerReference": { _attr: { "r:id": "rId100", "w:type": "default" } } });
expect(tree["w:sectPr"][5]).to.deep.equal({ "w:footerReference": { _attr: { "r:id": "rId200", "w:type": "even" } } });
expect(tree["w:sectPr"][6]).to.deep.equal({ "w:pgNumType": { _attr: { "w:fmt": "cardinalText", "w:start": 10 } } });
});
it("should create section properties with no options", () => {
@ -69,25 +67,23 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
});
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] });
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": { _attr: { "w:space": 708 } } });
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": { _attr: { "w:linePitch": 360 } } });
});
it("should create section properties with changed options", () => {
@ -97,22 +93,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 0,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 0,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
});
});
@ -123,22 +117,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 0,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:bottom": 0,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
});
});
@ -150,22 +142,20 @@ describe("SectionProperties", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": { _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } } });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
"w:pgMar": {
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
"w:mirrorMargins": false,
},
],
},
});
});
@ -179,7 +169,7 @@ describe("SectionProperties", () => {
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const pgBorders = tree["w:sectPr"].find((item) => item["w:pgBorders"] !== undefined);
expect(pgBorders).to.deep.equal({
"w:pgBorders": [{ _attr: { "w:offsetFrom": "page" } }],
"w:pgBorders": { _attr: { "w:offsetFrom": "page" } },
});
});
@ -191,7 +181,7 @@ describe("SectionProperties", () => {
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const pgNumType = tree["w:sectPr"].find((item) => item["w:pgNumType"] !== undefined);
expect(pgNumType).to.deep.equal({
"w:pgNumType": [{ _attr: { "w:fmt": "upperRoman" } }],
"w:pgNumType": { _attr: { "w:fmt": "upperRoman" } },
});
});

View File

@ -11,8 +11,7 @@ describe("PageSize", () => {
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:titlePg"]);
expect(tree["w:titlePg"]).to.be.an.instanceof(Array);
expect(tree["w:titlePg"][0]).to.deep.equal({ _attr: { "w:val": "1" } });
expect(tree["w:titlePg"]).to.deep.equal({ _attr: { "w:val": "1" } });
});
});
});

View File

@ -52,7 +52,7 @@ describe("Document", () => {
expect(body[0])
.to.have.property("w:p")
.which.includes({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "sample paragraph text"] }],
"w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "sample paragraph text"] }],
});
});
});
@ -84,9 +84,9 @@ describe("Document", () => {
.to.have.property("w:tbl")
.which.includes({
"w:tblGrid": [
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 100 } }] },
{ "w:gridCol": { _attr: { "w:w": 100 } } },
{ "w:gridCol": { _attr: { "w:w": 100 } } },
{ "w:gridCol": { _attr: { "w:w": 100 } } },
],
});
expect(body[0]["w:tbl"].filter((x) => x["w:tr"])).to.have.length(2);

View File

@ -25,8 +25,8 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"][0]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("default");
});
it("should create with first headers and footers", () => {
@ -45,8 +45,8 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"][0]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"]._attr["w:type"]).to.equal("first");
});
it("should create with correct headers", () => {
@ -69,13 +69,13 @@ describe("File", () => {
const tree = new Formatter().format(doc.Document.Body);
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:headerReference"][0]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][6]["w:headerReference"][0]._attr["w:type"]).to.equal("even");
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][5]["w:headerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][6]["w:headerReference"]._attr["w:type"]).to.equal("even");
expect(tree["w:body"][1]["w:sectPr"][7]["w:footerReference"][0]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][8]["w:footerReference"][0]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][9]["w:footerReference"][0]._attr["w:type"]).to.equal("even");
expect(tree["w:body"][1]["w:sectPr"][7]["w:footerReference"]._attr["w:type"]).to.equal("default");
expect(tree["w:body"][1]["w:sectPr"][8]["w:footerReference"]._attr["w:type"]).to.equal("first");
expect(tree["w:body"][1]["w:sectPr"][9]["w:footerReference"]._attr["w:type"]).to.equal("even");
});
});

View File

@ -11,8 +11,7 @@ describe("Footnote", () => {
const tree = new Formatter().format(footnote);
expect(Object.keys(tree)).to.deep.equal(["w:footnote"]);
expect(tree["w:footnote"]).to.be.an.instanceof(Array);
expect(tree["w:footnote"][0]).to.deep.equal({ _attr: { "w:type": "separator", "w:id": 1 } });
expect(tree["w:footnote"]).to.deep.equal({ _attr: { "w:type": "separator", "w:id": 1 } });
});
it("should create a footnote without a footnote type", () => {
@ -20,8 +19,7 @@ describe("Footnote", () => {
const tree = new Formatter().format(footnote);
expect(Object.keys(tree)).to.deep.equal(["w:footnote"]);
expect(tree["w:footnote"]).to.be.an.instanceof(Array);
expect(tree["w:footnote"][0]).to.deep.equal({ _attr: { "w:id": 1 } });
expect(tree["w:footnote"]).to.deep.equal({ _attr: { "w:id": 1 } });
});
});
});

View File

@ -27,10 +27,10 @@ describe("Media", () => {
const file = new File();
const image1 = Media.addImage(file, "test");
const tree = new Formatter().format(image1.Paragraph);
const inlineElements = tree["w:p"][1]["w:r"][1]["w:drawing"][0]["wp:inline"];
const inlineElements = tree["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
const graphicData = inlineElements.find((x) => x["a:graphic"]);
expect(graphicData["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"][0]).to.deep.equal({
expect(graphicData["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
_attr: {
"r:embed": `rId{testId.png}`,
cstate: "none",
@ -39,10 +39,10 @@ describe("Media", () => {
const image2 = Media.addImage(file, "test");
const tree2 = new Formatter().format(image2.Paragraph);
const inlineElements2 = tree2["w:p"][1]["w:r"][1]["w:drawing"][0]["wp:inline"];
const inlineElements2 = tree2["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
const graphicData2 = inlineElements2.find((x) => x["a:graphic"]);
expect(graphicData2["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"][0]).to.deep.equal({
expect(graphicData2["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
_attr: {
"r:embed": `rId{testId.png}`,
cstate: "none",

View File

@ -7,6 +7,8 @@ import { LevelForOverride } from "./level";
import { Num } from "./num";
import { Numbering } from "./numbering";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Numbering", () => {
let numbering: Numbering;
@ -22,7 +24,7 @@ describe("Numbering", () => {
expect(abstractNums).to.have.lengthOf(1);
expect(abstractNums[0]["w:abstractNum"]).to.deep.include.members([
{ _attr: { "w:abstractNumId": 0, "w15:restartNumberingAfterBreak": 0 } },
{ "w:multiLevelType": [{ _attr: { "w:val": "hybridMultilevel" } }] },
{ "w:multiLevelType": { _attr: { "w:val": "hybridMultilevel" } } },
]);
abstractNums
@ -37,9 +39,9 @@ describe("Numbering", () => {
{ "w:numFmt": [{ _attr: { "w:val": "bullet" } }] },
]);
// Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test:
// {"w:lvlText": [{"_attr": {"w:val": "•"}}]},
// {"w:rPr": [{"w:rFonts": [{"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}]}]},
// {"w:pPr": [{"_attr": {}},
// {"w:lvlText": {"_attr": {"w:val": "•"}}},
// {"w:rPr": [{"w:rFonts": {"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}}]},
// {"w:pPr": [
// {"w:ind": [{"_attr": {"w:left": 720, "w:hanging": 360}}]}]},
});
});
@ -65,7 +67,7 @@ describe("Numbering", () => {
expect(n).to.be.instanceof(Num);
const tree = new Formatter().format(numbering);
const serializedN = tree["w:numbering"].find((obj) => obj["w:num"] && obj["w:num"][0]._attr["w:numId"] === n.id);
expect(serializedN["w:num"][1]["w:abstractNumId"][0]._attr["w:val"]).to.equal(a2.id);
expect(serializedN["w:num"][1]["w:abstractNumId"]._attr["w:val"]).to.equal(a2.id);
});
it("assigns a unique ID to each concrete numbering it creates", () => {
@ -89,10 +91,10 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)", "end");
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "end" } }] });
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:start": { _attr: { "w:val": 1 } } });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "end" } } });
expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } });
expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
});
it("uses 'start' as the default alignment", () => {
@ -100,10 +102,10 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(3, "lowerLetter", "%1)");
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({ _attr: { "w:ilvl": 3, "w15:tentative": 1 } });
expect(tree["w:lvl"]).to.include({ "w:start": [{ _attr: { "w:val": 1 } }] });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": [{ _attr: { "w:val": "start" } }] });
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:start": { _attr: { "w:val": 1 } } });
expect(tree["w:lvl"]).to.include({ "w:lvlJc": { _attr: { "w:val": "start" } } });
expect(tree["w:lvl"]).to.include({ "w:numFmt": { _attr: { "w:val": "lowerLetter" } } });
expect(tree["w:lvl"]).to.include({ "w:lvlText": { _attr: { "w:val": "%1)" } } });
});
describe("formatting methods: paragraph properties", () => {
@ -112,7 +114,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerLetter", "%0.").indent({ left: 720 });
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }],
"w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
});
});
@ -121,7 +123,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:pPr": [{ "w:spacing": { _attr: { "w:before": 50, "w:after": 150 } } }],
});
});
@ -130,7 +132,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
});
});
@ -139,7 +141,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
});
});
@ -148,7 +150,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
});
});
@ -157,7 +159,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
});
});
@ -170,16 +172,14 @@ describe("AbstractNumbering", () => {
{
"w:pBdr": [
{
"w:bottom": [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:val": "single",
"w:sz": "6",
},
"w:bottom": {
_attr: {
"w:color": "auto",
"w:space": "1",
"w:val": "single",
"w:sz": "6",
},
],
},
},
],
},
@ -194,7 +194,7 @@ describe("AbstractNumbering", () => {
expect(tree["w:lvl"]).to.include({
"w:pPr": [
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "left", "w:pos": 1200 } }] }],
"w:tabs": [{ "w:tab": { _attr: { "w:val": "left", "w:pos": 1200 } } }],
},
],
});
@ -207,7 +207,7 @@ describe("AbstractNumbering", () => {
expect(tree["w:lvl"]).to.include({
"w:pPr": [
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "right", "w:pos": 9026 } }] }],
"w:tabs": [{ "w:tab": { _attr: { "w:val": "right", "w:pos": 9026 } } }],
},
],
});
@ -218,7 +218,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepLines();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:keepLines": [] }],
"w:pPr": [{ "w:keepLines": EMPTY_OBJECT }],
});
});
@ -227,7 +227,7 @@ describe("AbstractNumbering", () => {
const level = abstractNumbering.createLevel(0, "lowerRoman", "%0.").keepNext();
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:pPr": [{ "w:keepNext": [] }],
"w:pPr": [{ "w:keepNext": EMPTY_OBJECT }],
});
});
});
@ -238,7 +238,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }],
});
});
@ -247,7 +247,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:smallCaps": { _attr: { "w:val": true } } }],
});
});
@ -256,7 +256,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:caps": { _attr: { "w:val": true } } }],
});
});
@ -265,7 +265,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:strike": { _attr: { "w:val": true } } }],
});
});
@ -274,7 +274,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:dstrike": { _attr: { "w:val": true } } }],
});
});
@ -283,7 +283,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "subscript" } } }],
});
});
@ -292,7 +292,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "superscript" } } }],
});
});
@ -302,7 +302,7 @@ describe("AbstractNumbering", () => {
const tree = new Formatter().format(level);
expect(tree["w:lvl"]).to.include({
"w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] },
{ "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
],
});
});
@ -312,7 +312,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
});
});
@ -321,7 +321,7 @@ describe("AbstractNumbering", () => {
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 } }] }],
"w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
});
});
@ -331,7 +331,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
});
});
@ -340,7 +340,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
});
});
@ -349,7 +349,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
});
});
});
@ -359,7 +359,7 @@ describe("AbstractNumbering", () => {
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" } }] }],
"w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
});
});
});
@ -388,20 +388,12 @@ describe("concrete numbering", () => {
},
},
{
"w:lvl": [
{
_attr: {
"w:ilvl": 3,
"w15:tentative": 1,
},
"w:lvl": {
_attr: {
"w:ilvl": 3,
"w15:tentative": 1,
},
{
"w:pPr": [],
},
{
"w:rPr": [],
},
],
},
},
],
});
@ -418,29 +410,19 @@ describe("concrete numbering", () => {
},
},
{
"w:startOverride": [
{
_attr: {
"w:val": 9,
},
"w:startOverride": {
_attr: {
"w:val": 9,
},
],
},
},
{
"w:lvl": [
{
_attr: {
"w:ilvl": 1,
"w15:tentative": 1,
},
"w:lvl": {
_attr: {
"w:ilvl": 1,
"w15:tentative": 1,
},
{
"w:pPr": [],
},
{
"w:rPr": [],
},
],
},
},
],
});
@ -454,7 +436,7 @@ describe("concrete numbering", () => {
"w:lvlOverride": [
{ _attr: { "w:ilvl": 1 } },
{
"w:lvl": [{ _attr: { "w15:tentative": 1, "w:ilvl": 1 } }, { "w:pPr": [] }, { "w:rPr": [] }],
"w:lvl": { _attr: { "w15:tentative": 1, "w:ilvl": 1 } },
},
],
});

View File

@ -10,7 +10,7 @@ describe("Spacing", () => {
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 } }],
"w:spacing": { _attr: { "w:after": 120, "w:before": 100, "w:line": 150 } },
});
});
@ -18,7 +18,7 @@ describe("Spacing", () => {
const spacing = new Spacing({ before: 100 });
const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({
"w:spacing": [{ _attr: { "w:before": 100 } }],
"w:spacing": { _attr: { "w:before": 100 } },
});
});
});
@ -30,7 +30,7 @@ describe("ContextualSpacing", () => {
const spacing = new ContextualSpacing(true);
const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({
"w:contextualSpacing": [{ _attr: { "w:val": 1 } }],
"w:contextualSpacing": { _attr: { "w:val": 1 } },
});
});
@ -38,7 +38,7 @@ describe("ContextualSpacing", () => {
const spacing = new ContextualSpacing(false);
const tree = new Formatter().format(spacing);
expect(tree).to.deep.equal({
"w:contextualSpacing": [{ _attr: { "w:val": 0 } }],
"w:contextualSpacing": { _attr: { "w:val": 0 } },
});
});
});

View File

@ -5,6 +5,8 @@ import { Formatter } from "export/formatter";
import { ImageParagraph } from "./image";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Image", () => {
let image: ImageParagraph;
@ -45,14 +47,8 @@ describe("Image", () => {
const tree = new Formatter().format(image);
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [
{
"w:rPr": [],
},
{
"w:drawing": [
{
@ -66,49 +62,41 @@ describe("Image", () => {
},
},
{
"wp:extent": [
{
_attr: {
cx: 20,
cy: 20,
},
"wp:extent": {
_attr: {
cx: 20,
cy: 20,
},
],
},
},
{
"wp:effectExtent": [
{
_attr: {
b: 0,
l: 0,
r: 0,
t: 0,
},
"wp:effectExtent": {
_attr: {
b: 0,
l: 0,
r: 0,
t: 0,
},
],
},
},
{
"wp:docPr": [
{
_attr: {
descr: "",
id: 0,
name: "",
},
"wp:docPr": {
_attr: {
descr: "",
id: 0,
name: "",
},
],
},
},
{
"wp:cNvGraphicFramePr": [
{
"a:graphicFrameLocks": [
{
_attr: {
noChangeAspect: 1,
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
},
"a:graphicFrameLocks": {
_attr: {
noChangeAspect: 1,
"xmlns:a": "http://schemas.openxmlformats.org/drawingml/2006/main",
},
],
},
},
],
},
@ -137,27 +125,23 @@ describe("Image", () => {
{
"pic:nvPicPr": [
{
"pic:cNvPr": [
{
_attr: {
desc: "",
id: 0,
name: "",
},
"pic:cNvPr": {
_attr: {
desc: "",
id: 0,
name: "",
},
],
},
},
{
"pic:cNvPicPr": [
{
"a:picLocks": [
{
_attr: {
noChangeArrowheads: 1,
noChangeAspect: 1,
},
"a:picLocks": {
_attr: {
noChangeArrowheads: 1,
noChangeAspect: 1,
},
],
},
},
],
},
@ -166,22 +150,20 @@ describe("Image", () => {
{
"pic:blipFill": [
{
"a:blip": [
{
_attr: {
cstate: "none",
"r:embed": "rId{test.png}",
},
"a:blip": {
_attr: {
cstate: "none",
"r:embed": "rId{test.png}",
},
],
},
},
{
"a:srcRect": [],
"a:srcRect": EMPTY_OBJECT,
},
{
"a:stretch": [
{
"a:fillRect": [],
"a:fillRect": EMPTY_OBJECT,
},
],
},
@ -197,24 +179,20 @@ describe("Image", () => {
{
"a:xfrm": [
{
"a:ext": [
{
_attr: {
cx: 10,
cy: 10,
},
"a:ext": {
_attr: {
cx: 10,
cy: 10,
},
],
},
},
{
"a:off": [
{
_attr: {
x: 0,
y: 0,
},
"a:off": {
_attr: {
x: 0,
y: 0,
},
],
},
},
],
},
@ -226,7 +204,7 @@ describe("Image", () => {
},
},
{
"a:avLst": [],
"a:avLst": EMPTY_OBJECT,
},
],
},

View File

@ -31,7 +31,7 @@ describe("Hyperlink", () => {
const tree = new Formatter().format(hyperlink);
const runJson = {
"w:r": [
{ "w:rPr": [{ "w:rStyle": [{ _attr: { "w:val": "Hyperlink" } }] }] },
{ "w:rPr": [{ "w:rStyle": { _attr: { "w:val": "Hyperlink" } } }] },
{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "https://example.com"] },
],
};

View File

@ -6,6 +6,8 @@ import * as file from "file";
import { Numbering } from "../numbering";
import { LeaderType } from "./formatting";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Paragraph", () => {
let paragraph: file.Paragraph;
@ -40,7 +42,7 @@ describe("Paragraph", () => {
expect(tree)
.to.be.an("array")
.which.includes({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "this is a test run"] }],
"w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "this is a test run"] }],
});
});
});
@ -52,7 +54,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading1" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading1" } } }],
},
],
});
@ -66,7 +68,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading2" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading2" } } }],
},
],
});
@ -80,7 +82,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading3" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading3" } } }],
},
],
});
@ -94,7 +96,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading4" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading4" } } }],
},
],
});
@ -108,7 +110,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading5" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading5" } } }],
},
],
});
@ -122,7 +124,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Heading6" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Heading6" } } }],
},
],
});
@ -136,7 +138,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "Title" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "Title" } } }],
},
],
});
@ -150,7 +152,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
},
],
});
@ -164,7 +166,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
},
],
});
@ -178,7 +180,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
},
],
});
@ -192,7 +194,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "start" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "start" } } }],
},
],
});
@ -206,7 +208,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "end" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "end" } } }],
},
],
});
@ -220,7 +222,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "distribute" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "distribute" } } }],
},
],
});
@ -234,7 +236,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
},
],
});
@ -252,14 +254,12 @@ describe("Paragraph", () => {
{
"w:tabs": [
{
"w:tab": [
{
_attr: {
"w:pos": 9026,
"w:val": "right",
},
"w:tab": {
_attr: {
"w:pos": 9026,
"w:val": "right",
},
],
},
},
],
},
@ -281,15 +281,13 @@ describe("Paragraph", () => {
{
"w:tabs": [
{
"w:tab": [
{
_attr: {
"w:pos": 100,
"w:val": "left",
"w:leader": "hyphen",
},
"w:tab": {
_attr: {
"w:pos": 100,
"w:val": "left",
"w:leader": "hyphen",
},
],
},
},
],
},
@ -311,15 +309,13 @@ describe("Paragraph", () => {
{
"w:tabs": [
{
"w:tab": [
{
_attr: {
"w:pos": 100,
"w:val": "right",
"w:leader": "dot",
},
"w:tab": {
_attr: {
"w:pos": 100,
"w:val": "right",
"w:leader": "dot",
},
],
},
},
],
},
@ -341,15 +337,13 @@ describe("Paragraph", () => {
{
"w:tabs": [
{
"w:tab": [
{
_attr: {
"w:pos": 100,
"w:val": "center",
"w:leader": "middleDot",
},
"w:tab": {
_attr: {
"w:pos": 100,
"w:val": "center",
"w:leader": "middleDot",
},
],
},
},
],
},
@ -367,7 +361,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:contextualSpacing": [{ _attr: { "w:val": 1 } }] }],
"w:pPr": [{ "w:contextualSpacing": { _attr: { "w:val": 1 } } }],
},
],
});
@ -379,7 +373,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:contextualSpacing": [{ _attr: { "w:val": 0 } }] }],
"w:pPr": [{ "w:contextualSpacing": { _attr: { "w:val": 0 } } }],
},
],
});
@ -397,16 +391,14 @@ describe("Paragraph", () => {
{
"w:pBdr": [
{
"w:bottom": [
{
_attr: {
"w:val": "single",
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
},
"w:bottom": {
_attr: {
"w:val": "single",
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
},
],
},
},
],
},
@ -430,28 +422,24 @@ describe("Paragraph", () => {
{
"w:pBdr": [
{
"w:left": [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
"w:val": "single",
},
"w:left": {
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
"w:val": "single",
},
],
},
},
{
"w:right": [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
"w:val": "single",
},
"w:right": {
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "6",
"w:val": "single",
},
],
},
},
],
},
@ -469,10 +457,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [{ "w:rPr": [] }, { "w:br": [{ _attr: { "w:type": "page" } }] }],
"w:r": [{ "w:br": { _attr: { "w:type": "page" } } }],
},
],
});
@ -488,7 +473,7 @@ describe("Paragraph", () => {
{
"w:pPr": [
{
"w:pageBreakBefore": [],
"w:pageBreakBefore": EMPTY_OBJECT,
},
],
},
@ -510,7 +495,7 @@ describe("Paragraph", () => {
.which.is.an("array")
.which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }],
"w:pStyle": { _attr: { "w:val": "ListParagraph" } },
});
});
@ -526,7 +511,7 @@ describe("Paragraph", () => {
.which.is.an("array")
.which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }],
"w:pStyle": { _attr: { "w:val": "ListParagraph" } },
});
});
@ -542,7 +527,7 @@ describe("Paragraph", () => {
.which.is.an("array")
.which.has.length.at.least(2);
expect(tree["w:p"][0]["w:pPr"][1]).to.deep.equal({
"w:numPr": [{ "w:ilvl": [{ _attr: { "w:val": 1 } }] }, { "w:numId": [{ _attr: { "w:val": 1 } }] }],
"w:numPr": [{ "w:ilvl": { _attr: { "w:val": 1 } } }, { "w:numId": { _attr: { "w:val": 1 } } }],
});
});
});
@ -565,7 +550,7 @@ describe("Paragraph", () => {
.which.is.an("array")
.which.has.length.at.least(1);
expect(tree["w:p"][0]["w:pPr"][0]).to.deep.equal({
"w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }],
"w:pStyle": { _attr: { "w:val": "ListParagraph" } },
});
});
@ -581,11 +566,11 @@ describe("Paragraph", () => {
"w:p": [
{
"w:pPr": [
{ "w:pStyle": [{ _attr: { "w:val": "ListParagraph" } }] },
{ "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 } } },
],
},
],
@ -602,7 +587,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:pStyle": [{ _attr: { "w:val": "myFancyStyle" } }] }],
"w:pPr": [{ "w:pStyle": { _attr: { "w:val": "myFancyStyle" } } }],
},
],
});
@ -616,7 +601,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }],
"w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
},
],
});
@ -630,7 +615,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 90, "w:line": 50 } }] }],
"w:pPr": [{ "w:spacing": { _attr: { "w:before": 90, "w:line": 50 } } }],
},
],
});
@ -642,7 +627,7 @@ describe("Paragraph", () => {
paragraph.keepLines();
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [{ "w:pPr": [{ "w:keepLines": [] }] }],
"w:p": [{ "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }] }],
});
});
});
@ -652,7 +637,7 @@ describe("Paragraph", () => {
paragraph.keepNext();
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [{ "w:pPr": [{ "w:keepNext": [] }] }],
"w:p": [{ "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }] }],
});
});
});
@ -662,7 +647,7 @@ describe("Paragraph", () => {
paragraph.bidirectional();
const tree = new Formatter().format(paragraph);
expect(tree).to.deep.equal({
"w:p": [{ "w:pPr": [{ "w:bidi": [] }] }],
"w:p": [{ "w:pPr": [{ "w:bidi": EMPTY_OBJECT }] }],
});
});
});
@ -674,7 +659,7 @@ describe("Paragraph", () => {
expect(tree).to.deep.equal({
"w:p": [
{
"w:pPr": [{ "w:outlineLvl": [{ _attr: { "w:val": "0" } }] }],
"w:pPr": [{ "w:outlineLvl": { _attr: { "w:val": "0" } } }],
},
],
});

View File

@ -1,8 +1,8 @@
// http://officeopenxml.com/WPparagraphProperties.php
import { XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlComponent } from "file/xml-components";
import { Border } from "./formatting/border";
export class ParagraphProperties extends XmlComponent {
export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {
public readonly paragraphBorder: Border;
constructor() {

View File

@ -1,6 +1,6 @@
import { XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlComponent } from "file/xml-components";
export class RunProperties extends XmlComponent {
export class RunProperties extends IgnoreIfEmptyXmlComponent {
constructor() {
super("w:rPr");
}

View File

@ -9,7 +9,7 @@ describe("Text", () => {
it("creates an empty text run if no text is given", () => {
const t = new Text("");
const f = new Formatter().format(t);
expect(f).to.deep.equal({ "w:t": [{ _attr: { "xml:space": "preserve" } }] });
expect(f).to.deep.equal({ "w:t": { _attr: { "xml:space": "preserve" } } });
});
it("adds the passed in text to the component", () => {

View File

@ -9,16 +9,16 @@ describe("RunFonts", () => {
it("uses the font name for both ascii and hAnsi", () => {
const tree = new Formatter().format(new RunFonts("Times"));
expect(tree).to.deep.equal({
"w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }],
"w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } },
});
});
it("uses hint if given", () => {
const tree = new Formatter().format(new RunFonts("Times", "default"));
expect(tree).to.deep.equal({
"w:rFonts": [
{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times", "w:hint": "default" } },
],
"w:rFonts": {
_attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times", "w:hint": "default" },
},
});
});
});

View File

@ -41,7 +41,7 @@ describe("Run", () => {
run.underline();
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }] }],
"w:r": [{ "w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }] }],
});
});
@ -49,7 +49,7 @@ describe("Run", () => {
run.underline("double", "990011");
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "990011" } }] }] }],
"w:r": [{ "w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "990011" } } }] }],
});
});
});
@ -114,7 +114,7 @@ describe("Run", () => {
"w:r": [
{
"w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] },
{ "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
],
},
],
@ -127,7 +127,7 @@ describe("Run", () => {
run.color("001122");
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:color": [{ _attr: { "w:val": "001122" } }] }] }],
"w:r": [{ "w:rPr": [{ "w:color": { _attr: { "w:val": "001122" } } }] }],
});
});
});
@ -139,7 +139,7 @@ describe("Run", () => {
expect(tree).to.deep.equal({
"w:r": [
{
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }],
"w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
},
],
});
@ -151,7 +151,7 @@ describe("Run", () => {
run.rightToLeft();
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:rtl": [{ _attr: { "w:val": true } }] }] }],
"w:r": [{ "w:rPr": [{ "w:rtl": { _attr: { "w:val": true } } }] }],
});
});
});
@ -162,11 +162,10 @@ describe("Run", () => {
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [
{ "w:rPr": [] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
{ "w:fldChar": { _attr: { "w:fldCharType": "begin" } } },
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "NUMPAGES"] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] },
{ "w:fldChar": { _attr: { "w:fldCharType": "separate" } } },
{ "w:fldChar": { _attr: { "w:fldCharType": "end" } } },
],
});
});
@ -178,11 +177,10 @@ describe("Run", () => {
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [
{ "w:rPr": [] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
{ "w:fldChar": { _attr: { "w:fldCharType": "begin" } } },
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "PAGE"] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] },
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] },
{ "w:fldChar": { _attr: { "w:fldCharType": "separate" } } },
{ "w:fldChar": { _attr: { "w:fldCharType": "end" } } },
],
});
});
@ -193,7 +191,7 @@ describe("Run", () => {
run.style("myRunStyle");
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [{ "w:rPr": [{ "w:rStyle": [{ _attr: { "w:val": "myRunStyle" } }] }] }],
"w:r": [{ "w:rPr": [{ "w:rStyle": { _attr: { "w:val": "myRunStyle" } } }] }],
});
});
});

View File

@ -17,17 +17,12 @@ describe("Sequential Identifier", () => {
const DEFAULT_SEQ = {
"w:r": [
{
"w:rPr": [],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
"w:fldChar": {
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
],
},
},
{
"w:instrText": [
@ -40,22 +35,18 @@ const DEFAULT_SEQ = {
],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "separate",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "separate",
},
],
},
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "end",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "end",
},
],
},
},
],
};

View File

@ -12,7 +12,7 @@ describe("TextRun", () => {
run = new TextRun("test");
const f = new Formatter().format(run);
expect(f).to.deep.equal({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "test"] }],
"w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "test"] }],
});
});
});

View File

@ -17,7 +17,7 @@ describe("Underline", () => {
const underline = new u.Underline();
const tree = new Formatter().format(underline);
expect(tree).to.deep.equal({
"w:u": [{ _attr: { "w:val": "single" } }],
"w:u": { _attr: { "w:val": "single" } },
});
});
@ -25,7 +25,7 @@ describe("Underline", () => {
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" } }],
"w:u": { _attr: { "w:val": "double", "w:color": "FF00CC" } },
});
});
});

View File

@ -11,8 +11,7 @@ describe("Relationships", () => {
const properties = new Relationships();
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["Relationships"]);
expect(tree["Relationships"]).to.be.an.instanceof(Array);
expect(tree["Relationships"][0]).to.deep.equal({
expect(tree["Relationships"]).to.deep.equal({
_attr: { xmlns: "http://schemas.openxmlformats.org/package/2006/relationships" },
});
});

View File

@ -2,13 +2,15 @@ import { expect } from "chai";
import { Formatter } from "export/formatter";
import { Compatibility } from "file/settings/compatibility";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Compatibility", () => {
describe("#constructor", () => {
it("creates an initially empty property object", () => {
const compatibility = new Compatibility();
const tree = new Formatter().format(compatibility);
expect(tree).to.deep.equal({ "w:compat": [] });
expect(tree).to.deep.equal({ "w:compat": EMPTY_OBJECT });
});
});
@ -18,7 +20,7 @@ describe("Compatibility", () => {
compatibility.doNotExpandShiftReturn();
const tree = new Formatter().format(compatibility);
expect(tree).to.deep.equal({ "w:compat": [{ "w:doNotExpandShiftReturn": [] }] });
expect(tree).to.deep.equal({ "w:compat": [{ "w:doNotExpandShiftReturn": EMPTY_OBJECT }] });
});
});
});

View File

@ -13,9 +13,7 @@ describe("Settings", () => {
expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:settings");
expect(tree["w:settings"]).is.an.instanceof(Array);
expect(tree["w:settings"]).has.length(1);
keys = Object.keys(tree["w:settings"][0]);
keys = Object.keys(tree["w:settings"]);
expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr");
@ -39,12 +37,12 @@ describe("Settings", () => {
expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:updateFields");
const updateFieldsArray = rootArray[1]["w:updateFields"];
keys = Object.keys(updateFieldsArray[0]);
const updateFields = rootArray[1]["w:updateFields"];
keys = Object.keys(updateFields);
expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr");
const updateFieldsAttr = updateFieldsArray[0]._attr;
const updateFieldsAttr = updateFields._attr;
expect(updateFieldsAttr["w:val"]).to.be.equal(true);
};
it("should add a UpdateFields with value true", () => {

View File

@ -5,22 +5,18 @@ import { Formatter } from "export/formatter";
import { UpdateFields } from "./update-fields";
const UF_TRUE = {
"w:updateFields": [
{
_attr: {
"w:val": true,
},
"w:updateFields": {
_attr: {
"w:val": true,
},
],
},
};
const UF_FALSE = {
"w:updateFields": [
{
_attr: {
"w:val": false,
},
"w:updateFields": {
_attr: {
"w:val": false,
},
],
},
};
describe("Update Fields", () => {
describe("#constructor", () => {

View File

@ -71,24 +71,34 @@ describe("External styles factory", () => {
deleted: false,
root: [
{
_attr: {
"w:ascii": "Arial",
"w:cstheme": "minorHAnsi",
"w:eastAsiaTheme": "minorHAnsi",
"w:hAnsi": "Arial",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:ascii": "Arial",
"w:cstheme": "minorHAnsi",
"w:eastAsiaTheme": "minorHAnsi",
"w:hAnsi": "Arial",
},
rootKey: "_attr",
},
],
rootKey: "w:rFonts",
},
{
_attr: {
"w:bidi": "ar-SA",
"w:eastAsia": "en-US",
"w:val": "en-US",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:bidi": "ar-SA",
"w:eastAsia": "en-US",
"w:val": "en-US",
},
rootKey: "_attr",
},
],
rootKey: "w:lang",
},
],
@ -104,13 +114,18 @@ describe("External styles factory", () => {
deleted: false,
root: [
{
_attr: {
"w:after": "160",
"w:line": "259",
"w:lineRule": "auto",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:after": "160",
"w:line": "259",
"w:lineRule": "auto",
},
rootKey: "_attr",
},
],
rootKey: "w:spacing",
},
],
@ -123,12 +138,17 @@ describe("External styles factory", () => {
rootKey: "w:docDefaults",
});
expect(importedStyle.root[2]).to.deep.equal({
_attr: {
"w:defLockedState": "1",
"w:defUIPriority": "99",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:defLockedState": "1",
"w:defUIPriority": "99",
},
rootKey: "_attr",
},
],
rootKey: "w:latentStyles",
});
});
@ -139,19 +159,28 @@ describe("External styles factory", () => {
expect(importedStyle.root.length).to.equal(5);
expect(importedStyle.root[3]).to.deep.equal({
_attr: {
"w:default": "1",
"w:styleId": "Normal",
"w:type": "paragraph",
},
deleted: false,
root: [
{
_attr: {
"w:val": "Normal",
},
deleted: false,
root: [],
root: {
"w:default": "1",
"w:styleId": "Normal",
"w:type": "paragraph",
},
rootKey: "_attr",
},
{
deleted: false,
root: [
{
deleted: false,
root: {
"w:val": "Normal",
},
rootKey: "_attr",
},
],
rootKey: "w:name",
},
{
@ -164,26 +193,40 @@ describe("External styles factory", () => {
});
expect(importedStyle.root[4]).to.deep.equal({
_attr: {
"w:styleId": "Heading1",
"w:type": "paragraph",
},
deleted: false,
root: [
{
_attr: {
"w:val": "heading 1",
},
deleted: false,
root: [],
root: {
"w:styleId": "Heading1",
"w:type": "paragraph",
},
rootKey: "_attr",
},
{
deleted: false,
root: [
{
deleted: false,
root: {
"w:val": "heading 1",
},
rootKey: "_attr",
},
],
rootKey: "w:name",
},
{
_attr: {
"w:val": "Normal",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:val": "Normal",
},
rootKey: "_attr",
},
],
rootKey: "w:basedOn",
},
{
@ -203,14 +246,19 @@ describe("External styles factory", () => {
deleted: false,
root: [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:sz": "4",
"w:val": "single",
},
deleted: false,
root: [],
root: [
{
deleted: false,
root: {
"w:color": "auto",
"w:space": "1",
"w:sz": "4",
"w:val": "single",
},
rootKey: "_attr",
},
],
rootKey: "w:bottom",
},
],

View File

@ -4,6 +4,8 @@ import { Formatter } from "export/formatter";
import { CharacterStyle } from "./character-style";
import { EMPTY_OBJECT } from "file/xml-components";
describe("CharacterStyle", () => {
describe("#constructor", () => {
it("should set the style type to character and use the given style id", () => {
@ -12,18 +14,15 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:rPr": [] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -35,19 +34,16 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] },
{ "w:rPr": [] },
{ "w:name": { _attr: { "w:val": "Style Name" } } },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -61,20 +57,17 @@ describe("CharacterStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{ "w:rPr": [] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": [{ _attr: { "w:val": "otherId" } }] },
{ "w:basedOn": { _attr: { "w:val": "otherId" } } },
],
});
});
@ -88,19 +81,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }],
"w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -114,19 +105,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -139,19 +128,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -164,19 +151,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -192,27 +177,23 @@ describe("CharacterStyle", () => {
{
"w:rPr": [
{
"w:vertAlign": [
{
_attr: {
"w:val": "superscript",
},
"w:vertAlign": {
_attr: {
"w:val": "superscript",
},
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
},
],
},
{
"w:unhideWhenUsed": [],
"w:uiPriority": {
_attr: {
"w:val": "99",
},
},
},
{
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -225,19 +206,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }],
"w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -250,19 +229,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -275,19 +252,17 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -300,21 +275,16 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:link": [{ _attr: { "w:val": "MyLink" } }] },
{ "w:link": { _attr: { "w:val": "MyLink" } } },
],
});
});
@ -326,19 +296,14 @@ describe("CharacterStyle", () => {
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "myStyleId" } },
{
"w:rPr": [],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{ "w:unhideWhenUsed": [] },
{ "w:semiHidden": [] },
{ "w:unhideWhenUsed": EMPTY_OBJECT },
{ "w:semiHidden": EMPTY_OBJECT },
],
});
});

View File

@ -2,52 +2,54 @@ import { expect } from "chai";
import { Formatter } from "export/formatter";
import * as components from "./components";
import { EMPTY_OBJECT } from "file/xml-components";
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" } }] });
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" } }] });
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" } }] });
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" } }] });
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" } }] });
expect(tree).to.deep.equal({ "w:uiPriority": { _attr: { "w:val": "123" } } });
});
it("UnhideWhenUsed#constructor", () => {
const style = new components.UnhideWhenUsed();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:unhideWhenUsed": [] });
expect(tree).to.deep.equal({ "w:unhideWhenUsed": EMPTY_OBJECT });
});
it("QuickFormat#constructor", () => {
const style = new components.QuickFormat();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:qFormat": [] });
expect(tree).to.deep.equal({ "w:qFormat": EMPTY_OBJECT });
});
it("SemiHidden#constructor", () => {
const style = new components.SemiHidden();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({ "w:semiHidden": [] });
expect(tree).to.deep.equal({ "w:semiHidden": EMPTY_OBJECT });
});
});

View File

@ -2,6 +2,8 @@ import { expect } from "chai";
import { Formatter } from "export/formatter";
import * as defaultStyels from "./default-styles";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Default Styles", () => {
it("HeadingStyle#constructor", () => {
const style = new defaultStyels.HeadingStyle("Heading1", "Heading 1");
@ -9,12 +11,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } },
{ "w:name": [{ _attr: { "w:val": "Heading 1" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 1" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -25,12 +25,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Title" } },
{ "w:name": [{ _attr: { "w:val": "Title" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Title" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -41,12 +39,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading1" } },
{ "w:name": [{ _attr: { "w:val": "Heading 1" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 1" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -57,12 +53,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading2" } },
{ "w:name": [{ _attr: { "w:val": "Heading 2" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 2" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -73,12 +67,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading3" } },
{ "w:name": [{ _attr: { "w:val": "Heading 3" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 3" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -89,12 +81,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading4" } },
{ "w:name": [{ _attr: { "w:val": "Heading 4" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 4" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -105,12 +95,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading5" } },
{ "w:name": [{ _attr: { "w:val": "Heading 5" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 5" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -121,12 +109,10 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "Heading6" } },
{ "w:name": [{ _attr: { "w:val": "Heading 6" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:next": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "Heading 6" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:next": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -137,11 +123,9 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "ListParagraph" } },
{ "w:name": [{ _attr: { "w:val": "List Paragraph" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:qFormat": [] },
{ "w:name": { _attr: { "w:val": "List Paragraph" } } },
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:qFormat": EMPTY_OBJECT },
],
});
});
@ -152,60 +136,52 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "FootnoteText" } },
{ "w:name": [{ _attr: { "w:val": "footnote text" } }] },
{ "w:name": { _attr: { "w:val": "footnote text" } } },
{
"w:pPr": [
{
"w:spacing": [
{
_attr: {
"w:after": 0,
"w:line": 240,
"w:lineRule": "auto",
},
"w:spacing": {
_attr: {
"w:after": 0,
"w:line": 240,
"w:lineRule": "auto",
},
],
},
},
],
},
{
"w:rPr": [
{
"w:sz": [
{
_attr: {
"w:val": 20,
},
"w:sz": {
_attr: {
"w:val": 20,
},
],
},
},
{
"w:szCs": [
{
_attr: {
"w:val": 20,
},
"w:szCs": {
_attr: {
"w:val": 20,
},
],
},
],
},
{ "w:basedOn": [{ _attr: { "w:val": "Normal" } }] },
{ "w:link": [{ _attr: { "w:val": "FootnoteTextChar" } }] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
},
],
},
{ "w:basedOn": { _attr: { "w:val": "Normal" } } },
{ "w:link": { _attr: { "w:val": "FootnoteTextChar" } } },
{
"w:semiHidden": [],
"w:uiPriority": {
_attr: {
"w:val": "99",
},
},
},
{
"w:unhideWhenUsed": [],
"w:semiHidden": EMPTY_OBJECT,
},
{
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
});
@ -217,36 +193,32 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "FootnoteReference" } },
{ "w:name": [{ _attr: { "w:val": "footnote reference" } }] },
{ "w:name": { _attr: { "w:val": "footnote reference" } } },
{
"w:rPr": [
{
"w:vertAlign": [
{
_attr: {
"w:val": "superscript",
},
"w:vertAlign": {
_attr: {
"w:val": "superscript",
},
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
},
],
},
{
"w:unhideWhenUsed": [],
"w:uiPriority": {
_attr: {
"w:val": "99",
},
},
},
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] },
{
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
{
"w:semiHidden": [],
"w:semiHidden": EMPTY_OBJECT,
},
],
});
@ -258,45 +230,39 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "FootnoteTextChar" } },
{ "w:name": [{ _attr: { "w:val": "Footnote Text Char" } }] },
{ "w:name": { _attr: { "w:val": "Footnote Text Char" } } },
{
"w:rPr": [
{
"w:sz": [
{
_attr: {
"w:val": 20,
},
"w:sz": {
_attr: {
"w:val": 20,
},
],
},
},
{
"w:szCs": [
{
_attr: {
"w:val": 20,
},
"w:szCs": {
_attr: {
"w:val": 20,
},
],
},
],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
},
],
},
{
"w:unhideWhenUsed": [],
"w:uiPriority": {
_attr: {
"w:val": "99",
},
},
},
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] },
{ "w:link": [{ _attr: { "w:val": "FootnoteText" } }] },
{
"w:semiHidden": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
{ "w:link": { _attr: { "w:val": "FootnoteText" } } },
{
"w:semiHidden": EMPTY_OBJECT,
},
],
});
@ -308,23 +274,21 @@ describe("Default Styles", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "Hyperlink" } },
{ "w:name": [{ _attr: { "w:val": "Hyperlink" } }] },
{ "w:name": { _attr: { "w:val": "Hyperlink" } } },
{
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "0563C1" } }] }, { "w:u": [{ _attr: { "w:val": "single" } }] }],
"w:rPr": [{ "w:color": { _attr: { "w:val": "0563C1" } } }, { "w:u": { _attr: { "w:val": "single" } } }],
},
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
{ "w:basedOn": [{ _attr: { "w:val": "DefaultParagraphFont" } }] },
{ "w:basedOn": { _attr: { "w:val": "DefaultParagraphFont" } } },
],
});
});

View File

@ -4,13 +4,15 @@ import { Formatter } from "export/formatter";
import { ParagraphStyle } from "./paragraph-style";
import { EMPTY_OBJECT } from "file/xml-components";
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": [] }, { "w:rPr": [] }],
"w:style": { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
});
});
@ -20,9 +22,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:name": { _attr: { "w:val": "Style Name" } } },
],
});
});
@ -35,9 +35,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:basedOn": [{ _attr: { "w:val": "otherId" } }] },
{ "w:basedOn": { _attr: { "w:val": "otherId" } } },
],
});
});
@ -46,12 +44,7 @@ describe("ParagraphStyle", () => {
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": [] },
{ "w:rPr": [] },
{ "w:qFormat": [] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:qFormat": EMPTY_OBJECT }],
});
});
@ -61,9 +54,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:next": [{ _attr: { "w:val": "otherId" } }] },
{ "w:next": { _attr: { "w:val": "otherId" } } },
],
});
});
@ -77,9 +68,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:ind": [{ _attr: { "w:left": 720 } }] }],
"w:pPr": [{ "w:ind": { _attr: { "w:left": 720 } } }],
},
{ "w:rPr": [] },
],
});
});
@ -91,9 +81,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:spacing": [{ _attr: { "w:before": 50, "w:after": 150 } }] }],
"w:pPr": [{ "w:spacing": { _attr: { "w:before": 50, "w:after": 150 } } }],
},
{ "w:rPr": [] },
],
});
});
@ -105,9 +94,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "center" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "center" } } }],
},
{ "w:rPr": [] },
],
});
});
@ -118,9 +106,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:spacing": [{ _attr: { "w:val": 24 } }] }],
"w:rPr": [{ "w:spacing": { _attr: { "w:val": 24 } } }],
},
],
});
@ -133,9 +120,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "left" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "left" } } }],
},
{ "w:rPr": [] },
],
});
});
@ -147,9 +133,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "right" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "right" } } }],
},
{ "w:rPr": [] },
],
});
});
@ -161,9 +146,8 @@ describe("ParagraphStyle", () => {
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{
"w:pPr": [{ "w:jc": [{ _attr: { "w:val": "both" } }] }],
"w:pPr": [{ "w:jc": { _attr: { "w:val": "both" } } }],
},
{ "w:rPr": [] },
],
});
});
@ -179,22 +163,19 @@ describe("ParagraphStyle", () => {
{
"w:pBdr": [
{
"w:bottom": [
{
_attr: {
"w:color": "auto",
"w:space": "1",
"w:val": "single",
"w:sz": "6",
},
"w:bottom": {
_attr: {
"w:color": "auto",
"w:space": "1",
"w:val": "single",
"w:sz": "6",
},
],
},
},
],
},
],
},
{ "w:rPr": [] },
],
});
});
@ -208,11 +189,10 @@ describe("ParagraphStyle", () => {
{
"w:pPr": [
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "left", "w:pos": 1200 } }] }],
"w:tabs": [{ "w:tab": { _attr: { "w:val": "left", "w:pos": 1200 } } }],
},
],
},
{ "w:rPr": [] },
],
});
});
@ -226,11 +206,10 @@ describe("ParagraphStyle", () => {
{
"w:pPr": [
{
"w:tabs": [{ "w:tab": [{ _attr: { "w:val": "right", "w:pos": 9026 } }] }],
"w:tabs": [{ "w:tab": { _attr: { "w:val": "right", "w:pos": 9026 } } }],
},
],
},
{ "w:rPr": [] },
],
});
});
@ -239,11 +218,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").keepLines();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:keepLines": [] }] },
{ "w:rPr": [] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:pPr": [{ "w:keepLines": EMPTY_OBJECT }] }],
});
});
@ -251,11 +226,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").keepNext();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:keepNext": [] }] },
{ "w:rPr": [] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:pPr": [{ "w:keepNext": EMPTY_OBJECT }] }],
});
});
@ -265,8 +236,7 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [{ "w:outlineLvl": [{ _attr: { "w:val": "1" } }] }] },
{ "w:rPr": [] },
{ "w:pPr": [{ "w:outlineLvl": { _attr: { "w:val": "1" } } }] },
],
});
});
@ -279,9 +249,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:sz": [{ _attr: { "w:val": 24 } }] }, { "w:szCs": [{ _attr: { "w:val": 24 } }] }],
"w:rPr": [{ "w:sz": { _attr: { "w:val": 24 } } }, { "w:szCs": { _attr: { "w:val": 24 } } }],
},
],
});
@ -293,9 +262,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:smallCaps": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:smallCaps": { _attr: { "w:val": true } } }],
},
],
});
@ -307,9 +275,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:caps": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:caps": { _attr: { "w:val": true } } }],
},
],
});
@ -321,9 +288,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:strike": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:strike": { _attr: { "w:val": true } } }],
},
],
});
@ -335,9 +301,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:dstrike": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:dstrike": { _attr: { "w:val": true } } }],
},
],
});
@ -349,9 +314,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "subscript" } }] }],
"w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "subscript" } } }],
},
],
});
@ -363,9 +327,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:vertAlign": [{ _attr: { "w:val": "superscript" } }] }],
"w:rPr": [{ "w:vertAlign": { _attr: { "w:val": "superscript" } } }],
},
],
});
@ -377,10 +340,9 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [
{ "w:rFonts": [{ _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } }] },
{ "w:rFonts": { _attr: { "w:ascii": "Times", "w:cs": "Times", "w:eastAsia": "Times", "w:hAnsi": "Times" } } },
],
},
],
@ -393,9 +355,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:b": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:b": { _attr: { "w:val": true } } }],
},
],
});
@ -407,9 +368,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:i": [{ _attr: { "w:val": true } }] }],
"w:rPr": [{ "w:i": { _attr: { "w:val": true } } }],
},
],
});
@ -422,9 +382,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "single" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "single" } } }],
},
],
});
@ -436,9 +395,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double" } } }],
},
],
});
@ -450,9 +408,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:u": [{ _attr: { "w:val": "double", "w:color": "005599" } }] }],
"w:rPr": [{ "w:u": { _attr: { "w:val": "double", "w:color": "005599" } } }],
},
],
});
@ -465,9 +422,8 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{
"w:rPr": [{ "w:color": [{ _attr: { "w:val": "123456" } }] }],
"w:rPr": [{ "w:color": { _attr: { "w:val": "123456" } } }],
},
],
});
@ -477,12 +433,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").link("MyLink");
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:link": [{ _attr: { "w:val": "MyLink" } }] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:link": { _attr: { "w:val": "MyLink" } } }],
});
});
@ -490,12 +441,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").semiHidden();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:semiHidden": [] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:semiHidden": EMPTY_OBJECT }],
});
});
@ -505,16 +451,12 @@ describe("ParagraphStyle", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
],
});
@ -524,12 +466,7 @@ describe("ParagraphStyle", () => {
const style = new ParagraphStyle("myStyleId").unhideWhenUsed();
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:unhideWhenUsed": [] },
],
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } }, { "w:unhideWhenUsed": EMPTY_OBJECT }],
});
});
});

View File

@ -12,7 +12,7 @@ describe("Style", () => {
});
const tree = new Formatter().format(style);
expect(tree).to.deep.equal({
"w:style": [{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId", "w:default": true } }],
"w:style": { _attr: { "w:type": "paragraph", "w:styleId": "myStyleId", "w:default": true } },
});
});
@ -28,7 +28,7 @@ describe("Style", () => {
expect(tree).to.deep.equal({
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "myStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Style Name" } }] },
{ "w:name": { _attr: { "w:val": "Style Name" } } },
],
});
});

View File

@ -6,6 +6,8 @@ import { CharacterStyle, ParagraphStyle } from "./style";
import { Styles } from "./styles";
import { EMPTY_OBJECT } from "file/xml-components";
describe("Styles", () => {
let styles: Styles;
@ -27,7 +29,7 @@ describe("Styles", () => {
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": [] }, { "w:rPr": [] }],
"w:style": { _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } },
},
]);
});
@ -40,9 +42,7 @@ describe("Styles", () => {
{
"w:style": [
{ _attr: { "w:type": "paragraph", "w:styleId": "pStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Paragraph Style" } }] },
{ "w:pPr": [] },
{ "w:rPr": [] },
{ "w:name": { _attr: { "w:val": "Paragraph Style" } } },
],
},
]);
@ -58,18 +58,15 @@ describe("Styles", () => {
{
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "pStyleId" } },
{ "w:rPr": [] },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
},
@ -84,19 +81,16 @@ describe("Styles", () => {
{
"w:style": [
{ _attr: { "w:type": "character", "w:styleId": "pStyleId" } },
{ "w:name": [{ _attr: { "w:val": "Character Style" } }] },
{ "w:rPr": [] },
{ "w:name": { _attr: { "w:val": "Character Style" } } },
{
"w:uiPriority": [
{
_attr: {
"w:val": "99",
},
"w:uiPriority": {
_attr: {
"w:val": "99",
},
],
},
},
{
"w:unhideWhenUsed": [],
"w:unhideWhenUsed": EMPTY_OBJECT,
},
],
},

View File

@ -49,13 +49,11 @@ const DEFAULT_TOC = {
{
"w:sdtPr": [
{
"w:alias": [
{
_attr: {
"w:val": "Table of Contents",
},
"w:alias": {
_attr: {
"w:val": "Table of Contents",
},
],
},
},
],
},
@ -63,23 +61,15 @@ const DEFAULT_TOC = {
"w:sdtContent": [
{
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [
{
"w:rPr": [],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
"w:fldChar": {
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
],
},
},
{
"w:instrText": [
@ -92,13 +82,11 @@ const DEFAULT_TOC = {
],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "separate",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "separate",
},
],
},
},
],
},
@ -106,22 +94,14 @@ const DEFAULT_TOC = {
},
{
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [
{
"w:rPr": [],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "end",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "end",
},
],
},
},
],
},
@ -137,13 +117,11 @@ const COMPLETE_TOC = {
{
"w:sdtPr": [
{
"w:alias": [
{
_attr: {
"w:val": "Summary",
},
"w:alias": {
_attr: {
"w:val": "Summary",
},
],
},
},
],
},
@ -151,23 +129,15 @@ const COMPLETE_TOC = {
"w:sdtContent": [
{
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [
{
"w:rPr": [],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
"w:fldChar": {
_attr: {
"w:fldCharType": "begin",
"w:dirty": true,
},
],
},
},
{
"w:instrText": [
@ -180,13 +150,11 @@ const COMPLETE_TOC = {
],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "separate",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "separate",
},
],
},
},
],
},
@ -194,22 +162,14 @@ const COMPLETE_TOC = {
},
{
"w:p": [
{
"w:pPr": [],
},
{
"w:r": [
{
"w:rPr": [],
},
{
"w:fldChar": [
{
_attr: {
"w:fldCharType": "end",
},
"w:fldChar": {
_attr: {
"w:fldCharType": "end",
},
],
},
},
],
},

View File

@ -4,20 +4,22 @@ import { Formatter } from "export/formatter";
import { GridCol, TableGrid } from "./grid";
import { EMPTY_OBJECT } from "file/xml-components";
describe("GridCol", () => {
describe("#constructor", () => {
it("sets the width attribute to the value given", () => {
const grid = new GridCol(1234);
const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({
"w:gridCol": [{ _attr: { "w:w": 1234 } }],
"w:gridCol": { _attr: { "w:w": 1234 } },
});
});
it("does not set a width attribute if not given", () => {
const grid = new GridCol();
const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({ "w:gridCol": [] });
expect(tree).to.deep.equal({ "w:gridCol": EMPTY_OBJECT });
});
});
});
@ -29,9 +31,9 @@ describe("TableGrid", () => {
const tree = new Formatter().format(grid);
expect(tree).to.deep.equal({
"w:tblGrid": [
{ "w:gridCol": [{ _attr: { "w:w": 1234 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 321 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 123 } }] },
{ "w:gridCol": { _attr: { "w:w": 1234 } } },
{ "w:gridCol": { _attr: { "w:w": 321 } } },
{ "w:gridCol": { _attr: { "w:w": 123 } } },
],
});
});

View File

@ -7,30 +7,26 @@ import { ShadingType, TableShading } from "./shading";
describe("TableShading", () => {
describe("#constructor", () => {
it("should create", () => {
const cellMargain = new TableShading({});
const tree = new Formatter().format(cellMargain);
const shading = new TableShading({});
const tree = new Formatter().format(shading);
expect(tree).to.deep.equal({
"w:shd": [
{
_attr: {},
},
],
"w:shd": {
_attr: {},
},
});
});
it("should create with params", () => {
const cellMargain = new TableShading({ val: ShadingType.PERCENT_40, color: "FF0000", fill: "555555" });
const tree = new Formatter().format(cellMargain);
const shading = new TableShading({ val: ShadingType.PERCENT_40, color: "FF0000", fill: "555555" });
const tree = new Formatter().format(shading);
expect(tree).to.deep.equal({
"w:shd": [
{
_attr: {
"w:color": "FF0000",
"w:fill": "555555",
"w:val": "pct40",
},
"w:shd": {
_attr: {
"w:color": "FF0000",
"w:fill": "555555",
"w:val": "pct40",
},
],
},
});
});
});

View File

@ -10,14 +10,12 @@ describe("TopCellMargain", () => {
const cellMargain = new TopCellMargain(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({
"w:top": [
{
_attr: {
"w:type": "dxa",
"w:w": 1,
},
"w:top": {
_attr: {
"w:type": "dxa",
"w:w": 1,
},
],
},
});
});
});
@ -29,14 +27,12 @@ describe("BottomCellMargain", () => {
const cellMargain = new BottomCellMargain(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({
"w:bottom": [
{
_attr: {
"w:type": "dxa",
"w:w": 1,
},
"w:bottom": {
_attr: {
"w:type": "dxa",
"w:w": 1,
},
],
},
});
});
});
@ -48,14 +44,12 @@ describe("LeftCellMargain", () => {
const cellMargain = new LeftCellMargain(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({
"w:start": [
{
_attr: {
"w:type": "dxa",
"w:w": 1,
},
"w:start": {
_attr: {
"w:type": "dxa",
"w:w": 1,
},
],
},
});
});
});
@ -67,14 +61,12 @@ describe("RightCellMargain", () => {
const cellMargain = new RightCellMargain(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({
"w:end": [
{
_attr: {
"w:type": "dxa",
"w:w": 1,
},
"w:end": {
_attr: {
"w:type": "dxa",
"w:w": 1,
},
],
},
});
});
});

View File

@ -12,44 +12,36 @@ describe("TableCellMargain", () => {
expect(tree).to.deep.equal({
"w:tcMar": [
{
"w:top": [
{
_attr: {
"w:type": "dxa",
"w:w": 0,
},
"w:top": {
_attr: {
"w:type": "dxa",
"w:w": 0,
},
],
},
},
{
"w:bottom": [
{
_attr: {
"w:type": "dxa",
"w:w": 0,
},
"w:bottom": {
_attr: {
"w:type": "dxa",
"w:w": 0,
},
],
},
},
{
"w:end": [
{
_attr: {
"w:type": "dxa",
"w:w": 0,
},
"w:end": {
_attr: {
"w:type": "dxa",
"w:w": 0,
},
],
},
},
{
"w:start": [
{
_attr: {
"w:type": "dxa",
"w:w": 0,
},
"w:start": {
_attr: {
"w:type": "dxa",
"w:w": 0,
},
],
},
},
],
});
@ -66,44 +58,36 @@ describe("TableCellMargain", () => {
expect(tree).to.deep.equal({
"w:tcMar": [
{
"w:top": [
{
_attr: {
"w:type": "dxa",
"w:w": 5,
},
"w:top": {
_attr: {
"w:type": "dxa",
"w:w": 5,
},
],
},
},
{
"w:bottom": [
{
_attr: {
"w:type": "dxa",
"w:w": 5,
},
"w:bottom": {
_attr: {
"w:type": "dxa",
"w:w": 5,
},
],
},
},
{
"w:end": [
{
_attr: {
"w:type": "dxa",
"w:w": 5,
},
"w:end": {
_attr: {
"w:type": "dxa",
"w:w": 5,
},
],
},
},
{
"w:start": [
{
_attr: {
"w:type": "dxa",
"w:w": 5,
},
"w:start": {
_attr: {
"w:type": "dxa",
"w:w": 5,
},
],
},
},
],
});

View File

@ -1,5 +1,5 @@
import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
interface ICellBorder {
readonly style: BorderStyle;
@ -24,17 +24,11 @@ class BaseTableCellBorder extends XmlComponent {
}
}
export class TableCellBorders extends XmlComponent {
export class TableCellBorders extends IgnoreIfEmptyXmlComponent {
constructor() {
super("w:tcBorders");
}
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopBorder(style: BorderStyle, size: number, color: string): TableCellBorders {
const top = new BaseTableCellBorder("w:top");
top.setProperties(style, size, color);

View File

@ -9,77 +9,80 @@ import { TableCellProperties } from "./table-cell-properties";
describe("TableCellProperties", () => {
describe("#constructor", () => {
it("creates an initially empty property object", () => {
const cellMargain = new TableCellProperties();
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [] });
const properties = new TableCellProperties();
// The TableCellProperties is ignorable if there are no attributes,
// which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(properties)).to.throw("XMLComponent did not format correctly");
});
});
describe("#addGridSpan", () => {
it("adds grid span", () => {
const cellMargain = new TableCellProperties();
cellMargain.addGridSpan(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:gridSpan": [{ _attr: { "w:val": 1 } }] }] });
const properties = new TableCellProperties();
properties.addGridSpan(1);
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:gridSpan": { _attr: { "w:val": 1 } } }] });
});
});
describe("#addVerticalMerge", () => {
it("adds vertical merge", () => {
const cellMargain = new TableCellProperties();
cellMargain.addVerticalMerge(VMergeType.CONTINUE);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "continue" } }] }] });
const properties = new TableCellProperties();
properties.addVerticalMerge(VMergeType.CONTINUE);
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "continue" } } }] });
});
});
describe("#setVerticalAlign", () => {
it("sets vertical align", () => {
const cellMargain = new TableCellProperties();
cellMargain.setVerticalAlign(VerticalAlign.BOTTOM);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vAlign": [{ _attr: { "w:val": "bottom" } }] }] });
const properties = new TableCellProperties();
properties.setVerticalAlign(VerticalAlign.BOTTOM);
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:vAlign": { _attr: { "w:val": "bottom" } } }] });
});
});
describe("#setWidth", () => {
it("should set width", () => {
const cellMargain = new TableCellProperties();
cellMargain.setWidth(1, WidthType.DXA);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": [{ _attr: { "w:type": "dxa", "w:w": 1 } }] }] });
const properties = new TableCellProperties();
properties.setWidth(1, WidthType.DXA);
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": { _attr: { "w:type": "dxa", "w:w": 1 } } }] });
});
it("should set width using default of AUTO", () => {
const cellMargain = new TableCellProperties();
cellMargain.setWidth(1);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": [{ _attr: { "w:type": "auto", "w:w": 1 } }] }] });
const properties = new TableCellProperties();
properties.setWidth(1);
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:tcW": { _attr: { "w:type": "auto", "w:w": 1 } } }] });
});
});
describe("#setShading", () => {
it("sets shading", () => {
const cellMargain = new TableCellProperties();
cellMargain.setShading({
const properties = new TableCellProperties();
properties.setShading({
fill: "test",
color: "000",
});
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:shd": [{ _attr: { "w:fill": "test", "w:color": "000" } }] }] });
const tree = new Formatter().format(properties);
expect(tree).to.deep.equal({ "w:tcPr": [{ "w:shd": { _attr: { "w:fill": "test", "w:color": "000" } } }] });
});
});
describe("#Borders", () => {
it("should return the TableCellBorders if Border has borders", () => {
const cellMargain = new TableCellProperties();
cellMargain.Borders.addTopBorder(BorderStyle.DASH_DOT_STROKED, 3, "red");
const borders = cellMargain.Borders;
const properties = new TableCellProperties();
properties.Borders.addTopBorder(BorderStyle.DASH_DOT_STROKED, 3, "red");
const borders = properties.Borders;
const tree = new Formatter().format(borders);
expect(tree).to.deep.equal({
"w:tcBorders": [{ "w:top": [{ _attr: { "w:val": "dashDotStroked", "w:sz": 3, "w:color": "red" } }] }],
"w:tcBorders": [{ "w:top": { _attr: { "w:val": "dashDotStroked", "w:sz": 3, "w:color": "red" } } }],
});
});
});

View File

@ -1,10 +1,10 @@
import { XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent } from "file/xml-components";
import { ITableShadingAttributesProperties, TableShading } from "../shading";
import { ITableCellMargainOptions, TableCellMargain } from "./cell-margain/table-cell-margains";
import { GridSpan, TableCellBorders, TableCellWidth, VAlign, VerticalAlign, VMerge, VMergeType, WidthType } from "./table-cell-components";
export class TableCellProperties extends XmlComponent {
export class TableCellProperties extends IgnoreIfEmptyXmlComponent {
private readonly cellBorder: TableCellBorders;
constructor() {

View File

@ -22,15 +22,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:top": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
"w:top": {
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
],
},
},
],
});
@ -44,15 +42,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:start": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
"w:start": {
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
],
},
},
],
});
@ -66,15 +62,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:bottom": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
"w:bottom": {
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
],
},
},
],
});
@ -88,15 +82,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:end": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
"w:end": {
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
],
},
},
],
});
@ -110,15 +102,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:left": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
"w:left": {
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
],
},
},
],
});
@ -132,15 +122,13 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:right": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
"w:right": {
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
],
},
},
],
});
@ -159,70 +147,58 @@ describe("TableCellBorders", () => {
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:top": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
"w:top": {
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
],
},
},
{
"w:end": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
"w:end": {
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
],
},
},
{
"w:bottom": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
"w:bottom": {
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
],
},
},
{
"w:start": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
"w:start": {
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
],
},
},
{
"w:left": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
"w:left": {
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
],
},
},
{
"w:right": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
"w:right": {
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
],
},
},
],
});
@ -236,14 +212,12 @@ describe("TableCellWidth", () => {
const tcWidth = new TableCellWidth(100, WidthType.DXA);
const tree = new Formatter().format(tcWidth);
expect(tree).to.deep.equal({
"w:tcW": [
{
_attr: {
"w:type": "dxa",
"w:w": 100,
},
"w:tcW": {
_attr: {
"w:type": "dxa",
"w:w": 100,
},
],
},
});
});
});

View File

@ -30,16 +30,10 @@ export class TableCell extends XmlComponent {
public prepForXml(): IXmlableObject | undefined {
// Cells must end with a paragraph
const retval = super.prepForXml();
if (!retval) {
return undefined;
if (!(this.root[this.root.length - 1] instanceof Paragraph)) {
this.createParagraph();
}
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
return super.prepForXml();
}
public createParagraph(text?: string): Paragraph {

View File

@ -5,6 +5,8 @@ import { Formatter } from "export/formatter";
import { TableCell } from "./table-cell";
import { TableColumn } from "./table-column";
import { EMPTY_OBJECT } from "file/xml-components";
describe("TableColumn", () => {
let cells: TableCell[];
beforeEach(() => {
@ -37,15 +39,15 @@ describe("TableColumn", () => {
const tree = new Formatter().format(cells[0]);
expect(tree).to.deep.equal({
"w:tc": [{ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "restart" } }] }] }, { "w:p": [{ "w:pPr": [] }] }],
"w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "restart" } } }] }, { "w:p": EMPTY_OBJECT }],
});
const tree2 = new Formatter().format(cells[1]);
expect(tree2).to.deep.equal({ "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] });
expect(tree2).to.deep.equal({ "w:tc": [{ "w:p": EMPTY_OBJECT }] });
const tree3 = new Formatter().format(cells[2]);
expect(tree3).to.deep.equal({
"w:tc": [{ "w:tcPr": [{ "w:vMerge": [{ _attr: { "w:val": "continue" } }] }] }, { "w:p": [{ "w:pPr": [] }] }],
"w:tc": [{ "w:tcPr": [{ "w:vMerge": { _attr: { "w:val": "continue" } } }] }, { "w:p": EMPTY_OBJECT }],
});
});
});

View File

@ -18,7 +18,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin();
cellMargain.addTopMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:top": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] });
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:top": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
});
});
@ -27,7 +27,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin();
cellMargain.addLeftMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:left": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] });
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:left": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
});
});
@ -36,7 +36,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin();
cellMargain.addBottomMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:bottom": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] });
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:bottom": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
});
});
@ -45,7 +45,7 @@ describe("TableCellMargin", () => {
const cellMargain = new TableCellMargin();
cellMargain.addRightMargin(1234, WidthType.DXA);
const tree = new Formatter().format(cellMargain);
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:right": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] });
expect(tree).to.deep.equal({ "w:tblCellMar": [{ "w:right": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] });
});
});
});

View File

@ -1,4 +1,4 @@
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { WidthType } from "../table-cell";
@ -17,17 +17,11 @@ class BaseTableCellMargin extends XmlComponent {
}
}
export class TableCellMargin extends XmlComponent {
export class TableCellMargin extends IgnoreIfEmptyXmlComponent {
constructor() {
super("w:tblCellMar");
}
public prepForXml(): IXmlableObject | undefined {
if (this.root.length > 0) {
return super.prepForXml();
}
}
public addTopMargin(value: number, type: WidthType = WidthType.DXA): void {
const top = new BaseTableCellMargin("w:top");

View File

@ -26,20 +26,18 @@ describe("Table Float Properties", () => {
});
const DEFAULT_TFP = {
"w:tblpPr": [
{
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
"w:tblpPr": {
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
],
},
};

View File

@ -9,8 +9,11 @@ describe("TableProperties", () => {
describe("#constructor", () => {
it("creates an initially empty property object", () => {
const tp = new TableProperties();
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({ "w:tblPr": [] });
// The TableProperties is ignorable if there are no attributes,
// which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(tp)).to.throw("XMLComponent did not format correctly");
});
});
@ -19,7 +22,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setWidth(1234, WidthType.DXA);
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblW": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }],
"w:tblPr": [{ "w:tblW": { _attr: { "w:type": "dxa", "w:w": 1234 } } }],
});
});
@ -27,7 +30,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setWidth(1234);
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 1234 } }] }],
"w:tblPr": [{ "w:tblW": { _attr: { "w:type": "auto", "w:w": 1234 } } }],
});
});
});
@ -37,7 +40,7 @@ describe("TableProperties", () => {
const tp = new TableProperties().setFixedWidthLayout();
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblLayout": [{ _attr: { "w:type": "fixed" } }] }],
"w:tblPr": [{ "w:tblLayout": { _attr: { "w:type": "fixed" } } }],
});
});
});
@ -48,7 +51,7 @@ describe("TableProperties", () => {
tp.CellMargin.addTopMargin(1234, WidthType.DXA);
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblCellMar": [{ "w:top": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }],
"w:tblPr": [{ "w:tblCellMar": [{ "w:top": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] }],
});
});
@ -57,7 +60,7 @@ describe("TableProperties", () => {
tp.CellMargin.addLeftMargin(1234, WidthType.DXA);
const tree = new Formatter().format(tp);
expect(tree).to.deep.equal({
"w:tblPr": [{ "w:tblCellMar": [{ "w:left": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }] }],
"w:tblPr": [{ "w:tblCellMar": [{ "w:left": { _attr: { "w:type": "dxa", "w:w": 1234 } } }] }],
});
});
});

View File

@ -1,4 +1,4 @@
import { XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent } from "file/xml-components";
import { ITableShadingAttributesProperties, TableShading } from "../shading";
import { WidthType } from "../table-cell";
@ -8,7 +8,7 @@ import { ITableFloatOptions, TableFloatProperties } from "./table-float-properti
import { TableLayout, TableLayoutType } from "./table-layout";
import { PreferredTableWidth } from "./table-width";
export class TableProperties extends XmlComponent {
export class TableProperties extends IgnoreIfEmptyXmlComponent {
private readonly cellMargin: TableCellMargin;
constructor() {

View File

@ -6,8 +6,11 @@ describe("TableRowProperties", () => {
describe("#constructor", () => {
it("creates an initially empty property object", () => {
const rowProperties = new TableRowProperties();
const tree = new Formatter().format(rowProperties);
expect(tree).to.deep.equal({ "w:trPr": [] });
// The TableRowProperties is ignorable if there are no attributes,
// which results in prepForXml returning undefined, which causes
// the formatter to throw an error if that is the only object it
// has been asked to format.
expect(() => new Formatter().format(rowProperties)).to.throw("XMLComponent did not format correctly");
});
});
@ -16,7 +19,7 @@ describe("TableRowProperties", () => {
const rowProperties = new TableRowProperties();
rowProperties.setCantSplit();
const tree = new Formatter().format(rowProperties);
expect(tree).to.deep.equal({ "w:trPr": [{ "w:cantSplit": [{ _attr: { "w:val": true } }] }] });
expect(tree).to.deep.equal({ "w:trPr": [{ "w:cantSplit": { _attr: { "w:val": true } } }] });
});
});
@ -25,7 +28,7 @@ describe("TableRowProperties", () => {
const rowProperties = new TableRowProperties();
rowProperties.setTableHeader();
const tree = new Formatter().format(rowProperties);
expect(tree).to.deep.equal({ "w:trPr": [{ "w:tblHeader": [{ _attr: { "w:val": true } }] }] });
expect(tree).to.deep.equal({ "w:trPr": [{ "w:tblHeader": { _attr: { "w:val": true } } }] });
});
});
});

View File

@ -1,6 +1,6 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { IgnoreIfEmptyXmlComponent, XmlAttributeComponent, XmlComponent } from "file/xml-components";
export class TableRowProperties extends XmlComponent {
export class TableRowProperties extends IgnoreIfEmptyXmlComponent {
constructor() {
super("w:trPr");
}

View File

@ -5,17 +5,15 @@ import { Formatter } from "export/formatter";
import { TableCell } from "../table-cell";
import { TableRow } from "./table-row";
import { EMPTY_OBJECT } from "file/xml-components";
describe("TableRow", () => {
describe("#constructor", () => {
it("should create with no cells", () => {
const tableRow = new TableRow([]);
const tree = new Formatter().format(tableRow);
expect(tree).to.deep.equal({
"w:tr": [
{
"w:trPr": [],
},
],
"w:tr": EMPTY_OBJECT,
});
});
@ -24,20 +22,10 @@ describe("TableRow", () => {
const tree = new Formatter().format(tableRow);
expect(tree).to.deep.equal({
"w:tr": [
{
"w:trPr": [],
},
{
"w:tc": [
{
"w:tcPr": [],
},
{
"w:p": [
{
"w:pPr": [],
},
],
"w:p": EMPTY_OBJECT,
},
],
},

View File

@ -8,71 +8,63 @@ import { Table } from "./table";
// import { WidthType } from "./table-cell";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-properties";
import { EMPTY_OBJECT } from "file/xml-components";
const DEFAULT_TABLE_PROPERTIES = {
"w:tblCellMar": [
{
"w:bottom": [
{
_attr: {
"w:type": "auto",
"w:w": 0,
},
"w:bottom": {
_attr: {
"w:type": "auto",
"w:w": 0,
},
],
},
},
{
"w:top": [
{
_attr: {
"w:type": "auto",
"w:w": 0,
},
"w:top": {
_attr: {
"w:type": "auto",
"w:w": 0,
},
],
},
},
{
"w:left": [
{
_attr: {
"w:type": "auto",
"w:w": 0,
},
"w:left": {
_attr: {
"w:type": "auto",
"w:w": 0,
},
],
},
},
{
"w:right": [
{
_attr: {
"w:type": "auto",
"w:w": 0,
},
"w:right": {
_attr: {
"w:type": "auto",
"w:w": 0,
},
],
},
},
],
};
const BORDERS = {
"w:tblBorders": [
{ "w:top": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:left": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:bottom": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:right": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:insideH": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:insideV": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
{ "w:top": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:left": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:bottom": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:right": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:insideH": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
{ "w:insideV": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
],
};
const WIDTHS = {
"w:tblW": [
{
_attr: {
"w:type": "auto",
"w:w": 100,
},
"w:tblW": {
_attr: {
"w:type": "auto",
"w:w": 100,
},
],
},
};
// const f = {
@ -81,45 +73,43 @@ const WIDTHS = {
// "w:tblPr": [
// {
// "w:tblCellMar": [
// { "w:bottom": [{ _attr: { "w:type": "auto", "w:w": 0 } }] },
// { "w:top": [{ _attr: { "w:type": "auto", "w:w": 0 } }] },
// { "w:left": [{ _attr: { "w:type": "auto", "w:w": 0 } }] },
// { "w:right": [{ _attr: { "w:type": "auto", "w:w": 0 } }] },
// { "w:bottom": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:top": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:left": { _attr: { "w:type": "auto", "w:w": 0 } } },
// { "w:right": { _attr: { "w:type": "auto", "w:w": 0 } } },
// ],
// },
// {
// "w:tblBorders": [
// { "w:top": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:left": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:bottom": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:right": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:insideH": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:insideV": [{ _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } }] },
// { "w:top": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:left": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:bottom": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:right": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:insideH": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// { "w:insideV": { _attr: { "w:val": "single", "w:sz": 4, "w:space": 0, "w:color": "auto" } } },
// ],
// },
// { "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 100 } }] },
// { "w:tblW": { _attr: { "w:type": "auto", "w:w": 100 } } },
// {
// "w:tblpPr": [
// {
// _attr: {
// "w:horzAnchor": "margin",
// "w:vertAnchor": "page",
// "w:tblpX": 10,
// "w:tblpXSpec": "center",
// "w:tblpY": 20,
// "w:tblpYSpec": "bottom",
// "w:bottomFromText": 30,
// "w:topFromText": 40,
// "w:leftFromText": 50,
// "w:rightFromText": 60,
// },
// "w:tblpPr": {
// _attr: {
// "w:horzAnchor": "margin",
// "w:vertAnchor": "page",
// "w:tblpX": 10,
// "w:tblpXSpec": "center",
// "w:tblpY": 20,
// "w:tblpYSpec": "bottom",
// "w:bottomFromText": 30,
// "w:topFromText": 40,
// "w:leftFromText": 50,
// "w:rightFromText": 60,
// },
// ],
// },
// },
// ],
// },
// { "w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }] },
// { "w:tr": [{ "w:trPr": [] }, { "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] }] },
// { "w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }] },
// { "w:tr": [{ "w:tc": [{ "w:p": EMPTY_OBJECT }] }] },
// ],
// };
@ -131,16 +121,16 @@ describe("Table", () => {
columns: 2,
});
const tree = new Formatter().format(table);
const cell = { "w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }] };
const cell = { "w:tc": [{ "w:p": EMPTY_OBJECT }] };
expect(tree).to.deep.equal({
"w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }],
"w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
},
{ "w:tr": [{ "w:trPr": [] }, cell, cell] },
{ "w:tr": [{ "w:trPr": [] }, cell, cell] },
{ "w:tr": [{ "w:trPr": [] }, cell, cell] },
{ "w:tr": [cell, cell] },
{ "w:tr": [cell, cell] },
{ "w:tr": [cell, cell] },
],
});
});
@ -172,9 +162,8 @@ describe("Table", () => {
const tree = new Formatter().format(table);
const cell = (c) => ({
"w:tc": [
{ "w:tcPr": [] },
{
"w:p": [{ "w:pPr": [] }, { "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
"w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
},
],
});
@ -182,10 +171,10 @@ describe("Table", () => {
"w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }],
"w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
},
{ "w:tr": [{ "w:trPr": [] }, cell("A1"), cell("B1")] },
{ "w:tr": [{ "w:trPr": [] }, cell("A2"), cell("B2")] },
{ "w:tr": [cell("A1"), cell("B1")] },
{ "w:tr": [cell("A2"), cell("B2")] },
],
});
});
@ -222,9 +211,8 @@ describe("Table", () => {
const tree = new Formatter().format(table);
const cell = (c) => ({
"w:tc": [
{ "w:tcPr": [] },
{
"w:p": [{ "w:pPr": [] }, { "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
"w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, c] }] }],
},
],
});
@ -232,10 +220,10 @@ describe("Table", () => {
"w:tbl": [
{ "w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS] },
{
"w:tblGrid": [{ "w:gridCol": [{ _attr: { "w:w": 100 } }] }, { "w:gridCol": [{ _attr: { "w:w": 100 } }] }],
"w:tblGrid": [{ "w:gridCol": { _attr: { "w:w": 100 } } }, { "w:gridCol": { _attr: { "w:w": 100 } } }],
},
{ "w:tr": [{ "w:trPr": [] }, cell("A1"), cell("B1")] },
{ "w:tr": [{ "w:trPr": [] }, cell("A2"), cell("B2")] },
{ "w:tr": [cell("A1"), cell("B1")] },
{ "w:tr": [cell("A2"), cell("B2")] },
],
});
});
@ -250,7 +238,7 @@ describe("Table", () => {
// .which.is.an("array")
// .with.has.length.at.least(1);
// expect(tree["w:tbl"][0]).to.deep.equal({
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": [{ _attr: { "w:type": "pct", "w:w": "1000%" } }] }],
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": { _attr: { "w:type": "pct", "w:w": "1000%" } } }],
// });
// });
@ -259,7 +247,7 @@ describe("Table", () => {
// const tree = new Formatter().format(table);
// expect(tree["w:tbl"][0]).to.deep.equal({
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": [{ _attr: { "w:type": "auto", "w:w": 1000 } }] }],
// "w:tblPr": [DEFAULT_TABLE_PROPERTIES, { "w:tblW": { _attr: { "w:type": "auto", "w:w": 1000 } } }],
// });
// });
// });
@ -276,7 +264,7 @@ describe("Table", () => {
.which.is.an("array")
.with.has.length.at.least(1);
expect(tree["w:tbl"][0]).to.deep.equal({
"w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS, { "w:tblLayout": [{ _attr: { "w:type": "fixed" } }] }],
"w:tblPr": [DEFAULT_TABLE_PROPERTIES, BORDERS, WIDTHS, { "w:tblLayout": { _attr: { "w:type": "fixed" } } }],
});
});
});
@ -298,7 +286,7 @@ describe("Table", () => {
.to.be.an("array")
.which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [{ "w:tcPr": [] }, { "w:p": [{ "w:pPr": [] }] }],
"w:tc": [{ "w:p": EMPTY_OBJECT }],
});
});
@ -325,7 +313,7 @@ describe("Table", () => {
const cell = row["w:tr"].find((x) => x["w:tc"]);
expect(cell).not.to.be.undefined;
expect(cell["w:tc"][cell["w:tc"].length - 1]).to.deep.equal({
"w:p": [{ "w:pPr": [] }],
"w:p": EMPTY_OBJECT,
});
});
@ -346,12 +334,8 @@ describe("Table", () => {
.which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [
{ "w:tcPr": [] },
{
"w:p": [
{ "w:pPr": [] },
{ "w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "Hello"] }] },
],
"w:p": [{ "w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "Hello"] }] }],
},
],
});
@ -377,12 +361,10 @@ describe("Table", () => {
.which.has.length.at.least(1);
expect(row["w:tr"].find((x) => x["w:tc"])).to.deep.equal({
"w:tc": [
{ "w:tcPr": [] },
{
"w:p": [
{ "w:pPr": [] },
{
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "Test paragraph"] }],
"w:r": [{ "w:t": [{ _attr: { "xml:space": "preserve" } }, "Test paragraph"] }],
},
],
},
@ -421,22 +403,20 @@ describe("Table", () => {
BORDERS,
WIDTHS,
{
"w:tblpPr": [
{
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
"w:tblpPr": {
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
],
},
},
],
});

View File

@ -6,7 +6,7 @@ export type AttributeMap<T> = { [P in keyof T]: string };
export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
// tslint:disable-next-line:readonly-keyword
protected root: T;
protected readonly xmlKeys: AttributeMap<T>;
protected readonly xmlKeys?: AttributeMap<T>;
constructor(properties: T) {
super("_attr");
@ -18,7 +18,7 @@ export abstract class XmlAttributeComponent<T> extends BaseXmlComponent {
Object.keys(this.root).forEach((key) => {
const value = this.root[key];
if (value !== undefined) {
const newKey = this.xmlKeys[key];
const newKey = (this.xmlKeys && this.xmlKeys[key]) || key;
attrs[newKey] = value;
}
});

View File

@ -1,7 +1,7 @@
import { expect } from "chai";
import { Element, xml2js } from "xml-js";
import { ImportedXmlComponent } from "./";
import { EMPTY_OBJECT, ImportedXmlComponent } from "./";
import { convertToXmlComponent } from "./imported-xml-component";
const xmlString = `
@ -25,11 +25,25 @@ const convertedXmlElement = {
deleted: false,
rootKey: "w:p",
root: [
{ deleted: false, rootKey: "_attr", root: { "w:one": "value 1", "w:two": "value 2" } },
{ deleted: false, rootKey: "w:rPr", root: [{ deleted: false, rootKey: "w:noProof", root: ["some value"] }] },
{ deleted: false, rootKey: "w:r", root: [{ deleted: false, rootKey: "w:t", root: ["Text 1"] }], _attr: { active: "true" } },
{ deleted: false, rootKey: "w:r", root: [{ deleted: false, rootKey: "w:t", root: ["Text 2"] }], _attr: { active: "true" } },
{
deleted: false,
rootKey: "w:r",
root: [
{ deleted: false, rootKey: "_attr", root: { active: "true" } },
{ deleted: false, rootKey: "w:t", root: ["Text 1"] },
],
},
{
deleted: false,
rootKey: "w:r",
root: [
{ deleted: false, rootKey: "_attr", root: { active: "true" } },
{ deleted: false, rootKey: "w:t", root: ["Text 2"] },
],
},
],
_attr: { "w:one": "value 1", "w:two": "value 2" },
},
],
rootKey: undefined,
@ -59,7 +73,7 @@ describe("ImportedXmlComponent", () => {
},
},
{
"w:child": [],
"w:child": EMPTY_OBJECT,
},
],
});

View File

@ -1,6 +1,6 @@
// tslint:disable:no-any
import { Element as XmlElement, xml2js } from "xml-js";
import { IXmlableObject, XmlComponent } from ".";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from ".";
/**
* Converts the given xml element (in json format) into XmlComponent.
@ -27,6 +27,10 @@ export function convertToXmlComponent(element: XmlElement): ImportedXmlComponent
}
}
class ImportedXmlComponentAttributes extends XmlAttributeComponent<any> {
// noop
}
/**
* Represents imported xml component from xml file.
*/
@ -46,58 +50,14 @@ export class ImportedXmlComponent extends XmlComponent {
* @param importedContent xml content of the imported component
*/
// tslint:disable-next-line:variable-name
private readonly _attr: any;
// tslint:disable-next-line:variable-name
constructor(rootKey: string, _attr?: any) {
super(rootKey);
if (_attr) {
this._attr = _attr;
this.root.push(new ImportedXmlComponentAttributes(_attr));
}
}
/**
* Transforms the object so it can be converted to xml. Example:
* <w:someKey someAttr="1" otherAttr="11">
* <w:child childAttr="2">
* </w:child>
* </w:someKey>
* {
* 'w:someKey': [
* {
* _attr: {
* someAttr: "1",
* otherAttr: "11"
* }
* },
* {
* 'w:child': [
* {
* _attr: {
* childAttr: "2"
* }
* }
* ]
* }
* ]
* }
*/
public prepForXml(): IXmlableObject | undefined {
const result = super.prepForXml();
if (!result) {
return undefined;
}
if (!!this._attr) {
if (!Array.isArray(result[this.rootKey])) {
result[this.rootKey] = [result[this.rootKey]];
}
result[this.rootKey].unshift({ _attr: this._attr });
}
return result;
}
public push(xmlComponent: XmlComponent | string): void {
this.root.push(xmlComponent);
}

View File

@ -1,7 +1,7 @@
import { assert } from "chai";
import { expect } from "chai";
import { Utility } from "tests/utility";
import { XmlComponent } from "./";
import { EMPTY_OBJECT, XmlComponent } from "./";
class TestComponent extends XmlComponent {}
@ -15,7 +15,7 @@ describe("XmlComponent", () => {
describe("#constructor()", () => {
it("should create an Xml Component which has the correct rootKey", () => {
const newJson = Utility.jsonify(xmlComponent);
assert.equal(newJson.rootKey, "w:test");
expect(newJson.rootKey).to.equal("w:test");
});
});
@ -31,7 +31,7 @@ describe("XmlComponent", () => {
return;
}
assert.equal(xml["w:test"].length, 0);
expect(xml["w:test"]).to.deep.equal(EMPTY_OBJECT);
});
});
});

View File

@ -2,6 +2,8 @@ import { BaseXmlComponent } from "./base";
import { IXmlableObject } from "./xmlable-object";
export { BaseXmlComponent };
export const EMPTY_OBJECT = Object.seal({});
export abstract class XmlComponent extends BaseXmlComponent {
// tslint:disable-next-line:readonly-keyword
protected root: Array<BaseXmlComponent | string>;
@ -17,7 +19,7 @@ export abstract class XmlComponent extends BaseXmlComponent {
if (c instanceof BaseXmlComponent) {
return !c.IsDeleted;
}
return true;
return c !== undefined;
})
.map((comp) => {
if (comp instanceof BaseXmlComponent) {
@ -26,8 +28,15 @@ export abstract class XmlComponent extends BaseXmlComponent {
return comp;
})
.filter((comp) => comp !== undefined); // Exclude undefined
// If we only have a single IXmlableObject in our children array and it
// represents our attributes, use the object itself as our children to
// avoid an unneeded XML close element. (Note: We have to use this
// function to get typescript to allow our check.)
// Additionally, if the array is empty, use an empty object as our
// children in order to get an empty XML element generated.
const onlyAttrs = (c) => typeof c === "object" && c._attr;
return {
[this.rootKey]: children,
[this.rootKey]: children.length ? (children.length === 1 && onlyAttrs(children[0]) ? children[0] : children) : EMPTY_OBJECT,
};
}
@ -41,3 +50,14 @@ export abstract class XmlComponent extends BaseXmlComponent {
this.deleted = true;
}
}
export abstract class IgnoreIfEmptyXmlComponent extends XmlComponent {
public prepForXml(): IXmlableObject | undefined {
const result = super.prepForXml();
// Ignore the object if its falsey or is an empty object (would produce
// an empty XML element if allowed to be included in the output).
if (result && (typeof result[this.rootKey] !== "object" || Object.keys(result[this.rootKey]).length)) {
return result;
}
}
}