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