function helpers(groups, options) { if (typeof groups === 'string') { groups = [groups]; } else if (!Array.isArray(groups)) { options = groups; groups = null; } options = options || {}; var hbs = options.handlebars || options.hbs || require('handlebars'); define(module.exports, 'handlebars', hbs); if (groups) { groups.forEach(function(key) { hbs.registerHelper(lib[key]); }); } else { forIn(lib, function(group, key) { hbs.registerHelper(group); }); } return hbs.helpers; }
n/a
function proxy(name, alias) { var key = alias; // camel-case the module `name` if `alias` is not defined if (typeof key !== 'string') { key = camelcase(name); } // create a getter to lazily invoke the module the first time it's called function getter() { return cache[key] || (cache[key] = requireFn(name)); } // trip the getter if `process.env.UNLAZY` is defined if (unlazy(process.env)) { getter(); } set(proxy, key, getter); return getter; }
n/a
function micromatch(files, patterns, opts) { if (!files || !patterns) return []; opts = opts || {}; if (typeof opts.cache === 'undefined') { opts.cache = true; } if (!Array.isArray(patterns)) { return match(files, patterns, opts); } var len = patterns.length, i = 0; var omit = [], keep = []; while (len--) { var glob = patterns[i++]; if (typeof glob === 'string' && glob.charCodeAt(0) === 33 /* ! */) { omit.push.apply(omit, match(files, glob.slice(1), opts)); } else { keep.push.apply(keep, match(files, glob, opts)); } } return utils.diff(keep, omit); }
n/a
function relative(a, b, stat) { if (typeof a !== 'string') { throw new TypeError('relative expects a string.'); } if (a == '' && !b) return a; var len = arguments.length; if (len === 1) { b = a; a = process.cwd(); stat = null; } if (len === 2 && typeof b === 'boolean') { b = a; a = process.cwd(); stat = true; } if (len === 2 && typeof b === 'object') { stat = b; b = a; a = process.cwd(); } var origB = b; // see if a slash exists before normalizing var slashA = endsWith(a, '/'); var slashB = endsWith(b, '/'); a = unixify(a); b = unixify(b); // if `a` had a slash, add it back if (slashA) { a = a + '/'; } if (isFile(a, stat)) { a = path.dirname(a); } var res = path.relative(a, b); if (res === '') { return '.'; } // if `b` originally had a slash, and the path ends // with `b` missing a slash, then re-add the slash. var noslash = trimEnd(origB, '/'); if (slashB && (res === noslash || endsWith(res, noslash))) { res = res + '/'; } return res; }
n/a
after = function (array, n) { if (utils.isUndefined(array)) return ''; return array.slice(n); }
n/a
arrayify = function (value) { return value ? (Array.isArray(value) ? value : [value]) : []; }
...
helpers.css = function(array, options) {
if (arguments.length < 2) {
options = array;
array = [];
}
var styles = utils.arrayify(array);
var assets = '';
if (this && this.options) {
assets = this.options.assets || '';
}
if (options.hash.href) {
...
before = function (array, n) { if (utils.isUndefined(array)) return ''; return array.slice(0, -n); }
n/a
eachIndex = function (array, options) { var result = ''; for (var i = 0; i < array.length; i++) { result += options.fn({item: array[i], index: i}); } return result; }
n/a
filter = function (array, value, options) { var content = ''; var results = []; // filter on a specific property var prop = options.hash && options.hash.property; if (prop) { results = utils.filter(array, function(val) { return utils.get(val, prop) === value; }); } else { // filter on a string value results = utils.filter(array, function(v) { return value === v; }); } if (results && results.length > 0) { for (var i = 0; i < results.length; i++) { content += options.fn(results[i]); } return content; } return options.inverse(this); }
...
helpers.filter = function(array, value, options) {
var content = '';
var results = [];
// filter on a specific property
var prop = options.hash && options.hash.property;
if (prop) {
results = utils.filter(array, function(val) {
return utils.get(val, prop) === value;
});
} else {
// filter on a string value
results = utils.filter(array, function(v) {
return value === v;
...
first = function (array, n) { if (utils.isUndefined(array)) return ''; if (!utils.isNumber(n)) { return array[0]; } return array.slice(0, n); }
n/a
forEach = function (array, options) { var data = utils.createFrame(options, options.hash); var len = array.length; var buffer = ''; var i = -1; while (++i < len) { var item = array[i]; data.index = i; item.index = i + 1; item.total = len; item.isFirst = i === 0; item.isLast = i === (len - 1); buffer += options.fn(item, {data: data}); } return buffer; }
...
options = options || {};
var hbs = options.handlebars || options.hbs || require('handlebars');
define(module.exports, 'handlebars', hbs);
if (groups) {
groups.forEach(function(key) {
hbs.registerHelper(lib[key]);
});
} else {
forIn(lib, function(group, key) {
hbs.registerHelper(group);
});
}
...
inArray = function (array, value, options) { if (utils.indexOf(array, value) > -1) { return options.fn(this); } return options.inverse(this); }
n/a
isArray = function (value) { return Array.isArray(value); }
...
/**
* Expose helpers
*/
module.exports = function helpers(groups, options) {
if (typeof groups === 'string') {
groups = [groups];
} else if (!Array.isArray(groups)) {
options = groups;
groups = null;
}
options = options || {};
var hbs = options.handlebars || options.hbs || require('handlebars');
...
join = function (array, sep) { if (utils.isUndefined(array)) return ''; sep = typeof sep !== 'string' ? ', ' : sep; return array.join(sep); }
...
*/
helpers.join = function(array, sep) {
if (utils.isUndefined(array)) return '';
sep = typeof sep !== 'string'
? ', '
: sep;
return array.join(sep);
};
/**
* Returns the last item, or last `n` items of an array.
* Opposite of [first](#first).
*
* ```handlebars
...
last = function (array, n) { if (!utils.isNumber(n)) { return array[array.length - 1]; } return array.slice(-n); }
n/a
lengthEqual = function (array, length, options) { if (array.length === length) { return options.fn(this); } return options.inverse(this); }
n/a
map = function (array, fn) { if (utils.isUndefined(array)) return ''; if (typeof array === 'string' && /[[]/.test(array)) { array = utils.tryParse(array) || []; } var len = array.length; var res = new Array(len); var i = -1; while (++i < len) { res[i] = fn(array[i], i, array); } return res; }
...
* @param {String} `directory`
* @return {Array}
* @api public
*/
helpers.readdir = function(dir, filter) {
var files = fs.readdirSync(dir);
files = files.map(function(fp) {
return path.join(dir, fp);
});
if (utils.isOptions(filter)) {
return files;
}
if (typeof filter === 'function') {
return filter(files);
...
some = function (arr, cb, options) { cb = utils.iterator(cb, this); if (arr == null) { return options.inverse(this); } var len = arr.length, i = -1; while (++i < len) { if (cb(arr[i], i, arr)) { return options.fn(this); } } return options.inverse(this); }
n/a
sort = function (arr, options) { if (utils.isUndefined(arr)) return ''; if (utils.get(options, 'hash.reverse')) { return arr.sort().reverse(); } return arr.sort(); }
...
* @param {String|Function} `key` The object key to sort by, or sorting function.
* @api public
*/
helpers.sort = function(arr, options) {
if (utils.isUndefined(arr)) return '';
if (utils.get(options, 'hash.reverse')) {
return arr.sort().reverse();
}
return arr.sort();
};
/**
* Sort an `array`. If an array of objects is passed,
* you may optionally pass a `key` to sort on as the second
...
sortBy = function (arr) { if (utils.isUndefined(arr)) return ''; var args = [].slice.call(arguments); args.pop(); // remove hbs options object if (typeof args[0] === 'string' && /[[]/.test(args[0])) { args[0] = utils.tryParse(args[0]) || []; } if (utils.isUndefined(args[1])) { return args[0].sort(); } return utils.sortBy.apply(null, args); }
n/a
withAfter = function (array, idx, options) { array = array.slice(idx); var result = ''; var len = array.length, i = -1; while (++i < len) { result += options.fn(array[i]); } return result; }
n/a
withBefore = function (array, idx, options) { array = array.slice(0, -idx); var result = ''; var len = array.length, i = -1; while (++i < len) { result += options.fn(array[i]); } return result; }
n/a
withFirst = function (arr, idx, options) { if (utils.isUndefined(arr)) return ''; arr = utils.result(arr); if (!utils.isUndefined(idx)) { idx = parseFloat(utils.result(idx)); } if (utils.isUndefined(idx)) { options = idx; return options.fn(arr[0]); } arr = arr.slice(0, idx); var len = arr.length, i = -1; var result = ''; while (++i < len) { result += options.fn(arr[i]); } return result; }
n/a
withLast = function (array, idx, options) { if (utils.isUndefined(array)) return ''; array = utils.result(array); if (!utils.isUndefined(idx)) { idx = parseFloat(utils.result(idx)); } if (utils.isUndefined(idx)) { options = idx; return options.fn(array[array.length - 1]); } array = array.slice(-idx); var len = array.length, i = -1; var result = ''; while (++i < len) { result += options.fn(array[i]); } return result; }
n/a
withSort = function (array, prop, options) { if (utils.isUndefined(array)) return ''; var result = ''; if (utils.isUndefined(prop)) { options = prop; array = array.sort(); if (utils.get(options, 'hash.reverse')) { array = array.reverse(); } for (var i = 0, len = array.length; i < len; i++) { result += options.fn(array[i]); } return result; } array.sort(function(a, b) { a = utils.get(a, prop); b = utils.get(b, prop); return a > b ? 1 : (a < b ? -1 : 0); }); if (utils.get(options, 'hash.reverse')) { array = array.reverse(); } var alen = array.length, j = -1; while (++j < alen) { result += options.fn(array[j]); } return result; }
n/a
function embed(fp, ext) { ext = typeof ext !== 'string' ? path.extname(fp).slice(1) : ext; var code = fs.readFileSync(fp, 'utf8'); if (ext === 'markdown' || ext === 'md') { ext = 'markdown'; // if the string is markdown, escape backticks code = code.split('`').join('`'); } return utils.block(code, ext).trim() + '\n'; }
n/a
gist = function (id) { return utils.tag('script', {src: 'https://gist.github.com/' + id + '.js'}); }
n/a
function jsFiddle(options) { var attr = object.merge({}, options, options.hash); delete attr.name; delete attr.hash; delete attr.data; if (typeof attr.id === 'undefined') { throw new Error('jsfiddle helper expects an `id`'); } attr.id = 'http://jsfiddle.net/' + attr.id; attr.width = attr.width || '100%'; attr.height = attr.height || '300'; attr.skin = attr.skin || '/presentation/'; attr.tabs = (attr.tabs || 'result,js,html,css') + attr.skin; attr.src = attr.id + '/embedded/' + attr.tabs; attr.allowfullscreen = attr.allowfullscreen || 'allowfullscreen'; attr.frameborder = attr.frameborder || '0'; delete attr.tabs; delete attr.skin; delete attr.id; return utils.tag('iframe', attr); }
n/a
isEmpty = function (collection, options) { if (options == null) { options = collection; return options.fn(this); } if (Array.isArray(collection) && !collection.length) { return options.fn(this); } var keys = Object.keys(collection); if (typeof collection === 'object' && !keys.length) { return options.fn(this); } return options.inverse(this); }
n/a
iterate = function (context, options) { if (Array.isArray(context)) { return forEach.apply(forEach, arguments); } else if (utils.isObject(context)) { return forOwn.apply(forOwn, arguments); } return options.inverse(this); }
n/a
length = function (value) { if (utils.isUndefined(value)) return ''; if (typeof value === 'string' && /[[]/.test(value)) { value = utils.tryParse(value) || []; } if (utils.isObject(value)) { value = Object.keys(value); } return value.length; }
n/a
and = function (a, b, options) { if (a && b) { return options.fn(this); } return options.inverse(this); }
n/a
compare = function (a, operator, b, options) {
/*eslint eqeqeq: 0*/
if (arguments.length < 4) {
throw new Error('handlebars Helper {{compare}} expects 4 arguments');
}
var result;
switch (operator) {
case '==':
result = a == b;
break;
case '===':
result = a === b;
break;
case '!=':
result = a != b;
break;
case '!==':
result = a !== b;
break;
case '<':
result = a < b;
break;
case '>':
result = a > b;
break;
case '<=':
result = a <= b;
break;
case '>=':
result = a >= b;
break;
case 'typeof':
result = typeof a === b;
break;
default: {
throw new Error('helper {{compare}}: invalid operator: `' + operator + '`');
}
}
if (result === false) {
return options.inverse(this);
}
return options.fn(this);
}
n/a
contains = function (collection, value, startIndex, options) { if (typeof startIndex === 'object') { options = startIndex; startIndex = undefined; } if (utils.contains(collection, value, startIndex)) { return options.fn(this); } return options.inverse(this); }
...
*/
helpers.contains = function(collection, value, startIndex, options) {
if (typeof startIndex === 'object') {
options = startIndex;
startIndex = undefined;
}
if (utils.contains(collection, value, startIndex)) {
return options.fn(this);
}
return options.inverse(this);
};
/**
* Block helper that renders a block if `a` is **greater than** `b`.
...
eq = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a === b) { return options.fn(this); } return options.inverse(this); }
n/a
gt = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a > b) { return options.fn(this); } return options.inverse(this); }
n/a
gte = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a >= b) { return options.fn(this); } return options.inverse(this); }
n/a
has = function (value, pattern, options) { if (arguments.length === 2) { return pattern.inverse(this); } if (arguments.length === 1) { return value.inverse(this); } if ((Array.isArray(value) || isString(value)) && isString(pattern)) { if (value.indexOf(pattern) > -1) { return options.fn(this); } } if (isObject(value) && isString(pattern) && pattern in value) { return options.fn(this); } return options.inverse(this); }
n/a
ifEven = function (num, options) { return utils.isEven(num) ? options.fn(this) : options.inverse(this); }
n/a
ifNth = function (a, b, options) { if (utils.isNumber(a) && utils.isNumber(b) && b % a === 0) { return options.fn(this); } return options.inverse(this); }
n/a
ifOdd = function (val, options) { return utils.isOdd(val) ? options.fn(this) : options.inverse(this); }
n/a
is = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a === b) { return options.fn(this); } return options.inverse(this); }
n/a
isnt = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a !== b) { return options.fn(this); } return options.inverse(this); }
n/a
lt = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a < b) { return options.fn(this); } return options.inverse(this); }
n/a
lte = function (a, b, options) { if (arguments.length === 2) { options = b; b = options.hash.compare; } if (a <= b) { return options.fn(this); } return options.inverse(this); }
n/a
neither = function (a, b, options) { if (!a && !b) { return options.fn(this); } return options.inverse(this); }
n/a
or = function () { var len = arguments.length - 1; var options = arguments[len]; for (var i = 0; i < len; i++) { if (arguments[i]) { return options.fn(this); } } return options.inverse(this); }
n/a
unlessEq = function (context, options) { if (context === options.hash.compare) { return options.inverse(this); } return options.fn(this); }
n/a
unlessGt = function (context, options) { if (context > options.hash.compare) { return options.inverse(this); } return options.fn(this); }
n/a
unlessGteq = function (context, options) { if (context >= options.hash.compare) { return options.inverse(this); } return options.fn(this); }
n/a
unlessLt = function (context, options) { if (context < options.hash.compare) { return options.inverse(this); } return options.fn(this); }
n/a
unlessLteq = function (context, options) { if (context <= options.hash.compare) { return options.inverse(this); } return options.fn(this); }
n/a
function momentHelper(str, pattern, options) { // if no args are passed, return a formatted date if (str == null && pattern == null) { moment.locale('en'); return moment().format('MMMM DD, YYYY'); } var opts = {lang: 'en', date: new Date()}; opts = extend({}, opts, str, pattern, options); opts = extend({}, opts, opts.hash); // set the language to use moment.locale(opts.lang); if (opts.datejs === false) { return moment(new Date(str)).format(pattern); } // if both args are strings, this could apply to either lib. // so instead of doing magic we'll just ask the user to tell // us if the args should be passed to date.js or moment. if (typeof str === 'string' && typeof pattern === 'string') { return moment(date(str)).format(pattern); } // If handlebars, expose moment methods as hash properties if (opts.hash) { if (opts.context) { extend(opts.hash, opts.context); } var res = moment(str); for (var key in opts.hash) { if (res[key]) { return res[key](opts.hash[key]); } else { console.log('moment.js does not support "' + key + '"'); } } } if (typeOf(str) === 'object') { return moment(str).format(pattern); } // if only a string is passed, assume it's a date pattern ('YYYY') if (typeof str === 'string' && !pattern) { return moment().format(str); } return moment(str).format(pattern); }
n/a
fileSize = function (num) { var bytes = parseInt(num, 10); if (!utils.isNumber(bytes)) { console.error('helper {{fileSize}} cannot parse: "' + num + '"'); return num.toString(); // Graceful degradation } // KB is technically a Kilobit, but it seems more readable. var metric = ['byte', 'bytes', 'KB', 'MB', 'GB']; var res; if (bytes === 0) { return '0 bytes'; } else { // Base 1000 (rather than 1024) matches Mac OS X res = Math.floor(Math.log(bytes) / Math.log(1000)); // No decimals for anything smaller than 1 MB num = (bytes / Math.pow(1000, Math.floor(res))).toFixed(res < 2 ? 0 : 1); if (bytes === 1) { res = -1; // special case: 1 byte (singular) } } return num + ' ' + metric[res + 1]; }
n/a
read = function (filepath) { return fs.readFileSync(filepath, 'utf8'); }
n/a
readdir = function (dir, filter) { var files = fs.readdirSync(dir); files = files.map(function(fp) { return path.join(dir, fp); }); if (utils.isOptions(filter)) { return files; } if (typeof filter === 'function') { return filter(files); } if (utils.isRegex(filter)) { var re = utils.toRegex(filter); return files.filter(function(fp) { return re.test(fp); }); } if (utils.isGlob(filter)) { var isMatch = utils.mm.matcher(filter); return files.filter(function(fp) { return isMatch(fp); }); } if (['isFile', 'isDirectory'].indexOf(filter) !== -1) { return files.filter(function(fp) { var stat = fs.statSync(fp); return stat[filter](); }); } return files; }
n/a
css = function (array, options) { if (arguments.length < 2) { options = array; array = []; } var styles = utils.arrayify(array); var assets = ''; if (this && this.options) { assets = this.options.assets || ''; } if (options.hash.href) { styles = utils.arrayify(options.hash.href); } return styles.map(function(item) { var ext = path.extname(item); var fp = path.join(assets, item); if (ext === '.less') { return '<link type="text/css" rel="stylesheet/less" href="' + fp + '">'; } return '<link type="text/css" rel="stylesheet" href="' + fp + '">'; }).join('\n'); }
n/a
ellipsis = function (str, limit) { if (str && typeof str === 'string') { if (str.length <= limit) { return str; } return helpers.truncate(str, limit) + '…'; } }
n/a
js = function (context) { if (utils.typeOf(context) === 'object') { var attr = html.toAttributes(context.hash); return '<script' + attr + '></script>'; } if (utils.typeOf(context) === 'string') { return '<script src="' + context + '"></script>'; } context = utils.arrayify(context); return context.map(function(fp) { return (path.extname(fp) === '.coffee') ? utils.tag('script', {type: 'text/coffeescript', src: fp}) : utils.tag('script', {src: fp}); }).join('\n'); }
n/a
ol = function (context, options) { return ('<ol ' + (parseAttr(options.hash)) + '>') + context.map(function(item) { if (typeof item !== 'string') { item = options.fn(item); } return '<li>' + item + '</li>'; }).join('\n') + '</ol>'; }
n/a
sanitize = function (str) { return html.sanitize(str); }
...
*
* @param {String} `str` The string of HTML to sanitize.
* @return {String}
* @api public
*/
helpers.sanitize = function(str) {
return html.sanitize(str);
};
/**
* Truncate a string by removing all HTML tags and limiting the result
* to the specified `length`. Aslo see [ellipsis](#ellipsis).
*
* ```js
...
thumbnailImage = function (context) { var figure = ''; var image = ''; var link = context.full || false; var imageAttributes = { alt: context.alt, src: context.thumbnail, width: context.size.width, height: context.size.height }; var figureAttributes = { id: 'image-' + context.id }; var linkAttributes = { href: link, rel: 'thumbnail' }; if (context.classes) { if (context.classes.image) { imageAttributes.class = context.classes.image.join(' '); } if (context.classes.figure) { figureAttributes.class = context.classes.figure.join(' '); } if (context.classes.link) { linkAttributes.class = context.classes.link.join(' '); } } figure += '<figure ' + parseAttr(figureAttributes) + '>\n'; image += '<img ' + parseAttr(imageAttributes) + '>\n'; if (link) { figure += '<a ' + parseAttr(linkAttributes) + '>\n' + image + '</a>\n'; } else { figure += image; } if (context.caption) { figure += '<figcaption>' + context.caption + '</figcaption>\n'; } figure += '</figure>'; return figure; }
n/a
truncate = function (str, limit, suffix) { if (str && typeof str === 'string') { var ch = typeof suffix === 'string' ? suffix : ''; if (str.length > limit) { return html.sanitize(str).slice(0, limit - ch.length) + ch; } return str; } }
...
*/
helpers.ellipsis = function(str, limit) {
if (str && typeof str === 'string') {
if (str.length <= limit) {
return str;
}
return helpers.truncate(str, limit) + '…';
}
};
/**
* Generate one or more `<script></script>` tags with paths/urls to
* javascript or coffeescript files.
*
...
ul = function (context, options) { return ('<ul ' + (parseAttr(options.hash)) + '>') + context.map(function(item) { if (typeof item !== 'string') { item = options.fn(item); } return '<li>' + item + '</li>'; }).join('\n') + '</ul>'; }
n/a
i18n = function (prop, context, options) { if (utils.isOptions(context)) { options = context; context = {}; } if (typeof prop !== 'string') { throw new Error('{{i18n}} helper expected "key" to be a string'); } var opts = utils.merge({}, this, options.hash); // account for `options` being passed on the context if (opts.options) { opts = utils.merge({}, opts, opts.options); delete opts.options; } var lang = opts.language || opts.lang; if (typeof lang !== 'string') { throw new Error('{{i18n}} helper expected "language" parameter to be a string'); } var value = utils.get(opts, lang); if (typeof value === 'undefined') { throw new Error('{{i18n}} helper cannot find language "' + lang + '"'); } var result = utils.get(value, prop); if (typeof result === 'undefined') { throw new Error('{{i18n}} helper cannot find property "' + prop + '" for language "' + lang + '"'); } return result; }
n/a
inflect = function (count, singular, plural, include) { var word = (count > 1 || count === 0) ? plural : singular; if (utils.isUndefined(include) || include === false) { return word; } else { return String(count) + ' ' + word; } }
n/a
ordinalize = function (val) { var num = Math.abs(Math.round(val)); var res = num % 100; if (utils.indexOf([11, 12, 13], res) >= 0) { return '' + val + 'th'; } switch (num % 10) { case 1: return '' + val + 'st'; case 2: return '' + val + 'nd'; case 3: return '' + val + 'rd'; default: { return '' + val + 'th'; } } }
n/a
function inspect_(context, options) { context = JSON.stringify(context, null, 2); var ext = options && options.hash && options.hash.ext || 'html'; return switchOutput(ext, context); }
n/a
function bold_() { arguments[0] = chalk.bold(arguments[0]); console.log.apply(console, arguments); }
n/a
function debug_(val) { var args = [].slice.call(arguments); console.log(); console.log('================================='); console.log('context: %j', this); console.log(); if (!isUndefined(val)) { console.log.apply(console, ['value: %j'].concat(val)); } console.log('================================='); console.log(); return; }
n/a
function error_() { arguments[0] = chalk.red(arguments[0]); console.error.apply(console, arguments); }
...
* @api public
*/
helpers.fileSize = function(num) {
var bytes = parseInt(num, 10);
if (!utils.isNumber(bytes)) {
console.error('helper {{fileSize}} cannot parse: "' + num + '
x22;');
return num.toString(); // Graceful degradation
}
// KB is technically a Kilobit, but it seems more readable.
var metric = ['byte', 'bytes', 'KB', 'MB', 'GB'];
var res;
...
function info_() { arguments[0] = chalk.cyan(arguments[0]); console.log.apply(console, arguments); }
n/a
function log_() { console.log.apply(console, arguments); }
...
var metric = ['byte', 'bytes', 'KB', 'MB', 'GB'];
var res;
if (bytes === 0) {
return '0 bytes';
} else {
// Base 1000 (rather than 1024) matches Mac OS X
res = Math.floor(Math.log(bytes) / Math.log(1000));
// No decimals for anything smaller than 1 MB
num = (bytes / Math.pow(1000, Math.floor(res))).toFixed(res < 2 ? 0 : 1);
if (bytes === 1) {
res = -1; // special case: 1 byte (singular)
}
...
function warn_() { arguments[0] = chalk.yellow(arguments[0]); console.warn.apply(console, arguments); }
n/a
function helper(context, options) { if (typeof context === 'string') { var opts = merge({}, config, options); var md = new Remarkable(opts); return md.render(context); } if (isObject(context) && typeof context.fn === 'function') { options = context; context = {}; } options = merge({ html: true, breaks: true }, config, options); options = merge({}, options, options.markdown, options.hash); if (options.hasOwnProperty('lang')) { options.langPrefix = options.lang; } var md = new Remarkable(options); var ctx = merge({}, options, this.context, context); return md.render(options.fn(ctx)); }
n/a
md = function (name, options, cb) { if (typeof options === 'function') { cb = options; options = {}; } if (typeof cb !== 'function') { return helper.sync.apply(this, arguments); } if (typeof this === 'undefined' || typeof this.app === 'undefined') { throw new Error('md async helper expects `app` to be exposed on the context'); } var opts = extend({cwd: process.cwd()}, this.options, options); opts = extend({}, opts, opts.hash); var md = markdown(opts); var filepath = path.resolve(opts.cwd, name); var view; var str = ''; if (exists(filepath)) { // create a collection to ensure middleware is consistent this.app.create('mdfiles'); str = fs.readFileSync(filepath, 'utf8'); view = this.app.mdfile(filepath, {path: filepath, content: str}); } else { view = this.app.find(name); } if (typeof view === 'undefined') { cb(null, ''); return; } view.content = ent.decode(md.render(view.content)); this.app.render(view, this.context, function(err, res) { if (err) return cb(err); cb(null, res.content); }); }
n/a
match = function () { var args = utils.getArgs(this, arguments); return utils.mm.match.apply(utils.mm, args); }
...
* @return {String}
* @api public
*/
helpers.titleize = function(str) {
if (str && typeof str === 'string') {
var title = str.replace(/[ \-_]+/g, ' ');
var words = title.match(/\w+/g);
var len = words.length;
var res = [];
var i = 0;
while (len--) {
var word = words[i++];
res.push(exports.capitalize(word));
}
...
isMatch = function () { var args = utils.getArgs(this, arguments); return utils.mm.isMatch.apply(utils.mm, args); }
n/a
mm = function () { var args = utils.getArgs(this, arguments); return utils.mm.apply(utils.mm, args); }
n/a
add = function (a, b) { return a + b; }
n/a
avg = function () { var args = utils.flatten([].concat.apply([], arguments)); // remove handlebars options object args.pop(); return exports.sum(args) / args.length; }
n/a
ceil = function (value) { return Math.ceil(value); }
...
**Params**
* `value` **{Number}**
### [{{ceil}}](lib/math.js#L76)
Get the `Math.ceil()` of the given value.
**Params**
* `value` **{Number}**
### [{{round}}](lib/math.js#L87)
...
divide = function (a, b) { return a / b; }
n/a
floor = function (value) { return Math.floor(value); }
...
**Params**
* `a` **{Number}**: factor
* `b` **{Number}**: multiplier
### [{{floor}}](lib/math.js#L65)
Get the `Math.floor()` of the given value.
**Params**
* `value` **{Number}**
### [{{ceil}}](lib/math.js#L76)
...
multiply = function (a, b) { return a * b; }
n/a
round = function (value) { return Math.round(value); }
...
*
* @param {String} `val` The value to ordinalize.
* @return {String} The ordinalized number
* @api public
*/
helpers.ordinalize = function(val) {
var num = Math.abs(Math.round(val));
var res = num % 100;
if (utils.indexOf([11, 12, 13], res) >= 0) {
return '' + val + 'th';
}
switch (num % 10) {
...
subtract = function (a, b) { return a - b; }
n/a
sum = function () { var args = utils.flatten([].concat.apply([], arguments)); var i = args.length, sum = 0; while (i--) { if (!utils.isNumber(args[i])) { continue; } sum += (+args[i]); } return sum; }
...
* @api public
*/
helpers.avg = function() {
var args = utils.flatten([].concat.apply([], arguments));
// remove handlebars options object
args.pop();
return exports.sum(args) / args.length;
};
...
default = function (value, defaultValue) { return value == null ? defaultValue : value; }
n/a
noop = function (options) { return options.fn(this); }
n/a
option = function (prop) { var opts = (this && this.options) || {}; return utils.get(opts, prop); }
n/a
withHash = function (options) { if (options.hash && Object.keys(options.hash).length) { return options.fn(options.hash); } else { return options.inverse(this); } }
n/a
addCommas = function (num) { return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); }
n/a
phoneNumber = function (num) { num = num.toString(); return '(' + num.substr(0, 3) + ') ' + num.substr(3, 3) + '-' + num.substr(6, 4); }
n/a
random = function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
...
* @param {Number} `max`
* @contributor Tim Douglas <https://github.com/timdouglas>
* @return {String}
* @api public
*/
helpers.random = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
/**
* Abbreviate numbers to the given number of `precision`. This is for
* general numbers, not size in bytes.
*
* @param {Number} `number`
...
toAbbr = function (number, precision) { if (!utils.isNumber(number)) { number = 0; } if (utils.isUndefined(precision)) { precision = 2; } number = +number; // 2 decimal places => 100, 3 => 1000, etc. precision = Math.pow(10, precision); var abbr = ['k', 'm', 'b', 't', 'q']; var len = abbr.length - 1; while (len >= 0) { var size = Math.pow(10, (len + 1) * 3); if (size <= (number + 1)) { number = Math.round(number * precision / size) / precision; number += abbr[len]; break; } len--; } return number; }
n/a
toExponential = function (number, digits) { if (!utils.isNumber(number)) { number = 0; } if (utils.isUndefined(digits)) { digits = 0; } number = +number; return number.toExponential(digits); }
...
if (!utils.isNumber(number)) {
number = 0;
}
if (utils.isUndefined(digits)) {
digits = 0;
}
number = +number;
return number.toExponential(digits);
};
/**
* Formats the given number using fixed-point notation.
*
* @param {Number} `number`
* @param {Number} `digits` Optional. The number of digits to use after the decimal point; this may be a value between 0 and 20,
inclusive, and implementations may optionally support a larger range of values. If this argument is omitted, it is treated as 0.
...
toFixed = function (number, digits) { if (!utils.isNumber(number)) { number = 0; } if (utils.isUndefined(digits)) { digits = 0; } number = +number; return number.toFixed(digits); }
...
if (bytes === 0) {
return '0 bytes';
} else {
// Base 1000 (rather than 1024) matches Mac OS X
res = Math.floor(Math.log(bytes) / Math.log(1000));
// No decimals for anything smaller than 1 MB
num = (bytes / Math.pow(1000, Math.floor(res))).toFixed(res < 2 ? 0 : 1);
if (bytes === 1) {
res = -1; // special case: 1 byte (singular)
}
}
return num + ' ' + metric[res + 1];
};
...
toFloat = function (number) { return parseFloat(number); }
n/a
toInt = function (number) { return parseInt(number, 10); }
n/a
toPrecision = function (number, precision) { if (!utils.isNumber(number)) { number = 0; } if (utils.isUndefined(precision)) { precision = 1; } number = +number; return number.toPrecision(precision); }
...
if (!utils.isNumber(number)) {
number = 0;
}
if (utils.isUndefined(precision)) {
precision = 1;
}
number = +number;
return number.toPrecision(precision);
};
...
JSONparse = function (str, options) { return options.fn(JSON.parse(str)); }
n/a
JSONstringify = function (obj, indent) { if (!utils.isNumber(indent)) { indent = 0; } return JSON.stringify(obj, null, indent); }
n/a
extend = function () { var args = [].slice.call(arguments); var last = args[args.length - 1]; if (last && utils.isObject(last) && last.hash) { last = last.hash; args.pop(); // remove handlebars options object args.push(last); } var len = args.length; var context = {}; var i = -1; while (++i < len) { var obj = args[i]; if (utils.isObject(obj)) { for (var key in obj) { if (obj.hasOwnProperty(key)) { context[key] = obj[key]; } } } } return context; }
...
helpers.pick = function(props, context, options) {
var keys = array.arrayify(props);
var len = keys.length, i = -1;
var result = {};
while (++i < len) {
result = helpers.extend(result, utils.getObject(context, keys[i]));
}
if (options.fn) {
if (Object.keys(result).length) {
return options.fn(result);
} else {
return options.inverse(context);
...
forIn = function (obj, options) { if (!utils.isOptions(options)) { return obj.inverse(this); } var data = utils.createFrame(options, options.hash); var result = ''; for (var key in obj) { data.key = key; result += options.fn(obj[key], {data: data}); } return result; }
n/a
forOwn = function (obj, options) { if (!utils.isOptions(options)) { return obj.inverse(this); } var data = utils.createFrame(options, options.hash); var result = ''; for (var key in obj) { if (obj.hasOwnProperty(key)) { data.key = key; result += options.fn(obj[key], {data: data}); } } return result; }
n/a
get = function (prop, context, options) { var val = utils.get(context, prop); if (options && options.fn) { return val ? options.fn(val) : options.inverse(context); } return val; }
...
var content = '';
var results = [];
// filter on a specific property
var prop = options.hash && options.hash.property;
if (prop) {
results = utils.filter(array, function(val) {
return utils.get(val, prop) === value;
});
} else {
// filter on a string value
results = utils.filter(array, function(v) {
return value === v;
});
...
getObject = function (prop, context) { return utils.getObject(context, prop); }
...
* @param {String} `prop` The property to get, optionally using dot notation for nested properties.
* @param {Object} `context` The context object
* @return {String}
* @api public
*/
helpers.getObject = function(prop, context) {
return utils.getObject(context, prop);
};
/**
* Return true if `key` is an own, enumerable property
* of the given `context` object.
*
* ```handlebars
...
hasOwn = function (context, key) { return hasOwn.call(context, key); }
n/a
isObject = function (value) { return value && typeof value === 'object' && !Array.isArray(value); }
...
* @block
* @api public
*/
helpers.iterate = function(context, options) {
if (Array.isArray(context)) {
return forEach.apply(forEach, arguments);
} else if (utils.isObject(context)) {
return forOwn.apply(forOwn, arguments);
}
return options.inverse(this);
};
/**
* Returns the length of the given collection. When using a string literal in the
...
merge = function (context) { var args = [].slice.call(arguments); var last = args[args.length - 1]; if (last && typeof last === 'object' && last.hash) { last = last.hash; args.pop(); // remove handlebars options object args.push(last); } context = utils.merge.apply(utils.merge, args); return context; }
...
*
* @param {Object} `params`
* @return {String}
* @api public
*/
helpers.jsfiddle = function jsFiddle(options) {
var attr = object.merge({}, options, options.hash);
delete attr.name;
delete attr.hash;
delete attr.data;
if (typeof attr.id === 'undefined') {
throw new Error('jsfiddle helper expects an `id`');
}
...
parseJSON = function (str, options) { return options.fn(JSON.parse(str)); }
n/a
pick = function (props, context, options) { var keys = array.arrayify(props); var len = keys.length, i = -1; var result = {}; while (++i < len) { result = helpers.extend(result, utils.getObject(context, keys[i])); } if (options.fn) { if (Object.keys(result).length) { return options.fn(result); } else { return options.inverse(context); } } return result; }
n/a
stringify = function (obj, indent) { if (!utils.isNumber(indent)) { indent = 0; } return JSON.stringify(obj, null, indent); }
...
* @api public
*/
helpers.JSONstringify = function(obj, indent) {
if (!utils.isNumber(indent)) {
indent = 0;
}
return JSON.stringify(obj, null, indent);
};
/**
* Alias for JSONstringify. this will be
* deprecated in a future release
*/
...
toPath = function () { var prop = []; for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === "string" || typeof arguments[i] === "number") { prop.push(arguments[i]); } } return prop.join('.'); }
n/a
absolute = function (filepath, options) { var context = utils.merge({}, this, options); var ctx = utils.merge({}, context.root, context, context._parent, context.hash); var cwd = ctx.cwd || process.cwd(); return path.resolve(cwd, filepath); }
n/a
basename = function (filepath) { return path.basename(filepath); }
...
* ```
* @param {String} `ext`
* @return {String}
* @api public
*/
helpers.basename = function(filepath) {
return path.basename(filepath);
};
/**
* Get the "stem" from the given `filepath`.
*
* ```handlebars
* {{stem "docs/toc.md"}}
...
dirname = function (filepath) { return path.dirname(filepath); }
...
* ```
* @param {String} `ext`
* @return {String}
* @api public
*/
helpers.dirname = function(filepath) {
return path.dirname(filepath);
};
/**
* Get the relative filepath from `a` to `b`.
*
* ```handlebars
* {{relative a b}}
...
extname = function (filepath) { return path.extname(filepath); }
...
* @param {String} `fp` filepath to the file to embed.
* @param {String} `language` Optionally specify the language to use for syntax highlighting.
* @return {String}
* @api public
*/
helpers.embed = function embed(fp, ext) {
ext = typeof ext !== 'string' ? path.extname(fp).slice(1) : ext;
var code = fs.readFileSync(fp, 'utf8');
if (ext === 'markdown' || ext === 'md') {
ext = 'markdown';
// if the string is markdown, escape backticks
code = code.split('`').join('`');
}
return utils.block(code, ext).trim() + '\n';
...
relative = function (a, b) { return utils.relative(a, b); }
...
* @param {String} `a`
* @param {String} `b`
* @return {String}
* @api public
*/
helpers.relative = function(a, b) {
return utils.relative(a, b);
};
/**
* Get the file extension from the given `filepath`.
*
* ```handlebars
* {{basename "docs/toc.md"}}
...
segments = function (fp, a, b) { return utils.normalize(fp).split('/').slice(a, b).join('/'); }
n/a
stem = function (filepath) { return path.basename(filepath, path.extname(filepath)); }
n/a
camelcase = function (str) { return utils.changecase(str, function(ch) { return ch.toUpperCase(); }); }
n/a
capitalize = function (str) { if (str && typeof str === 'string') { return str.charAt(0).toUpperCase() + str.slice(1); } }
...
* @return {String}
* @api public
*/
helpers.capitalizeAll = function(str) {
if (str && typeof str === 'string') {
return str.replace(/\w\S*/g, function(word) {
return exports.capitalize(word);
});
}
};
/**
* Center a string using non-breaking spaces
*
...
capitalizeAll = function (str) { if (str && typeof str === 'string') { return str.replace(/\w\S*/g, function(word) { return exports.capitalize(word); }); } }
n/a
center = function (str, spaces) { if (str && typeof str === 'string') { var space = ''; var i = 0; while (i < spaces) { space += ' '; i++; } return space + str + space; } }
n/a
chop = function (str) { return utils.chop(str); }
...
* @name .chop
* @param {String} `string` The string to chop.
* @return {String}
* @api public
*/
helpers.chop = function(str) {
return utils.chop(str);
};
/**
* dash-case the characters in `string`. Replaces non-word
* characters and periods with hyphens.
*
* ```js
...
dashcase = function (str) { return utils.changecase(str, function(ch) { return '-' + ch; }); }
n/a
dotcase = function (str) { return utils.changecase(str, function(ch) { return '.' + ch; }); }
n/a
hyphenate = function (str) { if (str && typeof str === 'string') { return str.split(' ').join('-'); } }
n/a
isString = function (value) { return utils.isString(value); }
...
* ```
* @param {String} `value`
* @return {Boolean}
* @api public
*/
helpers.isString = function(value) {
return utils.isString(value);
};
/**
* Lowercase all characters in the given string.
*
* ```handlebars
* {{lowercase "Foo BAR baZ"}}
...
lowercase = function (str) { if (str && typeof str === 'string') { return str.toLowerCase(); } }
n/a
occurrences = function (str, substring) { if (str && typeof str === 'string') { var len = substring.length; var pos = 0; var n = 0; while ((pos = str.indexOf(substring, pos))) { if (pos > -1) { n++; pos += len; } else { break; } } return n; } }
n/a
pascalcase = function (str) { str = utils.changecase(str, function(ch) { return ch.toUpperCase(); }); return str.charAt(0).toUpperCase() + str.slice(1); }
n/a
pathcase = function (str) { return utils.changecase(str, function(ch) { return '/' + ch; }); }
n/a
plusify = function (str) { if (str && typeof str === 'string') { return str.split(' ').join('+'); } }
n/a
replace = function (str, a, b) { if (str && typeof str === 'string') { if (!a || typeof a !== 'string') return str; if (!b || typeof b !== 'string') b = ''; return str.split(a).join(b); } }
...
*
* @param {Number} `num`
* @return {Number}
* @api public
*/
helpers.addCommas = function(num) {
return num.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,');
};
/**
* Convert a string or number to a formatted phone number.
*
* @param {Number|String} `num` The phone number to format, e.g. `8005551212`
* @return {Number} Formatted phone number: `(800) 555-1212`
...
reverse = function (str) { if (str && typeof str === 'string') { return str.split('').reverse().join(''); } }
...
* @param {String|Function} `key` The object key to sort by, or sorting function.
* @api public
*/
helpers.sort = function(arr, options) {
if (utils.isUndefined(arr)) return '';
if (utils.get(options, 'hash.reverse')) {
return arr.sort().reverse();
}
return arr.sort();
};
/**
* Sort an `array`. If an array of objects is passed,
* you may optionally pass a `key` to sort on as the second
...
sentence = function (str) { if (str && typeof str === 'string') { var re = /((?:\S[^\.\?\!]*)[\.\?\!]*)/g; return str.replace(re, function(txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } }
n/a
snakecase = function (str) { return utils.changecase(str, function(ch) { return '_' + ch; }); }
n/a
split = function (str, ch) { if (!helpers.isString(str)) return ''; if (typeof ch !== 'string') ch = ','; return str.split(ch); }
...
helpers.embed = function embed(fp, ext) {
ext = typeof ext !== 'string' ? path.extname(fp).slice(1) : ext;
var code = fs.readFileSync(fp, 'utf8');
if (ext === 'markdown' || ext === 'md') {
ext = 'markdown';
// if the string is markdown, escape backticks
code = code.split('`').join('`');
}
return utils.block(code, ext).trim() + '\n';
};
/**
* Embed a GitHub Gist using only the id of the Gist
*
...
startsWith = function (prefix, str, options) { var args = [].slice.call(arguments); options = args.pop(); if (str && typeof str === 'string') { if (str.indexOf(prefix) === 0) { return options.fn(this); } } if (typeof options.inverse === 'function') { return options.inverse(this); } return ''; }
n/a
titleize = function (str) { if (str && typeof str === 'string') { var title = str.replace(/[ \-_]+/g, ' '); var words = title.match(/\w+/g); var len = words.length; var res = []; var i = 0; while (len--) { var word = words[i++]; res.push(exports.capitalize(word)); } return res.join(' '); } }
n/a
trim = function (str) { if (!helpers.isString(str)) return ''; return str.trim(); }
...
ext = typeof ext !== 'string' ? path.extname(fp).slice(1) : ext;
var code = fs.readFileSync(fp, 'utf8');
if (ext === 'markdown' || ext === 'md') {
ext = 'markdown';
// if the string is markdown, escape backticks
code = code.split('`').join('`');
}
return utils.block(code, ext).trim() + '\n';
};
/**
* Embed a GitHub Gist using only the id of the Gist
*
* ```handlebars
* {{gist "12345"}}
...
uppercase = function (str, options) { if (str && typeof str === 'string') { return str.toUpperCase(); } else { options = str; } if (typeof options === 'object' && options.fn) { return options.fn(this).toUpperCase(); } return ''; }
n/a
decodeURI = function (str) { return decodeURIComponent(str); }
n/a
encodeURI = function (str) { return encodeURIComponent(str); }
n/a
stripProtocol = function (str) { var parsed = url.parse(str); delete parsed.protocol; return parsed.format(); }
n/a
stripQuerystring = function (url) { return url.split('?')[0]; }
n/a
urlParse = function (str) { return url.parse(str); }
n/a
urlResolve = function (base, href) { return url.resolve(base, href); }
n/a
function proxy(name, alias) { var key = alias; // camel-case the module `name` if `alias` is not defined if (typeof key !== 'string') { key = camelcase(name); } // create a getter to lazily invoke the module the first time it's called function getter() { return cache[key] || (cache[key] = requireFn(name)); } // trip the getter if `process.env.UNLAZY` is defined if (unlazy(process.env)) { getter(); } set(proxy, key, getter); return getter; }
n/a
arrayify = function (val) { return val ? (Array.isArray(val) ? val : [val]) : []; }
...
helpers.css = function(array, options) {
if (arguments.length < 2) {
options = array;
array = [];
}
var styles = utils.arrayify(array);
var assets = '';
if (this && this.options) {
assets = this.options.assets || '';
}
if (options.hash.href) {
...
function pre(str, lang) { if (typeof str !== 'string') { throw new TypeError('markdown-pre expects a string.'); } var code = ''; code += '```' + (typeof lang === 'string' ? lang : ''); code += '\n'; code += str; code += '\n'; code += '```'; return code; }
...
ext = typeof ext !== 'string' ? path.extname(fp).slice(1) : ext;
var code = fs.readFileSync(fp, 'utf8');
if (ext === 'markdown' || ext === 'md') {
ext = 'markdown';
// if the string is markdown, escape backticks
code = code.split('`').join('`');
}
return utils.block(code, ext).trim() + '\n';
};
/**
* Embed a GitHub Gist using only the id of the Gist
*
* ```handlebars
* {{gist "12345"}}
...
changecase = function (str, fn) { if (!utils.isString(str)) return ''; if (str.length === 1) { return str.toLowerCase(); } str = utils.chop(str).toLowerCase(); if (typeof fn !== 'function') { fn = utils.identity; } var re = /[-_.\W\s]+(\w|$)/g; return str.replace(re, function(_, ch) { return fn(ch); }); }
...
* `string` **{String}**: The string to change.
* `returns` **{String}**
**Example**
```js
utils.changecase('fooBarBaz');
//=> 'foo bar baz'
utils.changecase('fooBarBaz' '-');
//=> 'foo-bar-baz'
```
### [{{random}}](lib/utils/index.js#L137)
...
chop = function (str) { if (!utils.isString(str)) return ''; var re = /^[-_.\W\s]+|[-_.\W\s]+$/g; return str.trim().replace(re, ''); }
...
* @name .chop
* @param {String} `string` The string to chop.
* @return {String}
* @api public
*/
helpers.chop = function(str) {
return utils.chop(str);
};
/**
* dash-case the characters in `string`. Replaces non-word
* characters and periods with hyphens.
*
* ```js
...
contains = function (val, obj, start) { var len = val ? val.length : 0; var idx = start < 0 ? Math.max(0, len + start) : start; var res = false; var i = 0; start = idx || 0; if (Array.isArray(val)) { res = utils.indexOf(val, obj, start) > -1; } else if (utils.isNumber(len)) { res = (typeof val === 'string' ? val.indexOf(obj, start) : utils.indexOf(val, obj, start)) > -1; } else { utils.iterator(val, function(ele) { if (start < i++) { return !(res = (ele === obj)); } }); } return res; }
...
*/
helpers.contains = function(collection, value, startIndex, options) {
if (typeof startIndex === 'object') {
options = startIndex;
startIndex = undefined;
}
if (utils.contains(collection, value, startIndex)) {
return options.fn(this);
}
return options.inverse(this);
};
/**
* Block helper that renders a block if `a` is **greater than** `b`.
...
function createFrame(data) { if (!utils.isObject(data)) { throw new TypeError('createFrame expects data to be an object'); } var extend = utils.extend; var frame = extend({}, data); frame._parent = data; utils.define(frame, 'extend', function(data) { extend(this, data); }); if (arguments.length > 1) { var args = [].slice.call(arguments, 1); var len = args.length, i = -1; while (++i < len) { frame.extend(args[i] || {}); } } return frame; }
...
* @param {Array} `array`
* @return {String}
* @block
* @api public
*/
helpers.forEach = function(array, options) {
var data = utils.createFrame(options, options.hash);
var len = array.length;
var buffer = '';
var i = -1;
while (++i < len) {
var item = array[i];
data.index = i;
...
function filter(arr, fn, thisArg) { if (arr == null) { return []; } if (typeof fn !== 'function') { throw new TypeError('expected callback to be a function'); } var iterator = makeIterator(fn, thisArg); var len = arr.length; var res = arr.slice(); var i = -1; while (len--) { if (!iterator(arr[len], i++)) { res.splice(len, 1); } } return res; }
...
helpers.filter = function(array, value, options) {
var content = '';
var results = [];
// filter on a specific property
var prop = options.hash && options.hash.property;
if (prop) {
results = utils.filter(array, function(val) {
return utils.get(val, prop) === value;
});
} else {
// filter on a string value
results = utils.filter(array, function(v) {
return value === v;
...
function flatten(arr) { return flat(arr, []); }
...
* @name .sum
* @param {Array} `array` Array of numbers to add up.
* @return {Number}
* @api public
*/
helpers.sum = function() {
var args = utils.flatten([].concat.apply([], arguments));
var i = args.length, sum = 0;
while (i--) {
if (!utils.isNumber(args[i])) {
continue;
}
sum += (+args[i]);
}
...
function forOwn(obj, fn, thisArg) { forIn(obj, function(val, key) { if (hasOwn.call(obj, key)) { return fn.call(thisArg, obj[key], key, obj); } }); }
n/a
get = function (obj, prop, a, b, c) { if (!isObject(obj) || !prop) { return obj; } prop = toString(prop); // allowing for multiple properties to be passed as // a string or array, but much faster (3-4x) than doing // `[].slice.call(arguments)` if (a) prop += '.' + toString(a); if (b) prop += '.' + toString(b); if (c) prop += '.' + toString(c); if (prop in obj) { return obj[prop]; } var segs = prop.split('.'); var len = segs.length; var i = -1; while (obj && (++i < len)) { var key = segs[i]; while (key[key.length - 1] === '\\') { key = key.slice(0, -1) + '.' + segs[++i]; } obj = obj[key]; } return obj; }
...
var content = '';
var results = [];
// filter on a specific property
var prop = options.hash && options.hash.property;
if (prop) {
results = utils.filter(array, function(val) {
return utils.get(val, prop) === value;
});
} else {
// filter on a string value
results = utils.filter(array, function(v) {
return value === v;
});
...
getArgs = function (app, args) { var opts = utils.merge({}, app && app.options); if (!Array.isArray(args)) { args = [].slice.call(args); } var last = args[args.length - 1]; // merge `options.hash` into the options if (utils.isOptions(last)) { var hbsOptions = args.pop(); opts = utils.get(opts, hbsOptions.name) || opts; opts = utils.merge({}, opts, hbsOptions.hash); // if the last arg is an object, merge it // into the options } else if (utils.isObject(last)) { opts = utils.merge({}, opts, args.pop()); } args.push(opts); return args; }
...
* @param {Array|String} `patterns` One or more glob patterns.
* @param {Object} `options`
* @return {Array} Array of matches
* @api public
*/
helpers.mm = function() {
var args = utils.getArgs(this, arguments);
return utils.mm.apply(utils.mm, args);
};
/**
* Returns an array of files that match the given glob pattern.
* Options may be passed on the hash or on `this.options`.
*
...
function getObject(obj, prop) { if (!prop) return obj; if (!obj) return {}; var segs = String(prop).split(/[[.\]]/).filter(Boolean); var last = segs[segs.length - 1], res = {}; while (prop = segs.shift()) { obj = obj[prop]; if (!obj) return {}; } if (isNumber(last)) return [obj]; res[last] = obj; return res; }
...
* @param {String} `prop` The property to get, optionally using dot notation for nested properties.
* @param {Object} `context` The context object
* @return {String}
* @api public
*/
helpers.getObject = function(prop, context) {
return utils.getObject(context, prop);
};
/**
* Return true if `key` is an own, enumerable property
* of the given `context` object.
*
* ```handlebars
...
identity = function (val) { return val; }
n/a
function indexOf(arr, ele, start) { start = start || 0; var idx = -1; if (arr == null) return idx; var len = arr.length; var i = start < 0 ? (len + start) : start; if (i >= arr.length) { return -1; } while (i < len) { if (arr[i] === ele) { return i; } i++; } return -1; }
...
* @param {Object} `options`
* @return {String}
* @block
* @api public
*/
helpers.inArray = function(array, value, options) {
if (utils.indexOf(array, value) > -1) {
return options.fn(this);
}
return options.inverse(this);
};
/**
* Returns true if `value` is an es5 array.
...
isEmpty = function (val) { if (val === 0 || val === '0') { return false; } if (!val || (Array.isArray(val) && val.length === 0)) { return true; } if (typeof val === 'object' && !Object.keys(val).length) { return true; } return false; }
n/a
function isEven(i) { if (!isNumber(i)) { throw new TypeError('is-even expects a number.'); } return !isOdd(i); }
...
* @param {Object} `options` Handlebars provided options object
* @return {String} Block, or inverse block if specified and falsey.
* @block
* @api public
*/
helpers.ifEven = function(num, options) {
return utils.isEven(num)
? options.fn(this)
: options.inverse(this);
};
/**
* Conditionally renders a block if the remainder is zero when
* `a` operand is divided by `b`. If an inverse block is specified
...
function isGlob(str) { if (typeof str !== 'string' || str === '') { return false; } if (isExtglob(str)) return true; var regex = /(\\).|([*?]|\[.*\]|\{.*\}|\(.*\|.*\)|^!)/; var match; while ((match = regex.exec(str))) { if (match[2]) return true; str = str.slice(match.index + match[0].length); } return false; }
...
}
if (utils.isRegex(filter)) {
var re = utils.toRegex(filter);
return files.filter(function(fp) {
return re.test(fp);
});
}
if (utils.isGlob(filter)) {
var isMatch = utils.mm.matcher(filter);
return files.filter(function(fp) {
return isMatch(fp);
});
}
if (['isFile', 'isDirectory'].indexOf(filter) !== -1) {
return files.filter(function(fp) {
...
function isNumber(num) { var type = typeOf(num); if (type === 'string') { if (!num.trim()) return false; } else if (type !== 'number') { return false; } return (num - num + 1) >= 0; }
...
* @param {Number} `n` Number of items to return, starting at `0`.
* @return {Array}
* @api public
*/
helpers.first = function(array, n) {
if (utils.isUndefined(array)) return '';
if (!utils.isNumber(n)) {
return array[0];
}
return array.slice(0, n);
};
/**
* Iterates over each item in an array and exposes the current item
...
isObject = function (val) { return val && typeof val === 'object' && !Array.isArray(val); }
...
* @block
* @api public
*/
helpers.iterate = function(context, options) {
if (Array.isArray(context)) {
return forEach.apply(forEach, arguments);
} else if (utils.isObject(context)) {
return forOwn.apply(forOwn, arguments);
}
return options.inverse(this);
};
/**
* Returns the length of the given collection. When using a string literal in the
...
function isOdd(i) { if (!isNumber(i)) { throw new TypeError('is-odd expects a number.'); } return !!(~~i & 1); }
...
* @param {Object} `options` Handlebars provided options object
* @return {String} Block, or inverse block if specified and falsey.
* @block
* @api public
*/
helpers.ifOdd = function(val, options) {
return utils.isOdd(val)
? options.fn(this)
: options.inverse(this);
};
/**
* Block helper that renders a block if `a` is **equal to** `b`.
* If an inverse block is specified it will be rendered when falsy.
...
isOptions = function (val) { return utils.isObject(val) && val.hasOwnProperty('hash'); }
...
*/
helpers.readdir = function(dir, filter) {
var files = fs.readdirSync(dir);
files = files.map(function(fp) {
return path.join(dir, fp);
});
if (utils.isOptions(filter)) {
return files;
}
if (typeof filter === 'function') {
return filter(files);
}
if (utils.isRegex(filter)) {
var re = utils.toRegex(filter);
...
isRegex = function (val) { if (utils.typeOf(val) === 'regexp') { return true; } if (typeof val !== 'string') { return false; } return val.charAt(0) === '/' && val.slice(-1) === '\/'; }
...
});
if (utils.isOptions(filter)) {
return files;
}
if (typeof filter === 'function') {
return filter(files);
}
if (utils.isRegex(filter)) {
var re = utils.toRegex(filter);
return files.filter(function(fp) {
return re.test(fp);
});
}
if (utils.isGlob(filter)) {
var isMatch = utils.mm.matcher(filter);
...
isString = function (val) { return val && typeof val === 'string'; }
...
* ```
* @param {String} `value`
* @return {Boolean}
* @api public
*/
helpers.isString = function(value) {
return utils.isString(value);
};
/**
* Lowercase all characters in the given string.
*
* ```handlebars
* {{lowercase "Foo BAR baZ"}}
...
isUndefined = function (val) { return typeof val === 'undefined' || (val.hash != null); }
...
* @param {Array} `array` Collection
* @param {Number} `n` Starting index (number of items to exclude)
* @return {Array} Array exluding `n` items.
* @api public
*/
helpers.after = function(array, n) {
if (utils.isUndefined(array)) return '';
return array.slice(n);
};
/**
* Cast the given `value` to an array.
*
* ```handlebars
...
function makeIterator(target, thisArg) { switch (typeOf(target)) { case 'undefined': case 'null': return noop; case 'function': // function is the first to improve perf (most common case) // also avoid using `Function#call` if not needed, which boosts // perf a lot in some cases return (typeof thisArg !== 'undefined') ? function(val, i, arr) { return target.call(thisArg, val, i, arr); } : target; case 'object': return function(val) { return deepMatches(val, target); }; case 'regexp': return function(str) { return target.test(str); }; case 'string': case 'number': default: { return prop(target); } } }
...
* @param {Options} Handlebars provided options object
* @return {Array}
* @block
* @api public
*/
helpers.some = function(arr, cb, options) {
cb = utils.iterator(cb, this);
if (arr == null) {
return options.inverse(this);
}
var len = arr.length, i = -1;
while (++i < len) {
if (cb(arr[i], i, arr)) {
return options.fn(this);
...
function mixinDeep(target, objects) { var len = arguments.length, i = 0; while (++i < len) { var obj = arguments[i]; if (isObject(obj)) { forIn(obj, copy, target); } } return target; }
...
*
* @param {Object} `params`
* @return {String}
* @api public
*/
helpers.jsfiddle = function jsFiddle(options) {
var attr = object.merge({}, options, options.hash);
delete attr.name;
delete attr.hash;
delete attr.data;
if (typeof attr.id === 'undefined') {
throw new Error('jsfiddle helper expects an `id`');
}
...
function micromatch(files, patterns, opts) { if (!files || !patterns) return []; opts = opts || {}; if (typeof opts.cache === 'undefined') { opts.cache = true; } if (!Array.isArray(patterns)) { return match(files, patterns, opts); } var len = patterns.length, i = 0; var omit = [], keep = []; while (len--) { var glob = patterns[i++]; if (typeof glob === 'string' && glob.charCodeAt(0) === 33 /* ! */) { omit.push.apply(omit, match(files, glob.slice(1), opts)); } else { keep.push.apply(keep, match(files, glob, opts)); } } return utils.diff(keep, omit); }
n/a
function normalizePath(str, stripTrailing) { if (typeof str !== 'string') { throw new TypeError('expected a string'); } str = str.replace(/[\\\/]+/g, '/'); if (stripTrailing !== false) { str = removeTrailingSeparator(str); } return str; }
...
*
* @param {String} `filepath` The file path to split into segments.
* @return {String} Returns a single, joined file path.
* @api public
*/
helpers.segments = function(fp, a, b) {
return utils.normalize(fp).split('/').slice(a, b).join('/');
};
...
random = function (min, max) { return min + Math.floor(Math.random() * (max - min + 1)); }
...
* @param {Number} `max`
* @contributor Tim Douglas <https://github.com/timdouglas>
* @return {String}
* @api public
*/
helpers.random = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
/**
* Abbreviate numbers to the given number of `precision`. This is for
* general numbers, not size in bytes.
*
* @param {Number} `number`
...
function relative(a, b, stat) { if (typeof a !== 'string') { throw new TypeError('relative expects a string.'); } if (a == '' && !b) return a; var len = arguments.length; if (len === 1) { b = a; a = process.cwd(); stat = null; } if (len === 2 && typeof b === 'boolean') { b = a; a = process.cwd(); stat = true; } if (len === 2 && typeof b === 'object') { stat = b; b = a; a = process.cwd(); } var origB = b; // see if a slash exists before normalizing var slashA = endsWith(a, '/'); var slashB = endsWith(b, '/'); a = unixify(a); b = unixify(b); // if `a` had a slash, add it back if (slashA) { a = a + '/'; } if (isFile(a, stat)) { a = path.dirname(a); } var res = path.relative(a, b); if (res === '') { return '.'; } // if `b` originally had a slash, and the path ends // with `b` missing a slash, then re-add the slash. var noslash = trimEnd(origB, '/'); if (slashB && (res === noslash || endsWith(res, noslash))) { res = res + '/'; } return res; }
...
* @param {String} `a`
* @param {String} `b`
* @return {String}
* @api public
*/
helpers.relative = function(a, b) {
return utils.relative(a, b);
};
/**
* Get the file extension from the given `filepath`.
*
* ```handlebars
* {{basename "docs/toc.md"}}
...
result = function (value) { if (typeof value === 'function') { return value(); } return value; }
...
* @return {String}
* @block
* @api public
*/
helpers.withFirst = function(arr, idx, options) {
if (utils.isUndefined(arr)) return '';
arr = utils.result(arr);
if (!utils.isUndefined(idx)) {
idx = parseFloat(utils.result(idx));
}
if (utils.isUndefined(idx)) {
options = idx;
...
function arraySort(arr, props, opts) { if (arr == null) { return []; } if (!Array.isArray(arr)) { throw new TypeError('array-sort expects an array.'); } if (arguments.length === 1) { return arr.sort(); } var args = flatten([].slice.call(arguments, 1)); // if the last argument appears to be a plain object, // it's not a valid `compare` arg, so it must be options. if (typeOf(args[args.length - 1]) === 'object') { opts = args.pop(); } return arr.sort(sortBy(args, opts)); }
n/a
tag = function (tag, attribs, text) { if (!isObject(attribs)) { text = attribs; attribs = {}; } if (typeof text === 'undefined') { text = ''; } if (typeof text !== 'string') { throw new TypeError('expected text to be a string'); } var html = '<' + tag; for (var key in attribs) { var val = attribs[key]; if (val === true) { html += ' ' + key; } if (typeof val === 'string') { html += ' ' + key + '="' + val + '"'; } } if (voidElements.hasOwnProperty(tag)) { return html + '>' + text; } return html + '>' + text + '</' + tag + '>'; }
...
* ```
* @param {String} `id`
* @return {String}
* @api public
*/
helpers.gist = function(id) {
return utils.tag('script', {src: 'https://gist.github.com/' + id
+ '.js'});
};
/**
* Generate the HTML for a jsFiddle link with the given `params`
*
* ```handlebars
* {{jsfiddle id="0dfk10ks" tabs="true"}}
...
toRegex = function (val) { return new RegExp(val.replace(/^\/|\/$/g, '')); }
...
* `value` **{Object}**
* `returns` **{Boolean}**
**Example**
```js
utils.toRegex('"/foo/"');
//=> /foo/
```
### [{{isRegex}}](lib/utils/index.js#L69)
Returns true if the given value appears to be a
regular expression.
...
tryParse = function (str) { try { return JSON.parse(str); } catch (err) {} return null; }
...
* @return {String}
* @api public
*/
helpers.map = function(array, fn) {
if (utils.isUndefined(array)) return '';
if (typeof array === 'string' && /[[]/.test(array)) {
array = utils.tryParse(array) || [];
}
var len = array.length;
var res = new Array(len);
var i = -1;
while (++i < len) {
res[i] = fn(array[i], i, array);
...
function kindOf(val) { // primitivies if (typeof val === 'undefined') { return 'undefined'; } if (val === null) { return 'null'; } if (val === true || val === false || val instanceof Boolean) { return 'boolean'; } if (typeof val === 'string' || val instanceof String) { return 'string'; } if (typeof val === 'number' || val instanceof Number) { return 'number'; } // functions if (typeof val === 'function' || val instanceof Function) { return 'function'; } // array if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { return 'array'; } // check for instances of RegExp and Date before calling `toString` if (val instanceof RegExp) { return 'regexp'; } if (val instanceof Date) { return 'date'; } // other objects var type = toString.call(val); if (type === '[object RegExp]') { return 'regexp'; } if (type === '[object Date]') { return 'date'; } if (type === '[object Arguments]') { return 'arguments'; } if (type === '[object Error]') { return 'error'; } // buffer if (typeof Buffer !== 'undefined' && isBuffer(val)) { return 'buffer'; } // es6: Map, WeakMap, Set, WeakSet if (type === '[object Set]') { return 'set'; } if (type === '[object WeakSet]') { return 'weakset'; } if (type === '[object Map]') { return 'map'; } if (type === '[object WeakMap]') { return 'weakmap'; } if (type === '[object Symbol]') { return 'symbol'; } // typed arrays if (type === '[object Int8Array]') { return 'int8array'; } if (type === '[object Uint8Array]') { return 'uint8array'; } if (type === '[object Uint8ClampedArray]') { return 'uint8clampedarray'; } if (type === '[object Int16Array]') { return 'int16array'; } if (type === '[object Uint16Array]') { return 'uint16array'; } if (type === '[object Int32Array]') { return 'int32array'; } if (type === '[object Uint32Array]') { return 'uint32array'; } if (type === '[object Float32Array]') { return 'float32array'; } if (type === '[object Float64Array]') { return 'float64array'; } // must be a plain object return 'object'; }
...
*
* @param {Object} `context`
* @return {String}
* @api public
*/
helpers.js = function(context) {
if (utils.typeOf(context) === 'object') {
var attr = html.toAttributes(context.hash);
return '<script' + attr + '></script>';
}
if (utils.typeOf(context) === 'string') {
return '<script src="' + context + '"></script>';
}
...
function micromatch(files, patterns, opts) { if (!files || !patterns) return []; opts = opts || {}; if (typeof opts.cache === 'undefined') { opts.cache = true; } if (!Array.isArray(patterns)) { return match(files, patterns, opts); } var len = patterns.length, i = 0; var omit = [], keep = []; while (len--) { var glob = patterns[i++]; if (typeof glob === 'string' && glob.charCodeAt(0) === 33 /* ! */) { omit.push.apply(omit, match(files, glob.slice(1), opts)); } else { keep.push.apply(keep, match(files, glob, opts)); } } return utils.diff(keep, omit); }
n/a
function any(fp, patterns, opts) { if (!Array.isArray(patterns) && typeof patterns !== 'string') { throw new TypeError(msg('any', 'patterns', 'a string or array')); } patterns = utils.arrayify(patterns); var len = patterns.length; fp = utils.unixify(fp, opts); while (len--) { var isMatch = matcher(patterns[len], opts); if (isMatch(fp)) { return true; } } return false; }
n/a
braceExpand = function (str, options) { if (typeof str !== 'string') { throw new Error('braces expects a string'); } return braces(str, options); }
n/a
braces = function (str, options) { if (typeof str !== 'string') { throw new Error('braces expects a string'); } return braces(str, options); }
n/a
function contains(fp, pattern, opts) { if (typeof fp !== 'string') { throw new TypeError(msg('contains', 'pattern', 'a string')); } opts = opts || {}; opts.contains = (pattern !== ''); fp = utils.unixify(fp, opts); if (opts.contains && !utils.isGlob(pattern)) { return fp.indexOf(pattern) !== -1; } return matcher(pattern, opts)(fp); }
...
*/
helpers.contains = function(collection, value, startIndex, options) {
if (typeof startIndex === 'object') {
options = startIndex;
startIndex = undefined;
}
if (utils.contains(collection, value, startIndex)) {
return options.fn(this);
}
return options.inverse(this);
};
/**
* Block helper that renders a block if `a` is **greater than** `b`.
...
function expand(pattern, options) {
if (typeof pattern !== 'string') {
throw new TypeError('micromatch.expand(): argument should be a string.');
}
var glob = new Glob(pattern, options || {});
var opts = glob.options;
if (!utils.isGlob(pattern)) {
glob.pattern = glob.pattern.replace(/([\/.])/g, '\\$1');
return glob;
}
glob.pattern = glob.pattern.replace(/(\+)(?!\()/g, '\\$1');
glob.pattern = glob.pattern.split('$').join('\\$');
if (typeof opts.braces !== 'boolean' && typeof opts.nobraces !== 'boolean') {
opts.braces = true;
}
if (glob.pattern === '.*') {
return {
pattern: '\\.' + star,
tokens: tok,
options: opts
};
}
if (glob.pattern === '*') {
return {
pattern: oneStar(opts.dot),
tokens: tok,
options: opts
};
}
// parse the glob pattern into tokens
glob.parse();
var tok = glob.tokens;
tok.is.negated = opts.negated;
// dotfile handling
if ((opts.dotfiles === true || tok.is.dotfile) && opts.dot !== false) {
opts.dotfiles = true;
opts.dot = true;
}
if ((opts.dotdirs === true || tok.is.dotdir) && opts.dot !== false) {
opts.dotdirs = true;
opts.dot = true;
}
// check for braces with a dotfile pattern
if (/[{,]\./.test(glob.pattern)) {
opts.makeRe = false;
opts.dot = true;
}
if (opts.nonegate !== true) {
opts.negated = glob.negated;
}
// if the leading character is a dot or a slash, escape it
if (glob.pattern.charAt(0) === '.' && glob.pattern.charAt(1) !== '/') {
glob.pattern = '\\' + glob.pattern;
}
/**
* Extended globs
*/
// expand braces, e.g `{1..5}`
glob.track('before braces');
if (tok.is.braces) {
glob.braces();
}
glob.track('after braces');
// expand extglobs, e.g `foo/!(a|b)`
glob.track('before extglob');
if (tok.is.extglob) {
glob.extglob();
}
glob.track('after extglob');
// expand brackets, e.g `[[:alpha:]]`
glob.track('before brackets');
if (tok.is.brackets) {
glob.brackets();
}
glob.track('after brackets');
// special patterns
glob._replace('[!', '[^');
glob._replace('(?', '(%~');
glob._replace(/\[\]/, '\\[\\]');
glob._replace('/[', '/' + (opts.dot ? dotfiles : nodot) + '[', true);
glob._replace('/?', '/' + (opts.dot ? dotfiles : nodot) + '[^/]', true);
glob._replace('/.', '/(?=.)\\.', true);
// windows drives
glob._replace(/^(\w):([\\\/]+?)/gi, '(?=.)$1:$2', true);
// negate slashes in exclusion ranges
if (glob.pattern.indexOf('[^') !== -1) {
glob.pattern = negateSlash(glob.pattern);
}
if (opts.globstar !== false && glob.pattern === '**') {
glob.pattern = globstar(opts.dot);
} else {
glob.pattern = balance(glob.pattern, '[', ']');
glob.escape(glob.pattern);
// if the pattern has `**`
if (tok.is.globstar) {
glob.pattern = collapse(glob.pattern, '/**');
glob.pattern = collapse(glob.pattern, '**/');
glob._replace('/**/', '(?:/' + globstar(opts.dot) + '/|/)', true);
glob._replace(/\*{2,}/g, '**');
// 'foo/*'
glob._replace(/(\w+)\*(?!\/)/g, '$1[^/]*?', true);
glob._replace(/\*\*\/\*(\w)/g, globstar(opts.dot) + '\\/' + (opts.dot ? dotfiles : nodot) + '[^/]*?$1', true);
if (opts.dot !== true) {
glob._replace(/\*\*\/(.)/g, '(?:**\\/|)$1');
}
// 'foo/**' or '{**,*}', but not 'foo**'
if (tok.path.dirname !== '' || /,\*\*|\*\*,/.test(glob.orig)) {
glob._replace('**', globstar(opts.dot), true);
}
}
// ends with /*
glob._replace(/\/\*$/, '\\/' + oneStar(opts.dot), true);
// ends with *, no slashes
glob._replace(/(?!\/)\*$/, star, true);
// has 'n*.' (partial wildcard w/ file extension)
glob._replace(/([^\/]+)\*/, '$1' + oneStar(true), true);
// has '*'
glob._replace('*', oneStar(opts.dot), true);
glob._replace('?.', '?\\.', true);
glob._replace('?:', '?:', true);
glob._replace(/\?+/g, function(match) {
var len = match.length;
if (len === 1) {
return qmark;
}
return qmark + '{' ...
n/a
function filter(patterns, opts) { if (!Array.isArray(patterns) && typeof patterns !== 'string') { throw new TypeError(msg('filter', 'patterns', 'a string or array')); } patterns = utils.arrayify(patterns); var len = patterns.length, i = 0; var patternMatchers = Array(len); while (i < len) { patternMatchers[i] = matcher(patterns[i++], opts); } return function(fp) { if (fp == null) return []; var len = patternMatchers.length, i = 0; var res = true; fp = utils.unixify(fp, opts); while (i < len) { var fn = patternMatchers[i++]; if (!fn(fp)) { res = false; break; } } return res; }; }
...
helpers.filter = function(array, value, options) {
var content = '';
var results = [];
// filter on a specific property
var prop = options.hash && options.hash.property;
if (prop) {
results = utils.filter(array, function(val) {
return utils.get(val, prop) === value;
});
} else {
// filter on a string value
results = utils.filter(array, function(v) {
return value === v;
...
function isMatch(fp, pattern, opts) { if (typeof fp !== 'string') { throw new TypeError(msg('isMatch', 'filepath', 'a string')); } fp = utils.unixify(fp, opts); if (utils.typeOf(pattern) === 'object') { return matcher(fp, pattern); } return matcher(pattern, opts)(fp); }
n/a
function makeRe(glob, opts) { if (utils.typeOf(glob) !== 'string') { throw new Error(msg('makeRe', 'glob', 'a string')); } return utils.cache(toRegex, glob, opts); }
n/a
function match(files, pattern, opts) { if (utils.typeOf(files) !== 'string' && !Array.isArray(files)) { throw new Error(msg('match', 'files', 'a string or array')); } files = utils.arrayify(files); opts = opts || {}; var negate = opts.negate || false; var orig = pattern; if (typeof pattern === 'string') { negate = pattern.charAt(0) === '!'; if (negate) { pattern = pattern.slice(1); } // we need to remove the character regardless, // so the above logic is still needed if (opts.nonegate === true) { negate = false; } } var _isMatch = matcher(pattern, opts); var len = files.length, i = 0; var res = []; while (i < len) { var file = files[i++]; var fp = utils.unixify(file, opts); if (!_isMatch(fp)) { continue; } res.push(fp); } if (res.length === 0) { if (opts.failglob === true) { throw new Error('micromatch.match() found no matches for: "' + orig + '".'); } if (opts.nonull || opts.nullglob) { res.push(utils.unescapeGlob(orig)); } } // if `negate` was defined, diff negated files if (negate) { res = utils.diff(files, res); } // if `ignore` was defined, diff ignored filed if (opts.ignore && opts.ignore.length) { pattern = opts.ignore; opts = utils.omit(opts, ['ignore']); res = utils.diff(res, micromatch(res, pattern, opts)); } if (opts.nodupes) { return utils.unique(res); } return res; }
...
* @return {String}
* @api public
*/
helpers.titleize = function(str) {
if (str && typeof str === 'string') {
var title = str.replace(/[ \-_]+/g, ' ');
var words = title.match(/\w+/g);
var len = words.length;
var res = [];
var i = 0;
while (len--) {
var word = words[i++];
res.push(exports.capitalize(word));
}
...
function matchKeys(obj, glob, options) { if (utils.typeOf(obj) !== 'object') { throw new TypeError(msg('matchKeys', 'first argument', 'an object')); } var fn = matcher(glob, options); var res = {}; for (var key in obj) { if (obj.hasOwnProperty(key) && fn(key)) { res[key] = obj[key]; } } return res; }
n/a
function matcher(pattern, opts) { // pattern is a function if (typeof pattern === 'function') { return pattern; } // pattern is a regex if (pattern instanceof RegExp) { return function(fp) { return pattern.test(fp); }; } if (typeof pattern !== 'string') { throw new TypeError(msg('matcher', 'pattern', 'a string, regex, or function')); } // strings, all the way down... pattern = utils.unixify(pattern, opts); // pattern is a non-glob string if (!utils.isGlob(pattern)) { return utils.matchPath(pattern, opts); } // pattern is a glob string var re = makeRe(pattern, opts); // `matchBase` is defined if (opts && opts.matchBase) { return utils.hasFilename(re, opts); } // `matchBase` is not defined return function(fp) { fp = utils.unixify(fp, opts); return re.test(fp); }; }
...
if (utils.isRegex(filter)) {
var re = utils.toRegex(filter);
return files.filter(function(fp) {
return re.test(fp);
});
}
if (utils.isGlob(filter)) {
var isMatch = utils.mm.matcher(filter);
return files.filter(function(fp) {
return isMatch(fp);
});
}
if (['isFile', 'isDirectory'].indexOf(filter) !== -1) {
return files.filter(function(fp) {
var stat = fs.statSync(fp);
...
function relative(a, b, stat) { if (typeof a !== 'string') { throw new TypeError('relative expects a string.'); } if (a == '' && !b) return a; var len = arguments.length; if (len === 1) { b = a; a = process.cwd(); stat = null; } if (len === 2 && typeof b === 'boolean') { b = a; a = process.cwd(); stat = true; } if (len === 2 && typeof b === 'object') { stat = b; b = a; a = process.cwd(); } var origB = b; // see if a slash exists before normalizing var slashA = endsWith(a, '/'); var slashB = endsWith(b, '/'); a = unixify(a); b = unixify(b); // if `a` had a slash, add it back if (slashA) { a = a + '/'; } if (isFile(a, stat)) { a = path.dirname(a); } var res = path.relative(a, b); if (res === '') { return '.'; } // if `b` originally had a slash, and the path ends // with `b` missing a slash, then re-add the slash. var noslash = trimEnd(origB, '/'); if (slashB && (res === noslash || endsWith(res, noslash))) { res = res + '/'; } return res; }
...
* @param {String} `a`
* @param {String} `b`
* @return {String}
* @api public
*/
helpers.relative = function(a, b) {
return utils.relative(a, b);
};
/**
* Get the file extension from the given `filepath`.
*
* ```handlebars
* {{basename "docs/toc.md"}}
...
function toBase(base, fp) { base = unixify(base); fp = unixify(fp); var res = fp.slice(base.length); if (res.charAt(0) === '/') { res = res.slice(1); } return res; }
n/a