2016-01-07 23:24:25 +00:00
|
|
|
/**
|
|
|
|
Definition of the HtmlPdfCLIGenerator class.
|
|
|
|
@module html-pdf-generator.js
|
|
|
|
@license MIT. See LICENSE.md for details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var TemplateGenerator = require('./template-generator')
|
|
|
|
, FS = require('fs-extra')
|
|
|
|
, HTML = require( 'html' )
|
|
|
|
, PATH = require('path')
|
|
|
|
, SLASH = require('slash');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,
|
2016-01-08 13:40:19 +00:00
|
|
|
wkhtmltopdf, and other PDF engines over a CLI (command-line interface).
|
|
|
|
If an engine isn't installed for a particular platform, error out gracefully.
|
2016-01-07 23:24:25 +00:00
|
|
|
*/
|
|
|
|
var HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend({
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init: function() {
|
|
|
|
this._super( 'pdf', 'html' );
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generate the binary PDF.
|
|
|
|
*/
|
|
|
|
onBeforeSave: function( info ) {
|
2016-01-08 14:00:43 +00:00
|
|
|
|
2016-01-07 23:24:25 +00:00
|
|
|
try {
|
2016-01-08 10:11:38 +00:00
|
|
|
var safe_eng = info.opts.pdf || 'wkhtmltopdf';
|
|
|
|
engines[ safe_eng ].call( this, info.mk, info.outputFile );
|
2016-01-07 23:24:25 +00:00
|
|
|
return null; // halt further processing
|
|
|
|
}
|
|
|
|
catch(ex) {
|
|
|
|
// { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', ... }
|
|
|
|
// { [Error: ENOENT] }
|
2016-01-08 10:11:38 +00:00
|
|
|
throw ( ex.inner && ex.inner.code === 'ENOENT' ) ?
|
|
|
|
{ fluenterror: this.codes.notOnPath, engine: ex.cmd } :
|
|
|
|
{ fluenterror: this.codes.pdfGeneration, inner: ex.inner };
|
2016-01-07 23:24:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-08 13:40:19 +00:00
|
|
|
|
|
|
|
|
2016-01-07 23:24:25 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-08 13:40:19 +00:00
|
|
|
// TODO: Move each engine to a separate module
|
2016-01-07 23:24:25 +00:00
|
|
|
var engines = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-01-08 13:40:19 +00:00
|
|
|
Generate a PDF from HTML using wkhtmltopdf's CLI interface.
|
|
|
|
Spawns a child process with `wkhtmltopdf <source> <target>`. wkhtmltopdf
|
|
|
|
must be installed and path-accessible.
|
|
|
|
TODO: If HTML generation has run, reuse that output
|
|
|
|
TODO: Local web server to ease wkhtmltopdf rendering
|
2016-01-07 23:24:25 +00:00
|
|
|
*/
|
|
|
|
wkhtmltopdf: function(markup, fOut) {
|
|
|
|
|
|
|
|
// Save the markup to a temporary file
|
|
|
|
var tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
|
|
|
|
FS.writeFileSync( tempFile, markup, 'utf8' );
|
|
|
|
|
2016-01-08 10:11:38 +00:00
|
|
|
var spawn = require('child_process').spawnSync;
|
|
|
|
var info = spawn('wkhtmltopdf', [
|
2016-01-07 23:24:25 +00:00
|
|
|
tempFile, fOut
|
|
|
|
]);
|
2016-01-08 10:11:38 +00:00
|
|
|
if( info.error ) {
|
|
|
|
throw {
|
|
|
|
cmd: 'wkhtmltopdf',
|
|
|
|
inner: info.error
|
|
|
|
};
|
|
|
|
}
|
2016-01-07 23:24:25 +00:00
|
|
|
|
|
|
|
// child.stdout.on('data', function(chunk) {
|
|
|
|
// // output will be here in chunks
|
|
|
|
// });
|
|
|
|
|
|
|
|
// or if you want to send output elsewhere
|
|
|
|
//child.stdout.pipe(dest);
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-01-08 13:40:19 +00:00
|
|
|
Generate a PDF from HTML using Phantom's CLI interface.
|
|
|
|
Spawns a child process with `phantomjs <script> <source> <target>`. Phantom
|
|
|
|
must be installed and path-accessible.
|
|
|
|
TODO: If HTML generation has run, reuse that output
|
|
|
|
TODO: Local web server to ease Phantom rendering
|
2016-01-07 23:24:25 +00:00
|
|
|
*/
|
|
|
|
phantom: function( markup, fOut ) {
|
|
|
|
|
|
|
|
// Save the markup to a temporary file
|
|
|
|
var tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
|
|
|
|
FS.writeFileSync( tempFile, markup, 'utf8' );
|
|
|
|
|
|
|
|
var scriptPath = SLASH( PATH.relative( process.cwd(),
|
|
|
|
PATH.resolve( __dirname, '../utils/rasterize.js' ) ) );
|
|
|
|
var sourcePath = SLASH( PATH.relative( process.cwd(), tempFile) );
|
|
|
|
var destPath = SLASH( PATH.relative( process.cwd(), fOut) );
|
|
|
|
|
2016-01-08 10:11:38 +00:00
|
|
|
var spawn = require('child_process').spawnSync;
|
2016-01-08 13:40:19 +00:00
|
|
|
var info = spawn('phantomjs', [ scriptPath, sourcePath, destPath ]);
|
2016-01-08 10:11:38 +00:00
|
|
|
if( info.error ) {
|
|
|
|
throw {
|
|
|
|
cmd: 'phantomjs',
|
|
|
|
inner: info.error
|
|
|
|
};
|
|
|
|
}
|
2016-01-07 23:24:25 +00:00
|
|
|
|
|
|
|
// child.stdout.on('data', function(chunk) {
|
|
|
|
// // output will be here in chunks
|
|
|
|
// });
|
|
|
|
//
|
|
|
|
// // or if you want to send output elsewhere
|
|
|
|
// child.stdout.pipe(dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}());
|