Documentation and Refactoring (#3028)

* Documentation and Refactoring

* Documentation and Refactoring

* Fix lint issues

* Convert components to Builder style

---------

Co-authored-by: Dolan Miu <dmiu@bloomberg.net>
This commit is contained in:
Dolan
2025-04-14 16:43:15 +05:30
committed by GitHub
parent 8ba9a448d3
commit 4d1a351649
78 changed files with 1178 additions and 620 deletions

View File

@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathAccentCharacter } from "./math-accent-character";
import { createMathAccentCharacter } from "./math-accent-character";
describe("MathAccentCharacter", () => {
describe("#constructor()", () => {
it("should create a MathAccentCharacter with correct root key", () => {
const mathAccentCharacter = new MathAccentCharacter("∑");
const mathAccentCharacter = createMathAccentCharacter({ accent: "∑" });
const tree = new Formatter().format(mathAccentCharacter);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,12 @@
// http://www.datypic.com/sc/ooxml/e-m_chr-1.html
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
class MathAccentCharacterAttributes extends XmlAttributeComponent<{ readonly accent: string }> {
protected readonly xmlKeys = { accent: "m:val" };
}
type MathAccentCharacterOptions = { readonly accent: string };
export class MathAccentCharacter extends XmlComponent {
public constructor(accent: string) {
super("m:chr");
this.root.push(new MathAccentCharacterAttributes({ accent }));
}
}
export const createMathAccentCharacter = ({ accent }: MathAccentCharacterOptions): XmlComponent =>
new BuilderElement<MathAccentCharacterOptions>({
name: "m:chr",
attributes: {
accent: { key: "m:val", value: accent },
},
});

View File

@ -3,12 +3,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathRun } from "../math-run";
import { MathBase } from "./math-base";
import { createMathBase } from "./math-base";
describe("MathBase", () => {
describe("createMathBase", () => {
describe("#constructor()", () => {
it("should create a MathBase with correct root key", () => {
const mathBase = new MathBase([new MathRun("2+2")]);
const mathBase = createMathBase({ children: [new MathRun("2+2")] });
const tree = new Formatter().format(mathBase);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_e-1.html
import { XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
export class MathBase extends XmlComponent {
public constructor(children: readonly MathComponent[]) {
super("m:e");
type MathBaseOptions = {
readonly children: readonly MathComponent[];
};
for (const child of children) {
this.root.push(child);
}
}
}
export const createMathBase = ({ children }: MathBaseOptions): XmlComponent =>
new BuilderElement({
name: "m:e",
children,
});

View File

@ -1,10 +1,10 @@
import { XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "./math-base";
import { MathNAryProperties } from "./math-n-ary-properties";
import { MathSubScriptElement } from "./math-sub-script";
import { MathSuperScriptElement } from "./math-super-script";
import { createMathBase } from "./math-base";
import { createMathNAryProperties } from "./math-n-ary-properties";
import { createMathSubScriptElement } from "./math-sub-script";
import { createMathSuperScriptElement } from "./math-super-script";
export type IMathIntegralOptions = {
readonly children: readonly MathComponent[];
@ -16,16 +16,23 @@ export class MathIntegral extends XmlComponent {
public constructor(options: IMathIntegralOptions) {
super("m:nary");
this.root.push(new MathNAryProperties("", !!options.superScript, !!options.subScript, "subSup"));
this.root.push(
createMathNAryProperties({
accent: "",
hasSuperScript: !!options.superScript,
hasSubScript: !!options.subScript,
limitLocationVal: "subSup",
}),
);
if (!!options.subScript) {
this.root.push(new MathSubScriptElement(options.subScript));
this.root.push(createMathSubScriptElement({ children: options.subScript }));
}
if (!!options.superScript) {
this.root.push(new MathSuperScriptElement(options.superScript));
this.root.push(createMathSuperScriptElement({ children: options.superScript }));
}
this.root.push(new MathBase(options.children));
this.root.push(createMathBase({ children: options.children }));
}
}

View File

@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathLimitLocation } from "./math-limit-location";
import { createMathLimitLocation } from "./math-limit-location";
describe("MathLimitLocation", () => {
describe("createMathLimitLocation", () => {
describe("#constructor()", () => {
it("should create a MathLimitLocation with correct root key", () => {
const mathLimitLocation = new MathLimitLocation();
const mathLimitLocation = createMathLimitLocation({});
const tree = new Formatter().format(mathLimitLocation);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,12 @@
// http://www.datypic.com/sc/ooxml/e-m_limLoc-1.html
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
class MathLimitLocationAttributes extends XmlAttributeComponent<{ readonly value: string }> {
protected readonly xmlKeys = { value: "m:val" };
}
type MathLimitLocationOptions = { readonly value?: string };
export class MathLimitLocation extends XmlComponent {
public constructor(value?: string) {
super("m:limLoc");
this.root.push(new MathLimitLocationAttributes({ value: value || "undOvr" }));
}
}
export const createMathLimitLocation = ({ value }: MathLimitLocationOptions): XmlComponent =>
new BuilderElement<Required<MathLimitLocationOptions>>({
name: "m:limLoc",
attributes: {
value: { key: "m:val", value: value || "undOvr" },
},
});

View File

@ -2,7 +2,7 @@
import { XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "./math-base";
import { createMathBase } from "./math-base";
import { MathLimit } from "./math-limit";
export type IMathLimitLowerOptions = {
@ -14,7 +14,7 @@ export class MathLimitLower extends XmlComponent {
public constructor(options: IMathLimitLowerOptions) {
super("m:limLow");
this.root.push(new MathBase(options.children));
this.root.push(createMathBase({ children: options.children }));
this.root.push(new MathLimit(options.limit));
}
}

View File

@ -2,7 +2,7 @@
import { XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "./math-base";
import { createMathBase } from "./math-base";
import { MathLimit } from "./math-limit";
export type IMathLimitUpperOptions = {
@ -14,7 +14,7 @@ export class MathLimitUpper extends XmlComponent {
public constructor(options: IMathLimitUpperOptions) {
super("m:limUpp");
this.root.push(new MathBase(options.children));
this.root.push(createMathBase({ children: options.children }));
this.root.push(new MathLimit(options.limit));
}
}

View File

@ -2,12 +2,16 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathNAryProperties } from "./math-n-ary-properties";
import { createMathNAryProperties } from "./math-n-ary-properties";
describe("MathNAryProperties", () => {
describe("createMathNAryProperties", () => {
describe("#constructor()", () => {
it("should create a MathNAryProperties with correct root key", () => {
const mathNAryProperties = new MathNAryProperties("∑", true, true);
const mathNAryProperties = createMathNAryProperties({
accent: "∑",
hasSuperScript: true,
hasSubScript: true,
});
const tree = new Formatter().format(mathNAryProperties);
expect(tree).to.deep.equal({
@ -31,7 +35,11 @@ describe("MathNAryProperties", () => {
});
it("should add super-script hide attributes", () => {
const mathNAryProperties = new MathNAryProperties("∑", false, true);
const mathNAryProperties = createMathNAryProperties({
accent: "∑",
hasSuperScript: false,
hasSubScript: true,
});
const tree = new Formatter().format(mathNAryProperties);
expect(tree).to.deep.equal({
@ -62,7 +70,11 @@ describe("MathNAryProperties", () => {
});
it("should add sub-script hide attributes", () => {
const mathNAryProperties = new MathNAryProperties("∑", true, false);
const mathNAryProperties = createMathNAryProperties({
accent: "∑",
hasSuperScript: true,
hasSubScript: false,
});
const tree = new Formatter().format(mathNAryProperties);
expect(tree).to.deep.equal({
@ -93,7 +105,11 @@ describe("MathNAryProperties", () => {
});
it("should add both super-script and sub-script hide attributes", () => {
const mathNAryProperties = new MathNAryProperties("∑", false, false);
const mathNAryProperties = createMathNAryProperties({
accent: "∑",
hasSuperScript: false,
hasSubScript: false,
});
const tree = new Formatter().format(mathNAryProperties);
expect(tree).to.deep.equal({

View File

@ -1,26 +1,30 @@
// http://www.datypic.com/sc/ooxml/e-m_naryPr-1.html
import { XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
import { MathAccentCharacter } from "./math-accent-character";
import { MathLimitLocation } from "./math-limit-location";
import { MathSubScriptHide } from "./math-sub-script-hide";
import { MathSuperScriptHide } from "./math-super-script-hide";
import { createMathAccentCharacter } from "./math-accent-character";
import { createMathLimitLocation } from "./math-limit-location";
import { createMathSubScriptHide } from "./math-sub-script-hide";
import { createMathSuperScriptHide } from "./math-super-script-hide";
export class MathNAryProperties extends XmlComponent {
public constructor(accent: string, hasSuperScript: boolean, hasSubScript: boolean, limitLocationVal?: string) {
super("m:naryPr");
type MathNAryPropertiesOptions = {
readonly accent: string;
readonly hasSuperScript: boolean;
readonly hasSubScript: boolean;
readonly limitLocationVal?: string;
};
if (!!accent) {
this.root.push(new MathAccentCharacter(accent));
}
this.root.push(new MathLimitLocation(limitLocationVal));
if (!hasSuperScript) {
this.root.push(new MathSuperScriptHide());
}
if (!hasSubScript) {
this.root.push(new MathSubScriptHide());
}
}
}
export const createMathNAryProperties = ({
accent,
hasSuperScript,
hasSubScript,
limitLocationVal,
}: MathNAryPropertiesOptions): XmlComponent =>
new BuilderElement({
name: "m:naryPr",
children: [
...(!!accent ? [createMathAccentCharacter({ accent })] : []),
createMathLimitLocation({ value: limitLocationVal }),
...(!hasSuperScript ? [createMathSuperScriptHide()] : []),
...(!hasSubScript ? [createMathSubScriptHide()] : []),
],
});

View File

@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathSubScriptHide } from "./math-sub-script-hide";
import { createMathSubScriptHide } from "./math-sub-script-hide";
describe("MathSubScriptHide", () => {
describe("createMathSubScriptHide", () => {
describe("#constructor()", () => {
it("should create a MathSubScriptHide with correct root key", () => {
const mathSubScriptHide = new MathSubScriptHide();
const mathSubScriptHide = createMathSubScriptHide();
const tree = new Formatter().format(mathSubScriptHide);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,10 @@
// http://www.datypic.com/sc/ooxml/e-m_subHide-1.html
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
class MathSubScriptHideAttributes extends XmlAttributeComponent<{ readonly hide: number }> {
protected readonly xmlKeys = { hide: "m:val" };
}
export class MathSubScriptHide extends XmlComponent {
public constructor() {
super("m:subHide");
this.root.push(new MathSubScriptHideAttributes({ hide: 1 }));
}
}
export const createMathSubScriptHide = (): XmlComponent =>
new BuilderElement<{ readonly hide: number }>({
name: "m:subHide",
attributes: {
hide: { key: "m:val", value: 1 },
},
});

View File

@ -3,12 +3,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathRun } from "../math-run";
import { MathSubScriptElement } from "./math-sub-script";
import { createMathSubScriptElement } from "./math-sub-script";
describe("MathSubScriptElement", () => {
describe("createMathSubScriptElement", () => {
describe("#constructor()", () => {
it("should create a MathSubScriptElement with correct root key", () => {
const mathSubScriptElement = new MathSubScriptElement([new MathRun("2+2")]);
const mathSubScriptElement = createMathSubScriptElement({ children: [new MathRun("2+2")] });
const tree = new Formatter().format(mathSubScriptElement);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_sub-3.html
import { XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
export class MathSubScriptElement extends XmlComponent {
public constructor(children: readonly MathComponent[]) {
super("m:sub");
type MathSubScriptElementOptions = {
readonly children: readonly MathComponent[];
};
for (const child of children) {
this.root.push(child);
}
}
}
export const createMathSubScriptElement = ({ children }: MathSubScriptElementOptions): XmlComponent =>
new BuilderElement({
name: "m:sub",
children,
});

View File

@ -2,10 +2,10 @@
import { XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
import { MathBase } from "./math-base";
import { MathNAryProperties } from "./math-n-ary-properties";
import { MathSubScriptElement } from "./math-sub-script";
import { MathSuperScriptElement } from "./math-super-script";
import { createMathBase } from "./math-base";
import { createMathNAryProperties } from "./math-n-ary-properties";
import { createMathSubScriptElement } from "./math-sub-script";
import { createMathSuperScriptElement } from "./math-super-script";
export type IMathSumOptions = {
readonly children: readonly MathComponent[];
@ -17,16 +17,22 @@ export class MathSum extends XmlComponent {
public constructor(options: IMathSumOptions) {
super("m:nary");
this.root.push(new MathNAryProperties("∑", !!options.superScript, !!options.subScript));
this.root.push(
createMathNAryProperties({
accent: "∑",
hasSuperScript: !!options.superScript,
hasSubScript: !!options.subScript,
}),
);
if (!!options.subScript) {
this.root.push(new MathSubScriptElement(options.subScript));
this.root.push(createMathSubScriptElement({ children: options.subScript }));
}
if (!!options.superScript) {
this.root.push(new MathSuperScriptElement(options.superScript));
this.root.push(createMathSuperScriptElement({ children: options.superScript }));
}
this.root.push(new MathBase(options.children));
this.root.push(createMathBase({ children: options.children }));
}
}

View File

@ -2,12 +2,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathSuperScriptHide } from "./math-super-script-hide";
import { createMathSuperScriptHide } from "./math-super-script-hide";
describe("MathSuperScriptHide", () => {
describe("createMathSuperScriptHide", () => {
describe("#constructor()", () => {
it("should create a MathSuperScriptHide with correct root key", () => {
const mathSuperScriptHide = new MathSuperScriptHide();
const mathSuperScriptHide = createMathSuperScriptHide();
const tree = new Formatter().format(mathSuperScriptHide);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,10 @@
// http://www.datypic.com/sc/ooxml/e-m_subHide-1.html
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
class MathSuperScriptHideAttributes extends XmlAttributeComponent<{ readonly hide: number }> {
protected readonly xmlKeys = { hide: "m:val" };
}
export class MathSuperScriptHide extends XmlComponent {
public constructor() {
super("m:supHide");
this.root.push(new MathSuperScriptHideAttributes({ hide: 1 }));
}
}
export const createMathSuperScriptHide = (): XmlComponent =>
new BuilderElement<{ readonly hide: number }>({
name: "m:supHide",
attributes: {
hide: { key: "m:val", value: 1 },
},
});

View File

@ -3,12 +3,12 @@ import { describe, expect, it } from "vitest";
import { Formatter } from "@export/formatter";
import { MathRun } from "../math-run";
import { MathSuperScriptElement } from "./math-super-script";
import { createMathSuperScriptElement } from "./math-super-script";
describe("MathSuperScriptElement", () => {
describe("createMathSuperScriptElement", () => {
describe("#constructor()", () => {
it("should create a MathSuperScriptElement with correct root key", () => {
const mathSuperScriptElement = new MathSuperScriptElement([new MathRun("2+2")]);
const mathSuperScriptElement = createMathSuperScriptElement({ children: [new MathRun("2+2")] });
const tree = new Formatter().format(mathSuperScriptElement);
expect(tree).to.deep.equal({

View File

@ -1,14 +1,14 @@
// http://www.datypic.com/sc/ooxml/e-m_sup-3.html
import { XmlComponent } from "@file/xml-components";
import { BuilderElement, XmlComponent } from "@file/xml-components";
import { MathComponent } from "../math-component";
export class MathSuperScriptElement extends XmlComponent {
public constructor(children: readonly MathComponent[]) {
super("m:sup");
type MathSuperScriptElementOptions = {
readonly children: readonly MathComponent[];
};
for (const child of children) {
this.root.push(child);
}
}
}
export const createMathSuperScriptElement = ({ children }: MathSuperScriptElementOptions): XmlComponent =>
new BuilderElement({
name: "m:sup",
children,
});