mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-25 09:50:11 +00:00
Start integrating JRS and FRESH rendering paths.
This commit is contained in:
parent
4a2a47f551
commit
d6280e6d89
@ -29,7 +29,7 @@ Error-handling routines for HackMyResume.
|
||||
|
||||
err: function( ex, shouldExit ) {
|
||||
|
||||
var msg = '', exitCode, log = console.log, showStack = false;
|
||||
var msg = '', exitCode, log = console.log, showStack = ex.showStack;
|
||||
|
||||
// If the exception has been handled elsewhere and shouldExit is true,
|
||||
// let's get out of here, otherwise silently return.
|
||||
|
@ -16,8 +16,7 @@ Definition of the JRSTheme class.
|
||||
|
||||
|
||||
/**
|
||||
The JRSTheme class is a representation of a JSON Resume
|
||||
theme asset. See also: FRESHTheme.
|
||||
The JRSTheme class is a representation of a JSON Resume theme asset.
|
||||
@class JRSTheme
|
||||
*/
|
||||
function JRSTheme() {
|
||||
@ -41,12 +40,31 @@ Definition of the JRSTheme class.
|
||||
// Open and parse the theme's package.json file.
|
||||
var pkgJsonPath = PATH.join( thFolder, 'package.json' );
|
||||
if( pathExists( pkgJsonPath )) {
|
||||
|
||||
var thApi = require( thFolder )
|
||||
, thPkg = require( pkgJsonPath );
|
||||
|
||||
this.name = thPkg.name;
|
||||
this.render = (thApi && thApi.render) || undefined;
|
||||
this.engine = 'jrs';
|
||||
|
||||
// Create theme formats (HTML and PDF)
|
||||
this.formats = {
|
||||
html: { title:'html', outFormat:'html', ext:'html' }
|
||||
html: { outFormat: 'html', files: [
|
||||
{
|
||||
action: 'transform',
|
||||
render: this.render,
|
||||
//path: absPath,
|
||||
major: true,
|
||||
//orgPath: PATH.relative(thFolder, absPath),
|
||||
ext: pathInfo.extname.slice(1),
|
||||
//title: friendlyName( outFmt ),
|
||||
//pre: outFmt,
|
||||
// outFormat: outFmt || pathInfo.name,
|
||||
//data: FS.readFileSync( absPath, 'utf8' ),
|
||||
css: null
|
||||
}
|
||||
]}
|
||||
};
|
||||
}
|
||||
else {
|
||||
|
76
src/eng/jrs-generator.js
Normal file
76
src/eng/jrs-generator.js
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
Definition of the JRSGenerator class.
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module jrs-generator.js
|
||||
*/
|
||||
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
|
||||
var _ = require('underscore')
|
||||
, HANDLEBARS = require('handlebars')
|
||||
, FS = require('fs')
|
||||
, registerHelpers = require('./handlebars-helpers')
|
||||
, PATH = require('path')
|
||||
, parsePath = require('parse-filepath')
|
||||
, READFILES = require('recursive-readdir-sync')
|
||||
, SLASH = require('slash')
|
||||
, MD = require('marked');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Perform template-based resume generation for JSON Resume themes.
|
||||
@class JRSGenerator
|
||||
*/
|
||||
var JRSGenerator = module.exports = {
|
||||
|
||||
|
||||
|
||||
|
||||
generate: function( json, jst, format, cssInfo, opts, theme ) {
|
||||
|
||||
// JSON Resume themes don't have a specific structure, so the safest thing
|
||||
// to do is copy all files from source to dest.
|
||||
// var COPY = require('copy');
|
||||
// var globs = [ '*.css', '*.js', '*.png', '*.jpg', '*.gif', '*.bmp' ];
|
||||
// COPY.sync( globs , outFolder, {
|
||||
// cwd: theme.folder, nodir: true,
|
||||
// ignore: ['node_modules/','node_modules/**']
|
||||
// // rewrite: function(p1, p2) {
|
||||
// // return PATH.join(p2, p1);
|
||||
// // }
|
||||
// });
|
||||
|
||||
// Disable JRS theme chatter (console.log, console.error, etc.)
|
||||
var off = ['log', 'error', 'dir'], org = off.map(function(c){
|
||||
var ret = console[c]; console[c] = function(){}; return ret;
|
||||
});
|
||||
|
||||
// Freeze and render
|
||||
var rezHtml = theme.render( json.harden() );
|
||||
|
||||
// Turn logging back on
|
||||
off.forEach(function(c, idx){ console[c] = org[idx]; });
|
||||
|
||||
// Unfreeze and apply Markdown
|
||||
rezHtml = rezHtml.replace( /@@@@~.*?~@@@@/gm, function(val){
|
||||
return MDIN( val.replace( /~@@@@/gm,'' ).replace( /@@@@~/gm,'' ) );
|
||||
});
|
||||
|
||||
return rezHtml;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
function MDIN(txt) { // TODO: Move this
|
||||
return MD(txt || '' ).replace(/^\s*<p>|<\/p>\s*$/gi, '');
|
||||
}
|
||||
|
||||
|
||||
}());
|
@ -20,7 +20,8 @@ Definition of the HtmlPdfCLIGenerator class.
|
||||
|
||||
/**
|
||||
An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,
|
||||
wkhtmltopdf, and other PDF libraries over a CLI.
|
||||
wkhtmltopdf, and other PDF engines over a CLI (command-line interface).
|
||||
If an engine isn't installed for a particular platform, error out gracefully.
|
||||
*/
|
||||
var HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend({
|
||||
|
||||
@ -36,6 +37,7 @@ Definition of the HtmlPdfCLIGenerator class.
|
||||
Generate the binary PDF.
|
||||
*/
|
||||
onBeforeSave: function( info ) {
|
||||
console.log('Called');
|
||||
try {
|
||||
var safe_eng = info.opts.pdf || 'wkhtmltopdf';
|
||||
engines[ safe_eng ].call( this, info.mk, info.outputFile );
|
||||
@ -50,16 +52,23 @@ Definition of the HtmlPdfCLIGenerator class.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
// TODO: Move each engine to a separate module
|
||||
var engines = {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Generate a PDF from HTML using wkhtmltopdf.
|
||||
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
|
||||
*/
|
||||
wkhtmltopdf: function(markup, fOut) {
|
||||
|
||||
@ -89,8 +98,11 @@ Definition of the HtmlPdfCLIGenerator class.
|
||||
|
||||
|
||||
/**
|
||||
Generate a PDF from HTML using Phantom.
|
||||
See: https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js
|
||||
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
|
||||
*/
|
||||
phantom: function( markup, fOut ) {
|
||||
|
||||
@ -104,7 +116,7 @@ Definition of the HtmlPdfCLIGenerator class.
|
||||
var destPath = SLASH( PATH.relative( process.cwd(), fOut) );
|
||||
|
||||
var spawn = require('child_process').spawnSync;
|
||||
var info = spawn('1phantomjs', [ scriptPath, sourcePath, destPath ]);
|
||||
var info = spawn('phantomjs', [ scriptPath, sourcePath, destPath ]);
|
||||
if( info.error ) {
|
||||
throw {
|
||||
cmd: 'phantomjs',
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
Definition of the TemplateGenerator class.
|
||||
Definition of the TemplateGenerator class. TODO: Refactor
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module template-generator.js
|
||||
*/
|
||||
@ -145,6 +145,10 @@ Definition of the TemplateGenerator class.
|
||||
|
||||
var thisFilePath;
|
||||
|
||||
if( theme.engine === 'jrs' ) {
|
||||
file.info.orgPath = '';
|
||||
}
|
||||
|
||||
if( file.info.action === 'transform' ) {
|
||||
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
||||
try {
|
||||
@ -175,7 +179,8 @@ Definition of the TemplateGenerator class.
|
||||
FS.copySync( file.info.path, thisFilePath );
|
||||
}
|
||||
catch(ex) {
|
||||
console.log(ex);
|
||||
ex.showStack = true;
|
||||
require('../core/error-handler').err( ex );
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -274,8 +279,8 @@ Definition of the TemplateGenerator class.
|
||||
theme );
|
||||
}
|
||||
catch(ex) {
|
||||
console.log(ex);
|
||||
throw ex;
|
||||
ex.showStack = true;
|
||||
require('../core/error-handler').err( ex );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
// Check for invalid outputs
|
||||
var inv = verifyOutputs( dst, theme );
|
||||
if( inv && inv.length ) {
|
||||
throw { fluenterror: HACKMYSTATUS.invalidTarget, data: inv, theme: theme };
|
||||
throw {fluenterror: HACKMYSTATUS.invalidTarget, data: inv, theme: theme};
|
||||
}
|
||||
|
||||
// Load input resumes...
|
||||
@ -184,6 +184,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
|
||||
// If targInfo.fmt.files exists, this format is backed by a document.
|
||||
// Fluent/FRESH themes are handled here.
|
||||
// TODO: Make FRESH and JRS themes render on the same path
|
||||
if( targInfo.fmt.files && targInfo.fmt.files.length ) {
|
||||
theFormat = _fmts.filter(
|
||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||
@ -194,23 +195,23 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
|
||||
// Otherwise this is either a) a JSON Resume theme or b) an ad-hoc format
|
||||
// (JSON, YML, or PNG) that every theme gets "for free".
|
||||
else {
|
||||
|
||||
theFormat = _fmts.filter( function(fmt) {
|
||||
return fmt.name === targInfo.fmt.outFormat;
|
||||
})[0];
|
||||
|
||||
var outFolder = PATH.dirname( f );
|
||||
MKDIRP.sync( outFolder ); // Ensure dest folder exists;
|
||||
|
||||
// JSON Resume themes have a 'render' method that needs to be called
|
||||
if( theme.render ) {
|
||||
return renderJRSTheme( f, outFolder, theme );
|
||||
}
|
||||
else {
|
||||
return theFormat.gen.generate( rez, f, _opts );
|
||||
}
|
||||
}
|
||||
// else {
|
||||
//
|
||||
// theFormat = _fmts.filter( function(fmt) {
|
||||
// return fmt.name === targInfo.fmt.outFormat;
|
||||
// })[0];
|
||||
//
|
||||
// var outFolder = PATH.dirname( f );
|
||||
// MKDIRP.sync( outFolder ); // Ensure dest folder exists;
|
||||
//
|
||||
// // JSON Resume themes have a 'render' method that needs to be called
|
||||
// if( theme.render ) {
|
||||
// return renderJRSTheme( f, outFolder, theme );
|
||||
// }
|
||||
// else {
|
||||
// return theFormat.gen.generate( rez, f, _opts );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
catch( ex ) {
|
||||
_err( ex );
|
||||
@ -219,49 +220,6 @@ Implementation of the 'generate' verb for HackMyResume.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Render a JSON Resume theme. JSON Resume themes have an index.js that needs
|
||||
to be called to perform the render. Additionally, we need to flow Markdown
|
||||
styles to the JSON Resume (to the extent possible).
|
||||
TODO: Refactor
|
||||
*/
|
||||
function renderJRSTheme( f, outFolder, theme ) {
|
||||
|
||||
var COPY = require('copy');
|
||||
var globs = [ '*.css', '*.js', '*.png', '*.jpg', '*.gif', '*.bmp' ];
|
||||
COPY.sync( globs , outFolder, {
|
||||
cwd: theme.folder, nodir: true,
|
||||
ignore: ['node_modules/','node_modules/**']
|
||||
// rewrite: function(p1, p2) {
|
||||
// return PATH.join(p2, p1);
|
||||
// }
|
||||
});
|
||||
|
||||
// Disable JRS theme chatter (console.log, console.error, etc.)
|
||||
var off = ['log', 'error', 'dir'], org = off.map(function(c){
|
||||
var ret = console[c]; console[c] = function(){}; return ret;
|
||||
});
|
||||
|
||||
// Freeze and render
|
||||
var rezHtml = theme.render( rez.harden() );
|
||||
|
||||
// Turn logging back on
|
||||
off.forEach(function(c, idx){ console[c] = org[idx]; });
|
||||
|
||||
// Unfreeze and apply Markdown
|
||||
rezHtml = rezHtml.replace( /@@@@~.*?~@@@@/gm, function(val){
|
||||
return MDIN( val.replace( /~@@@@/gm,'' ).replace( /@@@@~/gm,'' ) );
|
||||
});
|
||||
|
||||
// Save the file
|
||||
FS.writeFileSync( f, rezHtml );
|
||||
|
||||
// Return markup to the client
|
||||
return rezHtml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Ensure that user-specified outputs/targets are valid.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user