Class: ANSI::String

Inherits:
Object
  • Object
show all
Defined in:
lib/ansi/string.rb

Overview

String

ANSI Strings store a regular string (@text) and a Hash mapping character index to ANSI codes (@marks). For example is we have the string:

"Big Apple"

And applied the color red to it, the marks hash would be:

{ 0=>[:red] , 9=>[:clear] }

TODO: In the future we may be able to subclass String, instead of delegating via @text, but not until it is more compatible.

Constant Summary collapse

CLR =
ANSI::Code.clear

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text = nil, marks = nil) {|_self| ... } ⇒ String

New Ansi::String

Yields:

  • (_self)

Yield Parameters:

  • _self (ANSI::String)

    the object that the method was called on



34
35
36
37
38
# File 'lib/ansi/string.rb', line 34

def initialize(text=nil, marks=nil)
  @text  = (text  || '').to_s
  @marks = marks  || []
  yield(self) if block_given?
end

Instance Attribute Details

#marksObject (readonly)

Returns the value of attribute marks.



31
32
33
# File 'lib/ansi/string.rb', line 31

def marks
  @marks
end

#textObject (readonly)

Returns the value of attribute text.



30
31
32
# File 'lib/ansi/string.rb', line 30

def text
  @text
end

Instance Method Details

#+(other) ⇒ Object

Add one String to another, or to a regular String.



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ansi/string.rb', line 74

def +(other)
  case other
  when String
    ntext  = text + other.text
    nmarks = marks.dup
    omarks = shift_marks(0, text.size, other.marks)
    omarks.each{ |(i, c)| nmarks << [i,c] }
  else
    ntext  = text + other.to_s
    nmarks = marks.dup
  end
  self.class.new(ntext, nmarks)
end

#ansi(code) ⇒ Object Also known as: color



194
195
196
197
198
199
# File 'lib/ansi/string.rb', line 194

def ansi(code)
  m = marks.dup
  m.unshift([0, code])
  m.push([size, :clear])
  self.class.new(text, m)
end

#ansi!(code) ⇒ Object Also known as: color!



203
204
205
206
# File 'lib/ansi/string.rb', line 203

def ansi!(code)
  marks.unshift([0, ansicolor])
  marks.push([size, :clear])
end

#blackObject



212
# File 'lib/ansi/string.rb', line 212

def black      ; color(:black)    ; end

#black!Object



223
# File 'lib/ansi/string.rb', line 223

def black!     ; color!(:black)   ; end

#blueObject



211
# File 'lib/ansi/string.rb', line 211

def blue       ; color(:blue)     ; end

#blue!Object



222
# File 'lib/ansi/string.rb', line 222

def blue!      ; color!(:blue)    ; end

#boldObject



217
# File 'lib/ansi/string.rb', line 217

def bold       ; ansi(:bold)       ; end

#bold!Object



228
# File 'lib/ansi/string.rb', line 228

def bold!      ; ansi!(:bold)      ; end

#cyanObject



215
# File 'lib/ansi/string.rb', line 215

def cyan       ; color(:cyan)     ; end

#cyan!Object



226
# File 'lib/ansi/string.rb', line 226

def cyan!      ; color!(:cyan)    ; end

#downcaseObject

Downcase the string.



70
# File 'lib/ansi/string.rb', line 70

def downcase  ; self.class.new(text.upcase, marks) ; end

#downcase!Object



71
# File 'lib/ansi/string.rb', line 71

def downcase! ; text.upcase! ; end

#greenObject



210
# File 'lib/ansi/string.rb', line 210

def green      ; color(:green)    ; end

#green!Object



221
# File 'lib/ansi/string.rb', line 221

def green!     ; color!(:green)   ; end

#gsub(pattern, replacement = nil, &block) ⇒ Object

See #gsub!.



189
190
191
# File 'lib/ansi/string.rb', line 189

def gsub(pattern, replacement=nil, &block)
  dup.gsub!(pattern, replacement, &block)
end

#gsub!(pattern, replacement = nil, &block) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/ansi/string.rb', line 163

def gsub!(pattern, replacement=nil, &block)
  mark_changes   = []
  mark_additions = []
  text = @text.gsub(pattern) do |s|
    index = $~.begin(0)
    replacement = block.call(self.class.new(s)) if block_given?
    if self.class===replacement
      adj_marks = replacement.marks.map{ |(i,c)| [i+index,c] }
      mark_additions.concat(adj_marks)
      replacement = replacement.text
    end
    delta = (replacement.size - s.size)
    mark_changes << [index, delta]
    replacement
  end
  marks = @marks
  mark_changes.each do |(index, delta)|
    marks = shift_marks(index, delta, marks)
  end
  marks.concat(mark_additions)
  @text  = text
  @marks = marks
  self
end

#magentaObject



213
# File 'lib/ansi/string.rb', line 213

def magenta    ; color(:magenta)  ; end

#magenta!Object



224
# File 'lib/ansi/string.rb', line 224

def magenta!   ; color!(:magenta) ; end

#redObject



209
# File 'lib/ansi/string.rb', line 209

def red        ; color(:red)      ; end

#red!Object



220
# File 'lib/ansi/string.rb', line 220

def red!       ; color!(:red)     ; end

#sizeObject

The size of the base text.



63
# File 'lib/ansi/string.rb', line 63

def size ; text.size ; end

#slice(*args) ⇒ Object Also known as: []

slice



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/ansi/string.rb', line 99

def slice(*args)
  if args.size == 2
    index, len = *args
    endex  = index+len
    new_text  = text[index, len]
    new_marks = []
    marks.each do |(i, v)|
      new_marks << [i, v] if i >= index && i < endex
    end
    self.class.new(new_text, new_marks)
  elsif args.size == 1
    rng = args.first
    case rng
    when Range
      index, endex = rng.begin, rng.end
      new_text  = text[rng]
      new_marks = []
      marks.each do |(i, v)|
        new_marks << [i, v] if i >= index && i < endex
      end
      self.class.new(new_text, new_marks)
    else
      nm = marks.select do |(i,c)|
        marks[0] == rng or ( marks[0] == rng + 1 && [:clear, :reset].include?(marks[1]) )
      end
      self.class.new(text[rng,1], nm)
    end
  else
    raise ArgumentError
  end
end

#sub(pattern, replacement = nil, &block) ⇒ Object

See #sub!.



158
159
160
# File 'lib/ansi/string.rb', line 158

def sub(pattern,replacement=nil, &block)
  dup.sub!(pattern, replacement, &block)
end

#sub!(pattern, replacement = nil, &block) ⇒ Object

This is more limited than the normal String method. It does not yet support a block, and replacement won’t substitue for 1, 2, etc.

TODO: block support.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/ansi/string.rb', line 139

def sub!(pattern, replacement=nil, &block)
  mark_changes = []
  text = @text.sub(pattern) do |s|
    index  = $~.begin(0)
    replacement = block.call(s) if block_given?
    delta  = (replacement.size - s.size)
    mark_changes << [index, delta]
    replacement
  end
  marks = @marks
  mark_changes.each do |index, delta|
    marks = shift_marks(index, delta, marks)
  end
  @text  = text
  @marks = marks
  self
end

#to_sObject Also known as: to_str

Convert Ansi::String object to normal String. This converts the intental markup codes to ANSI codes.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ansi/string.rb', line 42

def to_s
  s = text.dup
  m = marks.sort do |(a,b)|
    v = b[0] <=> a[0]
    if v == 0
      (b[1] == :clear or b[1] == :reset) ? -1 : 1
    else
      v
    end
  end
  m.each do |(index, code)|
    s.insert(index, ANSICode.__send__(code))
  end
  #s << CLR unless s =~ /#{Regexp.escape(CLR)}$/  # always end with a clear
  s
end

#underlineObject



218
# File 'lib/ansi/string.rb', line 218

def underline  ; ansi(:underline)  ; end

#underline!Object



229
# File 'lib/ansi/string.rb', line 229

def underline! ; ansi!(:underline) ; end

#upcaseObject

Upcase the string.



66
# File 'lib/ansi/string.rb', line 66

def upcase  ; self.class.new(text.upcase, marks) ; end

#upcase!Object



67
# File 'lib/ansi/string.rb', line 67

def upcase! ; text.upcase! ; end

#yellowObject



214
# File 'lib/ansi/string.rb', line 214

def yellow     ; color(:yellow)   ; end

#yellow!Object



225
# File 'lib/ansi/string.rb', line 225

def yellow!    ; color!(:yellow)  ; end