mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2025-05-02 20:37:08 +01:00
Finish HackMyCore reshaping.
Reintroduce HackMyCore, dropping the interim submodule, and reorganize and improve tests.
This commit is contained in:
64
dist/helpers/console-helpers.js
vendored
Normal file
64
dist/helpers/console-helpers.js
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
/**
|
||||
Generic template helper definitions for command-line output.
|
||||
@module console-helpers.js
|
||||
@license MIT. See LICENSE.md for details.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var CHALK, LO, PAD, _, consoleFormatHelpers;
|
||||
|
||||
PAD = require('string-padding');
|
||||
|
||||
LO = require('lodash');
|
||||
|
||||
CHALK = require('chalk');
|
||||
|
||||
_ = require('underscore');
|
||||
|
||||
require('../utils/string');
|
||||
|
||||
consoleFormatHelpers = module.exports = {
|
||||
v: function(val, defaultVal, padding, style) {
|
||||
var retVal, spaces;
|
||||
retVal = val === null || val === void 0 ? defaultVal : val;
|
||||
spaces = 0;
|
||||
if (String.is(padding)) {
|
||||
spaces = parseInt(padding, 10);
|
||||
if (isNaN(spaces)) {
|
||||
spaces = 0;
|
||||
}
|
||||
} else if (_.isNumber(padding)) {
|
||||
spaces = padding;
|
||||
}
|
||||
if (spaces !== 0) {
|
||||
retVal = PAD(retVal, Math.abs(spaces), null, spaces > 0 ? PAD.LEFT : PAD.RIGHT);
|
||||
}
|
||||
if (style && String.is(style)) {
|
||||
retVal = LO.get(CHALK, style)(retVal);
|
||||
}
|
||||
return retVal;
|
||||
},
|
||||
gapLength: function(val) {
|
||||
if (val < 35) {
|
||||
return CHALK.green.bold(val);
|
||||
} else if (val < 95) {
|
||||
return CHALK.yellow.bold(val);
|
||||
} else {
|
||||
return CHALK.red.bold(val);
|
||||
}
|
||||
},
|
||||
style: function(val, style) {
|
||||
return LO.get(CHALK, style)(val);
|
||||
},
|
||||
isPlural: function(val, options) {
|
||||
if (val > 1) {
|
||||
return options.fn(this);
|
||||
}
|
||||
},
|
||||
pad: function(val, spaces) {
|
||||
return PAD(val, Math.abs(spaces), null, spaces > 0 ? PAD.LEFT : PAD.RIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
612
dist/helpers/generic-helpers.js
vendored
Normal file
612
dist/helpers/generic-helpers.js
vendored
Normal file
@ -0,0 +1,612 @@
|
||||
|
||||
/**
|
||||
Generic template helper definitions for HackMyResume / FluentCV.
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module helpers/generic-helpers
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var FS, FluentDate, GenericHelpers, H2W, HMSTATUS, LO, MD, PATH, XML, _, _fromTo, _reportError, moment, printf, skillLevelToIndex, unused;
|
||||
|
||||
MD = require('marked');
|
||||
|
||||
H2W = require('../utils/html-to-wpml');
|
||||
|
||||
XML = require('xml-escape');
|
||||
|
||||
FluentDate = require('../core/fluent-date');
|
||||
|
||||
HMSTATUS = require('../core/status-codes');
|
||||
|
||||
moment = require('moment');
|
||||
|
||||
FS = require('fs');
|
||||
|
||||
LO = require('lodash');
|
||||
|
||||
PATH = require('path');
|
||||
|
||||
printf = require('printf');
|
||||
|
||||
_ = require('underscore');
|
||||
|
||||
unused = require('../utils/string');
|
||||
|
||||
|
||||
/** Generic template helper function definitions. */
|
||||
|
||||
GenericHelpers = module.exports = {
|
||||
|
||||
/**
|
||||
Convert the input date to a specified format through Moment.js.
|
||||
If date is invalid, will return the time provided by the user,
|
||||
or default to the fallback param or 'Present' if that is set to true
|
||||
@method formatDate
|
||||
*/
|
||||
formatDate: function(datetime, format, fallback) {
|
||||
var momentDate, ref, ref1;
|
||||
if (moment) {
|
||||
momentDate = moment(datetime);
|
||||
if (momentDate.isValid()) {
|
||||
return momentDate.format(format);
|
||||
}
|
||||
}
|
||||
return datetime || ((ref = typeof fallback === 'string') != null ? ref : {
|
||||
fallback: (ref1 = fallback === true) != null ? ref1 : {
|
||||
'Present': null
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Given a resume sub-object with a start/end date, format a representation of
|
||||
the date range.
|
||||
@method dateRange
|
||||
*/
|
||||
dateRange: function(obj, fmt, sep, fallback, options) {
|
||||
if (!obj) {
|
||||
return '';
|
||||
}
|
||||
return _fromTo(obj.start, obj.end, fmt, sep, fallback, options);
|
||||
},
|
||||
|
||||
/**
|
||||
Format a from/to date range for display.
|
||||
@method toFrom
|
||||
*/
|
||||
fromTo: function() {
|
||||
return _fromTo.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
Return a named color value as an RRGGBB string.
|
||||
@method toFrom
|
||||
*/
|
||||
color: function(colorName, colorDefault) {
|
||||
var ret;
|
||||
if (!(colorName && colorName.trim())) {
|
||||
return _reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontList',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'name'
|
||||
});
|
||||
} else {
|
||||
if (!GenericHelpers.theme.colors) {
|
||||
return colorDefault;
|
||||
}
|
||||
ret = GenericHelpers.theme.colors[colorName];
|
||||
if (!(ret && ret.trim())) {
|
||||
return colorDefault;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Return true if the section is present on the resume and has at least one
|
||||
element.
|
||||
@method section
|
||||
*/
|
||||
section: function(title, options) {
|
||||
var obj;
|
||||
title = title.trim().toLowerCase();
|
||||
obj = LO.get(this.r, title);
|
||||
if (_.isArray(obj)) {
|
||||
if (obj.length) {
|
||||
return options.fn(this);
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
} else if (_.isObject(obj)) {
|
||||
return (obj.history && obj.history.length) || (obj.sets && obj.sets.length ? options.fn(this) : void 0);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Emit the size of the specified named font.
|
||||
@param key {String} A named style from the "fonts" section of the theme's
|
||||
theme.json file. For example: 'default' or 'heading1'.
|
||||
*/
|
||||
fontSize: function(key, defSize, units) {
|
||||
var fontSpec, hasDef, ret;
|
||||
ret = '';
|
||||
hasDef = defSize && (String.is(defSize) || _.isNumber(defSize));
|
||||
if (!(key && key.trim())) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontSize',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'key'
|
||||
});
|
||||
return ret;
|
||||
} else if (GenericHelpers.theme.fonts) {
|
||||
fontSpec = LO.get(GenericHelpers.theme.fonts, this.format + '.' + key);
|
||||
if (!fontSpec) {
|
||||
if (GenericHelpers.theme.fonts.all) {
|
||||
fontSpec = GenericHelpers.theme.fonts.all[key];
|
||||
}
|
||||
}
|
||||
if (fontSpec) {
|
||||
if (String.is(fontSpec)) {
|
||||
|
||||
} else if (_.isArray(fontSpec)) {
|
||||
if (!String.is(fontSpec[0])) {
|
||||
ret = fontSpec[0].size;
|
||||
}
|
||||
} else {
|
||||
ret = fontSpec.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ret) {
|
||||
if (hasDef) {
|
||||
ret = defSize;
|
||||
} else {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontSize',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'defSize'
|
||||
});
|
||||
ret = '';
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
Emit the font face (such as 'Helvetica' or 'Calibri') associated with the
|
||||
provided key.
|
||||
@param key {String} A named style from the "fonts" section of the theme's
|
||||
theme.json file. For example: 'default' or 'heading1'.
|
||||
@param defFont {String} The font to use if the specified key isn't present.
|
||||
Can be any valid font-face name such as 'Helvetica Neue' or 'Calibri'.
|
||||
*/
|
||||
fontFace: function(key, defFont) {
|
||||
var fontSpec, hasDef, ret;
|
||||
ret = '';
|
||||
hasDef = defFont && String.is(defFont);
|
||||
if (!(key && key.trim())) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontFace',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'key'
|
||||
});
|
||||
return ret;
|
||||
} else if (GenericHelpers.theme.fonts) {
|
||||
fontSpec = LO.get(GenericHelpers.theme.fonts, this.format + '.' + key);
|
||||
if (!fontSpec) {
|
||||
if (GenericHelpers.theme.fonts.all) {
|
||||
fontSpec = GenericHelpers.theme.fonts.all[key];
|
||||
}
|
||||
}
|
||||
if (fontSpec) {
|
||||
if (String.is(fontSpec)) {
|
||||
ret = fontSpec;
|
||||
} else if (_.isArray(fontSpec)) {
|
||||
ret = String.is(fontSpec[0]) ? fontSpec[0] : fontSpec[0].name;
|
||||
} else {
|
||||
ret = fontSpec.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(ret && ret.trim())) {
|
||||
ret = defFont;
|
||||
if (!hasDef) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontFace',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'defFont'
|
||||
});
|
||||
ret = '';
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
Emit a comma-delimited list of font names suitable associated with the
|
||||
provided key.
|
||||
@param key {String} A named style from the "fonts" section of the theme's
|
||||
theme.json file. For example: 'default' or 'heading1'.
|
||||
@param defFontList {Array} The font list to use if the specified key isn't
|
||||
present. Can be an array of valid font-face name such as 'Helvetica Neue'
|
||||
or 'Calibri'.
|
||||
@param sep {String} The default separator to use in the rendered output.
|
||||
Defaults to ", " (comma with a space).
|
||||
*/
|
||||
fontList: function(key, defFontList, sep) {
|
||||
var fontSpec, hasDef, ret;
|
||||
ret = '';
|
||||
hasDef = defFontList && String.is(defFontList);
|
||||
if (!(key && key.trim())) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontList',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'key'
|
||||
});
|
||||
} else if (GenericHelpers.theme.fonts) {
|
||||
fontSpec = LO.get(GenericHelpers.theme.fonts, this.format + '.' + key);
|
||||
if (!fontSpec) {
|
||||
if (GenericHelpers.theme.fonts.all) {
|
||||
fontSpec = GenericHelpers.theme.fonts.all[key];
|
||||
}
|
||||
}
|
||||
if (fontSpec) {
|
||||
if (String.is(fontSpec)) {
|
||||
ret = fontSpec;
|
||||
} else if (_.isArray(fontSpec)) {
|
||||
fontSpec = fontSpec.map(function(ff) {
|
||||
return "'" + (String.is(ff) ? ff : ff.name) + "'";
|
||||
});
|
||||
ret = fontSpec.join(sep === void 0 ? ', ' : sep || '');
|
||||
} else {
|
||||
ret = fontSpec.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(ret && ret.trim())) {
|
||||
if (!hasDef) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'fontList',
|
||||
error: HMSTATUS.missingParam,
|
||||
expected: 'defFontList'
|
||||
});
|
||||
ret = '';
|
||||
} else {
|
||||
ret = defFontList;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
Capitalize the first letter of the word.
|
||||
@method section
|
||||
*/
|
||||
camelCase: function(val) {
|
||||
val = (val && val.trim()) || '';
|
||||
if (val) {
|
||||
return val.charAt(0).toUpperCase() + val.slice(1);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Return true if the context has the property or subpropery.
|
||||
@method has
|
||||
*/
|
||||
has: function(title, options) {
|
||||
title = title && title.trim().toLowerCase();
|
||||
if (LO.get(this.r, title)) {
|
||||
return options.fn(this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Generic template helper function to display a user-overridable section
|
||||
title for a FRESH resume theme. Use this in lieue of hard-coding section
|
||||
titles.
|
||||
|
||||
Usage:
|
||||
|
||||
{{sectionTitle "sectionName"}}
|
||||
{{sectionTitle "sectionName" "sectionTitle"}}
|
||||
|
||||
Example:
|
||||
|
||||
{{sectionTitle "Education"}}
|
||||
{{sectionTitle "Employment" "Project History"}}
|
||||
|
||||
@param sect_name The name of the section being title. Must be one of the
|
||||
top-level FRESH resume sections ("info", "education", "employment", etc.).
|
||||
@param sect_title The theme-specified section title. May be replaced by the
|
||||
user.
|
||||
@method sectionTitle
|
||||
*/
|
||||
sectionTitle: function(sname, stitle) {
|
||||
stitle = (stitle && String.is(stitle) && stitle) || sname;
|
||||
return (this.opts.stitles && this.opts.stitles[sname.toLowerCase().trim()]) || stitle;
|
||||
},
|
||||
|
||||
/**
|
||||
Convert inline Markdown to inline WordProcessingML.
|
||||
@method wpml
|
||||
*/
|
||||
wpml: function(txt, inline) {
|
||||
if (!txt) {
|
||||
return '';
|
||||
}
|
||||
inline = (inline && !inline.hash) || false;
|
||||
txt = XML(txt.trim());
|
||||
txt = inline ? MD(txt).replace(/^\s*<p>|<\/p>\s*$/gi, '') : MD(txt);
|
||||
txt = H2W(txt);
|
||||
return txt;
|
||||
},
|
||||
|
||||
/**
|
||||
Emit a conditional link.
|
||||
@method link
|
||||
*/
|
||||
link: function(text, url) {
|
||||
if (url && url.trim()) {
|
||||
return '<a href="' + url + '">' + text + '</a>';
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Return the last word of the specified text.
|
||||
@method lastWord
|
||||
*/
|
||||
lastWord: function(txt) {
|
||||
if (txt && txt.trim()) {
|
||||
return _.last(txt.split(' '));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Convert a skill level to an RGB color triplet. TODO: refactor
|
||||
@method skillColor
|
||||
@param lvl Input skill level. Skill level can be expressed as a string
|
||||
("beginner", "intermediate", etc.), as an integer (1,5,etc), as a string
|
||||
integer ("1", "5", etc.), or as an RRGGBB color triplet ('#C00000',
|
||||
'#FFFFAA').
|
||||
*/
|
||||
skillColor: function(lvl) {
|
||||
var idx, skillColors;
|
||||
idx = skillLevelToIndex(lvl);
|
||||
skillColors = (this.theme && this.theme.palette && this.theme.palette.skillLevels) || ['#FFFFFF', '#5CB85C', '#F1C40F', '#428BCA', '#C00000'];
|
||||
return skillColors[idx];
|
||||
},
|
||||
|
||||
/**
|
||||
Return an appropriate height. TODO: refactor
|
||||
@method lastWord
|
||||
*/
|
||||
skillHeight: function(lvl) {
|
||||
var idx;
|
||||
idx = skillLevelToIndex(lvl);
|
||||
return ['38.25', '30', '16', '8', '0'][idx];
|
||||
},
|
||||
|
||||
/**
|
||||
Return all but the last word of the input text.
|
||||
@method initialWords
|
||||
*/
|
||||
initialWords: function(txt) {
|
||||
if (txt && txt.trim()) {
|
||||
return _.initial(txt.split(' ')).join(' ');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Trim the protocol (http or https) from a URL/
|
||||
@method trimURL
|
||||
*/
|
||||
trimURL: function(url) {
|
||||
if (url && url.trim()) {
|
||||
return url.trim().replace(/^https?:\/\//i, '');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Convert text to lowercase.
|
||||
@method toLower
|
||||
*/
|
||||
toLower: function(txt) {
|
||||
if (txt && txt.trim()) {
|
||||
return txt.toLowerCase();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Convert text to lowercase.
|
||||
@method toLower
|
||||
*/
|
||||
toUpper: function(txt) {
|
||||
if (txt && txt.trim()) {
|
||||
return txt.toUpperCase();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Return true if either value is truthy.
|
||||
@method either
|
||||
*/
|
||||
either: function(lhs, rhs, options) {
|
||||
if (lhs || rhs) {
|
||||
return options.fn(this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Conditional stylesheet link. Creates a link to the specified stylesheet with
|
||||
<link> or embeds the styles inline with <style></style>, depending on the
|
||||
theme author's and user's preferences.
|
||||
@param url {String} The path to the CSS file.
|
||||
@param linkage {String} The default link method. Can be either `embed` or
|
||||
`link`. If omitted, defaults to `embed`. Can be overridden by the `--css`
|
||||
command-line switch.
|
||||
*/
|
||||
styleSheet: function(url, linkage) {
|
||||
var rawCss, renderedCss, ret;
|
||||
linkage = this.opts.css || linkage || 'embed';
|
||||
ret = '';
|
||||
if (linkage === 'link') {
|
||||
ret = printf('<link href="%s" rel="stylesheet" type="text/css">', url);
|
||||
} else {
|
||||
rawCss = FS.readFileSync(PATH.join(this.opts.themeObj.folder, '/src/', url), 'utf8');
|
||||
renderedCss = this.engine.generateSimple(this, rawCss);
|
||||
ret = printf('<style>%s</style>', renderedCss);
|
||||
}
|
||||
if (this.opts.themeObj.inherits && this.opts.themeObj.inherits.html && this.format === 'html') {
|
||||
ret += linkage === 'link' ? '<link href="' + this.opts.themeObj.overrides.path + '" rel="stylesheet" type="text/css">' : '<style>' + this.opts.themeObj.overrides.data + '</style>';
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
Perform a generic comparison.
|
||||
See: http://doginthehat.com.au/2012/02/comparison-block-helper-for-handlebars-templates
|
||||
@method compare
|
||||
*/
|
||||
compare: function(lvalue, rvalue, options) {
|
||||
var operator, operators, result;
|
||||
if (arguments.length < 3) {
|
||||
throw new Error("Handlerbars Helper 'compare' needs 2 parameters");
|
||||
}
|
||||
operator = options.hash.operator || "==";
|
||||
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);
|
||||
}
|
||||
result = operators[operator](lvalue, rvalue);
|
||||
if (result) {
|
||||
return options.fn(this);
|
||||
} else {
|
||||
return options.inverse(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Report an error to the outside world without throwing an exception. Currently
|
||||
relies on kludging the running verb into. opts.
|
||||
*/
|
||||
|
||||
_reportError = function(code, params) {
|
||||
return GenericHelpers.opts.errHandler.err(code, params);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Format a from/to date range for display.
|
||||
*/
|
||||
|
||||
_fromTo = function(dateA, dateB, fmt, sep, fallback) {
|
||||
var dateATrim, dateBTrim, dateFrom, dateTemp, dateTo, reserved;
|
||||
if (moment.isMoment(dateA) || moment.isMoment(dateB)) {
|
||||
_reportError(HMSTATUS.invalidHelperUse, {
|
||||
helper: 'dateRange'
|
||||
});
|
||||
return '';
|
||||
}
|
||||
dateFrom = null;
|
||||
dateTo = null;
|
||||
dateTemp = null;
|
||||
dateA = dateA || '';
|
||||
dateB = dateB || '';
|
||||
dateATrim = dateA.trim().toLowerCase();
|
||||
dateBTrim = dateB.trim().toLowerCase();
|
||||
reserved = ['current', 'present', 'now', ''];
|
||||
fmt = (fmt && String.is(fmt) && fmt) || 'YYYY-MM';
|
||||
sep = (sep && String.is(sep) && sep) || ' — ';
|
||||
if (_.contains(reserved, dateATrim)) {
|
||||
dateFrom = fallback || '???';
|
||||
} else {
|
||||
dateTemp = FluentDate.fmt(dateA);
|
||||
dateFrom = dateTemp.format(fmt);
|
||||
}
|
||||
if (_.contains(reserved, dateBTrim)) {
|
||||
dateTo = fallback || 'Current';
|
||||
} else {
|
||||
dateTemp = FluentDate.fmt(dateB);
|
||||
dateTo = dateTemp.format(fmt);
|
||||
}
|
||||
if (dateFrom && dateTo) {
|
||||
return dateFrom + sep + dateTo;
|
||||
} else if (dateFrom || dateTo) {
|
||||
return dateFrom || dateTo;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
skillLevelToIndex = function(lvl) {
|
||||
var idx, intVal;
|
||||
idx = 0;
|
||||
if (String.is(lvl)) {
|
||||
lvl = lvl.trim().toLowerCase();
|
||||
intVal = parseInt(lvl);
|
||||
if (isNaN(intVal)) {
|
||||
switch (lvl) {
|
||||
case 'beginner':
|
||||
idx = 1;
|
||||
break;
|
||||
case 'intermediate':
|
||||
idx = 2;
|
||||
break;
|
||||
case 'advanced':
|
||||
idx = 3;
|
||||
break;
|
||||
case 'master':
|
||||
idx = 4;
|
||||
}
|
||||
} else {
|
||||
idx = Math.min(intVal / 2, 4);
|
||||
idx = Math.max(0, idx);
|
||||
}
|
||||
} else {
|
||||
idx = Math.min(lvl / 2, 4);
|
||||
idx = Math.max(0, idx);
|
||||
}
|
||||
return idx;
|
||||
};
|
||||
|
||||
}).call(this);
|
29
dist/helpers/handlebars-helpers.js
vendored
Normal file
29
dist/helpers/handlebars-helpers.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
/**
|
||||
Template helper definitions for Handlebars.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module handlebars-helpers.js
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var HANDLEBARS, _, helpers;
|
||||
|
||||
HANDLEBARS = require('handlebars');
|
||||
|
||||
_ = require('underscore');
|
||||
|
||||
helpers = require('./generic-helpers');
|
||||
|
||||
|
||||
/**
|
||||
Register useful Handlebars helpers.
|
||||
@method registerHelpers
|
||||
*/
|
||||
|
||||
module.exports = function(theme, opts) {
|
||||
helpers.theme = theme;
|
||||
helpers.opts = opts;
|
||||
return HANDLEBARS.registerHelper(helpers);
|
||||
};
|
||||
|
||||
}).call(this);
|
36
dist/helpers/underscore-helpers.js
vendored
Normal file
36
dist/helpers/underscore-helpers.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
/**
|
||||
Template helper definitions for Underscore.
|
||||
@license MIT. Copyright (c) 2016 hacksalot (https://github.com/hacksalot)
|
||||
@module handlebars-helpers.js
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var HANDLEBARS, _, helpers;
|
||||
|
||||
HANDLEBARS = require('handlebars');
|
||||
|
||||
_ = require('underscore');
|
||||
|
||||
helpers = require('./generic-helpers');
|
||||
|
||||
|
||||
/**
|
||||
Register useful Underscore helpers.
|
||||
@method registerHelpers
|
||||
*/
|
||||
|
||||
module.exports = function(theme, opts, cssInfo, ctx, eng) {
|
||||
helpers.theme = theme;
|
||||
helpers.opts = opts;
|
||||
helpers.cssInfo = cssInfo;
|
||||
helpers.engine = eng;
|
||||
ctx.h = helpers;
|
||||
return _.each(helpers, function(hVal, hKey) {
|
||||
if (_.isFunction(hVal)) {
|
||||
return _.bind(hVal, ctx);
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
}).call(this);
|
Reference in New Issue
Block a user