Tidied up table components
This commit is contained in:
2
src/file/table/table-properties/index.ts
Normal file
2
src/file/table/table-properties/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./table-properties";
|
||||
export * from "./table-float-properties";
|
36
src/file/table/table-properties/table-borders.ts
Normal file
36
src/file/table/table-properties/table-borders.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
export class TableBorders extends XmlComponent {
|
||||
constructor() {
|
||||
super("w:tblBorders");
|
||||
this.root.push(new TableBordersElement("w:top", "single", 4, 0, "auto"));
|
||||
this.root.push(new TableBordersElement("w:left", "single", 4, 0, "auto"));
|
||||
this.root.push(new TableBordersElement("w:bottom", "single", 4, 0, "auto"));
|
||||
this.root.push(new TableBordersElement("w:right", "single", 4, 0, "auto"));
|
||||
this.root.push(new TableBordersElement("w:insideH", "single", 4, 0, "auto"));
|
||||
this.root.push(new TableBordersElement("w:insideV", "single", 4, 0, "auto"));
|
||||
}
|
||||
}
|
||||
|
||||
class TableBordersElement extends XmlComponent {
|
||||
constructor(elementName: string, value: string, size: number, space: number, color: string) {
|
||||
super(elementName);
|
||||
this.root.push(
|
||||
new TableBordersAttributes({
|
||||
value,
|
||||
size,
|
||||
space,
|
||||
color,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TableBordersAttributes extends XmlAttributeComponent<{ value: string; size: number; space: number; color: string }> {
|
||||
protected xmlKeys = {
|
||||
value: "w:val",
|
||||
size: "w:sz",
|
||||
space: "w:space",
|
||||
color: "w:color",
|
||||
};
|
||||
}
|
58
src/file/table/table-properties/table-cell-margin.ts
Normal file
58
src/file/table/table-properties/table-cell-margin.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
import { WidthType } from "../table-cell";
|
||||
|
||||
class TableCellMarginAttributes extends XmlAttributeComponent<{ type: WidthType; value: number }> {
|
||||
protected xmlKeys = { value: "w:w", type: "w:sz" };
|
||||
}
|
||||
|
||||
class BaseTableCellMargin extends XmlComponent {
|
||||
public setProperties(value: number, type: WidthType = WidthType.DXA): void {
|
||||
this.root.push(
|
||||
new TableCellMarginAttributes({
|
||||
type: type,
|
||||
value: value,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class TableCellMargin extends XmlComponent {
|
||||
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");
|
||||
|
||||
top.setProperties(value, type);
|
||||
this.root.push(top);
|
||||
}
|
||||
|
||||
public addLeftMargin(value: number, type: WidthType = WidthType.DXA): void {
|
||||
const left = new BaseTableCellMargin("w:left");
|
||||
|
||||
left.setProperties(value, type);
|
||||
this.root.push(left);
|
||||
}
|
||||
|
||||
public addBottomMargin(value: number, type: WidthType = WidthType.DXA): void {
|
||||
const bottom = new BaseTableCellMargin("w:bottom");
|
||||
|
||||
bottom.setProperties(value, type);
|
||||
this.root.push(bottom);
|
||||
}
|
||||
|
||||
public addRightMargin(value: number, type: WidthType = WidthType.DXA): void {
|
||||
const right = new BaseTableCellMargin("w:right");
|
||||
|
||||
right.setProperties(value, type);
|
||||
this.root.push(right);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { Formatter } from "../../../export/formatter";
|
||||
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType, TableFloatProperties } from "./table-float-properties";
|
||||
|
||||
describe("Table Float Properties", () => {
|
||||
describe("#constructor", () => {
|
||||
it("should construct a TableFloatProperties with all options", () => {
|
||||
const tfp = new TableFloatProperties({
|
||||
horizontalAnchor: TableAnchorType.MARGIN,
|
||||
verticalAnchor: TableAnchorType.PAGE,
|
||||
absoluteHorizontalPosition: 10,
|
||||
relativeHorizontalPosition: RelativeHorizontalPosition.CENTER,
|
||||
absoluteVerticalPosition: 20,
|
||||
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
|
||||
bottomFromText: 30,
|
||||
topFromText: 40,
|
||||
leftFromText: 50,
|
||||
rightFromText: 60,
|
||||
});
|
||||
const tree = new Formatter().format(tfp);
|
||||
expect(tree).to.be.deep.equal(DEFAULT_TFP);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
134
src/file/table/table-properties/table-float-properties.ts
Normal file
134
src/file/table/table-properties/table-float-properties.ts
Normal file
@ -0,0 +1,134 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
export enum TableAnchorType {
|
||||
MARGIN = "margin",
|
||||
PAGE = "page",
|
||||
TEXT = "text",
|
||||
}
|
||||
|
||||
export enum RelativeHorizontalPosition {
|
||||
CENTER = "center",
|
||||
INSIDE = "inside",
|
||||
LEFT = "left",
|
||||
OUTSIDE = "outside",
|
||||
RIGHT = "right",
|
||||
}
|
||||
|
||||
export enum RelativeVerticalPosition {
|
||||
CENTER = "center",
|
||||
INSIDE = "inside",
|
||||
BOTTOM = "bottom",
|
||||
OUTSIDE = "outside",
|
||||
INLINE = "inline",
|
||||
TOP = "top",
|
||||
}
|
||||
|
||||
export interface ITableFloatOptions {
|
||||
/**
|
||||
* Specifies the horizontal anchor or the base object from which the horizontal positioning in the
|
||||
* tblpX or tblpXSpec attribute should be determined.
|
||||
* margin - relative to the vertical edge of the text margin before any text runs (left edge for left-to-right paragraphs)
|
||||
* page - relative to the vertical edge of the page before any text runs (left edge for left-to-right paragraphs)
|
||||
* text - relative to the vertical edge of the text margin for the column in which the anchor paragraph is located
|
||||
* If omitted, the value is assumed to be page.
|
||||
*/
|
||||
horizontalAnchor?: TableAnchorType;
|
||||
|
||||
/**
|
||||
* Specifies an absolute horizontal position for the table, relative to the horizontalAnchor.
|
||||
* The value is in twentieths of a point. Note that the value can be negative, in which case the
|
||||
* table is positioned before the anchor object in the direction of horizontal text flow.
|
||||
* If relativeHorizontalPosition is also specified, then the absoluteHorizontalPosition attribute is ignored.
|
||||
* If the attribute is omitted, the value is assumed to be zero.
|
||||
*/
|
||||
absoluteHorizontalPosition?: number;
|
||||
|
||||
/**
|
||||
* Specifies a relative horizontal position for the table, relative to the horizontalAnchor attribute.
|
||||
* This will supersede the absoluteHorizontalPosition attribute.
|
||||
* Possible values are:
|
||||
* center - the table should be horizontally centered with respect to the anchor
|
||||
* inside - the table should be inside of the anchor
|
||||
* left - the table should be left aligned with respect to the anchor
|
||||
* outside - the table should be outside of the anchor
|
||||
* right - the table should be right aligned with respect to the anchor
|
||||
*/
|
||||
relativeHorizontalPosition?: RelativeHorizontalPosition;
|
||||
|
||||
/**
|
||||
* Specifies the vertical anchor or the base object from which the vertical positioning
|
||||
* in the absoluteVerticalPosition attribute should be determined. Possible values are:
|
||||
* margin - relative to the horizontal edge of the text margin before any text runs (top edge for top-to-bottom paragraphs)
|
||||
* page - relative to the horizontal edge of the page before any text runs (top edge for top-to-bottom paragraphs)
|
||||
* text - relative to the horizontal edge of the text margin for the column in which the anchor paragraph is located
|
||||
* If omitted, the value is assumed to be page.
|
||||
*/
|
||||
verticalAnchor?: TableAnchorType;
|
||||
|
||||
/**
|
||||
* Specifies an absolute vertical position for the table, relative to the verticalAnchor anchor.
|
||||
* The value is in twentieths of a point. Note that the value can be negative, in which case the table is
|
||||
* positioned before the anchor object in the direction of vertical text flow.
|
||||
* If relativeVerticalPosition is also specified, then the absoluteVerticalPosition attribute is ignored.
|
||||
* If the attribute is omitted, the value is assumed to be zero.
|
||||
*/
|
||||
absoluteVerticalPosition?: number;
|
||||
|
||||
/**
|
||||
* Specifies a relative vertical position for the table, relative to the verticalAnchor attribute.
|
||||
* This will supersede the absoluteVerticalPosition attribute. Possible values are:
|
||||
* center - the table should be vertically centered with respect to the anchor
|
||||
* inside - the table should be vertically aligned to the edge of the anchor and inside the anchor
|
||||
* bottom - the table should be vertically aligned to the bottom edge of the anchor
|
||||
* outside - the table should be vertically aligned to the edge of the anchor and outside the anchor
|
||||
* inline - the table should be vertically aligned in line with the surrounding text (so as to not allow any text wrapping around it)
|
||||
* top - the table should be vertically aligned to the top edge of the anchor
|
||||
*/
|
||||
relativeVerticalPosition?: RelativeVerticalPosition;
|
||||
|
||||
/**
|
||||
* Specifies the minimun distance to be maintained between the table and the top of text in the paragraph
|
||||
* below the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
|
||||
*/
|
||||
bottomFromText?: number;
|
||||
|
||||
/**
|
||||
* Specifies the minimun distance to be maintained between the table and the bottom edge of text in the paragraph
|
||||
* above the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
|
||||
*/
|
||||
topFromText?: number;
|
||||
|
||||
/**
|
||||
* Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
|
||||
* to the left of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
|
||||
*/
|
||||
leftFromText?: number;
|
||||
|
||||
/**
|
||||
* Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
|
||||
* to the right of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
|
||||
*/
|
||||
rightFromText?: number;
|
||||
}
|
||||
|
||||
export class TableFloatOptionsAttributes extends XmlAttributeComponent<ITableFloatOptions> {
|
||||
protected xmlKeys = {
|
||||
horizontalAnchor: "w:horzAnchor",
|
||||
verticalAnchor: "w:vertAnchor",
|
||||
absoluteHorizontalPosition: "w:tblpX",
|
||||
relativeHorizontalPosition: "w:tblpXSpec",
|
||||
absoluteVerticalPosition: "w:tblpY",
|
||||
relativeVerticalPosition: "w:tblpYSpec",
|
||||
bottomFromText: "w:bottomFromText",
|
||||
topFromText: "w:topFromText",
|
||||
leftFromText: "w:leftFromText",
|
||||
rightFromText: "w:rightFromText",
|
||||
};
|
||||
}
|
||||
|
||||
export class TableFloatProperties extends XmlComponent {
|
||||
constructor(options: ITableFloatOptions) {
|
||||
super("w:tblpPr");
|
||||
this.root.push(new TableFloatOptionsAttributes(options));
|
||||
}
|
||||
}
|
17
src/file/table/table-properties/table-layout.ts
Normal file
17
src/file/table/table-properties/table-layout.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
export enum TableLayoutType {
|
||||
AUTOFIT = "autofit",
|
||||
FIXED = "fixed",
|
||||
}
|
||||
|
||||
class TableLayoutAttributes extends XmlAttributeComponent<{ type: TableLayoutType }> {
|
||||
protected xmlKeys = { type: "w:type" };
|
||||
}
|
||||
|
||||
export class TableLayout extends XmlComponent {
|
||||
constructor(type: TableLayoutType) {
|
||||
super("w:tblLayout");
|
||||
this.root.push(new TableLayoutAttributes({ type }));
|
||||
}
|
||||
}
|
46
src/file/table/table-properties/table-properties.spec.ts
Normal file
46
src/file/table/table-properties/table-properties.spec.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { Formatter } from "../../../export/formatter";
|
||||
import { WidthType } from "../table-cell";
|
||||
import { TableProperties } from "./table-properties";
|
||||
|
||||
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": [] });
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setWidth", () => {
|
||||
it("adds a table width property", () => {
|
||||
const tp = new TableProperties().setWidth(WidthType.DXA, 1234);
|
||||
const tree = new Formatter().format(tp);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:tblPr": [{ "w:tblW": [{ _attr: { "w:type": "dxa", "w:w": 1234 } }] }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setFixedWidthLayout", () => {
|
||||
it("sets the table to fixed width layout", () => {
|
||||
const tp = new TableProperties().setFixedWidthLayout();
|
||||
const tree = new Formatter().format(tp);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:tblPr": [{ "w:tblLayout": [{ _attr: { "w:type": "fixed" } }] }],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#cellMargin", () => {
|
||||
it("adds a table cell top margin", () => {
|
||||
const tp = new 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:sz": "dxa", "w:w": 1234 } }] }] }],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
43
src/file/table/table-properties/table-properties.ts
Normal file
43
src/file/table/table-properties/table-properties.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { XmlComponent } from "file/xml-components";
|
||||
|
||||
import { WidthType } from "../table-cell";
|
||||
import { TableBorders } from "./table-borders";
|
||||
import { TableCellMargin } from "./table-cell-margin";
|
||||
import { ITableFloatOptions, TableFloatProperties } from "./table-float-properties";
|
||||
import { TableLayout, TableLayoutType } from "./table-layout";
|
||||
import { PreferredTableWidth } from "./table-width";
|
||||
|
||||
export class TableProperties extends XmlComponent {
|
||||
private readonly cellMargin: TableCellMargin;
|
||||
|
||||
constructor() {
|
||||
super("w:tblPr");
|
||||
|
||||
this.cellMargin = new TableCellMargin();
|
||||
this.root.push(this.cellMargin);
|
||||
}
|
||||
|
||||
public setWidth(type: WidthType, w: number | string): TableProperties {
|
||||
this.root.push(new PreferredTableWidth(type, w));
|
||||
return this;
|
||||
}
|
||||
|
||||
public setFixedWidthLayout(): TableProperties {
|
||||
this.root.push(new TableLayout(TableLayoutType.FIXED));
|
||||
return this;
|
||||
}
|
||||
|
||||
public setBorder(): TableProperties {
|
||||
this.root.push(new TableBorders());
|
||||
return this;
|
||||
}
|
||||
|
||||
public get CellMargin(): TableCellMargin {
|
||||
return this.cellMargin;
|
||||
}
|
||||
|
||||
public setTableFloatProperties(tableFloatOptions: ITableFloatOptions): TableProperties {
|
||||
this.root.push(new TableFloatProperties(tableFloatOptions));
|
||||
return this;
|
||||
}
|
||||
}
|
19
src/file/table/table-properties/table-width.ts
Normal file
19
src/file/table/table-properties/table-width.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
|
||||
import { WidthType } from "../table-cell";
|
||||
|
||||
interface ITableWidth {
|
||||
type: WidthType;
|
||||
w: number | string;
|
||||
}
|
||||
|
||||
class TableWidthAttributes extends XmlAttributeComponent<ITableWidth> {
|
||||
protected xmlKeys = { type: "w:type", w: "w:w" };
|
||||
}
|
||||
|
||||
export class PreferredTableWidth extends XmlComponent {
|
||||
constructor(type: WidthType, w: number | string) {
|
||||
super("w:tblW");
|
||||
this.root.push(new TableWidthAttributes({ type, w }));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user