mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-10-31 13:17:26 +00:00 
			
		
		
		
	Introduce formal generators.
Introduce a shallow hierarchy of simple generator classes, collecting common functionality and allowing for future snap-in generator replacement. Use John Resig's "class"-based inheritance per http://ejohn.org/blog/simple-javascript-inheritance/.
This commit is contained in:
		
							
								
								
									
										13
									
								
								src/gen/base-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/gen/base-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /** | ||||
| Base resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| (function() { | ||||
|   var Class = require( './class' ); | ||||
|   var BaseGenerator = module.exports = Class.extend({ | ||||
|     init: function( outputFormat ) { | ||||
|       this.format = outputFormat; | ||||
|     } | ||||
|   }); | ||||
| }()); | ||||
							
								
								
									
										67
									
								
								src/gen/class.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/gen/class.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* Simple JavaScript Inheritance | ||||
|  * By John Resig http://ejohn.org/ | ||||
|  * MIT Licensed. | ||||
|  * http://ejohn.org/blog/simple-javascript-inheritance/ | ||||
|  */ | ||||
| // Inspired by base2 and Prototype | ||||
| (function(){ | ||||
|   var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; | ||||
|  | ||||
|   // The base Class implementation (does nothing) | ||||
|   this.Class = function(){}; | ||||
|   module.exports = Class; | ||||
|  | ||||
|   // Create a new Class that inherits from this class | ||||
|   Class.extend = function(prop) { | ||||
|     var _super = this.prototype; | ||||
|  | ||||
|     // Instantiate a base class (but only create the instance, | ||||
|     // don't run the init constructor) | ||||
|     initializing = true; | ||||
|     var prototype = new this(); | ||||
|     initializing = false; | ||||
|  | ||||
|     // Copy the properties over onto the new prototype | ||||
|     for (var name in prop) { | ||||
|       // Check if we're overwriting an existing function | ||||
|       prototype[name] = typeof prop[name] == "function" && | ||||
|         typeof _super[name] == "function" && fnTest.test(prop[name]) ? | ||||
|         (function(name, fn){ | ||||
|           return function() { | ||||
|             var tmp = this._super; | ||||
|  | ||||
|             // Add a new ._super() method that is the same method | ||||
|             // but on the super-class | ||||
|             this._super = _super[name]; | ||||
|  | ||||
|             // The method only need to be bound temporarily, so we | ||||
|             // remove it when we're done executing | ||||
|             var ret = fn.apply(this, arguments); | ||||
|             this._super = tmp; | ||||
|  | ||||
|             return ret; | ||||
|           }; | ||||
|         })(name, prop[name]) : | ||||
|         prop[name]; | ||||
|     } | ||||
|  | ||||
|     // The dummy class constructor | ||||
|     function Class() { | ||||
|       // All construction is actually done in the init method | ||||
|       if ( !initializing && this.init ) | ||||
|         this.init.apply(this, arguments); | ||||
|     } | ||||
|  | ||||
|     // Populate our constructed prototype object | ||||
|     Class.prototype = prototype; | ||||
|  | ||||
|     // Enforce the constructor to be what we expect | ||||
|     Class.prototype.constructor = Class; | ||||
|  | ||||
|     // And make this class extendable | ||||
|     Class.extend = arguments.callee; | ||||
|  | ||||
|     return Class; | ||||
|   }; | ||||
|  | ||||
| })(); | ||||
							
								
								
									
										31
									
								
								src/gen/html-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/gen/html-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| /** | ||||
| HTML resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
| var FS = require('fs-extra'); | ||||
| var HTML = require( 'html' ); | ||||
|  | ||||
| var HtmlGenerator = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function() { | ||||
|     this._super( 'html' ); | ||||
|   }, | ||||
|  | ||||
|   /** | ||||
|   Generate an HTML resume with optional pretty printing. | ||||
|   */ | ||||
|   onBeforeSave: function( mk, themeFile, outputFile ) { | ||||
|     var cssSrc = themeFile.replace( /.html$/g, '.css' ); | ||||
|     var cssDst = outputFile.replace( /.html$/g, '.css' ); | ||||
|     FS.copy( cssSrc, cssDst, function( e ) { | ||||
|       if( e ) err( "Couldn't copy CSS file to destination: " + err); | ||||
|     }); | ||||
|     return true ? | ||||
|       HTML.prettyPrint( mk, { indent_size: 2 } ) : mk; | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| module.exports = HtmlGenerator; | ||||
							
								
								
									
										31
									
								
								src/gen/html-pdf-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/gen/html-pdf-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| /** | ||||
| HTML-based PDF resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
| var FS = require('fs-extra'); | ||||
| var HTML = require( 'html' ); | ||||
|  | ||||
| var HtmlPdfGenerator = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function() { | ||||
|     this._super( 'pdf', 'html' ); | ||||
|   }, | ||||
|  | ||||
|   /** | ||||
|   Generate an HTML resume with optional pretty printing. | ||||
|   */ | ||||
|   onBeforeSave: function( mk, themeFile, outputFile ) { | ||||
|     var cssSrc = themeFile.replace( /.html$/g, '.css' ); | ||||
|     var cssDst = outputFile.replace( /.html$/g, '.css' ); | ||||
|     FS.copy( cssSrc, cssDst, function( e ) { | ||||
|       if( e ) err( "Couldn't copy CSS file to destination: " + err); | ||||
|     }); | ||||
|     return true ? | ||||
|       HTML.prettyPrint( mk, { indent_size: 2 } ) : mk; | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| module.exports = HtmlPdfGenerator; | ||||
							
								
								
									
										148
									
								
								src/gen/template-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								src/gen/template-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| /** | ||||
| Template-based resume generator base for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| (function() { | ||||
|  | ||||
|   var FS = require( 'fs' ); | ||||
|   var BaseGenerator = require( './base-generator' ); | ||||
|   var _ = require( 'underscore' ); | ||||
|   var MD = require( 'marked' ); | ||||
|   var XML = require( 'xml-escape' ); | ||||
|   var path = require('path'); | ||||
|  | ||||
|   var _opts = { | ||||
|     keepBreaks: true, | ||||
|     nSym: '&newl;', | ||||
|     rSym: '&retn;', | ||||
|     template: { | ||||
|       interpolate: /\{\{(.+?)\}\}/g, | ||||
|       escape: /\{\{\=(.+?)\}\}/g, | ||||
|       evaluate: /\{\%(.+?)\%\}/g, | ||||
|       comment: /\{\#(.+?)\#\}/g | ||||
|     }, | ||||
|     filters: { | ||||
|       out: function( txt ) { return txt; }, | ||||
|       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\>|\<\/p\>\s*$/gi, ''); }, | ||||
|       lower: function( txt ) { return txt.toLowerCase(); } | ||||
|     }, | ||||
|     prettyPrint: true, | ||||
|     prettyIndent: 2 | ||||
|   }; | ||||
|  | ||||
|   var TemplateGenerator = BaseGenerator.extend({ | ||||
|  | ||||
|     /** outputFormat: html, txt, pdf, doc | ||||
|         templateFormat: html or txt | ||||
|     **/ | ||||
|     init: function( outputFormat, templateFormat, cssFile ){ | ||||
|       this._super( outputFormat ); | ||||
|       this.tplFormat = templateFormat || outputFormat; | ||||
|     }, | ||||
|  | ||||
|     /** Default generation method for template-based generators. */ | ||||
|     generate: function( rez, f, themeName ) { | ||||
|       try { | ||||
|  | ||||
|         // Get the output file type (pdf, html, txt, etc) | ||||
|         var fName = path.basename( f, '.' + this.format ); | ||||
|  | ||||
|         // Load the active theme file, including CSS data if req'd | ||||
|         var themeFile = path.join( __dirname, '../../../watermark/', themeName, this.format + '.' + this.tplFormat ); | ||||
|         var cssData = this.tplFormat === 'html' ? FS.readFileSync( path.join( __dirname, '../../../watermark/', themeName, 'html.css' ), 'utf8' ) : null; | ||||
|         var mk = FS.readFileSync( themeFile, 'utf8' ); | ||||
|  | ||||
|         // Compile and invoke the template! | ||||
|         mk = this.single( rez, mk, this.format, cssData, fName ); | ||||
|         this.onBeforeSave && (mk = this.onBeforeSave( mk, themeFile, f )); | ||||
|  | ||||
|         // Post-process and save the file | ||||
|         FS.writeFileSync( f, mk, 'utf8' ); | ||||
|         return mk; | ||||
|       } | ||||
|       catch( ex ) { | ||||
|         err( ex ); | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|     Perform a single resume JSON-to-DEST resume transformation. Exists as a | ||||
|     separate function in order to expose string-based transformations to clients | ||||
|     who don't have access to filesystem resources (in-browser, etc.). | ||||
|     */ | ||||
|     single: function( json, jst, format, styles, fName ) { | ||||
|  | ||||
|       // Freeze whitespace in the template | ||||
|       _opts.keepBreaks && ( jst = freeze(jst) ); | ||||
|  | ||||
|       // Tweak underscore's default template delimeters | ||||
|       _.templateSettings = _opts.template; | ||||
|  | ||||
|       // Convert {{ someVar }} to {% print(filt.out(someVar) %} | ||||
|       // Convert {{ someVar|someFilter }} to {% print(filt.someFilter(someVar) %} | ||||
|       jst = jst.replace( _.templateSettings.interpolate, function replace(m, p1) { | ||||
|         if( p1.indexOf('|') > -1 ) { | ||||
|           var terms = p1.split('|'); | ||||
|           return '{% print( filt.' + terms[1] + '( ' + terms[0] + ' )) %}'; | ||||
|         } | ||||
|         else { | ||||
|           return '{% print( filt.out(' + p1 + ') ) %}'; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|       // Strip {# comments #} | ||||
|       jst = jst.replace( _.templateSettings.comment, ''); | ||||
|       json.display_progress_bar = true; | ||||
|  | ||||
|       // Compile and run the template. TODO: avoid unnecessary recompiles. | ||||
|       jst = _.template( jst )({ r: json, css: styles, embedCss: false, cssFile: fName, filt: _opts.filters }); | ||||
|  | ||||
|       // Unfreeze whitespace | ||||
|       _opts.keepBreaks && ( jst = unfreeze(jst) ); | ||||
|  | ||||
|       return jst; | ||||
|     } | ||||
|  | ||||
|  | ||||
|   }); | ||||
|  | ||||
|   /** | ||||
|   Export the TemplateGenerator function/ctor. | ||||
|   */ | ||||
|   module.exports = TemplateGenerator; | ||||
|  | ||||
|   /** | ||||
|   Freeze newlines for protection against errant JST parsers. | ||||
|   */ | ||||
|   function freeze( markup ) { | ||||
|     return markup | ||||
|       .replace( _reg.regN, _opts.nSym ) | ||||
|       .replace( _reg.regR, _opts.rSym ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   Unfreeze newlines when the coast is clear. | ||||
|   */ | ||||
|   function unfreeze( markup ) { | ||||
|     return markup | ||||
|       .replace( _reg.regSymR, '\r' ) | ||||
|       .replace( _reg.regSymN, '\n' ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|   Regexes for linebreak preservation. | ||||
|   */ | ||||
|   var _reg = { | ||||
|     regN: new RegExp( '\n', 'g' ), | ||||
|     regR: new RegExp( '\r', 'g' ), | ||||
|     regSymN: new RegExp( _opts.nSym, 'g' ), | ||||
|     regSymR: new RegExp( _opts.rSym, 'g' ) | ||||
|   }; | ||||
|  | ||||
|  | ||||
|  | ||||
| }()); | ||||
							
								
								
									
										15
									
								
								src/gen/text-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/gen/text-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /** | ||||
| Plain text resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
| var TextGenerator = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function(){ | ||||
|     this._super( 'txt' ); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
|  | ||||
| module.exports = TextGenerator; | ||||
							
								
								
									
										13
									
								
								src/gen/word-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/gen/word-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /** | ||||
| MS Word resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
| var WordGenerator = module.exports = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function(){ | ||||
|     this._super( 'doc', 'xml' ); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user