blackwinter-ruby-nuggets 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +676 -0
- data/ChangeLog +5 -0
- data/README +60 -0
- data/Rakefile +20 -0
- data/lib/nuggets/all.rb +34 -0
- data/lib/nuggets/array/combination.rb +86 -0
- data/lib/nuggets/array/flatten_once.rb +68 -0
- data/lib/nuggets/array/format.rb +124 -0
- data/lib/nuggets/array/in_order.rb +62 -0
- data/lib/nuggets/array/monotone.rb +101 -0
- data/lib/nuggets/array/only.rb +56 -0
- data/lib/nuggets/array/rand.rb +45 -0
- data/lib/nuggets/array/shuffle.rb +133 -0
- data/lib/nuggets/array/to_hash.rb +86 -0
- data/lib/nuggets/enumerable/agrep.rb +82 -0
- data/lib/nuggets/enumerable/all_any_extended.rb +99 -0
- data/lib/nuggets/enumerable/minmax.rb +119 -0
- data/lib/nuggets/env/user_encoding.rb +53 -0
- data/lib/nuggets/env/user_home.rb +54 -0
- data/lib/nuggets/file/which.rb +74 -0
- data/lib/nuggets/hash/at.rb +87 -0
- data/lib/nuggets/hash/in_order.rb +52 -0
- data/lib/nuggets/hash/insert.rb +65 -0
- data/lib/nuggets/hash/only.rb +68 -0
- data/lib/nuggets/integer/factorial.rb +74 -0
- data/lib/nuggets/integer/to_binary_s.rb +47 -0
- data/lib/nuggets/io/agrep.rb +43 -0
- data/lib/nuggets/io/modes.rb +133 -0
- data/lib/nuggets/numeric/between.rb +2 -0
- data/lib/nuggets/numeric/duration.rb +109 -0
- data/lib/nuggets/numeric/limit.rb +70 -0
- data/lib/nuggets/numeric/signum.rb +60 -0
- data/lib/nuggets/numeric/to_multiple.rb +68 -0
- data/lib/nuggets/object/blank.rb +119 -0
- data/lib/nuggets/object/boolean.rb +69 -0
- data/lib/nuggets/object/eigenclass.rb +2 -0
- data/lib/nuggets/object/ghost_class.rb +2 -0
- data/lib/nuggets/object/metaclass.rb +2 -0
- data/lib/nuggets/object/msend.rb +55 -0
- data/lib/nuggets/object/singleton_class.rb +150 -0
- data/lib/nuggets/object/uniclass.rb +2 -0
- data/lib/nuggets/object/virtual_class.rb +2 -0
- data/lib/nuggets/proc/bind.rb +68 -0
- data/lib/nuggets/string/capitalize_first.rb +63 -0
- data/lib/nuggets/string/case.rb +104 -0
- data/lib/nuggets/string/evaluate.rb +53 -0
- data/lib/nuggets/string/msub.rb +82 -0
- data/lib/nuggets/string/nsub.rb +80 -0
- data/lib/nuggets/string/sub_with_md.rb +131 -0
- data/lib/nuggets/string/word_wrap.rb +111 -0
- data/lib/nuggets/tempfile/open.rb +54 -0
- data/lib/nuggets/uri/content_type.rb +65 -0
- data/lib/nuggets/uri/exist.rb +63 -0
- data/lib/nuggets/util/added_methods/init.rb +3 -0
- data/lib/nuggets/util/added_methods.rb +407 -0
- data/lib/nuggets/util/ansicolor2css.rb +90 -0
- data/lib/nuggets/util/content_type.rb +104 -0
- data/lib/nuggets/util/dotted_decimal.rb +66 -0
- data/lib/nuggets/util/i18n.rb +143 -0
- data/lib/nuggets/version.rb +27 -0
- data/lib/nuggets.rb +73 -0
- metadata +124 -0
@@ -0,0 +1,407 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-nuggets, some extensions to the Ruby programming #
|
5
|
+
# language. #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-nuggets is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'ruby2ruby'
|
30
|
+
rescue LoadError
|
31
|
+
end
|
32
|
+
|
33
|
+
module Util
|
34
|
+
|
35
|
+
# Watch for added methods and record them. Inspired by unroller,
|
36
|
+
# <http://unroller.rubyforge.org/classes/Unroller.html#M000034>.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# require 'rubygems'
|
41
|
+
# require 'nuggets/util/added_methods/init'
|
42
|
+
#
|
43
|
+
# require 'some/library/or/whatever'
|
44
|
+
#
|
45
|
+
# matches = Util::AddedMethods.find(
|
46
|
+
# :name => 'method_name',
|
47
|
+
# :class => SomeClass # optional
|
48
|
+
# )
|
49
|
+
#
|
50
|
+
# # get the class(es) where matching method(s) were defined
|
51
|
+
# matches.each { |am| puts am.klass # also am[:klass] or am[:class] }
|
52
|
+
#
|
53
|
+
# # assume the first one is the one we're looking for
|
54
|
+
# am = matches.first
|
55
|
+
#
|
56
|
+
# # is it a singleton method?
|
57
|
+
# puts am.singleton?
|
58
|
+
#
|
59
|
+
# # where exactly has it been defined?
|
60
|
+
# puts "#{am.file}, line #{am.line}"
|
61
|
+
#
|
62
|
+
# # now get its source
|
63
|
+
# puts am # implies #to_s, you can also call #extract_source directly
|
64
|
+
#
|
65
|
+
# TODO:
|
66
|
+
# - multi-line statements in irb w/o ruby2ruby? (=> extract_source)
|
67
|
+
# - polishing!
|
68
|
+
|
69
|
+
module AddedMethods
|
70
|
+
|
71
|
+
extend self
|
72
|
+
|
73
|
+
HISTFILENAME = '(Readline::HISTORY)'.freeze unless const_defined?(:HISTFILENAME)
|
74
|
+
|
75
|
+
class AddedMethod
|
76
|
+
|
77
|
+
attr_accessor :base, :klass, :name, :singleton, :file, :line, :def
|
78
|
+
|
79
|
+
def initialize(args = {})
|
80
|
+
args.each { |key, value|
|
81
|
+
send("#{key}=", value)
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
alias_method 'class=', 'klass='
|
86
|
+
alias_method :singleton?, :singleton
|
87
|
+
|
88
|
+
def [](key)
|
89
|
+
send(key.to_sym == :class ? :klass : key)
|
90
|
+
end
|
91
|
+
|
92
|
+
def source
|
93
|
+
@source ||= extract_source
|
94
|
+
end
|
95
|
+
|
96
|
+
def extract_source(num_lines = nil)
|
97
|
+
lines = extract_source_from_script_lines(num_lines)
|
98
|
+
|
99
|
+
# try to make sure we correctly extracted the method
|
100
|
+
# definition, otherwise try to get it from Ruby2Ruby
|
101
|
+
lines.first =~ /\b#{name}\b/ ? lines : extract_source_from_r2r || lines
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_s
|
105
|
+
str = "# File #{file}, line #{line}"
|
106
|
+
|
107
|
+
case lines = source
|
108
|
+
when Array
|
109
|
+
num = line - 1
|
110
|
+
width = (num + lines.size).to_s.length
|
111
|
+
|
112
|
+
lines.map! { |l| "%0#{width}d: %s" % [num += 1, l] }
|
113
|
+
|
114
|
+
"#{' ' * width} #{str}\n#{lines}"
|
115
|
+
when String
|
116
|
+
"#{str}#{lines}"
|
117
|
+
else
|
118
|
+
str
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def extract_source_from_script_lines(num_lines = nil)
|
125
|
+
return unless Object.const_defined?(:SCRIPT_LINES__)
|
126
|
+
return unless script_lines = SCRIPT_LINES__[file]
|
127
|
+
|
128
|
+
start, from, to = line - 1, line, script_lines.size - 1
|
129
|
+
|
130
|
+
# suppose we're already in a block
|
131
|
+
in_block = 1
|
132
|
+
|
133
|
+
num_lines ||= case definition = script_lines[start]
|
134
|
+
# def ... end, or do ... end style block
|
135
|
+
when /\b(?:def|do)\b/
|
136
|
+
definition =~ /\bend\b/ ? 1 : begin
|
137
|
+
from.upto(to) { |i|
|
138
|
+
case line = script_lines[i]
|
139
|
+
when /[^;\s]\s+(?:if|unless)\b/
|
140
|
+
# probably postfix conditional, ignore
|
141
|
+
when /\b(?:if|unless|while|until|def|do)\b/
|
142
|
+
in_block += 1
|
143
|
+
when /\bend\b/
|
144
|
+
in_block -= 1
|
145
|
+
end
|
146
|
+
|
147
|
+
break i - start + 1 if in_block.zero?
|
148
|
+
}
|
149
|
+
end
|
150
|
+
# { ... } style block
|
151
|
+
when /\bdefine_method\b/
|
152
|
+
from.upto(to) { |i|
|
153
|
+
line = script_lines[i]
|
154
|
+
|
155
|
+
in_block += line.count('{')
|
156
|
+
in_block -= line.count('}')
|
157
|
+
|
158
|
+
break i - start + 1 if in_block.zero?
|
159
|
+
}
|
160
|
+
else
|
161
|
+
1
|
162
|
+
end
|
163
|
+
|
164
|
+
script_lines[start, num_lines]
|
165
|
+
end
|
166
|
+
|
167
|
+
# Use Ruby2Ruby as a last resort. But note that it only
|
168
|
+
# ever finds the *latest*, i.e. currently active, method
|
169
|
+
# definition, not necessarily the one we're looking for.
|
170
|
+
def extract_source_from_r2r
|
171
|
+
if Object.const_defined?(:Ruby2Ruby)
|
172
|
+
" [R2R]\n#{Ruby2Ruby.translate(klass, name)}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
def init(regexp = nil, klasses = [], &block)
|
179
|
+
init_script_lines
|
180
|
+
patch_readline_history
|
181
|
+
|
182
|
+
define_callback(:__init, regexp, klasses, &block) if regexp
|
183
|
+
install_callbacks
|
184
|
+
end
|
185
|
+
|
186
|
+
def callbacks
|
187
|
+
init_callbacks
|
188
|
+
CALLBACKS
|
189
|
+
end
|
190
|
+
|
191
|
+
def callback(*args, &inner_block)
|
192
|
+
callback_args = [identify_added_method(*args << caller), caller, inner_block]
|
193
|
+
callbacks.each { |name, callback| callback[*callback_args] }
|
194
|
+
end
|
195
|
+
|
196
|
+
def define_callback(name, regexp = //, klasses = [], &outer_block)
|
197
|
+
raise TypeError, "wrong argument type #{name.class} (expected Symbol)" unless name.is_a?(Symbol)
|
198
|
+
raise "callback with name #{name} already exists" if callbacks.assoc(name)
|
199
|
+
|
200
|
+
raise TypeError, "wrong argument type #{regexp.class} (expected Regexp)" unless regexp.is_a?(Regexp)
|
201
|
+
raise TypeError, "wrong argument type #{klasses.class} (expected container object)" unless klasses.respond_to?(:empty?) && klasses.respond_to?(:include?)
|
202
|
+
|
203
|
+
callbacks << [name, lambda { |am, callstack, inner_block|
|
204
|
+
method, klass = am.name, am.klass
|
205
|
+
|
206
|
+
return if %w[method_added singleton_method_added].include?(method)
|
207
|
+
|
208
|
+
return unless klasses.empty? || klasses.include?(klass.to_s)
|
209
|
+
return unless method =~ regexp
|
210
|
+
|
211
|
+
if outer_block || inner_block
|
212
|
+
outer_block[am] if outer_block
|
213
|
+
inner_block[am] if inner_block
|
214
|
+
else
|
215
|
+
msg = "[#{am.base}] Adding #{'singleton ' if am.singleton?}method #{klass}##{method}"
|
216
|
+
|
217
|
+
msg << if irb?(callstack)
|
218
|
+
" in (irb:#{IRB.conf[:MAIN_CONTEXT].instance_variable_get(:@line_no)})"
|
219
|
+
else
|
220
|
+
" at #{where(callstack)}"
|
221
|
+
end
|
222
|
+
|
223
|
+
puts msg
|
224
|
+
end
|
225
|
+
}]
|
226
|
+
end
|
227
|
+
|
228
|
+
def remove_callback(name)
|
229
|
+
callbacks.delete_if { |n, _| n == name }
|
230
|
+
end
|
231
|
+
|
232
|
+
def replace_callback(name, regexp = nil, klasses = [], &outer_block)
|
233
|
+
remove_callback(name)
|
234
|
+
define_callback(name, regexp, klasses, &outer_block)
|
235
|
+
end
|
236
|
+
|
237
|
+
def install_callbacks(bases = [Object, Class, Module, Kernel])
|
238
|
+
bases.each { |base|
|
239
|
+
[base, singleton_class(base)].each { |b|
|
240
|
+
b.send(:define_method, :method_added) { |id| AddedMethods.callback(b, self, id, false) }
|
241
|
+
b.send(:define_method, :singleton_method_added) { |id| AddedMethods.callback(b, self, id, true) }
|
242
|
+
}
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
def all_methods
|
247
|
+
init_all_methods
|
248
|
+
ALL_METHODS
|
249
|
+
end
|
250
|
+
|
251
|
+
def find(conditions = {})
|
252
|
+
conditions = conditions.dup
|
253
|
+
|
254
|
+
class_condition = conditions.delete(:class)
|
255
|
+
file_condition = conditions.delete(:file)
|
256
|
+
|
257
|
+
results = []
|
258
|
+
|
259
|
+
all_methods.each { |klass, files|
|
260
|
+
if class_condition
|
261
|
+
next unless class_condition.is_a?(Array) ? class_condition.include?(klass) : klass == class_condition
|
262
|
+
end
|
263
|
+
|
264
|
+
files.each { |file, entries|
|
265
|
+
if file_condition
|
266
|
+
next unless file_condition.is_a?(Regexp) ? file =~ file_condition : file == file_condition
|
267
|
+
end
|
268
|
+
|
269
|
+
entries.each { |am|
|
270
|
+
results << am if conditions.all? { |key, value|
|
271
|
+
case value
|
272
|
+
when Array, Range: value.include?(am[key])
|
273
|
+
when Regexp: value =~ am[key].to_s
|
274
|
+
else value == am[key]
|
275
|
+
end
|
276
|
+
}
|
277
|
+
}
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
results
|
282
|
+
end
|
283
|
+
|
284
|
+
def find_by_class(*classes)
|
285
|
+
conditions = classes.last.is_a?(Hash) ? classes.pop : {}
|
286
|
+
find(conditions.merge(:class => classes))
|
287
|
+
end
|
288
|
+
|
289
|
+
def find_by_name(*names)
|
290
|
+
conditions = names.last.is_a?(Hash) ? names.pop : {}
|
291
|
+
find(conditions.merge(:name => names.map { |m| m.to_s }))
|
292
|
+
end
|
293
|
+
|
294
|
+
def find_one_by_name_or_class(name_or_class, conditions = {})
|
295
|
+
(name_or_class.is_a?(Class) ?
|
296
|
+
find_by_class(name_or_class) :
|
297
|
+
find_by_name(name_or_class)
|
298
|
+
).last
|
299
|
+
end
|
300
|
+
|
301
|
+
alias_method :[], :find_one_by_name_or_class
|
302
|
+
|
303
|
+
private
|
304
|
+
|
305
|
+
def singleton_class(klass = self)
|
306
|
+
class << klass; self; end
|
307
|
+
end
|
308
|
+
|
309
|
+
def init_script_lines
|
310
|
+
unless Object.const_defined?(:SCRIPT_LINES__)
|
311
|
+
Object.const_set(:SCRIPT_LINES__, {})
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def init_callbacks
|
316
|
+
unless const_defined?(:CALLBACKS)
|
317
|
+
const_set(:CALLBACKS, [])
|
318
|
+
define_callback(:__default, //, [], &added_method_callback)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def init_all_methods
|
323
|
+
unless const_defined?(:ALL_METHODS)
|
324
|
+
const_set(:ALL_METHODS, Hash.new { |h, k|
|
325
|
+
h[k] = Hash.new { |i, j| i[j] = [] }
|
326
|
+
})
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def patch_readline_history
|
331
|
+
return unless have_readline_history?
|
332
|
+
return if Readline::HISTORY.respond_to?(:_added_methods_original_push)
|
333
|
+
|
334
|
+
class << Readline::HISTORY
|
335
|
+
alias_method :_added_methods_original_push, :push
|
336
|
+
|
337
|
+
def push(l)
|
338
|
+
(SCRIPT_LINES__[HISTFILENAME] ||= Readline::HISTORY.to_a) << l
|
339
|
+
_added_methods_original_push(l)
|
340
|
+
end
|
341
|
+
|
342
|
+
alias_method :<<, :push
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def have_readline_history?
|
347
|
+
Object.const_defined?(:Readline) && Readline.const_defined?(:HISTORY)
|
348
|
+
end
|
349
|
+
|
350
|
+
def defined_in_irb?(callstack)
|
351
|
+
callstack = callstack.dup
|
352
|
+
|
353
|
+
callstack.shift # ignore immediate caller
|
354
|
+
callstack.reject! { |c| c =~ /\(irb\):|:in `irb_binding'/ }
|
355
|
+
callstack.pop if callstack.last =~ %r{/irb/workspace\.rb:}
|
356
|
+
|
357
|
+
callstack.empty?
|
358
|
+
end
|
359
|
+
|
360
|
+
def irb?(callstack)
|
361
|
+
have_readline_history? && defined_in_irb?(callstack)
|
362
|
+
end
|
363
|
+
|
364
|
+
def where(callstack, default = '(none):0')
|
365
|
+
callstack.find { |i| i !~ /:in `.*'/ } || callstack[1] || default
|
366
|
+
end
|
367
|
+
|
368
|
+
def added_method_callback
|
369
|
+
lambda { |am| add_method(am) }
|
370
|
+
end
|
371
|
+
|
372
|
+
def add_method(am)
|
373
|
+
am = AddedMethod.new(am) unless am.is_a?(AddedMethod)
|
374
|
+
all_methods[am.klass][am.file] << am
|
375
|
+
end
|
376
|
+
|
377
|
+
def identify_added_method(base, klass, id, singleton, callstack)
|
378
|
+
am = {
|
379
|
+
:base => base,
|
380
|
+
:class => klass,
|
381
|
+
:name => id.id2name,
|
382
|
+
:singleton => singleton
|
383
|
+
}
|
384
|
+
|
385
|
+
if irb?(callstack)
|
386
|
+
am.update(
|
387
|
+
:file => HISTFILENAME,
|
388
|
+
:line => Readline::HISTORY.size,
|
389
|
+
:def => begin Readline::HISTORY[-1] rescue IndexError end
|
390
|
+
)
|
391
|
+
else
|
392
|
+
file, line, _ = where(callstack).split(':')
|
393
|
+
line = line.to_i
|
394
|
+
|
395
|
+
am.update(
|
396
|
+
:file => file,
|
397
|
+
:line => line,
|
398
|
+
:def => (SCRIPT_LINES__[file] || [])[line - 1]
|
399
|
+
)
|
400
|
+
end
|
401
|
+
|
402
|
+
AddedMethod.new(am)
|
403
|
+
end
|
404
|
+
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-nuggets, some extensions to the Ruby programming #
|
5
|
+
# language. #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-nuggets is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
module Util
|
29
|
+
|
30
|
+
module ANSIColor2CSS
|
31
|
+
|
32
|
+
extend self
|
33
|
+
|
34
|
+
COLOUR_RE = %r{\e\[((?:[0-9]|[34][0-7])(?:;(?:[0-9]|[34][0-7]))*)m}
|
35
|
+
|
36
|
+
OPEN = '<span style="'.freeze
|
37
|
+
OPENC = '">'.freeze
|
38
|
+
CLOSE = '</span>'.freeze
|
39
|
+
|
40
|
+
ATTRIBUTES = {
|
41
|
+
'0' => CLOSE, # clear
|
42
|
+
'1' => 'font-weight: bold', # bold
|
43
|
+
'2' => '', # dark
|
44
|
+
'3' => 'font-style: italic', # italic -- not widely implemented
|
45
|
+
'4' => 'text-decoration: underline', # underline
|
46
|
+
'5' => 'text-decoration: blink', # blink
|
47
|
+
'6' => 'text-decoration: blink', # rapid blink -- not widely implemented
|
48
|
+
'7' => '', # negative
|
49
|
+
'8' => '', # concealed
|
50
|
+
'9' => 'text-decoration: line-through', # strikethrough -- not widely implemented
|
51
|
+
'30' => 'color: black', # black
|
52
|
+
'31' => 'color: red', # red
|
53
|
+
'32' => 'color: green', # green
|
54
|
+
'33' => 'color: yellow', # yellow
|
55
|
+
'34' => 'color: blue', # blue
|
56
|
+
'35' => 'color: magenta', # magenta
|
57
|
+
'36' => 'color: cyan', # cyan
|
58
|
+
'37' => 'color: white', # white
|
59
|
+
'40' => 'background-color: black', # on black
|
60
|
+
'41' => 'background-color: red', # on red
|
61
|
+
'42' => 'background-color: green', # on green
|
62
|
+
'43' => 'background-color: yellow', # on yellow
|
63
|
+
'44' => 'background-color: blue', # on blue
|
64
|
+
'45' => 'background-color: magenta', # on magenta
|
65
|
+
'46' => 'background-color: cyan', # on cyan
|
66
|
+
'47' => 'background-color: white' # on white
|
67
|
+
}
|
68
|
+
|
69
|
+
def convert(string)
|
70
|
+
string.gsub(COLOUR_RE) {
|
71
|
+
subst, attrs = '', $1.split(';')
|
72
|
+
|
73
|
+
subst << CLOSE if attrs.delete('0')
|
74
|
+
subst << OPEN << attrs.map { |c| ATTRIBUTES[c] }.join('; ') << OPENC unless attrs.empty?
|
75
|
+
|
76
|
+
subst
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
class String
|
85
|
+
|
86
|
+
def ansicolor2css
|
87
|
+
Util::ANSIColor2CSS.convert(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-nuggets, some extensions to the Ruby programming #
|
5
|
+
# language. #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-nuggets is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rubygems'
|
30
|
+
rescue LoadError
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'filemagic/ext'
|
35
|
+
rescue LoadError
|
36
|
+
def File.content_type(path) # :nodoc:
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
begin
|
42
|
+
require 'nuggets/uri/content_type'
|
43
|
+
rescue LoadError
|
44
|
+
module URI
|
45
|
+
def self.content_type(path) # :nodoc:
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
begin
|
52
|
+
require 'mime/types'
|
53
|
+
rescue LoadError
|
54
|
+
module MIME # :nodoc:
|
55
|
+
class Types # :nodoc:
|
56
|
+
def self.of(path)
|
57
|
+
[]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module Util
|
64
|
+
|
65
|
+
module ContentType
|
66
|
+
|
67
|
+
extend self
|
68
|
+
|
69
|
+
# call-seq:
|
70
|
+
# ContentType.of(path) => aString or nil
|
71
|
+
#
|
72
|
+
# Get the MIME-Type of the file living at +path+. Either by looking
|
73
|
+
# directly into the file (requires FileMagic), or, assuming +path+
|
74
|
+
# might denote a URI, by asking the web server (via OpenURI), or
|
75
|
+
# finally by just looking at the file extension (requires MIME::Types).
|
76
|
+
# Returns +nil+ in case no decision could be made.
|
77
|
+
#
|
78
|
+
# NOTE: This is really only useful with the filemagic and mime-types gems
|
79
|
+
# installed.
|
80
|
+
def of(path)
|
81
|
+
File.content_type(path) || URI.content_type(path) ||
|
82
|
+
((t = MIME::Types.of(path)).empty? ? nil : t.first.content_type)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
# Just a short-cut to make the code read nicer...
|
90
|
+
ContentType = Util::ContentType
|
91
|
+
|
92
|
+
if $0 == __FILE__
|
93
|
+
[
|
94
|
+
__FILE__,
|
95
|
+
'bla/blub.jpg',
|
96
|
+
'bla/blub.blob',
|
97
|
+
'http://www.google.de',
|
98
|
+
'http://blackwinter.de/misc/ww.png',
|
99
|
+
'http://blackwinter.de/misc/ww.jpg',
|
100
|
+
'http://blackwinter.de/bla/blub.blob'
|
101
|
+
].each { |f|
|
102
|
+
p [f, ContentType.of(f)]
|
103
|
+
}
|
104
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-nuggets, some extensions to the Ruby programming #
|
5
|
+
# language. #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-nuggets is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
require 'nuggets/integer/to_binary_s'
|
29
|
+
|
30
|
+
class Integer
|
31
|
+
|
32
|
+
# call-seq:
|
33
|
+
# int.to_dotted_decimal => aString
|
34
|
+
#
|
35
|
+
# Converts _int_ to dotted-decimal notation.
|
36
|
+
def to_dotted_decimal
|
37
|
+
to_binary_s(32).unpack('a8' * 4).map { |s| s.to_i(2) }.join('.')
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class String
|
43
|
+
|
44
|
+
# call-seq:
|
45
|
+
# str.from_dotted_decimal => anInteger
|
46
|
+
#
|
47
|
+
# Converts _str_ from dotted-decimal notation to integer.
|
48
|
+
def from_dotted_decimal
|
49
|
+
split('.').map { |i| i.to_i.to_binary_s(8) }.join.to_i(2)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
if $0 == __FILE__
|
55
|
+
[2294967042, 4294967040].each { |i|
|
56
|
+
p i.to_binary_s(32)
|
57
|
+
p i.to_dotted_decimal
|
58
|
+
}
|
59
|
+
|
60
|
+
puts '#' * 34
|
61
|
+
|
62
|
+
%w[77.47.161.3 196.101.53.1].each { |s|
|
63
|
+
p s
|
64
|
+
p s.from_dotted_decimal.to_binary_s(32)
|
65
|
+
}
|
66
|
+
end
|