mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2025-05-12 00:27:08 +01:00
Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
93456b5f40 | |||
72f29bf402 | |||
f6fc384466 | |||
c5ab3fdfae | |||
78c5081a29 | |||
d0c181ee8c | |||
80c6bb6e8b | |||
786b3fd3b2 | |||
f0a22be731 | |||
ade60022fd | |||
7daba910ed | |||
a016d6d91a | |||
fcaa97ed35 | |||
bb7373a229 | |||
759dcc30e7 | |||
0e47f02a33 | |||
5fe90517e7 | |||
92128da381 | |||
1441fe3ae5 | |||
b0bc71cd66 | |||
e908e8bb34 | |||
d708a6c6d8 | |||
a630741098 | |||
01d148e47c | |||
dbd41ec439 | |||
fc9cbab974 |
@ -17,6 +17,8 @@ module.exports = function (grunt) {
|
||||
all: { src: ['tests/*.js'] }
|
||||
},
|
||||
|
||||
clean: ['tests/sandbox'],
|
||||
|
||||
yuidoc: {
|
||||
compile: {
|
||||
name: '<%= pkg.name %>',
|
||||
@ -46,10 +48,11 @@ module.exports = function (grunt) {
|
||||
grunt.loadNpmTasks('grunt-simple-mocha');
|
||||
grunt.loadNpmTasks('grunt-contrib-yuidoc');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
|
||||
grunt.registerTask('test', 'Test the FluentCV library.',
|
||||
function( config ) { grunt.task.run( ['simplemocha:all'] ); });
|
||||
grunt.registerTask('document', 'Generate FluentCV library documentation.',
|
||||
grunt.registerTask('test', 'Test the HackMyResume library.',
|
||||
function( config ) { grunt.task.run( ['clean','simplemocha:all'] ); });
|
||||
grunt.registerTask('document', 'Generate HackMyResume library documentation.',
|
||||
function( config ) { grunt.task.run( ['yuidoc'] ); });
|
||||
grunt.registerTask('default', [ 'jshint', 'test', 'yuidoc' ]);
|
||||
|
||||
|
170
README.md
170
README.md
@ -1,12 +1,14 @@
|
||||
fluentCV
|
||||
========
|
||||
*Create polished technical résumés and CVs in multiple formats from your command
|
||||
line or shell. See [FluentCV Desktop][7] for the desktop version. OS X ~ Windows
|
||||
~ Linux.*
|
||||
HackMyResume
|
||||
============
|
||||
*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,
|
||||
plain text, and other arbitrary formats. Fight the power, save trees. Compatible
|
||||
with [FRESH][fresca] and [JRS][6] resumes.*
|
||||
|
||||

|
||||

|
||||
|
||||
FluentCV is a dev-friendly Swiss Army knife for resumes and CVs. Use it to:
|
||||
HackMyResume is a dev-friendly, local-only Swiss Army knife for resumes and CVs.
|
||||
Use it to:
|
||||
|
||||
1. **Generate** HTML, Markdown, LaTeX, MS Word, PDF, plain text, JSON, XML,
|
||||
YAML, print, smoke signal, carrier pigeon, and other arbitrary-format resumes
|
||||
@ -14,7 +16,8 @@ and CVs, from a single source of truth—without violating DRY.
|
||||
2. **Convert** resumes between [FRESH][fresca] and [JSON Resume][6] formats.
|
||||
3. **Validate** resumes against either format.
|
||||
|
||||
FluentCV supports both the [FRESH][fresca] and [JSON Resume][6] source formats.
|
||||
HackMyResume is built with Node.js and runs on recent versions of OS X, Linux,
|
||||
or Windows.
|
||||
|
||||
## Features
|
||||
|
||||
@ -22,8 +25,6 @@ FluentCV supports both the [FRESH][fresca] and [JSON Resume][6] source formats.
|
||||
- Store your resume data as a durable, versionable JSON or YAML document.
|
||||
- Generate polished resumes in multiple formats without violating [DRY][dry].
|
||||
- Output to HTML, Markdown, LaTeX, PDF, MS Word, JSON, YAML, plain text, or XML.
|
||||
- Compatible with [FRESH][fresh], [JSON Resume][6], [FRESCA][fresca], and
|
||||
[FCV Desktop][7].
|
||||
- Validate resumes against the FRESH or JSON Resume schema.
|
||||
- Support for multiple input and output resumes.
|
||||
- Use from your command line or [desktop][7].
|
||||
@ -31,10 +32,10 @@ FluentCV supports both the [FRESH][fresca] and [JSON Resume][6] source formats.
|
||||
|
||||
## Install
|
||||
|
||||
Install FluentCV with NPM:
|
||||
Install HackMyResume with NPM:
|
||||
|
||||
```bash
|
||||
[sudo] npm install fluentcv -g
|
||||
[sudo] npm install hackmyresume -g
|
||||
```
|
||||
|
||||
Note: for PDF generation you'll need to install a copy of [wkhtmltopdf][3] for
|
||||
@ -43,49 +44,52 @@ access to `xelatex` and similar.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To use FluentCV you'll need to create a valid resume in either [FRESH][fresca]
|
||||
or [JSON Resume][6] format. Then you can start using the command line tool.
|
||||
There are four basic commands you should be aware of:
|
||||
To use HackMyResume you'll need to create a valid resume in either
|
||||
[FRESH][fresca] or [JSON Resume][6] format. Then you can start using the command
|
||||
line tool. There are four basic commands you should be aware of:
|
||||
|
||||
- `build` generates resumes in HTML, Word, Markdown, PDF, and other formats. Use
|
||||
it when you need to submit, upload, print, or email resumes in specific formats.
|
||||
- `**build**` generates resumes in HTML, Word, Markdown, PDF, and other formats.
|
||||
Use it when you need to submit, upload, print, or email resumes in specific
|
||||
formats.
|
||||
|
||||
```bash
|
||||
# fluentcv BUILD <INPUTS> TO <OUTPUTS> [-t THEME]
|
||||
fluentcv BUILD resume.json TO out/resume.all
|
||||
fluentcv BUILD r1.json r2.json TO out/rez.html out/rez.md foo/rez.all
|
||||
# hackmyresume BUILD <INPUTS> TO <OUTPUTS> [-t THEME]
|
||||
hackmyresume BUILD resume.json TO out/resume.all
|
||||
hackmyresume BUILD r1.json r2.json TO out/rez.html out/rez.md foo/rez.all
|
||||
```
|
||||
|
||||
- `new` creates a new resume in FRESH or JSON Resume format.
|
||||
- `**new**` creates a new resume in FRESH or JSON Resume format.
|
||||
|
||||
```bash
|
||||
# fluentcv NEW <OUTPUTS> [-f <FORMAT>]
|
||||
fluentcv NEW resume.json
|
||||
fluentcv NEW resume.json -f fresh
|
||||
fluentcv NEW r1.json r2.json -f jrs
|
||||
# hackmyresume NEW <OUTPUTS> [-f <FORMAT>]
|
||||
hackmyresume NEW resume.json
|
||||
hackmyresume NEW resume.json -f fresh
|
||||
hackmyresume NEW r1.json r2.json -f jrs
|
||||
```
|
||||
|
||||
- `convert` converts your source resume between FRESH and JSON Resume formats.
|
||||
Use it to convert between the two formats to take advantage of tools and services.
|
||||
- `**convert**` converts your source resume between FRESH and JSON Resume
|
||||
formats.
|
||||
Use it to convert between the two formats to take advantage of tools and
|
||||
services.
|
||||
|
||||
```bash
|
||||
# fluentcv CONVERT <INPUTS> TO <OUTPUTS>
|
||||
fluentcv CONVERT resume.json TO resume-jrs.json
|
||||
fluentcv CONVERT 1.json 2.json 3.json TO out/1.json out/2.json out/3.json
|
||||
# hackmyresume CONVERT <INPUTS> TO <OUTPUTS>
|
||||
hackmyresume CONVERT resume.json TO resume-jrs.json
|
||||
hackmyresume CONVERT 1.json 2.json 3.json TO out/1.json out/2.json out/3.json
|
||||
```
|
||||
|
||||
- `validate` validates the specified resume against either the FRESH or JSON
|
||||
- `**validate**` validates the specified resume against either the FRESH or JSON
|
||||
Resume schema. Use it to make sure your resume data is sufficient and complete.
|
||||
|
||||
```bash
|
||||
# fluentcv VALIDATE <INPUTS>
|
||||
fluentcv VALIDATE resume.json
|
||||
fluentcv VALIDATE r1.json r2.json r3.json
|
||||
# hackmyresume VALIDATE <INPUTS>
|
||||
hackmyresume VALIDATE resume.json
|
||||
hackmyresume VALIDATE r1.json r2.json r3.json
|
||||
```
|
||||
|
||||
## Supported Output Formats
|
||||
|
||||
FluentCV supports these output formats:
|
||||
HackMyResume supports these output formats:
|
||||
|
||||
Output Format | Ext | Notes
|
||||
------------- | --- | -----
|
||||
@ -103,11 +107,11 @@ image | .png, .bmp | Forthcoming.
|
||||
|
||||
## Install
|
||||
|
||||
FluentCV requires a recent version of [Node.js][4] and [NPM][5]. Then:
|
||||
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 **fluentCV** with `[sudo] npm install fluentcv -g`.
|
||||
2. Install **HackMyResume** with `[sudo] npm install hackmyresume -g`.
|
||||
3. You're ready to go.
|
||||
|
||||
## Use
|
||||
@ -116,7 +120,7 @@ Assuming you've got a JSON-formatted resume handy, generating resumes in
|
||||
different formats and combinations easy. Just run:
|
||||
|
||||
```bash
|
||||
fluentcv BUILD <INPUTS> <OUTPUTS> [-t theme].
|
||||
hackmyresume BUILD <INPUTS> <OUTPUTS> [-t theme].
|
||||
```
|
||||
|
||||
Where `<INPUTS>` is one or more .json resume files, separated by spaces;
|
||||
@ -125,25 +129,25 @@ theme (default to Modern). For example:
|
||||
|
||||
```bash
|
||||
# Generate all resume formats (HTML, PDF, DOC, TXT, YML, etc.)
|
||||
fluentcv build resume.json -o out/resume.all -t modern
|
||||
hackmyresume build resume.json -o out/resume.all -t modern
|
||||
|
||||
# Generate a specific resume format
|
||||
fluentcv build resume.json TO out/resume.html
|
||||
fluentcv build resume.json TO out/resume.pdf
|
||||
fluentcv build resume.json TO out/resume.md
|
||||
fluentcv build resume.json TO out/resume.doc
|
||||
fluentcv build resume.json TO out/resume.json
|
||||
fluentcv build resume.json TO out/resume.txt
|
||||
fluentcv build resume.json TO out/resume.yml
|
||||
hackmyresume build resume.json TO out/resume.html
|
||||
hackmyresume build resume.json TO out/resume.pdf
|
||||
hackmyresume build resume.json TO out/resume.md
|
||||
hackmyresume build resume.json TO out/resume.doc
|
||||
hackmyresume build resume.json TO out/resume.json
|
||||
hackmyresume build resume.json TO out/resume.txt
|
||||
hackmyresume build resume.json TO out/resume.yml
|
||||
|
||||
# Specify 2 inputs and 3 outputs
|
||||
fluentcv 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:
|
||||
|
||||
```
|
||||
*** FluentCV v0.9.0 ***
|
||||
*** HackMyResume v0.9.0 ***
|
||||
Reading JSON resume: foo/resume.json
|
||||
Applying MODERN Theme (7 formats)
|
||||
Generating HTML resume: out/resume.html
|
||||
@ -159,28 +163,37 @@ Generating YAML resume: out/resume.yml
|
||||
|
||||
### Applying a theme
|
||||
|
||||
You can specify a predefined or custom theme via the optional `-t` parameter. For a predefined theme, include the theme name. For a custom theme, include the path to the custom theme's folder.
|
||||
You can specify a predefined or custom theme via the optional `-t` parameter.
|
||||
For a predefined theme, include the theme name. For a custom theme, include the
|
||||
path to the custom theme's folder.
|
||||
|
||||
```bash
|
||||
fluentcv build resume.json -t modern
|
||||
fluentcv build resume.json -t ~/foo/bar/my-custom-theme/
|
||||
hackmyresume build resume.json -t modern
|
||||
hackmyresume build resume.json -t ~/foo/bar/my-custom-theme/
|
||||
```
|
||||
|
||||
As of v0.9.0, available predefined themes are `modern`, `minimist`, and `hello-world`, and `compact`.
|
||||
As of v1.0.0, available predefined themes are `positive`, `modern`, `compact`,
|
||||
`minimist`, and `hello-world`.
|
||||
|
||||
### Merging resumes
|
||||
|
||||
You can **merge multiple resumes together** by specifying them in order from most generic to most specific:
|
||||
You can **merge multiple resumes together** by specifying them in order from
|
||||
most generic to most specific:
|
||||
|
||||
```bash
|
||||
# Merge specific.json onto base.json and generate all formats
|
||||
fluentcv build base.json specific.json -o resume.all
|
||||
hackmyresume build base.json specific.json -o resume.all
|
||||
```
|
||||
|
||||
This can be useful for overriding a base (generic) resume with information from a specific (targeted) resume. For example, you might override your generic catch-all "software developer" resume with specific details from your targeted "game developer" resume, or combine two partial resumes into a "complete" resume. Merging follows conventional [extend()][9]-style behavior and there's no arbitrary limit to how many resumes you can merge:
|
||||
This can be useful for overriding a base (generic) resume with information from
|
||||
a specific (targeted) resume. For example, you might override your generic
|
||||
catch-all "software developer" resume with specific details from your targeted
|
||||
"game developer" resume, or combine two partial resumes into a "complete"
|
||||
resume. Merging follows conventional [extend()][9]-style behavior and there's
|
||||
no arbitrary limit to how many resumes you can merge:
|
||||
|
||||
```bash
|
||||
fluentcv 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: in2.json
|
||||
Reading JSON resume: in3.json
|
||||
@ -192,72 +205,75 @@ Generating WORD resume: out.doc
|
||||
|
||||
### Multiple targets
|
||||
|
||||
You can specify **multiple output targets** and FluentCV will build them:
|
||||
You can specify **multiple output targets** and HackMyResume will build them:
|
||||
|
||||
```bash
|
||||
# Generate out1.doc, out1.pdf, and foo.txt from me.json.
|
||||
fluentcv build me.json -o out1.doc -o out1.pdf -o foo.txt
|
||||
hackmyresume build me.json -o out1.doc -o out1.pdf -o foo.txt
|
||||
```
|
||||
|
||||
You can also omit the output file(s) and/or theme completely:
|
||||
|
||||
```bash
|
||||
# Equivalent to "fluentcv resume.json resume.all -t modern"
|
||||
fluentcv build resume.json
|
||||
# Equivalent to "hackmyresume resume.json resume.all -t modern"
|
||||
hackmyresume build resume.json
|
||||
```
|
||||
|
||||
### Using .all
|
||||
|
||||
The special `.all` extension tells FluentCV to generate all supported output formats for the given resume. For example, this...
|
||||
The special `.all` extension tells HackMyResume to generate all supported output
|
||||
formats for the given resume. For example, this...
|
||||
|
||||
```bash
|
||||
# Generate all resume formats (HTML, PDF, DOC, TXT, etc.)
|
||||
fluentcv build me.json -o out/resume.all
|
||||
hackmyresume build me.json -o out/resume.all
|
||||
```
|
||||
|
||||
..tells FluentCV to read `me.json` and generate `out/resume.md`, `out/resume.doc`, `out/resume.html`, `out/resume.txt`, `out/resume.pdf`, and `out/resume.json`.
|
||||
..tells HackMyResume to read `me.json` and generate `out/resume.md`,
|
||||
`out/resume.doc`, `out/resume.html`, `out/resume.txt`, `out/resume.pdf`, and
|
||||
`out/resume.json`.
|
||||
|
||||
### Validating
|
||||
|
||||
FluentCV can also validate your resumes against either the [FRESH /
|
||||
HackMyResume can also validate your resumes against either the [FRESH /
|
||||
FRESCA][fresca] or [JSON Resume][6] formats. To validate one or more existing
|
||||
resumes, use the `validate` command:
|
||||
|
||||
```bash
|
||||
# Validate myresume.json against either the FRESH or JSON Resume schema.
|
||||
fluentcv validate resumeA.json resumeB.json
|
||||
hackmyresume validate resumeA.json resumeB.json
|
||||
```
|
||||
|
||||
FluentCV will validate each specified resume in turn:
|
||||
HackMyResume will validate each specified resume in turn:
|
||||
|
||||
```bash
|
||||
*** FluentCV v0.9.0 ***
|
||||
*** HackMyResume v0.9.0 ***
|
||||
Validating JSON resume: resumeA.json (INVALID)
|
||||
Validating JSON resume: resumeB.json (VALID)
|
||||
```
|
||||
|
||||
### Converting
|
||||
|
||||
FluentCV can convert between the [FRESH][fresca] and [JSON Resume][6] formats.
|
||||
Just run:
|
||||
HackMyResume can convert between the [FRESH][fresca] and [JSON Resume][6]
|
||||
formats. Just run:
|
||||
|
||||
```bash
|
||||
fluentcv CONVERT <INPUTS> <OUTPUTS>
|
||||
hackmyresume CONVERT <INPUTS> <OUTPUTS>
|
||||
```
|
||||
|
||||
where <INPUTS> is one or more resumes in FRESH or JSON Resume format, and
|
||||
<OUTPUTS> is a corresponding list of output file names. FluentCV will autodetect
|
||||
the format (FRESH or JRS) of each input resume and convert it to the other
|
||||
format (JRS or FRESH).
|
||||
<OUTPUTS> is a corresponding list of output file names. HackMyResume will
|
||||
autodetect the format (FRESH or JRS) of each input resume and convert it to the
|
||||
other format (JRS or FRESH).
|
||||
|
||||
### Prettifying
|
||||
|
||||
FluentCV applies [js-beautify][10]-style HTML prettification by default to
|
||||
HackMyResume applies [js-beautify][10]-style HTML prettification by default to
|
||||
HTML-formatted resumes. To disable prettification, the `--nopretty` or `-n` flag
|
||||
can be used:
|
||||
|
||||
```bash
|
||||
fluentcv generate resume.json out.all --nopretty
|
||||
hackmyresume generate resume.json out.all --nopretty
|
||||
```
|
||||
|
||||
### Silent Mode
|
||||
@ -265,8 +281,8 @@ fluentcv generate resume.json out.all --nopretty
|
||||
Use `-s` or `--silent` to run in silent mode:
|
||||
|
||||
```bash
|
||||
fluentcv generate resume.json -o someFile.all -s
|
||||
fluentcv generate resume.json -o someFile.all --silent
|
||||
hackmyresume generate resume.json -o someFile.all -s
|
||||
hackmyresume generate resume.json -o someFile.all --silent
|
||||
```
|
||||
|
||||
## License
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 53 KiB |
BIN
assets/hackmyresume_cli.png
Normal file
BIN
assets/hackmyresume_cli.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
assets/resume-bouqet.png
Normal file
BIN
assets/resume-bouqet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
29
package.json
29
package.json
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "fluentcv",
|
||||
"version": "0.10.3",
|
||||
"name": "hackmyresume",
|
||||
"version": "1.0.1",
|
||||
"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": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fluentdesk/fluentcv.git"
|
||||
"url": "https://github.com/hacksalot/HackMyResume.git"
|
||||
},
|
||||
"keywords": [
|
||||
"resume",
|
||||
@ -18,23 +18,27 @@
|
||||
"PDF",
|
||||
"YAML",
|
||||
"HTML",
|
||||
"CLI"
|
||||
"LaTeX",
|
||||
"CLI",
|
||||
"Handlebars",
|
||||
"Underscore",
|
||||
"template"
|
||||
],
|
||||
"author": "James M. Devlin",
|
||||
"author": "hacksalot <hacksalot@fluentdesk.com> (https://github.com/hacksalot)",
|
||||
"license": "MIT",
|
||||
"preferGlobal": "true",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fluentdesk/fluentcv/issues"
|
||||
"url": "https://github.com/hacksalot/HackMyResume/issues"
|
||||
},
|
||||
"main": "src/fluentcmd.js",
|
||||
"main": "src/hackmycmd.js",
|
||||
"bin": {
|
||||
"fluentcv": "src/index.js"
|
||||
"hackmyresume": "src/index.js"
|
||||
},
|
||||
"homepage": "https://github.com/fluentdesk/fluentcv",
|
||||
"homepage": "https://github.com/hacksalot/HackMyResume",
|
||||
"dependencies": {
|
||||
"colors": "^1.1.2",
|
||||
"fluent-themes": "~0.6.3-beta",
|
||||
"fresca": "~0.2.1",
|
||||
"fluent-themes": "~0.7.0-beta",
|
||||
"fresca": "~0.2.2",
|
||||
"fs-extra": "^0.24.0",
|
||||
"handlebars": "^4.0.5",
|
||||
"html": "0.0.10",
|
||||
@ -54,10 +58,11 @@
|
||||
"devDependencies": {
|
||||
"chai": "*",
|
||||
"grunt": "*",
|
||||
"grunt-contrib-clean": "^0.7.0",
|
||||
"grunt-contrib-jshint": "^0.11.3",
|
||||
"grunt-contrib-yuidoc": "^0.10.0",
|
||||
"grunt-simple-mocha": "*",
|
||||
"is-my-json-valid": "^2.12.2",
|
||||
"jane-q-fullstacker": "fluentdesk/jane-q-fullstacker",
|
||||
"mocha": "*",
|
||||
"resample": "fluentdesk/resample"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
The FluentCV date representation.
|
||||
The HackMyResume date representation.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module fluent-date.js
|
||||
*/
|
||||
@ -13,7 +13,7 @@ formats to be aware of here.
|
||||
2. The default "YYYY-MM-DD" format used in JSON Resume ("2015-02-10")
|
||||
3. Year-and-month only ("2015-04")
|
||||
4. Year-only "YYYY" ("2015")
|
||||
5. The friendly FluentCV "mmm YYYY" format ("Mar 2015" or "Dec 2008")
|
||||
5. The friendly HackMyResume "mmm YYYY" format ("Mar 2015" or "Dec 2008")
|
||||
6. Empty dates ("", " ")
|
||||
7. Any other date format that Moment.js can parse from
|
||||
Note: Moment can transparently parse all or most of these, without requiring us
|
||||
|
@ -16,7 +16,7 @@ Definition of the Theme class.
|
||||
, RECURSIVE_READ_DIR = require('recursive-readdir-sync');
|
||||
|
||||
/**
|
||||
The Theme class is a representation of a FluentCV theme asset.
|
||||
The Theme class is a representation of a HackMyResume theme asset.
|
||||
@class Theme
|
||||
*/
|
||||
function Theme() {
|
||||
@ -100,6 +100,7 @@ Definition of the Theme class.
|
||||
var outFmt = '', isMajor = false;
|
||||
var portion = pathInfo.dir.replace(tplFolder,'');
|
||||
if( portion && portion.trim() ) {
|
||||
if( portion[1] === '_' ) return;
|
||||
var reg = /^(?:\/|\\)(html|latex|doc|pdf|partials)(?:\/|\\)?/ig;
|
||||
var res = reg.exec( portion );
|
||||
if( res ) {
|
||||
@ -152,7 +153,7 @@ Definition of the Theme class.
|
||||
.forEach(function( cssf ) {
|
||||
// For each CSS file, get its corresponding HTML file
|
||||
var idx = _.findIndex(fmts, function( fmt ) {
|
||||
return fmt.pre === cssf.pre && fmt.ext === 'html';
|
||||
return fmt && fmt.pre === cssf.pre && fmt.ext === 'html';
|
||||
});
|
||||
cssf.action = null;
|
||||
fmts[ idx ].css = cssf.data;
|
||||
|
@ -11,93 +11,40 @@ Definition of the HandlebarsGenerator class.
|
||||
var _ = require('underscore')
|
||||
, HANDLEBARS = require('handlebars')
|
||||
, FS = require('fs')
|
||||
, moment = require('moment')
|
||||
, MD = require('marked')
|
||||
, H2W = require('../utils/html-to-wpml');
|
||||
, registerHelpers = require('./handlebars-helpers');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Perform template-based resume generation using Handlebars.js.
|
||||
@method generate
|
||||
@class HandlebarsGenerator
|
||||
*/
|
||||
module.exports = function( json, jst, format, cssInfo, opts, theme ) {
|
||||
var HandlebarsGenerator = module.exports = {
|
||||
|
||||
// Pre-compile any partials present in the theme.
|
||||
_.each( theme.partials, function( el ) {
|
||||
var tplData = FS.readFileSync( el.path, 'utf8' );
|
||||
var compiledTemplate = HANDLEBARS.compile( tplData );
|
||||
HANDLEBARS.registerPartial( el.name, compiledTemplate );
|
||||
});
|
||||
generate: function( json, jst, format, cssInfo, opts, theme ) {
|
||||
|
||||
// Register necessary helpers.
|
||||
registerHelpers();
|
||||
// Pre-compile any partials present in the theme.
|
||||
_.each( theme.partials, function( el ) {
|
||||
var tplData = FS.readFileSync( el.path, 'utf8' );
|
||||
var compiledTemplate = HANDLEBARS.compile( tplData );
|
||||
HANDLEBARS.registerPartial( el.name, compiledTemplate );
|
||||
});
|
||||
|
||||
// Compile and run the Handlebars template.
|
||||
var template = HANDLEBARS.compile(jst);
|
||||
return template({
|
||||
r: json,
|
||||
filt: opts.filters,
|
||||
cssInfo: cssInfo,
|
||||
headFragment: opts.headFragment || ''
|
||||
});
|
||||
// Register necessary helpers.
|
||||
registerHelpers();
|
||||
|
||||
// Compile and run the Handlebars template.
|
||||
var template = HANDLEBARS.compile(jst);
|
||||
return template({
|
||||
r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
|
||||
RAW: json,
|
||||
filt: opts.filters,
|
||||
cssInfo: cssInfo,
|
||||
headFragment: opts.headFragment || ''
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Register useful Handlebars helpers.
|
||||
@method registerHelpers
|
||||
*/
|
||||
function registerHelpers() {
|
||||
|
||||
// Set up a date formatting helper so we can do:
|
||||
// {{#formatDate val 'YYYY-MM'}}
|
||||
HANDLEBARS.registerHelper("formatDate", function(datetime, format) {
|
||||
if( moment ) {
|
||||
return moment( datetime ).format( format );
|
||||
}
|
||||
else {
|
||||
return datetime;
|
||||
}
|
||||
});
|
||||
|
||||
// Set up a Markdown-to-WordProcessingML helper so we can do:
|
||||
// {{#wmpl val [true|false]}}
|
||||
HANDLEBARS.registerHelper("wpml", function( txt, inline ) {
|
||||
inline = (inline && !inline.hash) || false;
|
||||
txt = inline ?
|
||||
MD(txt.trim()).replace(/^\s*<p>|<\/p>\s*$/gi, '') :
|
||||
MD(txt.trim());
|
||||
txt = H2W( txt.trim() );
|
||||
return txt;
|
||||
});
|
||||
|
||||
// Set up a generic conditional helper so we can do:
|
||||
// {{#compare val otherVal operator="<"}}
|
||||
// http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/
|
||||
HANDLEBARS.registerHelper('compare', function(lvalue, rvalue, options) {
|
||||
if (arguments.length < 3)
|
||||
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
|
||||
var operator = options.hash.operator || "==";
|
||||
var operators = {
|
||||
'==': function(l,r) { return l == r; },
|
||||
'===': function(l,r) { return l === r; },
|
||||
'!=': function(l,r) { return l != r; },
|
||||
'<': function(l,r) { return l < r; },
|
||||
'>': function(l,r) { return l > r; },
|
||||
'<=': function(l,r) { return l <= r; },
|
||||
'>=': function(l,r) { return l >= r; },
|
||||
'typeof': function(l,r) { return typeof l == r; }
|
||||
};
|
||||
if (!operators[operator])
|
||||
throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
|
||||
var result = operators[operator](lvalue,rvalue);
|
||||
return result ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}());
|
||||
|
124
src/eng/handlebars-helpers.js
Normal file
124
src/eng/handlebars-helpers.js
Normal file
@ -0,0 +1,124 @@
|
||||
/**
|
||||
Template helper definitions for Handlebars.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module handlebars-helpers.js
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
var HANDLEBARS = require('handlebars')
|
||||
, MD = require('marked')
|
||||
, H2W = require('../utils/html-to-wpml')
|
||||
, moment = require('moment')
|
||||
, _ = require('underscore');
|
||||
|
||||
/**
|
||||
Register useful Handlebars helpers.
|
||||
@method registerHelpers
|
||||
*/
|
||||
module.exports = function() {
|
||||
|
||||
// Set up a date formatting helper so we can do:
|
||||
// {{formatDate val 'YYYY-MM'}}
|
||||
HANDLEBARS.registerHelper("formatDate", function(datetime, format) {
|
||||
return moment ? moment( datetime ).format( format ) : datetime;
|
||||
});
|
||||
|
||||
// Set up a Markdown-to-WordProcessingML helper so we can do:
|
||||
// {{wmpl val [true|false]}}
|
||||
HANDLEBARS.registerHelper("wpml", function( txt, inline ) {
|
||||
if(!txt) return '';
|
||||
inline = (inline && !inline.hash) || false;
|
||||
txt = inline ?
|
||||
MD(txt.trim()).replace(/^\s*<p>|<\/p>\s*$/gi, '') :
|
||||
MD(txt.trim());
|
||||
txt = H2W( txt.trim() );
|
||||
return txt;
|
||||
});
|
||||
|
||||
// Set up a last-word helper so we can do:
|
||||
// {{lastWord val [true|false]}}
|
||||
HANDLEBARS.registerHelper("link", function( text, url ) {
|
||||
return url && url.trim() ?
|
||||
('<a href="' + url + '">' + text + '</a>') : text;
|
||||
});
|
||||
|
||||
// Set up a last-word helper so we can do:
|
||||
// {{lastWord val [true|false]}}
|
||||
HANDLEBARS.registerHelper("lastWord", function( txt ) {
|
||||
return txt && txt.trim() ? _.last( txt.split(' ') ) : '';
|
||||
});
|
||||
|
||||
// Set up a skill colorizing helper:
|
||||
// {{skillColor val}}
|
||||
HANDLEBARS.registerHelper("skillColor", function( lvl ) {
|
||||
switch(lvl) {
|
||||
case 'beginner': return '#5CB85C';
|
||||
case 'intermediate': return '#F1C40F';
|
||||
case 'advanced': return '#428BCA';
|
||||
case 'master': return '#C00000';
|
||||
}
|
||||
});
|
||||
|
||||
// Set up a skill colorizing helper:
|
||||
// {{skillColor val}}
|
||||
HANDLEBARS.registerHelper("skillHeight", function( lvl ) {
|
||||
switch(lvl) {
|
||||
case 'beginner': return '30';
|
||||
case 'intermediate': return '16';
|
||||
case 'advanced': return '8';
|
||||
case 'master': return '0';
|
||||
}
|
||||
});
|
||||
|
||||
// Set up a Markdown-to-WordProcessingML helper so we can do:
|
||||
// {{initialWords val [true|false]}}
|
||||
HANDLEBARS.registerHelper("initialWords", function( txt ) {
|
||||
return txt && txt.trim() ? _.initial( txt.split(' ') ).join(' ') : '';
|
||||
});
|
||||
|
||||
// Set up a URL-trimming helper to drop the protocol so we can do:
|
||||
// {{trimURL url}}
|
||||
HANDLEBARS.registerHelper("trimURL", function( url ) {
|
||||
return url && url.trim() ? url.trim().replace(/^https?:\/\//i, '') : '';
|
||||
});
|
||||
|
||||
// Set up a URL-trimming helper to drop the protocol so we can do:
|
||||
// {{trimURL url}}
|
||||
HANDLEBARS.registerHelper("toLower", function( txt ) {
|
||||
return txt && txt.trim() ? txt.toLowerCase() : '';
|
||||
});
|
||||
|
||||
// Set up a Markdown-to-WordProcessingML helper so we can do:
|
||||
// {{either A B}}
|
||||
HANDLEBARS.registerHelper("either", function( lhs, rhs, options ) {
|
||||
if (lhs || rhs) return options.fn(this);
|
||||
});
|
||||
|
||||
// Set up a generic conditional helper so we can do:
|
||||
// {{compare val otherVal operator="<"}}
|
||||
// http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates/
|
||||
HANDLEBARS.registerHelper('compare', function(lvalue, rvalue, options) {
|
||||
if (arguments.length < 3)
|
||||
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
|
||||
var operator = options.hash.operator || "==";
|
||||
var operators = {
|
||||
'==': function(l,r) { return l == r; },
|
||||
'===': function(l,r) { return l === r; },
|
||||
'!=': function(l,r) { return l != r; },
|
||||
'<': function(l,r) { return l < r; },
|
||||
'>': function(l,r) { return l > r; },
|
||||
'<=': function(l,r) { return l <= r; },
|
||||
'>=': function(l,r) { return l >= r; },
|
||||
'typeof': function(l,r) { return typeof l == r; }
|
||||
};
|
||||
if (!operators[operator])
|
||||
throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
|
||||
var result = operators[operator](lvalue,rvalue);
|
||||
return result ? options.fn(this) : options.inverse(this);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}());
|
@ -1,37 +1,52 @@
|
||||
/**
|
||||
Definition of the UnderscoreGenerator class.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module underscore-generator.js
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
|
||||
|
||||
var _ = require('underscore');
|
||||
|
||||
module.exports = function( json, jst, format, cssInfo, opts, theme ) {
|
||||
|
||||
// Tweak underscore's default template delimeters
|
||||
var delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
|
||||
if( opts.themeObj && opts.themeObj.delimeters ) {
|
||||
delims = _.mapObject( delims, function(val,key) {
|
||||
return new RegExp( val, "ig");
|
||||
|
||||
/**
|
||||
Perform template-based resume generation using Underscore.js.
|
||||
@class UnderscoreGenerator
|
||||
*/
|
||||
var UnderscoreGenerator = module.exports = {
|
||||
|
||||
generate: function( json, jst, format, cssInfo, opts, theme ) {
|
||||
|
||||
// Tweak underscore's default template delimeters
|
||||
var delims = (opts.themeObj && opts.themeObj.delimeters) || opts.template;
|
||||
if( opts.themeObj && opts.themeObj.delimeters ) {
|
||||
delims = _.mapObject( delims, function(val,key) {
|
||||
return new RegExp( val, "ig");
|
||||
});
|
||||
}
|
||||
_.templateSettings = delims;
|
||||
|
||||
// Strip {# comments #}
|
||||
jst = jst.replace( delims.comment, '');
|
||||
|
||||
// Compile and run the template. TODO: avoid unnecessary recompiles.
|
||||
var compiled = _.template(jst);
|
||||
var ret = compiled({
|
||||
r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
|
||||
filt: opts.filters,
|
||||
XML: require('xml-escape'),
|
||||
RAW: json,
|
||||
cssInfo: cssInfo,
|
||||
headFragment: opts.headFragment || ''
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
_.templateSettings = delims;
|
||||
|
||||
// Strip {# comments #}
|
||||
jst = jst.replace( delims.comment, '');
|
||||
// Compile and run the template. TODO: avoid unnecessary recompiles.
|
||||
var compiled = _.template(jst);
|
||||
var ret = compiled({
|
||||
r: format === 'html' || format === 'pdf' ? json.markdownify() : json,
|
||||
filt: opts.filters,
|
||||
XML: require('xml-escape'),
|
||||
RAW: json,
|
||||
cssInfo: cssInfo,
|
||||
headFragment: opts.headFragment || ''
|
||||
});
|
||||
return ret;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}());
|
||||
|
@ -11,7 +11,7 @@ Definition of the HtmlPdfGenerator class.
|
||||
, HTML = require( 'html' );
|
||||
|
||||
/**
|
||||
An HTML-based PDF resume generator for FluentCV.
|
||||
An HTML-based PDF resume generator for HackMyResume.
|
||||
*/
|
||||
var HtmlPdfGenerator = module.exports = TemplateGenerator.extend({
|
||||
|
||||
|
@ -142,9 +142,8 @@ Definition of the TemplateGenerator class.
|
||||
*/
|
||||
single: function( json, jst, format, cssInfo, opts, theme ) {
|
||||
this.opts.freezeBreaks && ( jst = freeze(jst) );
|
||||
var eng = require( '../eng/' + ((opts.themeObj && opts.themeObj.engine) ||
|
||||
opts.engine) + '-generator' );
|
||||
var result = eng( json, jst, format, cssInfo, opts, theme );
|
||||
var eng = require( '../eng/' + theme.engine + '-generator' );
|
||||
var result = eng.generate( json, jst, format, cssInfo, opts, theme );
|
||||
this.opts.freezeBreaks && ( result = unfreeze(result) );
|
||||
return result;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
External API surface for FluentCV:CLI.
|
||||
External API surface for HackMyResume.
|
||||
@license MIT. Copyright (c) 2015 James M. Devlin / FluentDesk.
|
||||
@module fluentlib.js
|
||||
@module hackmyapi.js
|
||||
*/
|
||||
|
||||
module.exports = {
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
Internal resume generation logic for FluentCV.
|
||||
Internal resume generation logic for HackMyResume.
|
||||
@license MIT. Copyright (c) 2015 James M. Devlin / FluentDesk.
|
||||
@module fluentcmd.js
|
||||
@module hackmycmd.js
|
||||
*/
|
||||
|
||||
(function() {
|
||||
@ -12,7 +12,7 @@ Internal resume generation logic for FluentCV.
|
||||
, unused = require('./utils/string')
|
||||
, FS = require('fs')
|
||||
, _ = require('underscore')
|
||||
, FLUENT = require('./fluentlib')
|
||||
, FLUENT = require('./hackmyapi')
|
||||
, PATH = require('path')
|
||||
, MKDIRP = require('mkdirp')
|
||||
//, COLORS = require('colors')
|
||||
@ -106,7 +106,7 @@ Internal resume generation logic for FluentCV.
|
||||
|
||||
_log( 'Generating '.useful +
|
||||
targInfo.fmt.outFormat.toUpperCase().useful.bold +
|
||||
' resume: '.useful + path.relative(process.cwd(), f ).useful.bold);
|
||||
' resume: '.useful + path.relative(process.cwd(), f ).replace(/\\/g,'/').useful.bold);
|
||||
|
||||
theFormat = _fmts.filter(
|
||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||
@ -133,7 +133,7 @@ Internal resume generation logic for FluentCV.
|
||||
else {
|
||||
_log( 'Generating '.useful +
|
||||
targInfo.fmt.outFormat.toUpperCase().useful.bold +
|
||||
' resume: '.useful + path.relative(process.cwd(), f ).useful.bold);
|
||||
' resume: '.useful + path.relative(process.cwd(), f ).replace(/\\/g,'/').useful.bold);
|
||||
|
||||
theFormat = _fmts.filter(
|
||||
function(fmt) { return fmt.name === targInfo.fmt.outFormat; })[0];
|
||||
@ -312,7 +312,7 @@ Internal resume generation logic for FluentCV.
|
||||
];
|
||||
|
||||
/**
|
||||
Default FluentCV options.
|
||||
Default HackMyResume options.
|
||||
*/
|
||||
var _opts = {
|
||||
theme: 'modern',
|
||||
@ -335,7 +335,7 @@ Internal resume generation logic for FluentCV.
|
||||
new: create,
|
||||
help: help
|
||||
},
|
||||
lib: require('./fluentlib'),
|
||||
lib: require('./hackmyapi'),
|
||||
options: _opts,
|
||||
formats: _fmts
|
||||
};
|
@ -1,19 +1,19 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
/**
|
||||
Command-line interface (CLI) for FluentCV:CLI.
|
||||
Command-line interface (CLI) for HackMyResume.
|
||||
@license MIT. Copyright (c) 2015 James M. Devlin / FluentDesk.
|
||||
@module index.js
|
||||
*/
|
||||
|
||||
var ARGS = require( 'minimist' )
|
||||
, FCMD = require( './fluentcmd')
|
||||
, FCMD = require( './hackmycmd')
|
||||
, PKG = require('../package.json')
|
||||
, COLORS = require('colors')
|
||||
, FS = require('fs')
|
||||
, PATH = require('path')
|
||||
, opts = { }
|
||||
, title = ('*** FluentCV v' + PKG.version + ' ***').bold.white
|
||||
, title = ('\n*** HackMyResume v' + PKG.version + ' ***').bold.white
|
||||
, _ = require('underscore');
|
||||
|
||||
|
||||
|
18
src/use.txt
18
src/use.txt
@ -1,6 +1,6 @@
|
||||
Usage:
|
||||
|
||||
fluentcv <COMMAND> <SOURCES> [TO <TARGETS>] [-t <THEME>] [-f <FORMAT>]
|
||||
hackmyresume <COMMAND> <SOURCES> [TO <TARGETS>] [-t <THEME>] [-f <FORMAT>]
|
||||
|
||||
<COMMAND> should be BUILD, NEW, CONVERT, VALIDATE, or HELP. <SOURCES> should
|
||||
be the path to one or more FRESH or JSON Resume format resumes. <TARGETS>
|
||||
@ -10,16 +10,16 @@ COMPACT, MINIMIST, MODERN, or HELLO-WORLD) or the relative path to a custom
|
||||
theme. <FORMAT> should be either FRESH (for a FRESH-format resume) or JRS
|
||||
(for a JSON Resume-format resume).
|
||||
|
||||
fluentcv BUILD resume.json TO out/resume.all
|
||||
fluentcv NEW resume.json
|
||||
fluentcv CONVERT resume.json TO resume-jrs.json
|
||||
fluentcv VALIDATE resume.json
|
||||
hackmyresume BUILD resume.json TO out/resume.all
|
||||
hackmyresume NEW resume.json
|
||||
hackmyresume CONVERT resume.json TO resume-jrs.json
|
||||
hackmyresume VALIDATE resume.json
|
||||
|
||||
Both SOURCES and TARGETS can accept multiple files:
|
||||
|
||||
fluentCV BUILD r1.json r2.json TO out/resume.all out2/resume.html
|
||||
fluentCV NEW r1.json r2.json r3.json
|
||||
fluentCV VALIDATE resume.json resume2.json resume3.json
|
||||
hackmyresume BUILD r1.json r2.json TO out/resume.all out2/resume.html
|
||||
hackmyresume NEW r1.json r2.json r3.json
|
||||
hackmyresume VALIDATE resume.json resume2.json resume3.json
|
||||
|
||||
See https://github.com/fluentdesk/fluentCV/blob/master/README.md for more
|
||||
See https://github.com/hacksalot/hackmyresume/blob/master/README.md for more
|
||||
information.
|
||||
|
@ -11,49 +11,49 @@ Definition of the Markdown to WordProcessingML conversion routine.
|
||||
|
||||
module.exports = function( html ) {
|
||||
|
||||
var final = '';
|
||||
var is_bold = false, is_italic = false, is_link = false;
|
||||
var depth = 0;
|
||||
|
||||
// Tokenize the HTML stream.
|
||||
var tokens = HTML5Tokenizer.tokenize( html );
|
||||
|
||||
var final = '', is_bold, is_italic, is_link, link_url;
|
||||
|
||||
// Process <em>, <strong>, and <a> elements in the HTML stream, producing
|
||||
// equivalent WordProcessingML that can be dumped into a <w:p> or other
|
||||
// text container element.
|
||||
_.each( tokens, function( tok ) {
|
||||
|
||||
switch( tok.type ) {
|
||||
|
||||
case 'StartTag':
|
||||
switch( tok.tagName ) {
|
||||
case 'p':
|
||||
final += '<w:p>';
|
||||
break;
|
||||
case 'strong':
|
||||
is_bold = true;
|
||||
break;
|
||||
case 'em':
|
||||
is_italic = true;
|
||||
break;
|
||||
case 'p': final += '<w:p>'; break;
|
||||
case 'strong': is_bold = true; break;
|
||||
case 'em': is_italic = true; break;
|
||||
case 'a':
|
||||
is_link = true;
|
||||
link_url = tok.attributes.filter(function(attr){
|
||||
return attr[0] === 'href'; }
|
||||
)[0][1];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'EndTag':
|
||||
switch( tok.tagName ) {
|
||||
case 'p':
|
||||
final += '</w:p>';
|
||||
break;
|
||||
case 'strong':
|
||||
is_bold = false;
|
||||
break;
|
||||
case 'em':
|
||||
is_italic = false;
|
||||
break;
|
||||
case 'a':
|
||||
is_link = false;
|
||||
break;
|
||||
case 'p': final += '</w:p>'; break;
|
||||
case 'strong': is_bold = false; break;
|
||||
case 'em': is_italic = false; break;
|
||||
case 'a': is_link = false; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Chars':
|
||||
var style = is_bold ? '<w:b/>' : '';
|
||||
style += is_italic ? '<w:i/>': '';
|
||||
final += '<w:r><w:rPr>' + style + '</w:rPr><w:t>' + tok.chars + '</w:t></w:r>';
|
||||
style += is_link ? '<w:rStyle w:val="Hyperlink"/>' : '';
|
||||
final +=
|
||||
(is_link ? ('<w:hlink w:dest="' + link_url + '">') : '') +
|
||||
'<w:r><w:rPr>' + style + '</w:rPr><w:t>' + tok.chars +
|
||||
'</w:t></w:r>' + (is_link ? '</w:hlink>' : '');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -1,14 +1,14 @@
|
||||
{
|
||||
"basics": {
|
||||
"name": "Jane Doe",
|
||||
"label": "Senior Developer / Code Ninja",
|
||||
"name": "Jane Q. Fullstacker",
|
||||
"label": "Senior Developer",
|
||||
"summary": "**Full-stack software developer with 6+ years industry experience** specializing in scalable cloud architectures for this, that, and the other. A native of southern CA, Jane enjoys hiking, mystery novels, and the company of Rufus, her two-year-old beagle.",
|
||||
"website": "http://jane-doe.me",
|
||||
"website": "http://janef.me/blog",
|
||||
"phone": "1-650-999-7777",
|
||||
"email": "jdoe@onecoolstartup.io",
|
||||
"picture": "jane_doe.png",
|
||||
"location": {
|
||||
"address": "Jane Doe\n123 Somewhere Rd.\nMountain View, CA 94035",
|
||||
"address": "Jane Fullstacker\n123 Somewhere Rd.\nMountain View, CA 94035",
|
||||
"postalCode": "94035",
|
||||
"city": "Mountain View",
|
||||
"countryCode": "US",
|
||||
@ -17,13 +17,13 @@
|
||||
"profiles": [
|
||||
{
|
||||
"network": "GitHub",
|
||||
"username": "jane-doe-was-here",
|
||||
"url": "https://github.com/jane-doe-was-here"
|
||||
"username": "janef-was-here",
|
||||
"url": "https://github.com/janef-was-here"
|
||||
},
|
||||
{
|
||||
"network": "Twitter",
|
||||
"username": "jane-doe-was-here",
|
||||
"url": "https://twitter.com/jane-doe-was-here"
|
||||
"username": "janef-was-here",
|
||||
"url": "https://twitter.com/janef-was-here"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -104,17 +104,55 @@
|
||||
],
|
||||
"skills": [
|
||||
{
|
||||
"name": "Programming",
|
||||
"name": "Web Dev",
|
||||
"keywords": [
|
||||
"C++",
|
||||
"Ruby",
|
||||
"Xcode"
|
||||
"JavaScript",
|
||||
"HTML 5",
|
||||
"CSS",
|
||||
"LAMP",
|
||||
"MVC",
|
||||
"REST"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Project Management",
|
||||
"name": "JavaScript",
|
||||
"keywords": [
|
||||
"Agile"
|
||||
"Node.js",
|
||||
"Angular.js",
|
||||
"jQuery",
|
||||
"Bootstrap",
|
||||
"React.js",
|
||||
"Backbone.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Database",
|
||||
"keywords": [
|
||||
"MySQL",
|
||||
"PostgreSQL",
|
||||
"NoSQL",
|
||||
"ORM",
|
||||
"Hibernate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Cloud",
|
||||
"keywords": [
|
||||
"AWS",
|
||||
"EC2",
|
||||
"RDS",
|
||||
"S3",
|
||||
"Azure",
|
||||
"Dropbox"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Project",
|
||||
"keywords": [
|
||||
"Agile",
|
||||
"TFS",
|
||||
"Unified Process",
|
||||
"MS Project"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -166,10 +204,10 @@
|
||||
"website": "http://codeproject.com/build-ui-electron-atom.aspx"
|
||||
},
|
||||
{
|
||||
"name": "Jane Doe Unplugged",
|
||||
"name": "Jane Fullstacker's Blog",
|
||||
"publisher": "self",
|
||||
"releaseDate": "2011",
|
||||
"website": "http://jane-doe.me"
|
||||
"website": "http://janef.me"
|
||||
},
|
||||
{
|
||||
"name": "Teach Yourself GORFF in 21 Days",
|
||||
@ -218,7 +256,8 @@
|
||||
},
|
||||
{
|
||||
"language": "Spanish",
|
||||
"level": "Moderate"
|
||||
"level": "Moderate",
|
||||
"years": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ var chai = require('chai')
|
||||
, FRESHResume = require('../src/core/fresh-resume')
|
||||
, CONVERTER = require('../src/core/convert')
|
||||
, FS = require('fs')
|
||||
, MKDIRP = require('mkdirp')
|
||||
, _ = require('underscore');
|
||||
|
||||
chai.config.includeStack = false;
|
||||
@ -21,6 +22,7 @@ describe('FRESH/JRS converter', function () {
|
||||
var fileB = path.join( __dirname, 'sandbox/richard-hendriks.json' );
|
||||
|
||||
_sheet = new FRESHResume().open( fileA );
|
||||
MKDIRP.sync( path.parse(fileB).dir );
|
||||
_sheet.saveAs( fileB, 'JRS' );
|
||||
|
||||
var rawA = FS.readFileSync( fileA, 'utf8' );
|
||||
|
@ -16,7 +16,7 @@ describe('jane-doe.json (FRESH)', function () {
|
||||
it('should open without throwing an exception', function () {
|
||||
function tryOpen() {
|
||||
_sheet = new FRESHResume().open(
|
||||
'node_modules/FRESCA/exemplar/jane-doe.json' );
|
||||
'node_modules/jane-q-fullstacker/resume/jane-resume.json' );
|
||||
}
|
||||
tryOpen.should.not.Throw();
|
||||
});
|
||||
@ -43,13 +43,13 @@ describe('jane-doe.json (FRESH)', function () {
|
||||
|
||||
it('should save without throwing an exception', function(){
|
||||
function trySave() {
|
||||
_sheet.save( 'tests/sandbox/jane-doe.json' );
|
||||
_sheet.save( 'tests/sandbox/jane-q-fullstacker.json' );
|
||||
}
|
||||
trySave.should.not.Throw();
|
||||
});
|
||||
|
||||
it('should not be modified after saving', function() {
|
||||
var savedSheet = new FRESHResume().open('tests/sandbox/jane-doe.json');
|
||||
var savedSheet = new FRESHResume().open('tests/sandbox/jane-q-fullstacker.json');
|
||||
_sheet.stringify().should.equal( savedSheet.stringify() )
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,7 @@ describe('jane-doe.json (JRS)', function () {
|
||||
it('should open without throwing an exception', function () {
|
||||
function tryOpen() {
|
||||
_sheet = new JRSResume().open(
|
||||
path.join( __dirname, 'resumes/jrs/jane-doe.json' ) );
|
||||
path.join( __dirname, 'resumes/jrs/jane-q-fullstacker.json' ) );
|
||||
}
|
||||
tryOpen.should.not.Throw();
|
||||
});
|
||||
@ -39,13 +39,13 @@ describe('jane-doe.json (JRS)', function () {
|
||||
|
||||
it('should save without throwing an exception', function(){
|
||||
function trySave() {
|
||||
_sheet.save( 'tests/sandbox/jane-doe.json' );
|
||||
_sheet.save( 'tests/sandbox/jane-q-fullstacker.json' );
|
||||
}
|
||||
trySave.should.not.Throw();
|
||||
});
|
||||
|
||||
it('should not be modified after saving', function() {
|
||||
var savedSheet = new JRSResume().open( 'tests/sandbox/jane-doe.json' );
|
||||
var savedSheet = new JRSResume().open( 'tests/sandbox/jane-q-fullstacker.json' );
|
||||
_sheet.stringify().should.equal( savedSheet.stringify() )
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ var chai = require('chai')
|
||||
, path = require('path')
|
||||
, _ = require('underscore')
|
||||
, FRESHResume = require('../src/core/fresh-resume')
|
||||
, FCMD = require( '../src/fluentcmd')
|
||||
, FCMD = require( '../src/hackmycmd')
|
||||
, validator = require('is-my-json-valid')
|
||||
, COLORS = require('colors');
|
||||
|
||||
@ -29,8 +29,8 @@ describe('Testing themes', function () {
|
||||
function genTheme( themeName ) {
|
||||
it( themeName.toUpperCase() + ' theme should generate without throwing an exception', function () {
|
||||
function tryOpen() {
|
||||
var src = ['node_modules/FRESCA/exemplar/jane-doe.json'];
|
||||
var dst = ['tests/sandbox/hello-world/resume.all'];
|
||||
var src = ['node_modules/jane-q-fullstacker/resume/jane-resume.json'];
|
||||
var dst = ['tests/sandbox/' + themeName + '/resume.all'];
|
||||
var opts = {
|
||||
theme: themeName,
|
||||
format: 'FRESH',
|
||||
@ -48,5 +48,6 @@ describe('Testing themes', function () {
|
||||
genTheme('modern');
|
||||
genTheme('minimist');
|
||||
genTheme('awesome');
|
||||
genTheme('positive');
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user