mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-23 00:40:10 +00:00
Merge remote-tracking branch 'refs/remotes/origin/dev'
This commit is contained in:
commit
5bc8b9c987
58
CONTRIBUTING.md
Normal file
58
CONTRIBUTING.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
*Note: HackMyResume is also available as [FluentCV][fcv]. Contributors are
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
HackMyResume without clearing it with us — but helps avoid duplication of work
|
||||||
|
and ensures that your changes will be accepted once submitted.
|
||||||
|
2. **Fork and clone** the HackMyResume project.
|
||||||
|
3. Ideally, **create a new feature branch** (eg, `feat/new-awesome-feature` or
|
||||||
|
similar; call it whatever you like) to perform your work in.
|
||||||
|
4. **Install dependencies** by running `npm install` in the top-level
|
||||||
|
HackMyResume folder.
|
||||||
|
5. Make your **commits** as usual.
|
||||||
|
6. **Verify** your changes locally with `npm test`.
|
||||||
|
7. **Push** your commits.
|
||||||
|
7. **Submit a pull request** from your feature branch to the HackMyResume `dev`
|
||||||
|
branch.
|
||||||
|
8. We'll typically **respond** within 24 hours.
|
||||||
|
9. Your awesome changes will be **merged** after verification.
|
||||||
|
|
||||||
|
## Project Maintainers
|
||||||
|
|
||||||
|
HackMyResume is currently maintained by [hacksalot][ha] with assistance from
|
||||||
|
[tomheon][th] and our awesome [contributors][awesome]. Please direct all official
|
||||||
|
or internal inquiries to:
|
||||||
|
|
||||||
|
```
|
||||||
|
admin@hackmyresume.com
|
||||||
|
```
|
||||||
|
|
||||||
|
You can reach hacksalot directly at:
|
||||||
|
|
||||||
|
```
|
||||||
|
hacksalot@indevious.com
|
||||||
|
```
|
||||||
|
|
||||||
|
Thanks! See you out there in the trenches.
|
||||||
|
|
||||||
|
[fcv]: https://github.com/fluentdesk/fluentcv
|
||||||
|
[flow]: https://guides.github.com/introduction/flow/
|
||||||
|
[iss]: https://github.com/hacksalot/HackMyResume/issues
|
||||||
|
[ha]: https://github.com/hacksalot
|
||||||
|
[th]: https://github.com/tomheon
|
||||||
|
[awesome]: https://github.com/hacksalot/HackMyResume/graphs/contributors
|
10
Gruntfile.js
10
Gruntfile.js
@ -14,10 +14,10 @@ module.exports = function (grunt) {
|
|||||||
ui: 'bdd',
|
ui: 'bdd',
|
||||||
reporter: 'spec'
|
reporter: 'spec'
|
||||||
},
|
},
|
||||||
all: { src: ['tests/*.js'] }
|
all: { src: ['test/*.js'] }
|
||||||
},
|
},
|
||||||
|
|
||||||
clean: ['tests/sandbox'],
|
clean: ['test/sandbox'],
|
||||||
|
|
||||||
yuidoc: {
|
yuidoc: {
|
||||||
compile: {
|
compile: {
|
||||||
@ -38,7 +38,7 @@ module.exports = function (grunt) {
|
|||||||
laxcomma: true,
|
laxcomma: true,
|
||||||
expr: true
|
expr: true
|
||||||
},
|
},
|
||||||
all: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js']
|
all: ['Gruntfile.js', 'src/**/*.js', 'test/*.js']
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -51,9 +51,9 @@ module.exports = function (grunt) {
|
|||||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||||
|
|
||||||
grunt.registerTask('test', 'Test the HackMyResume library.',
|
grunt.registerTask('test', 'Test the HackMyResume library.',
|
||||||
function( config ) { grunt.task.run( ['clean','simplemocha:all'] ); });
|
function( config ) { grunt.task.run( ['clean','jshint','simplemocha:all'] ); });
|
||||||
grunt.registerTask('document', 'Generate HackMyResume library documentation.',
|
grunt.registerTask('document', 'Generate HackMyResume library documentation.',
|
||||||
function( config ) { grunt.task.run( ['yuidoc'] ); });
|
function( config ) { grunt.task.run( ['yuidoc'] ); });
|
||||||
grunt.registerTask('default', [ 'jshint', 'test', 'yuidoc' ]);
|
grunt.registerTask('default', [ 'test', 'yuidoc' ]);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
102
README.md
102
README.md
@ -32,6 +32,7 @@ or Windows.
|
|||||||
- Support for multiple input and output resumes.
|
- Support for multiple input and output resumes.
|
||||||
- Use from your command line or [desktop][7].
|
- Use from your command line or [desktop][7].
|
||||||
- Free and open-source through the MIT license.
|
- Free and open-source through the MIT license.
|
||||||
|
- Updated daily.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@ -42,8 +43,36 @@ Install HackMyResume with NPM:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note: for PDF generation you'll need to install a copy of [wkhtmltopdf][3] for
|
Note: for PDF generation you'll need to install a copy of [wkhtmltopdf][3] for
|
||||||
your platform. For LaTeX generation you'll need a valid LaTeX environment with
|
your platform.
|
||||||
access to `xelatex` and similar.
|
|
||||||
|
## Installing Themes
|
||||||
|
|
||||||
|
HackMyResume supports both [FRESH][fresh-themes] and [JSON Resume][jrst]-style
|
||||||
|
résumé themes.
|
||||||
|
|
||||||
|
- FRESH themes currently come preinstalled with HackMyResume.
|
||||||
|
- JSON Resume themes can be installed from NPM, GitHub, or manually.
|
||||||
|
|
||||||
|
To install a JSON Resume theme, just `cd` to the folder where you want to store
|
||||||
|
your themes and run one of:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install with NPM
|
||||||
|
npm install jsonresume-theme-[theme-name]
|
||||||
|
|
||||||
|
# Install with GitHub
|
||||||
|
git clone https://github.com/[user-or-org]/[repo-name]
|
||||||
|
```
|
||||||
|
|
||||||
|
Then when you're ready to generate your resume, just reference the location of
|
||||||
|
the theme folder as you installed it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hackmyresume BUILD resume.json TO out/resume.all -t node_modules/jsonresume-theme-classy
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: You can use install themes anywhere on your file system. You don't need a
|
||||||
|
package.json or other NPM/Node infrastructure.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@ -98,9 +127,9 @@ Output Format | Ext | Notes
|
|||||||
------------- | --- | -----
|
------------- | --- | -----
|
||||||
HTML | .html | A standard HTML 5 + CSS resume format that can be viewed in a browser, deployed to a website, etc.
|
HTML | .html | A standard HTML 5 + CSS resume format that can be viewed in a browser, deployed to a website, etc.
|
||||||
Markdown | .md | A structured Markdown document that can be used as-is or used to generate HTML.
|
Markdown | .md | A structured Markdown document that can be used as-is or used to generate HTML.
|
||||||
LaTeX | .tex | A structured LaTeX document (or collection of documents).
|
LaTeX | .tex | A structured LaTeX document (or collection of documents) that can be processed with pdflatex, xelatex, and similar tools.
|
||||||
MS Word | .doc | A Microsoft Word office document.
|
MS Word | .doc | A Microsoft Word office document (XML-driven; WordProcessingML).
|
||||||
Adobe Acrobat (PDF) | .pdf | A binary PDF document driven by an HTML theme.
|
Adobe Acrobat (PDF) | .pdf | A binary PDF document driven by an HTML theme (through wkhtmltopdf).
|
||||||
plain text | .txt | A formatted plain text document appropriate for emails or copy-paste.
|
plain text | .txt | A formatted plain text document appropriate for emails or copy-paste.
|
||||||
JSON | .json | A JSON representation of the resume.
|
JSON | .json | A JSON representation of the resume.
|
||||||
YAML | .yml | A YAML representation of the resume.
|
YAML | .yml | A YAML representation of the resume.
|
||||||
@ -108,15 +137,6 @@ RTF | .rtf | Forthcoming.
|
|||||||
Textile | .textile | Forthcoming.
|
Textile | .textile | Forthcoming.
|
||||||
image | .png, .bmp | Forthcoming.
|
image | .png, .bmp | Forthcoming.
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
HackMyResume requires a recent version of [Node.js][4] and [NPM][5]. Then:
|
|
||||||
|
|
||||||
1. Install the latest official [wkhtmltopdf][3] binary for your platform.
|
|
||||||
2. Optionally install an updated LaTeX environment (LaTeX resumes only).
|
|
||||||
2. Install **HackMyResume** with `[sudo] npm install hackmyresume -g`.
|
|
||||||
3. You're ready to go.
|
|
||||||
|
|
||||||
## Use
|
## Use
|
||||||
|
|
||||||
Assuming you've got a JSON-formatted resume handy, generating resumes in
|
Assuming you've got a JSON-formatted resume handy, generating resumes in
|
||||||
@ -132,19 +152,19 @@ theme (default to Modern). For example:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate all resume formats (HTML, PDF, DOC, TXT, YML, etc.)
|
# Generate all resume formats (HTML, PDF, DOC, TXT, YML, etc.)
|
||||||
hackmyresume build resume.json -o out/resume.all -t modern
|
hackmyresume BUILD resume.json TO out/resume.all -t modern
|
||||||
|
|
||||||
# Generate a specific resume format
|
# Generate a specific resume format
|
||||||
hackmyresume build resume.json TO out/resume.html
|
hackmyresume BUILD resume.json TO out/resume.html
|
||||||
hackmyresume build resume.json TO out/resume.pdf
|
hackmyresume BUILD resume.json TO out/resume.pdf
|
||||||
hackmyresume build resume.json TO out/resume.md
|
hackmyresume BUILD resume.json TO out/resume.md
|
||||||
hackmyresume build resume.json TO out/resume.doc
|
hackmyresume BUILD resume.json TO out/resume.doc
|
||||||
hackmyresume build resume.json TO out/resume.json
|
hackmyresume BUILD resume.json TO out/resume.json
|
||||||
hackmyresume build resume.json TO out/resume.txt
|
hackmyresume BUILD resume.json TO out/resume.txt
|
||||||
hackmyresume build resume.json TO out/resume.yml
|
hackmyresume BUILD resume.json TO out/resume.yml
|
||||||
|
|
||||||
# Specify 2 inputs and 3 outputs
|
# Specify 2 inputs and 3 outputs
|
||||||
hackmyresume build in1.json in2.json TO out.html out.doc out.pdf
|
hackmyresume BUILD in1.json in2.json TO out.html out.doc out.pdf
|
||||||
```
|
```
|
||||||
|
|
||||||
You should see something to the effect of:
|
You should see something to the effect of:
|
||||||
@ -171,8 +191,8 @@ For a predefined theme, include the theme name. For a custom theme, include the
|
|||||||
path to the custom theme's folder.
|
path to the custom theme's folder.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hackmyresume build resume.json -t modern
|
hackmyresume BUILD resume.json TO out/rez.all -t modern
|
||||||
hackmyresume build resume.json -t ~/foo/bar/my-custom-theme/
|
hackmyresume BUILD resume.json TO OUT.rez.all -t ~/foo/bar/my-custom-theme/
|
||||||
```
|
```
|
||||||
|
|
||||||
As of v1.0.0, available predefined themes are `positive`, `modern`, `compact`,
|
As of v1.0.0, available predefined themes are `positive`, `modern`, `compact`,
|
||||||
@ -185,7 +205,7 @@ most generic to most specific:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Merge specific.json onto base.json and generate all formats
|
# Merge specific.json onto base.json and generate all formats
|
||||||
hackmyresume build base.json specific.json -o resume.all
|
hackmyresume BUILD base.json specific.json TO resume.all
|
||||||
```
|
```
|
||||||
|
|
||||||
This can be useful for overriding a base (generic) resume with information from
|
This can be useful for overriding a base (generic) resume with information from
|
||||||
@ -196,7 +216,7 @@ resume. Merging follows conventional [extend()][9]-style behavior and there's
|
|||||||
no arbitrary limit to how many resumes you can merge:
|
no arbitrary limit to how many resumes you can merge:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hackmyresume build in1.json in2.json in3.json in4.json TO out.html out.doc
|
hackmyresume BUILD in1.json in2.json in3.json in4.json TO out.html out.doc
|
||||||
Reading JSON resume: in1.json
|
Reading JSON resume: in1.json
|
||||||
Reading JSON resume: in2.json
|
Reading JSON resume: in2.json
|
||||||
Reading JSON resume: in3.json
|
Reading JSON resume: in3.json
|
||||||
@ -212,14 +232,7 @@ You can specify **multiple output targets** and HackMyResume will build them:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate out1.doc, out1.pdf, and foo.txt from me.json.
|
# Generate out1.doc, out1.pdf, and foo.txt from me.json.
|
||||||
hackmyresume build me.json -o out1.doc -o out1.pdf -o foo.txt
|
hackmyresume BUILD me.json TO out1.doc out1.pdf foo.txt
|
||||||
```
|
|
||||||
|
|
||||||
You can also omit the output file(s) and/or theme completely:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Equivalent to "hackmyresume resume.json resume.all -t modern"
|
|
||||||
hackmyresume build resume.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using .all
|
### Using .all
|
||||||
@ -229,7 +242,7 @@ formats for the given resume. For example, this...
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate all resume formats (HTML, PDF, DOC, TXT, etc.)
|
# Generate all resume formats (HTML, PDF, DOC, TXT, etc.)
|
||||||
hackmyresume build me.json -o out/resume.all
|
hackmyresume BUILD me.json TO out/resume.all
|
||||||
```
|
```
|
||||||
|
|
||||||
..tells HackMyResume to read `me.json` and generate `out/resume.md`,
|
..tells HackMyResume to read `me.json` and generate `out/resume.md`,
|
||||||
@ -244,7 +257,7 @@ resumes, use the `validate` command:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Validate myresume.json against either the FRESH or JSON Resume schema.
|
# Validate myresume.json against either the FRESH or JSON Resume schema.
|
||||||
hackmyresume validate resumeA.json resumeB.json
|
hackmyresume VALIDATE resumeA.json resumeB.json
|
||||||
```
|
```
|
||||||
|
|
||||||
HackMyResume will validate each specified resume in turn:
|
HackMyResume will validate each specified resume in turn:
|
||||||
@ -276,7 +289,7 @@ HTML-formatted resumes. To disable prettification, the `--nopretty` or `-n` flag
|
|||||||
can be used:
|
can be used:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hackmyresume generate resume.json out.all --nopretty
|
hackmyresume BUILD resume.json out.all --nopretty
|
||||||
```
|
```
|
||||||
|
|
||||||
### Silent Mode
|
### Silent Mode
|
||||||
@ -284,10 +297,16 @@ hackmyresume generate resume.json out.all --nopretty
|
|||||||
Use `-s` or `--silent` to run in silent mode:
|
Use `-s` or `--silent` to run in silent mode:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hackmyresume generate resume.json -o someFile.all -s
|
hackmyresume BUILD resume.json -o someFile.all -s
|
||||||
hackmyresume generate resume.json -o someFile.all --silent
|
hackmyresume BUILD resume.json -o someFile.all --silent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
HackMyResume is a community-driven free and open source project under the MIT
|
||||||
|
License. Contributions are encouraged and we respond to all PRs and issues,
|
||||||
|
usually within 24 hours. See [CONTRIBUTING.md][contribute] for details.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT. Go crazy. See [LICENSE.md][1] for details.
|
MIT. Go crazy. See [LICENSE.md][1] for details.
|
||||||
@ -307,3 +326,6 @@ MIT. Go crazy. See [LICENSE.md][1] for details.
|
|||||||
[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|
||||||
[travis-image]: https://img.shields.io/travis/palomajs/paloma.svg?style=flat-square
|
[travis-image]: https://img.shields.io/travis/palomajs/paloma.svg?style=flat-square
|
||||||
[travis-url]: https://travis-ci.org/hacksalot/HackMyResume
|
[travis-url]: https://travis-ci.org/hacksalot/HackMyResume
|
||||||
|
[contribute]: CONTRIBUTING.md
|
||||||
|
[fresh-themes]: https://github.com/fluentdesk/fluent-themes
|
||||||
|
[jrst]: https://www.npmjs.com/search?q=jsonresume-theme
|
||||||
|
17
package.json
17
package.json
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "hackmyresume",
|
"name": "hackmyresume",
|
||||||
"version": "1.2.2",
|
"version": "1.3.0-beta",
|
||||||
"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",
|
||||||
"url": "https://github.com/hacksalot/HackMyResume.git"
|
"url": "https://github.com/hacksalot/HackMyResume.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha && grunt",
|
"test": "grunt clean && mocha",
|
||||||
"grunt": "grunt"
|
"grunt": "grunt"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -29,6 +29,11 @@
|
|||||||
"template"
|
"template"
|
||||||
],
|
],
|
||||||
"author": "hacksalot <hacksalot@indevious.com> (https://github.com/hacksalot)",
|
"author": "hacksalot <hacksalot@indevious.com> (https://github.com/hacksalot)",
|
||||||
|
"contributors": [
|
||||||
|
"Edmund Jorgensen (https://github.com/tomheon)",
|
||||||
|
"Ya Zhuang (https://github.com/zhuangya)",
|
||||||
|
"hacksalot <hacksalot@indevious.com> (https://github.com/hacksalot)"
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"preferGlobal": "true",
|
"preferGlobal": "true",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
@ -41,7 +46,8 @@
|
|||||||
"homepage": "https://github.com/hacksalot/HackMyResume",
|
"homepage": "https://github.com/hacksalot/HackMyResume",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"colors": "^1.1.2",
|
"colors": "^1.1.2",
|
||||||
"fluent-themes": "~0.7.1-beta",
|
"copy": "^0.1.3",
|
||||||
|
"fluent-themes": "~0.8.0-beta",
|
||||||
"fresca": "~0.2.2",
|
"fresca": "~0.2.2",
|
||||||
"fs-extra": "^0.24.0",
|
"fs-extra": "^0.24.0",
|
||||||
"handlebars": "^4.0.5",
|
"handlebars": "^4.0.5",
|
||||||
@ -57,6 +63,7 @@
|
|||||||
"path-exists": "^2.1.0",
|
"path-exists": "^2.1.0",
|
||||||
"recursive-readdir-sync": "^1.0.6",
|
"recursive-readdir-sync": "^1.0.6",
|
||||||
"simple-html-tokenizer": "^0.2.0",
|
"simple-html-tokenizer": "^0.2.0",
|
||||||
|
"string.prototype.startswith": "^0.2.0",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
"webshot": "^0.16.0",
|
"webshot": "^0.16.0",
|
||||||
"wkhtmltopdf": "^0.1.5",
|
"wkhtmltopdf": "^0.1.5",
|
||||||
@ -72,6 +79,10 @@
|
|||||||
"grunt-contrib-yuidoc": "^0.10.0",
|
"grunt-contrib-yuidoc": "^0.10.0",
|
||||||
"grunt-simple-mocha": "*",
|
"grunt-simple-mocha": "*",
|
||||||
"jane-q-fullstacker": "fluentdesk/jane-q-fullstacker",
|
"jane-q-fullstacker": "fluentdesk/jane-q-fullstacker",
|
||||||
|
"jsonresume-theme-boilerplate": "^0.1.2",
|
||||||
|
"jsonresume-theme-classy": "^1.0.9",
|
||||||
|
"jsonresume-theme-modern": "0.0.18",
|
||||||
|
"jsonresume-theme-sceptile": "^1.0.5",
|
||||||
"mocha": "*",
|
"mocha": "*",
|
||||||
"resample": "fluentdesk/resample"
|
"resample": "fluentdesk/resample"
|
||||||
}
|
}
|
||||||
|
93
src/core/error-handler.js
Normal file
93
src/core/error-handler.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
@module error-handler.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var HACKMYSTATUS = require('./status-codes')
|
||||||
|
, PKG = require('../../package.json')
|
||||||
|
, title = ('\n*** HackMyResume v' + PKG.version + ' ***').bold.white;
|
||||||
|
|
||||||
|
var ErrorHandler = module.exports = {
|
||||||
|
|
||||||
|
|
||||||
|
err: function( ex, shouldExit ) {
|
||||||
|
var msg = '', exitCode;
|
||||||
|
|
||||||
|
if( ex.fluenterror ){
|
||||||
|
switch( ex.fluenterror ) { // TODO: Remove magic numbers
|
||||||
|
|
||||||
|
case HACKMYSTATUS.themeNotFound:
|
||||||
|
msg = "The specified theme couldn't be found: " + ex.data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.copyCSS:
|
||||||
|
msg = "Couldn't copy CSS file to destination folder";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.resumeNotFound:
|
||||||
|
msg = 'Please '.guide + 'specify a valid input resume'.guide.bold +
|
||||||
|
' in FRESH or JSON Resume format.'.guide;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.missingCommand:
|
||||||
|
msg = title + "\nPlease ".guide + "specify a command".guide.bold + " (".guide +
|
||||||
|
Object.keys( FCMD.verbs ).map( function(v, idx, ar) {
|
||||||
|
return (idx === ar.length - 1 ? 'or '.guide : '') +
|
||||||
|
v.toUpperCase().guide;
|
||||||
|
}).join(', '.guide) + ").\n\n".guide +
|
||||||
|
FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' ).info.bold;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.invalidCommand:
|
||||||
|
msg = 'Please '.guide + 'specify the output resume file'.guide.bold +
|
||||||
|
' that should be created.'.guide;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.resumeNotFoundAlt:
|
||||||
|
msg = 'Please '.guide + 'specify a valid input resume'.guide.bold +
|
||||||
|
' in either FRESH or JSON Resume format.'.guide;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.inputOutputParity:
|
||||||
|
msg = 'Please '.guide + 'specify an output file name'.guide.bold +
|
||||||
|
' for every input file you wish to convert.'.guide;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.createNameMissing:
|
||||||
|
msg = 'Please '.guide + 'specify the filename of the resume'.guide.bold +
|
||||||
|
' to create.'.guide;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HACKMYSTATUS.wkhtmltopdf:
|
||||||
|
msg = 'ERROR: PDF generation failed. '.red.bold + ('Make sure wkhtmltopdf is ' +
|
||||||
|
'installed and accessible from your path.').red;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
exitCode = ex.fluenterror;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = ex.toString();
|
||||||
|
exitCode = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx = msg.indexOf('Error: ');
|
||||||
|
var trimmed = idx === -1 ? msg : msg.substring( idx + 7 );
|
||||||
|
if( !ex.fluenterror || ex.fluenterror < 3 ) { // TODO: magic #s
|
||||||
|
console.log( ('ERROR: ' + trimmed.toString()).red.bold );
|
||||||
|
console.log( ex.stack.gray);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log( trimmed.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( shouldExit )
|
||||||
|
process.exit( exitCode );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
@ -143,15 +143,12 @@ Definition of the FRESHResume class.
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Open and parse the specified JSON resume sheet. Merge the JSON object model
|
Initialize the FreshResume from JSON data.
|
||||||
onto this Sheet instance with extend() and convert sheet dates to a safe &
|
Open and parse the specified FRESH resume. Merge the JSON object model onto
|
||||||
|
this Sheet instance with extend() and convert sheet dates to a safe &
|
||||||
consistent format. Then sort each section by startDate descending.
|
consistent format. Then sort each section by startDate descending.
|
||||||
*/
|
*/
|
||||||
FreshResume.prototype.parse = function( stringData, opts ) {
|
FreshResume.prototype.parseJSON = function( rep, opts ) {
|
||||||
|
|
||||||
// Parse the incoming JSON representation
|
|
||||||
var rep = JSON.parse( stringData );
|
|
||||||
|
|
||||||
// Convert JSON Resume to FRESH if necessary
|
// Convert JSON Resume to FRESH if necessary
|
||||||
if( rep.basics ) {
|
if( rep.basics ) {
|
||||||
rep = CONVERTER.toFRESH( rep );
|
rep = CONVERTER.toFRESH( rep );
|
||||||
@ -178,6 +175,13 @@ Definition of the FRESHResume class.
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize the the FreshResume from string data.
|
||||||
|
*/
|
||||||
|
FreshResume.prototype.parse = function( stringData, opts ) {
|
||||||
|
return this.parseJSON( JSON.parse( stringData ), opts );
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return a unique list of all keywords across all skills.
|
Return a unique list of all keywords across all skills.
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@ Definition of the JRSResume class.
|
|||||||
, validator = require('is-my-json-valid')
|
, validator = require('is-my-json-valid')
|
||||||
, _ = require('underscore')
|
, _ = require('underscore')
|
||||||
, PATH = require('path')
|
, PATH = require('path')
|
||||||
|
, MD = require('marked')
|
||||||
, moment = require('moment');
|
, moment = require('moment');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,6 +71,7 @@ Definition of the JRSResume class.
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Initialize the JRS Resume from string data.
|
||||||
Open and parse the specified JSON resume sheet. Merge the JSON object model
|
Open and parse the specified JSON resume sheet. Merge the JSON object model
|
||||||
onto this Sheet instance with extend() and convert sheet dates to a safe &
|
onto this Sheet instance with extend() and convert sheet dates to a safe &
|
||||||
consistent format. Then sort each section by startDate descending.
|
consistent format. Then sort each section by startDate descending.
|
||||||
@ -77,7 +79,14 @@ Definition of the JRSResume class.
|
|||||||
JRSResume.prototype.parse = function( stringData, opts ) {
|
JRSResume.prototype.parse = function( stringData, opts ) {
|
||||||
opts = opts || { };
|
opts = opts || { };
|
||||||
var rep = JSON.parse( stringData );
|
var rep = JSON.parse( stringData );
|
||||||
|
return this.parseJSON( rep, opts );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize the JRSRume from JSON data.
|
||||||
|
*/
|
||||||
|
JRSResume.prototype.parseJSON = function( rep, opts ) {
|
||||||
|
opts = opts || { };
|
||||||
extend( true, this, rep );
|
extend( true, this, rep );
|
||||||
// Set up metadata
|
// Set up metadata
|
||||||
if( opts.imp === undefined || opts.imp ) {
|
if( opts.imp === undefined || opts.imp ) {
|
||||||
@ -230,6 +239,70 @@ Definition of the JRSResume class.
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JRSResume.prototype.dupe = function() {
|
||||||
|
var rnew = new JRSResume();
|
||||||
|
rnew.parse( this.stringify(), { } );
|
||||||
|
return rnew;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a copy of this resume in which all fields have been interpreted as
|
||||||
|
Markdown.
|
||||||
|
*/
|
||||||
|
JRSResume.prototype.harden = function() {
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
var ret = this.dupe();
|
||||||
|
|
||||||
|
function HD(txt) {
|
||||||
|
return '@@@@~' + txt + '~@@@@';
|
||||||
|
}
|
||||||
|
|
||||||
|
function HDIN(txt){
|
||||||
|
//return MD(txt || '' ).replace(/^\s*<p>|<\/p>\s*$/gi, '');
|
||||||
|
return HD(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: refactor recursion
|
||||||
|
function hardenStringsInObject( obj, inline ) {
|
||||||
|
|
||||||
|
if( !obj ) return;
|
||||||
|
inline = inline === undefined || inline;
|
||||||
|
|
||||||
|
|
||||||
|
if( Object.prototype.toString.call( obj ) === '[object Array]' ) {
|
||||||
|
obj.forEach(function(elem, idx, ar){
|
||||||
|
if( typeof elem === 'string' || elem instanceof String )
|
||||||
|
ar[idx] = inline ? HDIN(elem) : HD( elem );
|
||||||
|
else
|
||||||
|
hardenStringsInObject( elem );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (typeof obj === 'object') {
|
||||||
|
Object.keys( obj ).forEach(function(key) {
|
||||||
|
var sub = obj[key];
|
||||||
|
if( typeof sub === 'string' || sub instanceof String ) {
|
||||||
|
if( _.contains(['skills','url','website','startDate','endDate','releaseDate','date','phone','email','address','postalCode','city','country','region'], key) )
|
||||||
|
return;
|
||||||
|
if( key === 'summary' )
|
||||||
|
obj[key] = HD( obj[key] );
|
||||||
|
else
|
||||||
|
obj[key] = inline ? HDIN( obj[key] ) : HD( obj[key] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hardenStringsInObject( sub );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys( ret ).forEach(function(member){
|
||||||
|
hardenStringsInObject( ret[ member ] );
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
(function(){
|
|
||||||
|
|
||||||
var FRESHResume = require('../core/fresh-resume');
|
|
||||||
|
|
||||||
module.exports = function loadSourceResumes( src, log, fn ) {
|
|
||||||
return src.map( function( res ) {
|
|
||||||
log( 'Reading '.info + 'SOURCE'.infoBold + ' resume: '.info +
|
|
||||||
res.cyan.bold );
|
|
||||||
return (fn && fn(res)) || (new FRESHResume()).open( res );
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
}());
|
|
43
src/core/resume-factory.js
Normal file
43
src/core/resume-factory.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
Core resume-loading logic for HackMyResume.
|
||||||
|
@module resume-factory.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
require('string.prototype.startswith');
|
||||||
|
var FS = require('fs');
|
||||||
|
var ResumeConverter = require('./convert');
|
||||||
|
|
||||||
|
/**
|
||||||
|
A simple factory class for FRESH and JSON Resumes.
|
||||||
|
@class ResumeFactory
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Load one or more resumes in a specific source format.
|
||||||
|
*/
|
||||||
|
load: function ( src, log, fn, toFormat ) {
|
||||||
|
|
||||||
|
toFormat = toFormat && (toFormat.toLowerCase().trim()) || 'fresh';
|
||||||
|
var ResumeClass = require('../core/' + toFormat + '-resume');
|
||||||
|
|
||||||
|
return src.map( function( res ) {
|
||||||
|
var rezJson = JSON.parse( FS.readFileSync( res ) );
|
||||||
|
var orgFormat = ( rezJson.meta && rezJson.meta.format &&
|
||||||
|
rezJson.meta.format.startsWith('FRESH@') ) ?
|
||||||
|
'fresh' : 'jrs';
|
||||||
|
if(orgFormat !== toFormat) {
|
||||||
|
rezJson = ResumeConverter[ 'to' + toFormat.toUpperCase() ]( rezJson );
|
||||||
|
}
|
||||||
|
// TODO: Core should not log
|
||||||
|
log( 'Reading '.info + orgFormat.toUpperCase().infoBold + ' resume: '.info + res.cyan.bold );
|
||||||
|
return (fn && fn(res)) || (new ResumeClass()).parseJSON( rezJson );
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
22
src/core/spawn-watch.js
Normal file
22
src/core/spawn-watch.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
@module spawn-watch.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
// Catch various out-of-band child process errors such as ENOENT for PDFs
|
||||||
|
// http://stackoverflow.com/q/27688804
|
||||||
|
var SpawnWatcher = module.exports = function() {
|
||||||
|
var childProcess = require("child_process");
|
||||||
|
var oldSpawn = childProcess.spawn;
|
||||||
|
childProcess.spawn = function() {
|
||||||
|
return oldSpawn.apply(this, arguments)
|
||||||
|
.on('error', function(err) {
|
||||||
|
require('./error-handler').err( err, false );
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
|
||||||
|
//SpawnWatcher();
|
||||||
|
|
||||||
|
}());
|
21
src/core/status-codes.js
Normal file
21
src/core/status-codes.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
Status codes for HackMyResume.
|
||||||
|
@module status-codes.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
success: 0,
|
||||||
|
themeNotFound: 1,
|
||||||
|
copyCss: 2,
|
||||||
|
resumeNotFound: 3,
|
||||||
|
missingCommand: 4,
|
||||||
|
invalidCommand: 5,
|
||||||
|
resumeNotFoundAlt: 6,
|
||||||
|
inputOutputParity: 7,
|
||||||
|
createNameMissing: 8,
|
||||||
|
wkhtmltopdf: 9
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
Definition of the Theme class.
|
Definition of the Theme class.
|
||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
@license MIT. Copyright (c) 2015 hacksalot / FluentDesk.
|
||||||
@module theme.js
|
@module theme.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ Definition of the Theme class.
|
|||||||
, _ = require('underscore')
|
, _ = require('underscore')
|
||||||
, PATH = require('path')
|
, PATH = require('path')
|
||||||
, parsePath = require('parse-filepath')
|
, parsePath = require('parse-filepath')
|
||||||
|
, pathExists = require('path-exists').sync
|
||||||
, EXTEND = require('../utils/extend')
|
, EXTEND = require('../utils/extend')
|
||||||
, moment = require('moment')
|
, moment = require('moment')
|
||||||
, RECURSIVE_READ_DIR = require('recursive-readdir-sync');
|
, RECURSIVE_READ_DIR = require('recursive-readdir-sync');
|
||||||
@ -29,9 +30,26 @@ Definition of the Theme class.
|
|||||||
*/
|
*/
|
||||||
Theme.prototype.open = function( themeFolder ) {
|
Theme.prototype.open = function( themeFolder ) {
|
||||||
|
|
||||||
// Open the [theme-name].json file; should have the same name as folder
|
|
||||||
this.folder = themeFolder;
|
this.folder = themeFolder;
|
||||||
|
|
||||||
|
// Open the [theme-name].json file; should have the same name as folder
|
||||||
var pathInfo = parsePath( themeFolder );
|
var pathInfo = parsePath( themeFolder );
|
||||||
|
|
||||||
|
// Set up a formats hash for the theme
|
||||||
|
var formatsHash = { };
|
||||||
|
|
||||||
|
// See if the theme has a package.json. If so, load it.
|
||||||
|
var packageJsonPath = PATH.join(themeFolder, 'package.json');
|
||||||
|
if( pathExists( packageJsonPath ) ) {
|
||||||
|
var themePack = require( themeFolder );
|
||||||
|
var themePkgJson = require( packageJsonPath );
|
||||||
|
this.name = themePkgJson.name;
|
||||||
|
this.render = (themePack && themePack.render) || undefined;
|
||||||
|
this.formats = { html: { title: 'html', outFormat: 'html', ext: 'html', path: null, data: null } };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, do a full theme load
|
||||||
var themeFile = PATH.join( themeFolder, pathInfo.basename + '.json' );
|
var themeFile = PATH.join( themeFolder, pathInfo.basename + '.json' );
|
||||||
var themeInfo = JSON.parse( FS.readFileSync( themeFile, 'utf8' ) );
|
var themeInfo = JSON.parse( FS.readFileSync( themeFile, 'utf8' ) );
|
||||||
var that = this;
|
var that = this;
|
||||||
@ -39,9 +57,6 @@ Definition of the Theme class.
|
|||||||
// Move properties from the theme JSON file to the theme object
|
// Move properties from the theme JSON file to the theme object
|
||||||
EXTEND( true, this, themeInfo );
|
EXTEND( true, this, themeInfo );
|
||||||
|
|
||||||
// Set up a formats has for the theme
|
|
||||||
var formatsHash = { };
|
|
||||||
|
|
||||||
// Check for an explicit "formats" entry in the theme JSON. If it has one,
|
// Check for an explicit "formats" entry in the theme JSON. If it has one,
|
||||||
// then this theme declares its files explicitly.
|
// then this theme declares its files explicitly.
|
||||||
if( !!this.formats ) {
|
if( !!this.formats ) {
|
||||||
|
@ -26,14 +26,7 @@ Definition of the BaseGenerator class.
|
|||||||
/**
|
/**
|
||||||
Status codes.
|
Status codes.
|
||||||
*/
|
*/
|
||||||
codes: {
|
codes: require('../core/status-codes'),
|
||||||
success: 0,
|
|
||||||
themeNotFound: 1,
|
|
||||||
copyCss: 2,
|
|
||||||
resumeNotFound: 3,
|
|
||||||
missingCommand: 4,
|
|
||||||
invalidCommand: 5
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generator options.
|
Generator options.
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
Definition of the HtmlPdfGenerator class.
|
Definition of the HtmlPdfGenerator class.
|
||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
|
||||||
@module html-pdf-generator.js
|
@module html-pdf-generator.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -23,7 +22,7 @@ Definition of the HtmlPdfGenerator class.
|
|||||||
Generate the binary PDF.
|
Generate the binary PDF.
|
||||||
*/
|
*/
|
||||||
onBeforeSave: function( info ) {
|
onBeforeSave: function( info ) {
|
||||||
pdf( info.mk, info.outputFile );
|
pdf.call( this, info.mk, info.outputFile );
|
||||||
return null; // halt further processing
|
return null; // halt further processing
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,39 +33,50 @@ Definition of the HtmlPdfGenerator class.
|
|||||||
*/
|
*/
|
||||||
function pdf( markup, fOut ) {
|
function pdf( markup, fOut ) {
|
||||||
|
|
||||||
var pdfCount = 0;
|
pdf_wkhtmltopdf.call( this, markup, fOut );
|
||||||
if( false ) { //( _opts.pdf === 'phantom' || _opts.pdf == 'all' ) {
|
|
||||||
pdfCount++;
|
|
||||||
require('phantom').create( function( ph ) {
|
|
||||||
ph.createPage( function( page ) {
|
|
||||||
page.setContent( markup );
|
|
||||||
page.set('paperSize', {
|
|
||||||
format: 'A4',
|
|
||||||
orientation: 'portrait',
|
|
||||||
margin: '1cm'
|
|
||||||
});
|
|
||||||
page.set("viewportSize", {
|
|
||||||
width: 1024, // TODO: option-ify
|
|
||||||
height: 768 // TODO: Use "A" sizes
|
|
||||||
});
|
|
||||||
page.set('onLoadFinished', function(success) {
|
|
||||||
page.render( fOut );
|
|
||||||
pdfCount++;
|
|
||||||
ph.exit();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{ dnodeOpts: { weak: false } } );
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if( true ) { // _opts.pdf === 'wkhtmltopdf' || _opts.pdf == 'all' ) {
|
|
||||||
var fOut2 = fOut;
|
/**
|
||||||
if( pdfCount == 1 ) {
|
Generate a PDF from HTML using wkhtmltopdf.
|
||||||
fOut2 = fOut2.replace(/\.pdf$/g, '.b.pdf');
|
*/
|
||||||
|
function pdf_wkhtmltopdf( markup, fOut ) {
|
||||||
|
var wk;
|
||||||
|
try {
|
||||||
|
wk = require('wkhtmltopdf');
|
||||||
|
wk( markup, { pageSize: 'letter' } )
|
||||||
|
.pipe( FS.createWriteStream( fOut ) );
|
||||||
}
|
}
|
||||||
require('wkhtmltopdf')( markup, { pageSize: 'letter' } )
|
catch(ex) {
|
||||||
.pipe( FS.createWriteStream( fOut2 ) );
|
// { [Error: write EPIPE] code: 'EPIPE', errno: 'EPIPE', syscall: 'write' }
|
||||||
pdfCount++;
|
// { [Error: ENOENT] }
|
||||||
|
throw { fluenterror: this.codes.wkhtmltopdf };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// function pdf_phantom() {
|
||||||
|
// pdfCount++;
|
||||||
|
// require('phantom').create( function( ph ) {
|
||||||
|
// ph.createPage( function( page ) {
|
||||||
|
// page.setContent( markup );
|
||||||
|
// page.set('paperSize', {
|
||||||
|
// format: 'A4',
|
||||||
|
// orientation: 'portrait',
|
||||||
|
// margin: '1cm'
|
||||||
|
// });
|
||||||
|
// page.set("viewportSize", {
|
||||||
|
// width: 1024, // TODO: option-ify
|
||||||
|
// height: 768 // TODO: Use "A" sizes
|
||||||
|
// });
|
||||||
|
// page.set('onLoadFinished', function(success) {
|
||||||
|
// page.render( fOut );
|
||||||
|
// pdfCount++;
|
||||||
|
// ph.exit();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// { dnodeOpts: { weak: false } } );
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -156,7 +156,7 @@ Definition of the TemplateGenerator class.
|
|||||||
{ outputFile: fileName, mk: file.data } );
|
{ outputFile: fileName, mk: file.data } );
|
||||||
}
|
}
|
||||||
catch(ex) {
|
catch(ex) {
|
||||||
console.log(ex);
|
require('../core/error-handler').err(ex, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( file.info.action === null/* && theme.explicit*/ ) {
|
else if( file.info.action === null/* && theme.explicit*/ ) {
|
||||||
|
55
src/index.js
55
src/index.js
@ -2,27 +2,32 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Command-line interface (CLI) for HackMyResume.
|
Command-line interface (CLI) for HackMyResume.
|
||||||
@license MIT. Copyright (c) 2015 James M. Devlin / FluentDesk.
|
@license MIT. Copyright (c) 2015 hacksalot (https://github.com/hacksalot)
|
||||||
@module index.js
|
@module index.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var ARGS = require( 'minimist' )
|
|
||||||
|
|
||||||
|
var SPAWNW = require('./core/spawn-watch')
|
||||||
|
, ARGS = require( 'minimist' )
|
||||||
, FCMD = require( './hackmycmd')
|
, FCMD = require( './hackmycmd')
|
||||||
, PKG = require('../package.json')
|
, PKG = require('../package.json')
|
||||||
, COLORS = require('colors')
|
, COLORS = require('colors')
|
||||||
, FS = require('fs')
|
, FS = require('fs')
|
||||||
, PATH = require('path')
|
, PATH = require('path')
|
||||||
|
, HACKMYSTATUS = require('./core/status-codes')
|
||||||
, opts = { }
|
, opts = { }
|
||||||
, title = ('\n*** HackMyResume v' + PKG.version + ' ***').bold.white
|
, title = ('\n*** HackMyResume v' + PKG.version + ' ***').bold.white
|
||||||
, _ = require('underscore');
|
, _ = require('underscore');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
catch( ex ) {
|
catch( ex ) {
|
||||||
handleError( ex );
|
require('./core/error-handler').err( ex, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,47 +95,3 @@ function getOpts( args ) {
|
|||||||
silent: args.s || args.silent
|
silent: args.s || args.silent
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
function handleError( ex ) {
|
|
||||||
var msg = '', exitCode;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( ex.fluenterror ){
|
|
||||||
switch( ex.fluenterror ) { // TODO: Remove magic numbers
|
|
||||||
case 1: msg = "The specified theme couldn't be found: " + ex.data; break;
|
|
||||||
case 2: msg = "Couldn't copy CSS file to destination folder"; break;
|
|
||||||
case 3: msg = 'Please '.guide + 'specify a valid input resume'.guide.bold + ' in FRESH or JSON Resume format.'.guide; break;
|
|
||||||
case 4: msg = title + "\nPlease ".guide + "specify a command".guide.bold + " (".guide +
|
|
||||||
Object.keys( FCMD.verbs ).map( function(v, idx, ar) {
|
|
||||||
return (idx === ar.length - 1 ? 'or '.guide : '') +
|
|
||||||
v.toUpperCase().guide;
|
|
||||||
}).join(', '.guide) + ").\n\n".guide + FS.readFileSync( PATH.join(__dirname, 'use.txt'), 'utf8' ).info.bold;
|
|
||||||
break;
|
|
||||||
//case 4: msg = title + '\n' + ; break;
|
|
||||||
case 5: msg = 'Please '.guide + 'specify the output resume file'.guide.bold + ' that should be created.'.guide; break;
|
|
||||||
case 6: msg = 'Please '.guide + 'specify a valid input resume'.guide.bold + ' in either FRESH or JSON Resume format.'.guide; break;
|
|
||||||
case 7: msg = 'Please '.guide + 'specify an output file name'.guide.bold + ' for every input file you wish to convert.'.guide; break;
|
|
||||||
case 8: msg = 'Please '.guide + 'specify the filename of the resume'.guide.bold + ' to create.'.guide; break;
|
|
||||||
}
|
|
||||||
exitCode = ex.fluenterror;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg = ex.toString();
|
|
||||||
exitCode = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
var idx = msg.indexOf('Error: ');
|
|
||||||
var trimmed = idx === -1 ? msg : msg.substring( idx + 7 );
|
|
||||||
if( !ex.fluenterror || ex.fluenterror < 3 ) { // TODO: magic #s
|
|
||||||
console.log( ('ERROR: ' + trimmed.toString()).red.bold );
|
|
||||||
console.log( ex.stack.gray);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
console.log( trimmed.toString() );
|
|
||||||
|
|
||||||
process.exit( exitCode );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
Definitions of string utility functions.
|
Definitions of string utility functions.
|
||||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
|
||||||
@module string.js
|
@module string.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -10,6 +9,8 @@ See: http://stackoverflow.com/a/32800728/4942583
|
|||||||
@method isNullOrWhitespace
|
@method isNullOrWhitespace
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
String.isNullOrWhitespace = function( input ) {
|
String.isNullOrWhitespace = function( input ) {
|
||||||
return !input || !input.trim();
|
return !input || !input.trim();
|
||||||
};
|
};
|
||||||
@ -21,3 +22,5 @@ String.prototype.endsWith = function(suffix) {
|
|||||||
String.is = function( val ) {
|
String.is = function( val ) {
|
||||||
return typeof val === 'string' || val instanceof String;
|
return typeof val === 'string' || val instanceof String;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
(function(){
|
(function(){
|
||||||
|
|
||||||
var loadSourceResumes = require('../core/load-source-resumes');
|
var ResumeFactory = require('../core/resume-factory');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convert between FRESH and JRS formats.
|
Convert between FRESH and JRS formats.
|
||||||
@ -16,7 +16,7 @@
|
|||||||
if( src && dst && src.length && dst.length && src.length !== dst.length ) {
|
if( src && dst && src.length && dst.length && src.length !== dst.length ) {
|
||||||
throw { fluenterror: 7 };
|
throw { fluenterror: 7 };
|
||||||
}
|
}
|
||||||
var sheets = loadSourceResumes( src, _log );
|
var sheets = ResumeFactory.load( src, _log );
|
||||||
sheets.forEach(function(sheet, idx){
|
sheets.forEach(function(sheet, idx){
|
||||||
var sourceFormat = sheet.imp.orgFormat === 'JRS' ? 'JRS' : 'FRESH';
|
var sourceFormat = sheet.imp.orgFormat === 'JRS' ? 'JRS' : 'FRESH';
|
||||||
var targetFormat = sourceFormat === 'JRS' ? 'FRESH' : 'JRS';
|
var targetFormat = sourceFormat === 'JRS' ? 'FRESH' : 'JRS';
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var PATH = require('path')
|
var PATH = require('path')
|
||||||
|
, FS = require('fs')
|
||||||
, parsePath = require('parse-filepath')
|
, parsePath = require('parse-filepath')
|
||||||
|
, MD = require('marked')
|
||||||
, MKDIRP = require('mkdirp')
|
, MKDIRP = require('mkdirp')
|
||||||
, _opts = require('../core/default-options')
|
, _opts = require('../core/default-options')
|
||||||
, FluentTheme = require('../core/theme')
|
, FluentTheme = require('../core/theme')
|
||||||
, loadSourceResumes = require('../core/load-source-resumes')
|
, ResumeFactory = require('../core/resume-factory')
|
||||||
, _ = require('underscore')
|
, _ = require('underscore')
|
||||||
, _fmts = require('../core/default-formats')
|
, _fmts = require('../core/default-formats')
|
||||||
, _err, _log, rez;
|
, _err, _log, rez;
|
||||||
@ -36,19 +38,6 @@
|
|||||||
_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 : false;
|
_opts.prettify = opts.prettify === true ? _opts.prettify : false;
|
||||||
|
|
||||||
// Load input resumes...
|
|
||||||
if( !src || !src.length ) { throw { fluenterror: 3 }; }
|
|
||||||
var sheets = loadSourceResumes( src, _log );
|
|
||||||
|
|
||||||
// Merge input resumes...
|
|
||||||
var msg = '';
|
|
||||||
rez = _.reduceRight( sheets, function( a, b, idx ) {
|
|
||||||
msg += ((idx == sheets.length - 2) ?
|
|
||||||
'Merging '.gray+ a.imp.fileName : '') + ' onto '.gray + b.imp.fileName;
|
|
||||||
return extend( true, b, a );
|
|
||||||
});
|
|
||||||
msg && _log(msg);
|
|
||||||
|
|
||||||
// Verify the specified theme name/path
|
// Verify the specified theme name/path
|
||||||
var relativeThemeFolder = '../../node_modules/fluent-themes/themes';
|
var relativeThemeFolder = '../../node_modules/fluent-themes/themes';
|
||||||
var tFolder = PATH.resolve( __dirname, relativeThemeFolder, _opts.theme);
|
var tFolder = PATH.resolve( __dirname, relativeThemeFolder, _opts.theme);
|
||||||
@ -63,8 +52,23 @@
|
|||||||
// Load the theme
|
// Load the theme
|
||||||
var theTheme = (new FluentTheme()).open( tFolder );
|
var theTheme = (new FluentTheme()).open( tFolder );
|
||||||
_opts.themeObj = theTheme;
|
_opts.themeObj = theTheme;
|
||||||
|
var numFormats = theTheme.formats ? Object.keys(theTheme.formats).length : 2;
|
||||||
_log( 'Applying '.info + theTheme.name.toUpperCase().infoBold +
|
_log( 'Applying '.info + theTheme.name.toUpperCase().infoBold +
|
||||||
(' theme (' + Object.keys(theTheme.formats).length + ' formats)').info);
|
(' theme (' + numFormats + ' formats)').info);
|
||||||
|
|
||||||
|
// Load input resumes...
|
||||||
|
if( !src || !src.length ) { throw { fluenterror: 3 }; }
|
||||||
|
var sheets = ResumeFactory.load( src, _log, null,
|
||||||
|
theTheme.render ? 'JRS' : 'FRESH' );
|
||||||
|
|
||||||
|
// Merge input resumes...
|
||||||
|
var msg = '';
|
||||||
|
rez = _.reduceRight( sheets, function( a, b, idx ) {
|
||||||
|
msg += ((idx == sheets.length - 2) ?
|
||||||
|
'Merging '.gray+ a.imp.fileName : '') + ' onto '.gray + b.imp.fileName;
|
||||||
|
return extend( true, b, a );
|
||||||
|
});
|
||||||
|
msg && _log(msg);
|
||||||
|
|
||||||
// Expand output resumes... (can't use map() here)
|
// Expand output resumes... (can't use map() here)
|
||||||
var targets = [], that = this;
|
var targets = [], that = this;
|
||||||
@ -74,11 +78,15 @@
|
|||||||
pa = parsePath(to),
|
pa = parsePath(to),
|
||||||
fmat = pa.extname || '.all';
|
fmat = pa.extname || '.all';
|
||||||
|
|
||||||
targets.push.apply(targets, fmat === '.all' ?
|
targets.push.apply(
|
||||||
|
targets, fmat === '.all' ?
|
||||||
|
|
||||||
Object.keys( theTheme.formats ).map(function(k){
|
Object.keys( theTheme.formats ).map(function(k){
|
||||||
var z = theTheme.formats[k];
|
var z = theTheme.formats[k];
|
||||||
return { file: to.replace(/all$/g,z.outFormat), fmt: z };
|
return { file: to.replace(/all$/g,z.outFormat), fmt: z };
|
||||||
}) : [{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]);
|
}) :
|
||||||
|
|
||||||
|
[{ file: to, fmt: theTheme.getFormat( fmat.slice(1) ) }]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -95,6 +103,11 @@
|
|||||||
"/foo/bar/resume.pdf" or "c:\foo\bar\resume.txt".
|
"/foo/bar/resume.pdf" or "c:\foo\bar\resume.txt".
|
||||||
*/
|
*/
|
||||||
function single( targInfo, theme ) {
|
function single( targInfo, theme ) {
|
||||||
|
|
||||||
|
function MDIN(txt) {
|
||||||
|
return MD(txt || '' ).replace(/^\s*<p>|<\/p>\s*$/gi, '');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var f = targInfo.file
|
var f = targInfo.file
|
||||||
, fType = targInfo.fmt.outFormat
|
, fType = targInfo.fmt.outFormat
|
||||||
@ -113,22 +126,6 @@
|
|||||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||||
MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
|
MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
|
||||||
theFormat.gen.generate( rez, f, _opts );
|
theFormat.gen.generate( rez, f, _opts );
|
||||||
|
|
||||||
// targInfo.fmt.files.forEach( function( form ) {
|
|
||||||
//
|
|
||||||
// if( form.action === 'transform' ) {
|
|
||||||
// var theFormat = _fmts.filter( function( fmt ) {
|
|
||||||
// return fmt.name === targInfo.fmt.outFormat;
|
|
||||||
// })[0];
|
|
||||||
// MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
|
|
||||||
// theFormat.gen.generate( rez, f, _opts );
|
|
||||||
// }
|
|
||||||
// else if( form.action === null ) {
|
|
||||||
// // Copy the file
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Otherwise the theme has no files section
|
// Otherwise the theme has no files section
|
||||||
else {
|
else {
|
||||||
@ -138,10 +135,46 @@
|
|||||||
|
|
||||||
theFormat = _fmts.filter(
|
theFormat = _fmts.filter(
|
||||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||||
MKDIRP.sync( PATH.dirname( f ) ); // Ensure dest folder exists;
|
|
||||||
|
var outFolder = PATH.dirname( f );
|
||||||
|
MKDIRP.sync( outFolder ); // Ensure dest folder exists;
|
||||||
|
|
||||||
|
// TODO: refactor
|
||||||
|
if( theme.render ) {
|
||||||
|
var COPY = require('copy');
|
||||||
|
var globs = [ /*'**',*/ '*.css', '*.js', '*.png', '*.jpg', '*.gif', '*.bmp' ];
|
||||||
|
COPY.sync( globs , outFolder, {
|
||||||
|
cwd: theme.folder, nodir: true,
|
||||||
|
ignore: ['node_modules/','node_modules/**']
|
||||||
|
// rewrite: function(p1, p2) {
|
||||||
|
// return PATH.join(p2, p1);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent JSON Resume theme .js from chattering
|
||||||
|
var consoleLog = console.log;
|
||||||
|
console.log = function() { };
|
||||||
|
|
||||||
|
// Call the theme's render method
|
||||||
|
var rezDupe = rez.harden();
|
||||||
|
var rezHtml = theme.render( rezDupe );
|
||||||
|
|
||||||
|
// Turn logging back on
|
||||||
|
console.log = consoleLog;
|
||||||
|
|
||||||
|
// Unharden
|
||||||
|
rezHtml = rezHtml.replace( /@@@@~.+?~@@@@/g, function(val){
|
||||||
|
return MDIN( val.replace( /~@@@@/gm,'' ).replace( /@@@@~/gm,'' ) );
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save the file
|
||||||
|
FS.writeFileSync( f, rezHtml );
|
||||||
|
}
|
||||||
|
else {
|
||||||
theFormat.gen.generate( rez, f, _opts );
|
theFormat.gen.generate( rez, f, _opts );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch( ex ) {
|
catch( ex ) {
|
||||||
_err( ex );
|
_err( ex );
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var FS = require('fs');
|
var FS = require('fs');
|
||||||
var loadSourceResumes = require('../core/load-source-resumes');
|
var ResumeFactory = require('../core/resume-factory');
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
|
|
||||||
@ -20,7 +20,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Load input resumes...
|
// Load input resumes...
|
||||||
var sheets = loadSourceResumes(src, _log, function( res ) {
|
var sheets = ResumeFactory.load(src, _log, function( res ) {
|
||||||
try {
|
try {
|
||||||
return {
|
return {
|
||||||
file: res,
|
file: res,
|
||||||
|
@ -43,15 +43,15 @@ describe('Testing CLI interface', function () {
|
|||||||
silent: true
|
silent: true
|
||||||
};
|
};
|
||||||
|
|
||||||
run( 'new', ['tests/sandbox/new-fresh-resume.json'], [], opts, ' (FRESH format)' );
|
run( 'new', ['test/sandbox/new-fresh-resume.json'], [], opts, ' (FRESH format)' );
|
||||||
run( 'new', ['tests/sandbox/new-jrs-resume.json'], [], opts2, ' (JRS format)' );
|
run( 'new', ['test/sandbox/new-jrs-resume.json'], [], opts2, ' (JRS format)' );
|
||||||
run( 'new', ['tests/sandbox/new-1.json', 'tests/sandbox/new-2.json', 'tests/sandbox/new-3.json'], [], opts, ' (multiple FRESH resumes)' );
|
run( 'new', ['test/sandbox/new-1.json', 'test/sandbox/new-2.json', 'test/sandbox/new-3.json'], [], opts, ' (multiple FRESH resumes)' );
|
||||||
run( 'new', ['tests/sandbox/new-jrs-1.json', 'tests/sandbox/new-jrs-2.json', 'tests/sandbox/new-jrs-3.json'], [], opts, ' (multiple JRS resumes)' );
|
run( 'new', ['test/sandbox/new-jrs-1.json', 'test/sandbox/new-jrs-2.json', 'test/sandbox/new-jrs-3.json'], [], opts, ' (multiple JRS resumes)' );
|
||||||
run( 'new', ['tests/sandbox/new-jrs-resume.json'], [], opts2, ' (JRS format)' );
|
run( 'new', ['test/sandbox/new-jrs-resume.json'], [], opts2, ' (JRS format)' );
|
||||||
fail( 'new', [], [], opts, " (when a filename isn't specified)" );
|
fail( 'new', [], [], opts, " (when a filename isn't specified)" );
|
||||||
|
|
||||||
run( 'validate', ['node_modules/jane-q-fullstacker/resume/jane-resume.json'], [], opts, ' (FRESH format)' );
|
run( 'validate', ['node_modules/jane-q-fullstacker/resume/jane-resume.json'], [], opts, ' (FRESH format)' );
|
||||||
run( 'validate', ['tests/sandbox/new-fresh-resume.json'], [], opts, ' (FRESH format)' );
|
run( 'validate', ['test/sandbox/new-fresh-resume.json'], [], opts, ' (FRESH format)' );
|
||||||
|
|
||||||
function run( verb, src, dst, opts, msg ) {
|
function run( verb, src, dst, opts, msg ) {
|
||||||
msg = msg || '.';
|
msg = msg || '.';
|
||||||
|
@ -43,13 +43,13 @@ describe('jane-doe.json (FRESH)', function () {
|
|||||||
|
|
||||||
it('should save without throwing an exception', function(){
|
it('should save without throwing an exception', function(){
|
||||||
function trySave() {
|
function trySave() {
|
||||||
_sheet.save( 'tests/sandbox/jane-q-fullstacker.json' );
|
_sheet.save( 'test/sandbox/jane-q-fullstacker.json' );
|
||||||
}
|
}
|
||||||
trySave.should.not.Throw();
|
trySave.should.not.Throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be modified after saving', function() {
|
it('should not be modified after saving', function() {
|
||||||
var savedSheet = new FRESHResume().open('tests/sandbox/jane-q-fullstacker.json');
|
var savedSheet = new FRESHResume().open('test/sandbox/jane-q-fullstacker.json');
|
||||||
_sheet.stringify().should.equal( savedSheet.stringify() );
|
_sheet.stringify().should.equal( savedSheet.stringify() );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ function testResume( opts ) {
|
|||||||
it('should save without throwing an exception', function() {
|
it('should save without throwing an exception', function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
function trySave() {
|
function trySave() {
|
||||||
_sheet.save( 'tests/sandbox/' + opts.title + '.json' );
|
_sheet.save( 'test/sandbox/' + opts.title + '.json' );
|
||||||
}
|
}
|
||||||
trySave.should.not.Throw();
|
trySave.should.not.Throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be modified after saving', function() {
|
it('should not be modified after saving', function() {
|
||||||
var savedSheet = new JRSResume().open( 'tests/sandbox/' + opts.title + '.json' );
|
var savedSheet = new JRSResume().open( 'test/sandbox/' + opts.title + '.json' );
|
||||||
_sheet.stringify().should.equal( savedSheet.stringify() );
|
_sheet.stringify().should.equal( savedSheet.stringify() );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
var chai = require('chai')
|
var SPAWNWATCHER = require('../src/core/spawn-watch')
|
||||||
|
, chai = require('chai')
|
||||||
, expect = chai.expect
|
, expect = chai.expect
|
||||||
, should = chai.should()
|
, should = chai.should()
|
||||||
, path = require('path')
|
, path = require('path')
|
||||||
@ -26,14 +27,16 @@ describe('Testing themes', function () {
|
|||||||
useful: 'green',
|
useful: 'green',
|
||||||
});
|
});
|
||||||
|
|
||||||
function genTheme( themeName ) {
|
function genTheme( fmt, src, themeName, themeLoc, testTitle ) {
|
||||||
it( themeName.toUpperCase() + ' theme should generate without throwing an exception', function () {
|
themeLoc = themeLoc || themeName;
|
||||||
|
testTitle = themeName.toUpperCase() + ' theme should generate without throwing an exception';
|
||||||
|
it( testTitle, function () {
|
||||||
function tryOpen() {
|
function tryOpen() {
|
||||||
var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
//var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
||||||
var dst = ['tests/sandbox/' + themeName + '/resume.all'];
|
var dst = ['test/sandbox/' + fmt + '/' + themeName + '/resume.all'];
|
||||||
var opts = {
|
var opts = {
|
||||||
theme: themeName,
|
theme: themeLoc,
|
||||||
format: 'FRESH',
|
format: fmt,
|
||||||
prettify: true,
|
prettify: true,
|
||||||
silent: true
|
silent: true
|
||||||
};
|
};
|
||||||
@ -43,11 +46,28 @@ describe('Testing themes', function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
genTheme('hello-world');
|
var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
||||||
genTheme('compact');
|
genTheme('FRESH', src, 'hello-world');
|
||||||
genTheme('modern');
|
genTheme('FRESH', src, 'compact');
|
||||||
genTheme('minimist');
|
genTheme('FRESH', src, 'modern');
|
||||||
genTheme('awesome');
|
genTheme('FRESH', src, 'minimist');
|
||||||
genTheme('positive');
|
genTheme('FRESH', src, 'awesome');
|
||||||
|
genTheme('FRESH', src, 'positive');
|
||||||
|
genTheme('FRESH', src, 'jsonresume-theme-boilerplate', 'node_modules/jsonresume-theme-boilerplate' );
|
||||||
|
genTheme('FRESH', src, 'jsonresume-theme-sceptile', 'node_modules/jsonresume-theme-sceptile' );
|
||||||
|
genTheme('FRESH', src, 'jsonresume-theme-modern', 'node_modules/jsonresume-theme-modern' );
|
||||||
|
genTheme('FRESH', src, 'jsonresume-theme-classy', 'node_modules/jsonresume-theme-classy' );
|
||||||
|
|
||||||
|
src = ['test/resumes/jrs-0.0.0/richard-hendriks.json'];
|
||||||
|
genTheme('JRS', src, 'hello-world');
|
||||||
|
genTheme('JRS', src, 'compact');
|
||||||
|
genTheme('JRS', src, 'modern');
|
||||||
|
genTheme('JRS', src, 'minimist');
|
||||||
|
genTheme('JRS', src, 'awesome');
|
||||||
|
genTheme('JRS', src, 'positive');
|
||||||
|
genTheme('JRS', src, 'jsonresume-theme-boilerplate', 'node_modules/jsonresume-theme-boilerplate' );
|
||||||
|
genTheme('JRS', src, 'jsonresume-theme-sceptile', 'node_modules/jsonresume-theme-sceptile' );
|
||||||
|
genTheme('JRS', src, 'jsonresume-theme-modern', 'node_modules/jsonresume-theme-modern' );
|
||||||
|
genTheme('JRS', src, 'jsonresume-theme-classy', 'node_modules/jsonresume-theme-classy' );
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user