showoffer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +559 -0
- data/Rakefile +27 -0
- data/bin/showoffer +189 -0
- data/lib/commandline_parser.rb +67 -0
- data/lib/showoff.rb +515 -0
- data/lib/showoff/version.rb +3 -0
- data/lib/showoff_utils.rb +360 -0
- data/public/css/960.css +653 -0
- data/public/css/fg.menu.css +114 -0
- data/public/css/onepage.css +60 -0
- data/public/css/pdf.css +12 -0
- data/public/css/presenter.css +76 -0
- data/public/css/reset.css +53 -0
- data/public/css/sh_style.css +66 -0
- data/public/css/showoff.css +403 -0
- data/public/css/spinner_bar.gif +0 -0
- data/public/css/theme/images/ui-bg_diagonals-small_100_f0efea_40x40.png +0 -0
- data/public/css/theme/images/ui-bg_flat_35_f0f0f0_40x100.png +0 -0
- data/public/css/theme/images/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
- data/public/css/theme/images/ui-bg_glow-ball_25_2e2e28_600x600.png +0 -0
- data/public/css/theme/images/ui-bg_highlight-soft_100_f0efea_1x100.png +0 -0
- data/public/css/theme/images/ui-bg_highlight-soft_25_327E04_1x100.png +0 -0
- data/public/css/theme/images/ui-bg_highlight-soft_25_5A9D1A_1x100.png +0 -0
- data/public/css/theme/images/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
- data/public/css/theme/images/ui-bg_inset-soft_22_3b3b35_1x100.png +0 -0
- data/public/css/theme/images/ui-icons_808080_256x240.png +0 -0
- data/public/css/theme/images/ui-icons_8DC262_256x240.png +0 -0
- data/public/css/theme/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/css/theme/images/ui-icons_e7e6e4_256x240.png +0 -0
- data/public/css/theme/images/ui-icons_eeeeee_256x240.png +0 -0
- data/public/css/theme/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/css/theme/ui.accordion.css +9 -0
- data/public/css/theme/ui.all.css +2 -0
- data/public/css/theme/ui.base.css +9 -0
- data/public/css/theme/ui.core.css +37 -0
- data/public/css/theme/ui.datepicker.css +62 -0
- data/public/css/theme/ui.dialog.css +13 -0
- data/public/css/theme/ui.progressbar.css +4 -0
- data/public/css/theme/ui.resizable.css +13 -0
- data/public/css/theme/ui.slider.css +17 -0
- data/public/css/theme/ui.tabs.css +9 -0
- data/public/css/theme/ui.theme.css +245 -0
- data/public/favicon.ico +0 -0
- data/public/highlight/AUTHORS.en.txt +46 -0
- data/public/highlight/AUTHORS.ru.txt +46 -0
- data/public/highlight/LICENSE +24 -0
- data/public/highlight/README.md +136 -0
- data/public/highlight/README.ru.md +140 -0
- data/public/highlight/classref.txt +437 -0
- data/public/highlight/export.html +87 -0
- data/public/highlight/highlight.js +630 -0
- data/public/highlight/highlight.pack.js +1 -0
- data/public/highlight/languages/1c.js +68 -0
- data/public/highlight/languages/apache.js +432 -0
- data/public/highlight/languages/avrasm.js +75 -0
- data/public/highlight/languages/axapta.js +43 -0
- data/public/highlight/languages/bash.js +56 -0
- data/public/highlight/languages/cmake.js +24 -0
- data/public/highlight/languages/cpp.js +62 -0
- data/public/highlight/languages/cs.js +41 -0
- data/public/highlight/languages/css.js +101 -0
- data/public/highlight/languages/delphi.js +70 -0
- data/public/highlight/languages/diff.js +64 -0
- data/public/highlight/languages/django.js +72 -0
- data/public/highlight/languages/dos.js +29 -0
- data/public/highlight/languages/erlang-repl.js +81 -0
- data/public/highlight/languages/erlang.js +201 -0
- data/public/highlight/languages/go.js +58 -0
- data/public/highlight/languages/haskell.js +77 -0
- data/public/highlight/languages/ini.js +32 -0
- data/public/highlight/languages/java.js +45 -0
- data/public/highlight/languages/javascript.js +53 -0
- data/public/highlight/languages/lisp.js +87 -0
- data/public/highlight/languages/lua.js +75 -0
- data/public/highlight/languages/mel.js +40 -0
- data/public/highlight/languages/nginx.js +224 -0
- data/public/highlight/languages/objectivec.js +94 -0
- data/public/highlight/languages/parser3.js +52 -0
- data/public/highlight/languages/perl.js +143 -0
- data/public/highlight/languages/php.js +55 -0
- data/public/highlight/languages/profile.js +49 -0
- data/public/highlight/languages/python.js +71 -0
- data/public/highlight/languages/renderman.js +230 -0
- data/public/highlight/languages/ruby.js +203 -0
- data/public/highlight/languages/scala.js +60 -0
- data/public/highlight/languages/smalltalk.js +55 -0
- data/public/highlight/languages/sql.js +90 -0
- data/public/highlight/languages/tex.js +62 -0
- data/public/highlight/languages/vala.js +75 -0
- data/public/highlight/languages/vbscript.js +30 -0
- data/public/highlight/languages/vhdl.js +30 -0
- data/public/highlight/languages/xml.js +103 -0
- data/public/highlight/styles/arta.css +151 -0
- data/public/highlight/styles/ascetic.css +45 -0
- data/public/highlight/styles/brown_paper.css +105 -0
- data/public/highlight/styles/brown_papersq.png +0 -0
- data/public/highlight/styles/dark.css +103 -0
- data/public/highlight/styles/default.css +121 -0
- data/public/highlight/styles/far.css +118 -0
- data/public/highlight/styles/github.css +129 -0
- data/public/highlight/styles/idea.css +118 -0
- data/public/highlight/styles/ir_black.css +103 -0
- data/public/highlight/styles/magula.css +118 -0
- data/public/highlight/styles/school_book.css +111 -0
- data/public/highlight/styles/school_book.png +0 -0
- data/public/highlight/styles/solarized_dark.css +96 -0
- data/public/highlight/styles/solarized_light.css +96 -0
- data/public/highlight/styles/sunburst.css +147 -0
- data/public/highlight/styles/vs.css +84 -0
- data/public/highlight/styles/zenburn.css +115 -0
- data/public/highlight/test.html +1609 -0
- data/public/js/coffee-script.js +8 -0
- data/public/js/core.js +79 -0
- data/public/js/fg.menu.js +645 -0
- data/public/js/jTypeWriter.js +26 -0
- data/public/js/jquery-1.4.2.min.js +154 -0
- data/public/js/jquery-print.js +109 -0
- data/public/js/jquery.batchImageLoad.js +56 -0
- data/public/js/jquery.cookie.js +96 -0
- data/public/js/jquery.cycle.all.js +1284 -0
- data/public/js/jquery.doubletap-0.1.js +105 -0
- data/public/js/jquery.uuid.js +24 -0
- data/public/js/jquery.ws-0.3pre.js +201 -0
- data/public/js/onepage.js +5 -0
- data/public/js/presenter.js +193 -0
- data/public/js/sh_lang/sh_bison.min.js +1 -0
- data/public/js/sh_lang/sh_c.min.js +1 -0
- data/public/js/sh_lang/sh_caml.min.js +1 -0
- data/public/js/sh_lang/sh_changelog.min.js +1 -0
- data/public/js/sh_lang/sh_coffeescript.min.js +1 -0
- data/public/js/sh_lang/sh_cpp.min.js +1 -0
- data/public/js/sh_lang/sh_csharp.min.js +1 -0
- data/public/js/sh_lang/sh_css.min.js +1 -0
- data/public/js/sh_lang/sh_cucumber.min.js +2 -0
- data/public/js/sh_lang/sh_desktop.min.js +1 -0
- data/public/js/sh_lang/sh_diff.min.js +1 -0
- data/public/js/sh_lang/sh_erlang.min.js +1 -0
- data/public/js/sh_lang/sh_flex.min.js +1 -0
- data/public/js/sh_lang/sh_glsl.min.js +1 -0
- data/public/js/sh_lang/sh_haxe.min.js +1 -0
- data/public/js/sh_lang/sh_html.min.js +1 -0
- data/public/js/sh_lang/sh_java.min.js +1 -0
- data/public/js/sh_lang/sh_javascript.min.js +1 -0
- data/public/js/sh_lang/sh_javascript_dom.min.js +1 -0
- data/public/js/sh_lang/sh_latex.min.js +1 -0
- data/public/js/sh_lang/sh_ldap.min.js +1 -0
- data/public/js/sh_lang/sh_log.min.js +1 -0
- data/public/js/sh_lang/sh_lsm.min.js +1 -0
- data/public/js/sh_lang/sh_m4.min.js +1 -0
- data/public/js/sh_lang/sh_makefile.min.js +1 -0
- data/public/js/sh_lang/sh_oracle.min.js +1 -0
- data/public/js/sh_lang/sh_pascal.min.js +1 -0
- data/public/js/sh_lang/sh_perl.min.js +1 -0
- data/public/js/sh_lang/sh_php.min.js +1 -0
- data/public/js/sh_lang/sh_prolog.min.js +1 -0
- data/public/js/sh_lang/sh_properties.min.js +1 -0
- data/public/js/sh_lang/sh_python.min.js +1 -0
- data/public/js/sh_lang/sh_ruby.min.js +1 -0
- data/public/js/sh_lang/sh_scala.min.js +1 -0
- data/public/js/sh_lang/sh_sh.min.js +1 -0
- data/public/js/sh_lang/sh_slang.min.js +1 -0
- data/public/js/sh_lang/sh_sml.min.js +1 -0
- data/public/js/sh_lang/sh_spec.min.js +1 -0
- data/public/js/sh_lang/sh_sql.min.js +1 -0
- data/public/js/sh_lang/sh_tcl.min.js +1 -0
- data/public/js/sh_lang/sh_xml.min.js +1 -0
- data/public/js/sh_lang/sh_xorg.min.js +1 -0
- data/public/js/sh_main.min.js +4 -0
- data/public/js/showoff.js +652 -0
- data/public/js/showoffcore.js +13 -0
- data/public/scripts/script.js +280 -0
- data/public/themes/ribbon/fonts/DroidSansMono.svg +626 -0
- data/public/themes/ribbon/fonts/DroidSansMono.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.Italic.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.Italic.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.Italic.woff +0 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Bold.woff +0 -0
- data/public/themes/ribbon/fonts/PTSans.Italic.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.Italic.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Italic.woff +0 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.Bold.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.Bold.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.Bold.woff +0 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.Narrow.woff +0 -0
- data/public/themes/ribbon/fonts/PTSans.svg +728 -0
- data/public/themes/ribbon/fonts/PTSans.ttf +0 -0
- data/public/themes/ribbon/fonts/PTSans.woff +0 -0
- data/public/themes/ribbon/fonts/TargetBlank.otf +0 -0
- data/public/themes/ribbon/fonts/TargetBlank.svg +14 -0
- data/public/themes/ribbon/images/grid.png +0 -0
- data/public/themes/ribbon/images/linen.png +0 -0
- data/public/themes/ribbon/images/ribbon.svg +4 -0
- data/public/themes/ribbon/styles/fonts.css +63 -0
- data/public/themes/ribbon/styles/print.css +68 -0
- data/public/themes/ribbon/styles/reset.css +42 -0
- data/public/themes/ribbon/styles/style.css +408 -0
- data/views/header.erb +11 -0
- data/views/index.erb +13 -0
- data/views/onepage.erb +39 -0
- data/views/presenter.erb +70 -0
- metadata +328 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
<!-- saved from url=(0013)about:internet -->
|
2
|
+
<!-- ^^^ This is for IE not to show security warning for local files,
|
3
|
+
see http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx-->
|
4
|
+
|
5
|
+
<!--
|
6
|
+
Highlighted code export
|
7
|
+
Copyright (c) Vladimir Gubarkov <xonixx@gmail.com>
|
8
|
+
-->
|
9
|
+
|
10
|
+
<html>
|
11
|
+
<head>
|
12
|
+
<title>Highlited code export</title>
|
13
|
+
<link rel="stylesheet" href="styles/default.css">
|
14
|
+
<meta charset="utf-8">
|
15
|
+
<style type="text/css">
|
16
|
+
#t1, #t2 { width: 100%;}
|
17
|
+
tr { vertical-align: top; }
|
18
|
+
address { margin-top: 4em; }
|
19
|
+
</style>
|
20
|
+
<script src="highlight.pack.js"></script>
|
21
|
+
<script>hljs.initHighlightingOnLoad();</script>
|
22
|
+
</head>
|
23
|
+
<body>
|
24
|
+
<script type="text/javascript">
|
25
|
+
String.prototype.escape = function() {
|
26
|
+
return this.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
27
|
+
}
|
28
|
+
|
29
|
+
function doIt() {
|
30
|
+
var viewDiv = document.getElementById("highlight-view");
|
31
|
+
var t1 = document.getElementById("t1");
|
32
|
+
var t2 = document.getElementById("t2");
|
33
|
+
var selector = document.getElementById("langSelector");
|
34
|
+
var selectedLang = selector.options[selector.selectedIndex].value.toLowerCase();
|
35
|
+
if(selectedLang) {
|
36
|
+
viewDiv.innerHTML = '<pre><code class="'+selectedLang+'">'+t1.value.escape()+"</code></pre>";
|
37
|
+
} else { // try auto
|
38
|
+
viewDiv.innerHTML = '<pre><code>' + t1.value.escape() + "</code></pre>";
|
39
|
+
}
|
40
|
+
hljs.highlightBlock(viewDiv.firstChild.firstChild);
|
41
|
+
t2.value = viewDiv.innerHTML;
|
42
|
+
}
|
43
|
+
|
44
|
+
function copyToBuffer(textToCopy) {
|
45
|
+
if (window.clipboardData) { // IE
|
46
|
+
window.clipboardData.setData("Text", textToCopy);
|
47
|
+
} else if (window.netscape) { // FF
|
48
|
+
// from http://developer.mozilla.org/en/docs/Using_the_Clipboard
|
49
|
+
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
50
|
+
var gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
|
51
|
+
gClipboardHelper.copyString(textToCopy);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
</script>
|
55
|
+
<script type="text/javascript">
|
56
|
+
var langSelectorHtml = '<label>Language <select id="langSelector">';
|
57
|
+
langSelectorHtml += '<option value="">Auto</option>';
|
58
|
+
for (var i in hljs.LANGUAGES) {
|
59
|
+
if (hljs.LANGUAGES.hasOwnProperty(i))
|
60
|
+
langSelectorHtml += '<option value=\"'+i+'\">'+i.charAt(0).toUpperCase()+i.substr(1)+'</option>';
|
61
|
+
}
|
62
|
+
langSelectorHtml += '</select></label>';
|
63
|
+
document.write(langSelectorHtml);
|
64
|
+
</script>
|
65
|
+
<table width="100%">
|
66
|
+
<tr>
|
67
|
+
<td><textarea rows="20" cols="50" id="t1"></textarea></td>
|
68
|
+
<td><textarea rows="20" cols="50" id="t2"></textarea></td>
|
69
|
+
</tr>
|
70
|
+
<tr>
|
71
|
+
<td>Write a code snippet</td>
|
72
|
+
<td>Get HTML to paste anywhere (for actual styles and colors see sample.css)</td>
|
73
|
+
</tr>
|
74
|
+
</table>
|
75
|
+
<table width="98%">
|
76
|
+
<tr>
|
77
|
+
<td><input type="button" value="Export →" onclick="doIt()"/></td>
|
78
|
+
<td align="right"><input type="button" value="Copy to buffer" onclick="copyToBuffer(document.getElementById('t2').value);"/></td>
|
79
|
+
</tr>
|
80
|
+
</table>
|
81
|
+
<div id="highlight-view"></div>
|
82
|
+
<address>
|
83
|
+
Export script: <a href="mailto:xonixx@gmail.com">Vladimir Gubarkov</a><br>
|
84
|
+
Highlighting: <a href="http://softwaremaniacs.org/soft/highlight/">highlight.js</a>
|
85
|
+
</address>
|
86
|
+
</body>
|
87
|
+
</html>
|
@@ -0,0 +1,630 @@
|
|
1
|
+
/*
|
2
|
+
Syntax highlighting with language autodetection.
|
3
|
+
http://softwaremaniacs.org/soft/highlight/
|
4
|
+
*/
|
5
|
+
|
6
|
+
var hljs = new function() {
|
7
|
+
|
8
|
+
/* Utility functions */
|
9
|
+
|
10
|
+
function escape(value) {
|
11
|
+
return value.replace(/&/gm, '&').replace(/</gm, '<');
|
12
|
+
}
|
13
|
+
|
14
|
+
function langRe(language, value, global) {
|
15
|
+
return RegExp(
|
16
|
+
value,
|
17
|
+
'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')
|
18
|
+
);
|
19
|
+
}
|
20
|
+
|
21
|
+
function findCode(pre) {
|
22
|
+
for (var i = 0; i < pre.childNodes.length; i++) {
|
23
|
+
var node = pre.childNodes[i];
|
24
|
+
if (node.nodeName == 'CODE')
|
25
|
+
return node;
|
26
|
+
if (!(node.nodeType == 3 && node.nodeValue.match(/\s+/)))
|
27
|
+
break;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
function blockText(block, ignoreNewLines) {
|
32
|
+
var result = '';
|
33
|
+
for (var i = 0; i < block.childNodes.length; i++)
|
34
|
+
if (block.childNodes[i].nodeType == 3) {
|
35
|
+
var chunk = block.childNodes[i].nodeValue;
|
36
|
+
if (ignoreNewLines)
|
37
|
+
chunk = chunk.replace(/\n/g, '');
|
38
|
+
result += chunk;
|
39
|
+
} else if (block.childNodes[i].nodeName == 'BR')
|
40
|
+
result += '\n';
|
41
|
+
else
|
42
|
+
result += blockText(block.childNodes[i]);
|
43
|
+
// Thank you, MSIE...
|
44
|
+
if (/MSIE [678]/.test(navigator.userAgent))
|
45
|
+
result = result.replace(/\r/g, '\n');
|
46
|
+
return result;
|
47
|
+
}
|
48
|
+
|
49
|
+
function blockLanguage(block) {
|
50
|
+
var classes = block.className.split(/\s+/)
|
51
|
+
classes = classes.concat(block.parentNode.className.split(/\s+/));
|
52
|
+
for (var i = 0; i < classes.length; i++) {
|
53
|
+
var class_ = classes[i].replace(/^language-/, '');
|
54
|
+
if (languages[class_] || class_ == 'no-highlight') {
|
55
|
+
return class_;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
/* Stream merging */
|
61
|
+
|
62
|
+
function nodeStream(node) {
|
63
|
+
var result = [];
|
64
|
+
(function (node, offset) {
|
65
|
+
for (var i = 0; i < node.childNodes.length; i++) {
|
66
|
+
if (node.childNodes[i].nodeType == 3)
|
67
|
+
offset += node.childNodes[i].nodeValue.length;
|
68
|
+
else if (node.childNodes[i].nodeName == 'BR')
|
69
|
+
offset += 1
|
70
|
+
else {
|
71
|
+
result.push({
|
72
|
+
event: 'start',
|
73
|
+
offset: offset,
|
74
|
+
node: node.childNodes[i]
|
75
|
+
});
|
76
|
+
offset = arguments.callee(node.childNodes[i], offset)
|
77
|
+
result.push({
|
78
|
+
event: 'stop',
|
79
|
+
offset: offset,
|
80
|
+
node: node.childNodes[i]
|
81
|
+
});
|
82
|
+
}
|
83
|
+
}
|
84
|
+
return offset;
|
85
|
+
})(node, 0);
|
86
|
+
return result;
|
87
|
+
}
|
88
|
+
|
89
|
+
function mergeStreams(stream1, stream2, value) {
|
90
|
+
var processed = 0;
|
91
|
+
var result = '';
|
92
|
+
var nodeStack = [];
|
93
|
+
|
94
|
+
function selectStream() {
|
95
|
+
if (stream1.length && stream2.length) {
|
96
|
+
if (stream1[0].offset != stream2[0].offset)
|
97
|
+
return (stream1[0].offset < stream2[0].offset) ? stream1 : stream2;
|
98
|
+
else {
|
99
|
+
/*
|
100
|
+
To avoid starting the stream just before it should stop the order is
|
101
|
+
ensured that stream1 always starts first and closes last:
|
102
|
+
|
103
|
+
if (event1 == 'start' && event2 == 'start')
|
104
|
+
return stream1;
|
105
|
+
if (event1 == 'start' && event2 == 'stop')
|
106
|
+
return stream2;
|
107
|
+
if (event1 == 'stop' && event2 == 'start')
|
108
|
+
return stream1;
|
109
|
+
if (event1 == 'stop' && event2 == 'stop')
|
110
|
+
return stream2;
|
111
|
+
|
112
|
+
... which is collapsed to:
|
113
|
+
*/
|
114
|
+
return stream2[0].event == 'start' ? stream1 : stream2;
|
115
|
+
}
|
116
|
+
} else {
|
117
|
+
return stream1.length ? stream1 : stream2;
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
function open(node) {
|
122
|
+
var result = '<' + node.nodeName.toLowerCase();
|
123
|
+
for (var i = 0; i < node.attributes.length; i++) {
|
124
|
+
var attribute = node.attributes[i];
|
125
|
+
result += ' ' + attribute.nodeName.toLowerCase();
|
126
|
+
if (attribute.nodeValue != undefined && attribute.nodeValue != false && attribute.nodeValue != null) {
|
127
|
+
result += '="' + escape(attribute.nodeValue) + '"';
|
128
|
+
}
|
129
|
+
}
|
130
|
+
return result + '>';
|
131
|
+
}
|
132
|
+
|
133
|
+
while (stream1.length || stream2.length) {
|
134
|
+
var current = selectStream().splice(0, 1)[0];
|
135
|
+
result += escape(value.substr(processed, current.offset - processed));
|
136
|
+
processed = current.offset;
|
137
|
+
if ( current.event == 'start') {
|
138
|
+
result += open(current.node);
|
139
|
+
nodeStack.push(current.node);
|
140
|
+
} else if (current.event == 'stop') {
|
141
|
+
var i = nodeStack.length;
|
142
|
+
do {
|
143
|
+
i--;
|
144
|
+
var node = nodeStack[i];
|
145
|
+
result += ('</' + node.nodeName.toLowerCase() + '>');
|
146
|
+
} while (node != current.node);
|
147
|
+
nodeStack.splice(i, 1);
|
148
|
+
while (i < nodeStack.length) {
|
149
|
+
result += open(nodeStack[i]);
|
150
|
+
i++;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
result += value.substr(processed);
|
155
|
+
return result;
|
156
|
+
}
|
157
|
+
|
158
|
+
/* Initialization */
|
159
|
+
|
160
|
+
function compileModes() {
|
161
|
+
|
162
|
+
function compileMode(mode, language, is_default) {
|
163
|
+
if (mode.compiled)
|
164
|
+
return;
|
165
|
+
|
166
|
+
if (!is_default) {
|
167
|
+
mode.beginRe = langRe(language, mode.begin ? mode.begin : '\\B|\\b');
|
168
|
+
if (!mode.end && !mode.endsWithParent)
|
169
|
+
mode.end = '\\B|\\b'
|
170
|
+
if (mode.end)
|
171
|
+
mode.endRe = langRe(language, mode.end);
|
172
|
+
}
|
173
|
+
if (mode.illegal)
|
174
|
+
mode.illegalRe = langRe(language, mode.illegal);
|
175
|
+
if (mode.relevance == undefined)
|
176
|
+
mode.relevance = 1;
|
177
|
+
if (mode.keywords)
|
178
|
+
mode.lexemsRe = langRe(language, mode.lexems || hljs.IDENT_RE, true);
|
179
|
+
for (var key in mode.keywords) {
|
180
|
+
if (!mode.keywords.hasOwnProperty(key))
|
181
|
+
continue;
|
182
|
+
if (mode.keywords[key] instanceof Object)
|
183
|
+
mode.keywordGroups = mode.keywords;
|
184
|
+
else
|
185
|
+
mode.keywordGroups = {'keyword': mode.keywords};
|
186
|
+
break;
|
187
|
+
}
|
188
|
+
if (!mode.contains) {
|
189
|
+
mode.contains = [];
|
190
|
+
}
|
191
|
+
// compiled flag is set before compiling submodes to avoid self-recursion
|
192
|
+
// (see lisp where quoted_list contains quoted_list)
|
193
|
+
mode.compiled = true;
|
194
|
+
for (var i = 0; i < mode.contains.length; i++) {
|
195
|
+
compileMode(mode.contains[i], language, false);
|
196
|
+
}
|
197
|
+
if (mode.starts) {
|
198
|
+
compileMode(mode.starts, language, false);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
for (var i in languages) {
|
203
|
+
if (!languages.hasOwnProperty(i))
|
204
|
+
continue;
|
205
|
+
compileMode(languages[i].defaultMode, languages[i], true);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
/*
|
210
|
+
Core highlighting function. Accepts a language name and a string with the
|
211
|
+
code to highlight. Returns an object with the following properties:
|
212
|
+
|
213
|
+
- relevance (int)
|
214
|
+
- keyword_count (int)
|
215
|
+
- value (an HTML string with highlighting markup)
|
216
|
+
|
217
|
+
*/
|
218
|
+
function highlight(language_name, value) {
|
219
|
+
if (!compileModes.called) {
|
220
|
+
compileModes();
|
221
|
+
compileModes.called = true;
|
222
|
+
}
|
223
|
+
|
224
|
+
function subMode(lexem, mode) {
|
225
|
+
for (var i = 0; i < mode.contains.length; i++) {
|
226
|
+
if (mode.contains[i].beginRe.test(lexem)) {
|
227
|
+
return mode.contains[i];
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
function endOfMode(mode_index, lexem) {
|
233
|
+
if (modes[mode_index].end && modes[mode_index].endRe.test(lexem))
|
234
|
+
return 1;
|
235
|
+
if (modes[mode_index].endsWithParent) {
|
236
|
+
var level = endOfMode(mode_index - 1, lexem);
|
237
|
+
return level ? level + 1 : 0;
|
238
|
+
}
|
239
|
+
return 0;
|
240
|
+
}
|
241
|
+
|
242
|
+
function isIllegal(lexem, mode) {
|
243
|
+
return mode.illegalRe && mode.illegalRe.test(lexem);
|
244
|
+
}
|
245
|
+
|
246
|
+
function compileTerminators(mode, language) {
|
247
|
+
var terminators = [];
|
248
|
+
|
249
|
+
for (var i = 0; i < mode.contains.length; i++) {
|
250
|
+
terminators.push(mode.contains[i].begin);
|
251
|
+
}
|
252
|
+
|
253
|
+
var index = modes.length - 1;
|
254
|
+
do {
|
255
|
+
if (modes[index].end) {
|
256
|
+
terminators.push(modes[index].end);
|
257
|
+
}
|
258
|
+
index--;
|
259
|
+
} while (modes[index + 1].endsWithParent);
|
260
|
+
|
261
|
+
if (mode.illegal) {
|
262
|
+
terminators.push(mode.illegal);
|
263
|
+
}
|
264
|
+
|
265
|
+
return langRe(language, '(' + terminators.join('|') + ')', true);
|
266
|
+
}
|
267
|
+
|
268
|
+
function eatModeChunk(value, index) {
|
269
|
+
var mode = modes[modes.length - 1];
|
270
|
+
if (!mode.terminators) {
|
271
|
+
mode.terminators = compileTerminators(mode, language);
|
272
|
+
}
|
273
|
+
mode.terminators.lastIndex = index;
|
274
|
+
var match = mode.terminators.exec(value);
|
275
|
+
if (match)
|
276
|
+
return [value.substr(index, match.index - index), match[0], false];
|
277
|
+
else
|
278
|
+
return [value.substr(index), '', true];
|
279
|
+
}
|
280
|
+
|
281
|
+
function keywordMatch(mode, match) {
|
282
|
+
var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0]
|
283
|
+
for (var className in mode.keywordGroups) {
|
284
|
+
if (!mode.keywordGroups.hasOwnProperty(className))
|
285
|
+
continue;
|
286
|
+
var value = mode.keywordGroups[className].hasOwnProperty(match_str);
|
287
|
+
if (value)
|
288
|
+
return [className, value];
|
289
|
+
}
|
290
|
+
return false;
|
291
|
+
}
|
292
|
+
|
293
|
+
function processKeywords(buffer, mode) {
|
294
|
+
if (!mode.keywords)
|
295
|
+
return escape(buffer);
|
296
|
+
var result = '';
|
297
|
+
var last_index = 0;
|
298
|
+
mode.lexemsRe.lastIndex = 0;
|
299
|
+
var match = mode.lexemsRe.exec(buffer);
|
300
|
+
while (match) {
|
301
|
+
result += escape(buffer.substr(last_index, match.index - last_index));
|
302
|
+
var keyword_match = keywordMatch(mode, match);
|
303
|
+
if (keyword_match) {
|
304
|
+
keyword_count += keyword_match[1];
|
305
|
+
result += '<span class="'+ keyword_match[0] +'">' + escape(match[0]) + '</span>';
|
306
|
+
} else {
|
307
|
+
result += escape(match[0]);
|
308
|
+
}
|
309
|
+
last_index = mode.lexemsRe.lastIndex;
|
310
|
+
match = mode.lexemsRe.exec(buffer);
|
311
|
+
}
|
312
|
+
result += escape(buffer.substr(last_index, buffer.length - last_index));
|
313
|
+
return result;
|
314
|
+
}
|
315
|
+
|
316
|
+
function processBuffer(buffer, mode) {
|
317
|
+
if (mode.subLanguage && languages[mode.subLanguage]) {
|
318
|
+
var result = highlight(mode.subLanguage, buffer);
|
319
|
+
keyword_count += result.keyword_count;
|
320
|
+
return result.value;
|
321
|
+
} else {
|
322
|
+
return processKeywords(buffer, mode);
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
function startNewMode(mode, lexem) {
|
327
|
+
var markup = mode.className?'<span class="' + mode.className + '">':'';
|
328
|
+
if (mode.returnBegin) {
|
329
|
+
result += markup;
|
330
|
+
mode.buffer = '';
|
331
|
+
} else if (mode.excludeBegin) {
|
332
|
+
result += escape(lexem) + markup;
|
333
|
+
mode.buffer = '';
|
334
|
+
} else {
|
335
|
+
result += markup;
|
336
|
+
mode.buffer = lexem;
|
337
|
+
}
|
338
|
+
modes.push(mode);
|
339
|
+
relevance += mode.relevance;
|
340
|
+
}
|
341
|
+
|
342
|
+
function processModeInfo(buffer, lexem, end) {
|
343
|
+
var current_mode = modes[modes.length - 1];
|
344
|
+
if (end) {
|
345
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode);
|
346
|
+
return false;
|
347
|
+
}
|
348
|
+
|
349
|
+
var new_mode = subMode(lexem, current_mode);
|
350
|
+
if (new_mode) {
|
351
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode);
|
352
|
+
startNewMode(new_mode, lexem);
|
353
|
+
return new_mode.returnBegin;
|
354
|
+
}
|
355
|
+
|
356
|
+
var end_level = endOfMode(modes.length - 1, lexem);
|
357
|
+
if (end_level) {
|
358
|
+
var markup = current_mode.className?'</span>':'';
|
359
|
+
if (current_mode.returnEnd) {
|
360
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode) + markup;
|
361
|
+
} else if (current_mode.excludeEnd) {
|
362
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode) + markup + escape(lexem);
|
363
|
+
} else {
|
364
|
+
result += processBuffer(current_mode.buffer + buffer + lexem, current_mode) + markup;
|
365
|
+
}
|
366
|
+
while (end_level > 1) {
|
367
|
+
markup = modes[modes.length - 2].className?'</span>':'';
|
368
|
+
result += markup;
|
369
|
+
end_level--;
|
370
|
+
modes.length--;
|
371
|
+
}
|
372
|
+
var last_ended_mode = modes[modes.length - 1];
|
373
|
+
modes.length--;
|
374
|
+
modes[modes.length - 1].buffer = '';
|
375
|
+
if (last_ended_mode.starts) {
|
376
|
+
startNewMode(last_ended_mode.starts, '');
|
377
|
+
}
|
378
|
+
return current_mode.returnEnd;
|
379
|
+
}
|
380
|
+
|
381
|
+
if (isIllegal(lexem, current_mode))
|
382
|
+
throw 'Illegal';
|
383
|
+
}
|
384
|
+
|
385
|
+
var language = languages[language_name];
|
386
|
+
var modes = [language.defaultMode];
|
387
|
+
var relevance = 0;
|
388
|
+
var keyword_count = 0;
|
389
|
+
var result = '';
|
390
|
+
try {
|
391
|
+
var index = 0;
|
392
|
+
language.defaultMode.buffer = '';
|
393
|
+
do {
|
394
|
+
var mode_info = eatModeChunk(value, index);
|
395
|
+
var return_lexem = processModeInfo(mode_info[0], mode_info[1], mode_info[2]);
|
396
|
+
index += mode_info[0].length;
|
397
|
+
if (!return_lexem) {
|
398
|
+
index += mode_info[1].length;
|
399
|
+
}
|
400
|
+
} while (!mode_info[2]);
|
401
|
+
if(modes.length > 1)
|
402
|
+
throw 'Illegal';
|
403
|
+
return {
|
404
|
+
relevance: relevance,
|
405
|
+
keyword_count: keyword_count,
|
406
|
+
value: result
|
407
|
+
}
|
408
|
+
} catch (e) {
|
409
|
+
if (e == 'Illegal') {
|
410
|
+
return {
|
411
|
+
relevance: 0,
|
412
|
+
keyword_count: 0,
|
413
|
+
value: escape(value)
|
414
|
+
}
|
415
|
+
} else {
|
416
|
+
throw e;
|
417
|
+
}
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
/*
|
422
|
+
Highlighting with language detection. Accepts a string with the code to
|
423
|
+
highlight. Returns an object with the following properties:
|
424
|
+
|
425
|
+
- language (detected language)
|
426
|
+
- relevance (int)
|
427
|
+
- keyword_count (int)
|
428
|
+
- value (an HTML string with highlighting markup)
|
429
|
+
- second_best (object with the same structure for second-best heuristically
|
430
|
+
detected language, may be absent)
|
431
|
+
|
432
|
+
*/
|
433
|
+
function highlightAuto(text) {
|
434
|
+
var result = {
|
435
|
+
keyword_count: 0,
|
436
|
+
relevance: 0,
|
437
|
+
value: escape(text)
|
438
|
+
};
|
439
|
+
var second_best = result;
|
440
|
+
for (var key in languages) {
|
441
|
+
if (!languages.hasOwnProperty(key))
|
442
|
+
continue;
|
443
|
+
var current = highlight(key, text);
|
444
|
+
current.language = key;
|
445
|
+
if (current.keyword_count + current.relevance > second_best.keyword_count + second_best.relevance) {
|
446
|
+
second_best = current;
|
447
|
+
}
|
448
|
+
if (current.keyword_count + current.relevance > result.keyword_count + result.relevance) {
|
449
|
+
second_best = result;
|
450
|
+
result = current;
|
451
|
+
}
|
452
|
+
}
|
453
|
+
if (second_best.language) {
|
454
|
+
result.second_best = second_best;
|
455
|
+
}
|
456
|
+
return result;
|
457
|
+
}
|
458
|
+
|
459
|
+
/*
|
460
|
+
Post-processing of the highlighted markup:
|
461
|
+
|
462
|
+
- replace TABs with something more useful
|
463
|
+
- replace real line-breaks with '<br>' for non-pre containers
|
464
|
+
|
465
|
+
*/
|
466
|
+
function fixMarkup(value, tabReplace, useBR) {
|
467
|
+
if (tabReplace) {
|
468
|
+
value = value.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1, offset, s) {
|
469
|
+
return p1.replace(/\t/g, tabReplace);
|
470
|
+
})
|
471
|
+
}
|
472
|
+
if (useBR) {
|
473
|
+
value = value.replace(/\n/g, '<br>');
|
474
|
+
}
|
475
|
+
return value;
|
476
|
+
}
|
477
|
+
|
478
|
+
/*
|
479
|
+
Applies highlighting to a DOM node containing code. Accepts a DOM node and
|
480
|
+
two optional parameters for fixMarkup.
|
481
|
+
*/
|
482
|
+
function highlightBlock(block, tabReplace, useBR) {
|
483
|
+
var text = blockText(block, useBR);
|
484
|
+
var language = blockLanguage(block);
|
485
|
+
if (language == 'no-highlight')
|
486
|
+
return;
|
487
|
+
if (language) {
|
488
|
+
var result = highlight(language, text);
|
489
|
+
} else {
|
490
|
+
var result = highlightAuto(text);
|
491
|
+
language = result.language;
|
492
|
+
}
|
493
|
+
var original = nodeStream(block);
|
494
|
+
if (original.length) {
|
495
|
+
var pre = document.createElement('pre');
|
496
|
+
pre.innerHTML = result.value;
|
497
|
+
result.value = mergeStreams(original, nodeStream(pre), text);
|
498
|
+
}
|
499
|
+
result.value = fixMarkup(result.value, tabReplace, useBR);
|
500
|
+
|
501
|
+
var class_name = block.className;
|
502
|
+
if (!class_name.match('(\\s|^)(language-)?' + language + '(\\s|$)')) {
|
503
|
+
class_name = class_name ? (class_name + ' ' + language) : language;
|
504
|
+
}
|
505
|
+
if (/MSIE [678]/.test(navigator.userAgent) && block.tagName == 'CODE' && block.parentNode.tagName == 'PRE') {
|
506
|
+
// This is for backwards compatibility only. IE needs this strange
|
507
|
+
// hack becasue it cannot just cleanly replace <code> block contents.
|
508
|
+
var pre = block.parentNode;
|
509
|
+
var container = document.createElement('div');
|
510
|
+
container.innerHTML = '<pre><code>' + result.value + '</code></pre>';
|
511
|
+
block = container.firstChild.firstChild;
|
512
|
+
container.firstChild.className = pre.className;
|
513
|
+
pre.parentNode.replaceChild(container.firstChild, pre);
|
514
|
+
} else {
|
515
|
+
block.innerHTML = result.value;
|
516
|
+
}
|
517
|
+
block.className = class_name;
|
518
|
+
block.result = {
|
519
|
+
language: language,
|
520
|
+
kw: result.keyword_count,
|
521
|
+
re: result.relevance
|
522
|
+
};
|
523
|
+
if (result.second_best) {
|
524
|
+
block.second_best = {
|
525
|
+
language: result.second_best.language,
|
526
|
+
kw: result.second_best.keyword_count,
|
527
|
+
re: result.second_best.relevance
|
528
|
+
};
|
529
|
+
}
|
530
|
+
}
|
531
|
+
|
532
|
+
/*
|
533
|
+
Applies highlighting to all <pre><code>..</code></pre> blocks on a page.
|
534
|
+
*/
|
535
|
+
function initHighlighting() {
|
536
|
+
if (initHighlighting.called)
|
537
|
+
return;
|
538
|
+
initHighlighting.called = true;
|
539
|
+
var pres = document.getElementsByTagName('pre');
|
540
|
+
for (var i = 0; i < pres.length; i++) {
|
541
|
+
var code = findCode(pres[i]);
|
542
|
+
if (code)
|
543
|
+
highlightBlock(code, hljs.tabReplace);
|
544
|
+
}
|
545
|
+
}
|
546
|
+
|
547
|
+
/*
|
548
|
+
Attaches highlighting to the page load event.
|
549
|
+
*/
|
550
|
+
function initHighlightingOnLoad() {
|
551
|
+
if (window.addEventListener) {
|
552
|
+
window.addEventListener('DOMContentLoaded', initHighlighting, false);
|
553
|
+
window.addEventListener('load', initHighlighting, false);
|
554
|
+
} else if (window.attachEvent)
|
555
|
+
window.attachEvent('onload', initHighlighting);
|
556
|
+
else
|
557
|
+
window.onload = initHighlighting;
|
558
|
+
}
|
559
|
+
|
560
|
+
var languages = {}; // a shortcut to avoid writing "this." everywhere
|
561
|
+
|
562
|
+
/* Interface definition */
|
563
|
+
|
564
|
+
this.LANGUAGES = languages;
|
565
|
+
this.highlight = highlight;
|
566
|
+
this.highlightAuto = highlightAuto;
|
567
|
+
this.fixMarkup = fixMarkup;
|
568
|
+
this.highlightBlock = highlightBlock;
|
569
|
+
this.initHighlighting = initHighlighting;
|
570
|
+
this.initHighlightingOnLoad = initHighlightingOnLoad;
|
571
|
+
|
572
|
+
// Common regexps
|
573
|
+
this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*';
|
574
|
+
this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*';
|
575
|
+
this.NUMBER_RE = '\\b\\d+(\\.\\d+)?';
|
576
|
+
this.C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)';
|
577
|
+
this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
|
578
|
+
|
579
|
+
// Common modes
|
580
|
+
this.BACKSLASH_ESCAPE = {
|
581
|
+
begin: '\\\\.', relevance: 0
|
582
|
+
};
|
583
|
+
this.APOS_STRING_MODE = {
|
584
|
+
className: 'string',
|
585
|
+
begin: '\'', end: '\'',
|
586
|
+
illegal: '\\n',
|
587
|
+
contains: [this.BACKSLASH_ESCAPE],
|
588
|
+
relevance: 0
|
589
|
+
};
|
590
|
+
this.QUOTE_STRING_MODE = {
|
591
|
+
className: 'string',
|
592
|
+
begin: '"', end: '"',
|
593
|
+
illegal: '\\n',
|
594
|
+
contains: [this.BACKSLASH_ESCAPE],
|
595
|
+
relevance: 0
|
596
|
+
};
|
597
|
+
this.C_LINE_COMMENT_MODE = {
|
598
|
+
className: 'comment',
|
599
|
+
begin: '//', end: '$'
|
600
|
+
};
|
601
|
+
this.C_BLOCK_COMMENT_MODE = {
|
602
|
+
className: 'comment',
|
603
|
+
begin: '/\\*', end: '\\*/'
|
604
|
+
};
|
605
|
+
this.HASH_COMMENT_MODE = {
|
606
|
+
className: 'comment',
|
607
|
+
begin: '#', end: '$'
|
608
|
+
};
|
609
|
+
this.NUMBER_MODE = {
|
610
|
+
className: 'number',
|
611
|
+
begin: this.NUMBER_RE,
|
612
|
+
relevance: 0
|
613
|
+
};
|
614
|
+
this.C_NUMBER_MODE = {
|
615
|
+
className: 'number',
|
616
|
+
begin: this.C_NUMBER_RE,
|
617
|
+
relevance: 0
|
618
|
+
};
|
619
|
+
|
620
|
+
// Utility functions
|
621
|
+
this.inherit = function(parent, obj) {
|
622
|
+
var result = {}
|
623
|
+
for (var key in parent)
|
624
|
+
result[key] = parent[key];
|
625
|
+
if (obj)
|
626
|
+
for (var key in obj)
|
627
|
+
result[key] = obj[key];
|
628
|
+
return result;
|
629
|
+
}
|
630
|
+
}();
|