From a54476eede679463a38f1a6c4171b5b911a59a22 Mon Sep 17 00:00:00 2001 From: hacksalot Date: Mon, 21 Dec 2015 00:36:08 -0500 Subject: [PATCH] Reaffirm string-based generation. In recent commits, HackMyResume generation logic, much like the pilots in Top Gun who became too reliant on air-to-air missiles and lost the true art of dogfighting, has become dependent on file-based generation as implicit file assumptions have crept in. This commit reaffirms the file-less, string-based nature of the generation process and, as a side effect, adjusts the behavior of (binary) PDF generation to match. --- src/core/theme.js | 2 +- src/eng/generic-helpers.js | 2 +- src/gen/html-generator.js | 10 --- src/gen/html-pdf-generator.js | 4 +- src/gen/template-generator.js | 116 ++++++++++++++++++++++++---------- 5 files changed, 88 insertions(+), 46 deletions(-) diff --git a/src/core/theme.js b/src/core/theme.js index 68d8fb8..1eaa1ea 100644 --- a/src/core/theme.js +++ b/src/core/theme.js @@ -134,7 +134,7 @@ Definition of the Theme class. action: 'transform', path: absPath, major: isMajor, - orgPath: PATH.relative(that.folder, absPath), + orgPath: PATH.relative(tplFolder, absPath), ext: pathInfo.ext.slice(1), title: friendlyName( outFmt ), pre: outFmt, diff --git a/src/eng/generic-helpers.js b/src/eng/generic-helpers.js index 167c23d..ab9c1f6 100644 --- a/src/eng/generic-helpers.js +++ b/src/eng/generic-helpers.js @@ -161,7 +161,7 @@ Generic template helper definitions for FluentCV. } else { idx = Math.min( lvl / 2, 4 ); - idx = Math.max( 0, intVal ); + idx = Math.max( 0, idx ); } return idx; } diff --git a/src/gen/html-generator.js b/src/gen/html-generator.js index 41bfbcd..8b82a3d 100644 --- a/src/gen/html-generator.js +++ b/src/gen/html-generator.js @@ -22,16 +22,6 @@ Definition of the HTMLGenerator class. the HTML resume prior to saving. */ onBeforeSave: function( info ) { - var cssSrc = PATH.join( info.theme.folder, 'src', '*.css' ) - , outFolder = PATH.parse( info.outputFile ).dir, that = this; - - info.theme.cssFiles.forEach( function( f ) { - var fi = PATH.parse( f.path ); - FS.copySync( f.path, PATH.join( outFolder, fi.base ), { clobber: true }, function( e ) { - throw { fluenterror: that.codes.copyCss, data: [cssSrc,cssDst] }; - }); - }); - return this.opts.prettify ? HTML.prettyPrint( info.mk, this.opts.prettify ) : info.mk; } diff --git a/src/gen/html-pdf-generator.js b/src/gen/html-pdf-generator.js index 6e32ea5..853de90 100644 --- a/src/gen/html-pdf-generator.js +++ b/src/gen/html-pdf-generator.js @@ -23,8 +23,8 @@ Definition of the HtmlPdfGenerator class. Generate the binary PDF. */ onBeforeSave: function( info ) { - pdf(info.mk, info.outputFile); - return info.mk; + pdf( info.mk, info.outputFile ); + return null; // halt further processing } }); diff --git a/src/gen/template-generator.js b/src/gen/template-generator.js index fb6ee39..e12eef0 100644 --- a/src/gen/template-generator.js +++ b/src/gen/template-generator.js @@ -38,7 +38,9 @@ Definition of the TemplateGenerator class. raw: function( txt ) { return txt; }, xml: function( txt ) { return XML(txt); }, md: function( txt ) { return MD( txt || '' ); }, - mdin: function( txt ) { return MD(txt || '' ).replace(/^\s*

|<\/p>\s*$/gi, ''); }, + mdin: function( txt ) { + return MD(txt || '' ).replace(/^\s*

|<\/p>\s*$/gi, ''); + }, lower: function( txt ) { return txt.toLowerCase(); }, link: function( name, url ) { return url ? '' + name + '' : name; } @@ -69,24 +71,14 @@ Definition of the TemplateGenerator class. }, - - invoke: function( rez, themeMarkup, cssInfo, opts ) { - this.opts = EXTEND( true, {}, _defaultOpts, opts ); - mk = this.single( rez, themeMarkup, this.format, cssInfo, { } ); - this.onBeforeSave && (mk = this.onBeforeSave( mk, themeFile, f )); - return mk; - }, - - - /** - Default generation method for template-based generators. - @method generate + String-based template generation method. + @method invoke @param rez A FreshResume object. - @param f Full path to the output resume file to generate. @param opts Generator options. + @returns An array of strings representing generated output files. */ - generate: function( rez, f, opts ) { + invoke: function( rez, opts ) { // Carry over options this.opts = EXTEND( true, { }, _defaultOpts, opts ); @@ -96,20 +88,81 @@ Definition of the TemplateGenerator class. var theme = themeInfo.theme; var tFolder = themeInfo.folder; var tplFolder = PATH.join( tFolder, 'src' ); + var curFmt = theme.getFormat( this.format ); + var that = this; + + // "Generate": process individual files within the theme + return { + files: curFmt.files.map( function( tplInfo ) { + return { + info: tplInfo, + data: tplInfo.action === 'transform' ? + transform.call( that, rez, tplInfo, theme ) : undefined + }; + }).filter(function(item){ return item !== null; }), + themeInfo: themeInfo + }; + + }, + + + + /** + File-based template generation method. + @method generate + @param rez A FreshResume object. + @param f Full path to the output resume file to generate. + @param opts Generator options. + */ + generate: function( rez, f, opts ) { + + // Call the generation method + var genInfo = this.invoke( rez, opts ); + + // Carry over options + this.opts = EXTEND( true, { }, _defaultOpts, opts ); + + // Load the theme + var themeInfo = genInfo.themeInfo; + var theme = themeInfo.theme; + var tFolder = themeInfo.folder; + var tplFolder = PATH.join( tFolder, 'src' ); var outFolder = PATH.parse(f).dir; var curFmt = theme.getFormat( this.format ); var that = this; // "Generate": process individual files within the theme - curFmt.files.forEach(function(tplInfo){ - if( tplInfo.action === 'transform' ) { - transform.call( that, rez, f, tplInfo, theme, outFolder ); + genInfo.files.forEach(function( file ){ + + var thisFilePath; + + if( file.info.action === 'transform' ) { + thisFilePath = PATH.join( outFolder, file.info.orgPath ); + try { + if( that.onBeforeSave ) { + file.data = that.onBeforeSave({ + theme: theme, + outputFile: (file.info.major ? f : thisFilePath), + mk: file.data + }); + if( !file.data ) return; // PDF etc + } + var fileName = file.info.major ? f : thisFilePath; + MKDIRP.sync( PATH.dirname( fileName ) ); + FS.writeFileSync( fileName, file.data, + { encoding: 'utf8', flags: 'w' } ); + that.onAfterSave && that.onAfterSave( + { outputFile: fileName, mk: file.data } ); + } + catch(ex) { + console.log(ex); + } } - else if( tplInfo.action === null && theme.explicit ) { - var thisFilePath = PATH.join(outFolder, tplInfo.orgPath); + else if( file.info.action === null/* && theme.explicit*/ ) { + thisFilePath = PATH.join( outFolder, file.info.orgPath ); try { MKDIRP.sync( PATH.dirname(thisFilePath) ); - FS.copySync( tplInfo.path, thisFilePath ); + FS.copySync( file.info.path, thisFilePath ); } catch(ex) { console.log(ex); @@ -142,8 +195,10 @@ Definition of the TemplateGenerator class. */ single: function( json, jst, format, cssInfo, opts, theme ) { this.opts.freezeBreaks && ( jst = freeze(jst) ); + var eng = require( '../eng/' + theme.engine + '-generator' ); var result = eng.generate( json, jst, format, cssInfo, opts, theme ); + this.opts.freezeBreaks && ( result = unfreeze(result) ); return result; } @@ -188,18 +243,15 @@ Definition of the TemplateGenerator class. - /** - Transform a single subfile. - */ - function transform( rez, f, tplInfo, theme, outFolder ) { - var cssInfo = { file: tplInfo.css ? tplInfo.cssPath : null, data: tplInfo.css || null }; - var mk = this.single( rez, tplInfo.data, this.format, cssInfo, this.opts, theme ); - this.onBeforeSave && (mk = this.onBeforeSave( { mk: mk, theme: theme, outputFile: f } )); - var thisFilePath = PATH.join( outFolder, tplInfo.orgPath ); + function transform( rez, tplInfo, theme ) { try { - MKDIRP.sync( PATH.dirname( tplInfo.major ? f : thisFilePath) ); - FS.writeFileSync( tplInfo.major ? f : thisFilePath, mk, { encoding: 'utf8', flags: 'w' } ); - this.onAfterSave && (mk = this.onAfterSave( { outputFile: (tplInfo.major ? f : thisFilePath), mk: mk } )); + var cssInfo = { + file: tplInfo.css ? tplInfo.cssPath : null, + data: tplInfo.css || null + }; + + return this.single( rez, tplInfo.data, this.format, cssInfo, this.opts, + theme ); } catch(ex) { console.log(ex);