coderay 0.7.4.215 → 0.8.260
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +421 -257
- data/README +24 -13
- data/bin/coderay +9 -4
- data/lib/coderay.rb +19 -17
- data/lib/coderay/duo.rb +67 -9
- data/lib/coderay/encoder.rb +18 -9
- data/lib/coderay/encoders/_map.rb +2 -1
- data/lib/coderay/encoders/debug.rb +14 -11
- data/lib/coderay/encoders/html.rb +44 -17
- data/lib/coderay/encoders/html/css.rb +13 -8
- data/lib/coderay/encoders/html/numerization.rb +8 -6
- data/lib/coderay/encoders/html/output.rb +3 -1
- data/lib/coderay/encoders/statistic.rb +2 -6
- data/lib/coderay/encoders/text.rb +2 -3
- data/lib/coderay/encoders/tokens.rb +3 -3
- data/lib/coderay/encoders/xml.rb +1 -2
- data/lib/coderay/for_redcloth.rb +72 -0
- data/lib/coderay/helpers/file_type.rb +38 -9
- data/lib/coderay/helpers/gzip_simple.rb +1 -0
- data/lib/coderay/helpers/plugin.rb +15 -8
- data/lib/coderay/helpers/word_list.rb +4 -0
- data/lib/coderay/scanner.rb +30 -13
- data/lib/coderay/scanners/_map.rb +1 -1
- data/lib/coderay/scanners/c.rb +3 -1
- data/lib/coderay/scanners/css.rb +181 -0
- data/lib/coderay/scanners/debug.rb +1 -0
- data/lib/coderay/scanners/delphi.rb +1 -0
- data/lib/coderay/scanners/diff.rb +104 -0
- data/lib/coderay/scanners/java.rb +179 -0
- data/lib/coderay/scanners/java/builtin_types.rb +419 -0
- data/lib/coderay/scanners/java_script.rb +187 -0
- data/lib/coderay/scanners/json.rb +106 -0
- data/lib/coderay/scanners/nitro_xhtml.rb +5 -4
- data/lib/coderay/scanners/plaintext.rb +2 -0
- data/lib/coderay/scanners/rhtml.rb +2 -2
- data/lib/coderay/scanners/ruby.rb +64 -50
- data/lib/coderay/scanners/ruby/patterns.rb +15 -19
- data/lib/coderay/scanners/scheme.rb +142 -0
- data/lib/coderay/scanners/sql.Keith.rb +143 -0
- data/lib/coderay/scanners/sql.rb +154 -0
- data/lib/coderay/scanners/xml.rb +1 -0
- data/lib/coderay/styles/cycnus.rb +30 -9
- data/lib/coderay/styles/murphy.rb +15 -2
- data/lib/coderay/{encoders/html/classes.rb → token_classes.rb} +14 -9
- data/lib/coderay/tokens.rb +33 -14
- data/lib/term/ansicolor.rb +220 -0
- metadata +62 -44
@@ -34,9 +34,12 @@ module Encoders
|
|
34
34
|
private
|
35
35
|
|
36
36
|
CSS_CLASS_PATTERN = /
|
37
|
-
(
|
38
|
-
|
39
|
-
|
37
|
+
( # $1 = selectors
|
38
|
+
(?:
|
39
|
+
(?: \s* \. [-\w]+ )+
|
40
|
+
\s* ,?
|
41
|
+
)+
|
42
|
+
)
|
40
43
|
\s* \{ \s*
|
41
44
|
( [^\}]+ )? # $2 = style
|
42
45
|
\s* \} \s*
|
@@ -44,12 +47,14 @@ module Encoders
|
|
44
47
|
( . ) # $3 = error
|
45
48
|
/mx
|
46
49
|
def parse stylesheet
|
47
|
-
stylesheet.scan CSS_CLASS_PATTERN do |
|
50
|
+
stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
|
48
51
|
raise "CSS parse error: '#{error.inspect}' not recognized" if error
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
for selector in selectors.split(',')
|
53
|
+
classes = selector.scan(/[-\w]+/)
|
54
|
+
cl = classes.pop
|
55
|
+
@classes[cl] ||= Hash.new
|
56
|
+
@classes[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
@@ -51,12 +51,12 @@ module Encoders
|
|
51
51
|
case mode
|
52
52
|
when :inline
|
53
53
|
max_width = (start + line_count).to_s.size
|
54
|
-
|
54
|
+
line_number = start
|
55
55
|
gsub!(/^/) do
|
56
|
-
|
57
|
-
indent = ' ' * (max_width -
|
58
|
-
res = "<span class=\"no\">#{indent}#{
|
59
|
-
|
56
|
+
line_number_text = bolding.call line_number
|
57
|
+
indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
|
58
|
+
res = "<span class=\"no\">#{indent}#{line_number_text}</span> "
|
59
|
+
line_number += 1
|
60
60
|
res
|
61
61
|
end
|
62
62
|
|
@@ -71,6 +71,7 @@ module Encoders
|
|
71
71
|
line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
|
72
72
|
|
73
73
|
line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers)
|
74
|
+
gsub!(/<\/div>\n/) { '</div>' }
|
74
75
|
gsub!(/\n/) { "<tt>\n</tt>" }
|
75
76
|
wrap_in! line_numbers_table_tpl
|
76
77
|
@wrapped_in = :div
|
@@ -90,8 +91,9 @@ module Encoders
|
|
90
91
|
end
|
91
92
|
close = '</span>' * opened_tags.size
|
92
93
|
|
93
|
-
"<li>#{open}#{line}#{close}</li
|
94
|
+
"<li>#{open}#{line}#{close}</li>\n"
|
94
95
|
end
|
96
|
+
chomp!("\n")
|
95
97
|
wrap_in! LIST
|
96
98
|
@wrapped_in = :div
|
97
99
|
|
@@ -28,17 +28,13 @@ module Encoders
|
|
28
28
|
@type_stats[kind].count += 1
|
29
29
|
@type_stats[kind].size += text.size
|
30
30
|
@type_stats['TOTAL'].size += text.size
|
31
|
+
@type_stats['TOTAL'].count += 1
|
31
32
|
end
|
32
33
|
|
33
34
|
# TODO Hierarchy handling
|
34
35
|
def block_token action, kind
|
35
|
-
#@content_type = kind
|
36
|
-
@type_stats['open/close'].count += 1
|
37
|
-
end
|
38
|
-
|
39
|
-
def token text, kind
|
40
|
-
super
|
41
36
|
@type_stats['TOTAL'].count += 1
|
37
|
+
@type_stats['open/close'].count += 1
|
42
38
|
end
|
43
39
|
|
44
40
|
STATS = <<-STATS
|
@@ -14,13 +14,12 @@ module Encoders
|
|
14
14
|
|
15
15
|
protected
|
16
16
|
def setup options
|
17
|
-
|
17
|
+
@out = ''
|
18
18
|
@sep = options[:separator]
|
19
19
|
end
|
20
20
|
|
21
21
|
def token text, kind
|
22
|
-
|
23
|
-
@out << text + @sep
|
22
|
+
@out << text + @sep if text.is_a? ::String
|
24
23
|
end
|
25
24
|
|
26
25
|
def finish options
|
data/lib/coderay/encoders/xml.rb
CHANGED
@@ -22,7 +22,6 @@ module Encoders
|
|
22
22
|
protected
|
23
23
|
|
24
24
|
def setup options
|
25
|
-
@out = ''
|
26
25
|
@doc = REXML::Document.new
|
27
26
|
@doc << REXML::XMLDecl.new
|
28
27
|
@tab_width = options[:tab_width]
|
@@ -33,7 +32,7 @@ module Encoders
|
|
33
32
|
@doc.write @out, options[:pretty], options[:transitive], true
|
34
33
|
@out
|
35
34
|
end
|
36
|
-
|
35
|
+
|
37
36
|
def text_token text, kind
|
38
37
|
if kind == :space
|
39
38
|
token = @node
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module CodeRay # :nodoc:
|
2
|
+
|
3
|
+
# A little hack to enable CodeRay highlighting in RedCloth.
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# require 'coderay'
|
7
|
+
# require 'coderay/for_redcloth'
|
8
|
+
# RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
|
9
|
+
#
|
10
|
+
# Make sure you have RedCloth 4.0.3 activated, for example by calling
|
11
|
+
# require 'rubygems'
|
12
|
+
# before RedCloth is loaded and before calling CodeRay.for_redcloth.
|
13
|
+
module ForRedCloth
|
14
|
+
|
15
|
+
def self.install
|
16
|
+
gem 'RedCloth', '>= 4.0.3' rescue nil
|
17
|
+
require 'redcloth'
|
18
|
+
raise 'CodeRay.for_redcloth needs RedCloth 4.0.3 or later.' unless RedCloth::VERSION.to_s >= '4.0.3'
|
19
|
+
RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc
|
20
|
+
RedCloth::Formatters::HTML.module_eval do
|
21
|
+
def unescape(html)
|
22
|
+
replacements = {
|
23
|
+
'&' => '&',
|
24
|
+
'"' => '"',
|
25
|
+
'>' => '>',
|
26
|
+
'<' => '<',
|
27
|
+
}
|
28
|
+
html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] }
|
29
|
+
end
|
30
|
+
undef_method :code, :bc_open, :bc_close, :escape_pre
|
31
|
+
def code(opts) # :nodoc:
|
32
|
+
opts[:block] = true
|
33
|
+
if opts[:lang] && !filter_coderay
|
34
|
+
require 'coderay'
|
35
|
+
@in_bc ||= nil
|
36
|
+
format = @in_bc ? :div : :span
|
37
|
+
highlighted_code = CodeRay.encode opts[:text], opts[:lang], format, :stream => true
|
38
|
+
highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) }
|
39
|
+
highlighted_code = unescape(highlighted_code) unless @in_bc
|
40
|
+
highlighted_code
|
41
|
+
else
|
42
|
+
"<code#{pba(opts)}>#{opts[:text]}</code>"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
def bc_open(opts) # :nodoc:
|
46
|
+
opts[:block] = true
|
47
|
+
@in_bc = opts
|
48
|
+
opts[:lang] ? '' : "<pre#{pba(opts)}>"
|
49
|
+
end
|
50
|
+
def bc_close(opts) # :nodoc:
|
51
|
+
@in_bc = nil
|
52
|
+
opts[:lang] ? '' : "</pre>\n"
|
53
|
+
end
|
54
|
+
def escape_pre(text)
|
55
|
+
if @in_bc ||= nil
|
56
|
+
text
|
57
|
+
else
|
58
|
+
html_esc(text, :html_escape_preformatted)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module TextileDoc # :nodoc:
|
65
|
+
attr_accessor :filter_coderay
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
CodeRay::ForRedCloth.install
|
@@ -1,3 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
module CodeRay
|
3
|
+
|
1
4
|
# = FileType
|
2
5
|
#
|
3
6
|
# A simple filetype recognizer.
|
@@ -31,12 +34,12 @@ module FileType
|
|
31
34
|
# That means you can get filetypes from files that don't exist.
|
32
35
|
def [] filename, read_shebang = false
|
33
36
|
name = File.basename filename
|
34
|
-
ext = File.extname
|
35
|
-
|
37
|
+
ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot
|
38
|
+
ext2 = filename[/\.(.*)/, 1] # from first dot
|
36
39
|
|
37
40
|
type =
|
38
|
-
TypeFromExt[ext] ||
|
39
41
|
TypeFromExt[ext.downcase] ||
|
42
|
+
(TypeFromExt[ext2.downcase] if ext2) ||
|
40
43
|
TypeFromName[name] ||
|
41
44
|
TypeFromName[name.downcase]
|
42
45
|
type ||= shebang(filename) if read_shebang
|
@@ -47,8 +50,11 @@ module FileType
|
|
47
50
|
def shebang filename
|
48
51
|
begin
|
49
52
|
File.open filename, 'r' do |f|
|
50
|
-
first_line = f.gets
|
51
|
-
|
53
|
+
if first_line = f.gets
|
54
|
+
if type = first_line[TypeFromShebang]
|
55
|
+
type.to_sym
|
56
|
+
end
|
57
|
+
end
|
52
58
|
end
|
53
59
|
rescue IOError
|
54
60
|
nil
|
@@ -78,15 +84,20 @@ module FileType
|
|
78
84
|
'rb' => :ruby,
|
79
85
|
'rbw' => :ruby,
|
80
86
|
'rake' => :ruby,
|
87
|
+
'mab' => :ruby,
|
81
88
|
'cpp' => :c,
|
82
89
|
'c' => :c,
|
83
90
|
'h' => :c,
|
91
|
+
'js' => :java_script,
|
84
92
|
'xml' => :xml,
|
85
93
|
'htm' => :html,
|
86
94
|
'html' => :html,
|
87
95
|
'xhtml' => :xhtml,
|
88
96
|
'raydebug' => :debug,
|
89
97
|
'rhtml' => :rhtml,
|
98
|
+
'html.erb' => :rhtml,
|
99
|
+
'ss' => :scheme,
|
100
|
+
'sch' => :scheme,
|
90
101
|
'yaml' => :yaml,
|
91
102
|
'yml' => :yaml,
|
92
103
|
}
|
@@ -100,17 +111,20 @@ module FileType
|
|
100
111
|
|
101
112
|
end
|
102
113
|
|
114
|
+
end
|
115
|
+
|
103
116
|
if $0 == __FILE__
|
104
117
|
$VERBOSE = true
|
105
|
-
eval DATA.read, nil, $0, __LINE__+4
|
118
|
+
eval DATA.read, nil, $0, __LINE__ + 4
|
106
119
|
end
|
107
120
|
|
108
121
|
__END__
|
109
|
-
|
110
122
|
require 'test/unit'
|
111
123
|
|
112
124
|
class TC_FileType < Test::Unit::TestCase
|
113
|
-
|
125
|
+
|
126
|
+
include CodeRay
|
127
|
+
|
114
128
|
def test_fetch
|
115
129
|
assert_raise FileType::UnknownFileType do
|
116
130
|
FileType.fetch ''
|
@@ -161,6 +175,7 @@ class TC_FileType < Test::Unit::TestCase
|
|
161
175
|
assert_equal :xhtml, FileType['test.xhtml']
|
162
176
|
assert_equal :xhtml, FileType['test.html.xhtml']
|
163
177
|
assert_equal :rhtml, FileType['_form.rhtml']
|
178
|
+
assert_equal :rhtml, FileType['_form.html.erb']
|
164
179
|
end
|
165
180
|
|
166
181
|
def test_yaml
|
@@ -170,7 +185,7 @@ class TC_FileType < Test::Unit::TestCase
|
|
170
185
|
assert_not_equal :yaml, FileType['YAML']
|
171
186
|
end
|
172
187
|
|
173
|
-
def
|
188
|
+
def test_no_shebang
|
174
189
|
dir = './test'
|
175
190
|
if File.directory? dir
|
176
191
|
Dir.chdir dir do
|
@@ -178,5 +193,19 @@ class TC_FileType < Test::Unit::TestCase
|
|
178
193
|
end
|
179
194
|
end
|
180
195
|
end
|
196
|
+
|
197
|
+
def test_shebang_empty_file
|
198
|
+
require 'tmpdir'
|
199
|
+
tmpfile = File.join(Dir.tmpdir, 'bla')
|
200
|
+
File.open(tmpfile, 'w') { } # touch
|
201
|
+
assert_equal nil, FileType[tmpfile]
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_shebang
|
205
|
+
require 'tmpdir'
|
206
|
+
tmpfile = File.join(Dir.tmpdir, 'bla')
|
207
|
+
File.open(tmpfile, 'w') { |f| f.puts '#!/usr/bin/env ruby' }
|
208
|
+
assert_equal :ruby, FileType[tmpfile, true]
|
209
|
+
end
|
181
210
|
|
182
211
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
module CodeRay
|
2
|
+
|
1
3
|
# = PluginHost
|
2
4
|
#
|
3
|
-
# $Id: plugin.rb
|
5
|
+
# $Id: plugin.rb 255 2008-09-21 16:25:44Z murphy $
|
4
6
|
#
|
5
7
|
# A simple subclass plugin system.
|
6
8
|
#
|
@@ -20,7 +22,7 @@
|
|
20
22
|
#
|
21
23
|
# Generators[:fancy] #-> FancyGenerator
|
22
24
|
# # or
|
23
|
-
# require_plugin 'Generators/fancy'
|
25
|
+
# CodeRay.require_plugin 'Generators/fancy'
|
24
26
|
module PluginHost
|
25
27
|
|
26
28
|
# Raised if Encoders::[] fails because:
|
@@ -133,9 +135,13 @@ module PluginHost
|
|
133
135
|
# map :navy => :dark_blue
|
134
136
|
# default :gray
|
135
137
|
# end
|
136
|
-
def default id
|
137
|
-
|
138
|
-
|
138
|
+
def default id = nil
|
139
|
+
if id
|
140
|
+
id = validate_id id
|
141
|
+
plugin_hash[nil] = id
|
142
|
+
else
|
143
|
+
plugin_hash[nil]
|
144
|
+
end
|
139
145
|
end
|
140
146
|
|
141
147
|
# Every plugin must register itself for one or more
|
@@ -310,17 +316,18 @@ module Plugin
|
|
310
316
|
|
311
317
|
end
|
312
318
|
|
313
|
-
|
314
319
|
# Convenience method for plugin loading.
|
315
320
|
# The syntax used is:
|
316
321
|
#
|
317
|
-
# require_plugin '<Host ID>/<Plugin ID>'
|
322
|
+
# CodeRay.require_plugin '<Host ID>/<Plugin ID>'
|
318
323
|
#
|
319
324
|
# Returns the loaded plugin.
|
320
|
-
def require_plugin path
|
325
|
+
def self.require_plugin path
|
321
326
|
host_id, plugin_id = path.split '/', 2
|
322
327
|
host = PluginHost.host_by_id(host_id)
|
323
328
|
raise PluginHost::HostNotFound,
|
324
329
|
"No host for #{host_id.inspect} found." unless host
|
325
330
|
host.load plugin_id
|
326
331
|
end
|
332
|
+
|
333
|
+
end
|
data/lib/coderay/scanner.rb
CHANGED
@@ -4,7 +4,7 @@ module CodeRay
|
|
4
4
|
|
5
5
|
# = Scanners
|
6
6
|
#
|
7
|
-
# $Id: scanner.rb
|
7
|
+
# $Id: scanner.rb 253 2008-09-16 22:07:44Z murphy $
|
8
8
|
#
|
9
9
|
# This module holds the Scanner class and its subclasses.
|
10
10
|
# For example, the Ruby scanner is named CodeRay::Scanners::Ruby
|
@@ -66,7 +66,17 @@ module CodeRay
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def normify code
|
69
|
-
code = code.to_s
|
69
|
+
code = code.to_s
|
70
|
+
code.force_encoding 'binary' if code.respond_to? :force_encoding
|
71
|
+
code.to_unix
|
72
|
+
end
|
73
|
+
|
74
|
+
def file_extension extension = nil
|
75
|
+
if extension
|
76
|
+
@file_extension = extension.to_s
|
77
|
+
else
|
78
|
+
@file_extension ||= plugin_id.to_s
|
79
|
+
end
|
70
80
|
end
|
71
81
|
|
72
82
|
end
|
@@ -117,9 +127,6 @@ module CodeRay
|
|
117
127
|
setup
|
118
128
|
end
|
119
129
|
|
120
|
-
# More mnemonic accessor name for the input string.
|
121
|
-
alias code string
|
122
|
-
|
123
130
|
def reset
|
124
131
|
super
|
125
132
|
reset_instance
|
@@ -131,6 +138,10 @@ module CodeRay
|
|
131
138
|
reset_instance
|
132
139
|
end
|
133
140
|
|
141
|
+
# More mnemonic accessor name for the input string.
|
142
|
+
alias code string
|
143
|
+
alias code= string=
|
144
|
+
|
134
145
|
# Scans the code and returns all tokens in a Tokens object.
|
135
146
|
def tokenize new_string=nil, options = {}
|
136
147
|
options = @options.merge(options)
|
@@ -148,6 +159,11 @@ module CodeRay
|
|
148
159
|
def tokens
|
149
160
|
@cached_tokens ||= tokenize
|
150
161
|
end
|
162
|
+
|
163
|
+
# Whether the scanner is in streaming mode.
|
164
|
+
def streaming?
|
165
|
+
!!@options[:stream]
|
166
|
+
end
|
151
167
|
|
152
168
|
# Traverses the tokens.
|
153
169
|
def each &block
|
@@ -195,7 +211,7 @@ module CodeRay
|
|
195
211
|
raise ScanError, <<-EOE % [
|
196
212
|
|
197
213
|
|
198
|
-
***ERROR in %s: %s
|
214
|
+
***ERROR in %s: %s (after %d tokens)
|
199
215
|
|
200
216
|
tokens:
|
201
217
|
%s
|
@@ -211,13 +227,14 @@ surrounding code:
|
|
211
227
|
***ERROR***
|
212
228
|
|
213
229
|
EOE
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
230
|
+
File.basename(caller[0]),
|
231
|
+
msg,
|
232
|
+
tokens.size,
|
233
|
+
tokens.last(10).map { |t| t.inspect }.join("\n"),
|
234
|
+
line, pos,
|
235
|
+
matched, state, bol?, eos?,
|
236
|
+
string[pos-ambit,ambit],
|
237
|
+
string[pos,ambit],
|
221
238
|
]
|
222
239
|
end
|
223
240
|
|