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