Module: MMMD::TextManager
- Included in:
- Renderers::Plainterm
- Defined in:
- lib/mmmd/renderers/plainterm.rb
Overview
Module for managing terminal output
Instance Method Summary collapse
-
#_indent(text) ⇒ Object
Indent all lines (inner).
-
#bg(text, options) ⇒ String
ANSI SGR escape code for bg color.
-
#bold(text, _options) ⇒ String
ANSI SGR escape code for bold text.
-
#box(text, options) ⇒ String
Draw a screen-width box around text.
-
#bullet(text, _options) ⇒ Object
Bulletpoints.
-
#center(text, options) ⇒ Object
Draw text centered.
-
#center_cc(text, size) ⇒ String
Center-justify a line while ignoring terminal control codes.
-
#extra_newlines(text, options) ⇒ Object
Add extra newlines around the text.
-
#fg(text, options) ⇒ String
ANSI SGR escape code for fg color.
-
#indent(text, _options) ⇒ Object
Indent all lines.
-
#italics(text, _options) ⇒ String
ANSI SGR escape code for italics text.
-
#leftline(text, _options) ⇒ Object
Left overline all lines.
-
#ljust_cc(text, size) ⇒ String
Left-justify a line while ignoring terminal control codes.
-
#numbered(text, options) ⇒ Object
Numbers.
-
#rjust(text, options) ⇒ Object
Draw text right-justified.
-
#rjust_cc(text, size) ⇒ String
Right-justify a line while ignoring terminal control codes.
-
#smort_length(text) ⇒ Integer
(TODO: smorter stronger better faster) SmЯt™ word length.
-
#strikethrough(text, _options) ⇒ String
ANSI SGR escape code for strikethrough text.
-
#underline(text, _options) ⇒ String
ANSI SGR escape code for underline text.
-
#underline_block(text, options) ⇒ Object
Underline the last line of the text piece.
-
#underline_full_block(text, options) ⇒ Object
Underline last line edge to edge.
-
#wordwrap(text, width) ⇒ String
Word wrapping algorithm.
Instance Method Details
#_indent(text) ⇒ Object
Indent all lines (inner)
222 223 224 225 226 |
# File 'lib/mmmd/renderers/plainterm.rb', line 222 def _indent(text) text.lines.map do |line| " #{line}" end.join("") end |
#bg(text, options) ⇒ String
ANSI SGR escape code for bg color
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/mmmd/renderers/plainterm.rb', line 13 def bg(text, ) color = ['bg'] if color.is_a? Integer "\e[48;5;#{color}m#{text}\e[49m" elsif color.is_a? String and color.match?(/\A#[A-Fa-f0-9]{6}\Z/) vector = color.scan(/[A-Fa-f0-9]{2}/).map { |x| x.to_i(16) } "\e[48;2;#{vector[0]};#{vector[1]};#{vector[2]}\e[49m" else Kernel.warn "WARNING: Invalid color - #{color}" text end end |
#bold(text, _options) ⇒ String
ANSI SGR escape code for bold text
47 48 49 |
# File 'lib/mmmd/renderers/plainterm.rb', line 47 def bold(text, ) "\e[1m#{text}\e[22m" end |
#box(text, options) ⇒ String
Draw a screen-width box around text
156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/mmmd/renderers/plainterm.rb', line 156 def box(text, ) size = [:hsize] - 2 text = wordwrap(text, (size * 0.8).floor).lines.filter_map do |line| "│#{ljust_cc(line, size)}│" unless line.empty? end.join("\n") <<~TEXT ╭#{'─' * size}╮ #{text} ╰#{'─' * size}╯ TEXT end |
#bullet(text, _options) ⇒ Object
Bulletpoints
236 237 238 |
# File 'lib/mmmd/renderers/plainterm.rb', line 236 def bullet(text, ) "-#{_indent(text)[1..]}" end |
#center(text, options) ⇒ Object
Draw text centered
177 178 179 180 181 182 |
# File 'lib/mmmd/renderers/plainterm.rb', line 177 def center(text, ) size = [:hsize] wordwrap(text, (size * 0.8).floor).lines.filter_map do |line| center_cc(line, size) unless line.empty? end.join("\n") end |
#center_cc(text, size) ⇒ String
Center-justify a line while ignoring terminal control codes
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/mmmd/renderers/plainterm.rb', line 138 def center_cc(text, size) text.lines.map do |line| textlength = smort_length(line) if textlength < size freelength = size - textlength rightlength = freelength / 2 leftlength = freelength - rightlength " " * leftlength + line + " " * rightlength else line end end.join("\n") end |
#extra_newlines(text, options) ⇒ Object
Add extra newlines around the text
200 201 202 203 204 205 206 |
# File 'lib/mmmd/renderers/plainterm.rb', line 200 def extra_newlines(text, ) size = [:hsize] textlines = text.lines textlines.prepend("#{' ' * size}\n") textlines.append("\n#{' ' * size}\n") textlines.join("") end |
#fg(text, options) ⇒ String
ANSI SGR escape code for fg color
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/mmmd/renderers/plainterm.rb', line 30 def fg(text, ) color = ['fg'] if color.is_a? Integer "\e[38;5;#{color}m#{text}\e[39m" elsif color.is_a? String and color.match?(/\A#[A-Fa-f0-9]{6}\Z/) vector = color.scan(/[A-Fa-f0-9]{2}/).map { |x| x.to_i(16) } "\e[38;2;#{vector[0]};#{vector[1]};#{vector[2]}\e[39m" else Kernel.warn "WARNING: Invalid color - #{color}" text end end |
#indent(text, _options) ⇒ Object
Indent all lines
217 218 219 |
# File 'lib/mmmd/renderers/plainterm.rb', line 217 def indent(text, ) _indent(text) end |
#italics(text, _options) ⇒ String
ANSI SGR escape code for italics text
55 56 57 |
# File 'lib/mmmd/renderers/plainterm.rb', line 55 def italics(text, ) "\e[3m#{text}\e[23m" end |
#leftline(text, _options) ⇒ Object
Left overline all lines
229 230 231 232 233 |
# File 'lib/mmmd/renderers/plainterm.rb', line 229 def leftline(text, ) text.lines.map do |line| " │ #{line}" end.join("") end |
#ljust_cc(text, size) ⇒ String
Left-justify a line while ignoring terminal control codes
116 117 118 119 120 121 |
# File 'lib/mmmd/renderers/plainterm.rb', line 116 def ljust_cc(text, size) text.lines.map do |line| textlength = smort_length(line) textlength < size ? line + " " * (size - textlength) : line end.join("\n") end |
#numbered(text, options) ⇒ Object
Numbers
241 242 243 244 245 246 |
# File 'lib/mmmd/renderers/plainterm.rb', line 241 def numbered(text, ) number = [:number] length = number.to_s.length + 1 (length / 4 + 1).times { text = _indent(text) } "#{number}.#{text[length..]}" end |
#rjust(text, options) ⇒ Object
Draw text right-justified
169 170 171 172 173 174 |
# File 'lib/mmmd/renderers/plainterm.rb', line 169 def rjust(text, ) size = [:hsize] wordwrap(text, (size * 0.8).floor).lines.filter_map do |line| rjust_cc(line, size) unless line.empty? end.join("\n") end |
#rjust_cc(text, size) ⇒ String
Right-justify a line while ignoring terminal control codes
127 128 129 130 131 132 |
# File 'lib/mmmd/renderers/plainterm.rb', line 127 def rjust_cc(text, size) text.lines.map do |line| textlength = smort_length(line) textlength < size ? " " * (size - textlength) + line : line end.join("\n") end |
#smort_length(text) ⇒ Integer
(TODO: smorter stronger better faster) SmЯt™ word length
108 109 110 |
# File 'lib/mmmd/renderers/plainterm.rb', line 108 def smort_length(text) text.gsub(/\e\[[^m]+m/, '').length end |
#strikethrough(text, _options) ⇒ String
ANSI SGR escape code for strikethrough text
71 72 73 |
# File 'lib/mmmd/renderers/plainterm.rb', line 71 def strikethrough(text, ) "\e[9m#{text}\e[29m" end |
#underline(text, _options) ⇒ String
ANSI SGR escape code for underline text
63 64 65 |
# File 'lib/mmmd/renderers/plainterm.rb', line 63 def underline(text, ) "\e[4m#{text}\e[24m" end |
#underline_block(text, options) ⇒ Object
Underline the last line of the text piece
185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/mmmd/renderers/plainterm.rb', line 185 def underline_block(text, ) textlines = text.lines last = "".match(/()()()/) textlines.each do |x| current = x.match(/\A(\s*)(.+?)(\s*)\Z/) last = current if smort_length(current[2]) > smort_length(last[2]) end ltxt = last[1] ctxt = textlines.last.slice(last.offset(2)[0]..last.offset(2)[1] - 1) rtxt = last[3] textlines[-1] = [ltxt, underline(ctxt, ), rtxt].join('') textlines.join("") end |
#underline_full_block(text, options) ⇒ Object
Underline last line edge to edge
209 210 211 212 213 214 |
# File 'lib/mmmd/renderers/plainterm.rb', line 209 def underline_full_block(text, ) textlines = text.lines last_line = textlines.last.match(/^.*$/)[0] textlines[-1] = "#{underline(last_line, )}\n" textlines.join("") end |
#wordwrap(text, width) ⇒ String
Word wrapping algorithm
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/mmmd/renderers/plainterm.rb', line 79 def wordwrap(text, width) words = text.split(/( +)/) output = [] line = "" length = 0 until words.empty? word = words.shift wordlength = smort_length(word) if wordlength > width words.prepend(word[width..]) word = word[..width - 1] end if length + wordlength + 1 > width output.append(line.lstrip) line = word length = wordlength next end length += wordlength line += word end output.append(line.lstrip) output.join("\n") end |