coderay 0.9.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/{lib/README → README_INDEX.rdoc} +10 -21
  2. data/Rakefile +6 -6
  3. data/bin/coderay +193 -64
  4. data/lib/coderay.rb +61 -105
  5. data/lib/coderay/duo.rb +17 -21
  6. data/lib/coderay/encoder.rb +100 -112
  7. data/lib/coderay/encoders/_map.rb +12 -7
  8. data/lib/coderay/encoders/comment_filter.rb +12 -30
  9. data/lib/coderay/encoders/count.rb +29 -11
  10. data/lib/coderay/encoders/debug.rb +32 -20
  11. data/lib/coderay/encoders/div.rb +13 -9
  12. data/lib/coderay/encoders/filter.rb +34 -51
  13. data/lib/coderay/encoders/html.rb +155 -161
  14. data/lib/coderay/encoders/html/css.rb +4 -9
  15. data/lib/coderay/encoders/html/numbering.rb +115 -0
  16. data/lib/coderay/encoders/html/output.rb +22 -70
  17. data/lib/coderay/encoders/json.rb +59 -45
  18. data/lib/coderay/encoders/lines_of_code.rb +12 -57
  19. data/lib/coderay/encoders/null.rb +6 -14
  20. data/lib/coderay/encoders/page.rb +13 -9
  21. data/lib/coderay/encoders/span.rb +13 -9
  22. data/lib/coderay/encoders/statistic.rb +58 -39
  23. data/lib/coderay/encoders/terminal.rb +179 -0
  24. data/lib/coderay/encoders/text.rb +31 -17
  25. data/lib/coderay/encoders/token_kind_filter.rb +111 -0
  26. data/lib/coderay/encoders/xml.rb +19 -18
  27. data/lib/coderay/encoders/yaml.rb +37 -9
  28. data/lib/coderay/for_redcloth.rb +4 -4
  29. data/lib/coderay/helpers/file_type.rb +127 -246
  30. data/lib/coderay/helpers/gzip.rb +41 -0
  31. data/lib/coderay/helpers/plugin.rb +241 -306
  32. data/lib/coderay/helpers/word_list.rb +65 -126
  33. data/lib/coderay/scanner.rb +173 -156
  34. data/lib/coderay/scanners/_map.rb +18 -17
  35. data/lib/coderay/scanners/c.rb +63 -77
  36. data/lib/coderay/scanners/clojure.rb +217 -0
  37. data/lib/coderay/scanners/cpp.rb +71 -84
  38. data/lib/coderay/scanners/css.rb +103 -120
  39. data/lib/coderay/scanners/debug.rb +47 -44
  40. data/lib/coderay/scanners/delphi.rb +70 -76
  41. data/lib/coderay/scanners/diff.rb +141 -50
  42. data/lib/coderay/scanners/erb.rb +81 -0
  43. data/lib/coderay/scanners/groovy.rb +104 -113
  44. data/lib/coderay/scanners/haml.rb +168 -0
  45. data/lib/coderay/scanners/html.rb +181 -110
  46. data/lib/coderay/scanners/java.rb +73 -75
  47. data/lib/coderay/scanners/java/builtin_types.rb +2 -0
  48. data/lib/coderay/scanners/java_script.rb +90 -101
  49. data/lib/coderay/scanners/json.rb +40 -53
  50. data/lib/coderay/scanners/php.rb +123 -147
  51. data/lib/coderay/scanners/python.rb +93 -91
  52. data/lib/coderay/scanners/raydebug.rb +66 -0
  53. data/lib/coderay/scanners/ruby.rb +343 -326
  54. data/lib/coderay/scanners/ruby/patterns.rb +40 -106
  55. data/lib/coderay/scanners/ruby/string_state.rb +71 -0
  56. data/lib/coderay/scanners/sql.rb +80 -66
  57. data/lib/coderay/scanners/text.rb +26 -0
  58. data/lib/coderay/scanners/xml.rb +1 -1
  59. data/lib/coderay/scanners/yaml.rb +74 -73
  60. data/lib/coderay/style.rb +10 -7
  61. data/lib/coderay/styles/_map.rb +3 -3
  62. data/lib/coderay/styles/alpha.rb +143 -0
  63. data/lib/coderay/token_kinds.rb +90 -0
  64. data/lib/coderay/tokens.rb +102 -277
  65. data/lib/coderay/tokens_proxy.rb +55 -0
  66. data/lib/coderay/version.rb +3 -0
  67. data/test/functional/basic.rb +200 -18
  68. data/test/functional/examples.rb +130 -0
  69. data/test/functional/for_redcloth.rb +15 -8
  70. data/test/functional/suite.rb +9 -6
  71. metadata +103 -123
  72. data/FOLDERS +0 -53
  73. data/bin/coderay_stylesheet +0 -4
  74. data/lib/coderay/encoders/html/numerization.rb +0 -133
  75. data/lib/coderay/encoders/term.rb +0 -158
  76. data/lib/coderay/encoders/token_class_filter.rb +0 -84
  77. data/lib/coderay/helpers/gzip_simple.rb +0 -123
  78. data/lib/coderay/scanners/nitro_xhtml.rb +0 -136
  79. data/lib/coderay/scanners/plaintext.rb +0 -20
  80. data/lib/coderay/scanners/rhtml.rb +0 -78
  81. data/lib/coderay/scanners/scheme.rb +0 -145
  82. data/lib/coderay/styles/cycnus.rb +0 -152
  83. data/lib/coderay/styles/murphy.rb +0 -134
  84. data/lib/coderay/token_classes.rb +0 -86
  85. data/test/functional/load_plugin_scanner.rb +0 -11
  86. data/test/functional/vhdl.rb +0 -126
  87. data/test/functional/word_list.rb +0 -79
@@ -1,16 +1,17 @@
1
1
  module CodeRay
2
2
  module Scanners
3
3
 
4
+ # Scanner for C++.
5
+ #
6
+ # Aliases: +cplusplus+, c++
4
7
  class CPlusPlus < Scanner
5
8
 
6
- include Streamable
7
-
8
9
  register_for :cpp
9
10
  file_extension 'cpp'
10
11
  title 'C++'
11
12
 
12
- # http://www.cppreference.com/wiki/keywords/start
13
- RESERVED_WORDS = [
13
+ #-- http://www.cppreference.com/wiki/keywords/start
14
+ KEYWORDS = [
14
15
  'and', 'and_eq', 'asm', 'bitand', 'bitor', 'break',
15
16
  'case', 'catch', 'class', 'compl', 'const_cast',
16
17
  'continue', 'default', 'delete', 'do', 'dynamic_cast', 'else',
@@ -18,37 +19,39 @@ module Scanners
18
19
  'not', 'not_eq', 'or', 'or_eq', 'reinterpret_cast', 'return',
19
20
  'sizeof', 'static_cast', 'struct', 'switch', 'template',
20
21
  'throw', 'try', 'typedef', 'typeid', 'typename', 'union',
21
- 'while', 'xor', 'xor_eq'
22
- ]
23
-
22
+ 'while', 'xor', 'xor_eq',
23
+ ] # :nodoc:
24
+
24
25
  PREDEFINED_TYPES = [
25
26
  'bool', 'char', 'double', 'float', 'int', 'long',
26
- 'short', 'signed', 'unsigned', 'wchar_t', 'string'
27
- ]
27
+ 'short', 'signed', 'unsigned', 'wchar_t', 'string',
28
+ ] # :nodoc:
28
29
  PREDEFINED_CONSTANTS = [
29
30
  'false', 'true',
30
31
  'EOF', 'NULL',
31
- ]
32
+ ] # :nodoc:
32
33
  PREDEFINED_VARIABLES = [
33
- 'this'
34
- ]
34
+ 'this',
35
+ ] # :nodoc:
35
36
  DIRECTIVES = [
36
37
  'auto', 'const', 'explicit', 'extern', 'friend', 'inline', 'mutable', 'operator',
37
38
  'private', 'protected', 'public', 'register', 'static', 'using', 'virtual', 'void',
38
- 'volatile'
39
- ]
40
-
39
+ 'volatile',
40
+ ] # :nodoc:
41
+
41
42
  IDENT_KIND = WordList.new(:ident).
42
- add(RESERVED_WORDS, :reserved).
43
- add(PREDEFINED_TYPES, :pre_type).
43
+ add(KEYWORDS, :keyword).
44
+ add(PREDEFINED_TYPES, :predefined_type).
44
45
  add(PREDEFINED_VARIABLES, :local_variable).
45
46
  add(DIRECTIVES, :directive).
46
- add(PREDEFINED_CONSTANTS, :pre_constant)
47
-
48
- ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
49
- UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
47
+ add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc:
50
48
 
51
- def scan_tokens tokens, options
49
+ ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
50
+ UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc:
51
+
52
+ protected
53
+
54
+ def scan_tokens encoder, options
52
55
 
53
56
  state = :initial
54
57
  label_expected = true
@@ -58,9 +61,6 @@ module Scanners
58
61
 
59
62
  until eos?
60
63
 
61
- kind = nil
62
- match = nil
63
-
64
64
  case state
65
65
 
66
66
  when :initial
@@ -70,15 +70,14 @@ module Scanners
70
70
  in_preproc_line = false
71
71
  label_expected = label_expected_before_preproc_line
72
72
  end
73
- tokens << [match, :space]
74
- next
73
+ encoder.text_token match, :space
75
74
 
76
- elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
77
- kind = :comment
75
+ elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
76
+ encoder.text_token match, :comment
78
77
 
79
78
  elsif match = scan(/ \# \s* if \s* 0 /x)
80
79
  match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos?
81
- kind = :comment
80
+ encoder.text_token match, :comment
82
81
 
83
82
  elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x)
84
83
  label_expected = match =~ /[;\{\}]/
@@ -86,7 +85,7 @@ module Scanners
86
85
  label_expected = true if match == ':'
87
86
  case_expected = false
88
87
  end
89
- kind = :operator
88
+ encoder.text_token match, :operator
90
89
 
91
90
  elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
92
91
  kind = IDENT_KIND[match]
@@ -95,7 +94,7 @@ module Scanners
95
94
  match << matched
96
95
  else
97
96
  label_expected = false
98
- if kind == :reserved
97
+ if kind == :keyword
99
98
  case match
100
99
  when 'class'
101
100
  state = :class_name_expected
@@ -104,122 +103,110 @@ module Scanners
104
103
  end
105
104
  end
106
105
  end
106
+ encoder.text_token match, kind
107
107
 
108
- elsif scan(/\$/)
109
- kind = :ident
108
+ elsif match = scan(/\$/)
109
+ encoder.text_token match, :ident
110
110
 
111
111
  elsif match = scan(/L?"/)
112
- tokens << [:open, :string]
112
+ encoder.begin_group :string
113
113
  if match[0] == ?L
114
- tokens << ['L', :modifier]
114
+ encoder.text_token match, 'L', :modifier
115
115
  match = '"'
116
116
  end
117
117
  state = :string
118
- kind = :delimiter
118
+ encoder.text_token match, :delimiter
119
119
 
120
- elsif scan(/#[ \t]*(\w*)/)
121
- kind = :preprocessor
120
+ elsif match = scan(/#[ \t]*(\w*)/)
121
+ encoder.text_token match, :preprocessor
122
122
  in_preproc_line = true
123
123
  label_expected_before_preproc_line = label_expected
124
124
  state = :include_expected if self[1] == 'include'
125
125
 
126
- elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
126
+ elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
127
127
  label_expected = false
128
- kind = :char
128
+ encoder.text_token match, :char
129
129
 
130
- elsif scan(/0[xX][0-9A-Fa-f]+/)
130
+ elsif match = scan(/0[xX][0-9A-Fa-f]+/)
131
131
  label_expected = false
132
- kind = :hex
132
+ encoder.text_token match, :hex
133
133
 
134
- elsif scan(/(?:0[0-7]+)(?![89.eEfF])/)
134
+ elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/)
135
135
  label_expected = false
136
- kind = :oct
136
+ encoder.text_token match, :octal
137
137
 
138
- elsif scan(/(?:\d+)(?![.eEfF])L?L?/)
138
+ elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/)
139
139
  label_expected = false
140
- kind = :integer
140
+ encoder.text_token match, :integer
141
141
 
142
- elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
142
+ elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
143
143
  label_expected = false
144
- kind = :float
144
+ encoder.text_token match, :float
145
145
 
146
146
  else
147
- getch
148
- kind = :error
147
+ encoder.text_token getch, :error
149
148
 
150
149
  end
151
150
 
152
151
  when :string
153
- if scan(/[^\\"]+/)
154
- kind = :content
155
- elsif scan(/"/)
156
- tokens << ['"', :delimiter]
157
- tokens << [:close, :string]
152
+ if match = scan(/[^\\"]+/)
153
+ encoder.text_token match, :content
154
+ elsif match = scan(/"/)
155
+ encoder.text_token match, :delimiter
156
+ encoder.end_group :string
158
157
  state = :initial
159
158
  label_expected = false
160
- next
161
- elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
162
- kind = :char
163
- elsif scan(/ \\ | $ /x)
164
- tokens << [:close, :string]
165
- kind = :error
159
+ elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
160
+ encoder.text_token match, :char
161
+ elsif match = scan(/ \\ | $ /x)
162
+ encoder.end_group :string
163
+ encoder.text_token match, :error
166
164
  state = :initial
167
165
  label_expected = false
168
166
  else
169
- raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
167
+ raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
170
168
  end
171
169
 
172
170
  when :include_expected
173
- if scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
174
- kind = :include
171
+ if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
172
+ encoder.text_token match, :include
175
173
  state = :initial
176
174
 
177
175
  elsif match = scan(/\s+/)
178
- kind = :space
176
+ encoder.text_token match, :space
179
177
  state = :initial if match.index ?\n
180
178
 
181
179
  else
182
180
  state = :initial
183
- next
184
181
 
185
182
  end
186
183
 
187
184
  when :class_name_expected
188
- if scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
189
- kind = :class
185
+ if match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
186
+ encoder.text_token match, :class
190
187
  state = :initial
191
188
 
192
189
  elsif match = scan(/\s+/)
193
- kind = :space
190
+ encoder.text_token match, :space
194
191
 
195
192
  else
196
- getch
197
- kind = :error
193
+ encoder.text_token getch, :error
198
194
  state = :initial
199
195
 
200
196
  end
201
197
 
202
198
  else
203
- raise_inspect 'Unknown state', tokens
199
+ raise_inspect 'Unknown state', encoder
204
200
 
205
201
  end
206
202
 
207
- match ||= matched
208
- if $CODERAY_DEBUG and not kind
209
- raise_inspect 'Error token %p in line %d' %
210
- [[match, kind], line], tokens
211
- end
212
- raise_inspect 'Empty token', tokens unless match
213
-
214
- tokens << [match, kind]
215
-
216
203
  end
217
204
 
218
205
  if state == :string
219
- tokens << [:close, :string]
206
+ encoder.end_group :string
220
207
  end
221
208
 
222
- tokens
209
+ encoder
223
210
  end
224
211
 
225
212
  end
@@ -2,208 +2,191 @@ module CodeRay
2
2
  module Scanners
3
3
 
4
4
  class CSS < Scanner
5
-
5
+
6
6
  register_for :css
7
-
7
+
8
8
  KINDS_NOT_LOC = [
9
9
  :comment,
10
10
  :class, :pseudo_class, :type,
11
11
  :constant, :directive,
12
- :key, :value, :operator, :color, :float, :content, :delimiter,
12
+ :key, :value, :operator, :color, :float, :string,
13
13
  :error, :important,
14
- ]
14
+ ] # :nodoc:
15
15
 
16
- module RE
16
+ module RE # :nodoc:
17
17
  Hex = /[0-9a-fA-F]/
18
18
  Unicode = /\\#{Hex}{1,6}(?:\r\n|\s)?/ # differs from standard because it allows uppercase hex too
19
19
  Escape = /#{Unicode}|\\[^\r\n\f0-9a-fA-F]/
20
20
  NMChar = /[-_a-zA-Z0-9]|#{Escape}/
21
21
  NMStart = /[_a-zA-Z]|#{Escape}/
22
22
  NL = /\r\n|\r|\n|\f/
23
- String1 = /"(?:[^\n\r\f\\"]|\\#{NL}|#{Escape})*"?/ # FIXME: buggy regexp
24
- String2 = /'(?:[^\n\r\f\\']|\\#{NL}|#{Escape})*'?/ # FIXME: buggy regexp
23
+ String1 = /"(?:[^\n\r\f\\"]|\\#{NL}|#{Escape})*"?/ # TODO: buggy regexp
24
+ String2 = /'(?:[^\n\r\f\\']|\\#{NL}|#{Escape})*'?/ # TODO: buggy regexp
25
25
  String = /#{String1}|#{String2}/
26
-
26
+
27
27
  HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/
28
28
  Color = /#{HexColor}/
29
-
29
+
30
30
  Num = /-?(?:[0-9]+|[0-9]*\.[0-9]+)/
31
31
  Name = /#{NMChar}+/
32
32
  Ident = /-?#{NMStart}#{NMChar}*/
33
33
  AtKeyword = /@#{Ident}/
34
34
  Percentage = /#{Num}%/
35
-
35
+
36
36
  reldimensions = %w[em ex px]
37
37
  absdimensions = %w[in cm mm pt pc]
38
38
  Unit = Regexp.union(*(reldimensions + absdimensions))
39
-
39
+
40
40
  Dimension = /#{Num}#{Unit}/
41
-
41
+
42
42
  Comment = %r! /\* (?: .*? \*/ | .* ) !mx
43
- Function = /(?:url|alpha)\((?:[^)\n\r\f]|\\\))*\)?/
44
-
43
+ Function = /(?:url|alpha|attr|counters?)\((?:[^)\n\r\f]|\\\))*\)?/
44
+
45
45
  Id = /##{Name}/
46
46
  Class = /\.#{Name}/
47
47
  PseudoClass = /:#{Name}/
48
48
  AttributeSelector = /\[[^\]]*\]?/
49
-
50
49
  end
51
-
52
- def scan_tokens tokens, options
50
+
51
+ protected
52
+
53
+ def scan_tokens encoder, options
53
54
 
54
55
  value_expected = nil
55
56
  states = [:initial]
56
-
57
+
57
58
  until eos?
58
-
59
- kind = nil
60
- match = nil
61
-
62
- if scan(/\s+/)
63
- kind = :space
64
-
59
+
60
+ if match = scan(/\s+/)
61
+ encoder.text_token match, :space
62
+
65
63
  elsif case states.last
66
64
  when :initial, :media
67
- if scan(/(?>#{RE::Ident})(?!\()|\*/ox)
68
- kind = :type
69
- elsif scan RE::Class
70
- kind = :class
71
- elsif scan RE::Id
72
- kind = :constant
73
- elsif scan RE::PseudoClass
74
- kind = :pseudo_class
65
+ if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox)
66
+ encoder.text_token match, :type
67
+ next
68
+ elsif match = scan(RE::Class)
69
+ encoder.text_token match, :class
70
+ next
71
+ elsif match = scan(RE::Id)
72
+ encoder.text_token match, :constant
73
+ next
74
+ elsif match = scan(RE::PseudoClass)
75
+ encoder.text_token match, :pseudo_class
76
+ next
75
77
  elsif match = scan(RE::AttributeSelector)
76
78
  # TODO: Improve highlighting inside of attribute selectors.
77
- tokens << [:open, :string]
78
- tokens << [match[0,1], :delimiter]
79
- tokens << [match[1..-2], :content] if match.size > 2
80
- tokens << [match[-1,1], :delimiter] if match[-1] == ?]
81
- tokens << [:close, :string]
79
+ encoder.text_token match[0,1], :operator
80
+ encoder.text_token match[1..-2], :attribute_name if match.size > 2
81
+ encoder.text_token match[-1,1], :operator if match[-1] == ?]
82
82
  next
83
83
  elsif match = scan(/@media/)
84
- kind = :directive
84
+ encoder.text_token match, :directive
85
85
  states.push :media_before_name
86
+ next
86
87
  end
87
88
 
88
89
  when :block
89
- if scan(/(?>#{RE::Ident})(?!\()/ox)
90
+ if match = scan(/(?>#{RE::Ident})(?!\()/ox)
90
91
  if value_expected
91
- kind = :value
92
+ encoder.text_token match, :value
92
93
  else
93
- kind = :key
94
+ encoder.text_token match, :key
94
95
  end
96
+ next
95
97
  end
96
-
98
+
97
99
  when :media_before_name
98
- if scan RE::Ident
99
- kind = :type
100
+ if match = scan(RE::Ident)
101
+ encoder.text_token match, :type
100
102
  states[-1] = :media_after_name
103
+ next
101
104
  end
102
105
 
103
106
  when :media_after_name
104
- if scan(/\{/)
105
- kind = :operator
107
+ if match = scan(/\{/)
108
+ encoder.text_token match, :operator
106
109
  states[-1] = :media
110
+ next
107
111
  end
108
112
 
109
- when :comment
110
- if scan(/(?:[^*\s]|\*(?!\/))+/)
111
- kind = :comment
112
- elsif scan(/\*\//)
113
- kind = :comment
114
- states.pop
115
- elsif scan(/\s+/)
116
- kind = :space
117
- end
118
-
119
113
  else
120
- raise_inspect 'Unknown state', tokens
121
-
114
+ #:nocov:
115
+ raise_inspect 'Unknown state', encoder
116
+ #:nocov:
117
+
122
118
  end
123
-
124
- elsif scan(/\/\*/)
125
- kind = :comment
126
- states.push :comment
127
-
128
- elsif scan(/\{/)
119
+
120
+ elsif match = scan(/\/\*(?:.*?\*\/|\z)/m)
121
+ encoder.text_token match, :comment
122
+
123
+ elsif match = scan(/\{/)
129
124
  value_expected = false
130
- kind = :operator
125
+ encoder.text_token match, :operator
131
126
  states.push :block
132
-
133
- elsif scan(/\}/)
127
+
128
+ elsif match = scan(/\}/)
134
129
  value_expected = false
135
130
  if states.last == :block || states.last == :media
136
- kind = :operator
131
+ encoder.text_token match, :operator
137
132
  states.pop
138
133
  else
139
- kind = :error
134
+ encoder.text_token match, :error
140
135
  end
141
-
136
+
142
137
  elsif match = scan(/#{RE::String}/o)
143
- tokens << [:open, :string]
144
- tokens << [match[0, 1], :delimiter]
145
- tokens << [match[1..-2], :content] if match.size > 2
146
- tokens << [match[-1, 1], :delimiter] if match.size >= 2
147
- tokens << [:close, :string]
148
- next
149
-
138
+ encoder.begin_group :string
139
+ encoder.text_token match[0, 1], :delimiter
140
+ encoder.text_token match[1..-2], :content if match.size > 2
141
+ encoder.text_token match[-1, 1], :delimiter if match.size >= 2
142
+ encoder.end_group :string
143
+
150
144
  elsif match = scan(/#{RE::Function}/o)
151
- tokens << [:open, :string]
145
+ encoder.begin_group :string
152
146
  start = match[/^\w+\(/]
153
- tokens << [start, :delimiter]
147
+ encoder.text_token start, :delimiter
154
148
  if match[-1] == ?)
155
- tokens << [match[start.size..-2], :content]
156
- tokens << [')', :delimiter]
149
+ encoder.text_token match[start.size..-2], :content
150
+ encoder.text_token ')', :delimiter
157
151
  else
158
- tokens << [match[start.size..-1], :content]
152
+ encoder.text_token match[start.size..-1], :content
159
153
  end
160
- tokens << [:close, :string]
161
- next
162
-
163
- elsif scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
164
- kind = :float
165
-
166
- elsif scan(/#{RE::Color}/o)
167
- kind = :color
168
-
169
- elsif scan(/! *important/)
170
- kind = :important
171
-
172
- elsif scan(/rgb\([^()\n]*\)?/)
173
- kind = :color
174
-
175
- elsif scan(/#{RE::AtKeyword}/o)
176
- kind = :directive
177
-
154
+ encoder.end_group :string
155
+
156
+ elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
157
+ encoder.text_token match, :float
158
+
159
+ elsif match = scan(/#{RE::Color}/o)
160
+ encoder.text_token match, :color
161
+
162
+ elsif match = scan(/! *important/)
163
+ encoder.text_token match, :important
164
+
165
+ elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/)
166
+ encoder.text_token match, :color
167
+
168
+ elsif match = scan(RE::AtKeyword)
169
+ encoder.text_token match, :directive
170
+
178
171
  elsif match = scan(/ [+>:;,.=()\/] /x)
179
172
  if match == ':'
180
173
  value_expected = true
181
174
  elsif match == ';'
182
175
  value_expected = false
183
176
  end
184
- kind = :operator
185
-
177
+ encoder.text_token match, :operator
178
+
186
179
  else
187
- getch
188
- kind = :error
189
-
190
- end
191
-
192
- match ||= matched
193
- if $CODERAY_DEBUG and not kind
194
- raise_inspect 'Error token %p in line %d' %
195
- [[match, kind], line], tokens
180
+ encoder.text_token getch, :error
181
+
196
182
  end
197
- raise_inspect 'Empty token', tokens unless match
198
-
199
- tokens << [match, kind]
200
-
183
+
201
184
  end
202
-
203
- tokens
185
+
186
+ encoder
204
187
  end
205
-
188
+
206
189
  end
207
-
190
+
208
191
  end
209
192
  end