rmtools 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +84 -26
- data/Rakefile +7 -4
- data/ext/extconf.rb +1 -1
- data/ext/rmtools.cpp +27 -12
- data/ext/rmtools.h +6 -5
- data/lib/rmtools/b.rb +18 -0
- data/lib/rmtools/console/coloring.rb +72 -0
- data/lib/rmtools/console/highlight.rb +13 -0
- data/lib/rmtools/{printing.rb → console/printing.rb} +17 -2
- data/lib/rmtools/console.rb +1 -0
- data/lib/rmtools/conversions/enum.rb +23 -0
- data/lib/rmtools/conversions/int.rb +47 -0
- data/lib/rmtools/conversions/string.rb +26 -0
- data/lib/rmtools/conversions.rb +1 -0
- data/lib/rmtools/core/arguments.rb +52 -0
- data/lib/rmtools/{boolean.rb → core/boolean.rb} +0 -13
- data/lib/rmtools/core/class.rb +41 -0
- data/lib/rmtools/core/js.rb +45 -0
- data/lib/rmtools/core/kernel.rb +28 -0
- data/lib/rmtools/{module.rb → core/module.rb} +0 -41
- data/lib/rmtools/core/numeric.rb +35 -0
- data/lib/rmtools/{object.rb → core/object.rb} +2 -23
- data/lib/rmtools/core/proc.rb +18 -0
- data/lib/rmtools/core/regexp.rb +11 -0
- data/lib/rmtools/core/string_compliance.rb +31 -0
- data/lib/rmtools/core.rb +1 -0
- data/lib/rmtools/db/active_record.rb +54 -0
- data/lib/rmtools/db.rb +7 -0
- data/lib/rmtools/debug/binding.rb +56 -0
- data/lib/rmtools/debug/highlight.rb +23 -0
- data/lib/rmtools/debug/logging.rb +176 -0
- data/lib/rmtools/debug/present.rb +38 -0
- data/lib/rmtools/debug/timer.rb +19 -0
- data/lib/rmtools/debug/traceback.rb +92 -0
- data/lib/rmtools/debug.rb +1 -0
- data/lib/rmtools/debug_notrace.rb +1 -0
- data/lib/rmtools/enumerable/array.rb +134 -0
- data/lib/rmtools/enumerable/array_iterators.rb +33 -0
- data/lib/rmtools/enumerable/common.rb +49 -0
- data/lib/rmtools/{hash.rb → enumerable/hash.rb} +8 -8
- data/lib/rmtools/enumerable/object_space.rb +19 -0
- data/lib/rmtools/enumerable/range.rb +201 -0
- data/lib/rmtools/enumerable.rb +1 -0
- data/lib/rmtools/experimental/blackhole.rb +12 -0
- data/lib/rmtools/experimental/deprecation.rb +36 -0
- data/lib/rmtools/experimental/dumps.rb +28 -0
- data/lib/rmtools/{numeric.rb → experimental/numeric.rb} +22 -51
- data/lib/rmtools/experimental/rails_backtrace.rb +29 -0
- data/lib/rmtools/experimental/string.rb +56 -0
- data/lib/rmtools/{tree.rb → experimental/tree.rb} +0 -0
- data/lib/rmtools/experimental.rb +1 -0
- data/lib/rmtools/fs/dir.rb +89 -0
- data/lib/rmtools/fs/file.rb +104 -0
- data/lib/rmtools/fs/io.rb +58 -0
- data/lib/rmtools/fs/tools.rb +49 -0
- data/lib/rmtools/fs.rb +1 -0
- data/lib/rmtools/functional/fold.rb +32 -0
- data/lib/rmtools/{string_to_proc.rb → functional/string_to_proc.rb} +2 -22
- data/lib/rmtools/functional/unfold.rb +16 -0
- data/lib/rmtools/functional.rb +1 -0
- data/lib/rmtools/ip/numeric.rb +35 -0
- data/lib/rmtools/ip/string.rb +45 -0
- data/lib/rmtools/ip.rb +1 -0
- data/lib/rmtools/lang/ansi.rb +17 -0
- data/lib/rmtools/lang/cyrillic.rb +106 -0
- data/lib/rmtools/lang/regexp.rb +8 -0
- data/lib/rmtools/lang/shortcuts.rb +20 -0
- data/lib/rmtools/lang.rb +1 -0
- data/lib/rmtools/rand/array.rb +39 -0
- data/lib/rmtools/rand/enum.rb +26 -0
- data/lib/rmtools/rand/range.rb +13 -0
- data/lib/rmtools/{random.rb → rand/string.rb} +13 -107
- data/lib/rmtools/rand.rb +1 -0
- data/lib/rmtools/require.rb +13 -0
- data/lib/rmtools/setup.rb +6 -5
- data/lib/rmtools/text/string_parse.rb +60 -0
- data/lib/rmtools/{stringscanner.rb → text/string_scanner.rb} +3 -2
- data/lib/rmtools/text/string_simple.rb +75 -0
- data/lib/rmtools/text/string_split.rb +148 -0
- data/lib/rmtools/text/textilize.rb +44 -0
- data/lib/rmtools/text.rb +1 -0
- data/lib/rmtools/time/global.rb +17 -0
- data/lib/rmtools/time/russian.rb +47 -0
- data/lib/rmtools/time.rb +1 -32
- data/lib/rmtools/xml/document.rb +28 -0
- data/lib/rmtools/xml/finders.rb +84 -0
- data/lib/rmtools/xml/libxml.rb +11 -0
- data/lib/rmtools/xml/node.rb +196 -0
- data/lib/rmtools/xml/string.rb +43 -0
- data/lib/rmtools/xml/xpath.rb +32 -0
- data/lib/rmtools/xml.rb +7 -0
- data/lib/rmtools.rb +8 -44
- metadata +97 -72
- data/lib/rmtools/arguments.rb +0 -24
- data/lib/rmtools/array.rb +0 -189
- data/lib/rmtools/binding.rb +0 -23
- data/lib/rmtools/coloring.rb +0 -82
- data/lib/rmtools/cyr-time.rb +0 -49
- data/lib/rmtools/cyrilic.rb +0 -124
- data/lib/rmtools/dumps.rb +0 -192
- data/lib/rmtools/enum.rb +0 -90
- data/lib/rmtools/io.rb +0 -303
- data/lib/rmtools/js.rb +0 -25
- data/lib/rmtools/limited_string.rb +0 -17
- data/lib/rmtools/logging.rb +0 -158
- data/lib/rmtools/proc.rb +0 -25
- data/lib/rmtools/range.rb +0 -100
- data/lib/rmtools/string.rb +0 -276
- data/lib/rmtools/traceback.rb +0 -106
@@ -0,0 +1,47 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
def digit_date
|
4
|
+
gsub(/jan|[яЯ][нН][вВ]([аА][рР][яЯьЬ]?)?/i, '01').
|
5
|
+
gsub(/feb|[фФ][еЕ][вВ]([рР][аА][лЛ][яЯьЬ]?)?/i, '02').
|
6
|
+
gsub(/mar|[мМ][аА][рР]([тТ][аА]?)?/i, '03').
|
7
|
+
gsub(/apr|[аА][пП][рР]([еЕ][лЛ][яЯьЬ]?)?/i, '04').
|
8
|
+
gsub(/may|[мМ][аА][яЯйЙ]?/i, '05').
|
9
|
+
gsub(/june?|[иИ][юЮ][нН][яЯьЬ]?/i, '06').
|
10
|
+
gsub(/july?|[иИ][юЮ][лЛ][яЯьЬ]?/i, '07').
|
11
|
+
gsub(/aug|[аА][вВ][гГ]([уУ][сС][тТ][аА]?)?/i, '08').
|
12
|
+
gsub(/sep|[сС][еЕ][нН]([тТ][яЯ][бБ][рР][яЯьЬ]?)?/i, '09').
|
13
|
+
gsub(/oct|[оО][кК][тТ]([яЯ][бБ][рР][яЯьЬ]?)?/i, '10').
|
14
|
+
gsub(/nov|[нН][оО][яЯ]([бБ][рР][яЯьЬ]?)?/i, '11').
|
15
|
+
gsub(/dec|[дД][еЕ][кК]([аА][бБ][рР][яЯьЬ]?)?/i, '12')
|
16
|
+
end
|
17
|
+
alias :digitize :digit_date
|
18
|
+
|
19
|
+
def tr_date
|
20
|
+
gsub(/[яЯ][нН][вВ]([аА][рР][яЯьЬ]?)?/, 'jan').
|
21
|
+
gsub(/[фФ][еЕ][вВ]([рР][аА][лЛ][яЯьЬ]?)?/, 'feb').
|
22
|
+
gsub(/[мМ][аА][рР]([тТ][аА]?)?/, 'mar').
|
23
|
+
gsub(/[аА][пП][рР]([еЕ][лЛ][яЯьЬ]?)?/, 'apr').
|
24
|
+
gsub(/[мМ][аА][яЯйЙ]?/, 'may').
|
25
|
+
gsub(/[иИ][юЮ][нН][яЯьЬ]?/, 'jun').
|
26
|
+
gsub(/[иИ][юЮ][лЛ][яЯьЬ]?/, 'jul').
|
27
|
+
gsub(/[аА][вВ][гГ]([уУ][сС][тТ][аА]?)?/, 'aug').
|
28
|
+
gsub(/[сС][еЕ][нН]([тТ][яЯ][бБ][рР][яЯьЬ]?)?/, 'sep').
|
29
|
+
gsub(/[оО][кК][тТ]([яЯ][бБ][рР][яЯьЬ]?)?/, 'oct').
|
30
|
+
gsub(/[нН][оО][яЯ]([бБ][рР][яЯьЬ]?)?/, 'nov').
|
31
|
+
gsub(/[дД][еЕ][кК]([аА][бБ][рР][яЯьЬ]?)?/, 'dec')
|
32
|
+
end
|
33
|
+
|
34
|
+
def digit_nums
|
35
|
+
gsub(/[оО][дД][иИ][нН]|[еЕ][дД][иИ][нН][иИ][цЦ][аА]/, '1').
|
36
|
+
gsub(/[дД][вВ]([оО][йЙ][кК])?[аА]/, '2').
|
37
|
+
gsub(/[тТ][рР]([иИ]|[оО][йЙ][кК][аА])/, '3').
|
38
|
+
gsub(/[чЧ][еЕ][тТ]([ыЫ][рР][еЕ]|[вВ][еЕёЁ][рР][кК][аА])/, '4').
|
39
|
+
gsub(/[пП][яЯ][тТ]([ьЬ]|[еЕёЁ][рР][кК][аА])/, '5').
|
40
|
+
gsub(/[шШ][еЕ][сС][тТ]([ьЬ]|[еЕёЁ][рР][кК][аА])/, '6').
|
41
|
+
gsub(/[сС][еЕ][мМ]([ьЬ]|[еЕёЁ][рР][кК][аА])/, '7').
|
42
|
+
gsub(/[вВ][оО][сС]([еЕ][мМ][ьЬ]|[ьЬ][мМ][еЕёЁ][рР][кК][аА])/i, '8').
|
43
|
+
gsub(/[дД][еЕ][вВ][яЯ][тТ]([ьЬ]|[кК][аА])/, '9').
|
44
|
+
gsub(/[нН][оОуУ][лЛ][ьЬ]/, '0')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/rmtools/time.rb
CHANGED
@@ -1,32 +1 @@
|
|
1
|
-
|
2
|
-
module RMTools
|
3
|
-
|
4
|
-
def timer(ts=1, output=true)
|
5
|
-
timez = ts - 1
|
6
|
-
panic, verbose = $panic, $verbose
|
7
|
-
$panic = $verbose = false
|
8
|
-
t1 = Time.now
|
9
|
-
timez.times {yield}
|
10
|
-
res = yield
|
11
|
-
t2 = (Time.now.to_f*1000).round
|
12
|
-
t1 = (t1.to_f*1000).round
|
13
|
-
$panic, $verbose = panic, verbose
|
14
|
-
res = res.inspect
|
15
|
-
puts "#{output ? "res: #{res.size > 1000 ? res[0...1000]+"…" : res}\n" : "size of res string: #{res.to_s.size}, "}one: #{(t2-t1).to_f/ts}ms, total: #{(t2-t1).to_f}ms"
|
16
|
-
end
|
17
|
-
|
18
|
-
def puttime(ms=nil)
|
19
|
-
t = Time.now
|
20
|
-
if ms
|
21
|
-
t.strftime("%H:%M:%S")+sprintf(".%03d ", t.usec/1000)
|
22
|
-
else
|
23
|
-
t.strftime("%d.%m.%y %H:%M:%S ")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def putdate
|
28
|
-
Time.now.strftime("%d.%m.%y")
|
29
|
-
end
|
30
|
-
|
31
|
-
module_function :puttime, :putdate
|
32
|
-
end
|
1
|
+
require_with_path __FILE__, '*'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LibXML::XML
|
2
|
+
|
3
|
+
class Document
|
4
|
+
|
5
|
+
def title
|
6
|
+
(a = context(nil).find('head//title')[0]) && a.content.strip
|
7
|
+
end
|
8
|
+
|
9
|
+
def body
|
10
|
+
context(nil).find('body')[0] || root
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_xhtml
|
14
|
+
html = to_s
|
15
|
+
html.sub! "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n", ''
|
16
|
+
html.gsub! %r{<a name(=\"\S+\")\s+id\1(\s*[a-z0-9="]*\s*>)}, '<a name\1\2'
|
17
|
+
html.gsub! %r{\n?<!\[CDATA\[\s*(.+?)\s*\]\]>\n?}m, '\1'
|
18
|
+
html.gsub! %r{<html( +xmlns=\"http://\S+\")\1}, '<html\1'
|
19
|
+
html
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"<#XMLDocument #{title && "«#{title}» "}(#{to_xhtml.size.bytes})>"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require_with_path 'text/string_scanner'
|
2
|
+
|
3
|
+
module LibXML::XML
|
4
|
+
DefaultNS = {}
|
5
|
+
|
6
|
+
FindByIndex = lambda {|node, ns, ss|
|
7
|
+
node = node.is(Array) ?
|
8
|
+
node.sum {|n| n.__find(nil, ns, ss)[ss.matched[1..-2].to_i].to_a} :
|
9
|
+
node.__find(nil, ns, ss)[ss.matched[1..-2].to_i]
|
10
|
+
node.is(Array) && node.size == 1 ? node[0] : node
|
11
|
+
}
|
12
|
+
FindByProc = lambda {|node, ns, ss|
|
13
|
+
node = node.is(Array) ?
|
14
|
+
node.sum {|n| n.__find(nil, ns, ss).select(&ss.matched[1..-2]).to_a} :
|
15
|
+
node.__find(nil, ns, ss).select(&ss.matched[1..-2])
|
16
|
+
node.is(Array) && node.size == 1 ? node[0] : node
|
17
|
+
}
|
18
|
+
|
19
|
+
class Node
|
20
|
+
undef :find if method_defined? :find
|
21
|
+
undef :at if method_defined? :at
|
22
|
+
|
23
|
+
def __find(xp=nil, ns=nil, ss=nil)
|
24
|
+
xp ||= ss.head
|
25
|
+
context(ns).find(XPath.filter xp)
|
26
|
+
end
|
27
|
+
|
28
|
+
def find(xpath, nslist=DefaultNS)
|
29
|
+
node = self
|
30
|
+
ss = StringScanner.new xpath
|
31
|
+
ss.each %r{\[-?\d+\]|\{[^\}]+\}},
|
32
|
+
?[ => lambda {|ss|
|
33
|
+
if node; node = FindByIndex[node, nslist, ss]
|
34
|
+
else return [] end },
|
35
|
+
?{ => lambda {|ss|
|
36
|
+
if node; node = FindByProc[node, nslist, ss]
|
37
|
+
else return [] end },
|
38
|
+
nil => lambda {|str|
|
39
|
+
node = node.is(Array) ?
|
40
|
+
node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
|
41
|
+
}
|
42
|
+
node ? (!ss.eos? || node.is(Array)) ? node : [node] : []
|
43
|
+
end
|
44
|
+
|
45
|
+
def at(xpath, nslist=DefaultNS)
|
46
|
+
find(xpath, nslist)[0]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class Document
|
52
|
+
undef :find if method_defined? :find
|
53
|
+
undef :at if method_defined? :at
|
54
|
+
|
55
|
+
def __find(xp=nil, ns=nil, ss=nil)
|
56
|
+
xp ||= ss.head
|
57
|
+
context(ns).find(XPath.filter xp)
|
58
|
+
end
|
59
|
+
|
60
|
+
def find(xpath, nslist=DefaultNS)
|
61
|
+
xpath.sub!(/^([\w*])/, '//\1')
|
62
|
+
node = self
|
63
|
+
ss = StringScanner.new xpath
|
64
|
+
ss.each %r{\[-?\d+\]|\{[^\}]+\}},
|
65
|
+
?[ => lambda {|ss|
|
66
|
+
if node; node = FindByIndex[node, nslist, ss]
|
67
|
+
else return [] end },
|
68
|
+
?{ => lambda {|ss|
|
69
|
+
if node; node = FindByProc[node, nslist, ss]
|
70
|
+
else return [] end },
|
71
|
+
nil => lambda {|str|
|
72
|
+
node = node.is(Array) ?
|
73
|
+
node.sum {|n| n.__find(str, nslist).to_a} : node.__find(str, nslist)
|
74
|
+
}
|
75
|
+
node ? (!ss.eos? || node.is(Array)) ? node : [node] : []
|
76
|
+
end
|
77
|
+
|
78
|
+
def at(xpath, nslist=DefaultNS)
|
79
|
+
find(xpath, nslist)[0]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
module LibXML::XML
|
2
|
+
|
3
|
+
class Node
|
4
|
+
__init__
|
5
|
+
|
6
|
+
alias :get :[]
|
7
|
+
alias :root? :parent?
|
8
|
+
alias :root :parent
|
9
|
+
|
10
|
+
def [](*item)
|
11
|
+
if item[0].is String
|
12
|
+
get item[0]
|
13
|
+
else to_a[*item]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# JQUERY-LIKE MANIPULATION
|
18
|
+
def self.build(str, copy=true)
|
19
|
+
nodes = Document.string("<html>#{str}</html>", :options=>97).root.to_a
|
20
|
+
copy ? nodes.copies(true) : nodes
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from(str, copy=true)
|
24
|
+
build(str, copy)[0]
|
25
|
+
end
|
26
|
+
|
27
|
+
def append(obj)
|
28
|
+
case obj
|
29
|
+
when Node then self << obj
|
30
|
+
when Array then obj.each {|n| append n}
|
31
|
+
else append Node.build obj.to_s
|
32
|
+
end
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def after(obj)
|
37
|
+
case obj
|
38
|
+
when Node then self.next = obj
|
39
|
+
when Array then obj.reverse_each {|n| after n}
|
40
|
+
else after Node.build obj.to_s
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def before(obj)
|
46
|
+
case obj
|
47
|
+
when Node then self.prev = obj
|
48
|
+
when Array then obj.each {|n| before n}
|
49
|
+
else before Node.build obj.to_s
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def prepend obj
|
55
|
+
first ? first.before(obj) : append(obj)
|
56
|
+
end
|
57
|
+
|
58
|
+
def html(str=nil)
|
59
|
+
if str
|
60
|
+
self.content = ''
|
61
|
+
append str
|
62
|
+
else to_a.join
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def text(str=nil)
|
67
|
+
if str
|
68
|
+
self.content = str
|
69
|
+
self
|
70
|
+
else
|
71
|
+
self.content
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# FETCH CONTENT
|
77
|
+
def text_nodes(lvl=0) # 0 => nevermind
|
78
|
+
nodes = []
|
79
|
+
xp = "*"
|
80
|
+
loop {
|
81
|
+
ary = find(xp).to_a
|
82
|
+
break if ary.empty?
|
83
|
+
nodes.concat(ary.childrens.flatten.find_all {|e|
|
84
|
+
e.text? && e.text[/[a-zA-Zа-яА-Я]/]
|
85
|
+
})
|
86
|
+
xp << "/*"
|
87
|
+
break if (lvl -= 1) == 0
|
88
|
+
}
|
89
|
+
nodes
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# FORM
|
94
|
+
InputsMapper = lambda {|i| [i['name'], i.name == 'select' ?
|
95
|
+
(i.at('option[selected]') || i.at('option')) :
|
96
|
+
(i.value || i.checked)]
|
97
|
+
}
|
98
|
+
def inputs
|
99
|
+
[Hash[find("input[name][type=hidden]").map(&InputsMapper)],
|
100
|
+
Hash[
|
101
|
+
["input[name][type!=hidden]", "textarea[name]", "select[name]"].sum {|s|
|
102
|
+
find(s).map &InputsMapper
|
103
|
+
}
|
104
|
+
]]
|
105
|
+
end
|
106
|
+
|
107
|
+
def inputs_all
|
108
|
+
Hash[["input[name]", "textarea[name]", "select[name]"].sum {|s|
|
109
|
+
find(s).map &InputsMapper
|
110
|
+
}]
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
# ATTRIBUTES
|
115
|
+
def to_hash
|
116
|
+
attributes.to_hash
|
117
|
+
end
|
118
|
+
|
119
|
+
%w{style id width height onclick ondbclick 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}.each {|name|
|
120
|
+
define_method(name) {self[name]}
|
121
|
+
define_method(name+'=') {|value| self[name] = value}
|
122
|
+
}
|
123
|
+
def klass() self['class'] end
|
124
|
+
def klass=(name) self['class'] = name end
|
125
|
+
def metod() self['method'] end
|
126
|
+
def metod=(name) self['method'] = name end
|
127
|
+
|
128
|
+
|
129
|
+
# RELATED FINDERS
|
130
|
+
alias :prevNode :prev
|
131
|
+
alias :nextNode :next
|
132
|
+
|
133
|
+
def prev(*args) getNode :prevNode, *args end
|
134
|
+
def next(*args) getNode :nextNode, *args end
|
135
|
+
def closest(*args) getNode :parent, *args end
|
136
|
+
|
137
|
+
private
|
138
|
+
Searches = {}
|
139
|
+
def getNode meth, filter=nil, skip=true
|
140
|
+
unless filter
|
141
|
+
send meth
|
142
|
+
else
|
143
|
+
return unless el = skip ? send(meth) : self
|
144
|
+
unless nil;cond = Searches[filter]
|
145
|
+
m = filter.match %r{(\w+)?#{ # span
|
146
|
+
}(?:\.(\w+))?(?:#([\-\w]+))?#{# .class #id
|
147
|
+
}(\[((\w+)#{ # [name
|
148
|
+
}(([!^$~]?)=([\-\w]+))?)?\])#{# ^= name-beg]
|
149
|
+
}?}
|
150
|
+
cond = []
|
151
|
+
cond << "_.name == '#{m[1]}'" if m[1]
|
152
|
+
cond << "_['class'] == '#{m[2]}'" if m[2]
|
153
|
+
cond << "_['id'] == '#{m[3]}'" if m[3]
|
154
|
+
if m[4]
|
155
|
+
if m[5]
|
156
|
+
attr = m[6]
|
157
|
+
attr_cond = m[7]
|
158
|
+
if attr_cond
|
159
|
+
cond_op = m[8]
|
160
|
+
attr_value = m[9]
|
161
|
+
cond << case cond_op
|
162
|
+
when '!'; "_['#{attr}'] != '#{attr_value}' "
|
163
|
+
when '^'; "_['#{attr}'] =~ /^#{attr_value}/ "
|
164
|
+
when '$'; "_['#{attr}'] =~ /#{attr_value}$/"
|
165
|
+
when '~'; "_['#{attr}'] =~ /#{attr_value}/ "
|
166
|
+
else "_['#{attr}'] == '#{attr_value}'"
|
167
|
+
end
|
168
|
+
else
|
169
|
+
cond << "_['#{attr}']"
|
170
|
+
end
|
171
|
+
elsif !(m[2] or m[3])
|
172
|
+
cond << "!_.attributes?"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
cond = Searches[filter] = Proc.eval("|_| #{cond*' && '}")
|
176
|
+
end
|
177
|
+
if cond[el]
|
178
|
+
el
|
179
|
+
else
|
180
|
+
while el = el.send(meth) and el.kinda Node and !cond[el]; end
|
181
|
+
el if el and el.kinda Node and cond[el]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
|
188
|
+
class Attributes
|
189
|
+
|
190
|
+
def to_hash
|
191
|
+
Hash[map {|a| [a.name,a.value]}]
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_with_path 'lang/shortcuts'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
def xml_charset
|
6
|
+
charset = (charset = self[0,2000].match(/(?:encoding|charset)=(.+?)"/)) ?
|
7
|
+
charset[1].upcase : 'UTF8'
|
8
|
+
if charset and charset != 'UTF-8'
|
9
|
+
utf!(charset) rescue(charset = nil)
|
10
|
+
end
|
11
|
+
charset
|
12
|
+
end
|
13
|
+
|
14
|
+
def xml_to_utf
|
15
|
+
charset = (charset = self[0,2000].match(/(?:encoding|charset)=(.+?)"/)) ?
|
16
|
+
charset[1].upcase : 'UTF8'
|
17
|
+
if charset and charset != 'UTF-8'
|
18
|
+
utf!(charset) rescue()
|
19
|
+
end
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_doc(forceutf=nil)
|
24
|
+
str = b || "<html/>"
|
25
|
+
doc = if forceutf
|
26
|
+
XML::HTMLParser.string(str.xml_to_utf, :options => 97,
|
27
|
+
:encoding => XML::Encoding::UTF_8).parse
|
28
|
+
else
|
29
|
+
begin
|
30
|
+
XML::HTMLParser.string(str, :options => 97).parse
|
31
|
+
rescue
|
32
|
+
if enc = xml_charset
|
33
|
+
XML::HTMLParser.string(str, :options => 97,
|
34
|
+
:encoding => eval('XML::Encoding::'+enc.upcase.tr('-','_'))).parse
|
35
|
+
else to_doc :force
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
doc.order_elements!
|
40
|
+
doc
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module LibXML
|
2
|
+
|
3
|
+
module XML::XPath
|
4
|
+
Finders = {}
|
5
|
+
|
6
|
+
def self.filter(xpath)
|
7
|
+
return xpath if xpath.ord == ?!
|
8
|
+
if x = Finders[xpath]; return x end
|
9
|
+
if xpath[%r{\[@?\w+([^\w!]=).+?\]}]
|
10
|
+
raise XML::Error, "can't process '#{$1}' operator"
|
11
|
+
end
|
12
|
+
x = xpath.dup
|
13
|
+
x.gsub! %r{\.([\w-]+)([\[\{/]|\Z)}, '[@class="\1"]\2'
|
14
|
+
x.gsub! %r{#([\w-]+)([\[\{/]|\Z)}, '[@id="\1"]\2'
|
15
|
+
x.gsub! %r{(^|/)([^.#\w*/'"])}, '\1*\2'
|
16
|
+
x.gsub! %r{\[([a-z]+)}, '[@\1'
|
17
|
+
x.gsub! %r{(\[(?:@\w+!?=)?)['"]?([^'"\]@]+)['"]?\]}, '\1"\2"]'
|
18
|
+
if x !~%r{^(#{
|
19
|
+
}(\./|\.//|/|//)?#{
|
20
|
+
}(\w+:)?(\w+|\*)#{ # [ns:]name
|
21
|
+
}(\[(@\w+(!?="[^"]+")?|"[^"]+")\])*#{# attributes [@href!="pics/xynta.jpeg"]
|
22
|
+
}(\[-?\d+\]|\{[^\}]+\})?#{ # inruby-filters (see finder functions ^)
|
23
|
+
})+$}
|
24
|
+
raise XML::Error, "can't process `#{xpath}`"
|
25
|
+
end
|
26
|
+
x = '//'+x if x !~ %r{^[./]}
|
27
|
+
x.sub! %r{^/}, './'
|
28
|
+
Finders[xpath] = x
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/rmtools/xml.rb
ADDED
data/lib/rmtools.rb
CHANGED
@@ -1,51 +1,15 @@
|
|
1
|
-
require '
|
2
|
-
require 'iconv'
|
3
|
-
require 'cgi'
|
4
|
-
require 'set'
|
5
|
-
require 'strscan'
|
6
|
-
|
7
|
-
# why did I put it in here?
|
8
|
-
# require "bundler/setup"
|
9
|
-
|
10
|
-
# being required *after* rmtools/random it overrides some of a functions and then whine about they are "deprecated", huh
|
11
|
-
require 'activesupport' rescue nil
|
1
|
+
require 'active_support'
|
12
2
|
|
13
3
|
module RMTools
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
'
|
18
|
-
'
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
'boolean', # {obj.b -> self or false} with python logic
|
23
|
-
# and native boolean #to_i and #<=>
|
24
|
-
# Since 2.3.8 active_support has analogue: #presence
|
25
|
-
# BTW, why so slow?
|
26
|
-
|
27
|
-
'logging', 'coloring', # lazy logger
|
28
|
-
# with caller processing and highlighting
|
29
|
-
# 'traceback', # python-like traceback for exceptions
|
30
|
-
# uses ANSI coloring; kinda buggy, so better
|
31
|
-
# require 'rmtools/traceback' separately
|
32
|
-
|
33
|
-
|
34
|
-
'printing', # transparent print: print text (or object info) and erase it
|
35
|
-
'limited_string', # for compact string inspecting
|
36
|
-
|
37
|
-
'binding', # binding inspect
|
38
|
-
'arguments', # arguments parsing and types validation
|
39
|
-
|
40
|
-
'cyrilic', 'cyr-time', # String & Regexp methods for Russian processing
|
41
|
-
|
42
|
-
# some bicycles just for convenience
|
43
|
-
'dumps', 'time', 'random'
|
44
|
-
].each {|f| require "#{rmtools}/#{f}"}
|
4
|
+
require File.expand_path('require', __FILE__[0..-4])
|
5
|
+
[ 'core', 'enumerable', 'text', 'b', 'time', 'functional',
|
6
|
+
'conversions', 'ip', 'lang', 'rand',
|
7
|
+
'console', 'fs', 'debug',
|
8
|
+
'db', 'xml',
|
9
|
+
'../rmtools.so'
|
10
|
+
].each {|file| require_with_path file}
|
45
11
|
end
|
46
12
|
|
47
|
-
require "#{rmtools}/rmtools.so" rescue nil
|
48
|
-
|
49
13
|
$log = RMTools::RMLogger.new
|
50
14
|
|
51
15
|
# Comment out in case of any method conflicts
|