Simplify run format properties, removing duplicate classes. Add values functions, which check and clean up values for specific defined types from the schema

This commit is contained in:
Tom Hunkapiller
2021-05-24 08:20:08 +03:00
parent 449e1ed963
commit ee105cdb83
13 changed files with 274 additions and 265 deletions

View File

@ -2,18 +2,35 @@ import { expect } from "chai";
import { Formatter } from "export/formatter";
import { Bold } from "./formatting";
import { CharacterSpacing, Color } from "./formatting";
describe("Bold", () => {
describe("CharacterSpacing", () => {
describe("#constructor()", () => {
it("should create", () => {
const currentBold = new Bold();
const element = new CharacterSpacing(32);
const tree = new Formatter().format(currentBold);
const tree = new Formatter().format(element);
expect(tree).to.deep.equal({
"w:b": {
"w:spacing": {
_attr: {
"w:val": true,
"w:val": 32,
},
},
});
});
});
});
describe("Color", () => {
describe("#constructor()", () => {
it("should create", () => {
const element = new Color("#FFFFFF");
const tree = new Formatter().format(element);
expect(tree).to.deep.equal({
"w:color": {
_attr: {
"w:val": "FFFFFF",
},
},
});

View File

@ -1,170 +1,55 @@
import { hexColorValue, signedTwipsMeasureValue } from "file/values";
import { Attributes, XmlComponent } from "file/xml-components";
export class Bold extends XmlComponent {
constructor() {
super("w:b");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class BoldComplexScript extends XmlComponent {
constructor() {
super("w:bCs");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class CharacterSpacing extends XmlComponent {
constructor(value: number) {
constructor(value: number | string) {
super("w:spacing");
this.root.push(
new Attributes({
val: value,
}),
);
}
}
export class Italics extends XmlComponent {
constructor() {
super("w:i");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class ItalicsComplexScript extends XmlComponent {
constructor() {
super("w:iCs");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class Caps extends XmlComponent {
constructor() {
super("w:caps");
this.root.push(
new Attributes({
val: true,
val: signedTwipsMeasureValue(value),
}),
);
}
}
// <xsd:complexType name="CT_Color">
// <xsd:attribute name="val" type="ST_HexColor" use="required"/>
// <xsd:attribute name="themeColor" type="ST_ThemeColor" use="optional"/>
// <xsd:attribute name="themeTint" type="ST_UcharHexNumber" use="optional"/>
// <xsd:attribute name="themeShade" type="ST_UcharHexNumber" use="optional"/>
// </xsd:complexType>
export class Color extends XmlComponent {
constructor(color: string) {
super("w:color");
this.root.push(
new Attributes({
val: color,
}),
);
}
}
export class DoubleStrike extends XmlComponent {
constructor() {
super("w:dstrike");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class Emboss extends XmlComponent {
constructor() {
super("w:emboss");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class Imprint extends XmlComponent {
constructor() {
super("w:imprint");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class SmallCaps extends XmlComponent {
constructor() {
super("w:smallCaps");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class Strike extends XmlComponent {
constructor() {
super("w:strike");
this.root.push(
new Attributes({
val: true,
}),
);
}
}
export class Size extends XmlComponent {
constructor(size: number) {
super("w:sz");
this.root.push(
new Attributes({
val: size,
}),
);
}
}
export class SizeComplexScript extends XmlComponent {
constructor(size: number) {
super("w:szCs");
this.root.push(
new Attributes({
val: size,
}),
);
}
}
export class RightToLeft extends XmlComponent {
constructor() {
super("w:rtl");
this.root.push(
new Attributes({
val: true,
val: hexColorValue(color),
}),
);
}
}
// <xsd:simpleType name="ST_HighlightColor">
// <xsd:restriction base="xsd:string">
// <xsd:enumeration value="black"/>
// <xsd:enumeration value="blue"/>
// <xsd:enumeration value="cyan"/>
// <xsd:enumeration value="green"/>
// <xsd:enumeration value="magenta"/>
// <xsd:enumeration value="red"/>
// <xsd:enumeration value="yellow"/>
// <xsd:enumeration value="white"/>
// <xsd:enumeration value="darkBlue"/>
// <xsd:enumeration value="darkCyan"/>
// <xsd:enumeration value="darkGreen"/>
// <xsd:enumeration value="darkMagenta"/>
// <xsd:enumeration value="darkRed"/>
// <xsd:enumeration value="darkYellow"/>
// <xsd:enumeration value="darkGray"/>
// <xsd:enumeration value="lightGray"/>
// <xsd:enumeration value="none"/>
// </xsd:restriction>
// </xsd:simpleType>
export class Highlight extends XmlComponent {
constructor(color: string) {
super("w:highlight");

View File

@ -1,25 +1,7 @@
import { IShadingAttributesProperties, Shading } from "file/shading";
import { IgnoreIfEmptyXmlComponent, XmlComponent } from "file/xml-components";
import { HpsMeasureElement, IgnoreIfEmptyXmlComponent, OnOffElement, XmlComponent } from "file/xml-components";
import { EmphasisMark, EmphasisMarkType } from "./emphasis-mark";
import {
Bold,
BoldComplexScript,
Caps,
CharacterSpacing,
Color,
DoubleStrike,
Emboss,
Highlight,
HighlightComplexScript,
Imprint,
Italics,
ItalicsComplexScript,
RightToLeft,
Size,
SizeComplexScript,
SmallCaps,
Strike,
} from "./formatting";
import { CharacterSpacing, Color, Highlight, HighlightComplexScript } from "./formatting";
import { IFontAttributesProperties, RunFonts } from "./run-fonts";
import { SubScript, SuperScript } from "./script";
import { Style } from "./style";
@ -43,8 +25,8 @@ export interface IRunStylePropertiesOptions {
readonly type?: EmphasisMarkType;
};
readonly color?: string;
readonly size?: number;
readonly sizeComplexScript?: boolean | number;
readonly size?: number | string;
readonly sizeComplexScript?: boolean | number | string;
readonly rightToLeft?: boolean;
readonly smallCaps?: boolean;
readonly allCaps?: boolean;
@ -65,6 +47,49 @@ export interface IRunPropertiesOptions extends IRunStylePropertiesOptions {
readonly style?: string;
}
// <xsd:group name="EG_RPrBase">
// <xsd:choice>
// <xsd:element name="rStyle" type="CT_String"/>
// <xsd:element name="rFonts" type="CT_Fonts"/>
// <xsd:element name="b" type="CT_OnOff"/>
// <xsd:element name="bCs" type="CT_OnOff"/>
// <xsd:element name="i" type="CT_OnOff"/>
// <xsd:element name="iCs" type="CT_OnOff"/>
// <xsd:element name="caps" type="CT_OnOff"/>
// <xsd:element name="smallCaps" type="CT_OnOff"/>
// <xsd:element name="strike" type="CT_OnOff"/>
// <xsd:element name="dstrike" type="CT_OnOff"/>
// <xsd:element name="outline" type="CT_OnOff"/>
// <xsd:element name="shadow" type="CT_OnOff"/>
// <xsd:element name="emboss" type="CT_OnOff"/>
// <xsd:element name="imprint" type="CT_OnOff"/>
// <xsd:element name="noProof" type="CT_OnOff"/>
// <xsd:element name="snapToGrid" type="CT_OnOff"/>
// <xsd:element name="vanish" type="CT_OnOff"/>
// <xsd:element name="webHidden" type="CT_OnOff"/>
// <xsd:element name="color" type="CT_Color"/>
// <xsd:element name="spacing" type="CT_SignedTwipsMeasure"/>
// <xsd:element name="w" type="CT_TextScale"/>
// <xsd:element name="kern" type="CT_HpsMeasure"/>
// <xsd:element name="position" type="CT_SignedHpsMeasure"/>
// <xsd:element name="sz" type="CT_HpsMeasure"/>
// <xsd:element name="szCs" type="CT_HpsMeasure"/>
// <xsd:element name="highlight" type="CT_Highlight"/>
// <xsd:element name="u" type="CT_Underline"/>
// <xsd:element name="effect" type="CT_TextEffect"/>
// <xsd:element name="bdr" type="CT_Border"/>
// <xsd:element name="shd" type="CT_Shd"/>
// <xsd:element name="fitText" type="CT_FitText"/>
// <xsd:element name="vertAlign" type="CT_VerticalAlignRun"/>
// <xsd:element name="rtl" type="CT_OnOff"/>
// <xsd:element name="cs" type="CT_OnOff"/>
// <xsd:element name="em" type="CT_Em"/>
// <xsd:element name="lang" type="CT_Language"/>
// <xsd:element name="eastAsianLayout" type="CT_EastAsianLayout"/>
// <xsd:element name="specVanish" type="CT_OnOff"/>
// <xsd:element name="oMath" type="CT_OnOff"/>
// </xsd:choice>
// </xsd:group>
export class RunProperties extends IgnoreIfEmptyXmlComponent {
constructor(options?: IRunPropertiesOptions) {
super("w:rPr");
@ -74,17 +99,17 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent {
}
if (options.bold) {
this.push(new Bold());
this.push(new OnOffElement("w:b"));
}
if ((options.boldComplexScript === undefined && options.bold) || options.boldComplexScript) {
this.push(new BoldComplexScript());
this.push(new OnOffElement("w:bCs"));
}
if (options.italics) {
this.push(new Italics());
this.push(new OnOffElement("w:i"));
}
if ((options.italicsComplexScript === undefined && options.italics) || options.italicsComplexScript) {
this.push(new ItalicsComplexScript());
this.push(new OnOffElement("w:iCs"));
}
if (options.underline) {
@ -100,32 +125,31 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent {
}
if (options.size) {
this.push(new Size(options.size));
this.push(new HpsMeasureElement("w:sz", options.size));
}
const szCs =
options.sizeComplexScript === undefined || options.sizeComplexScript === true ? options.size : options.sizeComplexScript;
if (szCs) {
this.push(new SizeComplexScript(szCs));
this.push(new HpsMeasureElement("w:szCs", szCs));
}
if (options.rightToLeft) {
this.push(new RightToLeft());
this.push(new OnOffElement("w:rtl"));
}
// These two are mutually exclusive
if (options.smallCaps) {
this.push(new SmallCaps());
}
if (options.allCaps) {
this.push(new Caps());
this.push(new OnOffElement("w:smallCaps"));
} else if (options.allCaps) {
this.push(new OnOffElement("w:caps"));
}
if (options.strike) {
this.push(new Strike());
this.push(new OnOffElement("w:strike"));
}
if (options.doubleStrike) {
this.push(new DoubleStrike());
this.push(new OnOffElement("w:dstrike"));
}
if (options.subScript) {
@ -166,11 +190,11 @@ export class RunProperties extends IgnoreIfEmptyXmlComponent {
}
if (options.emboss) {
this.push(new Emboss());
this.push(new OnOffElement("w:emboss"));
}
if (options.imprint) {
this.push(new Imprint());
this.push(new OnOffElement("w:imprint"));
}
if (options.shading) {

View File

@ -1,47 +0,0 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { DoubleStrike, Strike } from "./formatting";
describe("Strike", () => {
let strike: Strike;
beforeEach(() => {
strike = new Strike();
});
describe("#constructor()", () => {
it("should create a Strike with correct root key", () => {
const tree = new Formatter().format(strike);
expect(tree).to.deep.equal({
"w:strike": {
_attr: {
"w:val": true,
},
},
});
});
});
});
describe("DoubleStrike", () => {
let strike: DoubleStrike;
beforeEach(() => {
strike = new DoubleStrike();
});
describe("#constructor()", () => {
it("should create a Double Strike with correct root key", () => {
const tree = new Formatter().format(strike);
expect(tree).to.deep.equal({
"w:dstrike": {
_attr: {
"w:val": true,
},
},
});
});
});
});

View File

@ -49,7 +49,7 @@ describe("SymbolRun", () => {
emphasisMark: {
type: EmphasisMarkType.DOT,
},
color: "green",
color: "00FF00",
size: 40,
highlight: "yellow",
});
@ -65,7 +65,7 @@ describe("SymbolRun", () => {
{ "w:iCs": { _attr: { "w:val": true } } },
{ "w:u": { _attr: { "w:val": "double", "w:color": "red" } } },
{ "w:em": { _attr: { "w:val": "dot" } } },
{ "w:color": { _attr: { "w:val": "green" } } },
{ "w:color": { _attr: { "w:val": "00FF00" } } },
{ "w:sz": { _attr: { "w:val": 40 } } },
{ "w:szCs": { _attr: { "w:val": 40 } } },
{ "w:highlight": { _attr: { "w:val": "yellow" } } },

View File

@ -21,7 +21,7 @@ export enum UnderlineType {
}
export abstract class BaseUnderline extends XmlComponent {
constructor(underlineType: string, color?: string) {
constructor(underlineType: UnderlineType, color?: string) {
super("w:u");
this.root.push(
new Attributes({
@ -40,96 +40,96 @@ export class Underline extends BaseUnderline {
export class DashUnderline extends BaseUnderline {
constructor() {
super("dash");
super(UnderlineType.DASH);
}
}
export class DashDotDotHeavyUnderline extends BaseUnderline {
constructor() {
super("dashDotDotHeavy");
super(UnderlineType.DASHDOTDOTHEAVY);
}
}
export class DashDotHeavyUnderline extends BaseUnderline {
constructor() {
super("dashDotHeavy");
super(UnderlineType.DASHDOTHEAVY);
}
}
export class DashLongUnderline extends BaseUnderline {
constructor() {
super("dashLong");
super(UnderlineType.DASHLONG);
}
}
export class DashLongHeavyUnderline extends BaseUnderline {
constructor() {
super("dashLongHeavy");
super(UnderlineType.DASHLONGHEAVY);
}
}
export class DotDashUnderline extends BaseUnderline {
constructor() {
super("dotDash");
super(UnderlineType.DOTDASH);
}
}
export class DotDotDashUnderline extends BaseUnderline {
constructor() {
super("dotDotDash");
super(UnderlineType.DOTDOTDASH);
}
}
export class DottedUnderline extends BaseUnderline {
constructor() {
super("dotted");
super(UnderlineType.DOTTED);
}
}
export class DottedHeavyUnderline extends BaseUnderline {
constructor() {
super("dottedHeavy");
super(UnderlineType.DOTTEDHEAVY);
}
}
export class DoubleUnderline extends BaseUnderline {
constructor() {
super("double");
super(UnderlineType.DOUBLE);
}
}
export class SingleUnderline extends BaseUnderline {
constructor() {
super("single");
super(UnderlineType.SINGLE);
}
}
export class ThickUnderline extends BaseUnderline {
constructor() {
super("thick");
super(UnderlineType.THICK);
}
}
export class WaveUnderline extends BaseUnderline {
constructor() {
super("wave");
super(UnderlineType.WAVE);
}
}
export class WavyDoubleUnderline extends BaseUnderline {
constructor() {
super("wavyDouble");
super(UnderlineType.WAVYDOUBLE);
}
}
export class WavyHeavyUnderline extends BaseUnderline {
constructor() {
super("wavyHeavy");
super(UnderlineType.WAVYHEAVY);
}
}
export class WordsUnderline extends BaseUnderline {
constructor() {
super("words");
super(UnderlineType.WORDS);
}
}