rmtools 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +84 -26
  3. data/Rakefile +7 -4
  4. data/ext/extconf.rb +1 -1
  5. data/ext/rmtools.cpp +27 -12
  6. data/ext/rmtools.h +6 -5
  7. data/lib/rmtools/b.rb +18 -0
  8. data/lib/rmtools/console/coloring.rb +72 -0
  9. data/lib/rmtools/console/highlight.rb +13 -0
  10. data/lib/rmtools/{printing.rb → console/printing.rb} +17 -2
  11. data/lib/rmtools/console.rb +1 -0
  12. data/lib/rmtools/conversions/enum.rb +23 -0
  13. data/lib/rmtools/conversions/int.rb +47 -0
  14. data/lib/rmtools/conversions/string.rb +26 -0
  15. data/lib/rmtools/conversions.rb +1 -0
  16. data/lib/rmtools/core/arguments.rb +52 -0
  17. data/lib/rmtools/{boolean.rb → core/boolean.rb} +0 -13
  18. data/lib/rmtools/core/class.rb +41 -0
  19. data/lib/rmtools/core/js.rb +45 -0
  20. data/lib/rmtools/core/kernel.rb +28 -0
  21. data/lib/rmtools/{module.rb → core/module.rb} +0 -41
  22. data/lib/rmtools/core/numeric.rb +35 -0
  23. data/lib/rmtools/{object.rb → core/object.rb} +2 -23
  24. data/lib/rmtools/core/proc.rb +18 -0
  25. data/lib/rmtools/core/regexp.rb +11 -0
  26. data/lib/rmtools/core/string_compliance.rb +31 -0
  27. data/lib/rmtools/core.rb +1 -0
  28. data/lib/rmtools/db/active_record.rb +54 -0
  29. data/lib/rmtools/db.rb +7 -0
  30. data/lib/rmtools/debug/binding.rb +56 -0
  31. data/lib/rmtools/debug/highlight.rb +23 -0
  32. data/lib/rmtools/debug/logging.rb +176 -0
  33. data/lib/rmtools/debug/present.rb +38 -0
  34. data/lib/rmtools/debug/timer.rb +19 -0
  35. data/lib/rmtools/debug/traceback.rb +92 -0
  36. data/lib/rmtools/debug.rb +1 -0
  37. data/lib/rmtools/debug_notrace.rb +1 -0
  38. data/lib/rmtools/enumerable/array.rb +134 -0
  39. data/lib/rmtools/enumerable/array_iterators.rb +33 -0
  40. data/lib/rmtools/enumerable/common.rb +49 -0
  41. data/lib/rmtools/{hash.rb → enumerable/hash.rb} +8 -8
  42. data/lib/rmtools/enumerable/object_space.rb +19 -0
  43. data/lib/rmtools/enumerable/range.rb +201 -0
  44. data/lib/rmtools/enumerable.rb +1 -0
  45. data/lib/rmtools/experimental/blackhole.rb +12 -0
  46. data/lib/rmtools/experimental/deprecation.rb +36 -0
  47. data/lib/rmtools/experimental/dumps.rb +28 -0
  48. data/lib/rmtools/{numeric.rb → experimental/numeric.rb} +22 -51
  49. data/lib/rmtools/experimental/rails_backtrace.rb +29 -0
  50. data/lib/rmtools/experimental/string.rb +56 -0
  51. data/lib/rmtools/{tree.rb → experimental/tree.rb} +0 -0
  52. data/lib/rmtools/experimental.rb +1 -0
  53. data/lib/rmtools/fs/dir.rb +89 -0
  54. data/lib/rmtools/fs/file.rb +104 -0
  55. data/lib/rmtools/fs/io.rb +58 -0
  56. data/lib/rmtools/fs/tools.rb +49 -0
  57. data/lib/rmtools/fs.rb +1 -0
  58. data/lib/rmtools/functional/fold.rb +32 -0
  59. data/lib/rmtools/{string_to_proc.rb → functional/string_to_proc.rb} +2 -22
  60. data/lib/rmtools/functional/unfold.rb +16 -0
  61. data/lib/rmtools/functional.rb +1 -0
  62. data/lib/rmtools/ip/numeric.rb +35 -0
  63. data/lib/rmtools/ip/string.rb +45 -0
  64. data/lib/rmtools/ip.rb +1 -0
  65. data/lib/rmtools/lang/ansi.rb +17 -0
  66. data/lib/rmtools/lang/cyrillic.rb +106 -0
  67. data/lib/rmtools/lang/regexp.rb +8 -0
  68. data/lib/rmtools/lang/shortcuts.rb +20 -0
  69. data/lib/rmtools/lang.rb +1 -0
  70. data/lib/rmtools/rand/array.rb +39 -0
  71. data/lib/rmtools/rand/enum.rb +26 -0
  72. data/lib/rmtools/rand/range.rb +13 -0
  73. data/lib/rmtools/{random.rb → rand/string.rb} +13 -107
  74. data/lib/rmtools/rand.rb +1 -0
  75. data/lib/rmtools/require.rb +13 -0
  76. data/lib/rmtools/setup.rb +6 -5
  77. data/lib/rmtools/text/string_parse.rb +60 -0
  78. data/lib/rmtools/{stringscanner.rb → text/string_scanner.rb} +3 -2
  79. data/lib/rmtools/text/string_simple.rb +75 -0
  80. data/lib/rmtools/text/string_split.rb +148 -0
  81. data/lib/rmtools/text/textilize.rb +44 -0
  82. data/lib/rmtools/text.rb +1 -0
  83. data/lib/rmtools/time/global.rb +17 -0
  84. data/lib/rmtools/time/russian.rb +47 -0
  85. data/lib/rmtools/time.rb +1 -32
  86. data/lib/rmtools/xml/document.rb +28 -0
  87. data/lib/rmtools/xml/finders.rb +84 -0
  88. data/lib/rmtools/xml/libxml.rb +11 -0
  89. data/lib/rmtools/xml/node.rb +196 -0
  90. data/lib/rmtools/xml/string.rb +43 -0
  91. data/lib/rmtools/xml/xpath.rb +32 -0
  92. data/lib/rmtools/xml.rb +7 -0
  93. data/lib/rmtools.rb +8 -44
  94. metadata +97 -72
  95. data/lib/rmtools/arguments.rb +0 -24
  96. data/lib/rmtools/array.rb +0 -189
  97. data/lib/rmtools/binding.rb +0 -23
  98. data/lib/rmtools/coloring.rb +0 -82
  99. data/lib/rmtools/cyr-time.rb +0 -49
  100. data/lib/rmtools/cyrilic.rb +0 -124
  101. data/lib/rmtools/dumps.rb +0 -192
  102. data/lib/rmtools/enum.rb +0 -90
  103. data/lib/rmtools/io.rb +0 -303
  104. data/lib/rmtools/js.rb +0 -25
  105. data/lib/rmtools/limited_string.rb +0 -17
  106. data/lib/rmtools/logging.rb +0 -158
  107. data/lib/rmtools/proc.rb +0 -25
  108. data/lib/rmtools/range.rb +0 -100
  109. data/lib/rmtools/string.rb +0 -276
  110. 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
- # encoding: utf-8
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,11 @@
1
+ require 'xml'
2
+ require_with_path 'xml/{xpath,finders,node,document,string}'
3
+ require_with_path 'enumerable/common'
4
+
5
+ module LibXML::XML
6
+ Error.reset_handler
7
+
8
+ class XPath::Object
9
+ include Enumerable
10
+ end
11
+ 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
@@ -0,0 +1,7 @@
1
+ begin
2
+ require 'xml'
3
+ LibXML::XML
4
+ require_with_path __FILE__, 'libxml'
5
+ rescue
6
+ nil
7
+ end
data/lib/rmtools.rb CHANGED
@@ -1,51 +1,15 @@
1
- require 'fileutils'
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
- rmtools = File.expand_path(__FILE__)[0..-4]
15
- require "#{rmtools}/string_to_proc"
16
- [ 'string_to_proc',
17
- 'string', 'object', 'module', 'enum', 'array', 'hash',
18
- 'numeric', 'stringscanner', 'proc', 'io', 'range',
19
-
20
- 'js', # js hash getter/setter and string concat logic
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