diff options
Diffstat (limited to 'public/prism/prism-markup-templating.js')
| -rw-r--r-- | public/prism/prism-markup-templating.js | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/public/prism/prism-markup-templating.js b/public/prism/prism-markup-templating.js new file mode 100644 index 0000000..267ca96 --- /dev/null +++ b/public/prism/prism-markup-templating.js @@ -0,0 +1,134 @@ +(function (Prism) { + /** + * Returns the placeholder for the given language id and index. + * + * @param {string} language + * @param {string|number} index + * @returns {string} + */ + function getPlaceholder(language, index) { + return '___' + language.toUpperCase() + index + '___'; + } + + Object.defineProperties((Prism.languages['markup-templating'] = {}), { + buildPlaceholders: { + /** + * Tokenize all inline templating expressions matching `placeholderPattern`. + * + * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns + * `true` will be replaced. + * + * @param {object} env The environment of the `before-tokenize` hook. + * @param {string} language The language id. + * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders. + * @param {(match: string) => boolean} [replaceFilter] + */ + value: function (env, language, placeholderPattern, replaceFilter) { + if (env.language !== language) { + return; + } + + var tokenStack = (env.tokenStack = []); + + env.code = env.code.replace(placeholderPattern, function (match) { + if (typeof replaceFilter === 'function' && !replaceFilter(match)) { + return match; + } + var i = tokenStack.length; + var placeholder; + + // Check for existing strings + while ( + env.code.indexOf((placeholder = getPlaceholder(language, i))) !== -1 + ) { + ++i; + } + + // Create a sparse array + tokenStack[i] = match; + + return placeholder; + }); + + // Switch the grammar to markup + env.grammar = Prism.languages.markup; + }, + }, + tokenizePlaceholders: { + /** + * Replace placeholders with proper tokens after tokenizing. + * + * @param {object} env The environment of the `after-tokenize` hook. + * @param {string} language The language id. + */ + 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); + + function walkTokens(tokens) { + for (var i = 0; i < tokens.length; i++) { + // all placeholders are replaced already + if (j >= keys.length) { + break; + } + + 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 placeholder = getPlaceholder(language, k); + + var index = s.indexOf(placeholder); + if (index > -1) { + ++j; + + var before = s.substring(0, index); + var middle = new Prism.Token( + language, + Prism.tokenize(t, env.grammar), + 'language-' + language, + t + ); + var after = s.substring(index + placeholder.length); + + var replacement = []; + if (before) { + replacement.push.apply(replacement, walkTokens([before])); + } + replacement.push(middle); + if (after) { + replacement.push.apply(replacement, walkTokens([after])); + } + + if (typeof token === 'string') { + tokens.splice.apply(tokens, [i, 1].concat(replacement)); + } else { + token.content = replacement; + } + } + } else if ( + token.content /* && typeof token.content !== 'string' */ + ) { + walkTokens(token.content); + } + } + + return tokens; + } + + walkTokens(env.tokens); + }, + }, + }); +})(Prism); |
