UNPKG

sugar

Version:

A Javascript utility library for working with native objects.

90 lines (78 loc) 2.3 kB
'use strict'; var STRING_FORMAT_REG = require('../var/STRING_FORMAT_REG'), CommonChars = require('../var/CommonChars'), memoizeFunction = require('./memoizeFunction'); var OPEN_BRACE = CommonChars.OPEN_BRACE, CLOSE_BRACE = CommonChars.CLOSE_BRACE; function createFormatMatcher(bracketMatcher, percentMatcher, precheck) { var reg = STRING_FORMAT_REG; var compileMemoized = memoizeFunction(compile); function getToken(format, match) { var get, token, literal, fn; var bKey = match[2]; var pLit = match[3]; var pKey = match[5]; if (match[4] && percentMatcher) { token = pKey; get = percentMatcher; } else if (bKey) { token = bKey; get = bracketMatcher; } else if (pLit && percentMatcher) { literal = pLit; } else { literal = match[1] || match[0]; } if (get) { assertPassesPrecheck(precheck, bKey, pKey); fn = function(obj, opt) { return get(obj, token, opt); }; } format.push(fn || getLiteral(literal)); } function getSubstring(format, str, start, end) { if (end > start) { var sub = str.slice(start, end); assertNoUnmatched(sub, OPEN_BRACE); assertNoUnmatched(sub, CLOSE_BRACE); format.push(function() { return sub; }); } } function getLiteral(str) { return function() { return str; }; } function assertPassesPrecheck(precheck, bt, pt) { if (precheck && !precheck(bt, pt)) { throw new TypeError('Invalid token '+ (bt || pt) +' in format string'); } } function assertNoUnmatched(str, chr) { if (str.indexOf(chr) !== -1) { throw new TypeError('Unmatched '+ chr +' in format string'); } } function compile(str) { var format = [], lastIndex = 0, match; reg.lastIndex = 0; while(match = reg.exec(str)) { getSubstring(format, str, lastIndex, match.index); getToken(format, match); lastIndex = reg.lastIndex; } getSubstring(format, str, lastIndex, str.length); return format; } return function(str, obj, opt) { var format = compileMemoized(str), result = ''; for (var i = 0; i < format.length; i++) { result += format[i](obj, opt); } return result; }; } module.exports = createFormatMatcher;