From 9bb31f57226877f78f23fb766773aa8486297bb7 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Thu, 30 Jun 2011 00:52:42 +0200 Subject: initial commit --- deps/highlight.js/highlight_src.js | 603 +++++++++++++++++++++++++++++++++++++ 1 file changed, 603 insertions(+) create mode 100644 deps/highlight.js/highlight_src.js (limited to 'deps/highlight.js/highlight_src.js') diff --git a/deps/highlight.js/highlight_src.js b/deps/highlight.js/highlight_src.js new file mode 100644 index 0000000..be695d6 --- /dev/null +++ b/deps/highlight.js/highlight_src.js @@ -0,0 +1,603 @@ +/* +Syntax highlighting with language autodetection. +http://softwaremaniacs.org/soft/highlight/ +*/ + +var hljs = new function() { + var LANGUAGES = {} + // selected_languages is used to support legacy mode of selecting languages + // available for highlighting by passing them as arguments into + // initHighlighting function. Currently the whole library is expected to + // contain only those language definitions that are actually get used. + var selected_languages = {}; + + /* Utility functions */ + + function escape(value) { + return value.replace(/&/gm, '&').replace(//gm, '>'); + } + + function contains(array, item) { + if (!array) + return false; + for (var i = 0; i < array.length; i++) + if (array[i] == item) + return true; + return false; + } + + function langRe(language, value, global) { + var mode = 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : ''); + return new RegExp(value, mode); + } + + function findCode(pre) { + for (var i = 0; i < pre.childNodes.length; i++) { + node = pre.childNodes[i]; + if (node.nodeName == 'CODE') + return node; + if (!(node.nodeType == 3 && node.nodeValue.match(/\s+/))) + return null; + } + } + + function blockText(block) { + var result = ''; + for (var i = 0; i < block.childNodes.length; i++) + if (block.childNodes[i].nodeType == 3) + result += block.childNodes[i].nodeValue; + else if (block.childNodes[i].nodeName == 'BR') + result += '\n'; + else + result += blockText(block.childNodes[i]); + return result; + } + + function blockLanguage(block) { + var classes = block.className.split(/\s+/) + classes = classes.concat(block.parentNode.className.split(/\s+/)); + for (var i = 0; i < classes.length; i++) { + var class_ = classes[i].replace(/^language-/, ''); + if (class_ == 'no-highlight') { + throw 'No highlight' + } + if (LANGUAGES[class_]) { + return class_; + } + } + } + + /* Stream merging */ + + function nodeStream(node) { + var result = []; + (function (node, offset) { + for (var i = 0; i < node.childNodes.length; i++) { + if (node.childNodes[i].nodeType == 3) + offset += node.childNodes[i].nodeValue.length; + else if (node.childNodes[i].nodeName == 'BR') + offset += 1 + else { + result.push({ + event: 'start', + offset: offset, + node: node.childNodes[i] + }); + offset = arguments.callee(node.childNodes[i], offset) + result.push({ + event: 'stop', + offset: offset, + node: node.childNodes[i] + }); + } + } + return offset; + })(node, 0); + return result; + } + + function mergeStreams(stream1, stream2, value) { + var processed = 0; + var result = ''; + var nodeStack = []; + + function selectStream() { + if (stream1.length && stream2.length) { + if (stream1[0].offset != stream2[0].offset) + return (stream1[0].offset < stream2[0].offset) ? stream1 : stream2; + else + return (stream1[0].event == 'start' && stream2[0].event == 'stop') ? stream2 : stream1; + } else { + return stream1.length ? stream1 : stream2; + } + } + + function open(node) { + var result = '<' + node.nodeName.toLowerCase(); + for (var i = 0; i < node.attributes.length; i++) { + var attribute = node.attributes[i]; + result += ' ' + attribute.nodeName.toLowerCase(); + if (attribute.nodeValue != undefined) { + result += '="' + escape(attribute.nodeValue) + '"'; + } + } + return result + '>'; + } + + function close(node) { + return ''; + } + + while (stream1.length || stream2.length) { + var current = selectStream().splice(0, 1)[0]; + result += escape(value.substr(processed, current.offset - processed)); + processed = current.offset; + if ( current.event == 'start') { + result += open(current.node); + nodeStack.push(current.node); + } else if (current.event == 'stop') { + var i = nodeStack.length; + do { + i--; + var node = nodeStack[i]; + result += close(node); + } while (node != current.node); + nodeStack.splice(i, 1); + while (i < nodeStack.length) { + result += open(nodeStack[i]); + i++; + } + } + } + result += value.substr(processed); + return result; + } + + /* Core highlighting function */ + + function highlight(language_name, value) { + function compileSubModes(mode, language) { + mode.sub_modes = []; + for (var i = 0; i < mode.contains.length; i++) { + for (var j = 0; j < language.modes.length; j++) { + if (language.modes[j].className == mode.contains[i]) { + mode.sub_modes[mode.sub_modes.length] = language.modes[j]; + } + } + } + } + + function subMode(lexem, mode) { + if (!mode.contains) { + return null; + } + if (!mode.sub_modes) { + compileSubModes(mode, language); + } + for (var i = 0; i < mode.sub_modes.length; i++) { + if (mode.sub_modes[i].beginRe.test(lexem)) { + return mode.sub_modes[i]; + } + } + return null; + } + + function endOfMode(mode_index, lexem) { + if (modes[mode_index].end && modes[mode_index].endRe.test(lexem)) + return 1; + if (modes[mode_index].endsWithParent) { + var level = endOfMode(mode_index - 1, lexem); + return level ? level + 1 : 0; + } + return 0; + } + + function isIllegal(lexem, mode) { + return mode.illegalRe && mode.illegalRe.test(lexem); + } + + function compileTerminators(mode, language) { + var terminators = []; + + function addTerminator(re) { + if (!contains(terminators, re)) { + terminators[terminators.length] = re; + } + } + + if (mode.contains) + for (var i = 0; i < language.modes.length; i++) { + if (contains(mode.contains, language.modes[i].className)) { + addTerminator(language.modes[i].begin); + } + } + + var index = modes.length - 1; + do { + if (modes[index].end) { + addTerminator(modes[index].end); + } + index--; + } while (modes[index + 1].endsWithParent); + + if (mode.illegal) { + addTerminator(mode.illegal); + } + + var terminator_re = '(' + terminators[0]; + for (var i = 0; i < terminators.length; i++) + terminator_re += '|' + terminators[i]; + terminator_re += ')'; + return langRe(language, terminator_re); + } + + function eatModeChunk(value, index) { + var mode = modes[modes.length - 1]; + if (!mode.terminators) { + mode.terminators = compileTerminators(mode, language); + } + value = value.substr(index); + var match = mode.terminators.exec(value); + if (!match) + return [value, '', true]; + if (match.index == 0) + return ['', match[0], false]; + else + return [value.substr(0, match.index), match[0], false]; + } + + function keywordMatch(mode, match) { + var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0] + for (var className in mode.keywordGroups) { + if (!mode.keywordGroups.hasOwnProperty(className)) + continue; + var value = mode.keywordGroups[className].hasOwnProperty(match_str); + if (value) + return [className, value]; + } + return false; + } + + function processKeywords(buffer, mode) { + if (!mode.keywords || !mode.lexems) + return escape(buffer); + if (!mode.lexemsRe) { + var lexems_re = '(' + mode.lexems[0]; + for (var i = 1; i < mode.lexems.length; i++) + lexems_re += '|' + mode.lexems[i]; + lexems_re += ')'; + mode.lexemsRe = langRe(language, lexems_re, true); + } + var result = ''; + var last_index = 0; + mode.lexemsRe.lastIndex = 0; + var match = mode.lexemsRe.exec(buffer); + while (match) { + result += escape(buffer.substr(last_index, match.index - last_index)); + var keyword_match = keywordMatch(mode, match); + if (keyword_match) { + keyword_count += keyword_match[1]; + result += '' + escape(match[0]) + ''; + } else { + result += escape(match[0]); + } + last_index = mode.lexemsRe.lastIndex; + match = mode.lexemsRe.exec(buffer); + } + result += escape(buffer.substr(last_index, buffer.length - last_index)); + return result; + } + + function processBuffer(buffer, mode) { + if (mode.subLanguage && selected_languages[mode.subLanguage]) { + var result = highlight(mode.subLanguage, buffer); + keyword_count += result.keyword_count; + relevance += result.relevance; + return result.value; + } else { + return processKeywords(buffer, mode); + } + } + + function startNewMode(mode, lexem) { + var markup = mode.noMarkup?'':''; + if (mode.returnBegin) { + result += markup; + mode.buffer = ''; + } else if (mode.excludeBegin) { + result += escape(lexem) + markup; + mode.buffer = ''; + } else { + result += markup; + mode.buffer = lexem; + } + modes[modes.length] = mode; + } + + function processModeInfo(buffer, lexem, end) { + var current_mode = modes[modes.length - 1]; + if (end) { + result += processBuffer(current_mode.buffer + buffer, current_mode); + return false; + } + + var new_mode = subMode(lexem, current_mode); + if (new_mode) { + result += processBuffer(current_mode.buffer + buffer, current_mode); + startNewMode(new_mode, lexem); + relevance += new_mode.relevance; + return new_mode.returnBegin; + } + + var end_level = endOfMode(modes.length - 1, lexem); + if (end_level) { + var markup = current_mode.noMarkup?'':''; + if (current_mode.returnEnd) { + result += processBuffer(current_mode.buffer + buffer, current_mode) + markup; + } else if (current_mode.excludeEnd) { + result += processBuffer(current_mode.buffer + buffer, current_mode) + markup + escape(lexem); + } else { + result += processBuffer(current_mode.buffer + buffer + lexem, current_mode) + markup; + } + while (end_level > 1) { + markup = modes[modes.length - 2].noMarkup?'':''; + result += markup; + end_level--; + modes.length--; + } + modes.length--; + modes[modes.length - 1].buffer = ''; + if (current_mode.starts) { + for (var i = 0; i < language.modes.length; i++) { + if (language.modes[i].className == current_mode.starts) { + startNewMode(language.modes[i], ''); + break; + } + } + } + return current_mode.returnEnd; + } + + if (isIllegal(lexem, current_mode)) + throw 'Illegal'; + } + + var language = LANGUAGES[language_name]; + var modes = [language.defaultMode]; + var relevance = 0; + var keyword_count = 0; + var result = ''; + try { + var index = 0; + language.defaultMode.buffer = ''; + do { + var mode_info = eatModeChunk(value, index); + var return_lexem = processModeInfo(mode_info[0], mode_info[1], mode_info[2]); + index += mode_info[0].length; + if (!return_lexem) { + index += mode_info[1].length; + } + } while (!mode_info[2]); + if(modes.length > 1) + throw 'Illegal'; + return { + relevance: relevance, + keyword_count: keyword_count, + value: result + } + } catch (e) { + if (e == 'Illegal') { + return { + relevance: 0, + keyword_count: 0, + value: escape(value) + } + } else { + throw e; + } + } + } + + /* Initialization */ + + function compileModes() { + for (var i in LANGUAGES) { + if (!LANGUAGES.hasOwnProperty(i)) + continue; + var language = LANGUAGES[i]; + for (var j = 0; j < language.modes.length; j++) { + var mode = language.modes[j]; + if (mode.begin) + mode.beginRe = langRe(language, '^' + mode.begin); + if (mode.end) + mode.endRe = langRe(language, '^' + mode.end); + if (mode.illegal) + mode.illegalRe = langRe(language, '^(?:' + mode.illegal + ')'); + language.defaultMode.illegalRe = langRe(language, '^(?:' + language.defaultMode.illegal + ')'); + if (mode.relevance == undefined) { + mode.relevance = 1; + } + if (!mode.displayClassName) { + mode.displayClassName = mode.className; + } + } + } + } + + function compileKeywords() { + + function compileModeKeywords(mode) { + if (!mode.keywordGroups) { + for (var key in mode.keywords) { + if (!mode.keywords.hasOwnProperty(key)) + continue; + if (mode.keywords[key] instanceof Object) + mode.keywordGroups = mode.keywords; + else + mode.keywordGroups = {'keyword': mode.keywords}; + break; + } + } + } + + for (var i in LANGUAGES) { + if (!LANGUAGES.hasOwnProperty(i)) + continue; + var language = LANGUAGES[i]; + compileModeKeywords(language.defaultMode); + for (var j = 0; j < language.modes.length; j++) { + compileModeKeywords(language.modes[j]); + } + } + } + + function initialize() { + if (initialize.called) + return; + initialize.called = true; + compileModes(); + compileKeywords(); + selected_languages = LANGUAGES; + } + + /* Public library functions */ + + function highlightBlock(block, tabReplace) { + initialize(); + + try { + var text = blockText(block); + var language = blockLanguage(block); + } catch (e) { + if (e == 'No highlight') + return; + } + + if (language) { + var result = highlight(language, text).value; + } else { + var max_relevance = 0; + for (var key in selected_languages) { + if (!selected_languages.hasOwnProperty(key)) + continue; + var lang_result = highlight(key, text); + var relevance = lang_result.keyword_count + lang_result.relevance; + if (relevance > max_relevance) { + max_relevance = relevance; + var result = lang_result.value; + language = key; + } + } + } + + if (result) { + var class_name = block.className; + if (!class_name.match(language)) { + class_name += ' ' + language; + } + var original = nodeStream(block); + if (original.length) { + var pre = document.createElement('pre'); + pre.innerHTML = result; + result = mergeStreams(original, nodeStream(pre), text); + } + if (tabReplace) { + result = result.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1, offset, s) { + return p1.replace(/\t/g, tabReplace); + }) + } + // See these 4 lines? This is IE's notion of "block.innerHTML = result". Love this browser :-/ + var container = document.createElement('div'); + container.innerHTML = '
' + result + '
'; + var environment = block.parentNode.parentNode; + environment.replaceChild(container.firstChild, block.parentNode); + } + } + + function initHighlighting() { + if (initHighlighting.called) + return; + initHighlighting.called = true; + initialize(); + if (arguments.length) { + for (var i = 0; i < arguments.length; i++) { + if (LANGUAGES[arguments[i]]) { + selected_languages[arguments[i]] = LANGUAGES[arguments[i]]; + } + } + } + var pres = document.getElementsByTagName('pre'); + for (var i = 0; i < pres.length; i++) { + var code = findCode(pres[i]); + if (code) + highlightBlock(code, hljs.tabReplace); + } + } + + function initHighlightingOnLoad() { + var original_arguments = arguments; + var handler = function(){initHighlighting.apply(null, original_arguments)}; + if (window.addEventListener) { + window.addEventListener('DOMContentLoaded', handler, false); + window.addEventListener('load', handler, false); + } else if (window.attachEvent) + window.attachEvent('onload', handler); + else + window.onload = handler; + } + + /* Interface definition */ + + this.LANGUAGES = LANGUAGES; + this.initHighlightingOnLoad = initHighlightingOnLoad; + this.highlightBlock = highlightBlock; + this.initHighlighting = initHighlighting; + + // Common regexps + this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*'; + this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*'; + this.NUMBER_RE = '\\b\\d+(\\.\\d+)?'; + this.C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)'; + this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~'; + + // Common modes + this.APOS_STRING_MODE = { + className: 'string', + begin: '\'', end: '\'', + illegal: '\\n', + contains: ['escape'], + relevance: 0 + }; + this.QUOTE_STRING_MODE = { + className: 'string', + begin: '"', end: '"', + illegal: '\\n', + contains: ['escape'], + relevance: 0 + }; + this.BACKSLASH_ESCAPE = { + className: 'escape', + begin: '\\\\.', end: '^', noMarkup: true, + relevance: 0 + }; + this.C_LINE_COMMENT_MODE = { + className: 'comment', + begin: '//', end: '$', + relevance: 0 + }; + this.C_BLOCK_COMMENT_MODE = { + className: 'comment', + begin: '/\\*', end: '\\*/' + }; + this.HASH_COMMENT_MODE = { + className: 'comment', + begin: '#', end: '$' + }; + this.C_NUMBER_MODE = { + className: 'number', + begin: this.C_NUMBER_RE, end: '^', + relevance: 0 + }; +}(); + +var initHighlightingOnLoad = hljs.initHighlightingOnLoad; -- cgit v1.2.3