Newer
Older
const program = require("commander");
const ora = require("ora");
const path = require("path");
const fs = require("fs");
// const { promisify } = require("util");
// const writeFileAsync = promisify(fs.writeFile);
const replaceExt = require("replace-ext");
function commaSeparatedList(value) {
return value.split(',');
}
.version(require("../package.json").version)
.arguments("[inputPath]")
.option("-i, --inputs [inputs]", "Inputs")
.option("-o, --output [output]", "Output")
.option("-d, --debug", "Debug")
.option("-l, --landscape", "Landscape printing", false)
.option("-s, --page-size [size]", "Print to Page Size [size]")
.option("-w, --width [size]", "Print to Page Width [width] in MM")
.option("-h --height [size]", "Print to Page Height [weight] in MM")
.option("--forceTransparentBackground", "Print with transparent background")
// .option("-m, --page-margin [margin]", "Print with margin [margin]")
// .option("-n, --hyphenate [lang]", "Hyphenate with language [language], defaults to "en-us"")
// .option("-hi, --hypher_ignore [str]", "Ignore passed element selectors, such as ".class_to_ignore, h1"")
// .option("-ho, --hypher_only [str]", "Only hyphenate passed elements selector, such as ".hyphenate, aside"")
// .option("-e, --encoding [type]", "Set the encoding of the input html, defaults to "utf-8"")
.option("-t, --timeout [ms]", "Set a max timeout of [ms]")
.option("-x, --html", "output html file")
.option("-b, --blockLocal", "Disallow access to filesystem for local files")
.option("-r, --blockRemote", "Disallow requests to remote servers")
.option("--allowedPath [allowedPaths]", "Only allow access to given filesystem paths, repeatable.", collect, [])
.option("--allowedDomain [allowedDomains]", "Only allow access to given remote domains, repeatable", collect, [])
.option("--outline-tags [tags]", "Specifies that an outline should be " +
"generated for the resulting PDF document. [tags] specifies which " +
"HTML tags should be considered for that outline. " +
"\"h1,h2\" will trigger an outline with \"h1\" tags as root elements " +
"and \"h2\" elements as their childs.")
.option("--additional-script <script>", "Additional script tags which are " +
"added to the HTML document before rendering. This is useful for " +
"adding custom pagedjs handlers. The option can be repeated.",
collect, [])
.option("--browserEndpoint <browserEndpoint>", "Use a remote Chrome server with browserWSEndpoint")
.option("--browserArgs <browserArgs>", "Launch Chrome with comma separated args", commaSeparatedList)
function collect(value, previous) {
return previous.concat(value);
}
const options = program.opts();
let input = options.inputs || program.args[0];
let relativePath;
let allowLocal;
try {
relativePath = path.resolve(dir, input);
let headless = typeof options.debug === "undefined";
// var hyphenator;
// var hyphenateOptions;
if (!input) {
console.error("You must include an input path");
return process.exit(1);
}
if ([".html", ".xhtml"].indexOf(path.extname(relativePath)) === -1) {
console.error("Must pass a html or xhtml file as input");
}
try {
fs.accessSync(relativePath, fs.F_OK);
} catch (e) {
console.error("Input cannot be found", e);
return process.exit(1);
}
if (typeof(options.output) === "string") {
output = path.resolve(dir, options.output);
} else if (typeof(options.output) !== "undefined") {
output = "./" + replaceExt(path.basename(input), ".pdf");
const spinner = ora({
spinner: "circleQuarters"
if (typeof input === "string") {
spinner.start("Loading: " + input);
} else {
spinner.start("Loading");
}
headless: headless,
allowLocal: allowLocal,
allowRemote: !options.blockRemote,
allowedPaths: options.allowedPaths,
allowedDomains: options.allowedDomains,
additionalScripts: options.additionalScript,
browserEndpoint: options.browserEndpoint,
timeout: options.timeout,
browserArgs: options.browserArgs
if (options.forceTransparentBackground) {
printerOptions.overrideDefaultBackgroundColor = { r: 0, g: 0, b: 0, a: 0 }; // Workaround to get a transparent background in the resulting PDF. See https://bugs.chromium.org/p/chromium/issues/detail?id=498892 for more information.
}
let printer = new Printer(printerOptions);
printer.on("page", (page) => {
if (page.position === 0) {
spinner.succeed("Loaded");
spinner.start("Rendering: Page " + (page.position + 1));
} else {
spinner.text = "Rendering: Page " + (page.position + 1);
printer.on("rendered", (msg) => {
spinner.succeed(msg);
spinner.start("Generating");
});
printer.on("postprocessing", (msg) => {
spinner.succeed("Generated");
spinner.start("Processing");
});
if (options.html) {
file = await printer.html(input, options)
.catch((e) => {
console.error(e);
process.exit(1);
});
options.outlineTags = !options.outlineTags ? [] : options.outlineTags.split(",");
file = await printer.pdf(input, options)
.catch((e) => {
console.error(e);
process.exit(1);
});
spinner.succeed("Processed");
if (file) {
fs.writeFile(output, file, (err) => {
if (err) throw err;
spinner.succeed("Saved to " + output);