diff --git a/src/cli/analyze.hbs b/src/cli/analyze.hbs new file mode 100644 index 0000000..aa64a51 --- /dev/null +++ b/src/cli/analyze.hbs @@ -0,0 +1,30 @@ + +{{style "SECTIONS (" "bold"}}{{style totals.numSections "white" }}{{style ")" "bold"}} + + employment: {{v totals.totals.employment "-" 2 "bold" }} + projects: {{v totals.totals.projects "-" 2 "bold" }} + education: {{v totals.totals.education "-" 2 "bold" }} + service: {{v totals.totals.service "-" 2 "bold" }} + skills: {{v totals.totals.skills "-" 2 "bold" }} + writing: {{v totals.totals.writing "-" 2 "bold" }} + speaking: {{v totals.totals.speaking "-" 2 "bold" }} + reading: {{v totals.totals.reading "-" 2 "bold" }} + social: {{v totals.totals.social "-" 2 "bold" }} + references: {{v totals.totals.references "-" 2 "bold" }} + testimonials: {{v totals.totals.testimonials "-" 2 "bold" }} + languages: {{v totals.totals.languages "-" 2 "bold" }} + interests: {{v totals.totals.interests "-" 2 "bold" }} + +{{style "COVERAGE (" "bold"}}{{style coverage.pct "white"}}{{style ")" "bold"}} + + Total Days: {{v coverage.duration.total "-" 5 "bold" }} + Employed: {{v coverage.duration.work "-" 5 "bold" }} + Gaps: {{v coverage.gaps.length "-" 5 "bold" }} [{{#if coverage.gaps.length }}{{#each coverage.gaps }}{{#unless @first}} {{/unless}}{{heat duration }}{{/each}}{{/if}}] + Overlaps: {{v coverage.overlaps.length "-" 5 "bold" }} [{{#if coverage.overlaps.length }}{{#each coverage.overlaps }}{{#unless @first}} {{/unless}}{{heat duration }}{{/each}}{{/if}}] + +{{style "KEYWORDS (" "bold"}}{{style keywords.length "white" }}{{style ")" "bold"}} + +{{#each keywords }}{{{pad name 18}}}: {{v count "-" 5 "bold"}} mention{{#isPlural count}}s{{/isPlural}} +{{/each}} + ------------------------------- +{{v keywords.length "0" 9 "bold"}} {{style "KEYWORDS" "bold"}} {{v keywords.totalKeywords "0" 5 "bold"}} {{style "mentions" "bold"}} diff --git a/src/cli/out.js b/src/cli/out.js index f76020d..63a191f 100644 --- a/src/cli/out.js +++ b/src/cli/out.js @@ -15,6 +15,9 @@ Output routines for HackMyResume. , _ = require('underscore') , Class = require('../utils/class.js') , PATH = require('path') + , LO = require('lodash') + , FS = require('fs') + , HANDLEBARS = require('handlebars') , pad = require('string-padding'); @@ -128,45 +131,18 @@ Output routines for HackMyResume. break; case HME.afterAnalyze: - // TODO: templatize all of this var info = evt.info; - var padding = 20; - this.log(chalk.cyan.bold('\nSECTIONS') + chalk.cyan(' (') + - chalk.white.bold(_.keys(info.totals).length) + chalk.cyan('):\n')); - - _.each( info.totals, function(tot, key) { - this.log(chalk.cyan(pad(key + ': ',20)) + - chalk.cyan.bold(pad(tot.toString(),5))); - }, this); - - this.log(); - this.log(chalk.cyan.bold('COVERAGE') + chalk.cyan(' (') + chalk.white.bold( info.coverage.pct ) + chalk.cyan('):\n')); - this.log(chalk.cyan(pad('Total Days: ', padding)) + chalk.cyan.bold( pad(info.coverage.duration.total.toString(),5) )); - this.log(chalk.cyan(pad('Employed: ', padding)) + chalk.cyan.bold( pad((info.coverage.duration.total - info.coverage.duration.gaps).toString(),5) )); - this.log(chalk.cyan(pad('Gaps: ', padding + 4)) + chalk.cyan.bold(info.coverage.gaps.length) + chalk.cyan(' [') + info.coverage.gaps.map(function(g) { - var clr = 'green'; - if( g.duration > 35 ) clr = 'yellow'; - if( g.duration > 90 ) clr = 'red'; - return chalk[clr].bold( g.duration) ; - }).join(', ') + chalk.cyan(']') ); - - this.log(chalk.cyan(pad('Overlaps: ', padding + 4)) + chalk.cyan.bold(info.coverage.overlaps.length) + chalk.cyan(' [') + info.coverage.overlaps.map(function(ol) { - var clr = 'green'; - if( ol.duration > 35 ) clr = 'yellow'; - if( ol.duration > 90 ) clr = 'red'; - return chalk[clr].bold( ol.duration) ; - }).join(', ') + chalk.cyan(']') ); - + var rawTpl = FS.readFileSync( PATH.join( __dirname, 'analyze.hbs' ), 'utf8'); + HANDLEBARS.registerHelper( consoleFormatHelpers ); + var template = HANDLEBARS.compile(rawTpl, { strict: false, assumeObjects: false }); var tot = 0; - this.log(); - this.log( chalk.cyan.bold('KEYWORDS') + chalk.cyan(' (') + chalk.white.bold( info.keywords.length ) + - chalk.cyan('):\n\n') + - info.keywords.map(function(g) { - tot += g.count; - return chalk.cyan( pad(g.name + ': ', padding) ) + chalk.cyan.bold( pad( g.count.toString(), 5 )) + chalk.cyan(' mentions'); - }).join('\n')); + info.keywords.forEach(function(g) { + tot += g.count; + }); + info.keywords.totalKeywords = tot; + var output = template( info ); - this.log(chalk.cyan( pad('TOTAL: ', padding) ) + chalk.white.bold( pad( tot.toString(), 5 )) + chalk.cyan(' mentions')); + this.log(chalk.cyan(output)); break; case HME.beforeConvert: @@ -183,5 +159,50 @@ Output routines for HackMyResume. }); + var consoleFormatHelpers = { + v: function( val, defaultVal, padding, style ) { + retVal = ( val === null || val === undefined ) ? defaultVal : val; + var spaces = 0; + if( String.is(padding) ) { + spaces = parseInt( padding, 10 ); + if( isNaN(spaces) ) spaces = 0; + } + else if( _.isNumber(padding) ) { + spaces = padding; + } + + if( spaces !== 0 ) + retVal = pad( retVal, Math.abs(spaces), null, spaces > 0 ? pad.LEFT : pad.RIGHT ); + + if( style && String.is( style )) { + retVal = LO.get( chalk, style )( retVal ); + } + + return retVal; + }, + + heat: function(val) { + if( val < 35 ) + return chalk.green.bold(val); + else if( val < 95 ) + return chalk.yellow.bold(val); + else + return chalk.red.bold(val); + }, + + style: function( val, style ) { + return LO.get( chalk, style )( val ); + }, + + isPlural: function( val, options ) { + if( val > 1 ) + return options.fn(this); + }, + + pad: function( val, spaces ) { + return pad(val, Math.abs(spaces), null, spaces > 0 ? pad.LEFT : pad.RIGHT ); + } + }; + }()); diff --git a/src/inspectors/totals-inspector.js b/src/inspectors/totals-inspector.js index f7432c4..06db4e4 100644 --- a/src/inspectors/totals-inspector.js +++ b/src/inspectors/totals-inspector.js @@ -30,25 +30,29 @@ Section analysis for HackMyResume. /** Run the Totals Inspector on a resume. @method run - @return An array of objects containing summary information for each section - on the resume. + @return An object containing summary information for each section on the + resume. */ run: function( rez ) { - var ret = { }; + var sectionTotals = { }; _.each( rez, function(val, key){ if( _.isArray( val ) && !_.isString(val) ) { - ret[ key ] = val.length; + sectionTotals[ key ] = val.length; } else if( val.history && _.isArray( val.history ) ) { - ret[ key ] = val.history.length; + sectionTotals[ key ] = val.history.length; } else if( val.sets && _.isArray( val.sets ) ) { - ret[ key ] = val.sets.length; + sectionTotals[ key ] = val.sets.length; } }); - return ret; + return { + totals: sectionTotals, + numSections: Object.keys( sectionTotals ).length + }; + }