Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restart page numbering #511

Merged
merged 4 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
88 changes: 88 additions & 0 deletions demo/42-restart-page-numbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Page numbers - Start from 0 on a new section
// Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs";
import { AlignmentType, Document, Header, Packer, PageBreak, PageNumber, PageNumberSeparator, Paragraph, TextRun } from "../build";

const doc = new Document();

doc.addSection({
headers: {
default: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [
new TextRun("My Title "),
new TextRun({
children: ["Page ", PageNumber.CURRENT],
}),
],
}),
],
}),
first: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [
new TextRun("First Page Header "),
new TextRun({
children: ["Page ", PageNumber.CURRENT],
}),
],
}),
],
}),
},
children: [
new Paragraph({
children: [new TextRun("First Page"), new PageBreak()],
}),
new Paragraph("Second Page"),
],
});

doc.addSection({
properties: {
pageNumberStart: 1,
pageNumberSeparator: PageNumberSeparator.EM_DASH
},
headers: {
default: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [
new TextRun("My Title "),
new TextRun({
children: ["Page ", PageNumber.CURRENT],
}),
],
}),
],
}),
first: new Header({
children: [
new Paragraph({
alignment: AlignmentType.RIGHT,
children: [
new TextRun("First Page Header of Second section"),
new TextRun({
children: ["Page ", PageNumber.CURRENT],
}),
],
}),
],
}),
},
children: [
new Paragraph({
children: [new TextRun("Third Page"), new PageBreak()],
}),
new Paragraph("Fourth Page"),
],
});

Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});
File renamed without changes.
5 changes: 5 additions & 0 deletions src/file/document/body/body.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ describe("Body", () => {
},
{ "w:cols": { _attr: { "w:space": 708, "w:sep": false, "w:num": 1 } } },
{ "w:docGrid": { _attr: { "w:linePitch": 360 } } },
{
"w:pgNumType": {
_attr: {},
},
},
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,36 @@ export enum PageNumberFormat {
DECIMAL_FULL_WIDTH = "decimalFullWidth",
}

export enum PageNumberSeparator {
COLON = "colon",
EM_DASH = "emDash",
EN_DASH = "endash",
HYPHEN = "hyphen",
PERIOD = "period",
}

export interface IPageNumberTypeAttributes {
readonly pageNumberStart?: number;
readonly pageNumberFormatType?: PageNumberFormat;
readonly pageNumberSeparator?: PageNumberSeparator;
}

export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberTypeAttributes> {
protected readonly xmlKeys = {
pageNumberStart: "w:start",
pageNumberFormatType: "w:fmt",
pageNumberSeparator: "w:chapSep",
};
}

export class PageNumberType extends XmlComponent {
constructor(start?: number, numberFormat?: PageNumberFormat) {
constructor(start?: number, numberFormat?: PageNumberFormat, separator?: PageNumberSeparator) {
super("w:pgNumType");
this.root.push(
new PageNumberTypeAttributes({
pageNumberStart: start,
pageNumberFormatType: numberFormat,
pageNumberSeparator: separator,
}),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Formatter } from "export/formatter";
import { FooterWrapper } from "file/footer-wrapper";
import { HeaderWrapper } from "file/header-wrapper";
import { Media } from "file/media";
import { LineNumberRestartFormat } from "./line-number";

import { PageBorderOffsetFrom } from "./page-border";
import { PageNumberFormat } from "./page-number";
Expand Down Expand Up @@ -194,12 +195,12 @@ describe("SectionProperties", () => {
});
});

it("should create section properties without page number type", () => {
it("should create section properties with a page number type by default", () => {
const properties = new SectionProperties({});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const pgNumType = tree["w:sectPr"].find((item) => item["w:pgNumType"] !== undefined);
expect(pgNumType).to.equal(undefined);
expect(pgNumType).to.deep.equal({ "w:pgNumType": { _attr: {} } });
});

it("should create section properties with section type", () => {
Expand All @@ -213,5 +214,20 @@ describe("SectionProperties", () => {
"w:type": { _attr: { "w:val": "continuous" } },
});
});

it("should create section properties line number type", () => {
const properties = new SectionProperties({
lineNumberCountBy: 2,
lineNumberStart: 2,
lineNumberRestart: LineNumberRestartFormat.CONTINUOUS,
lineNumberDistance: 4,
});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
const type = tree["w:sectPr"].find((item) => item["w:lnNumType"] !== undefined);
expect(type).to.deep.equal({
"w:lnNumType": { _attr: { "w:countBy": 2, "w:distance": 4, "w:restart": "continuous", "w:start": 2 } },
});
});
});
});
15 changes: 7 additions & 8 deletions src/file/document/body/section-properties/section-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ export class SectionProperties extends XmlComponent {
public readonly rightMargin: number;
public readonly leftMargin: number;

constructor(options: SectionPropertiesOptions = { column: {} }) {
super("w:sectPr");

const {
constructor(
{
width = 11906,
height = 16838,
top = convertInchesToTwip(1),
Expand All @@ -86,6 +84,7 @@ export class SectionProperties extends XmlComponent {
footers,
pageNumberFormatType,
pageNumberStart,
pageNumberSeparator,
lineNumberCountBy,
lineNumberStart,
lineNumberRestart,
Expand All @@ -98,7 +97,9 @@ export class SectionProperties extends XmlComponent {
titlePage = false,
verticalAlign,
type,
} = options;
}: SectionPropertiesOptions = { column: {} },
) {
super("w:sectPr");

this.leftMargin = left;
this.rightMargin = right;
Expand All @@ -112,9 +113,7 @@ export class SectionProperties extends XmlComponent {
this.addHeaders(headers);
this.addFooters(footers);

if (pageNumberStart || pageNumberFormatType) {
this.root.push(new PageNumberType(pageNumberStart, pageNumberFormatType));
}
this.root.push(new PageNumberType(pageNumberStart, pageNumberFormatType, pageNumberSeparator));

if (lineNumberCountBy || lineNumberStart || lineNumberRestart || lineNumberDistance) {
this.root.push(new LineNumberType(lineNumberCountBy, lineNumberStart, lineNumberRestart, lineNumberDistance));
Expand Down
5 changes: 5 additions & 0 deletions src/file/file.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ describe("File", () => {
},
},
},
{
"w:pgNumType": {
_attr: {},
},
},
],
},
],
Expand Down