mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-12-23 13:47:22 +00:00
Merge branch 'master' of https://github.com/hacksalot/HackMyResume
This commit is contained in:
commit
2b3c83c57e
@ -327,5 +327,5 @@ MIT. Go crazy. See [LICENSE.md][1] for details.
|
||||
[travis-image]: https://img.shields.io/travis/palomajs/paloma.svg?style=flat-square
|
||||
[travis-url]: https://travis-ci.org/hacksalot/HackMyResume
|
||||
[contribute]: CONTRIBUTING.md
|
||||
[fresh-themes]: https://github.com/fluentdesk/fluent-themes
|
||||
[fresh-themes]: https://github.com/fluentdesk/fresh-themes
|
||||
[jrst]: https://www.npmjs.com/search?q=jsonresume-theme
|
||||
|
@ -47,7 +47,7 @@
|
||||
"dependencies": {
|
||||
"colors": "^1.1.2",
|
||||
"copy": "^0.1.3",
|
||||
"fluent-themes": "~0.8.0-beta",
|
||||
"fresh-themes": "~0.9.3-beta",
|
||||
"fresca": "~0.2.2",
|
||||
"fs-extra": "^0.24.0",
|
||||
"handlebars": "^4.0.5",
|
||||
@ -79,6 +79,7 @@
|
||||
"grunt-contrib-yuidoc": "^0.10.0",
|
||||
"grunt-simple-mocha": "*",
|
||||
"jane-q-fullstacker": "fluentdesk/jane-q-fullstacker",
|
||||
"johnny-trouble-resume": "fluentdesk/johnny-trouble-resume",
|
||||
"jsonresume-theme-boilerplate": "^0.1.2",
|
||||
"jsonresume-theme-classy": "^1.0.9",
|
||||
"jsonresume-theme-modern": "0.0.18",
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
var HACKMYSTATUS = require('./status-codes')
|
||||
, PKG = require('../../package.json')
|
||||
, FS = require('fs')
|
||||
, FCMD = require('../hackmycmd')
|
||||
, PATH = require('path')
|
||||
, title = ('\n*** HackMyResume v' + PKG.version + ' ***').bold.white;
|
||||
|
||||
var ErrorHandler = module.exports = {
|
||||
@ -26,17 +29,21 @@
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.resumeNotFound:
|
||||
msg = 'Please '.guide + 'specify a valid input resume'.guide.bold +
|
||||
msg = 'Please '.guide + 'feed me a resume'.guide.bold +
|
||||
' in FRESH or JSON Resume format.'.guide;
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.missingCommand:
|
||||
msg = title + "\nPlease ".guide + "specify a command".guide.bold + " (".guide +
|
||||
Object.keys( FCMD.verbs ).map( function(v, idx, ar) {
|
||||
msg = title + "\nPlease ".guide + "give me a command".guide.bold +
|
||||
" (".guide;
|
||||
|
||||
msg += Object.keys( FCMD.verbs ).map( function(v, idx, ar) {
|
||||
return (idx === ar.length - 1 ? 'or '.guide : '') +
|
||||
v.toUpperCase().guide;
|
||||
}).join(', '.guide) + ").\n\n".guide +
|
||||
FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' ).info.bold;
|
||||
}).join(', '.guide) + ").\n\n".guide;
|
||||
|
||||
msg += FS.readFileSync(
|
||||
PATH.resolve(__dirname, '../use.txt'), 'utf8' ).info.bold;
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.invalidCommand:
|
||||
@ -45,7 +52,7 @@
|
||||
break;
|
||||
|
||||
case HACKMYSTATUS.resumeNotFoundAlt:
|
||||
msg = 'Please '.guide + 'specify a valid input resume'.guide.bold +
|
||||
msg = 'Please '.guide + 'feed me a resume'.guide.bold +
|
||||
' in either FRESH or JSON Resume format.'.guide;
|
||||
break;
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
/**
|
||||
Definition of the Theme class.
|
||||
@license MIT. Copyright (c) 2015 hacksalot / FluentDesk.
|
||||
@module theme.js
|
||||
Definition of the FRESHTheme class.
|
||||
@module fresh-theme.js
|
||||
@license MIT. See LICENSE.md for details.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
|
||||
var FS = require('fs')
|
||||
, extend = require('../utils/extend')
|
||||
, validator = require('is-my-json-valid')
|
||||
@ -15,20 +17,25 @@ Definition of the Theme class.
|
||||
, pathExists = require('path-exists').sync
|
||||
, EXTEND = require('../utils/extend')
|
||||
, moment = require('moment')
|
||||
, RECURSIVE_READ_DIR = require('recursive-readdir-sync');
|
||||
, READFILES = require('recursive-readdir-sync');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
The Theme class is a representation of a HackMyResume theme asset.
|
||||
@class Theme
|
||||
The FRESHTheme class is a representation of a FRESH theme
|
||||
asset. See also: JRSTheme.
|
||||
@class FRESHTheme
|
||||
*/
|
||||
function Theme() {
|
||||
function FRESHTheme() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Open and parse the specified theme.
|
||||
*/
|
||||
Theme.prototype.open = function( themeFolder ) {
|
||||
FRESHTheme.prototype.open = function( themeFolder ) {
|
||||
|
||||
this.folder = themeFolder;
|
||||
|
||||
@ -38,18 +45,7 @@ Definition of the Theme class.
|
||||
// Set up a formats hash for the theme
|
||||
var formatsHash = { };
|
||||
|
||||
// See if the theme has a package.json. If so, load it.
|
||||
var packageJsonPath = PATH.join(themeFolder, 'package.json');
|
||||
if( pathExists( packageJsonPath ) ) {
|
||||
var themePack = require( themeFolder );
|
||||
var themePkgJson = require( packageJsonPath );
|
||||
this.name = themePkgJson.name;
|
||||
this.render = (themePack && themePack.render) || undefined;
|
||||
this.formats = { html: { title: 'html', outFormat: 'html', ext: 'html', path: null, data: null } };
|
||||
return this;
|
||||
}
|
||||
|
||||
// Otherwise, do a full theme load
|
||||
// Load the theme
|
||||
var themeFile = PATH.join( themeFolder, pathInfo.basename + '.json' );
|
||||
var themeInfo = JSON.parse( FS.readFileSync( themeFile, 'utf8' ) );
|
||||
var that = this;
|
||||
@ -67,10 +63,6 @@ Definition of the Theme class.
|
||||
formatsHash = loadImplicit.call( this );
|
||||
}
|
||||
|
||||
// Add freebie formats every theme gets
|
||||
formatsHash.json = { title: 'json', outFormat: 'json', pre: 'json', ext: 'json', path: null, data: null };
|
||||
formatsHash.yml = { title: 'yaml', outFormat: 'yml', pre: 'yml', ext: 'yml', path: null, data: null };
|
||||
|
||||
// Cache
|
||||
this.formats = formatsHash;
|
||||
|
||||
@ -80,20 +72,29 @@ Definition of the Theme class.
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Determine if the theme supports the specified output format.
|
||||
*/
|
||||
Theme.prototype.hasFormat = function( fmt ) {
|
||||
FRESHTheme.prototype.hasFormat = function( fmt ) {
|
||||
return _.has( this.formats, fmt );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Determine if the theme supports the specified output format.
|
||||
*/
|
||||
Theme.prototype.getFormat = function( fmt ) {
|
||||
FRESHTheme.prototype.getFormat = function( fmt ) {
|
||||
return this.formats[ fmt ];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Load the theme implicitly, by scanning the theme folder for
|
||||
files. TODO: Refactor duplicated code with loadExplicit.
|
||||
*/
|
||||
function loadImplicit() {
|
||||
|
||||
// Set up a hash of formats supported by this theme.
|
||||
@ -107,7 +108,7 @@ Definition of the Theme class.
|
||||
// Iterate over all files in the theme folder, producing an array, fmts,
|
||||
// containing info for each file. While we're doing that, also build up
|
||||
// the formatsHash object.
|
||||
var fmts = RECURSIVE_READ_DIR( tplFolder ).map( function( absPath ) {
|
||||
var fmts = READFILES(tplFolder).map( function(absPath) {
|
||||
|
||||
// If this file lives in a specific format folder within the theme,
|
||||
// such as "/latex" or "/html", then that format is the output format
|
||||
@ -135,7 +136,7 @@ Definition of the Theme class.
|
||||
// compact-[outputformat].[extension], for ex, compact-pdf.html.
|
||||
if( !outFmt ) {
|
||||
var idx = pathInfo.name.lastIndexOf('-');
|
||||
outFmt = ( idx === -1 ) ? pathInfo.name : pathInfo.name.substr( idx + 1 );
|
||||
outFmt = (idx === -1) ? pathInfo.name : pathInfo.name.substr(idx + 1);
|
||||
isMajor = true;
|
||||
}
|
||||
|
||||
@ -165,9 +166,13 @@ Definition of the Theme class.
|
||||
});
|
||||
|
||||
// Now, get all the CSS files...
|
||||
(this.cssFiles = fmts.filter(function( fmt ){ return fmt && (fmt.ext === 'css'); }))
|
||||
(this.cssFiles = fmts.filter(function( fmt ){
|
||||
return fmt && (fmt.ext === 'css');
|
||||
}))
|
||||
|
||||
// For each CSS file, get its corresponding HTML file
|
||||
.forEach(function( cssf ) {
|
||||
// For each CSS file, get its corresponding HTML file
|
||||
|
||||
var idx = _.findIndex(fmts, function( fmt ) {
|
||||
return fmt && fmt.pre === cssf.pre && fmt.ext === 'html';
|
||||
});
|
||||
@ -184,33 +189,39 @@ Definition of the Theme class.
|
||||
return formatsHash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Load the theme explicitly, by following the 'formats' hash
|
||||
in the theme's JSON settings file.
|
||||
*/
|
||||
function loadExplicit() {
|
||||
|
||||
var that = this;
|
||||
// Set up a hash of formats supported by this theme.
|
||||
// Housekeeping
|
||||
var formatsHash = { };
|
||||
|
||||
// Establish the base theme folder
|
||||
var tplFolder = PATH.join( this.folder, 'src' );
|
||||
|
||||
var act = null;
|
||||
var that = this;
|
||||
|
||||
// Iterate over all files in the theme folder, producing an array, fmts,
|
||||
// containing info for each file. While we're doing that, also build up
|
||||
// the formatsHash object.
|
||||
var fmts = RECURSIVE_READ_DIR( tplFolder ).map( function( absPath ) {
|
||||
var fmts = READFILES( tplFolder ).map( function( absPath ) {
|
||||
|
||||
act = null;
|
||||
// If this file is mentioned in the theme's JSON file under "transforms"
|
||||
var pathInfo = parsePath(absPath);
|
||||
var absPathSafe = absPath.trim().toLowerCase();
|
||||
var outFmt = _.find( Object.keys( that.formats ), function( fmtKey ) {
|
||||
var fmtVal = that.formats[ fmtKey ];
|
||||
return _.some( fmtVal.transform, function( fpath ) {
|
||||
var absPathB = PATH.join( that.folder, fpath ).trim().toLowerCase();
|
||||
return absPathB === absPathSafe;
|
||||
var outFmt = _.find(
|
||||
Object.keys( that.formats ),
|
||||
function( fmtKey ) {
|
||||
var fmtVal = that.formats[ fmtKey ];
|
||||
return _.some( fmtVal.transform, function(fpath) {
|
||||
var absPathB = PATH.join( that.folder, fpath )
|
||||
.trim().toLowerCase();
|
||||
return absPathB === absPathSafe;
|
||||
});
|
||||
});
|
||||
});
|
||||
if( outFmt ) {
|
||||
act = 'transform';
|
||||
}
|
||||
@ -231,7 +242,7 @@ Definition of the Theme class.
|
||||
// compact-[outputformat].[extension], for ex, compact-pdf.html.
|
||||
if( !outFmt ) {
|
||||
var idx = pathInfo.name.lastIndexOf('-');
|
||||
outFmt = ( idx === -1 ) ? pathInfo.name : pathInfo.name.substr( idx + 1 );
|
||||
outFmt = (idx === -1) ? pathInfo.name : pathInfo.name.substr(idx + 1);
|
||||
}
|
||||
|
||||
// We should have a valid output format now.
|
||||
@ -261,7 +272,11 @@ Definition of the Theme class.
|
||||
});
|
||||
|
||||
// Now, get all the CSS files...
|
||||
(this.cssFiles = fmts.filter(function( fmt ){ return fmt.ext === 'css'; }))
|
||||
(this.cssFiles = fmts.filter(function( fmt ){
|
||||
return fmt.ext === 'css';
|
||||
}))
|
||||
|
||||
// For each CSS file, get its corresponding HTML file
|
||||
.forEach(function( cssf ) {
|
||||
// For each CSS file, get its corresponding HTML file
|
||||
var idx = _.findIndex(fmts, function( fmt ) {
|
||||
@ -279,12 +294,22 @@ Definition of the Theme class.
|
||||
return formatsHash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Return a more friendly name for certain formats.
|
||||
TODO: Refactor
|
||||
*/
|
||||
function friendlyName( val ) {
|
||||
val = val.trim().toLowerCase();
|
||||
var friendly = { yml: 'yaml', md: 'markdown', txt: 'text' };
|
||||
return friendly[val] || val;
|
||||
}
|
||||
|
||||
module.exports = Theme;
|
||||
|
||||
|
||||
module.exports = FRESHTheme;
|
||||
|
||||
|
||||
|
||||
}());
|
85
src/core/jrs-theme.js
Normal file
85
src/core/jrs-theme.js
Normal file
@ -0,0 +1,85 @@
|
||||
/**
|
||||
Definition of the JRSTheme class.
|
||||
@module jrs-theme.js
|
||||
@license MIT. See LICENSE.MD for details.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
|
||||
var _ = require('underscore')
|
||||
, PATH = require('path')
|
||||
, parsePath = require('parse-filepath')
|
||||
, pathExists = require('path-exists').sync;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
The JRSTheme class is a representation of a JSON Resume
|
||||
theme asset. See also: FRESHTheme.
|
||||
@class JRSTheme
|
||||
*/
|
||||
function JRSTheme() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Open and parse the specified theme.
|
||||
@method open
|
||||
*/
|
||||
JRSTheme.prototype.open = function( thFolder ) {
|
||||
|
||||
this.folder = thFolder;
|
||||
|
||||
// Open the [theme-name].json file; should have the same
|
||||
// name as folder
|
||||
var pathInfo = parsePath( thFolder );
|
||||
|
||||
// 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.formats = {
|
||||
html: { title:'html', outFormat:'html', ext:'html' }
|
||||
};
|
||||
}
|
||||
else {
|
||||
throw { fluenterror: 10 };
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Determine if the theme supports the output format.
|
||||
@method hasFormat
|
||||
*/
|
||||
JRSTheme.prototype.hasFormat = function( fmt ) {
|
||||
return _.has( this.formats, fmt );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Return the requested output format.
|
||||
@method getFormat
|
||||
*/
|
||||
JRSTheme.prototype.getFormat = function( fmt ) {
|
||||
return this.formats[ fmt ];
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = JRSTheme;
|
||||
|
||||
|
||||
|
||||
}());
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
Status codes for HackMyResume.
|
||||
@module status-codes.js
|
||||
@license MIT. See LICENSE.MD for details.
|
||||
*/
|
||||
|
||||
(function(){
|
||||
@ -15,7 +16,8 @@ Status codes for HackMyResume.
|
||||
resumeNotFoundAlt: 6,
|
||||
inputOutputParity: 7,
|
||||
createNameMissing: 8,
|
||||
wkhtmltopdf: 9
|
||||
wkhtmltopdf: 9,
|
||||
missingPackageJSON: 10
|
||||
};
|
||||
|
||||
}());
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Generic template helper definitions for FluentCV.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
Generic template helper definitions for HackMyResume / FluentCV.
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module generic-helpers.js
|
||||
*/
|
||||
|
||||
@ -114,6 +114,16 @@ Generic template helper definitions for FluentCV.
|
||||
if (lhs || rhs) return options.fn(this);
|
||||
},
|
||||
|
||||
/**
|
||||
Conditional stylesheet link. Either display the link or embed the stylesheet
|
||||
via <style></style> tag.
|
||||
*/
|
||||
styleSheet: function( file, options ) {
|
||||
return ( this.opts.css === 'link') ?
|
||||
'<link href="' + file + '" rel="stylesheet" type="text/css">' :
|
||||
'<style>' + this.cssInfo.data + '</style>';
|
||||
},
|
||||
|
||||
/**
|
||||
Perform a generic comparison.
|
||||
See: http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates
|
||||
|
@ -40,6 +40,7 @@ Definition of the HandlebarsGenerator class.
|
||||
RAW: json,
|
||||
filt: opts.filters,
|
||||
cssInfo: cssInfo,
|
||||
opts: opts,
|
||||
headFragment: opts.headFragment || ''
|
||||
});
|
||||
|
||||
|
@ -11,7 +11,6 @@ Definition of the UnderscoreGenerator class.
|
||||
var _ = require('underscore');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Perform template-based resume generation using Underscore.js.
|
||||
@class UnderscoreGenerator
|
||||
@ -32,6 +31,10 @@ Definition of the UnderscoreGenerator class.
|
||||
// Strip {# comments #}
|
||||
jst = jst.replace( delims.comment, '');
|
||||
|
||||
var helpers = require('./generic-helpers');
|
||||
helpers.opts = opts;
|
||||
helpers.cssInfo = cssInfo;
|
||||
|
||||
// Compile and run the template. TODO: avoid unnecessary recompiles.
|
||||
var compiled = _.template(jst);
|
||||
var ret = compiled({
|
||||
@ -40,13 +43,15 @@ Definition of the UnderscoreGenerator class.
|
||||
XML: require('xml-escape'),
|
||||
RAW: json,
|
||||
cssInfo: cssInfo,
|
||||
headFragment: opts.headFragment || ''
|
||||
headFragment: opts.headFragment || '',
|
||||
opts: opts,
|
||||
h: helpers
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}());
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
Definition of the BaseGenerator class.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module base-generator.js
|
||||
@license MIT. See LICENSE.md for details.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Definition of the HtmlPngGenerator class.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@license MIT. See LICENSE.MD for details.
|
||||
@module html-png-generator.js
|
||||
*/
|
||||
|
||||
@ -11,7 +11,7 @@ Definition of the HtmlPngGenerator class.
|
||||
, HTML = require( 'html' );
|
||||
|
||||
/**
|
||||
An HTML-based PDF resume generator for HackMyResume.
|
||||
An HTML-based PNG resume generator for HackMyResume.
|
||||
*/
|
||||
var HtmlPngGenerator = module.exports = TemplateGenerator.extend({
|
||||
|
||||
@ -19,24 +19,29 @@ Definition of the HtmlPngGenerator class.
|
||||
this._super( 'png', 'html' );
|
||||
},
|
||||
|
||||
/**
|
||||
Generate the binary PDF.
|
||||
*/
|
||||
onBeforeSave: function( info ) {
|
||||
png( info.mk, info.outputFile );
|
||||
return null; // halt further processing
|
||||
invoke: function( rez, themeMarkup, cssInfo, opts ) {
|
||||
//return YAML.stringify( JSON.parse( rez.stringify() ), Infinity, 2 );
|
||||
},
|
||||
|
||||
generate: function( rez, f, opts ) {
|
||||
var htmlResults = opts.targets.filter(function(t){
|
||||
return t.fmt.outFormat === 'html';
|
||||
});
|
||||
var htmlFile = htmlResults[0].final.files.filter(function(fl){
|
||||
return fl.info.ext === 'html';
|
||||
});
|
||||
png(htmlFile[0].data, f);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
Generate a PDF from HTML.
|
||||
Generate a PNG from HTML.
|
||||
*/
|
||||
function png( markup, fOut ) {
|
||||
|
||||
require('webshot')( markup , { encoding: 'binary', siteType: 'html' } )
|
||||
.pipe( FS.createWriteStream( fOut ) );
|
||||
|
||||
// require('webshot')( markup , { encoding: 'binary', siteType: 'html' } )
|
||||
// .pipe( FS.createWriteStream( fOut ) );
|
||||
require('webshot')( markup , fOut, { siteType: 'html' }, function(err) { } );
|
||||
}
|
||||
|
||||
}());
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
Definition of the TemplateGenerator class.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module template-generator.js
|
||||
*/
|
||||
|
||||
@ -17,7 +17,8 @@ Definition of the TemplateGenerator class.
|
||||
, MKDIRP = require('mkdirp')
|
||||
, BaseGenerator = require( './base-generator' )
|
||||
, EXTEND = require('../utils/extend')
|
||||
, Theme = require('../core/theme');
|
||||
, FRESHTheme = require('../core/fresh-theme')
|
||||
, JRSTheme = require('../core/jrs-theme');
|
||||
|
||||
|
||||
|
||||
@ -77,7 +78,14 @@ Definition of the TemplateGenerator class.
|
||||
@method invoke
|
||||
@param rez A FreshResume object.
|
||||
@param opts Generator options.
|
||||
@returns An array of strings representing generated output files.
|
||||
@returns An array of objects representing the generated output files. Each
|
||||
object has this format:
|
||||
|
||||
{
|
||||
files: [ { info: { }, data: [ ] }, { ... } ],
|
||||
themeInfo: { }
|
||||
}
|
||||
|
||||
*/
|
||||
invoke: function( rez, opts ) {
|
||||
|
||||
@ -182,6 +190,8 @@ Definition of the TemplateGenerator class.
|
||||
});
|
||||
}
|
||||
|
||||
return genInfo;
|
||||
|
||||
},
|
||||
|
||||
|
||||
@ -220,20 +230,28 @@ Definition of the TemplateGenerator class.
|
||||
Given a theme title, load the corresponding theme.
|
||||
*/
|
||||
function themeFromMoniker() {
|
||||
|
||||
// Verify the specified theme name/path
|
||||
var tFolder = PATH.join(
|
||||
parsePath( require.resolve('fluent-themes') ).dirname,
|
||||
parsePath( require.resolve('fresh-themes') ).dirname,
|
||||
this.opts.theme
|
||||
);
|
||||
var exists = require('path-exists').sync;
|
||||
if( !exists( tFolder ) ) {
|
||||
tFolder = PATH.resolve( this.opts.theme );
|
||||
if( !exists( tFolder ) ) {
|
||||
throw { fluenterror: this.codes.themeNotFound, data: this.opts.theme};
|
||||
}
|
||||
}
|
||||
|
||||
var t = this.opts.themeObj || new Theme().open( tFolder );
|
||||
var t;
|
||||
if( this.opts.theme.startsWith('jsonresume-theme-') ) {
|
||||
console.log('LOADING JSON RESUME');
|
||||
t = new JRSTheme().open( tFolder );
|
||||
}
|
||||
else {
|
||||
var exists = require('path-exists').sync;
|
||||
if( !exists( tFolder ) ) {
|
||||
tFolder = PATH.resolve( this.opts.theme );
|
||||
if( !exists( tFolder ) ) {
|
||||
throw { fluenterror: this.codes.themeNotFound, data: this.opts.theme};
|
||||
}
|
||||
}
|
||||
t = this.opts.themeObj || new FRESHTheme().open( tFolder );
|
||||
}
|
||||
|
||||
// Load the theme and format
|
||||
return {
|
||||
|
@ -8,7 +8,8 @@ module.exports = {
|
||||
Sheet: require('./core/fresh-resume'),
|
||||
FRESHResume: require('./core/fresh-resume'),
|
||||
JRSResume: require('./core/jrs-resume'),
|
||||
Theme: require('./core/theme'),
|
||||
FRESHTheme: require('./core/fresh-theme'),
|
||||
JRSTheme: require('./core/jrs-theme'),
|
||||
FluentDate: require('./core/fluent-date'),
|
||||
HtmlGenerator: require('./gen/html-generator'),
|
||||
TextGenerator: require('./gen/text-generator'),
|
||||
|
@ -8,29 +8,34 @@ Internal resume generation logic for HackMyResume.
|
||||
module.exports = function () {
|
||||
|
||||
var unused = require('./utils/string')
|
||||
, PATH = require('path');
|
||||
, PATH = require('path')
|
||||
, FS = require('fs');
|
||||
|
||||
|
||||
/**
|
||||
Display help documentation.
|
||||
*/
|
||||
function help() {
|
||||
console.log( FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' )
|
||||
.useful.bold );
|
||||
var manPage = FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' );
|
||||
console.log( manPage.useful.bold );
|
||||
}
|
||||
|
||||
/**
|
||||
Internal module interface. Used by FCV Desktop and HMR.
|
||||
*/
|
||||
var v = {
|
||||
build: require('./verbs/generate'),
|
||||
validate: require('./verbs/validate'),
|
||||
convert: require('./verbs/convert'),
|
||||
new: require('./verbs/create'),
|
||||
help: help
|
||||
};
|
||||
|
||||
return {
|
||||
verbs: {
|
||||
generate: require('./verbs/generate'),
|
||||
build: require('./verbs/generate'),
|
||||
validate: require('./verbs/validate'),
|
||||
convert: require('./verbs/convert'),
|
||||
create: require('./verbs/create'),
|
||||
new: require('./verbs/create'),
|
||||
help: help
|
||||
verbs: v,
|
||||
alias: {
|
||||
generate: v.build,
|
||||
create: v.build
|
||||
},
|
||||
lib: require('./hackmyapi'),
|
||||
options: require('./core/default-options'),
|
||||
|
@ -55,7 +55,7 @@ function main() {
|
||||
// Get the action to be performed
|
||||
var params = a._.map( function(p){ return p.toLowerCase().trim(); });
|
||||
var verb = params[0];
|
||||
if( !FCMD.verbs[ verb ] ) {
|
||||
if( !FCMD.verbs[ verb ] && !FCMD.alias[ verb ] ) {
|
||||
logMsg('Invalid command: "'.warn + verb.warn.bold + '"'.warn);
|
||||
return;
|
||||
}
|
||||
@ -74,10 +74,9 @@ function main() {
|
||||
var src = a._.slice(1, splitAt === -1 ? undefined : splitAt );
|
||||
var dst = splitAt === -1 ? [] : a._.slice( splitAt + 1 );
|
||||
( splitAt === -1 ) && src.length > 1 && dst.push( src.pop() ); // Allow omitting TO keyword
|
||||
var parms = [ src, dst, opts, logMsg ];
|
||||
|
||||
// Invoke the action
|
||||
FCMD.verbs[ verb ].apply( null, parms );
|
||||
(FCMD.verbs[verb] || FCMD.alias[verb]).apply(null, [src, dst, opts, logMsg]);
|
||||
|
||||
}
|
||||
|
||||
@ -92,6 +91,7 @@ function getOpts( args ) {
|
||||
theme: args.t || 'modern',
|
||||
format: args.f || 'FRESH',
|
||||
prettify: !noPretty,
|
||||
silent: args.s || args.silent
|
||||
silent: args.s || args.silent,
|
||||
css: args.css || 'embed'
|
||||
};
|
||||
}
|
||||
|
@ -1,17 +1,29 @@
|
||||
/**
|
||||
Implementation of the 'generate' verb for HackMyResume.
|
||||
@module generate.js
|
||||
@license MIT. See LICENSE.md for details.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
|
||||
var PATH = require('path')
|
||||
, FS = require('fs')
|
||||
, parsePath = require('parse-filepath')
|
||||
, MD = require('marked')
|
||||
, MKDIRP = require('mkdirp')
|
||||
, EXTEND = require('../utils/extend')
|
||||
, parsePath = require('parse-filepath')
|
||||
, _opts = require('../core/default-options')
|
||||
, FluentTheme = require('../core/theme')
|
||||
, FluentTheme = require('../core/fresh-theme')
|
||||
, JRSTheme = require('../core/jrs-theme')
|
||||
, ResumeFactory = require('../core/resume-factory')
|
||||
, _ = require('underscore')
|
||||
, _fmts = require('../core/default-formats')
|
||||
, _err, _log, rez;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Handle an exception.
|
||||
*/
|
||||
@ -19,42 +31,29 @@
|
||||
throw ex;
|
||||
}
|
||||
|
||||
module.exports =
|
||||
|
||||
|
||||
/**
|
||||
Given a source JSON resume, a destination resume path, and a theme file,
|
||||
generate 0..N resumes in the desired formats.
|
||||
Given a source resume in FRESH or JRS format, a destination resume path, and a
|
||||
theme file, generate 0..N resumes in the desired formats.
|
||||
@param src Path to the source JSON resume file: "rez/resume.json".
|
||||
@param dst An array of paths to the target resume file(s).
|
||||
@param theme Friendly name of the resume theme. Defaults to "modern".
|
||||
@param logger Optional logging override.
|
||||
*/
|
||||
function generate( src, dst, opts, logger, errHandler ) {
|
||||
function build( src, dst, opts, logger, errHandler ) {
|
||||
|
||||
// Housekeeping...
|
||||
_log = logger || console.log;
|
||||
_err = errHandler || error;
|
||||
|
||||
//_opts = extend( true, _opts, opts );
|
||||
_opts.theme = (opts.theme && opts.theme.toLowerCase().trim())|| 'modern';
|
||||
_opts.prettify = opts.prettify === true ? _opts.prettify : false;
|
||||
_opts.css = opts.css;
|
||||
|
||||
// Verify the specified theme name/path
|
||||
var relativeThemeFolder = '../../node_modules/fluent-themes/themes';
|
||||
var tFolder = PATH.resolve( __dirname, relativeThemeFolder, _opts.theme);
|
||||
var exists = require('path-exists').sync;
|
||||
if( !exists( tFolder ) ) {
|
||||
tFolder = PATH.resolve( _opts.theme );
|
||||
if (!exists( tFolder )) {
|
||||
throw { fluenterror: 1, data: _opts.theme };
|
||||
}
|
||||
}
|
||||
|
||||
// Load the theme
|
||||
var theTheme = (new FluentTheme()).open( tFolder );
|
||||
_opts.themeObj = theTheme;
|
||||
var numFormats = theTheme.formats ? Object.keys(theTheme.formats).length : 2;
|
||||
_log( 'Applying '.info + theTheme.name.toUpperCase().infoBold +
|
||||
(' theme (' + numFormats + ' formats)').info);
|
||||
// Load the theme...
|
||||
var tFolder = verify_theme( _opts.theme );
|
||||
var theTheme = load_theme( tFolder );
|
||||
|
||||
// Load input resumes...
|
||||
if( !src || !src.length ) { throw { fluenterror: 3 }; }
|
||||
@ -70,41 +69,29 @@
|
||||
});
|
||||
msg && _log(msg);
|
||||
|
||||
// Expand output resumes... (can't use map() here)
|
||||
var targets = [], that = this;
|
||||
( (dst && dst.length && dst) || ['resume.all'] ).forEach( function(t) {
|
||||
|
||||
var to = PATH.resolve(t),
|
||||
pa = parsePath(to),
|
||||
fmat = pa.extname || '.all';
|
||||
|
||||
targets.push.apply(
|
||||
targets, fmat === '.all' ?
|
||||
|
||||
Object.keys( theTheme.formats ).map(function(k){
|
||||
var z = theTheme.formats[k];
|
||||
return { file: to.replace(/all$/g,z.outFormat), fmt: z };
|
||||
}) :
|
||||
|
||||
[{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]);
|
||||
|
||||
});
|
||||
// Expand output resumes...
|
||||
var targets = expand( dst, theTheme );
|
||||
|
||||
// Run the transformation!
|
||||
var finished = targets.map( function(t) { return single(t, theTheme); });
|
||||
targets.forEach( function(t) {
|
||||
t.final = single( t, theTheme, targets );
|
||||
});
|
||||
|
||||
// Don't send the client back empty-handed
|
||||
return { sheet: rez, targets: targets, processed: finished };
|
||||
};
|
||||
return { sheet: rez, targets: targets, processed: targets };
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Generate a single resume of a specific format.
|
||||
@param f Full path to the destination resume to generate, for example,
|
||||
"/foo/bar/resume.pdf" or "c:\foo\bar\resume.txt".
|
||||
Generate a single target resume such as "out/rez.html" or "out/rez.doc".
|
||||
@param targInfo Information for the target resume.
|
||||
@param theme A FRESHTheme or JRSTheme object.
|
||||
@returns
|
||||
*/
|
||||
function single( targInfo, theme ) {
|
||||
function single( targInfo, theme, finished ) {
|
||||
|
||||
function MDIN(txt) {
|
||||
function MDIN(txt) { // TODO: Move this
|
||||
return MD(txt || '' ).replace(/^\s*<p>|<\/p>\s*$/gi, '');
|
||||
}
|
||||
|
||||
@ -114,32 +101,32 @@
|
||||
, fName = PATH.basename(f, '.' + fType)
|
||||
, theFormat;
|
||||
|
||||
// If targInfo.fmt.files exists, this theme has an explicit "files"
|
||||
// section in its theme.json file.
|
||||
if( targInfo.fmt.files && targInfo.fmt.files.length ) {
|
||||
|
||||
_log( 'Generating '.useful +
|
||||
targInfo.fmt.outFormat.toUpperCase().useful.bold +
|
||||
' resume: '.useful + PATH.relative(process.cwd(), f ).replace(/\\/g,'/').useful.bold);
|
||||
' resume: '.useful + PATH.relative(process.cwd(), f ).useful.bold );
|
||||
|
||||
// If targInfo.fmt.files exists, this format is backed by a document.
|
||||
// Fluent/FRESH themes are handled here.
|
||||
if( targInfo.fmt.files && targInfo.fmt.files.length ) {
|
||||
theFormat = _fmts.filter(
|
||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||
MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
|
||||
theFormat.gen.generate( rez, f, _opts );
|
||||
_opts.targets = finished;
|
||||
return theFormat.gen.generate( rez, f, _opts );
|
||||
}
|
||||
// Otherwise the theme has no files section
|
||||
else {
|
||||
_log( 'Generating '.useful +
|
||||
targInfo.fmt.outFormat.toUpperCase().useful.bold +
|
||||
' resume: '.useful + PATH.relative(process.cwd(), f ).replace(/\\/g,'/').useful.bold);
|
||||
|
||||
theFormat = _fmts.filter(
|
||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||
// 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;
|
||||
|
||||
// TODO: refactor
|
||||
// JSON Resume themes have a 'render' method that needs to be called
|
||||
if( theme.render ) {
|
||||
var COPY = require('copy');
|
||||
var globs = [ /*'**',*/ '*.css', '*.js', '*.png', '*.jpg', '*.gif', '*.bmp' ];
|
||||
@ -151,7 +138,7 @@
|
||||
// }
|
||||
});
|
||||
|
||||
// Prevent JSON Resume theme .js from chattering
|
||||
// Prevent JSON Resume theme .js from chattering (TODO: redirect IO)
|
||||
var consoleLog = console.log;
|
||||
console.log = function() { };
|
||||
|
||||
@ -169,9 +156,12 @@
|
||||
|
||||
// Save the file
|
||||
FS.writeFileSync( f, rezHtml );
|
||||
|
||||
// Return markup to the client
|
||||
return rezHtml;
|
||||
}
|
||||
else {
|
||||
theFormat.gen.generate( rez, f, _opts );
|
||||
return theFormat.gen.generate( rez, f, _opts );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,4 +170,117 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Expand output files. For example, "foo.all" should be expanded to
|
||||
["foo.html", "foo.doc", "foo.pdf", "etc"].
|
||||
@param dst An array of output files as specified by the user.
|
||||
@param theTheme A FRESHTheme or JRSTheme object.
|
||||
*/
|
||||
function expand( dst, theTheme ) {
|
||||
|
||||
// Add freebie formats (JSON, YAML, PNG) every theme gets...
|
||||
// Add HTML-driven PNG only if the theme has an HTML format.
|
||||
theTheme.formats.json = theTheme.formats.json || {
|
||||
freebie: true, title: 'json', outFormat: 'json', pre: 'json',
|
||||
ext: 'json', path: null, data: null
|
||||
};
|
||||
theTheme.formats.yml = theTheme.formats.yml || {
|
||||
freebie: true, title: 'yaml', outFormat: 'yml', pre: 'yml',
|
||||
ext: 'yml', path: null, data: null
|
||||
};
|
||||
if( theTheme.formats.html && !theTheme.formats.png ) {
|
||||
theTheme.formats.png = {
|
||||
freebie: true, title: 'png', outFormat: 'png',
|
||||
ext: 'yml', path: null, data: null
|
||||
};
|
||||
}
|
||||
|
||||
// Set up the destination collection. It's either the array of files passed
|
||||
// by the user or 'out/resume.all' if no targets were specified.
|
||||
var destColl = (dst && dst.length && dst) ||
|
||||
[PATH.normalize('out/resume.all')];
|
||||
|
||||
// Assemble an array of expanded target files... (can't use map() here)
|
||||
var targets = [];
|
||||
destColl.forEach( function(t) {
|
||||
|
||||
var to = PATH.resolve(t), pa = parsePath(to),fmat = pa.extname || '.all';
|
||||
|
||||
var explicitFormats = _.omit( theTheme.formats, function(val, key) {
|
||||
return !val.freebie;
|
||||
});
|
||||
var implicitFormats = _.omit( theTheme.formats, function(val) {
|
||||
return val.freebie;
|
||||
});
|
||||
|
||||
targets.push.apply(
|
||||
targets, fmat === '.all' ?
|
||||
Object.keys( implicitFormats ).map( function( k ) {
|
||||
var z = theTheme.formats[k];
|
||||
return { file: to.replace( /all$/g, z.outFormat ), fmt: z };
|
||||
}) :
|
||||
[{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]);
|
||||
|
||||
targets.push.apply(
|
||||
targets, fmat === '.all' ?
|
||||
Object.keys( explicitFormats ).map( function( k ) {
|
||||
var z = theTheme.formats[k];
|
||||
return { file: to.replace( /all$/g, z.outFormat ), fmt: z };
|
||||
}) :
|
||||
[{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]);
|
||||
|
||||
});
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Verify the specified theme name/path.
|
||||
*/
|
||||
function verify_theme( themeNameOrPath ) {
|
||||
var tFolder = PATH.resolve(
|
||||
__dirname,
|
||||
'../../node_modules/fresh-themes/themes',
|
||||
themeNameOrPath
|
||||
);
|
||||
var exists = require('path-exists').sync;
|
||||
if( !exists( tFolder ) ) {
|
||||
tFolder = PATH.resolve( themeNameOrPath );
|
||||
if( !exists( tFolder ) ) {
|
||||
throw { fluenterror: 1, data: _opts.theme };
|
||||
}
|
||||
}
|
||||
return tFolder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Load the specified theme.
|
||||
*/
|
||||
function load_theme( tFolder ) {
|
||||
|
||||
// Create a FRESH or JRS theme object
|
||||
var theTheme = _opts.theme.indexOf('jsonresume-theme-') > -1 ?
|
||||
new JRSTheme().open(tFolder) : new FluentTheme().open( tFolder );
|
||||
|
||||
// Cache the theme object
|
||||
_opts.themeObj = theTheme;
|
||||
|
||||
// Output a message TODO: core should not log
|
||||
var numFormats = Object.keys(theTheme.formats).length;
|
||||
_log( 'Applying '.info + theTheme.name.toUpperCase().infoBold +
|
||||
(' theme (' + numFormats + ' formats)').info);
|
||||
return theTheme;
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = build;
|
||||
|
||||
|
||||
|
||||
}());
|
||||
|
@ -9,59 +9,54 @@ var chai = require('chai')
|
||||
|
||||
chai.config.includeStack = false;
|
||||
|
||||
describe('jane-doe.json (FRESH)', function () {
|
||||
function testResume(opts) {
|
||||
|
||||
var _sheet;
|
||||
describe( opts.title + ' (FRESH)', function () {
|
||||
|
||||
it('should open without throwing an exception', function () {
|
||||
function tryOpen() {
|
||||
_sheet = new FRESHResume().open(
|
||||
'node_modules/jane-q-fullstacker/resume/jane-resume.json' );
|
||||
}
|
||||
tryOpen.should.not.Throw();
|
||||
});
|
||||
var _sheet;
|
||||
|
||||
it('should have one or more of each section', function() {
|
||||
expect(
|
||||
//(_sheet.basics) &&
|
||||
_sheet.name && _sheet.info && _sheet.location && _sheet.contact &&
|
||||
(_sheet.employment.history && _sheet.employment.history.length > 0) &&
|
||||
(_sheet.skills && _sheet.skills.list.length > 0) &&
|
||||
(_sheet.education.history && _sheet.education.history.length > 0) &&
|
||||
(_sheet.service.history && _sheet.service.history.length > 0) &&
|
||||
(_sheet.writing && _sheet.writing.length > 0) &&
|
||||
(_sheet.recognition && _sheet.recognition.length > 0) &&
|
||||
(_sheet.samples && _sheet.samples.length > 0) &&
|
||||
(_sheet.references && _sheet.references.length > 0) &&
|
||||
(_sheet.interests && _sheet.interests.length > 0)
|
||||
).to.equal( true );
|
||||
});
|
||||
it('should open without throwing an exception', function () {
|
||||
function tryOpen() {
|
||||
_sheet = new FRESHResume().open( opts.path );
|
||||
}
|
||||
tryOpen.should.not.Throw();
|
||||
});
|
||||
|
||||
it('should have a work duration of 7 years', function() {
|
||||
_sheet.computed.numYears.should.equal( 7 );
|
||||
});
|
||||
it('should have one or more of each section', function() {
|
||||
var newObj = _.pick( _sheet, opts.sections );
|
||||
expect( Object.keys(newObj).length ).to.equal( opts.sections.length );
|
||||
});
|
||||
|
||||
it('should save without throwing an exception', function(){
|
||||
function trySave() {
|
||||
_sheet.save( 'test/sandbox/jane-q-fullstacker.json' );
|
||||
}
|
||||
trySave.should.not.Throw();
|
||||
});
|
||||
it('should have a work duration of ' + opts.duration + ' years', function() {
|
||||
_sheet.computed.numYears.should.equal( opts.duration );
|
||||
});
|
||||
|
||||
it('should not be modified after saving', function() {
|
||||
var savedSheet = new FRESHResume().open('test/sandbox/jane-q-fullstacker.json');
|
||||
_sheet.stringify().should.equal( savedSheet.stringify() );
|
||||
});
|
||||
it('should save without throwing an exception', function(){
|
||||
function trySave() {
|
||||
_sheet.save( 'test/sandbox/' + opts.title + '.json' );
|
||||
}
|
||||
trySave.should.not.Throw();
|
||||
});
|
||||
|
||||
it('should validate against the FRESH resume schema', function() {
|
||||
var result = _sheet.isValid();
|
||||
// var schemaJson = require('fresca');
|
||||
// var validate = validator( schemaJson, { verbose: true } );
|
||||
// var result = validate( JSON.parse( _sheet.imp.raw ) );
|
||||
result || console.log("\n\nOops, resume didn't validate. " +
|
||||
"Validation errors:\n\n", _sheet.imp.validationErrors, "\n\n");
|
||||
result.should.equal( true );
|
||||
});
|
||||
it('should not be modified after saving', function() {
|
||||
var savedSheet = new FRESHResume().open('test/sandbox/' + opts.title + '.json');
|
||||
_sheet.stringify().should.equal( savedSheet.stringify() );
|
||||
});
|
||||
|
||||
it('should validate against the FRESH resume schema', function() {
|
||||
var result = _sheet.isValid();
|
||||
// var schemaJson = require('fresca');
|
||||
// var validate = validator( schemaJson, { verbose: true } );
|
||||
// var result = validate( JSON.parse( _sheet.imp.raw ) );
|
||||
result || console.log("\n\nOops, resume didn't validate. " +
|
||||
"Validation errors:\n\n", _sheet.imp.validationErrors, "\n\n");
|
||||
result.should.equal( true );
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var sects = [ 'info', 'employment', 'service', 'skills', 'education', 'writing', 'recognition', 'references' ];
|
||||
testResume({ title: 'jane-q-fullstacker', path: 'node_modules/jane-q-fullstacker/resume/jane-resume.json', duration: 7, sections: sects });
|
||||
testResume({ title: 'johnny-trouble-resume', path: 'node_modules/johnny-trouble-resume/src/johnny-trouble.fresh.json', duration: 3, sections: sects });
|
||||
|
@ -12,7 +12,9 @@ var SPAWNWATCHER = require('../src/core/spawn-watch')
|
||||
|
||||
chai.config.includeStack = false;
|
||||
|
||||
describe('Testing themes', function () {
|
||||
function genThemes( title, src, fmt ) {
|
||||
|
||||
describe('Testing themes against ' + title.toUpperCase() + ' resume ' + '(' + fmt + ')' , function () {
|
||||
|
||||
var _sheet;
|
||||
|
||||
@ -29,11 +31,11 @@ describe('Testing themes', function () {
|
||||
|
||||
function genTheme( fmt, src, themeName, themeLoc, testTitle ) {
|
||||
themeLoc = themeLoc || themeName;
|
||||
testTitle = themeName.toUpperCase() + ' theme should generate without throwing an exception';
|
||||
testTitle = themeName.toUpperCase() + ' theme (' + fmt + ') should generate without throwing an exception';
|
||||
it( testTitle, function () {
|
||||
function tryOpen() {
|
||||
//var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
||||
var dst = ['test/sandbox/' + fmt + '/' + themeName + '/resume.all'];
|
||||
var dst = ['test/sandbox/' + fmt + '/' + title + '/' + themeName + '/resume.all'];
|
||||
var opts = {
|
||||
theme: themeLoc,
|
||||
format: fmt,
|
||||
@ -46,28 +48,21 @@ describe('Testing themes', function () {
|
||||
});
|
||||
}
|
||||
|
||||
var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
||||
genTheme('FRESH', src, 'hello-world');
|
||||
genTheme('FRESH', src, 'compact');
|
||||
genTheme('FRESH', src, 'modern');
|
||||
genTheme('FRESH', src, 'minimist');
|
||||
genTheme('FRESH', src, 'awesome');
|
||||
genTheme('FRESH', src, 'positive');
|
||||
genTheme('FRESH', src, 'jsonresume-theme-boilerplate', 'node_modules/jsonresume-theme-boilerplate' );
|
||||
genTheme('FRESH', src, 'jsonresume-theme-sceptile', 'node_modules/jsonresume-theme-sceptile' );
|
||||
genTheme('FRESH', src, 'jsonresume-theme-modern', 'node_modules/jsonresume-theme-modern' );
|
||||
genTheme('FRESH', src, 'jsonresume-theme-classy', 'node_modules/jsonresume-theme-classy' );
|
||||
genTheme(fmt, src, 'hello-world');
|
||||
genTheme(fmt, src, 'compact');
|
||||
genTheme(fmt, src, 'modern');
|
||||
genTheme(fmt, src, 'minimist');
|
||||
genTheme(fmt, src, 'awesome');
|
||||
genTheme(fmt, src, 'positive');
|
||||
genTheme(fmt, src, 'jsonresume-theme-boilerplate', 'node_modules/jsonresume-theme-boilerplate' );
|
||||
genTheme(fmt, src, 'jsonresume-theme-sceptile', 'node_modules/jsonresume-theme-sceptile' );
|
||||
genTheme(fmt, src, 'jsonresume-theme-modern', 'node_modules/jsonresume-theme-modern' );
|
||||
genTheme(fmt, src, 'jsonresume-theme-classy', 'node_modules/jsonresume-theme-classy' );
|
||||
|
||||
src = ['test/resumes/jrs-0.0.0/richard-hendriks.json'];
|
||||
genTheme('JRS', src, 'hello-world');
|
||||
genTheme('JRS', src, 'compact');
|
||||
genTheme('JRS', src, 'modern');
|
||||
genTheme('JRS', src, 'minimist');
|
||||
genTheme('JRS', src, 'awesome');
|
||||
genTheme('JRS', src, 'positive');
|
||||
genTheme('JRS', src, 'jsonresume-theme-boilerplate', 'node_modules/jsonresume-theme-boilerplate' );
|
||||
genTheme('JRS', src, 'jsonresume-theme-sceptile', 'node_modules/jsonresume-theme-sceptile' );
|
||||
genTheme('JRS', src, 'jsonresume-theme-modern', 'node_modules/jsonresume-theme-modern' );
|
||||
genTheme('JRS', src, 'jsonresume-theme-classy', 'node_modules/jsonresume-theme-classy' );
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
genThemes( 'jane-q-fullstacker', ['node_modules/jane-q-fullstacker/resume/jane-resume.json'], 'FRESH' );
|
||||
genThemes( 'johnny-trouble', ['node_modules/johnny-trouble-resume/src/johnny-trouble.fresh.json'], 'FRESH' );
|
||||
genThemes( 'richard-hendriks', ['test/resumes/jrs-0.0.0/richard-hendriks.json'], 'JRS' );
|
||||
|
Loading…
Reference in New Issue
Block a user