// vim: et:ts=4:sw=4:sts=4:ft=js /*@ @*/ Ox.SyntaxHighlighter = function(options, self) { self = self || {}; var that = new Ox.Element({}, self) .defaults({ height: 40, lineLength: 80, //@ number of characters per line showLinebreaks: false, //@ show linebreak symbols showTabs: false, //@ show tab symbols showWhitespace: false, //@ show irregular leading or trailing whitespace source: '', //@ JavaScript source stripComments: false, //@ strip all comments stripLinebreaks: false, //@ strip multiple linebreaks, NOT IMPLEMENTED stripWhitespace: false, //@ strip all whitespace, NOT IMPLEMENTED tabLength: 4, //@ number of spaces per tab width: 80 }) .options(options || {}) .addClass('OxSyntaxHighlighter'); var foo = $('
') //.css({marginTop: '-1000px'}) .html(Ox.repeat('_', 80)) .appendTo(that.$element); //alert(foo.width()); foo.remove(); 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; if ( !(self.options.stripComments && token.type == 'comment') ) { classNames = 'Ox' + Ox.toTitleCase(token.type); if (token.type == 'whitespace') { if (isAfterLinebreak() && hasIrregularSpaces()) { classNames += ' OxLeading' } else if (isBeforeLinebreak()) { classNames += ' OxTrailing' } } self.source += '' + encodeToken(token.source, token.type) + ''; } 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 token.source.split('').reduce(function(prev, curr) { return prev + (curr == ' ' ? 1 : 0); }, 0) % self.options.tabLength; } }); self.lines = self.source.split('
'); self.lineNumbersWidth = self.lines.length.toString().length * 7 + 7; self.sourceCodeWidth = 80 * 7 + ( self.lines.length > 40 ? Ox.UI.SCROLLBAR_SIZE : 0 ); self.height = 40 * 14 + ( Math.max.apply(null, self.lines.map(function(line) { return line.length; })) > 80 ? Ox.UI.SCROLLBAR_SIZE : 0 ); that.css({ width: self.lineNumbersWidth + self.sourceCodeWidth, height: self.height }); self.$lineNumbers = new Ox.Element() .addClass('OxLineNumbers') .css({ width: self.lineNumbersWidth + 'px', height: (self.lines.length * 14) + 'px' }) .html( Ox.range(self.lines.length).map(function(line) { return (line + 1) + ' '; }).join('
') ) .appendTo(that); self.$source = new Ox.Element() .addClass('OxSourceCode') .css({ left: self.lineNumbersWidth + 'px', width: self.sourceCodeWidth + 'px', height: (self.lines.length * 14) + 'px' }) .html(self.source) .appendTo(that); function encodeToken(source, type) { var linebreak = '
', tab = Ox.repeat(' ', self.options.tabLength); if (self.options.showLinebreaks) { if (type == 'linebreak') { linebreak = '\u21A9' + linebreak; } else { linebreak = '\u21A9' + linebreak; } } if (self.options.showTabs) { tab = '\u2192' + tab.substr(6) + ''; } source = Ox.encodeHTML(source) .replace(/ /g, ' ') .replace(/\t/g, tab) .replace(/\n/g, linebreak); return source; } self.setOption = function() { }; return that; };