Prism.languages['markup-templating'] = {}; Object.defineProperties(Prism.languages['markup-templating'], { buildPlaceholders: { // Tokenize all inline templating expressions matching placeholderPattern // If the replaceFilter function is provided, it will be called with every match. // If it returns false, the match will not be replaced. value: function (env, language, placeholderPattern, replaceFilter) { if (env.language !== language) { return; } env.tokenStack = []; env.code = env.code.replace(placeholderPattern, function(match) { if (typeof replaceFilter === 'function' && !replaceFilter(match)) { return match; } var i = env.tokenStack.length; // Check for existing strings while (env.code.indexOf('___' + language.toUpperCase() + i + '___') !== -1) ++i; // Create a sparse array env.tokenStack[i] = match; return '___' + language.toUpperCase() + i + '___'; }); // Switch the grammar to markup env.grammar = Prism.languages.markup; } }, tokenizePlaceholders: { // Replace placeholders with proper tokens after tokenizing value: function (env, language) { if (env.language !== language || !env.tokenStack) { return; } // Switch the grammar back env.grammar = Prism.languages[language]; var j = 0; var keys = Object.keys(env.tokenStack); var walkTokens = function (tokens) { if (j >= keys.length) { return; } for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; if (typeof token === 'string' || (token.content && typeof token.content === 'string')) { var k = keys[j]; var t = env.tokenStack[k]; var s = typeof token === 'string' ? token : token.content; var index = s.indexOf('___' + language.toUpperCase() + k + '___'); if (index > -1) { ++j; var before = s.substring(0, index); var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar, language), 'language-' + language, t); var after = s.substring(index + ('___' + language.toUpperCase() + k + '___').length); var replacement; if (before || after) { replacement = [before, middle, after].filter(function (v) { return !!v; }); walkTokens(replacement); } else { replacement = middle; } if (typeof token === 'string') { Array.prototype.splice.apply(tokens, [i, 1].concat(replacement)); } else { token.content = replacement; } if (j >= keys.length) { break; } } } else if (token.content && typeof token.content !== 'string') { walkTokens(token.content); } } }; walkTokens(env.tokens); } } });