String

Colorize your outputs

Since we mostly work with the command-line, we need our output to be more elegant. Here are the main colors you may need to do so. You can always add to this set.
1
class String
2
def red; colorize(self, "\e[1m\e[31m"); end
3
def green; colorize(self, "\e[1m\e[32m"); end
4
def dark_green; colorize(self, "\e[32m"); end
5
def yellow; colorize(self, "\e[1m\e[33m"); end
6
def blue; colorize(self, "\e[1m\e[34m"); end
7
def dark_blue; colorize(self, "\e[34m"); end
8
def purple; colorize(self, "\e[35m"); end
9
def dark_purple; colorize(self, "\e[1;35m"); end
10
def cyan; colorize(self, "\e[1;36m"); end
11
def dark_cyan; colorize(self, "\e[36m"); end
12
def pure; colorize(self, "\e[0m\e[28m"); end
13
def bold; colorize(self, "\e[1m"); end
14
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
15
end
Copied!
All you need is to call the color when you puts it
1
puts "RubyFu".red
2
puts "RubyFu".green
3
puts "RubyFu".yellow.bold
Copied!
To understand this code, let's explain it with a diagram
1
\033 [0; 31m
2
^ ^ ^
3
| | |
4
| | |--------------------------------------- [The color number]
5
| |-------------------- [The modifier] (ends with "m")
6
|-- [Escaped character] | 0 - normal
7
(you can use "\e") | 1 - bold
8
| 2 - normal again
9
| 3 - background color
10
| 4 - underline
11
| 5 - blinking
Copied!
Or you can use an external gem called [colorized] for fancier options
1
gem install colorize
Copied!
Then just require it in your script
1
require 'colorize'
Copied!

Overwriting Console Output

It's awesome to have more flexibility in your terminal, and sometimes we need to do more with our scripts.
Overwriting console output makes our applications elegant and less noisy for repeated outputs like counting and loading progress bars.
I've read a how-to about bash Prompt cursor movement and I found it is convenient to have in our scripts. Here's what I've found so far
1
- Position the Cursor:
2
\033[<L>;<C>H
3
Or
4
\033[<L>;<C>f
5
puts the cursor at line L and column C.
6
- Move the cursor up N lines:
7
\033[<N>A
8
- Move the cursor down N lines:
9
\033[<N>B
10
- Move the cursor forward N columns:
11
\033[<N>C
12
- Move the cursor backward N columns:
13
\033[<N>D
14
- Clear the screen, move to (0,0):
15
\033[2J
16
- Erase to end of line:
17
\033[K
18
- Save cursor position:
19
\033[s
20
- Restore cursor position:
21
\033[u
Copied!
So to test these I created the following PoC
1
#!/usr/bin/env ruby
2
# KING SABRI | @KINGSABRI
3
(1..3).map do |num|
4
print "\rNumber: #{num}"
5
sleep 0.5
6
print ("\033[1B") # Move cursor down 1 line
7
8
('a'..'c').map do |char|
9
print "\rCharacter: #{char}"
10
print ("\e[K")
11
sleep 0.5
12
print ("\033[1B") # Move cursor down 1 lines
13
14
('A'..'C').map do |char1|
15
print "\rCapital letters: #{char1}"
16
print ("\e[K")
17
sleep 0.3
18
end
19
print ("\033[1A") # Move curse up 1 line
20
21
end
22
23
print ("\033[1A") # Move curse up 1 line
24
end
25
26
print ("\033[2B") # Move cursor down 2 lines
27
28
puts ""
Copied!
So far so good, but why don't we make these as Ruby methods for more elegant usage? So I came up with the following
1
# KING SABRI | @KINGSABRI
2
class String
3
def mv_up(n=1)
4
cursor(self, "\033[#{n}A")
5
end
6
7
def mv_down(n=1)
8
cursor(self, "\033[#{n}B")
9
end
10
11
def mv_fw(n=1)
12
cursor(self, "\033[#{n}C")
13
end
14
15
def mv_bw(n=1)
16
cursor(self, "\033[#{n}D")
17
end
18
19
def cls_upline
20
cursor(self, "\e[K")
21
end
22
23
def cls
24
# cursor(self, "\033[2J")
25
cursor(self, "\e[H\e[2J")
26
end
27
28
def save_position
29
cursor(self, "\033[s")
30
end
31
32
def restore_position
33
cursor(self, "\033[u")
34
end
35
36
def cursor(text, position)
37
"\r#{position}#{text}"
38
end
39
end
Copied!
Then as a PoC, I've used the same previous PoC code (after updating String class on-the-fly in the same script)
1
#!/usr/bin/env ruby
2
# KING SABRI | @KINGSABRI
3
# Level 1
4
(1..3).map do |num|
5
print "\rNumber: #{num}"
6
sleep 0.7
7
# Level 2
8
('a'..'c').map do |char|
9
print "Characters: #{char}".mv_down
10
sleep 0.5
11
# Level 3
12
('A'..'C').map do |char1|
13
print "Capital: #{char1}".mv_down
14
sleep 0.2
15
print "".mv_up
16
end
17
print "".mv_up
18
end
19
sleep 0.7
20
end
21
print "".mv_down 3
Copied!
It's much more elegant, isn't it? Say yes plz
Some application...

Create Progress Percent

1
(1..10).each do |percent|
2
print "#{percent*10}% complete\r"
3
sleep(0.5)
4
print ("\e[K") # Delete current line
5
end
6
puts "Done!"
Copied!
Another example
1
(1..5).to_a.reverse.each do |c|
2
print "\rI'll exit after #{c} second(s)"
3
print "\e[K"
4
sleep 1
5
end
Copied!
Using our elegant way (after updating String class on-the-fly)
1
(1..5).to_a.reverse.each do |c|
2
print "I'll exit after #{c} second".cls_upline
3
sleep 1
4
end
5
puts
Copied!