rmtools 1.1.11 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +16 -21
- data/README.txt +17 -5
- data/Rakefile +1 -1
- data/lib/rmtools/console/coloring.rb +58 -42
- data/lib/rmtools/console/highlight.rb +1 -1
- data/lib/rmtools/core/arguments.rb +7 -4
- data/lib/rmtools/core/js.rb +6 -5
- data/lib/rmtools/core/kernel.rb +37 -1
- data/lib/rmtools/core/module.rb +1 -1
- data/lib/rmtools/{debug → dev}/binding.rb +6 -6
- data/lib/rmtools/{experimental → dev}/blackhole.rb +0 -0
- data/lib/rmtools/dev/code_reader.rb +431 -0
- data/lib/rmtools/{debug → dev}/highlight.rb +2 -2
- data/lib/rmtools/{debug → dev}/logging.rb +44 -47
- data/lib/rmtools/{debug → dev}/observing.rb +8 -2
- data/lib/rmtools/dev/present.rb +63 -0
- data/lib/rmtools/{debug → dev}/timer.rb +3 -3
- data/lib/rmtools/{debug → dev}/trace_format.rb +3 -9
- data/lib/rmtools/{debug → dev}/traceback.rb +1 -1
- data/lib/rmtools/{debug.rb → dev.rb} +0 -0
- data/lib/rmtools/dev_min.rb +2 -0
- data/lib/rmtools/enumerable/array.rb +12 -1
- data/lib/rmtools/enumerable/array_iterators.rb +5 -3
- data/lib/rmtools/enumerable/common.rb +0 -2
- data/lib/rmtools/enumerable/hash.rb +10 -4
- data/lib/rmtools/enumerable/object_space.rb +11 -9
- data/lib/rmtools/enumerable/range.rb +21 -0
- data/lib/rmtools/fs/tools.rb +6 -2
- data/lib/rmtools/install.rb +4 -2
- data/lib/rmtools/lang/cyrillic.rb +2 -2
- data/lib/rmtools/lang/{shortcuts.rb → helpers.rb} +0 -0
- data/lib/rmtools/load.rb +1 -1
- data/lib/rmtools/text/regexp.rb +74 -0
- data/lib/rmtools/text/string_rtl.rb +28 -0
- data/lib/rmtools/text/string_scanner.rb +19 -9
- data/lib/rmtools/text/string_simple.rb +11 -3
- data/lib/rmtools/text/string_split.rb +1 -5
- data/lib/rmtools/xml/node.rb +1 -1
- data/lib/rmtools/xml/string.rb +2 -2
- data/lib/rmtools.rb +1 -8
- data/lib/rmtools_dev.rb +6 -0
- metadata +21 -26
- data/lib/rmtools/debug/present.rb +0 -39
- data/lib/rmtools/debug_notrace.rb +0 -2
- data/lib/rmtools/experimental/dumps.rb +0 -29
- data/lib/rmtools/experimental/numeric.rb +0 -54
- data/lib/rmtools/experimental/rails_backtrace.rb +0 -30
- data/lib/rmtools/experimental/string.rb +0 -56
- data/lib/rmtools/experimental/tree.rb +0 -72
- data/lib/rmtools/experimental.rb +0 -2
- data/lib/rmtools_nodebug.rb +0 -3
- data/lib/rmtools_notrace.rb +0 -7
- data/lib/rmtools_safe.rb +0 -2
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class Object
|
3
|
+
|
4
|
+
def present
|
5
|
+
[true, false, nil, Numeric, String, Regexp].each {|klass| return puts inspect if klass === self}
|
6
|
+
Hash[readable_variables.map {|v| [":#{v}", __send__(v)]}].present
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class Array
|
12
|
+
|
13
|
+
def present(inspect_string=nil)
|
14
|
+
res = "[ "
|
15
|
+
indent = (size-1).to_s.size
|
16
|
+
res << map_with_index {|k,i|
|
17
|
+
"#{i.to_s.rjust(indent)}: #{(k.is String and !inspect_string) ? k : k.inspect}"
|
18
|
+
}*"\n "
|
19
|
+
res << "]"
|
20
|
+
puts res
|
21
|
+
end
|
22
|
+
|
23
|
+
# draw array as box
|
24
|
+
# just calls #inspect if max element.inspect size is greater than console width
|
25
|
+
def as_box(opts={})
|
26
|
+
opts = {:max_cols => Inf, :padding => 0}.merge opts
|
27
|
+
return inspect unless cols = ENV['COLUMNS']
|
28
|
+
cols = cols.to_i
|
29
|
+
cell_size = map {|e| e.inspect.size}.max + opts[:padding]*2
|
30
|
+
if n = [(1..cols/2).max {|i| i*(cell_size+1) < cols}, opts[:max_cols]].min
|
31
|
+
table = div(n)
|
32
|
+
border = '+'+('-'*cell_size+'+')*n
|
33
|
+
need_lb = border.size < cols
|
34
|
+
border << "\n" if need_lb
|
35
|
+
last_border = table.last.size == n ?
|
36
|
+
border :
|
37
|
+
'+'+('-'*cell_size+'+')*table.last.size + '-'*((cell_size+1)*(n-table.last.size)-1) + '+'
|
38
|
+
table.map {|rows|
|
39
|
+
str = '|'+rows.map {|cell| cell.inspect.center(cell_size)}*'|'+'|'
|
40
|
+
str << ' '*((cell_size+1)*(n-rows.size)-1)+'|' if rows.size < n
|
41
|
+
border + str + ("\n" if need_lb)
|
42
|
+
}.join + last_border
|
43
|
+
else inspect
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Hash
|
50
|
+
|
51
|
+
def present(inspect_string=nil)
|
52
|
+
str = "{ "
|
53
|
+
sorted = sort rescue to_a.sort_by_to_s
|
54
|
+
str << sorted.map {|k,v|
|
55
|
+
"#{(k.is String and !inspect_string) ? k : k.inspect} => #{(v.is String and !inspect_string) ? v : v.inspect},"
|
56
|
+
}*"\n "
|
57
|
+
str << "}"
|
58
|
+
puts str
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
@@ -5,14 +5,14 @@ module RMTools
|
|
5
5
|
|
6
6
|
def timer(ts=1, output=true)
|
7
7
|
timez = ts - 1
|
8
|
-
|
9
|
-
$
|
8
|
+
quiet, mute_warn = $quiet, $log.mute_warn
|
9
|
+
$quiet = $log.mute_warn = true
|
10
10
|
t1 = Time.now
|
11
11
|
timez.times {yield}
|
12
12
|
res = yield
|
13
13
|
t2 = (Time.now.to_f*1000).round
|
14
14
|
t1 = (t1.to_f*1000).round
|
15
|
-
$
|
15
|
+
$quiet, $log.mute_warn = quiet, mute_warn
|
16
16
|
res = res.inspect
|
17
17
|
puts "#{output ? "res: #{res.size > 1000 ? res[0...1000]+"…" : res}\n" : "size of res string: #{res.to_s.size}, "}one: #{Painter.gray '%0.4fms'%[(t2-t1).to_f/ts]}, total: #{Painter.gray "#{(t2-t1).to_f}ms"}"
|
18
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
RMTools::require '
|
3
|
-
RMTools::require '
|
2
|
+
RMTools::require 'dev/highlight'
|
3
|
+
RMTools::require 'dev/logging'
|
4
4
|
|
5
5
|
module RMTools
|
6
6
|
|
@@ -21,15 +21,9 @@ module RMTools
|
|
21
21
|
# >> divbyzero
|
22
22
|
def format_trace(a)
|
23
23
|
bt, calls, i = [], [], 0
|
24
|
-
# $log.info 'a.size', binding
|
25
24
|
m = a[0].parse:caller
|
26
25
|
while i < a.size
|
27
|
-
# $log.info 'i a[i]', binding
|
28
26
|
m2 = a[i+1] && a[i+1].parse(:caller)
|
29
|
-
# $log.info 'm m2', binding
|
30
|
-
# $log.info 'm.func [m.path,m.line]==[m2.path,m2.line]', binding if m and m2
|
31
|
-
# $log.info 'm.path m.line a[i]', binding if m
|
32
|
-
# $log.info RMTools.highlighted_line(m.path, m.line) if m
|
33
27
|
if m and m.func and m2 and [m.path, m.line] == [m2.path, m2.line]
|
34
28
|
calls << " -> `#{m.func}'"
|
35
29
|
elsif m and m.line != 0 and line = RMTools.highlighted_line(m.path, m.line)
|
@@ -40,10 +34,10 @@ module RMTools
|
|
40
34
|
i += 1
|
41
35
|
m = m2
|
42
36
|
end
|
43
|
-
# $log << RMTools::Painter.r("FORMAT DONE! #{bt.size} lines formatted")
|
44
37
|
bt
|
45
38
|
end
|
46
39
|
|
40
|
+
# disclaimer: Firefox (at least 3.6+) on Windoze does not allow to use file:// protocol T_T
|
47
41
|
def format_trace_to_html(a)
|
48
42
|
a.map! do |lines|
|
49
43
|
caller_string, snippet = lines/"\n"
|
File without changes
|
@@ -105,10 +105,12 @@ class Array
|
|
105
105
|
# when [/\d/, '10']; '%*d'%[a, b]
|
106
106
|
# ...
|
107
107
|
# end
|
108
|
+
#
|
109
|
+
# symbol :~ stands for Object
|
108
110
|
def ===(obj)
|
109
111
|
return true if casecmp(obj)
|
110
112
|
!!(obj.kinda(Array) and obj.size == size and
|
111
|
-
each_with_index {|e, i| e ==
|
113
|
+
each_with_index {|e, i| e == :~ or e === obj[i] or return false})
|
112
114
|
end
|
113
115
|
|
114
116
|
|
@@ -131,4 +133,13 @@ class Array
|
|
131
133
|
# fastering activesupport's method
|
132
134
|
def group_by(&b) count(:group, &b) end
|
133
135
|
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
# rightmost #find
|
140
|
+
def rfind
|
141
|
+
reverse_each {|e| return e if yield e}
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
|
134
145
|
end
|
@@ -18,9 +18,11 @@ unless defined? RMTools::Iterators
|
|
18
18
|
|
19
19
|
def method_missing(method, *args, &block)
|
20
20
|
if match = (meth = method.to_s).match(RMTools::Iterators)
|
21
|
-
iterator, meth = match[1
|
22
|
-
|
23
|
-
|
21
|
+
iterator, meth = match[1], match[2].to_sym
|
22
|
+
begin
|
23
|
+
return iterator == :sum ?
|
24
|
+
__send__(iterator, args.shift) {|i| i.__send__ meth, *args, &block}:
|
25
|
+
__send__(iterator) {|i| i.__send__ meth, *args, &block}
|
24
26
|
rescue NoMethodError => e
|
25
27
|
e.message << " (`#{method}' interpreted as decorator-function `#{meth}')"
|
26
28
|
raise e
|
@@ -11,10 +11,11 @@ class Hash
|
|
11
11
|
if RUBY_VERSION >= '1.9.2'
|
12
12
|
def unify_keys
|
13
13
|
keys.each {|k|
|
14
|
-
|
14
|
+
case k
|
15
|
+
when String
|
15
16
|
sk = k.to_sym
|
16
17
|
self[sk] = self[k] if !self[sk]
|
17
|
-
|
18
|
+
when Symbol, Numeric
|
18
19
|
sk = k.to_s
|
19
20
|
self[sk] = self[k] if !self[sk]
|
20
21
|
end
|
@@ -24,16 +25,21 @@ if RUBY_VERSION >= '1.9.2'
|
|
24
25
|
else
|
25
26
|
def unify_keys
|
26
27
|
each {|k, v|
|
27
|
-
|
28
|
+
case k
|
29
|
+
when String
|
28
30
|
sk = k.to_sym
|
29
31
|
self[sk] = v if !self[sk]
|
30
|
-
|
32
|
+
when Symbol, Numeric
|
31
33
|
sk = k.to_s
|
32
34
|
self[sk] = v if !self[sk]
|
33
35
|
end
|
34
36
|
}
|
35
37
|
end
|
36
38
|
end
|
39
|
+
|
40
|
+
def any?
|
41
|
+
!empty?
|
42
|
+
end
|
37
43
|
|
38
44
|
def max_by_key; [(m = keys.max), self[m]] end
|
39
45
|
|
@@ -3,18 +3,20 @@ RMTools::require 'enumerable/common'
|
|
3
3
|
|
4
4
|
module ObjectSpace
|
5
5
|
extend Enumerable
|
6
|
+
class << self
|
6
7
|
|
7
|
-
|
8
|
+
def each(&b) each_object(&b) end
|
8
9
|
|
9
|
-
|
10
|
+
def size() each_object {} end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def find(id=nil)
|
13
|
+
if id
|
14
|
+
find {|obj| obj.object_id == id}
|
15
|
+
else
|
16
|
+
each_object {|obj| return obj if yield obj}
|
17
|
+
nil
|
18
|
+
end
|
17
19
|
end
|
20
|
+
|
18
21
|
end
|
19
|
-
|
20
22
|
end
|
@@ -99,6 +99,27 @@ class Range
|
|
99
99
|
ie*(ie+1)/2 - (1..self.begin-1).sum
|
100
100
|
end
|
101
101
|
|
102
|
+
# monotone function definition interval min/max border
|
103
|
+
def min(&fun)
|
104
|
+
return first if yield first
|
105
|
+
return unless yield last
|
106
|
+
if yield(c = center)
|
107
|
+
(first+1..c-1).min(&fun) || c
|
108
|
+
else
|
109
|
+
(c+1..last).min(&fun)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def max(&fun)
|
114
|
+
return last if yield last
|
115
|
+
return unless yield first
|
116
|
+
if yield(c = center)
|
117
|
+
(c+1..last-1).max(&fun) || c
|
118
|
+
else
|
119
|
+
(first..c-1).max(&fun)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
102
123
|
end
|
103
124
|
|
104
125
|
class XRange
|
data/lib/rmtools/fs/tools.rb
CHANGED
@@ -33,14 +33,18 @@ module RMTools
|
|
33
33
|
return if !lines or lines.empty?
|
34
34
|
str = ""
|
35
35
|
last = lines.max
|
36
|
+
lines_found = false
|
36
37
|
if File.file?(df)
|
37
38
|
File.open(df, 'r') {|f|
|
38
39
|
f.each {|line|
|
39
40
|
no = f.lineno
|
40
|
-
|
41
|
+
if no.in lines
|
42
|
+
str << line
|
43
|
+
lines_found = true
|
44
|
+
end
|
41
45
|
break if no == last
|
42
46
|
}}
|
43
|
-
str
|
47
|
+
lines_found && str
|
44
48
|
else
|
45
49
|
STDERR.puts "#{df} is missed!"
|
46
50
|
end
|
data/lib/rmtools/install.rb
CHANGED
@@ -8,10 +8,12 @@ def ext_files_not_modified(ext_name='rmtools', version='\d')
|
|
8
8
|
return unless gem
|
9
9
|
gemspec = gem[1]
|
10
10
|
path = gemspec.full_gem_path
|
11
|
-
gemspec.files.grep(/^ext\//).find {|f|
|
11
|
+
!gemspec.files.grep(/^ext\//).find {|f|
|
12
|
+
!(File.file?(installed=File.join(path, f)) and IO.read(f) == IO.read(installed))
|
13
|
+
}
|
12
14
|
end
|
13
15
|
|
14
|
-
def compile_manifest(exc
|
16
|
+
def compile_manifest(exc=%w(pkg))
|
15
17
|
fs = Dir.new('.').recursive_content
|
16
18
|
RMTools.rw 'Manifest.txt', (exc ? fs.reject {|i| i[/^(#{exc*'|'})\//]} : fs)*"\n"
|
17
19
|
end
|
@@ -14,7 +14,7 @@ class String
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def swap
|
17
|
-
sub(/([a-zA-Z])|([
|
17
|
+
sub(/([a-zA-Z])|([А-пр-ёЁ])/) {|m| return $~[1]? en2ru: ru2en}
|
18
18
|
self
|
19
19
|
end
|
20
20
|
|
@@ -23,7 +23,7 @@ class String
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def cyr?
|
26
|
-
self !~ /[
|
26
|
+
self !~ /[^А-пр-ёЁ]/
|
27
27
|
end
|
28
28
|
|
29
29
|
def csqueeze
|
File without changes
|
data/lib/rmtools/load.rb
CHANGED
@@ -6,7 +6,7 @@ module RMTools
|
|
6
6
|
|
7
7
|
require File.expand_path('require', dir)
|
8
8
|
[ 'core', 'enumerable', 'text', 'time', 'functional',
|
9
|
-
'conversions', 'ip', 'lang', 'rand',
|
9
|
+
'conversions', 'ip', 'lang', 'rand', 'console', 'b',
|
10
10
|
'fs', 'db', 'xml',
|
11
11
|
'../rmtools.so'
|
12
12
|
].each {|file| RMTools::require file}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
RMTools::require 'text/string_scanner'
|
2
|
+
|
3
|
+
class Regexp
|
4
|
+
|
5
|
+
# reverses a regexp just like an ordinal string so one can use it for lookbehind
|
6
|
+
# /abc(?=>d.+f){1,10}(?=>[^g+h-j]*\w+?)*?$/.reverse
|
7
|
+
### => /^(?=\w+?[^g+h-j]*>)*?(?=f.+d>){1,10}cba/
|
8
|
+
def reverse
|
9
|
+
return self if source.size == 1 or source.size == 2 && (source.ord == ?\\ or source[0] == source[1])
|
10
|
+
new = []
|
11
|
+
bs = klass = count = nil
|
12
|
+
group_marks = []
|
13
|
+
oppose = {'('=>')', ')'=>'(', '^'=>'$', '$'=>'^'}
|
14
|
+
borders = {'Z'=>'\A', 'A'=>'\Z'}
|
15
|
+
ext = options&2 != 0
|
16
|
+
StringScanner(source).each(/./) {|s|
|
17
|
+
if (m = s.matched) == '\\'
|
18
|
+
(klass || new) << '\\' if !(bs = !bs)
|
19
|
+
else
|
20
|
+
if bs
|
21
|
+
if !klass and m =~ /\d/
|
22
|
+
if m != '0' and s.+ !~ /\d/
|
23
|
+
raise RegexpError, "there is no meaning in use of groups \\#{m} inside of reversed regexp at #{s.pos-1}"
|
24
|
+
else
|
25
|
+
chars = s.check_until(/\D/)[0..-2]
|
26
|
+
new << ((m == '0' ? m : '0' << m) << chars).to_i(8).chr
|
27
|
+
s.pos += chars.size
|
28
|
+
end
|
29
|
+
elsif !klass and m == 'x'
|
30
|
+
chars = s.check_until(/[^a-f\d]/)[0..-2]
|
31
|
+
new << chars.to_i(16).chr
|
32
|
+
s.pos += chars.size
|
33
|
+
else
|
34
|
+
(klass || new) << ((b = borders[m]) ? b.dup : '\\' << m)
|
35
|
+
end
|
36
|
+
elsif ext and m =~ /\s/
|
37
|
+
next
|
38
|
+
elsif ext and m == '#'
|
39
|
+
s.scan_until(/\n\s*/)
|
40
|
+
else case m.ord
|
41
|
+
when ?[; klass = ''
|
42
|
+
when ?]; new << "[#{klass}]"; klass = nil
|
43
|
+
when ?{; klass ? klass << m : count = ''
|
44
|
+
when ?}; klass ? klass << m : _find_paren(new) << "{#{count}}"; count = nil
|
45
|
+
when ?^, ?$; klass ? klass << m : new << oppose[m]
|
46
|
+
when ?+, ?*; klass ? klass << m : _find_paren(new) << m
|
47
|
+
when ??
|
48
|
+
if new.last == ')'
|
49
|
+
group_marks << s.scan_until(/./)
|
50
|
+
else klass ? klass << m : _find_paren(new) << m
|
51
|
+
end
|
52
|
+
when ?)
|
53
|
+
gm = group_marks.pop
|
54
|
+
gm ? new << ('(?' << gm) : (klass || new) << '('
|
55
|
+
else (count || klass || new) << ((op = oppose[m]) ? op.dup : m)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
bs = false
|
59
|
+
end
|
60
|
+
}
|
61
|
+
new.reverse.join.to_re
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def _find_paren(new)
|
66
|
+
if new.last.ord == ?(
|
67
|
+
n = 0
|
68
|
+
new.rfind {|e| e.ord == ?( ? !(n+=1) : (e.ord == ?) && (n-=1) == 0)}
|
69
|
+
else
|
70
|
+
new.last
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
RMTools::require 'text/regexp'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# rightmost #sub
|
6
|
+
def rsub(from, to=nil, &block)
|
7
|
+
if block
|
8
|
+
reverse.sub(from.reverse) {|m| block[m.reverse].reverse}.reverse
|
9
|
+
else
|
10
|
+
q = to.scan(/\\\d(\D|$)/).size+1
|
11
|
+
to = to.reverse
|
12
|
+
to.gsub!(/(^|\D)(\d)\\/) {"#$1\\#{q-$2.to_i}"} if q > 1
|
13
|
+
reverse.sub(from.reverse, to).reverse
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# in-place #rsub
|
18
|
+
def rsub!(from, to=nil, &block)
|
19
|
+
new = rsub from, to, &block
|
20
|
+
new == self ? nil : replace(new)
|
21
|
+
end
|
22
|
+
|
23
|
+
# lookbehind #split
|
24
|
+
def rsplit(splitter=$/, qty=0)
|
25
|
+
reverse.split(splitter.reverse, qty).reverse.reverses
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -5,7 +5,7 @@ class StringScanner
|
|
5
5
|
attr_reader :last
|
6
6
|
__init__
|
7
7
|
|
8
|
-
# #each( <Regexp>, { <0..255> => ->{|self|}, ... } )
|
8
|
+
# #each( <Regexp>, { <0..255 | :~ | nil> => ->{|self|}, ... } )
|
9
9
|
# #each( <Regexp>, [ [ <Regexp>, ->{|self, <MatchData>|} ], ... ] )
|
10
10
|
# #each( <Regexp> ) {|self|}
|
11
11
|
# Example:
|
@@ -27,7 +27,7 @@ class StringScanner
|
|
27
27
|
if cbs
|
28
28
|
if cbs.is Hash
|
29
29
|
while res
|
30
|
-
if cb = cbs[matched.ord]
|
30
|
+
if cb = cbs[matched.ord] || cbs[:~]
|
31
31
|
cb[self]
|
32
32
|
@last = pos
|
33
33
|
res = !eos? && scan_until(re)
|
@@ -41,7 +41,7 @@ class StringScanner
|
|
41
41
|
while res
|
42
42
|
if cb = cbs.find {|pair| pair[0] and matched[pair[0]]}
|
43
43
|
# patterns should be as explicit as possible
|
44
|
-
cb[1][self, $~]
|
44
|
+
cb[1][self, $~] if cb[1]
|
45
45
|
@last = pos
|
46
46
|
res = !eos? && scan_until(re)
|
47
47
|
else break
|
@@ -61,19 +61,29 @@ class StringScanner
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def head
|
64
|
-
string[@last...pos-
|
64
|
+
string[@last...pos-matched_size]
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
string[pos..-1]
|
69
|
-
end
|
67
|
+
alias tail post_match
|
70
68
|
|
71
69
|
def hl_next(re)
|
72
|
-
(res = scan_until re) &&
|
70
|
+
(res = scan_until re) && Painter.hl(string[[pos-1000, 0].max..pos+1000], res)
|
71
|
+
end
|
72
|
+
|
73
|
+
def next_in(n)
|
74
|
+
string[pos+n-1, 1]
|
73
75
|
end
|
74
76
|
|
77
|
+
def prev_in(n)
|
78
|
+
string[pos-matched_size-n, 1]
|
79
|
+
end
|
80
|
+
|
81
|
+
def +; string[pos, 1] end
|
82
|
+
|
83
|
+
def -; string[pos-matched_size-1, 1] end
|
84
|
+
|
75
85
|
def self.each string, *args, &b
|
76
|
-
new
|
86
|
+
new(string).each *args, &b
|
77
87
|
end
|
78
88
|
|
79
89
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
class String
|
3
3
|
|
4
4
|
def inline
|
5
|
-
|
5
|
+
index("\n").nil?
|
6
6
|
end
|
7
7
|
|
8
|
-
def lchomp(match)
|
8
|
+
def lchomp(match=/\r\n?/)
|
9
9
|
if index(match) == 0
|
10
10
|
self[match.size..-1]
|
11
11
|
else
|
@@ -13,7 +13,7 @@ class String
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def lchomp!(match)
|
16
|
+
def lchomp!(match=/\r\n?/)
|
17
17
|
if index(match) == 0
|
18
18
|
self[0...match.size] = ''
|
19
19
|
self
|
@@ -70,4 +70,12 @@ class String
|
|
70
70
|
Regexp.new(esc ? Regexp.escape(self) : self)
|
71
71
|
end
|
72
72
|
|
73
|
+
# "b ц ~ \255 秀".bytes
|
74
|
+
### => ["62", "20", "d1", "86", "20", "7e", "20", "ad", "20", "e7", "a7", "80"]
|
75
|
+
def bytes
|
76
|
+
arr = []
|
77
|
+
each_byte {|b| arr << b.hex}
|
78
|
+
arr
|
79
|
+
end
|
80
|
+
|
73
81
|
end
|
@@ -3,10 +3,6 @@ RMTools::require 'text/string_simple'
|
|
3
3
|
RMTools::require 'enumerable/array_iterators'
|
4
4
|
|
5
5
|
class String
|
6
|
-
|
7
|
-
def rsplit(splitter=$/, qty=0)
|
8
|
-
reverse.split(splitter, qty).reverse.reverses
|
9
|
-
end
|
10
6
|
|
11
7
|
# Same as split, but without :reject_splitter option keeps splitters on the left of parts
|
12
8
|
# with :report_headers option collects all regexp'ed splitters along with result array
|
@@ -48,7 +44,7 @@ class String
|
|
48
44
|
|
49
45
|
def div(len, *)
|
50
46
|
if !len.is Fixnum
|
51
|
-
|
47
|
+
deprecate_method "Use #sharp_split instead."
|
52
48
|
return sharp_split len
|
53
49
|
end
|
54
50
|
return [self] if len <= 0
|
data/lib/rmtools/xml/node.rb
CHANGED
@@ -117,7 +117,7 @@ module LibXML::XML
|
|
117
117
|
attributes.to_hash
|
118
118
|
end
|
119
119
|
|
120
|
-
%w{style id width height onclick
|
120
|
+
%w{style id width height onclick ondblclick oncontextmenu onmousedown onmousemove onmouseout onmouseover onmouseup src onerror onload href type value size onchange onselect onblur onfocus onfocusin onfocusout onkeydown onkeypress onkeyup action target enctype onsubmit checked selected disabled}.each {|name|
|
121
121
|
define_method(name) {self[name]}
|
122
122
|
define_method(name+'=') {|value| self[name] = value}
|
123
123
|
}
|
data/lib/rmtools/xml/string.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
RMTools::require 'lang/
|
2
|
+
RMTools::require 'lang/helpers'
|
3
3
|
|
4
4
|
class String
|
5
5
|
|
@@ -32,7 +32,7 @@ class String
|
|
32
32
|
rescue
|
33
33
|
if enc = xml_charset
|
34
34
|
XML::HTMLParser.string(str, :options => 97,
|
35
|
-
:encoding =>
|
35
|
+
:encoding => XML::Encoding.const_get(enc.upcase.tr('-','_').to_sym)).parse
|
36
36
|
else to_doc :force
|
37
37
|
end
|
38
38
|
end
|
data/lib/rmtools.rb
CHANGED
@@ -1,9 +1,2 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
3
|
-
$__MAIN__ = self
|
4
1
|
require 'rmtools/load'
|
5
|
-
RMTools::require '
|
6
|
-
RMTools::require 'debug'
|
7
|
-
RMTools::require 'console'
|
8
|
-
|
9
|
-
unless defined? Rails; class Object; include RMTools end end
|
2
|
+
RMTools::require 'dev_min'
|