Method: Rex::Text.cowsay

Defined in:
lib/rex/text/silly.rb

.cowsay(text, width = 39) ⇒ Object

Converts a string to one similar to what would be used by cowsay(1), a UNIX utility for displaying text as if it was coming from an ASCII-cow’s mouth:

 __________________
< the cow says moo >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Parameters:

  • text (String)

    The string to cowsay

  • width (Integer) (defaults to: 39)

    Width of the cow's cloud. Default's to cowsay(1)'s default, 39.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rex/text/silly.rb', line 24

def self.cowsay(text, width=39)
  # cowsay(1) chunks a message up into 39-byte chunks and wraps it in '| ' and ' |'
  # Rex::Text.wordwrap(text, 0, 39, ' |', '| ') almost does this, but won't
  # split a word that has > 39 characters in it which results in oddly formed
  # text in the cowsay banner, so just do it by hand.  This big mess wraps
  # the provided text in an ASCII-cloud and then makes it look like the cloud
  # is a thought/word coming from the ASCII-cow.  Each line in the
  # ASCII-cloud is no more than the specified number-characters long, and the
  # cloud corners are made to look rounded
  text_lines = text.scan(Regexp.new(".{1,#{width-4}}"))
  max_length = text_lines.map(&:size).sort.last
  cloud_parts = []
  cloud_parts << " #{'_' * (max_length + 2)}"
  if text_lines.size == 1
    cloud_parts << "< #{text} >"
  else
    cloud_parts << "/ #{text_lines.first.ljust(max_length, ' ')} \\"
    if text_lines.size > 2
      text_lines[1, text_lines.length - 2].each do |line|
        cloud_parts << "| #{line.ljust(max_length, ' ')} |"
      end
    end
    cloud_parts << "\\ #{text_lines.last.ljust(max_length, ' ')} /"
  end
  cloud_parts << " #{'-' * (max_length + 2)}"
  cloud_parts << <<EOS
   \\   ,__,
    \\  (oo)____
       (__)    )\\
          ||--|| *
EOS
  cloud_parts.join("\n")
end