Module: Hirb::Colors::StringUtil

Defined in:
lib/hirb/colors/string_util.rb

Constant Summary collapse

COLORIZED_REGEX =
/\e\[(\d|;)+m/

Instance Method Summary collapse

Instance Method Details

#ljust(string, desired_length) ⇒ Object



29
30
31
32
# File 'lib/hirb/colors/string_util.rb', line 29

def ljust(string, desired_length)
  leftover = desired_length - size(string)
  leftover > 0 ? string + " " * leftover : string
end

#rjust(string, desired_length) ⇒ Object



12
13
14
15
# File 'lib/hirb/colors/string_util.rb', line 12

def rjust(string, desired_length)
  leftover = desired_length - size(string)
  leftover > 0 ? " " * leftover + string : string
end

#size(string) ⇒ Object



8
9
10
# File 'lib/hirb/colors/string_util.rb', line 8

def size(string)
  string.gsub(COLORIZED_REGEX, '').scan(/./).length
end

#slice(*args) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/hirb/colors/string_util.rb', line 17

def slice(string, start, finish)
  if string =~ COLORIZED_REGEX
    slice_colorized_string(string, start, finish)
  else
    string.scan(/./).slice(start, finish).join('')
  end
end

#slice_colorized_string(string, slice_start, slice_end) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/hirb/colors/string_util.rb', line 53

def slice_colorized_string(string, slice_start, slice_end)
  # store the codes and their position in the original string
  markers = []
  string.scan(COLORIZED_REGEX) do |code|
    marker = { :code     => code,
               :position => Regexp.last_match.offset(0).first
    }
    markers << marker
  end

  markers_before_slice = []
  markers_in_slice     = []
  markers_after_slice  = []
  # interate over elements in code_markers
  # will be mutating array so cannot use .each
  markers.size.times do
    marker = markers.shift
    # shift remaining markers position by that of the popped code
    markers.map! { |c| c[:position] -= marker[:code].size; c }
    if marker[:position] <= slice_start
      markers_before_slice << marker
    elsif marker[:position] > slice_start && marker[:position] < slice_end
      markers_in_slice << marker
    else
      markers_after_slice << marker
    end
  end

  # slice the string without the codes
  slice = string.gsub(COLORIZED_REGEX, '').slice(slice_start, slice_end)

  # insert codes back into the slice
  markers_in_slice.each do |marker|
    slice.insert(marker[:position], marker[:code])
    markers_in_slice.map! { |c| c[:position] += marker[:code].size; c }
  end

  markers_before_slice.each { |marker| slice.insert(0, marker[:code])}
  markers_after_slice.each { |marker| slice << marker[:code] }

  slice
end