forked from devongovett/node-wkhtmltopdf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
100 lines (83 loc) · 2.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
var spawn = require('child_process').spawn;
var slang = require('slang');
function quote(val) {
// escape and quote the value if it is a string and this isn't windows
if (typeof val === 'string' && process.platform !== 'win32')
val = '"' + val.replace(/(["\\$`])/g, '\\$1') + '"';
return val;
}
function 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);
var args = [wkhtmltopdf.command, '--quiet'];
keys.forEach(function(key) {
var val = options[key];
if (key !== 'toc' && key !== 'cover' && key !== 'page')
key = key.length === 1 ? '-' + key : '--' + slang.dasherize(key);
if (val !== false && !Array.isArray(val) && !(val instanceof Object))
args.push(key);
//TODO: merge in changes from here: https://github.com/terradatum/node-wkhtmltopdf
if (Array.isArray(val)) {
val.forEach(function(v) {
args.push(key);
args.push(quote(v));
});
} else if (val instanceof Object) {
Object.keys(val).forEach(function(k) {
args.push(key);
args.push(quote(k));
args.push(quote(val[k]));
});
} else if (typeof val !== 'boolean') {
args.push(quote(val));
}
});
//ML - pass in files using the file:/// prefix
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
if (process.platform === 'win32') {
var child = spawn(args[0], args.slice(1));
} else {
// this nasty business prevents piping problems on linux
console.log(args.join(' '));
var child = spawn('/bin/sh', ['-c', args.join(' ') + ' | cat']);
}
// call the callback with null error when the process exits successfully
if (callback)
child.on('close', function() { callback(null); });
// setup error handling
var stream = child.stdout;
function handleError(err) {
console.error(err);
// if not, or there are listeners for errors, emit the error event
if (!callback || stream.listeners('error').length > 0)
stream.emit('error', err);
}
child.once('error', handleError);
child.stderr.once('data', function(err) {
handleError(new Error((err || '').toString().trim()));
});
//write input to stdin if it isn't a url
if (!isUrl)
child.stdin.end(input);
//return stdout stream so we can pipe
return stream;
}
wkhtmltopdf.command = 'xvfb-run --auto-servernum --server-args="-screen 0, 1024x768x24" wkhtmltopdf';
module.exports = wkhtmltopdf;