coderay 0.7.4.215 → 0.8.260
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/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
|
|