description and source-codefunction wkhtmltopdf(input, options, callback) {
if (!options) {
options = {};
} else if (typeof options == 'function') {
callback = options;
options = {};
}
var output = options.output;
delete options.output;
// make sure the special keys are last
var extraKeys = [];
var keys = Object.keys(options).filter(function(key) {
if (key === 'toc' || key === 'cover' || key === 'page') {
extraKeys.push(key);
return false;
}
return true;
}).concat(extraKeys);
// make sure toc specific args appear after toc arg
if (keys.indexOf('toc') >= 0) {
var tocArgs = ['disableDottedLines', 'tocHeaderText', 'tocLevelIndentation', 'disableTocLinks', 'tocTextSizeShrink', 'xslStyleSheet
'];
var myTocArgs = [];
keys = keys.filter(function(key){
if (tocArgs.find(function(tkey){ return tkey === key })) {
myTocArgs.push(key);
return false;
}
return true;
});
var spliceArgs = [keys.indexOf('toc')+1, 0].concat(myTocArgs);
Array.prototype.splice.apply(keys, spliceArgs);
}
var args = [wkhtmltopdf.command];
if (!options.debug) {
args.push('--quiet');
}
keys.forEach(function(key) {
var val = options[key];
if (key === 'ignore' || key === 'debug' || key === 'debugStdOut') { // skip adding the ignore/debug keys
return false;
}
if (key !== 'toc' && key !== 'cover' && key !== 'page') {
key = key.length === 1 ? '-' + key : '--' + slang.dasherize(key);
}
if (Array.isArray(val)) { // add repeatable args
val.forEach(function(valueStr) {
args.push(key);
if (Array.isArray(valueStr)) { // if repeatable args has key/value pair
valueStr.forEach(function(keyOrValueStr) {
args.push(quote(keyOrValueStr));
});
} else {
args.push(quote(valueStr));
}
});
} else { // add normal args
if (val !== false) {
args.push(key);
}
if (typeof val !== 'boolean') {
args.push(quote(val));
}
}
});
var isUrl = /^(https?|file):\/\//.test(input);
args.push(isUrl ? quote(input) : '-'); // stdin if HTML given directly
args.push(output ? quote(output) : '-'); // stdout if no output file
// show the command that is being run if debug opion is passed
if (options.debug && !(options instanceof Function)) {
console.log('[node-wkhtmltopdf] [debug] [command] ' + args.join(' '));
}
if (process.platform === 'win32') {
var child = spawn(args[0], args.slice(1));
} else if (process.platform === 'darwin') {
var child = spawn('/bin/sh', ['-c', args.join(' ') + ' | cat ; exit ${PIPESTATUS[0]}']);
} else {
// this nasty business prevents piping problems on linux
// The return code should be that of wkhtmltopdf and not of cat
// http://stackoverflow.com/a/18295541/1705056
var child = spawn(wkhtmltopdf.shell, ['-c', args.join(' ') + ' | cat ; exit ${PIPESTATUS[0]}']);
}
var stream = child.stdout;
// call the callback with null error when the process exits successfully
child.on('exit', function(code) {
if (code !== 0) {
stderrMessages.push('wkhtmltopdf exited with code ' + code);
handleError(stderrMessages);
} else if (callback) {
callback(null, stream); // stream is child.stdout
}
});
// setup error handling
var stderrMessages = [];
function handleError(err) {
var errObj = null;
if (Array.isArray(err)) {
// check ignore warnings array before killing child
if (options.ignore && options.ignore instanceof Array) {
var ignoreError = false;
options.ignore.forEach(function(opt) {
err.forEach(function(error) {
if (typeof opt === 'string' && opt === error) {
ignoreError = true;
}
if (opt instanceof RegExp && error.match(opt)) {
ignoreError = true;
}
});
});
if (ignoreError) {
return true;
}
}
errObj = new Error(err.join('\n'));
} else if ( ...