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
@@ -2,9 +2,9 @@
2
2
  module CodeRay
3
3
  module Scanners
4
4
 
5
- module Ruby::Patterns # :nodoc:
5
+ module Ruby::Patterns # :nodoc: all
6
6
 
7
- RESERVED_WORDS = %w[
7
+ KEYWORDS = %w[
8
8
  and def end in or unless begin
9
9
  defined? ensure module redo super until
10
10
  BEGIN break do next rescue then
@@ -13,25 +13,27 @@ module Scanners
13
13
  undef yield
14
14
  ]
15
15
 
16
- DEF_KEYWORDS = %w[ def ]
17
- UNDEF_KEYWORDS = %w[ undef ]
18
- ALIAS_KEYWORDS = %w[ alias ]
19
- MODULE_KEYWORDS = %w[ class module ]
20
- DEF_NEW_STATE = WordList.new(:initial).
21
- add(DEF_KEYWORDS, :def_expected).
22
- add(UNDEF_KEYWORDS, :undef_expected).
23
- add(ALIAS_KEYWORDS, :alias_expected).
24
- add(MODULE_KEYWORDS, :module_expected)
25
-
16
+ # See http://murfy.de/ruby-constants.
26
17
  PREDEFINED_CONSTANTS = %w[
27
18
  nil true false self
28
- DATA ARGV ARGF
19
+ DATA ARGV ARGF ENV
20
+ FALSE TRUE NIL
21
+ STDERR STDIN STDOUT
22
+ TOPLEVEL_BINDING
23
+ RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL
24
+ RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION
29
25
  __FILE__ __LINE__ __ENCODING__
30
26
  ]
31
27
 
32
28
  IDENT_KIND = WordList.new(:ident).
33
- add(RESERVED_WORDS, :reserved).
34
- add(PREDEFINED_CONSTANTS, :pre_constant)
29
+ add(KEYWORDS, :keyword).
30
+ add(PREDEFINED_CONSTANTS, :predefined_constant)
31
+
32
+ KEYWORD_NEW_STATE = WordList.new(:initial).
33
+ add(%w[ def ], :def_expected).
34
+ add(%w[ undef ], :undef_expected).
35
+ add(%w[ alias ], :alias_expected).
36
+ add(%w[ class module ], :module_expected)
35
37
 
36
38
  IDENT = 'ä'[/[[:alpha:]]/] == 'ä' ? /[[:alpha:]_][[:alnum:]_]*/ : /[^\W\d]\w*/
37
39
 
@@ -46,7 +48,9 @@ module Scanners
46
48
  | ===? | =~ # simple equality, case equality, match
47
49
  | ![~=@]? # negation with and without at sign, not-equal and not-match
48
50
  /ox
49
- METHOD_NAME_EX = / #{IDENT} (?:[?!]|=(?!>))? | #{METHOD_NAME_OPERATOR} /ox
51
+ METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x
52
+ METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox
53
+ METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox
50
54
  INSTANCE_VARIABLE = / @ #{IDENT} /ox
51
55
  CLASS_VARIABLE = / @@ #{IDENT} /ox
52
56
  OBJECT_VARIABLE = / @@? #{IDENT} /ox
@@ -60,8 +64,7 @@ module Scanners
60
64
  }
61
65
  QUOTE_TO_TYPE.default = :string
62
66
 
63
- REGEXP_MODIFIERS = /[mixounse]*/
64
- REGEXP_SYMBOLS = /[|?*+(){}\[\].^$]/
67
+ REGEXP_MODIFIERS = /[mousenix]*/
65
68
 
66
69
  DECIMAL = /\d+(?:_\d+)*/
67
70
  OCTAL = /0_?[0-7]+(?:_[0-7]+)*/
@@ -87,7 +90,7 @@ module Scanners
87
90
  [abefnrstv]
88
91
  | [0-7]{1,3}
89
92
  | x[0-9A-Fa-f]{1,2}
90
- | .?
93
+ | .
91
94
  /mx
92
95
 
93
96
  CONTROL_META_ESCAPE = /
@@ -110,12 +113,10 @@ module Scanners
110
113
 
111
114
  # NOTE: This is not completely correct, but
112
115
  # nobody needs heredoc delimiters ending with \n.
113
- # Also, delimiters starting with numbers are allowed.
114
- # but they are more often than not a false positive.
115
116
  HEREDOC_OPEN = /
116
117
  << (-)? # $1 = float
117
118
  (?:
118
- ( #{IDENT} ) # $2 = delim
119
+ ( [A-Za-z_0-9]+ ) # $2 = delim
119
120
  |
120
121
  ( ["'`\/] ) # $3 = quote, type
121
122
  ( [^\n]*? ) \3 # $4 = delim
@@ -134,6 +135,8 @@ module Scanners
134
135
  (?: \Z | (?=^\#CODE) )
135
136
  /mx
136
137
 
138
+ RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo
139
+
137
140
  # Checks for a valid value to follow. This enables
138
141
  # value_expected in method calls without parentheses.
139
142
  VALUE_FOLLOWS = /
@@ -144,7 +147,7 @@ module Scanners
144
147
  | [-+] \d
145
148
  | #{CHARACTER}
146
149
  )
147
- /x
150
+ /ox
148
151
  KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[
149
152
  and end in or unless begin
150
153
  defined? ensure redo super until
@@ -153,89 +156,20 @@ module Scanners
153
156
  while elsif if not return
154
157
  yield
155
158
  ])
156
-
157
- RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo
158
-
159
- RDOC_DATA_START = / ^=begin (?!\S) | ^__END__$ /x
160
-
161
- FANCY_START_CORRECT = / % ( [qQwWxsr] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /mx
162
-
163
- FancyStringType = {
164
- 'q' => [:string, false],
165
- 'Q' => [:string, true],
166
- 'r' => [:regexp, true],
167
- 's' => [:symbol, false],
168
- 'x' => [:shell, true]
169
- }
170
- FancyStringType['w'] = FancyStringType['q']
171
- FancyStringType['W'] = FancyStringType[''] = FancyStringType['Q']
172
-
173
- class StringState < Struct.new :type, :interpreted, :delim, :heredoc,
174
- :paren, :paren_depth, :pattern, :next_state
175
-
176
- CLOSING_PAREN = Hash[ *%w[
177
- ( )
178
- [ ]
179
- < >
180
- { }
181
- ] ]
182
-
183
- CLOSING_PAREN.each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with <<
184
- OPENING_PAREN = CLOSING_PAREN.invert
185
-
186
- STRING_PATTERN = Hash.new do |h, k|
187
- delim, interpreted = *k
188
- delim_pattern = Regexp.escape(delim.dup) # dup: workaround for old Ruby
189
- if closing_paren = CLOSING_PAREN[delim]
190
- delim_pattern = delim_pattern[0..-1] if defined? JRUBY_VERSION # JRuby fix
191
- delim_pattern << Regexp.escape(closing_paren)
192
- end
193
- delim_pattern << '\\\\' unless delim == '\\'
194
-
195
- special_escapes =
196
- case interpreted
197
- when :regexp_symbols
198
- '| ' + REGEXP_SYMBOLS.source
199
- when :words
200
- '| \s'
201
- end
202
-
203
- h[k] =
204
- if interpreted and not delim == '#'
205
- / (?= [#{delim_pattern}] | \# [{$@] #{special_escapes} ) /mx
206
- else
207
- / (?= [#{delim_pattern}] #{special_escapes} ) /mx
208
- end
209
- end
210
-
211
- HEREDOC_PATTERN = Hash.new do |h, k|
212
- delim, interpreted, indented = *k
213
- delim_pattern = Regexp.escape(delim.dup) # dup: workaround for old Ruby
214
- delim_pattern = / \n #{ '(?>[\ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
215
- h[k] =
216
- if interpreted
217
- / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc
218
- else
219
- / (?= #{delim_pattern}() | \\ ) /mx
220
- end
221
- end
222
-
223
- def initialize kind, interpreted, delim, heredoc = false
224
- if heredoc
225
- pattern = HEREDOC_PATTERN[ [delim, interpreted, heredoc == :indented] ]
226
- delim = nil
227
- else
228
- pattern = STRING_PATTERN[ [delim, interpreted] ]
229
- if paren = CLOSING_PAREN[delim]
230
- delim, paren = paren, delim
231
- paren_depth = 1
232
- end
233
- end
234
- super kind, interpreted, delim, heredoc, paren, paren_depth, pattern, :initial
235
- end
236
- end unless defined? StringState
237
-
159
+
160
+ FANCY_STRING_START = / % ( [QqrsWwx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x
161
+ FANCY_STRING_KIND = Hash.new(:string).merge({
162
+ 'r' => :regexp,
163
+ 's' => :symbol,
164
+ 'x' => :shell,
165
+ })
166
+ FANCY_STRING_INTERPRETED = Hash.new(true).merge({
167
+ 'q' => false,
168
+ 's' => false,
169
+ 'w' => false,
170
+ })
171
+
238
172
  end
239
-
173
+
240
174
  end
241
175
  end
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+ module CodeRay
3
+ module Scanners
4
+
5
+ class Ruby
6
+
7
+ class StringState < Struct.new :type, :interpreted, :delim, :heredoc,
8
+ :opening_paren, :paren_depth, :pattern, :next_state # :nodoc: all
9
+
10
+ CLOSING_PAREN = Hash[ *%w[
11
+ ( )
12
+ [ ]
13
+ < >
14
+ { }
15
+ ] ].each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with <<
16
+
17
+ STRING_PATTERN = Hash.new do |h, k|
18
+ delim, interpreted = *k
19
+ # delim = delim.dup # workaround for old Ruby
20
+ delim_pattern = Regexp.escape(delim)
21
+ if closing_paren = CLOSING_PAREN[delim]
22
+ delim_pattern << Regexp.escape(closing_paren)
23
+ end
24
+ delim_pattern << '\\\\' unless delim == '\\'
25
+
26
+ # special_escapes =
27
+ # case interpreted
28
+ # when :regexp_symbols
29
+ # '| [|?*+(){}\[\].^$]'
30
+ # end
31
+
32
+ h[k] =
33
+ if interpreted && delim != '#'
34
+ / (?= [#{delim_pattern}] | \# [{$@] ) /mx
35
+ else
36
+ / (?= [#{delim_pattern}] ) /mx
37
+ end
38
+ end
39
+
40
+ def initialize kind, interpreted, delim, heredoc = false
41
+ if heredoc
42
+ pattern = heredoc_pattern delim, interpreted, heredoc == :indented
43
+ delim = nil
44
+ else
45
+ pattern = STRING_PATTERN[ [delim, interpreted] ]
46
+ if closing_paren = CLOSING_PAREN[delim]
47
+ opening_paren = delim
48
+ delim = closing_paren
49
+ paren_depth = 1
50
+ end
51
+ end
52
+ super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial
53
+ end
54
+
55
+ def heredoc_pattern delim, interpreted, indented
56
+ # delim = delim.dup # workaround for old Ruby
57
+ delim_pattern = Regexp.escape(delim)
58
+ delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
59
+ if interpreted
60
+ / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc
61
+ else
62
+ / (?= #{delim_pattern}() | \\ ) /mx
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
71
+ end
@@ -5,31 +5,49 @@ module CodeRay module Scanners
5
5
 
6
6
  register_for :sql
7
7
 
8
- RESERVED_WORDS = %w(
9
- and as avg before begin between by case collate columns create database
10
- databases delete distinct drop else end engine exists fields from full
11
- group having if index inner insert into is join key like not on or order
12
- outer primary prompt replace select set show table tables then trigger
13
- union update using values when where
8
+ KEYWORDS = %w(
9
+ all and any as before begin between by case check collate
10
+ each else end exists
11
+ for foreign from full group having if in inner is join
12
+ like not of on or order outer over references
13
+ then to union using values when where
14
+ left right distinct
15
+ )
16
+
17
+ OBJECTS = %w(
18
+ database databases table tables column columns fields index constraint
19
+ constraints transaction function procedure row key view trigger
20
+ )
21
+
22
+ COMMANDS = %w(
23
+ add alter comment create delete drop grant insert into select update set
24
+ show prompt begin commit rollback replace truncate
14
25
  )
15
26
 
16
27
  PREDEFINED_TYPES = %w(
17
- bigint bin binary bit blob bool boolean char date datetime decimal
18
- double enum float hex int integer longblob longtext mediumblob mediumint
19
- mediumtext oct smallint text time timestamp tinyblob tinyint tinytext
20
- unsigned varchar year
28
+ char varchar varchar2 enum binary text tinytext mediumtext
29
+ longtext blob tinyblob mediumblob longblob timestamp
30
+ date time datetime year double decimal float int
31
+ integer tinyint mediumint bigint smallint unsigned bit
32
+ bool boolean hex bin oct
21
33
  )
22
34
 
23
- PREDEFINED_FUNCTIONS = %w( sum cast abs pi count min max avg )
35
+ PREDEFINED_FUNCTIONS = %w( sum cast substring abs pi count min max avg now )
24
36
 
25
- DIRECTIVES = %w( auto_increment unique default charset )
37
+ DIRECTIVES = %w(
38
+ auto_increment unique default charset initially deferred
39
+ deferrable cascade immediate read write asc desc after
40
+ primary foreign return engine
41
+ )
26
42
 
27
43
  PREDEFINED_CONSTANTS = %w( null true false )
28
44
 
29
- IDENT_KIND = CaseIgnoringWordList.new(:ident).
30
- add(RESERVED_WORDS, :reserved).
31
- add(PREDEFINED_TYPES, :pre_type).
32
- add(PREDEFINED_CONSTANTS, :pre_constant).
45
+ IDENT_KIND = WordList::CaseIgnoring.new(:ident).
46
+ add(KEYWORDS, :keyword).
47
+ add(OBJECTS, :type).
48
+ add(COMMANDS, :class).
49
+ add(PREDEFINED_TYPES, :predefined_type).
50
+ add(PREDEFINED_CONSTANTS, :predefined_constant).
33
51
  add(PREDEFINED_FUNCTIONS, :predefined).
34
52
  add(DIRECTIVES, :directive)
35
53
 
@@ -38,58 +56,60 @@ module CodeRay module Scanners
38
56
 
39
57
  STRING_PREFIXES = /[xnb]|_\w+/i
40
58
 
41
- def scan_tokens tokens, options
59
+ def scan_tokens encoder, options
42
60
 
43
61
  state = :initial
44
62
  string_type = nil
45
63
  string_content = ''
64
+ name_expected = false
46
65
 
47
66
  until eos?
48
67
 
49
- kind = nil
50
- match = nil
51
-
52
68
  if state == :initial
53
69
 
54
- if scan(/ \s+ | \\\n /x)
55
- kind = :space
70
+ if match = scan(/ \s+ | \\\n /x)
71
+ encoder.text_token match, :space
56
72
 
57
- elsif scan(/(?:--\s?|#).*/)
58
- kind = :comment
73
+ elsif match = scan(/(?:--\s?|#).*/)
74
+ encoder.text_token match, :comment
59
75
 
60
- elsif scan(%r! /\* (?: .*? \*/ | .* ) !mx)
61
- kind = :comment
76
+ elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx)
77
+ encoder.text_token match, self[1] ? :directive : :comment
62
78
 
63
- elsif scan(/ [-+*\/=<>;,!&^|()\[\]{}~%] | \.(?!\d) /x)
64
- kind = :operator
79
+ elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x)
80
+ name_expected = true if match == '.' && check(/[A-Za-z_]/)
81
+ encoder.text_token match, :operator
65
82
 
66
- elsif scan(/(#{STRING_PREFIXES})?([`"'])/o)
83
+ elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o)
67
84
  prefix = self[1]
68
85
  string_type = self[2]
69
- tokens << [:open, :string]
70
- tokens << [prefix, :modifier] if prefix
86
+ encoder.begin_group :string
87
+ encoder.text_token prefix, :modifier if prefix
71
88
  match = string_type
72
89
  state = :string
73
- kind = :delimiter
90
+ encoder.text_token match, :delimiter
74
91
 
75
92
  elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9]* /x)
76
- kind = match[0] == ?@ ? :variable : IDENT_KIND[match.downcase]
93
+ encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match])
94
+ name_expected = false
77
95
 
78
- elsif scan(/0[xX][0-9A-Fa-f]+/)
79
- kind = :hex
96
+ elsif match = scan(/0[xX][0-9A-Fa-f]+/)
97
+ encoder.text_token match, :hex
80
98
 
81
- elsif scan(/0[0-7]+(?![89.eEfF])/)
82
- kind = :oct
99
+ elsif match = scan(/0[0-7]+(?![89.eEfF])/)
100
+ encoder.text_token match, :octal
83
101
 
84
- elsif scan(/(?>\d+)(?![.eEfF])/)
85
- kind = :integer
102
+ elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/)
103
+ encoder.text_token match, :integer
86
104
 
87
- elsif scan(/\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/)
88
- kind = :float
105
+ elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/)
106
+ encoder.text_token match, :float
107
+
108
+ elsif match = scan(/\\N/)
109
+ encoder.text_token match, :predefined_constant
89
110
 
90
111
  else
91
- getch
92
- kind = :error
112
+ encoder.text_token getch, :error
93
113
 
94
114
  end
95
115
 
@@ -104,54 +124,48 @@ module CodeRay module Scanners
104
124
  next
105
125
  end
106
126
  unless string_content.empty?
107
- tokens << [string_content, :content]
127
+ encoder.text_token string_content, :content
108
128
  string_content = ''
109
129
  end
110
- tokens << [matched, :delimiter]
111
- tokens << [:close, :string]
130
+ encoder.text_token match, :delimiter
131
+ encoder.end_group :string
112
132
  state = :initial
113
133
  string_type = nil
114
- next
115
134
  else
116
135
  string_content << match
117
136
  end
118
- next
119
- elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
137
+ elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
120
138
  unless string_content.empty?
121
- tokens << [string_content, :content]
139
+ encoder.text_token string_content, :content
122
140
  string_content = ''
123
141
  end
124
- kind = :char
142
+ encoder.text_token match, :char
125
143
  elsif match = scan(/ \\ . /mox)
126
144
  string_content << match
127
145
  next
128
- elsif scan(/ \\ | $ /x)
146
+ elsif match = scan(/ \\ | $ /x)
129
147
  unless string_content.empty?
130
- tokens << [string_content, :content]
148
+ encoder.text_token string_content, :content
131
149
  string_content = ''
132
150
  end
133
- kind = :error
151
+ encoder.text_token match, :error
134
152
  state = :initial
135
153
  else
136
- raise "else case \" reached; %p not handled." % peek(1), tokens
154
+ raise "else case \" reached; %p not handled." % peek(1), encoder
137
155
  end
138
156
 
139
157
  else
140
- raise 'else-case reached', tokens
158
+ raise 'else-case reached', encoder
141
159
 
142
160
  end
143
161
 
144
- match ||= matched
145
- unless kind
146
- raise_inspect 'Error token %p in line %d' %
147
- [[match, kind], line], tokens, state
148
- end
149
- raise_inspect 'Empty token', tokens unless match
150
-
151
- tokens << [match, kind]
152
-
153
162
  end
154
- tokens
163
+
164
+ if state == :string
165
+ encoder.end_group state
166
+ end
167
+
168
+ encoder
155
169
 
156
170
  end
157
171