some improvements to syntax highlighter
This commit is contained in:
parent
0b629a1b40
commit
30ebbee085
5 changed files with 76 additions and 64 deletions
|
@ -18,10 +18,14 @@ Ox.load('UI', {
|
||||||
$options = Ox.Element()
|
$options = Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
Ox.FormElementGroup({
|
Ox.FormElementGroup({
|
||||||
elements: ['showLineNumbers', 'showLinebreaks', 'showTabs', 'showWhitespace'].map(function(v, i) {
|
elements: [
|
||||||
|
'showLineNumbers', 'showLinebreaks', 'showTabs', 'showWhitespace', 'stripComments'
|
||||||
|
].map(function(v, i) {
|
||||||
return Ox.Checkbox({
|
return Ox.Checkbox({
|
||||||
overlap: 'right',
|
overlap: 'right',
|
||||||
title: Ox.toDashes(v).split('-').map(function(v) { return Ox.toTitleCase(v); }).join(' '),
|
title: Ox.toDashes(v).split('-').map(function(v) {
|
||||||
|
return Ox.toTitleCase(v);
|
||||||
|
}).join(' '),
|
||||||
width: 160
|
width: 160
|
||||||
}).bindEvent({
|
}).bindEvent({
|
||||||
change: function(event) {
|
change: function(event) {
|
||||||
|
|
|
@ -1455,23 +1455,24 @@ SyntaxHightlighter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.OxSyntaxHighlighter > div {
|
.OxSyntaxHighlighter > div {
|
||||||
|
display: table-cell;
|
||||||
|
padding: 4px;
|
||||||
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
|
font-family: Menlo, Monaco, DejaVu Sans Mono, Bitstream Vera Sans Mono, Consolas, Lucida Console;
|
||||||
//line-height: 14px;
|
//line-height: 14px;
|
||||||
}
|
}
|
||||||
.OxSyntaxHighlighter > .OxLineNumbers {
|
.OxSyntaxHighlighter > .OxLineNumbers {
|
||||||
padding: 4px;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
.OxSyntaxHighlighter > .OxSourceCode {
|
.OxSyntaxHighlighter > .OxSourceCode {
|
||||||
padding: 4px;
|
white-space: nowrap;
|
||||||
-moz-user-select: text;
|
-moz-user-select: text;
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
}
|
}
|
||||||
.OxSyntaxHighlighter > .OxSourceCode .OxLinebreak {
|
.OxSyntaxHighlighter > .OxSourceCode .OxLinebreak {
|
||||||
-moz-user-select: none;
|
//-moz-user-select: none;
|
||||||
-webkit-user-select: none;
|
//-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
Ox.SyntaxHighlighter <function> Syntax Highlighter
|
||||||
|
(options[, self]) -> <o> Syntax Highlighter
|
||||||
|
options <o> Options
|
||||||
|
offset <n|1> First line number
|
||||||
|
showLineNumbers <b|false> If true, show line numbers
|
||||||
|
showLinebreaks <b|false> If true, show linebreaks
|
||||||
|
showWhitespace <b|false> If true, show whitespace
|
||||||
|
stripComments <b|false> If true, strip comments
|
||||||
|
self <o> Shared private
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.SyntaxHighlighter = function(options, self) {
|
Ox.SyntaxHighlighter = function(options, self) {
|
||||||
|
|
||||||
self = self || {};
|
self = self || {};
|
||||||
var that = Ox.Element({}, self)
|
var that = Ox.Element({}, self)
|
||||||
.defaults({
|
.defaults({
|
||||||
height: 40,
|
height: 40,
|
||||||
|
@ -28,35 +36,24 @@ Ox.SyntaxHighlighter = function(options, self) {
|
||||||
|
|
||||||
renderSource();
|
renderSource();
|
||||||
|
|
||||||
function encodeToken(source, token) {
|
|
||||||
var linebreak = '<br/>',
|
|
||||||
tab = Ox.repeat(' ', self.options.tabLength);
|
|
||||||
if (self.options.showLinebreaks) {
|
|
||||||
if (token.type == 'linebreak') {
|
|
||||||
linebreak = '\u21A9' + linebreak;
|
|
||||||
} else {
|
|
||||||
linebreak = '<span class="OxLinebreak">\u21A9</span>' + linebreak;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (self.options.showTabs) {
|
|
||||||
tab = '<span class="OxTab">\u2192' + tab.substr(6) + '</span>';
|
|
||||||
}
|
|
||||||
return Ox.encodeHTML(source)
|
|
||||||
.replace(/ /g, ' ')
|
|
||||||
.replace(/\t/g, tab)
|
|
||||||
.replace(/\n/g, linebreak);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderSource() {
|
function renderSource() {
|
||||||
|
var lines, source = '', tokens,
|
||||||
|
linebreak = (
|
||||||
|
self.options.showLinebreaks ?
|
||||||
|
'<span class="OxLinebreak">\u21A9</span>' : ''
|
||||||
|
) + '<br/>',
|
||||||
|
tab = (
|
||||||
|
self.options.showTabs ?
|
||||||
|
'<span class="OxTab">\u2192</span>' : ''
|
||||||
|
) + Ox.repeat(' ', self.options.tabLength - self.options.showTabs),
|
||||||
|
whitespace = self.options.showWhitespace ? '\u00B7' : ' ';
|
||||||
self.options.source = self.options.source
|
self.options.source = self.options.source
|
||||||
.replace(/\r\n/g, '\n')
|
.replace(/\r\n/g, '\n')
|
||||||
.replace(/\r/g, '\n');
|
.replace(/\r/g, '\n');
|
||||||
self.cursor = 0;
|
tokens = Ox.tokenize(self.options.source);
|
||||||
self.source = '';
|
tokens.forEach(function(token, i) {
|
||||||
self.tokens = Ox.tokenize(self.options.source);
|
|
||||||
self.tokens.forEach(function(token, i) {
|
|
||||||
var classNames,
|
var classNames,
|
||||||
source = self.options.source.substr(token.offset, token.length);
|
substr = self.options.source.substr(token.offset, token.length);
|
||||||
if (
|
if (
|
||||||
!(self.options.stripComments && token.type == 'comment')
|
!(self.options.stripComments && token.type == 'comment')
|
||||||
) {
|
) {
|
||||||
|
@ -68,48 +65,61 @@ Ox.SyntaxHighlighter = function(options, self) {
|
||||||
classNames += ' OxTrailing'
|
classNames += ' OxTrailing'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.source += '<span class="' + classNames + '">' +
|
source += '<span class="' + classNames + '">' +
|
||||||
encodeToken(source, token.type) + '</span>';
|
Ox.encodeHTML(substr)
|
||||||
|
.replace(/ /g, whitespace)
|
||||||
|
.replace(/\t/g, tab)
|
||||||
|
.replace(/\n/g, linebreak) + '</span>';
|
||||||
}
|
}
|
||||||
self.cursor += token.length;
|
|
||||||
function isAfterLinebreak() {
|
function isAfterLinebreak() {
|
||||||
return i == 0 ||
|
return i == 0 ||
|
||||||
self.tokens[i - 1].type == 'linebreak';
|
tokens[i - 1].type == 'linebreak';
|
||||||
}
|
}
|
||||||
function isBeforeLinebreak() {
|
function isBeforeLinebreak() {
|
||||||
return i == self.tokens.length - 1 ||
|
return i == tokens.length - 1 ||
|
||||||
self.tokens[i + 1].type == 'linebreak';
|
tokens[i + 1].type == 'linebreak';
|
||||||
}
|
}
|
||||||
function hasIrregularSpaces() {
|
function hasIrregularSpaces() {
|
||||||
return source.split('').reduce(function(prev, curr) {
|
return substr.split('').reduce(function(prev, curr) {
|
||||||
return prev + (curr == ' ' ? 1 : 0);
|
return prev + (curr == ' ' ? 1 : 0);
|
||||||
}, 0) % self.options.tabLength;
|
}, 0) % self.options.tabLength;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.lines = self.source.split('<br/>');
|
lines = source.split('<br/>');
|
||||||
|
|
||||||
that.empty();
|
that.empty();
|
||||||
|
///*
|
||||||
|
var $test = new Ox.Element()
|
||||||
|
.css({
|
||||||
|
position: 'absolute',
|
||||||
|
top: '-1000px'
|
||||||
|
})
|
||||||
|
.html(Ox.repeat(' ', self.options.lineLength))
|
||||||
|
.appendTo(that);
|
||||||
|
var width = $test.width() + 4; // add padding
|
||||||
|
$test.removeElement();
|
||||||
|
//*/
|
||||||
if (self.options.showLineNumbers) {
|
if (self.options.showLineNumbers) {
|
||||||
self.$lineNumbers = new Ox.Element()
|
self.$lineNumbers = new Ox.Element()
|
||||||
.addClass('OxLineNumbers')
|
.addClass('OxLineNumbers')
|
||||||
.css({
|
.html(
|
||||||
display: 'table-cell',
|
Ox.range(lines.length).map(function(line) {
|
||||||
padding: '4px',
|
return (line + self.options.offset);
|
||||||
})
|
}).join('<br/>')
|
||||||
.html(
|
)
|
||||||
Ox.range(self.lines.length).map(function(line) {
|
.appendTo(that);
|
||||||
return (line + self.options.offset);
|
|
||||||
}).join('<br/>')
|
|
||||||
)
|
|
||||||
.appendTo(that);
|
|
||||||
}
|
}
|
||||||
self.$source = new Ox.Element()
|
self.$source = new Ox.Element()
|
||||||
.addClass('OxSourceCode')
|
.addClass('OxSourceCode')
|
||||||
.css({
|
.css({
|
||||||
display: 'table-cell',
|
background: '-moz-linear-gradient(left, rgb(255, 255, 255), rgb(255, 255, 255) ' +
|
||||||
padding: '4px'
|
width + 'px, rgb(248, 248, 248) ' + width + 'px, rgb(248, 248, 248))'
|
||||||
})
|
})
|
||||||
.html(self.source)
|
.css({
|
||||||
|
background: '-webkit-linear-gradient(left, rgb(255, 255, 255) ' +
|
||||||
|
width + 'px, rgb(192, 192, 192) ' + width + 'px, rgb(255, 255, 255) ' +
|
||||||
|
(width + 1) + 'px)'
|
||||||
|
})
|
||||||
|
.html(source)
|
||||||
.appendTo(that);
|
.appendTo(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -421,6 +421,9 @@ SyntaxHighlighter
|
||||||
.OxThemeClassic .OxSourceCode .OxTab {
|
.OxThemeClassic .OxSourceCode .OxTab {
|
||||||
color: rgb(192, 192, 192);
|
color: rgb(192, 192, 192);
|
||||||
}
|
}
|
||||||
|
.OxThemeClassic .OxSourceCode .OxWhitespace {
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
}
|
||||||
.OxThemeClassic .OxSourceCode .OxWhitespace.OxLeading,
|
.OxThemeClassic .OxSourceCode .OxWhitespace.OxLeading,
|
||||||
.OxThemeClassic .OxSourceCode .OxWhitespace.OxTrailing {
|
.OxThemeClassic .OxSourceCode .OxWhitespace.OxTrailing {
|
||||||
background: rgb(255, 128, 128);
|
background: rgb(255, 128, 128);
|
||||||
|
|
12
source/Ox.js
12
source/Ox.js
|
@ -3950,11 +3950,9 @@ Ox.repeat = function(val, num) {
|
||||||
var ret;
|
var ret;
|
||||||
if (Ox.isArray(val)) {
|
if (Ox.isArray(val)) {
|
||||||
ret = [];
|
ret = [];
|
||||||
if (num >= 1) {
|
num >= 1 && Ox.loop(num, function() {
|
||||||
Ox.loop(num, function() {
|
ret = Ox.merge(ret, val);
|
||||||
ret = Ox.merge(ret, val);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = num >= 1 ? new Array(num + 1).join(val.toString()) : '';
|
ret = num >= 1 ? new Array(num + 1).join(val.toString()) : '';
|
||||||
}
|
}
|
||||||
|
@ -4463,10 +4461,6 @@ Ox.isRegExp <f> Tests if a value is a regular expression
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
Ox.isRegExp = function(val) {
|
Ox.isRegExp = function(val) {
|
||||||
/*
|
|
||||||
>>> Ox.isRegExp(/ /)
|
|
||||||
true
|
|
||||||
*/
|
|
||||||
return val instanceof RegExp;
|
return val instanceof RegExp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue