index.js
function renderData(textString, options, data, doSpecials) {

	var replacer = function replacer(match, $1, $2) {
		var extracted,
			dataValue,
			key = String($1 || '').trim(),
			defaultValue = String($2 || '').trim();

		// literal bracket excaping via \[ text ]
		if(match.substr(0, 1) === "\\") {
			return match.substr(1);
		}

		if (options && typeof options === 'object' && options.strictKeys) {
			extracted = _extract(key, data);
			dataValue = !Number.isNaN(extracted) ? extracted : match;
		} else {
			extracted = _extract(key, data);
			dataValue = !Number.isNaN(extracted) ? extracted : defaultValue;
		}
		if (defaultValue) {
			if (null === dataValue || typeof dataValue === 'object' || typeof dataValue === 'function' ) {
				dataValue = '';
			}
		}
		return String(dataValue) || String(defaultValue);
	};

	var pattern = new RegExp('\\\\?\\[(?:\\s*([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');
	var spPattern = new RegExp('\\\\?\\[(?:\\s*(KEY|INDEX|VALUE)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');

	if(typeof data === 'object'  && data !== null) {
		if (options && typeof options === 'object' && options.prefix) {
			pattern = new RegExp('\\\\?\\[(?:\\s*'+rxquote(String(options.prefix))+'[\\.\\-\\_]([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');
		}
		if (doSpecials) {
			textString = textString.replace(spPattern, replacer);
		}
		textString = textString.replace(pattern, replacer);
	} else {
		throw new Error('No data to render!');
	}

	// clean any uncaught bracket-escape sequences
	return textString.replace(/(?:\\+)\[(.+)(?:\\+)\]/g, "[$1]").replace(/(?:\\+)\[(.+)(?:\\*)\]/g, "[$1]");
}
function renderData(textString, options, data, doSpecials) {

	var replacer = function replacer(match, $1, $2) {
		var extracted,
			dataValue,
			key = String($1 || '').trim(),
			defaultValue = String($2 || '').trim();

		// literal bracket excaping via \[ text ]
		if(match.substr(0, 1) === "\\") {
			return match.substr(1);
		}

		if (options && typeof options === 'object' && options.strictKeys) {
			extracted = _extract(key, data);
			dataValue = !Number.isNaN(extracted) ? extracted : match;
		} else {
			extracted = _extract(key, data);
			dataValue = !Number.isNaN(extracted) ? extracted : defaultValue;
		}
		if (defaultValue) {
			if (null === dataValue || typeof dataValue === 'object' || typeof dataValue === 'function' ) {
				dataValue = '';
			}
		}
		return String(dataValue) || String(defaultValue);
	};

	var pattern = new RegExp('\\\\?\\[(?:\\s*([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');
	var spPattern = new RegExp('\\\\?\\[(?:\\s*(KEY|INDEX|VALUE)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');

	if(typeof data === 'object'  && data !== null) {
		if (options && typeof options === 'object' && options.prefix) {
			pattern = new RegExp('\\\\?\\[(?:\\s*'+rxquote(String(options.prefix))+'[\\.\\-\\_]([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]', 'g');
		}
		if (doSpecials) {
			textString = textString.replace(spPattern, replacer);
		}
		textString = textString.replace(pattern, replacer);
	} else {
		throw new Error('No data to render!');
	}

	// clean any uncaught bracket-escape sequences
	return textString.replace(/(?:\\+)\[(.+)(?:\\+)\]/g, "[$1]").replace(/(?:\\+)\[(.+)(?:\\*)\]/g, "[$1]");
}
function renderData ( textString , options , data , doSpecials ) { var replacer = function replacer ( match , $1 , $2 ) { var extracted , dataValue , key = String ( $1 || '' ) . trim ( ) , defaultValue = String ( $2 || '' ) . trim ( ) ; // literal bracket excaping via \[ text ] if ( match . substr ( 0 , 1 ) === "\\" ) { return match . substr ( 1 ) ; } if ( options && typeof options === 'object' && options . strictKeys ) { extracted = _extract ( key , data ) ; dataValue = ! Number . isNaN ( extracted ) ? extracted : match ; } else { extracted = _extract ( key , data ) ; dataValue = ! Number . isNaN ( extracted ) ? extracted : defaultValue ; } if ( defaultValue ) { if ( null === dataValue || typeof dataValue === 'object' || typeof dataValue === 'function' ) { dataValue = '' ; } } return String ( dataValue ) || String ( defaultValue ) ; } ; var pattern = new RegExp ( '\\\\?\\[(?:\\s*([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]' , 'g' ) ; var spPattern = new RegExp ( '\\\\?\\[(?:\\s*(KEY|INDEX|VALUE)\\s*)(?:\\:([^\\[\\]]+))?\\]' , 'g' ) ; if ( typeof data === 'object' && data !== null ) { if ( options && typeof options === 'object' && options . prefix ) { pattern = new RegExp ( '\\\\?\\[(?:\\s*' + rxquote ( String ( options . prefix ) ) + '[\\.\\-\\_]([\\w\\-\\.]+)\\s*)(?:\\:([^\\[\\]]+))?\\]' , 'g' ) ; } if ( doSpecials ) { textString = textString . replace ( spPattern , replacer ) ; } textString = textString . replace ( pattern , replacer ) ; } else { throw new Error ( 'No data to render!' ) ; } // clean any uncaught bracket-escape sequences return textString . replace ( / (?:\\+)\[(.+)(?:\\+)\] / g , "[$1]" ) . replace ( / (?:\\+)\[(.+)(?:\\*)\] / g , "[$1]" ) ; }
Text tag renderer

@param {String} 	textString 	The template string.
@param {Object} 	options 		The current options config.
@param {Object} 	data 			The source keys and values as an object.
@param {Bool}		doSpecials 	Optional - render plain special keys [KEY, INDEX, VALUE]
@returns {String}
Text tag renderer