Class: String

Inherits:
Object show all
Includes:
Nuggets::String::WcMixin
Defined in:
lib/nuggets/string/case.rb,
lib/nuggets/string/wc.rb,
lib/nuggets/util/i18n.rb,
lib/nuggets/string/msub.rb,
lib/nuggets/string/nsub.rb,
lib/nuggets/string/evaluate.rb,
lib/nuggets/string/word_wrap.rb,
lib/nuggets/string/sub_with_md.rb,
lib/nuggets/util/ansicolor2css.rb,
lib/nuggets/util/dotted_decimal.rb,
lib/nuggets/string/capitalize_first.rb

Overview

#

A component of ruby-nuggets, some extensions to the Ruby programming # language. #

#

Copyright © 2007-2008 Jens Wille #

#

Authors: #

Jens Wille <[email protected]>                                    #
                                                                        #

ruby-nuggets is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 3 of the License, or (at your option) # any later version. #

#

ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. #

#

You should have received a copy of the GNU General Public License along # with ruby-nuggets. If not, see <www.gnu.org/licenses/>. #

#

++

Defined Under Namespace

Modules: Case

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Nuggets::String::WcMixin

#byte_count, #char_count, #count_by_re, #count_by_re2, #line_count, #wc, #word_count

Class Method Details

.gimme_match_data!Object

call-seq:

gimme_match_data!

Replaces the traditional substitution methods with their MatchData passing equivalents. USE WITH CAUTION!



82
83
84
85
86
87
# File 'lib/nuggets/string/sub_with_md.rb', line 82

def self.gimme_match_data!
  alias_method :sub,   :sub_with_md
  alias_method :sub!,  :sub_with_md!
  alias_method :gsub,  :gsub_with_md
  alias_method :gsub!, :gsub_with_md!
end

Instance Method Details

#ansicolor2cssObject



86
87
88
# File 'lib/nuggets/util/ansicolor2css.rb', line 86

def ansicolor2css
  Util::ANSIColor2CSS.convert(self)
end

#capitalize_firstObject

call-seq:

str.capitalize_first => new_string

Capitalizes the first character in str, but without downcasing the rest like String#capitalize does.



35
36
37
38
# File 'lib/nuggets/string/capitalize_first.rb', line 35

def capitalize_first
  return self if empty?
  self[0..0].upcase << self[1..-1]
end

#capitalize_first!Object

call-seq:

str.capitalize_first! => str

Destructive version of #capitalize_first.



44
45
46
# File 'lib/nuggets/string/capitalize_first.rb', line 44

def capitalize_first!
  replace capitalize_first
end

#capitalized?Boolean

call-seq:

str.capitalized? => true or false

Tell whether str is capitalized.

Returns:

  • (Boolean)


78
79
80
# File 'lib/nuggets/string/case.rb', line 78

def capitalized?
  self == capitalize
end

#caseObject

call-seq:

str.case => aSymbol

Returns a symbol indicating the case of str.



42
43
44
45
46
# File 'lib/nuggets/string/case.rb', line 42

def case
  self == downcase ? Case::LOWER :
  self == upcase   ? Case::UPPER :
                     Case::MIXED
end

#evaluate(binding = TOPLEVEL_BINDING) ⇒ Object

call-seq:

str.evaluate(binding = TOPLEVEL_BINDING) => new_str

Basically turns Kernel#eval into an instance method of String – inspired by Ruby Cookbook example 1.3. This allows to pre-populate strings with substitution expressions (“#…”) that can get evaluated in a different environment (= binding) at a later point.



37
38
39
# File 'lib/nuggets/string/evaluate.rb', line 37

def evaluate(binding = TOPLEVEL_BINDING)
  eval(%Q{%Q{#{self}}}, binding)
end

#from_dotted_decimalObject

call-seq:

str.from_dotted_decimal => anInteger

Converts str from dotted-decimal notation to integer.



48
49
50
# File 'lib/nuggets/util/dotted_decimal.rb', line 48

def from_dotted_decimal
  split('.').map { |i| i.to_i.to_binary_s(8) }.join.to_i(2)
end

#gsub_with_md(pattern, replacement = nil) ⇒ Object

call-seq:

str.gsub_with_md(pattern) { |match_data| ... } => new_str

Just like #gsub, but passes the MatchData object instead of the current match string to the block.



61
62
63
64
65
# File 'lib/nuggets/string/sub_with_md.rb', line 61

def gsub_with_md(pattern, replacement = nil)
  replacement ?
    gsub_without_md(pattern, replacement) :
    (_dup = dup).gsub_with_md!(pattern) { |*a| yield(*a) } || _dup
end

#gsub_with_md!(pattern, replacement = nil) ⇒ Object

call-seq:

str.gsub_with_md!(pattern) { |match_data| ... } => str or nil

Destructive version of #gsub_with_md.



71
72
73
74
75
# File 'lib/nuggets/string/sub_with_md.rb', line 71

def gsub_with_md!(pattern, replacement = nil)
  replacement ?
    gsub_without_md!(pattern, replacement) :
    gsub_without_md!(pattern) { |match| yield $~ }
end

#lower_case?Boolean Also known as: downcase?

call-seq:

str.lower_case? => true or false

Tell whether str is all lower case.

Returns:

  • (Boolean)


52
53
54
# File 'lib/nuggets/string/case.rb', line 52

def lower_case?
  self.case == Case::LOWER
end

#mixed_case?Boolean

call-seq:

str.mixed_case? => true or false

Tell whether str is mixed case.

Returns:

  • (Boolean)


70
71
72
# File 'lib/nuggets/string/case.rb', line 70

def mixed_case?
  self.case == Case::MIXED
end

#msub(*substitutions) ⇒ Object

call-seq:

str.msub(*substitutions) => new_str

Performs multiple substitutions on str with order being taken into account (thus results of previous substitutions won’t be subject to later ones) – inspired by Ruby Cookbook example 1.18.

The substitutions parameter can be an array or a list of [pattern, substitution] pairs, or, simply, a hash. Note that, when using a hash, the ordering of how substitutions are processed might differ from what you intended – instead use an array when order matters. pattern can be a string or a regexp, substitution may contain string expressions (cf. #evaluate).



45
46
47
# File 'lib/nuggets/string/msub.rb', line 45

def msub(*substitutions)
  (_dup = dup).msub!(*substitutions) || _dup
end

#msub!(*substitutions) ⇒ Object

call-seq:

str.msub!(*substitutions) => str or nil

Destructive version of #msub.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/nuggets/string/msub.rb', line 53

def msub!(*substitutions)
  substitutions = substitutions.first if substitutions.first.is_a?(Hash)

  binding = substitutions.is_a?(Hash) ? substitutions.delete(:__binding__) :
    substitutions.last.is_a?(Hash) ? substitutions.pop[:__binding__] : nil
  binding ||= Kernel.binding

  keys, subs, cache = [], [], {}

  substitutions.each { |key, value|
    key = Regexp.new(Regexp.escape(key)) unless key.is_a?(Regexp)

    keys << key
    subs << [key, value]
  }

  gsub!(Regexp.union(*keys)) { |match|
    cache[match] ||= begin
      eval("__match__ = #{match.inspect}", binding)
      subs.find { |key, _| key =~ match }.last.evaluate(binding)
    end
  }
end

#nsub(*args) ⇒ Object

call-seq:

str.nsub(pattern, replacement, count) => new_str
str.nsub(pattern, count) { |match| ... } => new_str

Returns a copy of str with the first count occurrences of pattern replaced with either replacement or the value of the block.



36
37
38
39
40
41
# File 'lib/nuggets/string/nsub.rb', line 36

def nsub(*args)
  _dup = dup
  (block_given? ?
    _dup.nsub!(*args) { |*a| yield(*a) } :
    _dup.nsub!(*args)) || _dup
end

#nsub!(*args) ⇒ Object

call-seq:

str.nsub!(pattern, replacement, count) => str or nil
str.nsub!(pattern, count) { |match| ... } => str or nil

Performs the substitutions of #nsub in place, returning str, or nil if no substitutions were performed.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/nuggets/string/nsub.rb', line 49

def nsub!(*args)
  pattern, i = args.first, 0

  case args.size
    when 2
      # Only +count+ given
      count = args.last

      gsub!(pattern) { |match| (i += 1) <= count ? yield(match) : match }
    when 3
      # Both +replacement+ and +count+ given;
      # ignore block (just like String#gsub does)
      replacement, count = args.values_at(1, 2)

      gsub!(pattern) { |match| (i += 1) <= count ? replacement : match }
    else
      raise ArgumentError, "wrong number of arguments (#{args.size} for 2-3)"
  end
end

#replace_diacriticsObject

call-seq:

str.replace_diacritics => new_str

Substitutes any diacritics in str with their replacements as per Util::I18n::DIACRITICS.



110
111
112
# File 'lib/nuggets/util/i18n.rb', line 110

def replace_diacritics
  (_dup = dup).replace_diacritics! || _dup
end

#replace_diacritics!Object

call-seq:

str.replace_diacritics! => str or nil

Destructive version of #replace_diacritics.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/nuggets/util/i18n.rb', line 118

def replace_diacritics!
  gsub!(/#{Regexp.union(*Util::I18n::DIACRITICS.keys)}/) { |m|
    s = Util::I18n::DIACRITICS[m]

    # Try to adjust case:
    #   'Äh' => 'AEh' => 'Aeh'
    #
    # But:
    #   'SÖS' => 'SOES' (not 'SOeS'!)
    if s.length > 1
      t = $'[0..0]
      s[1..-1] = s[1..-1].downcase if t == t.downcase
    end

    s
  }
end

#sub_with_md(pattern, replacement = nil) ⇒ Object

call-seq:

str.sub_with_md(pattern) { |match_data| ... } => new_str

Just like #sub, but passes the MatchData object instead of the current match string to the block.



40
41
42
43
44
# File 'lib/nuggets/string/sub_with_md.rb', line 40

def sub_with_md(pattern, replacement = nil)
  replacement ?
    sub_without_md(pattern, replacement) :
    (_dup = dup).sub_with_md!(pattern) { |*a| yield(*a) } || _dup
end

#sub_with_md!(pattern, replacement = nil) ⇒ Object

call-seq:

str.sub_with_md!(pattern) { |match_data| ... } => str or nil

Destructive version of #sub_with_md.



50
51
52
53
54
# File 'lib/nuggets/string/sub_with_md.rb', line 50

def sub_with_md!(pattern, replacement = nil)
  replacement ?
    sub_without_md!(pattern, replacement) :
    sub_without_md!(pattern) { |match| yield $~ }
end

#upper_case?Boolean Also known as: upcase?

call-seq:

str.upper_case? => true or false

Tell whether str is all upper case.

Returns:

  • (Boolean)


61
62
63
# File 'lib/nuggets/string/case.rb', line 61

def upper_case?
  self.case == Case::UPPER
end

#word_wrap(line_width = 80, as_array = false) ⇒ Object

call-seq:

str.word_wrap(line_width) => new_str

Word wrap a string not exceeding line_width. Based on the Ruby Facets implementation, but preserves paragraphs. Thus str == str.word_wrap(str.split("\n").map { |l| l.length }.max).



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/nuggets/string/word_wrap.rb', line 38

def word_wrap(line_width = 80, as_array = false)
  wrapped = []

  split(/(\n+)/).to_enum(:each_slice, 2).each { |paragraph, linebreaks|
    wrapped << paragraph.word_wrap_paragraph!(line_width) << linebreaks
  }

  wrapped = wrapped.join
  
  as_array ? wrapped.split("\n") : wrapped
end

#word_wrap!(line_width = 80) ⇒ Object

call-seq:

str.word_wrap!(line_width) => str

As with #word_wrap, but modifies the string in place.



54
55
56
# File 'lib/nuggets/string/word_wrap.rb', line 54

def word_wrap!(line_width = 80)
  replace word_wrap(line_width)
end

#word_wrap_paragraph(line_width = 80) ⇒ Object

call-seq:

str.word_wrap_paragraph(line_width) => new_str

Similar to #word_wrap, but assumes a single paragraph.



62
63
64
# File 'lib/nuggets/string/word_wrap.rb', line 62

def word_wrap_paragraph(line_width = 80)
  (_dup = dup).word_wrap_paragraph!(line_width) || _dup
end

#word_wrap_paragraph!(line_width = 80) ⇒ Object

call-seq:

str.word_wrap_paragraph!(line_width) => str

Destructive version of #word_wrap_paragraph.



70
71
72
73
74
75
# File 'lib/nuggets/string/word_wrap.rb', line 70

def word_wrap_paragraph!(line_width = 80)
  gsub!(/(.{1,#{line_width}})(?:\s+|$)/, "\\1\n")
  sub!(/\n$/, '')

  self
end