coderay-beta 0.9.1

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