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
@@ -3,6 +3,7 @@ module Scanners
3
3
 
4
4
  module Java::BuiltinTypes # :nodoc:
5
5
 
6
+ #:nocov:
6
7
  List = %w[
7
8
  AbstractAction AbstractBorder AbstractButton AbstractCellEditor AbstractCollection
8
9
  AbstractColorChooserPanel AbstractDocument AbstractExecutorService AbstractInterruptibleChannel
@@ -412,6 +413,7 @@ module Scanners
412
413
  XPathFactoryConfigurationException XPathFunction XPathFunctionException XPathFunctionResolver
413
414
  XPathVariableResolver ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream ZoneView
414
415
  ]
416
+ #:nocov:
415
417
 
416
418
  end
417
419
 
@@ -1,28 +1,29 @@
1
1
  module CodeRay
2
2
  module Scanners
3
-
3
+
4
+ # Scanner for JavaScript.
5
+ #
6
+ # Aliases: +ecmascript+, +ecma_script+, +javascript+
4
7
  class JavaScript < Scanner
5
-
6
- include Streamable
7
-
8
+
8
9
  register_for :java_script
9
10
  file_extension 'js'
10
-
11
+
11
12
  # The actual JavaScript keywords.
12
13
  KEYWORDS = %w[
13
14
  break case catch continue default delete do else
14
15
  finally for function if in instanceof new
15
16
  return switch throw try typeof var void while with
16
- ]
17
+ ] # :nodoc:
17
18
  PREDEFINED_CONSTANTS = %w[
18
- false null true undefined
19
- ]
19
+ false null true undefined NaN Infinity
20
+ ] # :nodoc:
20
21
 
21
- MAGIC_VARIABLES = %w[ this arguments ] # arguments was introduced in JavaScript 1.4
22
+ MAGIC_VARIABLES = %w[ this arguments ] # :nodoc: arguments was introduced in JavaScript 1.4
22
23
 
23
24
  KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
24
25
  case delete in instanceof new return throw typeof with
25
- ]
26
+ ] # :nodoc:
26
27
 
27
28
  # Reserved for future use.
28
29
  RESERVED_WORDS = %w[
@@ -30,68 +31,66 @@ module Scanners
30
31
  final float goto implements import int interface long native package
31
32
  private protected public short static super synchronized throws transient
32
33
  volatile
33
- ]
34
+ ] # :nodoc:
34
35
 
35
36
  IDENT_KIND = WordList.new(:ident).
36
37
  add(RESERVED_WORDS, :reserved).
37
- add(PREDEFINED_CONSTANTS, :pre_constant).
38
+ add(PREDEFINED_CONSTANTS, :predefined_constant).
38
39
  add(MAGIC_VARIABLES, :local_variable).
39
- add(KEYWORDS, :keyword)
40
-
41
- ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
42
- UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
43
- REGEXP_ESCAPE = / [bBdDsSwW] /x
40
+ add(KEYWORDS, :keyword) # :nodoc:
41
+
42
+ ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
43
+ UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc:
44
+ REGEXP_ESCAPE = / [bBdDsSwW] /x # :nodoc:
44
45
  STRING_CONTENT_PATTERN = {
45
46
  "'" => /[^\\']+/,
46
47
  '"' => /[^\\"]+/,
47
48
  '/' => /[^\\\/]+/,
48
- }
49
+ } # :nodoc:
49
50
  KEY_CHECK_PATTERN = {
50
51
  "'" => / (?> [^\\']* (?: \\. [^\\']* )* ) ' \s* : /mx,
51
52
  '"' => / (?> [^\\"]* (?: \\. [^\\"]* )* ) " \s* : /mx,
52
- }
53
-
54
- def scan_tokens tokens, options
55
-
53
+ } # :nodoc:
54
+
55
+ protected
56
+
57
+ def scan_tokens encoder, options
58
+
56
59
  state = :initial
57
60
  string_delimiter = nil
58
61
  value_expected = true
59
62
  key_expected = false
60
63
  function_expected = false
61
-
64
+
62
65
  until eos?
63
-
64
- kind = nil
65
- match = nil
66
66
 
67
67
  case state
68
-
68
+
69
69
  when :initial
70
-
70
+
71
71
  if match = scan(/ \s+ | \\\n /x)
72
72
  value_expected = true if !value_expected && match.index(?\n)
73
- tokens << [match, :space]
74
- next
75
-
76
- elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
73
+ encoder.text_token match, :space
74
+
75
+ elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
77
76
  value_expected = true
78
- kind = :comment
79
-
77
+ encoder.text_token match, :comment
78
+
80
79
  elsif check(/\.?\d/)
81
80
  key_expected = value_expected = false
82
- if scan(/0[xX][0-9A-Fa-f]+/)
83
- kind = :hex
84
- elsif scan(/(?>0[0-7]+)(?![89.eEfF])/)
85
- kind = :oct
86
- elsif scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
87
- kind = :float
88
- elsif scan(/\d+/)
89
- kind = :integer
81
+ if match = scan(/0[xX][0-9A-Fa-f]+/)
82
+ encoder.text_token match, :hex
83
+ elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
84
+ encoder.text_token match, :octal
85
+ elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
86
+ encoder.text_token match, :float
87
+ elsif match = scan(/\d+/)
88
+ encoder.text_token match, :integer
90
89
  end
91
-
90
+
92
91
  elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim)
93
- # FIXME: scan over nested tags
94
- xml_scanner.tokenize match
92
+ # TODO: scan over nested tags
93
+ xml_scanner.tokenize match, :tokens => encoder
95
94
  value_expected = false
96
95
  next
97
96
 
@@ -100,12 +99,12 @@ module Scanners
100
99
  last_operator = match[-1]
101
100
  key_expected = (last_operator == ?{) || (last_operator == ?,)
102
101
  function_expected = false
103
- kind = :operator
104
-
105
- elsif scan(/ [)\]}]+ /x)
102
+ encoder.text_token match, :operator
103
+
104
+ elsif match = scan(/ [)\]}]+ /x)
106
105
  function_expected = key_expected = value_expected = false
107
- kind = :operator
108
-
106
+ encoder.text_token match, :operator
107
+
109
108
  elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x)
110
109
  kind = IDENT_KIND[match]
111
110
  value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
@@ -123,101 +122,91 @@ module Scanners
123
122
  end
124
123
  function_expected = (kind == :keyword) && (match == 'function')
125
124
  key_expected = false
126
-
125
+ encoder.text_token match, kind
126
+
127
127
  elsif match = scan(/["']/)
128
128
  if key_expected && check(KEY_CHECK_PATTERN[match])
129
129
  state = :key
130
130
  else
131
131
  state = :string
132
132
  end
133
- tokens << [:open, state]
133
+ encoder.begin_group state
134
134
  string_delimiter = match
135
- kind = :delimiter
136
-
137
- elsif value_expected && (match = scan(/\/(?=\S)/))
138
- tokens << [:open, :regexp]
135
+ encoder.text_token match, :delimiter
136
+
137
+ elsif value_expected && (match = scan(/\//))
138
+ encoder.begin_group :regexp
139
139
  state = :regexp
140
140
  string_delimiter = '/'
141
- kind = :delimiter
142
-
143
- elsif scan(/ \/ /x)
141
+ encoder.text_token match, :delimiter
142
+
143
+ elsif match = scan(/ \/ /x)
144
144
  value_expected = true
145
145
  key_expected = false
146
- kind = :operator
147
-
146
+ encoder.text_token match, :operator
147
+
148
148
  else
149
- getch
150
- kind = :error
151
-
149
+ encoder.text_token getch, :error
150
+
152
151
  end
153
-
152
+
154
153
  when :string, :regexp, :key
155
- if scan(STRING_CONTENT_PATTERN[string_delimiter])
156
- kind = :content
154
+ if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
155
+ encoder.text_token match, :content
157
156
  elsif match = scan(/["'\/]/)
158
- tokens << [match, :delimiter]
157
+ encoder.text_token match, :delimiter
159
158
  if state == :regexp
160
159
  modifiers = scan(/[gim]+/)
161
- tokens << [modifiers, :modifier] if modifiers && !modifiers.empty?
160
+ encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty?
162
161
  end
163
- tokens << [:close, state]
162
+ encoder.end_group state
164
163
  string_delimiter = nil
165
164
  key_expected = value_expected = false
166
165
  state = :initial
167
- next
168
166
  elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
169
167
  if string_delimiter == "'" && !(match == "\\\\" || match == "\\'")
170
- kind = :content
168
+ encoder.text_token match, :content
171
169
  else
172
- kind = :char
170
+ encoder.text_token match, :char
173
171
  end
174
- elsif state == :regexp && scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
175
- kind = :char
176
- elsif scan(/\\./m)
177
- kind = :content
178
- elsif scan(/ \\ | $ /x)
179
- tokens << [:close, state]
180
- kind = :error
172
+ elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
173
+ encoder.text_token match, :char
174
+ elsif match = scan(/\\./m)
175
+ encoder.text_token match, :content
176
+ elsif match = scan(/ \\ | $ /x)
177
+ encoder.end_group state
178
+ encoder.text_token match, :error
181
179
  key_expected = value_expected = false
182
180
  state = :initial
183
181
  else
184
- raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
182
+ raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
185
183
  end
186
-
184
+
187
185
  else
188
- raise_inspect 'Unknown state', tokens
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
186
+ raise_inspect 'Unknown state', encoder
187
+
196
188
  end
197
- raise_inspect 'Empty token', tokens unless match
198
189
 
199
- tokens << [match, kind]
200
-
201
190
  end
202
-
191
+
203
192
  if [:string, :regexp].include? state
204
- tokens << [:close, state]
193
+ encoder.end_group state
205
194
  end
206
-
207
- tokens
195
+
196
+ encoder
208
197
  end
209
-
198
+
210
199
  protected
211
-
200
+
212
201
  def reset_instance
213
202
  super
214
203
  @xml_scanner.reset if defined? @xml_scanner
215
204
  end
216
-
205
+
217
206
  def xml_scanner
218
207
  @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false
219
208
  end
220
-
209
+
221
210
  end
222
211
 
223
212
  end
@@ -1,22 +1,24 @@
1
1
  module CodeRay
2
2
  module Scanners
3
3
 
4
+ # Scanner for JSON (JavaScript Object Notation).
4
5
  class JSON < Scanner
5
6
 
6
- include Streamable
7
-
8
7
  register_for :json
9
8
  file_extension 'json'
10
9
 
11
10
  KINDS_NOT_LOC = [
12
11
  :float, :char, :content, :delimiter,
13
12
  :error, :integer, :operator, :value,
14
- ]
13
+ ] # :nodoc:
14
+
15
+ ESCAPE = / [bfnrt\\"\/] /x # :nodoc:
16
+ UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc:
15
17
 
16
- ESCAPE = / [bfnrt\\"\/] /x
17
- UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x
18
+ protected
18
19
 
19
- def scan_tokens tokens, options
20
+ # See http://json.org/ for a definition of the JSON lexic/grammar.
21
+ def scan_tokens encoder, options
20
22
 
21
23
  state = :initial
22
24
  stack = []
@@ -24,82 +26,67 @@ module Scanners
24
26
 
25
27
  until eos?
26
28
 
27
- kind = nil
28
- match = nil
29
-
30
29
  case state
31
30
 
32
31
  when :initial
33
- if match = scan(/ \s+ | \\\n /x)
34
- tokens << [match, :space]
35
- next
32
+ if match = scan(/ \s+ /x)
33
+ encoder.text_token match, :space
34
+ elsif match = scan(/"/)
35
+ state = key_expected ? :key : :string
36
+ encoder.begin_group state
37
+ encoder.text_token match, :delimiter
36
38
  elsif match = scan(/ [:,\[{\]}] /x)
37
- kind = :operator
39
+ encoder.text_token match, :operator
38
40
  case match
39
- when '{' then stack << :object; key_expected = true
40
- when '[' then stack << :array
41
41
  when ':' then key_expected = false
42
42
  when ',' then key_expected = true if stack.last == :object
43
+ when '{' then stack << :object; key_expected = true
44
+ when '[' then stack << :array
43
45
  when '}', ']' then stack.pop # no error recovery, but works for valid JSON
44
46
  end
45
47
  elsif match = scan(/ true | false | null /x)
46
- kind = :value
47
- elsif match = scan(/-?(?:0|[1-9]\d*)/)
48
- kind = :integer
49
- if scan(/\.\d+(?:[eE][-+]?\d+)?|[eE][-+]?\d+/)
48
+ encoder.text_token match, :value
49
+ elsif match = scan(/ -? (?: 0 | [1-9]\d* ) /x)
50
+ if scan(/ \.\d+ (?:[eE][-+]?\d+)? | [eE][-+]? \d+ /x)
50
51
  match << matched
51
- kind = :float
52
+ encoder.text_token match, :float
53
+ else
54
+ encoder.text_token match, :integer
52
55
  end
53
- elsif match = scan(/"/)
54
- state = key_expected ? :key : :string
55
- tokens << [:open, state]
56
- kind = :delimiter
57
56
  else
58
- getch
59
- kind = :error
57
+ encoder.text_token getch, :error
60
58
  end
61
59
 
62
60
  when :string, :key
63
- if scan(/[^\\"]+/)
64
- kind = :content
65
- elsif scan(/"/)
66
- tokens << ['"', :delimiter]
67
- tokens << [:close, state]
61
+ if match = scan(/[^\\"]+/)
62
+ encoder.text_token match, :content
63
+ elsif match = scan(/"/)
64
+ encoder.text_token match, :delimiter
65
+ encoder.end_group state
68
66
  state = :initial
69
- next
70
- elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
71
- kind = :char
72
- elsif scan(/\\./m)
73
- kind = :content
74
- elsif scan(/ \\ | $ /x)
75
- tokens << [:close, state]
76
- kind = :error
67
+ elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
68
+ encoder.text_token match, :char
69
+ elsif match = scan(/\\./m)
70
+ encoder.text_token match, :content
71
+ elsif match = scan(/ \\ | $ /x)
72
+ encoder.end_group state
73
+ encoder.text_token match, :error
77
74
  state = :initial
78
75
  else
79
- raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
76
+ raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
80
77
  end
81
78
 
82
79
  else
83
- raise_inspect 'Unknown state', tokens
80
+ raise_inspect 'Unknown state: %p' % [state], encoder
84
81
 
85
82
  end
86
-
87
- match ||= matched
88
- if $CODERAY_DEBUG and not kind
89
- raise_inspect 'Error token %p in line %d' %
90
- [[match, kind], line], tokens
91
- end
92
- raise_inspect 'Empty token', tokens unless match
93
-
94
- tokens << [match, kind]
95
-
96
83
  end
97
84
 
98
85
  if [:string, :key].include? state
99
- tokens << [:close, state]
86
+ encoder.end_group state
100
87
  end
101
88
 
102
- tokens
89
+ encoder
103
90
  end
104
91
 
105
92
  end