coderay 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +35 -0
- data/lib/README +7 -3
- data/lib/coderay.rb +5 -3
- data/lib/coderay/encoders/_map.rb +1 -0
- data/lib/coderay/encoders/html.rb +2 -2
- data/lib/coderay/encoders/html/css.rb +1 -1
- data/lib/coderay/encoders/lines_of_code.rb +1 -1
- data/lib/coderay/encoders/term.rb +28 -7
- data/lib/coderay/for_redcloth.rb +12 -2
- data/lib/coderay/helpers/plugin.rb +1 -1
- data/lib/coderay/scanner.rb +4 -1
- data/lib/coderay/scanners/c.rb +1 -1
- data/lib/coderay/scanners/cpp.rb +1 -1
- data/lib/coderay/scanners/css.rb +1 -1
- data/lib/coderay/scanners/debug.rb +3 -3
- data/lib/coderay/scanners/delphi.rb +1 -1
- data/lib/coderay/scanners/diff.rb +1 -1
- data/lib/coderay/scanners/groovy.rb +2 -1
- data/lib/coderay/scanners/html.rb +1 -1
- data/lib/coderay/scanners/java.rb +1 -1
- data/lib/coderay/scanners/java_script.rb +1 -1
- data/lib/coderay/scanners/json.rb +1 -1
- data/lib/coderay/scanners/php.rb +2 -1
- data/lib/coderay/scanners/python.rb +1 -1
- data/lib/coderay/scanners/ruby.rb +17 -8
- data/lib/coderay/scanners/scheme.rb +1 -1
- data/lib/coderay/scanners/yaml.rb +6 -10
- data/lib/coderay/tokens.rb +0 -3
- data/test/functional/basic.rb +118 -0
- data/test/functional/for_redcloth.rb +77 -0
- data/test/functional/load_plugin_scanner.rb +11 -0
- data/test/functional/suite.rb +12 -0
- data/test/functional/vhdl.rb +126 -0
- data/test/functional/word_list.rb +79 -0
- metadata +32 -14
- data/lib/term/ansicolor.rb +0 -220
@@ -284,14 +284,23 @@ module Scanners
|
|
284
284
|
kind = :class_variable
|
285
285
|
|
286
286
|
else
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
287
|
+
if !unicode
|
288
|
+
# check for unicode
|
289
|
+
debug, $DEBUG = $DEBUG, false
|
290
|
+
begin
|
291
|
+
if check(/./mu).size > 1
|
292
|
+
# seems like we should try again with unicode
|
293
|
+
unicode = true
|
294
|
+
end
|
295
|
+
rescue
|
296
|
+
# bad unicode char; use getch
|
297
|
+
ensure
|
298
|
+
$DEBUG = debug
|
299
|
+
end
|
300
|
+
next if unicode
|
294
301
|
end
|
302
|
+
kind = :error
|
303
|
+
match = getch
|
295
304
|
|
296
305
|
end
|
297
306
|
|
@@ -370,7 +379,7 @@ module Scanners
|
|
370
379
|
last_token_dot = last_token_dot == :set
|
371
380
|
end
|
372
381
|
|
373
|
-
if $
|
382
|
+
if $CODERAY_DEBUG and not kind
|
374
383
|
raise_inspect 'Error token %p in line %d' %
|
375
384
|
[[match, kind], line], tokens, state
|
376
385
|
end
|
@@ -21,14 +21,7 @@ module Scanners
|
|
21
21
|
|
22
22
|
kind = nil
|
23
23
|
match = nil
|
24
|
-
|
25
|
-
if bol?
|
26
|
-
key_indent = nil
|
27
|
-
if $DEBUG
|
28
|
-
indent = check(/ +/) ? matched.size : 0
|
29
|
-
tokens << [indent.to_s, :debug]
|
30
|
-
end
|
31
|
-
end
|
24
|
+
key_indent = nil if bol?
|
32
25
|
|
33
26
|
if match = scan(/ +[\t ]*/)
|
34
27
|
kind = :space
|
@@ -128,8 +121,11 @@ module Scanners
|
|
128
121
|
|
129
122
|
match ||= matched
|
130
123
|
|
131
|
-
|
132
|
-
|
124
|
+
if $CODERAY_DEBUG and not kind
|
125
|
+
raise_inspect 'Error token %p in line %d' %
|
126
|
+
[[match, kind], line], tokens, state
|
127
|
+
end
|
128
|
+
raise_inspect 'Empty token', tokens, state unless match
|
133
129
|
|
134
130
|
tokens << [match, kind]
|
135
131
|
|
data/lib/coderay/tokens.rb
CHANGED
@@ -129,7 +129,6 @@ module CodeRay
|
|
129
129
|
# for example, consecutive //-comment lines could already be
|
130
130
|
# joined in one comment token by the Scanner.
|
131
131
|
def optimize
|
132
|
-
print ' Tokens#optimize: before: %d - ' % size if $DEBUG
|
133
132
|
last_kind = last_text = nil
|
134
133
|
new = self.class.new
|
135
134
|
for text, kind in self
|
@@ -148,8 +147,6 @@ module CodeRay
|
|
148
147
|
end
|
149
148
|
end
|
150
149
|
new << [last_text, last_kind] if last_kind
|
151
|
-
print 'after: %d (%d saved = %2.0f%%)' %
|
152
|
-
[new.size, size - new.size, 1.0 - (new.size.to_f / size)] if $DEBUG
|
153
150
|
new
|
154
151
|
end
|
155
152
|
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'coderay'
|
3
|
+
|
4
|
+
class BasicTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_version
|
7
|
+
assert_nothing_raised do
|
8
|
+
assert_match(/\A\d\.\d\.\d\z/, CodeRay::VERSION)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RUBY_TEST_CODE = 'puts "Hello, World!"'
|
13
|
+
|
14
|
+
RUBY_TEST_TOKENS = [
|
15
|
+
['puts', :ident],
|
16
|
+
[' ', :space],
|
17
|
+
[:open, :string],
|
18
|
+
['"', :delimiter],
|
19
|
+
['Hello, World!', :content],
|
20
|
+
['"', :delimiter],
|
21
|
+
[:close, :string]
|
22
|
+
]
|
23
|
+
def test_simple_scan
|
24
|
+
assert_nothing_raised do
|
25
|
+
assert_equal RUBY_TEST_TOKENS, CodeRay.scan(RUBY_TEST_CODE, :ruby).to_ary
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
RUBY_TEST_HTML = 'puts <span class="s"><span class="dl">"</span>' +
|
30
|
+
'<span class="k">Hello, World!</span><span class="dl">"</span></span>'
|
31
|
+
def test_simple_highlight
|
32
|
+
assert_nothing_raised do
|
33
|
+
assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_duo
|
38
|
+
assert_equal(RUBY_TEST_CODE,
|
39
|
+
CodeRay::Duo[:plain, :plain].highlight(RUBY_TEST_CODE))
|
40
|
+
assert_equal(RUBY_TEST_CODE,
|
41
|
+
CodeRay::Duo[:plain => :plain].highlight(RUBY_TEST_CODE))
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_duo_stream
|
45
|
+
assert_equal(RUBY_TEST_CODE,
|
46
|
+
CodeRay::Duo[:plain, :plain].highlight(RUBY_TEST_CODE, :stream => true))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_comment_filter
|
50
|
+
assert_equal <<-EXPECTED, CodeRay.scan(<<-INPUT, :ruby).comment_filter.text
|
51
|
+
#!/usr/bin/env ruby
|
52
|
+
|
53
|
+
code
|
54
|
+
|
55
|
+
more code
|
56
|
+
EXPECTED
|
57
|
+
#!/usr/bin/env ruby
|
58
|
+
=begin
|
59
|
+
A multi-line comment.
|
60
|
+
=end
|
61
|
+
code
|
62
|
+
# A single-line comment.
|
63
|
+
more code # and another comment, in-line.
|
64
|
+
INPUT
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_lines_of_code
|
68
|
+
assert_equal 2, CodeRay.scan(<<-INPUT, :ruby).lines_of_code
|
69
|
+
#!/usr/bin/env ruby
|
70
|
+
=begin
|
71
|
+
A multi-line comment.
|
72
|
+
=end
|
73
|
+
code
|
74
|
+
# A single-line comment.
|
75
|
+
more code # and another comment, in-line.
|
76
|
+
INPUT
|
77
|
+
rHTML = <<-RHTML
|
78
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
79
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
80
|
+
|
81
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
82
|
+
<head>
|
83
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
84
|
+
<title><%= controller.controller_name.titleize %>: <%= controller.action_name %></title>
|
85
|
+
<%= stylesheet_link_tag 'scaffold' %>
|
86
|
+
</head>
|
87
|
+
<body>
|
88
|
+
|
89
|
+
<p style="color: green"><%= flash[:notice] %></p>
|
90
|
+
|
91
|
+
<div id="main">
|
92
|
+
<%= yield %>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
</body>
|
96
|
+
</html>
|
97
|
+
RHTML
|
98
|
+
assert_equal 0, CodeRay.scan(rHTML, :html).lines_of_code
|
99
|
+
assert_equal 0, CodeRay.scan(rHTML, :php).lines_of_code
|
100
|
+
assert_equal 0, CodeRay.scan(rHTML, :yaml).lines_of_code
|
101
|
+
assert_equal 4, CodeRay.scan(rHTML, :rhtml).lines_of_code
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_rubygems_not_loaded
|
105
|
+
assert_equal nil, defined? Gem
|
106
|
+
end if ENV['check_rubygems'] && RUBY_VERSION < '1.9'
|
107
|
+
|
108
|
+
def test_list_of_encoders
|
109
|
+
assert_kind_of(Array, CodeRay::Encoders.list)
|
110
|
+
assert CodeRay::Encoders.list.include?('count')
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_list_of_scanners
|
114
|
+
assert_kind_of(Array, CodeRay::Scanners.list)
|
115
|
+
assert CodeRay::Scanners.list.include?('plaintext')
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
$: << 'lib'
|
3
|
+
require 'coderay'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rubygems' unless defined? Gem
|
7
|
+
gem 'RedCloth', '>= 4.0.3' rescue nil
|
8
|
+
require 'redcloth'
|
9
|
+
rescue LoadError
|
10
|
+
warn 'RedCloth not found - skipping for_redcloth tests.'
|
11
|
+
end
|
12
|
+
|
13
|
+
class BasicTest < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_for_redcloth
|
16
|
+
require 'coderay/for_redcloth'
|
17
|
+
assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">puts <span style=\"background-color:#fff0f0;color:#D20\"><span style=\"color:#710\">"</span><span style=\"\">Hello, World!</span><span style=\"color:#710\">"</span></span></span></p>",
|
18
|
+
RedCloth.new('@[ruby]puts "Hello, World!"@').to_html
|
19
|
+
assert_equal <<-BLOCKCODE.chomp,
|
20
|
+
<div lang="ruby" class="CodeRay">
|
21
|
+
<div class="code"><pre>puts <span style="background-color:#fff0f0;color:#D20"><span style="color:#710">"</span><span style="">Hello, World!</span><span style="color:#710">"</span></span></pre></div>
|
22
|
+
</div>
|
23
|
+
BLOCKCODE
|
24
|
+
RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_for_redcloth_no_lang
|
28
|
+
require 'coderay/for_redcloth'
|
29
|
+
assert_equal "<p><code>puts \"Hello, World!\"</code></p>",
|
30
|
+
RedCloth.new('@puts "Hello, World!"@').to_html
|
31
|
+
assert_equal <<-BLOCKCODE.chomp,
|
32
|
+
<pre><code>puts \"Hello, World!\"</code></pre>
|
33
|
+
BLOCKCODE
|
34
|
+
RedCloth.new('bc. puts "Hello, World!"').to_html
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_for_redcloth_style
|
38
|
+
require 'coderay/for_redcloth'
|
39
|
+
assert_equal <<-BLOCKCODE.chomp,
|
40
|
+
<pre style=\"color: red;\"><code style=\"color: red;\">puts \"Hello, World!\"</code></pre>
|
41
|
+
BLOCKCODE
|
42
|
+
RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_for_redcloth_escapes
|
46
|
+
require 'coderay/for_redcloth'
|
47
|
+
assert_equal '<p><span lang="ruby" class="CodeRay">></span></p>',
|
48
|
+
RedCloth.new('@[ruby]>@').to_html
|
49
|
+
assert_equal <<-BLOCKCODE.chomp,
|
50
|
+
<div lang="ruby" class="CodeRay">
|
51
|
+
<div class="code"><pre>&</pre></div>
|
52
|
+
</div>
|
53
|
+
BLOCKCODE
|
54
|
+
RedCloth.new('bc[ruby]. &').to_html
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_for_redcloth_escapes2
|
58
|
+
require 'coderay/for_redcloth'
|
59
|
+
assert_equal "<p><span lang=\"c\" class=\"CodeRay\"><span style=\"color:#579\">#include</span> <span style=\"color:#B44;font-weight:bold\"><test.h></span></span></p>",
|
60
|
+
RedCloth.new('@[c]#include <test.h>@').to_html
|
61
|
+
end
|
62
|
+
|
63
|
+
# See http://jgarber.lighthouseapp.com/projects/13054/tickets/124-code-markup-does-not-allow-brackets.
|
64
|
+
def test_for_redcloth_false_positive
|
65
|
+
require 'coderay/for_redcloth'
|
66
|
+
assert_equal '<p><code>[project]_dff.skjd</code></p>',
|
67
|
+
RedCloth.new('@[project]_dff.skjd@').to_html
|
68
|
+
# false positive, but expected behavior / known issue
|
69
|
+
assert_equal "<p><span lang=\"ruby\" class=\"CodeRay\">_dff.skjd</span></p>",
|
70
|
+
RedCloth.new('@[ruby]_dff.skjd@').to_html
|
71
|
+
assert_equal <<-BLOCKCODE.chomp,
|
72
|
+
<pre><code>[project]_dff.skjd</code></pre>
|
73
|
+
BLOCKCODE
|
74
|
+
RedCloth.new('bc. [project]_dff.skjd').to_html
|
75
|
+
end
|
76
|
+
|
77
|
+
end if defined? RedCloth
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
MYDIR = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
$: << 'lib'
|
6
|
+
require 'coderay'
|
7
|
+
puts "Running basic CodeRay #{CodeRay::VERSION} tests..."
|
8
|
+
|
9
|
+
suite = %w(basic load_plugin_scanner word_list)
|
10
|
+
for test_case in suite
|
11
|
+
load File.join(MYDIR, test_case + '.rb')
|
12
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
class VHDL < CodeRay::Scanners::Scanner
|
2
|
+
|
3
|
+
register_for :vhdl
|
4
|
+
|
5
|
+
RESERVED_WORDS = [
|
6
|
+
'access','after','alias','all','assert','architecture','begin',
|
7
|
+
'block','body','buffer','bus','case','component','configuration','constant',
|
8
|
+
'disconnect','downto','else','elsif','end','entity','exit','file','for',
|
9
|
+
'function','generate','generic','group','guarded','if','impure','in',
|
10
|
+
'inertial','inout','is','label','library','linkage','literal','loop',
|
11
|
+
'map','new','next','null','of','on','open','others','out','package',
|
12
|
+
'port','postponed','procedure','process','pure','range','record','register',
|
13
|
+
'reject','report','return','select','severity','signal','shared','subtype',
|
14
|
+
'then','to','transport','type','unaffected','units','until','use','variable',
|
15
|
+
'wait','when','while','with','note','warning','error','failure','and',
|
16
|
+
'or','xor','not','nor',
|
17
|
+
'array'
|
18
|
+
]
|
19
|
+
|
20
|
+
PREDEFINED_TYPES = [
|
21
|
+
'bit','bit_vector','character','boolean','integer','real','time','string',
|
22
|
+
'severity_level','positive','natural','signed','unsigned','line','text',
|
23
|
+
'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
|
24
|
+
'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
|
25
|
+
'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector'
|
26
|
+
]
|
27
|
+
|
28
|
+
PREDEFINED_CONSTANTS = [
|
29
|
+
|
30
|
+
]
|
31
|
+
|
32
|
+
IDENT_KIND = CodeRay::CaseIgnoringWordList.new(:ident).
|
33
|
+
add(RESERVED_WORDS, :reserved).
|
34
|
+
add(PREDEFINED_TYPES, :pre_type).
|
35
|
+
add(PREDEFINED_CONSTANTS, :pre_constant)
|
36
|
+
|
37
|
+
ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
|
38
|
+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
|
39
|
+
|
40
|
+
def scan_tokens tokens, options
|
41
|
+
|
42
|
+
state = :initial
|
43
|
+
|
44
|
+
until eos?
|
45
|
+
|
46
|
+
kind = nil
|
47
|
+
match = nil
|
48
|
+
|
49
|
+
case state
|
50
|
+
|
51
|
+
when :initial
|
52
|
+
|
53
|
+
if scan(/ \s+ | \\\n /x)
|
54
|
+
kind = :space
|
55
|
+
|
56
|
+
elsif scan(/-- .*/x)
|
57
|
+
kind = :comment
|
58
|
+
|
59
|
+
elsif scan(/ [-+*\/=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
|
60
|
+
kind = :operator
|
61
|
+
|
62
|
+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
|
63
|
+
kind = IDENT_KIND[match.downcase]
|
64
|
+
|
65
|
+
elsif match = scan(/[a-z]?"/i)
|
66
|
+
tokens << [:open, :string]
|
67
|
+
state = :string
|
68
|
+
kind = :delimiter
|
69
|
+
|
70
|
+
elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
|
71
|
+
kind = :char
|
72
|
+
|
73
|
+
elsif scan(/(?:\d+)(?![.eEfF])/)
|
74
|
+
kind = :integer
|
75
|
+
|
76
|
+
elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
|
77
|
+
kind = :float
|
78
|
+
|
79
|
+
else
|
80
|
+
getch
|
81
|
+
kind = :error
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
when :string
|
86
|
+
if scan(/[^\\\n"]+/)
|
87
|
+
kind = :content
|
88
|
+
elsif scan(/"/)
|
89
|
+
tokens << ['"', :delimiter]
|
90
|
+
tokens << [:close, :string]
|
91
|
+
state = :initial
|
92
|
+
next
|
93
|
+
elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
|
94
|
+
kind = :char
|
95
|
+
elsif scan(/ \\ | $ /x)
|
96
|
+
tokens << [:close, :string]
|
97
|
+
kind = :error
|
98
|
+
state = :initial
|
99
|
+
else
|
100
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
|
101
|
+
end
|
102
|
+
|
103
|
+
else
|
104
|
+
raise_inspect 'Unknown state', tokens
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
match ||= matched
|
109
|
+
if $DEBUG and not kind
|
110
|
+
raise_inspect 'Error token %p in line %d' %
|
111
|
+
[[match, kind], line], tokens
|
112
|
+
end
|
113
|
+
raise_inspect 'Empty token', tokens unless match
|
114
|
+
|
115
|
+
tokens << [match, kind]
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
if state == :string
|
120
|
+
tokens << [:close, :string]
|
121
|
+
end
|
122
|
+
|
123
|
+
tokens
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|