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
data/lib/coderay/scanners/c.rb
CHANGED
@@ -4,6 +4,8 @@ module Scanners
|
|
4
4
|
class C < Scanner
|
5
5
|
|
6
6
|
register_for :c
|
7
|
+
|
8
|
+
include Streamable
|
7
9
|
|
8
10
|
RESERVED_WORDS = [
|
9
11
|
'asm', 'break', 'case', 'continue', 'default', 'do', 'else',
|
@@ -42,7 +44,7 @@ module Scanners
|
|
42
44
|
|
43
45
|
kind = nil
|
44
46
|
match = nil
|
45
|
-
|
47
|
+
|
46
48
|
case state
|
47
49
|
|
48
50
|
when :initial
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
class CSS < Scanner
|
5
|
+
|
6
|
+
register_for :css
|
7
|
+
|
8
|
+
module RE
|
9
|
+
NonASCII = /[\x80-\xFF]/
|
10
|
+
Hex = /[0-9a-fA-F]/
|
11
|
+
Unicode = /\\#{Hex}{1,6}(?:\r\n|\s)?/ # differs from standard because it allows uppercase hex too
|
12
|
+
Escape = /#{Unicode}|\\[^\r\n\f0-9a-fA-F]/
|
13
|
+
NMChar = /[-_a-zA-Z0-9]|#{NonASCII}|#{Escape}/
|
14
|
+
NMStart = /[_a-zA-Z]|#{NonASCII}|#{Escape}/
|
15
|
+
NL = /\r\n|\r|\n|\f/
|
16
|
+
String1 = /"(?:[^\n\r\f\\"]|\\#{NL}|#{Escape})*"?/ # FIXME: buggy regexp
|
17
|
+
String2 = /'(?:[^\n\r\f\\']|\\#{NL}|#{Escape})*'?/ # FIXME: buggy regexp
|
18
|
+
String = /#{String1}|#{String2}/
|
19
|
+
|
20
|
+
HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/
|
21
|
+
Color = /#{HexColor}/
|
22
|
+
|
23
|
+
Num = /-?(?:[0-9]+|[0-9]*\.[0-9]+)/
|
24
|
+
Name = /#{NMChar}+/
|
25
|
+
Ident = /-?#{NMStart}#{NMChar}*/
|
26
|
+
AtKeyword = /@#{Ident}/
|
27
|
+
Percentage = /#{Num}%/
|
28
|
+
|
29
|
+
reldimensions = %w[em ex px]
|
30
|
+
absdimensions = %w[in cm mm pt pc]
|
31
|
+
Unit = Regexp.union(*(reldimensions + absdimensions))
|
32
|
+
|
33
|
+
Dimension = /#{Num}#{Unit}/
|
34
|
+
|
35
|
+
Comment = %r! /\* (?: .*? \*/ | .* ) !mx
|
36
|
+
Function = /(?:url|alpha)\((?:[^)\n\r\f]|\\\))*\)?/
|
37
|
+
|
38
|
+
Id = /##{Name}/
|
39
|
+
Class = /\.#{Name}/
|
40
|
+
PseudoClass = /:#{Name}/
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def scan_tokens tokens, options
|
45
|
+
|
46
|
+
value_expected = nil
|
47
|
+
states = [:initial]
|
48
|
+
|
49
|
+
until eos?
|
50
|
+
|
51
|
+
kind = nil
|
52
|
+
match = nil
|
53
|
+
|
54
|
+
if scan(/\s+/)
|
55
|
+
kind = :space
|
56
|
+
|
57
|
+
elsif case states.last
|
58
|
+
when :initial
|
59
|
+
if scan(/#{RE::Ident}|\*/ox)
|
60
|
+
kind = :keyword
|
61
|
+
elsif scan RE::Class
|
62
|
+
kind = :class
|
63
|
+
elsif scan RE::Id
|
64
|
+
kind = :constant
|
65
|
+
elsif scan RE::PseudoClass
|
66
|
+
kind = :pseudo_class
|
67
|
+
elsif scan RE::Name
|
68
|
+
kind = :identifier
|
69
|
+
end
|
70
|
+
|
71
|
+
when :block
|
72
|
+
if scan(/(?>#{RE::Ident})(?!\()/ox)
|
73
|
+
if value_expected
|
74
|
+
kind = :value
|
75
|
+
else
|
76
|
+
kind = :key
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
when :comment
|
81
|
+
if scan(/(?:[^*\s]|\*(?!\/))+/)
|
82
|
+
kind = :comment
|
83
|
+
elsif scan(/\*\//)
|
84
|
+
kind = :comment
|
85
|
+
states.pop
|
86
|
+
elsif scan(/\s+/)
|
87
|
+
kind = :space
|
88
|
+
end
|
89
|
+
|
90
|
+
else
|
91
|
+
raise_inspect 'Unknown state', tokens
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
elsif scan(/\/\*/)
|
96
|
+
kind = :comment
|
97
|
+
states.push :comment
|
98
|
+
|
99
|
+
elsif scan(/\{/)
|
100
|
+
value_expected = false
|
101
|
+
kind = :operator
|
102
|
+
states.push :block
|
103
|
+
|
104
|
+
elsif scan(/\}/)
|
105
|
+
value_expected = false
|
106
|
+
if states.last == :block
|
107
|
+
kind = :operator
|
108
|
+
states.pop
|
109
|
+
else
|
110
|
+
kind = :error
|
111
|
+
end
|
112
|
+
|
113
|
+
elsif match = scan(/#{RE::String}/o)
|
114
|
+
tokens << [:open, :string]
|
115
|
+
tokens << [match[0, 1], :delimiter]
|
116
|
+
tokens << [match[1..-2], :content] if match.size > 2
|
117
|
+
tokens << [match[-1, 1], :delimiter] if match.size >= 2
|
118
|
+
tokens << [:close, :string]
|
119
|
+
next
|
120
|
+
|
121
|
+
elsif match = scan(/#{RE::Function}/o)
|
122
|
+
tokens << [:open, :string]
|
123
|
+
start = match[/^\w+\(/]
|
124
|
+
tokens << [start, :delimiter]
|
125
|
+
if match[-1] == ?)
|
126
|
+
tokens << [match[start.size..-2], :content]
|
127
|
+
tokens << [')', :delimiter]
|
128
|
+
else
|
129
|
+
tokens << [match[start.size..-1], :content]
|
130
|
+
end
|
131
|
+
tokens << [:close, :string]
|
132
|
+
next
|
133
|
+
|
134
|
+
elsif scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
|
135
|
+
kind = :float
|
136
|
+
|
137
|
+
elsif scan(/#{RE::Color}/o)
|
138
|
+
kind = :color
|
139
|
+
|
140
|
+
elsif scan(/! *important/)
|
141
|
+
kind = :important
|
142
|
+
|
143
|
+
elsif scan(/rgb\([^()\n]*\)?/)
|
144
|
+
kind = :color
|
145
|
+
|
146
|
+
elsif scan(/#{RE::AtKeyword}/o)
|
147
|
+
kind = :directive
|
148
|
+
|
149
|
+
elsif match = scan(/ [+>:;,.=()\/] /x)
|
150
|
+
if match == ':'
|
151
|
+
value_expected = true
|
152
|
+
elsif match == ';'
|
153
|
+
value_expected = false
|
154
|
+
end
|
155
|
+
kind = :operator
|
156
|
+
|
157
|
+
else
|
158
|
+
getch
|
159
|
+
kind = :error
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
match ||= matched
|
164
|
+
if $DEBUG and not kind
|
165
|
+
raise_inspect 'Error token %p in line %d' %
|
166
|
+
[[match, kind], line], tokens
|
167
|
+
end
|
168
|
+
raise_inspect 'Empty token', tokens unless match
|
169
|
+
|
170
|
+
tokens << [match, kind]
|
171
|
+
# tokens << [states.inspect, :error]
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
tokens
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
class Diff < Scanner
|
5
|
+
|
6
|
+
register_for :diff
|
7
|
+
|
8
|
+
def scan_tokens tokens, options
|
9
|
+
|
10
|
+
line_kind = nil
|
11
|
+
state = :initial
|
12
|
+
|
13
|
+
until eos?
|
14
|
+
kind = match = nil
|
15
|
+
|
16
|
+
if match = scan(/\n/)
|
17
|
+
if line_kind
|
18
|
+
tokens << [:end_line, line_kind]
|
19
|
+
line_kind = nil
|
20
|
+
end
|
21
|
+
tokens << [match, :space]
|
22
|
+
next
|
23
|
+
end
|
24
|
+
|
25
|
+
case state
|
26
|
+
|
27
|
+
when :initial
|
28
|
+
if match = scan(/--- |\+\+\+ |=+|_+/)
|
29
|
+
tokens << [:begin_line, line_kind = :head]
|
30
|
+
tokens << [match, :head]
|
31
|
+
next unless match = scan(/.+/)
|
32
|
+
kind = :plain
|
33
|
+
elsif match = scan(/Index: |Property changes on: /)
|
34
|
+
tokens << [:begin_line, line_kind = :head]
|
35
|
+
tokens << [match, :head]
|
36
|
+
next unless match = scan(/.+/)
|
37
|
+
kind = :plain
|
38
|
+
elsif match = scan(/Added: /)
|
39
|
+
tokens << [:begin_line, line_kind = :head]
|
40
|
+
tokens << [match, :head]
|
41
|
+
next unless match = scan(/.+/)
|
42
|
+
kind = :plain
|
43
|
+
state = :added
|
44
|
+
elsif match = scan(/\\ /)
|
45
|
+
tokens << [:begin_line, line_kind = :change]
|
46
|
+
tokens << [match, :change]
|
47
|
+
next unless match = scan(/.+/)
|
48
|
+
kind = :plain
|
49
|
+
elsif scan(/(@@)((?>[^@\n]*))(@@)/)
|
50
|
+
tokens << [:begin_line, line_kind = :change]
|
51
|
+
tokens << [self[1], :change]
|
52
|
+
tokens << [self[2], :plain]
|
53
|
+
tokens << [self[3], :change]
|
54
|
+
next unless match = scan(/.+/)
|
55
|
+
kind = :plain
|
56
|
+
elsif match = scan(/\+/)
|
57
|
+
tokens << [:begin_line, line_kind = :insert]
|
58
|
+
tokens << [match, :insert]
|
59
|
+
next unless match = scan(/.+/)
|
60
|
+
kind = :plain
|
61
|
+
elsif match = scan(/-/)
|
62
|
+
tokens << [:begin_line, line_kind = :delete]
|
63
|
+
tokens << [match, :delete]
|
64
|
+
next unless match = scan(/.+/)
|
65
|
+
kind = :plain
|
66
|
+
elsif scan(/ .*/)
|
67
|
+
kind = :comment
|
68
|
+
elsif scan(/.+/)
|
69
|
+
tokens << [:begin_line, line_kind = :head]
|
70
|
+
kind = :plain
|
71
|
+
else
|
72
|
+
raise_inspect 'else case rached'
|
73
|
+
end
|
74
|
+
|
75
|
+
when :added
|
76
|
+
if match = scan(/ \+/)
|
77
|
+
tokens << [:begin_line, line_kind = :insert]
|
78
|
+
tokens << [match, :insert]
|
79
|
+
next unless match = scan(/.+/)
|
80
|
+
kind = :plain
|
81
|
+
else
|
82
|
+
state = :initial
|
83
|
+
next
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
match ||= matched
|
88
|
+
if $DEBUG and not kind
|
89
|
+
raise_inspect 'Error token %p in line %d' %
|
90
|
+
[[match, kind], line], tokens
|
91
|
+
end
|
92
|
+
raise_inspect 'Empty token', tokens unless match
|
93
|
+
|
94
|
+
tokens << [match, kind]
|
95
|
+
end
|
96
|
+
|
97
|
+
tokens << [:end_line, line_kind] if line_kind
|
98
|
+
tokens
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
class Java < Scanner
|
5
|
+
|
6
|
+
include Streamable
|
7
|
+
register_for :java
|
8
|
+
helper :builtin_types
|
9
|
+
|
10
|
+
# TODO: Check this!
|
11
|
+
KEYWORDS = %w[
|
12
|
+
break case catch continue default do else
|
13
|
+
false finally for if instanceof new null
|
14
|
+
return switch throw true try typeof while
|
15
|
+
debugger export import package
|
16
|
+
]
|
17
|
+
|
18
|
+
MAGIC_VARIABLES = %w[ this super ]
|
19
|
+
TYPES = %w[
|
20
|
+
boolean byte char class interface double enum float String int long short void
|
21
|
+
] << '[]'
|
22
|
+
DIRECTIVES = %w[
|
23
|
+
abstract extends final implements native private protected public
|
24
|
+
static strictfp synchronized threadsafe throws transient volatile
|
25
|
+
]
|
26
|
+
|
27
|
+
# Reserved for future use.
|
28
|
+
|
29
|
+
IDENT_KIND = WordList.new(:ident).
|
30
|
+
add(KEYWORDS, :keyword).
|
31
|
+
add(MAGIC_VARIABLES, :local_variable).
|
32
|
+
add(TYPES, :type).
|
33
|
+
add(BuiltinTypes::List, :type).
|
34
|
+
add(DIRECTIVES, :directive)
|
35
|
+
|
36
|
+
ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
|
37
|
+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
|
38
|
+
REGEXP_ESCAPE = / [bBdDsSwW] /x
|
39
|
+
STRING_CONTENT_PATTERN = {
|
40
|
+
"'" => /[^\\']+/,
|
41
|
+
'"' => /[^\\"]+/,
|
42
|
+
'/' => /[^\\\/]+/,
|
43
|
+
}
|
44
|
+
IDENT = /[a-zA-Z_][A-Za-z_0-9]*/
|
45
|
+
|
46
|
+
def scan_tokens tokens, options
|
47
|
+
|
48
|
+
state = :initial
|
49
|
+
string_delimiter = nil
|
50
|
+
import_clause = class_name_follows = last_token_dot = false
|
51
|
+
|
52
|
+
until eos?
|
53
|
+
|
54
|
+
kind = nil
|
55
|
+
match = nil
|
56
|
+
|
57
|
+
case state
|
58
|
+
|
59
|
+
when :initial
|
60
|
+
|
61
|
+
if match = scan(/ \s+ | \\\n /x)
|
62
|
+
tokens << [match, :space]
|
63
|
+
next
|
64
|
+
|
65
|
+
elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
|
66
|
+
kind = :comment
|
67
|
+
|
68
|
+
elsif import_clause && scan(/ #{IDENT} (?: \. #{IDENT} )* /ox)
|
69
|
+
kind = :include
|
70
|
+
|
71
|
+
elsif match = scan(/ #{IDENT} | \[\] /ox)
|
72
|
+
kind = IDENT_KIND[match]
|
73
|
+
if last_token_dot
|
74
|
+
kind = :ident
|
75
|
+
elsif class_name_follows
|
76
|
+
kind = :class
|
77
|
+
class_name_follows = false
|
78
|
+
else
|
79
|
+
import_clause = true if match == 'import'
|
80
|
+
class_name_follows = true if match == 'class'
|
81
|
+
end
|
82
|
+
|
83
|
+
elsif scan(/ \.(?!\d) | [,?:(\[)\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<<?=? | >>>?=? /x)
|
84
|
+
kind = :operator
|
85
|
+
|
86
|
+
elsif scan(/;/)
|
87
|
+
import_clause = false
|
88
|
+
kind = :operator
|
89
|
+
|
90
|
+
elsif scan(/\{/)
|
91
|
+
class_name_follows = false
|
92
|
+
kind = :operator
|
93
|
+
|
94
|
+
elsif check(/[\d.]/)
|
95
|
+
if scan(/0[xX][0-9A-Fa-f]+/)
|
96
|
+
kind = :hex
|
97
|
+
elsif scan(/(?>0[0-7]+)(?![89.eEfF])/)
|
98
|
+
kind = :oct
|
99
|
+
elsif scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
|
100
|
+
kind = :float
|
101
|
+
elsif scan(/\d+[lL]?/)
|
102
|
+
kind = :integer
|
103
|
+
end
|
104
|
+
|
105
|
+
elsif match = scan(/["']/)
|
106
|
+
tokens << [:open, :string]
|
107
|
+
state = :string
|
108
|
+
string_delimiter = match
|
109
|
+
kind = :delimiter
|
110
|
+
|
111
|
+
elsif scan(/ @ #{IDENT} /ox)
|
112
|
+
kind = :annotation
|
113
|
+
|
114
|
+
else
|
115
|
+
getch
|
116
|
+
kind = :error
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
when :string, :regexp
|
121
|
+
if scan(STRING_CONTENT_PATTERN[string_delimiter])
|
122
|
+
kind = :content
|
123
|
+
elsif match = scan(/["'\/]/)
|
124
|
+
tokens << [match, :delimiter]
|
125
|
+
if state == :regexp
|
126
|
+
modifiers = scan(/[gim]+/)
|
127
|
+
tokens << [modifiers, :modifier] if modifiers && !modifiers.empty?
|
128
|
+
end
|
129
|
+
tokens << [:close, state]
|
130
|
+
string_delimiter = nil
|
131
|
+
state = :initial
|
132
|
+
next
|
133
|
+
elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
|
134
|
+
if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
|
135
|
+
kind = :content
|
136
|
+
else
|
137
|
+
kind = :char
|
138
|
+
end
|
139
|
+
elsif state == :regexp && scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
|
140
|
+
kind = :char
|
141
|
+
elsif scan(/\\./m)
|
142
|
+
kind = :content
|
143
|
+
elsif scan(/ \\ | $ /x)
|
144
|
+
tokens << [:close, :delimiter]
|
145
|
+
kind = :error
|
146
|
+
state = :initial
|
147
|
+
else
|
148
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
|
149
|
+
end
|
150
|
+
|
151
|
+
else
|
152
|
+
raise_inspect 'Unknown state', tokens
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
match ||= matched
|
157
|
+
if $DEBUG and not kind
|
158
|
+
raise_inspect 'Error token %p in line %d' %
|
159
|
+
[[match, kind], line], tokens
|
160
|
+
end
|
161
|
+
raise_inspect 'Empty token', tokens unless match
|
162
|
+
|
163
|
+
last_token_dot = match == '.'
|
164
|
+
|
165
|
+
tokens << [match, kind]
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
if [:string, :regexp].include? state
|
170
|
+
tokens << [:close, state]
|
171
|
+
end
|
172
|
+
|
173
|
+
tokens
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|