romanvbabenko-rhighlightjs 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/assets/images/brown_papersq.png +0 -0
- data/assets/images/paperbg.gif +0 -0
- data/assets/images/school_book.png +0 -0
- data/assets/javascripts/highlight.js +570 -0
- data/assets/javascripts/highlight.pack.js +1 -0
- data/assets/javascripts/languages/1c.js +95 -0
- data/assets/javascripts/languages/apache.js +442 -0
- data/assets/javascripts/languages/avrasm.js +89 -0
- data/assets/javascripts/languages/axapta.js +52 -0
- data/assets/javascripts/languages/bash.js +81 -0
- data/assets/javascripts/languages/cpp.js +42 -0
- data/assets/javascripts/languages/cs.js +47 -0
- data/assets/javascripts/languages/css.js +81 -0
- data/assets/javascripts/languages/delphi.js +82 -0
- data/assets/javascripts/languages/diff.js +65 -0
- data/assets/javascripts/languages/django.js +61 -0
- data/assets/javascripts/languages/dos.js +33 -0
- data/assets/javascripts/languages/dynamic.js +460 -0
- data/assets/javascripts/languages/html-xml.js +140 -0
- data/assets/javascripts/languages/ini.js +40 -0
- data/assets/javascripts/languages/java.js +58 -0
- data/assets/javascripts/languages/javascript.js +50 -0
- data/assets/javascripts/languages/lisp.js +89 -0
- data/assets/javascripts/languages/mel.js +51 -0
- data/assets/javascripts/languages/parser3.js +54 -0
- data/assets/javascripts/languages/perl.js +152 -0
- data/assets/javascripts/languages/php.js +54 -0
- data/assets/javascripts/languages/profile.js +51 -0
- data/assets/javascripts/languages/python.js +75 -0
- data/assets/javascripts/languages/renderman.js +239 -0
- data/assets/javascripts/languages/ruby.js +176 -0
- data/assets/javascripts/languages/smalltalk.js +52 -0
- data/assets/javascripts/languages/sql.js +52 -0
- data/assets/javascripts/languages/static.js +223 -0
- data/assets/javascripts/languages/vbscript.js +27 -0
- data/assets/javascripts/languages/www.js +257 -0
- data/assets/javascripts/styleswitch.js +57 -0
- data/assets/stylesheets/ascetic.css +42 -0
- data/assets/stylesheets/brown_paper.css +104 -0
- data/assets/stylesheets/brown_papersq.png +0 -0
- data/assets/stylesheets/dark.css +101 -0
- data/assets/stylesheets/default.css +103 -0
- data/assets/stylesheets/far.css +113 -0
- data/assets/stylesheets/github.css +90 -0
- data/assets/stylesheets/idea.css +74 -0
- data/assets/stylesheets/ir_black.css +67 -0
- data/assets/stylesheets/magula.css +105 -0
- data/assets/stylesheets/notebook.css +106 -0
- data/assets/stylesheets/school_book.css +106 -0
- data/assets/stylesheets/school_book.png +0 -0
- data/assets/stylesheets/sunburst.css +112 -0
- data/assets/stylesheets/vs.css +68 -0
- data/assets/stylesheets/zenburn.css +113 -0
- data/assets/stylesheets/zenburn.css.txt +108 -0
- data/bin/rhighlightjs +6 -0
- data/init.rb +2 -0
- data/install.rb +3 -0
- data/lib/rhighlightjs.rb +28 -0
- data/rhighlightjs.gemspec +170 -0
- data/tasks/rhighlightjs_tasks.rake +18 -0
- data/test/rhighlightjs_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- data/uninstall.rb +1 -0
- metadata +134 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 romanvbabenko
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
= Rhighlightjs
|
2
|
+
|
3
|
+
It is the helper for {higlight.js}[http://softwaremaniacs.org/soft/highlight] by Ivan Salagaev (currently v5.4)
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
gem install romanvbabenko-rhighlightjs
|
8
|
+
|
9
|
+
config/environment.rb
|
10
|
+
|
11
|
+
config.gem 'romanvbabenko-rhighlightjs', :lib => 'rhighlightjs',
|
12
|
+
:source => 'http://gems.github.com'
|
13
|
+
|
14
|
+
./script/plugin install git://github.com/romanvbabenko/rhighlightjs.git
|
15
|
+
|
16
|
+
OR
|
17
|
+
|
18
|
+
git clone git://github.com/romanvbabenko/rhighlightjs.git ./vendor/plugins/
|
19
|
+
|
20
|
+
rake rhighlightjs:install
|
21
|
+
|
22
|
+
== New project with gem "rhighlightjs"
|
23
|
+
|
24
|
+
rails blog
|
25
|
+
cd blog
|
26
|
+
rhighlightjs
|
27
|
+
|
28
|
+
This command copy assets files to application public directory.
|
29
|
+
|
30
|
+
== Example
|
31
|
+
|
32
|
+
|
33
|
+
In view:
|
34
|
+
|
35
|
+
<%= highlighter 'github', :languages => [:ruby] %>
|
36
|
+
|
37
|
+
<pre><code>
|
38
|
+
class Person
|
39
|
+
attr_accessors :last_name, :first_name
|
40
|
+
def say
|
41
|
+
puts "Hello world"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
</code></pre>
|
45
|
+
|
46
|
+
== Copyright
|
47
|
+
|
48
|
+
Blog: http://romanvbabenko.com
|
49
|
+
|
50
|
+
Copyright (c) 2008 Roman V. Babenko, released under the MIT license
|
51
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rhighlightjs"
|
8
|
+
gem.summary = %Q{It is the helper for higlight.js}
|
9
|
+
gem.description = %Q{Javascript syntax highlighter by Ivan Salagaev}
|
10
|
+
gem.email = "romanvbabenko@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/romanvbabenko/rhighlightjs"
|
12
|
+
gem.authors = ["romanvbabenko"]
|
13
|
+
gem.add_development_dependency "thoughtbot-shoulda"
|
14
|
+
gem.files.include Dir['assets/**/*']
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/*_test.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/*_test.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
if File.exist?('VERSION')
|
48
|
+
version = File.read('VERSION')
|
49
|
+
else
|
50
|
+
version = ""
|
51
|
+
end
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "rhighlightjs #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
58
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,570 @@
|
|
1
|
+
/*
|
2
|
+
Syntax highlighting with language autodetection.
|
3
|
+
http://softwaremaniacs.org/soft/highlight/
|
4
|
+
*/
|
5
|
+
|
6
|
+
var hljs = new function() {
|
7
|
+
var LANGUAGES = {}
|
8
|
+
var selected_languages = {};
|
9
|
+
|
10
|
+
function escape(value) {
|
11
|
+
return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
12
|
+
}
|
13
|
+
|
14
|
+
function contains(array, item) {
|
15
|
+
if (!array)
|
16
|
+
return false;
|
17
|
+
for (var i = 0; i < array.length; i++)
|
18
|
+
if (array[i] == item)
|
19
|
+
return true;
|
20
|
+
return false;
|
21
|
+
}
|
22
|
+
|
23
|
+
function highlight(language_name, value) {
|
24
|
+
function compileSubModes(mode, language) {
|
25
|
+
mode.sub_modes = [];
|
26
|
+
for (var i = 0; i < mode.contains.length; i++) {
|
27
|
+
for (var j = 0; j < language.modes.length; j++) {
|
28
|
+
if (language.modes[j].className == mode.contains[i]) {
|
29
|
+
mode.sub_modes[mode.sub_modes.length] = language.modes[j];
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
function subMode(lexem, mode) {
|
36
|
+
if (!mode.contains) {
|
37
|
+
return null;
|
38
|
+
}
|
39
|
+
if (!mode.sub_modes) {
|
40
|
+
compileSubModes(mode, language);
|
41
|
+
}
|
42
|
+
for (var i = 0; i < mode.sub_modes.length; i++) {
|
43
|
+
if (mode.sub_modes[i].beginRe.test(lexem)) {
|
44
|
+
return mode.sub_modes[i];
|
45
|
+
}
|
46
|
+
}
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
|
50
|
+
function endOfMode(mode_index, lexem) {
|
51
|
+
if (modes[mode_index].end && modes[mode_index].endRe.test(lexem))
|
52
|
+
return 1;
|
53
|
+
if (modes[mode_index].endsWithParent) {
|
54
|
+
var level = endOfMode(mode_index - 1, lexem);
|
55
|
+
return level ? level + 1 : 0;
|
56
|
+
}
|
57
|
+
return 0;
|
58
|
+
}
|
59
|
+
|
60
|
+
function isIllegal(lexem, mode) {
|
61
|
+
return mode.illegalRe && mode.illegalRe.test(lexem);
|
62
|
+
}
|
63
|
+
|
64
|
+
function compileTerminators(mode, language) {
|
65
|
+
var terminators = [];
|
66
|
+
|
67
|
+
function addTerminator(re) {
|
68
|
+
if (!contains(terminators, re)) {
|
69
|
+
terminators[terminators.length] = re;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
if (mode.contains)
|
74
|
+
for (var i = 0; i < language.modes.length; i++) {
|
75
|
+
if (contains(mode.contains, language.modes[i].className)) {
|
76
|
+
addTerminator(language.modes[i].begin);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
var index = modes.length - 1;
|
81
|
+
do {
|
82
|
+
if (modes[index].end) {
|
83
|
+
addTerminator(modes[index].end);
|
84
|
+
}
|
85
|
+
index--;
|
86
|
+
} while (modes[index + 1].endsWithParent);
|
87
|
+
|
88
|
+
if (mode.illegal) {
|
89
|
+
addTerminator(mode.illegal);
|
90
|
+
}
|
91
|
+
|
92
|
+
var terminator_re = '(' + terminators[0];
|
93
|
+
for (var i = 0; i < terminators.length; i++)
|
94
|
+
terminator_re += '|' + terminators[i];
|
95
|
+
terminator_re += ')';
|
96
|
+
return langRe(language, terminator_re);
|
97
|
+
}
|
98
|
+
|
99
|
+
function eatModeChunk(value, index) {
|
100
|
+
var mode = modes[modes.length - 1];
|
101
|
+
if (!mode.terminators) {
|
102
|
+
mode.terminators = compileTerminators(mode, language);
|
103
|
+
}
|
104
|
+
value = value.substr(index);
|
105
|
+
var match = mode.terminators.exec(value);
|
106
|
+
if (!match)
|
107
|
+
return [value, '', true];
|
108
|
+
if (match.index == 0)
|
109
|
+
return ['', match[0], false];
|
110
|
+
else
|
111
|
+
return [value.substr(0, match.index), match[0], false];
|
112
|
+
}
|
113
|
+
|
114
|
+
function keywordMatch(mode, match) {
|
115
|
+
var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0]
|
116
|
+
for (var className in mode.keywordGroups) {
|
117
|
+
if (!mode.keywordGroups.hasOwnProperty(className))
|
118
|
+
continue;
|
119
|
+
var value = mode.keywordGroups[className].hasOwnProperty(match_str);
|
120
|
+
if (value)
|
121
|
+
return [className, value];
|
122
|
+
}
|
123
|
+
return false;
|
124
|
+
}
|
125
|
+
|
126
|
+
function processKeywords(buffer, mode) {
|
127
|
+
if (!mode.keywords || !mode.lexems)
|
128
|
+
return escape(buffer);
|
129
|
+
if (!mode.lexemsRe) {
|
130
|
+
var lexems_re = '(' + mode.lexems[0];
|
131
|
+
for (var i = 1; i < mode.lexems.length; i++)
|
132
|
+
lexems_re += '|' + mode.lexems[i];
|
133
|
+
lexems_re += ')';
|
134
|
+
mode.lexemsRe = langRe(language, lexems_re, true);
|
135
|
+
}
|
136
|
+
var result = '';
|
137
|
+
var last_index = 0;
|
138
|
+
mode.lexemsRe.lastIndex = 0;
|
139
|
+
var match = mode.lexemsRe.exec(buffer);
|
140
|
+
while (match) {
|
141
|
+
result += escape(buffer.substr(last_index, match.index - last_index));
|
142
|
+
var keyword_match = keywordMatch(mode, match);
|
143
|
+
if (keyword_match) {
|
144
|
+
keyword_count += keyword_match[1];
|
145
|
+
result += '<span class="'+ keyword_match[0] +'">' + escape(match[0]) + '</span>';
|
146
|
+
} else {
|
147
|
+
result += escape(match[0]);
|
148
|
+
}
|
149
|
+
last_index = mode.lexemsRe.lastIndex;
|
150
|
+
match = mode.lexemsRe.exec(buffer);
|
151
|
+
}
|
152
|
+
result += escape(buffer.substr(last_index, buffer.length - last_index));
|
153
|
+
return result;
|
154
|
+
}
|
155
|
+
|
156
|
+
function processBuffer(buffer, mode) {
|
157
|
+
if (mode.subLanguage && selected_languages[mode.subLanguage]) {
|
158
|
+
var result = highlight(mode.subLanguage, buffer);
|
159
|
+
keyword_count += result.keyword_count;
|
160
|
+
relevance += result.relevance;
|
161
|
+
return result.value;
|
162
|
+
} else {
|
163
|
+
return processKeywords(buffer, mode);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
function startNewMode(mode, lexem) {
|
168
|
+
var markup = mode.noMarkup?'':'<span class="' + mode.className + '">';
|
169
|
+
if (mode.returnBegin) {
|
170
|
+
result += markup;
|
171
|
+
mode.buffer = '';
|
172
|
+
} else if (mode.excludeBegin) {
|
173
|
+
result += escape(lexem) + markup;
|
174
|
+
mode.buffer = '';
|
175
|
+
} else {
|
176
|
+
result += markup;
|
177
|
+
mode.buffer = lexem;
|
178
|
+
}
|
179
|
+
modes[modes.length] = mode;
|
180
|
+
}
|
181
|
+
|
182
|
+
function processModeInfo(buffer, lexem, end) {
|
183
|
+
var current_mode = modes[modes.length - 1];
|
184
|
+
if (end) {
|
185
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode);
|
186
|
+
return false;
|
187
|
+
}
|
188
|
+
|
189
|
+
var new_mode = subMode(lexem, current_mode);
|
190
|
+
if (new_mode) {
|
191
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode);
|
192
|
+
startNewMode(new_mode, lexem);
|
193
|
+
relevance += new_mode.relevance;
|
194
|
+
return new_mode.returnBegin;
|
195
|
+
}
|
196
|
+
|
197
|
+
var end_level = endOfMode(modes.length - 1, lexem);
|
198
|
+
if (end_level) {
|
199
|
+
var markup = current_mode.noMarkup?'':'</span>';
|
200
|
+
if (current_mode.returnEnd) {
|
201
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode) + markup;
|
202
|
+
} else if (current_mode.excludeEnd) {
|
203
|
+
result += processBuffer(current_mode.buffer + buffer, current_mode) + markup + escape(lexem);
|
204
|
+
} else {
|
205
|
+
result += processBuffer(current_mode.buffer + buffer + lexem, current_mode) + markup;
|
206
|
+
}
|
207
|
+
while (end_level > 1) {
|
208
|
+
markup = modes[modes.length - 2].noMarkup?'':'</span>';
|
209
|
+
result += markup;
|
210
|
+
end_level--;
|
211
|
+
modes.length--;
|
212
|
+
}
|
213
|
+
modes.length--;
|
214
|
+
modes[modes.length - 1].buffer = '';
|
215
|
+
if (current_mode.starts) {
|
216
|
+
for (var i = 0; i < language.modes.length; i++) {
|
217
|
+
if (language.modes[i].className == current_mode.starts) {
|
218
|
+
startNewMode(language.modes[i], '');
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
return current_mode.returnEnd;
|
224
|
+
}
|
225
|
+
|
226
|
+
if (isIllegal(lexem, current_mode))
|
227
|
+
throw 'Illegal';
|
228
|
+
}
|
229
|
+
|
230
|
+
var language = LANGUAGES[language_name];
|
231
|
+
var modes = [language.defaultMode];
|
232
|
+
var relevance = 0;
|
233
|
+
var keyword_count = 0;
|
234
|
+
var result = '';
|
235
|
+
try {
|
236
|
+
var index = 0;
|
237
|
+
language.defaultMode.buffer = '';
|
238
|
+
do {
|
239
|
+
var mode_info = eatModeChunk(value, index);
|
240
|
+
var return_lexem = processModeInfo(mode_info[0], mode_info[1], mode_info[2]);
|
241
|
+
index += mode_info[0].length;
|
242
|
+
if (!return_lexem) {
|
243
|
+
index += mode_info[1].length;
|
244
|
+
}
|
245
|
+
} while (!mode_info[2]);
|
246
|
+
if(modes.length > 1)
|
247
|
+
throw 'Illegal';
|
248
|
+
return {
|
249
|
+
relevance: relevance,
|
250
|
+
keyword_count: keyword_count,
|
251
|
+
value: result
|
252
|
+
}
|
253
|
+
} catch (e) {
|
254
|
+
if (e == 'Illegal') {
|
255
|
+
return {
|
256
|
+
relevance: 0,
|
257
|
+
keyword_count: 0,
|
258
|
+
value: escape(value)
|
259
|
+
}
|
260
|
+
} else {
|
261
|
+
throw e;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
function blockText(block) {
|
267
|
+
var result = '';
|
268
|
+
for (var i = 0; i < block.childNodes.length; i++)
|
269
|
+
if (block.childNodes[i].nodeType == 3)
|
270
|
+
result += block.childNodes[i].nodeValue;
|
271
|
+
else if (block.childNodes[i].nodeName == 'BR')
|
272
|
+
result += '\n';
|
273
|
+
else
|
274
|
+
result += blockText(block.childNodes[i]);
|
275
|
+
return result;
|
276
|
+
}
|
277
|
+
|
278
|
+
function blockLanguage(block) {
|
279
|
+
var classes = block.className.split(/\s+/)
|
280
|
+
classes = classes.concat(block.parentNode.className.split(/\s+/));
|
281
|
+
for (var i = 0; i < classes.length; i++) {
|
282
|
+
var class_ = classes[i].replace(/^language-/, '');
|
283
|
+
if (class_ == 'no-highlight') {
|
284
|
+
throw 'No highlight'
|
285
|
+
}
|
286
|
+
if (LANGUAGES[class_]) {
|
287
|
+
return class_;
|
288
|
+
}
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
function nodeStream(node) {
|
293
|
+
var result = [];
|
294
|
+
(function (node, offset) {
|
295
|
+
for (var i = 0; i < node.childNodes.length; i++) {
|
296
|
+
if (node.childNodes[i].nodeType == 3)
|
297
|
+
offset += node.childNodes[i].nodeValue.length;
|
298
|
+
else if (node.childNodes[i].nodeName == 'BR')
|
299
|
+
offset += 1
|
300
|
+
else {
|
301
|
+
result.push({
|
302
|
+
event: 'start',
|
303
|
+
offset: offset,
|
304
|
+
node: node.childNodes[i]
|
305
|
+
});
|
306
|
+
offset = arguments.callee(node.childNodes[i], offset)
|
307
|
+
result.push({
|
308
|
+
event: 'stop',
|
309
|
+
offset: offset,
|
310
|
+
node: node.childNodes[i]
|
311
|
+
});
|
312
|
+
}
|
313
|
+
}
|
314
|
+
return offset;
|
315
|
+
})(node, 0);
|
316
|
+
return result;
|
317
|
+
}
|
318
|
+
|
319
|
+
function mergeStreams(stream1, stream2, value) {
|
320
|
+
var processed = 0;
|
321
|
+
var result = '';
|
322
|
+
var nodeStack = [];
|
323
|
+
|
324
|
+
function selectStream() {
|
325
|
+
if (stream1.length && stream2.length) {
|
326
|
+
if (stream1[0].offset != stream2[0].offset)
|
327
|
+
return (stream1[0].offset < stream2[0].offset) ? stream1 : stream2;
|
328
|
+
else
|
329
|
+
return (stream1[0].event == 'start' && stream2[0].event == 'stop') ? stream2 : stream1;
|
330
|
+
} else {
|
331
|
+
return stream1.length ? stream1 : stream2;
|
332
|
+
}
|
333
|
+
}
|
334
|
+
|
335
|
+
function open(node) {
|
336
|
+
var result = '<' + node.nodeName.toLowerCase();
|
337
|
+
for (var i = 0; i < node.attributes.length; i++) {
|
338
|
+
result += ' ' + node.attributes[i].nodeName.toLowerCase() + '="' + escape(node.attributes[i].nodeValue) + '"';
|
339
|
+
}
|
340
|
+
return result + '>';
|
341
|
+
}
|
342
|
+
|
343
|
+
function close(node) {
|
344
|
+
return '</' + node.nodeName.toLowerCase() + '>';
|
345
|
+
}
|
346
|
+
|
347
|
+
while (stream1.length || stream2.length) {
|
348
|
+
var current = selectStream().splice(0, 1)[0];
|
349
|
+
result += escape(value.substr(processed, current.offset - processed));
|
350
|
+
processed = current.offset;
|
351
|
+
if ( current.event == 'start') {
|
352
|
+
result += open(current.node);
|
353
|
+
nodeStack.push(current.node);
|
354
|
+
} else if (current.event == 'stop') {
|
355
|
+
var i = nodeStack.length;
|
356
|
+
do {
|
357
|
+
i--;
|
358
|
+
var node = nodeStack[i];
|
359
|
+
result += close(node);
|
360
|
+
} while (node != current.node);
|
361
|
+
nodeStack.splice(i, 1);
|
362
|
+
while (i < nodeStack.length) {
|
363
|
+
result += open(nodeStack[i]);
|
364
|
+
i++;
|
365
|
+
}
|
366
|
+
}
|
367
|
+
}
|
368
|
+
result += value.substr(processed);
|
369
|
+
return result;
|
370
|
+
}
|
371
|
+
|
372
|
+
function highlightBlock(block, tabReplace) {
|
373
|
+
try {
|
374
|
+
var text = blockText(block);
|
375
|
+
var language = blockLanguage(block);
|
376
|
+
} catch (e) {
|
377
|
+
if (e == 'No highlight')
|
378
|
+
return;
|
379
|
+
}
|
380
|
+
|
381
|
+
if (language) {
|
382
|
+
var result = highlight(language, text).value;
|
383
|
+
} else {
|
384
|
+
var max_relevance = 0;
|
385
|
+
for (var key in selected_languages) {
|
386
|
+
if (!selected_languages.hasOwnProperty(key))
|
387
|
+
continue;
|
388
|
+
var lang_result = highlight(key, text);
|
389
|
+
var relevance = lang_result.keyword_count + lang_result.relevance;
|
390
|
+
if (relevance > max_relevance) {
|
391
|
+
max_relevance = relevance;
|
392
|
+
var result = lang_result.value;
|
393
|
+
language = key;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
if (result) {
|
399
|
+
if (tabReplace) {
|
400
|
+
result = result.replace(/^(\t+)/gm, function(match, p1, offset, s) {
|
401
|
+
return p1.replace(/\t/g, tabReplace);
|
402
|
+
})
|
403
|
+
}
|
404
|
+
var class_name = block.className;
|
405
|
+
if (!class_name.match(language)) {
|
406
|
+
class_name += ' ' + language;
|
407
|
+
}
|
408
|
+
var original = nodeStream(block);
|
409
|
+
if (original.length) {
|
410
|
+
var pre = document.createElement('pre');
|
411
|
+
pre.innerHTML = result;
|
412
|
+
result = mergeStreams(original, nodeStream(pre), text);
|
413
|
+
}
|
414
|
+
// See these 4 lines? This is IE's notion of "block.innerHTML = result". Love this browser :-/
|
415
|
+
var container = document.createElement('div');
|
416
|
+
container.innerHTML = '<pre><code class="' + class_name + '">' + result + '</code></pre>';
|
417
|
+
var environment = block.parentNode.parentNode;
|
418
|
+
environment.replaceChild(container.firstChild, block.parentNode);
|
419
|
+
}
|
420
|
+
}
|
421
|
+
|
422
|
+
function langRe(language, value, global) {
|
423
|
+
var mode = 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '');
|
424
|
+
return new RegExp(value, mode);
|
425
|
+
}
|
426
|
+
|
427
|
+
function compileModes() {
|
428
|
+
for (var i in LANGUAGES) {
|
429
|
+
if (!LANGUAGES.hasOwnProperty(i))
|
430
|
+
continue;
|
431
|
+
var language = LANGUAGES[i];
|
432
|
+
for (var j = 0; j < language.modes.length; j++) {
|
433
|
+
if (language.modes[j].begin)
|
434
|
+
language.modes[j].beginRe = langRe(language, '^' + language.modes[j].begin);
|
435
|
+
if (language.modes[j].end)
|
436
|
+
language.modes[j].endRe = langRe(language, '^' + language.modes[j].end);
|
437
|
+
if (language.modes[j].illegal)
|
438
|
+
language.modes[j].illegalRe = langRe(language, '^(?:' + language.modes[j].illegal + ')');
|
439
|
+
language.defaultMode.illegalRe = langRe(language, '^(?:' + language.defaultMode.illegal + ')');
|
440
|
+
if (language.modes[j].relevance == undefined) {
|
441
|
+
language.modes[j].relevance = 1;
|
442
|
+
}
|
443
|
+
}
|
444
|
+
}
|
445
|
+
}
|
446
|
+
|
447
|
+
function compileKeywords() {
|
448
|
+
|
449
|
+
function compileModeKeywords(mode) {
|
450
|
+
if (!mode.keywordGroups) {
|
451
|
+
for (var key in mode.keywords) {
|
452
|
+
if (!mode.keywords.hasOwnProperty(key))
|
453
|
+
continue;
|
454
|
+
if (mode.keywords[key] instanceof Object)
|
455
|
+
mode.keywordGroups = mode.keywords;
|
456
|
+
else
|
457
|
+
mode.keywordGroups = {'keyword': mode.keywords};
|
458
|
+
break;
|
459
|
+
}
|
460
|
+
}
|
461
|
+
}
|
462
|
+
|
463
|
+
for (var i in LANGUAGES) {
|
464
|
+
if (!LANGUAGES.hasOwnProperty(i))
|
465
|
+
continue;
|
466
|
+
var language = LANGUAGES[i];
|
467
|
+
compileModeKeywords(language.defaultMode);
|
468
|
+
for (var j = 0; j < language.modes.length; j++) {
|
469
|
+
compileModeKeywords(language.modes[j]);
|
470
|
+
}
|
471
|
+
}
|
472
|
+
}
|
473
|
+
|
474
|
+
function findCode(pre) {
|
475
|
+
for (var i = 0; i < pre.childNodes.length; i++) {
|
476
|
+
node = pre.childNodes[i];
|
477
|
+
if (node.nodeName == 'CODE')
|
478
|
+
return node;
|
479
|
+
if (!(node.nodeType == 3 && node.nodeValue.match(/\s+/)))
|
480
|
+
return null;
|
481
|
+
}
|
482
|
+
}
|
483
|
+
|
484
|
+
function initHighlighting() {
|
485
|
+
if (initHighlighting.called)
|
486
|
+
return;
|
487
|
+
initHighlighting.called = true;
|
488
|
+
compileModes();
|
489
|
+
compileKeywords();
|
490
|
+
if (arguments.length) {
|
491
|
+
for (var i = 0; i < arguments.length; i++) {
|
492
|
+
if (LANGUAGES[arguments[i]]) {
|
493
|
+
selected_languages[arguments[i]] = LANGUAGES[arguments[i]];
|
494
|
+
}
|
495
|
+
}
|
496
|
+
} else
|
497
|
+
selected_languages = LANGUAGES;
|
498
|
+
var pres = document.getElementsByTagName('pre');
|
499
|
+
for (var i = 0; i < pres.length; i++) {
|
500
|
+
var code = findCode(pres[i]);
|
501
|
+
if (code)
|
502
|
+
highlightBlock(code, hljs.tabReplace);
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
function initHighlightingOnLoad() {
|
507
|
+
var original_arguments = arguments;
|
508
|
+
var handler = function(){initHighlighting.apply(null, original_arguments)};
|
509
|
+
if (window.addEventListener) {
|
510
|
+
window.addEventListener('DOMContentLoaded', handler, false);
|
511
|
+
window.addEventListener('load', handler, false);
|
512
|
+
} else if (window.attachEvent)
|
513
|
+
window.attachEvent('onload', handler);
|
514
|
+
else
|
515
|
+
window.onload = handler;
|
516
|
+
}
|
517
|
+
|
518
|
+
this.LANGUAGES = LANGUAGES;
|
519
|
+
this.initHighlightingOnLoad = initHighlightingOnLoad;
|
520
|
+
this.highlightBlock = highlightBlock;
|
521
|
+
this.initHighlighting = initHighlighting;
|
522
|
+
|
523
|
+
// Common regexps
|
524
|
+
this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*';
|
525
|
+
this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*';
|
526
|
+
this.NUMBER_RE = '\\b\\d+(\\.\\d+)?';
|
527
|
+
this.C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)';
|
528
|
+
this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
|
529
|
+
|
530
|
+
// Common modes
|
531
|
+
this.APOS_STRING_MODE = {
|
532
|
+
className: 'string',
|
533
|
+
begin: '\'', end: '\'',
|
534
|
+
illegal: '\\n',
|
535
|
+
contains: ['escape'],
|
536
|
+
relevance: 0
|
537
|
+
};
|
538
|
+
this.QUOTE_STRING_MODE = {
|
539
|
+
className: 'string',
|
540
|
+
begin: '"', end: '"',
|
541
|
+
illegal: '\\n',
|
542
|
+
contains: ['escape'],
|
543
|
+
relevance: 0
|
544
|
+
};
|
545
|
+
this.BACKSLASH_ESCAPE = {
|
546
|
+
className: 'escape',
|
547
|
+
begin: '\\\\.', end: '^', noMarkup: true,
|
548
|
+
relevance: 0
|
549
|
+
};
|
550
|
+
this.C_LINE_COMMENT_MODE = {
|
551
|
+
className: 'comment',
|
552
|
+
begin: '//', end: '$',
|
553
|
+
relevance: 0
|
554
|
+
};
|
555
|
+
this.C_BLOCK_COMMENT_MODE = {
|
556
|
+
className: 'comment',
|
557
|
+
begin: '/\\*', end: '\\*/'
|
558
|
+
};
|
559
|
+
this.HASH_COMMENT_MODE = {
|
560
|
+
className: 'comment',
|
561
|
+
begin: '#', end: '$'
|
562
|
+
};
|
563
|
+
this.C_NUMBER_MODE = {
|
564
|
+
className: 'number',
|
565
|
+
begin: this.C_NUMBER_RE, end: '^',
|
566
|
+
relevance: 0
|
567
|
+
};
|
568
|
+
}();
|
569
|
+
|
570
|
+
var initHighlightingOnLoad = hljs.initHighlightingOnLoad;
|