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
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
|