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.
Files changed (47) hide show
  1. data/LICENSE +421 -257
  2. data/README +24 -13
  3. data/bin/coderay +9 -4
  4. data/lib/coderay.rb +19 -17
  5. data/lib/coderay/duo.rb +67 -9
  6. data/lib/coderay/encoder.rb +18 -9
  7. data/lib/coderay/encoders/_map.rb +2 -1
  8. data/lib/coderay/encoders/debug.rb +14 -11
  9. data/lib/coderay/encoders/html.rb +44 -17
  10. data/lib/coderay/encoders/html/css.rb +13 -8
  11. data/lib/coderay/encoders/html/numerization.rb +8 -6
  12. data/lib/coderay/encoders/html/output.rb +3 -1
  13. data/lib/coderay/encoders/statistic.rb +2 -6
  14. data/lib/coderay/encoders/text.rb +2 -3
  15. data/lib/coderay/encoders/tokens.rb +3 -3
  16. data/lib/coderay/encoders/xml.rb +1 -2
  17. data/lib/coderay/for_redcloth.rb +72 -0
  18. data/lib/coderay/helpers/file_type.rb +38 -9
  19. data/lib/coderay/helpers/gzip_simple.rb +1 -0
  20. data/lib/coderay/helpers/plugin.rb +15 -8
  21. data/lib/coderay/helpers/word_list.rb +4 -0
  22. data/lib/coderay/scanner.rb +30 -13
  23. data/lib/coderay/scanners/_map.rb +1 -1
  24. data/lib/coderay/scanners/c.rb +3 -1
  25. data/lib/coderay/scanners/css.rb +181 -0
  26. data/lib/coderay/scanners/debug.rb +1 -0
  27. data/lib/coderay/scanners/delphi.rb +1 -0
  28. data/lib/coderay/scanners/diff.rb +104 -0
  29. data/lib/coderay/scanners/java.rb +179 -0
  30. data/lib/coderay/scanners/java/builtin_types.rb +419 -0
  31. data/lib/coderay/scanners/java_script.rb +187 -0
  32. data/lib/coderay/scanners/json.rb +106 -0
  33. data/lib/coderay/scanners/nitro_xhtml.rb +5 -4
  34. data/lib/coderay/scanners/plaintext.rb +2 -0
  35. data/lib/coderay/scanners/rhtml.rb +2 -2
  36. data/lib/coderay/scanners/ruby.rb +64 -50
  37. data/lib/coderay/scanners/ruby/patterns.rb +15 -19
  38. data/lib/coderay/scanners/scheme.rb +142 -0
  39. data/lib/coderay/scanners/sql.Keith.rb +143 -0
  40. data/lib/coderay/scanners/sql.rb +154 -0
  41. data/lib/coderay/scanners/xml.rb +1 -0
  42. data/lib/coderay/styles/cycnus.rb +30 -9
  43. data/lib/coderay/styles/murphy.rb +15 -2
  44. data/lib/coderay/{encoders/html/classes.rb → token_classes.rb} +14 -9
  45. data/lib/coderay/tokens.rb +33 -14
  46. data/lib/term/ansicolor.rb +220 -0
  47. metadata +62 -44
@@ -5,8 +5,8 @@ module Scanners
5
5
  :plain => :plaintext,
6
6
  :pascal => :delphi,
7
7
  :irb => :ruby,
8
- :xml => :html,
9
8
  :xhtml => :nitro_xhtml,
9
+ :javascript => :java_script,
10
10
  :nitro => :nitro_xhtml
11
11
 
12
12
  default :plain
@@ -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
@@ -6,6 +6,7 @@ module Scanners
6
6
 
7
7
  include Streamable
8
8
  register_for :debug
9
+ file_extension 'raydebug'
9
10
 
10
11
  protected
11
12
  def scan_tokens tokens, options
@@ -4,6 +4,7 @@ module Scanners
4
4
  class Delphi < Scanner
5
5
 
6
6
  register_for :delphi
7
+ file_extension 'pas'
7
8
 
8
9
  RESERVED_WORDS = [
9
10
  'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class',
@@ -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