coderay 1.0.0.800pre → 1.0.0.815pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/{README.rdoc → README_INDEX.rdoc} +2 -0
  2. data/Rakefile +3 -3
  3. data/bin/coderay +31 -9
  4. data/lib/coderay.rb +2 -1
  5. data/lib/coderay/encoder.rb +11 -1
  6. data/lib/coderay/encoders/_map.rb +0 -1
  7. data/lib/coderay/encoders/count.rb +9 -3
  8. data/lib/coderay/encoders/debug.rb +1 -1
  9. data/lib/coderay/encoders/filter.rb +12 -6
  10. data/lib/coderay/encoders/html.rb +11 -1
  11. data/lib/coderay/encoders/html/css.rb +1 -1
  12. data/lib/coderay/encoders/html/output.rb +0 -1
  13. data/lib/coderay/encoders/json.rb +20 -7
  14. data/lib/coderay/encoders/lines_of_code.rb +2 -1
  15. data/lib/coderay/encoders/statistic.rb +5 -6
  16. data/lib/coderay/encoders/text.rb +8 -5
  17. data/lib/coderay/encoders/token_kind_filter.rb +1 -0
  18. data/lib/coderay/encoders/xml.rb +5 -3
  19. data/lib/coderay/encoders/yaml.rb +13 -8
  20. data/lib/coderay/helpers/file_type.rb +4 -4
  21. data/lib/coderay/helpers/plugin.rb +7 -5
  22. data/lib/coderay/scanner.rb +30 -18
  23. data/lib/coderay/scanners/_map.rb +14 -13
  24. data/lib/coderay/scanners/clojure.rb +1 -1
  25. data/lib/coderay/scanners/css.rb +36 -27
  26. data/lib/coderay/scanners/{rhtml.rb → erb.rb} +3 -3
  27. data/lib/coderay/scanners/groovy.rb +1 -1
  28. data/lib/coderay/scanners/java_script.rb +1 -1
  29. data/lib/coderay/scanners/php.rb +2 -2
  30. data/lib/coderay/scanners/ruby.rb +11 -6
  31. data/lib/coderay/tokens.rb +1 -3
  32. data/test/functional/basic.rb +26 -19
  33. data/test/functional/examples.rb +2 -0
  34. data/test/functional/for_redcloth.rb +12 -6
  35. data/test/functional/suite.rb +2 -1
  36. metadata +26 -9
  37. data/lib/coderay/scanners/nitro_xhtml.rb +0 -136
  38. data/lib/coderay/scanners/scheme.rb +0 -136
@@ -90,7 +90,7 @@ module CodeRay
90
90
  'h' => :c,
91
91
  'htm' => :page,
92
92
  'html' => :page,
93
- 'html.erb' => :rhtml,
93
+ 'html.erb' => :erb,
94
94
  'java' => :java,
95
95
  'js' => :java_script,
96
96
  'json' => :json,
@@ -109,14 +109,14 @@ module CodeRay
109
109
  'raydebug' => :raydebug,
110
110
  'rb' => :ruby,
111
111
  'rbw' => :ruby,
112
- 'rhtml' => :rhtml,
112
+ 'rhtml' => :erb,
113
113
  'rjs' => :ruby,
114
114
  'rpdf' => :ruby,
115
115
  'ru' => :ruby,
116
116
  'rxml' => :ruby,
117
- 'sch' => :scheme,
117
+ # 'sch' => :scheme,
118
118
  'sql' => :sql,
119
- 'ss' => :scheme,
119
+ # 'ss' => :scheme,
120
120
  'xhtml' => :page,
121
121
  'xml' => :xml,
122
122
  'yaml' => :yaml,
@@ -114,9 +114,10 @@ module CodeRay
114
114
  def default id = nil
115
115
  if id
116
116
  id = validate_id id
117
- plugin_hash[nil] = id
117
+ raise "The default plugin can't be named \"default\"." if id == :default
118
+ plugin_hash[:default] = id
118
119
  else
119
- load nil
120
+ load :default
120
121
  end
121
122
  end
122
123
 
@@ -179,10 +180,11 @@ module CodeRay
179
180
  require path
180
181
  rescue LoadError => boom
181
182
  if @plugin_map_loaded
182
- if h.has_key?(nil) # default plugin
183
- h[nil]
183
+ if h.has_key?(:default)
184
+ warn '%p could not load plugin %p; falling back to %p' % [self, id, h[:default]]
185
+ h[:default]
184
186
  else
185
- raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom]
187
+ raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom]
186
188
  end
187
189
  else
188
190
  load_plugin_map
@@ -74,7 +74,7 @@ module CodeRay
74
74
  if code.respond_to? :encoding
75
75
  code = encode_with_encoding code, self.encoding
76
76
  else
77
- code = to_unix code if code.index ?\r
77
+ code = to_unix code
78
78
  end
79
79
  # code = code.dup if code.eql? original
80
80
  code
@@ -100,7 +100,7 @@ module CodeRay
100
100
  def encode_with_encoding code, target_encoding
101
101
  if code.encoding == target_encoding
102
102
  if code.valid_encoding?
103
- return to_unix(code)
103
+ return to_unix code
104
104
  else
105
105
  source_encoding = guess_encoding code
106
106
  end
@@ -112,7 +112,7 @@ module CodeRay
112
112
  end
113
113
 
114
114
  def to_unix code
115
- code.gsub(/\r\n?/, "\n")
115
+ code.index(?\r) ? code.gsub(/\r\n?/, "\n") : code
116
116
  end
117
117
 
118
118
  def guess_encoding s
@@ -221,27 +221,39 @@ module CodeRay
221
221
  end
222
222
  include Enumerable
223
223
 
224
- # The current line position of the scanner. See also #column.
224
+ # The current line position of the scanner, starting with 1.
225
+ # See also: #column.
225
226
  #
226
227
  # Beware, this is implemented inefficiently. It should be used
227
228
  # for debugging only.
228
- def line
229
- string[0..pos].count("\n") + 1
229
+ def line pos = self.pos
230
+ return 1 if pos <= 0
231
+ binary_string[0...pos].count("\n") + 1
230
232
  end
231
233
 
232
- # The current column position of the scanner. See also #line.
234
+ # The current column position of the scanner, starting with 1.
235
+ # See also: #line.
233
236
  #
234
237
  # Beware, this is implemented inefficiently. It should be used
235
238
  # for debugging only.
236
239
  def column pos = self.pos
237
- return 0 if pos <= 0
238
- string = self.string
239
- if string.respond_to?(:bytesize) && string.bytesize != string.size
240
- #:nocov:
241
- string = string.dup.force_encoding('binary')
242
- #:nocov:
243
- end
244
- pos - (string.rindex(?\n, pos) || 0)
240
+ return 1 if pos <= 0
241
+ pos - (binary_string.rindex(?\n, pos - 1) || -1)
242
+ end
243
+
244
+ # The string in binary encoding.
245
+ #
246
+ # To be used with #pos, which is the index of the byte the scanner
247
+ # will scan next.
248
+ def binary_string
249
+ @binary_string ||=
250
+ if string.respond_to?(:bytesize) && string.bytesize != string.size
251
+ #:nocov:
252
+ string.dup.force_encoding('binary')
253
+ #:nocov:
254
+ else
255
+ string
256
+ end
245
257
  end
246
258
 
247
259
  protected
@@ -267,7 +279,7 @@ module CodeRay
267
279
  def reset_instance
268
280
  @tokens.clear if @tokens.respond_to?(:clear) && !@options[:keep_tokens]
269
281
  @cached_tokens = nil
270
- @bin_string = nil if defined? @bin_string
282
+ @binary_string = nil if defined? @binary_string
271
283
  end
272
284
 
273
285
  # Scanner error with additional status information
@@ -297,8 +309,8 @@ surrounding code:
297
309
  tokens.respond_to?(:last) ? tokens.last(10).map { |t| t.inspect }.join("\n") : '',
298
310
  line, column, pos,
299
311
  matched, state, bol?, eos?,
300
- string[pos - ambit, ambit],
301
- string[pos, ambit],
312
+ binary_string[pos - ambit, ambit],
313
+ binary_string[pos, ambit],
302
314
  ], backtrace
303
315
  end
304
316
 
@@ -2,20 +2,21 @@ module CodeRay
2
2
  module Scanners
3
3
 
4
4
  map \
5
- :cplusplus => :cpp,
6
- :'c++' => :cpp,
7
- :ecmascript => :java_script,
5
+ :'c++' => :cpp,
6
+ :cplusplus => :cpp,
7
+ :ecmascript => :java_script,
8
8
  :ecma_script => :java_script,
9
- :irb => :ruby,
10
- :javascript => :java_script,
11
- :js => :java_script,
12
- :nitro => :nitro_xhtml,
13
- :pascal => :delphi,
14
- :patch => :diff,
15
- :plain => :text,
16
- :plaintext => :text,
17
- :xhtml => :html,
18
- :yml => :yaml
9
+ :rhtml => :erb,
10
+ :eruby => :erb,
11
+ :irb => :ruby,
12
+ :javascript => :java_script,
13
+ :js => :java_script,
14
+ :pascal => :delphi,
15
+ :patch => :diff,
16
+ :plain => :text,
17
+ :plaintext => :text,
18
+ :xhtml => :html,
19
+ :yml => :yaml
19
20
 
20
21
  default :text
21
22
 
@@ -156,7 +156,7 @@ module CodeRay
156
156
  elsif match = scan(/['`\(\[\)\]\{\}]|\#[({]|~@?|[@\^]/)
157
157
  encoder.text_token match, :operator
158
158
  elsif match = scan(/;.*/)
159
- encoder.text_token match, :comment # FIXME: recognize (comment ...) too
159
+ encoder.text_token match, :comment # TODO: recognize (comment ...) too
160
160
  elsif match = scan(/\#?\\(?:newline|space|.?)/)
161
161
  encoder.text_token match, :char
162
162
  elsif match = scan(/\#[ft]/)
@@ -2,9 +2,9 @@ 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,
@@ -20,28 +20,28 @@ module Scanners
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
43
  Function = /(?:url|alpha|attr|counters?)\((?:[^)\n\r\f]|\\\))*\)?/
44
-
44
+
45
45
  Id = /##{Name}/
46
46
  Class = /\.#{Name}/
47
47
  PseudoClass = /:#{Name}/
@@ -64,20 +64,26 @@ module Scanners
64
64
  when :initial, :media
65
65
  if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox)
66
66
  encoder.text_token match, :type
67
+ next
67
68
  elsif match = scan(RE::Class)
68
69
  encoder.text_token match, :class
70
+ next
69
71
  elsif match = scan(RE::Id)
70
72
  encoder.text_token match, :constant
73
+ next
71
74
  elsif match = scan(RE::PseudoClass)
72
75
  encoder.text_token match, :pseudo_class
76
+ next
73
77
  elsif match = scan(RE::AttributeSelector)
74
78
  # TODO: Improve highlighting inside of attribute selectors.
75
79
  encoder.text_token match[0,1], :operator
76
80
  encoder.text_token match[1..-2], :attribute_name if match.size > 2
77
81
  encoder.text_token match[-1,1], :operator if match[-1] == ?]
82
+ next
78
83
  elsif match = scan(/@media/)
79
84
  encoder.text_token match, :directive
80
85
  states.push :media_before_name
86
+ next
81
87
  end
82
88
 
83
89
  when :block
@@ -87,18 +93,21 @@ module Scanners
87
93
  else
88
94
  encoder.text_token match, :key
89
95
  end
96
+ next
90
97
  end
91
-
98
+
92
99
  when :media_before_name
93
100
  if match = scan(RE::Ident)
94
101
  encoder.text_token match, :type
95
102
  states[-1] = :media_after_name
103
+ next
96
104
  end
97
105
 
98
106
  when :media_after_name
99
107
  if match = scan(/\{/)
100
108
  encoder.text_token match, :operator
101
109
  states[-1] = :media
110
+ next
102
111
  end
103
112
 
104
113
  else
@@ -110,12 +119,12 @@ module Scanners
110
119
 
111
120
  elsif match = scan(/\/\*(?:.*?\*\/|\z)/m)
112
121
  encoder.text_token match, :comment
113
-
122
+
114
123
  elsif match = scan(/\{/)
115
124
  value_expected = false
116
125
  encoder.text_token match, :operator
117
126
  states.push :block
118
-
127
+
119
128
  elsif match = scan(/\}/)
120
129
  value_expected = false
121
130
  if states.last == :block || states.last == :media
@@ -124,14 +133,14 @@ module Scanners
124
133
  else
125
134
  encoder.text_token match, :error
126
135
  end
127
-
136
+
128
137
  elsif match = scan(/#{RE::String}/o)
129
138
  encoder.begin_group :string
130
139
  encoder.text_token match[0, 1], :delimiter
131
140
  encoder.text_token match[1..-2], :content if match.size > 2
132
141
  encoder.text_token match[-1, 1], :delimiter if match.size >= 2
133
142
  encoder.end_group :string
134
-
143
+
135
144
  elsif match = scan(/#{RE::Function}/o)
136
145
  encoder.begin_group :string
137
146
  start = match[/^\w+\(/]
@@ -143,22 +152,22 @@ module Scanners
143
152
  encoder.text_token match[start.size..-1], :content
144
153
  end
145
154
  encoder.end_group :string
146
-
155
+
147
156
  elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox)
148
157
  encoder.text_token match, :float
149
-
158
+
150
159
  elsif match = scan(/#{RE::Color}/o)
151
160
  encoder.text_token match, :color
152
-
161
+
153
162
  elsif match = scan(/! *important/)
154
163
  encoder.text_token match, :important
155
-
164
+
156
165
  elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/)
157
166
  encoder.text_token match, :color
158
-
167
+
159
168
  elsif match = scan(RE::AtKeyword)
160
169
  encoder.text_token match, :directive
161
-
170
+
162
171
  elsif match = scan(/ [+>:;,.=()\/] /x)
163
172
  if match == ':'
164
173
  value_expected = true
@@ -166,18 +175,18 @@ module Scanners
166
175
  value_expected = false
167
176
  end
168
177
  encoder.text_token match, :operator
169
-
178
+
170
179
  else
171
180
  encoder.text_token getch, :error
172
-
181
+
173
182
  end
174
-
183
+
175
184
  end
176
-
185
+
177
186
  encoder
178
187
  end
179
-
188
+
180
189
  end
181
-
190
+
182
191
  end
183
192
  end
@@ -5,9 +5,9 @@ module Scanners
5
5
  load :ruby
6
6
 
7
7
  # Scanner for HTML ERB templates.
8
- class RHTML < Scanner
8
+ class ERB < Scanner
9
9
 
10
- register_for :rhtml
10
+ register_for :erb
11
11
  title 'HTML ERB Template'
12
12
 
13
13
  KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
@@ -56,7 +56,7 @@ module Scanners
56
56
  if start_tag[/\A<%#/]
57
57
  encoder.text_token code, :comment
58
58
  else
59
- @ruby_scanner.tokenize code
59
+ @ruby_scanner.tokenize code, :tokens => encoder
60
60
  end unless code.empty?
61
61
  encoder.text_token end_tag, :inline_delimiter unless end_tag.empty?
62
62
  encoder.end_group :inline
@@ -220,7 +220,7 @@ module Scanners
220
220
  encoder.text_token match, :content
221
221
 
222
222
  elsif match = scan(/ \\. /mx)
223
- encoder.text_token match, :content # FIXME: Shouldn't this be :error?
223
+ encoder.text_token match, :content # TODO: Shouldn't this be :error?
224
224
 
225
225
  elsif match = scan(/ \\ | \n /x)
226
226
  encoder.end_group state
@@ -89,7 +89,7 @@ module Scanners
89
89
  end
90
90
 
91
91
  elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim)
92
- # FIXME: scan over nested tags
92
+ # TODO: scan over nested tags
93
93
  xml_scanner.tokenize match, :tokens => encoder
94
94
  value_expected = false
95
95
  next
@@ -234,8 +234,8 @@ module Scanners
234
234
  def scan_tokens encoder, options
235
235
 
236
236
  if check(RE::PHP_START) || # starts with <?
237
- (match?(/\s*<\S/) && exist?(RE::PHP_START)) || # starts with tag and contains <?
238
- exist?(RE::HTML_INDICATOR) ||
237
+ (match?(/\s*<\S/) && check(/.{1,1000}#{RE::PHP_START}/om)) || # starts with tag and contains <?
238
+ check(/.{0,1000}#{RE::HTML_INDICATOR}/om) ||
239
239
  check(/.{1,100}#{RE::PHP_START}/om) # PHP start after max 100 chars
240
240
  # is HTML with embedded PHP, so start with HTML
241
241
  states = [:initial]
@@ -26,7 +26,7 @@ module Scanners
26
26
  state, heredocs = @state
27
27
  heredocs = heredocs.dup if heredocs.is_a?(Array)
28
28
 
29
- if state && state.instance_of?(self.class::StringState)
29
+ if state && state.instance_of?(StringState)
30
30
  encoder.begin_group state.type
31
31
  end
32
32
 
@@ -426,13 +426,18 @@ module Scanners
426
426
  end
427
427
 
428
428
  # cleaning up
429
- if options[:keep_state]
430
- heredocs = nil if heredocs && heredocs.empty?
431
- @state = state, heredocs
429
+ if state.is_a? StringState
430
+ encoder.end_group state.type
432
431
  end
433
432
 
434
- if state.is_a? self.class::StringState
435
- encoder.end_group state.type
433
+ if options[:keep_state]
434
+ if state.is_a?(StringState) && state.heredoc
435
+ (heredocs ||= []).unshift state
436
+ state = :initial
437
+ elsif heredocs && heredocs.empty?
438
+ heredocs = nil
439
+ end
440
+ @state = state, heredocs
436
441
  end
437
442
 
438
443
  if inline_block_stack