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