Created
May 11, 2015 19:58
-
-
Save mrlannigan/65a6ee5c2dfd384df40e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (exports) { | |
var shortCodeRegex = /\{\{\s*(.+?)\}\}/g, | |
hasWhitespaceRegex = /\s+/; | |
/** | |
* @param {string} input - Parsed string | |
* @param {object} [context] - context object defining shortcodes | |
* @param {object} [callContext] - call context for any functions called within any shortcode replacement | |
* | |
* Supported Inputs: | |
* {{Count_ForSale_Total}} | |
* {{Count_ForSale_Total test="argument"}} | |
* {{Test_Func test="argument" nice="dude" }} | |
* | |
* Not Supported Inputs: | |
* {{Count_ForSale_Total test=arguments}} | |
*/ | |
exports.replace = function doShortCodeReplace(input, context, callContext) { | |
callContext = callContext || this; | |
return input.replace(shortCodeRegex, function (wholeMatch, shortCode, index) { | |
var result, | |
typeofResult, | |
codeArguments, | |
codeKey, | |
tmpCodeArguments, | |
matchedCodeArguments, | |
argumentsRegex, | |
hasWhitespace; | |
hasWhitespace = hasWhitespaceRegex.test(shortCode); | |
// test for no whitespace before checking context hash | |
if (!hasWhitespace) { | |
// grab value from keyed hash | |
result = context[shortCode]; | |
typeofResult = typeof result; | |
// check if valid | |
if (typeofResult === 'undefined') { | |
return '{{! Invalid Shortcode : "' + shortCode + '" }}'; | |
} | |
// short-circuit processing, no need to continue if not a function | |
if (typeofResult !== 'function') { | |
return result; | |
} | |
} else { | |
// if whitespace exists, start processing for arguments | |
result = shortCode; | |
} | |
// check if has arguments | |
if (hasWhitespace) { | |
argumentsRegex = /(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[$"']))+.)["']?/g; | |
result = result.split(' '); | |
codeKey = result.shift(); | |
tmpCodeArguments = result.join(' '); | |
// grab value from keyed hash | |
result = context[codeKey]; | |
typeofResult = typeof result; | |
if (typeofResult !== 'function') { | |
return result; | |
} | |
codeArguments = {}; | |
while ((matchedCodeArguments = argumentsRegex.exec(tmpCodeArguments)) != null) { | |
codeArguments[matchedCodeArguments[1]] = matchedCodeArguments[2]; | |
} | |
if (Object.keys(codeArguments).length < 1) { | |
return '{{! Invalid Shortcode : "' + shortCode + '" : Invalid arguments format given (no matches) }}'; | |
} | |
return safeFunctionCall(result, callContext, codeArguments); | |
} | |
return result; | |
}); | |
} | |
/** | |
Pass through function to safely call function and not disqualifying from compilation | |
**/ | |
function safeFunctionCall(func, context, options) { | |
try { | |
return func.call(context, options); | |
} catch (err) { | |
var _toString = err.toString; | |
err.toString = function () { | |
return '{{! ' + _toString.call(err) + ' }}'; | |
} | |
return err; | |
} | |
} | |
})(exports); | |
/***** EXAMPLE *****/ | |
var context = { | |
Count_ForSale_Total: 123456, | |
Count_ForRent_Total: 9876, | |
Test_Func: function (options) { | |
return 'Test Function: ' + JSON.stringify(options); | |
} | |
}; | |
console.log(exports.replace('{{ Count_ForSale_Total}} For Sale Homes and {{Test_Func test="dude" neat="oh" sweet="man" }} For Rent Homes', context)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment