mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-11-03 22:37:27 +00:00 
			
		
		
		
	Compare commits
	
		
			62 Commits
		
	
	
		
			v1.7.3
			...
			juan-canha
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					901659cc4f | ||
| 
						 | 
					3cf850ea0e | ||
| 
						 | 
					1b0bc87b60 | ||
| 
						 | 
					5d3b993737 | ||
| 
						 | 
					917fd8e3f3 | ||
| 
						 | 
					6ac2cd490b | ||
| 
						 | 
					8100190978 | ||
| 
						 | 
					7c36ff8331 | ||
| 
						 | 
					255a518565 | ||
| 
						 | 
					2d595350c6 | ||
| 
						 | 
					ca92d41d9e | ||
| 
						 | 
					3f8e795c61 | ||
| 
						 | 
					9927e79900 | ||
| 
						 | 
					dbef9f0a35 | ||
| 
						 | 
					c889664c31 | ||
| 
						 | 
					7a60cd0bab | ||
| 
						 | 
					964350d3c7 | ||
| 
						 | 
					b57d9f05af | ||
| 
						 | 
					b26799f9fc | ||
| 
						 | 
					daeffd27b5 | ||
| 
						 | 
					f87eb46549 | ||
| 
						 | 
					da7cd28734 | ||
| 
						 | 
					31e0bb69cc | ||
| 
						 | 
					5c248cca2a | ||
| 
						 | 
					f83eb018e8 | ||
| 
						 | 
					317a250917 | ||
| 
						 | 
					aaa5e1fc1f | ||
| 
						 | 
					1bc4263a46 | ||
| 
						 | 
					e191af1fb0 | ||
| 
						 | 
					7c0a9bcc02 | ||
| 
						 | 
					d894f62607 | ||
| 
						 | 
					2758038858 | ||
| 
						 | 
					661fb91861 | ||
| 
						 | 
					3c551eb923 | ||
| 
						 | 
					5bf4bda6de | ||
| 
						 | 
					49ae016f08 | ||
| 
						 | 
					89957aed76 | ||
| 
						 | 
					233025ddcc | ||
| 
						 | 
					11dd8952d8 | ||
| 
						 | 
					d7c83613df | ||
| 
						 | 
					a456093f13 | ||
| 
						 | 
					dd4851498a | ||
| 
						 | 
					f72b02a0f4 | ||
| 
						 | 
					63a0c78fc5 | ||
| 
						 | 
					fd39cc9fd9 | ||
| 
						 | 
					70f45d468d | ||
| 
						 | 
					212b01092c | ||
| 
						 | 
					36d641801b | ||
| 
						 | 
					bd278268f6 | ||
| 
						 | 
					abe31e30e0 | ||
| 
						 | 
					314d8d8763 | ||
| 
						 | 
					ed0792e8f8 | ||
| 
						 | 
					90765bf90b | ||
| 
						 | 
					f1ba7765ee | ||
| 
						 | 
					27c7a0264a | ||
| 
						 | 
					8e806dc04f | ||
| 
						 | 
					8ec6b5ed6a | ||
| 
						 | 
					4ef4ec5d42 | ||
| 
						 | 
					2f523b845b | ||
| 
						 | 
					1c416f39d3 | ||
| 
						 | 
					1de0eff7b3 | ||
| 
						 | 
					f8a39b0908 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -4,6 +4,7 @@ doc/
 | 
				
			|||||||
docs/
 | 
					docs/
 | 
				
			||||||
local/
 | 
					local/
 | 
				
			||||||
npm-debug.log
 | 
					npm-debug.log
 | 
				
			||||||
 | 
					*.map
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Emacs detritus
 | 
					# Emacs detritus
 | 
				
			||||||
# -*- mode: gitignore; -*-
 | 
					# -*- mode: gitignore; -*-
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								BUILDING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								BUILDING.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					Building
 | 
				
			||||||
 | 
					========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*See [CONTRIBUTING.md][contrib] for more information on contributing to the
 | 
				
			||||||
 | 
					HackMyResume or FluentCV projects.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HackMyResume is a standard Node.js command line app implemented in a mix of
 | 
				
			||||||
 | 
					CoffeeScript and JavaScript. Setting up a build environment is easy:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Prerequisites ##
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. OS: Linux, OS X, or Windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Install [Node.js][node] and [Grunt][grunt].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Set up a build environment ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Fork [hacksalot/HackMyResume][hmr] to your GitHub account.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Clone your fork locally.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. From within the top-level HackMyResume folder, run `npm install` to install
 | 
				
			||||||
 | 
					project dependencies.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. Create a new branch, based on the latest HackMyResume `dev` branch, to
 | 
				
			||||||
 | 
					contain your work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. Run `npm link` in the HackMyResume folder so that the `hackmyresume` command
 | 
				
			||||||
 | 
					will reference your local installation (you may need to
 | 
				
			||||||
 | 
					`npm uninstall -g hackmyresume` first).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Making changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. HackMyResume sources live in the [`/src`][src] folder. Always make your edits
 | 
				
			||||||
 | 
					there, never in the generated `/dist` folder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. After making your changes, run `grunt build` to package the HackMyResume
 | 
				
			||||||
 | 
					sources to the `/dist` folder. This will transform CoffeeScript files to
 | 
				
			||||||
 | 
					JavaScript and perform other build steps as necessary. In the future, a watch
 | 
				
			||||||
 | 
					task or guardfile will be added to automate this step.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Do local spot testing with `hackmyresume` as normal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. When you're ready to submit your changes, run `grunt test` to run the HMR
 | 
				
			||||||
 | 
					test suite. Fix any errors that occur.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. Commit and push your changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					6. Submit a pull request targeting the HackMyResume `dev` branch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node]: https://nodejs.org/en/
 | 
				
			||||||
 | 
					[grunt]: http://gruntjs.com/
 | 
				
			||||||
 | 
					[hmr]: https://github.com/hacksalot/HackMyResume
 | 
				
			||||||
 | 
					[src]: https://github.com/hacksalot/HackMyResume/tree/master/src
 | 
				
			||||||
 | 
					[contrib]: https://github.com/hacksalot/HackMyResume/blob/master/CONTRIBUTING.md
 | 
				
			||||||
							
								
								
									
										105
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,108 @@
 | 
				
			|||||||
CHANGELOG
 | 
					CHANGELOG
 | 
				
			||||||
=========
 | 
					=========
 | 
				
			||||||
 | 
					## v1.8.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Updated `Awesome` theme to latest version of [Awesome-CV][acv].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Introduced new theme helpers: `pad`, `date`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed an issue where the `Awesome` theme wouldn't correctly generate LaTeX
 | 
				
			||||||
 | 
					outputs (#138).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Emit a line number for syntax errors around embedded newlines in JSON strings
 | 
				
			||||||
 | 
					(#137).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fix several PDF / PNG generation errors (#132, others).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Display a more helpful error message when attempting to generate a PDF or PNG
 | 
				
			||||||
 | 
					on a machine where PhantomJS and/or wkhtmltopdf are either not installed or
 | 
				
			||||||
 | 
					not path-accessible.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed an issue that would cause long-running PDF/PNG generation to fail in
 | 
				
			||||||
 | 
					certain environments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed an issue involving an unhelpful spawn-related exception (#136).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- JSHint will no longer gripe at the use of `== null` and `!= null` in
 | 
				
			||||||
 | 
					CoffeeScript transpilation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Introduced [template-friendly Awesome-CV fork][awefork] to isolate template
 | 
				
			||||||
 | 
					expansion logic & provide better durability for HackMyResume's `awesome` theme.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed a couple temporary regressions (#139, #140) on the dev branch.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Additional tests.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Minor breaking HackMyResume API changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.7.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [Build instructions](https://github.com/hacksalot/HackMyResume/blob/master/BUILDING.md).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- More precise date handling.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue with incomplete PDF generation (#127).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue with building JSON Resume themes (#128).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue with generating `.json` output format by itself (#97).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.7.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue with generated PDFs being chopped off and displaying a mysterious sequence of numbers of unknown and possibly alien origin (#127).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Unsightly border on Modern:PDF.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Modern|Positive:PDF formats now correctly reference their PDF-specific CSS files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `Incorrect helper use` warning in Positive:DOC.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.7.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Interim release supporting FluentCV Desktop.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Moved [HackMyCore](https://github.com/hacksalot/HackMyCore) dependency to
 | 
				
			||||||
 | 
					submodule.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.7.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Caffeinate. CoffeeScript now used throughout
 | 
				
			||||||
 | 
					[HackMyResume](https://github.com/hacksalot/HackMyResume) and
 | 
				
			||||||
 | 
					[HackMyCore](https://github.com/hacksalot/HackMyCore); generated JavaScript
 | 
				
			||||||
 | 
					lives in `/dist`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue with generating a single PDF with the `.pdf` extension (#99).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.7.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [Internal] Relocated HMR processing code to the
 | 
				
			||||||
 | 
					[HackMyCore](https://github.com/hacksalot/HackMyCore) project. Shouldn't affect
 | 
				
			||||||
 | 
					normal use.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## v1.6.0
 | 
					## v1.6.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Major Improvements
 | 
					### Major Improvements
 | 
				
			||||||
@@ -304,3 +407,5 @@ theme.
 | 
				
			|||||||
[i111]: https://github.com/hacksalot/HackMyResume/issues/111
 | 
					[i111]: https://github.com/hacksalot/HackMyResume/issues/111
 | 
				
			||||||
[fresca]: https://github.com/fluentdesk/FRESCA
 | 
					[fresca]: https://github.com/fluentdesk/FRESCA
 | 
				
			||||||
[themes]: https://github.com/fluentdesk/fresh-themes
 | 
					[themes]: https://github.com/fluentdesk/fresh-themes
 | 
				
			||||||
 | 
					[awefork]: https://github.com/fluentdesk/Awesome-CV
 | 
				
			||||||
 | 
					[acv]: https://github.com/posquit0/Awesome-CV
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,17 +4,11 @@ Contributing
 | 
				
			|||||||
*Note: HackMyResume is also available as [FluentCV][fcv]. Contributors are
 | 
					*Note: HackMyResume is also available as [FluentCV][fcv]. Contributors are
 | 
				
			||||||
credited in both.*
 | 
					credited in both.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HackMyResume needs your help! Our contribution workflow is based on [GitHub
 | 
					 | 
				
			||||||
Flow][flow] and we respond to all pull requests and issues, usually within 24
 | 
					 | 
				
			||||||
hours. HackMyResume has no corporate affiliation and no commercial basis, which
 | 
					 | 
				
			||||||
allows the project to maintain a strict user-first policy, rapid development
 | 
					 | 
				
			||||||
velocity, and a liberal stance on contributions and exotic functionality in
 | 
					 | 
				
			||||||
keeping with the spirit (and name) of the tool.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In short, your code is welcome here.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## How To Contribute
 | 
					## How To Contribute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*See [BUILDING.md][building] for instructions on setting up a HackMyResume
 | 
				
			||||||
 | 
					development environment.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Optional: [**open an issue**][iss] identifying the feature or bug you'd like
 | 
					1. Optional: [**open an issue**][iss] identifying the feature or bug you'd like
 | 
				
			||||||
to implement or fix. This step isn't required — you can start hacking away on
 | 
					to implement or fix. This step isn't required — you can start hacking away on
 | 
				
			||||||
HackMyResume without clearing it with us — but helps avoid duplication of work
 | 
					HackMyResume without clearing it with us — but helps avoid duplication of work
 | 
				
			||||||
@@ -25,7 +19,7 @@ similar; call it whatever you like) to perform your work in.
 | 
				
			|||||||
4. **Install dependencies** by running `npm install` in the top-level
 | 
					4. **Install dependencies** by running `npm install` in the top-level
 | 
				
			||||||
HackMyResume folder.
 | 
					HackMyResume folder.
 | 
				
			||||||
5. Make your **commits** as usual.
 | 
					5. Make your **commits** as usual.
 | 
				
			||||||
6. **Verify** your changes locally with `npm test`.
 | 
					6. **Verify** your changes locally with `grunt test`.
 | 
				
			||||||
7. **Push** your commits.
 | 
					7. **Push** your commits.
 | 
				
			||||||
7. **Submit a pull request** from your feature branch to the HackMyResume `dev`
 | 
					7. **Submit a pull request** from your feature branch to the HackMyResume `dev`
 | 
				
			||||||
branch.
 | 
					branch.
 | 
				
			||||||
@@ -48,7 +42,7 @@ You can reach hacksalot directly at:
 | 
				
			|||||||
hacksalot@indevious.com
 | 
					hacksalot@indevious.com
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Thanks! See you out there in the trenches.
 | 
					Thanks for your interest in the HackMyResume project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[fcv]: https://github.com/fluentdesk/fluentcv
 | 
					[fcv]: https://github.com/fluentdesk/fluentcv
 | 
				
			||||||
[flow]: https://guides.github.com/introduction/flow/
 | 
					[flow]: https://guides.github.com/introduction/flow/
 | 
				
			||||||
@@ -56,3 +50,4 @@ Thanks! See you out there in the trenches.
 | 
				
			|||||||
[ha]: https://github.com/hacksalot
 | 
					[ha]: https://github.com/hacksalot
 | 
				
			||||||
[th]: https://github.com/tomheon
 | 
					[th]: https://github.com/tomheon
 | 
				
			||||||
[awesome]: https://github.com/hacksalot/HackMyResume/graphs/contributors
 | 
					[awesome]: https://github.com/hacksalot/HackMyResume/graphs/contributors
 | 
				
			||||||
 | 
					[building]: https://github.com/hacksalot/HackMyResume/blob/master/BUILDING.md
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,9 @@ module.exports = function (grunt) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    coffee: {
 | 
					    coffee: {
 | 
				
			||||||
      main: {
 | 
					      main: {
 | 
				
			||||||
 | 
					        options: {
 | 
				
			||||||
 | 
					          sourceMap: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        expand: true,
 | 
					        expand: true,
 | 
				
			||||||
        cwd: 'src',
 | 
					        cwd: 'src',
 | 
				
			||||||
        src: ['**/*.coffee'],
 | 
					        src: ['**/*.coffee'],
 | 
				
			||||||
@@ -67,7 +70,8 @@ module.exports = function (grunt) {
 | 
				
			|||||||
    jshint: {
 | 
					    jshint: {
 | 
				
			||||||
      options: {
 | 
					      options: {
 | 
				
			||||||
        laxcomma: true,
 | 
					        laxcomma: true,
 | 
				
			||||||
        expr: true
 | 
					        expr: true,
 | 
				
			||||||
 | 
					        eqnull: true
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      all: ['Gruntfile.js', 'dist/cli/**/*.js', 'test/*.js']
 | 
					      all: ['Gruntfile.js', 'dist/cli/**/*.js', 'test/*.js']
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
The MIT License
 | 
					The MIT License
 | 
				
			||||||
===============
 | 
					===============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright (c) 2016 hacksalot (https://github.com/hacksalot)
 | 
					Copyright (c) 2015-2016 hacksalot (https://github.com/hacksalot)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
of this software and associated documentation files (the "Software"), to deal
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ HackMyResume
 | 
				
			|||||||
[![Latest release][img-release]][latest-release]
 | 
					[![Latest release][img-release]][latest-release]
 | 
				
			||||||
[![Build status (MASTER)][img-master]][travis-url-master]
 | 
					[![Build status (MASTER)][img-master]][travis-url-master]
 | 
				
			||||||
[![Build status (DEV)][img-dev]][travis-url-dev]
 | 
					[![Build status (DEV)][img-dev]][travis-url-dev]
 | 
				
			||||||
 | 
					[](https://gitter.im/hacksalot/HackMyResume?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*Create polished résumés and CVs in multiple formats from your command line or
 | 
					*Create polished résumés and CVs in multiple formats from your command line or
 | 
				
			||||||
shell. Author in clean Markdown and JSON, export to Word, HTML, PDF, LaTeX,
 | 
					shell. Author in clean Markdown and JSON, export to Word, HTML, PDF, LaTeX,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								dist/cli/error.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								dist/cli/error.js
									
									
									
									
										vendored
									
									
								
							@@ -35,8 +35,7 @@ Error-handling routines for HackMyResume.
 | 
				
			|||||||
  require('string.prototype.startswith');
 | 
					  require('string.prototype.startswith');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Error handler for HackMyResume. All errors are handled here.
 | 
				
			||||||
  Error handler for HackMyResume. All errors are handled here.
 | 
					 | 
				
			||||||
  @class ErrorHandler
 | 
					  @class ErrorHandler
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,7 +61,7 @@ Error-handling routines for HackMyResume.
 | 
				
			|||||||
          stack = ex.stack || (ex.inner && ex.inner.stack);
 | 
					          stack = ex.stack || (ex.inner && ex.inner.stack);
 | 
				
			||||||
          stack && o(chalk.gray(stack));
 | 
					          stack && o(chalk.gray(stack));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (ex.quit || objError.quit) {
 | 
					        if (shouldExit) {
 | 
				
			||||||
          if (this.debug) {
 | 
					          if (this.debug) {
 | 
				
			||||||
            o(chalk.cyan('Exiting with error code ' + ex.fluenterror.toString()));
 | 
					            o(chalk.cyan('Exiting with error code ' + ex.fluenterror.toString()));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
@@ -140,7 +139,6 @@ Error-handling routines for HackMyResume.
 | 
				
			|||||||
        if (ex.inner) {
 | 
					        if (ex.inner) {
 | 
				
			||||||
          msg += chalk.red('\n' + ex.inner);
 | 
					          msg += chalk.red('\n' + ex.inner);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        withStack = true;
 | 
					 | 
				
			||||||
        quit = false;
 | 
					        quit = false;
 | 
				
			||||||
        etype = 'error';
 | 
					        etype = 'error';
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@@ -215,13 +213,27 @@ Error-handling routines for HackMyResume.
 | 
				
			|||||||
        if (SyntaxErrorEx.is(ex.inner)) {
 | 
					        if (SyntaxErrorEx.is(ex.inner)) {
 | 
				
			||||||
          console.error(printf(M2C(this.msgs.readError.msg, 'red'), ex.file));
 | 
					          console.error(printf(M2C(this.msgs.readError.msg, 'red'), ex.file));
 | 
				
			||||||
          se = new SyntaxErrorEx(ex, ex.raw);
 | 
					          se = new SyntaxErrorEx(ex, ex.raw);
 | 
				
			||||||
          msg = printf(M2C(this.msgs.parseError.msg, 'red'), se.line, se.col);
 | 
					          if ((se.line != null) && (se.col != null)) {
 | 
				
			||||||
        } else if (ex.inner && ex.inner.line !== void 0 && ex.inner.col !== void 0) {
 | 
					            msg = printf(M2C(this.msgs.parseError.msg[0], 'red'), se.line, se.col);
 | 
				
			||||||
          msg = printf(M2C(this.msgs.parseError.msg, 'red'), ex.inner.line, ex.inner.col);
 | 
					          } else if (se.line != null) {
 | 
				
			||||||
 | 
					            msg = printf(M2C(this.msgs.parseError.msg[1], 'red'), se.line);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            msg = M2C(this.msgs.parseError.msg[2], 'red');
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else if (ex.inner && (ex.inner.line != null) && (ex.inner.col != null)) {
 | 
				
			||||||
 | 
					          msg = printf(M2C(this.msgs.parseError.msg[0], 'red'), ex.inner.line, ex.inner.col);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          msg = ex;
 | 
					          msg = ex;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        etype = 'error';
 | 
					        etype = 'error';
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case HMSTATUS.createError:
 | 
				
			||||||
 | 
					        msg = printf(M2C(this.msgs.createError.msg), ex.inner.path);
 | 
				
			||||||
 | 
					        etype = 'error';
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case HMSTATUS.validateError:
 | 
				
			||||||
 | 
					        msg = printf(M2C(this.msgs.validateError.msg), ex.inner.toString());
 | 
				
			||||||
 | 
					        etype = 'error';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      msg: msg,
 | 
					      msg: msg,
 | 
				
			||||||
@@ -232,3 +244,5 @@ Error-handling routines for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=error.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								dist/cli/main.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								dist/cli/main.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ Definition of the `main` function.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var Command, EXTEND, FS, HME, HMR, HMSTATUS, OUTPUT, PAD, PATH, PKG, StringUtils, _, _opts, _out, _title, chalk, execute, initOptions, initialize, loadOptions, logMsg, main, safeLoadJSON, splitSrcDest;
 | 
					  var Command, EXTEND, FS, HME, HMR, HMSTATUS, M2C, OUTPUT, PAD, PATH, PKG, StringUtils, _, _err, _exitCallback, _opts, _out, _title, chalk, execute, executeFail, executeSuccess, initOptions, initialize, loadOptions, logMsg, main, printf, safeLoadJSON, splitSrcDest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HMR = require('../index');
 | 
					  HMR = require('../index');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,12 +36,20 @@ Definition of the `main` function.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Command = require('commander').Command;
 | 
					  Command = require('commander').Command;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  M2C = require('../utils/md2chalk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  printf = require('printf');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _opts = {};
 | 
					  _opts = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _title = chalk.white.bold('\n*** HackMyResume v' + PKG.version + ' ***');
 | 
					  _title = chalk.white.bold('\n*** HackMyResume v' + PKG.version + ' ***');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _out = new OUTPUT(_opts);
 | 
					  _out = new OUTPUT(_opts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _err = require('./error');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _exitCallback = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
  A callable implementation of the HackMyResume CLI. Encapsulates the command
 | 
					  A callable implementation of the HackMyResume CLI. Encapsulates the command
 | 
				
			||||||
@@ -51,9 +59,9 @@ Definition of the `main` function.
 | 
				
			|||||||
  process.argv (in production) or custom parameters (in test).
 | 
					  process.argv (in production) or custom parameters (in test).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  main = module.exports = function(rawArgs) {
 | 
					  main = module.exports = function(rawArgs, exitCallback) {
 | 
				
			||||||
    var args, initInfo, program;
 | 
					    var args, initInfo, program;
 | 
				
			||||||
    initInfo = initialize(rawArgs);
 | 
					    initInfo = initialize(rawArgs, exitCallback);
 | 
				
			||||||
    args = initInfo.args;
 | 
					    args = initInfo.args;
 | 
				
			||||||
    program = new Command('hackmyresume').version(PKG.version).description(chalk.yellow.bold('*** HackMyResume ***')).option('-s --silent', 'Run in silent mode').option('--no-color', 'Disable colors').option('--color', 'Enable colors').option('-d --debug', 'Enable diagnostics', false).option('-a --assert', 'Treat warnings as errors', false).option('-v --version', 'Show the version').allowUnknownOption();
 | 
					    program = new Command('hackmyresume').version(PKG.version).description(chalk.yellow.bold('*** HackMyResume ***')).option('-s --silent', 'Run in silent mode').option('--no-color', 'Disable colors').option('--color', 'Enable colors').option('-d --debug', 'Enable diagnostics', false).option('-a --assert', 'Treat warnings as errors', false).option('-v --version', 'Show the version').allowUnknownOption();
 | 
				
			||||||
    program.jsonArgs = initInfo.options;
 | 
					    program.jsonArgs = initInfo.options;
 | 
				
			||||||
@@ -92,8 +100,9 @@ Definition of the `main` function.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* Massage command-line args and setup Commander.js. */
 | 
					  /* Massage command-line args and setup Commander.js. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initialize = function(ar) {
 | 
					  initialize = function(ar, exitCallback) {
 | 
				
			||||||
    var o;
 | 
					    var o;
 | 
				
			||||||
 | 
					    _exitCallback = exitCallback || process.exit;
 | 
				
			||||||
    o = initOptions(ar);
 | 
					    o = initOptions(ar);
 | 
				
			||||||
    o.silent || logMsg(_title);
 | 
					    o.silent || logMsg(_title);
 | 
				
			||||||
    if (o.debug) {
 | 
					    if (o.debug) {
 | 
				
			||||||
@@ -105,20 +114,18 @@ Definition of the `main` function.
 | 
				
			|||||||
      _out.log(chalk.cyan(PAD('  FRESCA:', 25, null, PAD.RIGHT)) + chalk.cyan.bold(PKG.dependencies.fresca));
 | 
					      _out.log(chalk.cyan(PAD('  FRESCA:', 25, null, PAD.RIGHT)) + chalk.cyan.bold(PKG.dependencies.fresca));
 | 
				
			||||||
      _out.log('');
 | 
					      _out.log('');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    _err.init(o.debug, o.assert, o.silent);
 | 
				
			||||||
    if (o.verb && !HMR.verbs[o.verb] && !HMR.alias[o.verb]) {
 | 
					    if (o.verb && !HMR.verbs[o.verb] && !HMR.alias[o.verb]) {
 | 
				
			||||||
      throw {
 | 
					      _err.err({
 | 
				
			||||||
        fluenterror: HMSTATUS.invalidCommand,
 | 
					        fluenterror: HMSTATUS.invalidCommand,
 | 
				
			||||||
        quit: true,
 | 
					        quit: true,
 | 
				
			||||||
        attempted: o.orgVerb
 | 
					        attempted: o.orgVerb
 | 
				
			||||||
      };
 | 
					      }, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Command.prototype.missingArgument = function(name) {
 | 
					    Command.prototype.missingArgument = function(name) {
 | 
				
			||||||
      if (this.name() !== 'new') {
 | 
					      _err.err({
 | 
				
			||||||
        throw {
 | 
					        fluenterror: this.name() !== 'new' ? HMSTATUS.resumeNotFound : HMSTATUS.createNameMissing
 | 
				
			||||||
          fluenterror: HMSTATUS.resumeNotFound,
 | 
					      }, true);
 | 
				
			||||||
          quit: true
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    Command.prototype.helpInformation = function() {
 | 
					    Command.prototype.helpInformation = function() {
 | 
				
			||||||
      var manPage;
 | 
					      var manPage;
 | 
				
			||||||
@@ -136,7 +143,7 @@ Definition of the `main` function.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  initOptions = function(ar) {
 | 
					  initOptions = function(ar) {
 | 
				
			||||||
    oVerb;
 | 
					    oVerb;
 | 
				
			||||||
    var args, cleanArgs, inf, isDebug, isMono, isSilent, oJSON, oVerb, optStr, optsIdx, verb, vidx;
 | 
					    var args, cleanArgs, inf, isAssert, isDebug, isMono, isSilent, oJSON, oVerb, optStr, optsIdx, verb, vidx;
 | 
				
			||||||
    verb = '';
 | 
					    verb = '';
 | 
				
			||||||
    args = ar.slice();
 | 
					    args = ar.slice();
 | 
				
			||||||
    cleanArgs = args.slice(2);
 | 
					    cleanArgs = args.slice(2);
 | 
				
			||||||
@@ -177,6 +184,9 @@ Definition of the `main` function.
 | 
				
			|||||||
    isSilent = _.some(args, function(v) {
 | 
					    isSilent = _.some(args, function(v) {
 | 
				
			||||||
      return v === '-s' || v === '--silent';
 | 
					      return v === '-s' || v === '--silent';
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    isAssert = _.some(args, function(v) {
 | 
				
			||||||
 | 
					      return v === '-a' || v === '--assert';
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
    isMono = _.some(args, function(v) {
 | 
					    isMono = _.some(args, function(v) {
 | 
				
			||||||
      return v === '--no-color';
 | 
					      return v === '--no-color';
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -184,6 +194,7 @@ Definition of the `main` function.
 | 
				
			|||||||
      color: !isMono,
 | 
					      color: !isMono,
 | 
				
			||||||
      debug: isDebug,
 | 
					      debug: isDebug,
 | 
				
			||||||
      silent: isSilent,
 | 
					      silent: isSilent,
 | 
				
			||||||
 | 
					      assert: isAssert,
 | 
				
			||||||
      orgVerb: oVerb,
 | 
					      orgVerb: oVerb,
 | 
				
			||||||
      verb: verb,
 | 
					      verb: verb,
 | 
				
			||||||
      json: oJSON,
 | 
					      json: oJSON,
 | 
				
			||||||
@@ -195,24 +206,43 @@ Definition of the `main` function.
 | 
				
			|||||||
  /* Invoke a HackMyResume verb. */
 | 
					  /* Invoke a HackMyResume verb. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  execute = function(src, dst, opts, log) {
 | 
					  execute = function(src, dst, opts, log) {
 | 
				
			||||||
    var hand, v;
 | 
					    var prom, v;
 | 
				
			||||||
    loadOptions.call(this, opts, this.parent.jsonArgs);
 | 
					 | 
				
			||||||
    hand = require('./error');
 | 
					 | 
				
			||||||
    hand.init(_opts.debug, _opts.assert, _opts.silent);
 | 
					 | 
				
			||||||
    v = new HMR.verbs[this.name()]();
 | 
					    v = new HMR.verbs[this.name()]();
 | 
				
			||||||
 | 
					    loadOptions.call(this, opts, this.parent.jsonArgs);
 | 
				
			||||||
    _opts.errHandler = v;
 | 
					    _opts.errHandler = v;
 | 
				
			||||||
    _out.init(_opts);
 | 
					    _out.init(_opts);
 | 
				
			||||||
    v.on('hmr:status', function() {
 | 
					    v.on('hmr:status', function() {
 | 
				
			||||||
      return _out["do"].apply(_out, arguments);
 | 
					      return _out["do"].apply(_out, arguments);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    v.on('hmr:error', function() {
 | 
					    v.on('hmr:error', function() {
 | 
				
			||||||
      return hand.err.apply(hand, arguments);
 | 
					      return _err.err.apply(_err, arguments);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    v.invoke.call(v, src, dst, _opts, log);
 | 
					    prom = v.invoke.call(v, src, dst, _opts, log);
 | 
				
			||||||
    if (v.errorCode) {
 | 
					    prom.then(executeSuccess, executeFail);
 | 
				
			||||||
      console.log('Exiting with error code ' + v.errorCode);
 | 
					  };
 | 
				
			||||||
      return process.exit(v.errorCode);
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Success handler for verb invocations. Calls process.exit by default */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  executeSuccess = function(obj) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Failure handler for verb invocations. Calls process.exit by default */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  executeFail = function(err) {
 | 
				
			||||||
 | 
					    var finalErrorCode, msgs;
 | 
				
			||||||
 | 
					    finalErrorCode = -1;
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					      finalErrorCode = err.fluenterror ? err.fluenterror : err;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (_opts.debug) {
 | 
				
			||||||
 | 
					      msgs = require('./msg').errors;
 | 
				
			||||||
 | 
					      logMsg(printf(M2C(msgs.exiting.msg, 'cyan'), finalErrorCode));
 | 
				
			||||||
 | 
					      if (err.stack) {
 | 
				
			||||||
 | 
					        logMsg(err.stack);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _exitCallback(finalErrorCode);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -282,3 +312,5 @@ Definition of the `main` function.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=main.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/cli/msg.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/cli/msg.js
									
									
									
									
										vendored
									
									
								
							@@ -15,3 +15,5 @@ Message-handling routines for HackMyResume.
 | 
				
			|||||||
  module.exports = YAML.load(PATH.join(__dirname, 'msg.yml'));
 | 
					  module.exports = YAML.load(PATH.join(__dirname, 'msg.yml'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=msg.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								dist/cli/msg.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								dist/cli/msg.yml
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,8 @@ events:
 | 
				
			|||||||
    msg: Invoking **%s** command.
 | 
					    msg: Invoking **%s** command.
 | 
				
			||||||
  beforeCreate:
 | 
					  beforeCreate:
 | 
				
			||||||
    msg: Creating new **%s** resume: **%s**
 | 
					    msg: Creating new **%s** resume: **%s**
 | 
				
			||||||
 | 
					  afterCreate:
 | 
				
			||||||
 | 
					    msg: Creating new **%s** resume: **%s**
 | 
				
			||||||
  afterRead:
 | 
					  afterRead:
 | 
				
			||||||
    msg: Reading **%s** resume: **%s**
 | 
					    msg: Reading **%s** resume: **%s**
 | 
				
			||||||
  beforeTheme:
 | 
					  beforeTheme:
 | 
				
			||||||
@@ -41,6 +43,8 @@ events:
 | 
				
			|||||||
      - "VALID!"
 | 
					      - "VALID!"
 | 
				
			||||||
      - "INVALID"
 | 
					      - "INVALID"
 | 
				
			||||||
      - "BROKEN"
 | 
					      - "BROKEN"
 | 
				
			||||||
 | 
					      - "MISSING"
 | 
				
			||||||
 | 
					      - "ERROR"
 | 
				
			||||||
  beforePeek:
 | 
					  beforePeek:
 | 
				
			||||||
    msg:
 | 
					    msg:
 | 
				
			||||||
      - Peeking at **%s** in **%s**
 | 
					      - Peeking at **%s** in **%s**
 | 
				
			||||||
@@ -79,7 +83,10 @@ errors:
 | 
				
			|||||||
  readError:
 | 
					  readError:
 | 
				
			||||||
    msg: Reading **???** resume: **%s**
 | 
					    msg: Reading **???** resume: **%s**
 | 
				
			||||||
  parseError:
 | 
					  parseError:
 | 
				
			||||||
    msg: Invalid or corrupt JSON on line %s column %s.
 | 
					    msg:
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON on line %s column %s.
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON on line %s.
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON.
 | 
				
			||||||
  invalidHelperUse:
 | 
					  invalidHelperUse:
 | 
				
			||||||
    msg: "**Warning**: Incorrect use of the **%s** theme helper."
 | 
					    msg: "**Warning**: Incorrect use of the **%s** theme helper."
 | 
				
			||||||
  fileSaveError:
 | 
					  fileSaveError:
 | 
				
			||||||
@@ -96,3 +103,9 @@ errors:
 | 
				
			|||||||
    msg: "Invalid number of parameters. Expected: **%s**."
 | 
					    msg: "Invalid number of parameters. Expected: **%s**."
 | 
				
			||||||
  missingParam:
 | 
					  missingParam:
 | 
				
			||||||
    msg: The '**%s**' parameter was needed but not supplied.
 | 
					    msg: The '**%s**' parameter was needed but not supplied.
 | 
				
			||||||
 | 
					  createError:
 | 
				
			||||||
 | 
					    msg: Failed to create **'%s'**.
 | 
				
			||||||
 | 
					  exiting:
 | 
				
			||||||
 | 
					    msg: Exiting with status code **%s**.
 | 
				
			||||||
 | 
					  validateError:
 | 
				
			||||||
 | 
					    msg: "An error occurred during validation:\n%s"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										76
									
								
								dist/cli/out.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								dist/cli/out.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ Output routines for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var Class, EXTEND, FS, HANDLEBARS, HME, LO, M2C, OutputHandler, PATH, YAML, _, chalk, dbgStyle, pad, printf;
 | 
					  var EXTEND, FS, HANDLEBARS, HME, LO, M2C, OutputHandler, PATH, YAML, _, chalk, dbgStyle, pad, printf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  chalk = require('chalk');
 | 
					  chalk = require('chalk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,8 +14,6 @@ Output routines for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _ = require('underscore');
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Class = require('../utils/class.js');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  M2C = require('../utils/md2chalk.js');
 | 
					  M2C = require('../utils/md2chalk.js');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PATH = require('path');
 | 
					  PATH = require('path');
 | 
				
			||||||
@@ -39,20 +37,27 @@ Output routines for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /** A stateful output module. All HMR console output handled here. */
 | 
					  /** A stateful output module. All HMR console output handled here. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  OutputHandler = module.exports = Class.extend({
 | 
					  module.exports = OutputHandler = (function() {
 | 
				
			||||||
    init: function(opts) {
 | 
					    function OutputHandler(opts) {
 | 
				
			||||||
 | 
					      this.init(opts);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OutputHandler.prototype.init = function(opts) {
 | 
				
			||||||
      this.opts = EXTEND(true, this.opts || {}, opts);
 | 
					      this.opts = EXTEND(true, this.opts || {}, opts);
 | 
				
			||||||
      this.msgs = YAML.load(PATH.join(__dirname, 'msg.yml')).events;
 | 
					      this.msgs = YAML.load(PATH.join(__dirname, 'msg.yml')).events;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
    log: function(msg) {
 | 
					
 | 
				
			||||||
 | 
					    OutputHandler.prototype.log = function(msg) {
 | 
				
			||||||
      var finished;
 | 
					      var finished;
 | 
				
			||||||
      msg = msg || '';
 | 
					      msg = msg || '';
 | 
				
			||||||
      printf = require('printf');
 | 
					      printf = require('printf');
 | 
				
			||||||
      finished = printf.apply(printf, arguments);
 | 
					      finished = printf.apply(printf, arguments);
 | 
				
			||||||
      return this.opts.silent || console.log(finished);
 | 
					      return this.opts.silent || console.log(finished);
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
    "do": function(evt) {
 | 
					
 | 
				
			||||||
      var L, WRAP, info, msg, numFormats, output, rawTpl, sty, style, suffix, template, that, themeName, tot;
 | 
					    OutputHandler.prototype["do"] = function(evt) {
 | 
				
			||||||
 | 
					      var L, WRAP, adj, info, msg, msgs, numFormats, output, rawTpl, sty, style, suffix, template, that, themeName, tot;
 | 
				
			||||||
      that = this;
 | 
					      that = this;
 | 
				
			||||||
      L = function() {
 | 
					      L = function() {
 | 
				
			||||||
        return that.log.apply(that, arguments);
 | 
					        return that.log.apply(that, arguments);
 | 
				
			||||||
@@ -60,8 +65,8 @@ Output routines for HackMyResume.
 | 
				
			|||||||
      switch (evt.sub) {
 | 
					      switch (evt.sub) {
 | 
				
			||||||
        case HME.begin:
 | 
					        case HME.begin:
 | 
				
			||||||
          return this.opts.debug && L(M2C(this.msgs.begin.msg, dbgStyle), evt.cmd.toUpperCase());
 | 
					          return this.opts.debug && L(M2C(this.msgs.begin.msg, dbgStyle), evt.cmd.toUpperCase());
 | 
				
			||||||
        case HME.beforeCreate:
 | 
					        case HME.afterCreate:
 | 
				
			||||||
          L(M2C(this.msgs.beforeCreate.msg, 'green'), evt.fmt, evt.file);
 | 
					          L(M2C(this.msgs.beforeCreate.msg, evt.isError ? 'red' : 'green'), evt.fmt, evt.file);
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case HME.beforeTheme:
 | 
					        case HME.beforeTheme:
 | 
				
			||||||
          return this.opts.debug && L(M2C(this.msgs.beforeTheme.msg, dbgStyle), evt.theme.toUpperCase());
 | 
					          return this.opts.debug && L(M2C(this.msgs.beforeTheme.msg, dbgStyle), evt.theme.toUpperCase());
 | 
				
			||||||
@@ -127,11 +132,35 @@ Output routines for HackMyResume.
 | 
				
			|||||||
        case HME.afterInlineConvert:
 | 
					        case HME.afterInlineConvert:
 | 
				
			||||||
          return L(M2C(this.msgs.afterInlineConvert.msg, 'gray', 'white.dim'), evt.file, evt.fmt);
 | 
					          return L(M2C(this.msgs.afterInlineConvert.msg, 'gray', 'white.dim'), evt.file, evt.fmt);
 | 
				
			||||||
        case HME.afterValidate:
 | 
					        case HME.afterValidate:
 | 
				
			||||||
          style = evt.isValid ? 'green' : 'yellow';
 | 
					          style = 'red';
 | 
				
			||||||
          L(M2C(this.msgs.afterValidate.msg[0], 'white') + chalk[style].bold(evt.isValid ? this.msgs.afterValidate.msg[1] : this.msgs.afterValidate.msg[2]), evt.file, evt.fmt);
 | 
					          adj = '';
 | 
				
			||||||
          if (evt.errors) {
 | 
					          msgs = this.msgs.afterValidate.msg;
 | 
				
			||||||
            return _.each(evt.errors, function(err, idx) {
 | 
					          switch (evt.status) {
 | 
				
			||||||
              return L(chalk.yellow.bold('--> ') + chalk.yellow(err.field.replace('data.', 'resume.').toUpperCase() + ' ' + err.message));
 | 
					            case 'valid':
 | 
				
			||||||
 | 
					              style = 'green';
 | 
				
			||||||
 | 
					              adj = msgs[1];
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case 'invalid':
 | 
				
			||||||
 | 
					              style = 'yellow';
 | 
				
			||||||
 | 
					              adj = msgs[2];
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case 'broken':
 | 
				
			||||||
 | 
					              style = 'red';
 | 
				
			||||||
 | 
					              adj = msgs[3];
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case 'missing':
 | 
				
			||||||
 | 
					              style = 'red';
 | 
				
			||||||
 | 
					              adj = msgs[4];
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case 'unknown':
 | 
				
			||||||
 | 
					              style = 'red';
 | 
				
			||||||
 | 
					              adj = msgs[5];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          evt.schema = evt.schema.replace('jars', 'JSON Resume').toUpperCase();
 | 
				
			||||||
 | 
					          L(M2C(msgs[0], 'white') + chalk[style].bold(adj), evt.file, evt.schema);
 | 
				
			||||||
 | 
					          if (evt.violations) {
 | 
				
			||||||
 | 
					            _.each(evt.violations, function(err, idx) {
 | 
				
			||||||
 | 
					              L(chalk.yellow.bold('--> ') + chalk.yellow(err.field.replace('data.', 'resume.').toUpperCase() + ' ' + err.message));
 | 
				
			||||||
            }, this);
 | 
					            }, this);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
@@ -142,16 +171,23 @@ Output routines for HackMyResume.
 | 
				
			|||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            L(M2C(this.msgs.beforePeek.msg[1], sty), evt.file);
 | 
					            L(M2C(this.msgs.beforePeek.msg[1], sty), evt.file);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (evt.target !== void 0) {
 | 
					          if (evt.target !== void 0 && !evt.error) {
 | 
				
			||||||
            return console.dir(evt.target, {
 | 
					            return console.dir(evt.target, {
 | 
				
			||||||
              depth: null,
 | 
					              depth: null,
 | 
				
			||||||
              colors: true
 | 
					              colors: true
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
          } else if (!evt.error) {
 | 
					          } else if (!evt.error) {
 | 
				
			||||||
            return L(M2C(this.msgs.afterPeek.msg, 'yellow'), evt.requested, evt.file);
 | 
					            return L(M2C(this.msgs.afterPeek.msg, 'yellow'), evt.requested, evt.file);
 | 
				
			||||||
 | 
					          } else if (evt.error) {
 | 
				
			||||||
 | 
					            return L(chalk.red(evt.error.inner.inner));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return OutputHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=out.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										73
									
								
								dist/core/abstract-resume.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								dist/core/abstract-resume.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					Definition of the AbstractResume class.
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 | 
					@module core/abstract-resume
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var AbstractResume, FluentDate, _, __;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  __ = require('lodash');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FluentDate = require('./fluent-date');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AbstractResume = (function() {
 | 
				
			||||||
 | 
					    function AbstractResume() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					    Compute the total duration of the work history.
 | 
				
			||||||
 | 
					    @returns The total duration of the sheet's work history, that is, the number
 | 
				
			||||||
 | 
					    of years between the start date of the earliest job on the resume and the
 | 
				
			||||||
 | 
					    *latest end date of all jobs in the work history*. This last condition is for
 | 
				
			||||||
 | 
					    sheets that have overlapping jobs.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AbstractResume.prototype.duration = function(collKey, startKey, endKey, unit) {
 | 
				
			||||||
 | 
					      var firstDate, hist, lastDate, new_e;
 | 
				
			||||||
 | 
					      unit = unit || 'years';
 | 
				
			||||||
 | 
					      hist = __.get(this, collKey);
 | 
				
			||||||
 | 
					      if (!hist || !hist.length) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      new_e = hist.map(function(job) {
 | 
				
			||||||
 | 
					        var obj;
 | 
				
			||||||
 | 
					        obj = _.pick(job, [startKey, endKey]);
 | 
				
			||||||
 | 
					        if (!_.has(obj, endKey)) {
 | 
				
			||||||
 | 
					          obj[endKey] = 'current';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (obj && (obj[startKey] || obj[endKey])) {
 | 
				
			||||||
 | 
					          obj = _.pairs(obj);
 | 
				
			||||||
 | 
					          obj[0][1] = FluentDate.fmt(obj[0][1]);
 | 
				
			||||||
 | 
					          if (obj.length > 1) {
 | 
				
			||||||
 | 
					            obj[1][1] = FluentDate.fmt(obj[1][1]);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return obj;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      new_e = _.filter(_.flatten(new_e, true), function(v) {
 | 
				
			||||||
 | 
					        return v && v.length && v[0] && v[0].length;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      if (!new_e || !new_e.length) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      new_e = _.sortBy(new_e, function(elem) {
 | 
				
			||||||
 | 
					        return elem[1].unix();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      firstDate = _.first(new_e)[1];
 | 
				
			||||||
 | 
					      lastDate = _.last(new_e)[1];
 | 
				
			||||||
 | 
					      return lastDate.diff(firstDate, unit);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return AbstractResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  module.exports = AbstractResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=abstract-resume.js.map
 | 
				
			||||||
							
								
								
									
										2
									
								
								dist/core/default-formats.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/core/default-formats.js
									
									
									
									
										vendored
									
									
								
							@@ -58,3 +58,5 @@ Event code definitions.
 | 
				
			|||||||
  ];
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=default-formats.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/core/default-options.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/core/default-options.js
									
									
									
									
										vendored
									
									
								
							@@ -16,3 +16,5 @@ Event code definitions.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=default-options.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								dist/core/event-codes.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								dist/core/event-codes.js
									
									
									
									
										vendored
									
									
								
							@@ -33,7 +33,12 @@ Event code definitions.
 | 
				
			|||||||
    beforeInlineConvert: 22,
 | 
					    beforeInlineConvert: 22,
 | 
				
			||||||
    afterInlineConvert: 23,
 | 
					    afterInlineConvert: 23,
 | 
				
			||||||
    beforeValidate: 24,
 | 
					    beforeValidate: 24,
 | 
				
			||||||
    afterValidate: 25
 | 
					    afterValidate: 25,
 | 
				
			||||||
 | 
					    beforeWrite: 26,
 | 
				
			||||||
 | 
					    afterWrite: 27,
 | 
				
			||||||
 | 
					    applyTheme: 28
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=event-codes.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								dist/core/fluent-date.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								dist/core/fluent-date.js
									
									
									
									
										vendored
									
									
								
							@@ -10,6 +10,8 @@ The HackMyResume date representation.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  moment = require('moment');
 | 
					  moment = require('moment');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  require('../utils/string');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  Create a FluentDate from a string or Moment date object. There are a few date
 | 
					  Create a FluentDate from a string or Moment date object. There are a few date
 | 
				
			||||||
@@ -33,6 +35,10 @@ The HackMyResume date representation.
 | 
				
			|||||||
      this.rep = this.fmt(dt);
 | 
					      this.rep = this.fmt(dt);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FluentDate.isCurrent = function(dt) {
 | 
				
			||||||
 | 
					      return !dt || (String.is(dt) && /^(present|now|current)$/.test(dt));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return FluentDate;
 | 
					    return FluentDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  })();
 | 
					  })();
 | 
				
			||||||
@@ -54,7 +60,7 @@ The HackMyResume date representation.
 | 
				
			|||||||
  module.exports = FluentDate;
 | 
					  module.exports = FluentDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FluentDate.fmt = function(dt, throws) {
 | 
					  FluentDate.fmt = function(dt, throws) {
 | 
				
			||||||
    var defTime, month, mt, parts, ref, temp;
 | 
					    var month, mt, parts, ref, temp;
 | 
				
			||||||
    throws = (throws === void 0 || throws === null) || throws;
 | 
					    throws = (throws === void 0 || throws === null) || throws;
 | 
				
			||||||
    if (typeof dt === 'string' || dt instanceof String) {
 | 
					    if (typeof dt === 'string' || dt instanceof String) {
 | 
				
			||||||
      dt = dt.toLowerCase().trim();
 | 
					      dt = dt.toLowerCase().trim();
 | 
				
			||||||
@@ -72,33 +78,7 @@ The HackMyResume date representation.
 | 
				
			|||||||
      } else if (/^\s*\d{4}\s*$/.test(dt)) {
 | 
					      } else if (/^\s*\d{4}\s*$/.test(dt)) {
 | 
				
			||||||
        return moment(dt, 'YYYY');
 | 
					        return moment(dt, 'YYYY');
 | 
				
			||||||
      } else if (/^\s*$/.test(dt)) {
 | 
					      } else if (/^\s*$/.test(dt)) {
 | 
				
			||||||
        defTime = {
 | 
					        return moment();
 | 
				
			||||||
          isNull: true,
 | 
					 | 
				
			||||||
          isBefore: function(other) {
 | 
					 | 
				
			||||||
            if (other && !other.isNull) {
 | 
					 | 
				
			||||||
              return true;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          isAfter: function(other) {
 | 
					 | 
				
			||||||
            if (other && !other.isNull) {
 | 
					 | 
				
			||||||
              return false;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          unix: function() {
 | 
					 | 
				
			||||||
            return 0;
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          format: function() {
 | 
					 | 
				
			||||||
            return '';
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          diff: function() {
 | 
					 | 
				
			||||||
            return 0;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        return defTime;
 | 
					 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        mt = moment(dt);
 | 
					        mt = moment(dt);
 | 
				
			||||||
        if (mt.isValid()) {
 | 
					        if (mt.isValid()) {
 | 
				
			||||||
@@ -123,3 +103,5 @@ The HackMyResume date representation.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=fluent-date.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								dist/core/fresh-resume.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								dist/core/fresh-resume.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var CONVERTER, FS, FreshResume, JRSResume, MD, PATH, XML, _, __, _parseDates, extend, moment, validator;
 | 
					  var AbstractResume, CONVERTER, FS, FluentDate, FreshResume, JRSResume, MD, PATH, XML, _, __, _parseDates, extend, moment, validator,
 | 
				
			||||||
 | 
					    extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs');
 | 
					  FS = require('fs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,6 +32,10 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  JRSResume = require('./jrs-resume');
 | 
					  JRSResume = require('./jrs-resume');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FluentDate = require('./fluent-date');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AbstractResume = require('./abstract-resume');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
 | 
					  A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
 | 
				
			||||||
@@ -37,19 +43,12 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
  @constructor
 | 
					  @constructor
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FreshResume = (function() {
 | 
					  FreshResume = (function(superClass) {
 | 
				
			||||||
    function FreshResume() {}
 | 
					    extend1(FreshResume, superClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function FreshResume() {
 | 
				
			||||||
    /** Initialize the FreshResume from file. */
 | 
					      return FreshResume.__super__.constructor.apply(this, arguments);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    FreshResume.prototype.open = function(file, opts) {
 | 
					 | 
				
			||||||
      var raw, ret;
 | 
					 | 
				
			||||||
      raw = FS.readFileSync(file, 'utf8');
 | 
					 | 
				
			||||||
      ret = this.parse(raw, opts);
 | 
					 | 
				
			||||||
      this.imp.file = file;
 | 
					 | 
				
			||||||
      return ret;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Initialize the the FreshResume from JSON string data. */
 | 
					    /** Initialize the the FreshResume from JSON string data. */
 | 
				
			||||||
@@ -376,36 +375,8 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    Calculate the total duration of the sheet. Assumes this.work has been sorted
 | 
					 | 
				
			||||||
    by start date descending, perhaps via a call to Sheet.sort().
 | 
					 | 
				
			||||||
    @returns The total duration of the sheet's work history, that is, the number
 | 
					 | 
				
			||||||
    of years between the start date of the earliest job on the resume and the
 | 
					 | 
				
			||||||
    *latest end date of all jobs in the work history*. This last condition is for
 | 
					 | 
				
			||||||
    sheets that have overlapping jobs.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    FreshResume.prototype.duration = function(unit) {
 | 
					    FreshResume.prototype.duration = function(unit) {
 | 
				
			||||||
      var careerLast, careerStart, empHist, firstJob;
 | 
					      return FreshResume.__super__.duration.call(this, 'employment.history', 'start', 'end', unit);
 | 
				
			||||||
      unit = unit || 'years';
 | 
					 | 
				
			||||||
      empHist = __.get(this, 'employment.history');
 | 
					 | 
				
			||||||
      if (empHist && empHist.length) {
 | 
					 | 
				
			||||||
        firstJob = _.last(empHist);
 | 
					 | 
				
			||||||
        careerStart = firstJob.start ? firstJob.safe.start : '';
 | 
					 | 
				
			||||||
        if ((typeof careerStart === 'string' || careerStart instanceof String) && !careerStart.trim()) {
 | 
					 | 
				
			||||||
          return 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        careerLast = _.max(empHist, function(w) {
 | 
					 | 
				
			||||||
          if (w.safe && w.safe.end) {
 | 
					 | 
				
			||||||
            return w.safe.end.unix();
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            return moment().unix();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        return careerLast.safe.end.diff(careerStart, unit);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -420,7 +391,11 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
        if (a.safe.start.isBefore(b.safe.start)) {
 | 
					        if (a.safe.start.isBefore(b.safe.start)) {
 | 
				
			||||||
          return 1;
 | 
					          return 1;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          return (a.safe.start.isAfter(b.safe.start) && -1) || 0;
 | 
					          if (a.safe.start.isAfter(b.safe.start)) {
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      sortSection = function(key) {
 | 
					      sortSection = function(key) {
 | 
				
			||||||
@@ -448,7 +423,7 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return FreshResume;
 | 
					    return FreshResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  })();
 | 
					  })(AbstractResume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -456,7 +431,7 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FreshResume["default"] = function() {
 | 
					  FreshResume["default"] = function() {
 | 
				
			||||||
    return new FreshResume().parseJSON(require('fresh-resume-starter'));
 | 
					    return new FreshResume().parseJSON(require('fresh-resume-starter').fresh);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -499,7 +474,7 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (Object.prototype.toString.call(obj) === '[object Array]') {
 | 
					      if (Object.prototype.toString.call(obj) === '[object Array]') {
 | 
				
			||||||
        return obj.forEach(function(elem) {
 | 
					        obj.forEach(function(elem) {
 | 
				
			||||||
          return replaceDatesInObject(elem);
 | 
					          return replaceDatesInObject(elem);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      } else if (typeof obj === 'object') {
 | 
					      } else if (typeof obj === 'object') {
 | 
				
			||||||
@@ -509,19 +484,19 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
        Object.keys(obj).forEach(function(key) {
 | 
					        Object.keys(obj).forEach(function(key) {
 | 
				
			||||||
          return replaceDatesInObject(obj[key]);
 | 
					          return replaceDatesInObject(obj[key]);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        return ['start', 'end', 'date'].forEach(function(val) {
 | 
					        ['start', 'end', 'date'].forEach(function(val) {
 | 
				
			||||||
          if ((obj[val] !== void 0) && (!obj.safe || !obj.safe[val])) {
 | 
					          if ((obj[val] !== void 0) && (!obj.safe || !obj.safe[val])) {
 | 
				
			||||||
            obj.safe = obj.safe || {};
 | 
					            obj.safe = obj.safe || {};
 | 
				
			||||||
            obj.safe[val] = _fmt(obj[val]);
 | 
					            obj.safe[val] = _fmt(obj[val]);
 | 
				
			||||||
            if (obj[val] && (val === 'start') && !obj.end) {
 | 
					            if (obj[val] && (val === 'start') && !obj.end) {
 | 
				
			||||||
              return obj.safe.end = _fmt('current');
 | 
					              obj.safe.end = _fmt('current');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return Object.keys(this).forEach(function(member) {
 | 
					    Object.keys(this).forEach(function(member) {
 | 
				
			||||||
      return replaceDatesInObject(that[member]);
 | 
					      replaceDatesInObject(that[member]);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -531,3 +506,5 @@ Definition of the FRESHResume class.
 | 
				
			|||||||
  module.exports = FreshResume;
 | 
					  module.exports = FreshResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=fresh-resume.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										211
									
								
								dist/core/fresh-theme.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										211
									
								
								dist/core/fresh-theme.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var EXTEND, FRESHTheme, FS, HMSTATUS, PATH, READFILES, _, friendlyName, loadExplicit, loadImplicit, loadSafeJson, moment, parsePath, pathExists, validator;
 | 
					  var EXTEND, FRESHTheme, FS, HMSTATUS, PATH, READFILES, _, _load, _loadOne, friendlyName, loadSafeJson, moment, parsePath, pathExists, validator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs');
 | 
					  FS = require('fs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,9 +31,7 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
  READFILES = require('recursive-readdir-sync');
 | 
					  READFILES = require('recursive-readdir-sync');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /* A representation of a FRESH theme asset.
 | 
				
			||||||
  The FRESHTheme class is a representation of a FRESH theme
 | 
					 | 
				
			||||||
  asset. See also: JRSTheme.
 | 
					 | 
				
			||||||
  @class FRESHTheme
 | 
					  @class FRESHTheme
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,9 +39,7 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
    function FRESHTheme() {}
 | 
					    function FRESHTheme() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /* Open and parse the specified theme. */
 | 
				
			||||||
    Open and parse the specified theme.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FRESHTheme.prototype.open = function(themeFolder) {
 | 
					    FRESHTheme.prototype.open = function(themeFolder) {
 | 
				
			||||||
      var cached, formatsHash, pathInfo, that, themeFile, themeInfo;
 | 
					      var cached, formatsHash, pathInfo, that, themeFile, themeInfo;
 | 
				
			||||||
@@ -71,12 +67,7 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
          return formatsHash[key] = cached[th].getFormat(key);
 | 
					          return formatsHash[key] = cached[th].getFormat(key);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!!this.formats) {
 | 
					      formatsHash = _load.call(this, formatsHash);
 | 
				
			||||||
        formatsHash = loadExplicit.call(this, formatsHash);
 | 
					 | 
				
			||||||
        this.explicit = true;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        formatsHash = loadImplicit.call(this, formatsHash);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      this.formats = formatsHash;
 | 
					      this.formats = formatsHash;
 | 
				
			||||||
      this.name = parsePath(this.folder).name;
 | 
					      this.name = parsePath(this.folder).name;
 | 
				
			||||||
      return this;
 | 
					      return this;
 | 
				
			||||||
@@ -101,63 +92,17 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
  })();
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Load the theme implicitly, by scanning the theme folder for files. TODO:
 | 
					  /* Load and parse theme source files. */
 | 
				
			||||||
  Refactor duplicated code with loadExplicit.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadImplicit = function(formatsHash) {
 | 
					  _load = function(formatsHash) {
 | 
				
			||||||
    var fmts, major, that, tplFolder;
 | 
					    var copyOnly, fmts, major, that, tplFolder;
 | 
				
			||||||
    that = this;
 | 
					    that = this;
 | 
				
			||||||
    major = false;
 | 
					    major = false;
 | 
				
			||||||
    tplFolder = PATH.join(this.folder, 'src');
 | 
					    tplFolder = PATH.join(this.folder, 'src');
 | 
				
			||||||
 | 
					    copyOnly = ['.ttf', '.otf', '.png', '.jpg', '.jpeg', '.pdf'];
 | 
				
			||||||
    fmts = READFILES(tplFolder).map(function(absPath) {
 | 
					    fmts = READFILES(tplFolder).map(function(absPath) {
 | 
				
			||||||
      var idx, isMajor, obj, outFmt, pathInfo, portion, reg, res;
 | 
					      return _loadOne.call(this, absPath, formatsHash, tplFolder);
 | 
				
			||||||
      pathInfo = parsePath(absPath);
 | 
					    }, this);
 | 
				
			||||||
      outFmt = '';
 | 
					 | 
				
			||||||
      isMajor = false;
 | 
					 | 
				
			||||||
      portion = pathInfo.dirname.replace(tplFolder, '');
 | 
					 | 
				
			||||||
      if (portion && portion.trim()) {
 | 
					 | 
				
			||||||
        if (portion[1] === '_') {
 | 
					 | 
				
			||||||
          return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        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 (!outFmt) {
 | 
					 | 
				
			||||||
        idx = pathInfo.name.lastIndexOf('-');
 | 
					 | 
				
			||||||
        outFmt = idx === -1 ? pathInfo.name : pathInfo.name.substr(idx + 1);
 | 
					 | 
				
			||||||
        isMajor = true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      formatsHash[outFmt] = formatsHash[outFmt] || {
 | 
					 | 
				
			||||||
        outFormat: outFmt,
 | 
					 | 
				
			||||||
        files: []
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      obj = {
 | 
					 | 
				
			||||||
        action: 'transform',
 | 
					 | 
				
			||||||
        path: absPath,
 | 
					 | 
				
			||||||
        major: isMajor,
 | 
					 | 
				
			||||||
        orgPath: PATH.relative(tplFolder, absPath),
 | 
					 | 
				
			||||||
        ext: pathInfo.extname.slice(1),
 | 
					 | 
				
			||||||
        title: friendlyName(outFmt),
 | 
					 | 
				
			||||||
        pre: outFmt,
 | 
					 | 
				
			||||||
        data: FS.readFileSync(absPath, 'utf8'),
 | 
					 | 
				
			||||||
        css: null
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      formatsHash[outFmt].files.push(obj);
 | 
					 | 
				
			||||||
      return obj;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.cssFiles = fmts.filter(function(fmt) {
 | 
					    this.cssFiles = fmts.filter(function(fmt) {
 | 
				
			||||||
      return fmt && (fmt.ext === 'css');
 | 
					      return fmt && (fmt.ext === 'css');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -183,89 +128,93 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /* Load a single theme file. */
 | 
				
			||||||
  Load the theme explicitly, by following the 'formats' hash
 | 
					 | 
				
			||||||
  in the theme's JSON settings file.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadExplicit = function(formatsHash) {
 | 
					  _loadOne = function(absPath, formatsHash, tplFolder) {
 | 
				
			||||||
    var act, fmts, that, tplFolder;
 | 
					    var absPathSafe, act, defFormats, idx, isPrimary, obj, outFmt, pathInfo, portion, ref, ref1, reg, res;
 | 
				
			||||||
    tplFolder = PATH.join(this.folder, 'src');
 | 
					    pathInfo = parsePath(absPath);
 | 
				
			||||||
    act = null;
 | 
					    absPathSafe = absPath.trim().toLowerCase();
 | 
				
			||||||
    that = this;
 | 
					    outFmt = '';
 | 
				
			||||||
    fmts = READFILES(tplFolder).map(function(absPath) {
 | 
					    act = 'copy';
 | 
				
			||||||
      var absPathSafe, idx, obj, outFmt, pathInfo, portion, reg, res;
 | 
					    isPrimary = false;
 | 
				
			||||||
      act = null;
 | 
					    if (this.explicit) {
 | 
				
			||||||
      pathInfo = parsePath(absPath);
 | 
					      outFmt = _.find(Object.keys(this.formats), function(fmtKey) {
 | 
				
			||||||
      absPathSafe = absPath.trim().toLowerCase();
 | 
					 | 
				
			||||||
      outFmt = _.find(Object.keys(that.formats), function(fmtKey) {
 | 
					 | 
				
			||||||
        var fmtVal;
 | 
					        var fmtVal;
 | 
				
			||||||
        fmtVal = that.formats[fmtKey];
 | 
					        fmtVal = this.formats[fmtKey];
 | 
				
			||||||
        return _.some(fmtVal.transform, function(fpath) {
 | 
					        return _.some(fmtVal.transform, function(fpath) {
 | 
				
			||||||
          var absPathB;
 | 
					          var absPathB;
 | 
				
			||||||
          absPathB = PATH.join(that.folder, fpath).trim().toLowerCase();
 | 
					          absPathB = PATH.join(this.folder, fpath).trim().toLowerCase();
 | 
				
			||||||
          return absPathB === absPathSafe;
 | 
					          return absPathB === absPathSafe;
 | 
				
			||||||
        });
 | 
					        }, this);
 | 
				
			||||||
      });
 | 
					      }, this);
 | 
				
			||||||
      if (outFmt) {
 | 
					      if (outFmt) {
 | 
				
			||||||
        act = 'transform';
 | 
					        act = 'transform';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!outFmt) {
 | 
					    }
 | 
				
			||||||
        portion = pathInfo.dirname.replace(tplFolder, '');
 | 
					    if (!outFmt) {
 | 
				
			||||||
        if (portion && portion.trim()) {
 | 
					      portion = pathInfo.dirname.replace(tplFolder, '');
 | 
				
			||||||
          reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig;
 | 
					      if (portion && portion.trim()) {
 | 
				
			||||||
          res = reg.exec(portion);
 | 
					        if (portion[1] === '_') {
 | 
				
			||||||
          res && (outFmt = res[1]);
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        reg = /^(?:\/|\\)(html|latex|doc|pdf|png|partials)(?:\/|\\)?/ig;
 | 
				
			||||||
 | 
					        res = reg.exec(portion);
 | 
				
			||||||
 | 
					        if (res) {
 | 
				
			||||||
 | 
					          if (res[1] !== 'partials') {
 | 
				
			||||||
 | 
					            outFmt = res[1];
 | 
				
			||||||
 | 
					            if (!this.explicit) {
 | 
				
			||||||
 | 
					              act = 'transform';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.partials = this.partials || [];
 | 
				
			||||||
 | 
					            this.partials.push({
 | 
				
			||||||
 | 
					              name: pathInfo.name,
 | 
				
			||||||
 | 
					              path: absPath
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (!outFmt) {
 | 
					    }
 | 
				
			||||||
        idx = pathInfo.name.lastIndexOf('-');
 | 
					    if (!outFmt) {
 | 
				
			||||||
        outFmt = idx === -1 ? pathInfo.name : pathInfo.name.substr(idx + 1);
 | 
					      idx = pathInfo.name.lastIndexOf('-');
 | 
				
			||||||
 | 
					      outFmt = idx === -1 ? pathInfo.name : pathInfo.name.substr(idx + 1);
 | 
				
			||||||
 | 
					      if (!this.explicit) {
 | 
				
			||||||
 | 
					        act = 'transform';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      formatsHash[outFmt] = formatsHash[outFmt] || {
 | 
					      defFormats = require('./default-formats');
 | 
				
			||||||
        outFormat: outFmt,
 | 
					      isPrimary = _.some(defFormats, function(form) {
 | 
				
			||||||
        files: [],
 | 
					        return form.name === outFmt && pathInfo.extname !== '.css';
 | 
				
			||||||
        symLinks: that.formats[outFmt].symLinks
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      obj = {
 | 
					 | 
				
			||||||
        action: act,
 | 
					 | 
				
			||||||
        orgPath: PATH.relative(that.folder, absPath),
 | 
					 | 
				
			||||||
        path: absPath,
 | 
					 | 
				
			||||||
        ext: pathInfo.extname.slice(1),
 | 
					 | 
				
			||||||
        title: friendlyName(outFmt),
 | 
					 | 
				
			||||||
        pre: outFmt,
 | 
					 | 
				
			||||||
        data: FS.readFileSync(absPath, 'utf8'),
 | 
					 | 
				
			||||||
        css: null
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      formatsHash[outFmt].files.push(obj);
 | 
					 | 
				
			||||||
      return obj;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.cssFiles = fmts.filter(function(fmt) {
 | 
					 | 
				
			||||||
      return fmt.ext === 'css';
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    this.cssFiles.forEach(function(cssf) {
 | 
					 | 
				
			||||||
      var idx;
 | 
					 | 
				
			||||||
      idx = _.findIndex(fmts, function(fmt) {
 | 
					 | 
				
			||||||
        return fmt.pre === cssf.pre && fmt.ext === 'html';
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      fmts[idx].css = cssf.data;
 | 
					    }
 | 
				
			||||||
      return fmts[idx].cssPath = cssf.path;
 | 
					    formatsHash[outFmt] = formatsHash[outFmt] || {
 | 
				
			||||||
    });
 | 
					      outFormat: outFmt,
 | 
				
			||||||
    fmts = fmts.filter(function(fmt) {
 | 
					      files: []
 | 
				
			||||||
      return fmt.ext !== 'css';
 | 
					    };
 | 
				
			||||||
    });
 | 
					    if ((ref = this.formats) != null ? (ref1 = ref[outFmt]) != null ? ref1.symLinks : void 0 : void 0) {
 | 
				
			||||||
    return formatsHash;
 | 
					      formatsHash[outFmt].symLinks = this.formats[outFmt].symLinks;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    obj = {
 | 
				
			||||||
 | 
					      action: act,
 | 
				
			||||||
 | 
					      primary: isPrimary,
 | 
				
			||||||
 | 
					      path: absPath,
 | 
				
			||||||
 | 
					      orgPath: PATH.relative(tplFolder, absPath),
 | 
				
			||||||
 | 
					      ext: pathInfo.extname.slice(1),
 | 
				
			||||||
 | 
					      title: friendlyName(outFmt),
 | 
				
			||||||
 | 
					      pre: outFmt,
 | 
				
			||||||
 | 
					      data: FS.readFileSync(absPath, 'utf8'),
 | 
				
			||||||
 | 
					      css: null
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    formatsHash[outFmt].files.push(obj);
 | 
				
			||||||
 | 
					    return obj;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /* Return a more friendly name for certain formats. */
 | 
				
			||||||
  Return a more friendly name for certain formats.
 | 
					 | 
				
			||||||
  TODO: Refactor
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  friendlyName = function(val) {
 | 
					  friendlyName = function(val) {
 | 
				
			||||||
    var friendly;
 | 
					    var friendly;
 | 
				
			||||||
    val = val.trim().toLowerCase();
 | 
					    val = (val && val.trim().toLowerCase()) || '';
 | 
				
			||||||
    friendly = {
 | 
					    friendly = {
 | 
				
			||||||
      yml: 'yaml',
 | 
					      yml: 'yaml',
 | 
				
			||||||
      md: 'markdown',
 | 
					      md: 'markdown',
 | 
				
			||||||
@@ -277,3 +226,5 @@ Definition of the FRESHTheme class.
 | 
				
			|||||||
  module.exports = FRESHTheme;
 | 
					  module.exports = FRESHTheme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=fresh-theme.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										57
									
								
								dist/core/jrs-resume.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								dist/core/jrs-resume.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Definition of the JRSResume class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var CONVERTER, FS, JRSResume, MD, PATH, _, _parseDates, extend, moment, validator;
 | 
					  var AbstractResume, CONVERTER, FS, JRSResume, MD, PATH, _, _parseDates, extend, moment, validator,
 | 
				
			||||||
 | 
					    extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs');
 | 
					  FS = require('fs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,6 +26,8 @@ Definition of the JRSResume class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  moment = require('moment');
 | 
					  moment = require('moment');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AbstractResume = require('./abstract-resume');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
 | 
					  A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
 | 
				
			||||||
@@ -31,21 +35,14 @@ Definition of the JRSResume class.
 | 
				
			|||||||
  @class JRSResume
 | 
					  @class JRSResume
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  JRSResume = (function() {
 | 
					  JRSResume = (function(superClass) {
 | 
				
			||||||
    var clear, format;
 | 
					    var clear;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function JRSResume() {}
 | 
					    extend1(JRSResume, superClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function JRSResume() {
 | 
				
			||||||
    /** Initialize the JSResume from file. */
 | 
					      return JRSResume.__super__.constructor.apply(this, arguments);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    JRSResume.prototype.open = function(file, opts) {
 | 
					 | 
				
			||||||
      var raw, ret;
 | 
					 | 
				
			||||||
      raw = FS.readFileSync(file, 'utf8');
 | 
					 | 
				
			||||||
      ret = this.parse(raw, opts);
 | 
					 | 
				
			||||||
      this.imp.file = file;
 | 
					 | 
				
			||||||
      return ret;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Initialize the the JSResume from string. */
 | 
					    /** Initialize the the JSResume from string. */
 | 
				
			||||||
@@ -138,7 +135,7 @@ Definition of the JRSResume class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /** Return the resume format. */
 | 
					    /** Return the resume format. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    format = function() {
 | 
					    JRSResume.prototype.format = function() {
 | 
				
			||||||
      return 'JRS';
 | 
					      return 'JRS';
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -249,30 +246,8 @@ Definition of the JRSResume class.
 | 
				
			|||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    Calculate the total duration of the sheet. Assumes this.work has been sorted
 | 
					 | 
				
			||||||
    by start date descending, perhaps via a call to Sheet.sort().
 | 
					 | 
				
			||||||
    @returns The total duration of the sheet's work history, that is, the number
 | 
					 | 
				
			||||||
    of years between the start date of the earliest job on the resume and the
 | 
					 | 
				
			||||||
    *latest end date of all jobs in the work history*. This last condition is for
 | 
					 | 
				
			||||||
    sheets that have overlapping jobs.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    JRSResume.prototype.duration = function(unit) {
 | 
					    JRSResume.prototype.duration = function(unit) {
 | 
				
			||||||
      var careerLast, careerStart;
 | 
					      return JRSResume.__super__.duration.call(this, 'work', 'startDate', 'endDate', unit);
 | 
				
			||||||
      unit = unit || 'years';
 | 
					 | 
				
			||||||
      if (this.work && this.work.length) {
 | 
					 | 
				
			||||||
        careerStart = this.work[this.work.length - 1].safeStartDate;
 | 
					 | 
				
			||||||
        if ((typeof careerStart === 'string' || careerStart instanceof String) && !careerStart.trim()) {
 | 
					 | 
				
			||||||
          return 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        careerLast = _.max(this.work, function(w) {
 | 
					 | 
				
			||||||
          return w.safeEndDate.unix();
 | 
					 | 
				
			||||||
        }).safeEndDate;
 | 
					 | 
				
			||||||
        return careerLast.diff(careerStart, unit);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return 0;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -372,13 +347,13 @@ Definition of the JRSResume class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return JRSResume;
 | 
					    return JRSResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  })();
 | 
					  })(AbstractResume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Get the default (empty) sheet. */
 | 
					  /** Get the default (empty) sheet. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  JRSResume["default"] = function() {
 | 
					  JRSResume["default"] = function() {
 | 
				
			||||||
    return new JRSResume().open(PATH.join(__dirname, 'empty-jrs.json'), 'Empty');
 | 
					    return new JRSResume().parseJSON(require('fresh-resume-starter').jrs);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -443,3 +418,5 @@ Definition of the JRSResume class.
 | 
				
			|||||||
  module.exports = JRSResume;
 | 
					  module.exports = JRSResume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=jrs-resume.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								dist/core/jrs-theme.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								dist/core/jrs-theme.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,7 @@ Definition of the JRSTheme class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var JRSTheme, PATH, _, getFormat, parsePath, pathExists;
 | 
					  var JRSTheme, PATH, _, parsePath, pathExists;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _ = require('underscore');
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,17 +25,13 @@ Definition of the JRSTheme class.
 | 
				
			|||||||
  JRSTheme = (function() {
 | 
					  JRSTheme = (function() {
 | 
				
			||||||
    function JRSTheme() {}
 | 
					    function JRSTheme() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return JRSTheme;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  })();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ({
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Open and parse the specified theme.
 | 
					    Open and parse the specified theme.
 | 
				
			||||||
    @method open
 | 
					    @method open
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    open: function(thFolder) {
 | 
					
 | 
				
			||||||
 | 
					    JRSTheme.prototype.open = function(thFolder) {
 | 
				
			||||||
      var pathInfo, pkgJsonPath, thApi, thPkg;
 | 
					      var pathInfo, pkgJsonPath, thApi, thPkg;
 | 
				
			||||||
      this.folder = thFolder;
 | 
					      this.folder = thFolder;
 | 
				
			||||||
      pathInfo = parsePath(thFolder);
 | 
					      pathInfo = parsePath(thFolder);
 | 
				
			||||||
@@ -53,7 +49,7 @@ Definition of the JRSTheme class.
 | 
				
			|||||||
              {
 | 
					              {
 | 
				
			||||||
                action: 'transform',
 | 
					                action: 'transform',
 | 
				
			||||||
                render: this.render,
 | 
					                render: this.render,
 | 
				
			||||||
                major: true,
 | 
					                primary: true,
 | 
				
			||||||
                ext: 'html',
 | 
					                ext: 'html',
 | 
				
			||||||
                css: null
 | 
					                css: null
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
@@ -65,7 +61,7 @@ Definition of the JRSTheme class.
 | 
				
			|||||||
              {
 | 
					              {
 | 
				
			||||||
                action: 'transform',
 | 
					                action: 'transform',
 | 
				
			||||||
                render: this.render,
 | 
					                render: this.render,
 | 
				
			||||||
                major: true,
 | 
					                primary: true,
 | 
				
			||||||
                ext: 'pdf',
 | 
					                ext: 'pdf',
 | 
				
			||||||
                css: null
 | 
					                css: null
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
@@ -78,26 +74,34 @@ Definition of the JRSTheme class.
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return this;
 | 
					      return this;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Determine if the theme supports the output format.
 | 
					    Determine if the theme supports the output format.
 | 
				
			||||||
    @method hasFormat
 | 
					    @method hasFormat
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    hasFormat: function(fmt) {
 | 
					
 | 
				
			||||||
 | 
					    JRSTheme.prototype.hasFormat = function(fmt) {
 | 
				
			||||||
      return _.has(this.formats, fmt);
 | 
					      return _.has(this.formats, fmt);
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Return the requested output format.
 | 
					    Return the requested output format.
 | 
				
			||||||
    @method getFormat
 | 
					    @method getFormat
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getFormat = function(fmt) {
 | 
					    JRSTheme.prototype.getFormat = function(fmt) {
 | 
				
			||||||
    return this.formats[fmt];
 | 
					      return this.formats[fmt];
 | 
				
			||||||
  };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return JRSTheme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  module.exports = JRSTheme;
 | 
					  module.exports = JRSTheme;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=jrs-theme.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								dist/core/resume-factory.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								dist/core/resume-factory.js
									
									
									
									
										vendored
									
									
								
							@@ -83,7 +83,7 @@ Definition of the ResumeFactory class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _parse = function(fileName, opts, eve) {
 | 
					  _parse = function(fileName, opts, eve) {
 | 
				
			||||||
    var ex, orgFormat, rawData, ret;
 | 
					    var orgFormat, rawData, ret;
 | 
				
			||||||
    rawData = null;
 | 
					    rawData = null;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      eve && eve.stat(HME.beforeRead, {
 | 
					      eve && eve.stat(HME.beforeRead, {
 | 
				
			||||||
@@ -108,20 +108,15 @@ Definition of the ResumeFactory class.
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    } catch (_error) {
 | 
					    } catch (_error) {
 | 
				
			||||||
      ex = {
 | 
					      return {
 | 
				
			||||||
        fluenterror: rawData ? HACKMYSTATUS.parseError : HACKMYSTATUS.readError,
 | 
					        fluenterror: rawData ? HACKMYSTATUS.parseError : HACKMYSTATUS.readError,
 | 
				
			||||||
        inner: _error,
 | 
					        inner: _error,
 | 
				
			||||||
        raw: rawData,
 | 
					        raw: rawData,
 | 
				
			||||||
        file: fileName,
 | 
					        file: fileName
 | 
				
			||||||
        shouldExit: false
 | 
					 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      opts.quit && (ex.quit = true);
 | 
					 | 
				
			||||||
      eve && eve.err(ex.fluenterror, ex);
 | 
					 | 
				
			||||||
      if (opts["throw"]) {
 | 
					 | 
				
			||||||
        throw ex;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return ex;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=resume-factory.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								dist/core/status-codes.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								dist/core/status-codes.js
									
									
									
									
										vendored
									
									
								
							@@ -16,7 +16,7 @@ Status codes for HackMyResume.
 | 
				
			|||||||
    resumeNotFoundAlt: 6,
 | 
					    resumeNotFoundAlt: 6,
 | 
				
			||||||
    inputOutputParity: 7,
 | 
					    inputOutputParity: 7,
 | 
				
			||||||
    createNameMissing: 8,
 | 
					    createNameMissing: 8,
 | 
				
			||||||
    pdfgeneration: 9,
 | 
					    pdfGeneration: 9,
 | 
				
			||||||
    missingPackageJSON: 10,
 | 
					    missingPackageJSON: 10,
 | 
				
			||||||
    invalid: 11,
 | 
					    invalid: 11,
 | 
				
			||||||
    invalidFormat: 12,
 | 
					    invalidFormat: 12,
 | 
				
			||||||
@@ -31,7 +31,11 @@ Status codes for HackMyResume.
 | 
				
			|||||||
    compileTemplate: 21,
 | 
					    compileTemplate: 21,
 | 
				
			||||||
    themeLoad: 22,
 | 
					    themeLoad: 22,
 | 
				
			||||||
    invalidParamCount: 23,
 | 
					    invalidParamCount: 23,
 | 
				
			||||||
    missingParam: 24
 | 
					    missingParam: 24,
 | 
				
			||||||
 | 
					    createError: 25,
 | 
				
			||||||
 | 
					    validateError: 26
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=status-codes.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								dist/generators/base-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										41
									
								
								dist/generators/base-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,33 +1,40 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the BaseGenerator class.
 | 
					Definition of the BaseGenerator class.
 | 
				
			||||||
@module base-generator.js
 | 
					@module generators/base-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					The BaseGenerator class is the root of the generator hierarchy. Functionality
 | 
				
			||||||
 | 
					common to ALL generators lives here.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BaseGenerator, Class;
 | 
					  var BaseGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Class = require('../utils/class');
 | 
					  module.exports = BaseGenerator = (function() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
  The BaseGenerator class is the root of the generator hierarchy. Functionality
 | 
					 | 
				
			||||||
  common to ALL generators lives here.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  BaseGenerator = module.exports = Class.extend({
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Base-class initialize. */
 | 
					    /** Base-class initialize. */
 | 
				
			||||||
    init: function(outputFormat) {
 | 
					    function BaseGenerator(format) {
 | 
				
			||||||
      return this.format = outputFormat;
 | 
					      this.format = format;
 | 
				
			||||||
    },
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Status codes. */
 | 
					    /** Status codes. */
 | 
				
			||||||
    codes: require('../core/status-codes'),
 | 
					
 | 
				
			||||||
 | 
					    BaseGenerator.prototype.codes = require('../core/status-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Generator options. */
 | 
					    /** Generator options. */
 | 
				
			||||||
    opts: {}
 | 
					
 | 
				
			||||||
  });
 | 
					    BaseGenerator.prototype.opts = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return BaseGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=base-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								dist/generators/html-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								dist/generators/html-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the HTMLGenerator class.
 | 
					Definition of the HTMLGenerator class.
 | 
				
			||||||
 | 
					@module generators/html-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module html-generator.js
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var FS, HTML, HtmlGenerator, PATH, TemplateGenerator;
 | 
					  var FS, HTML, HtmlGenerator, PATH, TemplateGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,16 +20,20 @@ Definition of the HTMLGenerator class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  require('string.prototype.endswith');
 | 
					  require('string.prototype.endswith');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HtmlGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = HtmlGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(HtmlGenerator, superClass);
 | 
				
			||||||
      return this._super('html');
 | 
					
 | 
				
			||||||
    },
 | 
					    function HtmlGenerator() {
 | 
				
			||||||
 | 
					      HtmlGenerator.__super__.constructor.call(this, 'html');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Copy satellite CSS files to the destination and optionally pretty-print
 | 
					    Copy satellite CSS files to the destination and optionally pretty-print
 | 
				
			||||||
    the HTML resume prior to saving.
 | 
					    the HTML resume prior to saving.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    onBeforeSave: function(info) {
 | 
					
 | 
				
			||||||
 | 
					    HtmlGenerator.prototype.onBeforeSave = function(info) {
 | 
				
			||||||
      if (info.outputFile.endsWith('.css')) {
 | 
					      if (info.outputFile.endsWith('.css')) {
 | 
				
			||||||
        return info.mk;
 | 
					        return info.mk;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -36,7 +42,12 @@ Definition of the HTMLGenerator class.
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        return info.mk;
 | 
					        return info.mk;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return HtmlGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=html-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								dist/generators/html-pdf-cli-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										103
									
								
								dist/generators/html-pdf-cli-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,25 +1,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the HtmlPdfCLIGenerator class.
 | 
					Definition of the HtmlPdfCLIGenerator class.
 | 
				
			||||||
@module html-pdf-generator.js
 | 
					@module generators/html-pdf-generator.js
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var FS, HTML, HtmlPdfCLIGenerator, PATH, SLASH, SPAWN, TemplateGenerator, engines;
 | 
					  var FS, HMSTATUS, HtmlPdfCLIGenerator, PATH, SLASH, SPAWN, TemplateGenerator, _, engines,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs-extra');
 | 
					  FS = require('fs-extra');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HTML = require('html');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  PATH = require('path');
 | 
					  PATH = require('path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SPAWN = require('../utils/safe-spawn');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  SLASH = require('slash');
 | 
					  SLASH = require('slash');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HMSTATUS = require('../core/status-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SPAWN = require('../utils/safe-spawn');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,
 | 
					  An HTML-driven PDF resume generator for HackMyResume. Talks to Phantom,
 | 
				
			||||||
@@ -27,39 +31,51 @@ Definition of the HtmlPdfCLIGenerator class.
 | 
				
			|||||||
  If an engine isn't installed for a particular platform, error out gracefully.
 | 
					  If an engine isn't installed for a particular platform, error out gracefully.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = HtmlPdfCLIGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(HtmlPdfCLIGenerator, superClass);
 | 
				
			||||||
      return this._super('pdf', 'html');
 | 
					
 | 
				
			||||||
    },
 | 
					    function HtmlPdfCLIGenerator() {
 | 
				
			||||||
 | 
					      HtmlPdfCLIGenerator.__super__.constructor.call(this, 'pdf', 'html');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Generate the binary PDF. */
 | 
					    /** Generate the binary PDF. */
 | 
				
			||||||
    onBeforeSave: function(info) {
 | 
					
 | 
				
			||||||
      var ex, safe_eng;
 | 
					    HtmlPdfCLIGenerator.prototype.onBeforeSave = function(info) {
 | 
				
			||||||
      try {
 | 
					      var safe_eng;
 | 
				
			||||||
        safe_eng = info.opts.pdf || 'wkhtmltopdf';
 | 
					      if (info.ext !== 'html' && info.ext !== 'pdf') {
 | 
				
			||||||
        if (safe_eng !== 'none') {
 | 
					        return info.mk;
 | 
				
			||||||
          engines[safe_eng].call(this, info.mk, info.outputFile);
 | 
					      }
 | 
				
			||||||
          return null;
 | 
					      safe_eng = info.opts.pdf || 'wkhtmltopdf';
 | 
				
			||||||
        }
 | 
					      if (safe_eng === 'phantom') {
 | 
				
			||||||
      } catch (_error) {
 | 
					        safe_eng = 'phantomjs';
 | 
				
			||||||
        ex = _error;
 | 
					      }
 | 
				
			||||||
        if (ex.inner && ex.inner.code === 'ENOENT') {
 | 
					      if (_.has(engines, safe_eng)) {
 | 
				
			||||||
          throw {
 | 
					        this.errHandler = info.opts.errHandler;
 | 
				
			||||||
            fluenterror: this.codes.notOnPath,
 | 
					        engines[safe_eng].call(this, info.mk, info.outputFile, this.onError);
 | 
				
			||||||
            inner: ex.inner,
 | 
					        return null;
 | 
				
			||||||
            engine: ex.cmd,
 | 
					      }
 | 
				
			||||||
            stack: ex.inner && ex.inner.stack
 | 
					    };
 | 
				
			||||||
          };
 | 
					
 | 
				
			||||||
        } else {
 | 
					
 | 
				
			||||||
          throw {
 | 
					    /* Low-level error callback for spawn(). May be called after HMR process
 | 
				
			||||||
            fluenterror: this.codes.pdfGeneration,
 | 
					    termination, so object references may not be valid here. That's okay; if
 | 
				
			||||||
            inner: ex,
 | 
					    the references are invalid, the error was already logged. We could use
 | 
				
			||||||
            stack: ex.stack
 | 
					    spawn-watch here but that causes issues on legacy Node.js.
 | 
				
			||||||
          };
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HtmlPdfCLIGenerator.prototype.onError = function(ex, param) {
 | 
				
			||||||
 | 
					      var ref;
 | 
				
			||||||
 | 
					      if ((ref = param.errHandler) != null) {
 | 
				
			||||||
 | 
					        if (typeof ref.err === "function") {
 | 
				
			||||||
 | 
					          ref.err(HMSTATUS.pdfGeneration, ex);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return HtmlPdfCLIGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  engines = {
 | 
					  engines = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,11 +86,11 @@ Definition of the HtmlPdfCLIGenerator class.
 | 
				
			|||||||
    TODO: If HTML generation has run, reuse that output
 | 
					    TODO: If HTML generation has run, reuse that output
 | 
				
			||||||
    TODO: Local web server to ease wkhtmltopdf rendering
 | 
					    TODO: Local web server to ease wkhtmltopdf rendering
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    wkhtmltopdf: function(markup, fOut) {
 | 
					    wkhtmltopdf: function(markup, fOut, on_error) {
 | 
				
			||||||
      var info, tempFile;
 | 
					      var tempFile;
 | 
				
			||||||
      tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
 | 
					      tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
 | 
				
			||||||
      FS.writeFileSync(tempFile, markup, 'utf8');
 | 
					      FS.writeFileSync(tempFile, markup, 'utf8');
 | 
				
			||||||
      return info = SPAWN('wkhtmltopdf', [tempFile, fOut]);
 | 
					      SPAWN('wkhtmltopdf', [tempFile, fOut], false, on_error, this);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -84,15 +100,18 @@ Definition of the HtmlPdfCLIGenerator class.
 | 
				
			|||||||
    TODO: If HTML generation has run, reuse that output
 | 
					    TODO: If HTML generation has run, reuse that output
 | 
				
			||||||
    TODO: Local web server to ease Phantom rendering
 | 
					    TODO: Local web server to ease Phantom rendering
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    phantom: function(markup, fOut) {
 | 
					    phantomjs: function(markup, fOut, on_error) {
 | 
				
			||||||
      var destPath, info, scriptPath, sourcePath, tempFile;
 | 
					      var destPath, scriptPath, sourcePath, tempFile;
 | 
				
			||||||
      tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
 | 
					      tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
 | 
				
			||||||
      FS.writeFileSync(tempFile, markup, 'utf8');
 | 
					      FS.writeFileSync(tempFile, markup, 'utf8');
 | 
				
			||||||
      scriptPath = SLASH(PATH.relative(process.cwd(), PATH.resolve(__dirname, '../utils/rasterize.js')));
 | 
					      scriptPath = PATH.relative(process.cwd(), PATH.resolve(__dirname, '../utils/rasterize.js'));
 | 
				
			||||||
 | 
					      scriptPath = SLASH(scriptPath);
 | 
				
			||||||
      sourcePath = SLASH(PATH.relative(process.cwd(), tempFile));
 | 
					      sourcePath = SLASH(PATH.relative(process.cwd(), tempFile));
 | 
				
			||||||
      destPath = SLASH(PATH.relative(process.cwd(), fOut));
 | 
					      destPath = SLASH(PATH.relative(process.cwd(), fOut));
 | 
				
			||||||
      return info = SPAWN('phantomjs', [scriptPath, sourcePath, destPath]);
 | 
					      SPAWN('phantomjs', [scriptPath, sourcePath, destPath], false, on_error, this);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=html-pdf-cli-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								dist/generators/html-png-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								dist/generators/html-png-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the HtmlPngGenerator class.
 | 
					Definition of the HtmlPngGenerator class.
 | 
				
			||||||
 | 
					@module generators/html-png-generator
 | 
				
			||||||
@license MIT. See LICENSE.MD for details.
 | 
					@license MIT. See LICENSE.MD for details.
 | 
				
			||||||
@module html-png-generator.js
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var FS, HTML, HtmlPngGenerator, PATH, SLASH, SPAWN, TemplateGenerator, phantom;
 | 
					  var FS, HTML, HtmlPngGenerator, PATH, SLASH, SPAWN, TemplateGenerator, phantom,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,12 +27,16 @@ Definition of the HtmlPngGenerator class.
 | 
				
			|||||||
  An HTML-based PNG resume generator for HackMyResume.
 | 
					  An HTML-based PNG resume generator for HackMyResume.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HtmlPngGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = HtmlPngGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(HtmlPngGenerator, superClass);
 | 
				
			||||||
      return this._super('png', 'html');
 | 
					
 | 
				
			||||||
    },
 | 
					    function HtmlPngGenerator() {
 | 
				
			||||||
    invoke: function(rez, themeMarkup, cssInfo, opts) {},
 | 
					      HtmlPngGenerator.__super__.constructor.call(this, 'png', 'html');
 | 
				
			||||||
    generate: function(rez, f, opts) {
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HtmlPngGenerator.prototype.invoke = function(rez, themeMarkup, cssInfo, opts) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    HtmlPngGenerator.prototype.generate = function(rez, f, opts) {
 | 
				
			||||||
      var htmlFile, htmlResults;
 | 
					      var htmlFile, htmlResults;
 | 
				
			||||||
      htmlResults = opts.targets.filter(function(t) {
 | 
					      htmlResults = opts.targets.filter(function(t) {
 | 
				
			||||||
        return t.fmt.outFormat === 'html';
 | 
					        return t.fmt.outFormat === 'html';
 | 
				
			||||||
@@ -39,8 +45,11 @@ Definition of the HtmlPngGenerator class.
 | 
				
			|||||||
        return fl.info.ext === 'html';
 | 
					        return fl.info.ext === 'html';
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      phantom(htmlFile[0].data, f);
 | 
					      phantom(htmlFile[0].data, f);
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return HtmlPngGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -62,3 +71,5 @@ Definition of the HtmlPngGenerator class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=html-png-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								dist/generators/json-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								dist/generators/json-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the JsonGenerator class.
 | 
					Definition of the JsonGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/json-generator
 | 
					@module generators/json-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BaseGenerator, FS, JsonGenerator, _;
 | 
					  var BaseGenerator, FJCV, FS, JsonGenerator, _,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BaseGenerator = require('./base-generator');
 | 
					  BaseGenerator = require('./base-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,32 +16,32 @@ Definition of the JsonGenerator class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _ = require('underscore');
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FJCV = require('fresh-jrs-converter');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
  The JsonGenerator generates a JSON resume directly.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  JsonGenerator = module.exports = BaseGenerator.extend({
 | 
					  /** The JsonGenerator generates a FRESH or JRS resume as an output. */
 | 
				
			||||||
    init: function() {
 | 
					
 | 
				
			||||||
      return this._super('json');
 | 
					  module.exports = JsonGenerator = (function(superClass) {
 | 
				
			||||||
    },
 | 
					    extend(JsonGenerator, superClass);
 | 
				
			||||||
    keys: ['imp', 'warnings', 'computed', 'filt', 'ctrl', 'index', 'safeStartDate', 'safeEndDate', 'safeDate', 'safeReleaseDate', 'result', 'isModified', 'htmlPreview', 'safe'],
 | 
					
 | 
				
			||||||
    invoke: function(rez) {
 | 
					    function JsonGenerator() {
 | 
				
			||||||
      var replacer;
 | 
					      JsonGenerator.__super__.constructor.call(this, 'json');
 | 
				
			||||||
      replacer = function(key, value) {
 | 
					 | 
				
			||||||
        if (_.some(this.keys, function(val) {
 | 
					 | 
				
			||||||
          return key.trim() === val;
 | 
					 | 
				
			||||||
        })) {
 | 
					 | 
				
			||||||
          return void 0;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          return value;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      return JSON.stringify(rez, replacer, 2);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    generate: function(rez, f) {
 | 
					 | 
				
			||||||
      FS.writeFileSync(f, this.invoke(rez), 'utf8');
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    JsonGenerator.prototype.invoke = function(rez) {
 | 
				
			||||||
 | 
					      var altRez;
 | 
				
			||||||
 | 
					      altRez = FJCV['to' + (rez.format() === 'FRESH' ? 'JRS' : 'FRESH')](rez);
 | 
				
			||||||
 | 
					      return altRez = FJCV.toSTRING(altRez);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JsonGenerator.prototype.generate = function(rez, f) {
 | 
				
			||||||
 | 
					      FS.writeFileSync(f, this.invoke(rez), 'utf8');
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return JsonGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(BaseGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=json-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								dist/generators/json-yaml-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								dist/generators/json-yaml-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the JsonYamlGenerator class.
 | 
					Definition of the JsonYamlGenerator class.
 | 
				
			||||||
@module json-yaml-generator.js
 | 
					@module generators/json-yaml-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BaseGenerator, FS, JsonYamlGenerator, YAML;
 | 
					  var BaseGenerator, FS, JsonYamlGenerator, YAML,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BaseGenerator = require('./base-generator');
 | 
					  BaseGenerator = require('./base-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,18 +23,28 @@ Definition of the JsonYamlGenerator class.
 | 
				
			|||||||
  also YamlGenerator (yaml-generator.js).
 | 
					  also YamlGenerator (yaml-generator.js).
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  JsonYamlGenerator = module.exports = BaseGenerator.extend({
 | 
					  module.exports = JsonYamlGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(JsonYamlGenerator, superClass);
 | 
				
			||||||
      return this._super('yml');
 | 
					
 | 
				
			||||||
    },
 | 
					    function JsonYamlGenerator() {
 | 
				
			||||||
    invoke: function(rez, themeMarkup, cssInfo, opts) {
 | 
					      JsonYamlGenerator.__super__.constructor.call(this, 'yml');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    JsonYamlGenerator.prototype.invoke = function(rez, themeMarkup, cssInfo, opts) {
 | 
				
			||||||
      return YAML.stringify(JSON.parse(rez.stringify()), Infinity, 2);
 | 
					      return YAML.stringify(JSON.parse(rez.stringify()), Infinity, 2);
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
    generate: function(rez, f, opts) {
 | 
					
 | 
				
			||||||
 | 
					    JsonYamlGenerator.prototype.generate = function(rez, f, opts) {
 | 
				
			||||||
      var data;
 | 
					      var data;
 | 
				
			||||||
      data = YAML.stringify(JSON.parse(rez.stringify()), Infinity, 2);
 | 
					      data = YAML.stringify(JSON.parse(rez.stringify()), Infinity, 2);
 | 
				
			||||||
      return FS.writeFileSync(f, data, 'utf8');
 | 
					      FS.writeFileSync(f, data, 'utf8');
 | 
				
			||||||
    }
 | 
					      return data;
 | 
				
			||||||
  });
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return JsonYamlGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(BaseGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=json-yaml-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								dist/generators/latex-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								dist/generators/latex-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the LaTeXGenerator class.
 | 
					Definition of the LaTeXGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/latex-generator
 | 
					@module generators/latex-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var LaTeXGenerator, TemplateGenerator;
 | 
					  var LaTeXGenerator, TemplateGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,10 +17,17 @@ Definition of the LaTeXGenerator class.
 | 
				
			|||||||
  LaTeXGenerator generates a LaTeX resume via TemplateGenerator.
 | 
					  LaTeXGenerator generates a LaTeX resume via TemplateGenerator.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LaTeXGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = LaTeXGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(LaTeXGenerator, superClass);
 | 
				
			||||||
      return this._super('latex', 'tex');
 | 
					
 | 
				
			||||||
 | 
					    function LaTeXGenerator() {
 | 
				
			||||||
 | 
					      LaTeXGenerator.__super__.constructor.call(this, 'latex', 'tex');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return LaTeXGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=latex-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								dist/generators/markdown-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								dist/generators/markdown-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the MarkdownGenerator class.
 | 
					Definition of the MarkdownGenerator class.
 | 
				
			||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
 | 
					@module generators/markdown-generator
 | 
				
			||||||
@module markdown-generator.js
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var MarkdownGenerator, TemplateGenerator;
 | 
					  var MarkdownGenerator, TemplateGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,10 +17,17 @@ Definition of the MarkdownGenerator class.
 | 
				
			|||||||
  MarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator.
 | 
					  MarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MarkdownGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = MarkdownGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(MarkdownGenerator, superClass);
 | 
				
			||||||
      return this._super('md', 'txt');
 | 
					
 | 
				
			||||||
 | 
					    function MarkdownGenerator() {
 | 
				
			||||||
 | 
					      MarkdownGenerator.__super__.constructor.call(this, 'md', 'txt');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return MarkdownGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=markdown-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										131
									
								
								dist/generators/template-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								dist/generators/template-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the TemplateGenerator class. TODO: Refactor
 | 
					Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			||||||
 | 
					@module generators/template-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module template-generator.js
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BaseGenerator, EXTEND, FRESHTheme, FS, JRSTheme, MD, MKDIRP, PATH, TemplateGenerator, XML, _, _defaultOpts, _reg, freeze, parsePath, unfreeze;
 | 
					  var BaseGenerator, EXTEND, FRESHTheme, FS, JRSTheme, MD, MKDIRP, PATH, TemplateGenerator, XML, _, _defaultOpts, _reg, createSymLinks, freeze, parsePath, unfreeze,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs-extra');
 | 
					  FS = require('fs-extra');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,16 +40,21 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
  @class TemplateGenerator
 | 
					  @class TemplateGenerator
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = module.exports = BaseGenerator.extend({
 | 
					  module.exports = TemplateGenerator = (function(superClass) {
 | 
				
			||||||
 | 
					    extend(TemplateGenerator, superClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Constructor. Set the output format and template format for this
 | 
					    /** Constructor. Set the output format and template format for this
 | 
				
			||||||
    generator. Will usually be called by a derived generator such as
 | 
					    generator. Will usually be called by a derived generator such as
 | 
				
			||||||
    HTMLGenerator or MarkdownGenerator.
 | 
					    HTMLGenerator or MarkdownGenerator.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    init: function(outputFormat, templateFormat, cssFile) {
 | 
					
 | 
				
			||||||
      this._super(outputFormat);
 | 
					    function TemplateGenerator(outputFormat, templateFormat, cssFile) {
 | 
				
			||||||
 | 
					      TemplateGenerator.__super__.constructor.call(this, outputFormat);
 | 
				
			||||||
      this.tplFormat = templateFormat || outputFormat;
 | 
					      this.tplFormat = templateFormat || outputFormat;
 | 
				
			||||||
    },
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Generate a resume using string-based inputs and outputs without touching
 | 
					    /** Generate a resume using string-based inputs and outputs without touching
 | 
				
			||||||
    the filesystem.
 | 
					    the filesystem.
 | 
				
			||||||
@@ -57,7 +64,8 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
    @returns {Array} An array of objects representing the generated output
 | 
					    @returns {Array} An array of objects representing the generated output
 | 
				
			||||||
    files.
 | 
					    files.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    invoke: function(rez, opts) {
 | 
					
 | 
				
			||||||
 | 
					    TemplateGenerator.prototype.invoke = function(rez, opts) {
 | 
				
			||||||
      var curFmt, results;
 | 
					      var curFmt, results;
 | 
				
			||||||
      opts = opts ? (this.opts = EXTEND(true, {}, _defaultOpts, opts)) : this.opts;
 | 
					      opts = opts ? (this.opts = EXTEND(true, {}, _defaultOpts, opts)) : this.opts;
 | 
				
			||||||
      curFmt = opts.themeObj.getFormat(this.format);
 | 
					      curFmt = opts.themeObj.getFormat(this.format);
 | 
				
			||||||
@@ -66,11 +74,18 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
      results = curFmt.files.map(function(tplInfo, idx) {
 | 
					      results = curFmt.files.map(function(tplInfo, idx) {
 | 
				
			||||||
        var trx;
 | 
					        var trx;
 | 
				
			||||||
        trx = this.single(rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt);
 | 
					        if (tplInfo.action === 'transform') {
 | 
				
			||||||
        if (tplInfo.ext === 'css') {
 | 
					          trx = this.transform(rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt);
 | 
				
			||||||
          curFmt.files[idx].data = trx;
 | 
					          if (tplInfo.ext === 'css') {
 | 
				
			||||||
 | 
					            curFmt.files[idx].data = trx;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            tplInfo.ext === 'html';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          tplInfo.ext === 'html';
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof opts.onTransform === "function") {
 | 
				
			||||||
 | 
					          opts.onTransform(tplInfo);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
          info: tplInfo,
 | 
					          info: tplInfo,
 | 
				
			||||||
@@ -80,7 +95,8 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
      return {
 | 
					      return {
 | 
				
			||||||
        files: results
 | 
					        files: results
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Generate a resume using file-based inputs and outputs. Requires access
 | 
					    /** Generate a resume using file-based inputs and outputs. Requires access
 | 
				
			||||||
    to the local filesystem.
 | 
					    to the local filesystem.
 | 
				
			||||||
@@ -89,33 +105,44 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
    @param f Full path to the output resume file to generate.
 | 
					    @param f Full path to the output resume file to generate.
 | 
				
			||||||
    @param opts Generator options.
 | 
					    @param opts Generator options.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    generate: function(rez, f, opts) {
 | 
					
 | 
				
			||||||
 | 
					    TemplateGenerator.prototype.generate = function(rez, f, opts) {
 | 
				
			||||||
      var curFmt, genInfo, outFolder;
 | 
					      var curFmt, genInfo, outFolder;
 | 
				
			||||||
      this.opts = EXTEND(true, {}, _defaultOpts, opts);
 | 
					      this.opts = EXTEND(true, {}, _defaultOpts, opts);
 | 
				
			||||||
      genInfo = this.invoke(rez, null);
 | 
					      genInfo = this.invoke(rez, null);
 | 
				
			||||||
      outFolder = parsePath(f).dirname;
 | 
					      outFolder = parsePath(f).dirname;
 | 
				
			||||||
      curFmt = opts.themeObj.getFormat(this.format);
 | 
					      curFmt = opts.themeObj.getFormat(this.format);
 | 
				
			||||||
      genInfo.files.forEach(function(file) {
 | 
					      genInfo.files.forEach(function(file) {
 | 
				
			||||||
        var fileName, thisFilePath;
 | 
					        var thisFilePath;
 | 
				
			||||||
        file.info.orgPath = file.info.orgPath || '';
 | 
					        file.info.orgPath = file.info.orgPath || '';
 | 
				
			||||||
        thisFilePath = PATH.join(outFolder, file.info.orgPath);
 | 
					        thisFilePath = file.info.primary ? f : PATH.join(outFolder, file.info.orgPath);
 | 
				
			||||||
        if (this.onBeforeSave) {
 | 
					        if (file.info.action !== 'copy' && this.onBeforeSave) {
 | 
				
			||||||
          file.data = this.onBeforeSave({
 | 
					          file.data = this.onBeforeSave({
 | 
				
			||||||
            theme: opts.themeObj,
 | 
					            theme: opts.themeObj,
 | 
				
			||||||
            outputFile: file.info.major ? f : thisFilePath,
 | 
					            outputFile: thisFilePath,
 | 
				
			||||||
            mk: file.data,
 | 
					            mk: file.data,
 | 
				
			||||||
            opts: this.opts
 | 
					            opts: this.opts,
 | 
				
			||||||
 | 
					            ext: file.info.ext
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
          if (!file.data) {
 | 
					          if (!file.data) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        fileName = file.info.major ? f : thisFilePath;
 | 
					        if (typeof opts.beforeWrite === "function") {
 | 
				
			||||||
        MKDIRP.sync(PATH.dirname(fileName));
 | 
					          opts.beforeWrite(thisFilePath);
 | 
				
			||||||
        FS.writeFileSync(fileName, file.data, {
 | 
					        }
 | 
				
			||||||
          encoding: 'utf8',
 | 
					        MKDIRP.sync(PATH.dirname(thisFilePath));
 | 
				
			||||||
          flags: 'w'
 | 
					        if (file.info.action !== 'copy') {
 | 
				
			||||||
        });
 | 
					          FS.writeFileSync(thisFilePath, file.data, {
 | 
				
			||||||
 | 
					            encoding: 'utf8',
 | 
				
			||||||
 | 
					            flags: 'w'
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          FS.copySync(file.info.path, thisFilePath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (typeof opts.afterWrite === "function") {
 | 
				
			||||||
 | 
					          opts.afterWrite(thisFilePath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (this.onAfterSave) {
 | 
					        if (this.onAfterSave) {
 | 
				
			||||||
          return this.onAfterSave({
 | 
					          return this.onAfterSave({
 | 
				
			||||||
            outputFile: fileName,
 | 
					            outputFile: fileName,
 | 
				
			||||||
@@ -124,19 +151,10 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }, this);
 | 
					      }, this);
 | 
				
			||||||
      if (curFmt.symLinks) {
 | 
					      createSymLinks(curFmt, outFolder);
 | 
				
			||||||
        Object.keys(curFmt.symLinks).forEach(function(loc) {
 | 
					 | 
				
			||||||
          var absLoc, absTarg, ref, type;
 | 
					 | 
				
			||||||
          absLoc = PATH.join(outFolder, loc);
 | 
					 | 
				
			||||||
          absTarg = PATH.join(PATH.dirname(absLoc), curFmt.symLinks[loc]);
 | 
					 | 
				
			||||||
          type = (ref = parsePath(absLoc).extname) != null ? ref : {
 | 
					 | 
				
			||||||
            'file': 'junction'
 | 
					 | 
				
			||||||
          };
 | 
					 | 
				
			||||||
          return FS.symlinkSync(absTarg, absLoc, type);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return genInfo;
 | 
					      return genInfo;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Perform a single resume resume transformation using string-based inputs
 | 
					    /** Perform a single resume resume transformation using string-based inputs
 | 
				
			||||||
    and outputs without touching the local file system.
 | 
					    and outputs without touching the local file system.
 | 
				
			||||||
@@ -146,7 +164,8 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
    @param cssInfo Needs to be refactored.
 | 
					    @param cssInfo Needs to be refactored.
 | 
				
			||||||
    @param opts Options and passthrough data.
 | 
					    @param opts Options and passthrough data.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    single: function(json, jst, format, opts, theme, curFmt) {
 | 
					
 | 
				
			||||||
 | 
					    TemplateGenerator.prototype.transform = function(json, jst, format, opts, theme, curFmt) {
 | 
				
			||||||
      var eng, result;
 | 
					      var eng, result;
 | 
				
			||||||
      if (this.opts.freezeBreaks) {
 | 
					      if (this.opts.freezeBreaks) {
 | 
				
			||||||
        jst = freeze(jst);
 | 
					        jst = freeze(jst);
 | 
				
			||||||
@@ -157,13 +176,37 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
        result = unfreeze(result);
 | 
					        result = unfreeze(result);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return result;
 | 
					      return result;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TemplateGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(BaseGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  createSymLinks = function(curFmt, outFolder) {
 | 
				
			||||||
 | 
					    if (curFmt.symLinks) {
 | 
				
			||||||
 | 
					      Object.keys(curFmt.symLinks).forEach(function(loc) {
 | 
				
			||||||
 | 
					        var absLoc, absTarg, succeeded, type;
 | 
				
			||||||
 | 
					        absLoc = PATH.join(outFolder, loc);
 | 
				
			||||||
 | 
					        absTarg = PATH.join(PATH.dirname(absLoc), curFmt.symLinks[loc]);
 | 
				
			||||||
 | 
					        type = parsePath(absLoc).extname ? 'file' : 'junction';
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          return FS.symlinkSync(absTarg, absLoc, type);
 | 
				
			||||||
 | 
					        } catch (_error) {
 | 
				
			||||||
 | 
					          succeeded = false;
 | 
				
			||||||
 | 
					          if (_error.code === 'EEXIST') {
 | 
				
			||||||
 | 
					            FS.unlinkSync(absLoc);
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					              FS.symlinkSync(absTarg, absLoc, type);
 | 
				
			||||||
 | 
					              succeeded = true;
 | 
				
			||||||
 | 
					            } catch (_error) {}
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (!succeeded) {
 | 
				
			||||||
 | 
					            throw ex;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  };
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** Export the TemplateGenerator function/ctor. */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  module.exports = TemplateGenerator;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Freeze newlines for protection against errant JST parsers. */
 | 
					  /** Freeze newlines for protection against errant JST parsers. */
 | 
				
			||||||
@@ -241,3 +284,5 @@ Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=template-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								dist/generators/text-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								dist/generators/text-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Definition of the TextGenerator class.
 | 
					Definition of the TextGenerator class.
 | 
				
			||||||
 | 
					@module generators/text-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module text-generator.js
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var TemplateGenerator, TextGenerator;
 | 
					  var TemplateGenerator, TextGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,10 +17,17 @@ Definition of the TextGenerator class.
 | 
				
			|||||||
  The TextGenerator generates a plain-text resume via the TemplateGenerator.
 | 
					  The TextGenerator generates a plain-text resume via the TemplateGenerator.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TextGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = TextGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(TextGenerator, superClass);
 | 
				
			||||||
      return this._super('txt');
 | 
					
 | 
				
			||||||
 | 
					    function TextGenerator() {
 | 
				
			||||||
 | 
					      TextGenerator.__super__.constructor.call(this, 'txt');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return TextGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=text-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								dist/generators/word-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								dist/generators/word-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -1,19 +1,28 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
Definition of the WordGenerator class.
 | 
					Definition of the WordGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/word-generator
 | 
					@module generators/word-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var TemplateGenerator, WordGenerator;
 | 
					  var TemplateGenerator, WordGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  WordGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = WordGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(WordGenerator, superClass);
 | 
				
			||||||
      return this._super('doc', 'xml');
 | 
					
 | 
				
			||||||
 | 
					    function WordGenerator() {
 | 
				
			||||||
 | 
					      WordGenerator.__super__.constructor.call(this, 'doc', 'xml');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return WordGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=word-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								dist/generators/xml-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								dist/generators/xml-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -6,19 +6,26 @@ Definition of the XMLGenerator class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BaseGenerator, XMLGenerator;
 | 
					  var BaseGenerator, XMLGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BaseGenerator = require('./base-generator');
 | 
					  BaseGenerator = require('./base-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** The XmlGenerator generates an XML resume via the TemplateGenerator. */
 | 
				
			||||||
  The XmlGenerator generates an XML resume via the TemplateGenerator.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  XMLGenerator = module.exports = BaseGenerator.extend({
 | 
					  module.exports = XMLGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(XMLGenerator, superClass);
 | 
				
			||||||
      return this._super('xml');
 | 
					
 | 
				
			||||||
 | 
					    function XMLGenerator() {
 | 
				
			||||||
 | 
					      XMLGenerator.__super__.constructor.call(this, 'xml');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return XMLGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(BaseGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=xml-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								dist/generators/yaml-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								dist/generators/yaml-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Definition of the YAMLGenerator class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var TemplateGenerator, YAMLGenerator;
 | 
					  var TemplateGenerator, YAMLGenerator,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TemplateGenerator = require('./template-generator');
 | 
					  TemplateGenerator = require('./template-generator');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,10 +17,17 @@ Definition of the YAMLGenerator class.
 | 
				
			|||||||
  YamlGenerator generates a YAML-formatted resume via TemplateGenerator.
 | 
					  YamlGenerator generates a YAML-formatted resume via TemplateGenerator.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  YAMLGenerator = module.exports = TemplateGenerator.extend({
 | 
					  module.exports = YAMLGenerator = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(YAMLGenerator, superClass);
 | 
				
			||||||
      return this._super('yml', 'yml');
 | 
					
 | 
				
			||||||
 | 
					    function YAMLGenerator() {
 | 
				
			||||||
 | 
					      YAMLGenerator.__super__.constructor.call(this, 'yml', 'yml');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return YAMLGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(TemplateGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=yaml-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										71
									
								
								dist/helpers/block-helpers.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								dist/helpers/block-helpers.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					Block helper definitions for HackMyResume / FluentCV.
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 | 
					@module helpers/generic-helpers
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					  var BlockHelpers, HMSTATUS, LO, _, unused;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HMSTATUS = require('../core/status-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LO = require('lodash');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  unused = require('../utils/string');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Block helper function definitions. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BlockHelpers = module.exports = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					    Emit the enclosed content if the resume has a section with
 | 
				
			||||||
 | 
					    the specified name. Otherwise, emit an empty string ''.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    section: function(title, options) {
 | 
				
			||||||
 | 
					      var obj, ret;
 | 
				
			||||||
 | 
					      title = title.trim().toLowerCase();
 | 
				
			||||||
 | 
					      obj = LO.get(this.r, title);
 | 
				
			||||||
 | 
					      ret = '';
 | 
				
			||||||
 | 
					      if (obj) {
 | 
				
			||||||
 | 
					        if (_.isArray(obj)) {
 | 
				
			||||||
 | 
					          if (obj.length) {
 | 
				
			||||||
 | 
					            ret = options.fn(this);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else if (_.isObject(obj)) {
 | 
				
			||||||
 | 
					          if ((obj.history && obj.history.length) || (obj.sets && obj.sets.length)) {
 | 
				
			||||||
 | 
					            ret = options.fn(this);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					    Emit the enclosed content if the resume has the named
 | 
				
			||||||
 | 
					    property or subproperty.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    has: function(title, options) {
 | 
				
			||||||
 | 
					      title = title && title.trim().toLowerCase();
 | 
				
			||||||
 | 
					      if (LO.get(this.r, title)) {
 | 
				
			||||||
 | 
					        return options.fn(this);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					    Return true if either value is truthy.
 | 
				
			||||||
 | 
					    @method either
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    either: function(lhs, rhs, options) {
 | 
				
			||||||
 | 
					      if (lhs || rhs) {
 | 
				
			||||||
 | 
					        return options.fn(this);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=block-helpers.js.map
 | 
				
			||||||
							
								
								
									
										2
									
								
								dist/helpers/console-helpers.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/helpers/console-helpers.js
									
									
									
									
										vendored
									
									
								
							@@ -62,3 +62,5 @@ Generic template helper definitions for command-line output.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=console-helpers.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										161
									
								
								dist/helpers/generic-helpers.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								dist/helpers/generic-helpers.js
									
									
									
									
										vendored
									
									
								
							@@ -38,36 +38,85 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
  GenericHelpers = module.exports = {
 | 
					  GenericHelpers = module.exports = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Convert the input date to a specified format through Moment.js.
 | 
					    Emit a formatted string representing the specified datetime.
 | 
				
			||||||
    If date is invalid, will return the time provided by the user,
 | 
					    Convert the input date to the specified format through Moment.js. If date is
 | 
				
			||||||
    or default to the fallback param or 'Present' if that is set to true
 | 
					    valid, return the formatted date string. If date is null, undefined, or other
 | 
				
			||||||
    @method formatDate
 | 
					    falsy value, return the value of the 'fallback' parameter, if specified, or
 | 
				
			||||||
 | 
					    null if no fallback was specified. If date is invalid, but not null/undefined/
 | 
				
			||||||
 | 
					    falsy, return it as-is.
 | 
				
			||||||
 | 
					    @param {string|Moment} datetime A date value.
 | 
				
			||||||
 | 
					    @param {string} [dtFormat='YYYY-MM'] The desired datetime format. Must be a
 | 
				
			||||||
 | 
					    Moment.js-compatible datetime format.
 | 
				
			||||||
 | 
					    @param {string|Moment} fallback A fallback value to use if the specified date
 | 
				
			||||||
 | 
					    is null, undefined, or falsy.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    formatDate: function(datetime, format, fallback) {
 | 
					    formatDate: function(datetime, dtFormat, fallback) {
 | 
				
			||||||
      var momentDate, ref, ref1;
 | 
					      var momentDate;
 | 
				
			||||||
      if (moment) {
 | 
					      if (datetime == null) {
 | 
				
			||||||
 | 
					        datetime = void 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (dtFormat == null) {
 | 
				
			||||||
 | 
					        dtFormat = 'YYYY-MM';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (datetime && moment.isMoment(datetime)) {
 | 
				
			||||||
 | 
					        return datetime.format(dtFormat);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (String.is(datetime)) {
 | 
				
			||||||
 | 
					        momentDate = moment(datetime, dtFormat);
 | 
				
			||||||
 | 
					        if (momentDate.isValid()) {
 | 
				
			||||||
 | 
					          return momentDate.format(dtFormat);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        momentDate = moment(datetime);
 | 
					        momentDate = moment(datetime);
 | 
				
			||||||
        if (momentDate.isValid()) {
 | 
					        if (momentDate.isValid()) {
 | 
				
			||||||
          return momentDate.format(format);
 | 
					          return momentDate.format(dtFormat);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return datetime || ((ref = typeof fallback === 'string') != null ? ref : {
 | 
					      return datetime || (typeof fallback === 'string' ? fallback : (fallback === true ? 'Present' : ''));
 | 
				
			||||||
        fallback: (ref1 = fallback === true) != null ? ref1 : {
 | 
					    },
 | 
				
			||||||
          'Present': null
 | 
					
 | 
				
			||||||
        }
 | 
					    /**
 | 
				
			||||||
      });
 | 
					    Emit a formatted string representing the specified datetime.
 | 
				
			||||||
 | 
					    @param {string} dateValue A raw date value from the FRESH or JRS resume.
 | 
				
			||||||
 | 
					    @param {string} [dateFormat='YYYY-MM'] The desired datetime format. Must be
 | 
				
			||||||
 | 
					    compatible with Moment.js datetime formats.
 | 
				
			||||||
 | 
					    @param {string} [dateDefault=null] The default date value to use if the dateValue
 | 
				
			||||||
 | 
					    parameter is null, undefined, or falsy.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    date: function(dateValue, dateFormat, dateDefault) {
 | 
				
			||||||
 | 
					      var dateValueMoment, dateValueSafe, reserved;
 | 
				
			||||||
 | 
					      if (!dateDefault || !String.is(dateDefault)) {
 | 
				
			||||||
 | 
					        dateDefault = 'Current';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (!dateFormat || !String.is(dateFormat)) {
 | 
				
			||||||
 | 
					        dateFormat = 'YYYY-MM';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (!dateValue || !String.is(dateValue)) {
 | 
				
			||||||
 | 
					        dateValue = null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (!dateValue) {
 | 
				
			||||||
 | 
					        return dateDefault;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      reserved = ['current', 'present', 'now'];
 | 
				
			||||||
 | 
					      dateValueSafe = dateValue.trim().toLowerCase();
 | 
				
			||||||
 | 
					      if (_.contains(reserved, dateValueSafe)) {
 | 
				
			||||||
 | 
					        return dateValue;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      dateValueMoment = moment(dateValue, dateFormat);
 | 
				
			||||||
 | 
					      if (dateValueMoment.isValid()) {
 | 
				
			||||||
 | 
					        return dateValueMoment.format(dateFormat);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return dateValue;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Given a resume sub-object with a start/end date, format a representation of
 | 
					    Given a resume sub-object with a start/end date, format a representation of
 | 
				
			||||||
    the date range.
 | 
					    the date range.
 | 
				
			||||||
    @method dateRange
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    dateRange: function(obj, fmt, sep, fallback, options) {
 | 
					    dateRange: function(obj, fmt, sep, fallback) {
 | 
				
			||||||
      if (!obj) {
 | 
					      if (!obj) {
 | 
				
			||||||
        return '';
 | 
					        return '';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return _fromTo(obj.start, obj.end, fmt, sep, fallback, options);
 | 
					      return _fromTo(obj.start, obj.end, fmt, sep, fallback);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -102,30 +151,6 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    Return true if the section is present on the resume and has at least one
 | 
					 | 
				
			||||||
    element.
 | 
					 | 
				
			||||||
    @method section
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    section: function(title, options) {
 | 
					 | 
				
			||||||
      var obj, ret;
 | 
					 | 
				
			||||||
      title = title.trim().toLowerCase();
 | 
					 | 
				
			||||||
      obj = LO.get(this.r, title);
 | 
					 | 
				
			||||||
      ret = '';
 | 
					 | 
				
			||||||
      if (obj) {
 | 
					 | 
				
			||||||
        if (_.isArray(obj)) {
 | 
					 | 
				
			||||||
          if (obj.length) {
 | 
					 | 
				
			||||||
            ret = options.fn(this);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        } else if (_.isObject(obj)) {
 | 
					 | 
				
			||||||
          if ((obj.history && obj.history.length) || (obj.sets && obj.sets.length)) {
 | 
					 | 
				
			||||||
            ret = options.fn(this);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return ret;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Emit the size of the specified named font.
 | 
					    Emit the size of the specified named font.
 | 
				
			||||||
    @param key {String} A named style from the "fonts" section of the theme's
 | 
					    @param key {String} A named style from the "fonts" section of the theme's
 | 
				
			||||||
@@ -283,7 +308,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Capitalize the first letter of the word.
 | 
					    Capitalize the first letter of the word. TODO: Rename
 | 
				
			||||||
    @method section
 | 
					    @method section
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    camelCase: function(val) {
 | 
					    camelCase: function(val) {
 | 
				
			||||||
@@ -296,20 +321,8 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Return true if the context has the property or subpropery.
 | 
					    Display a user-overridable section title for a FRESH resume theme. Use this in
 | 
				
			||||||
    @method has
 | 
					    lieue of hard-coding section titles.
 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    has: function(title, options) {
 | 
					 | 
				
			||||||
      title = title && title.trim().toLowerCase();
 | 
					 | 
				
			||||||
      if (LO.get(this.r, title)) {
 | 
					 | 
				
			||||||
        return options.fn(this);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    Generic template helper function to display a user-overridable section
 | 
					 | 
				
			||||||
    title for a FRESH resume theme. Use this in lieue of hard-coding section
 | 
					 | 
				
			||||||
    titles.
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Usage:
 | 
					    Usage:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -332,10 +345,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
      return (this.opts.stitles && this.opts.stitles[sname.toLowerCase().trim()]) || stitle;
 | 
					      return (this.opts.stitles && this.opts.stitles[sname.toLowerCase().trim()]) || stitle;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /** Convert inline Markdown to inline WordProcessingML. */
 | 
				
			||||||
    Convert inline Markdown to inline WordProcessingML.
 | 
					 | 
				
			||||||
    @method wpml
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    wpml: function(txt, inline) {
 | 
					    wpml: function(txt, inline) {
 | 
				
			||||||
      if (!txt) {
 | 
					      if (!txt) {
 | 
				
			||||||
        return '';
 | 
					        return '';
 | 
				
			||||||
@@ -444,16 +454,6 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
    Return true if either value is truthy.
 | 
					 | 
				
			||||||
    @method either
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    either: function(lhs, rhs, options) {
 | 
					 | 
				
			||||||
      if (lhs || rhs) {
 | 
					 | 
				
			||||||
        return options.fn(this);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    Conditional stylesheet link. Creates a link to the specified stylesheet with
 | 
					    Conditional stylesheet link. Creates a link to the specified stylesheet with
 | 
				
			||||||
    <link> or embeds the styles inline with <style></style>, depending on the
 | 
					    <link> or embeds the styles inline with <style></style>, depending on the
 | 
				
			||||||
@@ -488,7 +488,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
    compare: function(lvalue, rvalue, options) {
 | 
					    compare: function(lvalue, rvalue, options) {
 | 
				
			||||||
      var operator, operators, result;
 | 
					      var operator, operators, result;
 | 
				
			||||||
      if (arguments.length < 3) {
 | 
					      if (arguments.length < 3) {
 | 
				
			||||||
        throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
 | 
					        throw new Error("Template helper 'compare' needs 2 parameters");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      operator = options.hash.operator || "==";
 | 
					      operator = options.hash.operator || "==";
 | 
				
			||||||
      operators = {
 | 
					      operators = {
 | 
				
			||||||
@@ -518,7 +518,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      if (!operators[operator]) {
 | 
					      if (!operators[operator]) {
 | 
				
			||||||
        throw new Error("Handlerbars Helper 'compare' doesn't know the operator " + operator);
 | 
					        throw new Error("Helper 'compare' doesn't know the operator " + operator);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      result = operators[operator](lvalue, rvalue);
 | 
					      result = operators[operator](lvalue, rvalue);
 | 
				
			||||||
      if (result) {
 | 
					      if (result) {
 | 
				
			||||||
@@ -526,6 +526,21 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        return options.inverse(this);
 | 
					        return options.inverse(this);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    pad: function(stringOrArray, padAmount, unused) {
 | 
				
			||||||
 | 
					      var PAD, ret;
 | 
				
			||||||
 | 
					      stringOrArray = stringOrArray || '';
 | 
				
			||||||
 | 
					      padAmount = padAmount || 0;
 | 
				
			||||||
 | 
					      ret = '';
 | 
				
			||||||
 | 
					      PAD = require('string-padding');
 | 
				
			||||||
 | 
					      if (!String.is(stringOrArray)) {
 | 
				
			||||||
 | 
					        ret = stringOrArray.map(function(line) {
 | 
				
			||||||
 | 
					          return PAD(line, line.length + Math.abs(padAmount), null, padAmount < 0 ? PAD.LEFT : PAD.RIGHT);
 | 
				
			||||||
 | 
					        }).join('\n');
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        ret = PAD(stringOrArray, stringOrArray.length + Math.abs(padAmount), null, padAmount < 0 ? PAD.LEFT : PAD.RIGHT);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -569,7 +584,7 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
      dateFrom = dateTemp.format(fmt);
 | 
					      dateFrom = dateTemp.format(fmt);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (_.contains(reserved, dateBTrim)) {
 | 
					    if (_.contains(reserved, dateBTrim)) {
 | 
				
			||||||
      dateTo = fallback || 'Current';
 | 
					      dateTo = fallback || 'Present';
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      dateTemp = FluentDate.fmt(dateB);
 | 
					      dateTemp = FluentDate.fmt(dateB);
 | 
				
			||||||
      dateTo = dateTemp.format(fmt);
 | 
					      dateTo = dateTemp.format(fmt);
 | 
				
			||||||
@@ -614,3 +629,5 @@ Generic template helper definitions for HackMyResume / FluentCV.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=generic-helpers.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								dist/helpers/handlebars-helpers.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								dist/helpers/handlebars-helpers.js
									
									
									
									
										vendored
									
									
								
							@@ -1,12 +1,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Template helper definitions for Handlebars.
 | 
					Template helper definitions for Handlebars.
 | 
				
			||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module handlebars-helpers.js
 | 
					@module handlebars-helpers.js
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var HANDLEBARS, _, helpers;
 | 
					  var HANDLEBARS, _, blockHelpers, helpers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HANDLEBARS = require('handlebars');
 | 
					  HANDLEBARS = require('handlebars');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,6 +14,8 @@ Template helper definitions for Handlebars.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  helpers = require('./generic-helpers');
 | 
					  helpers = require('./generic-helpers');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  blockHelpers = require('./block-helpers');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  Register useful Handlebars helpers.
 | 
					  Register useful Handlebars helpers.
 | 
				
			||||||
@@ -21,9 +23,26 @@ Template helper definitions for Handlebars.
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  module.exports = function(theme, opts) {
 | 
					  module.exports = function(theme, opts) {
 | 
				
			||||||
 | 
					    var wrappedHelpers;
 | 
				
			||||||
    helpers.theme = theme;
 | 
					    helpers.theme = theme;
 | 
				
			||||||
    helpers.opts = opts;
 | 
					    helpers.opts = opts;
 | 
				
			||||||
    return HANDLEBARS.registerHelper(helpers);
 | 
					    helpers.type = 'handlebars';
 | 
				
			||||||
 | 
					    wrappedHelpers = _.mapObject(helpers, function(hVal, hKey) {
 | 
				
			||||||
 | 
					      if (_.isFunction(hVal)) {
 | 
				
			||||||
 | 
					        _.wrap(hVal, function(func) {
 | 
				
			||||||
 | 
					          var args;
 | 
				
			||||||
 | 
					          args = Array.prototype.slice.call(arguments);
 | 
				
			||||||
 | 
					          args.shift();
 | 
				
			||||||
 | 
					          args.pop();
 | 
				
			||||||
 | 
					          return func.apply(this, args);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return hVal;
 | 
				
			||||||
 | 
					    }, this);
 | 
				
			||||||
 | 
					    HANDLEBARS.registerHelper(wrappedHelpers);
 | 
				
			||||||
 | 
					    HANDLEBARS.registerHelper(blockHelpers);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=handlebars-helpers.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								dist/helpers/underscore-helpers.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								dist/helpers/underscore-helpers.js
									
									
									
									
										vendored
									
									
								
							@@ -1,7 +1,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
Template helper definitions for Underscore.
 | 
					Template helper definitions for Underscore.
 | 
				
			||||||
@license MIT. Copyright (c) 2016 hacksalot (https://github.com/hacksalot)
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module handlebars-helpers.js
 | 
					@module handlebars-helpers.js
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,7 +26,7 @@ Template helper definitions for Underscore.
 | 
				
			|||||||
    helpers.cssInfo = cssInfo;
 | 
					    helpers.cssInfo = cssInfo;
 | 
				
			||||||
    helpers.engine = eng;
 | 
					    helpers.engine = eng;
 | 
				
			||||||
    ctx.h = helpers;
 | 
					    ctx.h = helpers;
 | 
				
			||||||
    return _.each(helpers, function(hVal, hKey) {
 | 
					    _.each(helpers, function(hVal, hKey) {
 | 
				
			||||||
      if (_.isFunction(hVal)) {
 | 
					      if (_.isFunction(hVal)) {
 | 
				
			||||||
        return _.bind(hVal, ctx);
 | 
					        return _.bind(hVal, ctx);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -34,3 +34,5 @@ Template helper definitions for Underscore.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=underscore-helpers.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							@@ -6,14 +6,10 @@ External API surface for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/** API facade for HackMyResume. */
 | 
				
			||||||
API facade for HackMyCore.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var HackMyCore;
 | 
					  module.exports = {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  HackMyCore = module.exports = {
 | 
					 | 
				
			||||||
    verbs: {
 | 
					    verbs: {
 | 
				
			||||||
      build: require('./verbs/build'),
 | 
					      build: require('./verbs/build'),
 | 
				
			||||||
      analyze: require('./verbs/analyze'),
 | 
					      analyze: require('./verbs/analyze'),
 | 
				
			||||||
@@ -33,6 +29,7 @@ API facade for HackMyCore.
 | 
				
			|||||||
    JRSResume: require('./core/jrs-resume'),
 | 
					    JRSResume: require('./core/jrs-resume'),
 | 
				
			||||||
    FRESHTheme: require('./core/fresh-theme'),
 | 
					    FRESHTheme: require('./core/fresh-theme'),
 | 
				
			||||||
    JRSTheme: require('./core/jrs-theme'),
 | 
					    JRSTheme: require('./core/jrs-theme'),
 | 
				
			||||||
 | 
					    ResumeFactory: require('./core/resume-factory'),
 | 
				
			||||||
    FluentDate: require('./core/fluent-date'),
 | 
					    FluentDate: require('./core/fluent-date'),
 | 
				
			||||||
    HtmlGenerator: require('./generators/html-generator'),
 | 
					    HtmlGenerator: require('./generators/html-generator'),
 | 
				
			||||||
    TextGenerator: require('./generators/text-generator'),
 | 
					    TextGenerator: require('./generators/text-generator'),
 | 
				
			||||||
@@ -47,3 +44,5 @@ API facade for HackMyCore.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=index.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/inspectors/gap-inspector.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/inspectors/gap-inspector.js
									
									
									
									
										vendored
									
									
								
							@@ -136,3 +136,5 @@ Employment gap analysis for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=gap-inspector.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/inspectors/keyword-inspector.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/inspectors/keyword-inspector.js
									
									
									
									
										vendored
									
									
								
							@@ -59,3 +59,5 @@ Keyword analysis for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=keyword-inspector.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/inspectors/totals-inspector.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/inspectors/totals-inspector.js
									
									
									
									
										vendored
									
									
								
							@@ -47,3 +47,5 @@ Section analysis for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=totals-inspector.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								dist/renderers/handlebars-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								dist/renderers/handlebars-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -43,7 +43,7 @@ Definition of the HandlebarsGenerator class.
 | 
				
			|||||||
        return template(data);
 | 
					        return template(data);
 | 
				
			||||||
      } catch (_error) {
 | 
					      } catch (_error) {
 | 
				
			||||||
        throw {
 | 
					        throw {
 | 
				
			||||||
          fluenterror: template ? HMSTATUS.invokeTemplate : HMSTATUS.compileTemplate,
 | 
					          fluenterror: HMSTATUS[template ? 'invokeTemplate' : 'compileTemplate'],
 | 
				
			||||||
          inner: _error
 | 
					          inner: _error
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -98,3 +98,5 @@ Definition of the HandlebarsGenerator class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=handlebars-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								dist/renderers/jrs-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								dist/renderers/jrs-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -36,10 +36,11 @@ Definition of the JRSGenerator class.
 | 
				
			|||||||
    generate: function(json, jst, format, cssInfo, opts, theme) {
 | 
					    generate: function(json, jst, format, cssInfo, opts, theme) {
 | 
				
			||||||
      var org, rezHtml, turnoff;
 | 
					      var org, rezHtml, turnoff;
 | 
				
			||||||
      turnoff = ['log', 'error', 'dir'];
 | 
					      turnoff = ['log', 'error', 'dir'];
 | 
				
			||||||
      org = turnoff.map(c)(function() {
 | 
					      org = turnoff.map(function(c) {
 | 
				
			||||||
        var ret;
 | 
					        var ret;
 | 
				
			||||||
        ret = console[c];
 | 
					        ret = console[c];
 | 
				
			||||||
        return console[c] = function() {};
 | 
					        console[c] = function() {};
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      rezHtml = theme.render(json.harden());
 | 
					      rezHtml = theme.render(json.harden());
 | 
				
			||||||
      turnoff.forEach(function(c, idx) {
 | 
					      turnoff.forEach(function(c, idx) {
 | 
				
			||||||
@@ -56,3 +57,5 @@ Definition of the JRSGenerator class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=jrs-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								dist/renderers/underscore-generator.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								dist/renderers/underscore-generator.js
									
									
									
									
										vendored
									
									
								
							@@ -6,13 +6,15 @@ Definition of the UnderscoreGenerator class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var HMSTATUS, UnderscoreGenerator, _, registerHelpers;
 | 
					  var UnderscoreGenerator, _, escapeLaTeX, registerHelpers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _ = require('underscore');
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  registerHelpers = require('../helpers/underscore-helpers');
 | 
					  registerHelpers = require('../helpers/underscore-helpers');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HMSTATUS = require('../core/status-codes');
 | 
					  require('../utils/string');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  escapeLaTeX = require('escape-latex');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -22,19 +24,20 @@ Definition of the UnderscoreGenerator class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  UnderscoreGenerator = module.exports = {
 | 
					  UnderscoreGenerator = module.exports = {
 | 
				
			||||||
    generateSimple: function(data, tpl) {
 | 
					    generateSimple: function(data, tpl) {
 | 
				
			||||||
      var template;
 | 
					      var HMS, t;
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        template = _.template(tpl);
 | 
					        t = _.template(tpl);
 | 
				
			||||||
        return template(data);
 | 
					        return t(data);
 | 
				
			||||||
      } catch (_error) {
 | 
					      } catch (_error) {
 | 
				
			||||||
 | 
					        HMS = require('../core/status-codes');
 | 
				
			||||||
        throw {
 | 
					        throw {
 | 
				
			||||||
          fluenterror: template ? HMSTATUS.invokeTemplate : HMSTATUS.compileTemplate,
 | 
					          fluenterror: HMS[t ? 'invokeTemplate' : 'compileTemplate'],
 | 
				
			||||||
          inner: _error
 | 
					          inner: _error
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    generate: function(json, jst, format, cssInfo, opts, theme) {
 | 
					    generate: function(json, jst, format, cssInfo, opts, theme) {
 | 
				
			||||||
      var ctx, delims;
 | 
					      var ctx, delims, r, traverse;
 | 
				
			||||||
      delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
 | 
					      delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
 | 
				
			||||||
      if (opts.themeObj && opts.themeObj.delimeters) {
 | 
					      if (opts.themeObj && opts.themeObj.delimeters) {
 | 
				
			||||||
        delims = _.mapObject(delims, function(val, key) {
 | 
					        delims = _.mapObject(delims, function(val, key) {
 | 
				
			||||||
@@ -42,9 +45,31 @@ Definition of the UnderscoreGenerator class.
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      _.templateSettings = delims;
 | 
					      _.templateSettings = delims;
 | 
				
			||||||
      jst = jst.replace(delims.comment, '');
 | 
					      r = null;
 | 
				
			||||||
 | 
					      switch (format) {
 | 
				
			||||||
 | 
					        case 'html':
 | 
				
			||||||
 | 
					          r = json.markdownify();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 'pdf':
 | 
				
			||||||
 | 
					          r = json.markdownify();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 'png':
 | 
				
			||||||
 | 
					          r = json.markdownify();
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 'latex':
 | 
				
			||||||
 | 
					          traverse = require('traverse');
 | 
				
			||||||
 | 
					          r = traverse(json).map(function(x) {
 | 
				
			||||||
 | 
					            if (this.isLeaf && String.is(this.node)) {
 | 
				
			||||||
 | 
					              return escapeLaTeX(this.node);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return this.node;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					          r = json;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      ctx = {
 | 
					      ctx = {
 | 
				
			||||||
        r: format === 'html' || format === 'pdf' || format === 'png' ? json.markdownify() : json,
 | 
					        r: r,
 | 
				
			||||||
        filt: opts.filters,
 | 
					        filt: opts.filters,
 | 
				
			||||||
        XML: require('xml-escape'),
 | 
					        XML: require('xml-escape'),
 | 
				
			||||||
        RAW: json,
 | 
					        RAW: json,
 | 
				
			||||||
@@ -58,3 +83,5 @@ Definition of the UnderscoreGenerator class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=underscore-generator.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										72
									
								
								dist/utils/class.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								dist/utils/class.js
									
									
									
									
										vendored
									
									
								
							@@ -1,72 +0,0 @@
 | 
				
			|||||||
/**
 | 
					 | 
				
			||||||
Definition of John Resig's `Class` class.
 | 
					 | 
				
			||||||
@module class.js
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 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]) : // jshint ignore:line
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								dist/utils/file-contains.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/file-contains.js
									
									
									
									
										vendored
									
									
								
							@@ -10,3 +10,5 @@ Definition of the SyntaxErrorEx class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=file-contains.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/html-to-wpml.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/html-to-wpml.js
									
									
									
									
										vendored
									
									
								
							@@ -59,3 +59,5 @@ Definition of the Markdown to WordProcessingML conversion routine.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=html-to-wpml.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/md2chalk.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/md2chalk.js
									
									
									
									
										vendored
									
									
								
							@@ -26,3 +26,5 @@ Inline Markdown-to-Chalk conversion routines.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=md2chalk.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/rasterize.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/rasterize.js
									
									
									
									
										vendored
									
									
								
							@@ -75,3 +75,5 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=rasterize.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/safe-json-loader.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/safe-json-loader.js
									
									
									
									
										vendored
									
									
								
							@@ -30,3 +30,5 @@ Definition of the SafeJsonLoader class.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=safe-json-loader.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								dist/utils/safe-spawn.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								dist/utils/safe-spawn.js
									
									
									
									
										vendored
									
									
								
							@@ -5,42 +5,42 @@ Safe spawn utility for HackMyResume / FluentCV.
 | 
				
			|||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Safely spawn a process synchronously or asynchronously without throwing an
 | 
				
			||||||
 | 
					exception
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  module.exports = function(cmd, args, isSync, callback) {
 | 
					  module.exports = function(cmd, args, isSync, callback, param) {
 | 
				
			||||||
    var info, spawn;
 | 
					    var info, spawn;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      spawn = require('child_process')[isSync ? 'spawnSync' : 'spawn'];
 | 
					      spawn = require('child_process')[isSync ? 'spawnSync' : 'spawn'];
 | 
				
			||||||
      info = spawn(cmd, args);
 | 
					      info = spawn(cmd, args);
 | 
				
			||||||
      if (!isSync) {
 | 
					      if (!isSync) {
 | 
				
			||||||
        info.on('error', function(err) {
 | 
					        info.on('error', function(err) {
 | 
				
			||||||
          if (callback != null) {
 | 
					          if (typeof callback === "function") {
 | 
				
			||||||
            callback(err);
 | 
					            callback(err, param);
 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            throw {
 | 
					 | 
				
			||||||
              cmd: cmd,
 | 
					 | 
				
			||||||
              inner: err
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        if (info.error) {
 | 
					        if (info.error) {
 | 
				
			||||||
          if (callback != null) {
 | 
					          if (typeof callback === "function") {
 | 
				
			||||||
            callback(err);
 | 
					            callback(info.error, param);
 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            throw {
 | 
					 | 
				
			||||||
              cmd: cmd,
 | 
					 | 
				
			||||||
              inner: info.error
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          return {
 | 
				
			||||||
 | 
					            cmd: cmd,
 | 
				
			||||||
 | 
					            inner: info.error
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } catch (_error) {
 | 
					    } catch (_error) {
 | 
				
			||||||
      if (callback != null) {
 | 
					      if (typeof callback === "function") {
 | 
				
			||||||
        return callback(_error);
 | 
					        callback(_error, param);
 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        throw _error;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return _error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=safe-spawn.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/string-transformer.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/string-transformer.js
									
									
									
									
										vendored
									
									
								
							@@ -60,3 +60,5 @@ Object string transformation.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=string-transformer.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								dist/utils/string.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/utils/string.js
									
									
									
									
										vendored
									
									
								
							@@ -25,3 +25,5 @@ See: http://stackoverflow.com/a/32800728/4942583
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=string.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								dist/utils/syntax-error-ex.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								dist/utils/syntax-error-ex.js
									
									
									
									
										vendored
									
									
								
							@@ -18,17 +18,31 @@ See: http://stackoverflow.com/q/13323356
 | 
				
			|||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var SyntaxErrorEx;
 | 
					  var SyntaxErrorEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SyntaxErrorEx = function(ex, rawData) {
 | 
					  SyntaxErrorEx = (function() {
 | 
				
			||||||
    var JSONLint, colNum, lineNum, lint;
 | 
					    function SyntaxErrorEx(ex, rawData) {
 | 
				
			||||||
    lineNum = null;
 | 
					      var JSONLint, colNum, lineNum, lint, ref;
 | 
				
			||||||
    colNum = null;
 | 
					      lineNum = null;
 | 
				
			||||||
    JSONLint = require('json-lint');
 | 
					      colNum = null;
 | 
				
			||||||
    lint = JSONLint(rawData, {
 | 
					      JSONLint = require('json-lint');
 | 
				
			||||||
      comments: false
 | 
					      lint = JSONLint(rawData, {
 | 
				
			||||||
    });
 | 
					        comments: false
 | 
				
			||||||
    this.line = lint.error ? lint.line : '???';
 | 
					      });
 | 
				
			||||||
    return this.col = lint.error ? lint.character : '???';
 | 
					      if (lint.error) {
 | 
				
			||||||
  };
 | 
					        ref = [lint.line, lint.character], this.line = ref[0], this.col = ref[1];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (!lint.error) {
 | 
				
			||||||
 | 
					        JSONLint = require('jsonlint');
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          JSONLint.parse(rawData);
 | 
				
			||||||
 | 
					        } catch (_error) {
 | 
				
			||||||
 | 
					          this.line = (/on line (\d+)/.exec(_error))[1];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return SyntaxErrorEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SyntaxErrorEx.is = function(ex) {
 | 
					  SyntaxErrorEx.is = function(ex) {
 | 
				
			||||||
    return ex instanceof SyntaxError;
 | 
					    return ex instanceof SyntaxError;
 | 
				
			||||||
@@ -37,3 +51,5 @@ See: http://stackoverflow.com/q/13323356
 | 
				
			|||||||
  module.exports = SyntaxErrorEx;
 | 
					  module.exports = SyntaxErrorEx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=syntax-error-ex.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										80
									
								
								dist/verbs/analyze.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								dist/verbs/analyze.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'analyze' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var AnalyzeVerb, HMEVENT, HMSTATUS, MKDIRP, PATH, ResumeFactory, Verb, _, _analyze, _loadInspectors, analyze, chalk;
 | 
					  var AnalyzeVerb, HMEVENT, HMSTATUS, MKDIRP, PATH, ResumeFactory, Verb, _, _analyze, _analyzeOne, _loadInspectors, chalk,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MKDIRP = require('mkdirp');
 | 
					  MKDIRP = require('mkdirp');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,53 +26,61 @@ Implementation of the 'analyze' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  chalk = require('chalk');
 | 
					  chalk = require('chalk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  AnalyzeVerb = module.exports = Verb.extend({
 | 
					
 | 
				
			||||||
    init: function() {
 | 
					  /** An invokable resume analysis command. */
 | 
				
			||||||
      return this._super('analyze');
 | 
					
 | 
				
			||||||
    },
 | 
					  module.exports = AnalyzeVerb = (function(superClass) {
 | 
				
			||||||
    invoke: function() {
 | 
					    extend(AnalyzeVerb, superClass);
 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					
 | 
				
			||||||
        cmd: 'analyze'
 | 
					    function AnalyzeVerb() {
 | 
				
			||||||
      });
 | 
					      AnalyzeVerb.__super__.constructor.call(this, 'analyze', _analyze);
 | 
				
			||||||
      analyze.apply(this, arguments);
 | 
					 | 
				
			||||||
      return this.stat(HMEVENT.end);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return AnalyzeVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Private workhorse for the 'analyze' command. */
 | 
				
			||||||
  Run the 'analyze' command.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  analyze = function(sources, dst, opts) {
 | 
					  _analyze = function(sources, dst, opts) {
 | 
				
			||||||
    var nlzrs;
 | 
					    var nlzrs, results;
 | 
				
			||||||
    if (!sources || !sources.length) {
 | 
					    if (!sources || !sources.length) {
 | 
				
			||||||
      throw {
 | 
					      this.err(HMSTATUS.resumeNotFound, {
 | 
				
			||||||
        fluenterror: HMSTATUS.resumeNotFound,
 | 
					 | 
				
			||||||
        quit: true
 | 
					        quit: true
 | 
				
			||||||
      };
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    nlzrs = _loadInspectors();
 | 
					    nlzrs = _loadInspectors();
 | 
				
			||||||
    return _.each(sources, function(src) {
 | 
					    results = _.map(sources, function(src) {
 | 
				
			||||||
      var result;
 | 
					      var r;
 | 
				
			||||||
      result = ResumeFactory.loadOne(src, {
 | 
					      r = ResumeFactory.loadOne(src, {
 | 
				
			||||||
        format: 'FRESH',
 | 
					        format: 'FRESH',
 | 
				
			||||||
        objectify: true
 | 
					        objectify: true
 | 
				
			||||||
      }, this);
 | 
					      }, this);
 | 
				
			||||||
      if (result.fluenterror) {
 | 
					      if (opts.assert && this.hasError()) {
 | 
				
			||||||
        return this.setError(result.fluenterror, result);
 | 
					        return {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (r.fluenterror) {
 | 
				
			||||||
 | 
					        r.quit = opts.assert;
 | 
				
			||||||
 | 
					        this.err(r.fluenterror, r);
 | 
				
			||||||
 | 
					        return r;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        return _analyze.call(this, result, nlzrs, opts);
 | 
					        return _analyzeOne.call(this, r, nlzrs, opts);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }, this);
 | 
					    }, this);
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(this.errorCode);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Analyze a single resume. */
 | 
				
			||||||
  Analyze a single resume.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _analyze = function(resumeObject, nlzrs, opts) {
 | 
					  _analyzeOne = function(resumeObject, nlzrs, opts) {
 | 
				
			||||||
    var info, rez, safeFormat;
 | 
					    var info, rez, safeFormat;
 | 
				
			||||||
    rez = resumeObject.rez;
 | 
					    rez = resumeObject.rez;
 | 
				
			||||||
    safeFormat = rez.meta && rez.meta.format && rez.meta.format.startsWith('FRESH') ? 'FRESH' : 'JRS';
 | 
					    safeFormat = rez.meta && rez.meta.format && rez.meta.format.startsWith('FRESH') ? 'FRESH' : 'JRS';
 | 
				
			||||||
@@ -81,16 +91,12 @@ Implementation of the 'analyze' verb for HackMyResume.
 | 
				
			|||||||
    info = _.mapObject(nlzrs, function(val, key) {
 | 
					    info = _.mapObject(nlzrs, function(val, key) {
 | 
				
			||||||
      return val.run(rez);
 | 
					      return val.run(rez);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    return this.stat(HMEVENT.afterAnalyze, {
 | 
					    this.stat(HMEVENT.afterAnalyze, {
 | 
				
			||||||
      info: info
 | 
					      info: info
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    return info;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
  Load inspectors.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  _loadInspectors = function() {
 | 
					  _loadInspectors = function() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      totals: require('../inspectors/totals-inspector'),
 | 
					      totals: require('../inspectors/totals-inspector'),
 | 
				
			||||||
@@ -100,3 +106,5 @@ Implementation of the 'analyze' verb for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=analyze.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										134
									
								
								dist/verbs/build.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										134
									
								
								dist/verbs/build.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var BuildVerb, FRESHTheme, FS, HMEVENT, HMSTATUS, JRSTheme, MD, MKDIRP, PATH, RConverter, RTYPES, ResumeFactory, Verb, _, _err, _fmts, _log, _opts, _rezObj, addFreebieFormats, build, expand, extend, loadTheme, parsePath, prep, single, verifyOutputs, verifyTheme;
 | 
					  var BuildVerb, FRESHTheme, FS, HMEVENT, HMSTATUS, JRSTheme, MD, MKDIRP, PATH, RConverter, RTYPES, ResumeFactory, Verb, _, _addFreebieFormats, _build, _err, _expand, _fmts, _loadTheme, _log, _opts, _prep, _rezObj, _single, _verifyOutputs, _verifyTheme, addFreebieFormats, build, expand, extend, loadTheme, parsePath, prep, single, verifyOutputs, verifyTheme,
 | 
				
			||||||
 | 
					    extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _ = require('underscore');
 | 
					  _ = require('underscore');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,24 +72,19 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /** An invokable resume generation command. */
 | 
					  /** An invokable resume generation command. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  BuildVerb = module.exports = Verb.extend({
 | 
					  module.exports = BuildVerb = (function(superClass) {
 | 
				
			||||||
 | 
					    extend1(BuildVerb, superClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Create a new build verb. */
 | 
					    /** Create a new build verb. */
 | 
				
			||||||
    init: function() {
 | 
					 | 
				
			||||||
      return this._super('build');
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Invoke the Build command. */
 | 
					    function BuildVerb() {
 | 
				
			||||||
    invoke: function() {
 | 
					      BuildVerb.__super__.constructor.call(this, 'build', _build);
 | 
				
			||||||
      var ret;
 | 
					 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'build'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      ret = build.apply(this, arguments);
 | 
					 | 
				
			||||||
      this.stat(HMEVENT.end);
 | 
					 | 
				
			||||||
      return ret;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return BuildVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -95,18 +92,18 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  theme file, generate 0..N resumes in the desired formats.
 | 
					  theme file, generate 0..N resumes in the desired formats.
 | 
				
			||||||
  @param src Path to the source JSON resume file: "rez/resume.json".
 | 
					  @param src Path to the source JSON resume file: "rez/resume.json".
 | 
				
			||||||
  @param dst An array of paths to the target resume file(s).
 | 
					  @param dst An array of paths to the target resume file(s).
 | 
				
			||||||
  @param theme Friendly name of the resume theme. Defaults to "modern".
 | 
					  @param opts Generation options.
 | 
				
			||||||
  @param logger Optional logging override.
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  build = function(src, dst, opts) {
 | 
					  _build = function(src, dst, opts) {
 | 
				
			||||||
    var ex, inv, isFRESH, mixed, newEx, orgFormat, rez, sheetObjects, sheets, tFolder, targets, theme, toFormat;
 | 
					    var inv, isFRESH, mixed, newEx, orgFormat, problemSheets, results, rez, sheetObjects, sheets, tFolder, targets, theme, toFormat;
 | 
				
			||||||
    if (!src || !src.length) {
 | 
					    if (!src || !src.length) {
 | 
				
			||||||
      this.err(HMSTATUS.resumeNotFound, {
 | 
					      this.err(HMSTATUS.resumeNotFound, {
 | 
				
			||||||
        quit: true
 | 
					        quit: true
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    prep(src, dst, opts);
 | 
					    _prep.call(this, src, dst, opts);
 | 
				
			||||||
    sheetObjects = ResumeFactory.load(src, {
 | 
					    sheetObjects = ResumeFactory.load(src, {
 | 
				
			||||||
      format: null,
 | 
					      format: null,
 | 
				
			||||||
      objectify: false,
 | 
					      objectify: false,
 | 
				
			||||||
@@ -115,9 +112,12 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
        sort: _opts.sort
 | 
					        sort: _opts.sort
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }, this);
 | 
					    }, this);
 | 
				
			||||||
    if (!sheetObjects || _.some(sheetObjects, function(so) {
 | 
					    problemSheets = _.filter(sheetObjects, function(so) {
 | 
				
			||||||
      return so.fluenterror;
 | 
					      return so.fluenterror;
 | 
				
			||||||
    })) {
 | 
					    });
 | 
				
			||||||
 | 
					    if (problemSheets && problemSheets.length) {
 | 
				
			||||||
 | 
					      problemSheets[0].quit = true;
 | 
				
			||||||
 | 
					      this.err(problemSheets[0].fluenterror, problemSheets[0]);
 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    sheets = sheetObjects.map(function(r) {
 | 
					    sheets = sheetObjects.map(function(r) {
 | 
				
			||||||
@@ -128,14 +128,20 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
      theme: _opts.theme
 | 
					      theme: _opts.theme
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      tFolder = verifyTheme.call(this, _opts.theme);
 | 
					      tFolder = _verifyTheme.call(this, _opts.theme);
 | 
				
			||||||
      theme = _opts.themeObj = loadTheme(tFolder);
 | 
					      if (tFolder.fluenterror) {
 | 
				
			||||||
 | 
					        tFolder.quit = true;
 | 
				
			||||||
 | 
					        this.err(tFolder.fluenterror, tFolder);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      theme = _opts.themeObj = _loadTheme(tFolder);
 | 
				
			||||||
 | 
					      _addFreebieFormats(theme);
 | 
				
			||||||
    } catch (_error) {
 | 
					    } catch (_error) {
 | 
				
			||||||
      ex = _error;
 | 
					 | 
				
			||||||
      newEx = {
 | 
					      newEx = {
 | 
				
			||||||
        fluenterror: HMSTATUS.themeLoad,
 | 
					        fluenterror: HMSTATUS.themeLoad,
 | 
				
			||||||
        inner: ex,
 | 
					        inner: _error,
 | 
				
			||||||
        attempted: _opts.theme
 | 
					        attempted: _opts.theme,
 | 
				
			||||||
 | 
					        quit: true
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      this.err(HMSTATUS.themeLoad, newEx);
 | 
					      this.err(HMSTATUS.themeLoad, newEx);
 | 
				
			||||||
      return null;
 | 
					      return null;
 | 
				
			||||||
@@ -143,12 +149,14 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
    this.stat(HMEVENT.afterTheme, {
 | 
					    this.stat(HMEVENT.afterTheme, {
 | 
				
			||||||
      theme: theme
 | 
					      theme: theme
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    inv = verifyOutputs.call(this, dst, theme);
 | 
					    inv = _verifyOutputs.call(this, dst, theme);
 | 
				
			||||||
    if (inv && inv.length) {
 | 
					    if (inv && inv.length) {
 | 
				
			||||||
      this.err(HMSTATUS.invalidFormat, {
 | 
					      this.err(HMSTATUS.invalidFormat, {
 | 
				
			||||||
        data: inv,
 | 
					        data: inv,
 | 
				
			||||||
        theme: theme
 | 
					        theme: theme,
 | 
				
			||||||
 | 
					        quit: true
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    rez = null;
 | 
					    rez = null;
 | 
				
			||||||
    if (sheets.length > 1) {
 | 
					    if (sheets.length > 1) {
 | 
				
			||||||
@@ -186,21 +194,34 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
        fmt: toFormat
 | 
					        fmt: toFormat
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    addFreebieFormats(theme);
 | 
					 | 
				
			||||||
    this.stat(HMEVENT.applyTheme, {
 | 
					    this.stat(HMEVENT.applyTheme, {
 | 
				
			||||||
      r: rez,
 | 
					      r: rez,
 | 
				
			||||||
      theme: theme
 | 
					      theme: theme
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    _rezObj = new RTYPES[toFormat]().parseJSON(rez);
 | 
					    _rezObj = new RTYPES[toFormat]().parseJSON(rez);
 | 
				
			||||||
    targets = expand(dst, theme);
 | 
					    targets = _expand(dst, theme);
 | 
				
			||||||
    _.each(targets, function(t) {
 | 
					    _.each(targets, function(t) {
 | 
				
			||||||
      return t.final = single.call(this, t, theme, targets);
 | 
					      var ref;
 | 
				
			||||||
 | 
					      if (this.hasError() && opts.assert) {
 | 
				
			||||||
 | 
					        return {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      t.final = _single.call(this, t, theme, targets);
 | 
				
			||||||
 | 
					      if ((ref = t.final) != null ? ref.fluenterror : void 0) {
 | 
				
			||||||
 | 
					        t.final.quit = opts.assert;
 | 
				
			||||||
 | 
					        this.err(t.final.fluenterror, t.final);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }, this);
 | 
					    }, this);
 | 
				
			||||||
    return {
 | 
					    results = {
 | 
				
			||||||
      sheet: _rezObj,
 | 
					      sheet: _rezObj,
 | 
				
			||||||
      targets: targets,
 | 
					      targets: targets,
 | 
				
			||||||
      processed: targets
 | 
					      processed: targets
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(results);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -208,7 +229,8 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  Prepare for a BUILD run.
 | 
					  Prepare for a BUILD run.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  prep = function(src, dst, opts) {
 | 
					  _prep = function(src, dst, opts) {
 | 
				
			||||||
 | 
					    var that;
 | 
				
			||||||
    _opts.theme = (opts.theme && opts.theme.toLowerCase().trim()) || 'modern';
 | 
					    _opts.theme = (opts.theme && opts.theme.toLowerCase().trim()) || 'modern';
 | 
				
			||||||
    _opts.prettify = opts.prettify === true;
 | 
					    _opts.prettify = opts.prettify === true;
 | 
				
			||||||
    _opts.css = opts.css;
 | 
					    _opts.css = opts.css;
 | 
				
			||||||
@@ -220,6 +242,16 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
    _opts.noTips = opts.noTips;
 | 
					    _opts.noTips = opts.noTips;
 | 
				
			||||||
    _opts.debug = opts.debug;
 | 
					    _opts.debug = opts.debug;
 | 
				
			||||||
    _opts.sort = opts.sort;
 | 
					    _opts.sort = opts.sort;
 | 
				
			||||||
 | 
					    that = this;
 | 
				
			||||||
 | 
					    _opts.onTransform = function(info) {
 | 
				
			||||||
 | 
					      that.stat(HMEVENT.afterTransform, info);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    _opts.beforeWrite = function(info) {
 | 
				
			||||||
 | 
					      that.stat(HMEVENT.beforeWrite, info);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    _opts.afterWrite = function(info) {
 | 
				
			||||||
 | 
					      that.stat(HMEVENT.afterWrite, info);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    (src.length > 1 && (!dst || !dst.length)) && dst.push(src.pop());
 | 
					    (src.length > 1 && (!dst || !dst.length)) && dst.push(src.pop());
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -231,14 +263,14 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  @param theme A FRESHTheme or JRSTheme object.
 | 
					  @param theme A FRESHTheme or JRSTheme object.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  single = function(targInfo, theme, finished) {
 | 
					  _single = function(targInfo, theme, finished) {
 | 
				
			||||||
    var e, ex, f, fName, fType, outFolder, ret, theFormat;
 | 
					    var e, ex, f, fName, fType, outFolder, ret, theFormat;
 | 
				
			||||||
    ret = null;
 | 
					    ret = null;
 | 
				
			||||||
    ex = null;
 | 
					    ex = null;
 | 
				
			||||||
    f = targInfo.file;
 | 
					    f = targInfo.file;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if (!targInfo.fmt) {
 | 
					      if (!targInfo.fmt) {
 | 
				
			||||||
        return;
 | 
					        return {};
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      fType = targInfo.fmt.outFormat;
 | 
					      fType = targInfo.fmt.outFormat;
 | 
				
			||||||
      fName = PATH.basename(f, '.' + fType);
 | 
					      fName = PATH.basename(f, '.' + fType);
 | 
				
			||||||
@@ -247,12 +279,12 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
        fmt: targInfo.fmt.outFormat,
 | 
					        fmt: targInfo.fmt.outFormat,
 | 
				
			||||||
        file: PATH.relative(process.cwd(), f)
 | 
					        file: PATH.relative(process.cwd(), f)
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					      _opts.targets = finished;
 | 
				
			||||||
      if (targInfo.fmt.files && targInfo.fmt.files.length) {
 | 
					      if (targInfo.fmt.files && targInfo.fmt.files.length) {
 | 
				
			||||||
        theFormat = _fmts.filter(function(fmt) {
 | 
					        theFormat = _fmts.filter(function(fmt) {
 | 
				
			||||||
          return fmt.name === targInfo.fmt.outFormat;
 | 
					          return fmt.name === targInfo.fmt.outFormat;
 | 
				
			||||||
        })[0];
 | 
					        })[0];
 | 
				
			||||||
        MKDIRP.sync(PATH.dirname(f));
 | 
					        MKDIRP.sync(PATH.dirname(f));
 | 
				
			||||||
        _opts.targets = finished;
 | 
					 | 
				
			||||||
        ret = theFormat.gen.generate(_rezObj, f, _opts);
 | 
					        ret = theFormat.gen.generate(_rezObj, f, _opts);
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        theFormat = _fmts.filter(function(fmt) {
 | 
					        theFormat = _fmts.filter(function(fmt) {
 | 
				
			||||||
@@ -273,22 +305,21 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    if (ex) {
 | 
					    if (ex) {
 | 
				
			||||||
      if (ex.fluenterror) {
 | 
					      if (ex.fluenterror) {
 | 
				
			||||||
        this.err(ex.fluenterror, ex);
 | 
					        ret = ex;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        this.err(HMSTATUS.generateError, {
 | 
					        ret = {
 | 
				
			||||||
 | 
					          fluenterror: HMSTATUS.generateError,
 | 
				
			||||||
          inner: ex
 | 
					          inner: ex
 | 
				
			||||||
        });
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Ensure that user-specified outputs/targets are valid. */
 | 
				
			||||||
  Ensure that user-specified outputs/targets are valid.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  verifyOutputs = function(targets, theme) {
 | 
					  _verifyOutputs = function(targets, theme) {
 | 
				
			||||||
    this.stat(HMEVENT.verifyOutputs, {
 | 
					    this.stat(HMEVENT.verifyOutputs, {
 | 
				
			||||||
      targets: targets,
 | 
					      targets: targets,
 | 
				
			||||||
      theme: theme
 | 
					      theme: theme
 | 
				
			||||||
@@ -315,7 +346,7 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  @param theTheme A FRESHTheme or JRSTheme object.
 | 
					  @param theTheme A FRESHTheme or JRSTheme object.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addFreebieFormats = function(theTheme) {
 | 
					  _addFreebieFormats = function(theTheme) {
 | 
				
			||||||
    theTheme.formats.json = theTheme.formats.json || {
 | 
					    theTheme.formats.json = theTheme.formats.json || {
 | 
				
			||||||
      freebie: true,
 | 
					      freebie: true,
 | 
				
			||||||
      title: 'json',
 | 
					      title: 'json',
 | 
				
			||||||
@@ -354,7 +385,7 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  @param theTheme A FRESHTheme or JRSTheme object.
 | 
					  @param theTheme A FRESHTheme or JRSTheme object.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  expand = function(dst, theTheme) {
 | 
					  _expand = function(dst, theTheme) {
 | 
				
			||||||
    var destColl, targets;
 | 
					    var destColl, targets;
 | 
				
			||||||
    destColl = (dst && dst.length && dst) || [PATH.normalize('out/resume.all')];
 | 
					    destColl = (dst && dst.length && dst) || [PATH.normalize('out/resume.all')];
 | 
				
			||||||
    targets = [];
 | 
					    targets = [];
 | 
				
			||||||
@@ -385,16 +416,17 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  Verify the specified theme name/path.
 | 
					  Verify the specified theme name/path.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  verifyTheme = function(themeNameOrPath) {
 | 
					  _verifyTheme = function(themeNameOrPath) {
 | 
				
			||||||
    var exists, tFolder;
 | 
					    var exists, tFolder;
 | 
				
			||||||
    tFolder = PATH.join(parsePath(require.resolve('fresh-themes')).dirname, '/themes/', themeNameOrPath);
 | 
					    tFolder = PATH.join(parsePath(require.resolve('fresh-themes')).dirname, '/themes/', themeNameOrPath);
 | 
				
			||||||
    exists = require('path-exists').sync;
 | 
					    exists = require('path-exists').sync;
 | 
				
			||||||
    if (!exists(tFolder)) {
 | 
					    if (!exists(tFolder)) {
 | 
				
			||||||
      tFolder = PATH.resolve(themeNameOrPath);
 | 
					      tFolder = PATH.resolve(themeNameOrPath);
 | 
				
			||||||
      if (!exists(tFolder)) {
 | 
					      if (!exists(tFolder)) {
 | 
				
			||||||
        this.err(HMSTATUS.themeNotFound, {
 | 
					        return {
 | 
				
			||||||
 | 
					          fluenterror: HMSTATUS.themeNotFound,
 | 
				
			||||||
          data: _opts.theme
 | 
					          data: _opts.theme
 | 
				
			||||||
        });
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return tFolder;
 | 
					    return tFolder;
 | 
				
			||||||
@@ -406,7 +438,7 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  theme.
 | 
					  theme.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadTheme = function(tFolder) {
 | 
					  _loadTheme = function(tFolder) {
 | 
				
			||||||
    var theTheme;
 | 
					    var theTheme;
 | 
				
			||||||
    theTheme = _opts.theme.indexOf('jsonresume-theme-') > -1 ? new JRSTheme().open(tFolder) : new FRESHTheme().open(tFolder);
 | 
					    theTheme = _opts.theme.indexOf('jsonresume-theme-') > -1 ? new JRSTheme().open(tFolder) : new FRESHTheme().open(tFolder);
 | 
				
			||||||
    _opts.themeObj = theTheme;
 | 
					    _opts.themeObj = theTheme;
 | 
				
			||||||
@@ -414,3 +446,5 @@ Implementation of the 'build' verb for HackMyResume.
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=build.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										118
									
								
								dist/verbs/convert.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										118
									
								
								dist/verbs/convert.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'convert' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var ConvertVerb, HMEVENT, HMSTATUS, ResumeFactory, Verb, _, chalk, convert;
 | 
					  var ConvertVerb, HMEVENT, HMSTATUS, ResumeFactory, Verb, _, _convert, _convertOne, chalk,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ResumeFactory = require('../core/resume-factory');
 | 
					  ResumeFactory = require('../core/resume-factory');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,76 +22,94 @@ Implementation of the 'convert' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  HMEVENT = require('../core/event-codes');
 | 
					  HMEVENT = require('../core/event-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ConvertVerb = module.exports = Verb.extend({
 | 
					  module.exports = ConvertVerb = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(ConvertVerb, superClass);
 | 
				
			||||||
      return this._super('convert');
 | 
					
 | 
				
			||||||
    },
 | 
					    function ConvertVerb() {
 | 
				
			||||||
    invoke: function() {
 | 
					      ConvertVerb.__super__.constructor.call(this, 'convert', _convert);
 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'convert'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      convert.apply(this, arguments);
 | 
					 | 
				
			||||||
      return this.stat(HMEVENT.end);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return ConvertVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Private workhorse method. Convert 0..N resumes between FRESH and JRS
 | 
				
			||||||
  Convert between FRESH and JRS formats.
 | 
					  formats.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  convert = function(srcs, dst, opts) {
 | 
					  _convert = function(srcs, dst, opts) {
 | 
				
			||||||
 | 
					    var results;
 | 
				
			||||||
    if (!srcs || !srcs.length) {
 | 
					    if (!srcs || !srcs.length) {
 | 
				
			||||||
      throw {
 | 
					      this.err(HMSTATUS.resumeNotFound, {
 | 
				
			||||||
        fluenterror: 6,
 | 
					 | 
				
			||||||
        quit: true
 | 
					        quit: true
 | 
				
			||||||
      };
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!dst || !dst.length) {
 | 
					    if (!dst || !dst.length) {
 | 
				
			||||||
      if (srcs.length === 1) {
 | 
					      if (srcs.length === 1) {
 | 
				
			||||||
        throw {
 | 
					        this.err(HMSTATUS.inputOutputParity, {
 | 
				
			||||||
          fluenterror: HMSTATUS.inputOutputParity,
 | 
					 | 
				
			||||||
          quit: true
 | 
					          quit: true
 | 
				
			||||||
        };
 | 
					        });
 | 
				
			||||||
      } else if (srcs.length === 2) {
 | 
					      } else if (srcs.length === 2) {
 | 
				
			||||||
        dst = dst || [];
 | 
					        dst = dst || [];
 | 
				
			||||||
        dst.push(srcs.pop());
 | 
					        dst.push(srcs.pop());
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        throw {
 | 
					        this.err(HMSTATUS.inputOutputParity, {
 | 
				
			||||||
          fluenterror: HMSTATUS.inputOutputParity,
 | 
					 | 
				
			||||||
          quit: true
 | 
					          quit: true
 | 
				
			||||||
        };
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (srcs && dst && srcs.length && dst.length && srcs.length !== dst.length) {
 | 
					    if (srcs && dst && srcs.length && dst.length && srcs.length !== dst.length) {
 | 
				
			||||||
      throw {
 | 
					      this.err(HMSTATUS.inputOutputParity, {
 | 
				
			||||||
        fluenterror: HMSTATUS.inputOutputParity({
 | 
					        quit: true
 | 
				
			||||||
          quit: true
 | 
					      });
 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    _.each(srcs, function(src, idx) {
 | 
					    results = _.map(srcs, function(src, idx) {
 | 
				
			||||||
      var rinfo, s, srcFmt, targetFormat;
 | 
					      var r;
 | 
				
			||||||
      rinfo = ResumeFactory.loadOne(src, {
 | 
					      if (opts.assert && this.hasError()) {
 | 
				
			||||||
        format: null,
 | 
					        return {};
 | 
				
			||||||
        objectify: true,
 | 
					 | 
				
			||||||
        "throw": false
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      if (rinfo.fluenterror) {
 | 
					 | 
				
			||||||
        this.err(rinfo.fluenterror, rinfo);
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      s = rinfo.rez;
 | 
					      r = _convertOne.call(this, src, dst, idx);
 | 
				
			||||||
      srcFmt = ((s.basics && s.basics.imp) || s.imp).orgFormat === 'JRS' ? 'JRS' : 'FRESH';
 | 
					      if (r.fluenterror) {
 | 
				
			||||||
      targetFormat = srcFmt === 'JRS' ? 'FRESH' : 'JRS';
 | 
					        r.quit = opts.assert;
 | 
				
			||||||
      this.stat(HMEVENT.beforeConvert, {
 | 
					        this.err(r.fluenterror, r);
 | 
				
			||||||
        srcFile: rinfo.file,
 | 
					      }
 | 
				
			||||||
        srcFmt: srcFmt,
 | 
					      return r;
 | 
				
			||||||
        dstFile: dst[idx],
 | 
					 | 
				
			||||||
        dstFmt: targetFormat
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      s.saveAs(dst[idx], targetFormat);
 | 
					 | 
				
			||||||
    }, this);
 | 
					    }, this);
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(results);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Private workhorse method. Convert a single resume. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _convertOne = function(src, dst, idx) {
 | 
				
			||||||
 | 
					    var rinfo, s, srcFmt, targetFormat;
 | 
				
			||||||
 | 
					    rinfo = ResumeFactory.loadOne(src, {
 | 
				
			||||||
 | 
					      format: null,
 | 
				
			||||||
 | 
					      objectify: true
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    if (rinfo.fluenterror) {
 | 
				
			||||||
 | 
					      return rinfo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    s = rinfo.rez;
 | 
				
			||||||
 | 
					    srcFmt = ((s.basics && s.basics.imp) || s.imp).orgFormat === 'JRS' ? 'JRS' : 'FRESH';
 | 
				
			||||||
 | 
					    targetFormat = srcFmt === 'JRS' ? 'FRESH' : 'JRS';
 | 
				
			||||||
 | 
					    this.stat(HMEVENT.beforeConvert, {
 | 
				
			||||||
 | 
					      srcFile: rinfo.file,
 | 
				
			||||||
 | 
					      srcFmt: srcFmt,
 | 
				
			||||||
 | 
					      dstFile: dst[idx],
 | 
				
			||||||
 | 
					      dstFmt: targetFormat
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    s.saveAs(dst[idx], targetFormat);
 | 
				
			||||||
 | 
					    return s;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=convert.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										88
									
								
								dist/verbs/create.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								dist/verbs/create.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'create' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var CreateVerb, HMEVENT, HMSTATUS, MKDIRP, PATH, Verb, _, chalk, create;
 | 
					  var CreateVerb, HMEVENT, HMSTATUS, MKDIRP, PATH, Verb, _, _create, _createOne, chalk,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MKDIRP = require('mkdirp');
 | 
					  MKDIRP = require('mkdirp');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,35 +24,55 @@ Implementation of the 'create' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  HMEVENT = require('../core/event-codes');
 | 
					  HMEVENT = require('../core/event-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CreateVerb = module.exports = Verb.extend({
 | 
					  module.exports = CreateVerb = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(CreateVerb, superClass);
 | 
				
			||||||
      return this._super('new');
 | 
					
 | 
				
			||||||
    },
 | 
					    function CreateVerb() {
 | 
				
			||||||
    invoke: function() {
 | 
					      CreateVerb.__super__.constructor.call(this, 'new', _create);
 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'create'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      create.apply(this, arguments);
 | 
					 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'convert'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return CreateVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /** Create a new empty resume in either FRESH or JRS format. */
 | 
				
			||||||
  Create a new empty resume in either FRESH or JRS format.
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create = function(src, dst, opts) {
 | 
					  _create = function(src, dst, opts) {
 | 
				
			||||||
 | 
					    var results;
 | 
				
			||||||
    if (!src || !src.length) {
 | 
					    if (!src || !src.length) {
 | 
				
			||||||
      throw {
 | 
					      this.err(HMSTATUS.createNameMissing, {
 | 
				
			||||||
        fluenterror: HMSTATUS.createNameMissing,
 | 
					 | 
				
			||||||
        quit: true
 | 
					        quit: true
 | 
				
			||||||
      };
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    _.each(src, function(t) {
 | 
					    results = _.map(src, function(t) {
 | 
				
			||||||
      var RezClass, safeFmt;
 | 
					      var r;
 | 
				
			||||||
 | 
					      if (opts.assert && this.hasError()) {
 | 
				
			||||||
 | 
					        return {};
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      r = _createOne.call(this, t, opts);
 | 
				
			||||||
 | 
					      if (r.fluenterror) {
 | 
				
			||||||
 | 
					        r.quit = opts.assert;
 | 
				
			||||||
 | 
					        this.err(r.fluenterror, r);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return r;
 | 
				
			||||||
 | 
					    }, this);
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(this.errorCode);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Create a single new resume */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _createOne = function(t, opts) {
 | 
				
			||||||
 | 
					    var RezClass, newRez, ret, safeFmt;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      ret = null;
 | 
				
			||||||
      safeFmt = opts.format.toUpperCase();
 | 
					      safeFmt = opts.format.toUpperCase();
 | 
				
			||||||
      this.stat(HMEVENT.beforeCreate, {
 | 
					      this.stat(HMEVENT.beforeCreate, {
 | 
				
			||||||
        fmt: safeFmt,
 | 
					        fmt: safeFmt,
 | 
				
			||||||
@@ -58,12 +80,24 @@ Implementation of the 'create' verb for HackMyResume.
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
      MKDIRP.sync(PATH.dirname(t));
 | 
					      MKDIRP.sync(PATH.dirname(t));
 | 
				
			||||||
      RezClass = require('../core/' + safeFmt.toLowerCase() + '-resume');
 | 
					      RezClass = require('../core/' + safeFmt.toLowerCase() + '-resume');
 | 
				
			||||||
      RezClass["default"]().save(t);
 | 
					      newRez = RezClass["default"]();
 | 
				
			||||||
      return this.stat(HMEVENT.afterCreate, {
 | 
					      newRez.save(t);
 | 
				
			||||||
 | 
					      ret = newRez;
 | 
				
			||||||
 | 
					    } catch (_error) {
 | 
				
			||||||
 | 
					      ret = {
 | 
				
			||||||
 | 
					        fluenterror: HMSTATUS.createError,
 | 
				
			||||||
 | 
					        inner: _error
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      this.stat(HMEVENT.afterCreate, {
 | 
				
			||||||
        fmt: safeFmt,
 | 
					        fmt: safeFmt,
 | 
				
			||||||
        file: t
 | 
					        file: t,
 | 
				
			||||||
 | 
					        isError: ret.fluenterror
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }, this);
 | 
					      return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=create.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										111
									
								
								dist/verbs/peek.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										111
									
								
								dist/verbs/peek.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'peek' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var HMEVENT, HMSTATUS, PeekVerb, Verb, _, __, peek, safeLoadJSON;
 | 
					  var HMEVENT, HMSTATUS, PeekVerb, Verb, _, __, _peek, _peekOne, safeLoadJSON,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Verb = require('../verbs/verb');
 | 
					  Verb = require('../verbs/verb');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,58 +22,85 @@ Implementation of the 'peek' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  HMEVENT = require('../core/event-codes');
 | 
					  HMEVENT = require('../core/event-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PeekVerb = module.exports = Verb.extend({
 | 
					  module.exports = PeekVerb = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(PeekVerb, superClass);
 | 
				
			||||||
      return this._super('peek');
 | 
					
 | 
				
			||||||
    },
 | 
					    function PeekVerb() {
 | 
				
			||||||
    invoke: function() {
 | 
					      PeekVerb.__super__.constructor.call(this, 'peek', _peek);
 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'peek'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      peek.apply(this, arguments);
 | 
					 | 
				
			||||||
      return this.stat(HMEVENT.end);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return PeekVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Peek at a resume, resume section, or resume field. */
 | 
					  /** Peek at a resume, resume section, or resume field. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  peek = function(src, dst, opts) {
 | 
					  _peek = function(src, dst, opts) {
 | 
				
			||||||
    var objPath;
 | 
					    var objPath, results;
 | 
				
			||||||
    if (!src || !src.length) {
 | 
					    if (!src || !src.length) {
 | 
				
			||||||
      ({
 | 
					      this.err(HMSTATUS.resumeNotFound, {
 | 
				
			||||||
        "throw": {
 | 
					        quit: true
 | 
				
			||||||
          fluenterror: HMSTATUS.resumeNotFound
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    objPath = (dst && dst[0]) || '';
 | 
					    objPath = (dst && dst[0]) || '';
 | 
				
			||||||
    _.each(src, function(t) {
 | 
					    results = _.map(src, function(t) {
 | 
				
			||||||
      var errCode, obj, tgt;
 | 
					      var tgt;
 | 
				
			||||||
      this.stat(HMEVENT.beforePeek, {
 | 
					      if (opts.assert && this.hasError()) {
 | 
				
			||||||
        file: t,
 | 
					        return {};
 | 
				
			||||||
        target: objPath
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      obj = safeLoadJSON(t);
 | 
					 | 
				
			||||||
      tgt = null;
 | 
					 | 
				
			||||||
      if (!obj.ex) {
 | 
					 | 
				
			||||||
        tgt = objPath ? __.get(obj.json, objPath) : obj.json;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.stat(HMEVENT.afterPeek, {
 | 
					      tgt = _peekOne.call(this, t, objPath);
 | 
				
			||||||
        file: t,
 | 
					      if (tgt.error) {
 | 
				
			||||||
        requested: objPath,
 | 
					        this.setError(tgt.error.fluenterror, tgt.error);
 | 
				
			||||||
        target: tgt,
 | 
					 | 
				
			||||||
        error: obj.ex
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      if (obj.ex) {
 | 
					 | 
				
			||||||
        errCode = obj.ex.operation === 'parse' ? HMSTATUS.parseError : HMSTATUS.readError;
 | 
					 | 
				
			||||||
        if (errCode === HMSTATUS.readError) {
 | 
					 | 
				
			||||||
          obj.ex.quiet = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.setError(errCode, obj.ex);
 | 
					 | 
				
			||||||
        return this.err(errCode, obj.ex);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      return tgt;
 | 
				
			||||||
    }, this);
 | 
					    }, this);
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(this.errorCode);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** Peek at a single resume, resume section, or resume field. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _peekOne = function(t, objPath) {
 | 
				
			||||||
 | 
					    var errCode, obj, pkgError, tgt;
 | 
				
			||||||
 | 
					    this.stat(HMEVENT.beforePeek, {
 | 
				
			||||||
 | 
					      file: t,
 | 
				
			||||||
 | 
					      target: objPath
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    obj = safeLoadJSON(t);
 | 
				
			||||||
 | 
					    tgt = null;
 | 
				
			||||||
 | 
					    if (!obj.ex) {
 | 
				
			||||||
 | 
					      tgt = objPath ? __.get(obj.json, objPath) : obj.json;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pkgError = null;
 | 
				
			||||||
 | 
					    if (obj.ex) {
 | 
				
			||||||
 | 
					      errCode = obj.ex.operation === 'parse' ? HMSTATUS.parseError : HMSTATUS.readError;
 | 
				
			||||||
 | 
					      if (errCode === HMSTATUS.readError) {
 | 
				
			||||||
 | 
					        obj.ex.quiet = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      pkgError = {
 | 
				
			||||||
 | 
					        fluenterror: errCode,
 | 
				
			||||||
 | 
					        inner: obj.ex
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.stat(HMEVENT.afterPeek, {
 | 
				
			||||||
 | 
					      file: t,
 | 
				
			||||||
 | 
					      requested: objPath,
 | 
				
			||||||
 | 
					      target: obj.ex ? void 0 : tgt,
 | 
				
			||||||
 | 
					      error: pkgError
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      val: obj.ex ? void 0 : tgt,
 | 
				
			||||||
 | 
					      error: pkgError
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=peek.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										145
									
								
								dist/verbs/validate.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										145
									
								
								dist/verbs/validate.js
									
									
									
									
										vendored
									
									
								
							@@ -6,7 +6,9 @@ Implementation of the 'validate' verb for HackMyResume.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var FS, HMEVENT, HMSTATUS, ResumeFactory, SyntaxErrorEx, ValidateVerb, Verb, _, chalk, safeLoadJSON, validate;
 | 
					  var FS, HMEVENT, HMSTATUS, ResumeFactory, SyntaxErrorEx, ValidateVerb, Verb, _, _validate, _validateOne, chalk, safeLoadJSON,
 | 
				
			||||||
 | 
					    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
 | 
					    hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FS = require('fs');
 | 
					  FS = require('fs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,84 +31,109 @@ Implementation of the 'validate' verb for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /** An invokable resume validation command. */
 | 
					  /** An invokable resume validation command. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ValidateVerb = module.exports = Verb.extend({
 | 
					  module.exports = ValidateVerb = (function(superClass) {
 | 
				
			||||||
    init: function() {
 | 
					    extend(ValidateVerb, superClass);
 | 
				
			||||||
      return this._super('validate');
 | 
					
 | 
				
			||||||
    },
 | 
					    function ValidateVerb() {
 | 
				
			||||||
    invoke: function() {
 | 
					      ValidateVerb.__super__.constructor.call(this, 'validate', _validate);
 | 
				
			||||||
      var ret;
 | 
					 | 
				
			||||||
      this.stat(HMEVENT.begin, {
 | 
					 | 
				
			||||||
        cmd: 'validate'
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      ret = validate.apply(this, arguments);
 | 
					 | 
				
			||||||
      this.stat(HMEVENT.end);
 | 
					 | 
				
			||||||
      return ret;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ValidateVerb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** Validate 1 to N resumes in FRESH or JSON Resume format. */
 | 
					  })(Verb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  validate = function(sources, unused, opts) {
 | 
					  _validate = function(sources, unused, opts) {
 | 
				
			||||||
    var schemas, validator;
 | 
					    var results, schemas, validator;
 | 
				
			||||||
    if (!sources || !sources.length) {
 | 
					    if (!sources || !sources.length) {
 | 
				
			||||||
      throw {
 | 
					      this.err(HMSTATUS.resumeNotFoundAlt, {
 | 
				
			||||||
        fluenterror: HMSTATUS.resumeNotFoundAlt,
 | 
					 | 
				
			||||||
        quit: true
 | 
					        quit: true
 | 
				
			||||||
      };
 | 
					      });
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    validator = require('is-my-json-valid');
 | 
					    validator = require('is-my-json-valid');
 | 
				
			||||||
    schemas = {
 | 
					    schemas = {
 | 
				
			||||||
      fresh: require('fresca'),
 | 
					      fresh: require('fresca'),
 | 
				
			||||||
      jars: require('../core/resume.json')
 | 
					      jars: require('../core/resume.json')
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return _.map(sources, function(t) {
 | 
					    results = _.map(sources, function(t) {
 | 
				
			||||||
      var errCode, errors, fmt, json, obj, ret;
 | 
					      var r;
 | 
				
			||||||
      ret = {
 | 
					      r = _validateOne.call(this, t, validator, schemas, opts);
 | 
				
			||||||
        file: t,
 | 
					      if (r.error) {
 | 
				
			||||||
        isValid: false
 | 
					        this.err(r.error.fluenterror, r.error);
 | 
				
			||||||
      };
 | 
					      }
 | 
				
			||||||
 | 
					      return r;
 | 
				
			||||||
 | 
					    }, this);
 | 
				
			||||||
 | 
					    if (this.hasError() && !opts.assert) {
 | 
				
			||||||
 | 
					      this.reject(this.errorCode);
 | 
				
			||||||
 | 
					    } else if (!this.hasError()) {
 | 
				
			||||||
 | 
					      this.resolve(results);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return results;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					  Validate a single resume.
 | 
				
			||||||
 | 
					  @returns {
 | 
				
			||||||
 | 
					    file: <fileName>,
 | 
				
			||||||
 | 
					    isValid: <validFlag>,
 | 
				
			||||||
 | 
					    status: <validationStatus>,
 | 
				
			||||||
 | 
					    violations: <validationErrors>,
 | 
				
			||||||
 | 
					    schema: <schemaType>,
 | 
				
			||||||
 | 
					    error: <errorObject>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _validateOne = function(t, validator, schemas, opts) {
 | 
				
			||||||
 | 
					    var errCode, obj, ret, validate;
 | 
				
			||||||
 | 
					    ret = {
 | 
				
			||||||
 | 
					      file: t,
 | 
				
			||||||
 | 
					      isValid: false,
 | 
				
			||||||
 | 
					      status: 'unknown',
 | 
				
			||||||
 | 
					      schema: '-----'
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
      obj = safeLoadJSON(t);
 | 
					      obj = safeLoadJSON(t);
 | 
				
			||||||
      if (!obj.ex) {
 | 
					      if (!obj.ex) {
 | 
				
			||||||
        json = obj.json;
 | 
					        if (obj.json.basics) {
 | 
				
			||||||
        fmt = json.basics ? 'jrs' : 'fresh';
 | 
					          ret.schema = 'jars';
 | 
				
			||||||
        errors = [];
 | 
					        } else {
 | 
				
			||||||
        try {
 | 
					          ret.schema = 'fresh';
 | 
				
			||||||
          validate = validator(schemas[fmt], {
 | 
					        }
 | 
				
			||||||
            formats: {
 | 
					        validate = validator(schemas[ret.schema], {
 | 
				
			||||||
              date: /^\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/
 | 
					          formats: {
 | 
				
			||||||
            }
 | 
					            date: /^\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/
 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
          ret.isValid = validate(json);
 | 
					 | 
				
			||||||
          if (!ret.isValid) {
 | 
					 | 
				
			||||||
            errors = validate.errors;
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } catch (_error) {
 | 
					        });
 | 
				
			||||||
          ret.ex = _error;
 | 
					        ret.isValid = validate(obj.json);
 | 
				
			||||||
 | 
					        ret.status = ret.isValid ? 'valid' : 'invalid';
 | 
				
			||||||
 | 
					        if (!ret.isValid) {
 | 
				
			||||||
 | 
					          ret.violations = validate.errors;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        errCode = obj.ex.operation === 'parse' ? HMSTATUS.parseError : HMSTATUS.readError;
 | 
					        if (obj.ex.operation === 'parse') {
 | 
				
			||||||
        if (errCode === HMSTATUS.readError) {
 | 
					          errCode = HMSTATUS.parseError;
 | 
				
			||||||
          obj.ex.quiet = true;
 | 
					          ret.status = 'broken';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          errCode = HMSTATUS.readError;
 | 
				
			||||||
 | 
					          ret.status = 'missing';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.setError(errCode, obj.ex);
 | 
					        ret.error = {
 | 
				
			||||||
        this.err(errCode, obj.ex);
 | 
					          fluenterror: errCode,
 | 
				
			||||||
      }
 | 
					          inner: obj.ex.inner,
 | 
				
			||||||
      this.stat(HMEVENT.afterValidate, {
 | 
					          quiet: errCode === HMSTATUS.readError
 | 
				
			||||||
        file: t,
 | 
					 | 
				
			||||||
        isValid: ret.isValid,
 | 
					 | 
				
			||||||
        fmt: fmt != null ? fmt.replace('jars', 'JSON Resume') : void 0,
 | 
					 | 
				
			||||||
        errors: errors
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      if (opts.assert && !ret.isValid) {
 | 
					 | 
				
			||||||
        throw {
 | 
					 | 
				
			||||||
          fluenterror: HMSTATUS.invalid,
 | 
					 | 
				
			||||||
          shouldExit: true
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      console.log('1111');
 | 
					    } catch (_error) {
 | 
				
			||||||
      return ret;
 | 
					      ret.error = {
 | 
				
			||||||
    }, this);
 | 
					        fluenterror: HMSTATUS.validateError,
 | 
				
			||||||
 | 
					        inner: _error
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.stat(HMEVENT.afterValidate, ret);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=validate.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										85
									
								
								dist/verbs/verb.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								dist/verbs/verb.js
									
									
									
									
										vendored
									
									
								
							@@ -6,64 +6,113 @@ Definition of the Verb class.
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function() {
 | 
					(function() {
 | 
				
			||||||
  var Class, EVENTS, Verb;
 | 
					  var EVENTS, HMEVENT, Promise, Verb;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  Class = require('../utils/class');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  EVENTS = require('events');
 | 
					  EVENTS = require('events');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HMEVENT = require('../core/event-codes');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Promise = require('pinkie-promise');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
  An instantiation of a HackMyResume command.
 | 
					  An abstract invokable verb.
 | 
				
			||||||
 | 
					  Provides base class functionality for verbs. Provide common services such as
 | 
				
			||||||
 | 
					  error handling, event management, and promise support.
 | 
				
			||||||
  @class Verb
 | 
					  @class Verb
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Verb = module.exports = Class.extend({
 | 
					  module.exports = Verb = (function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Constructor. Automatically called at creation. */
 | 
					    /** Constructor. Automatically called at creation. */
 | 
				
			||||||
    init: function(moniker) {
 | 
					    function Verb(moniker, workhorse) {
 | 
				
			||||||
      this.moniker = moniker;
 | 
					      this.moniker = moniker;
 | 
				
			||||||
 | 
					      this.workhorse = workhorse;
 | 
				
			||||||
      this.emitter = new EVENTS.EventEmitter();
 | 
					      this.emitter = new EVENTS.EventEmitter();
 | 
				
			||||||
    },
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Invoke the command. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.invoke = function() {
 | 
				
			||||||
 | 
					      var argsArray, that;
 | 
				
			||||||
 | 
					      this.stat(HMEVENT.begin, {
 | 
				
			||||||
 | 
					        cmd: this.moniker
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      argsArray = Array.prototype.slice.call(arguments);
 | 
				
			||||||
 | 
					      that = this;
 | 
				
			||||||
 | 
					      return this.promise = new Promise(function(res, rej) {
 | 
				
			||||||
 | 
					        that.resolve = res;
 | 
				
			||||||
 | 
					        that.reject = rej;
 | 
				
			||||||
 | 
					        that.workhorse.apply(that, argsArray);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Forward subscriptions to the event emitter. */
 | 
					    /** Forward subscriptions to the event emitter. */
 | 
				
			||||||
    on: function() {
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.on = function() {
 | 
				
			||||||
      return this.emitter.on.apply(this.emitter, arguments);
 | 
					      return this.emitter.on.apply(this.emitter, arguments);
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Fire an arbitrary event, scoped to "hmr:". */
 | 
					    /** Fire an arbitrary event, scoped to "hmr:". */
 | 
				
			||||||
    fire: function(evtName, payload) {
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.fire = function(evtName, payload) {
 | 
				
			||||||
      payload = payload || {};
 | 
					      payload = payload || {};
 | 
				
			||||||
      payload.cmd = this.moniker;
 | 
					      payload.cmd = this.moniker;
 | 
				
			||||||
      this.emitter.emit('hmr:' + evtName, payload);
 | 
					      this.emitter.emit('hmr:' + evtName, payload);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Handle an error condition. */
 | 
					    /** Handle an error condition. */
 | 
				
			||||||
    err: function(errorCode, payload, hot) {
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.err = function(errorCode, payload, hot) {
 | 
				
			||||||
      payload = payload || {};
 | 
					      payload = payload || {};
 | 
				
			||||||
      payload.sub = payload.fluenterror = errorCode;
 | 
					      payload.sub = payload.fluenterror = errorCode;
 | 
				
			||||||
      payload["throw"] = hot;
 | 
					      payload["throw"] = hot;
 | 
				
			||||||
 | 
					      this.setError(errorCode, payload);
 | 
				
			||||||
 | 
					      if (payload.quit) {
 | 
				
			||||||
 | 
					        this.reject(errorCode);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      this.fire('error', payload);
 | 
					      this.fire('error', payload);
 | 
				
			||||||
      if (hot) {
 | 
					      if (hot) {
 | 
				
			||||||
        throw payload;
 | 
					        throw payload;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Fire the 'hmr:status' error event. */
 | 
					    /** Fire the 'hmr:status' error event. */
 | 
				
			||||||
    stat: function(subEvent, payload) {
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.stat = function(subEvent, payload) {
 | 
				
			||||||
      payload = payload || {};
 | 
					      payload = payload || {};
 | 
				
			||||||
      payload.sub = subEvent;
 | 
					      payload.sub = subEvent;
 | 
				
			||||||
      this.fire('status', payload);
 | 
					      this.fire('status', payload);
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    },
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Has an error occurred during this verb invocation? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.hasError = function() {
 | 
				
			||||||
 | 
					      return this.errorCode || this.errorObj;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Associate error info with the invocation. */
 | 
					    /** Associate error info with the invocation. */
 | 
				
			||||||
    setError: function(code, obj) {
 | 
					
 | 
				
			||||||
 | 
					    Verb.prototype.setError = function(code, obj) {
 | 
				
			||||||
      this.errorCode = code;
 | 
					      this.errorCode = code;
 | 
				
			||||||
      this.errorObj = obj;
 | 
					      this.errorObj = obj;
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					    return Verb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}).call(this);
 | 
					}).call(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//# sourceMappingURL=verb.js.map
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								package.json
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "hackmyresume",
 | 
					  "name": "hackmyresume",
 | 
				
			||||||
  "version": "1.7.3",
 | 
					  "version": "1.8.0",
 | 
				
			||||||
  "description": "Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.",
 | 
					  "description": "Generate polished résumés and CVs in HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML, YAML, smoke signal, and carrier pigeon.",
 | 
				
			||||||
  "repository": {
 | 
					  "repository": {
 | 
				
			||||||
    "type": "git",
 | 
					    "type": "git",
 | 
				
			||||||
@@ -40,33 +40,36 @@
 | 
				
			|||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
  "preferGlobal": "true",
 | 
					  "preferGlobal": "true",
 | 
				
			||||||
  "bugs": {
 | 
					  "bugs": {
 | 
				
			||||||
    "url": "https://github.com/hacksalot/HackMyResume/issues"
 | 
					    "url": "https://github.com/JuanCanham/HackMyResume/issues"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "bin": {
 | 
					  "bin": {
 | 
				
			||||||
    "hackmyresume": "dist/cli/index.js"
 | 
					    "hackmyresume": "dist/cli/index.js"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "main": "src/index.js",
 | 
					  "main": "dist/index.js",
 | 
				
			||||||
  "homepage": "https://github.com/hacksalot/HackMyResume",
 | 
					  "homepage": "https://github.com/JuanCanham/HackMyResume",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "chalk": "^1.1.1",
 | 
					    "chalk": "^1.1.1",
 | 
				
			||||||
    "commander": "^2.9.0",
 | 
					    "commander": "^2.9.0",
 | 
				
			||||||
    "copy": "^0.1.3",
 | 
					    "copy": "^0.1.3",
 | 
				
			||||||
 | 
					    "escape-latex": "^0.1.2",
 | 
				
			||||||
    "extend": "^3.0.0",
 | 
					    "extend": "^3.0.0",
 | 
				
			||||||
    "fresca": "~0.6.0",
 | 
					    "fresca": "~0.6.0",
 | 
				
			||||||
    "fresh-jrs-converter": "^0.2.0",
 | 
					    "fresh-jrs-converter": "^0.2.2",
 | 
				
			||||||
    "fresh-resume-starter": "^0.2.2",
 | 
					    "fresh-resume-starter": "^0.2.2",
 | 
				
			||||||
    "fresh-themes": "^0.14.1-beta",
 | 
					    "fresh-themes": "git+https://git.juancanham.com/JuanCanham/fresh-themes.git#feature/certifications",
 | 
				
			||||||
    "fs-extra": "^0.26.4",
 | 
					    "fs-extra": "^0.26.4",
 | 
				
			||||||
    "handlebars": "^4.0.5",
 | 
					    "handlebars": "^4.0.5",
 | 
				
			||||||
    "html": "0.0.10",
 | 
					    "html": "0.0.10",
 | 
				
			||||||
    "is-my-json-valid": "^2.12.4",
 | 
					    "is-my-json-valid": "^2.12.4",
 | 
				
			||||||
    "json-lint": "^0.1.0",
 | 
					    "json-lint": "^0.1.0",
 | 
				
			||||||
 | 
					    "jsonlint": "^1.6.2",
 | 
				
			||||||
    "lodash": "^3.10.1",
 | 
					    "lodash": "^3.10.1",
 | 
				
			||||||
    "marked": "^0.3.5",
 | 
					    "marked": "^0.3.5",
 | 
				
			||||||
    "mkdirp": "^0.5.1",
 | 
					    "mkdirp": "^0.5.1",
 | 
				
			||||||
    "moment": "^2.11.1",
 | 
					    "moment": "^2.11.1",
 | 
				
			||||||
    "parse-filepath": "^0.6.3",
 | 
					    "parse-filepath": "^0.6.3",
 | 
				
			||||||
    "path-exists": "^2.1.0",
 | 
					    "path-exists": "^2.1.0",
 | 
				
			||||||
 | 
					    "pinkie-promise": "^2.0.0",
 | 
				
			||||||
    "printf": "^0.2.3",
 | 
					    "printf": "^0.2.3",
 | 
				
			||||||
    "recursive-readdir-sync": "^1.0.6",
 | 
					    "recursive-readdir-sync": "^1.0.6",
 | 
				
			||||||
    "simple-html-tokenizer": "^0.2.1",
 | 
					    "simple-html-tokenizer": "^0.2.1",
 | 
				
			||||||
@@ -82,7 +85,8 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "chai": "*",
 | 
					    "chai": "*",
 | 
				
			||||||
    "fresh-test-resumes": "^0.6.0",
 | 
					    "dir-compare": "0.0.2",
 | 
				
			||||||
 | 
					    "fresh-test-resumes": "^0.7.0",
 | 
				
			||||||
    "grunt": "*",
 | 
					    "grunt": "*",
 | 
				
			||||||
    "grunt-cli": "^0.1.13",
 | 
					    "grunt-cli": "^0.1.13",
 | 
				
			||||||
    "grunt-contrib-clean": "^0.7.0",
 | 
					    "grunt-contrib-clean": "^0.7.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,8 @@ require 'string.prototype.startswith'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###* Error handler for HackMyResume. All errors are handled here.
 | 
				
			||||||
Error handler for HackMyResume. All errors are handled here.
 | 
					@class ErrorHandler ###
 | 
				
			||||||
@class ErrorHandler
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
ErrorHandler = module.exports =
 | 
					ErrorHandler = module.exports =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: ( debug, assert, silent ) ->
 | 
					  init: ( debug, assert, silent ) ->
 | 
				
			||||||
@@ -38,7 +36,7 @@ ErrorHandler = module.exports =
 | 
				
			|||||||
  err: ( ex, shouldExit ) ->
 | 
					  err: ( ex, shouldExit ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Short-circuit logging output if --silent is on
 | 
					    # Short-circuit logging output if --silent is on
 | 
				
			||||||
    o = if this.silent then () -> else _defaultLog
 | 
					    o = if @silent then () -> else _defaultLog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Special case; can probably be removed.
 | 
					    # Special case; can probably be removed.
 | 
				
			||||||
    throw ex if ex.pass
 | 
					    throw ex if ex.pass
 | 
				
			||||||
@@ -51,7 +49,7 @@ ErrorHandler = module.exports =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      # Output the error message
 | 
					      # Output the error message
 | 
				
			||||||
      objError = assembleError.call @, ex
 | 
					      objError = assembleError.call @, ex
 | 
				
			||||||
      o( this[ 'format_' + objError.etype ]( objError.msg ))
 | 
					      o( @[ 'format_' + objError.etype ]( objError.msg ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Output the stack (sometimes)
 | 
					      # Output the stack (sometimes)
 | 
				
			||||||
      if objError.withStack
 | 
					      if objError.withStack
 | 
				
			||||||
@@ -59,20 +57,20 @@ ErrorHandler = module.exports =
 | 
				
			|||||||
        stack && o( chalk.gray( stack ) );
 | 
					        stack && o( chalk.gray( stack ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Quit if necessary
 | 
					      # Quit if necessary
 | 
				
			||||||
      if ex.quit || objError.quit
 | 
					      if shouldExit
 | 
				
			||||||
        if @debug
 | 
					        if @debug
 | 
				
			||||||
          o chalk.cyan('Exiting with error code ' + ex.fluenterror.toString())
 | 
					          o chalk.cyan('Exiting with error code ' + ex.fluenterror.toString())
 | 
				
			||||||
        if this.assert
 | 
					        if @assert
 | 
				
			||||||
          ex.pass = true
 | 
					          ex.pass = true
 | 
				
			||||||
          throw ex
 | 
					          throw ex
 | 
				
			||||||
        process.exit ex.fluenterror
 | 
					        process.exit ex.fluenterror
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Handle raw exceptions
 | 
					    # Handle raw exceptions
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      o( ex )
 | 
					      o ex
 | 
				
			||||||
      stackTrace = ex.stack || (ex.inner && ex.inner.stack)
 | 
					      stackTrace = ex.stack || (ex.inner && ex.inner.stack)
 | 
				
			||||||
      if stackTrace && this.debug
 | 
					      if stackTrace && this.debug
 | 
				
			||||||
        o( M2C(ex.stack || ex.inner.stack, 'gray') )
 | 
					        o M2C(ex.stack || ex.inner.stack, 'gray')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -139,7 +137,6 @@ assembleError = ( ex ) ->
 | 
				
			|||||||
    when HMSTATUS.pdfGeneration
 | 
					    when HMSTATUS.pdfGeneration
 | 
				
			||||||
      msg = M2C( this.msgs.pdfGeneration.msg, 'bold' )
 | 
					      msg = M2C( this.msgs.pdfGeneration.msg, 'bold' )
 | 
				
			||||||
      msg += chalk.red('\n' + ex.inner) if ex.inner
 | 
					      msg += chalk.red('\n' + ex.inner) if ex.inner
 | 
				
			||||||
      withStack = true
 | 
					 | 
				
			||||||
      quit = false
 | 
					      quit = false
 | 
				
			||||||
      etype = 'error'
 | 
					      etype = 'error'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -205,16 +202,30 @@ assembleError = ( ex ) ->
 | 
				
			|||||||
      etype = 'custom'
 | 
					      etype = 'custom'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    when HMSTATUS.parseError
 | 
					    when HMSTATUS.parseError
 | 
				
			||||||
      if SyntaxErrorEx.is( ex.inner )
 | 
					      if SyntaxErrorEx.is ex.inner
 | 
				
			||||||
        console.error printf( M2C(this.msgs.readError.msg, 'red'), ex.file )
 | 
					        console.error printf( M2C(this.msgs.readError.msg, 'red'), ex.file )
 | 
				
			||||||
        se = new SyntaxErrorEx ex, ex.raw
 | 
					        se = new SyntaxErrorEx ex, ex.raw
 | 
				
			||||||
        msg = printf M2C( this.msgs.parseError.msg, 'red' ), se.line, se.col
 | 
					        if se.line? and se.col?
 | 
				
			||||||
      else if ex.inner && ex.inner.line != undefined && ex.inner.col != undefined
 | 
					          msg = printf M2C( this.msgs.parseError.msg[0], 'red' ), se.line, se.col
 | 
				
			||||||
        msg = printf( M2C( this.msgs.parseError.msg, 'red' ), ex.inner.line, ex.inner.col)
 | 
					        else if se.line?
 | 
				
			||||||
 | 
					          msg = printf M2C( this.msgs.parseError.msg[1], 'red' ), se.line
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          msg = M2C @msgs.parseError.msg[2], 'red'
 | 
				
			||||||
 | 
					      else if ex.inner && ex.inner.line? && ex.inner.col?
 | 
				
			||||||
 | 
					        msg = printf( M2C( this.msgs.parseError.msg[0], 'red' ), ex.inner.line, ex.inner.col)
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        msg = ex
 | 
					        msg = ex
 | 
				
			||||||
      etype = 'error'
 | 
					      etype = 'error'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    when HMSTATUS.createError
 | 
				
			||||||
 | 
					      # inner.code could be EPERM, EACCES, etc
 | 
				
			||||||
 | 
					      msg = printf M2C( this.msgs.createError.msg ), ex.inner.path
 | 
				
			||||||
 | 
					      etype = 'error'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    when HMSTATUS.validateError
 | 
				
			||||||
 | 
					      msg = printf M2C( @msgs.validateError.msg ), ex.inner.toString()
 | 
				
			||||||
 | 
					      etype = 'error'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  msg: msg              # The error message to display
 | 
					  msg: msg              # The error message to display
 | 
				
			||||||
  withStack: withStack  # Whether to include the stack
 | 
					  withStack: withStack  # Whether to include the stack
 | 
				
			||||||
  quit: quit
 | 
					  quit: quit
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,9 +20,13 @@ _ = require 'underscore'
 | 
				
			|||||||
OUTPUT = require './out'
 | 
					OUTPUT = require './out'
 | 
				
			||||||
PAD = require 'string-padding'
 | 
					PAD = require 'string-padding'
 | 
				
			||||||
Command = require('commander').Command
 | 
					Command = require('commander').Command
 | 
				
			||||||
 | 
					M2C = require '../utils/md2chalk'
 | 
				
			||||||
 | 
					printf = require 'printf'
 | 
				
			||||||
_opts = { }
 | 
					_opts = { }
 | 
				
			||||||
_title = chalk.white.bold('\n*** HackMyResume v' +PKG.version+ ' ***')
 | 
					_title = chalk.white.bold('\n*** HackMyResume v' +PKG.version+ ' ***')
 | 
				
			||||||
_out = new OUTPUT( _opts )
 | 
					_out = new OUTPUT( _opts )
 | 
				
			||||||
 | 
					_err = require('./error')
 | 
				
			||||||
 | 
					_exitCallback = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,9 +37,9 @@ line interface as a single method accepting a parameter array.
 | 
				
			|||||||
@param rawArgs {Array} An array of command-line parameters. Will either be
 | 
					@param rawArgs {Array} An array of command-line parameters. Will either be
 | 
				
			||||||
process.argv (in production) or custom parameters (in test).
 | 
					process.argv (in production) or custom parameters (in test).
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
main = module.exports = (rawArgs) ->
 | 
					main = module.exports = ( rawArgs, exitCallback ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initInfo = initialize( rawArgs )
 | 
					  initInfo = initialize( rawArgs, exitCallback )
 | 
				
			||||||
  args = initInfo.args
 | 
					  args = initInfo.args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Create the top-level (application) command...
 | 
					  # Create the top-level (application) command...
 | 
				
			||||||
@@ -124,15 +128,15 @@ main = module.exports = (rawArgs) ->
 | 
				
			|||||||
  program.parse( args )
 | 
					  program.parse( args )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if !program.args.length
 | 
					  if !program.args.length
 | 
				
			||||||
    throw { fluenterror: 4 }
 | 
					    throw fluenterror: 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Massage command-line args and setup Commander.js. ###
 | 
					### Massage command-line args and setup Commander.js. ###
 | 
				
			||||||
initialize = ( ar ) ->
 | 
					initialize = ( ar, exitCallback ) ->
 | 
				
			||||||
 | 
					 | 
				
			||||||
  o = initOptions( ar );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _exitCallback = exitCallback || process.exit
 | 
				
			||||||
 | 
					  o = initOptions ar
 | 
				
			||||||
  o.silent || logMsg( _title )
 | 
					  o.silent || logMsg( _title )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Emit debug prelude if --debug was specified
 | 
					  # Emit debug prelude if --debug was specified
 | 
				
			||||||
@@ -147,14 +151,22 @@ initialize = ( ar ) ->
 | 
				
			|||||||
    #_out.log(chalk.cyan(PAD('  fresh-jrs-converter:',25, null, PAD.RIGHT)) + chalk.cyan.bold( PKG.dependencies['fresh-jrs-converter'] ))
 | 
					    #_out.log(chalk.cyan(PAD('  fresh-jrs-converter:',25, null, PAD.RIGHT)) + chalk.cyan.bold( PKG.dependencies['fresh-jrs-converter'] ))
 | 
				
			||||||
    _out.log('')
 | 
					    _out.log('')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _err.init o.debug, o.assert, o.silent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Handle invalid verbs here (a bit easier here than in commander.js)...
 | 
					  # Handle invalid verbs here (a bit easier here than in commander.js)...
 | 
				
			||||||
  if o.verb && !HMR.verbs[ o.verb ] && !HMR.alias[ o.verb ]
 | 
					  if o.verb && !HMR.verbs[ o.verb ] && !HMR.alias[ o.verb ]
 | 
				
			||||||
    throw { fluenterror: HMSTATUS.invalidCommand, quit: true, attempted: o.orgVerb }
 | 
					    _err.err fluenterror: HMSTATUS.invalidCommand, quit: true, attempted: o.orgVerb, true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Override the .missingArgument behavior
 | 
					  # Override the .missingArgument behavior
 | 
				
			||||||
  Command.prototype.missingArgument = (name) ->
 | 
					  Command.prototype.missingArgument = (name) ->
 | 
				
			||||||
    if this.name() != 'new'
 | 
					    _err.err
 | 
				
			||||||
      throw { fluenterror: HMSTATUS.resumeNotFound, quit: true }
 | 
					      fluenterror:
 | 
				
			||||||
 | 
					        if this.name() != 'new'
 | 
				
			||||||
 | 
					        then HMSTATUS.resumeNotFound
 | 
				
			||||||
 | 
					        else HMSTATUS.createNameMissing
 | 
				
			||||||
 | 
					      , true
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Override the .helpInformation behavior
 | 
					  # Override the .helpInformation behavior
 | 
				
			||||||
  Command.prototype.helpInformation = ->
 | 
					  Command.prototype.helpInformation = ->
 | 
				
			||||||
@@ -205,23 +217,17 @@ initOptions = ( ar ) ->
 | 
				
			|||||||
            oJSON = inf.json
 | 
					            oJSON = inf.json
 | 
				
			||||||
          # TODO: Error handling
 | 
					          # TODO: Error handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Grab the --debug flag
 | 
					  # Grab the --debug flag, --silent, --assert and --no-color flags
 | 
				
			||||||
  isDebug = _.some( args, (v) ->
 | 
					  isDebug = _.some args, (v) -> v == '-d' || v == '--debug'
 | 
				
			||||||
    return v == '-d' || v == '--debug'
 | 
					  isSilent = _.some args, (v) -> v == '-s' || v == '--silent'
 | 
				
			||||||
  )
 | 
					  isAssert = _.some args, (v) -> v == '-a' || v == '--assert'
 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Grab the --silent flag
 | 
					 | 
				
			||||||
  isSilent = _.some( args, (v) ->
 | 
					 | 
				
			||||||
    return v == '-s' || v == '--silent'
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Grab the --no-color flag
 | 
					 | 
				
			||||||
  isMono = _.some args, (v) -> v == '--no-color'
 | 
					  isMono = _.some args, (v) -> v == '--no-color'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    color: !isMono,
 | 
					    color: !isMono,
 | 
				
			||||||
    debug: isDebug,
 | 
					    debug: isDebug,
 | 
				
			||||||
    silent: isSilent,
 | 
					    silent: isSilent,
 | 
				
			||||||
 | 
					    assert: isAssert,
 | 
				
			||||||
    orgVerb: oVerb,
 | 
					    orgVerb: oVerb,
 | 
				
			||||||
    verb: verb,
 | 
					    verb: verb,
 | 
				
			||||||
    json: oJSON,
 | 
					    json: oJSON,
 | 
				
			||||||
@@ -233,19 +239,45 @@ initOptions = ( ar ) ->
 | 
				
			|||||||
### Invoke a HackMyResume verb. ###
 | 
					### Invoke a HackMyResume verb. ###
 | 
				
			||||||
execute = ( src, dst, opts, log ) ->
 | 
					execute = ( src, dst, opts, log ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadOptions.call( this, opts, this.parent.jsonArgs )
 | 
					  # Create the verb
 | 
				
			||||||
  hand = require( './error' )
 | 
					  v = new HMR.verbs[ @name() ]()
 | 
				
			||||||
  hand.init( _opts.debug, _opts.assert, _opts.silent )
 | 
					 | 
				
			||||||
  v = new HMR.verbs[ this.name() ]()
 | 
					 | 
				
			||||||
  _opts.errHandler = v
 | 
					 | 
				
			||||||
  _out.init( _opts )
 | 
					 | 
				
			||||||
  v.on( 'hmr:status', -> _out.do.apply( _out, arguments ) )
 | 
					 | 
				
			||||||
  v.on( 'hmr:error', ->  hand.err.apply( hand, arguments ) )
 | 
					 | 
				
			||||||
  v.invoke.call( v, src, dst, _opts, log )
 | 
					 | 
				
			||||||
  if v.errorCode
 | 
					 | 
				
			||||||
    console.log 'Exiting with error code ' + v.errorCode
 | 
					 | 
				
			||||||
    process.exit(v.errorCode)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Initialize command-specific options
 | 
				
			||||||
 | 
					  loadOptions.call( this, opts, this.parent.jsonArgs )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Set up error/output handling
 | 
				
			||||||
 | 
					  _opts.errHandler = v
 | 
				
			||||||
 | 
					  _out.init _opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Hook up event notifications
 | 
				
			||||||
 | 
					  v.on 'hmr:status', -> _out.do.apply _out, arguments
 | 
				
			||||||
 | 
					  v.on 'hmr:error', ->  _err.err.apply _err, arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Invoke the verb using promise syntax
 | 
				
			||||||
 | 
					  prom = v.invoke.call v, src, dst, _opts, log
 | 
				
			||||||
 | 
					  prom.then executeSuccess, executeFail
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Success handler for verb invocations. Calls process.exit by default ###
 | 
				
			||||||
 | 
					executeSuccess = (obj) ->
 | 
				
			||||||
 | 
					  # Can't call _exitCallback here (process.exit) when PDF is running in BK
 | 
				
			||||||
 | 
					  #_exitCallback 0; return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Failure handler for verb invocations. Calls process.exit by default ###
 | 
				
			||||||
 | 
					executeFail = (err) ->
 | 
				
			||||||
 | 
					  finalErrorCode = -1
 | 
				
			||||||
 | 
					  if err
 | 
				
			||||||
 | 
					    finalErrorCode = if err.fluenterror then err.fluenterror else err
 | 
				
			||||||
 | 
					  if _opts.debug
 | 
				
			||||||
 | 
					    msgs = require('./msg').errors;
 | 
				
			||||||
 | 
					    logMsg printf M2C( msgs.exiting.msg, 'cyan' ), finalErrorCode
 | 
				
			||||||
 | 
					    logMsg err.stack if err.stack
 | 
				
			||||||
 | 
					  _exitCallback finalErrorCode
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@ events:
 | 
				
			|||||||
    msg: Invoking **%s** command.
 | 
					    msg: Invoking **%s** command.
 | 
				
			||||||
  beforeCreate:
 | 
					  beforeCreate:
 | 
				
			||||||
    msg: Creating new **%s** resume: **%s**
 | 
					    msg: Creating new **%s** resume: **%s**
 | 
				
			||||||
 | 
					  afterCreate:
 | 
				
			||||||
 | 
					    msg: Creating new **%s** resume: **%s**
 | 
				
			||||||
  afterRead:
 | 
					  afterRead:
 | 
				
			||||||
    msg: Reading **%s** resume: **%s**
 | 
					    msg: Reading **%s** resume: **%s**
 | 
				
			||||||
  beforeTheme:
 | 
					  beforeTheme:
 | 
				
			||||||
@@ -41,6 +43,8 @@ events:
 | 
				
			|||||||
      - "VALID!"
 | 
					      - "VALID!"
 | 
				
			||||||
      - "INVALID"
 | 
					      - "INVALID"
 | 
				
			||||||
      - "BROKEN"
 | 
					      - "BROKEN"
 | 
				
			||||||
 | 
					      - "MISSING"
 | 
				
			||||||
 | 
					      - "ERROR"
 | 
				
			||||||
  beforePeek:
 | 
					  beforePeek:
 | 
				
			||||||
    msg:
 | 
					    msg:
 | 
				
			||||||
      - Peeking at **%s** in **%s**
 | 
					      - Peeking at **%s** in **%s**
 | 
				
			||||||
@@ -79,7 +83,10 @@ errors:
 | 
				
			|||||||
  readError:
 | 
					  readError:
 | 
				
			||||||
    msg: Reading **???** resume: **%s**
 | 
					    msg: Reading **???** resume: **%s**
 | 
				
			||||||
  parseError:
 | 
					  parseError:
 | 
				
			||||||
    msg: Invalid or corrupt JSON on line %s column %s.
 | 
					    msg:
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON on line %s column %s.
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON on line %s.
 | 
				
			||||||
 | 
					      - Invalid or corrupt JSON.
 | 
				
			||||||
  invalidHelperUse:
 | 
					  invalidHelperUse:
 | 
				
			||||||
    msg: "**Warning**: Incorrect use of the **%s** theme helper."
 | 
					    msg: "**Warning**: Incorrect use of the **%s** theme helper."
 | 
				
			||||||
  fileSaveError:
 | 
					  fileSaveError:
 | 
				
			||||||
@@ -96,3 +103,9 @@ errors:
 | 
				
			|||||||
    msg: "Invalid number of parameters. Expected: **%s**."
 | 
					    msg: "Invalid number of parameters. Expected: **%s**."
 | 
				
			||||||
  missingParam:
 | 
					  missingParam:
 | 
				
			||||||
    msg: The '**%s**' parameter was needed but not supplied.
 | 
					    msg: The '**%s**' parameter was needed but not supplied.
 | 
				
			||||||
 | 
					  createError:
 | 
				
			||||||
 | 
					    msg: Failed to create **'%s'**.
 | 
				
			||||||
 | 
					  exiting:
 | 
				
			||||||
 | 
					    msg: Exiting with status code **%s**.
 | 
				
			||||||
 | 
					  validateError:
 | 
				
			||||||
 | 
					    msg: "An error occurred during validation:\n%s"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,6 @@ Output routines for HackMyResume.
 | 
				
			|||||||
chalk = require('chalk')
 | 
					chalk = require('chalk')
 | 
				
			||||||
HME = require('../core/event-codes')
 | 
					HME = require('../core/event-codes')
 | 
				
			||||||
_ = require('underscore')
 | 
					_ = require('underscore')
 | 
				
			||||||
Class = require('../utils/class.js')
 | 
					 | 
				
			||||||
M2C = require('../utils/md2chalk.js')
 | 
					M2C = require('../utils/md2chalk.js')
 | 
				
			||||||
PATH = require('path')
 | 
					PATH = require('path')
 | 
				
			||||||
LO = require('lodash')
 | 
					LO = require('lodash')
 | 
				
			||||||
@@ -22,11 +21,20 @@ pad = require('string-padding')
 | 
				
			|||||||
dbgStyle = 'cyan';
 | 
					dbgStyle = 'cyan';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###* A stateful output module. All HMR console output handled here. ###
 | 
					 | 
				
			||||||
OutputHandler = module.exports = Class.extend
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: ( opts ) ->
 | 
					###* A stateful output module. All HMR console output handled here. ###
 | 
				
			||||||
    @opts = EXTEND( true, this.opts || { }, opts )
 | 
					module.exports = class OutputHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor: ( opts ) ->
 | 
				
			||||||
 | 
					    @init opts
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  init: (opts) ->
 | 
				
			||||||
 | 
					    @opts = EXTEND( true, @opts || { }, opts )
 | 
				
			||||||
    @msgs = YAML.load(PATH.join( __dirname, 'msg.yml' )).events
 | 
					    @msgs = YAML.load(PATH.join( __dirname, 'msg.yml' )).events
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,6 +47,7 @@ OutputHandler = module.exports = Class.extend
 | 
				
			|||||||
    @opts.silent || console.log( finished )
 | 
					    @opts.silent || console.log( finished )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  do: ( evt ) ->
 | 
					  do: ( evt ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    that = @
 | 
					    that = @
 | 
				
			||||||
@@ -50,8 +59,12 @@ OutputHandler = module.exports = Class.extend
 | 
				
			|||||||
        this.opts.debug &&
 | 
					        this.opts.debug &&
 | 
				
			||||||
        L( M2C( this.msgs.begin.msg, dbgStyle), evt.cmd.toUpperCase() )
 | 
					        L( M2C( this.msgs.begin.msg, dbgStyle), evt.cmd.toUpperCase() )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      when HME.beforeCreate
 | 
					      #when HME.beforeCreate
 | 
				
			||||||
        L( M2C( this.msgs.beforeCreate.msg, 'green' ), evt.fmt, evt.file )
 | 
					        #L( M2C( this.msgs.beforeCreate.msg, 'green' ), evt.fmt, evt.file )
 | 
				
			||||||
 | 
					        #break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      when HME.afterCreate
 | 
				
			||||||
 | 
					        L( M2C( @msgs.beforeCreate.msg, if evt.isError then 'red' else 'green' ), evt.fmt, evt.file )
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      when HME.beforeTheme
 | 
					      when HME.beforeTheme
 | 
				
			||||||
@@ -127,29 +140,43 @@ OutputHandler = module.exports = Class.extend
 | 
				
			|||||||
          evt.file, evt.fmt );
 | 
					          evt.file, evt.fmt );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      when HME.afterValidate
 | 
					      when HME.afterValidate
 | 
				
			||||||
        style = if evt.isValid then 'green' else 'yellow'
 | 
					        style = 'red'
 | 
				
			||||||
        L(
 | 
					        adj = ''
 | 
				
			||||||
          M2C( this.msgs.afterValidate.msg[0], 'white' ) +
 | 
					        msgs = @msgs.afterValidate.msg;
 | 
				
			||||||
          chalk[style].bold(
 | 
					        switch evt.status
 | 
				
			||||||
            if evt.isValid
 | 
					          when 'valid' then style = 'green'; adj = msgs[1]
 | 
				
			||||||
            then this.msgs.afterValidate.msg[1]
 | 
					          when 'invalid' then style = 'yellow'; adj = msgs[2]
 | 
				
			||||||
            else this.msgs.afterValidate.msg[2] ),
 | 
					          when 'broken' then style = 'red'; adj = msgs[3]
 | 
				
			||||||
          evt.file, evt.fmt
 | 
					          when 'missing' then style = 'red'; adj = msgs[4]
 | 
				
			||||||
        );
 | 
					          when 'unknown' then style = 'red'; adj = msgs[5]
 | 
				
			||||||
 | 
					        evt.schema = evt.schema.replace('jars','JSON Resume').toUpperCase()
 | 
				
			||||||
 | 
					        L(M2C( msgs[0], 'white' ) + chalk[style].bold(adj), evt.file, evt.schema)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if evt.errors
 | 
					        if evt.violations
 | 
				
			||||||
          _.each( evt.errors, (err,idx) ->
 | 
					          _.each evt.violations, (err,idx) ->
 | 
				
			||||||
            L( chalk.yellow.bold('--> ') + chalk.yellow(err.field.replace('data.','resume.').toUpperCase() + ' ' + err.message))
 | 
					            L( chalk.yellow.bold('--> ') +
 | 
				
			||||||
          , @)
 | 
					               chalk.yellow(err.field.replace('data.','resume.').toUpperCase() +
 | 
				
			||||||
 | 
					               ' ' + err.message))
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					          , @
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      when HME.afterPeek
 | 
					      when HME.afterPeek
 | 
				
			||||||
        sty = if evt.error then 'red' else ( if evt.target != undefined then 'green' else 'yellow' )
 | 
					        sty = if evt.error then 'red' else ( if evt.target != undefined then 'green' else 'yellow' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # "Peeking at 'someKey' in 'someFile'."
 | 
				
			||||||
        if evt.requested
 | 
					        if evt.requested
 | 
				
			||||||
          L(M2C(this.msgs.beforePeek.msg[0], sty), evt.requested, evt.file)
 | 
					          L(M2C(this.msgs.beforePeek.msg[0], sty), evt.requested, evt.file)
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          L(M2C(this.msgs.beforePeek.msg[1], sty), evt.file)
 | 
					          L(M2C(this.msgs.beforePeek.msg[1], sty), evt.file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if evt.target != undefined
 | 
					        # If the key was present, print it
 | 
				
			||||||
 | 
					        if evt.target != undefined and !evt.error
 | 
				
			||||||
          console.dir( evt.target, { depth: null, colors: true } )
 | 
					          console.dir( evt.target, { depth: null, colors: true } )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If the key was not present, but no error occurred, print it
 | 
				
			||||||
        else if !evt.error
 | 
					        else if !evt.error
 | 
				
			||||||
          L(M2C( this.msgs.afterPeek.msg, 'yellow'), evt.requested, evt.file);
 | 
					          L M2C( this.msgs.afterPeek.msg, 'yellow'), evt.requested, evt.file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        else if evt.error
 | 
				
			||||||
 | 
					          L chalk.red( evt.error.inner.inner )
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								src/core/abstract-resume.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/core/abstract-resume.coffee
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					###*
 | 
				
			||||||
 | 
					Definition of the AbstractResume class.
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 | 
					@module core/abstract-resume
 | 
				
			||||||
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_ = require 'underscore'
 | 
				
			||||||
 | 
					__ = require 'lodash'
 | 
				
			||||||
 | 
					FluentDate = require('./fluent-date')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AbstractResume
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Compute the total duration of the work history.
 | 
				
			||||||
 | 
					  @returns The total duration of the sheet's work history, that is, the number
 | 
				
			||||||
 | 
					  of years between the start date of the earliest job on the resume and the
 | 
				
			||||||
 | 
					  *latest end date of all jobs in the work history*. This last condition is for
 | 
				
			||||||
 | 
					  sheets that have overlapping jobs.
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					  duration: (collKey, startKey, endKey, unit) ->
 | 
				
			||||||
 | 
					    unit = unit || 'years'
 | 
				
			||||||
 | 
					    hist = __.get @, collKey
 | 
				
			||||||
 | 
					    return 0 if !hist or !hist.length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # BEGIN CODE DUPLICATION --> src/inspectors/gap-inspector.coffee (TODO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Convert the candidate's employment history to an array of dates,
 | 
				
			||||||
 | 
					    # where each element in the array is a start date or an end date of a
 | 
				
			||||||
 | 
					    # job -- it doesn't matter which.
 | 
				
			||||||
 | 
					    new_e = hist.map ( job ) ->
 | 
				
			||||||
 | 
					      obj = _.pick( job, [startKey, endKey] )
 | 
				
			||||||
 | 
					      # Synthesize an end date if this is a "current" gig
 | 
				
			||||||
 | 
					      obj[endKey] = 'current' if !_.has obj, endKey
 | 
				
			||||||
 | 
					      if obj && (obj[startKey] || obj[endKey])
 | 
				
			||||||
 | 
					        obj = _.pairs obj
 | 
				
			||||||
 | 
					        obj[0][1] = FluentDate.fmt( obj[0][1] )
 | 
				
			||||||
 | 
					        if obj.length > 1
 | 
				
			||||||
 | 
					          obj[1][1] = FluentDate.fmt( obj[1][1] )
 | 
				
			||||||
 | 
					      obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Flatten the array, remove empties, and sort
 | 
				
			||||||
 | 
					    new_e = _.filter _.flatten( new_e, true ), (v) ->
 | 
				
			||||||
 | 
					      return v && v.length && v[0] && v[0].length
 | 
				
			||||||
 | 
					    return 0 if !new_e or !new_e.length
 | 
				
			||||||
 | 
					    new_e = _.sortBy new_e, ( elem ) -> return elem[1].unix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # END CODE DUPLICATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    firstDate = _.first( new_e )[1];
 | 
				
			||||||
 | 
					    lastDate = _.last( new_e )[1];
 | 
				
			||||||
 | 
					    lastDate.diff firstDate, unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = AbstractResume
 | 
				
			||||||
@@ -33,3 +33,6 @@ module.exports =
 | 
				
			|||||||
  afterInlineConvert: 23
 | 
					  afterInlineConvert: 23
 | 
				
			||||||
  beforeValidate:   24
 | 
					  beforeValidate:   24
 | 
				
			||||||
  afterValidate:    25
 | 
					  afterValidate:    25
 | 
				
			||||||
 | 
					  beforeWrite:      26
 | 
				
			||||||
 | 
					  afterWrite:       27
 | 
				
			||||||
 | 
					  applyTheme:       28
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ The HackMyResume date representation.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
moment = require 'moment'
 | 
					moment = require 'moment'
 | 
				
			||||||
 | 
					require('../utils/string')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Create a FluentDate from a string or Moment date object. There are a few date
 | 
					Create a FluentDate from a string or Moment date object. There are a few date
 | 
				
			||||||
@@ -30,6 +31,8 @@ class FluentDate
 | 
				
			|||||||
  constructor: (dt) ->
 | 
					  constructor: (dt) ->
 | 
				
			||||||
    @rep = this.fmt dt
 | 
					    @rep = this.fmt dt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @isCurrent: (dt) ->
 | 
				
			||||||
 | 
					    !dt || (String.is(dt) and /^(present|now|current)$/.test(dt))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
months = {}
 | 
					months = {}
 | 
				
			||||||
abbr = {}
 | 
					abbr = {}
 | 
				
			||||||
@@ -56,16 +59,7 @@ FluentDate.fmt = ( dt, throws ) ->
 | 
				
			|||||||
    else if /^\s*\d{4}\s*$/.test(dt) # "2015"
 | 
					    else if /^\s*\d{4}\s*$/.test(dt) # "2015"
 | 
				
			||||||
      return moment dt, 'YYYY'
 | 
					      return moment dt, 'YYYY'
 | 
				
			||||||
    else if /^\s*$/.test(dt) # "", " "
 | 
					    else if /^\s*$/.test(dt) # "", " "
 | 
				
			||||||
      defTime =
 | 
					      return moment()
 | 
				
			||||||
        isNull: true
 | 
					 | 
				
			||||||
        isBefore: ( other ) ->
 | 
					 | 
				
			||||||
          if other and !other.isNull then true else false
 | 
					 | 
				
			||||||
        isAfter: ( other ) ->
 | 
					 | 
				
			||||||
          if other and !other.isNull then false else false
 | 
					 | 
				
			||||||
        unix: () -> 0
 | 
					 | 
				
			||||||
        format: () -> ''
 | 
					 | 
				
			||||||
        diff: () -> 0
 | 
					 | 
				
			||||||
      return defTime
 | 
					 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      mt = moment dt
 | 
					      mt = moment dt
 | 
				
			||||||
      if mt.isValid()
 | 
					      if mt.isValid()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,8 @@ XML = require 'xml-escape'
 | 
				
			|||||||
MD = require 'marked'
 | 
					MD = require 'marked'
 | 
				
			||||||
CONVERTER = require 'fresh-jrs-converter'
 | 
					CONVERTER = require 'fresh-jrs-converter'
 | 
				
			||||||
JRSResume = require './jrs-resume'
 | 
					JRSResume = require './jrs-resume'
 | 
				
			||||||
 | 
					FluentDate = require './fluent-date'
 | 
				
			||||||
 | 
					AbstractResume = require './abstract-resume'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,14 +27,9 @@ A FRESH resume or CV. FRESH resumes are backed by JSON, and each FreshResume
 | 
				
			|||||||
object is an instantiation of that JSON decorated with utility methods.
 | 
					object is an instantiation of that JSON decorated with utility methods.
 | 
				
			||||||
@constructor
 | 
					@constructor
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
class FreshResume
 | 
					class FreshResume extends AbstractResume
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Initialize the FreshResume from file. ###
 | 
					 | 
				
			||||||
  open: ( file, opts ) ->
 | 
					 | 
				
			||||||
    raw = FS.readFileSync file, 'utf8'
 | 
					 | 
				
			||||||
    ret = this.parse raw, opts
 | 
					 | 
				
			||||||
    @imp.file = file
 | 
					 | 
				
			||||||
    ret
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Initialize the the FreshResume from JSON string data. ###
 | 
					  ###* Initialize the the FreshResume from JSON string data. ###
 | 
				
			||||||
  parse: ( stringData, opts ) ->
 | 
					  parse: ( stringData, opts ) ->
 | 
				
			||||||
@@ -40,6 +37,7 @@ class FreshResume
 | 
				
			|||||||
    this.parseJSON JSON.parse( stringData ), opts
 | 
					    this.parseJSON JSON.parse( stringData ), opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Initialize the FreshResume from JSON.
 | 
					  Initialize the FreshResume from JSON.
 | 
				
			||||||
  Open and parse the specified FRESH resume. Merge the JSON object model onto
 | 
					  Open and parse the specified FRESH resume. Merge the JSON object model onto
 | 
				
			||||||
@@ -90,6 +88,7 @@ class FreshResume
 | 
				
			|||||||
    @
 | 
					    @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Save the sheet to disk (for environments that have disk access). ###
 | 
					  ###* Save the sheet to disk (for environments that have disk access). ###
 | 
				
			||||||
  save: ( filename ) ->
 | 
					  save: ( filename ) ->
 | 
				
			||||||
    @imp.file = filename || @imp.file
 | 
					    @imp.file = filename || @imp.file
 | 
				
			||||||
@@ -112,7 +111,6 @@ class FreshResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Duplicate this FreshResume instance.
 | 
					  Duplicate this FreshResume instance.
 | 
				
			||||||
  This method first extend()s this object onto an empty, creating a deep copy,
 | 
					  This method first extend()s this object onto an empty, creating a deep copy,
 | 
				
			||||||
@@ -135,6 +133,7 @@ class FreshResume
 | 
				
			|||||||
  stringify: () -> FreshResume.stringify @
 | 
					  stringify: () -> FreshResume.stringify @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Create a copy of this resume in which all string fields have been run through
 | 
					  Create a copy of this resume in which all string fields have been run through
 | 
				
			||||||
  a transformation function (such as a Markdown filter or XML encoder).
 | 
					  a transformation function (such as a Markdown filter or XML encoder).
 | 
				
			||||||
@@ -230,10 +229,6 @@ class FreshResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ###* Add work experience to the sheet. ###
 | 
					  ###* Add work experience to the sheet. ###
 | 
				
			||||||
  add: ( moniker ) ->
 | 
					  add: ( moniker ) ->
 | 
				
			||||||
    defSheet = FreshResume.default()
 | 
					    defSheet = FreshResume.default()
 | 
				
			||||||
@@ -256,7 +251,6 @@ class FreshResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Determine if the sheet includes a specific social profile (eg, GitHub).
 | 
					  Determine if the sheet includes a specific social profile (eg, GitHub).
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
@@ -266,6 +260,7 @@ class FreshResume
 | 
				
			|||||||
      p.network.trim().toLowerCase() == socialNetwork
 | 
					      p.network.trim().toLowerCase() == socialNetwork
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Return the specified network profile. ###
 | 
					  ###* Return the specified network profile. ###
 | 
				
			||||||
  getProfile: ( socialNetwork ) ->
 | 
					  getProfile: ( socialNetwork ) ->
 | 
				
			||||||
    socialNetwork = socialNetwork.trim().toLowerCase()
 | 
					    socialNetwork = socialNetwork.trim().toLowerCase()
 | 
				
			||||||
@@ -273,6 +268,7 @@ class FreshResume
 | 
				
			|||||||
      sn.network.trim().toLowerCase() == socialNetwork
 | 
					      sn.network.trim().toLowerCase() == socialNetwork
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return an array of profiles for the specified network, for when the user
 | 
					  Return an array of profiles for the specified network, for when the user
 | 
				
			||||||
  has multiple eg. GitHub accounts.
 | 
					  has multiple eg. GitHub accounts.
 | 
				
			||||||
@@ -283,6 +279,7 @@ class FreshResume
 | 
				
			|||||||
      sn.network.trim().toLowerCase() == socialNetwork
 | 
					      sn.network.trim().toLowerCase() == socialNetwork
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Determine if the sheet includes a specific skill. ###
 | 
					  ###* Determine if the sheet includes a specific skill. ###
 | 
				
			||||||
  hasSkill: ( skill ) ->
 | 
					  hasSkill: ( skill ) ->
 | 
				
			||||||
    skill = skill.trim().toLowerCase()
 | 
					    skill = skill.trim().toLowerCase()
 | 
				
			||||||
@@ -307,26 +304,8 @@ class FreshResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					 | 
				
			||||||
  Calculate the total duration of the sheet. Assumes this.work has been sorted
 | 
					 | 
				
			||||||
  by start date descending, perhaps via a call to Sheet.sort().
 | 
					 | 
				
			||||||
  @returns The total duration of the sheet's work history, that is, the number
 | 
					 | 
				
			||||||
  of years between the start date of the earliest job on the resume and the
 | 
					 | 
				
			||||||
  *latest end date of all jobs in the work history*. This last condition is for
 | 
					 | 
				
			||||||
  sheets that have overlapping jobs.
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  duration: (unit) ->
 | 
					  duration: (unit) ->
 | 
				
			||||||
    unit = unit || 'years'
 | 
					    super('employment.history', 'start', 'end', unit)
 | 
				
			||||||
    empHist = __.get(this, 'employment.history')
 | 
					 | 
				
			||||||
    if empHist && empHist.length
 | 
					 | 
				
			||||||
      firstJob = _.last( empHist )
 | 
					 | 
				
			||||||
      careerStart = if firstJob.start then firstJob.safe.start else ''
 | 
					 | 
				
			||||||
      if ((typeof careerStart == 'string' || careerStart instanceof String) && !careerStart.trim())
 | 
					 | 
				
			||||||
        return 0
 | 
					 | 
				
			||||||
      careerLast = _.max empHist, ( w ) ->
 | 
					 | 
				
			||||||
        return if w.safe && w.safe.end then w.safe.end.unix() else moment().unix()
 | 
					 | 
				
			||||||
      return careerLast.safe.end.diff careerStart, unit
 | 
					 | 
				
			||||||
    0
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -337,9 +316,9 @@ class FreshResume
 | 
				
			|||||||
  sort: () ->
 | 
					  sort: () ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    byDateDesc = (a,b) ->
 | 
					    byDateDesc = (a,b) ->
 | 
				
			||||||
      if ( a.safe.start.isBefore(b.safe.start) )
 | 
					      if a.safe.start.isBefore(b.safe.start)
 | 
				
			||||||
      then 1
 | 
					      then 1
 | 
				
			||||||
      else ( a.safe.start.isAfter(b.safe.start) && -1 ) || 0
 | 
					      else ( if a.safe.start.isAfter(b.safe.start) then -1 else 0 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sortSection = ( key ) ->
 | 
					    sortSection = ( key ) ->
 | 
				
			||||||
      ar = __.get this, key
 | 
					      ar = __.get this, key
 | 
				
			||||||
@@ -352,21 +331,19 @@ class FreshResume
 | 
				
			|||||||
    sortSection 'service.history'
 | 
					    sortSection 'service.history'
 | 
				
			||||||
    sortSection 'projects'
 | 
					    sortSection 'projects'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # this.awards && this.awards.sort( function(a, b) {
 | 
					 | 
				
			||||||
    #   return( a.safeDate.isBefore(b.safeDate) ) ? 1
 | 
					 | 
				
			||||||
    #     : ( a.safeDate.isAfter(b.safeDate) && -1 ) || 0;
 | 
					 | 
				
			||||||
    # });
 | 
					 | 
				
			||||||
    @writing && @writing.sort (a, b) ->
 | 
					    @writing && @writing.sort (a, b) ->
 | 
				
			||||||
      if a.safe.date.isBefore b.safe.date
 | 
					      if a.safe.date.isBefore b.safe.date
 | 
				
			||||||
      then 1
 | 
					      then 1
 | 
				
			||||||
      else ( a.safe.date.isAfter(b.safe.date) && -1 ) || 0
 | 
					      else ( a.safe.date.isAfter(b.safe.date) && -1 ) || 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Get the default (starter) sheet.
 | 
					Get the default (starter) sheet.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
FreshResume.default = () ->
 | 
					FreshResume.default = () ->
 | 
				
			||||||
  new FreshResume().parseJSON( require 'fresh-resume-starter' )
 | 
					  new FreshResume().parseJSON require('fresh-resume-starter').fresh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
@@ -382,6 +359,7 @@ FreshResume.stringify = ( obj ) ->
 | 
				
			|||||||
  JSON.stringify obj, replacer, 2
 | 
					  JSON.stringify obj, replacer, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Convert human-friendly dates into formal Moment.js dates for all collections.
 | 
					Convert human-friendly dates into formal Moment.js dates for all collections.
 | 
				
			||||||
We don't want to lose the raw textual date as entered by the user, so we store
 | 
					We don't want to lose the raw textual date as entered by the user, so we store
 | 
				
			||||||
@@ -400,6 +378,7 @@ _parseDates = () ->
 | 
				
			|||||||
    return if !obj
 | 
					    return if !obj
 | 
				
			||||||
    if Object.prototype.toString.call( obj ) == '[object Array]'
 | 
					    if Object.prototype.toString.call( obj ) == '[object Array]'
 | 
				
			||||||
      obj.forEach (elem) -> replaceDatesInObject( elem )
 | 
					      obj.forEach (elem) -> replaceDatesInObject( elem )
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
    else if typeof obj == 'object'
 | 
					    else if typeof obj == 'object'
 | 
				
			||||||
      if obj._isAMomentObject || obj.safe
 | 
					      if obj._isAMomentObject || obj.safe
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
@@ -410,14 +389,20 @@ _parseDates = () ->
 | 
				
			|||||||
          obj.safe[ val ] = _fmt obj[val]
 | 
					          obj.safe[ val ] = _fmt obj[val]
 | 
				
			||||||
          if obj[val] && (val == 'start') && !obj.end
 | 
					          if obj[val] && (val == 'start') && !obj.end
 | 
				
			||||||
            obj.safe.end = _fmt 'current'
 | 
					            obj.safe.end = _fmt 'current'
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
  Object.keys( this ).forEach (member) -> replaceDatesInObject(that[member])
 | 
					      return
 | 
				
			||||||
 | 
					  Object.keys( this ).forEach (member) ->
 | 
				
			||||||
 | 
					    replaceDatesInObject(that[member])
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###* Export the Sheet function/ctor. ###
 | 
					###* Export the Sheet function/ctor. ###
 | 
				
			||||||
module.exports = FreshResume
 | 
					module.exports = FreshResume
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Note 1: Adjust default date validation to allow YYYY and YYYY-MM formats
 | 
					# Note 1: Adjust default date validation to allow YYYY and YYYY-MM formats
 | 
				
			||||||
# in addition to YYYY-MM-DD. The original regex:
 | 
					# in addition to YYYY-MM-DD. The original regex:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,32 +20,26 @@ READFILES = require 'recursive-readdir-sync'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###
 | 
					### A representation of a FRESH theme asset.
 | 
				
			||||||
The FRESHTheme class is a representation of a FRESH theme
 | 
					@class FRESHTheme ###
 | 
				
			||||||
asset. See also: JRSTheme.
 | 
					 | 
				
			||||||
@class FRESHTheme
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
class FRESHTheme
 | 
					class FRESHTheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ### Open and parse the specified theme. ###
 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  Open and parse the specified theme.
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  open: ( themeFolder ) ->
 | 
					  open: ( themeFolder ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.folder = themeFolder;
 | 
					    @folder = themeFolder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Open the [theme-name].json file; should have the same name as folder
 | 
					    # Open the [theme-name].json file; should have the same name as folder
 | 
				
			||||||
    pathInfo = parsePath( themeFolder )
 | 
					    pathInfo = parsePath themeFolder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Set up a formats hash for the theme
 | 
					    # Set up a formats hash for the theme
 | 
				
			||||||
    formatsHash = { }
 | 
					    formatsHash = { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Load the theme
 | 
					    # Load the theme
 | 
				
			||||||
    themeFile = PATH.join( themeFolder, 'theme.json' )
 | 
					    themeFile = PATH.join themeFolder, 'theme.json'
 | 
				
			||||||
    themeInfo = loadSafeJson( themeFile )
 | 
					    themeInfo = loadSafeJson themeFile
 | 
				
			||||||
    if themeInfo.ex
 | 
					    if themeInfo.ex
 | 
				
			||||||
      throw
 | 
					      throw
 | 
				
			||||||
        fluenterror:
 | 
					        fluenterror:
 | 
				
			||||||
@@ -69,13 +63,8 @@ class FRESHTheme
 | 
				
			|||||||
        cached[ th ] = cached[th] || new FRESHTheme().open( themePath )
 | 
					        cached[ th ] = cached[th] || new FRESHTheme().open( themePath )
 | 
				
			||||||
        formatsHash[ key ] = cached[ th ].getFormat( key )
 | 
					        formatsHash[ key ] = cached[ th ].getFormat( key )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Check for an explicit "formats" entry in the theme JSON. If it has one,
 | 
					    # Load theme files
 | 
				
			||||||
    # then this theme declares its files explicitly.
 | 
					    formatsHash = _load.call @, formatsHash
 | 
				
			||||||
    if !!@formats
 | 
					 | 
				
			||||||
      formatsHash = loadExplicit.call this, formatsHash
 | 
					 | 
				
			||||||
      @explicit = true;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      formatsHash = loadImplicit.call this, formatsHash
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Cache
 | 
					    # Cache
 | 
				
			||||||
    @formats = formatsHash
 | 
					    @formats = formatsHash
 | 
				
			||||||
@@ -91,72 +80,22 @@ class FRESHTheme
 | 
				
			|||||||
  getFormat: ( fmt ) -> @formats[ fmt ]
 | 
					  getFormat: ( fmt ) -> @formats[ fmt ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Load the theme implicitly, by scanning the theme folder for files. TODO:
 | 
					 | 
				
			||||||
Refactor duplicated code with loadExplicit. ###
 | 
					 | 
				
			||||||
loadImplicit = (formatsHash) ->
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Set up a hash of formats supported by this theme.
 | 
					### Load and parse theme source files. ###
 | 
				
			||||||
 | 
					_load = (formatsHash) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  that = @
 | 
					  that = @
 | 
				
			||||||
  major = false
 | 
					  major = false
 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Establish the base theme folder
 | 
					 | 
				
			||||||
  tplFolder = PATH.join @folder, 'src'
 | 
					  tplFolder = PATH.join @folder, 'src'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  copyOnly = ['.ttf','.otf', '.png','.jpg','.jpeg','.pdf']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Iterate over all files in the theme folder, producing an array, fmts,
 | 
					  # 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
 | 
					  # containing info for each file. While we're doing that, also build up
 | 
				
			||||||
  # the formatsHash object.
 | 
					  # the formatsHash object.
 | 
				
			||||||
  fmts = READFILES(tplFolder).map (absPath) ->
 | 
					  fmts = READFILES(tplFolder).map (absPath) ->
 | 
				
			||||||
 | 
					    _loadOne.call @, absPath, formatsHash, tplFolder
 | 
				
			||||||
    # 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
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # 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 )
 | 
					 | 
				
			||||||
      isMajor = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # We should have a valid output format now.
 | 
					 | 
				
			||||||
    formatsHash[ outFmt ] = formatsHash[outFmt] || {
 | 
					 | 
				
			||||||
      outFormat: outFmt,
 | 
					 | 
				
			||||||
      files: []
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Create the file representation object.
 | 
					 | 
				
			||||||
    obj =
 | 
					 | 
				
			||||||
      action: 'transform'
 | 
					 | 
				
			||||||
      path: absPath
 | 
					 | 
				
			||||||
      major: isMajor
 | 
					 | 
				
			||||||
      orgPath: PATH.relative(tplFolder, 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...
 | 
					  # Now, get all the CSS files...
 | 
				
			||||||
  @cssFiles = fmts.filter (fmt) -> fmt and (fmt.ext == 'css')
 | 
					  @cssFiles = fmts.filter (fmt) -> fmt and (fmt.ext == 'css')
 | 
				
			||||||
@@ -180,98 +119,91 @@ loadImplicit = (formatsHash) ->
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###
 | 
					### Load a single theme file. ###
 | 
				
			||||||
Load the theme explicitly, by following the 'formats' hash
 | 
					_loadOne = ( absPath, formatsHash, tplFolder ) ->
 | 
				
			||||||
in the theme's JSON settings file.
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
loadExplicit = (formatsHash) ->
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Housekeeping
 | 
					  pathInfo = parsePath absPath
 | 
				
			||||||
  tplFolder = PATH.join this.folder, 'src'
 | 
					  absPathSafe = absPath.trim().toLowerCase()
 | 
				
			||||||
  act = null
 | 
					  outFmt = ''
 | 
				
			||||||
  that = this
 | 
					  act = 'copy'
 | 
				
			||||||
 | 
					  isPrimary = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Iterate over all files in the theme folder, producing an array, fmts,
 | 
					  # If this is an "explicit" theme, all files of importance are specified in
 | 
				
			||||||
  # containing info for each file. While we're doing that, also build up
 | 
					  # the "transform" section of the theme.json file.
 | 
				
			||||||
  # the formatsHash object.
 | 
					  if @explicit
 | 
				
			||||||
  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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    outFmt = _.find Object.keys( @formats ), ( fmtKey ) ->
 | 
				
			||||||
 | 
					      fmtVal = @formats[ fmtKey ]
 | 
				
			||||||
 | 
					      _.some fmtVal.transform, (fpath) ->
 | 
				
			||||||
 | 
					        absPathB = PATH.join( @folder, fpath ).trim().toLowerCase()
 | 
				
			||||||
 | 
					        absPathB == absPathSafe
 | 
				
			||||||
 | 
					      , @
 | 
				
			||||||
 | 
					    , @
 | 
				
			||||||
    act = 'transform' if outFmt
 | 
					    act = 'transform' if outFmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if !outFmt
 | 
				
			||||||
    # If this file lives in a specific format folder within the theme,
 | 
					    # If this file lives in a specific format folder within the theme,
 | 
				
			||||||
    # such as "/latex" or "/html", then that format is the output format
 | 
					    # such as "/latex" or "/html", then that format is the implicit output
 | 
				
			||||||
    # for all files within the folder.
 | 
					    # format for all files within the folder
 | 
				
			||||||
    if !outFmt
 | 
					    portion = pathInfo.dirname.replace tplFolder,''
 | 
				
			||||||
      portion = pathInfo.dirname.replace tplFolder,''
 | 
					    if portion && portion.trim()
 | 
				
			||||||
      if portion && portion.trim()
 | 
					      return if portion[1] == '_'
 | 
				
			||||||
        reg = /^(?:\/|\\)(html|latex|doc|pdf)(?:\/|\\)?/ig
 | 
					      reg = /^(?:\/|\\)(html|latex|doc|pdf|png|partials)(?:\/|\\)?/ig
 | 
				
			||||||
        res = reg.exec portion
 | 
					      res = reg.exec( portion )
 | 
				
			||||||
        res && (outFmt = res[1])
 | 
					      if res
 | 
				
			||||||
 | 
					        if res[1] != 'partials'
 | 
				
			||||||
 | 
					          outFmt = res[1]
 | 
				
			||||||
 | 
					          act = 'transform' if !@explicit
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          @partials = @partials || []
 | 
				
			||||||
 | 
					          @partials.push( { name: pathInfo.name, path: absPath } )
 | 
				
			||||||
 | 
					          return null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Otherwise, the output format is inferred from the filename, as in
 | 
					  # Otherwise, the output format is inferred from the filename, as in
 | 
				
			||||||
    # compact-[outputformat].[extension], for ex, compact-pdf.html.
 | 
					  # compact-[outputformat].[extension], for ex, compact-pdf.html
 | 
				
			||||||
    if !outFmt
 | 
					  if !outFmt
 | 
				
			||||||
      idx = pathInfo.name.lastIndexOf '-'
 | 
					    idx = pathInfo.name.lastIndexOf '-'
 | 
				
			||||||
      outFmt = if (idx == -1) then pathInfo.name else pathInfo.name.substr(idx + 1)
 | 
					    outFmt = if idx == -1 then pathInfo.name else pathInfo.name.substr idx+1
 | 
				
			||||||
 | 
					    act = 'transform' if !@explicit
 | 
				
			||||||
 | 
					    defFormats = require './default-formats'
 | 
				
			||||||
 | 
					    isPrimary = _.some defFormats, (form) ->
 | 
				
			||||||
 | 
					      form.name == outFmt and pathInfo.extname != '.css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # We should have a valid output format now.
 | 
					  # Make sure we have a valid formatsHash
 | 
				
			||||||
    formatsHash[ outFmt ] =
 | 
					  formatsHash[ outFmt ] = formatsHash[outFmt] || {
 | 
				
			||||||
      formatsHash[ outFmt ] || {
 | 
					    outFormat: outFmt,
 | 
				
			||||||
        outFormat: outFmt,
 | 
					    files: []
 | 
				
			||||||
        files: [],
 | 
					  }
 | 
				
			||||||
        symLinks: that.formats[ outFmt ].symLinks
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Create the file representation object.
 | 
					  # Move symlink descriptions from theme.json to the format
 | 
				
			||||||
    obj =
 | 
					  if @formats?[ outFmt ]?.symLinks
 | 
				
			||||||
      action: act
 | 
					    formatsHash[ outFmt ].symLinks = @formats[ outFmt ].symLinks
 | 
				
			||||||
      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.
 | 
					  # Create the file representation object
 | 
				
			||||||
    formatsHash[ outFmt ].files.push( obj )
 | 
					  obj =
 | 
				
			||||||
    obj
 | 
					    action: act
 | 
				
			||||||
 | 
					    primary: isPrimary
 | 
				
			||||||
 | 
					    path: absPath
 | 
				
			||||||
 | 
					    orgPath: PATH.relative tplFolder, absPath
 | 
				
			||||||
 | 
					    ext: pathInfo.extname.slice 1
 | 
				
			||||||
 | 
					    title: friendlyName outFmt
 | 
				
			||||||
 | 
					    pre: outFmt
 | 
				
			||||||
 | 
					    # outFormat: outFmt || pathInfo.name,
 | 
				
			||||||
 | 
					    data: FS.readFileSync absPath, 'utf8'
 | 
				
			||||||
 | 
					    css: null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Now, get all the CSS files...
 | 
					  # Add this file to the list of files for this format type.
 | 
				
			||||||
  @cssFiles = fmts.filter ( fmt ) -> fmt.ext == 'css'
 | 
					  formatsHash[ outFmt ].files.push( obj )
 | 
				
			||||||
 | 
					  obj
 | 
				
			||||||
  # 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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###
 | 
					### Return a more friendly name for certain formats. ###
 | 
				
			||||||
Return a more friendly name for certain formats.
 | 
					 | 
				
			||||||
TODO: Refactor
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
friendlyName = ( val ) ->
 | 
					friendlyName = ( val ) ->
 | 
				
			||||||
  val = val.trim().toLowerCase()
 | 
					  val = (val && val.trim().toLowerCase()) || ''
 | 
				
			||||||
  friendly = { yml: 'yaml', md: 'markdown', txt: 'text' }
 | 
					  friendly = { yml: 'yaml', md: 'markdown', txt: 'text' }
 | 
				
			||||||
  friendly[val] || val
 | 
					  friendly[val] || val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = FRESHTheme
 | 
					module.exports = FRESHTheme
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ PATH = require('path')
 | 
				
			|||||||
MD = require('marked')
 | 
					MD = require('marked')
 | 
				
			||||||
CONVERTER = require('fresh-jrs-converter')
 | 
					CONVERTER = require('fresh-jrs-converter')
 | 
				
			||||||
moment = require('moment')
 | 
					moment = require('moment')
 | 
				
			||||||
 | 
					AbstractResume = require('./abstract-resume')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
@@ -22,18 +22,10 @@ A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
 | 
				
			|||||||
is an instantiation of that JSON decorated with utility methods.
 | 
					is an instantiation of that JSON decorated with utility methods.
 | 
				
			||||||
@class JRSResume
 | 
					@class JRSResume
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
class JRSResume
 | 
					class JRSResume extends AbstractResume
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Initialize the JSResume from file. ###
 | 
					 | 
				
			||||||
  open: ( file, opts ) ->
 | 
					 | 
				
			||||||
    raw = FS.readFileSync file, 'utf8'
 | 
					 | 
				
			||||||
    ret = this.parse raw, opts
 | 
					 | 
				
			||||||
    @imp.file = file
 | 
					 | 
				
			||||||
    ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ###* Initialize the the JSResume from string. ###
 | 
					  ###* Initialize the the JSResume from string. ###
 | 
				
			||||||
  parse: ( stringData, opts ) ->
 | 
					  parse: ( stringData, opts ) ->
 | 
				
			||||||
    @imp = @imp ? raw: stringData
 | 
					    @imp = @imp ? raw: stringData
 | 
				
			||||||
@@ -113,8 +105,7 @@ class JRSResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Return the resume format. ###
 | 
					  ###* Return the resume format. ###
 | 
				
			||||||
  format = () -> 'JRS'
 | 
					  format: () -> 'JRS'
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,7 +148,6 @@ class JRSResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  ###* Add work experience to the sheet. ###
 | 
					  ###* Add work experience to the sheet. ###
 | 
				
			||||||
  add: ( moniker ) ->
 | 
					  add: ( moniker ) ->
 | 
				
			||||||
    defSheet = JRSResume.default()
 | 
					    defSheet = JRSResume.default()
 | 
				
			||||||
@@ -204,23 +194,8 @@ class JRSResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  duration: (unit) ->
 | 
				
			||||||
  Calculate the total duration of the sheet. Assumes this.work has been sorted
 | 
					    super('work', 'startDate', 'endDate', unit)
 | 
				
			||||||
  by start date descending, perhaps via a call to Sheet.sort().
 | 
					 | 
				
			||||||
  @returns The total duration of the sheet's work history, that is, the number
 | 
					 | 
				
			||||||
  of years between the start date of the earliest job on the resume and the
 | 
					 | 
				
			||||||
  *latest end date of all jobs in the work history*. This last condition is for
 | 
					 | 
				
			||||||
  sheets that have overlapping jobs.
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  duration: ( unit ) ->
 | 
					 | 
				
			||||||
    unit = unit || 'years';
 | 
					 | 
				
			||||||
    if this.work && this.work.length
 | 
					 | 
				
			||||||
      careerStart = this.work[ this.work.length - 1].safeStartDate
 | 
					 | 
				
			||||||
      if (typeof careerStart == 'string' || careerStart instanceof String) && !careerStart.trim()
 | 
					 | 
				
			||||||
        return 0
 | 
					 | 
				
			||||||
      careerLast = _.max( this.work, ( w ) -> w.safeEndDate.unix() ).safeEndDate;
 | 
					 | 
				
			||||||
      return careerLast.diff careerStart, unit
 | 
					 | 
				
			||||||
    0
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -250,6 +225,7 @@ class JRSResume
 | 
				
			|||||||
      else ( a.safeReleaseDate.isAfter(b.safeReleaseDate) && -1 ) || 0
 | 
					      else ( a.safeReleaseDate.isAfter(b.safeReleaseDate) && -1 ) || 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  dupe: () ->
 | 
					  dupe: () ->
 | 
				
			||||||
    rnew = new JRSResume()
 | 
					    rnew = new JRSResume()
 | 
				
			||||||
    rnew.parse this.stringify(), { }
 | 
					    rnew.parse this.stringify(), { }
 | 
				
			||||||
@@ -309,7 +285,7 @@ class JRSResume
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
###* Get the default (empty) sheet. ###
 | 
					###* Get the default (empty) sheet. ###
 | 
				
			||||||
JRSResume.default = () ->
 | 
					JRSResume.default = () ->
 | 
				
			||||||
  new JRSResume().open PATH.join( __dirname, 'empty-jrs.json'), 'Empty'
 | 
					  new JRSResume().parseJSON require('fresh-resume-starter').jrs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -327,6 +303,7 @@ JRSResume.stringify = ( obj ) ->
 | 
				
			|||||||
  JSON.stringify obj, replacer, 2
 | 
					  JSON.stringify obj, replacer, 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Convert human-friendly dates into formal Moment.js dates for all collections.
 | 
					Convert human-friendly dates into formal Moment.js dates for all collections.
 | 
				
			||||||
We don't want to lose the raw textual date as entered by the user, so we store
 | 
					We don't want to lose the raw textual date as entered by the user, so we store
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,68 +20,69 @@ The JRSTheme class is a representation of a JSON Resume theme asset.
 | 
				
			|||||||
class JRSTheme
 | 
					class JRSTheme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					 | 
				
			||||||
Open and parse the specified theme.
 | 
					 | 
				
			||||||
@method open
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
open: ( thFolder ) ->
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @folder = thFolder
 | 
					  ###*
 | 
				
			||||||
 | 
					  Open and parse the specified theme.
 | 
				
			||||||
 | 
					  @method open
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					  open: ( thFolder ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Open the [theme-name].json file; should have the same
 | 
					    @folder = thFolder
 | 
				
			||||||
  # name as folder
 | 
					 | 
				
			||||||
  pathInfo = parsePath thFolder
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Open and parse the theme's package.json file.
 | 
					    # Open the [theme-name].json file; should have the same
 | 
				
			||||||
  pkgJsonPath = PATH.join thFolder, 'package.json'
 | 
					    # name as folder
 | 
				
			||||||
  if pathExists pkgJsonPath
 | 
					    pathInfo = parsePath thFolder
 | 
				
			||||||
    thApi = require thFolder
 | 
					 | 
				
			||||||
    thPkg = require pkgJsonPath
 | 
					 | 
				
			||||||
    this.name = thPkg.name
 | 
					 | 
				
			||||||
    this.render = (thApi && thApi.render) || undefined
 | 
					 | 
				
			||||||
    this.engine = 'jrs'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Create theme formats (HTML and PDF). Just add the bare minimum mix of
 | 
					    # Open and parse the theme's package.json file.
 | 
				
			||||||
    # properties necessary to allow JSON Resume themes to share a rendering
 | 
					    pkgJsonPath = PATH.join thFolder, 'package.json'
 | 
				
			||||||
    # path with FRESH themes.
 | 
					    if pathExists pkgJsonPath
 | 
				
			||||||
    this.formats =
 | 
					      thApi = require thFolder
 | 
				
			||||||
      html:
 | 
					      thPkg = require pkgJsonPath
 | 
				
			||||||
        outFormat: 'html'
 | 
					      this.name = thPkg.name
 | 
				
			||||||
        files: [{
 | 
					      this.render = (thApi && thApi.render) || undefined
 | 
				
			||||||
          action: 'transform',
 | 
					      this.engine = 'jrs'
 | 
				
			||||||
          render: this.render,
 | 
					
 | 
				
			||||||
          major: true,
 | 
					      # Create theme formats (HTML and PDF). Just add the bare minimum mix of
 | 
				
			||||||
          ext: 'html',
 | 
					      # properties necessary to allow JSON Resume themes to share a rendering
 | 
				
			||||||
          css: null
 | 
					      # path with FRESH themes.
 | 
				
			||||||
        }]
 | 
					      this.formats =
 | 
				
			||||||
      pdf:
 | 
					        html:
 | 
				
			||||||
        outFormat: 'pdf'
 | 
					          outFormat: 'html'
 | 
				
			||||||
        files: [{
 | 
					          files: [{
 | 
				
			||||||
          action: 'transform',
 | 
					            action: 'transform',
 | 
				
			||||||
          render: this.render,
 | 
					            render: this.render,
 | 
				
			||||||
          major: true,
 | 
					            primary: true,
 | 
				
			||||||
          ext: 'pdf',
 | 
					            ext: 'html',
 | 
				
			||||||
          css: null
 | 
					            css: null
 | 
				
			||||||
        }]
 | 
					          }]
 | 
				
			||||||
  else
 | 
					        pdf:
 | 
				
			||||||
    throw { fluenterror: HACKMYSTATUS.missingPackageJSON };
 | 
					          outFormat: 'pdf'
 | 
				
			||||||
  @
 | 
					          files: [{
 | 
				
			||||||
 | 
					            action: 'transform',
 | 
				
			||||||
 | 
					            render: this.render,
 | 
				
			||||||
 | 
					            primary: true,
 | 
				
			||||||
 | 
					            ext: 'pdf',
 | 
				
			||||||
 | 
					            css: null
 | 
				
			||||||
 | 
					          }]
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      throw { fluenterror: HACKMYSTATUS.missingPackageJSON };
 | 
				
			||||||
 | 
					    @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					  ###*
 | 
				
			||||||
Determine if the theme supports the output format.
 | 
					  Determine if the theme supports the output format.
 | 
				
			||||||
@method hasFormat
 | 
					  @method hasFormat
 | 
				
			||||||
###
 | 
					  ###
 | 
				
			||||||
hasFormat: ( fmt ) ->  _.has this.formats, fmt
 | 
					  hasFormat: ( fmt ) ->  _.has this.formats, fmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					  ###*
 | 
				
			||||||
Return the requested output format.
 | 
					  Return the requested output format.
 | 
				
			||||||
@method getFormat
 | 
					  @method getFormat
 | 
				
			||||||
###
 | 
					  ###
 | 
				
			||||||
getFormat = ( fmt ) -> @formats[ fmt ]
 | 
					  getFormat: ( fmt ) -> @formats[ fmt ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = JRSTheme;
 | 
					module.exports = JRSTheme;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,13 +103,7 @@ _parse = ( fileName, opts, eve ) ->
 | 
				
			|||||||
    return ret
 | 
					    return ret
 | 
				
			||||||
  catch
 | 
					  catch
 | 
				
			||||||
    # Can be ENOENT, EACCES, SyntaxError, etc.
 | 
					    # Can be ENOENT, EACCES, SyntaxError, etc.
 | 
				
			||||||
    ex =
 | 
					    fluenterror: if rawData then HACKMYSTATUS.parseError else HACKMYSTATUS.readError
 | 
				
			||||||
      fluenterror: if rawData then HACKMYSTATUS.parseError else HACKMYSTATUS.readError
 | 
					    inner: _error
 | 
				
			||||||
      inner: _error
 | 
					    raw: rawData
 | 
				
			||||||
      raw: rawData
 | 
					    file: fileName
 | 
				
			||||||
      file: fileName
 | 
					 | 
				
			||||||
      shouldExit: false
 | 
					 | 
				
			||||||
    opts.quit && (ex.quit = true)
 | 
					 | 
				
			||||||
    eve && eve.err ex.fluenterror, ex
 | 
					 | 
				
			||||||
    throw ex if opts.throw
 | 
					 | 
				
			||||||
    ex
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ module.exports =
 | 
				
			|||||||
  resumeNotFoundAlt: 6
 | 
					  resumeNotFoundAlt: 6
 | 
				
			||||||
  inputOutputParity: 7
 | 
					  inputOutputParity: 7
 | 
				
			||||||
  createNameMissing: 8
 | 
					  createNameMissing: 8
 | 
				
			||||||
  pdfgeneration: 9
 | 
					  pdfGeneration: 9
 | 
				
			||||||
  missingPackageJSON: 10
 | 
					  missingPackageJSON: 10
 | 
				
			||||||
  invalid: 11
 | 
					  invalid: 11
 | 
				
			||||||
  invalidFormat: 12
 | 
					  invalidFormat: 12
 | 
				
			||||||
@@ -31,3 +31,5 @@ module.exports =
 | 
				
			|||||||
  themeLoad: 22
 | 
					  themeLoad: 22
 | 
				
			||||||
  invalidParamCount: 23
 | 
					  invalidParamCount: 23
 | 
				
			||||||
  missingParam: 24
 | 
					  missingParam: 24
 | 
				
			||||||
 | 
					  createError: 25
 | 
				
			||||||
 | 
					  validateError: 26
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,25 +1,19 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the BaseGenerator class.
 | 
					Definition of the BaseGenerator class.
 | 
				
			||||||
@module base-generator.js
 | 
					@module generators/base-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Use J. Resig's nifty class implementation
 | 
					 | 
				
			||||||
Class = require '../utils/class'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
The BaseGenerator class is the root of the generator hierarchy. Functionality
 | 
					The BaseGenerator class is the root of the generator hierarchy. Functionality
 | 
				
			||||||
common to ALL generators lives here.
 | 
					common to ALL generators lives here.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BaseGenerator = module.exports = Class.extend
 | 
					module.exports = class BaseGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Base-class initialize. ###
 | 
					  ###* Base-class initialize. ###
 | 
				
			||||||
  init: ( outputFormat ) -> @format = outputFormat
 | 
					  constructor: ( @format ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Status codes. ###
 | 
					  ###* Status codes. ###
 | 
				
			||||||
  codes: require '../core/status-codes'
 | 
					  codes: require '../core/status-codes'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the HTMLGenerator class.
 | 
					Definition of the HTMLGenerator class.
 | 
				
			||||||
 | 
					@module generators/html-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module html-generator.js
 | 
					 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,9 +14,9 @@ require 'string.prototype.endswith'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HtmlGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class HtmlGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: -> @_super 'html'
 | 
					  constructor: -> super 'html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Copy satellite CSS files to the destination and optionally pretty-print
 | 
					  Copy satellite CSS files to the destination and optionally pretty-print
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,18 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the HtmlPdfCLIGenerator class.
 | 
					Definition of the HtmlPdfCLIGenerator class.
 | 
				
			||||||
@module html-pdf-generator.js
 | 
					@module generators/html-pdf-generator.js
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = require('./template-generator')
 | 
					TemplateGenerator = require './template-generator'
 | 
				
			||||||
FS = require('fs-extra')
 | 
					FS = require 'fs-extra'
 | 
				
			||||||
HTML = require( 'html' )
 | 
					PATH = require 'path'
 | 
				
			||||||
PATH = require('path')
 | 
					SLASH = require 'slash'
 | 
				
			||||||
SPAWN = require('../utils/safe-spawn')
 | 
					_ = require 'underscore'
 | 
				
			||||||
SLASH = require('slash');
 | 
					HMSTATUS = require '../core/status-codes'
 | 
				
			||||||
 | 
					SPAWN = require '../utils/safe-spawn'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
@@ -21,33 +21,34 @@ wkhtmltopdf, and other PDF engines over a CLI (command-line interface).
 | 
				
			|||||||
If an engine isn't installed for a particular platform, error out gracefully.
 | 
					If an engine isn't installed for a particular platform, error out gracefully.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HtmlPdfCLIGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class HtmlPdfCLIGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'pdf', 'html'
 | 
					
 | 
				
			||||||
 | 
					  constructor: () -> super 'pdf', 'html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Generate the binary PDF. ###
 | 
					  ###* Generate the binary PDF. ###
 | 
				
			||||||
  onBeforeSave: ( info ) ->
 | 
					  onBeforeSave: ( info ) ->
 | 
				
			||||||
    try
 | 
					    #console.dir _.omit( info, 'mk' ), depth: null, colors: true
 | 
				
			||||||
      safe_eng = info.opts.pdf || 'wkhtmltopdf';
 | 
					    return info.mk if info.ext != 'html' and info.ext != 'pdf'
 | 
				
			||||||
      if safe_eng != 'none'
 | 
					    safe_eng = info.opts.pdf || 'wkhtmltopdf'
 | 
				
			||||||
        engines[ safe_eng ].call this, info.mk, info.outputFile
 | 
					    safe_eng = 'phantomjs' if safe_eng == 'phantom'
 | 
				
			||||||
        return null # halt further processing
 | 
					    if _.has engines, safe_eng
 | 
				
			||||||
    catch ex
 | 
					      @errHandler = info.opts.errHandler
 | 
				
			||||||
      # { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', ... }
 | 
					      engines[ safe_eng ].call @, info.mk, info.outputFile, @onError
 | 
				
			||||||
      # { [Error: ENOENT] }
 | 
					      return null # halt further processing
 | 
				
			||||||
      if ex.inner && ex.inner.code == 'ENOENT'
 | 
					
 | 
				
			||||||
        throw
 | 
					
 | 
				
			||||||
          fluenterror: this.codes.notOnPath
 | 
					
 | 
				
			||||||
          inner: ex.inner
 | 
					  ### Low-level error callback for spawn(). May be called after HMR process
 | 
				
			||||||
          engine: ex.cmd,
 | 
					  termination, so object references may not be valid here. That's okay; if
 | 
				
			||||||
          stack: ex.inner && ex.inner.stack
 | 
					  the references are invalid, the error was already logged. We could use
 | 
				
			||||||
      else
 | 
					  spawn-watch here but that causes issues on legacy Node.js. ###
 | 
				
			||||||
        throw
 | 
					  onError: (ex, param) ->
 | 
				
			||||||
          fluenterror: this.codes.pdfGeneration
 | 
					    param.errHandler?.err? HMSTATUS.pdfGeneration, ex
 | 
				
			||||||
          inner: ex
 | 
					    return
 | 
				
			||||||
          stack: ex.stack
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,11 +64,12 @@ engines =
 | 
				
			|||||||
  TODO: If HTML generation has run, reuse that output
 | 
					  TODO: If HTML generation has run, reuse that output
 | 
				
			||||||
  TODO: Local web server to ease wkhtmltopdf rendering
 | 
					  TODO: Local web server to ease wkhtmltopdf rendering
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
  wkhtmltopdf: (markup, fOut) ->
 | 
					  wkhtmltopdf: (markup, fOut, on_error) ->
 | 
				
			||||||
    # Save the markup to a temporary file
 | 
					    # Save the markup to a temporary file
 | 
				
			||||||
    tempFile = fOut.replace /\.pdf$/i, '.pdf.html'
 | 
					    tempFile = fOut.replace /\.pdf$/i, '.pdf.html'
 | 
				
			||||||
    FS.writeFileSync tempFile, markup, 'utf8'
 | 
					    FS.writeFileSync tempFile, markup, 'utf8'
 | 
				
			||||||
    info = SPAWN 'wkhtmltopdf', [ tempFile, fOut ]
 | 
					    SPAWN 'wkhtmltopdf', [ tempFile, fOut ], false, on_error, @
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,14 +80,13 @@ engines =
 | 
				
			|||||||
  TODO: If HTML generation has run, reuse that output
 | 
					  TODO: If HTML generation has run, reuse that output
 | 
				
			||||||
  TODO: Local web server to ease Phantom rendering
 | 
					  TODO: Local web server to ease Phantom rendering
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
 | 
					  phantomjs: ( markup, fOut, on_error ) ->
 | 
				
			||||||
  phantom: ( markup, fOut ) ->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Save the markup to a temporary file
 | 
					    # Save the markup to a temporary file
 | 
				
			||||||
    tempFile = fOut.replace(/\.pdf$/i, '.pdf.html');
 | 
					    tempFile = fOut.replace /\.pdf$/i, '.pdf.html'
 | 
				
			||||||
    FS.writeFileSync tempFile, markup, 'utf8'
 | 
					    FS.writeFileSync tempFile, markup, 'utf8'
 | 
				
			||||||
    scriptPath = SLASH( PATH.relative( process.cwd(),
 | 
					    scriptPath = PATH.relative process.cwd(), PATH.resolve( __dirname, '../utils/rasterize.js' )
 | 
				
			||||||
      PATH.resolve( __dirname, '../utils/rasterize.js' ) ) );
 | 
					    scriptPath = SLASH scriptPath
 | 
				
			||||||
    sourcePath = SLASH( PATH.relative( process.cwd(), tempFile) );
 | 
					    sourcePath = SLASH PATH.relative( process.cwd(), tempFile)
 | 
				
			||||||
    destPath = SLASH( PATH.relative( process.cwd(), fOut) );
 | 
					    destPath = SLASH PATH.relative( process.cwd(), fOut)
 | 
				
			||||||
    info = SPAWN('phantomjs', [ scriptPath, sourcePath, destPath ]);
 | 
					    SPAWN 'phantomjs', [ scriptPath, sourcePath, destPath ], false, on_error, @
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the HtmlPngGenerator class.
 | 
					Definition of the HtmlPngGenerator class.
 | 
				
			||||||
 | 
					@module generators/html-png-generator
 | 
				
			||||||
@license MIT. See LICENSE.MD for details.
 | 
					@license MIT. See LICENSE.MD for details.
 | 
				
			||||||
@module html-png-generator.js
 | 
					 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,9 +17,9 @@ PATH = require 'path'
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
An HTML-based PNG resume generator for HackMyResume.
 | 
					An HTML-based PNG resume generator for HackMyResume.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
HtmlPngGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class HtmlPngGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: -> @_super 'png', 'html'
 | 
					  constructor: -> super 'png', 'html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  invoke: ( rez, themeMarkup, cssInfo, opts ) ->
 | 
					  invoke: ( rez, themeMarkup, cssInfo, opts ) ->
 | 
				
			||||||
    # TODO: Not currently called or callable.
 | 
					    # TODO: Not currently called or callable.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,35 +1,25 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the JsonGenerator class.
 | 
					Definition of the JsonGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/json-generator
 | 
					@module generators/json-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BaseGenerator = require './base-generator'
 | 
					BaseGenerator = require './base-generator'
 | 
				
			||||||
FS = require 'fs'
 | 
					FS = require 'fs'
 | 
				
			||||||
_ = require 'underscore'
 | 
					_ = require 'underscore'
 | 
				
			||||||
 | 
					FJCV = require 'fresh-jrs-converter'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###* The JsonGenerator generates a FRESH or JRS resume as an output. ###
 | 
				
			||||||
The JsonGenerator generates a JSON resume directly.
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
JsonGenerator = module.exports = BaseGenerator.extend
 | 
					module.exports = class JsonGenerator extends BaseGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'json'
 | 
					  constructor: () -> super 'json'
 | 
				
			||||||
 | 
					 | 
				
			||||||
  keys: ['imp', 'warnings', 'computed', 'filt', 'ctrl', 'index',
 | 
					 | 
				
			||||||
    'safeStartDate', 'safeEndDate', 'safeDate', 'safeReleaseDate', 'result',
 | 
					 | 
				
			||||||
    'isModified', 'htmlPreview', 'safe' ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  invoke: ( rez ) ->
 | 
					  invoke: ( rez ) ->
 | 
				
			||||||
 | 
					    altRez = FJCV[ 'to' + if rez.format() == 'FRESH' then 'JRS' else 'FRESH' ] rez
 | 
				
			||||||
    # TODO: merge with FCVD
 | 
					    altRez = FJCV.toSTRING( altRez )
 | 
				
			||||||
    replacer = ( key,value ) -> # Exclude these keys from stringification
 | 
					    #altRez.stringify()
 | 
				
			||||||
      if (_.some @keys, (val) -> key.trim() == val)
 | 
					 | 
				
			||||||
        return undefined
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        value
 | 
					 | 
				
			||||||
    JSON.stringify rez, replacer, 2
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  generate: ( rez, f ) ->
 | 
					  generate: ( rez, f ) ->
 | 
				
			||||||
    FS.writeFileSync( f, this.invoke(rez), 'utf8' )
 | 
					    FS.writeFileSync f, @invoke(rez), 'utf8'
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the JsonYamlGenerator class.
 | 
					Definition of the JsonYamlGenerator class.
 | 
				
			||||||
@module json-yaml-generator.js
 | 
					@module generators/json-yaml-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,9 +18,9 @@ JSON without a template, producing an equivalent YAML-formatted resume. See
 | 
				
			|||||||
also YamlGenerator (yaml-generator.js).
 | 
					also YamlGenerator (yaml-generator.js).
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
JsonYamlGenerator = module.exports = BaseGenerator.extend
 | 
					module.exports = class JsonYamlGenerator extends BaseGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'yml'
 | 
					  constructor: () -> super 'yml'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  invoke: ( rez, themeMarkup, cssInfo, opts ) ->
 | 
					  invoke: ( rez, themeMarkup, cssInfo, opts ) ->
 | 
				
			||||||
    YAML.stringify JSON.parse( rez.stringify() ), Infinity, 2
 | 
					    YAML.stringify JSON.parse( rez.stringify() ), Infinity, 2
 | 
				
			||||||
@@ -28,3 +28,4 @@ JsonYamlGenerator = module.exports = BaseGenerator.extend
 | 
				
			|||||||
  generate: ( rez, f, opts ) ->
 | 
					  generate: ( rez, f, opts ) ->
 | 
				
			||||||
    data = YAML.stringify JSON.parse( rez.stringify() ), Infinity, 2
 | 
					    data = YAML.stringify JSON.parse( rez.stringify() ), Infinity, 2
 | 
				
			||||||
    FS.writeFileSync f, data, 'utf8'
 | 
					    FS.writeFileSync f, data, 'utf8'
 | 
				
			||||||
 | 
					    data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the LaTeXGenerator class.
 | 
					Definition of the LaTeXGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/latex-generator
 | 
					@module generators/latex-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = require './template-generator'
 | 
					TemplateGenerator = require './template-generator'
 | 
				
			||||||
@@ -9,6 +9,6 @@ TemplateGenerator = require './template-generator'
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
LaTeXGenerator generates a LaTeX resume via TemplateGenerator.
 | 
					LaTeXGenerator generates a LaTeX resume via TemplateGenerator.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
LaTeXGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class LaTeXGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'latex', 'tex'
 | 
					  constructor: () -> super 'latex', 'tex'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the MarkdownGenerator class.
 | 
					Definition of the MarkdownGenerator class.
 | 
				
			||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
 | 
					@module generators/markdown-generator
 | 
				
			||||||
@module markdown-generator.js
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = require './template-generator'
 | 
					TemplateGenerator = require './template-generator'
 | 
				
			||||||
@@ -9,6 +9,6 @@ TemplateGenerator = require './template-generator'
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
MarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator.
 | 
					MarkdownGenerator generates a Markdown-formatted resume via TemplateGenerator.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
MarkdownGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class MarkdownGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'md', 'txt'
 | 
					  constructor: () -> super 'md', 'txt'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the TemplateGenerator class. TODO: Refactor
 | 
					Definition of the TemplateGenerator class. TODO: Refactor
 | 
				
			||||||
 | 
					@module generators/template-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module template-generator.js
 | 
					 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,14 +27,16 @@ plain text, and XML versions of Microsoft Word, Excel, and OpenOffice.
 | 
				
			|||||||
@class TemplateGenerator
 | 
					@class TemplateGenerator
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = module.exports = BaseGenerator.extend
 | 
					module.exports = class TemplateGenerator extends BaseGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Constructor. Set the output format and template format for this
 | 
					  ###* Constructor. Set the output format and template format for this
 | 
				
			||||||
  generator. Will usually be called by a derived generator such as
 | 
					  generator. Will usually be called by a derived generator such as
 | 
				
			||||||
  HTMLGenerator or MarkdownGenerator. ###
 | 
					  HTMLGenerator or MarkdownGenerator. ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: ( outputFormat, templateFormat, cssFile ) ->
 | 
					  constructor: ( outputFormat, templateFormat, cssFile ) ->
 | 
				
			||||||
    @_super outputFormat
 | 
					    super outputFormat
 | 
				
			||||||
    @tplFormat = templateFormat || outputFormat
 | 
					    @tplFormat = templateFormat || outputFormat
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,27 +54,32 @@ TemplateGenerator = module.exports = BaseGenerator.extend
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    opts =
 | 
					    opts =
 | 
				
			||||||
      if opts
 | 
					      if opts
 | 
				
			||||||
      then (this.opts = EXTEND( true, { }, _defaultOpts, opts ))
 | 
					      then (@opts = EXTEND( true, { }, _defaultOpts, opts ))
 | 
				
			||||||
      else this.opts
 | 
					      else @opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Sort such that CSS files are processed before others
 | 
					    # Sort such that CSS files are processed before others
 | 
				
			||||||
    curFmt = opts.themeObj.getFormat( this.format )
 | 
					    curFmt = opts.themeObj.getFormat( this.format )
 | 
				
			||||||
    curFmt.files = _.sortBy curFmt.files, (fi) -> fi.ext != 'css'
 | 
					    curFmt.files = _.sortBy curFmt.files, (fi) -> fi.ext != 'css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Run the transformation!
 | 
					    # Run the transformation!
 | 
				
			||||||
    results = curFmt.files.map( ( tplInfo, idx ) ->
 | 
					    results = curFmt.files.map ( tplInfo, idx ) ->
 | 
				
			||||||
      trx = @.single rez, tplInfo.data, this.format, opts, opts.themeObj, curFmt
 | 
					      if tplInfo.action == 'transform'
 | 
				
			||||||
      if tplInfo.ext == 'css'
 | 
					        trx = @transform rez, tplInfo.data, @format, opts, opts.themeObj, curFmt
 | 
				
			||||||
        curFmt.files[idx].data = trx
 | 
					        if tplInfo.ext == 'css'
 | 
				
			||||||
      else tplInfo.ext == 'html'
 | 
					          curFmt.files[idx].data = trx
 | 
				
			||||||
        #tplInfo.css contains the CSS data loaded by theme
 | 
					        else tplInfo.ext == 'html'
 | 
				
			||||||
        #tplInfo.cssPath contains the absolute path to the source CSS File
 | 
					          #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
 | 
					      return info: tplInfo, data: trx
 | 
				
			||||||
    , @)
 | 
					    , @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    files: results
 | 
					    files: results
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Generate a resume using file-based inputs and outputs. Requires access
 | 
					  ###* Generate a resume using file-based inputs and outputs. Requires access
 | 
				
			||||||
  to the local filesystem.
 | 
					  to the local filesystem.
 | 
				
			||||||
  @method generate
 | 
					  @method generate
 | 
				
			||||||
@@ -83,53 +90,60 @@ TemplateGenerator = module.exports = BaseGenerator.extend
 | 
				
			|||||||
  generate: ( rez, f, opts ) ->
 | 
					  generate: ( rez, f, opts ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Prepare
 | 
					    # Prepare
 | 
				
			||||||
    this.opts = EXTEND( true, { }, _defaultOpts, opts );
 | 
					    @opts = EXTEND true, { }, _defaultOpts, opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Call the string-based generation method to perform the generation.
 | 
					    # Call the string-based generation method
 | 
				
			||||||
    genInfo = this.invoke( rez, null )
 | 
					    genInfo = @invoke rez, null
 | 
				
			||||||
    outFolder = parsePath( f ).dirname
 | 
					    outFolder = parsePath( f ).dirname
 | 
				
			||||||
    curFmt = opts.themeObj.getFormat( this.format )
 | 
					    curFmt = opts.themeObj.getFormat @format
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Process individual files within this format. For example, the HTML
 | 
					    # Process individual files within this format. For example, the HTML
 | 
				
			||||||
    # output format for a theme may have multiple HTML files, CSS files,
 | 
					    # output format for a theme may have multiple HTML files, CSS files,
 | 
				
			||||||
    # etc. Process them here.
 | 
					    # etc. Process them here.
 | 
				
			||||||
    genInfo.files.forEach(( file ) ->
 | 
					    genInfo.files.forEach ( file ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # console.dir _.omit(file.info,'cssData','data','css' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Pre-processing
 | 
					      # Pre-processing
 | 
				
			||||||
      file.info.orgPath = file.info.orgPath || '' # <-- For JRS themes
 | 
					      file.info.orgPath = file.info.orgPath || ''
 | 
				
			||||||
      thisFilePath = PATH.join( outFolder, file.info.orgPath )
 | 
					      thisFilePath =
 | 
				
			||||||
      if this.onBeforeSave
 | 
					        if file.info.primary
 | 
				
			||||||
 | 
					        then f
 | 
				
			||||||
 | 
					        else PATH.join outFolder, file.info.orgPath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if file.info.action != 'copy' and @onBeforeSave
 | 
				
			||||||
        file.data = this.onBeforeSave
 | 
					        file.data = this.onBeforeSave
 | 
				
			||||||
          theme: opts.themeObj
 | 
					          theme: opts.themeObj
 | 
				
			||||||
          outputFile: if file.info.major then f else thisFilePath
 | 
					          outputFile: thisFilePath
 | 
				
			||||||
          mk: file.data
 | 
					          mk: file.data
 | 
				
			||||||
          opts: this.opts
 | 
					          opts: @opts,
 | 
				
			||||||
 | 
					          ext: file.info.ext
 | 
				
			||||||
        if !file.data
 | 
					        if !file.data
 | 
				
			||||||
          return # PDF etc
 | 
					          return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # Write the file
 | 
					      # Write the file
 | 
				
			||||||
      fileName = if file.info.major then f else thisFilePath
 | 
					      opts.beforeWrite? thisFilePath
 | 
				
			||||||
      MKDIRP.sync PATH.dirname( fileName )
 | 
					      MKDIRP.sync PATH.dirname( thisFilePath )
 | 
				
			||||||
      FS.writeFileSync fileName, file.data, { encoding: 'utf8', flags: 'w' }
 | 
					
 | 
				
			||||||
 | 
					      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
 | 
					      # Post-processing
 | 
				
			||||||
      if @onAfterSave
 | 
					      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.
 | 
					    # Some themes require a symlink structure. If so, create it.
 | 
				
			||||||
    if curFmt.symLinks
 | 
					    createSymLinks curFmt, outFolder
 | 
				
			||||||
      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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    genInfo
 | 
					    genInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###* Perform a single resume resume transformation using string-based inputs
 | 
					  ###* Perform a single resume resume transformation using string-based inputs
 | 
				
			||||||
  and outputs without touching the local file system.
 | 
					  and outputs without touching the local file system.
 | 
				
			||||||
  @param json A FRESH or JRS resume object.
 | 
					  @param json A FRESH or JRS resume object.
 | 
				
			||||||
@@ -138,8 +152,8 @@ TemplateGenerator = module.exports = BaseGenerator.extend
 | 
				
			|||||||
  @param cssInfo Needs to be refactored.
 | 
					  @param cssInfo Needs to be refactored.
 | 
				
			||||||
  @param opts Options and passthrough data. ###
 | 
					  @param opts Options and passthrough data. ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  single: ( json, jst, format, opts, theme, curFmt ) ->
 | 
					  transform: ( json, jst, format, opts, theme, curFmt ) ->
 | 
				
			||||||
    if this.opts.freezeBreaks
 | 
					    if @opts.freezeBreaks
 | 
				
			||||||
      jst = freeze jst
 | 
					      jst = freeze jst
 | 
				
			||||||
    eng = require '../renderers/' + theme.engine  + '-generator'
 | 
					    eng = require '../renderers/' + theme.engine  + '-generator'
 | 
				
			||||||
    result = eng.generate json, jst, format, curFmt, opts, theme
 | 
					    result = eng.generate json, jst, format, curFmt, opts, theme
 | 
				
			||||||
@@ -149,9 +163,27 @@ TemplateGenerator = module.exports = BaseGenerator.extend
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###* Export the TemplateGenerator function/ctor. ###
 | 
					createSymLinks = ( curFmt, outFolder ) ->
 | 
				
			||||||
module.exports = TemplateGenerator
 | 
					  # 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 newlines for protection against errant JST parsers. ###
 | 
				
			||||||
@@ -167,6 +199,7 @@ unfreeze = ( markup ) ->
 | 
				
			|||||||
  markup.replace _reg.regSymN, '\n'
 | 
					  markup.replace _reg.regSymN, '\n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###* Default template generator options. ###
 | 
					###* Default template generator options. ###
 | 
				
			||||||
_defaultOpts =
 | 
					_defaultOpts =
 | 
				
			||||||
  engine: 'underscore'
 | 
					  engine: 'underscore'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Definition of the TextGenerator class.
 | 
					Definition of the TextGenerator class.
 | 
				
			||||||
 | 
					@module generators/text-generator
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module text-generator.js
 | 
					 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = require './template-generator'
 | 
					TemplateGenerator = require './template-generator'
 | 
				
			||||||
@@ -9,6 +9,6 @@ TemplateGenerator = require './template-generator'
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
The TextGenerator generates a plain-text resume via the TemplateGenerator.
 | 
					The TextGenerator generates a plain-text resume via the TemplateGenerator.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
TextGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class TextGenerator extends TemplateGenerator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init: () -> @_super 'txt'
 | 
					  constructor: () -> super 'txt'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,12 @@
 | 
				
			|||||||
###
 | 
					###
 | 
				
			||||||
Definition of the WordGenerator class.
 | 
					Definition of the WordGenerator class.
 | 
				
			||||||
@license MIT. See LICENSE.md for details.
 | 
					 | 
				
			||||||
@module generators/word-generator
 | 
					@module generators/word-generator
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemplateGenerator = require './template-generator'
 | 
					TemplateGenerator = require './template-generator'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WordGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class WordGenerator extends TemplateGenerator
 | 
				
			||||||
  init: () -> @_super 'doc', 'xml'
 | 
					
 | 
				
			||||||
 | 
					  constructor: () -> super 'doc', 'xml'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,7 @@ Definition of the XMLGenerator class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
BaseGenerator = require './base-generator'
 | 
					BaseGenerator = require './base-generator'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###* The XmlGenerator generates an XML resume via the TemplateGenerator. ###
 | 
				
			||||||
The XmlGenerator generates an XML resume via the TemplateGenerator.
 | 
					module.exports = class XMLGenerator extends BaseGenerator
 | 
				
			||||||
###
 | 
					
 | 
				
			||||||
XMLGenerator = module.exports = BaseGenerator.extend
 | 
					  constructor: () -> super 'xml'
 | 
				
			||||||
  init: () -> @_super 'xml'
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,5 +11,6 @@ TemplateGenerator = require './template-generator'
 | 
				
			|||||||
YamlGenerator generates a YAML-formatted resume via TemplateGenerator.
 | 
					YamlGenerator generates a YAML-formatted resume via TemplateGenerator.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
YAMLGenerator = module.exports = TemplateGenerator.extend
 | 
					module.exports = class YAMLGenerator extends TemplateGenerator
 | 
				
			||||||
  init: () -> @_super 'yml', 'yml'
 | 
					
 | 
				
			||||||
 | 
					  constructor: () -> super 'yml', 'yml'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								src/helpers/block-helpers.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/helpers/block-helpers.coffee
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					###*
 | 
				
			||||||
 | 
					Block helper definitions for HackMyResume / FluentCV.
 | 
				
			||||||
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
 | 
					@module helpers/generic-helpers
 | 
				
			||||||
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HMSTATUS = require '../core/status-codes'
 | 
				
			||||||
 | 
					LO = require 'lodash'
 | 
				
			||||||
 | 
					_ = require 'underscore'
 | 
				
			||||||
 | 
					unused = require '../utils/string'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###* Block helper function definitions. ###
 | 
				
			||||||
 | 
					BlockHelpers = module.exports =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Emit the enclosed content if the resume has a section with
 | 
				
			||||||
 | 
					  the specified name. Otherwise, emit an empty string ''.
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  section: ( title, options ) ->
 | 
				
			||||||
 | 
					    title = title.trim().toLowerCase()
 | 
				
			||||||
 | 
					    obj = LO.get this.r, title
 | 
				
			||||||
 | 
					    ret = ''
 | 
				
			||||||
 | 
					    if obj
 | 
				
			||||||
 | 
					      if _.isArray obj
 | 
				
			||||||
 | 
					        if obj.length
 | 
				
			||||||
 | 
					          ret = options.fn @
 | 
				
			||||||
 | 
					      else if _.isObject obj
 | 
				
			||||||
 | 
					        if (obj.history && obj.history.length) || (obj.sets && obj.sets.length)
 | 
				
			||||||
 | 
					            ret = options.fn @
 | 
				
			||||||
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Emit the enclosed content if the resume has the named
 | 
				
			||||||
 | 
					  property or subproperty.
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  has: ( title, options ) ->
 | 
				
			||||||
 | 
					    title = title && title.trim().toLowerCase()
 | 
				
			||||||
 | 
					    if LO.get this.r, title
 | 
				
			||||||
 | 
					      return options.fn this
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Return true if either value is truthy.
 | 
				
			||||||
 | 
					  @method either
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					  either: ( lhs, rhs, options ) -> options.fn @ if lhs || rhs    
 | 
				
			||||||
@@ -17,32 +17,95 @@ LO = require 'lodash'
 | 
				
			|||||||
PATH = require 'path'
 | 
					PATH = require 'path'
 | 
				
			||||||
printf = require 'printf'
 | 
					printf = require 'printf'
 | 
				
			||||||
_ = require 'underscore'
 | 
					_ = require 'underscore'
 | 
				
			||||||
unused = require '../utils/string';
 | 
					unused = require '../utils/string'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###* Generic template helper function definitions. ###
 | 
					###* Generic template helper function definitions. ###
 | 
				
			||||||
GenericHelpers = module.exports =
 | 
					GenericHelpers = module.exports =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					 | 
				
			||||||
  Convert the input date to a specified format through Moment.js.
 | 
					 | 
				
			||||||
  If date is invalid, will return the time provided by the user,
 | 
					 | 
				
			||||||
  or default to the fallback param or 'Present' if that is set to true
 | 
					 | 
				
			||||||
  @method formatDate
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  formatDate: (datetime, format, fallback) ->
 | 
					 | 
				
			||||||
    if moment
 | 
					 | 
				
			||||||
      momentDate = moment datetime
 | 
					 | 
				
			||||||
      return momentDate.format(format) if momentDate.isValid()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    datetime || (typeof fallback == 'string' ? fallback : (fallback == true ? 'Present' : null));
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Emit a formatted string representing the specified datetime.
 | 
				
			||||||
 | 
					  Convert the input date to the specified format through Moment.js. If date is
 | 
				
			||||||
 | 
					  valid, return the formatted date string. If date is null, undefined, or other
 | 
				
			||||||
 | 
					  falsy value, return the value of the 'fallback' parameter, if specified, or
 | 
				
			||||||
 | 
					  null if no fallback was specified. If date is invalid, but not null/undefined/
 | 
				
			||||||
 | 
					  falsy, return it as-is.
 | 
				
			||||||
 | 
					  @param {string|Moment} datetime A date value.
 | 
				
			||||||
 | 
					  @param {string} [dtFormat='YYYY-MM'] The desired datetime format. Must be a
 | 
				
			||||||
 | 
					  Moment.js-compatible datetime format.
 | 
				
			||||||
 | 
					  @param {string|Moment} fallback A fallback value to use if the specified date
 | 
				
			||||||
 | 
					  is null, undefined, or falsy.
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					  formatDate: (datetime, dtFormat, fallback) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    datetime ?= undefined
 | 
				
			||||||
 | 
					    dtFormat ?= 'YYYY-MM'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # If a Moment.js object was passed in, just call format on it
 | 
				
			||||||
 | 
					    if datetime and moment.isMoment datetime
 | 
				
			||||||
 | 
					      return datetime.format dtFormat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if String.is datetime
 | 
				
			||||||
 | 
					      # If a string was passed in, convert to Moment using the 2-paramter
 | 
				
			||||||
 | 
					      # constructor with an explicit format string.
 | 
				
			||||||
 | 
					      momentDate = moment datetime, dtFormat
 | 
				
			||||||
 | 
					      return momentDate.format(dtFormat) if momentDate.isValid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # If that didn't work, try again with the single-parameter constructor
 | 
				
			||||||
 | 
					      # but this may throw a deprecation warning
 | 
				
			||||||
 | 
					      momentDate = moment datetime
 | 
				
			||||||
 | 
					      return momentDate.format(dtFormat) if momentDate.isValid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # We weren't able to format the provided datetime. Now do one of three
 | 
				
			||||||
 | 
					    # things.
 | 
				
			||||||
 | 
					    #   1. If datetime is non-null/non-falsy, return it. For this helper,
 | 
				
			||||||
 | 
					    # string date values that we can't parse are assumed to be display dates.
 | 
				
			||||||
 | 
					    #   2. If datetime IS null or falsy, use the value from the fallback.
 | 
				
			||||||
 | 
					    #   3. If the fallback value is specifically 'true', emit 'Present'.
 | 
				
			||||||
 | 
					    datetime ||
 | 
				
			||||||
 | 
					      if typeof fallback == 'string'
 | 
				
			||||||
 | 
					      then fallback
 | 
				
			||||||
 | 
					      else (if fallback == true then 'Present' else '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###*
 | 
				
			||||||
 | 
					  Emit a formatted string representing the specified datetime.
 | 
				
			||||||
 | 
					  @param {string} dateValue A raw date value from the FRESH or JRS resume.
 | 
				
			||||||
 | 
					  @param {string} [dateFormat='YYYY-MM'] The desired datetime format. Must be
 | 
				
			||||||
 | 
					  compatible with Moment.js datetime formats.
 | 
				
			||||||
 | 
					  @param {string} [dateDefault=null] The default date value to use if the dateValue
 | 
				
			||||||
 | 
					  parameter is null, undefined, or falsy.
 | 
				
			||||||
 | 
					  ###
 | 
				
			||||||
 | 
					  date: (dateValue, dateFormat, dateDefault) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dateDefault = 'Current' if !dateDefault or !String.is dateDefault
 | 
				
			||||||
 | 
					    dateFormat = 'YYYY-MM' if !dateFormat or !String.is dateFormat
 | 
				
			||||||
 | 
					    dateValue = null if !dateValue or !String.is dateValue
 | 
				
			||||||
 | 
					    return dateDefault if !dateValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reserved = ['current', 'present', 'now']
 | 
				
			||||||
 | 
					    dateValueSafe = dateValue.trim().toLowerCase();
 | 
				
			||||||
 | 
					    return dateValue if _.contains reserved, dateValueSafe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dateValueMoment = moment dateValue, dateFormat
 | 
				
			||||||
 | 
					    return dateValueMoment.format dateFormat if dateValueMoment.isValid()
 | 
				
			||||||
 | 
					    dateValue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Given a resume sub-object with a start/end date, format a representation of
 | 
					  Given a resume sub-object with a start/end date, format a representation of
 | 
				
			||||||
  the date range.
 | 
					  the date range.
 | 
				
			||||||
  @method dateRange
 | 
					 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
  dateRange: ( obj, fmt, sep, fallback, options ) ->
 | 
					  dateRange: ( obj, fmt, sep, fallback ) ->
 | 
				
			||||||
    return '' if !obj
 | 
					    return '' if !obj
 | 
				
			||||||
    _fromTo obj.start, obj.end, fmt, sep, fallback, options
 | 
					    _fromTo obj.start, obj.end, fmt, sep, fallback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Format a from/to date range for display.
 | 
					  Format a from/to date range for display.
 | 
				
			||||||
@@ -50,6 +113,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  ###
 | 
					  ###
 | 
				
			||||||
  fromTo: () -> _fromTo.apply this, arguments
 | 
					  fromTo: () -> _fromTo.apply this, arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return a named color value as an RRGGBB string.
 | 
					  Return a named color value as an RRGGBB string.
 | 
				
			||||||
  @method toFrom
 | 
					  @method toFrom
 | 
				
			||||||
@@ -66,23 +131,7 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
        return colorDefault
 | 
					        return colorDefault
 | 
				
			||||||
      ret
 | 
					      ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					
 | 
				
			||||||
  Return true if the section is present on the resume and has at least one
 | 
					 | 
				
			||||||
  element.
 | 
					 | 
				
			||||||
  @method section
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  section: ( title, options ) ->
 | 
					 | 
				
			||||||
    title = title.trim().toLowerCase()
 | 
					 | 
				
			||||||
    obj = LO.get this.r, title
 | 
					 | 
				
			||||||
    ret = ''
 | 
					 | 
				
			||||||
    if obj
 | 
					 | 
				
			||||||
      if _.isArray obj
 | 
					 | 
				
			||||||
        if obj.length
 | 
					 | 
				
			||||||
          ret = options.fn @
 | 
					 | 
				
			||||||
      else if _.isObject obj
 | 
					 | 
				
			||||||
        if (obj.history && obj.history.length) || (obj.sets && obj.sets.length)
 | 
					 | 
				
			||||||
            ret = options.fn @
 | 
					 | 
				
			||||||
    ret
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Emit the size of the specified named font.
 | 
					  Emit the size of the specified named font.
 | 
				
			||||||
@@ -133,6 +182,7 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
    ret
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Emit the font face (such as 'Helvetica' or 'Calibri') associated with the
 | 
					  Emit the font face (such as 'Helvetica' or 'Calibri') associated with the
 | 
				
			||||||
  provided key.
 | 
					  provided key.
 | 
				
			||||||
@@ -185,6 +235,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Emit a comma-delimited list of font names suitable associated with the
 | 
					  Emit a comma-delimited list of font names suitable associated with the
 | 
				
			||||||
  provided key.
 | 
					  provided key.
 | 
				
			||||||
@@ -240,28 +292,21 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Capitalize the first letter of the word.
 | 
					  Capitalize the first letter of the word. TODO: Rename
 | 
				
			||||||
  @method section
 | 
					  @method section
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
  camelCase: (val) ->
 | 
					  camelCase: (val) ->
 | 
				
			||||||
    val = (val && val.trim()) || ''
 | 
					    val = (val && val.trim()) || ''
 | 
				
			||||||
    return if val then (val.charAt(0).toUpperCase() + val.slice(1)) else val
 | 
					    return if val then (val.charAt(0).toUpperCase() + val.slice(1)) else val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					
 | 
				
			||||||
  Return true if the context has the property or subpropery.
 | 
					 | 
				
			||||||
  @method has
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  has: ( title, options ) ->
 | 
					 | 
				
			||||||
    title = title && title.trim().toLowerCase()
 | 
					 | 
				
			||||||
    if LO.get this.r, title
 | 
					 | 
				
			||||||
      return options.fn this
 | 
					 | 
				
			||||||
    return
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Generic template helper function to display a user-overridable section
 | 
					  Display a user-overridable section title for a FRESH resume theme. Use this in
 | 
				
			||||||
  title for a FRESH resume theme. Use this in lieue of hard-coding section
 | 
					  lieue of hard-coding section titles.
 | 
				
			||||||
  titles.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Usage:
 | 
					  Usage:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -291,10 +336,9 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
      this.opts.stitles[ sname.toLowerCase().trim() ] ) ||
 | 
					      this.opts.stitles[ sname.toLowerCase().trim() ] ) ||
 | 
				
			||||||
      stitle;
 | 
					      stitle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					
 | 
				
			||||||
  Convert inline Markdown to inline WordProcessingML.
 | 
					
 | 
				
			||||||
  @method wpml
 | 
					  ###* Convert inline Markdown to inline WordProcessingML. ###
 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  wpml: ( txt, inline ) ->
 | 
					  wpml: ( txt, inline ) ->
 | 
				
			||||||
    return '' if !txt
 | 
					    return '' if !txt
 | 
				
			||||||
    inline = (inline && !inline.hash) || false
 | 
					    inline = (inline && !inline.hash) || false
 | 
				
			||||||
@@ -304,6 +348,7 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
    return txt
 | 
					    return txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Emit a conditional link.
 | 
					  Emit a conditional link.
 | 
				
			||||||
  @method link
 | 
					  @method link
 | 
				
			||||||
@@ -311,6 +356,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  link: ( text, url ) ->
 | 
					  link: ( text, url ) ->
 | 
				
			||||||
    return if url && url.trim() then ('<a href="' + url + '">' + text + '</a>') else text
 | 
					    return if url && url.trim() then ('<a href="' + url + '">' + text + '</a>') else text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return the last word of the specified text.
 | 
					  Return the last word of the specified text.
 | 
				
			||||||
  @method lastWord
 | 
					  @method lastWord
 | 
				
			||||||
@@ -318,6 +365,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  lastWord: ( txt ) ->
 | 
					  lastWord: ( txt ) ->
 | 
				
			||||||
    return if txt && txt.trim() then _.last( txt.split(' ') ) else ''
 | 
					    return if txt && txt.trim() then _.last( txt.split(' ') ) else ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Convert a skill level to an RGB color triplet. TODO: refactor
 | 
					  Convert a skill level to an RGB color triplet. TODO: refactor
 | 
				
			||||||
  @method skillColor
 | 
					  @method skillColor
 | 
				
			||||||
@@ -333,6 +382,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
      [ '#FFFFFF', '#5CB85C', '#F1C40F', '#428BCA', '#C00000' ]
 | 
					      [ '#FFFFFF', '#5CB85C', '#F1C40F', '#428BCA', '#C00000' ]
 | 
				
			||||||
    return skillColors[idx]
 | 
					    return skillColors[idx]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return an appropriate height. TODO: refactor
 | 
					  Return an appropriate height. TODO: refactor
 | 
				
			||||||
  @method lastWord
 | 
					  @method lastWord
 | 
				
			||||||
@@ -341,6 +392,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
    idx = skillLevelToIndex lvl
 | 
					    idx = skillLevelToIndex lvl
 | 
				
			||||||
    ['38.25', '30', '16', '8', '0'][idx]
 | 
					    ['38.25', '30', '16', '8', '0'][idx]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return all but the last word of the input text.
 | 
					  Return all but the last word of the input text.
 | 
				
			||||||
  @method initialWords
 | 
					  @method initialWords
 | 
				
			||||||
@@ -348,6 +401,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  initialWords: ( txt ) ->
 | 
					  initialWords: ( txt ) ->
 | 
				
			||||||
    if txt && txt.trim() then _.initial( txt.split(' ') ).join(' ') else ''
 | 
					    if txt && txt.trim() then _.initial( txt.split(' ') ).join(' ') else ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Trim the protocol (http or https) from a URL/
 | 
					  Trim the protocol (http or https) from a URL/
 | 
				
			||||||
  @method trimURL
 | 
					  @method trimURL
 | 
				
			||||||
@@ -355,27 +410,23 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  trimURL: ( url ) ->
 | 
					  trimURL: ( url ) ->
 | 
				
			||||||
    if url && url.trim() then url.trim().replace(/^https?:\/\//i, '') else ''
 | 
					    if url && url.trim() then url.trim().replace(/^https?:\/\//i, '') else ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					
 | 
				
			||||||
  Convert text to lowercase.
 | 
					 | 
				
			||||||
  @method toLower
 | 
					 | 
				
			||||||
  ###
 | 
					 | 
				
			||||||
  toLower: ( txt ) ->
 | 
					 | 
				
			||||||
    if txt && txt.trim() then txt.toLowerCase() else ''
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Convert text to lowercase.
 | 
					  Convert text to lowercase.
 | 
				
			||||||
  @method toLower
 | 
					  @method toLower
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
  toUpper: ( txt ) ->
 | 
					  toLower: ( txt ) -> if txt && txt.trim() then txt.toLowerCase() else ''
 | 
				
			||||||
    if txt && txt.trim() then txt.toUpperCase() else ''
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Return true if either value is truthy.
 | 
					  Convert text to lowercase.
 | 
				
			||||||
  @method either
 | 
					  @method toLower
 | 
				
			||||||
  ###
 | 
					  ###
 | 
				
			||||||
  either: ( lhs, rhs, options ) ->
 | 
					  toUpper: ( txt ) -> if txt && txt.trim() then txt.toUpperCase() else ''
 | 
				
			||||||
    if lhs || rhs
 | 
					
 | 
				
			||||||
      return options.fn this
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Conditional stylesheet link. Creates a link to the specified stylesheet with
 | 
					  Conditional stylesheet link. Creates a link to the specified stylesheet with
 | 
				
			||||||
@@ -413,6 +464,8 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
    # it when Handlebars is the chosen engine, which is most of the time.
 | 
					    # it when Handlebars is the chosen engine, which is most of the time.
 | 
				
			||||||
    ret
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###*
 | 
					  ###*
 | 
				
			||||||
  Perform a generic comparison.
 | 
					  Perform a generic comparison.
 | 
				
			||||||
  See: http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates
 | 
					  See: http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates
 | 
				
			||||||
@@ -420,7 +473,7 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
  ###
 | 
					  ###
 | 
				
			||||||
  compare: (lvalue, rvalue, options) ->
 | 
					  compare: (lvalue, rvalue, options) ->
 | 
				
			||||||
    if arguments.length < 3
 | 
					    if arguments.length < 3
 | 
				
			||||||
      throw new Error("Handlerbars Helper 'compare' needs 2 parameters")
 | 
					      throw new Error "Template helper 'compare' needs 2 parameters"
 | 
				
			||||||
    operator = options.hash.operator || "=="
 | 
					    operator = options.hash.operator || "=="
 | 
				
			||||||
    operators =
 | 
					    operators =
 | 
				
			||||||
        '==':       (l,r) -> l == r
 | 
					        '==':       (l,r) -> l == r
 | 
				
			||||||
@@ -432,12 +485,27 @@ GenericHelpers = module.exports =
 | 
				
			|||||||
        '>=':       (l,r) -> l >= r
 | 
					        '>=':       (l,r) -> l >= r
 | 
				
			||||||
        'typeof':   (l,r) -> typeof l == r
 | 
					        'typeof':   (l,r) -> typeof l == r
 | 
				
			||||||
    if !operators[operator]
 | 
					    if !operators[operator]
 | 
				
			||||||
      throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator)
 | 
					      throw new Error("Helper 'compare' doesn't know the operator "+operator)
 | 
				
			||||||
    result = operators[operator]( lvalue, rvalue )
 | 
					    result = operators[operator]( lvalue, rvalue )
 | 
				
			||||||
    return if result then options.fn(this) else options.inverse(this)
 | 
					    return if result then options.fn(this) else options.inverse(this)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pad: (stringOrArray, padAmount, unused ) ->
 | 
				
			||||||
 | 
					    stringOrArray = stringOrArray || ''
 | 
				
			||||||
 | 
					    padAmount = padAmount || 0
 | 
				
			||||||
 | 
					    ret = ''
 | 
				
			||||||
 | 
					    PAD = require 'string-padding'
 | 
				
			||||||
 | 
					    if !String.is stringOrArray
 | 
				
			||||||
 | 
					      ret = stringOrArray
 | 
				
			||||||
 | 
					        .map (line) -> PAD line, line.length + Math.abs(padAmount), null, if padAmount < 0 then PAD.LEFT else PAD.RIGHT
 | 
				
			||||||
 | 
					        .join '\n'
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      ret = PAD stringOrArray, stringOrArray.length + Math.abs(padAmount), null, if padAmount < 0 then PAD.LEFT else PAD.RIGHT
 | 
				
			||||||
 | 
					    ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Report an error to the outside world without throwing an exception. Currently
 | 
					Report an error to the outside world without throwing an exception. Currently
 | 
				
			||||||
relies on kludging the running verb into. opts.
 | 
					relies on kludging the running verb into. opts.
 | 
				
			||||||
@@ -445,6 +513,8 @@ relies on kludging the running verb into. opts.
 | 
				
			|||||||
_reportError = ( code, params ) ->
 | 
					_reportError = ( code, params ) ->
 | 
				
			||||||
  GenericHelpers.opts.errHandler.err( code, params )
 | 
					  GenericHelpers.opts.errHandler.err( code, params )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Format a from/to date range for display.
 | 
					Format a from/to date range for display.
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
@@ -476,7 +546,7 @@ _fromTo = ( dateA, dateB, fmt, sep, fallback ) ->
 | 
				
			|||||||
    dateFrom = dateTemp.format( fmt )
 | 
					    dateFrom = dateTemp.format( fmt )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if _.contains( reserved, dateBTrim )
 | 
					  if _.contains( reserved, dateBTrim )
 | 
				
			||||||
    dateTo = fallback || 'Current'
 | 
					    dateTo = fallback || 'Present'
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    dateTemp = FluentDate.fmt( dateB )
 | 
					    dateTemp = FluentDate.fmt( dateB )
 | 
				
			||||||
    dateTo = dateTemp.format( fmt )
 | 
					    dateTo = dateTemp.format( fmt )
 | 
				
			||||||
@@ -487,6 +557,8 @@ _fromTo = ( dateA, dateB, fmt, sep, fallback ) ->
 | 
				
			|||||||
    return dateFrom || dateTo
 | 
					    return dateFrom || dateTo
 | 
				
			||||||
  return ''
 | 
					  return ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
skillLevelToIndex = ( lvl ) ->
 | 
					skillLevelToIndex = ( lvl ) ->
 | 
				
			||||||
  idx = 0
 | 
					  idx = 0
 | 
				
			||||||
  if String.is( lvl )
 | 
					  if String.is( lvl )
 | 
				
			||||||
@@ -507,6 +579,7 @@ skillLevelToIndex = ( lvl ) ->
 | 
				
			|||||||
  idx
 | 
					  idx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Note [1] --------------------------------------------------------------------
 | 
					# Note [1] --------------------------------------------------------------------
 | 
				
			||||||
# Make sure it's precisely a string or array since some template engines jam
 | 
					# Make sure it's precisely a string or array since some template engines jam
 | 
				
			||||||
# their options/context object into the last parameter and we are allowing the
 | 
					# their options/context object into the last parameter and we are allowing the
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Template helper definitions for Handlebars.
 | 
					Template helper definitions for Handlebars.
 | 
				
			||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module handlebars-helpers.js
 | 
					@module handlebars-helpers.js
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HANDLEBARS = require 'handlebars'
 | 
					HANDLEBARS = require 'handlebars'
 | 
				
			||||||
_ = require 'underscore'
 | 
					_ = require 'underscore'
 | 
				
			||||||
helpers = require './generic-helpers'
 | 
					helpers = require './generic-helpers'
 | 
				
			||||||
 | 
					blockHelpers = require './block-helpers'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Register useful Handlebars helpers.
 | 
					Register useful Handlebars helpers.
 | 
				
			||||||
@@ -15,6 +16,21 @@ Register useful Handlebars helpers.
 | 
				
			|||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = ( theme, opts ) ->
 | 
					module.exports = ( theme, opts ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  helpers.theme = theme
 | 
					  helpers.theme = theme
 | 
				
			||||||
  helpers.opts = opts
 | 
					  helpers.opts = opts
 | 
				
			||||||
  HANDLEBARS.registerHelper helpers
 | 
					  helpers.type = 'handlebars'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  wrappedHelpers = _.mapObject helpers, ( hVal, hKey ) ->
 | 
				
			||||||
 | 
					    if _.isFunction hVal
 | 
				
			||||||
 | 
					      _.wrap hVal, (func) ->
 | 
				
			||||||
 | 
					        args = Array.prototype.slice.call arguments
 | 
				
			||||||
 | 
					        args.shift() # lose the 1st element (func)
 | 
				
			||||||
 | 
					        args.pop() # lose the last element (the Handlebars options hash)
 | 
				
			||||||
 | 
					        func.apply @, args
 | 
				
			||||||
 | 
					    hVal
 | 
				
			||||||
 | 
					  , @
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  HANDLEBARS.registerHelper wrappedHelpers
 | 
				
			||||||
 | 
					  HANDLEBARS.registerHelper blockHelpers
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,17 @@
 | 
				
			|||||||
###*
 | 
					###*
 | 
				
			||||||
Template helper definitions for Underscore.
 | 
					Template helper definitions for Underscore.
 | 
				
			||||||
@license MIT. Copyright (c) 2016 hacksalot (https://github.com/hacksalot)
 | 
					@license MIT. See LICENSE.md for details.
 | 
				
			||||||
@module handlebars-helpers.js
 | 
					@module handlebars-helpers.js
 | 
				
			||||||
###
 | 
					###
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HANDLEBARS = require('handlebars')
 | 
					HANDLEBARS = require('handlebars')
 | 
				
			||||||
_ = require('underscore')
 | 
					_ = require('underscore')
 | 
				
			||||||
helpers = require('./generic-helpers')
 | 
					helpers = require('./generic-helpers')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Register useful Underscore helpers.
 | 
					Register useful Underscore helpers.
 | 
				
			||||||
@method registerHelpers
 | 
					@method registerHelpers
 | 
				
			||||||
@@ -22,3 +26,4 @@ module.exports = ( theme, opts, cssInfo, ctx, eng ) ->
 | 
				
			|||||||
    if _.isFunction hVal
 | 
					    if _.isFunction hVal
 | 
				
			||||||
      _.bind hVal, ctx
 | 
					      _.bind hVal, ctx
 | 
				
			||||||
  , @
 | 
					  , @
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,9 @@ External API surface for HackMyResume.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###* API facade for HackMyResume. ###
 | 
				
			||||||
API facade for HackMyCore.
 | 
					 | 
				
			||||||
###
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
HackMyCore = module.exports =
 | 
					module.exports =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  verbs:
 | 
					  verbs:
 | 
				
			||||||
    build:              require './verbs/build'
 | 
					    build:              require './verbs/build'
 | 
				
			||||||
@@ -31,6 +29,7 @@ HackMyCore = module.exports =
 | 
				
			|||||||
  JRSResume:            require './core/jrs-resume'
 | 
					  JRSResume:            require './core/jrs-resume'
 | 
				
			||||||
  FRESHTheme:           require './core/fresh-theme'
 | 
					  FRESHTheme:           require './core/fresh-theme'
 | 
				
			||||||
  JRSTheme:             require './core/jrs-theme'
 | 
					  JRSTheme:             require './core/jrs-theme'
 | 
				
			||||||
 | 
					  ResumeFactory:        require './core/resume-factory'
 | 
				
			||||||
  FluentDate:           require './core/fluent-date'
 | 
					  FluentDate:           require './core/fluent-date'
 | 
				
			||||||
  HtmlGenerator:        require './generators/html-generator'
 | 
					  HtmlGenerator:        require './generators/html-generator'
 | 
				
			||||||
  TextGenerator:        require './generators/text-generator'
 | 
					  TextGenerator:        require './generators/text-generator'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,8 @@ HandlebarsGenerator = module.exports =
 | 
				
			|||||||
      return template data
 | 
					      return template data
 | 
				
			||||||
    catch
 | 
					    catch
 | 
				
			||||||
      throw
 | 
					      throw
 | 
				
			||||||
        fluenterror: if template then HMSTATUS.invokeTemplate else HMSTATUS.compileTemplate
 | 
					        fluenterror:
 | 
				
			||||||
 | 
					          HMSTATUS[ if template then 'invokeTemplate' else 'compileTemplate' ]
 | 
				
			||||||
        inner: _error
 | 
					        inner: _error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,9 +25,10 @@ JRSGenerator = module.exports =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Disable JRS theme chatter (console.log, console.error, etc.)
 | 
					    # Disable JRS theme chatter (console.log, console.error, etc.)
 | 
				
			||||||
    turnoff = ['log', 'error', 'dir'];
 | 
					    turnoff = ['log', 'error', 'dir'];
 | 
				
			||||||
    org = turnoff.map(c) ->
 | 
					    org = turnoff.map (c) ->
 | 
				
			||||||
      ret = console[c]
 | 
					      ret = console[c]
 | 
				
			||||||
      console[c] = () ->
 | 
					      console[c] = () ->
 | 
				
			||||||
 | 
					      ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Freeze and render
 | 
					    # Freeze and render
 | 
				
			||||||
    rezHtml = theme.render json.harden()
 | 
					    rezHtml = theme.render json.harden()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,8 @@ Definition of the UnderscoreGenerator class.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
_ = require 'underscore'
 | 
					_ = require 'underscore'
 | 
				
			||||||
registerHelpers = require '../helpers/underscore-helpers'
 | 
					registerHelpers = require '../helpers/underscore-helpers'
 | 
				
			||||||
HMSTATUS = require '../core/status-codes'
 | 
					require '../utils/string'
 | 
				
			||||||
 | 
					escapeLaTeX = require 'escape-latex'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
###*
 | 
					###*
 | 
				
			||||||
Perform template-based resume generation using Underscore.js.
 | 
					Perform template-based resume generation using Underscore.js.
 | 
				
			||||||
@@ -17,36 +17,57 @@ Perform template-based resume generation using Underscore.js.
 | 
				
			|||||||
###
 | 
					###
 | 
				
			||||||
UnderscoreGenerator = module.exports =
 | 
					UnderscoreGenerator = module.exports =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  generateSimple: ( data, tpl ) ->
 | 
					  generateSimple: ( data, tpl ) ->
 | 
				
			||||||
    try
 | 
					    try
 | 
				
			||||||
      # Compile and run the Handlebars template.
 | 
					      # Compile and run the Handlebars template.
 | 
				
			||||||
      template = _.template( tpl );
 | 
					      t = _.template tpl
 | 
				
			||||||
      return template( data );
 | 
					      t data
 | 
				
			||||||
    catch
 | 
					    catch
 | 
				
			||||||
 | 
					      #console.dir _error
 | 
				
			||||||
 | 
					      HMS = require '../core/status-codes'
 | 
				
			||||||
      throw
 | 
					      throw
 | 
				
			||||||
        fluenterror: if template then HMSTATUS.invokeTemplate else HMSTATUS.compileTemplate,
 | 
					        fluenterror: HMS[if t then 'invokeTemplate' else 'compileTemplate']
 | 
				
			||||||
        inner: _error
 | 
					        inner: _error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  generate: ( json, jst, format, cssInfo, opts, theme ) ->
 | 
					  generate: ( json, jst, format, cssInfo, opts, theme ) ->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Tweak underscore's default template delimeters
 | 
					    # Tweak underscore's default template delimeters
 | 
				
			||||||
    delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
 | 
					    delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
 | 
				
			||||||
    if opts.themeObj && opts.themeObj.delimeters
 | 
					    if opts.themeObj && opts.themeObj.delimeters
 | 
				
			||||||
      delims = _.mapObject delims, (val,key) -> new RegExp( val, "ig")
 | 
					      delims = _.mapObject delims, (val,key) -> new RegExp val, "ig"
 | 
				
			||||||
    _.templateSettings = delims;
 | 
					    _.templateSettings = delims;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Strip {# comments #}
 | 
					    # Massage resume strings / text
 | 
				
			||||||
    jst = jst.replace delims.comment, ''
 | 
					    r = null
 | 
				
			||||||
 | 
					    switch format
 | 
				
			||||||
 | 
					      when 'html' then r = json.markdownify()
 | 
				
			||||||
 | 
					      when 'pdf' then r = json.markdownify()
 | 
				
			||||||
 | 
					      when 'png' then r = json.markdownify()
 | 
				
			||||||
 | 
					      when 'latex'
 | 
				
			||||||
 | 
					        traverse = require 'traverse'
 | 
				
			||||||
 | 
					        r = traverse(json).map (x) ->
 | 
				
			||||||
 | 
					          if @isLeaf && String.is @node
 | 
				
			||||||
 | 
					            return escapeLaTeX @node
 | 
				
			||||||
 | 
					          @node
 | 
				
			||||||
 | 
					      else r = json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Set up the context
 | 
				
			||||||
    ctx =
 | 
					    ctx =
 | 
				
			||||||
      r: if format == 'html' || format == 'pdf' || format == 'png' then json.markdownify() else json
 | 
					      r: r
 | 
				
			||||||
      filt: opts.filters
 | 
					      filt: opts.filters
 | 
				
			||||||
      XML: require 'xml-escape'
 | 
					      XML: require 'xml-escape'
 | 
				
			||||||
      RAW: json
 | 
					      RAW: json
 | 
				
			||||||
      cssInfo: cssInfo
 | 
					      cssInfo: cssInfo
 | 
				
			||||||
      #engine: this
 | 
					      #engine: @
 | 
				
			||||||
      headFragment: opts.headFragment || ''
 | 
					      headFragment: opts.headFragment || ''
 | 
				
			||||||
      opts: opts
 | 
					      opts: opts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    registerHelpers theme, opts, cssInfo, ctx, this
 | 
					    # Link to our helpers
 | 
				
			||||||
 | 
					    registerHelpers theme, opts, cssInfo, ctx, @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Generate!
 | 
				
			||||||
    @generateSimple ctx, jst
 | 
					    @generateSimple ctx, jst
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user