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.

62 lines
1.4 KiB

8 months ago
  1. class Wrapper
  2. def self.wrap(text, prefix = ' > ', length = 80)
  3. pure = ''
  4. ansi_code = {}
  5. while (md = text.match(/\e\[\d+;?\d*m/))
  6. pos = md.begin(0) + pure.length
  7. pure += md.pre_match
  8. text = md.post_match
  9. append_in_hash(ansi_code, pos, md.match(0))
  10. end
  11. pure += text
  12. offset = 0
  13. ansi_extra = {}
  14. rows = pure.length / length
  15. last_code = nil
  16. rows.times do |i|
  17. pos = (i + 1) * length
  18. last_code = last_ansi_by_range(ansi_code, last_code, offset, pos)
  19. if last_code
  20. append_in_hash(ansi_extra, pos, "\e[0m\n#{prefix}#{last_code}")
  21. elsif pos < pure.length
  22. append_in_hash(ansi_extra, pos, "\n#{prefix}")
  23. end
  24. offset = pos + 1
  25. end
  26. ansi_extra.each_pair do |k, v|
  27. append_in_hash(ansi_code, k, v.first)
  28. end
  29. ansi_code = ansi_code.sort
  30. final = pure
  31. offset = 0
  32. ansi_code.each do |k, v|
  33. insert_text = v.join
  34. final = final.insert(k + offset, insert_text)
  35. offset += insert_text.length
  36. end
  37. final
  38. end
  39. def self.last_ansi_by_range(ansi_code, last_code, offset, pos)
  40. pos.downto(offset) do |i|
  41. next unless ansi_code.has_key?(i)
  42. result = ansi_code[i].last
  43. result = nil if result == "\e[0m"
  44. return result
  45. end
  46. last_code
  47. end
  48. def self.append_in_hash(hash, key, value)
  49. if hash.has_key?(key)
  50. hash[key] << value
  51. else
  52. hash[key] = [value]
  53. end
  54. end
  55. end