pdfmake 0.3.0-beta.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -40
- package/LICENSE +1 -1
- package/README.md +78 -85
- package/build/pdfmake.js +60308 -68400
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/build/vfs_fonts.js +4 -4
- package/fonts/Roboto/Roboto-Italic.ttf +0 -0
- package/fonts/Roboto/Roboto-Medium.ttf +0 -0
- package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
- package/fonts/Roboto/Roboto-Regular.ttf +0 -0
- package/js/3rd-party/svg-to-pdfkit/source.js +3626 -0
- package/js/3rd-party/svg-to-pdfkit.js +7 -0
- package/js/DocMeasure.js +645 -0
- package/js/DocPreprocessor.js +253 -0
- package/js/DocumentContext.js +305 -0
- package/js/ElementWriter.js +354 -0
- package/js/LayoutBuilder.js +1105 -0
- package/js/Line.js +105 -0
- package/js/OutputDocument.js +64 -0
- package/js/OutputDocumentServer.js +22 -0
- package/js/PDFDocument.js +144 -0
- package/js/PageElementWriter.js +155 -0
- package/js/PageSize.js +74 -0
- package/js/Printer.js +291 -0
- package/js/Renderer.js +383 -0
- package/js/SVGMeasure.js +69 -0
- package/js/StyleContextStack.js +168 -0
- package/js/TableProcessor.js +548 -0
- package/js/TextBreaker.js +166 -0
- package/js/TextDecorator.js +143 -0
- package/js/TextInlines.js +206 -0
- package/js/URLResolver.js +43 -0
- package/js/base.js +52 -0
- package/js/browser-extensions/OutputDocumentBrowser.js +81 -0
- package/js/browser-extensions/fonts/Roboto.js +38 -0
- package/js/browser-extensions/index.js +53 -0
- package/js/browser-extensions/pdfMake.js +3 -0
- package/js/browser-extensions/standard-fonts/Courier.js +38 -0
- package/js/browser-extensions/standard-fonts/Helvetica.js +38 -0
- package/js/browser-extensions/standard-fonts/Symbol.js +23 -0
- package/js/browser-extensions/standard-fonts/Times.js +38 -0
- package/js/browser-extensions/standard-fonts/ZapfDingbats.js +23 -0
- package/js/browser-extensions/virtual-fs-cjs.js +3 -0
- package/js/columnCalculator.js +148 -0
- package/js/helpers/node.js +98 -0
- package/js/helpers/tools.js +46 -0
- package/js/helpers/variableType.js +59 -0
- package/js/index.js +15 -0
- package/js/qrEnc.js +721 -0
- package/js/standardPageSizes.js +56 -0
- package/js/tableLayouts.js +98 -0
- package/js/virtual-fs.js +60 -0
- package/package.json +25 -24
- package/src/DocMeasure.js +28 -7
- package/src/DocPreprocessor.js +25 -6
- package/src/DocumentContext.js +62 -33
- package/src/ElementWriter.js +30 -7
- package/src/LayoutBuilder.js +557 -120
- package/src/OutputDocument.js +23 -37
- package/src/OutputDocumentServer.js +6 -11
- package/src/PDFDocument.js +1 -1
- package/src/PageElementWriter.js +21 -2
- package/src/Printer.js +134 -131
- package/src/Renderer.js +13 -15
- package/src/SVGMeasure.js +2 -2
- package/src/StyleContextStack.js +7 -44
- package/src/TableProcessor.js +62 -22
- package/src/TextBreaker.js +24 -5
- package/src/TextInlines.js +1 -1
- package/src/URLResolver.js +24 -58
- package/src/base.js +1 -1
- package/src/browser-extensions/OutputDocumentBrowser.js +33 -71
- package/src/browser-extensions/index.js +3 -3
- package/src/browser-extensions/pdfMake.js +0 -14
- package/src/browser-extensions/standard-fonts/Courier.js +4 -4
- package/src/browser-extensions/standard-fonts/Helvetica.js +4 -4
- package/src/browser-extensions/standard-fonts/Symbol.js +1 -1
- package/src/browser-extensions/standard-fonts/Times.js +4 -4
- package/src/browser-extensions/standard-fonts/ZapfDingbats.js +1 -1
- package/src/columnCalculator.js +24 -3
- package/src/helpers/tools.js +5 -0
- package/src/helpers/variableType.js +11 -0
- package/src/index.js +1 -1
- package/standard-fonts/Helvetica.js +0 -1
- package/src/browser-extensions/URLBrowserResolver.js +0 -84
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _default = exports.default = {
|
|
6
|
+
'4A0': [4767.87, 6740.79],
|
|
7
|
+
'2A0': [3370.39, 4767.87],
|
|
8
|
+
A0: [2383.94, 3370.39],
|
|
9
|
+
A1: [1683.78, 2383.94],
|
|
10
|
+
A2: [1190.55, 1683.78],
|
|
11
|
+
A3: [841.89, 1190.55],
|
|
12
|
+
A4: [595.28, 841.89],
|
|
13
|
+
A5: [419.53, 595.28],
|
|
14
|
+
A6: [297.64, 419.53],
|
|
15
|
+
A7: [209.76, 297.64],
|
|
16
|
+
A8: [147.40, 209.76],
|
|
17
|
+
A9: [104.88, 147.40],
|
|
18
|
+
A10: [73.70, 104.88],
|
|
19
|
+
B0: [2834.65, 4008.19],
|
|
20
|
+
B1: [2004.09, 2834.65],
|
|
21
|
+
B2: [1417.32, 2004.09],
|
|
22
|
+
B3: [1000.63, 1417.32],
|
|
23
|
+
B4: [708.66, 1000.63],
|
|
24
|
+
B5: [498.90, 708.66],
|
|
25
|
+
B6: [354.33, 498.90],
|
|
26
|
+
B7: [249.45, 354.33],
|
|
27
|
+
B8: [175.75, 249.45],
|
|
28
|
+
B9: [124.72, 175.75],
|
|
29
|
+
B10: [87.87, 124.72],
|
|
30
|
+
C0: [2599.37, 3676.54],
|
|
31
|
+
C1: [1836.85, 2599.37],
|
|
32
|
+
C2: [1298.27, 1836.85],
|
|
33
|
+
C3: [918.43, 1298.27],
|
|
34
|
+
C4: [649.13, 918.43],
|
|
35
|
+
C5: [459.21, 649.13],
|
|
36
|
+
C6: [323.15, 459.21],
|
|
37
|
+
C7: [229.61, 323.15],
|
|
38
|
+
C8: [161.57, 229.61],
|
|
39
|
+
C9: [113.39, 161.57],
|
|
40
|
+
C10: [79.37, 113.39],
|
|
41
|
+
RA0: [2437.80, 3458.27],
|
|
42
|
+
RA1: [1729.13, 2437.80],
|
|
43
|
+
RA2: [1218.90, 1729.13],
|
|
44
|
+
RA3: [864.57, 1218.90],
|
|
45
|
+
RA4: [609.45, 864.57],
|
|
46
|
+
SRA0: [2551.18, 3628.35],
|
|
47
|
+
SRA1: [1814.17, 2551.18],
|
|
48
|
+
SRA2: [1275.59, 1814.17],
|
|
49
|
+
SRA3: [907.09, 1275.59],
|
|
50
|
+
SRA4: [637.80, 907.09],
|
|
51
|
+
EXECUTIVE: [521.86, 756.00],
|
|
52
|
+
FOLIO: [612.00, 936.00],
|
|
53
|
+
LEGAL: [612.00, 1008.00],
|
|
54
|
+
LETTER: [612.00, 792.00],
|
|
55
|
+
TABLOID: [792.00, 1224.00]
|
|
56
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.tableLayouts = exports.defaultTableLayout = void 0;
|
|
5
|
+
/*eslint no-unused-vars: ["error", {"args": "none"}]*/
|
|
6
|
+
|
|
7
|
+
const tableLayouts = exports.tableLayouts = {
|
|
8
|
+
noBorders: {
|
|
9
|
+
hLineWidth(i) {
|
|
10
|
+
return 0;
|
|
11
|
+
},
|
|
12
|
+
vLineWidth(i) {
|
|
13
|
+
return 0;
|
|
14
|
+
},
|
|
15
|
+
paddingLeft(i) {
|
|
16
|
+
return i && 4 || 0;
|
|
17
|
+
},
|
|
18
|
+
paddingRight(i, node) {
|
|
19
|
+
return i < node.table.widths.length - 1 ? 4 : 0;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
headerLineOnly: {
|
|
23
|
+
hLineWidth(i, node) {
|
|
24
|
+
if (i === 0 || i === node.table.body.length) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
return i === node.table.headerRows ? 2 : 0;
|
|
28
|
+
},
|
|
29
|
+
vLineWidth(i) {
|
|
30
|
+
return 0;
|
|
31
|
+
},
|
|
32
|
+
paddingLeft(i) {
|
|
33
|
+
return i === 0 ? 0 : 8;
|
|
34
|
+
},
|
|
35
|
+
paddingRight(i, node) {
|
|
36
|
+
return i === node.table.widths.length - 1 ? 0 : 8;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
lightHorizontalLines: {
|
|
40
|
+
hLineWidth(i, node) {
|
|
41
|
+
if (i === 0 || i === node.table.body.length) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
return i === node.table.headerRows ? 2 : 1;
|
|
45
|
+
},
|
|
46
|
+
vLineWidth(i) {
|
|
47
|
+
return 0;
|
|
48
|
+
},
|
|
49
|
+
hLineColor(i) {
|
|
50
|
+
return i === 1 ? 'black' : '#aaa';
|
|
51
|
+
},
|
|
52
|
+
paddingLeft(i) {
|
|
53
|
+
return i === 0 ? 0 : 8;
|
|
54
|
+
},
|
|
55
|
+
paddingRight(i, node) {
|
|
56
|
+
return i === node.table.widths.length - 1 ? 0 : 8;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const defaultTableLayout = exports.defaultTableLayout = {
|
|
61
|
+
hLineWidth(i, node) {
|
|
62
|
+
return 1;
|
|
63
|
+
},
|
|
64
|
+
vLineWidth(i, node) {
|
|
65
|
+
return 1;
|
|
66
|
+
},
|
|
67
|
+
hLineColor(i, node) {
|
|
68
|
+
return 'black';
|
|
69
|
+
},
|
|
70
|
+
vLineColor(i, node) {
|
|
71
|
+
return 'black';
|
|
72
|
+
},
|
|
73
|
+
hLineStyle(i, node) {
|
|
74
|
+
return null;
|
|
75
|
+
},
|
|
76
|
+
vLineStyle(i, node) {
|
|
77
|
+
return null;
|
|
78
|
+
},
|
|
79
|
+
paddingLeft(i, node) {
|
|
80
|
+
return 4;
|
|
81
|
+
},
|
|
82
|
+
paddingRight(i, node) {
|
|
83
|
+
return 4;
|
|
84
|
+
},
|
|
85
|
+
paddingTop(i, node) {
|
|
86
|
+
return 2;
|
|
87
|
+
},
|
|
88
|
+
paddingBottom(i, node) {
|
|
89
|
+
return 2;
|
|
90
|
+
},
|
|
91
|
+
fillColor(i, node) {
|
|
92
|
+
return null;
|
|
93
|
+
},
|
|
94
|
+
fillOpacity(i, node) {
|
|
95
|
+
return 1;
|
|
96
|
+
},
|
|
97
|
+
defaultBorder: true
|
|
98
|
+
};
|
package/js/virtual-fs.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
const normalizeFilename = filename => {
|
|
6
|
+
if (filename.indexOf(__dirname) === 0) {
|
|
7
|
+
filename = filename.substring(__dirname.length);
|
|
8
|
+
}
|
|
9
|
+
if (filename.indexOf('/') === 0) {
|
|
10
|
+
filename = filename.substring(1);
|
|
11
|
+
}
|
|
12
|
+
return filename;
|
|
13
|
+
};
|
|
14
|
+
class VirtualFileSystem {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.storage = {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} filename
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
existsSync(filename) {
|
|
24
|
+
const normalizedFilename = normalizeFilename(filename);
|
|
25
|
+
return typeof this.storage[normalizedFilename] !== 'undefined';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {string} filename
|
|
30
|
+
* @param {?string|?object} options
|
|
31
|
+
* @returns {string|Buffer}
|
|
32
|
+
*/
|
|
33
|
+
readFileSync(filename, options) {
|
|
34
|
+
const normalizedFilename = normalizeFilename(filename);
|
|
35
|
+
const encoding = typeof options === 'object' ? options.encoding : options;
|
|
36
|
+
if (!this.existsSync(normalizedFilename)) {
|
|
37
|
+
throw new Error(`File '${normalizedFilename}' not found in virtual file system`);
|
|
38
|
+
}
|
|
39
|
+
const buffer = this.storage[normalizedFilename];
|
|
40
|
+
if (encoding) {
|
|
41
|
+
return buffer.toString(encoding);
|
|
42
|
+
}
|
|
43
|
+
return buffer;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} filename
|
|
48
|
+
* @param {string|Buffer} content
|
|
49
|
+
* @param {?string|?object} options
|
|
50
|
+
*/
|
|
51
|
+
writeFileSync(filename, content, options) {
|
|
52
|
+
const normalizedFilename = normalizeFilename(filename);
|
|
53
|
+
const encoding = typeof options === 'object' ? options.encoding : options;
|
|
54
|
+
if (!content && !options) {
|
|
55
|
+
throw new Error('No content');
|
|
56
|
+
}
|
|
57
|
+
this.storage[normalizedFilename] = encoding || typeof content === 'string' ? new Buffer(content, encoding) : content;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
var _default = exports.default = new VirtualFileSystem();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdfmake",
|
|
3
|
-
"version": "0.3.0
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Client/server side PDF printing in pure JavaScript",
|
|
5
5
|
"main": "js/index.js",
|
|
6
6
|
"esnext": "src/index.js",
|
|
@@ -9,44 +9,45 @@
|
|
|
9
9
|
"test": "tests"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"xmldoc": "^1.3.0"
|
|
12
|
+
"linebreak": "^1.1.0",
|
|
13
|
+
"pdfkit": "^0.17.2",
|
|
14
|
+
"xmldoc": "^2.0.3"
|
|
16
15
|
},
|
|
17
16
|
"devDependencies": {
|
|
18
|
-
"@babel/cli": "^7.
|
|
19
|
-
"@babel/core": "^7.
|
|
20
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
21
|
-
"@babel/preset-env": "^7.
|
|
17
|
+
"@babel/cli": "^7.28.3",
|
|
18
|
+
"@babel/core": "^7.28.5",
|
|
19
|
+
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
|
20
|
+
"@babel/preset-env": "^7.28.5",
|
|
21
|
+
"@eslint/js": "^9.39.2",
|
|
22
22
|
"assert": "^2.1.0",
|
|
23
|
-
"babel-loader": "^
|
|
23
|
+
"babel-loader": "^10.0.0",
|
|
24
24
|
"brfs": "^2.0.2",
|
|
25
25
|
"browserify-zlib": "^0.2.0",
|
|
26
|
-
"buffer": "6.0.3",
|
|
27
|
-
"core-js": "3.
|
|
28
|
-
"eslint": "^
|
|
29
|
-
"eslint-plugin-jsdoc": "^
|
|
30
|
-
"expose-loader": "^
|
|
26
|
+
"buffer": "^6.0.3",
|
|
27
|
+
"core-js": "^3.47.0",
|
|
28
|
+
"eslint": "^9.39.2",
|
|
29
|
+
"eslint-plugin-jsdoc": "^61.5.0",
|
|
30
|
+
"expose-loader": "^5.0.1",
|
|
31
31
|
"file-saver": "^2.0.5",
|
|
32
|
-
"
|
|
32
|
+
"globals": "^16.5.0",
|
|
33
|
+
"mocha": "^11.7.5",
|
|
33
34
|
"npm-run-all": "^4.1.5",
|
|
34
35
|
"process": "^0.11.10",
|
|
35
|
-
"rewire": "^
|
|
36
|
-
"shx": "^0.
|
|
37
|
-
"sinon": "^
|
|
38
|
-
"source-map-loader": "^
|
|
36
|
+
"rewire": "^9.0.1",
|
|
37
|
+
"shx": "^0.4.0",
|
|
38
|
+
"sinon": "^21.0.1",
|
|
39
|
+
"source-map-loader": "^5.0.0",
|
|
39
40
|
"stream-browserify": "^3.0.0",
|
|
40
41
|
"string-replace-webpack-plugin": "^0.1.3",
|
|
41
42
|
"svg-to-pdfkit": "^0.1.8",
|
|
42
|
-
"terser-webpack-plugin": "^5.3.
|
|
43
|
+
"terser-webpack-plugin": "^5.3.16",
|
|
43
44
|
"transform-loader": "^0.2.4",
|
|
44
45
|
"util": "^0.12.5",
|
|
45
|
-
"webpack": "^5.
|
|
46
|
-
"webpack-cli": "^
|
|
46
|
+
"webpack": "^5.104.1",
|
|
47
|
+
"webpack-cli": "^6.0.1"
|
|
47
48
|
},
|
|
48
49
|
"engines": {
|
|
49
|
-
"node": ">=
|
|
50
|
+
"node": ">=20"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"test": "run-s build mocha lint",
|
package/src/DocMeasure.js
CHANGED
|
@@ -34,12 +34,18 @@ class DocMeasure {
|
|
|
34
34
|
return this.measureNode(docStructure);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
measureBlock(node) {
|
|
38
|
+
return this.measureNode(node);
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
measureNode(node) {
|
|
38
42
|
return this.styleStack.auto(node, () => {
|
|
39
43
|
// TODO: refactor + rethink whether this is the proper way to handle margins
|
|
40
44
|
node._margin = getNodeMargin(node, this.styleStack);
|
|
41
45
|
|
|
42
|
-
if (node.
|
|
46
|
+
if (node.section) {
|
|
47
|
+
return extendMargins(this.measureSection(node));
|
|
48
|
+
} else if (node.columns) {
|
|
43
49
|
return extendMargins(this.measureColumns(node));
|
|
44
50
|
} else if (node.stack) {
|
|
45
51
|
return extendMargins(this.measureVerticalContainer(node));
|
|
@@ -128,8 +134,14 @@ class DocMeasure {
|
|
|
128
134
|
this.convertIfBase64Image(node);
|
|
129
135
|
|
|
130
136
|
let image = this.pdfDocument.provideImage(node.image);
|
|
137
|
+
|
|
131
138
|
let imageSize = { width: image.width, height: image.height };
|
|
132
139
|
|
|
140
|
+
// If EXIF orientation calls for it, swap width and height
|
|
141
|
+
if (image.orientation > 4) {
|
|
142
|
+
imageSize = { width: image.height, height: image.width };
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
this.measureImageWithDimensions(node, imageSize);
|
|
134
146
|
|
|
135
147
|
return node;
|
|
@@ -433,16 +445,17 @@ class DocMeasure {
|
|
|
433
445
|
if (item.listMarker._inlines) {
|
|
434
446
|
node._gapSize.width = Math.max(node._gapSize.width, item.listMarker._inlines[0].width);
|
|
435
447
|
}
|
|
436
|
-
|
|
448
|
+
|
|
449
|
+
if (node.reversed) {
|
|
450
|
+
counter--;
|
|
451
|
+
} else {
|
|
452
|
+
counter++;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
437
455
|
|
|
438
456
|
node._minWidth = Math.max(node._minWidth, items[i]._minWidth);
|
|
439
457
|
node._maxWidth = Math.max(node._maxWidth, items[i]._maxWidth);
|
|
440
458
|
|
|
441
|
-
if (node.reversed) {
|
|
442
|
-
counter--;
|
|
443
|
-
} else {
|
|
444
|
-
counter++;
|
|
445
|
-
}
|
|
446
459
|
}
|
|
447
460
|
|
|
448
461
|
node._minWidth += node._gapSize.width;
|
|
@@ -458,6 +471,14 @@ class DocMeasure {
|
|
|
458
471
|
return node;
|
|
459
472
|
}
|
|
460
473
|
|
|
474
|
+
measureSection(node) {
|
|
475
|
+
// TODO: properties
|
|
476
|
+
|
|
477
|
+
node.section = this.measureNode(node.section);
|
|
478
|
+
|
|
479
|
+
return node;
|
|
480
|
+
}
|
|
481
|
+
|
|
461
482
|
measureColumns(node) {
|
|
462
483
|
let columns = node.columns;
|
|
463
484
|
node._gap = this.styleStack.getProperty('columnGap') || 0;
|
package/src/DocPreprocessor.js
CHANGED
|
@@ -20,10 +20,17 @@ class DocPreprocessor {
|
|
|
20
20
|
this.parentNode = null;
|
|
21
21
|
this.tocs = [];
|
|
22
22
|
this.nodeReferences = [];
|
|
23
|
-
return this.preprocessNode(docStructure);
|
|
23
|
+
return this.preprocessNode(docStructure, true);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
preprocessBlock(node) {
|
|
27
|
+
this.parentNode = null;
|
|
28
|
+
this.tocs = [];
|
|
29
|
+
this.nodeReferences = [];
|
|
30
|
+
return this.preprocessNode(node);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
preprocessNode(node, isSectionAllowed = false) {
|
|
27
34
|
// expand shortcuts and casting values
|
|
28
35
|
if (Array.isArray(node)) {
|
|
29
36
|
node = { stack: node };
|
|
@@ -33,10 +40,16 @@ class DocPreprocessor {
|
|
|
33
40
|
node.text = convertValueToString(node.text);
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
if (node.
|
|
43
|
+
if (node.section) {
|
|
44
|
+
if (!isSectionAllowed) {
|
|
45
|
+
throw new Error(`Incorrect document structure, section node is only allowed at the root level of document structure: ${stringifyNode(node)}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return this.preprocessSection(node);
|
|
49
|
+
} else if (node.columns) {
|
|
37
50
|
return this.preprocessColumns(node);
|
|
38
51
|
} else if (node.stack) {
|
|
39
|
-
return this.preprocessVerticalContainer(node);
|
|
52
|
+
return this.preprocessVerticalContainer(node, isSectionAllowed);
|
|
40
53
|
} else if (node.ul) {
|
|
41
54
|
return this.preprocessList(node);
|
|
42
55
|
} else if (node.ol) {
|
|
@@ -64,6 +77,12 @@ class DocPreprocessor {
|
|
|
64
77
|
}
|
|
65
78
|
}
|
|
66
79
|
|
|
80
|
+
preprocessSection(node) {
|
|
81
|
+
node.section = this.preprocessNode(node.section);
|
|
82
|
+
|
|
83
|
+
return node;
|
|
84
|
+
}
|
|
85
|
+
|
|
67
86
|
preprocessColumns(node) {
|
|
68
87
|
let columns = node.columns;
|
|
69
88
|
|
|
@@ -74,11 +93,11 @@ class DocPreprocessor {
|
|
|
74
93
|
return node;
|
|
75
94
|
}
|
|
76
95
|
|
|
77
|
-
preprocessVerticalContainer(node) {
|
|
96
|
+
preprocessVerticalContainer(node, isSectionAllowed) {
|
|
78
97
|
let items = node.stack;
|
|
79
98
|
|
|
80
99
|
for (let i = 0, l = items.length; i < l; i++) {
|
|
81
|
-
items[i] = this.preprocessNode(items[i]);
|
|
100
|
+
items[i] = this.preprocessNode(items[i], isSectionAllowed);
|
|
82
101
|
}
|
|
83
102
|
|
|
84
103
|
return node;
|
package/src/DocumentContext.js
CHANGED
|
@@ -6,31 +6,27 @@ import { EventEmitter } from 'events';
|
|
|
6
6
|
* It facilitates column divisions and vertical sync
|
|
7
7
|
*/
|
|
8
8
|
class DocumentContext extends EventEmitter {
|
|
9
|
-
constructor(
|
|
9
|
+
constructor() {
|
|
10
10
|
super();
|
|
11
11
|
this.pages = [];
|
|
12
|
-
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
this.availableWidth = pageSize.width - pageMargins.left - pageMargins.right;
|
|
17
|
-
this.availableHeight = 0;
|
|
12
|
+
this.pageMargins = undefined;
|
|
13
|
+
this.x = undefined;
|
|
14
|
+
this.availableWidth = undefined;
|
|
15
|
+
this.availableHeight = undefined;
|
|
18
16
|
this.page = -1;
|
|
19
17
|
|
|
20
18
|
this.snapshots = [];
|
|
21
|
-
this.endingCell = null;
|
|
22
19
|
this.backgroundLength = [];
|
|
23
|
-
|
|
24
|
-
this.addPage(pageSize);
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
beginColumnGroup() {
|
|
22
|
+
beginColumnGroup(marginXTopParent, bottomByPage = {}) {
|
|
28
23
|
this.snapshots.push({
|
|
29
24
|
x: this.x,
|
|
30
25
|
y: this.y,
|
|
31
26
|
availableHeight: this.availableHeight,
|
|
32
27
|
availableWidth: this.availableWidth,
|
|
33
28
|
page: this.page,
|
|
29
|
+
bottomByPage: bottomByPage ? bottomByPage : {},
|
|
34
30
|
bottomMost: {
|
|
35
31
|
x: this.x,
|
|
36
32
|
y: this.y,
|
|
@@ -38,19 +34,34 @@ class DocumentContext extends EventEmitter {
|
|
|
38
34
|
availableWidth: this.availableWidth,
|
|
39
35
|
page: this.page
|
|
40
36
|
},
|
|
41
|
-
endingCell: this.endingCell,
|
|
42
37
|
lastColumnWidth: this.lastColumnWidth
|
|
43
38
|
});
|
|
44
39
|
|
|
45
40
|
this.lastColumnWidth = 0;
|
|
41
|
+
if (marginXTopParent) {
|
|
42
|
+
this.marginXTopParent = marginXTopParent;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
updateBottomByPage() {
|
|
47
|
+
const lastSnapshot = this.snapshots[this.snapshots.length - 1];
|
|
48
|
+
const lastPage = this.page;
|
|
49
|
+
let previousBottom = -Number.MIN_VALUE;
|
|
50
|
+
if (lastSnapshot.bottomByPage[lastPage]) {
|
|
51
|
+
previousBottom = lastSnapshot.bottomByPage[lastPage];
|
|
52
|
+
}
|
|
53
|
+
lastSnapshot.bottomByPage[lastPage] = Math.max(previousBottom, this.y);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
resetMarginXTopParent() {
|
|
57
|
+
this.marginXTopParent = null;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
beginColumn(width, offset, endingCell) {
|
|
49
61
|
let saved = this.snapshots[this.snapshots.length - 1];
|
|
50
62
|
|
|
51
|
-
this.calculateBottomMost(saved);
|
|
63
|
+
this.calculateBottomMost(saved, endingCell);
|
|
52
64
|
|
|
53
|
-
this.endingCell = endingCell;
|
|
54
65
|
this.page = saved.page;
|
|
55
66
|
this.x = this.x + this.lastColumnWidth + (offset || 0);
|
|
56
67
|
this.y = saved.y;
|
|
@@ -60,19 +71,18 @@ class DocumentContext extends EventEmitter {
|
|
|
60
71
|
this.lastColumnWidth = width;
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
calculateBottomMost(destContext) {
|
|
64
|
-
if (
|
|
65
|
-
this.saveContextInEndingCell(
|
|
66
|
-
this.endingCell = null;
|
|
74
|
+
calculateBottomMost(destContext, endingCell) {
|
|
75
|
+
if (endingCell) {
|
|
76
|
+
this.saveContextInEndingCell(endingCell);
|
|
67
77
|
} else {
|
|
68
78
|
destContext.bottomMost = bottomMostContext(this, destContext.bottomMost);
|
|
69
79
|
}
|
|
70
80
|
}
|
|
71
81
|
|
|
72
|
-
markEnding(endingCell) {
|
|
82
|
+
markEnding(endingCell, originalXOffset, discountY) {
|
|
73
83
|
this.page = endingCell._columnEndingContext.page;
|
|
74
|
-
this.x = endingCell._columnEndingContext.x;
|
|
75
|
-
this.y = endingCell._columnEndingContext.y;
|
|
84
|
+
this.x = endingCell._columnEndingContext.x + originalXOffset;
|
|
85
|
+
this.y = endingCell._columnEndingContext.y - discountY;
|
|
76
86
|
this.availableWidth = endingCell._columnEndingContext.availableWidth;
|
|
77
87
|
this.availableHeight = endingCell._columnEndingContext.availableHeight;
|
|
78
88
|
this.lastColumnWidth = endingCell._columnEndingContext.lastColumnWidth;
|
|
@@ -89,12 +99,11 @@ class DocumentContext extends EventEmitter {
|
|
|
89
99
|
};
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
completeColumnGroup(height) {
|
|
102
|
+
completeColumnGroup(height, endingCell) {
|
|
93
103
|
let saved = this.snapshots.pop();
|
|
94
104
|
|
|
95
|
-
this.calculateBottomMost(saved);
|
|
105
|
+
this.calculateBottomMost(saved, endingCell);
|
|
96
106
|
|
|
97
|
-
this.endingCell = null;
|
|
98
107
|
this.x = saved.x;
|
|
99
108
|
|
|
100
109
|
let y = saved.bottomMost.y;
|
|
@@ -116,6 +125,7 @@ class DocumentContext extends EventEmitter {
|
|
|
116
125
|
this.availableHeight -= (y - saved.bottomMost.y);
|
|
117
126
|
}
|
|
118
127
|
this.lastColumnWidth = saved.lastColumnWidth;
|
|
128
|
+
return saved.bottomByPage;
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
addMargin(left, right) {
|
|
@@ -133,14 +143,19 @@ class DocumentContext extends EventEmitter {
|
|
|
133
143
|
initializePage() {
|
|
134
144
|
this.y = this.pageMargins.top;
|
|
135
145
|
this.availableHeight = this.getCurrentPage().pageSize.height - this.pageMargins.top - this.pageMargins.bottom;
|
|
136
|
-
|
|
146
|
+
const { pageCtx, isSnapshot } = this.pageSnapshot();
|
|
147
|
+
pageCtx.availableWidth = this.getCurrentPage().pageSize.width - this.pageMargins.left - this.pageMargins.right;
|
|
148
|
+
if (isSnapshot && this.marginXTopParent) {
|
|
149
|
+
pageCtx.availableWidth -= this.marginXTopParent[0];
|
|
150
|
+
pageCtx.availableWidth -= this.marginXTopParent[1];
|
|
151
|
+
}
|
|
137
152
|
}
|
|
138
153
|
|
|
139
154
|
pageSnapshot() {
|
|
140
155
|
if (this.snapshots[0]) {
|
|
141
|
-
return this.snapshots[0];
|
|
156
|
+
return { pageCtx: this.snapshots[0], isSnapshot: true };
|
|
142
157
|
} else {
|
|
143
|
-
return this;
|
|
158
|
+
return { pageCtx: this, isSnapshot: false };
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
161
|
|
|
@@ -171,7 +186,6 @@ class DocumentContext extends EventEmitter {
|
|
|
171
186
|
availableHeight: this.availableHeight,
|
|
172
187
|
availableWidth: this.availableWidth,
|
|
173
188
|
page: this.page,
|
|
174
|
-
endingCell: this.endingCell,
|
|
175
189
|
lastColumnWidth: this.lastColumnWidth
|
|
176
190
|
});
|
|
177
191
|
}
|
|
@@ -184,7 +198,6 @@ class DocumentContext extends EventEmitter {
|
|
|
184
198
|
this.availableWidth = saved.availableWidth;
|
|
185
199
|
this.availableHeight = saved.availableHeight;
|
|
186
200
|
this.page = saved.page;
|
|
187
|
-
this.endingCell = saved.endingCell;
|
|
188
201
|
this.lastColumnWidth = saved.lastColumnWidth;
|
|
189
202
|
}
|
|
190
203
|
|
|
@@ -193,13 +206,23 @@ class DocumentContext extends EventEmitter {
|
|
|
193
206
|
let prevPage = this.page;
|
|
194
207
|
let prevY = this.y;
|
|
195
208
|
|
|
209
|
+
// If we are in a column group
|
|
210
|
+
if (this.snapshots.length > 0) {
|
|
211
|
+
let lastSnapshot = this.snapshots[this.snapshots.length - 1];
|
|
212
|
+
// We have to update prevY accordingly by also taking into consideration
|
|
213
|
+
// the 'y' of cells that don't break page
|
|
214
|
+
if (lastSnapshot.bottomMost && lastSnapshot.bottomMost.y) {
|
|
215
|
+
prevY = Math.max(this.y, lastSnapshot.bottomMost.y);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
196
219
|
let createNewPage = nextPageIndex >= this.pages.length;
|
|
197
220
|
if (createNewPage) {
|
|
198
221
|
let currentAvailableWidth = this.availableWidth;
|
|
199
222
|
let currentPageOrientation = this.getCurrentPage().pageSize.orientation;
|
|
200
223
|
|
|
201
224
|
let pageSize = getPageSize(this.getCurrentPage(), pageOrientation);
|
|
202
|
-
this.addPage(pageSize);
|
|
225
|
+
this.addPage(pageSize, null, this.getCurrentPage().customProperties);
|
|
203
226
|
|
|
204
227
|
if (currentPageOrientation === pageSize.orientation) {
|
|
205
228
|
this.availableWidth = currentAvailableWidth;
|
|
@@ -217,14 +240,20 @@ class DocumentContext extends EventEmitter {
|
|
|
217
240
|
};
|
|
218
241
|
}
|
|
219
242
|
|
|
220
|
-
addPage(pageSize) {
|
|
221
|
-
|
|
243
|
+
addPage(pageSize, pageMargin = null, customProperties = {}) {
|
|
244
|
+
if (pageMargin !== null) {
|
|
245
|
+
this.pageMargins = pageMargin;
|
|
246
|
+
this.x = pageMargin.left;
|
|
247
|
+
this.availableWidth = pageSize.width - pageMargin.left - pageMargin.right;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let page = { items: [], pageSize: pageSize, pageMargins: this.pageMargins, customProperties: customProperties };
|
|
222
251
|
this.pages.push(page);
|
|
223
252
|
this.backgroundLength.push(0);
|
|
224
253
|
this.page = this.pages.length - 1;
|
|
225
254
|
this.initializePage();
|
|
226
255
|
|
|
227
|
-
this.emit('pageAdded');
|
|
256
|
+
this.emit('pageAdded', page);
|
|
228
257
|
|
|
229
258
|
return page;
|
|
230
259
|
}
|