Merge pull request #511 from dolanmiu/feature/separator
Restart page numbering
This commit is contained in:
88
demo/42-restart-page-numbers.ts
Normal file
88
demo/42-restart-page-numbers.ts
Normal file
@ -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);
|
||||
});
|
@ -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: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -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,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -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";
|
||||
@ -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", () => {
|
||||
@ -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 } },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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),
|
||||
@ -86,6 +84,7 @@ export class SectionProperties extends XmlComponent {
|
||||
footers,
|
||||
pageNumberFormatType,
|
||||
pageNumberStart,
|
||||
pageNumberSeparator,
|
||||
lineNumberCountBy,
|
||||
lineNumberStart,
|
||||
lineNumberRestart,
|
||||
@ -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;
|
||||
@ -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));
|
||||
|
@ -160,6 +160,11 @@ describe("File", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"w:pgNumType": {
|
||||
_attr: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
Reference in New Issue
Block a user