123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 |
- 'use strict';
-
- var lib = require('./lib');
-
- var r = require('./runtime');
-
- var _exports = module.exports = {};
-
- function normalize(value, defaultValue) {
- if (value === null || value === undefined || value === false) {
- return defaultValue;
- }
-
- return value;
- }
-
- _exports.abs = Math.abs;
-
- function isNaN(num) {
- return num !== num; // eslint-disable-line no-self-compare
- }
-
- function batch(arr, linecount, fillWith) {
- var i;
- var res = [];
- var tmp = [];
-
- for (i = 0; i < arr.length; i++) {
- if (i % linecount === 0 && tmp.length) {
- res.push(tmp);
- tmp = [];
- }
-
- tmp.push(arr[i]);
- }
-
- if (tmp.length) {
- if (fillWith) {
- for (i = tmp.length; i < linecount; i++) {
- tmp.push(fillWith);
- }
- }
-
- res.push(tmp);
- }
-
- return res;
- }
-
- _exports.batch = batch;
-
- function capitalize(str) {
- str = normalize(str, '');
- var ret = str.toLowerCase();
- return r.copySafeness(str, ret.charAt(0).toUpperCase() + ret.slice(1));
- }
-
- _exports.capitalize = capitalize;
-
- function center(str, width) {
- str = normalize(str, '');
- width = width || 80;
-
- if (str.length >= width) {
- return str;
- }
-
- var spaces = width - str.length;
- var pre = lib.repeat(' ', spaces / 2 - spaces % 2);
- var post = lib.repeat(' ', spaces / 2);
- return r.copySafeness(str, pre + str + post);
- }
-
- _exports.center = center;
-
- function default_(val, def, bool) {
- if (bool) {
- return val || def;
- } else {
- return val !== undefined ? val : def;
- }
- } // TODO: it is confusing to export something called 'default'
-
-
- _exports['default'] = default_; // eslint-disable-line dot-notation
-
- function dictsort(val, caseSensitive, by) {
- if (!lib.isObject(val)) {
- throw new lib.TemplateError('dictsort filter: val must be an object');
- }
-
- var array = []; // deliberately include properties from the object's prototype
-
- for (var k in val) {
- // eslint-disable-line guard-for-in, no-restricted-syntax
- array.push([k, val[k]]);
- }
-
- var si;
-
- if (by === undefined || by === 'key') {
- si = 0;
- } else if (by === 'value') {
- si = 1;
- } else {
- throw new lib.TemplateError('dictsort filter: You can only sort by either key or value');
- }
-
- array.sort(function (t1, t2) {
- var a = t1[si];
- var b = t2[si];
-
- if (!caseSensitive) {
- if (lib.isString(a)) {
- a = a.toUpperCase();
- }
-
- if (lib.isString(b)) {
- b = b.toUpperCase();
- }
- }
-
- return a > b ? 1 : a === b ? 0 : -1; // eslint-disable-line no-nested-ternary
- });
- return array;
- }
-
- _exports.dictsort = dictsort;
-
- function dump(obj, spaces) {
- return JSON.stringify(obj, null, spaces);
- }
-
- _exports.dump = dump;
-
- function escape(str) {
- if (str instanceof r.SafeString) {
- return str;
- }
-
- str = str === null || str === undefined ? '' : str;
- return r.markSafe(lib.escape(str.toString()));
- }
-
- _exports.escape = escape;
-
- function safe(str) {
- if (str instanceof r.SafeString) {
- return str;
- }
-
- str = str === null || str === undefined ? '' : str;
- return r.markSafe(str.toString());
- }
-
- _exports.safe = safe;
-
- function first(arr) {
- return arr[0];
- }
-
- _exports.first = first;
-
- function forceescape(str) {
- str = str === null || str === undefined ? '' : str;
- return r.markSafe(lib.escape(str.toString()));
- }
-
- _exports.forceescape = forceescape;
-
- function groupby(arr, attr) {
- return lib.groupBy(arr, attr, this.env.opts.throwOnUndefined);
- }
-
- _exports.groupby = groupby;
-
- function indent(str, width, indentfirst) {
- str = normalize(str, '');
-
- if (str === '') {
- return '';
- }
-
- width = width || 4; // let res = '';
-
- var lines = str.split('\n');
- var sp = lib.repeat(' ', width);
- var res = lines.map(function (l, i) {
- return i === 0 && !indentfirst ? l : "" + sp + l;
- }).join('\n');
- return r.copySafeness(str, res);
- }
-
- _exports.indent = indent;
-
- function join(arr, del, attr) {
- del = del || '';
-
- if (attr) {
- arr = lib.map(arr, function (v) {
- return v[attr];
- });
- }
-
- return arr.join(del);
- }
-
- _exports.join = join;
-
- function last(arr) {
- return arr[arr.length - 1];
- }
-
- _exports.last = last;
-
- function lengthFilter(val) {
- var value = normalize(val, '');
-
- if (value !== undefined) {
- if (typeof Map === 'function' && value instanceof Map || typeof Set === 'function' && value instanceof Set) {
- // ECMAScript 2015 Maps and Sets
- return value.size;
- }
-
- if (lib.isObject(value) && !(value instanceof r.SafeString)) {
- // Objects (besides SafeStrings), non-primative Arrays
- return lib.keys(value).length;
- }
-
- return value.length;
- }
-
- return 0;
- }
-
- _exports.length = lengthFilter;
-
- function list(val) {
- if (lib.isString(val)) {
- return val.split('');
- } else if (lib.isObject(val)) {
- return lib._entries(val || {}).map(function (_ref) {
- var key = _ref[0],
- value = _ref[1];
- return {
- key: key,
- value: value
- };
- });
- } else if (lib.isArray(val)) {
- return val;
- } else {
- throw new lib.TemplateError('list filter: type not iterable');
- }
- }
-
- _exports.list = list;
-
- function lower(str) {
- str = normalize(str, '');
- return str.toLowerCase();
- }
-
- _exports.lower = lower;
-
- function nl2br(str) {
- if (str === null || str === undefined) {
- return '';
- }
-
- return r.copySafeness(str, str.replace(/\r\n|\n/g, '<br />\n'));
- }
-
- _exports.nl2br = nl2br;
-
- function random(arr) {
- return arr[Math.floor(Math.random() * arr.length)];
- }
-
- _exports.random = random;
- /**
- * Construct select or reject filter
- *
- * @param {boolean} expectedTestResult
- * @returns {function(array, string, *): array}
- */
-
- function getSelectOrReject(expectedTestResult) {
- function filter(arr, testName, secondArg) {
- if (testName === void 0) {
- testName = 'truthy';
- }
-
- var context = this;
- var test = context.env.getTest(testName);
- return lib.toArray(arr).filter(function examineTestResult(item) {
- return test.call(context, item, secondArg) === expectedTestResult;
- });
- }
-
- return filter;
- }
-
- _exports.reject = getSelectOrReject(false);
-
- function rejectattr(arr, attr) {
- return arr.filter(function (item) {
- return !item[attr];
- });
- }
-
- _exports.rejectattr = rejectattr;
- _exports.select = getSelectOrReject(true);
-
- function selectattr(arr, attr) {
- return arr.filter(function (item) {
- return !!item[attr];
- });
- }
-
- _exports.selectattr = selectattr;
-
- function replace(str, old, new_, maxCount) {
- var originalStr = str;
-
- if (old instanceof RegExp) {
- return str.replace(old, new_);
- }
-
- if (typeof maxCount === 'undefined') {
- maxCount = -1;
- }
-
- var res = ''; // Output
- // Cast Numbers in the search term to string
-
- if (typeof old === 'number') {
- old = '' + old;
- } else if (typeof old !== 'string') {
- // If it is something other than number or string,
- // return the original string
- return str;
- } // Cast numbers in the replacement to string
-
-
- if (typeof str === 'number') {
- str = '' + str;
- } // If by now, we don't have a string, throw it back
-
-
- if (typeof str !== 'string' && !(str instanceof r.SafeString)) {
- return str;
- } // ShortCircuits
-
-
- if (old === '') {
- // Mimic the python behaviour: empty string is replaced
- // by replacement e.g. "abc"|replace("", ".") -> .a.b.c.
- res = new_ + str.split('').join(new_) + new_;
- return r.copySafeness(str, res);
- }
-
- var nextIndex = str.indexOf(old); // if # of replacements to perform is 0, or the string to does
- // not contain the old value, return the string
-
- if (maxCount === 0 || nextIndex === -1) {
- return str;
- }
-
- var pos = 0;
- var count = 0; // # of replacements made
-
- while (nextIndex > -1 && (maxCount === -1 || count < maxCount)) {
- // Grab the next chunk of src string and add it with the
- // replacement, to the result
- res += str.substring(pos, nextIndex) + new_; // Increment our pointer in the src string
-
- pos = nextIndex + old.length;
- count++; // See if there are any more replacements to be made
-
- nextIndex = str.indexOf(old, pos);
- } // We've either reached the end, or done the max # of
- // replacements, tack on any remaining string
-
-
- if (pos < str.length) {
- res += str.substring(pos);
- }
-
- return r.copySafeness(originalStr, res);
- }
-
- _exports.replace = replace;
-
- function reverse(val) {
- var arr;
-
- if (lib.isString(val)) {
- arr = list(val);
- } else {
- // Copy it
- arr = lib.map(val, function (v) {
- return v;
- });
- }
-
- arr.reverse();
-
- if (lib.isString(val)) {
- return r.copySafeness(val, arr.join(''));
- }
-
- return arr;
- }
-
- _exports.reverse = reverse;
-
- function round(val, precision, method) {
- precision = precision || 0;
- var factor = Math.pow(10, precision);
- var rounder;
-
- if (method === 'ceil') {
- rounder = Math.ceil;
- } else if (method === 'floor') {
- rounder = Math.floor;
- } else {
- rounder = Math.round;
- }
-
- return rounder(val * factor) / factor;
- }
-
- _exports.round = round;
-
- function slice(arr, slices, fillWith) {
- var sliceLength = Math.floor(arr.length / slices);
- var extra = arr.length % slices;
- var res = [];
- var offset = 0;
-
- for (var i = 0; i < slices; i++) {
- var start = offset + i * sliceLength;
-
- if (i < extra) {
- offset++;
- }
-
- var end = offset + (i + 1) * sliceLength;
- var currSlice = arr.slice(start, end);
-
- if (fillWith && i >= extra) {
- currSlice.push(fillWith);
- }
-
- res.push(currSlice);
- }
-
- return res;
- }
-
- _exports.slice = slice;
-
- function sum(arr, attr, start) {
- if (start === void 0) {
- start = 0;
- }
-
- if (attr) {
- arr = lib.map(arr, function (v) {
- return v[attr];
- });
- }
-
- return start + arr.reduce(function (a, b) {
- return a + b;
- }, 0);
- }
-
- _exports.sum = sum;
- _exports.sort = r.makeMacro(['value', 'reverse', 'case_sensitive', 'attribute'], [], function sortFilter(arr, reversed, caseSens, attr) {
- var _this = this;
-
- // Copy it
- var array = lib.map(arr, function (v) {
- return v;
- });
- var getAttribute = lib.getAttrGetter(attr);
- array.sort(function (a, b) {
- var x = attr ? getAttribute(a) : a;
- var y = attr ? getAttribute(b) : b;
-
- if (_this.env.opts.throwOnUndefined && attr && (x === undefined || y === undefined)) {
- throw new TypeError("sort: attribute \"" + attr + "\" resolved to undefined");
- }
-
- if (!caseSens && lib.isString(x) && lib.isString(y)) {
- x = x.toLowerCase();
- y = y.toLowerCase();
- }
-
- if (x < y) {
- return reversed ? 1 : -1;
- } else if (x > y) {
- return reversed ? -1 : 1;
- } else {
- return 0;
- }
- });
- return array;
- });
-
- function string(obj) {
- return r.copySafeness(obj, obj);
- }
-
- _exports.string = string;
-
- function striptags(input, preserveLinebreaks) {
- input = normalize(input, '');
- var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>|<!--[\s\S]*?-->/gi;
- var trimmedInput = trim(input.replace(tags, ''));
- var res = '';
-
- if (preserveLinebreaks) {
- res = trimmedInput.replace(/^ +| +$/gm, '') // remove leading and trailing spaces
- .replace(/ +/g, ' ') // squash adjacent spaces
- .replace(/(\r\n)/g, '\n') // normalize linebreaks (CRLF -> LF)
- .replace(/\n\n\n+/g, '\n\n'); // squash abnormal adjacent linebreaks
- } else {
- res = trimmedInput.replace(/\s+/gi, ' ');
- }
-
- return r.copySafeness(input, res);
- }
-
- _exports.striptags = striptags;
-
- function title(str) {
- str = normalize(str, '');
- var words = str.split(' ').map(function (word) {
- return capitalize(word);
- });
- return r.copySafeness(str, words.join(' '));
- }
-
- _exports.title = title;
-
- function trim(str) {
- return r.copySafeness(str, str.replace(/^\s*|\s*$/g, ''));
- }
-
- _exports.trim = trim;
-
- function truncate(input, length, killwords, end) {
- var orig = input;
- input = normalize(input, '');
- length = length || 255;
-
- if (input.length <= length) {
- return input;
- }
-
- if (killwords) {
- input = input.substring(0, length);
- } else {
- var idx = input.lastIndexOf(' ', length);
-
- if (idx === -1) {
- idx = length;
- }
-
- input = input.substring(0, idx);
- }
-
- input += end !== undefined && end !== null ? end : '...';
- return r.copySafeness(orig, input);
- }
-
- _exports.truncate = truncate;
-
- function upper(str) {
- str = normalize(str, '');
- return str.toUpperCase();
- }
-
- _exports.upper = upper;
-
- function urlencode(obj) {
- var enc = encodeURIComponent;
-
- if (lib.isString(obj)) {
- return enc(obj);
- } else {
- var keyvals = lib.isArray(obj) ? obj : lib._entries(obj);
- return keyvals.map(function (_ref2) {
- var k = _ref2[0],
- v = _ref2[1];
- return enc(k) + "=" + enc(v);
- }).join('&');
- }
- }
-
- _exports.urlencode = urlencode; // For the jinja regexp, see
- // https://github.com/mitsuhiko/jinja2/blob/f15b814dcba6aa12bc74d1f7d0c881d55f7126be/jinja2/utils.py#L20-L23
-
- var puncRe = /^(?:\(|<|<)?(.*?)(?:\.|,|\)|\n|>)?$/; // from http://blog.gerv.net/2011/05/html5_email_address_regexp/
-
- var emailRe = /^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;
- var httpHttpsRe = /^https?:\/\/.*$/;
- var wwwRe = /^www\./;
- var tldRe = /\.(?:org|net|com)(?:\:|\/|$)/;
-
- function urlize(str, length, nofollow) {
- if (isNaN(length)) {
- length = Infinity;
- }
-
- var noFollowAttr = nofollow === true ? ' rel="nofollow"' : '';
- var words = str.split(/(\s+)/).filter(function (word) {
- // If the word has no length, bail. This can happen for str with
- // trailing whitespace.
- return word && word.length;
- }).map(function (word) {
- var matches = word.match(puncRe);
- var possibleUrl = matches ? matches[1] : word;
- var shortUrl = possibleUrl.substr(0, length); // url that starts with http or https
-
- if (httpHttpsRe.test(possibleUrl)) {
- return "<a href=\"" + possibleUrl + "\"" + noFollowAttr + ">" + shortUrl + "</a>";
- } // url that starts with www.
-
-
- if (wwwRe.test(possibleUrl)) {
- return "<a href=\"http://" + possibleUrl + "\"" + noFollowAttr + ">" + shortUrl + "</a>";
- } // an email address of the form username@domain.tld
-
-
- if (emailRe.test(possibleUrl)) {
- return "<a href=\"mailto:" + possibleUrl + "\">" + possibleUrl + "</a>";
- } // url that ends in .com, .org or .net that is not an email address
-
-
- if (tldRe.test(possibleUrl)) {
- return "<a href=\"http://" + possibleUrl + "\"" + noFollowAttr + ">" + shortUrl + "</a>";
- }
-
- return word;
- });
- return words.join('');
- }
-
- _exports.urlize = urlize;
-
- function wordcount(str) {
- str = normalize(str, '');
- var words = str ? str.match(/\w+/g) : null;
- return words ? words.length : null;
- }
-
- _exports.wordcount = wordcount;
-
- function float(val, def) {
- var res = parseFloat(val);
- return isNaN(res) ? def : res;
- }
-
- _exports.float = float;
- var intFilter = r.makeMacro(['value', 'default', 'base'], [], function doInt(value, defaultValue, base) {
- if (base === void 0) {
- base = 10;
- }
-
- var res = parseInt(value, base);
- return isNaN(res) ? defaultValue : res;
- });
- _exports.int = intFilter; // Aliases
-
- _exports.d = _exports.default;
- _exports.e = _exports.escape;
|