Comparing version 2.0.0 to 2.1.0
@@ -9,3 +9,18 @@ # Changelog | ||
## [2.1.0] - 2018-09-22 | ||
### Changed | ||
- When providing less cells than a row has columns, instead of throwing, autofill the row with empty cells #101 | ||
### Fixed | ||
- Vertical table border in combinaton with colspan #100 | ||
- Fix cyclic loop when parsing PDFs with TOCs #112 | ||
- Fix to, when adding other PDFs (either as image or whole pages), add objects only once #109 | ||
- Fix parsing of escaped characters in strings #114 | ||
## [2.0.0] - 2018-06-19 | ||
Version `2.0.0` is a re-write. The implementation is expected to settle with the current approach of streaming layouting with smart content chunking, which allows for having a small memory footprint even when creating a PDF document with thousands of pages. | ||
`2.0.0` requires Node >= 7. If you get an error on `require('pdfjs')` you are probably using an older Node.js version, which can be fixed by updating Node.js or by running pdfjs through a transpiler like babel. | ||
### Changed | ||
@@ -12,0 +27,0 @@ - The outline method now accepts an outline ID (number) as a valid input for the parent parameter |
@@ -233,2 +233,6 @@ 'use strict' | ||
if (this.minHeight > 0 && !this._parent._cursor.doesFit(this.minHeight)) { | ||
await this._parent._pageBreak(1) | ||
} | ||
if (this.y !== undefined) { | ||
@@ -238,2 +242,6 @@ this._cursor.y = this.y | ||
// Note: We could call `doesFit(this.minHeight)` here again to test whether the cell fits on the | ||
// newly created page. However, instead of throwing an error, when the minHeight is greater than | ||
// the document height, the minHeight is bounded to the documents height. | ||
this._startY = this._cursor.y | ||
@@ -263,2 +271,7 @@ | ||
const height = this._startY - this._cursor.y | ||
if (height < this.opts.minHeight) { | ||
this._cursor.y -= this.opts.minHeight - height | ||
} | ||
// create final createBackground | ||
@@ -318,2 +331,4 @@ await this._createBackground(!this._firstRendered, true) | ||
this.paddingLeft += this.borderLeftWidth | ||
this.minHeight = opts.minHeight || 0 | ||
} |
@@ -29,3 +29,3 @@ 'use strict' | ||
doesFit(height) { | ||
return (this.y - height) > this.bottom | ||
return (this.y - height) >= this.bottom | ||
} | ||
@@ -32,0 +32,0 @@ |
@@ -7,3 +7,3 @@ 'use strict' | ||
const PDF = require('./object') | ||
const Readable = require('stream').Readable | ||
const Readable = require('readable-stream') | ||
const uuid = require('uuid') | ||
@@ -10,0 +10,0 @@ const util = require('./util') |
@@ -22,5 +22,2 @@ 'use strict' | ||
// delete parent property to prevent endless loops when traversing the objects recursively | ||
page.properties.del('Parent') | ||
const objects = [] | ||
@@ -27,0 +24,0 @@ Parser.addObjectsRecursive(objects, page) |
@@ -53,3 +53,13 @@ 'use strict' | ||
return new PDFReference(parseObject.bind(null, xref, lexer.outer, id)) | ||
if (!lexer.state.references) { | ||
lexer.state.references = new Map() | ||
} | ||
const key = `${id} ${generation}` | ||
if (lexer.state.references.has(key)) { | ||
return lexer.state.references.get(key) | ||
} | ||
const ref = new PDFReference(parseObject.bind(null, xref, lexer.outer, id)) | ||
lexer.state.references.set(key, ref) | ||
return ref | ||
} | ||
@@ -56,0 +66,0 @@ } |
@@ -58,8 +58,8 @@ 'use strict' | ||
while (!done && (c = lexer._nextCharCode()) >= 0) { | ||
switch (true) { | ||
case c === 0x28: // ( | ||
switch (c) { | ||
case 0x28: // ( | ||
open++ | ||
str += String.fromCharCode('(') | ||
break | ||
case c === 0x29: // ) | ||
case 0x29: // ) | ||
if (open === 0) { | ||
@@ -72,3 +72,3 @@ done = true | ||
break | ||
case c === 0x5c: // \ | ||
case 0x5c: // \ | ||
c = lexer._nextCharCode() | ||
@@ -96,5 +96,17 @@ switch (c) { | ||
break | ||
case 0x30: // 0 | ||
case 0x31: // 1 | ||
case 0x32: // 2 | ||
case 0x33: // 3 | ||
case 0x34: // 4 | ||
case 0x35: // 5 | ||
case 0x36: // 6 | ||
case 0x37: // 7 | ||
case 0x38: // 8 | ||
case 0x39: // 9 | ||
const oct = String.fromCharCode(c) + lexer.readString(2) | ||
str += String.fromCharCode(parseInt(oct, 8)) | ||
break | ||
default: | ||
const hex = lexer.readString(3) | ||
str += String.fromCharCode(parseInt(hex, 16)) | ||
lexer.shift(-1) | ||
break | ||
@@ -101,0 +113,0 @@ } |
@@ -9,2 +9,3 @@ 'use strict' | ||
this._outer = outer | ||
this.state = outer ? outer.state : {} | ||
} | ||
@@ -11,0 +12,0 @@ |
@@ -73,2 +73,6 @@ 'use strict' | ||
for (const key in value.dictionary) { | ||
if (key === '/Parent') { | ||
// ignore parent property to prevent moving above Page objects | ||
continue | ||
} | ||
Parser.addObjectsRecursive(objects, value.dictionary[key]) | ||
@@ -75,0 +79,0 @@ } |
@@ -34,4 +34,4 @@ 'use strict' | ||
// on each page the row is rendered on, the row keeps track of the maximal y (or minimum | ||
// in terms of PDF, because y 0 is on the bottom) a cell is rendered to to be able to align | ||
// the backgrounds of all cells | ||
// in terms of PDF, because y 0 is on the bottom) a cell is rendered to, to be able to align | ||
// the backgrounds of all cells to the same height | ||
this._endY = null | ||
@@ -46,6 +46,6 @@ | ||
this._borderVerticalColors = [] | ||
this._minHeight = opts.minHeight || 0 | ||
this._hasTopBorder = false | ||
this._insideBreak = false | ||
this._startRendering = null | ||
@@ -105,2 +105,6 @@ } | ||
async _start() { | ||
if (this._minHeight > 0 && !this._parent._cursor.doesFit(this._minHeight)) { | ||
await this._parent._pageBreak(1) | ||
} | ||
// save start y of the row to be able to align all cells horizontally | ||
@@ -243,3 +247,10 @@ this._y = this._cursor.y | ||
if (this._columns !== this._widths.length) { | ||
throw new Error(`Cannot end row. Row has ${this._widths.length - this._columns} columns (cells) missing`) | ||
if (this._columns > this._widths.length) { | ||
throw new Error(`Row has ${this.columns} cells but only ${this._widths.length} columns`) | ||
} | ||
// fill missing columns with empty cells | ||
for (let i = this.columns; i < this._widths.length; ++i) { | ||
this.cell() | ||
} | ||
} | ||
@@ -281,5 +292,12 @@ | ||
this._widths.splice(column + 1, opts.colspan - 1) | ||
this._borderVerticalWidths.splice(column + 1, opts.colspan - 1) | ||
if (this._borderVerticalWidths) { | ||
this._borderVerticalWidths.splice(column + 1, opts.colspan - 1) | ||
} | ||
} | ||
if (opts.minHeight > this._minHeight) { | ||
this._minHeight = opts.minHeight | ||
} | ||
// adjust cell padding to add enough space for borders | ||
@@ -345,2 +363,7 @@ if (this._borderVerticalWidths) { | ||
const height = this._startY - this._cursor.y | ||
if (height < this.opts.minHeight) { | ||
this._cursor.y -= this.opts.minHeight - height | ||
} | ||
// decrease the counter of active cells | ||
@@ -347,0 +370,0 @@ row._columns-- |
@@ -129,2 +129,3 @@ 'use strict' | ||
lineHeight: opts.lineHeight, | ||
minHeight: opts.minHeight, | ||
} | ||
@@ -131,0 +132,0 @@ |
{ | ||
"name": "pdfjs", | ||
"author": "Markus Ast <npm.m@rkusa.st>", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "A Portable Document Format (PDF) generation library targeting both the server- and client-side.", | ||
@@ -23,2 +23,3 @@ "keywords": [ | ||
"pako": "^1.0.6", | ||
"readable-stream": "^2.3.6", | ||
"unorm": "^1.4.1", | ||
@@ -25,0 +26,0 @@ "uuid": "^3.0.1" |
@@ -12,11 +12,5 @@ ![pdfjs](https://cdn.rawgit.com/rkusa/pdfjs/2.x/logo.svg) | ||
```bash | ||
npm install pdfjs@2.0.0 | ||
npm install pdfjs | ||
``` | ||
## 2.0.0 Breaking Changes | ||
Version `2.0.0` is a re-write. The implementation is expected to settle with the current approach of streaming layouting with smart content chunking, which allows for having a small memory footprint even when creating a PDF document with thousands of pages. | ||
`2.0.0` requires Node >= 7. If you get an error on `require('pdfjs')` you are probably using an older Node.js version, which can be fixed by updating Node.js or by running pdfjs through a transpiler like babel. | ||
---------------- | ||
@@ -27,7 +21,7 @@ | ||
- Text (with common formatting options) | ||
- Images (JPEGs, other **PDFs**) | ||
- Images (JPEGs, other **PDFs** ¹) | ||
- Tables (fixed layout, header row) | ||
- Header & Footer | ||
- AFM fonts && OTF font embedding (as CID fonts, i.e., support for fonts with large character sets) | ||
- Add existing PDFs (merge them or add them as page templates) | ||
- Add existing PDFs (merge them or add them as page templates) ¹ | ||
- Document outline | ||
@@ -39,2 +33,4 @@ | ||
> ¹ Adding other PDFs as images or merging them together is still being considered a beta - proper error handling is adviced | ||
### History | ||
@@ -41,0 +37,0 @@ |
@@ -155,3 +155,3 @@ declare module "pdfjs" { | ||
*/ | ||
cell(text?: string, opts?: CellOptions & TextOptions): Cell; | ||
cell(text?: string, opts?: FragmentCellOptions & TextOptions): Cell; | ||
@@ -162,3 +162,3 @@ /** | ||
*/ | ||
cell(opts: CellOptions & TextOptions): Cell; | ||
cell(opts: FragmentCellOptions & TextOptions): Cell; | ||
@@ -208,3 +208,3 @@ /** | ||
*/ | ||
cell(text?: string, opts?: RowOptions & TextOptions): Cell; | ||
cell(text?: string, opts?: TableCellOptions & TextOptions): Cell; | ||
/** | ||
@@ -214,3 +214,3 @@ * Add a cell to the row | ||
*/ | ||
cell(opts: RowOptions & TextOptions): Cell; | ||
cell(opts: TableCellOptions & TextOptions): Cell; | ||
} | ||
@@ -223,3 +223,3 @@ | ||
*/ | ||
header(opts?: RowOptions & TextOptions): Row; | ||
header(opts?: TableCellOptions & TextOptions): Row; | ||
/** | ||
@@ -229,3 +229,3 @@ * Add a table row | ||
*/ | ||
row(opts?: RowOptions & TextOptions): Row; | ||
row(opts?: TableCellOptions & TextOptions): Row; | ||
} | ||
@@ -383,3 +383,3 @@ | ||
export type CellOptions = { | ||
export type FragmentCellOptions = { | ||
/** | ||
@@ -391,2 +391,7 @@ * The cell width | ||
/** | ||
* The cell minimal height | ||
* default: 0 | ||
*/ | ||
minHeight?: number; | ||
/** | ||
* x coordinate of where to render the cell | ||
@@ -562,10 +567,10 @@ * default: undefined | ||
borderHorizontalColors?: (rowIndex: number) => number; | ||
} & FragmentOptions & RowOptions; | ||
} & FragmentOptions & TableCellOptions; | ||
type RowOptions = { | ||
type TableCellOptions = { | ||
/** | ||
* The background color the cell | ||
* default: none | ||
* The cell minimal height | ||
* default: 0 | ||
*/ | ||
backgroundColor?: number; | ||
minHeight?: number; | ||
/** | ||
@@ -576,3 +581,8 @@ * How many columns the cell should span | ||
colspan?: number; | ||
} & CellOptions; | ||
/** | ||
* The background color the cell | ||
* default: none | ||
*/ | ||
backgroundColor?: number; | ||
} & PaddingOptions; | ||
@@ -579,0 +589,0 @@ type DocumentOptions = { |
@@ -194,3 +194,3 @@ import * as pdf from "pdfjs"; | ||
var tr2 = table5.header({ font: helveticaBoldFont, borderBottomWidth: 1.5 }); | ||
var tr2 = table5.header({ font: helveticaBoldFont }); | ||
tr2.cell("#"); | ||
@@ -197,0 +197,0 @@ tr2.cell("Unit"); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1270037
78
22086
6
44
2
1
+ Addedreadable-stream@^2.3.6
+ Addedcore-util-is@1.0.3(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)