-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Markup-templating improvements (#1653)
This makes minor improvements to markup-templating.
- Loading branch information
1 parent
6c9fe25
commit b62e282
Showing
2 changed files
with
107 additions
and
73 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,123 @@ | ||
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; | ||
} | ||
(function (Prism) { | ||
|
||
env.tokenStack = []; | ||
/** | ||
* 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 + '___'; | ||
} | ||
|
||
env.code = env.code.replace(placeholderPattern, function(match) { | ||
if (typeof replaceFilter === 'function' && !replaceFilter(match)) { | ||
return match; | ||
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 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; | ||
var tokenStack = env.tokenStack = []; | ||
|
||
return '___' + language.toUpperCase() + i + '___'; | ||
}); | ||
env.code = env.code.replace(placeholderPattern, function (match) { | ||
if (typeof replaceFilter === 'function' && !replaceFilter(match)) { | ||
return match; | ||
} | ||
var i = tokenStack.length; | ||
var placeholder; | ||
|
||
// 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; | ||
} | ||
// Check for existing strings | ||
while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1) | ||
++i; | ||
|
||
// Switch the grammar back | ||
env.grammar = Prism.languages[language]; | ||
// Create a sparse array | ||
tokenStack[i] = match; | ||
|
||
var j = 0; | ||
var keys = Object.keys(env.tokenStack); | ||
var walkTokens = function (tokens) { | ||
if (j >= keys.length) { | ||
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; | ||
} | ||
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; | ||
// 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); | ||
} | ||
} else if (token.content && typeof token.content !== 'string') { | ||
walkTokens(token.content); | ||
} | ||
|
||
return tokens; | ||
} | ||
}; | ||
|
||
walkTokens(env.tokens); | ||
walkTokens(env.tokens); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
|
||
}(Prism)); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.