forked from 0x2620/oxjs
better syntax highlighter demo, some bugfixes
This commit is contained in:
parent
37219bfbe9
commit
0b629a1b40
4 changed files with 214 additions and 189 deletions
|
|
@ -7,11 +7,12 @@
|
|||
Ox.SyntaxHighlighter = function(options, self) {
|
||||
|
||||
self = self || {};
|
||||
var that = new Ox.Element({}, self)
|
||||
var that = Ox.Element({}, self)
|
||||
.defaults({
|
||||
height: 40,
|
||||
lineLength: 80, //@ number of characters per line
|
||||
offset: 1, //@ first line number
|
||||
showLineNumbers: false,
|
||||
showLinebreaks: false, //@ show linebreak symbols
|
||||
showTabs: false, //@ show tab symbols
|
||||
showWhitespace: false, //@ show irregular leading or trailing whitespace
|
||||
|
|
@ -25,71 +26,7 @@ Ox.SyntaxHighlighter = function(options, self) {
|
|||
.options(options || {})
|
||||
.addClass('OxSyntaxHighlighter');
|
||||
|
||||
self.options.source = self.options.source
|
||||
.replace(/\r\n/g, '\n')
|
||||
.replace(/\r/g, '\n');
|
||||
|
||||
self.cursor = 0;
|
||||
self.source = '';
|
||||
self.tokens = Ox.tokenize(self.options.source);
|
||||
self.tokens.forEach(function(token, i) {
|
||||
var classNames,
|
||||
source = self.options.source.substr(token.offset, token.length);
|
||||
if (
|
||||
!(self.options.stripComments && token.type == 'comment')
|
||||
) {
|
||||
classNames = 'Ox' + Ox.toTitleCase(token.type);
|
||||
if (self.options.showWhitespace && token.type == 'whitespace') {
|
||||
if (isAfterLinebreak() && hasIrregularSpaces()) {
|
||||
classNames += ' OxLeading'
|
||||
} else if (isBeforeLinebreak()) {
|
||||
classNames += ' OxTrailing'
|
||||
}
|
||||
}
|
||||
self.source += '<span class="' + classNames + '">' +
|
||||
encodeToken(source, token.type) + '</span>';
|
||||
}
|
||||
self.cursor += token.length;
|
||||
function isAfterLinebreak() {
|
||||
return i == 0 ||
|
||||
self.tokens[i - 1].type == 'linebreak';
|
||||
}
|
||||
function isBeforeLinebreak() {
|
||||
return i == self.tokens.length - 1 ||
|
||||
self.tokens[i + 1].type == 'linebreak';
|
||||
}
|
||||
function hasIrregularSpaces() {
|
||||
return source.split('').reduce(function(prev, curr) {
|
||||
return prev + (curr == ' ' ? 1 : 0);
|
||||
}, 0) % self.options.tabLength;
|
||||
}
|
||||
});
|
||||
self.lines = self.source.split('<br/>');
|
||||
self.lineNumbersWidth = (
|
||||
self.lines.length + self.options.offset - 1
|
||||
).toString().length * 7;
|
||||
|
||||
self.$lineNumbers = new Ox.Element()
|
||||
.addClass('OxLineNumbers')
|
||||
.css({
|
||||
display: 'table-cell',
|
||||
width: self.lineNumbersWidth + 'px',
|
||||
padding: '4px',
|
||||
})
|
||||
.html(
|
||||
Ox.range(self.lines.length).map(function(line) {
|
||||
return (line + self.options.offset);
|
||||
}).join('<br/>')
|
||||
)
|
||||
.appendTo(that);
|
||||
self.$source = new Ox.Element()
|
||||
.addClass('OxSourceCode')
|
||||
.css({
|
||||
display: 'table-cell',
|
||||
padding: '4px'
|
||||
})
|
||||
.html(self.source)
|
||||
.appendTo(that);
|
||||
renderSource();
|
||||
|
||||
function encodeToken(source, token) {
|
||||
var linebreak = '<br/>',
|
||||
|
|
@ -110,8 +47,74 @@ Ox.SyntaxHighlighter = function(options, self) {
|
|||
.replace(/\n/g, linebreak);
|
||||
}
|
||||
|
||||
self.setOption = function() {
|
||||
|
||||
function renderSource() {
|
||||
self.options.source = self.options.source
|
||||
.replace(/\r\n/g, '\n')
|
||||
.replace(/\r/g, '\n');
|
||||
self.cursor = 0;
|
||||
self.source = '';
|
||||
self.tokens = Ox.tokenize(self.options.source);
|
||||
self.tokens.forEach(function(token, i) {
|
||||
var classNames,
|
||||
source = self.options.source.substr(token.offset, token.length);
|
||||
if (
|
||||
!(self.options.stripComments && token.type == 'comment')
|
||||
) {
|
||||
classNames = 'Ox' + Ox.toTitleCase(token.type);
|
||||
if (self.options.showWhitespace && token.type == 'whitespace') {
|
||||
if (isAfterLinebreak() && hasIrregularSpaces()) {
|
||||
classNames += ' OxLeading'
|
||||
} else if (isBeforeLinebreak()) {
|
||||
classNames += ' OxTrailing'
|
||||
}
|
||||
}
|
||||
self.source += '<span class="' + classNames + '">' +
|
||||
encodeToken(source, token.type) + '</span>';
|
||||
}
|
||||
self.cursor += token.length;
|
||||
function isAfterLinebreak() {
|
||||
return i == 0 ||
|
||||
self.tokens[i - 1].type == 'linebreak';
|
||||
}
|
||||
function isBeforeLinebreak() {
|
||||
return i == self.tokens.length - 1 ||
|
||||
self.tokens[i + 1].type == 'linebreak';
|
||||
}
|
||||
function hasIrregularSpaces() {
|
||||
return source.split('').reduce(function(prev, curr) {
|
||||
return prev + (curr == ' ' ? 1 : 0);
|
||||
}, 0) % self.options.tabLength;
|
||||
}
|
||||
});
|
||||
self.lines = self.source.split('<br/>');
|
||||
|
||||
that.empty();
|
||||
if (self.options.showLineNumbers) {
|
||||
self.$lineNumbers = new Ox.Element()
|
||||
.addClass('OxLineNumbers')
|
||||
.css({
|
||||
display: 'table-cell',
|
||||
padding: '4px',
|
||||
})
|
||||
.html(
|
||||
Ox.range(self.lines.length).map(function(line) {
|
||||
return (line + self.options.offset);
|
||||
}).join('<br/>')
|
||||
)
|
||||
.appendTo(that);
|
||||
}
|
||||
self.$source = new Ox.Element()
|
||||
.addClass('OxSourceCode')
|
||||
.css({
|
||||
display: 'table-cell',
|
||||
padding: '4px'
|
||||
})
|
||||
.html(self.source)
|
||||
.appendTo(that);
|
||||
}
|
||||
|
||||
self.setOption = function(key, value) {
|
||||
renderSource();
|
||||
};
|
||||
|
||||
return that;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue