mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-10-31 05:07:26 +00:00 
			
		
		
		
	Refactor generation.
Merge implicit and explicit generation paths, start emitting file transform & copy signals, fix various bugs, introduce new bugs, support better --debug outputs in the future.
This commit is contained in:
		| @@ -33,3 +33,6 @@ module.exports = | ||||
|   afterInlineConvert: 23 | ||||
|   beforeValidate:   24 | ||||
|   afterValidate:    25 | ||||
|   beforeWrite:      26 | ||||
|   afterWrite:       27 | ||||
|   applyTheme:       28 | ||||
|   | ||||
| @@ -69,13 +69,8 @@ class FRESHTheme | ||||
|         cached[ th ] = cached[th] || new FRESHTheme().open( themePath ) | ||||
|         formatsHash[ key ] = cached[ th ].getFormat( key ) | ||||
|  | ||||
|     # Check for an explicit "formats" entry in the theme JSON. If it has one, | ||||
|     # then this theme declares its files explicitly. | ||||
|     if !!@formats | ||||
|       formatsHash = loadExplicit.call this, formatsHash | ||||
|       @explicit = true; | ||||
|     else | ||||
|       formatsHash = loadImplicit.call this, formatsHash | ||||
|     # Load theme files | ||||
|     formatsHash = _load.call @, formatsHash | ||||
|  | ||||
|     # Cache | ||||
|     @formats = formatsHash | ||||
| @@ -91,9 +86,10 @@ class FRESHTheme | ||||
|   getFormat: ( fmt ) -> @formats[ fmt ] | ||||
|  | ||||
|  | ||||
|  | ||||
| ### Load the theme implicitly, by scanning the theme folder for files. TODO: | ||||
| Refactor duplicated code with loadExplicit. ### | ||||
| loadImplicit = (formatsHash) -> | ||||
| _load = (formatsHash) -> | ||||
|  | ||||
|   # Set up a hash of formats supported by this theme. | ||||
|   that = @ | ||||
| @@ -102,31 +98,43 @@ loadImplicit = (formatsHash) -> | ||||
|   # Establish the base theme folder | ||||
|   tplFolder = PATH.join @folder, 'src' | ||||
|  | ||||
|   copyOnly = ['.ttf','.otf', '.png','.jpg','.jpeg','.pdf'] | ||||
|  | ||||
|   # Iterate over all files in the theme folder, producing an array, fmts, | ||||
|   # containing info for each file. While we're doing that, also build up | ||||
|   # the formatsHash object. | ||||
|   fmts = READFILES(tplFolder).map (absPath) -> | ||||
|  | ||||
|     # 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. | ||||
|     pathInfo = parsePath absPath | ||||
|     absPathSafe = absPath.trim().toLowerCase() | ||||
|     outFmt = '' | ||||
|     isMajor = false | ||||
|     portion = pathInfo.dirname.replace tplFolder,'' | ||||
|     if portion && portion.trim() | ||||
|       return if portion[1] == '_' | ||||
|       reg = /^(?:\/|\\)(html|latex|doc|pdf|png|partials)(?:\/|\\)?/ig | ||||
|       res = reg.exec( portion ) | ||||
|       if res | ||||
|         if res[1] != 'partials' | ||||
|           outFmt = res[1] | ||||
|         else | ||||
|           that.partials = that.partials || [] | ||||
|           that.partials.push( { name: pathInfo.name, path: absPath } ) | ||||
|           return null | ||||
|  | ||||
|     # If this file is mentioned in the theme's JSON file under "transforms" | ||||
|     if that.formats | ||||
|       outFmt = _.find Object.keys( that.formats ), ( fmtKey ) -> | ||||
|           fmtVal = that.formats[ fmtKey ] | ||||
|           _.some fmtVal.transform, (fpath) -> | ||||
|             absPathB = PATH.join( that.folder, fpath ).trim().toLowerCase() | ||||
|             absPathB == absPathSafe | ||||
|       isMajor = true if outFmt | ||||
|  | ||||
|     if !outFmt | ||||
|       # 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. | ||||
|       portion = pathInfo.dirname.replace tplFolder,'' | ||||
|       if portion && portion.trim() | ||||
|         return if portion[1] == '_' | ||||
|         reg = /^(?:\/|\\)(html|latex|doc|pdf|png|partials)(?:\/|\\)?/ig | ||||
|         res = reg.exec( portion ) | ||||
|         if res | ||||
|           if res[1] != 'partials' | ||||
|             outFmt = res[1] | ||||
|           else | ||||
|             that.partials = that.partials || [] | ||||
|             that.partials.push( { name: pathInfo.name, path: absPath } ) | ||||
|             return null | ||||
|  | ||||
|     # Otherwise, the output format is inferred from the filename, as in | ||||
|     # compact-[outputformat].[extension], for ex, compact-pdf.html. | ||||
| @@ -135,23 +143,27 @@ loadImplicit = (formatsHash) -> | ||||
|       outFmt = if idx == -1 then pathInfo.name else pathInfo.name.substr( idx + 1 ) | ||||
|       isMajor = true | ||||
|  | ||||
|     act = if _.contains copyOnly, pathInfo.extname then 'copy' else 'transform' | ||||
|  | ||||
|     # We should have a valid output format now. | ||||
|     formatsHash[ outFmt ] = formatsHash[outFmt] || { | ||||
|       outFormat: outFmt, | ||||
|       files: [] | ||||
|     } | ||||
|     if that.formats?[ outFmt ]?.symLinks | ||||
|       formatsHash[ outFmt ].symLinks = that.formats[ outFmt ].symLinks | ||||
|  | ||||
|     # Create the file representation object. | ||||
|     obj = | ||||
|       action: 'transform' | ||||
|       action: act | ||||
|       path: absPath | ||||
|       major: isMajor | ||||
|       orgPath: PATH.relative(tplFolder, absPath) | ||||
|       ext: pathInfo.extname.slice(1) | ||||
|       title: friendlyName( outFmt ) | ||||
|       orgPath: PATH.relative tplFolder, absPath | ||||
|       ext: pathInfo.extname.slice 1 | ||||
|       title: friendlyName outFmt | ||||
|       pre: outFmt | ||||
|       # outFormat: outFmt || pathInfo.name, | ||||
|       data: FS.readFileSync( absPath, 'utf8' ) | ||||
|       data: FS.readFileSync absPath, 'utf8' | ||||
|       css: null | ||||
|  | ||||
|     # Add this file to the list of files for this format type. | ||||
| @@ -180,87 +192,90 @@ loadImplicit = (formatsHash) -> | ||||
|  | ||||
|  | ||||
|  | ||||
| ### | ||||
| Load the theme explicitly, by following the 'formats' hash | ||||
| in the theme's JSON settings file. | ||||
| ### | ||||
| loadExplicit = (formatsHash) -> | ||||
|  | ||||
|   # Housekeeping | ||||
|   tplFolder = PATH.join this.folder, 'src' | ||||
|   act = null | ||||
|   that = this | ||||
|  | ||||
|   # Iterate over all files in the theme folder, producing an array, fmts, | ||||
|   # containing info for each file. While we're doing that, also build up | ||||
|   # the formatsHash object. | ||||
|   fmts = READFILES( tplFolder ).map (absPath) -> | ||||
|  | ||||
|     act = null | ||||
|     # If this file is mentioned in the theme's JSON file under "transforms" | ||||
|     pathInfo = parsePath(absPath) | ||||
|     absPathSafe = absPath.trim().toLowerCase() | ||||
|     outFmt = _.find Object.keys( that.formats ), ( fmtKey ) -> | ||||
|         fmtVal = that.formats[ fmtKey ] | ||||
|         _.some fmtVal.transform, (fpath) -> | ||||
|           absPathB = PATH.join( that.folder, fpath ).trim().toLowerCase() | ||||
|           absPathB == absPathSafe | ||||
|  | ||||
|     act = 'transform' if outFmt | ||||
|  | ||||
|     # 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. | ||||
|     if !outFmt | ||||
|       portion = pathInfo.dirname.replace tplFolder,'' | ||||
|       if portion && portion.trim() | ||||
|         reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig | ||||
|         res = reg.exec portion | ||||
|         res && (outFmt = res[1]) | ||||
|  | ||||
|     # Otherwise, the output format is inferred from the filename, as in | ||||
|     # compact-[outputformat].[extension], for ex, compact-pdf.html. | ||||
|     if !outFmt | ||||
|       idx = pathInfo.name.lastIndexOf '-' | ||||
|       outFmt = if (idx == -1) then pathInfo.name else pathInfo.name.substr(idx + 1) | ||||
|  | ||||
|     # We should have a valid output format now. | ||||
|     formatsHash[ outFmt ] = | ||||
|       formatsHash[ outFmt ] || { | ||||
|         outFormat: outFmt, | ||||
|         files: [], | ||||
|         symLinks: that.formats[ outFmt ].symLinks | ||||
|       }; | ||||
|  | ||||
|     # Create the file representation object. | ||||
|     obj = | ||||
|       action: act | ||||
|       orgPath: PATH.relative(that.folder, absPath) | ||||
|       path: absPath | ||||
|       ext: pathInfo.extname.slice(1) | ||||
|       title: friendlyName( outFmt ) | ||||
|       pre: outFmt | ||||
|       # outFormat: outFmt || pathInfo.name, | ||||
|       data: FS.readFileSync( absPath, 'utf8' ) | ||||
|       css: null | ||||
|  | ||||
|     # Add this file to the list of files for this format type. | ||||
|     formatsHash[ outFmt ].files.push( obj ) | ||||
|     obj | ||||
|  | ||||
|   # Now, get all the CSS files... | ||||
|   @cssFiles = fmts.filter ( fmt ) -> fmt.ext == 'css' | ||||
|  | ||||
|   # For each CSS file, get its corresponding HTML file | ||||
|   @cssFiles.forEach ( cssf ) -> | ||||
|     # For each CSS file, get its corresponding HTML file | ||||
|     idx = _.findIndex fmts, ( fmt ) -> | ||||
|       fmt.pre == cssf.pre && fmt.ext == 'html' | ||||
|     fmts[ idx ].css = cssf.data; | ||||
|     fmts[ idx ].cssPath = cssf.path; | ||||
|   # Remove CSS files from the formats array | ||||
|   fmts = fmts.filter ( fmt) -> fmt.ext != 'css' | ||||
|   formatsHash | ||||
| # ### | ||||
| # Load the theme explicitly, by following the 'formats' hash | ||||
| # in the theme's JSON settings file. | ||||
| # ### | ||||
| # loadExplicit = (formatsHash) -> | ||||
| # | ||||
| #   # Housekeeping | ||||
| #   tplFolder = PATH.join this.folder, 'src' | ||||
| #   act = null | ||||
| #   that = this | ||||
| # | ||||
| #   # Iterate over all files in the theme folder, producing an array, fmts, | ||||
| #   # containing info for each file. While we're doing that, also build up | ||||
| #   # the formatsHash object. | ||||
| #   fmts = READFILES( tplFolder ).map (absPath) -> | ||||
| # | ||||
| #     act = null | ||||
| # | ||||
| #     pathInfo = parsePath absPath | ||||
| #     absPathSafe = absPath.trim().toLowerCase() | ||||
| # | ||||
| #     # If this file is mentioned in the theme's JSON file under "transforms" | ||||
| #     outFmt = _.find Object.keys( that.formats ), ( fmtKey ) -> | ||||
| #         fmtVal = that.formats[ fmtKey ] | ||||
| #         _.some fmtVal.transform, (fpath) -> | ||||
| #           absPathB = PATH.join( that.folder, fpath ).trim().toLowerCase() | ||||
| #           absPathB == absPathSafe | ||||
| # | ||||
| #     act = 'transform' if outFmt | ||||
| # | ||||
| #     # 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. | ||||
| #     if !outFmt | ||||
| #       portion = pathInfo.dirname.replace tplFolder,'' | ||||
| #       if portion && portion.trim() | ||||
| #         reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig | ||||
| #         res = reg.exec portion | ||||
| #         res && (outFmt = res[1]) | ||||
| # | ||||
| #     # Otherwise, the output format is inferred from the filename, as in | ||||
| #     # compact-[outputformat].[extension], for ex, compact-pdf.html. | ||||
| #     if !outFmt | ||||
| #       idx = pathInfo.name.lastIndexOf '-' | ||||
| #       outFmt = if (idx == -1) then pathInfo.name else pathInfo.name.substr(idx + 1) | ||||
| # | ||||
| #     # We should have a valid output format now. | ||||
| #     formatsHash[ outFmt ] = | ||||
| #       formatsHash[ outFmt ] || { | ||||
| #         outFormat: outFmt, | ||||
| #         files: [], | ||||
| #         symLinks: that.formats[ outFmt ].symLinks | ||||
| #       }; | ||||
| # | ||||
| #     # Create the file representation object. | ||||
| #     obj = | ||||
| #       action: act | ||||
| #       orgPath: PATH.relative(that.folder, absPath) | ||||
| #       path: absPath | ||||
| #       ext: pathInfo.extname.slice(1) | ||||
| #       title: friendlyName( outFmt ) | ||||
| #       pre: outFmt | ||||
| #       # outFormat: outFmt || pathInfo.name, | ||||
| #       data: FS.readFileSync( absPath, 'utf8' ) | ||||
| #       css: null | ||||
| # | ||||
| #     # Add this file to the list of files for this format type. | ||||
| #     formatsHash[ outFmt ].files.push( obj ) | ||||
| #     obj | ||||
| # | ||||
| #   # Now, get all the CSS files... | ||||
| #   @cssFiles = fmts.filter ( fmt ) -> fmt.ext == 'css' | ||||
| # | ||||
| #   # For each CSS file, get its corresponding HTML file | ||||
| #   @cssFiles.forEach ( cssf ) -> | ||||
| #     # For each CSS file, get its corresponding HTML file | ||||
| #     idx = _.findIndex fmts, ( fmt ) -> | ||||
| #       fmt.pre == cssf.pre && fmt.ext == 'html' | ||||
| #     fmts[ idx ].css = cssf.data | ||||
| #     fmts[ idx ].cssPath = cssf.path | ||||
| # | ||||
| #   # Remove CSS files from the formats array | ||||
| #   fmts = fmts.filter ( fmt) -> fmt.ext != 'css' | ||||
| #   formatsHash | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -29,6 +29,8 @@ plain text, and XML versions of Microsoft Word, Excel, and OpenOffice. | ||||
|  | ||||
| module.exports = class TemplateGenerator extends BaseGenerator | ||||
|  | ||||
|  | ||||
|  | ||||
|   ###* Constructor. Set the output format and template format for this | ||||
|   generator. Will usually be called by a derived generator such as | ||||
|   HTMLGenerator or MarkdownGenerator. ### | ||||
| @@ -60,19 +62,24 @@ module.exports = class TemplateGenerator extends BaseGenerator | ||||
|     curFmt.files = _.sortBy curFmt.files, (fi) -> fi.ext != 'css' | ||||
|  | ||||
|     # Run the transformation! | ||||
|     results = curFmt.files.map( ( tplInfo, idx ) -> | ||||
|       trx = @.single rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt | ||||
|       if tplInfo.ext == 'css' | ||||
|         curFmt.files[idx].data = trx | ||||
|       else tplInfo.ext == 'html' | ||||
|         #tplInfo.css contains the CSS data loaded by theme | ||||
|         #tplInfo.cssPath contains the absolute path to the source CSS File | ||||
|     results = curFmt.files.map ( tplInfo, idx ) -> | ||||
|       if tplInfo.action == 'transform' | ||||
|         trx = @transform rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt | ||||
|         if tplInfo.ext == 'css' | ||||
|           curFmt.files[idx].data = trx | ||||
|         else tplInfo.ext == 'html' | ||||
|           #tplInfo.css contains the CSS data loaded by theme | ||||
|           #tplInfo.cssPath contains the absolute path to the source CSS File | ||||
|       else | ||||
|         # Images and non-transformable binary files | ||||
|       opts.onTransform? tplInfo | ||||
|       return info: tplInfo, data: trx | ||||
|     , @) | ||||
|     , @ | ||||
|  | ||||
|     files: results | ||||
|  | ||||
|  | ||||
|  | ||||
|   ###* Generate a resume using file-based inputs and outputs. Requires access | ||||
|   to the local filesystem. | ||||
|   @method generate | ||||
| @@ -83,7 +90,7 @@ module.exports = class TemplateGenerator extends BaseGenerator | ||||
|   generate: ( rez, f, opts ) -> | ||||
|  | ||||
|     # Prepare | ||||
|     this.opts = EXTEND( true, { }, _defaultOpts, opts ); | ||||
|     @opts = EXTEND( true, { }, _defaultOpts, opts ); | ||||
|  | ||||
|     # Call the string-based generation method to perform the generation. | ||||
|     genInfo = this.invoke( rez, null ) | ||||
| @@ -93,43 +100,49 @@ module.exports = class TemplateGenerator extends BaseGenerator | ||||
|     # Process individual files within this format. For example, the HTML | ||||
|     # output format for a theme may have multiple HTML files, CSS files, | ||||
|     # etc. Process them here. | ||||
|     genInfo.files.forEach(( file ) -> | ||||
|     genInfo.files.forEach ( file ) -> | ||||
|  | ||||
|       # Pre-processing | ||||
|       file.info.orgPath = file.info.orgPath || '' # <-- For JRS themes | ||||
|       file.info.orgPath = file.info.orgPath || '' | ||||
|       thisFilePath = PATH.join( outFolder, file.info.orgPath ) | ||||
|       if this.onBeforeSave | ||||
|  | ||||
|       if file.info.action != 'copy' and @onBeforeSave | ||||
|         file.data = this.onBeforeSave | ||||
|           theme: opts.themeObj | ||||
|           outputFile: if file.info.major then f else thisFilePath | ||||
|           outputFile: thisFilePath #if file.info.major then f else thisFilePath | ||||
|           mk: file.data | ||||
|           opts: this.opts | ||||
|         if !file.data | ||||
|           return # PDF etc | ||||
|  | ||||
|       # Write the file | ||||
|       fileName = if file.info.major then f else thisFilePath | ||||
|       MKDIRP.sync PATH.dirname( fileName ) | ||||
|       FS.writeFileSync fileName, file.data, { encoding: 'utf8', flags: 'w' } | ||||
|       opts.beforeWrite? thisFilePath | ||||
|  | ||||
|       MKDIRP.sync PATH.dirname( thisFilePath ) | ||||
|  | ||||
|       #console.log( Object.keys(file.info) ) | ||||
|       console.log file.info.path | ||||
|  | ||||
|       if file.info.action != 'copy' | ||||
|         FS.writeFileSync thisFilePath, file.data, encoding: 'utf8', flags: 'w' | ||||
|       else | ||||
|         FS.copySync file.info.path, thisFilePath | ||||
|  | ||||
|       opts.afterWrite? thisFilePath | ||||
|  | ||||
|       # Post-processing | ||||
|       if @onAfterSave | ||||
|         @onAfterSave( outputFile: fileName, mk: file.data, opts: this.opts ) | ||||
|         @onAfterSave outputFile: fileName, mk: file.data, opts: this.opts | ||||
|  | ||||
|     , @) | ||||
|     , @ | ||||
|  | ||||
|     # Some themes require a symlink structure. If so, create it. | ||||
|     if curFmt.symLinks | ||||
|       Object.keys( curFmt.symLinks ).forEach (loc) -> | ||||
|         absLoc = PATH.join outFolder, loc | ||||
|         absTarg = PATH.join PATH.dirname(absLoc), curFmt.symLinks[loc] | ||||
|         # 'file', 'dir', or 'junction' (Windows only) | ||||
|         type = parsePath( absLoc ).extname ? 'file' : 'junction' | ||||
|         FS.symlinkSync absTarg, absLoc, type | ||||
|     createSymLinks curFmt, outFolder | ||||
|  | ||||
|     genInfo | ||||
|  | ||||
|  | ||||
|  | ||||
|   ###* Perform a single resume resume transformation using string-based inputs | ||||
|   and outputs without touching the local file system. | ||||
|   @param json A FRESH or JRS resume object. | ||||
| @@ -138,8 +151,8 @@ module.exports = class TemplateGenerator extends BaseGenerator | ||||
|   @param cssInfo Needs to be refactored. | ||||
|   @param opts Options and passthrough data. ### | ||||
|  | ||||
|   single: ( json, jst, format, opts, theme, curFmt ) -> | ||||
|     if this.opts.freezeBreaks | ||||
|   transform: ( json, jst, format, opts, theme, curFmt ) -> | ||||
|     if @opts.freezeBreaks | ||||
|       jst = freeze jst | ||||
|     eng = require '../renderers/' + theme.engine  + '-generator' | ||||
|     result = eng.generate json, jst, format, curFmt, opts, theme | ||||
| @@ -149,6 +162,29 @@ module.exports = class TemplateGenerator extends BaseGenerator | ||||
|  | ||||
|  | ||||
|  | ||||
| createSymLinks = ( curFmt, outFolder ) -> | ||||
|   # Some themes require a symlink structure. If so, create it. | ||||
|   if curFmt.symLinks | ||||
|     Object.keys( curFmt.symLinks ).forEach (loc) -> | ||||
|       absLoc = PATH.join outFolder, loc | ||||
|       absTarg = PATH.join PATH.dirname(absLoc), curFmt.symLinks[loc] | ||||
|       # Set type to 'file', 'dir', or 'junction' (Windows only) | ||||
|       type = if parsePath( absLoc ).extname then 'file' else 'junction' | ||||
|  | ||||
|       try | ||||
|         FS.symlinkSync absTarg, absLoc, type | ||||
|       catch | ||||
|         succeeded = false | ||||
|         if _error.code == 'EEXIST' | ||||
|           FS.unlinkSync absLoc | ||||
|           try | ||||
|             FS.symlinkSync absTarg, absLoc, type | ||||
|             succeeded = true | ||||
|         if !succeeded | ||||
|           throw ex | ||||
|     return | ||||
|  | ||||
|  | ||||
| ###* Freeze newlines for protection against errant JST parsers. ### | ||||
| freeze = ( markup ) -> | ||||
|   markup.replace( _reg.regN, _defaultOpts.nSym ) | ||||
| @@ -162,6 +198,7 @@ unfreeze = ( markup ) -> | ||||
|   markup.replace _reg.regSymN, '\n' | ||||
|  | ||||
|  | ||||
|  | ||||
| ###* Default template generator options. ### | ||||
| _defaultOpts = | ||||
|   engine: 'underscore' | ||||
|   | ||||
| @@ -22,12 +22,13 @@ UnderscoreGenerator = module.exports = | ||||
|   generateSimple: ( data, tpl ) -> | ||||
|     try | ||||
|       # Compile and run the Handlebars template. | ||||
|       tpl = _.template tpl | ||||
|       template data | ||||
|       t = _.template tpl | ||||
|       t data | ||||
|     catch | ||||
|       #console.dir _error | ||||
|       HMS = require '../core/status-codes' | ||||
|       throw | ||||
|         fluenterror: HMS[if tpl then 'invokeTemplate' else 'compileTemplate'] | ||||
|         fluenterror: HMS[if t then 'invokeTemplate' else 'compileTemplate'] | ||||
|         inner: _error | ||||
|  | ||||
|  | ||||
| @@ -49,9 +50,9 @@ UnderscoreGenerator = module.exports = | ||||
|       XML: require 'xml-escape' | ||||
|       RAW: json | ||||
|       cssInfo: cssInfo | ||||
|       #engine: this | ||||
|       #engine: @ | ||||
|       headFragment: opts.headFragment || '' | ||||
|       opts: opts | ||||
|  | ||||
|     registerHelpers theme, opts, cssInfo, ctx, this | ||||
|     registerHelpers theme, opts, cssInfo, ctx, @ | ||||
|     @generateSimple ctx, jst | ||||
|   | ||||
| @@ -59,7 +59,7 @@ _build = ( src, dst, opts ) -> | ||||
|     @err HMSTATUS.resumeNotFound, quit: true | ||||
|     return null | ||||
|  | ||||
|   _prep src, dst, opts | ||||
|   _prep.call @, src, dst, opts | ||||
|  | ||||
|   # Load input resumes as JSON... | ||||
|   sheetObjects = ResumeFactory.load src, | ||||
| @@ -175,6 +175,16 @@ _prep = ( src, dst, opts ) -> | ||||
|   _opts.noTips = opts.noTips | ||||
|   _opts.debug = opts.debug | ||||
|   _opts.sort = opts.sort | ||||
|   that = @ | ||||
|  | ||||
|   # Set up callbacks for internal generators | ||||
|   _opts.onTransform = (info) -> | ||||
|     that.stat HMEVENT.afterTransform, info; return | ||||
|   _opts.beforeWrite = (info) -> | ||||
|     that.stat HMEVENT.beforeWrite, info; return | ||||
|   _opts.afterWrite = (info) -> | ||||
|     that.stat HMEVENT.afterWrite, info; return | ||||
|  | ||||
|  | ||||
|   # If two or more files are passed to the GENERATE command and the TO | ||||
|   # keyword is omitted, the last file specifies the output file. | ||||
| @@ -203,7 +213,7 @@ _single = ( targInfo, theme, finished ) -> | ||||
|     fName = PATH.basename f, '.' + fType | ||||
|     theFormat = null | ||||
|  | ||||
|     @.stat HMEVENT.beforeGenerate, | ||||
|     @stat HMEVENT.beforeGenerate, | ||||
|       fmt: targInfo.fmt.outFormat | ||||
|       file: PATH.relative(process.cwd(), f) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user