rmtools 1.2.3 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -40,7 +40,6 @@ lib/rmtools/core/deprecation.rb
40
40
  lib/rmtools/core/regexp.rb
41
41
  lib/rmtools/core/class.rb
42
42
  lib/rmtools/core/proc.rb
43
- lib/rmtools/lang/helpers.rb
44
43
  lib/rmtools/lang/ansi.rb
45
44
  lib/rmtools/lang/regexp.rb
46
45
  lib/rmtools/lang/cyrillic.rb
@@ -84,6 +83,7 @@ lib/rmtools/enumerable/array_iterators.rb
84
83
  lib/rmtools/require.rb
85
84
  lib/rmtools/xml.rb
86
85
  lib/rmtools/conversions.rb
86
+ lib/rmtools/conversions/json.rb
87
87
  lib/rmtools/conversions/string.rb
88
88
  lib/rmtools/conversions/enum.rb
89
89
  lib/rmtools/conversions/int.rb
data/Rakefile CHANGED
@@ -2,14 +2,14 @@ require 'rake'
2
2
  require 'lib/rmtools/install'
3
3
  compile_manifest
4
4
 
5
- RMTOOLS_VERSION = '1.2.3'
5
+ RMTOOLS_VERSION = '1.2.7'
6
6
  begin
7
7
  require 'hoe'
8
8
  config = Hoe.spec 'rmtools' do
9
9
  developer("Shinku", "tinbka@gmail.com")
10
10
 
11
- self.summary = 'Yet another Ruby applied framework'
12
- self.description = 'Applied framework primarily for debug and text/arrays/files operation.'
11
+ self.summary = 'Yet another Ruby applied lib'
12
+ self.description = 'Applied library primarily for debug and text/arrays/files processing purposes.'
13
13
  self.changes = paragraphs_of('README.txt', 5..-1).join("\n\n")
14
14
  self.url = 'http://github.com/tinbka'
15
15
 
data/ext/rmtools.cpp CHANGED
@@ -234,23 +234,23 @@ static VALUE rb_ary_uniq_by(VALUE ary)
234
234
  /*
235
235
  * Make hash with unique items of +self+ or (when block given)
236
236
  * unique results of items yield for keys and
237
- * count of them in +self,
237
+ * count of them in +self+,
238
238
  * or (with option :fill) arrays of yield results,
239
239
  * or (with option :indexes) arrays of indexes of them,
240
240
  * or (with option :group) arrays of themselves for values
241
241
  *
242
- * [1, 2, 2, 2, 3, 3].count
242
+ * [1, 2, 2, 2, 3, 3].arrange
243
243
  * => {1=>1, 2=>3, 3=>2}
244
- * [1, 2, 2, 2, 3, 3].count {|i| i%2}
244
+ * [1, 2, 2, 2, 3, 3].arrange {|i| i%2}
245
245
  * => {0=>3, 1=>3}
246
- * [1, 2, 2, 2, 3, 3].count :fill
246
+ * [1, 2, 2, 2, 3, 3].arrange :fill
247
247
  * => {1=>[1], 2=>[2, 2, 2], 3=>[3, 3]}
248
- * [1, 2, 2, 2, 3, 3].count :indexes
248
+ * [1, 2, 2, 2, 3, 3].arrange :indexes
249
249
  * => {1=>[0], 2=>[1, 2, 3], 3=>[4, 5]}
250
- * [1, 2, 2, 2, 3, 3].count(:indexes) {|i| i%2}
250
+ * [1, 2, 2, 2, 3, 3].arrange(:indexes) {|i| i%2}
251
251
  * => {0=>[1, 2, 3], 1=>[0, 4, 5]}
252
252
  * :group is analogue to rails' group_by but twice faster
253
- * [1, 2, 2, 2, 3, 3].count(:group) {|i| i%2}
253
+ * [1, 2, 2, 2, 3, 3].arrange(:group) {|i| i%2}
254
254
  * => {0=>[2, 2, 2], 1=>[1, 3, 3]}
255
255
  */
256
256
  static VALUE rb_ary_count_items(int argc, VALUE *argv, VALUE ary)
@@ -539,7 +539,7 @@ extern "C" void Init_rmtools()
539
539
  rb_define_method(rb_cArray, "uniq_by", RUBY_METHOD_FUNC(rb_ary_uniq_by), 0);
540
540
  rb_define_method(rb_cArray, "uniq_by!", RUBY_METHOD_FUNC(rb_ary_uniq_by_bang), 0);
541
541
 
542
- rb_define_method(rb_cArray, "count", RUBY_METHOD_FUNC(rb_ary_count_items), -1);
542
+ rb_define_method(rb_cArray, "arrange", RUBY_METHOD_FUNC(rb_ary_count_items), -1);
543
543
 
544
544
  rb_define_method(rb_cArray, "partition", RUBY_METHOD_FUNC(rb_ary_partition), 0);
545
545
 
data/lib/rmtools/b.rb CHANGED
@@ -14,6 +14,9 @@ end
14
14
  class Proc
15
15
  def b; (self != NULL) && self end
16
16
  end
17
+ class NilClass
18
+ def b; false end
19
+ end
17
20
  module Enumerable
18
21
  def b; !empty? && self end
19
22
  end
@@ -19,8 +19,8 @@ module RMTools
19
19
  CYAN = 36
20
20
  GRAY = 37
21
21
 
22
- Colors = {:black => 30, :red => 31, :green => 32, :yellow => 33, :blue => 34, :purple => 35, :cyan => 36, :gray => 37,
23
- :k => 30, :r => 31, :g => 32, :y => 33, :b => 34, :p => 35, :c => 36
22
+ Colors = {:black => 30, :red => 31, :green => 32, :yellow => 33, :blue => 34, :purple => 35, :cyan => 36, :gray => 37, :pink => [35, 1],
23
+ :k => 30, :r => 31, :g => 32, :y => 33, :b => 34, :p => 35, :c => 36, :w => [37, 1]
24
24
  }.unify_keys
25
25
  Effects = {:bold => 1, :underline => 4, :graybg => 5, :boldbg => 7,
26
26
  :b => 1, :u => 4, :gbg => 5, :bbg => 7
@@ -37,7 +37,11 @@ module RMTools
37
37
  return str if ENV['ComSpec'] =~ /cmd(.exe)?$/
38
38
  if num.is String
39
39
  num = Colors[num]
40
- effect = Effects[num] if !num
40
+ if !num
41
+ effect = Effects[num]
42
+ elsif num.is Array
43
+ num, effect = num
44
+ end
41
45
  end
42
46
  effect = Effects[effect] if effect.is String
43
47
  if num and effect
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require 'cgi'
2
+ #require 'cgi'
3
3
 
4
4
  module Enumerable
5
5
 
@@ -0,0 +1,49 @@
1
+ <<-original
2
+ [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
3
+ klass.class_eval do
4
+ # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
5
+ def to_json(options = nil)
6
+ ActiveSupport::JSON.encode(self, options)
7
+ end
8
+ end
9
+ end
10
+ original
11
+ # Overwrites slow ActiveSupport ActiveSupport::JSON.encode by faster 1.9 stdlib JSON library
12
+ if RUBY_VERSION > '1.9'
13
+ [Array, Hash].each do |klass|
14
+ klass.class_eval do
15
+ def to_json(options=nil)
16
+ JSON.unparse(self, options)
17
+ end
18
+ end
19
+ end
20
+
21
+ class ActiveSupport::OrderedHash
22
+ # nothing lost here since javascript engines (at least Webkit) doesn't order objects
23
+ def to_json(options=nil)
24
+ JSON.unparse({}.merge!(self), options)
25
+ end
26
+ end
27
+
28
+ class String
29
+ # the opposite of #to_json
30
+ def from_json
31
+ JSON.parse self
32
+ end
33
+ end
34
+
35
+ else
36
+
37
+ def from_json
38
+ ActiveSupport::JSON.decode self
39
+ end
40
+
41
+ end
42
+
43
+ class Object
44
+
45
+ def to_json_safe(options=nil)
46
+ timeout(10) {to_json(options)}
47
+ end
48
+
49
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require 'cgi'
2
+ #require 'cgi'
3
3
 
4
4
  class String
5
5
 
@@ -17,11 +17,5 @@ class String
17
17
  }
18
18
  h
19
19
  end
20
-
21
- # the opposite of #to_json
22
- # active support activesupport
23
- def from_json
24
- ActiveSupport::JSON.decode self
25
- end
26
20
 
27
21
  end
@@ -13,6 +13,8 @@ class TrueClass
13
13
  def <= obj; !!obj or obj == true end
14
14
  def > obj; !obj end
15
15
  def >= obj; !obj or obj == true end
16
+
17
+ def call(*) self end
16
18
  end
17
19
 
18
20
  class FalseClass
@@ -29,6 +31,8 @@ class FalseClass
29
31
  def <= obj; !obj.nil? end
30
32
  def > obj; obj.nil? end
31
33
  def >= obj; !obj end
34
+
35
+ def call(*) self end
32
36
  end
33
37
 
34
38
  class NilClass
@@ -41,9 +41,10 @@ class Class
41
41
 
42
42
  # differs with #ancestors in that it doesn't show included modules
43
43
  def superclasses
44
- unfold(lambda {|c|!c}) {|c| [c.superclass, c]}
44
+ superclass ? superclass.unfold(lambda {|c|!c}) {|c| [c.superclass, c]} : []
45
45
  end
46
46
 
47
47
  end
48
48
 
49
- [Hash, Regexp, File, Dir, Range, Class, Module].each {|klass| klass.__init__}
49
+ require 'set'
50
+ [Hash, Array, Set, Regexp, File, Dir, Range, Class, Module].each {|klass| klass.__init__}
@@ -15,12 +15,23 @@ class Hash
15
15
  str = method.to_s
16
16
  if str =~ /=$/
17
17
  self[str[0..-2]] = args[0]
18
+ elsif !args.empty? or str =~ /[!?]$/
19
+ throw_no method
18
20
  else
19
- throw_no method if !args.empty? or str =~ /[!?]$/
20
21
  a = self[str]
21
22
  (a == default) ? self[method] : a
22
23
  end
23
24
  end
25
+
26
+ # Redefine since these methods are deprecated anyway
27
+ def type
28
+ a = self['type']
29
+ (a == default) ? self[:type] : a
30
+ end
31
+ def id
32
+ a = self['id']
33
+ (a == default) ? self[:id] : a
34
+ end
24
35
 
25
36
  end
26
37
 
@@ -22,7 +22,7 @@ class Module
22
22
  end
23
23
 
24
24
  def self_name
25
- @self_name ||= name.match[/[^:]+$/]
25
+ @self_name ||= name.match(/[^:]+$/)
26
26
  end
27
27
 
28
28
  def my_methods filter=//
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
  class Proc
3
3
  NULL = lambda {} unless defined? Proc::NULL
4
+ TRUE = lambda {true} unless defined? Proc::TRUE
5
+ FALSE = lambda {false} unless defined? Proc::FALSE
4
6
  attr_accessor :string
5
7
 
6
8
  def when
data/lib/rmtools/db.rb CHANGED
@@ -6,7 +6,11 @@ begin
6
6
  # fix for that mystic bug
7
7
  # /usr/lib/ruby/1.8/openssl/ssl-internal.rb:30: [BUG] Segmentation fault
8
8
  # ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux]
9
- require 'openssl/ssl'
9
+ if RUBY_VERSION < '1.9.3'
10
+ require 'openssl/ssl'
11
+ else
12
+ require 'openssl'
13
+ end
10
14
  rescue Exception
11
15
  p $!
12
16
  nil
@@ -89,6 +89,46 @@ module ActiveRecord
89
89
  "#{self.class.name.tableize}/#{id}"
90
90
  end
91
91
 
92
+ def self.select_rand(limit, options={})
93
+ cnt = options.delete :cnt
94
+ discnt = options.delete :discnt
95
+ where = options.delete :where
96
+ cnt_where = options.delete :cnt_where
97
+ tables = options.delete :tables
98
+ cnt_tables = options.delete :cnt_tables
99
+ fields = options.delete :fields
100
+
101
+ find_by_sql(["SELECT * FROM (
102
+ SELECT @cnt:=#{cnt ? cnt.to_i : 'COUNT(*)'}+1#{-discnt.to_i if discnt}, @lim:=#{limit.to_i}#{"FROM #{options[:cnt_tables] || table_name} WHERE #{cnt_where}" if !cnt}
103
+ ) vars
104
+ STRAIGHT_JOIN (
105
+ SELECT #{fields || table_name+'.*'}, @lim:=@lim-1 FROM #{tables || table_name} WHERE (@cnt:=@cnt-1) AND RAND() < @lim/@cnt#{" AND (#{where})" if where}
106
+ ) i", options])
107
+ end
108
+
109
+ class_attribute :enums
110
+ def self.enum hash
111
+ key = hash.keys.first
112
+ (self.enums ||= {}).merge! hash
113
+ define_attribute_methods if !attribute_methods_generated?
114
+ class_eval %{
115
+ def #{key}
116
+ missing_attribute('#{key}', caller) unless @attributes.has_key?('#{key}')
117
+ self.class.enums[:#{key}][@attributes['#{key}']]
118
+ end
119
+ def #{key}=(val)
120
+ write_attribute('#{key}', Fixnum === val ? val : self.class.enums[:#{key}].index val.to_s
121
+ end
122
+ }
123
+ end
124
+
125
+ # fix for thinking_sphinx equation in #instances_from_class:
126
+ # ids.collect {|obj_id| instances.detect do |obj| obj.primary_key_for_sphinx == obj_id end}
127
+ # where obj_id is Array
128
+ def primary_key_for_sphinx
129
+ [read_attribute(self.class.primary_key_for_sphinx)]
130
+ end
131
+
92
132
  end
93
133
 
94
134
  class Relation
@@ -6,8 +6,16 @@ class BlackHole
6
6
  # => #<BlackHole:0xb66367b0>
7
7
  #
8
8
  # Think twice before use it. It may devour your code!
9
- def method_missing(*)
10
- BlackHole.new
9
+ def method_missing(m, *args)
10
+ case m.to_s[-1,1]
11
+ when '?'; false
12
+ when '!'; nil
13
+ when '='; args.first
14
+ else self
15
+ end
11
16
  end
12
17
 
18
+ if RUBY_VERSION < '1.9'
19
+ undef id
20
+ end
13
21
  end
@@ -240,7 +240,7 @@ module RMTools
240
240
  self.class.__send__(:include, instructions_module)
241
241
  @Instructions = init_instructions
242
242
  @MainParseRE = MainParseRE
243
- add_method_seeker('.get_opts') {|s, args| $log << args}
243
+ add_method_seeker('.get_opts') {|s, args| $log <= args}
244
244
  end
245
245
 
246
246
  def add_instruction(re, &callback)
@@ -254,7 +254,7 @@ module RMTools
254
254
  else
255
255
  pattern = /(?:^|[\s#{Leftop}])(#{name})([(`"' ] *|:['"]?)/
256
256
  end
257
- $log<<pattern
257
+ $log <= pattern
258
258
  add_instruction(pattern) {|s, m|
259
259
  $log << m
260
260
  yield s, arguments(s, m)
@@ -44,20 +44,34 @@ module RMTools
44
44
  end
45
45
 
46
46
  def defaults
47
- puts %{ :q => false, # not print
47
+ puts %{ #common options:
48
+ :q => false, # not print
48
49
  :out => false, # output to file, may contain strftime's %H%M%Y etc for filename
49
- :color_out => false # do not clean control characters that make output to file colorful (set to true makes more readable out of tail -n/-f but hardly readable file as text by gui)
50
50
  :time => ["%H:%M:%S", "%03d"], # strftime, [msecs]
51
- :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}", # file:line :method
52
- :format => "%time %mode [%caller]: %text" # format of entire log string, %mode is {#{%w(debug log info warn).map {|i| @highlight[i.to_sym]}*', '}}}
51
+ :type => :console, # or :html
52
+ #console values:
53
+ :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}", # "file:line :method", %p is for fullpath
54
+ :format => "%time %mode [%caller]: %text" # format of entire log string, %mode is {#{%w(debug log info warn).map {|i| @highlight[i.to_sym]}*', '}}
55
+ :color_out => false # do not clean control characters that make output to file colorful; set to true makes more readable output of `tail' but hardly readable by gui file output
56
+ #html options:
57
+ :caller => "<a class='l'>%f:%l</a> <a class='m'>:%m</a>",
58
+ :format => "<div class='line'><a class='t'>%time</a> <a class='%mode'>%mode</m> [%caller]: <p>%text</p>%att</div>", # %att is for array of objects that should be formatted by the next option
59
+ :att =>"<div class='att'><div class='hide'>+</div><pre>%s</pre></div>", # .hide should be scripted to work like a spoiler
60
+ :serializer => RMTools::RMLogger::HTML # should respond to :render(obj); nil value means each object will be just #inspect'ed}
53
61
  end
54
62
 
55
63
  # set any needed params, the rest will be set by default
56
64
  def set_format *args
57
- global, format = args.fetch_opts [nil],
58
- :time => ["%H:%M:%S", "%03d"],
59
- :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}",
60
- :format => "%time %mode [%caller]: %text"
65
+ global, format = args.fetch_opts [nil], :type => :console, :time => ["%H:%M:%S", "%03d"]
66
+ format = if format[:type] == :html; {
67
+ :caller => "<a class='l'>%f:%l</a> <a class='m'>:%m</a>",
68
+ :format => "<div class='line'><a class='t'>%time</a> <a class='%mode'>%mode</m> [%caller]: <p>%text</p>%att</div>",
69
+ :att =>"<div class='att'><div class='hide'>+</div><pre>%s</pre></div>",
70
+ :serializer => RMTools::RMLogger::HTML
71
+ }; else {
72
+ :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}",
73
+ :format => "%time %mode [%caller]: %text"
74
+ } end.merge format
61
75
  if global
62
76
  _set_format @default_format, format
63
77
  else
@@ -76,27 +90,27 @@ module RMTools
76
90
  log_ = opts&NOLOG==0
77
91
  print_ = opts&NOPRINT==0
78
92
  str = cfg.fmt.dup
79
- str.sub! "%mode", @highlight[mode]
93
+ str.gsub! "%mode", @highlight[mode]
80
94
  if bind
81
95
  text = bind.report text
82
96
  elsif !text.is String
83
97
  text = text.inspect
84
98
  end
85
- str.sub! "%text", text
86
- str << "\n" if opts&INLINE==0
87
99
  out = cfg.out
88
100
  if cfg._time or cfg.path_format
89
101
  now = Time.now
90
102
  if cfg._time
91
103
  time = now.strftime cfg.tf[0]
92
104
  time << ".#{cfg.tf[1]%[now.usec/1000]}" if cfg.tf[1]
93
- str.sub! "%time", time
105
+ str.gsub! "%time", time
94
106
  end
95
107
  out = now.strftime cfg.out if cfg.path_format
96
108
  end
97
109
  if caler
98
- str.sub! "%caller", caler.sub(String::CALLER_RE, cfg.cf)
110
+ str.gsub! "%caller", caler.sub(String::CALLER_RE, cfg.cf)
99
111
  end
112
+ str.gsub! "%text", text
113
+ str << "\n" if opts&INLINE==0
100
114
  log_str = cfg.color_out ? str : @c.clean(str)
101
115
  RMTools.write out, log_str if log_
102
116
  Kernel.print str if print_
@@ -7,13 +7,17 @@ module RMTools
7
7
  quiet, mute_warn = $quiet, $log.mute_warn
8
8
  $quiet = $log.mute_warn = true
9
9
  t1 = Time.now
10
- timez.times {yield}
10
+ timez.times {yield} if timez > 0
11
11
  res = yield
12
- t2 = (Time.now.to_f*1000).round
13
- t1 = (t1.to_f*1000).round
12
+ t2 = Time.now
13
+ ts.times {}
14
+ t3 = Time.now.to_f*1000
15
+ t2 = t2.to_f*1000
16
+ t1 = t1.to_f*1000
17
+ delta = (t2 - t1 - (t3 - t2)).round.to_f
14
18
  $quiet, $log.mute_warn = quiet, mute_warn
15
19
  res = res.inspect
16
- 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"}"
20
+ puts "#{output ? "res: #{res.size > 1000 ? res[0...999]+"…" : res}\n" : "size of res string: #{res.to_s.size}, "}one: #{Painter.gray '%0.4fms'%[delta/ts]}, total: #{Painter.gray "#{delta}ms"}"
17
21
  end
18
22
 
19
23
  module_function :timer
@@ -3,6 +3,64 @@ require 'active_support/core_ext/array'
3
3
  RMTools::require 'functional/fold'
4
4
 
5
5
  class Array
6
+ # core methods overwrite
7
+ # sometimes we cannot afford do zillions of cycles just for ensure A | [] = A - [] = A or A & [] = []
8
+ # though - and & should be improved within C-extension to break loop when no items have lost in self
9
+ alias union |
10
+ alias induction +
11
+ alias subtraction -
12
+ alias intersection &
13
+ private :union, :induction, :subtraction, :intersection
14
+
15
+ def |(ary)
16
+ if empty?
17
+ ary.uniq
18
+ elsif ary.respond_to?:empty? and ary.empty?
19
+ dup
20
+ else union(ary)
21
+ end
22
+ end
23
+
24
+ def +(ary)
25
+ if empty?
26
+ if ary.respond_to?:empty? and ary.empty?
27
+ []
28
+ else ary.dup
29
+ end
30
+ elsif ary.respond_to?:empty? and ary.empty?
31
+ dup
32
+ else induction(ary)
33
+ end
34
+ end
35
+
36
+ def -(ary)
37
+ if empty?
38
+ []
39
+ elsif ary.respond_to?:empty? and ary.empty?
40
+ dup
41
+ else subtraction(ary)
42
+ end
43
+ end
44
+
45
+ def &(ary)
46
+ if empty? or (ary.respond_to?:empty? and ary.empty?)
47
+ []
48
+ else intersection(ary)
49
+ end
50
+ end
51
+
52
+ def ^(ary)
53
+ if empty? or (ary.respond_to? :empty? and ary.empty?)
54
+ [dup, ary.dup]
55
+ elsif self == ary
56
+ [[], []]
57
+ else
58
+ common = intersection ary
59
+ [self - common, ary - common]
60
+ end
61
+ end
62
+
63
+ alias diff ^
6
64
 
7
65
  # arithmetics
8
66
  def avg
@@ -97,6 +155,10 @@ class Array
97
155
  find {|e| e.__send__(key) == value}
98
156
  end
99
157
 
158
+ def select_by(key, value)
159
+ select {|e| e.__send__(key) == value}
160
+ end
161
+
100
162
  # concatenation
101
163
  # analogue to String#>>
102
164
  def >>(ary)
@@ -139,7 +201,7 @@ class Array
139
201
  def sum(identity=0, &b) foldl(:+, &b) || identity end
140
202
 
141
203
  # fastering activesupport's method
142
- def group_by(&b) count(:group, &b) end
204
+ def group_by(&b) arrange(:group, &b) end
143
205
 
144
206
 
145
207
 
@@ -14,14 +14,16 @@ unless defined? RMTools::Iterators
14
14
  # => [[1, 2, 3], [3, 4, 6]]
15
15
  class Array
16
16
  alias :throw_no :method_missing
17
- RMTools::Iterators = %r{^(#{(%w{every no select reject partition find_all find sum foldr}+instance_methods.grep(/_by$/))*'|'})_([\w\d\_]+[!?]?)}
17
+ RMTools::Iterators = %r{^(#{(instance_methods.grep(/_by$/)+%w{every no select reject partition find_all find sum foldr find_by select_by})*'|'})_([\w\d\_]+[!?]?)}
18
18
 
19
19
  def method_missing(method, *args, &block)
20
20
  if match = (meth = method.to_s).match(RMTools::Iterators)
21
21
  iterator, meth = match[1].to_sym, match[2].to_sym
22
22
  begin
23
- iterator = :every? if iterator == :every
24
- iterator = :no? if iterator == :no
23
+ case iterator
24
+ when :every then iterator = :every?
25
+ when :no then iterator = :no?
26
+ end
25
27
  return case iterator
26
28
  when :sum; sum(args.shift) {|i| i.__send__ meth, *args, &block}
27
29
  when :find_by; find_by(meth, *args)
@@ -28,6 +28,11 @@ class Range
28
28
  self & -range
29
29
  end
30
30
 
31
+ def ^(range)
32
+ common = self & range
33
+ self - common | range - common
34
+ end
35
+
31
36
  def x?(range)
32
37
  range_end = range.include_end.end
33
38
  self_end = self.include_end.end
@@ -169,6 +174,11 @@ class XRange
169
174
  self & -range
170
175
  end
171
176
 
177
+ def ^(range)
178
+ common = self & range
179
+ self - common | range - common
180
+ end
181
+
172
182
  private
173
183
 
174
184
  def intersect(range)
@@ -196,7 +206,7 @@ public
196
206
  end
197
207
 
198
208
  def include?(number_or_range)
199
- @ranges.find_include?(number_or_range)
209
+ @ranges.find {|r| r.include?(number_or_range)}
200
210
  end
201
211
 
202
212
  def begin
@@ -2,16 +2,60 @@
2
2
  RMTools::require 'fs/io'
3
3
 
4
4
  class File
5
+ PathMemo = {} if !defined? PathMemo
5
6
 
6
7
  def inspect
7
8
  "<#File \"#{path}\" #{closed? ? 'closed' : stat.size.bytes}>"
8
9
  end
9
10
 
10
- def self.include?(name, str)
11
- f = new name, 'r'
12
- incl = f.include? str
13
- f.close
14
- incl
11
+ class << self
12
+
13
+ def real_path path, memo=1
14
+ a = expand_path(path).split(/[\/\\]/)
15
+ a.each_index {|i|
16
+ if a[j=-(i+1)]['~']
17
+ n = i+2>a.size ? a[j] : join(a[0..-(i+2)], a[j])
18
+ a[j] = PathMemo[n] || real_name(n)
19
+ PathMemo[n] = a[j] if memo
20
+ else break
21
+ end
22
+ }
23
+ a*'/'
24
+ end
25
+
26
+ def real_name(df)
27
+ if file?(df)
28
+ new(df).real_name
29
+ elsif directory?(df)
30
+ Dir.new(df).real_name
31
+ end
32
+ end
33
+
34
+ def modify(pattern, bak=true, &block)
35
+ Dir[pattern].select {|file| __modify(file, bak, &block)}
36
+ end
37
+
38
+
39
+ def include?(name, str)
40
+ f = new name, 'r'
41
+ incl = f.include? str
42
+ f.close
43
+ incl
44
+ end
45
+
46
+ private
47
+ def __modify(file, bak=true)
48
+ if orig_text = read(file)
49
+ copy_text = orig_text.dup
50
+ res_text = yield copy_text
51
+ # res may be nil in case of gsub!
52
+ # though copy_text wouldn't be equal orig_text if something has been changed
53
+ if orig_text != res_text and (res_text or orig_text != copy_text)
54
+ rename file, file+'.bak' if bak
55
+ RMTools.rw(file, res_text.is(String) ? res_text : copy_text)
56
+ end
57
+ end
58
+ end
15
59
  end
16
60
 
17
61
  def include?(str)
@@ -39,13 +83,6 @@ class File
39
83
  File.new(path,'r')
40
84
  end
41
85
 
42
- def self.modify(file, bak=true)
43
- orig_text = read file
44
- text = yield orig_text
45
- rename file, file+'.bak' if bak
46
- RMTools.rw(file, text.is(String) ? text : orig_text)
47
- end
48
-
49
86
  def cp(df)
50
87
  dir = File.dirname df
51
88
  FileUtils.mkpath dir unless File.directory? dir
@@ -70,7 +107,7 @@ class File
70
107
  pc.reject! {|f| !f[re]}
71
108
  end
72
109
  if defined? Amatch
73
- count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|f| (ext ? f[0..-(ext.size+2)] : f).upcase.ljust(ms).send(m, n)}.max[1]}.count.to_a
110
+ count = [:hamming_similar, :levenshtein_similar, :jaro_similar].sum {|m| pc.group_by {|f| (ext ? f[0..-(ext.size+2)] : f).upcase.ljust(ms).send(m, n)}.max[1]}.arrange.to_a
74
111
  max = count.lasts.max
75
112
  res = count.find {|c|
76
113
  c[1] == max and File.file?(df=File.join(pp, c[0])) and File.stat(df) == ss
@@ -82,26 +119,4 @@ class File
82
119
  }
83
120
  end
84
121
 
85
- PathMemo = {} if !defined? PathMemo
86
- def self.real_path path, memo=1
87
- a = expand_path(path).split(/[\/\\]/)
88
- a.each_index {|i|
89
- if a[j=-(i+1)]['~']
90
- n = i+2>a.size ? a[j] : join(a[0..-(i+2)], a[j])
91
- a[j] = PathMemo[n] || real_name(n)
92
- PathMemo[n] = a[j] if memo
93
- else break
94
- end
95
- }
96
- a*'/'
97
- end
98
-
99
- def self.real_name(df)
100
- if file?(df)
101
- new(df).real_name
102
- elsif directory?(df)
103
- Dir.new(df).real_name
104
- end
105
- end
106
-
107
122
  end
data/lib/rmtools/fs/io.rb CHANGED
@@ -64,13 +64,13 @@ module RMTools
64
64
  if file = dest.find {|f| File.file?(f.tr '\\', '/')}
65
65
  File.open(file.tr('\\', '/'), File::RDONLY) {|f| f.read}
66
66
  else
67
- warn "couldn't read from neither #{dest[0].inspect} nor #{dest[1..-1].inspects*' nor '}; files missed (called from #{caller[0]})"
67
+ warn "couldn't read from neither #{dest[0].inspect} nor #{dest[1..-1].inspects*' nor '}; files missed (called from #{caller[2]})"
68
68
  end
69
69
  else
70
70
  if File.file? dest.tr('\\', '/')
71
71
  File.open(dest.tr('\\', '/'), File::RDONLY) {|f| f.read}
72
72
  else
73
- warn "couldn't read from #{dest.inspect}; file missed (called from #{caller[0]})"
73
+ warn "couldn't read from #{dest.inspect}; file missed (called from #{caller[2]})"
74
74
  end
75
75
  end
76
76
  }
@@ -1,19 +1,17 @@
1
1
  # encoding: utf-8
2
2
  require File.expand_path('require', File.dirname(__FILE__))
3
3
  RMTools::require 'fs'
4
- require 'digest/md5'
5
4
 
6
- def ext_files_not_modified(ext_name='rmtools', version='\d')
7
- gem = Gem.source_index.select {|a| a[0] =~ /^#{ext_name}-#{version}$/}[0]
8
- return unless gem
9
- gemspec = gem[1]
10
- path = gemspec.full_gem_path
11
- !gemspec.files.grep(/^ext\//).find {|f|
12
- !(File.file?(installed=File.join(path, f)) and IO.read(f) == IO.read(installed))
13
- }
5
+ def ext_files_not_modified(ext_name, version)
6
+ spec = Gem::Specification.find_all_by_name(ext_name).find {|s| s.version.version == version}
7
+ return unless spec
8
+ path = spec.full_gem_path
9
+ !spec.files.grep(/^ext\//).find {|f|
10
+ !(File.file?(installed=File.join(path, f)) and IO.read(f) == IO.read(installed))
11
+ }
14
12
  end
15
13
 
16
14
  def compile_manifest(exc=%w(pkg))
17
- fs = Dir.new('.').recursive_content
18
- RMTools.rw 'Manifest.txt', (exc ? fs.reject {|i| i[/^(#{exc*'|'})\//]} : fs)*"\n"
15
+ fs = Dir.new('.').recursive_content
16
+ RMTools.rw 'Manifest.txt', (exc ? fs.reject {|i| i[/^(#{exc*'|'})\//]} : fs)*"\n"
19
17
  end
@@ -1,18 +1,41 @@
1
1
  # encoding: utf-8
2
2
  require 'iconv'
3
+ # Although ruby >= 1.9.3 would complain about not using String#encode, iconv is 2-4 times faster and still handles the ruby string encoding
3
4
 
4
5
  module RMTools
5
6
  ANSI2UTF = Iconv.new("UTF-8", "WINDOWS-1251").method :iconv
6
7
  UTF2ANSI = Iconv.new("WINDOWS-1251", "UTF-8").method :iconv
7
-
8
+
8
9
  module Cyrillic
9
10
  RU_LETTERS = "абвгдеёжзийклмнопрстуфхцчшщьыъэюя", "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
10
11
 
11
- if RUBY_VERSION >= '1.9'
12
+ if RUBY_VERSION > '1.9'
12
13
  ANSI_LETTERS_UC = ["\270\340-\377", "\250\300-\337"].force_encodings "Windows-1251"
13
14
  ANSI_LETTERS_DC = ANSI_LETTERS_UC.reverse
14
15
  ANSI_YOYE = ["\270\250", "\345\305"].force_encodings "Windows-1251"
15
16
  ANSI_ENCODING = ANSI_LETTERS_UC[0].encoding
16
17
  end
17
18
  end
19
+
20
+ end
21
+
22
+ class String
23
+
24
+ # Actually, for short strings and 1251<->65001 it's much faster to use predefined ANSI2UTF and UTF2ANSI procs
25
+ def utf(from_encoding='WINDOWS-1251')
26
+ Iconv.new('UTF-8', from_encoding).iconv(self)
27
+ end
28
+
29
+ def ansi(from_encoding='UTF-8')
30
+ Iconv.new('WINDOWS-1251', from_encoding).iconv(self)
31
+ end
32
+
33
+ def utf!(from_encoding='WINDOWS-1251')
34
+ replace utf from_encoding
35
+ end
36
+
37
+ def ansi!(from_encoding='UTF-8')
38
+ replace ansi from_encoding
39
+ end
40
+
18
41
  end
@@ -1,13 +1,8 @@
1
1
  # encoding: utf-8
2
- RMTools::require 'lang/helpers'
2
+ RMTools::require 'lang/ansi'
3
3
 
4
4
  class String
5
5
  include RMTools::Cyrillic
6
-
7
- def cyr_ic
8
- gsub(/[ёЁ]/, '[ёЁ]').gsub(/[йЙ]/, '[йЙ]').gsub(/[цЦ]/, '[цЦ]').gsub(/[уУ]/, '[уУ]').gsub(/[кК]/, '[кК]').gsub(/[еЕ]/, '[еЕ]').gsub(/[нН]/, '[нН]').gsub(/[гГ]/, '[гГ]').gsub(/[шШ]/, '[шШ]').gsub(/[щЩ]/, '[щЩ]').gsub(/[зЗ]/, '[зЗ]').gsub(/[хХ]/, '[хХ]').gsub(/[ъЪ]/, '[ъЪ]').gsub(/[фФ]/, '[фФ]').gsub(/[ыЫ]/, '[ыЫ]').gsub(/[вВ]/, '[вВ]').gsub(/[аА]/, '[аА]').gsub(/[пП]/, '[пП]').gsub(/[рР]/, '[рР]').gsub(/[оО]/, '[оО]').gsub(/[лЛ]/, '[лЛ]').gsub(/[дД]/, '[дД]').gsub(/[жЖ]/, '[жЖ]').gsub(/[эЭ]/, '[эЭ]').gsub(/[яЯ]/, '[яЯ]').gsub(/[чЧ]/, '[чЧ]').gsub(/[сС]/, '[сС]').gsub(/[мМ]/, '[мМ]').gsub(/[иИ]/, '[иИ]').gsub(/[тТ]/, '[тТ]').gsub(/[ьЬ]/, '[ьЬ]').gsub(/[бБ]/, '[бБ]').gsub(/[юЮ]/, '[юЮ]')
9
- end
10
- alias :ci :cyr_ic
11
6
 
12
7
  def translit
13
8
  gsub(/[ёЁ]/, 'yo').gsub(/[йЙ]/, 'y').gsub(/[цЦ]/, 'c').gsub(/[уУ]/, 'u').gsub(/[кК]/, 'k').gsub(/[еЕ]/, 'e').gsub(/[нН]/, 'n').gsub(/[гГ]/, 'g').gsub(/[шШ]/, 'sh').gsub(/[щЩ]/, 'sch').gsub(/[зЗ]/, 'z').gsub(/[хХ]/, 'h').gsub(/[ьЬъЪ]/, "'").gsub(/[фФ]/, 'f').gsub(/[иИыЫ]/, 'i').gsub(/[вВ]/, 'v').gsub(/[аА]/, 'a').gsub(/[пП]/, 'p').gsub(/[рР]/, 'r').gsub(/[оО]/, 'o').gsub(/[лЛ]/, 'l').gsub(/[дД]/, 'd').gsub(/[жЖ]/, 'j').gsub(/[эЭ]/, 'e').gsub(/[яЯ]/, 'ya').gsub(/[чЧ]/, 'ch').gsub(/[сС]/, 's').gsub(/[мМ]/, 'm').gsub(/[тТ]/, 't').gsub(/[бБ]/, 'b').gsub(/[юЮ]/, 'yu')
@@ -26,11 +21,7 @@ class String
26
21
  self !~ /[^А-пр-ёЁ]/
27
22
  end
28
23
 
29
- def csqueeze
30
- ANSI2UTF[UTF2ANSI[self].squeeze]
31
- end
32
-
33
- if RUBY_VERSION >= "1.9"
24
+ if RUBY_VERSION > "1.9"
34
25
 
35
26
  def ru2en
36
27
  tr "ёйцукенгшщзхъфывапролдэячсмить/.ю?,б\"№;:жЁЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИВТЬБЮ", "`qwertyuiop[]asdfghjkl'zxcvbnm|/.&?,@\#$^;~QWERTYUIOP{}ASDFGHJKL:\"ZXCVBDNM<>"
@@ -52,10 +43,6 @@ class String
52
43
  tr(*ANSI_LETTERS_DC)
53
44
  end
54
45
 
55
- def ccap
56
- self[0].cupcase + self[1..-1]
57
- end
58
-
59
46
  def cuncap
60
47
  self[0].cdowncase + self[1..-1]
61
48
  end
@@ -66,10 +53,14 @@ class String
66
53
  tr(*ANSI_YOYE)
67
54
  end
68
55
 
69
- alias csize size
70
- alias cljust ljust
71
- alias cjust just
72
- alias ccenter center
56
+ alias csize size
57
+ alias cljust ljust
58
+ alias cjust rjust
59
+ alias ccenter center
60
+ alias ccap capitalize
61
+ alias csqueeze squeeze
62
+
63
+ def ci; self end
73
64
  else
74
65
 
75
66
  def csize
@@ -80,8 +71,8 @@ class String
80
71
  ANSI2UTF[UTF2ANSI[self].ljust(*args)]
81
72
  end
82
73
 
83
- def cjust(*args)
84
- ANSI2UTF[UTF2ANSI[self].just(*args)]
74
+ def crjust(*args)
75
+ ANSI2UTF[UTF2ANSI[self].rjust(*args)]
85
76
  end
86
77
 
87
78
  def ccenter(*args)
@@ -108,6 +99,10 @@ class String
108
99
  self[0,2].cdowncase(encode) + self[2..-1]
109
100
  end
110
101
 
102
+ def csqueeze
103
+ ANSI2UTF[UTF2ANSI[self].squeeze]
104
+ end
105
+
111
106
  def rmumlaut(encode=1)
112
107
  encode ?
113
108
  ANSI2UTF[UTF2ANSI[self].tr("\270\250", "\345\305")]:
@@ -121,6 +116,10 @@ class String
121
116
  def en2ru
122
117
  gsub("`", "ё").gsub("q", "й").gsub("w", "ц").gsub("e", "у").gsub("r", "к").gsub("t", "е").gsub("y", "н").gsub("u", "г").gsub("i", "ш").gsub("o", "щ").gsub("p", "з").gsub("[", "х").gsub("]", "ъ").gsub("a", "ф").gsub("s", "ы").gsub("d", "в").gsub("f", "а").gsub("g", "п").gsub("h", "р").gsub("j", "о").gsub("k", "л").gsub("l", "д").gsub(";", "ж").gsub(":", "Ж").gsub("'", "э").gsub("z", "я").gsub("x", "ч").gsub("c", "с").gsub("v", "м").gsub("b", "и").gsub("n", "т").gsub("m", "ь").gsub(",", "б").gsub(".", "ю").gsub("/", ".").gsub("|", "/").gsub("?", ",").gsub("\"", "Э").gsub("@", "\"").gsub("#", "№").gsub("$", ";").gsub("^", ":").gsub("&", "?").gsub("~", "Ё").gsub("Q", "Й").gsub("W", "Ц").gsub("E", "У").gsub("R", "К").gsub("T", "Е").gsub("Y", "Н").gsub("U", "Г").gsub("I", "Ш").gsub("O", "Щ").gsub("P", "З").gsub("{", "Х").gsub("}", "Ъ").gsub("A", "Ф").gsub("S", "Ы").gsub("D", "В").gsub("F", "А").gsub("G", "П").gsub("H", "Р").gsub("J", "О").gsub("K", "Л").gsub("L", "Д").gsub("Z", "Я").gsub("X", "Ч").gsub("C", "С").gsub("V", "М").gsub("B", "И").gsub("N", "Т").gsub("M", "Ь").gsub("<", "Б").gsub(">", "Ю")
123
118
  end
119
+
120
+ def ci
121
+ gsub(/[ёЁ]/, '[ёЁ]').gsub(/[йЙ]/, '[йЙ]').gsub(/[цЦ]/, '[цЦ]').gsub(/[уУ]/, '[уУ]').gsub(/[кК]/, '[кК]').gsub(/[еЕ]/, '[еЕ]').gsub(/[нН]/, '[нН]').gsub(/[гГ]/, '[гГ]').gsub(/[шШ]/, '[шШ]').gsub(/[щЩ]/, '[щЩ]').gsub(/[зЗ]/, '[зЗ]').gsub(/[хХ]/, '[хХ]').gsub(/[ъЪ]/, '[ъЪ]').gsub(/[фФ]/, '[фФ]').gsub(/[ыЫ]/, '[ыЫ]').gsub(/[вВ]/, '[вВ]').gsub(/[аА]/, '[аА]').gsub(/[пП]/, '[пП]').gsub(/[рР]/, '[рР]').gsub(/[оО]/, '[оО]').gsub(/[лЛ]/, '[лЛ]').gsub(/[дД]/, '[дД]').gsub(/[жЖ]/, '[жЖ]').gsub(/[эЭ]/, '[эЭ]').gsub(/[яЯ]/, '[яЯ]').gsub(/[чЧ]/, '[чЧ]').gsub(/[сС]/, '[сС]').gsub(/[мМ]/, '[мМ]').gsub(/[иИ]/, '[иИ]').gsub(/[тТ]/, '[тТ]').gsub(/[ьЬ]/, '[ьЬ]').gsub(/[бБ]/, '[бБ]').gsub(/[юЮ]/, '[юЮ]')
122
+ end
124
123
 
125
124
  end
126
125
 
@@ -3,7 +3,10 @@ RMTools::require 'lang/cyrillic'
3
3
 
4
4
  class Regexp
5
5
 
6
- def cyr_ic() Regexp.new(source.cyr_ic, options) end
7
- alias :ci :cyr_ic
6
+ if RUBY_VERSION > '1.9'
7
+ def ci; self end
8
+ else
9
+ def ci; Regexp.new(source.cyr_ic, options) end
10
+ end
8
11
 
9
12
  end
@@ -11,7 +11,7 @@ class Regexp
11
11
  bs = klass = count = nil
12
12
  group_marks = []
13
13
  oppose = {'('=>')', ')'=>'(', '^'=>'$', '$'=>'^'}
14
- borders = {'Z'=>'\A', 'A'=>'\Z'}
14
+ borders = {'Z'=>'\A', 'A'=>'\Z', 'z'=>'\a', 'a'=>'\z'}
15
15
  ext = options&2 != 0
16
16
  StringScanner(source).each(/./) {|s|
17
17
  if (m = s.matched) == '\\'
@@ -30,7 +30,7 @@ class String
30
30
  'pathname' => m[5] || '/',
31
31
  'path' => m[6] || '',
32
32
  'ext' => m[7],
33
- 'query' => m[8] && m[8].to_hash(false),
33
+ 'query' => m[8] && m[8].to_params(false),
34
34
  'anchor' => m[9] }
35
35
  when :caller
36
36
  m = match CALLER_RE
@@ -79,5 +79,14 @@ class String
79
79
  #end
80
80
  #
81
81
  # this method defined in Enumerable and returns Enumerable::Enumerator that should be converted to array of integers, not hex-strings
82
+ if RUBY_VERSION < '1.9'
83
+ def symbols_count
84
+ unpack('U*').size
85
+ end
86
+ else
87
+ def symbols_count
88
+ size
89
+ end
90
+ end
82
91
 
83
92
  end
@@ -59,7 +59,7 @@ class String
59
59
  private
60
60
  def split_by_syntax(str, maxlen, buflen=0)
61
61
  len, add = maxlen - buflen, nil
62
- [/[^.?!]+\z/, /[^;]+\z/, /[^\n]+/, /\S+\z/, /[^。]+z/, /[^、]+z/].each {|t|
62
+ [/[^.?!…]+\z/, /[^;]+\z/, /[^,:]+\z/, /[^\n]+/, /\S+\z/, /[^。、]+z/].each {|t|
63
63
  if !(add = str[t]) or add.size <= len
64
64
  return add
65
65
  end
@@ -116,13 +116,31 @@ class String
116
116
 
117
117
  # 'An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. '.cut_line 100
118
118
  # => "An elegant way to factor duplication out of options passed to a series of method calls..."
119
+ if RUBY_VERSION < '1.9'
119
120
  def cut_line(maxlen, *opts)
120
121
  terminator, opts = opts.fetch_opts [:syntax, :flags]
121
- opts[:charsize] ||= RUBY_VERSION < '1.9' && cyr? ? 2 : 1
122
+ opts[:charsize] ||= cyr? ? 2 : 1
122
123
  return self if size <= maxlen
123
- maxlen -= 3
124
- split_to_blocks(maxlen*opts[:charsize], terminator, :strips => true, :strict_overhead => false, :lines => 1)[0][0, maxlen].chomp('.') + '...'
124
+ blocks = split_to_blocks(maxlen*opts[:charsize]-3, terminator, :strips => true, :strict_overhead => false, :lines => 1)
125
+ cuted = (blocks[0] || self)[0, maxlen]
126
+ if terminator == :syntax
127
+ cuted.gsub!(/[.!?,;]$/, '')
128
+ else cuted.chomp!('.')
129
+ end
130
+ cuted + '…'
131
+ end
132
+ else
133
+ def cut_line(maxlen, terminator=:syntax)
134
+ return self if size <= maxlen
135
+ blocks = split_to_blocks(maxlen-1, terminator, :strips => true, :strict_overhead => false, :lines => 1)
136
+ cuted = (blocks[0] || self)[0, maxlen]
137
+ if terminator == :syntax
138
+ cuted.gsub!(/[.!?,;]$/, '')
139
+ else cuted.chomp!('.')
140
+ end
141
+ cuted + '…'
125
142
  end
143
+ end
126
144
 
127
145
  # puts 'An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. '.split_to_lines 50
128
146
  # produces:
@@ -134,12 +152,19 @@ class String
134
152
  #
135
153
  # This method is use cyrillic lib only to detect char byte-length
136
154
  # options: charsize, no_blanks, strips
155
+ if RUBY_VERSION < '1.9'
156
+ def split_to_lines(maxlen, *opts)
157
+ raise Exception, "Can't break text with maxlen = #{maxlen}" if maxlen < 1
158
+ opts = opts.fetch_opts([:flags], :strips => true).merge(:strict_overhead => false)
159
+ opts[:charsize] ||= a[0].cyr? ? 2 : 1
160
+ split("\n").map {|string| string.strip.split_to_blocks(maxlen*opts[:charsize], opts)}.flatten*"\n"
161
+ end
162
+ else
137
163
  def split_to_lines(maxlen, *opts)
138
164
  raise Exception, "Can't break text with maxlen = #{maxlen}" if maxlen < 1
139
- opts = opts.fetch_opts [:flags], :strips=>true
140
- a = split("\n")
141
- opts[:charsize] ||= RUBY_VERSION < '1.9' && a[0].cyr? ? 2 : 1
142
- a.map {|string| string.strip.split_to_blocks(maxlen*opts[:charsize], opts.merge(:strict_overhead => false))}.flatten*"\n"
165
+ opts = opts.fetch_opts([:flags], :strips => true).merge(:strict_overhead => false)
166
+ split("\n").map {|string| string.strip.split_to_blocks(maxlen, opts)}.flatten*"\n"
143
167
  end
168
+ end
144
169
 
145
170
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- RMTools::require 'lang/helpers'
2
+ RMTools::require 'lang/ansi'
3
3
 
4
4
  class String
5
5
 
@@ -11,6 +11,8 @@ module LibXML
11
11
  raise XML::Error, "can't process '#{$1}' operator"
12
12
  end
13
13
  x = xpath.dup
14
+ x.gsub! %r{([^\\])\s*>\s*}, '\1/'
15
+ x.gsub! %r{([^\\])\s+}, '\1//'
14
16
  x.gsub! %r{\.([\w-]+)([\[\{/]|\Z)}, '[@class="\1"]\2'
15
17
  x.gsub! %r{#([\w-]+)([\[\{/]|\Z)}, '[@id="\1"]\2'
16
18
  x.gsub! %r{(^|/)([^.#\w*/'"])}, '\1*\2'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmtools
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 3
10
- version: 1.2.3
9
+ - 7
10
+ version: 1.2.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Shinku
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-02 00:00:00 +03:00
19
- default_executable:
18
+ date: 2012-05-18 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: rake
@@ -65,7 +64,7 @@ dependencies:
65
64
  version: "2.12"
66
65
  type: :development
67
66
  version_requirements: *id003
68
- description: Applied framework primarily for debug and text/arrays/files operation.
67
+ description: Applied library primarily for debug and text/arrays/files processing purposes.
69
68
  email:
70
69
  - tinbka@gmail.com
71
70
  executables: []
@@ -119,7 +118,6 @@ files:
119
118
  - lib/rmtools/core/regexp.rb
120
119
  - lib/rmtools/core/class.rb
121
120
  - lib/rmtools/core/proc.rb
122
- - lib/rmtools/lang/helpers.rb
123
121
  - lib/rmtools/lang/ansi.rb
124
122
  - lib/rmtools/lang/regexp.rb
125
123
  - lib/rmtools/lang/cyrillic.rb
@@ -163,6 +161,7 @@ files:
163
161
  - lib/rmtools/require.rb
164
162
  - lib/rmtools/xml.rb
165
163
  - lib/rmtools/conversions.rb
164
+ - lib/rmtools/conversions/json.rb
166
165
  - lib/rmtools/conversions/string.rb
167
166
  - lib/rmtools/conversions/enum.rb
168
167
  - lib/rmtools/conversions/int.rb
@@ -174,7 +173,6 @@ files:
174
173
  - ./Manifest.txt
175
174
  - ./License.txt
176
175
  - ./README.txt
177
- has_rdoc: true
178
176
  homepage: http://github.com/tinbka
179
177
  licenses: []
180
178
 
@@ -205,9 +203,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
203
  requirements: []
206
204
 
207
205
  rubyforge_project: rmtools
208
- rubygems_version: 1.5.0
206
+ rubygems_version: 1.8.17
209
207
  signing_key:
210
208
  specification_version: 3
211
- summary: Yet another Ruby applied framework
209
+ summary: Yet another Ruby applied lib
212
210
  test_files: []
213
211
 
@@ -1,24 +0,0 @@
1
- # encoding: utf-8
2
- RMTools::require 'lang/ansi'
3
-
4
- class String
5
- ANSI2UTF = Iconv.new("UTF-8", "WINDOWS-1251").method :iconv
6
- UTF2ANSI = Iconv.new("WINDOWS-1251", "UTF-8").method :iconv
7
-
8
- # Actually, for short strings and 1251<->65001 it's much faster to use predefined ANSI2UTF and UTF2ANSI procs
9
- def utf(from_encoding='WINDOWS-1251')
10
- Iconv.new('UTF-8', from_encoding).iconv(self)
11
- end
12
-
13
- def utf!(from_encoding='WINDOWS-1251')
14
- replace utf from_encoding
15
- end
16
-
17
- def ansi(from_encoding='UTF-8')
18
- Iconv.new('WINDOWS-1251', from_encoding).iconv(self)
19
- end
20
-
21
- def ansi!(from_encoding='UTF-8')
22
- replace ansi from_encoding
23
- end
24
- end