coderay-beta 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/FOLDERS +53 -0
  2. data/LICENSE +504 -0
  3. data/bin/coderay +82 -0
  4. data/bin/coderay_stylesheet +4 -0
  5. data/lib/README +129 -0
  6. data/lib/coderay.rb +320 -0
  7. data/lib/coderay/duo.rb +85 -0
  8. data/lib/coderay/encoder.rb +213 -0
  9. data/lib/coderay/encoders/_map.rb +11 -0
  10. data/lib/coderay/encoders/comment_filter.rb +43 -0
  11. data/lib/coderay/encoders/count.rb +21 -0
  12. data/lib/coderay/encoders/debug.rb +49 -0
  13. data/lib/coderay/encoders/div.rb +19 -0
  14. data/lib/coderay/encoders/filter.rb +75 -0
  15. data/lib/coderay/encoders/html.rb +305 -0
  16. data/lib/coderay/encoders/html/css.rb +70 -0
  17. data/lib/coderay/encoders/html/numerization.rb +133 -0
  18. data/lib/coderay/encoders/html/output.rb +206 -0
  19. data/lib/coderay/encoders/json.rb +69 -0
  20. data/lib/coderay/encoders/lines_of_code.rb +90 -0
  21. data/lib/coderay/encoders/null.rb +26 -0
  22. data/lib/coderay/encoders/page.rb +20 -0
  23. data/lib/coderay/encoders/span.rb +19 -0
  24. data/lib/coderay/encoders/statistic.rb +77 -0
  25. data/lib/coderay/encoders/term.rb +137 -0
  26. data/lib/coderay/encoders/text.rb +32 -0
  27. data/lib/coderay/encoders/token_class_filter.rb +84 -0
  28. data/lib/coderay/encoders/xml.rb +71 -0
  29. data/lib/coderay/encoders/yaml.rb +22 -0
  30. data/lib/coderay/for_redcloth.rb +85 -0
  31. data/lib/coderay/helpers/file_type.rb +240 -0
  32. data/lib/coderay/helpers/gzip_simple.rb +123 -0
  33. data/lib/coderay/helpers/plugin.rb +349 -0
  34. data/lib/coderay/helpers/word_list.rb +138 -0
  35. data/lib/coderay/scanner.rb +284 -0
  36. data/lib/coderay/scanners/_map.rb +23 -0
  37. data/lib/coderay/scanners/c.rb +203 -0
  38. data/lib/coderay/scanners/cpp.rb +228 -0
  39. data/lib/coderay/scanners/css.rb +210 -0
  40. data/lib/coderay/scanners/debug.rb +62 -0
  41. data/lib/coderay/scanners/delphi.rb +150 -0
  42. data/lib/coderay/scanners/diff.rb +105 -0
  43. data/lib/coderay/scanners/groovy.rb +263 -0
  44. data/lib/coderay/scanners/html.rb +182 -0
  45. data/lib/coderay/scanners/java.rb +176 -0
  46. data/lib/coderay/scanners/java/builtin_types.rb +419 -0
  47. data/lib/coderay/scanners/java_script.rb +224 -0
  48. data/lib/coderay/scanners/json.rb +112 -0
  49. data/lib/coderay/scanners/nitro_xhtml.rb +136 -0
  50. data/lib/coderay/scanners/php.rb +526 -0
  51. data/lib/coderay/scanners/plaintext.rb +21 -0
  52. data/lib/coderay/scanners/python.rb +285 -0
  53. data/lib/coderay/scanners/rhtml.rb +74 -0
  54. data/lib/coderay/scanners/ruby.rb +404 -0
  55. data/lib/coderay/scanners/ruby/patterns.rb +238 -0
  56. data/lib/coderay/scanners/scheme.rb +145 -0
  57. data/lib/coderay/scanners/sql.rb +162 -0
  58. data/lib/coderay/scanners/xml.rb +17 -0
  59. data/lib/coderay/scanners/yaml.rb +144 -0
  60. data/lib/coderay/style.rb +20 -0
  61. data/lib/coderay/styles/_map.rb +7 -0
  62. data/lib/coderay/styles/cycnus.rb +151 -0
  63. data/lib/coderay/styles/murphy.rb +132 -0
  64. data/lib/coderay/token_classes.rb +86 -0
  65. data/lib/coderay/tokens.rb +391 -0
  66. data/lib/term/ansicolor.rb +220 -0
  67. metadata +123 -0
@@ -0,0 +1,349 @@
1
+ module CodeRay
2
+
3
+ # = PluginHost
4
+ #
5
+ # A simple subclass plugin system.
6
+ #
7
+ # Example:
8
+ # class Generators < PluginHost
9
+ # plugin_path 'app/generators'
10
+ # end
11
+ #
12
+ # class Generator
13
+ # extend Plugin
14
+ # PLUGIN_HOST = Generators
15
+ # end
16
+ #
17
+ # class FancyGenerator < Generator
18
+ # register_for :fancy
19
+ # end
20
+ #
21
+ # Generators[:fancy] #-> FancyGenerator
22
+ # # or
23
+ # CodeRay.require_plugin 'Generators/fancy'
24
+ module PluginHost
25
+
26
+ # Raised if Encoders::[] fails because:
27
+ # * a file could not be found
28
+ # * the requested Encoder is not registered
29
+ PluginNotFound = Class.new Exception
30
+ HostNotFound = Class.new Exception
31
+
32
+ PLUGIN_HOSTS = []
33
+ PLUGIN_HOSTS_BY_ID = {} # dummy hash
34
+
35
+ # Loads all plugins using list and load.
36
+ def load_all
37
+ for plugin in list
38
+ load plugin
39
+ end
40
+ end
41
+
42
+ # Returns the Plugin for +id+.
43
+ #
44
+ # Example:
45
+ # yaml_plugin = MyPluginHost[:yaml]
46
+ def [] id, *args, &blk
47
+ plugin = validate_id(id)
48
+ begin
49
+ plugin = plugin_hash.[] plugin, *args, &blk
50
+ end while plugin.is_a? Symbol
51
+ plugin
52
+ end
53
+
54
+ # Alias for +[]+.
55
+ alias load []
56
+
57
+ def require_helper plugin_id, helper_name
58
+ path = path_to File.join(plugin_id, helper_name)
59
+ require path
60
+ end
61
+
62
+ class << self
63
+
64
+ # Adds the module/class to the PLUGIN_HOSTS list.
65
+ def extended mod
66
+ PLUGIN_HOSTS << mod
67
+ end
68
+
69
+ # Warns you that you should not #include this module.
70
+ def included mod
71
+ warn "#{name} should not be included. Use extend."
72
+ end
73
+
74
+ # Find the PluginHost for host_id.
75
+ def host_by_id host_id
76
+ unless PLUGIN_HOSTS_BY_ID.default_proc
77
+ ph = Hash.new do |h, a_host_id|
78
+ for host in PLUGIN_HOSTS
79
+ h[host.host_id] = host
80
+ end
81
+ h.fetch a_host_id, nil
82
+ end
83
+ PLUGIN_HOSTS_BY_ID.replace ph
84
+ end
85
+ PLUGIN_HOSTS_BY_ID[host_id]
86
+ end
87
+
88
+ end
89
+
90
+ # The path where the plugins can be found.
91
+ def plugin_path *args
92
+ unless args.empty?
93
+ @plugin_path = File.expand_path File.join(*args)
94
+ load_map
95
+ end
96
+ @plugin_path
97
+ end
98
+
99
+ # The host's ID.
100
+ #
101
+ # If PLUGIN_HOST_ID is not set, it is simply the class name.
102
+ def host_id
103
+ if self.const_defined? :PLUGIN_HOST_ID
104
+ self::PLUGIN_HOST_ID
105
+ else
106
+ name
107
+ end
108
+ end
109
+
110
+ # Map a plugin_id to another.
111
+ #
112
+ # Usage: Put this in a file plugin_path/_map.rb.
113
+ #
114
+ # class MyColorHost < PluginHost
115
+ # map :navy => :dark_blue,
116
+ # :maroon => :brown,
117
+ # :luna => :moon
118
+ # end
119
+ def map hash
120
+ for from, to in hash
121
+ from = validate_id from
122
+ to = validate_id to
123
+ plugin_hash[from] = to unless plugin_hash.has_key? from
124
+ end
125
+ end
126
+
127
+ # Define the default plugin to use when no plugin is found
128
+ # for a given id.
129
+ #
130
+ # See also map.
131
+ #
132
+ # class MyColorHost < PluginHost
133
+ # map :navy => :dark_blue
134
+ # default :gray
135
+ # end
136
+ def default id = nil
137
+ if id
138
+ id = validate_id id
139
+ plugin_hash[nil] = id
140
+ else
141
+ plugin_hash[nil]
142
+ end
143
+ end
144
+
145
+ # Every plugin must register itself for one or more
146
+ # +ids+ by calling register_for, which calls this method.
147
+ #
148
+ # See Plugin#register_for.
149
+ def register plugin, *ids
150
+ for id in ids
151
+ unless id.is_a? Symbol
152
+ raise ArgumentError,
153
+ "id must be a Symbol, but it was a #{id.class}"
154
+ end
155
+ plugin_hash[validate_id(id)] = plugin
156
+ end
157
+ end
158
+
159
+ # A Hash of plugion_id => Plugin pairs.
160
+ def plugin_hash
161
+ @plugin_hash ||= create_plugin_hash
162
+ end
163
+
164
+ # Returns an array of all .rb files in the plugin path.
165
+ #
166
+ # The extension .rb is not included.
167
+ def list
168
+ Dir[path_to('*')].select do |file|
169
+ File.basename(file)[/^(?!_)\w+\.rb$/]
170
+ end.map do |file|
171
+ File.basename file, '.rb'
172
+ end
173
+ end
174
+
175
+ # Makes a map of all loaded plugins.
176
+ def inspect
177
+ map = plugin_hash.dup
178
+ map.each do |id, plugin|
179
+ map[id] = plugin.to_s[/(?>\w+)$/]
180
+ end
181
+ "#{name}[#{host_id}]#{map.inspect}"
182
+ end
183
+
184
+ protected
185
+ # Created a new plugin list and stores it to @plugin_hash.
186
+ def create_plugin_hash
187
+ @plugin_hash =
188
+ Hash.new do |h, plugin_id|
189
+ id = validate_id(plugin_id)
190
+ path = path_to id
191
+ begin
192
+ require path
193
+ rescue LoadError => boom
194
+ if h.has_key? nil # default plugin
195
+ h[id] = h[nil]
196
+ else
197
+ raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom]
198
+ end
199
+ else
200
+ # Plugin should have registered by now
201
+ unless h.has_key? id
202
+ raise PluginNotFound,
203
+ "No #{self.name} plugin for #{id.inspect} found in #{path}."
204
+ end
205
+ end
206
+ h[id]
207
+ end
208
+ end
209
+
210
+ # Loads the map file (see map).
211
+ #
212
+ # This is done automatically when plugin_path is called.
213
+ def load_map
214
+ mapfile = path_to '_map'
215
+ if File.exist? mapfile
216
+ require mapfile
217
+ elsif $DEBUG
218
+ warn 'no _map.rb found for %s' % name
219
+ end
220
+ end
221
+
222
+ # Returns the Plugin for +id+.
223
+ # Use it like Hash#fetch.
224
+ #
225
+ # Example:
226
+ # yaml_plugin = MyPluginHost[:yaml, :default]
227
+ def fetch id, *args, &blk
228
+ plugin_hash.fetch validate_id(id), *args, &blk
229
+ end
230
+
231
+ # Returns the expected path to the plugin file for the given id.
232
+ def path_to plugin_id
233
+ File.join plugin_path, "#{plugin_id}.rb"
234
+ end
235
+
236
+ # Converts +id+ to a Symbol if it is a String,
237
+ # or returns +id+ if it already is a Symbol.
238
+ #
239
+ # Raises +ArgumentError+ for all other objects, or if the
240
+ # given String includes non-alphanumeric characters (\W).
241
+ def validate_id id
242
+ if id.is_a? Symbol or id.nil?
243
+ id
244
+ elsif id.is_a? String
245
+ if id[/\w+/] == id
246
+ id.downcase.to_sym
247
+ else
248
+ raise ArgumentError, "Invalid id: '#{id}' given."
249
+ end
250
+ else
251
+ raise ArgumentError,
252
+ "String or Symbol expected, but #{id.class} given."
253
+ end
254
+ end
255
+
256
+ end
257
+
258
+
259
+ # = Plugin
260
+ #
261
+ # Plugins have to include this module.
262
+ #
263
+ # IMPORTANT: use extend for this module.
264
+ #
265
+ # Example: see PluginHost.
266
+ module Plugin
267
+
268
+ def included mod
269
+ warn "#{name} should not be included. Use extend."
270
+ end
271
+
272
+ # Register this class for the given langs.
273
+ # Example:
274
+ # class MyPlugin < PluginHost::BaseClass
275
+ # register_for :my_id
276
+ # ...
277
+ # end
278
+ #
279
+ # See PluginHost.register.
280
+ def register_for *ids
281
+ plugin_host.register self, *ids
282
+ end
283
+
284
+ # Returns the title of the plugin, or sets it to the
285
+ # optional argument +title+.
286
+ def title title = nil
287
+ if title
288
+ @title = title.to_s
289
+ else
290
+ @title ||= name[/([^:]+)$/, 1]
291
+ end
292
+ end
293
+
294
+ # The host for this Plugin class.
295
+ def plugin_host host = nil
296
+ if host and not host.is_a? PluginHost
297
+ raise ArgumentError,
298
+ "PluginHost expected, but #{host.class} given."
299
+ end
300
+ self.const_set :PLUGIN_HOST, host if host
301
+ self::PLUGIN_HOST
302
+ end
303
+
304
+ # Require some helper files.
305
+ #
306
+ # Example:
307
+ #
308
+ # class MyPlugin < PluginHost::BaseClass
309
+ # register_for :my_id
310
+ # helper :my_helper
311
+ #
312
+ # The above example loads the file myplugin/my_helper.rb relative to the
313
+ # file in which MyPlugin was defined.
314
+ #
315
+ # You can also load a helper from a different plugin:
316
+ #
317
+ # helper 'other_plugin/helper_name'
318
+ def helper *helpers
319
+ for helper in helpers
320
+ if helper.is_a?(String) && helper[/\//]
321
+ self::PLUGIN_HOST.require_helper $`, $'
322
+ else
323
+ self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
324
+ end
325
+ end
326
+ end
327
+
328
+ # Returns the pulgin id used by the engine.
329
+ def plugin_id
330
+ name[/\w+$/].downcase
331
+ end
332
+
333
+ end
334
+
335
+ # Convenience method for plugin loading.
336
+ # The syntax used is:
337
+ #
338
+ # CodeRay.require_plugin '<Host ID>/<Plugin ID>'
339
+ #
340
+ # Returns the loaded plugin.
341
+ def self.require_plugin path
342
+ host_id, plugin_id = path.split '/', 2
343
+ host = PluginHost.host_by_id(host_id)
344
+ raise PluginHost::HostNotFound,
345
+ "No host for #{host_id.inspect} found." unless host
346
+ host.load plugin_id
347
+ end
348
+
349
+ end
@@ -0,0 +1,138 @@
1
+ module CodeRay
2
+
3
+ # = WordList
4
+ #
5
+ # <b>A Hash subclass designed for mapping word lists to token types.</b>
6
+ #
7
+ # Copyright (c) 2006 by murphy (Kornelius Kalnbach) <murphy rubychan de>
8
+ #
9
+ # License:: LGPL / ask the author
10
+ # Version:: 1.1 (2006-Oct-19)
11
+ #
12
+ # A WordList is a Hash with some additional features.
13
+ # It is intended to be used for keyword recognition.
14
+ #
15
+ # WordList is highly optimized to be used in Scanners,
16
+ # typically to decide whether a given ident is a special token.
17
+ #
18
+ # For case insensitive words use CaseIgnoringWordList.
19
+ #
20
+ # Example:
21
+ #
22
+ # # define word arrays
23
+ # RESERVED_WORDS = %w[
24
+ # asm break case continue default do else
25
+ # ...
26
+ # ]
27
+ #
28
+ # PREDEFINED_TYPES = %w[
29
+ # int long short char void
30
+ # ...
31
+ # ]
32
+ #
33
+ # PREDEFINED_CONSTANTS = %w[
34
+ # EOF NULL ...
35
+ # ]
36
+ #
37
+ # # make a WordList
38
+ # IDENT_KIND = WordList.new(:ident).
39
+ # add(RESERVED_WORDS, :reserved).
40
+ # add(PREDEFINED_TYPES, :pre_type).
41
+ # add(PREDEFINED_CONSTANTS, :pre_constant)
42
+ #
43
+ # ...
44
+ #
45
+ # def scan_tokens tokens, options
46
+ # ...
47
+ #
48
+ # elsif scan(/[A-Za-z_][A-Za-z_0-9]*/)
49
+ # # use it
50
+ # kind = IDENT_KIND[match]
51
+ # ...
52
+ class WordList < Hash
53
+
54
+ # Creates a new WordList with +default+ as default value.
55
+ #
56
+ # You can activate +caching+ to store the results for every [] request.
57
+ #
58
+ # With caching, methods like +include?+ or +delete+ may no longer behave
59
+ # as you expect. Therefore, it is recommended to use the [] method only.
60
+ def initialize default = false, caching = false, &block
61
+ if block
62
+ raise ArgumentError, 'Can\'t combine block with caching.' if caching
63
+ super(&block)
64
+ else
65
+ if caching
66
+ super() do |h, k|
67
+ h[k] = h.fetch k, default
68
+ end
69
+ else
70
+ super default
71
+ end
72
+ end
73
+ end
74
+
75
+ # Add words to the list and associate them with +kind+.
76
+ #
77
+ # Returns +self+, so you can concat add calls.
78
+ def add words, kind = true
79
+ words.each do |word|
80
+ self[word] = kind
81
+ end
82
+ self
83
+ end
84
+
85
+ end
86
+
87
+
88
+ # A CaseIgnoringWordList is like a WordList, only that
89
+ # keys are compared case-insensitively.
90
+ #
91
+ # Ignoring the text case is realized by sending the +downcase+ message to
92
+ # all keys.
93
+ #
94
+ # Caching usually makes a CaseIgnoringWordList faster, but it has to be
95
+ # activated explicitely.
96
+ class CaseIgnoringWordList < WordList
97
+
98
+ # Creates a new case-insensitive WordList with +default+ as default value.
99
+ #
100
+ # You can activate caching to store the results for every [] request.
101
+ # This speeds up subsequent lookups for the same word, but also
102
+ # uses memory.
103
+ def initialize default = false, caching = false
104
+ if caching
105
+ super(default, false) do |h, k|
106
+ h[k] = h.fetch k.downcase, default
107
+ end
108
+ else
109
+ super(default, false)
110
+ extend Uncached
111
+ end
112
+ end
113
+
114
+ module Uncached # :nodoc:
115
+ def [] key
116
+ super(key.downcase)
117
+ end
118
+ end
119
+
120
+ # Add +words+ to the list and associate them with +kind+.
121
+ def add words, kind = true
122
+ words.each do |word|
123
+ self[word.downcase] = kind
124
+ end
125
+ self
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ __END__
133
+ # check memory consumption
134
+ END {
135
+ ObjectSpace.each_object(CodeRay::CaseIgnoringWordList) do |wl|
136
+ p wl.inject(0) { |memo, key, value| memo + key.size + 24 }
137
+ end
138
+ }