Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markup-templating improvements #1653

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 106 additions & 72 deletions components/prism-markup-templating.js
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' */) {
RunDevelopment marked this conversation as resolved.
Show resolved Hide resolved
walkTokens(token.content);
}
} else if (token.content && typeof token.content !== 'string') {
walkTokens(token.content);
}

return tokens;
}
};

walkTokens(env.tokens);
walkTokens(env.tokens);
}
}
}
});
});

}(Prism));
2 changes: 1 addition & 1 deletion components/prism-markup-templating.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.