node-poppler 8.0.4 → 8.0.5

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/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  const { execFile, spawn, spawnSync } = require("node:child_process");
4
- const { normalize, resolve: pathResolve } = require("node:path");
4
+ const { basename, normalize, resolve: pathResolve } = require("node:path");
5
5
  const { platform } = require("node:process");
6
6
  const { promisify } = require("node:util");
7
7
  const camelCase = require("camelcase");
@@ -9,6 +9,10 @@ const { lt } = require("semver");
9
9
 
10
10
  const execFileAsync = promisify(execFile);
11
11
 
12
+ /**
13
+ * @type {Readonly<Record<string, string>>}
14
+ * @ignore
15
+ */
12
16
  const ERROR_MSGS = {
13
17
  0: "No Error",
14
18
  1: "Error opening a PDF file",
@@ -36,6 +40,510 @@ const PDF_INFO_PATH_REG = /(.+)pdfinfo/u;
36
40
  * @typedef {Record<string, OptionDetails>} PopplerAcceptedOptions
37
41
  */
38
42
 
43
+ /**
44
+ * @typedef PdfAttachOptions
45
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
46
+ * @property {boolean} [replace] Replace embedded file with same name (if it exists).
47
+ */
48
+
49
+ /**
50
+ * @typedef PdfDetachOptions
51
+ * @property {boolean} [listEmbedded] List all of the embedded files in the PDF file.
52
+ * File names are converted to the text encoding specified by `options.outputEncoding`.
53
+ * @property {string} [outputEncoding] Sets the encoding to use for text output.
54
+ * This defaults to `UTF-8`.
55
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
56
+ * @property {string} [outputPath] Set the file name used when saving an embedded file with
57
+ * the save option enabled, or the directory if `options.saveall` is used.
58
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
59
+ * @property {boolean} [saveAllFiles] Save all of the embedded files. This uses the file
60
+ * names associated with the embedded files (as printed by `options.listEmbedded`).
61
+ * By default, the files are saved in the current directory; this can be changed
62
+ * with `options.outputPath`.
63
+ * @property {string} [saveFile] Save the specified embedded file.
64
+ * By default, this uses the file name associated with the embedded file (as printed by
65
+ * `options.listEmbedded`); the file name can be changed with `options.outputPath`.
66
+ * @property {number} [saveSpecificFile] Save the specified embedded file.
67
+ * By default, this uses the file name associated with the embedded file (as printed by
68
+ * `options.listEmbedded`); the file name can be changed with `options.outputPath`.
69
+ * @property {string} [userPassword] User password (for encrypted files).
70
+ */
71
+
72
+ /**
73
+ * @typedef PdfFontsOptions
74
+ * @property {number} [firstPageToExamine] Specifies the first page to examine.
75
+ * @property {number} [lastPageToExamine] Specifies the last page to examine.
76
+ * @property {boolean} [listSubstitutes] List the substitute fonts that poppler
77
+ * will use for non-embedded fonts.
78
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
79
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
80
+ * @property {string} [userPassword] User password (for encrypted files).
81
+ */
82
+
83
+ /**
84
+ * @typedef PdfImagesOptions
85
+ * @property {boolean} [allFiles] Write JPEG, JPEG2000, JBIG2, and CCITT images in their native format.
86
+ * CMYK files are written as TIFF files. All other images are written as PNG files.
87
+ * @property {boolean} [ccittFile] Generate CCITT images as CCITT files.
88
+ * @property {number} [firstPageToConvert] Specifies the first page to convert.
89
+ * @property {number} [lastPageToConvert] Specifies the last page to convert.
90
+ * @property {boolean} [jbig2File] Generate JBIG2 images as JBIG2 files.
91
+ * @property {boolean} [jpeg2000File] Generate JPEG2000 images at JP2 files.
92
+ * @property {boolean} [jpegFile] Generate JPEG images as JPEG files.
93
+ * @property {boolean} [list] Instead of writing the images, list the
94
+ * images along with various information for each image.
95
+ * NOTE: Do not specify the outputPrefix with this option.
96
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
97
+ * @property {boolean} [pngFile] Change the default output format to PNG.
98
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
99
+ * @property {boolean} [tiffFile] Change the default output format to TIFF.
100
+ * @property {string} [userPassword] Specify the user password for the PDF file.
101
+ */
102
+
103
+ /**
104
+ * @typedef PdfInfoOptions
105
+ * @property {number} [firstPageToConvert] First page to print.
106
+ * @property {number} [lastPageToConvert] Last page to print.
107
+ * @property {boolean} [listEncodingOptions] List the available encodings.
108
+ * @property {string} [outputEncoding] Sets the encoding to use for text output.
109
+ * This defaults to `UTF-8`.
110
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
111
+ * @property {boolean} [printAsJson] Print result as a JSON object.
112
+ * @property {boolean} [printBoundingBoxes] Prints the page box bounding boxes:
113
+ * MediaBox, CropBox, BleedBox, TrimBox, and ArtBox.
114
+ * @property {boolean} [printDocStruct] Prints the logical document structure
115
+ * of a Tagged-PDF file.
116
+ * @property {boolean} [printDocStructText] Print the textual content along with the
117
+ * document structure of a Tagged-PDF file. Note that extracting text this way might be slow
118
+ * for big PDF files.
119
+ * @property {boolean} [printIsoDates] Prints dates in ISO-8601 format (including the time zone).
120
+ * @property {boolean} [printJS] Prints all JavaScript in the PDF file.
121
+ * @property {boolean} [printMetadata] Prints document-level metadata. (This is the `Metadata`
122
+ * stream from the PDF file's Catalog object).
123
+ * @property {boolean} [printNamedDests] Print a list of all named destinations. If a page range
124
+ * is specified using the `options.firstPageToConvert` and `options.lastPageToConvert` options, only destinations
125
+ * in the page range are listed.
126
+ * @property {boolean} [printRawDates] Prints the raw (undecoded) date strings, directly from the PDF file.
127
+ * @property {boolean} [printUrls] Print all URLs in the PDF; only URLs referenced by PDF objects
128
+ * such as Link Annotations are listed, not URL strings in the text content.
129
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
130
+ * @property {string} [userPassword] User password (for encrypted files).
131
+ */
132
+
133
+ /**
134
+ * @typedef PdfSeparateOptions
135
+ * @property {number} [firstPageToExtract] Specifies the first page to extract.
136
+ * This defaults to page 1.
137
+ * @property {number} [lastPageToExtract] Specifies the last page to extract.
138
+ * This defaults to the last page of the PDF file.
139
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
140
+ */
141
+
142
+ /**
143
+ * @typedef PdfToCairoOptions
144
+ * @property {('best'|'default'|'fast'|'good'|'gray'|'none'|'subpixel')} [antialias] Set the cairo
145
+ * antialias option used for text and drawing in image files (or rasterized regions in vector output).
146
+ * @property {boolean} [cropBox] Uses the crop box rather than media box when
147
+ * generating the files (PNG/JPEG/TIFF only).
148
+ * @property {number} [cropHeight] Specifies the height of crop area in pixels
149
+ * (image output) or points (vector output).
150
+ * @property {number} [cropSize] Specifies the size of crop square in pixels
151
+ * (image output) or points (vector output).
152
+ * @property {number} [cropWidth] Specifies the width of crop area in pixels
153
+ * (image output) or points (vector output).
154
+ * @property {number} [cropXAxis] Specifies the x-coordinate of the crop area top left
155
+ * corner in pixels (image output) or points (vector output).
156
+ * @property {number} [cropYAxis] Specifies the y-coordinate of the crop area top left
157
+ * corner in pixels (image output) or points (vector output).
158
+ * @property {boolean} [duplex] Adds the %%IncludeFeature: *Duplex DuplexNoTumble DSC
159
+ * comment to the PostScript file (PS only). This tells the print manager to enable duplexing.
160
+ * @property {boolean} [epsFile] Generate an EPS file. An EPS file contains a single image,
161
+ * so if you use this option with a multi-page PDF file, you must use `options.firstPageToConvert` and
162
+ * `options.lastPageToConvert` to specify a single page.
163
+ * The page size options (originalPageSizes, paperSize, paperWidth, paperHeight) can not be used
164
+ * with this option.
165
+ * @property {boolean} [evenPagesOnly] Generates only the even numbered pages.
166
+ * @property {boolean} [fillPage] Expand PDF pages smaller than the paper to fill the
167
+ * paper (PS,PDF,SVG only). By default, these pages are not scaled.
168
+ * @property {number} [firstPageToConvert] Specifies the first page to convert.
169
+ * @property {boolean} [grayscaleFile] Generate grayscale file (PNG, JPEG, and TIFF only).
170
+ * @property {string} [iccFile] Use the specified ICC file as the output profile
171
+ * (PNG only). The profile will be embedded in the PNG file.
172
+ * @property {boolean} [jpegFile] Generate JPEG file(s).
173
+ * @property {string} [jpegOptions] When used with `options.jpegFile`, this option can
174
+ * be used to control the JPEG compression parameters. It takes a string of the form
175
+ * `"<opt>=<val>[,<opt>=<val>]"`. Currently available options are:
176
+ * - `quality` Selects the JPEG quality value. The value must be an integer between 0 and 100.
177
+ * - `progressive` Select progressive JPEG output. The possible values are "y", "n", indicating
178
+ * progressive (yes) or non-progressive (no), respectively.
179
+ * - `optimize` Sets whether to compute optimal Huffman coding tables for the JPEG output, which
180
+ * will create smaller files but make an extra pass over the data. The value must be "y" or "n",
181
+ * with "y" performing optimization, otherwise the default Huffman tables are used.
182
+ *
183
+ * Example: `"quality=95,optimize=y"`.
184
+ * @property {number} [lastPageToConvert] Specifies the last page to convert.
185
+ * @property {boolean} [monochromeFile] Generate monochrome file (PNG and TIFF only).
186
+ * @property {boolean} [noCenter] By default, PDF pages smaller than the paper
187
+ * (after any scaling) are centered on the paper. This option causes them to be aligned to
188
+ * the lower-left corner of the paper instead (PS,PDF,SVG only).
189
+ * @property {boolean} [noCrop] By default, printing output is cropped to the CropBox
190
+ * specified in the PDF file. This option disables cropping (PS, PDF, SVG only).
191
+ * @property {boolean} [noShrink] Do not scale PDF pages which are larger than the paper
192
+ * (PS,PDF,SVG only). By default, pages larger than the paper are shrunk to fit.
193
+ * @property {boolean} [oddPagesOnly] Generates only the odd numbered pages.
194
+ * @property {boolean} [originalPageSizes] Set the paper size of each page to match
195
+ * the size specified in the PDF file.
196
+ * @property {string} [ownerPassword] Specify the owner password for the PDF file.
197
+ * Providing this will bypass all security restrictions.
198
+ * @property {number} [paperHeight] Set the paper height, in points (PS, PDF, SVG only).
199
+ * @property {('A3'|'A4'|'legal'|'letter'|'match')} [paperSize] Set the paper size to one of `A3`, `A4`,
200
+ * `legal`, or `letter` (PS,PDF,SVG only). This can also be set to `match`, which will set the paper size
201
+ * of each page to match the size specified in the PDF file. If none of the paperSize,
202
+ * paperWidth, or paperHeight options are specified the default is to match the paper size.
203
+ * @property {number} [paperWidth] Set the paper width, in points (PS,PDF,SVG only).
204
+ * @property {boolean} [pdfFile] Generate PDF file.
205
+ * @property {boolean} [pngFile] Generate PNG file(s).
206
+ * @property {boolean} [printVersionInfo] Print copyright and version information.
207
+ * @property {boolean} [printDocStruct] If the input file contains structural information
208
+ * about the document's content, write this information to the output file (PDF only).
209
+ * @property {boolean} [psFile] Generate PS file.
210
+ * @property {boolean} [psLevel2] Generate Level 2 PostScript (PS only).
211
+ * @property {boolean} [psLevel3] Generate Level 3 PostScript (PS only). This enables all
212
+ * Level 2 features plus shading patterns and masked images. This is the default setting.
213
+ * @property {boolean} [quiet] Do not print any messages or errors.
214
+ * @property {number} [resolutionXAxis] Specifies the X resolution, in pixels per inch of
215
+ * image files (or rasterized regions in vector output). The default is 150 PPI.
216
+ * @property {number} [resolutionXYAxis] Specifies the X and Y resolution, in pixels per
217
+ * inch of image files (or rasterized regions in vector output). The default is 150 PPI.
218
+ * @property {number} [resolutionYAxis] Specifies the Y resolution, in pixels per inch of
219
+ * image files (or rasterized regions in vector output). The default is 150 PPI.
220
+ * @property {number} [scalePageTo] Scales the long side of each page (width for landscape
221
+ * pages, height for portrait pages) to fit in scale-to pixels. The size of the short side will
222
+ * be determined by the aspect ratio of the page (PNG/JPEG/TIFF only).
223
+ * @property {number} [scalePageToXAxis] Scales each page horizontally to fit in scale-to-x
224
+ * pixels. If scale-to-y is set to -1, the vertical size will determined by the aspect ratio of
225
+ * the page (PNG/JPEG/TIFF only).
226
+ * @property {number} [scalePageToYAxis] Scales each page vertically to fit in scale-to-y
227
+ * pixels. If scale-to-x is set to -1, the horizontal size will determined by the aspect ratio of
228
+ * the page (PNG/JPEG/TIFF only).
229
+ * @property {boolean} [singleFile] Writes only the first page and does not add digits.
230
+ * Can only be used with `options.jpegFile`, `options.pngFile`, and `options.tiffFile`.
231
+ * @property {boolean} [svgFile] Generate SVG (Scalable Vector Graphics) file.
232
+ * @property {('deflate'|'jpeg'|'lzw'|'none'|'packbits')} [tiffCompression] Set TIFF compression.
233
+ * @property {boolean} [tiffFile] Generate TIFF file(s).
234
+ * @property {boolean} [transparentPageColor] Use a transparent page color
235
+ * instead of white (PNG and TIFF only).
236
+ * @property {string} [userPassword] Specify the user password for the PDF file.
237
+ */
238
+
239
+ /**
240
+ * @typedef PdfToHtmlOptions
241
+ * @property {boolean} [complexOutput] Generate complex output.
242
+ * @property {boolean} [dataUrls] Use data URLs instead of external images in HTML.
243
+ * @property {boolean} [exchangePdfLinks] Exchange .pdf links with .html.
244
+ * @property {boolean} [extractHidden] Force hidden text extraction.
245
+ * @property {number} [firstPageToConvert] First page to print.
246
+ * @property {boolean} [fontFullName] Outputs the font name without any substitutions.
247
+ * @property {boolean} [ignoreImages] Ignore images.
248
+ * @property {('JPG'|'PNG')} [imageFormat] Image file format for Splash output (JPG or PNG).
249
+ * If complexOutput is selected, but imageFormat is not specified, PNG will be assumed.
250
+ * @property {number} [lastPageToConvert] Last page to print.
251
+ * @property {boolean} [noDrm] Override document DRM settings.
252
+ * @property {boolean} [noFrames] Generate no frames. Not supported in complex output mode.
253
+ * @property {boolean} [noMergeParagraph] Do not merge paragraphs.
254
+ * @property {boolean} [noRoundedCoordinates] Do not round coordinates
255
+ * (with XML output only).
256
+ * @property {string} [outputEncoding] Sets the encoding to use for text output.
257
+ * This defaults to `UTF-8`.
258
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
259
+ * @property {boolean} [printVersionInfo] Print copyright and version info.
260
+ * @property {boolean} [quiet] Do not print any messages or errors.
261
+ * @property {boolean} [singlePage] Generate single HTML that includes all pages.
262
+ * @property {boolean} [stdout] Use standard output.
263
+ * @property {string} [userPassword] User password (for encrypted files).
264
+ * @property {number} [wordBreakThreshold] Adjust the word break threshold percent.
265
+ * Default is 10. Word break occurs when distance between two adjacent characters is greater
266
+ * than this percent of character height.
267
+ * @property {boolean} [xmlOutput] Output for XML post-processing.
268
+ * @property {number} [zoom] Zoom the PDF document (default 1.5).
269
+ */
270
+
271
+ /**
272
+ * @typedef PdfToPpmOptions
273
+ * @property {('no'|'yes')} [antialiasFonts] Enable or disable font anti-aliasing.
274
+ * This defaults to `yes`.
275
+ * @property {('no'|'yes')} [antialiasVectors] Enable or disable vector anti-aliasing.
276
+ * This defaults to `yes`.
277
+ * @property {boolean} [cropBox] Uses the crop box rather than media box when
278
+ * generating the files (PNG/JPEG/TIFF only).
279
+ * @property {number} [cropHeight] Specifies the height of crop area in pixels
280
+ * (image output) or points (vector output).
281
+ * @property {number} [cropSize] Specifies the size of crop square in pixels
282
+ * (image output) or points (vector output).
283
+ * @property {number} [cropWidth] Specifies the width of crop area in pixels
284
+ * (image output) or points (vector output).
285
+ * @property {number} [cropXAxis] Specifies the x-coordinate of the crop area top left
286
+ * corner in pixels (image output) or points (vector output).
287
+ * @property {number} [cropYAxis] Specifies the y-coordinate of the crop area top left
288
+ * corner in pixels (image output) or points (vector output).
289
+ * @property {string} [defaultCmykProfile] If Poppler is compiled with colour management support, this option
290
+ * sets the DefaultCMYK color space to the ICC profile stored in the display profile file passed.
291
+ * @property {string} [defaultGrayProfile] If Poppler is compiled with colour management support, this option
292
+ * sets the DefaultGray color space to the ICC profile stored in the display profile file passed.
293
+ * @property {string} [defaultRgbProfile] If Poppler is compiled with colour management support, this option
294
+ * sets the DefaultRGB color space to the ICC profile stored in the display profile file passed.
295
+ * @property {string} [displayProfile] If Poppler is compiled with colour management support, this option
296
+ * sets the display profile to the ICC profile stored in the display profile file passed.
297
+ * @property {boolean} [evenPagesOnly] Generates only the even numbered pages.
298
+ * @property {number} [firstPageToConvert] Specifies the first page to convert.
299
+ * @property {('no'|'yes')} [freetype] Enable or disable FreeType (a TrueType / Type 1 font rasterizer).
300
+ * This defaults to `yes`.
301
+ * @property {boolean} [forcePageNumber] Force page number even if there is only one page.
302
+ * @property {boolean} [grayscaleFile] Generate grayscale PGM file (instead of a color PPM file).
303
+ * @property {boolean} [hideAnnotations] Hide annotations.
304
+ * @property {boolean} [jpegFile] Generate JPEG file instead a PPM file.
305
+ * @property {number} [lastPageToConvert] Specifies the last page to convert.
306
+ * @property {boolean} [monochromeFile] Generate monochrome PBM file (instead of a color PPM file).
307
+ * @property {boolean} [oddPagesOnly] Generates only the odd numbered pages.
308
+ * @property {string} [ownerPassword] Specify the owner password for the PDF file.
309
+ * Providing this will bypass all security restrictions.
310
+ * @property {boolean} [pngFile] Generate PNG file instead a PPM file.
311
+ * @property {boolean} [printProgress] Print progress info as each page is generated.
312
+ * Three space-separated fields are printed to STDERR: the number of the current page, the number
313
+ * of the last page that will be generated, and the path to the file written to.
314
+ * @property {boolean} [printVersionInfo] Print copyright and version information.
315
+ * @property {boolean} [quiet] Do not print any messages or errors.
316
+ * @property {number} [resolutionXAxis] Specifies the X resolution, in pixels per inch of
317
+ * image files (or rasterized regions in vector output). The default is 150 PPI.
318
+ * @property {number} [resolutionXYAxis] Specifies the X and Y resolution, in pixels per
319
+ * inch of image files (or rasterized regions in vector output). The default is 150 PPI.
320
+ * @property {number} [resolutionYAxis] Specifies the Y resolution, in pixels per inch of
321
+ * image files (or rasterized regions in vector output). The default is 150 PPI.
322
+ * @property {number} [scalePageTo] Scales the long side of each page (width for landscape
323
+ * pages, height for portrait pages) to fit in scale-to pixels. The size of the short side will
324
+ * be determined by the aspect ratio of the page.
325
+ * @property {number} [scalePageToXAxis] Scales each page horizontally to fit in scale-to-x
326
+ * pixels. If scale-to-y is set to -1, the vertical size will determined by the aspect ratio of
327
+ * the page.
328
+ * @property {number} [scalePageToYAxis] Scales each page vertically to fit in scale-to-y
329
+ * pixels. If scale-to-x is set to -1, the horizontal size will determined by the aspect ratio of
330
+ * the page.
331
+ * @property {string} [separator] Specify single character separator between name and page number.
332
+ * @property {boolean} [singleFile] Writes only the first page and does not add digits.
333
+ * @property {('none'|'shape'|'solid')} [thinLineMode] Specifies the thin line mode. This defaults to `none`.
334
+ * @property {('deflate'|'jpeg'|'lzw'|'none'|'packbits')} [tiffCompression] Set TIFF compression.
335
+ * @property {boolean} [tiffFile] Generate TIFF file instead a PPM file.
336
+ * @property {string} [userPassword] Specify the user password for the PDF file.
337
+ */
338
+
339
+ /**
340
+ * @typedef PdfToPsOptions
341
+ * @property {('no'|'yes')} [antialias] Enable anti-aliasing on rasterization, accepts `no` or `yes`.
342
+ * @property {boolean} [binary] Write binary data in Level 1 PostScript. By default,
343
+ * pdftops writes hex-encoded data in Level 1 PostScript. Binary data is non-standard in Level 1
344
+ * PostScript but reduces the file size and can be useful when Level 1 PostScript is required
345
+ * only for its restricted use of PostScript operators.
346
+ * @property {string} [defaultCmykProfile] If Poppler is compiled with colour management support, this option
347
+ * sets the DefaultCMYK color space to the ICC profile stored in the display profile file passed.
348
+ * @property {string} [defaultGrayProfile] If Poppler is compiled with colour management support, this option
349
+ * sets the DefaultGray color space to the ICC profile stored in the display profile file passed.
350
+ * @property {string} [defaultRgbProfile] If Poppler is compiled with colour management support, this option
351
+ * sets the DefaultRGB color space to the ICC profile stored in the display profile file passed.
352
+ * @property {boolean} [duplex] Set the Duplex pagedevice entry in the PostScript file.
353
+ * This tells duplex-capable printers to enable duplexing.
354
+ * @property {boolean} [epsFile] Generate an EPS file. An EPS file contains a single image,
355
+ * so if you use this option with a multi-page PDF file, you must use `options.firstPageToConvert` and
356
+ * `options.lastPageToConvert` to specify a single page.
357
+ * The page size options (originalPageSizes, paperSize, paperWidth, paperHeight) can not be used
358
+ * with this option.
359
+ * @property {boolean} [fillPage] Expand PDF pages smaller than the paper to fill the
360
+ * paper. By default, these pages are not scaled.
361
+ * @property {number} [firstPageToConvert] Specifies the first page to convert.
362
+ * @property {number} [form] Generate PostScript form which can be imported by software
363
+ * that understands forms.
364
+ * A form contains a single page, so if you use this option with a multi-page PDF file,
365
+ * you must use `options.firstPageToConvert` and `options.lastPageToConvert` to specify a single page.
366
+ * The `options.level1` option cannot be used with `options.form`.
367
+ * No more than one of the mode options (`options.epsFile`, `options.form`) may be given.
368
+ * @property {number} [lastPageToConvert] Specifies the last page to convert.
369
+ * @property {boolean} [level1] Generate Level 1 PostScript. The resulting PostScript
370
+ * files will be significantly larger (if they contain images), but will print on Level 1 printers.
371
+ * This also converts all images to black and white.
372
+ * @property {boolean} [level1Sep] Generate Level 1 separable PostScript.
373
+ * All colors are converted to CMYK. Images are written with separate stream data for the four components.
374
+ * @property {boolean} [level2] Generate Level 2 PostScript.
375
+ * Level 2 supports color images and image compression. This is the default setting.
376
+ * @property {boolean} [level2Sep] Generate Level 2 separable PostScript. All colors are
377
+ * converted to CMYK. The PostScript separation convention operators are used to handle custom (spot) colors.
378
+ * @property {boolean} [level3] Generate Level 3 PostScript.
379
+ * This enables all Level 2 features plus CID font embedding.
380
+ * @property {boolean} [level3Sep] Generate Level 3 separable PostScript.
381
+ * The separation handling is the same as for `options.level2Sep`.
382
+ * @property {boolean} [noCenter] By default, PDF pages smaller than the paper
383
+ * (after any scaling) are centered on the paper. This option causes them to be aligned to
384
+ * the lower-left corner of the paper instead.
385
+ * @property {boolean} [noCrop] By default, printing output is cropped to the CropBox
386
+ * specified in the PDF file. This option disables cropping.
387
+ * @property {boolean} [noEmbedCIDFonts] By default, any CID PostScript fonts which are
388
+ * embedded in the PDF file are copied into the PostScript file. This option disables that embedding.
389
+ * No attempt is made to substitute for non-embedded CID PostScript fonts.
390
+ * @property {boolean} [noEmbedCIDTrueTypeFonts] By default, any CID TrueType fonts which are
391
+ * embedded in the PDF file are copied into the PostScript file. This option disables that embedding.
392
+ * No attempt is made to substitute for non-embedded CID TrueType fonts.
393
+ * @property {boolean} [noEmbedTrueTypeFonts] By default, any TrueType fonts which are embedded
394
+ * in the PDF file are copied into the PostScript file. This option causes pdfToPs to substitute base fonts instead.
395
+ * Embedded fonts make PostScript files larger, but may be necessary for readable output.
396
+ * Also, some PostScript interpreters do not have TrueType rasterizers.
397
+ * @property {boolean} [noEmbedType1Fonts] By default, any Type 1 fonts which are embedded in the PDF file
398
+ * are copied into the PostScript file. This option causes pdfToPs to substitute base fonts instead.
399
+ * Embedded fonts make PostScript files larger, but may be necessary for readable output.
400
+ * @property {boolean} [noShrink] Do not scale PDF pages which are larger than the paper.
401
+ * By default, pages larger than the paper are shrunk to fit.
402
+ * @property {boolean} [opi] Generate OPI comments for all images and forms which have OPI information.
403
+ * @property {boolean} [optimizecolorspace] By default, bitmap images in the PDF pass through to the
404
+ * output PostScript in their original color space, which produces predictable results.
405
+ * This option converts RGB and CMYK images into Gray images if every pixel of the image has equal components.
406
+ * This can fix problems when doing color separations of PDFs that contain embedded black and
407
+ * white images encoded as RGB.
408
+ * @property {boolean} [originalPageSizes] Set the paper size of each page to match
409
+ * the size specified in the PDF file.
410
+ * @property {boolean} [overprint] Enable overprinting.
411
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
412
+ * @property {number} [paperHeight] Set the paper height, in points.
413
+ * @property {('A3'|'A4'|'legal'|'letter'|'match')} [paperSize] Set the paper size to one of `A3`, `A4`,
414
+ * `legal`, or `letter`. This can also be set to `match`, which will set the paper size
415
+ * of each page to match the size specified in the PDF file. If none of the paperSize,
416
+ * paperWidth, or paperHeight options are specified the default is to match the paper size.
417
+ * @property {number} [paperWidth] Set the paper width, in points.
418
+ * @property {boolean} [passfonts] By default, references to non-embedded 8-bit fonts
419
+ * in the PDF file are substituted with the closest `Helvetica`, `Times-Roman`, or `Courier` font.
420
+ * This option passes references to non-embedded fonts through to the PostScript file.
421
+ * @property {boolean} [preload] Preload images and forms.
422
+ * @property {boolean} [printVersionInfo] Print copyright and version information.
423
+ * @property {('CMYK8'|'MONO8'|'RGB8')} [processColorFormat] Sets the process color format as it is used
424
+ * during rasterization and transparency reduction.
425
+ *
426
+ * The default depends on the other settings: For `options.level1` the default is MONO8; for `options.level1Sep`,
427
+ * `options.level2Sep`, `options.level3Sep`, or `options.overprint` the default is CMYK8; in all other
428
+ * cases RGB8 is the default.
429
+ * If `option.processColorProfile` is set then `options.processColorFormat` is inferred from the specified ICC profile.
430
+ * @property {string} [processColorProfile] Sets the ICC profile that is assumed during
431
+ * rasterization and transparency reduction.
432
+ * @property {boolean} [quiet] Do not print any messages or errors.
433
+ * @property {('always'|'never'|'whenneeded')} [rasterize] By default, pdfToPs rasterizes pages as needed,
434
+ * for example, if they contain transparencies. To force rasterization, set `rasterize` to `always`.
435
+ * Use this to eliminate fonts.
436
+ * To prevent rasterization, set `rasterize` to `never`.
437
+ * This may produce files that display incorrectly.
438
+ * @property {number} [resolutionXYAxis] Specifies the X and Y resolution, in pixels per
439
+ * inch of image files (or rasterized regions in vector output). The default is 300 PPI.
440
+ * @property {string} [userPassword] User password (for encrypted files).
441
+ */
442
+
443
+ /**
444
+ * @typedef PdfToTextOptions
445
+ * @property {boolean} [boundingBoxXhtml] Generate an XHTML file containing bounding
446
+ * box information for each word in the file.
447
+ * @property {boolean} [boundingBoxXhtmlLayout] Generate an XHTML file containing
448
+ * bounding box information for each block, line, and word in the file.
449
+ * @property {boolean} [cropBox] Use the crop box rather than the media box with
450
+ * `options.boundingBoxXhtml` and `options.boundingBoxXhtmlLayout`.
451
+ * @property {number} [cropHeight] Specifies the height of crop area in pixels
452
+ * (image output) or points (vector output).
453
+ * @property {number} [cropWidth] Specifies the width of crop area in pixels
454
+ * (image output) or points (vector output).
455
+ * @property {number} [cropXAxis] Specifies the x-coordinate of the crop area top left
456
+ * corner in pixels (image output) or points (vector output).
457
+ * @property {number} [cropYAxis] Specifies the y-coordinate of the crop area top left
458
+ * corner in pixels (image output) or points (vector output).
459
+ * @property {('dos'|'mac'|'unix')} [eolConvention] Sets the end-of-line convention to use for
460
+ * text output: dos; mac; unix.
461
+ * @property {number} [firstPageToConvert] Specifies the first page to convert.
462
+ * @property {number} [fixedWidthLayout] Assume fixed-pitch (or tabular) text, with the
463
+ * specified character width (in points). This forces physical layout mode.
464
+ * @property {boolean} [generateHtmlMetaFile] Generate simple HTML file, including the
465
+ * meta information. This simply wraps the text in `<pre>` and `</pre>` and prepends the meta headers.
466
+ * @property {boolean} [generateTsvFile] Generate a TSV file containing the bounding box
467
+ * information for each block, line, and word in the file.
468
+ * @property {number} [lastPageToConvert] Specifies the last page to convert.
469
+ * @property {boolean} [listEncodingOptions] List the available encodings.
470
+ * @property {boolean} [maintainLayout] Maintain (as best as possible) the original physical
471
+ * layout of the text. The default is to undo physical layout (columns, hyphenation, etc.) and
472
+ * output the text in reading order.
473
+ * @property {boolean} [noDiagonalText] Discard diagonal text.
474
+ * @property {boolean} [noPageBreaks] Do not insert page breaks (form feed characters)
475
+ * between pages.
476
+ * @property {string} [outputEncoding] Sets the encoding to use for text output.
477
+ * This defaults to `UTF-8`.
478
+ * @property {string} [ownerPassword] Owner password (for encrypted files).
479
+ * @property {boolean} [printVersionInfo] Print copyright and version information.
480
+ * @property {boolean} [quiet] Do not print any messages or errors.
481
+ * @property {boolean} [rawLayout] Keep the text in content stream order. This is a
482
+ * hack which often undoes column formatting, etc. Use of raw mode is no longer recommended.
483
+ * @property {string} [userPassword] User password (for encrypted files).
484
+ */
485
+
486
+ /**
487
+ * @typedef PdfUniteOptions
488
+ * @property {boolean} [printVersionInfo] Print copyright and version information.
489
+ */
490
+
491
+ /**
492
+ * @author Frazer Smith
493
+ * @description Executes a Poppler binary with the provided arguments and file input.
494
+ * @ignore
495
+ * @param {string} binary - Path to the binary to execute.
496
+ * @param {string[]} args - Array of CLI arguments to pass to the binary.
497
+ * @param {Buffer|string} [file] - File input (Buffer or path).
498
+ * @param {object} [options] - Object containing execution options.
499
+ * @param {boolean} [options.binaryOutput] - Set binary encoding for stdout.
500
+ * @param {boolean} [options.preserveWhitespace] - If true, preserves leading and trailing whitespace in the output.
501
+ * @returns {Promise<string>} A promise that resolves with stdout, or rejects with an Error.
502
+ */
503
+ function executeBinary(binary, args, file, options = {}) {
504
+ return new Promise((resolve, reject) => {
505
+ const child = spawn(binary, args);
506
+
507
+ if (options.binaryOutput) {
508
+ child.stdout.setEncoding("binary");
509
+ }
510
+
511
+ if (Buffer.isBuffer(file)) {
512
+ child.stdin.write(file);
513
+ child.stdin.end();
514
+ }
515
+
516
+ let stdOut = "";
517
+ let stdErr = "";
518
+
519
+ child.stdout.on("data", (data) => {
520
+ stdOut += data;
521
+ });
522
+
523
+ child.stderr.on("data", (data) => {
524
+ stdErr += data;
525
+ });
526
+
527
+ child.on("close", (code) => {
528
+ /* istanbul ignore else */
529
+ if (stdOut !== "") {
530
+ resolve(options.preserveWhitespace ? stdOut : stdOut.trim());
531
+ } else if (code === 0) {
532
+ resolve(ERROR_MSGS[code]);
533
+ } else if (stdErr !== "") {
534
+ reject(new Error(stdErr.trim()));
535
+ } else {
536
+ reject(
537
+ new Error(
538
+ ERROR_MSGS[code ?? -1] ||
539
+ `${basename(binary)} ${args.join(" ")} exited with code ${code}`
540
+ )
541
+ );
542
+ }
543
+ });
544
+ });
545
+ }
546
+
39
547
  /**
40
548
  * @author Frazer Smith
41
549
  * @description Checks each option provided is valid, of the correct type, and can be used by specified
@@ -45,7 +553,7 @@ const PDF_INFO_PATH_REG = /(.+)pdfinfo/u;
45
553
  * @param {Record<string, any>} options - Object containing options to pass to binary.
46
554
  * @param {string} [version] - Version of binary.
47
555
  * @returns {string[]} Array of CLI arguments.
48
- * @throws If invalid arguments provided.
556
+ * @throws {Error} If invalid arguments provided.
49
557
  */
50
558
  function parseOptions(acceptedOptions, options, version) {
51
559
  /** @type {string[]} */
@@ -54,47 +562,47 @@ function parseOptions(acceptedOptions, options, version) {
54
562
  const invalidArgs = [];
55
563
 
56
564
  // Imperative loops are faster than functional loops, see https://romgrk.com/posts/optimizing-javascript
57
- const entries = Object.entries(options);
58
- const entriesLength = entries.length;
59
- for (let i = 0; i < entriesLength; i += 1) {
60
- // Destructuring adds overhead, so use index access
61
- const key = entries[i][0];
62
- if (Object.hasOwn(acceptedOptions, key)) {
63
- const option = entries[i][1];
64
- const acceptedOption = acceptedOptions[key];
65
-
66
- if (acceptedOption.type === typeof option) {
67
- // Skip boolean options if false
68
- if (acceptedOption.type !== "boolean" || option) {
69
- // Arg will be empty for some non-standard options
70
- if (acceptedOption.arg !== "") {
71
- args.push(acceptedOption.arg);
72
- }
565
+ const keys = Object.keys(options);
566
+ const keysLength = keys.length;
567
+ for (let i = 0; i < keysLength; i += 1) {
568
+ const key = keys[i];
569
+ if (!Object.hasOwn(acceptedOptions, key)) {
570
+ invalidArgs.push(`Invalid option provided '${key}'`);
571
+ continue;
572
+ }
73
573
 
74
- if (typeof option !== "boolean") {
75
- args.push(option);
76
- }
574
+ // @ts-ignore: keys are from options, TS cannot infer this
575
+ const option = options[key];
576
+ const acceptedOption = acceptedOptions[key];
577
+
578
+ if (acceptedOption.type === typeof option) {
579
+ // Skip boolean options if false
580
+ if (acceptedOption.type !== "boolean" || option) {
581
+ // Arg will be empty for some non-standard options
582
+ if (acceptedOption.arg !== "") {
583
+ args.push(acceptedOption.arg);
77
584
  }
78
- } else {
79
- invalidArgs.push(
80
- `Invalid value type provided for option '${key}', expected ${
81
- acceptedOption.type
82
- } but received ${typeof option}`
83
- );
84
- }
85
585
 
86
- if (
87
- acceptedOption.minVersion &&
88
- version &&
89
- // @ts-ignore: type checking is done above
90
- lt(version, acceptedOption.minVersion, { loose: true })
91
- ) {
92
- invalidArgs.push(
93
- `Invalid option provided for the current version of the binary used. '${key}' was introduced in v${acceptedOption.minVersion}, but received v${version}`
94
- );
586
+ if (typeof option !== "boolean") {
587
+ args.push(option);
588
+ }
95
589
  }
96
590
  } else {
97
- invalidArgs.push(`Invalid option provided '${key}'`);
591
+ invalidArgs.push(
592
+ `Invalid value type provided for option '${key}', expected ${
593
+ acceptedOption.type
594
+ } but received ${typeof option}`
595
+ );
596
+ }
597
+
598
+ if (
599
+ acceptedOption.minVersion &&
600
+ version &&
601
+ lt(version, acceptedOption.minVersion, { loose: true })
602
+ ) {
603
+ invalidArgs.push(
604
+ `Invalid option provided for the current version of the binary used. '${key}' was introduced in v${acceptedOption.minVersion}, but received v${version}`
605
+ );
98
606
  }
99
607
  }
100
608
  if (invalidArgs.length === 0) {
@@ -128,6 +636,7 @@ class Poppler {
128
636
  * in the PATH environment variable and use that as the path for all binaries.
129
637
  * For `win32` the binaries are bundled with the package and will be used
130
638
  * if a local installation is not found.
639
+ * @throws {Error} If the Poppler binaries cannot be found.
131
640
  */
132
641
  constructor(binPath) {
133
642
  this.#popplerPath = "";
@@ -632,9 +1141,7 @@ class Poppler {
632
1141
  * @param {string} file - Filepath of the PDF file to read.
633
1142
  * @param {string} fileToAttach - Filepath of the attachment to be embedded into the PDF file.
634
1143
  * @param {string} outputFile - Filepath of the file to output the results to.
635
- * @param {object} [options] - Object containing options to pass to binary.
636
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
637
- * @param {boolean} [options.replace] - Replace embedded file with same name (if it exists).
1144
+ * @param {PdfAttachOptions} [options] - Options to pass to pdfattach binary.
638
1145
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
639
1146
  */
640
1147
  async pdfAttach(file, fileToAttach, outputFile, options = {}) {
@@ -650,26 +1157,7 @@ class Poppler {
650
1157
  * @author Frazer Smith
651
1158
  * @description Lists or extracts embedded files (attachments) from a PDF file.
652
1159
  * @param {string} file - Filepath of the PDF file to read.
653
- * @param {object} [options] - Object containing options to pass to binary.
654
- * @param {boolean} [options.listEmbedded] - List all of the embedded files in the PDF file.
655
- * File names are converted to the text encoding specified by `options.outputEncoding`.
656
- * @param {string} [options.outputEncoding] - Sets the encoding to use for text output.
657
- * This defaults to `UTF-8`.
658
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
659
- * @param {string} [options.outputPath] - Set the file name used when saving an embedded file with
660
- * the save option enabled, or the directory if `options.saveall` is used.
661
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
662
- * @param {boolean} [options.saveAllFiles] - Save all of the embedded files. This uses the file
663
- * names associated with the embedded files (as printed by `options.listEmbedded`).
664
- * By default, the files are saved in the current directory; this can be changed
665
- * with `options.outputPath`.
666
- * @param {string} [options.saveFile] - Save the specified embedded file.
667
- * By default, this uses the file name associated with the embedded file (as printed by
668
- * `options.listEmbedded`); the file name can be changed with `options.outputPath`.
669
- * @param {number} [options.saveSpecificFile] - Save the specified embedded file.
670
- * By default, this uses the file name associated with the embedded file (as printed by
671
- * `options.listEmbedded`); the file name can be changed with `options.outputPath`.
672
- * @param {string} [options.userPassword] - User password (for encrypted files).
1160
+ * @param {PdfDetachOptions} [options] - Options to pass to pdfdetach binary.
673
1161
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
674
1162
  */
675
1163
  async pdfDetach(file, options = {}) {
@@ -685,63 +1173,16 @@ class Poppler {
685
1173
  * @author Frazer Smith
686
1174
  * @description Lists the fonts used in a PDF file along with various information for each font.
687
1175
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
688
- * @param {object} [options] - Object containing options to pass to binary.
689
- * @param {number} [options.firstPageToExamine] - Specifies the first page to examine.
690
- * @param {number} [options.lastPageToExamine] - Specifies the last page to examine.
691
- * @param {boolean} [options.listSubstitutes] - List the substitute fonts that poppler
692
- * will use for non-embedded fonts.
693
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
694
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
695
- * @param {string} [options.userPassword] - User password (for encrypted files).
1176
+ * @param {PdfFontsOptions} [options] - Options to pass to pdffonts binary.
696
1177
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
697
1178
  */
698
1179
  async pdfFonts(file, options = {}) {
699
1180
  const acceptedOptions = this.#getAcceptedOptions("pdfFonts");
700
1181
  const versionInfo = await this.#getVersion(this.#pdfFontsBin);
701
1182
  const args = parseOptions(acceptedOptions, options, versionInfo);
1183
+ args.push(Buffer.isBuffer(file) ? "-" : file);
702
1184
 
703
- return new Promise((resolve, reject) => {
704
- args.push(Buffer.isBuffer(file) ? "-" : file);
705
-
706
- const child = spawn(this.#pdfFontsBin, args);
707
-
708
- if (Buffer.isBuffer(file)) {
709
- child.stdin.write(file);
710
- child.stdin.end();
711
- }
712
-
713
- let stdOut = "";
714
- let stdErr = "";
715
-
716
- child.stdout.on("data", (data) => {
717
- stdOut += data;
718
- });
719
-
720
- child.stderr.on("data", (data) => {
721
- stdErr += data;
722
- });
723
-
724
- child.on("close", (code) => {
725
- /* istanbul ignore else */
726
- if (stdOut !== "") {
727
- resolve(stdOut.trim());
728
- } else if (code === 0) {
729
- resolve(ERROR_MSGS[code]);
730
- } else if (stdErr !== "") {
731
- reject(new Error(stdErr.trim()));
732
- } else {
733
- reject(
734
- new Error(
735
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
736
- ERROR_MSGS[code] ||
737
- `pdffonts ${args.join(
738
- " "
739
- )} exited with code ${code}`
740
- )
741
- );
742
- }
743
- });
744
- });
1185
+ return executeBinary(this.#pdfFontsBin, args, file);
745
1186
  }
746
1187
 
747
1188
  /**
@@ -749,23 +1190,7 @@ class Poppler {
749
1190
  * @description Saves images from a PDF file as PPM, PBM, PNG, TIFF, JPEG, JPEG2000, or JBIG2 files.
750
1191
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
751
1192
  * @param {string} [outputPrefix] - Filename prefix of output files.
752
- * @param {object} [options] - Object containing options to pass to binary.
753
- * @param {boolean} [options.allFiles] - Write JPEG, JPEG2000, JBIG2, and CCITT images in their native format.
754
- * CMYK files are written as TIFF files. All other images are written as PNG files.
755
- * @param {boolean} [options.ccittFile] - Generate CCITT images as CCITT files.
756
- * @param {number} [options.firstPageToConvert] - Specifies the first page to convert.
757
- * @param {number} [options.lastPageToConvert] - Specifies the last page to convert.
758
- * @param {boolean} [options.jbig2File] - Generate JBIG2 images as JBIG2 files.
759
- * @param {boolean} [options.jpeg2000File] - Generate JPEG2000 images at JP2 files.
760
- * @param {boolean} [options.jpegFile] - Generate JPEG images as JPEG files.
761
- * @param {boolean} [options.list] - Instead of writing the images, list the
762
- * images along with various information for each image.
763
- * NOTE: Do not specify the outputPrefix with this option.
764
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
765
- * @param {boolean} [options.pngFile] - Change the default output format to PNG.
766
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
767
- * @param {boolean} [options.tiffFile] - Change the default output format to TIFF.
768
- * @param {string} [options.userPassword] - Specify the user password for the PDF file.
1193
+ * @param {PdfImagesOptions} [options] - Options to pass to pdfimages binary.
769
1194
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
770
1195
  */
771
1196
  async pdfImages(file, outputPrefix, options = {}) {
@@ -773,85 +1198,20 @@ class Poppler {
773
1198
  const versionInfo = await this.#getVersion(this.#pdfImagesBin);
774
1199
  const args = parseOptions(acceptedOptions, options, versionInfo);
775
1200
 
776
- return new Promise((resolve, reject) => {
777
- args.push(Buffer.isBuffer(file) ? "-" : file);
778
-
779
- if (outputPrefix) {
780
- args.push(outputPrefix);
781
- }
1201
+ args.push(Buffer.isBuffer(file) ? "-" : file);
782
1202
 
783
- const child = spawn(this.#pdfImagesBin, args);
784
-
785
- if (Buffer.isBuffer(file)) {
786
- child.stdin.write(file);
787
- child.stdin.end();
788
- }
789
-
790
- let stdOut = "";
791
- let stdErr = "";
792
-
793
- child.stdout.on("data", (data) => {
794
- stdOut += data;
795
- });
796
-
797
- child.stderr.on("data", (data) => {
798
- stdErr += data;
799
- });
1203
+ if (outputPrefix) {
1204
+ args.push(outputPrefix);
1205
+ }
800
1206
 
801
- child.on("close", (code) => {
802
- /* istanbul ignore else */
803
- if (stdOut !== "") {
804
- resolve(stdOut.trim());
805
- } else if (code === 0) {
806
- resolve(ERROR_MSGS[code]);
807
- } else if (stdErr !== "") {
808
- reject(new Error(stdErr.trim()));
809
- } else {
810
- reject(
811
- new Error(
812
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
813
- ERROR_MSGS[code] ||
814
- `pdfimages ${args.join(
815
- " "
816
- )} exited with code ${code}`
817
- )
818
- );
819
- }
820
- });
821
- });
1207
+ return executeBinary(this.#pdfImagesBin, args, file);
822
1208
  }
823
1209
 
824
1210
  /**
825
1211
  * @author Frazer Smith
826
1212
  * @description Prints the contents of the `Info` dictionary from a PDF file.
827
1213
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
828
- * @param {object} [options] - Object containing options to pass to binary.
829
- * @param {number} [options.firstPageToConvert] - First page to print.
830
- * @param {number} [options.lastPageToConvert] - Last page to print.
831
- * @param {boolean} [options.listEncodingOptions] - List the available encodings.
832
- * @param {string} [options.outputEncoding] - Sets the encoding to use for text output.
833
- * This defaults to `UTF-8`.
834
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
835
- * @param {boolean} [options.printAsJson] - Print result as a JSON object.
836
- * @param {boolean} [options.printBoundingBoxes] - Prints the page box bounding boxes:
837
- * MediaBox, CropBox, BleedBox, TrimBox, and ArtBox.
838
- * @param {boolean} [options.printDocStruct] - Prints the logical document structure
839
- * of a Tagged-PDF file.
840
- * @param {boolean} [options.printDocStructText] - Print the textual content along with the
841
- * document structure of a Tagged-PDF file. Note that extracting text this way might be slow
842
- * for big PDF files.
843
- * @param {boolean} [options.printIsoDates] - Prints dates in ISO-8601 format (including the time zone).
844
- * @param {boolean} [options.printJS] - Prints all JavaScript in the PDF file.
845
- * @param {boolean} [options.printMetadata] - Prints document-level metadata. (This is the `Metadata`
846
- * stream from the PDF file's Catalog object).
847
- * @param {boolean} [options.printNamedDests] - Print a list of all named destinations. If a page range
848
- * is specified using the `options.firstPageToConvert` and `options.lastPageToConvert` options, only destinations
849
- * in the page range are listed.
850
- * @param {boolean} [options.printRawDates] - Prints the raw (undecoded) date strings, directly from the PDF file.
851
- * @param {boolean} [options.printUrls] - Print all URLs in the PDF; only URLs referenced by PDF objects
852
- * such as Link Annotations are listed, not URL strings in the text content.
853
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
854
- * @param {string} [options.userPassword] - User password (for encrypted files).
1214
+ * @param {PdfInfoOptions} [options] - Options to pass to pdfinfo binary.
855
1215
  * @returns {Promise<object|string>} A promise that resolves with a stdout string or JSON object if
856
1216
  * `options.printAsJson` is `true`, or rejects with an `Error` object.
857
1217
  */
@@ -864,14 +1224,14 @@ class Poppler {
864
1224
  /** @type {number} */
865
1225
  let fileSize;
866
1226
 
867
- return new Promise((resolve, reject) => {
868
- if (Buffer.isBuffer(file)) {
869
- args.push("-");
870
- fileSize = file.length;
871
- } else {
872
- args.push(file);
873
- }
1227
+ if (Buffer.isBuffer(file)) {
1228
+ args.push("-");
1229
+ fileSize = file.length;
1230
+ } else {
1231
+ args.push(file);
1232
+ }
874
1233
 
1234
+ return new Promise((resolve, reject) => {
875
1235
  const child = spawn(this.#pdfInfoBin, args);
876
1236
 
877
1237
  if (Buffer.isBuffer(file)) {
@@ -923,8 +1283,7 @@ class Poppler {
923
1283
  } else {
924
1284
  reject(
925
1285
  new Error(
926
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
927
- ERROR_MSGS[code] ||
1286
+ ERROR_MSGS[code ?? -1] ||
928
1287
  `pdfinfo ${args.join(
929
1288
  " "
930
1289
  )} exited with code ${code}`
@@ -944,12 +1303,7 @@ class Poppler {
944
1303
  * @param {string} outputPattern - Should contain %d (or any variant respecting printf format),
945
1304
  * since %d is replaced by the page number.
946
1305
  * As an example, `sample-%d.pdf` will produce `sample-1.pdf` for a single page document.
947
- * @param {object} [options] - Object containing options to pass to binary.
948
- * @param {number} [options.firstPageToExtract] - Specifies the first page to extract.
949
- * This defaults to page 1.
950
- * @param {number} [options.lastPageToExtract] - Specifies the last page to extract.
951
- * This defaults to the last page of the PDF file.
952
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
1306
+ * @param {PdfSeparateOptions} [options] - Options to pass to pdfseparate binary.
953
1307
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
954
1308
  */
955
1309
  async pdfSeparate(file, outputPattern, options = {}) {
@@ -973,156 +1327,20 @@ class Poppler {
973
1327
  * Encoding is set to `binary` if used with `options.singleFile` or `options.pdfFile`.
974
1328
  *
975
1329
  * If not set then the output filename will be derived from the PDF file name.
976
- * @param {object} [options] - Object containing options to pass to binary.
977
- * @param {('best'|'default'|'fast'|'good'|'gray'|'none'|'subpixel')} [options.antialias] - Set the cairo
978
- * antialias option used for text and drawing in image files (or rasterized regions in vector output).
979
- * @param {boolean} [options.cropBox] - Uses the crop box rather than media box when
980
- * generating the files (PNG/JPEG/TIFF only).
981
- * @param {number} [options.cropHeight] - Specifies the height of crop area in pixels
982
- * (image output) or points (vector output).
983
- * @param {number} [options.cropSize] - Specifies the size of crop square in pixels
984
- * (image output) or points (vector output).
985
- * @param {number} [options.cropWidth] - Specifies the width of crop area in pixels
986
- * (image output) or points (vector output).
987
- * @param {number} [options.cropXAxis] - Specifies the x-coordinate of the crop area top left
988
- * corner in pixels (image output) or points (vector output).
989
- * @param {number} [options.cropYAxis] - Specifies the y-coordinate of the crop area top left
990
- * corner in pixels (image output) or points (vector output).
991
- * @param {boolean} [options.duplex] - Adds the %%IncludeFeature: *Duplex DuplexNoTumble DSC
992
- * comment to the PostScript file (PS only). This tells the print manager to enable duplexing.
993
- * @param {boolean} [options.epsFile] - Generate an EPS file. An EPS file contains a single image,
994
- * so if you use this option with a multi-page PDF file, you must use `options.firstPageToConvert` and
995
- * `options.lastPageToConvert` to specify a single page.
996
- * The page size options (originalPageSizes, paperSize, paperWidth, paperHeight) can not be used
997
- * with this option.
998
- * @param {boolean} [options.evenPagesOnly] - Generates only the even numbered pages.
999
- * @param {boolean} [options.fillPage] - Expand PDF pages smaller than the paper to fill the
1000
- * paper (PS,PDF,SVG only). By default, these pages are not scaled.
1001
- * @param {number} [options.firstPageToConvert] - Specifies the first page to convert.
1002
- * @param {boolean} [options.grayscaleFile] - Generate grayscale file (PNG, JPEG, and TIFF only).
1003
- * @param {string} [options.iccFile] - Use the specified ICC file as the output profile
1004
- * (PNG only). The profile will be embedded in the PNG file.
1005
- * @param {boolean} [options.jpegFile] - Generate JPEG file(s).
1006
- * @param {string} [options.jpegOptions] - When used with `options.jpegFile`, this option can
1007
- * be used to control the JPEG compression parameters. It takes a string of the form
1008
- * `"<opt>=<val>[,<opt>=<val>]"`. Currently available options are:
1009
- * - `quality` Selects the JPEG quality value. The value must be an integer between 0 and 100.
1010
- * - `progressive` Select progressive JPEG output. The possible values are "y", "n", indicating
1011
- * progressive (yes) or non-progressive (no), respectively.
1012
- * - `optimize` Sets whether to compute optimal Huffman coding tables for the JPEG output, which
1013
- * will create smaller files but make an extra pass over the data. The value must be "y" or "n",
1014
- * with "y" performing optimization, otherwise the default Huffman tables are used.
1015
- *
1016
- * Example: `"quality=95,optimize=y"`.
1017
- * @param {number} [options.lastPageToConvert] - Specifies the last page to convert.
1018
- * @param {boolean} [options.monochromeFile] - Generate monochrome file (PNG and TIFF only).
1019
- * @param {boolean} [options.noCenter] - By default, PDF pages smaller than the paper
1020
- * (after any scaling) are centered on the paper. This option causes them to be aligned to
1021
- * the lower-left corner of the paper instead (PS,PDF,SVG only).
1022
- * @param {boolean} [options.noCrop] - By default, printing output is cropped to the CropBox
1023
- * specified in the PDF file. This option disables cropping (PS, PDF, SVG only).
1024
- * @param {boolean} [options.noShrink] - Do not scale PDF pages which are larger than the paper
1025
- * (PS,PDF,SVG only). By default, pages larger than the paper are shrunk to fit.
1026
- * @param {boolean} [options.oddPagesOnly] - Generates only the odd numbered pages.
1027
- * @param {boolean} [options.originalPageSizes] - Set the paper size of each page to match
1028
- * the size specified in the PDF file.
1029
- * @param {string} [options.ownerPassword] - Specify the owner password for the PDF file.
1030
- * Providing this will bypass all security restrictions.
1031
- * @param {number} [options.paperHeight] - Set the paper height, in points (PS, PDF, SVG only).
1032
- * @param {('A3'|'A4'|'legal'|'letter'|'match')} [options.paperSize] - Set the paper size to one of `A3`, `A4`,
1033
- * `legal`, or `letter` (PS,PDF,SVG only). This can also be set to `match`, which will set the paper size
1034
- * of each page to match the size specified in the PDF file. If none of the paperSize,
1035
- * paperWidth, or paperHeight options are specified the default is to match the paper size.
1036
- * @param {number} [options.paperWidth] - Set the paper width, in points (PS,PDF,SVG only).
1037
- * @param {boolean} [options.pdfFile] - Generate PDF file.
1038
- * @param {boolean} [options.pngFile] - Generate PNG file(s).
1039
- * @param {boolean} [options.printVersionInfo] - Print copyright and version information.
1040
- * @param {boolean} [options.printDocStruct] - If the input file contains structural information
1041
- * about the document's content, write this information to the output file (PDF only).
1042
- * @param {boolean} [options.psFile] - Generate PS file.
1043
- * @param {boolean} [options.psLevel2] - Generate Level 2 PostScript (PS only).
1044
- * @param {boolean} [options.psLevel3] - Generate Level 3 PostScript (PS only). This enables all
1045
- * Level 2 features plus shading patterns and masked images. This is the default setting.
1046
- * @param {boolean} [options.quiet] - Do not print any messages or errors.
1047
- * @param {number} [options.resolutionXAxis] - Specifies the X resolution, in pixels per inch of
1048
- * image files (or rasterized regions in vector output). The default is 150 PPI.
1049
- * @param {number} [options.resolutionXYAxis] - Specifies the X and Y resolution, in pixels per
1050
- * inch of image files (or rasterized regions in vector output). The default is 150 PPI.
1051
- * @param {number} [options.resolutionYAxis] - Specifies the Y resolution, in pixels per inch of
1052
- * image files (or rasterized regions in vector output). The default is 150 PPI.
1053
- * @param {number} [options.scalePageTo] - Scales the long side of each page (width for landscape
1054
- * pages, height for portrait pages) to fit in scale-to pixels. The size of the short side will
1055
- * be determined by the aspect ratio of the page (PNG/JPEG/TIFF only).
1056
- * @param {number} [options.scalePageToXAxis] - Scales each page horizontally to fit in scale-to-x
1057
- * pixels. If scale-to-y is set to -1, the vertical size will determined by the aspect ratio of
1058
- * the page (PNG/JPEG/TIFF only).
1059
- * @param {number} [options.scalePageToYAxis] - Scales each page vertically to fit in scale-to-y
1060
- * pixels. If scale-to-x is set to -1, the horizontal size will determined by the aspect ratio of
1061
- * the page (PNG/JPEG/TIFF only).
1062
- * @param {boolean} [options.singleFile] - Writes only the first page and does not add digits.
1063
- * Can only be used with `options.jpegFile`, `options.pngFile`, and `options.tiffFile`.
1064
- * @param {boolean} [options.svgFile] - Generate SVG (Scalable Vector Graphics) file.
1065
- * @param {('deflate'|'jpeg'|'lzw'|'none'|'packbits')} [options.tiffCompression] - Set TIFF compression.
1066
- * @param {boolean} [options.tiffFile] - Generate TIFF file(s).
1067
- * @param {boolean} [options.transparentPageColor] - Use a transparent page color
1068
- * instead of white (PNG and TIFF only).
1069
- * @param {string} [options.userPassword] - Specify the user password for the PDF file.
1330
+ * @param {PdfToCairoOptions} [options] - Options to pass to pdftocairo binary.
1070
1331
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1071
1332
  */
1072
1333
  async pdfToCairo(file, outputFile, options = {}) {
1073
1334
  const acceptedOptions = this.#getAcceptedOptions("pdfToCairo");
1074
1335
  const versionInfo = await this.#getVersion(this.#pdfToCairoBin);
1075
1336
  const args = parseOptions(acceptedOptions, options, versionInfo);
1337
+ args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1076
1338
 
1077
- return new Promise((resolve, reject) => {
1078
- args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1079
-
1080
- const child = spawn(this.#pdfToCairoBin, args);
1081
-
1082
- if (
1083
- outputFile === undefined &&
1084
- args.some((arg) => ["-singlefile", "-pdf"].includes(arg))
1085
- ) {
1086
- child.stdout.setEncoding("binary");
1087
- }
1088
-
1089
- if (Buffer.isBuffer(file)) {
1090
- child.stdin.write(file);
1091
- child.stdin.end();
1092
- }
1093
-
1094
- let stdOut = "";
1095
- let stdErr = "";
1096
-
1097
- child.stdout.on("data", (data) => {
1098
- stdOut += data;
1099
- });
1100
-
1101
- child.stderr.on("data", (data) => {
1102
- stdErr += data;
1103
- });
1339
+ const binaryOutput =
1340
+ outputFile === undefined &&
1341
+ args.some((arg) => ["-singlefile", "-pdf"].includes(arg));
1104
1342
 
1105
- child.on("close", (code) => {
1106
- /* istanbul ignore else */
1107
- if (stdOut !== "") {
1108
- resolve(stdOut.trim());
1109
- } else if (code === 0) {
1110
- resolve(ERROR_MSGS[code]);
1111
- } else if (stdErr !== "") {
1112
- reject(new Error(stdErr.trim()));
1113
- } else {
1114
- reject(
1115
- new Error(
1116
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
1117
- ERROR_MSGS[code] ||
1118
- `pdftocairo ${args.join(
1119
- " "
1120
- )} exited with code ${code}`
1121
- )
1122
- );
1123
- }
1124
- });
1125
- });
1343
+ return executeBinary(this.#pdfToCairoBin, args, file, { binaryOutput });
1126
1344
  }
1127
1345
 
1128
1346
  /**
@@ -1134,49 +1352,20 @@ class Poppler {
1134
1352
  * and create a new file, with `-html` appended to the end of the filename.
1135
1353
  *
1136
1354
  * Required if `file` is a Buffer.
1137
- * @param {object} [options] - Object containing options to pass to binary.
1138
- * @param {boolean} [options.complexOutput] - Generate complex output.
1139
- * @param {boolean} [options.dataUrls] - Use data URLs instead of external images in HTML.
1140
- * @param {boolean} [options.exchangePdfLinks] - Exchange .pdf links with .html.
1141
- * @param {boolean} [options.extractHidden] - Force hidden text extraction.
1142
- * @param {number} [options.firstPageToConvert] - First page to print.
1143
- * @param {boolean} [options.fontFullName] - Outputs the font name without any substitutions.
1144
- * @param {boolean} [options.ignoreImages] - Ignore images.
1145
- * @param {('JPG'|'PNG')} [options.imageFormat] - Image file format for Splash output (JPG or PNG).
1146
- * If complexOutput is selected, but imageFormat is not specified, PNG will be assumed.
1147
- * @param {number} [options.lastPageToConvert] - Last page to print.
1148
- * @param {boolean} [options.noDrm] - Override document DRM settings.
1149
- * @param {boolean} [options.noFrames] - Generate no frames. Not supported in complex output mode.
1150
- * @param {boolean} [options.noMergeParagraph] - Do not merge paragraphs.
1151
- * @param {boolean} [options.noRoundedCoordinates] - Do not round coordinates
1152
- * (with XML output only).
1153
- * @param {string} [options.outputEncoding] - Sets the encoding to use for text output.
1154
- * This defaults to `UTF-8`.
1155
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
1156
- * @param {boolean} [options.printVersionInfo] - Print copyright and version info.
1157
- * @param {boolean} [options.quiet] - Do not print any messages or errors.
1158
- * @param {boolean} [options.singlePage] - Generate single HTML that includes all pages.
1159
- * @param {boolean} [options.stdout] - Use standard output.
1160
- * @param {string} [options.userPassword] - User password (for encrypted files).
1161
- * @param {number} [options.wordBreakThreshold] - Adjust the word break threshold percent.
1162
- * Default is 10. Word break occurs when distance between two adjacent characters is greater
1163
- * than this percent of character height.
1164
- * @param {boolean} [options.xmlOutput] - Output for XML post-processing.
1165
- * @param {number} [options.zoom] - Zoom the PDF document (default 1.5).
1355
+ * @param {PdfToHtmlOptions} [options] - Options to pass to pdftohtml binary.
1166
1356
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1167
1357
  */
1168
1358
  async pdfToHtml(file, outputFile, options = {}) {
1169
1359
  const acceptedOptions = this.#getAcceptedOptions("pdfToHtml");
1170
1360
  const versionInfo = await this.#getVersion(this.#pdfToHtmlBin);
1171
1361
  const args = parseOptions(acceptedOptions, options, versionInfo);
1362
+ args.push(Buffer.isBuffer(file) ? "-" : file);
1172
1363
 
1173
- return new Promise((resolve, reject) => {
1174
- args.push(Buffer.isBuffer(file) ? "-" : file);
1175
-
1176
- if (outputFile) {
1177
- args.push(outputFile);
1178
- }
1364
+ if (outputFile) {
1365
+ args.push(outputFile);
1366
+ }
1179
1367
 
1368
+ return new Promise((resolve, reject) => {
1180
1369
  const child = spawn(this.#pdfToHtmlBin, args);
1181
1370
 
1182
1371
  if (Buffer.isBuffer(file)) {
@@ -1213,113 +1402,16 @@ class Poppler {
1213
1402
  * in Portable Bitmap (PBM) format.
1214
1403
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1215
1404
  * @param {string} outputPath - Filepath to output the results to.
1216
- * @param {object} [options] - Object containing options to pass to binary.
1217
- * @param {('no'|'yes')} [options.antialiasFonts] - Enable or disable font anti-aliasing.
1218
- * This defaults to `yes`.
1219
- * @param {('no'|'yes')} [options.antialiasVectors] - Enable or disable vector anti-aliasing.
1220
- * This defaults to `yes`.
1221
- * @param {boolean} [options.cropBox] - Uses the crop box rather than media box when
1222
- * generating the files (PNG/JPEG/TIFF only).
1223
- * @param {number} [options.cropHeight] - Specifies the height of crop area in pixels
1224
- * (image output) or points (vector output).
1225
- * @param {number} [options.cropSize] - Specifies the size of crop square in pixels
1226
- * (image output) or points (vector output).
1227
- * @param {number} [options.cropWidth] - Specifies the width of crop area in pixels
1228
- * (image output) or points (vector output).
1229
- * @param {number} [options.cropXAxis] - Specifies the x-coordinate of the crop area top left
1230
- * corner in pixels (image output) or points (vector output).
1231
- * @param {number} [options.cropYAxis] - Specifies the y-coordinate of the crop area top left
1232
- * corner in pixels (image output) or points (vector output).
1233
- * @param {string} [options.defaultCmykProfile] - If Poppler is compiled with colour management support, this option
1234
- * sets the DefaultCMYK color space to the ICC profile stored in the display profile file passed.
1235
- * @param {string} [options.defaultGrayProfile] - If Poppler is compiled with colour management support, this option
1236
- * sets the DefaultGray color space to the ICC profile stored in the display profile file passed.
1237
- * @param {string} [options.defaultRgbProfile] - If Poppler is compiled with colour management support, this option
1238
- * sets the DefaultRGB color space to the ICC profile stored in the display profile file passed.
1239
- * @param {string} [options.displayProfile] - If Poppler is compiled with colour management support, this option
1240
- * sets the display profile to the ICC profile stored in the display profile file passed.
1241
- * @param {boolean} [options.evenPagesOnly] - Generates only the even numbered pages.
1242
- * @param {number} [options.firstPageToConvert] - Specifies the first page to convert.
1243
- * @param {('no'|'yes')} [options.freetype] - Enable or disable FreeType (a TrueType / Type 1 font rasterizer).
1244
- * This defaults to `yes`.
1245
- * @param {boolean} [options.forcePageNumber] - Force page number even if there is only one page.
1246
- * @param {boolean} [options.grayscaleFile] - Generate grayscale PGM file (instead of a color PPM file).
1247
- * @param {boolean} [options.hideAnnotations] - Hide annotations.
1248
- * @param {boolean} [options.jpegFile] - Generate JPEG file instead a PPM file.
1249
- * @param {number} [options.lastPageToConvert] - Specifies the last page to convert.
1250
- * @param {boolean} [options.monochromeFile] - Generate monochrome PBM file (instead of a color PPM file).
1251
- * @param {boolean} [options.oddPagesOnly] - Generates only the odd numbered pages.
1252
- * @param {string} [options.ownerPassword] - Specify the owner password for the PDF file.
1253
- * Providing this will bypass all security restrictions.
1254
- * @param {boolean} [options.pngFile] - Generate PNG file instead a PPM file.
1255
- * @param {boolean} [options.printProgress] - Print progress info as each page is generated.
1256
- * Three space-separated fields are printed to STDERR: the number of the current page, the number
1257
- * of the last page that will be generated, and the path to the file written to.
1258
- * @param {boolean} [options.printVersionInfo] - Print copyright and version information.
1259
- * @param {boolean} [options.quiet] - Do not print any messages or errors.
1260
- * @param {number} [options.resolutionXAxis] - Specifies the X resolution, in pixels per inch of
1261
- * image files (or rasterized regions in vector output). The default is 150 PPI.
1262
- * @param {number} [options.resolutionXYAxis] - Specifies the X and Y resolution, in pixels per
1263
- * inch of image files (or rasterized regions in vector output). The default is 150 PPI.
1264
- * @param {number} [options.resolutionYAxis] - Specifies the Y resolution, in pixels per inch of
1265
- * image files (or rasterized regions in vector output). The default is 150 PPI.
1266
- * @param {number} [options.scalePageTo] - Scales the long side of each page (width for landscape
1267
- * pages, height for portrait pages) to fit in scale-to pixels. The size of the short side will
1268
- * be determined by the aspect ratio of the page.
1269
- * @param {number} [options.scalePageToXAxis] - Scales each page horizontally to fit in scale-to-x
1270
- * pixels. If scale-to-y is set to -1, the vertical size will determined by the aspect ratio of
1271
- * the page.
1272
- * @param {number} [options.scalePageToYAxis] - Scales each page vertically to fit in scale-to-y
1273
- * pixels. If scale-to-x is set to -1, the horizontal size will determined by the aspect ratio of
1274
- * the page.
1275
- * @param {string} [options.separator] - Specify single character separator between name and page number.
1276
- * @param {boolean} [options.singleFile] - Writes only the first page and does not add digits.
1277
- * @param {('none'|'shape'|'solid')} [options.thinLineMode] - Specifies the thin line mode. This defaults to `none`.
1278
- * @param {('deflate'|'jpeg'|'lzw'|'none'|'packbits')} [options.tiffCompression] - Set TIFF compression.
1279
- * @param {boolean} [options.tiffFile] - Generate TIFF file instead a PPM file.
1280
- * @param {string} [options.userPassword] - Specify the user password for the PDF file.
1405
+ * @param {PdfToPpmOptions} [options] - Options to pass to pdftoppm binary.
1281
1406
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1282
1407
  */
1283
1408
  async pdfToPpm(file, outputPath, options = {}) {
1284
1409
  const acceptedOptions = this.#getAcceptedOptions("pdfToPpm");
1285
1410
  const versionInfo = await this.#getVersion(this.#pdfToPpmBin);
1286
1411
  const args = parseOptions(acceptedOptions, options, versionInfo);
1412
+ args.push(Buffer.isBuffer(file) ? "-" : file, outputPath);
1287
1413
 
1288
- return new Promise((resolve, reject) => {
1289
- args.push(Buffer.isBuffer(file) ? "-" : file, outputPath);
1290
-
1291
- const child = spawn(this.#pdfToPpmBin, args);
1292
-
1293
- if (Buffer.isBuffer(file)) {
1294
- child.stdin.write(file);
1295
- child.stdin.end();
1296
- }
1297
-
1298
- let stdErr = "";
1299
-
1300
- child.stderr.on("data", (data) => {
1301
- stdErr += data;
1302
- });
1303
-
1304
- child.on("close", (code) => {
1305
- /* istanbul ignore else */
1306
- if (stdErr !== "") {
1307
- reject(new Error(stdErr.trim()));
1308
- } else if (code === 0) {
1309
- resolve(ERROR_MSGS[code]);
1310
- } else {
1311
- reject(
1312
- new Error(
1313
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
1314
- ERROR_MSGS[code] ||
1315
- `pdftoppm ${args.join(
1316
- " "
1317
- )} exited with code ${code}`
1318
- )
1319
- );
1320
- }
1321
- });
1322
- });
1414
+ return executeBinary(this.#pdfToPpmBin, args, file);
1323
1415
  }
1324
1416
 
1325
1417
  /**
@@ -1328,156 +1420,16 @@ class Poppler {
1328
1420
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1329
1421
  * @param {string} [outputFile] - Filepath of the file to output the results to.
1330
1422
  * If `undefined` then will write output to stdout.
1331
- * @param {object} [options] - Object containing options to pass to binary.
1332
- * @param {('no'|'yes')} [options.antialias] - Enable anti-aliasing on rasterization, accepts `no` or `yes`.
1333
- * @param {boolean} [options.binary] - Write binary data in Level 1 PostScript. By default,
1334
- * pdftops writes hex-encoded data in Level 1 PostScript. Binary data is non-standard in Level 1
1335
- * PostScript but reduces the file size and can be useful when Level 1 PostScript is required
1336
- * only for its restricted use of PostScript operators.
1337
- * @param {string} [options.defaultCmykProfile] - If Poppler is compiled with colour management support, this option
1338
- * sets the DefaultCMYK color space to the ICC profile stored in the display profile file passed.
1339
- * @param {string} [options.defaultGrayProfile] - If Poppler is compiled with colour management support, this option
1340
- * sets the DefaultGray color space to the ICC profile stored in the display profile file passed.
1341
- * @param {string} [options.defaultRgbProfile] - If Poppler is compiled with colour management support, this option
1342
- * sets the DefaultRGB color space to the ICC profile stored in the display profile file passed.
1343
- * @param {boolean} [options.duplex] - Set the Duplex pagedevice entry in the PostScript file.
1344
- * This tells duplex-capable printers to enable duplexing.
1345
- * @param {boolean} [options.epsFile] - Generate an EPS file. An EPS file contains a single image,
1346
- * so if you use this option with a multi-page PDF file, you must use `options.firstPageToConvert` and
1347
- * `options.lastPageToConvert` to specify a single page.
1348
- * The page size options (originalPageSizes, paperSize, paperWidth, paperHeight) can not be used
1349
- * with this option.
1350
- * @param {boolean} [options.fillPage] - Expand PDF pages smaller than the paper to fill the
1351
- * paper. By default, these pages are not scaled.
1352
- * @param {number} [options.firstPageToConvert] - Specifies the first page to convert.
1353
- * @param {number} [options.form] - Generate PostScript form which can be imported by software
1354
- * that understands forms.
1355
- * A form contains a single page, so if you use this option with a multi-page PDF file,
1356
- * you must use `options.firstPageToConvert` and `options.lastPageToConvert` to specify a single page.
1357
- * The `options.level1` option cannot be used with `options.form`.
1358
- * No more than one of the mode options (`options.epsFile`, `options.form`) may be given.
1359
- * @param {number} [options.lastPageToConvert] - Specifies the last page to convert.
1360
- * @param {boolean} [options.level1] - Generate Level 1 PostScript. The resulting PostScript
1361
- * files will be significantly larger (if they contain images), but will print on Level 1 printers.
1362
- * This also converts all images to black and white.
1363
- * @param {boolean} [options.level1Sep] - Generate Level 1 separable PostScript.
1364
- * All colors are converted to CMYK. Images are written with separate stream data for the four components.
1365
- * @param {boolean} [options.level2] - Generate Level 2 PostScript.
1366
- * Level 2 supports color images and image compression. This is the default setting.
1367
- * @param {boolean} [options.level2Sep] - Generate Level 2 separable PostScript. All colors are
1368
- * converted to CMYK. The PostScript separation convention operators are used to handle custom (spot) colors.
1369
- * @param {boolean} [options.level3] - Generate Level 3 PostScript.
1370
- * This enables all Level 2 featuresplus CID font embedding.
1371
- * @param {boolean} [options.level3Sep] - Generate Level 3 separable PostScript.
1372
- * The separation handling is the same as for `options.level2Sep`.
1373
- * @param {boolean} [options.noCenter] - By default, PDF pages smaller than the paper
1374
- * (after any scaling) are centered on the paper. This option causes them to be aligned to
1375
- * the lower-left corner of the paper instead.
1376
- * @param {boolean} [options.noCrop] - By default, printing output is cropped to the CropBox
1377
- * specified in the PDF file. This option disables cropping.
1378
- * @param {boolean} [options.noEmbedCIDFonts] - By default, any CID PostScript fonts which are
1379
- * embedded in the PDF file are copied into the PostScript file. This option disables that embedding.
1380
- * No attempt is made to substitute for non-embedded CID PostScript fonts.
1381
- * @param {boolean} [options.noEmbedCIDTrueTypeFonts] - By default, any CID TrueType fonts which are
1382
- * embedded in the PDF file are copied into the PostScript file. This option disables that embedding.
1383
- * No attempt is made to substitute for non-embedded CID TrueType fonts.
1384
- * @param {boolean} [options.noEmbedTrueTypeFonts] - By default, any TrueType fonts which are embedded
1385
- * in the PDF file are copied into the PostScript file. This option causes pdfToPs to substitute base fonts instead.
1386
- * Embedded fonts make PostScript files larger, but may be necessary for readable output.
1387
- * Also, some PostScript interpreters do not have TrueType rasterizers.
1388
- * @param {boolean} [options.noEmbedType1Fonts] - By default, any Type 1 fonts which are embedded in the PDF file
1389
- * are copied into the PostScript file. This option causes pdfToPs to substitute base fonts instead.
1390
- * Embedded fonts make PostScript files larger, but may be necessary for readable output.
1391
- * @param {boolean} [options.noShrink] - Do not scale PDF pages which are larger than the paper.
1392
- * By default, pages larger than the paper are shrunk to fit.
1393
- * @param {boolean} [options.opi] - Generate OPI comments for all images and forms which have OPI information.
1394
- * @param {boolean} [options.optimizecolorspace] - By default, bitmap images in the PDF pass through to the
1395
- * output PostScript in their original color space, which produces predictable results.
1396
- * This option converts RGB and CMYK images into Gray images if every pixel of the image has equal components.
1397
- * This can fix problems when doing color separations of PDFs that contain embedded black and
1398
- * white images encoded as RGB.
1399
- * @param {boolean} [options.originalPageSizes] - Set the paper size of each page to match
1400
- * the size specified in the PDF file.
1401
- * @param {boolean} [options.overprint] - Enable overprinting.
1402
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
1403
- * @param {number} [options.paperHeight] - Set the paper height, in points.
1404
- * @param {('A3'|'A4'|'legal'|'letter'|'match')} [options.paperSize] - Set the paper size to one of `A3`, `A4`,
1405
- * `legal`, or `letter`. This can also be set to `match`, which will set the paper size
1406
- * of each page to match the size specified in the PDF file. If none of the paperSize,
1407
- * paperWidth, or paperHeight options are specified the default is to match the paper size.
1408
- * @param {number} [options.paperWidth] - Set the paper width, in points.
1409
- * @param {boolean} [options.passfonts] - By default, references to non-embedded 8-bit fonts
1410
- * in the PDF file are substituted with the closest `Helvetica`, `Times-Roman`, or `Courier` font.
1411
- * This option passes references to non-embedded fonts through to the PostScript file.
1412
- * @param {boolean} [options.preload] - Preload images and forms.
1413
- * @param {boolean} [options.printVersionInfo] - Print copyright and version information.
1414
- * @param {('CMYK8'|'MONO8'|'RGB8')} [options.processColorFormat] - Sets the process color format as it is used
1415
- * during rasterization and transparency reduction.
1416
- *
1417
- * The default depends on the other settings: For `options.level1` the default is MONO8; for `options.level1Sep`,
1418
- * `options.level2Sep`, `options.level3Sep`, or `options.overprint` the default is CMYK8; in all other
1419
- * cases RGB8 is the default.
1420
- * If `option.processColorProfile` is set then `options.processColorFormat` is inferred from the specified ICC profile.
1421
- * @param {string} [options.processColorProfile] - Sets the ICC profile that is assumed during
1422
- * rasterization and transparency reduction.
1423
- * @param {boolean} [options.quiet] - Do not print any messages or errors.
1424
- * @param {('always'|'never'|'whenneeded')} [options.rasterize] - By default, pdfToPs rasterizes pages as needed,
1425
- * for example, if they contain transparencies. To force rasterization, set `rasterize` to `always`.
1426
- * Use this to eliminate fonts.
1427
- * To prevent rasterization, set `rasterize` to `never`.
1428
- * This may produce files that display incorrectly.
1429
- * @param {number} [options.resolutionXYAxis] - Specifies the X and Y resolution, in pixels per
1430
- * inch of image files (or rasterized regions in vector output). The default is 300 PPI.
1431
- * @param {string} [options.userPassword] - User password (for encrypted files).
1423
+ * @param {PdfToPsOptions} [options] - Options to pass to pdftops binary.
1432
1424
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1433
1425
  */
1434
1426
  async pdfToPs(file, outputFile, options = {}) {
1435
1427
  const acceptedOptions = this.#getAcceptedOptions("pdfToPs");
1436
1428
  const versionInfo = await this.#getVersion(this.#pdfToPsBin);
1437
1429
  const args = parseOptions(acceptedOptions, options, versionInfo);
1430
+ args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1438
1431
 
1439
- return new Promise((resolve, reject) => {
1440
- args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1441
-
1442
- const child = spawn(this.#pdfToPsBin, args);
1443
-
1444
- if (Buffer.isBuffer(file)) {
1445
- child.stdin.write(file);
1446
- child.stdin.end();
1447
- }
1448
-
1449
- let stdOut = "";
1450
- let stdErr = "";
1451
-
1452
- child.stdout.on("data", (data) => {
1453
- stdOut += data;
1454
- });
1455
-
1456
- child.stderr.on("data", (data) => {
1457
- stdErr += data;
1458
- });
1459
-
1460
- child.on("close", (code) => {
1461
- /* istanbul ignore else */
1462
- if (stdOut !== "") {
1463
- resolve(stdOut.trim());
1464
- } else if (code === 0) {
1465
- resolve(ERROR_MSGS[code]);
1466
- } else if (stdErr !== "") {
1467
- reject(new Error(stdErr.trim()));
1468
- } else {
1469
- reject(
1470
- new Error(
1471
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
1472
- ERROR_MSGS[code] ||
1473
- `pdftops ${args.join(
1474
- " "
1475
- )} exited with code ${code}`
1476
- )
1477
- );
1478
- }
1479
- });
1480
- });
1432
+ return executeBinary(this.#pdfToPsBin, args, file);
1481
1433
  }
1482
1434
 
1483
1435
  /**
@@ -1486,94 +1438,17 @@ class Poppler {
1486
1438
  * @param {(Buffer|string)} file - PDF file as Buffer, or filepath of the PDF file to read.
1487
1439
  * @param {string} [outputFile] - Filepath of the file to output the results to.
1488
1440
  * If `undefined` then will write output to stdout.
1489
- * @param {object} [options] - Object containing options to pass to binary.
1490
- * @param {boolean} [options.boundingBoxXhtml] - Generate an XHTML file containing bounding
1491
- * box information for each word in the file.
1492
- * @param {boolean} [options.boundingBoxXhtmlLayout] - Generate an XHTML file containing
1493
- * bounding box information for each block, line, and word in the file.
1494
- * @param {boolean} [options.cropBox] - Use the crop box rather than the media box with
1495
- * `options.boundingBoxXhtml` and `options.boundingBoxXhtmlLayout`.
1496
- * @param {number} [options.cropHeight] - Specifies the height of crop area in pixels
1497
- * (image output) or points (vector output).
1498
- * @param {number} [options.cropWidth] - Specifies the width of crop area in pixels
1499
- * (image output) or points (vector output).
1500
- * @param {number} [options.cropXAxis] - Specifies the x-coordinate of the crop area top left
1501
- * corner in pixels (image output) or points (vector output).
1502
- * @param {number} [options.cropYAxis] - Specifies the y-coordinate of the crop area top left
1503
- * corner in pixels (image output) or points (vector output).
1504
- * @param {('dos'|'mac'|'unix')} [options.eolConvention] - Sets the end-of-line convention to use for
1505
- * text output: dos; mac; unix.
1506
- * @param {number} [options.firstPageToConvert] - Specifies the first page to convert.
1507
- * @param {number} [options.fixedWidthLayout] - Assume fixed-pitch (or tabular) text, with the
1508
- * specified character width (in points). This forces physical layout mode.
1509
- * @param {boolean} [options.generateHtmlMetaFile] - Generate simple HTML file, including the
1510
- * meta information. This simply wraps the text in `<pre>` and `</pre>` and prepends the meta headers.
1511
- * @param {boolean} [options.generateTsvFile] - Generate a TSV file containing the bounding box
1512
- * information for each block, line, and word in the file.
1513
- * @param {number} [options.lastPageToConvert] - Specifies the last page to convert.
1514
- * @param {boolean} [options.listEncodingOptions] - List the available encodings.
1515
- * @param {boolean} [options.maintainLayout] - Maintain (as best as possible) the original physical
1516
- * layout of the text. The default is to undo physical layout (columns, hyphenation, etc.) and
1517
- * output the text in reading order.
1518
- * @param {boolean} [options.noDiagonalText] - Discard diagonal text.
1519
- * @param {boolean} [options.noPageBreaks] - Do not insert page breaks (form feed characters)
1520
- * between pages.
1521
- * @param {string} [options.outputEncoding] - Sets the encoding to use for text output.
1522
- * This defaults to `UTF-8`.
1523
- * @param {string} [options.ownerPassword] - Owner password (for encrypted files).
1524
- * @param {boolean} [options.printVersionInfo] - Print copyright and version information.
1525
- * @param {boolean} [options.quiet] - Do not print any messages or errors.
1526
- * @param {boolean} [options.rawLayout] - Keep the text in content stream order. This is a
1527
- * hack which often undoes column formatting, etc. Use of raw mode is no longer recommended.
1528
- * @param {string} [options.userPassword] - User password (for encrypted files).
1441
+ * @param {PdfToTextOptions} [options] - Options to pass to pdftotext binary.
1529
1442
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1530
1443
  */
1531
1444
  async pdfToText(file, outputFile, options = {}) {
1532
1445
  const acceptedOptions = this.#getAcceptedOptions("pdfToText");
1533
1446
  const versionInfo = await this.#getVersion(this.#pdfToTextBin);
1534
1447
  const args = parseOptions(acceptedOptions, options, versionInfo);
1448
+ args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1535
1449
 
1536
- return new Promise((resolve, reject) => {
1537
- args.push(Buffer.isBuffer(file) ? "-" : file, outputFile || "-");
1538
-
1539
- const child = spawn(this.#pdfToTextBin, args);
1540
-
1541
- if (Buffer.isBuffer(file)) {
1542
- child.stdin.write(file);
1543
- child.stdin.end();
1544
- }
1545
-
1546
- let stdOut = "";
1547
- let stdErr = "";
1548
-
1549
- child.stdout.on("data", (data) => {
1550
- stdOut += data;
1551
- });
1552
-
1553
- child.stderr.on("data", (data) => {
1554
- stdErr += data;
1555
- });
1556
-
1557
- child.on("close", (code) => {
1558
- /* istanbul ignore else */
1559
- if (stdOut !== "") {
1560
- resolve(options.maintainLayout ? stdOut : stdOut.trim());
1561
- } else if (code === 0) {
1562
- resolve(ERROR_MSGS[code]);
1563
- } else if (stdErr !== "") {
1564
- reject(new Error(stdErr.trim()));
1565
- } else {
1566
- reject(
1567
- new Error(
1568
- // @ts-ignore: Second operand used if code is not in ERROR_MSGS
1569
- ERROR_MSGS[code] ||
1570
- `pdftotext ${args.join(
1571
- " "
1572
- )} exited with code ${code}`
1573
- )
1574
- );
1575
- }
1576
- });
1450
+ return executeBinary(this.#pdfToTextBin, args, file, {
1451
+ preserveWhitespace: options.maintainLayout,
1577
1452
  });
1578
1453
  }
1579
1454
 
@@ -1584,8 +1459,7 @@ class Poppler {
1584
1459
  * @param {string[]} files - Filepaths of the PDF files to merge.
1585
1460
  * An entire directory of PDF files can be merged like so: `path/to/directory/*.pdf`.
1586
1461
  * @param {string} outputFile - Filepath of the file to output the resulting merged PDF to.
1587
- * @param {object} [options] - Object containing options to pass to binary.
1588
- * @param {boolean} [options.printVersionInfo] - Print copyright and version information.
1462
+ * @param {PdfUniteOptions} [options] - Options to pass to pdfunite binary.
1589
1463
  * @returns {Promise<string>} A promise that resolves with a stdout string, or rejects with an `Error` object.
1590
1464
  */
1591
1465
  async pdfUnite(files, outputFile, options = {}) {