Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
7b2e8ede07 | |||
7da242ee9e | |||
d71203d2a6 | |||
064cee9921 |
@ -3,6 +3,8 @@ import { ICompatibilityOptions } from "@file/settings/compatibility";
|
||||
import { FontOptions } from "@file/fonts/font-table";
|
||||
import { StringContainer, XmlComponent } from "@file/xml-components";
|
||||
import { dateTimeValue } from "@util/values";
|
||||
import { IHyphenationOptions } from "@file/settings";
|
||||
import { IFootnoteProperties } from "@file/settings/footnote-properties";
|
||||
|
||||
import { ICustomPropertyOptions } from "../custom-properties";
|
||||
import { IDocumentBackgroundOptions } from "../document";
|
||||
@ -42,6 +44,8 @@ export interface IPropertiesOptions {
|
||||
readonly evenAndOddHeaderAndFooters?: boolean;
|
||||
readonly defaultTabStop?: number;
|
||||
readonly fonts?: readonly FontOptions[];
|
||||
readonly hyphenation?: IHyphenationOptions;
|
||||
readonly footnoteProperties?: IFootnoteProperties;
|
||||
}
|
||||
|
||||
// <xs:element name="coreProperties" type="CT_CoreProperties"/>
|
||||
|
@ -5,6 +5,7 @@ import { FooterWrapper } from "@file/footer-wrapper";
|
||||
import { HeaderWrapper } from "@file/header-wrapper";
|
||||
import { VerticalAlign, VerticalAlignElement } from "@file/vertical-align";
|
||||
import { OnOffElement, XmlComponent } from "@file/xml-components";
|
||||
import { FootnoteProperties, IFootnoteProperties } from "@file/settings/footnote-properties";
|
||||
|
||||
import { HeaderFooterReference, HeaderFooterReferenceType, HeaderFooterType } from "./properties/header-footer-reference";
|
||||
import { Columns, IColumnsAttributes } from "./properties/columns";
|
||||
@ -39,6 +40,7 @@ export interface ISectionPropertiesOptions {
|
||||
readonly verticalAlign?: (typeof VerticalAlign)[keyof typeof VerticalAlign];
|
||||
readonly column?: IColumnsAttributes;
|
||||
readonly type?: (typeof SectionType)[keyof typeof SectionType];
|
||||
readonly footnoteProperties?: IFootnoteProperties;
|
||||
}
|
||||
|
||||
// <xsd:complexType name="CT_SectPr">
|
||||
@ -119,6 +121,7 @@ export class SectionProperties extends XmlComponent {
|
||||
verticalAlign,
|
||||
column,
|
||||
type,
|
||||
footnoteProperties,
|
||||
}: ISectionPropertiesOptions = {}) {
|
||||
super("w:sectPr");
|
||||
|
||||
@ -158,6 +161,10 @@ export class SectionProperties extends XmlComponent {
|
||||
this.root.push(new PageTextDirection(textDirection));
|
||||
}
|
||||
|
||||
if (footnoteProperties) {
|
||||
this.root.push(new FootnoteProperties(footnoteProperties));
|
||||
}
|
||||
|
||||
this.root.push(new DocumentGrid(linePitch, charSpace, gridType));
|
||||
}
|
||||
|
||||
|
@ -80,6 +80,12 @@ export class File {
|
||||
trackRevisions: options.features?.trackRevisions,
|
||||
updateFields: options.features?.updateFields,
|
||||
defaultTabStop: options.defaultTabStop,
|
||||
hyphenation: {
|
||||
autoHyphenation: options.hyphenation?.autoHyphenation,
|
||||
hyphenationZone: options.hyphenation?.hyphenationZone,
|
||||
consecutiveHyphenLimit: options.hyphenation?.consecutiveHyphenLimit,
|
||||
doNotHyphenateCaps: options.hyphenation?.doNotHyphenateCaps,
|
||||
}
|
||||
});
|
||||
|
||||
this.media = new Media();
|
||||
|
23
src/file/settings/footnote-format.ts
Normal file
23
src/file/settings/footnote-format.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
import { NumberFormat } from "@file/shared/number-format";
|
||||
|
||||
export class FootnoteNumberingFormatAttributes extends XmlAttributeComponent<{
|
||||
readonly numberFormat: (typeof NumberFormat)[keyof typeof NumberFormat];
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
numberFormat: "w:val",
|
||||
};
|
||||
}
|
||||
|
||||
export class FootnoteNumberingFormat extends XmlComponent {
|
||||
public constructor(numberFormat: (typeof NumberFormat)[keyof typeof NumberFormat]) {
|
||||
super("w:numFmt");
|
||||
|
||||
this.root.push(
|
||||
new FootnoteNumberingFormatAttributes({
|
||||
numberFormat,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
23
src/file/settings/footnote-positioning.ts
Normal file
23
src/file/settings/footnote-positioning.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { FootnotePositioningLocationType } from "@file/shared/footnote-properties";
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
|
||||
export class FootnotePositioningLocationAttributes extends XmlAttributeComponent<{
|
||||
readonly position: FootnotePositioningLocationType;
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
position: "w:val",
|
||||
};
|
||||
}
|
||||
|
||||
export class FootnotePositioningLocation extends XmlComponent {
|
||||
public constructor(position: FootnotePositioningLocationType) {
|
||||
super("w:pos");
|
||||
|
||||
this.root.push(
|
||||
new FootnotePositioningLocationAttributes({
|
||||
position,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
36
src/file/settings/footnote-properties.ts
Normal file
36
src/file/settings/footnote-properties.ts
Normal file
@ -0,0 +1,36 @@
|
||||
// http://www.datypic.com/sc/ooxml/e-w_footnotePr-2.html
|
||||
import { NumberValueElement, XmlComponent } from "@file/xml-components";
|
||||
import { FootnotePositioningLocationType, FootnoteRestartLocationType } from "@file/shared/footnote-properties";
|
||||
import { NumberFormat } from "@file/shared/number-format";
|
||||
import { FootnoteNumberingRestart } from "./footnote-restart";
|
||||
import { FootnotePositioningLocation } from "./footnote-positioning";
|
||||
import { FootnoteNumberingFormat } from "./footnote-format";
|
||||
|
||||
export interface IFootnoteProperties {
|
||||
readonly restartLocation?: FootnoteRestartLocationType;
|
||||
readonly positioningLocation?: FootnotePositioningLocationType;
|
||||
readonly numberFormat?: (typeof NumberFormat)[keyof typeof NumberFormat];
|
||||
readonly startingNumber?: number;
|
||||
}
|
||||
|
||||
export class FootnoteProperties extends XmlComponent {
|
||||
public constructor(options: IFootnoteProperties) {
|
||||
super("w:footnotePr");
|
||||
|
||||
if (options.restartLocation !== undefined) {
|
||||
this.root.push(new FootnoteNumberingRestart(options.restartLocation));
|
||||
}
|
||||
|
||||
if (options.positioningLocation !== undefined) {
|
||||
this.root.push(new FootnotePositioningLocation(options.positioningLocation));
|
||||
}
|
||||
|
||||
if (options.numberFormat !== undefined) {
|
||||
this.root.push(new FootnoteNumberingFormat(options.numberFormat));
|
||||
}
|
||||
|
||||
if (options.startingNumber !== undefined) {
|
||||
this.root.push(new NumberValueElement('w:numStart', options.startingNumber));
|
||||
}
|
||||
}
|
||||
}
|
22
src/file/settings/footnote-restart.ts
Normal file
22
src/file/settings/footnote-restart.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { FootnoteRestartLocationType } from "@file/shared/footnote-properties";
|
||||
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
|
||||
export class FootnoteRestartNumberingAttributes extends XmlAttributeComponent<{
|
||||
readonly restart: FootnoteRestartLocationType;
|
||||
}> {
|
||||
protected readonly xmlKeys = {
|
||||
restart: "w:val",
|
||||
};
|
||||
}
|
||||
|
||||
export class FootnoteNumberingRestart extends XmlComponent {
|
||||
public constructor(restart: FootnoteRestartLocationType) {
|
||||
super("w:numRestart");
|
||||
|
||||
this.root.push(
|
||||
new FootnoteRestartNumberingAttributes({
|
||||
restart,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
@ -129,6 +129,75 @@ describe("Settings", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should add autoHyphenation setting", () => {
|
||||
const options = {
|
||||
hyphenation: {
|
||||
autoHyphenation: true,
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new Formatter().format(new Settings(options));
|
||||
expect(Object.keys(tree)).has.length(1);
|
||||
expect(tree["w:settings"]).to.be.an("array");
|
||||
expect(tree["w:settings"]).to.deep.include({
|
||||
"w:autoHyphenation": {},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should add doNotHyphenateCaps setting", () => {
|
||||
const options = {
|
||||
hyphenation: {
|
||||
doNotHyphenateCaps: true,
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new Formatter().format(new Settings(options));
|
||||
expect(Object.keys(tree)).has.length(1);
|
||||
expect(tree["w:settings"]).to.be.an("array");
|
||||
expect(tree["w:settings"]).to.deep.include({
|
||||
"w:doNotHyphenateCaps": {},
|
||||
});
|
||||
});
|
||||
|
||||
it("should add hyphenationZone setting", () => {
|
||||
const options = {
|
||||
hyphenation: {
|
||||
hyphenationZone: 200,
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new Formatter().format(new Settings(options));
|
||||
expect(Object.keys(tree)).has.length(1);
|
||||
expect(tree["w:settings"]).to.be.an("array");
|
||||
expect(tree["w:settings"]).to.deep.include({
|
||||
"w:hyphenationZone": {
|
||||
_attr: {
|
||||
"w:val": 200,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should add consecutiveHyphenLimit setting", () => {
|
||||
const options = {
|
||||
hyphenation: {
|
||||
consecutiveHyphenLimit: 3,
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new Formatter().format(new Settings(options));
|
||||
expect(Object.keys(tree)).has.length(1);
|
||||
expect(tree["w:settings"]).to.be.an("array");
|
||||
expect(tree["w:settings"]).to.deep.include({
|
||||
"w:consecutiveHyphenLimit": {
|
||||
_attr: {
|
||||
"w:val": 3,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Remove when deprecating compatibilityModeVersion
|
||||
it("should add compatibility setting with legacy version", () => {
|
||||
const settings = new Settings({
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { NumberValueElement, OnOffElement, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
|
||||
|
||||
import { Compatibility, ICompatibilityOptions } from "./compatibility";
|
||||
import { FootnoteProperties, IFootnoteProperties } from "./footnote-properties";
|
||||
|
||||
export class SettingsAttributes extends XmlAttributeComponent<{
|
||||
readonly wpc?: string;
|
||||
@ -153,6 +154,19 @@ export interface ISettingsOptions {
|
||||
readonly updateFields?: boolean;
|
||||
readonly compatibility?: ICompatibilityOptions;
|
||||
readonly defaultTabStop?: number;
|
||||
readonly hyphenation?: IHyphenationOptions;
|
||||
readonly footnoteProperties?: IFootnoteProperties;
|
||||
}
|
||||
|
||||
export interface IHyphenationOptions {
|
||||
/** Specifies whether the application automatically hyphenates words as they are typed in the document. */
|
||||
readonly autoHyphenation?: boolean;
|
||||
/** Specifies the minimum number of characters at the beginning of a word before a hyphen can be inserted. */
|
||||
readonly hyphenationZone?: number;
|
||||
/** Specifies the maximum number of consecutive lines that can end with a hyphenated word. */
|
||||
readonly consecutiveHyphenLimit?: number;
|
||||
/** Specifies whether to hyphenate words in all capital letters. */
|
||||
readonly doNotHyphenateCaps?: boolean;
|
||||
}
|
||||
|
||||
export class Settings extends XmlComponent {
|
||||
@ -204,6 +218,30 @@ export class Settings extends XmlComponent {
|
||||
this.root.push(new NumberValueElement("w:defaultTabStop", options.defaultTabStop));
|
||||
}
|
||||
|
||||
// https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_autoHyphenation_topic_ID0EFUMX.html
|
||||
if (options.hyphenation?.autoHyphenation !== undefined) {
|
||||
this.root.push(new OnOffElement("w:autoHyphenation", options.hyphenation.autoHyphenation));
|
||||
}
|
||||
|
||||
// https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_hyphenationZone_topic_ID0ERI3X.html
|
||||
if (options.hyphenation?.hyphenationZone !== undefined) {
|
||||
this.root.push(new NumberValueElement("w:hyphenationZone", options.hyphenation.hyphenationZone));
|
||||
}
|
||||
|
||||
// https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_consecutiveHyphenLim_topic_ID0EQ6RX.html
|
||||
if (options.hyphenation?.consecutiveHyphenLimit !== undefined) {
|
||||
this.root.push(new NumberValueElement("w:consecutiveHyphenLimit", options.hyphenation.consecutiveHyphenLimit));
|
||||
}
|
||||
|
||||
// https://c-rex.net/samples/ooxml/e1/Part4/OOXML_P4_DOCX_doNotHyphenateCaps_topic_ID0EW4XX.html
|
||||
if (options.hyphenation?.doNotHyphenateCaps !== undefined) {
|
||||
this.root.push(new OnOffElement("w:doNotHyphenateCaps", options.hyphenation.doNotHyphenateCaps));
|
||||
}
|
||||
|
||||
if (options.footnoteProperties !== undefined) {
|
||||
this.root.push(new FootnoteProperties(options.footnoteProperties));
|
||||
}
|
||||
|
||||
this.root.push(
|
||||
new Compatibility({
|
||||
...(options.compatibility ?? {}),
|
||||
|
16
src/file/shared/footnote-properties.ts
Normal file
16
src/file/shared/footnote-properties.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export const FootnoteRestartLocation = {
|
||||
CONTINUOUS: "continuous",
|
||||
EACH_SECTION: "eachSect",
|
||||
EACH_PAGE: "eachPage",
|
||||
} as const;
|
||||
|
||||
export type FootnoteRestartLocationType = (typeof FootnoteRestartLocation)[keyof typeof FootnoteRestartLocation]
|
||||
|
||||
export const FootnotePositioningLocation = {
|
||||
PAGE_BOTTOM: "pageBottom",
|
||||
BENEATH_TEXT: "beneathText",
|
||||
SECTION_END: "sectEnd",
|
||||
DOCUMENT_END: "docEnd",
|
||||
} as const;
|
||||
|
||||
export type FootnotePositioningLocationType = (typeof FootnotePositioningLocation)[keyof typeof FootnotePositioningLocation]
|
@ -1,3 +1,4 @@
|
||||
export * from "./alignment";
|
||||
export * from "./number-format";
|
||||
export * from "./space-type";
|
||||
export * from "./footnote-properties";
|
||||
|
Reference in New Issue
Block a user