coderay 1.0.0.800pre → 1.0.0.815pre

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