mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-22 16:30: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 ) {
|
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,
|
// If the exception has been handled elsewhere and shouldExit is true,
|
||||||
// let's get out of here, otherwise silently return.
|
// 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
|
The JRSTheme class is a representation of a JSON Resume theme asset.
|
||||||
theme asset. See also: FRESHTheme.
|
|
||||||
@class JRSTheme
|
@class JRSTheme
|
||||||
*/
|
*/
|
||||||
function JRSTheme() {
|
function JRSTheme() {
|
||||||
@ -41,12 +40,31 @@ Definition of the JRSTheme class.
|
|||||||
// Open and parse the theme's package.json file.
|
// Open and parse the theme's package.json file.
|
||||||
var pkgJsonPath = PATH.join( thFolder, 'package.json' );
|
var pkgJsonPath = PATH.join( thFolder, 'package.json' );
|
||||||
if( pathExists( pkgJsonPath )) {
|
if( pathExists( pkgJsonPath )) {
|
||||||
|
|
||||||
var thApi = require( thFolder )
|
var thApi = require( thFolder )
|
||||||
, thPkg = require( pkgJsonPath );
|
, thPkg = require( pkgJsonPath );
|
||||||
|
|
||||||
this.name = thPkg.name;
|
this.name = thPkg.name;
|
||||||
this.render = (thApi && thApi.render) || undefined;
|
this.render = (thApi && thApi.render) || undefined;
|
||||||
|
this.engine = 'jrs';
|
||||||
|
|
||||||
|
// Create theme formats (HTML and PDF)
|
||||||
this.formats = {
|
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 {
|
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,
|
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({
|
var HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend({
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ Definition of the HtmlPdfCLIGenerator class.
|
|||||||
Generate the binary PDF.
|
Generate the binary PDF.
|
||||||
*/
|
*/
|
||||||
onBeforeSave: function( info ) {
|
onBeforeSave: function( info ) {
|
||||||
|
console.log('Called');
|
||||||
try {
|
try {
|
||||||
var safe_eng = info.opts.pdf || 'wkhtmltopdf';
|
var safe_eng = info.opts.pdf || 'wkhtmltopdf';
|
||||||
engines[ safe_eng ].call( this, info.mk, info.outputFile );
|
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 = {
|
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) {
|
wkhtmltopdf: function(markup, fOut) {
|
||||||
|
|
||||||
@ -89,8 +98,11 @@ Definition of the HtmlPdfCLIGenerator class.
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generate a PDF from HTML using Phantom.
|
Generate a PDF from HTML using Phantom's CLI interface.
|
||||||
See: https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js
|
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 ) {
|
phantom: function( markup, fOut ) {
|
||||||
|
|
||||||
@ -104,7 +116,7 @@ Definition of the HtmlPdfCLIGenerator class.
|
|||||||
var destPath = SLASH( PATH.relative( process.cwd(), fOut) );
|
var destPath = SLASH( PATH.relative( process.cwd(), fOut) );
|
||||||
|
|
||||||
var spawn = require('child_process').spawnSync;
|
var spawn = require('child_process').spawnSync;
|
||||||
var info = spawn('1phantomjs', [ scriptPath, sourcePath, destPath ]);
|
var info = spawn('phantomjs', [ scriptPath, sourcePath, destPath ]);
|
||||||
if( info.error ) {
|
if( info.error ) {
|
||||||
throw {
|
throw {
|
||||||
cmd: 'phantomjs',
|
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.
|
@license MIT. See LICENSE.md for details.
|
||||||
@module template-generator.js
|
@module template-generator.js
|
||||||
*/
|
*/
|
||||||
@ -145,6 +145,10 @@ Definition of the TemplateGenerator class.
|
|||||||
|
|
||||||
var thisFilePath;
|
var thisFilePath;
|
||||||
|
|
||||||
|
if( theme.engine === 'jrs' ) {
|
||||||
|
file.info.orgPath = '';
|
||||||
|
}
|
||||||
|
|
||||||
if( file.info.action === 'transform' ) {
|
if( file.info.action === 'transform' ) {
|
||||||
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
thisFilePath = PATH.join( outFolder, file.info.orgPath );
|
||||||
try {
|
try {
|
||||||
@ -175,7 +179,8 @@ Definition of the TemplateGenerator class.
|
|||||||
FS.copySync( file.info.path, thisFilePath );
|
FS.copySync( file.info.path, thisFilePath );
|
||||||
}
|
}
|
||||||
catch(ex) {
|
catch(ex) {
|
||||||
console.log(ex);
|
ex.showStack = true;
|
||||||
|
require('../core/error-handler').err( ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -274,8 +279,8 @@ Definition of the TemplateGenerator class.
|
|||||||
theme );
|
theme );
|
||||||
}
|
}
|
||||||
catch(ex) {
|
catch(ex) {
|
||||||
console.log(ex);
|
ex.showStack = true;
|
||||||
throw ex;
|
require('../core/error-handler').err( ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ Implementation of the 'generate' verb for HackMyResume.
|
|||||||
// Check for invalid outputs
|
// Check for invalid outputs
|
||||||
var inv = verifyOutputs( dst, theme );
|
var inv = verifyOutputs( dst, theme );
|
||||||
if( inv && inv.length ) {
|
if( inv && inv.length ) {
|
||||||
throw { fluenterror: HACKMYSTATUS.invalidTarget, data: inv, theme: theme };
|
throw {fluenterror: HACKMYSTATUS.invalidTarget, data: inv, theme: theme};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load input resumes...
|
// 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.
|
// If targInfo.fmt.files exists, this format is backed by a document.
|
||||||
// Fluent/FRESH themes are handled here.
|
// 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 ) {
|
if( targInfo.fmt.files && targInfo.fmt.files.length ) {
|
||||||
theFormat = _fmts.filter(
|
theFormat = _fmts.filter(
|
||||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
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
|
// 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".
|
// (JSON, YML, or PNG) that every theme gets "for free".
|
||||||
else {
|
// else {
|
||||||
|
//
|
||||||
theFormat = _fmts.filter( function(fmt) {
|
// theFormat = _fmts.filter( function(fmt) {
|
||||||
return fmt.name === targInfo.fmt.outFormat;
|
// return fmt.name === targInfo.fmt.outFormat;
|
||||||
})[0];
|
// })[0];
|
||||||
|
//
|
||||||
var outFolder = PATH.dirname( f );
|
// var outFolder = PATH.dirname( f );
|
||||||
MKDIRP.sync( outFolder ); // Ensure dest folder exists;
|
// MKDIRP.sync( outFolder ); // Ensure dest folder exists;
|
||||||
|
//
|
||||||
// JSON Resume themes have a 'render' method that needs to be called
|
// // JSON Resume themes have a 'render' method that needs to be called
|
||||||
if( theme.render ) {
|
// if( theme.render ) {
|
||||||
return renderJRSTheme( f, outFolder, theme );
|
// return renderJRSTheme( f, outFolder, theme );
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
return theFormat.gen.generate( rez, f, _opts );
|
// return theFormat.gen.generate( rez, f, _opts );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
catch( ex ) {
|
catch( ex ) {
|
||||||
_err( 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.
|
Ensure that user-specified outputs/targets are valid.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user