Refactors Liquid syntax highlighters to add line highlights.
Usage (ranges are space separated):
{% highlight js 1,4-6 %}
One range
Adds `highlight-line-active` to lines 1,4,5,6
{% highlight js 3-4 -1 %}
Two ranges (add/remove), remove is N/A
Adds `highlight-line-add` to lines 3,4
{% highlight js -1 3-4 %}
Two ranges (add/remove), add is N/A
Adds `highlight-line-remove` to lines 3,4
{% highlight js 3-4 5,8-10 %}
Two ranges, both are used
Adds `highlight-line-add` to lines 3-4
Adds `highlight-line-remove` to lines 5,8,9,10
This commit is contained in:
83
_src/LiquidHighlight.js
Normal file
83
_src/LiquidHighlight.js
Normal file
@@ -0,0 +1,83 @@
|
||||
const HighlightLines = require('./HighlightLines');
|
||||
|
||||
class LiquidHighlight {
|
||||
constructor(liquidEngine) {
|
||||
this.liquidEngine = liquidEngine;
|
||||
this.hooks = [];
|
||||
this.classHooks = [];
|
||||
}
|
||||
|
||||
addHook(hookFunction) {
|
||||
this.hooks.push(hookFunction);
|
||||
}
|
||||
|
||||
addClassHook(hookFunction) {
|
||||
this.classHooks.push(hookFunction);
|
||||
}
|
||||
|
||||
getObject() {
|
||||
let ret = function(highlighter) {
|
||||
return {
|
||||
parse: function(tagToken, remainTokens) {
|
||||
let split = tagToken.args.split(" ");
|
||||
|
||||
this.language = split[0];
|
||||
this.highlights = new HighlightLines(split.length === 2 ? split[1] : "");
|
||||
this.highlightsAdd = new HighlightLines(split.length === 3 ? split[1] : "");
|
||||
this.highlightsRemove = new HighlightLines(split.length === 3 ? split[2] : "");
|
||||
|
||||
this.tokens = [];
|
||||
|
||||
var stream = highlighter.liquidEngine.parser.parseStream(remainTokens);
|
||||
|
||||
stream
|
||||
.on('token', token => {
|
||||
if (token.name === 'endhighlight') {
|
||||
stream.stop();
|
||||
} else {
|
||||
this.tokens.push(token);
|
||||
}
|
||||
})
|
||||
.on('end', x => {
|
||||
throw new Error("tag highlight not closed");
|
||||
});
|
||||
|
||||
stream.start();
|
||||
},
|
||||
render: function(scope, hash) {
|
||||
let tokens = this.tokens.map(token => token.raw);
|
||||
let tokenStr = tokens.join('').trim();
|
||||
|
||||
for( let hook of highlighter.hooks ) {
|
||||
tokenStr = hook.call(this, this.language, tokenStr);
|
||||
}
|
||||
|
||||
let lines = tokenStr.split("\n").map(function(line, j) {
|
||||
let classHookClasses = [];
|
||||
for( let classHook of highlighter.classHooks ) {
|
||||
let ret = classHook(this.language, line, j);
|
||||
if( ret ) {
|
||||
classHookClasses.push(ret);
|
||||
}
|
||||
}
|
||||
|
||||
return '<div class="highlight-line' +
|
||||
(this.highlights.isHighlighted(j) ? ' highlight-line-active' : '') +
|
||||
(this.highlightsAdd.isHighlighted(j) ? ' highlight-line-add' : '') +
|
||||
(this.highlightsRemove.isHighlighted(j) ? ' highlight-line-remove' : '') +
|
||||
(classHookClasses.length ? " " + classHookClasses.join(" ") : "") +
|
||||
'">' +
|
||||
line +
|
||||
'</div>';
|
||||
}.bind(this));
|
||||
|
||||
return Promise.resolve(`<pre class="language-${this.language}"><code class="language-${this.language}">` + lines.join("") + "</code></pre>");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return ret(this);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LiquidHighlight;
|
||||
Reference in New Issue
Block a user