Merge branch 'master' into importDotx

# Conflicts:
#	src/import-dotx/import-dotx.ts
This commit is contained in:
Dolan
2018-10-31 22:09:36 +00:00
92 changed files with 857 additions and 404 deletions

View File

@ -1,7 +1,9 @@
// tslint:disable:no-string-literal
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { ContentTypes } from "./content-types";
describe("ContentTypes", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { CoreProperties } from "./properties";
describe("Properties", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { Body } from "./body";
describe("Body", () => {

View File

@ -1,7 +1,8 @@
import { expect } from "chai";
import { Formatter } from "../../../../../export/formatter";
import { BorderStyle } from "../../../../styles";
import { Formatter } from "export/formatter";
import { BorderStyle } from "file/styles";
import { PageBorderDisplay, PageBorders, PageBorderZOrder } from "./page-borders";
describe("PageBorders", () => {

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 { BorderStyle } from "../../../../styles";
export enum PageBorderDisplay {
ALL_PAGES = "allPages",

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../../../export/formatter";
import { Formatter } from "export/formatter";
import { PageSize } from "./page-size";
import { PageOrientation } from "./page-size-attributes";

View File

@ -1,14 +1,19 @@
import { expect } from "chai";
import { Formatter } from "../../../../export/formatter";
import { FooterWrapper } from "../../../footer-wrapper";
import { HeaderWrapper } from "../../../header-wrapper";
import { PageBorderOffsetFrom, PageNumberFormat } from "./";
import { Formatter } from "export/formatter";
import { FooterWrapper } from "file/footer-wrapper";
import { HeaderWrapper } from "file/header-wrapper";
import { Media } from "file/media";
import { PageBorderOffsetFrom } from "./page-border";
import { PageNumberFormat } from "./page-number";
import { SectionProperties } from "./section-properties";
describe("SectionProperties", () => {
describe("#constructor()", () => {
it("should create section properties with options", () => {
const media = new Media();
const properties = new SectionProperties({
width: 11906,
height: 16838,
@ -23,10 +28,10 @@ describe("SectionProperties", () => {
space: 708,
linePitch: 360,
headers: {
default: new HeaderWrapper(100),
default: new HeaderWrapper(media, 100),
},
footers: {
even: new FooterWrapper(200),
even: new FooterWrapper(media, 200),
},
pageNumberStart: 10,
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,

View File

@ -1,8 +1,8 @@
// http://officeopenxml.com/WPsection.php
import { FooterWrapper } from "file/footer-wrapper";
import { HeaderWrapper } from "file/header-wrapper";
import { XmlComponent } from "file/xml-components";
import { FooterWrapper } from "../../../footer-wrapper";
import { HeaderWrapper } from "../../../header-wrapper";
import { IPageBordersOptions, IPageNumberTypeAttributes, PageBorders, PageNumberFormat, PageNumberType } from "./";
import { Columns } from "./columns/columns";
import { IColumnsAttributes } from "./columns/columns-attributes";
import { DocumentGrid } from "./doc-grid/doc-grid";
@ -11,8 +11,10 @@ import { FooterReferenceType } from "./footer-reference";
import { FooterReference } from "./footer-reference/footer-reference";
import { HeaderReferenceType } from "./header-reference";
import { HeaderReference } from "./header-reference/header-reference";
import { IPageBordersOptions, PageBorders } from "./page-border";
import { PageMargin } from "./page-margin/page-margin";
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
import { IPageNumberTypeAttributes, PageNumberFormat, PageNumberType } from "./page-number";
import { PageSize } from "./page-size/page-size";
import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes";
import { TitlePage } from "./title-page/title-page";

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../../../export/formatter";
import { Formatter } from "export/formatter";
import { TitlePage } from "./title-page";
describe("PageSize", () => {

View File

@ -1,6 +1,7 @@
import { assert, expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { Paragraph } from "../paragraph";
import { Table } from "../table";
import { Document } from "./document";

View File

@ -1,8 +1,10 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { IDrawingOptions, TextWrapStyle } from ".././";
import { Anchor } from "./";
import { Utility } from "tests/utility";
import { IDrawingOptions } from "../drawing";
import { TextWrapStyle } from "../text-wrap";
import { Anchor } from "./anchor";
function createDrawing(drawingOptions: IDrawingOptions): Anchor {
return new Anchor(

View File

@ -1,7 +1,8 @@
import { assert } from "chai";
import { Utility } from "../../tests/utility";
import { Drawing, IDrawingOptions, PlacementPosition } from "./";
import { Utility } from "tests/utility";
import { Drawing, IDrawingOptions, PlacementPosition } from "./drawing";
const imageBase64Data = `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`;

View File

@ -1,4 +1,5 @@
import { XmlComponent } from "file/xml-components";
import { ExtentAttributes } from "./extent-attributes";
export class Extent extends XmlComponent {

View File

@ -1,8 +1,9 @@
import { assert } from "chai";
import { VerticalPositionAlign } from ".";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { Align } from "./align";
import { VerticalPositionAlign } from "./floating-position";
describe("Align", () => {
describe("#constructor()", () => {

View File

@ -1,7 +1,8 @@
import { assert } from "chai";
import { HorizontalPositionAlign, HorizontalPositionRelativeFrom } from ".";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { HorizontalPositionAlign, HorizontalPositionRelativeFrom } from "./floating-position";
import { HorizontalPosition } from "./horizontal-position";
describe("HorizontalPosition", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { PositionOffset } from "./position-offset";
describe("PositionOffset", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { SimplePos } from "./simple-pos";
describe("SimplePos", () => {

View File

@ -1,7 +1,8 @@
import { assert } from "chai";
import { VerticalPositionAlign, VerticalPositionRelativeFrom } from ".";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { VerticalPositionAlign, VerticalPositionRelativeFrom } from "./floating-position";
import { VerticalPosition } from "./vertical-position";
describe("VerticalPosition", () => {

View File

@ -173,13 +173,13 @@ export class File {
}
public createHeader(): HeaderWrapper {
const header = new HeaderWrapper(this.currentRelationshipId++);
const header = new HeaderWrapper(this.media, this.currentRelationshipId++);
this.addHeaderToDocument(header);
return header;
}
public createFooter(): FooterWrapper {
const footer = new FooterWrapper(this.currentRelationshipId++);
const footer = new FooterWrapper(this.media, this.currentRelationshipId++);
this.addFooterToDocument(footer);
return footer;
}

View File

@ -1,8 +1,8 @@
import { IMediaData } from "file/media";
import { XmlComponent } from "file/xml-components";
import { FooterReferenceType } from "./document";
import { Footer } from "./footer/footer";
import { Image, Media } from "./media";
import { Image, IMediaData, Media } from "./media";
import { ImageParagraph, Paragraph } from "./paragraph";
import { Relationships } from "./relationships";
import { Table } from "./table";
@ -15,10 +15,8 @@ export interface IDocumentFooter {
export class FooterWrapper {
private readonly footer: Footer;
private readonly relationships: Relationships;
private readonly media: Media;
constructor(referenceId: number, initContent?: XmlComponent) {
this.media = new Media();
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
this.footer = new Footer(referenceId, initContent);
this.relationships = new Relationships();
}
@ -48,7 +46,7 @@ export class FooterWrapper {
public addImageRelationship(image: Buffer, refId: number, width?: number, height?: number): IMediaData {
const mediaData = this.media.addMedia(image, refId, width, height);
this.relationships.createRelationship(
refId,
mediaData.referenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
`media/${mediaData.fileName}`,
);
@ -64,8 +62,10 @@ export class FooterWrapper {
);
}
public createImage(image: Buffer, width?: number, height?: number): void {
const mediaData = this.addImageRelationship(image, this.relationships.RelationshipCount, width, height);
public createImage(image: Buffer | string | Uint8Array | ArrayBuffer, width?: number, height?: number): void {
// TODO
// tslint:disable-next-line:no-any
const mediaData = this.addImageRelationship(image as any, this.relationships.RelationshipCount, width, height);
this.addImage(new Image(new ImageParagraph(mediaData)));
}

View File

@ -1,5 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { Footnote, FootnoteType } from "./footnote";
describe("Footnote", () => {

View File

@ -1,5 +1,6 @@
import { Paragraph } from "file/paragraph";
import { XmlComponent } from "file/xml-components";
import { Paragraph } from "../../paragraph";
import { FootnoteAttributes } from "./footnote-attributes";
import { FootnoteRefRun } from "./run/footnote-ref-run";

View File

@ -1,8 +1,8 @@
import { IMediaData } from "file/media";
import { XmlComponent } from "file/xml-components";
import { HeaderReferenceType } from "./document";
import { Header } from "./header/header";
import { Image, Media } from "./media";
import { Image, IMediaData, Media } from "./media";
import { ImageParagraph, Paragraph } from "./paragraph";
import { Relationships } from "./relationships";
import { Table } from "./table";
@ -15,10 +15,8 @@ export interface IDocumentHeader {
export class HeaderWrapper {
private readonly header: Header;
private readonly relationships: Relationships;
private readonly media: Media;
constructor(referenceId: number, initContent?: XmlComponent) {
this.media = new Media();
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
this.header = new Header(referenceId, initContent);
this.relationships = new Relationships();
}
@ -48,7 +46,7 @@ export class HeaderWrapper {
public addImageRelationship(image: Buffer, refId: number, width?: number, height?: number): IMediaData {
const mediaData = this.media.addMedia(image, refId, width, height);
this.relationships.createRelationship(
refId,
mediaData.referenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
`media/${mediaData.fileName}`,
);
@ -64,8 +62,10 @@ export class HeaderWrapper {
);
}
public createImage(image: Buffer, width?: number, height?: number): void {
const mediaData = this.addImageRelationship(image, this.relationships.RelationshipCount, width, height);
public createImage(image: Buffer | string | Uint8Array | ArrayBuffer, width?: number, height?: number): void {
// TODO
// tslint:disable-next-line:no-any
const mediaData = this.addImageRelationship(image as any, this.relationships.RelationshipCount, width, height);
this.addImage(new Image(new ImageParagraph(mediaData)));
}

View File

@ -87,7 +87,7 @@ export class Media {
}
const imageData = {
referenceId: this.map.size + relationshipsCount + 1,
referenceId: relationshipsCount,
stream: data,
path: filePath,
fileName: key,

View File

@ -1,9 +1,11 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Numbering } from "./";
import { Formatter } from "export/formatter";
import { AbstractNumbering } from "./abstract-numbering";
import { LevelForOverride } from "./level";
import { Num } from "./num";
import { Numbering } from "./numbering";
describe("Numbering", () => {
let numbering: Numbering;

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { ThematicBreak } from "./border";
describe("Border", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { PageBreak, PageBreakBefore } from "./page-break";
describe("PageBreak", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { Spacing } from "./spacing";
describe("Spacing", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { Style } from "./style";
describe("ParagraphStyle", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { LeftTabStop, MaxRightTabStop, RightTabStop } from "./tab-stop";
describe("LeftTabStop", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { NumberProperties } from "./unordered-list";
describe("NumberProperties", () => {

View File

@ -1,7 +1,8 @@
// tslint:disable:object-literal-key-quotes
import { assert, expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { ImageParagraph } from "./image";
describe("Image", () => {

View File

@ -1,7 +1,8 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Bookmark } from "./";
import { Utility } from "tests/utility";
import { Bookmark } from "./bookmark";
describe("Bookmark", () => {
let bookmark: Bookmark;

View File

@ -1,7 +1,8 @@
import { assert, expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Utility } from "../../../tests/utility";
import { Formatter } from "export/formatter";
import { Utility } from "tests/utility";
import { Hyperlink } from "./";
describe("Hyperlink", () => {

View File

@ -1,7 +1,8 @@
import { assert, expect } from "chai";
import { Formatter } from "../../export/formatter";
import * as file from "../../file";
import { Formatter } from "export/formatter";
import * as file from "file";
import { Numbering } from "../numbering";
describe("Paragraph", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { Break } from "./break";
describe("Break", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../../export/formatter";
import { Formatter } from "export/formatter";
import { Text } from "./text";
describe("Text", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { RunFonts } from "./run-fonts";
describe("RunFonts", () => {

View File

@ -1,7 +1,8 @@
import { assert, expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Utility } from "../../../tests/utility";
import { Formatter } from "export/formatter";
import { Utility } from "tests/utility";
import { Run } from "./";
describe("Run", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { SubScript, SuperScript } from "./script";
describe("SubScript", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { SequentialIdentifier } from "./sequential-identifier";
describe("Sequential Identifier", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { DoubleStrike, Strike } from "./formatting";
describe("Strike", () => {

View File

@ -1,6 +1,7 @@
import { assert } from "chai";
import { Utility } from "../../../tests/utility";
import { Utility } from "tests/utility";
import { Tab } from "./tab";
describe("Tab", () => {

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Formatter } from "export/formatter";
import { TextRun } from "./text-run";
describe("TextRun", () => {

View File

@ -1,7 +1,8 @@
import { assert, expect } from "chai";
import { Formatter } from "../../../export/formatter";
import { Utility } from "../../../tests/utility";
import { Formatter } from "export/formatter";
import { Utility } from "tests/utility";
import * as u from "./underline";
describe("Underline", () => {

View File

@ -1,7 +1,8 @@
// tslint:disable:no-string-literal
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { Relationships } from "./relationships";
describe("Relationships", () => {

View File

@ -1,6 +1,9 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Settings } from "./";
import { Formatter } from "export/formatter";
import { Settings } from "./settings";
describe("Settings", () => {
describe("#constructor", () => {
it("should create a empty Settings with correct rootKey", () => {

View File

@ -1,6 +1,9 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { UpdateFields } from "./";
import { Formatter } from "export/formatter";
import { UpdateFields } from "./update-fields";
const UF_TRUE = {
"w:updateFields": [
{

View File

@ -1,5 +1,5 @@
import { ParagraphProperties } from "file/paragraph/properties";
import { XmlComponent } from "file/xml-components";
import { ParagraphProperties } from "../../paragraph/properties";
export class ParagraphPropertiesDefaults extends XmlComponent {
constructor() {

View File

@ -1,7 +1,7 @@
import { Size, SizeComplexScript } from "file/paragraph/run/formatting";
import { RunProperties } from "file/paragraph/run/properties";
import { RunFonts } from "file/paragraph/run/run-fonts";
import { XmlComponent } from "file/xml-components";
import { Size, SizeComplexScript } from "../../paragraph/run/formatting";
import { RunProperties } from "../../paragraph/run/properties";
import { RunFonts } from "../../paragraph/run/run-fonts";
export class RunPropertiesDefaults extends XmlComponent {
private readonly properties: RunProperties;

View File

@ -1,30 +1 @@
import { BaseXmlComponent, XmlComponent } from "file/xml-components";
import { DocumentDefaults } from "./defaults";
import { ParagraphStyle } from "./style";
export * from "./border";
export class Styles extends XmlComponent {
constructor(initialStyles?: BaseXmlComponent) {
super("w:styles");
if (initialStyles) {
this.root.push(initialStyles);
}
}
public push(style: XmlComponent): Styles {
this.root.push(style);
return this;
}
public createDocumentDefaults(): DocumentDefaults {
const defaults = new DocumentDefaults();
this.push(defaults);
return defaults;
}
public createParagraphStyle(styleId: string, name?: string): ParagraphStyle {
const para = new ParagraphStyle(styleId, name);
this.push(para);
return para;
}
}
export * from "./styles";

View File

@ -1,7 +1,7 @@
import * as paragraph from "file/paragraph";
import * as formatting from "file/paragraph/run/formatting";
import { RunProperties } from "file/paragraph/run/properties";
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import * as paragraph from "../../paragraph";
import * as formatting from "../../paragraph/run/formatting";
import { RunProperties } from "../../paragraph/run/properties";
import { BasedOn, Link, Name, Next, QuickFormat, SemiHidden, UiPriority, UnhideWhenUsed } from "./components";

View File

@ -1,8 +1,10 @@
import { assert, expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Styles } from "./";
import { Formatter } from "export/formatter";
import { ParagraphStyle, Style } from "./style";
import * as components from "./style/components";
import { Styles } from "./styles";
describe("Styles", () => {
let styles: Styles;

30
src/file/styles/styles.ts Normal file
View File

@ -0,0 +1,30 @@
import { BaseXmlComponent, XmlComponent } from "file/xml-components";
import { DocumentDefaults } from "./defaults";
import { ParagraphStyle } from "./style";
export * from "./border";
export class Styles extends XmlComponent {
constructor(initialStyles?: BaseXmlComponent) {
super("w:styles");
if (initialStyles) {
this.root.push(initialStyles);
}
}
public push(style: XmlComponent): Styles {
this.root.push(style);
return this;
}
public createDocumentDefaults(): DocumentDefaults {
const defaults = new DocumentDefaults();
this.push(defaults);
return defaults;
}
public createParagraphStyle(styleId: string, name?: string): ParagraphStyle {
const para = new ParagraphStyle(styleId, name);
this.push(para);
return para;
}
}

View File

@ -56,7 +56,7 @@ export class FieldInstruction extends XmlComponent {
instruction = `${instruction} \\s "${this.properties.seqFieldIdentifierForPrefix}"`;
}
if (this.properties.stylesWithLevels && this.properties.stylesWithLevels.length) {
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName},${sl.level}`).join(",");
const styles = this.properties.stylesWithLevels.map((sl) => `${sl.styleName};${sl.level}`).join(";");
instruction = `${instruction} \\t "${styles}"`;
}
if (this.properties.useAppliedParagraphOutlineLevel) {

View File

@ -1,7 +1,9 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { ITableOfContentsOptions, StyleLevel, TableOfContents } from "./";
import { Formatter } from "export/formatter";
import { TableOfContents } from "./table-of-contents";
import { ITableOfContentsOptions, StyleLevel } from "./table-of-contents-properties";
describe("Table of Contents", () => {
describe("#constructor", () => {
@ -174,7 +176,7 @@ const COMPLETE_TOC = {
"xml:space": "preserve",
},
},
'TOC \\a "A" \\b "B" \\c "C" \\d "D" \\f "F" \\h \\l "L" \\n "N" \\o "O" \\p "P" \\s "S" \\t "SL,1,SL,2" \\u \\w \\x \\z',
'TOC \\a "A" \\b "B" \\c "C" \\d "D" \\f "F" \\h \\l "L" \\n "N" \\o "O" \\p "P" \\s "S" \\t "SL;1;SL;2" \\u \\w \\x \\z',
],
},
{

View File

@ -1,6 +1,7 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { GridCol, TableGrid } from "./grid";
describe("GridCol", () => {

View File

@ -1,2 +1,3 @@
export * from "./table";
export * from "./table-cell";
export * from "./table-properties";

View File

@ -1,97 +0,0 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { WidthType } from "./table-cell";
import { TableCellMargin } from "./table-cell-margin";
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("fixed"));
return this;
}
public setBorder(): TableProperties {
this.root.push(new TableBorders());
return this;
}
public get CellMargin(): TableCellMargin {
return this.cellMargin;
}
}
interface ITableWidth {
type: WidthType;
w: number | string;
}
class TableWidthAttributes extends XmlAttributeComponent<ITableWidth> {
protected xmlKeys = { type: "w:type", w: "w:w" };
}
class PreferredTableWidth extends XmlComponent {
constructor(type: WidthType, w: number | string) {
super("w:tblW");
this.root.push(new TableWidthAttributes({ type, w }));
}
}
type TableLayoutOptions = "autofit" | "fixed";
class TableLayoutAttributes extends XmlAttributeComponent<{ type: TableLayoutOptions }> {
protected xmlKeys = { type: "w:type" };
}
class TableLayout extends XmlComponent {
constructor(type: TableLayoutOptions) {
super("w:tblLayout");
this.root.push(new TableLayoutAttributes({ type }));
}
}
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",
};
}

View File

@ -0,0 +1,2 @@
export * from "./table-cell";
export * from "./table-cell-components";

View File

@ -1,5 +1,5 @@
import { BorderStyle } from "file/styles";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { BorderStyle } from "../styles";
interface ICellBorder {
style: BorderStyle;

View File

@ -0,0 +1,57 @@
import { XmlComponent } from "file/xml-components";
import {
GridSpan,
TableCellBorders,
TableCellShading,
TableCellWidth,
VAlign,
VerticalAlign,
VMerge,
VMergeType,
WidthType,
} from "./table-cell-components";
export class TableCellProperties extends XmlComponent {
private readonly cellBorder: TableCellBorders;
constructor() {
super("w:tcPr");
this.cellBorder = new TableCellBorders();
this.root.push(this.cellBorder);
}
public get Borders(): TableCellBorders {
return this.cellBorder;
}
public addGridSpan(cellSpan: number): TableCellProperties {
this.root.push(new GridSpan(cellSpan));
return this;
}
public addVerticalMerge(type: VMergeType): TableCellProperties {
this.root.push(new VMerge(type));
return this;
}
public setVerticalAlign(type: VerticalAlign): TableCellProperties {
this.root.push(new VAlign(type));
return this;
}
public setWidth(width: string | number, type: WidthType): TableCellProperties {
this.root.push(new TableCellWidth(width, type));
return this;
}
public setShading(attrs: object): TableCellProperties {
this.root.push(new TableCellShading(attrs));
return this;
}
}

View File

@ -1,8 +1,9 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { BorderStyle } from "../styles";
import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell";
import { Formatter } from "export/formatter";
import { BorderStyle } from "file/styles";
import { TableCellBorders, TableCellWidth, WidthType } from "./table-cell-components";
describe("TableCellBorders", () => {
describe("#prepForXml", () => {

View File

@ -0,0 +1,45 @@
// http://officeopenxml.com/WPtableGrid.php
import { Paragraph } from "file/paragraph";
import { IXmlableObject, XmlComponent } from "file/xml-components";
import { Table } from "../table";
import { TableCellProperties } from "./table-cell-properties";
export class TableCell extends XmlComponent {
private readonly properties: TableCellProperties;
constructor() {
super("w:tc");
this.properties = new TableCellProperties();
this.root.push(this.properties);
}
public addContent(content: Paragraph | Table): TableCell {
this.root.push(content);
return this;
}
public prepForXml(): IXmlableObject | undefined {
// Cells must end with a paragraph
const retval = super.prepForXml();
if (!retval) {
return undefined;
}
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addContent(para);
return para;
}
public get CellProperties(): TableCellProperties {
return this.properties;
}
}

View File

@ -0,0 +1,2 @@
export * from "./table-properties";
export * from "./table-float-properties";

View 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",
};
}

View File

@ -1,5 +1,6 @@
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { WidthType } from "./table-cell";
import { WidthType } from "../table-cell";
class TableCellMarginAttributes extends XmlAttributeComponent<{ type: WidthType; value: number }> {
protected xmlKeys = { value: "w:w", type: "w:sz" };

View File

@ -0,0 +1,45 @@
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,
},
},
],
};

View 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));
}
}

View 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 }));
}
}

View File

@ -1,8 +1,9 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { TableProperties } from "./properties";
import { WidthType } from "./table-cell";
import { Formatter } from "export/formatter";
import { WidthType } from "../table-cell";
import { TableProperties } from "./table-properties";
describe("TableProperties", () => {
describe("#constructor", () => {

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

View 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 }));
}
}

View File

@ -0,0 +1,2 @@
export * from "./table-row";
export * from "./table-row-properties";

View File

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

View File

@ -0,0 +1,40 @@
import { XmlComponent } from "file/xml-components";
import { TableCell } from "../table-cell";
import { TableRowProperties } from "./table-row-properties";
export class TableRow extends XmlComponent {
private readonly properties: TableRowProperties;
constructor(private readonly cells: TableCell[]) {
super("w:tr");
this.properties = new TableRowProperties();
this.root.push(this.properties);
cells.forEach((c) => this.root.push(c));
}
public getCell(ix: number): TableCell {
const cell = this.cells[ix];
if (!cell) {
throw Error("Index out of bounds when trying to get cell on row");
}
return cell;
}
public addGridSpan(index: number, cellSpan: number): TableCell {
const remainCell = this.cells[index];
remainCell.CellProperties.addGridSpan(cellSpan);
this.cells.splice(index + 1, cellSpan - 1);
this.root.splice(index + 2, cellSpan - 1);
return remainCell;
}
public mergeCells(startIndex: number, endIndex: number): TableCell {
const cellSpan = endIndex - startIndex + 1;
return this.addGridSpan(startIndex, cellSpan);
}
}

View File

@ -1,10 +1,12 @@
/* tslint:disable:no-unused-expression */
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Formatter } from "export/formatter";
import { Paragraph } from "../paragraph";
import { Table } from "./";
import { Table } from "./table";
import { WidthType } from "./table-cell";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-properties";
const DEFAULT_TABLE_PROPERTIES = {
"w:tblBorders": [
@ -294,4 +296,49 @@ describe("Table", () => {
});
});
});
describe("#float", () => {
it("sets the table float properties", () => {
const table = new Table(1, 1).float({
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(table);
expect(tree)
.to.have.property("w:tbl")
.which.is.an("array")
.with.has.length.at.least(1);
expect(tree["w:tbl"][0]).to.deep.equal({
"w:tblPr": [
DEFAULT_TABLE_PROPERTIES,
{
"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

@ -1,19 +1,10 @@
// http://officeopenxml.com/WPtableGrid.php
import {
GridSpan,
TableCellBorders,
TableCellShading,
TableCellWidth,
VAlign,
VerticalAlign,
VMerge,
VMergeType,
WidthType,
} from "file/table/table-cell";
import { IXmlableObject, XmlComponent } from "file/xml-components";
import { Paragraph } from "../paragraph";
import { XmlComponent } from "file/xml-components";
import { TableGrid } from "./grid";
import { TableProperties } from "./properties";
import { TableCell, WidthType } from "./table-cell";
import { ITableFloatOptions, TableProperties } from "./table-properties";
import { TableRow } from "./table-row";
export class Table extends XmlComponent {
private readonly properties: TableProperties;
@ -84,132 +75,12 @@ export class Table extends XmlComponent {
return this;
}
public float(tableFloatOptions: ITableFloatOptions): Table {
this.properties.setTableFloatProperties(tableFloatOptions);
return this;
}
public get Properties(): TableProperties {
return this.properties;
}
}
export class TableRow extends XmlComponent {
private readonly properties: TableRowProperties;
constructor(private readonly cells: TableCell[]) {
super("w:tr");
this.properties = new TableRowProperties();
this.root.push(this.properties);
cells.forEach((c) => this.root.push(c));
}
public getCell(ix: number): TableCell {
const cell = this.cells[ix];
if (!cell) {
throw Error("Index out of bounds when trying to get cell on row");
}
return cell;
}
public addGridSpan(index: number, cellSpan: number): TableCell {
const remainCell = this.cells[index];
remainCell.CellProperties.addGridSpan(cellSpan);
this.cells.splice(index + 1, cellSpan - 1);
this.root.splice(index + 2, cellSpan - 1);
return remainCell;
}
public mergeCells(startIndex: number, endIndex: number): TableCell {
const cellSpan = endIndex - startIndex + 1;
return this.addGridSpan(startIndex, cellSpan);
}
}
export class TableRowProperties extends XmlComponent {
constructor() {
super("w:trPr");
}
}
export class TableCell extends XmlComponent {
private readonly properties: TableCellProperties;
constructor() {
super("w:tc");
this.properties = new TableCellProperties();
this.root.push(this.properties);
}
public addContent(content: Paragraph | Table): TableCell {
this.root.push(content);
return this;
}
public prepForXml(): IXmlableObject | undefined {
// Cells must end with a paragraph
const retval = super.prepForXml();
if (!retval) {
return undefined;
}
const content = retval["w:tc"];
if (!content[content.length - 1]["w:p"]) {
content.push(new Paragraph().prepForXml());
}
return retval;
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addContent(para);
return para;
}
public get CellProperties(): TableCellProperties {
return this.properties;
}
}
export class TableCellProperties extends XmlComponent {
private readonly cellBorder: TableCellBorders;
constructor() {
super("w:tcPr");
this.cellBorder = new TableCellBorders();
this.root.push(this.cellBorder);
}
public get Borders(): TableCellBorders {
return this.cellBorder;
}
public addGridSpan(cellSpan: number): TableCellProperties {
this.root.push(new GridSpan(cellSpan));
return this;
}
public addVerticalMerge(type: VMergeType): TableCellProperties {
this.root.push(new VMerge(type));
return this;
}
public setVerticalAlign(type: VerticalAlign): TableCellProperties {
this.root.push(new VAlign(type));
return this;
}
public setWidth(width: string | number, type: WidthType): TableCellProperties {
this.root.push(new TableCellWidth(width, type));
return this;
}
public setShading(attrs: object): TableCellProperties {
this.root.push(new TableCellShading(attrs));
return this;
}
}

View File

@ -1,6 +1,6 @@
import { assert } from "chai";
import { Utility } from "../../tests/utility";
import { Utility } from "tests/utility";
import { XmlComponent } from "./";
class TestComponent extends XmlComponent {}