You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.1 KiB
89 lines
2.1 KiB
class Wrapper
|
|
def self.wrap(text, prefix = ' > ', length = 80)
|
|
text = carriage_return_filler(text.chomp(''), length)
|
|
|
|
pure = ''
|
|
ansi_code = {}
|
|
while (md = text.match(/\e\[\d+;?\d*m/))
|
|
pos = md.begin(0) + pure.length
|
|
pure += md.pre_match
|
|
text = md.post_match
|
|
append_in_hash(ansi_code, pos, md.match(0))
|
|
end
|
|
pure += text
|
|
|
|
offset = 0
|
|
ansi_extra = {}
|
|
rows = pure.length / length
|
|
last_code = nil
|
|
rows.times do |i|
|
|
pos = (i + 1) * length
|
|
last_code = last_ansi_by_range(ansi_code, last_code, offset, pos)
|
|
if last_code
|
|
append_in_hash(ansi_extra, pos, "\e[0m\n#{prefix}#{last_code}")
|
|
elsif pos < pure.length
|
|
append_in_hash(ansi_extra, pos, "\n#{prefix}")
|
|
end
|
|
offset = pos + 1
|
|
end
|
|
ansi_extra.each_pair do |k, v|
|
|
append_in_hash(ansi_code, k, v.first)
|
|
end
|
|
|
|
ansi_code = ansi_code.sort
|
|
|
|
final = pure
|
|
offset = 0
|
|
ansi_code.each do |k, v|
|
|
insert_text = v.join
|
|
final = final.insert(k + offset, insert_text)
|
|
offset += insert_text.length
|
|
end
|
|
|
|
final
|
|
end
|
|
|
|
private
|
|
|
|
def self.carriage_return_filler(text, length)
|
|
lines = text.split("\n")
|
|
return text if lines.count < 2
|
|
|
|
last_ansi = nil
|
|
final = lines.map do |line|
|
|
fill_count = length - line.length
|
|
current = line
|
|
result = last_ansi ? "#{last_ansi}#{line}" : line
|
|
last_ansi = nil if last_ansi == "\e[0m"
|
|
while (md = current.match(/\e\[\d+;?\d*m/))
|
|
last_ansi = md.to_s
|
|
fill_count += last_ansi.length
|
|
current = md.post_match
|
|
end
|
|
result = "#{result}\e[0m" if last_ansi
|
|
next result if fill_count < 1
|
|
|
|
"#{result}#{' ' * fill_count}"
|
|
end.join
|
|
last_ansi ? "#{final}\e[0m" : final
|
|
end
|
|
|
|
def self.last_ansi_by_range(ansi_code, last_code, offset, pos)
|
|
pos.downto(offset) do |i|
|
|
next unless ansi_code.has_key?(i)
|
|
|
|
result = ansi_code[i].last
|
|
result = nil if result == "\e[0m"
|
|
return result
|
|
end
|
|
last_code
|
|
end
|
|
|
|
def self.append_in_hash(hash, key, value)
|
|
if hash.has_key?(key)
|
|
hash[key] << value
|
|
else
|
|
hash[key] = [value]
|
|
end
|
|
end
|
|
end
|