coderay 0.9.8 → 1.0.0

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