diff --git a/src/file/core-properties/properties.ts b/src/file/core-properties/properties.ts index 9a9325090d..d672016325 100644 --- a/src/file/core-properties/properties.ts +++ b/src/file/core-properties/properties.ts @@ -4,6 +4,7 @@ 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"; @@ -44,6 +45,7 @@ export interface IPropertiesOptions { readonly defaultTabStop?: number; readonly fonts?: readonly FontOptions[]; readonly hyphenation?: IHyphenationOptions; + readonly footnoteProperties?: IFootnoteProperties; } // diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 2e9c61819b..c6be95bb76 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -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; } // @@ -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)); } diff --git a/src/file/settings/footnote-format.ts b/src/file/settings/footnote-format.ts new file mode 100644 index 0000000000..f39569e63a --- /dev/null +++ b/src/file/settings/footnote-format.ts @@ -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, + }), + ); + } +} + diff --git a/src/file/settings/footnote-positioning.ts b/src/file/settings/footnote-positioning.ts new file mode 100644 index 0000000000..28efd64de8 --- /dev/null +++ b/src/file/settings/footnote-positioning.ts @@ -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, + }), + ); + } +} + diff --git a/src/file/settings/footnote-properties.ts b/src/file/settings/footnote-properties.ts new file mode 100644 index 0000000000..1fab1a8ad5 --- /dev/null +++ b/src/file/settings/footnote-properties.ts @@ -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)); + } + } +} diff --git a/src/file/settings/footnote-restart.ts b/src/file/settings/footnote-restart.ts new file mode 100644 index 0000000000..9e0b7322f3 --- /dev/null +++ b/src/file/settings/footnote-restart.ts @@ -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, + }), + ); + } +} diff --git a/src/file/settings/settings.ts b/src/file/settings/settings.ts index e7e6e93b14..8c1217161a 100644 --- a/src/file/settings/settings.ts +++ b/src/file/settings/settings.ts @@ -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; @@ -154,6 +155,7 @@ export interface ISettingsOptions { readonly compatibility?: ICompatibilityOptions; readonly defaultTabStop?: number; readonly hyphenation?: IHyphenationOptions; + readonly footnoteProperties?: IFootnoteProperties; } export interface IHyphenationOptions { @@ -236,6 +238,10 @@ export class Settings extends XmlComponent { 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 ?? {}), diff --git a/src/file/shared/footnote-properties.ts b/src/file/shared/footnote-properties.ts new file mode 100644 index 0000000000..70ebb7ad8a --- /dev/null +++ b/src/file/shared/footnote-properties.ts @@ -0,0 +1,16 @@ +export enum FootnoteRestartLocation { + Continuous ="continuous", + EachSection = "eachSect", + EachPage = "eachPage", +} + +export type FootnoteRestartLocationType = (typeof FootnoteRestartLocation)[keyof typeof FootnoteRestartLocation] + +export enum FootnotePositioningLocation { + PageBottom = "pageBottom", + BeneathText = "beneathText", + SectionEnd = "sectEnd", + DocumentEnd = "docEnd", +} + +export type FootnotePositioningLocationType = (typeof FootnotePositioningLocation)[keyof typeof FootnotePositioningLocation] diff --git a/src/file/shared/index.ts b/src/file/shared/index.ts index 7edbd8d752..f9338a171a 100644 --- a/src/file/shared/index.ts +++ b/src/file/shared/index.ts @@ -1,3 +1,4 @@ export * from "./alignment"; export * from "./number-format"; export * from "./space-type"; +export * from "./footnote-properties";