coderay 0.4.5.73 → 0.5.0.100
Sign up to get free protection for your applications and to get access to all the features.
- data/README +3 -2
- data/demo/demo_css.rb +1 -1
- data/demo/demo_load_encoder.rb +8 -0
- data/demo/demo_load_scanner.rb +25 -0
- data/demo/demo_more.rb +3 -2
- data/demo/suite.rb +82 -0
- data/lib/coderay.rb +8 -2
- data/lib/coderay/encoder.rb +1 -1
- data/lib/coderay/encoders/_map.rb +8 -0
- data/lib/coderay/encoders/div.rb +3 -1
- data/lib/coderay/encoders/html.rb +8 -5
- data/lib/coderay/encoders/{helpers/html_helper.rb → html/classes.rb} +1 -0
- data/lib/coderay/encoders/html/css.rb +66 -0
- data/lib/coderay/encoders/html/numerization.rb +112 -0
- data/lib/coderay/encoders/{helpers/html_output.rb → html/output.rb} +27 -90
- data/lib/coderay/encoders/span.rb +2 -1
- data/lib/coderay/encoders/statistic.rb +1 -1
- data/lib/coderay/helpers/plugin.rb +100 -88
- data/lib/coderay/helpers/word_list.rb +108 -0
- data/lib/coderay/scanner.rb +3 -3
- data/lib/coderay/scanners/_map.rb +10 -0
- data/lib/coderay/scanners/c.rb +1 -1
- data/lib/coderay/scanners/delphi.rb +1 -1
- data/lib/coderay/scanners/ruby.rb +1 -1
- data/lib/coderay/scanners/{helpers/ruby_helper.rb → ruby/patterns.rb} +0 -0
- data/lib/coderay/style.rb +20 -0
- data/lib/coderay/{encoders/helpers/html_css.rb → styles/cycnus.rb} +22 -59
- data/lib/coderay/styles/murphy.rb +119 -0
- data/lib/coderay/tokens.rb +1 -1
- metadata +23 -15
- data/lib/coderay/helpers/scanner_helper.rb +0 -63
@@ -13,7 +13,9 @@ module CodeRay
|
|
13
13
|
# TODO: more doc.
|
14
14
|
module Output
|
15
15
|
|
16
|
-
|
16
|
+
require 'coderay/encoders/html/numerization.rb'
|
17
|
+
|
18
|
+
attr_accessor :css
|
17
19
|
|
18
20
|
class << self
|
19
21
|
|
@@ -23,9 +25,10 @@ module CodeRay
|
|
23
25
|
#
|
24
26
|
# a = Output.new '<span class="co">Code</span>'
|
25
27
|
# a.wrap! :page
|
26
|
-
def new string, element = nil
|
28
|
+
def new string, css, element = nil
|
27
29
|
output = string.clone.extend self
|
28
30
|
output.wrapped_in = element
|
31
|
+
output.css = css
|
29
32
|
output
|
30
33
|
end
|
31
34
|
|
@@ -35,19 +38,19 @@ module CodeRay
|
|
35
38
|
warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
|
36
39
|
end
|
37
40
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
+
def make_stylesheet css, in_tag = false
|
42
|
+
sheet = css.stylesheet
|
43
|
+
sheet = <<-CSS if in_tag
|
41
44
|
<style type="text/css">
|
42
|
-
#{
|
45
|
+
#{sheet}
|
43
46
|
</style>
|
44
47
|
CSS
|
45
|
-
|
48
|
+
sheet
|
46
49
|
end
|
47
50
|
|
48
|
-
def page_template_for_css css
|
49
|
-
|
50
|
-
PAGE.apply 'CSS',
|
51
|
+
def page_template_for_css css
|
52
|
+
sheet = make_stylesheet css
|
53
|
+
PAGE.apply 'CSS', sheet
|
51
54
|
end
|
52
55
|
|
53
56
|
# Define a new wrapper. This is meta programming.
|
@@ -61,6 +64,7 @@ module CodeRay
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
end
|
67
|
+
|
64
68
|
end
|
65
69
|
|
66
70
|
wrapper :div, :span, :page
|
@@ -69,6 +73,11 @@ module CodeRay
|
|
69
73
|
wrapped_in == element
|
70
74
|
end
|
71
75
|
|
76
|
+
def wrapped_in
|
77
|
+
@wrapped_in ||= nil
|
78
|
+
end
|
79
|
+
attr_writer :wrapped_in
|
80
|
+
|
72
81
|
def wrap_in template
|
73
82
|
clone.wrap_in! template
|
74
83
|
end
|
@@ -90,7 +99,7 @@ module CodeRay
|
|
90
99
|
when :page
|
91
100
|
wrap! :div if wrapped_in? nil
|
92
101
|
raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
|
93
|
-
wrap_in! Output.page_template_for_css
|
102
|
+
wrap_in! Output.page_template_for_css(@css)
|
94
103
|
when nil
|
95
104
|
return self
|
96
105
|
else
|
@@ -104,84 +113,8 @@ module CodeRay
|
|
104
113
|
clone.wrap!(*args)
|
105
114
|
end
|
106
115
|
|
107
|
-
NUMERIZABLE_WRAPPINGS = {
|
108
|
-
:table => [:div, :page],
|
109
|
-
:inline => :all,
|
110
|
-
nil => :all
|
111
|
-
}
|
112
|
-
|
113
|
-
def numerize! mode = :table, options = {}
|
114
|
-
return self unless mode
|
115
|
-
|
116
|
-
options = DEFAULT_OPTIONS.merge options
|
117
|
-
|
118
|
-
start = options[:line_number_start]
|
119
|
-
unless start.is_a? Integer
|
120
|
-
raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
|
121
|
-
end
|
122
|
-
|
123
|
-
allowed_wrappings = NUMERIZABLE_WRAPPINGS[mode]
|
124
|
-
unless allowed_wrappings == :all or allowed_wrappings.include? options[:wrap]
|
125
|
-
raise ArgumentError, "Can't numerize, :wrap must be in %p, but is %p" % [NUMERIZABLE_WRAPPINGS, options[:wrap]]
|
126
|
-
end
|
127
|
-
|
128
|
-
bold_every = options[:bold_every]
|
129
|
-
bolding =
|
130
|
-
if bold_every == :no_bolding or bold_every == 0
|
131
|
-
proc { |line| line.to_s }
|
132
|
-
elsif bold_every.is_a? Integer
|
133
|
-
proc do |line|
|
134
|
-
if line % bold_every == 0
|
135
|
-
"<strong>#{line}</strong>" # every bold_every-th number in bold
|
136
|
-
else
|
137
|
-
line.to_s
|
138
|
-
end
|
139
|
-
end
|
140
|
-
else
|
141
|
-
raise ArgumentError, "Invalid value %p for :bolding; :no_bolding or Integer expected." % bolding
|
142
|
-
end
|
143
|
-
|
144
|
-
line_count = count("\n")
|
145
|
-
line_count += 1 if self[-1] != ?\n
|
146
|
-
|
147
|
-
case mode
|
148
|
-
when :inline
|
149
|
-
max_width = (start + line_count).to_s.size
|
150
|
-
line = start
|
151
|
-
gsub!(/^/) do
|
152
|
-
line_number = bolding.call line
|
153
|
-
line += 1
|
154
|
-
"<span class=\"no\">#{ line_number.rjust(max_width) }</span> "
|
155
|
-
end
|
156
|
-
#wrap! :div
|
157
|
-
|
158
|
-
when :table
|
159
|
-
# This is really ugly.
|
160
|
-
# Because even monospace fonts seem to have different heights when bold,
|
161
|
-
# I make the newline bold, both in the code and the line numbers.
|
162
|
-
# FIXME Still not working perfect for Mr. Internet Exploder
|
163
|
-
line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
|
164
|
-
line_numbers << "\n" # also for Mr. MS Internet Exploder :-/
|
165
|
-
line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
|
166
|
-
|
167
|
-
line_numbers_tpl = DIV_TABLE.apply('LINE_NUMBERS', line_numbers)
|
168
|
-
gsub!(/\n/) { "<tt>\n</tt>" }
|
169
|
-
wrap_in! line_numbers_tpl
|
170
|
-
@wrapped_in = :div
|
171
|
-
|
172
|
-
else
|
173
|
-
raise ArgumentError, "Unknown value %p for mode: :inline or :table expected" % mode
|
174
|
-
end
|
175
|
-
|
176
|
-
self
|
177
|
-
end
|
178
|
-
|
179
|
-
def numerize *args
|
180
|
-
clone.numerize!(*args)
|
181
|
-
end
|
182
|
-
|
183
116
|
def stylesheet in_tag = false
|
184
|
-
Output.
|
117
|
+
Output.make_stylesheet @css, in_tag
|
185
118
|
end
|
186
119
|
|
187
120
|
class Template < String
|
@@ -224,14 +157,18 @@ module CodeRay
|
|
224
157
|
</div>
|
225
158
|
DIV
|
226
159
|
|
227
|
-
|
160
|
+
TABLE = <<-`TABLE`
|
228
161
|
<table class="CodeRay"> <tr>
|
229
162
|
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
|
230
163
|
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
|
231
164
|
</tr> </table>
|
232
|
-
|
165
|
+
TABLE
|
233
166
|
# title="double click to expand"
|
234
167
|
|
168
|
+
LIST = <<-`LIST`
|
169
|
+
<ol class="CodeRay"><%CONTENT%></ol>
|
170
|
+
LIST
|
171
|
+
|
235
172
|
PAGE = <<-`PAGE`
|
236
173
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
237
174
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
@@ -64,7 +64,7 @@ Token Types (%d):
|
|
64
64
|
@type_stats.each do |type, stat|
|
65
65
|
stat.size /= stat.count.to_f
|
66
66
|
end
|
67
|
-
types_stats = @type_stats.sort_by { |k, v| -v.count }.map do |k, v|
|
67
|
+
types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v|
|
68
68
|
TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size]
|
69
69
|
end.join
|
70
70
|
STATS % [
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# = PluginHost
|
2
2
|
#
|
3
|
-
# $Id: plugin.rb
|
3
|
+
# $Id: plugin.rb 100 2005-12-10 04:20:30Z murphy $
|
4
4
|
#
|
5
5
|
# A simple subclass plugin system.
|
6
6
|
#
|
@@ -32,12 +32,42 @@ module PluginHost
|
|
32
32
|
PLUGIN_HOSTS = []
|
33
33
|
PLUGIN_HOSTS_BY_ID = {} # dummy hash
|
34
34
|
|
35
|
+
# Loads all plugins using all_plugin_names and load.
|
36
|
+
def load_all
|
37
|
+
for plugin in all_plugin_names
|
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
|
+
#$stderr.puts 'Loading helper: ' + path
|
60
|
+
require path
|
61
|
+
end
|
62
|
+
|
35
63
|
class << self
|
36
64
|
|
65
|
+
# Adds the module/class to the PLUGIN_HOSTS list.
|
37
66
|
def extended mod
|
38
67
|
PLUGIN_HOSTS << mod
|
39
68
|
end
|
40
69
|
|
70
|
+
# Warns you that you should not #include this module.
|
41
71
|
def included mod
|
42
72
|
warn "#{name} should not be included. Use extend."
|
43
73
|
end
|
@@ -58,17 +88,11 @@ module PluginHost
|
|
58
88
|
|
59
89
|
end
|
60
90
|
|
61
|
-
def plugin_host_id host_id
|
62
|
-
if host_id.is_a? String
|
63
|
-
raise ArgumentError,
|
64
|
-
"String or Symbol expected, but #{lang.class} given."
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
91
|
# The path where the plugins can be found.
|
69
92
|
def plugin_path *args
|
70
93
|
unless args.empty?
|
71
|
-
@plugin_path = File.join(*args)
|
94
|
+
@plugin_path = File.expand_path File.join(*args)
|
95
|
+
load_map
|
72
96
|
end
|
73
97
|
@plugin_path
|
74
98
|
end
|
@@ -84,6 +108,44 @@ module PluginHost
|
|
84
108
|
end
|
85
109
|
end
|
86
110
|
|
111
|
+
# Map a plugin_id to another.
|
112
|
+
#
|
113
|
+
# Usage: Put this in a file plugin_path/_map.rb.
|
114
|
+
#
|
115
|
+
# class MyColorHost < PluginHost
|
116
|
+
# map :navy => :dark_blue,
|
117
|
+
# :maroon => :brown,
|
118
|
+
# :luna => :moon
|
119
|
+
# end
|
120
|
+
def map hash
|
121
|
+
for from, to in hash
|
122
|
+
from = validate_id from
|
123
|
+
to = validate_id to
|
124
|
+
plugin_hash[from] = to unless plugin_hash.has_key? from
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Every plugin must register itself for one or more
|
129
|
+
# +ids+ by calling register_for, which calls this method.
|
130
|
+
#
|
131
|
+
# See Plugin#register_for.
|
132
|
+
def register plugin, *ids
|
133
|
+
for id in ids
|
134
|
+
unless id.is_a? Symbol
|
135
|
+
raise ArgumentError,
|
136
|
+
"id must be a Symbol, but it was a #{id.class}"
|
137
|
+
end
|
138
|
+
plugin_hash[validate_id(id)] = plugin
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# A Hash of plugion_id => Plugin pairs.
|
143
|
+
def plugin_hash
|
144
|
+
@plugin_hash ||= create_plugin_hash
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
# Created a new plugin list and stores it to @plugin_hash.
|
87
149
|
def create_plugin_hash
|
88
150
|
@plugin_hash =
|
89
151
|
Hash.new do |h, plugin_id|
|
@@ -105,54 +167,37 @@ module PluginHost
|
|
105
167
|
end
|
106
168
|
end
|
107
169
|
|
108
|
-
|
109
|
-
|
170
|
+
# Makes a map of all loaded scanners.
|
171
|
+
def inspect
|
172
|
+
map = plugin_hash.dup
|
173
|
+
map.each do |id, plugin|
|
174
|
+
map[id] = plugin.name[/(?>[\w_]+)$/]
|
175
|
+
end
|
176
|
+
map.inspect
|
110
177
|
end
|
111
178
|
|
112
|
-
|
113
|
-
# Every plugin must register itself for one or more
|
114
|
-
# +ids+ by calling register_for, which calls this method.
|
179
|
+
# Loads the map file (see map).
|
115
180
|
#
|
116
|
-
#
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
123
|
-
plugin_hash[validate_id(id)] = plugin
|
181
|
+
# This is done automatically when plaugin_path is called.
|
182
|
+
def load_map
|
183
|
+
begin
|
184
|
+
require path_to('_map')
|
185
|
+
rescue LoadError
|
186
|
+
warn 'no _map.rb found for %s' % name if $DEBUG
|
124
187
|
end
|
125
188
|
end
|
126
189
|
|
127
|
-
|
128
190
|
# Returns an array of all .rb files in the plugin path.
|
129
191
|
#
|
130
192
|
# The extension .rb is not included.
|
131
193
|
def all_plugin_names
|
132
|
-
Dir[path_to('*')].
|
194
|
+
Dir[path_to('*')].select do |file|
|
195
|
+
File.basename(file)[/^(?!_)\w+\.rb$/]
|
196
|
+
end.map do |file|
|
133
197
|
File.basename file, '.rb'
|
134
198
|
end
|
135
199
|
end
|
136
200
|
|
137
|
-
# Loads all plugins using all_plugin_names and load.
|
138
|
-
def load_all
|
139
|
-
for plugin in all_plugin_names
|
140
|
-
load_plugin plugin
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
# Returns the Plugin for +id+.
|
146
|
-
#
|
147
|
-
# Example:
|
148
|
-
# yaml_plugin = MyPluginHost[:yaml]
|
149
|
-
def [] id, *args, &blk
|
150
|
-
plugin_hash.[] validate_id(id), *args, &blk
|
151
|
-
end
|
152
|
-
|
153
|
-
# Alias for +[]+.
|
154
|
-
alias load []
|
155
|
-
|
156
201
|
# Returns the Plugin for +id+.
|
157
202
|
# Use it like Hash#fetch.
|
158
203
|
#
|
@@ -167,7 +212,7 @@ module PluginHost
|
|
167
212
|
File.join plugin_path, "#{plugin_id}.rb"
|
168
213
|
end
|
169
214
|
|
170
|
-
# Converts +id+ to a
|
215
|
+
# Converts +id+ to a Symbol if it is a String,
|
171
216
|
# or returns +id+ if it already is a Symbol.
|
172
217
|
#
|
173
218
|
# Raises +ArgumentError+ for all other objects, or if the
|
@@ -177,7 +222,7 @@ module PluginHost
|
|
177
222
|
id
|
178
223
|
elsif id.is_a? String
|
179
224
|
if id[/\w+/] == id
|
180
|
-
id.
|
225
|
+
id.to_sym
|
181
226
|
else
|
182
227
|
raise ArgumentError, "Invalid id: '#{id}' given."
|
183
228
|
end
|
@@ -225,6 +270,16 @@ module Plugin
|
|
225
270
|
self::PLUGIN_HOST
|
226
271
|
end
|
227
272
|
|
273
|
+
def helper *helpers
|
274
|
+
for helper in helpers
|
275
|
+
self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def plugin_id
|
280
|
+
name[/[\w_]+$/].downcase
|
281
|
+
end
|
282
|
+
|
228
283
|
end
|
229
284
|
|
230
285
|
|
@@ -241,46 +296,3 @@ def require_plugin path
|
|
241
296
|
"No host for #{host_id.inspect} found." unless host
|
242
297
|
host.load plugin_id
|
243
298
|
end
|
244
|
-
|
245
|
-
|
246
|
-
if $0 == __FILE__
|
247
|
-
$VERBOSE = $DEBUG = true
|
248
|
-
eval DATA.read, nil, $0, __LINE__+4
|
249
|
-
end
|
250
|
-
|
251
|
-
__END__
|
252
|
-
|
253
|
-
require 'test/unit'
|
254
|
-
|
255
|
-
class TC_PLUGINS < Test::Unit::TestCase
|
256
|
-
|
257
|
-
class Generators
|
258
|
-
extend PluginHost
|
259
|
-
plugin_path '.'
|
260
|
-
end
|
261
|
-
|
262
|
-
class Generator
|
263
|
-
extend Plugin
|
264
|
-
plugin_host Generators
|
265
|
-
end
|
266
|
-
|
267
|
-
class FancyGenerator < Generator
|
268
|
-
register_for :plugin_host
|
269
|
-
end
|
270
|
-
|
271
|
-
def test_plugin
|
272
|
-
assert_nothing_raised do
|
273
|
-
Generators[:plugin_host]
|
274
|
-
end
|
275
|
-
assert_equal FancyGenerator, Generators[:plugin_host]
|
276
|
-
end
|
277
|
-
|
278
|
-
def test_require
|
279
|
-
assert_nothing_raised do
|
280
|
-
require_plugin('TC_PLUGINS::Generators/plugin_host')
|
281
|
-
end
|
282
|
-
assert_equal FancyGenerator,
|
283
|
-
require_plugin('TC_PLUGINS::Generators/plugin_host')
|
284
|
-
end
|
285
|
-
|
286
|
-
end
|