#1507 - Add scale for run

This commit is contained in:
Dolan
2022-11-03 00:30:16 +00:00
parent b9ceabcc07
commit 1b06fc71cf
15 changed files with 110 additions and 75 deletions

6
.nycrc
View File

@ -1,8 +1,8 @@
{
"check-coverage": true,
"statements": 99.73,
"branches": 98.32,
"functions": 99.83,
"statements": 99.79,
"branches": 98.41,
"functions": 100,
"lines": 99.73,
"include": [
"src/**/*.ts"

View File

@ -236,6 +236,18 @@ const doc = new Document({
new TextRun({
text: " Another Hello World",
}),
new TextRun({
scale: 50,
text: " Scaled text",
}),
],
}),
new Paragraph({
scale: 200,
children: [
new TextRun({
text: "Scaled paragraph",
}),
],
}),
],

View File

View File

@ -52,6 +52,7 @@ export interface IParagraphPropertiesOptions extends IParagraphStylePropertiesOp
readonly frame?: IFrameOptions;
readonly suppressLineNumbers?: boolean;
readonly wordWrap?: boolean;
readonly scale?: number;
}
export class ParagraphProperties extends IgnoreIfEmptyXmlComponent {

View File

@ -1,7 +1,14 @@
import { BorderElement, IBorderOptions } from "@file/border";
import { IShadingAttributesProperties, Shading } from "@file/shading";
import { ChangeAttributes, IChangedAttributesProperties } from "@file/track-revision/track-revision";
import { HpsMeasureElement, IgnoreIfEmptyXmlComponent, OnOffElement, StringValueElement, XmlComponent } from "@file/xml-components";
import {
HpsMeasureElement,
IgnoreIfEmptyXmlComponent,
NumberValueElement,
OnOffElement,
StringValueElement,
XmlComponent,
} from "@file/xml-components";
import { EmphasisMark, EmphasisMarkType } from "./emphasis-mark";
import { CharacterSpacing, Color, Highlight, HighlightComplexScript } from "./formatting";
@ -47,6 +54,7 @@ export interface IRunStylePropertiesOptions {
readonly border?: IBorderOptions;
readonly vanish?: boolean;
readonly specVanish?: boolean;
readonly scale?: number;
}
export interface IRunPropertiesOptions extends IRunStylePropertiesOptions {
@ -228,6 +236,10 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent {
// https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_specVanish_topic_ID0EIE1O.html
this.push(new OnOffElement("w:specVanish", options.vanish));
}
if (options.scale !== undefined) {
this.push(new NumberValueElement("w:w", options.scale));
}
}
public push(item: XmlComponent): void {

View File

@ -556,5 +556,29 @@ describe("Run", () => {
],
});
});
describe("#scale", () => {
it("should correctly set the border", () => {
const run = new Run({
scale: 200,
});
const tree = new Formatter().format(run);
expect(tree).to.deep.equal({
"w:r": [
{
"w:rPr": [
{
"w:w": {
_attr: {
"w:val": 200,
},
},
},
],
},
],
});
});
});
});
});

View File

@ -1,12 +0,0 @@
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
class AliasAttributes extends XmlAttributeComponent<{ readonly alias: string }> {
protected readonly xmlKeys = { alias: "w:val" };
}
export class Alias extends XmlComponent {
public constructor(alias: string) {
super("w:alias");
this.root.push(new AliasAttributes({ alias }));
}
}

View File

@ -1,10 +1,9 @@
// http://www.datypic.com/sc/ooxml/e-w_sdtPr-1.html
import { XmlComponent } from "@file/xml-components";
import { Alias } from "./alias";
import { StringValueElement, XmlComponent } from "@file/xml-components";
export class StructuredDocumentTagProperties extends XmlComponent {
public constructor(alias: string) {
super("w:sdtPr");
this.root.push(new Alias(alias));
this.root.push(new StringValueElement("w:alias", alias));
}
}

View File

@ -2,4 +2,3 @@ export * from "./table-properties";
export * from "./table-float-properties";
export * from "./table-layout";
export * from "./table-borders";
export * from "./table-overlap";

View File

@ -2,8 +2,13 @@ import { expect } from "chai";
import { Formatter } from "@export/formatter";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType, TableFloatProperties } from "./table-float-properties";
import { OverlapType } from "./table-overlap";
import {
OverlapType,
RelativeHorizontalPosition,
RelativeVerticalPosition,
TableAnchorType,
TableFloatProperties,
} from "./table-float-properties";
describe("Table Float Properties", () => {
describe("#constructor", () => {

View File

@ -1,8 +1,6 @@
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { StringEnumValueElement, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { signedTwipsMeasureValue, twipsMeasureValue } from "@util/values";
import { OverlapType, TableOverlap } from "./table-overlap";
export enum TableAnchorType {
MARGIN = "margin",
PAGE = "page",
@ -26,6 +24,17 @@ export enum RelativeVerticalPosition {
TOP = "top",
}
// <xsd:simpleType name="ST_TblOverlap">
// <xsd:restriction base="xsd:string">
// <xsd:enumeration value="never"/>
// <xsd:enumeration value="overlap"/>
// </xsd:restriction>
// </xsd:simpleType>
export enum OverlapType {
NEVER = "never",
OVERLAP = "overlap",
}
export interface ITableFloatOptions {
/* cSpell:disable */
/**
@ -171,7 +180,10 @@ export class TableFloatProperties extends XmlComponent {
);
if (options.overlap) {
this.root.push(new TableOverlap(options.overlap));
// <xsd:complexType name="CT_TblOverlap">
// <xsd:attribute name="val" type="ST_TblOverlap" use="required"/>
// </xsd:complexType>
this.root.push(new StringEnumValueElement<OverlapType>("w:tblOverlap", options.overlap));
}
}
}

View File

@ -1,22 +0,0 @@
import { expect } from "chai";
import { Formatter } from "@export/formatter";
import { OverlapType, TableOverlap } from "./table-overlap";
describe("TableOverlap", () => {
describe("#constructor", () => {
it("sets the width attribute to the value given", () => {
const tableOverlap = new TableOverlap(OverlapType.OVERLAP);
const tree = new Formatter().format(tableOverlap);
expect(tree).to.deep.equal({
"w:tblOverlap": {
_attr: {
"w:val": "overlap",
},
},
});
});
});
});

View File

@ -1,26 +0,0 @@
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
// <xsd:simpleType name="ST_TblOverlap">
// <xsd:restriction base="xsd:string">
// <xsd:enumeration value="never"/>
// <xsd:enumeration value="overlap"/>
// </xsd:restriction>
// </xsd:simpleType>
export enum OverlapType {
NEVER = "never",
OVERLAP = "overlap",
}
// <xsd:complexType name="CT_TblOverlap">
// <xsd:attribute name="val" type="ST_TblOverlap" use="required"/>
// </xsd:complexType>
class TableOverlapAttributes extends XmlAttributeComponent<{ readonly val: OverlapType }> {
protected readonly xmlKeys = { val: "w:val" };
}
export class TableOverlap extends XmlComponent {
public constructor(type: OverlapType) {
super("w:tblOverlap");
this.root.push(new TableOverlapAttributes({ val: type }));
}
}

View File

@ -3,7 +3,7 @@ import { Element, xml2js } from "xml-js";
import { EMPTY_OBJECT } from "@file/xml-components";
import { convertToXmlComponent, ImportedXmlComponent } from "./imported-xml-component";
import { convertToXmlComponent, ImportedRootElementAttributes, ImportedXmlComponent } from "./imported-xml-component";
import { IContext } from "./base";
const xmlString = `
@ -90,5 +90,29 @@ describe("ImportedXmlComponent", () => {
const converted = convertToXmlComponent(xmlObj);
expect(converted).to.deep.equal(convertedXmlElement);
});
it("should return undefined if xml type is invalid", () => {
const xmlObj = { type: "invalid" } as Element;
const converted = convertToXmlComponent(xmlObj);
expect(converted).to.equal(undefined);
});
});
});
describe("ImportedRootElementAttributes", () => {
let attributes: ImportedRootElementAttributes;
beforeEach(() => {
attributes = new ImportedRootElementAttributes({});
});
describe("#prepForXml()", () => {
it("should work", () => {
// tslint:disable-next-line: no-object-literal-type-assertion
const converted = attributes.prepForXml({} as IContext);
expect(converted).to.deep.equal({
_attr: {},
});
});
});
});

View File

@ -53,6 +53,13 @@ export class NumberValueElement extends XmlComponent {
}
}
export class StringEnumValueElement<T extends string> extends XmlComponent {
public constructor(name: string, val: T) {
super(name);
this.root.push(new Attributes({ val }));
}
}
// Simple nodes containing text.
//
// new StringContainer("hello", "world")