mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-10-31 13:17:26 +00:00 
			
		
		
		
	Introduce FluentLib sources.
This commit is contained in:
		
							
								
								
									
										43
									
								
								src/gen/base-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/gen/base-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /** | ||||
| Base resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 | James M. Devlin | ||||
| */ | ||||
|  | ||||
| (function() { | ||||
|  | ||||
|   // Use J. Resig's nifty class implementation | ||||
|   var Class = require( '../utils/class' ); | ||||
|  | ||||
|   /** | ||||
|   The BaseGenerator class is the root of the generator hierarchy. Functionality | ||||
|   common to ALL generators lives here. | ||||
|   */ | ||||
|  | ||||
|   var BaseGenerator = module.exports = Class.extend({ | ||||
|  | ||||
|     /** | ||||
|     Base-class initialize. | ||||
|     */ | ||||
|     init: function( outputFormat ) { | ||||
|       this.format = outputFormat; | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|     Status codes. | ||||
|     */ | ||||
|     codes: { | ||||
|       success: 0, | ||||
|       themeNotFound: 1, | ||||
|       copyCss: 2, | ||||
|       resumeNotFound: 3 | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|     Generator options. | ||||
|     */ | ||||
|     opts: { | ||||
|  | ||||
|     } | ||||
|  | ||||
|   }); | ||||
| }()); | ||||
							
								
								
									
										32
									
								
								src/gen/html-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/gen/html-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /** | ||||
| 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 = module.exports = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function() { | ||||
|     this._super( 'html' ); | ||||
|   }, | ||||
|  | ||||
|   /** | ||||
|   Generate an HTML resume with optional pretty printing. | ||||
|   */ | ||||
|   onBeforeSave: function( mk, theme, outputFile ) { | ||||
|     var themeFile = theme.getFormat('html').path; | ||||
|     var cssSrc = themeFile.replace( /.html$/g, '.css' ); | ||||
|     var cssDst = outputFile.replace( /.html$/g, '.css' ); | ||||
|     var that = this; | ||||
|     FS.copySync( cssSrc, cssDst, { clobber: true }, function( e ) { | ||||
|       throw { fluenterror: that.codes.copyCss, data: [cssSrc,cssDst] }; | ||||
|     }); | ||||
|  | ||||
|     return this.opts.prettify ? | ||||
|       HTML.prettyPrint( mk, this.opts.prettify ) : mk; | ||||
|   } | ||||
|  | ||||
| }); | ||||
							
								
								
									
										74
									
								
								src/gen/html-pdf-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/gen/html-pdf-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /** | ||||
| 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 = module.exports = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function() { | ||||
|     this._super( 'pdf', 'html' ); | ||||
|   }, | ||||
|  | ||||
|   /** | ||||
|   Generate an HTML resume with optional pretty printing. | ||||
|   TODO: Avoid copying the CSS file to dest if we don't need to. | ||||
|   */ | ||||
|   onBeforeSave: function( mk, themeFile, outputFile ) { | ||||
|     // var cssSrc = themeFile.replace( /pdf\.html$/gi, 'html.css' ); | ||||
|     // var cssDst = outputFile.replace( /\.pdf$/gi, '.css' ); | ||||
|     // var that = this; | ||||
|     // FS.copySync( cssSrc, cssDst, { clobber: true }, function( e ) { | ||||
|     //   if( e ) that.err( "Couldn't copy CSS file to destination: " + e); | ||||
|     // }); | ||||
|     // return true ? | ||||
|     //   HTML.prettyPrint( mk, { indent_size: 2 } ) : mk; | ||||
|  | ||||
|     pdf(mk, outputFile); | ||||
|     return mk; | ||||
|   } | ||||
|  | ||||
| }); | ||||
|  | ||||
| /** | ||||
| Generate a PDF from HTML. | ||||
| */ | ||||
| function pdf( markup, fOut ) { | ||||
|  | ||||
|   var pdfCount = 0; | ||||
|   if( false ) { //( _opts.pdf === 'phantom' || _opts.pdf == 'all' ) { | ||||
|     pdfCount++; | ||||
|     require('phantom').create( function( ph ) { | ||||
|       ph.createPage( function( page ) { | ||||
|         page.setContent( markup ); | ||||
|         page.set('paperSize', { | ||||
|           format: 'A4', | ||||
|           orientation: 'portrait', | ||||
|           margin: '1cm' | ||||
|         }); | ||||
|         page.set("viewportSize", { | ||||
|           width: 1024, // TODO: option-ify | ||||
|           height: 768 // TODO: Use "A" sizes | ||||
|         }); | ||||
|         page.set('onLoadFinished', function(success) { | ||||
|           page.render( fOut ); | ||||
|           pdfCount++; | ||||
|           ph.exit(); | ||||
|         }); | ||||
|       }, | ||||
|       { dnodeOpts: {  weak: false   } } ); | ||||
|     }); | ||||
|   } | ||||
|   if( true ) { // _opts.pdf === 'wkhtmltopdf' || _opts.pdf == 'all' ) { | ||||
|     var fOut2 = fOut; | ||||
|     if( pdfCount == 1 ) { | ||||
|       fOut2 = fOut2.replace(/\.pdf$/g, '.b.pdf'); | ||||
|     } | ||||
|     require('wkhtmltopdf')( markup, { pageSize: 'letter' } ) | ||||
|       .pipe( FS.createWriteStream( fOut2 ) ); | ||||
|       pdfCount++; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										35
									
								
								src/gen/json-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/gen/json-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| /** | ||||
| Definition of the JsonGenerator class. | ||||
| @license Copyright (c) 2015 | James M. Devlin | ||||
| */ | ||||
|  | ||||
| var BaseGenerator = require('./base-generator'); | ||||
| var FS = require('fs'); | ||||
| var _ = require('underscore'); | ||||
|  | ||||
| /** | ||||
| The JsonGenerator generates a JSON resume directly. | ||||
| */ | ||||
| var JsonGenerator = module.exports = BaseGenerator.extend({ | ||||
|  | ||||
|   init: function(){ | ||||
|     this._super( 'json' ); | ||||
|   }, | ||||
|  | ||||
|   invoke: function( rez ) { | ||||
|     // TODO: merge with FCVD | ||||
|     function replacer( key,value ) { // Exclude these keys from stringification | ||||
|       return _.some(['meta', 'warnings', 'computed', 'filt', 'ctrl', 'index', | ||||
|         'safeStartDate', 'safeEndDate', 'safeDate', 'safeReleaseDate', 'result', | ||||
|       'isModified', 'htmlPreview'], | ||||
|         function( val ) { return key.trim() === val; } | ||||
|       ) ? undefined : value; | ||||
|     } | ||||
|     return JSON.stringify( rez, replacer, 2 ); | ||||
|   }, | ||||
|  | ||||
|   generate: function( rez, f ) { | ||||
|     FS.writeFileSync( f, this.invoke(rez), 'utf8' ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
							
								
								
									
										37
									
								
								src/gen/json-yaml-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/gen/json-yaml-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /** | ||||
| A JSON-driven YAML resume generator for FluentLib. | ||||
| @module json-yaml-generator.js | ||||
| @license MIT. Copyright (c) 2015 James Devlin / FluentDesk | ||||
| */ | ||||
|  | ||||
| (function() { | ||||
|  | ||||
|   var BaseGenerator = require('./base-generator'); | ||||
|   var FS = require('fs'); | ||||
|   var YAML = require('yamljs'); | ||||
|  | ||||
|   /** | ||||
|   JsonYamlGenerator takes a JSON resume object and translates it directly to | ||||
|   JSON without a template, producing an equivalent YAML-formatted resume. See | ||||
|   also YamlGenerator (yaml-generator.js). | ||||
|   */ | ||||
|  | ||||
|   var JsonYamlGenerator = module.exports = BaseGenerator.extend({ | ||||
|  | ||||
|     init: function(){ | ||||
|       this._super( 'yml' ); | ||||
|     }, | ||||
|  | ||||
|     invoke: function( rez, themeMarkup, cssInfo, opts ) { | ||||
|       return YAML.stringify( JSON.parse( rez.stringify() ), Infinity, 2 ); | ||||
|     }, | ||||
|  | ||||
|     generate: function( rez, f, opts ) { | ||||
|       var data = YAML.stringify( JSON.parse( rez.stringify() ), Infinity, 2 ); | ||||
|       FS.writeFileSync( f, data, 'utf8' ); | ||||
|     } | ||||
|  | ||||
|  | ||||
|   }); | ||||
|  | ||||
| }()); | ||||
							
								
								
									
										17
									
								
								src/gen/markdown-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/gen/markdown-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| /** | ||||
| Markdown resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
|  | ||||
| /** | ||||
| MarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator. | ||||
| */ | ||||
| var MarkdownGenerator = module.exports = TemplateGenerator.extend({ | ||||
|  | ||||
|   init: function(){ | ||||
|     this._super( 'md', 'txt' ); | ||||
|   } | ||||
|  | ||||
| }); | ||||
							
								
								
									
										173
									
								
								src/gen/template-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/gen/template-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| /** | ||||
| Template-based resume generator base for FluentCV. | ||||
| @license Copyright (c) 2015 | James M. Devlin | ||||
| */ | ||||
|  | ||||
| var FS = require( 'fs' ) | ||||
|   , _ = require( 'underscore' ) | ||||
|   , MD = require( 'marked' ) | ||||
|   , XML = require( 'xml-escape' ) | ||||
|   , PATH = require('path') | ||||
|   , BaseGenerator = require( './base-generator' ) | ||||
|   , EXTEND = require('../utils/extend') | ||||
|   , Theme = require('../core/theme'); | ||||
|  | ||||
| // Default options. | ||||
| var _defaultOpts = { | ||||
|   themeRelative: '../../node_modules/watermark/themes', | ||||
|   keepBreaks: true, | ||||
|   freezeBreaks: true, | ||||
|   nSym: '&newl;', // newline entity | ||||
|   rSym: '&retn;', // return entity | ||||
|   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(); } | ||||
|   }, | ||||
|   prettify: { // ← See https://github.com/beautify-web/js-beautify#options | ||||
|     indent_size: 2, | ||||
|     unformatted: ['em','strong'], | ||||
|     max_char: 80, // ← See lib/html.js in above-linked repo | ||||
|     //wrap_line_length: 120, <-- Don't use this | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
| TemplateGenerator performs resume generation via Underscore-style template | ||||
| expansion and is appropriate for text-based formats like HTML, plain text, | ||||
| and XML versions of Microsoft Word, Excel, and OpenOffice. | ||||
| */ | ||||
| var TemplateGenerator = module.exports = 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. */ | ||||
|   invoke: function( rez, themeMarkup, cssInfo, opts ) { | ||||
|  | ||||
|     // Compile and invoke the template! | ||||
|     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. */ | ||||
|   generate: function( rez, f, opts ) { | ||||
|  | ||||
|     // Carry over options | ||||
|     this.opts = EXTEND( true, { }, _defaultOpts, opts ); | ||||
|  | ||||
|     // Verify the specified theme name/path | ||||
|     var tFolder = PATH.resolve( __dirname, this.opts.themeRelative, this.opts.theme ); | ||||
|     var exists = require('../utils/file-exists'); | ||||
|     if (!exists( tFolder )) { | ||||
|       tFolder = PATH.resolve( this.opts.theme ); | ||||
|       if (!exists( tFolder )) { | ||||
|         throw { fluenterror: this.codes.themeNotFound, data: this.opts.theme }; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Load the theme | ||||
|     var theme = opts.themeObj || new Theme().open( tFolder ); | ||||
|  | ||||
|     // Load theme and CSS data | ||||
|     var tplFolder = PATH.join( tFolder, 'templates' ); | ||||
|     var curFmt = theme.getFormat( this.format ); | ||||
|     var ctx = { file: curFmt.css ? curFmt.cssPath : null, data: curFmt.css || null }; | ||||
|  | ||||
|     // Compile and invoke the template! | ||||
|     var mk = this.single( rez, curFmt.data, this.format, ctx, opts ); | ||||
|     this.onBeforeSave && (mk = this.onBeforeSave( mk, theme, f )); | ||||
|     FS.writeFileSync( f, mk, { encoding: 'utf8', flags: 'w' } ); | ||||
|  | ||||
|   }, | ||||
|  | ||||
|   /** | ||||
|   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, cssInfo, opts ) { | ||||
|  | ||||
|     // Freeze whitespace in the template. | ||||
|     this.opts.freezeBreaks && ( jst = freeze(jst) ); | ||||
|  | ||||
|     // Tweak underscore's default template delimeters | ||||
|     _.templateSettings = this.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, filt: this.opts.filters, cssInfo: cssInfo, headFragment: this.opts.headFragment || '' }); | ||||
|  | ||||
|     // Unfreeze whitespace | ||||
|     this.opts.freezeBreaks && ( 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, _defaultOpts.nSym ) | ||||
|     .replace( _reg.regR, _defaultOpts.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( _defaultOpts.nSym, 'g' ), | ||||
|   regSymR: new RegExp( _defaultOpts.rSym, 'g' ) | ||||
| }; | ||||
							
								
								
									
										19
									
								
								src/gen/text-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/gen/text-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| /** | ||||
| Plain text resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 by James M. Devlin. All rights reserved. | ||||
| */ | ||||
|  | ||||
| var TemplateGenerator = require('./template-generator'); | ||||
|  | ||||
| /** | ||||
| The TextGenerator generates a plain-text resume via the TemplateGenerator. | ||||
| */ | ||||
| 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' ); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
							
								
								
									
										17
									
								
								src/gen/xml-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/gen/xml-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| /** | ||||
| XML resume generator for FluentCV. | ||||
| @license Copyright (c) 2015 | James M. Devlin | ||||
| */ | ||||
|  | ||||
| var BaseGenerator = require('./base-generator'); | ||||
|  | ||||
| /** | ||||
| The XmlGenerator generates an XML resume via the TemplateGenerator. | ||||
| */ | ||||
| var XmlGenerator = module.exports = BaseGenerator.extend({ | ||||
|  | ||||
|   init: function(){ | ||||
|     this._super( 'xml' ); | ||||
|   }, | ||||
|  | ||||
| }); | ||||
							
								
								
									
										24
									
								
								src/gen/yaml-generator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/gen/yaml-generator.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| /** | ||||
| A YAML resume generator for FluentLib. | ||||
| @module yaml-generator.js | ||||
| @license MIT. Copyright (c) 2015 James Devlin / FluentDesk | ||||
| */ | ||||
|  | ||||
|  | ||||
| (function() { | ||||
|  | ||||
|   var TemplateGenerator = require('./template-generator'); | ||||
|  | ||||
|   /** | ||||
|   YamlGenerator generates a YAML-formatted resume via TemplateGenerator. | ||||
|   */ | ||||
|  | ||||
|   var YamlGenerator = module.exports = TemplateGenerator.extend({ | ||||
|  | ||||
|     init: function(){ | ||||
|       this._super( 'yml', 'yml' ); | ||||
|     } | ||||
|  | ||||
|   }); | ||||
|  | ||||
| }()); | ||||
		Reference in New Issue
	
	Block a user