diff --git a/package.json b/package.json index 76b42a0..e8539e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hackmyresume", - "version": "1.2.1", + "version": "1.2.2", "description": "Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.", "repository": { "type": "git", @@ -49,6 +49,7 @@ "minimist": "^1.2.0", "mkdirp": "^0.5.1", "moment": "^2.10.6", + "parse-filepath": "^0.6.3", "path-exists": "^2.1.0", "recursive-readdir-sync": "^1.0.6", "simple-html-tokenizer": "^0.2.0", diff --git a/src/core/convert.js b/src/core/convert.js index 1113159..29f1a47 100644 --- a/src/core/convert.js +++ b/src/core/convert.js @@ -16,6 +16,7 @@ FRESH to JSON Resume conversion routiens. /** Convert from JSON Resume format to FRESH. @method toFresh + @todo Refactor */ toFRESH: function( src, foreign ) { @@ -67,6 +68,7 @@ FRESH to JSON Resume conversion routiens. Convert from FRESH format to JSON Resume. @param foreign True if non-JSON-Resume properties should be included in the result, false if those properties should be excluded. + @todo Refactor */ toJRS: function( src, foreign ) { @@ -112,6 +114,7 @@ FRESH to JSON Resume conversion routiens. }; function meta( direction, obj ) { + if( !obj ) return obj; // preserve null and undefined if( direction ) { obj = obj || { }; obj.format = obj.format || "FRESH@0.1.0"; @@ -121,6 +124,7 @@ FRESH to JSON Resume conversion routiens. } function employment( obj, direction ) { + if( !obj ) return obj; if( !direction ) { return obj && obj.history ? obj.history.map(function(emp){ @@ -157,6 +161,7 @@ FRESH to JSON Resume conversion routiens. function education( obj, direction ) { + if( !obj ) return obj; if( direction ) { return obj && obj.length ? { history: obj.map(function(edu){ @@ -191,6 +196,7 @@ FRESH to JSON Resume conversion routiens. } function service( obj, direction, foreign ) { + if( !obj ) return obj; if( direction ) { return { history: obj && obj.length ? obj.map(function(vol) { @@ -225,6 +231,7 @@ FRESH to JSON Resume conversion routiens. } function social( obj, direction ) { + if( !obj ) return obj; if( direction ) { return obj.map(function(pro){ return { @@ -247,6 +254,7 @@ FRESH to JSON Resume conversion routiens. } function recognition( obj, direction, foreign ) { + if( !obj ) return obj; if( direction ) { return obj && obj.length ? obj.map( function(awd){ @@ -275,6 +283,7 @@ FRESH to JSON Resume conversion routiens. } function references( obj, direction ) { + if( !obj ) return obj; if( direction ) { return obj && obj.length && obj.map(function(ref){ return { @@ -296,6 +305,7 @@ FRESH to JSON Resume conversion routiens. } function writing( obj, direction ) { + if( !obj ) return obj; if( direction ) { return obj.map(function( pub ) { return { diff --git a/src/core/theme.js b/src/core/theme.js index 1eaa1ea..3b5f729 100644 --- a/src/core/theme.js +++ b/src/core/theme.js @@ -11,6 +11,7 @@ Definition of the Theme class. , validator = require('is-my-json-valid') , _ = require('underscore') , PATH = require('path') + , parsePath = require('parse-filepath') , EXTEND = require('../utils/extend') , moment = require('moment') , RECURSIVE_READ_DIR = require('recursive-readdir-sync'); @@ -30,8 +31,8 @@ Definition of the Theme class. // Open the [theme-name].json file; should have the same name as folder this.folder = themeFolder; - var pathInfo = PATH.parse( themeFolder ); - var themeFile = PATH.join( themeFolder, pathInfo.base + '.json' ); + var pathInfo = parsePath( themeFolder ); + var themeFile = PATH.join( themeFolder, pathInfo.basename + '.json' ); var themeInfo = JSON.parse( FS.readFileSync( themeFile, 'utf8' ) ); var that = this; @@ -59,7 +60,7 @@ Definition of the Theme class. this.formats = formatsHash; // Set the official theme name - this.name = PATH.parse( this.folder ).name; + this.name = parsePath( this.folder ).name; return this; }; @@ -96,9 +97,9 @@ Definition of the Theme class. // If this file lives in a specific format folder within the theme, // such as "/latex" or "/html", then that format is the output format // for all files within the folder. - var pathInfo = PATH.parse(absPath); + var pathInfo = parsePath(absPath); var outFmt = '', isMajor = false; - var portion = pathInfo.dir.replace(tplFolder,''); + var portion = pathInfo.dirname.replace(tplFolder,''); if( portion && portion.trim() ) { if( portion[1] === '_' ) return; var reg = /^(?:\/|\\)(html|latex|doc|pdf|partials)(?:\/|\\)?/ig; @@ -135,7 +136,7 @@ Definition of the Theme class. path: absPath, major: isMajor, orgPath: PATH.relative(tplFolder, absPath), - ext: pathInfo.ext.slice(1), + ext: pathInfo.extname.slice(1), title: friendlyName( outFmt ), pre: outFmt, // outFormat: outFmt || pathInfo.name, @@ -186,7 +187,7 @@ Definition of the Theme class. act = null; // If this file is mentioned in the theme's JSON file under "transforms" - var pathInfo = PATH.parse(absPath); + var pathInfo = parsePath(absPath); var absPathSafe = absPath.trim().toLowerCase(); var outFmt = _.find( Object.keys( that.formats ), function( fmtKey ) { var fmtVal = that.formats[ fmtKey ]; @@ -203,7 +204,7 @@ Definition of the Theme class. // such as "/latex" or "/html", then that format is the output format // for all files within the folder. if( !outFmt ) { - var portion = pathInfo.dir.replace(tplFolder,''); + var portion = pathInfo.dirname.replace(tplFolder,''); if( portion && portion.trim() ) { var reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig; var res = reg.exec( portion ); @@ -231,7 +232,7 @@ Definition of the Theme class. action: act, orgPath: PATH.relative(that.folder, absPath), path: absPath, - ext: pathInfo.ext.slice(1), + ext: pathInfo.extname.slice(1), title: friendlyName( outFmt ), pre: outFmt, // outFormat: outFmt || pathInfo.name, diff --git a/src/gen/template-generator.js b/src/gen/template-generator.js index 4510ade..86687e8 100644 --- a/src/gen/template-generator.js +++ b/src/gen/template-generator.js @@ -13,6 +13,7 @@ Definition of the TemplateGenerator class. , MD = require( 'marked' ) , XML = require( 'xml-escape' ) , PATH = require('path') + , parsePath = require('parse-filepath') , MKDIRP = require('mkdirp') , BaseGenerator = require( './base-generator' ) , EXTEND = require('../utils/extend') @@ -127,7 +128,7 @@ Definition of the TemplateGenerator class. var theme = themeInfo.theme; var tFolder = themeInfo.folder; var tplFolder = PATH.join( tFolder, 'src' ); - var outFolder = PATH.parse(f).dir; + var outFolder = parsePath(f).dirname; var curFmt = theme.getFormat( this.format ); var that = this; @@ -176,7 +177,7 @@ Definition of the TemplateGenerator class. var absLoc = PATH.join(outFolder, loc); var absTarg = PATH.join(PATH.dirname(absLoc), curFmt.symLinks[loc]); // 'file', 'dir', or 'junction' (Windows only) - var type = PATH.parse( absLoc ).ext ? 'file' : 'junction'; + var type = parsePath( absLoc ).extname ? 'file' : 'junction'; FS.symlinkSync( absTarg, absLoc, type); }); } @@ -221,7 +222,7 @@ Definition of the TemplateGenerator class. function themeFromMoniker() { // Verify the specified theme name/path var tFolder = PATH.join( - PATH.parse( require.resolve('fluent-themes') ).dir, + parsePath( require.resolve('fluent-themes') ).dirname, this.opts.theme ); var exists = require('path-exists').sync; diff --git a/src/index.js b/src/index.js index 3f0bf40..5b65b71 100644 --- a/src/index.js +++ b/src/index.js @@ -91,6 +91,7 @@ function getOpts( args ) { }; } +// TODO: refactor function handleError( ex ) { var msg = '', exitCode; @@ -123,8 +124,10 @@ function handleError( ex ) { var idx = msg.indexOf('Error: '); var trimmed = idx === -1 ? msg : msg.substring( idx + 7 ); - if( !ex.fluenterror || ex.fluenterror < 3 ) + if( !ex.fluenterror || ex.fluenterror < 3 ) { // TODO: magic #s console.log( ('ERROR: ' + trimmed.toString()).red.bold ); + console.log( ex.stack.gray); + } else console.log( trimmed.toString() ); diff --git a/src/verbs/generate.js b/src/verbs/generate.js index 88857c8..d6629d2 100644 --- a/src/verbs/generate.js +++ b/src/verbs/generate.js @@ -1,6 +1,7 @@ (function() { var PATH = require('path') + , parsePath = require('parse-filepath') , MKDIRP = require('mkdirp') , _opts = require('../core/default-options') , FluentTheme = require('../core/theme') @@ -60,7 +61,7 @@ } // Load the theme - var theTheme = new FluentTheme().open( tFolder ); + var theTheme = (new FluentTheme()).open( tFolder ); _opts.themeObj = theTheme; _log( 'Applying '.info + theTheme.name.toUpperCase().infoBold + (' theme (' + Object.keys(theTheme.formats).length + ' formats)').info); @@ -70,8 +71,8 @@ ( (dst && dst.length && dst) || ['resume.all'] ).forEach( function(t) { var to = PATH.resolve(t), - pa = PATH.parse(to), - fmat = pa.ext || '.all'; + pa = parsePath(to), + fmat = pa.extname || '.all'; targets.push.apply(targets, fmat === '.all' ? Object.keys( theTheme.formats ).map(function(k){