cowsay makes it easy to print messages, warnings, or character strings with various animals and other creatures.

Installation

Stable version from CRAN

install.packages("cowsay")

or dev version from GitHub

install.packages("devtools")
devtools::install_github("sckott/cowsay")
library(cowsay)

The animals

The animals, and other ascii creatures, are all in a single named character vector that is exported from the package. Thus, you can access each animal yourself, and do whatever you want with it.

As of this writing, there are 44 animals.

The names of the animals:

sort(names(animals))
#>  [1] "ant"          "anxiouscat"   "bat"          "bat2"         "behindcat"   
#>  [6] "bigcat"       "buffalo"      "cat"          "chicken"      "chuck"       
#> [11] "clippy"       "cow"          "daemon"       "duck"         "duckling"    
#> [16] "egret"        "endlesshorse" "facecat"      "fish"         "frog"        
#> [21] "ghost"        "grumpycat"    "hypnotoad"    "longcat"      "longtailcat" 
#> [26] "monkey"       "mushroom"     "owl"          "pig"          "poop"        
#> [31] "pumpkin"      "rabbit"       "shark"        "shortcat"     "signbunny"   
#> [36] "smallcat"     "snowman"      "spider"       "squirrel"     "squirrel2"   
#> [41] "stretchycat"  "trilobite"    "turkey"       "yoda"

For example, access the cow

cow <- animals[['cow']]
cat(cow)
#> 
#>  ----- 
#> %s 
#>  ------ 
#>     \   ^__^ 
#>      \  (oo)\ ________ 
#>         (__)\         )\ /\ 
#>              ||------w|
#>              ||      ||

Say something

We expose the function say() in this package, which you can use to envoke any animal in the package, and make it say whatever you want. Some examples:

say("why did the chicken cross the road", "chicken")
#> 
#>  ----- 
#> why did the chicken cross the road 
#>  ------ 
#>     \   
#>      \
#>          _
#>        _/ }
#>       `>' \
#>       `|   \
#>        |   /'-.     .-.
#>         \'     ';`--' .'
#>          \'.    `'-./
#>           '.`-..-;`
#>             `;-..'
#>             _| _|
#>             /` /` [nosig]
#> 
say("boo!", "ghost")
#> 
#>  ----- 
#> boo! 
#>  ------ 
#>     \   
#>      \
#>      .-.
#>     (o o)
#>     | O \
#>      \   \
#>       `~~~' [nosig]
#> 
say("nope, don't do that", type = "warning")
#> Warning in say("nope, don't do that", type = "warning"): 
#>  -------------- 
#> nope, don't do that 
#>  --------------
#>     \
#>       \
#>         \
#>             |\___/|
#>           ==) ^Y^ (==
#>             \  ^  /
#>              )=*=(
#>             /     \
#>             |     |
#>            /| | | |\
#>            \| | |_|/\
#>       jgs  //_// ___/
#>                \_)
#> 

There’s the special time, that will print out the time

say('time')
#> 
#>  -------------- 
#> 2020-02-06 12:00:09 
#>  --------------
#>     \
#>       \
#>         \
#>             |\___/|
#>           ==) ^Y^ (==
#>             \  ^  /
#>              )=*=(
#>             /     \
#>             |     |
#>            /| | | |\
#>            \| | |_|/\
#>       jgs  //_// ___/
#>                \_)
#> 

It’s how you say it

You can use say() and give back a string, message, or warning

Message

say("hello world", by = "cow")
#> 
#>  ----- 
#> hello world 
#>  ------ 
#>     \   ^__^ 
#>      \  (oo)\ ________ 
#>         (__)\         )\ /\ 
#>              ||------w|
#>              ||      ||

Warning

say("hello world", by = "cow", type = "warning")
#> Warning in say("hello world", by = "cow", type = "warning"): 
#>  ----- 
#> hello world 
#>  ------ 
#>     \   ^__^ 
#>      \  (oo)\ ________ 
#>         (__)\         )\ /\ 
#>              ||------w|
#>              ||      ||

String

say("hello world", by = "cow", type = "string")
#> [1] "\n ----- \nhello world \n ------ \n    \\   ^__^ \n     \\  (oo)\\ ________ \n        (__)\\         )\\ /\\ \n             ||------w|\n             ||      ||"

Add color

library(jsonlite)
library(multicolor)

We rely on the crayon package for color and the multicolor package for multiple colors. The arguments you supply to what_color and by_color can be strings – either the color name or a hex value – or a function of class crayon.

say(what = "fortune",
    by = "rabbit",
    what_color = "#FF4500",
    by_color = "red")
#> Colors cannot be applied in this environment :( Try using a terminal or RStudio.
#> 
#>  ----- 
#> Some OSX users know that OSX is really Unix [...], others think that OSX is cooler Windows, and they have ontological problems with non-Apple phenomena and constructs.
#>  Roger Bivand
#>  R-SIG-Geo
#>  May 2012 
#>  ------ 
#>     \   
#>      \
#>       ( )_( )
#>       (='.'=)
#>       (^)_(^) [nosig]
#> 

colors() are all supported as are any rgb values that evaluate to a string. Supplying multiple colors for what_color or by_color is allowed, as long as they’re in a character vector. “rainbow” is also allowed.

# make a vector of animals safe to use on windows in case vignette built on windows
not_on_windows <- c('shortcat','longcat','fish','signbunny','stretchycat',
  'anxiouscat','longtailcat','grumpycat','mushroom')
names_safe <- names(animals)[!names(animals) %in% not_on_windows]
say(what = "fortune", 
    by = sample(names_safe, 1),
    what_color = rgb(.1, .2, .3),
    by_color = sample(colors(), 5),
    type = "message")
#> Colors cannot be applied in this environment :( Try using a terminal or RStudio.
#> 
#>  ----- 
#> For almost 40 years SAS has been the primary tool for statisticians worldwide and its easy-to-learn syntax, unsurpassed graphical system, powerful macro language and recent graphical user interfaces have made SAS the number one statistical software choice for both beginners and advanced users.
#>  Rolf Poalis, Biostatistics Denmark
#>  announcement of the SAS to R parser sas2R
#>  R-help
#>  April 1, 2004 
#>  ------ 
#>     \   
#>      \  
#>       \
#>          __
#>         /o \
#>       <=   |         ==
#>         |__|        /===
#>         |   \______/  =
#>         \     ====   /
#>          \__________/     [ab]
say(what = "fortune", 
    by = sample(names_safe, 1),
    what_color = rgb(.1, .2, .3),
    by_color = sample(colors(), 5),
    type = "message")
#> Colors cannot be applied in this environment :( Try using a terminal or RStudio.
#> 
#>  ----- 
#> I think [R] addresses a niche market for high-end data analysts that want free, readily available code. [...] We have customers who build engines for aircraft. I am happy they are not using freeware when I get on a jet.
#>  Anne H. Milley
#>  director of technology product marketing at SAS, quoted in Ashlee Vance's article "Data Analysts Captivated by R's Power"
#>  The New York Times
#>  January 2009 
#>  ------ 
#>     \   
#>      \  
#>       \
#>        ,
#>     _,,)\.~,,._
#>      (()`  ``)\))),,_
#>       |     \ ''((\)))),,_          ____
#>       |6`   |   ''((\())) "-.____.-"    `-.-,
#>       |    .'\    ''))))'                  \)))
#>       |   |   `.     ''                     ((((
#>       \, _)     \/                          |))))
#>        `'        |                          (((((
#>                  \                  |       ))))))
#>                   `|    |           ,\     /((((((
#>                    |   / `-.______.<  \   |  )))))
#>                    |   |  /         `. \  \  ((((
#>                    |  / \ |           `.\  | (((
#>                    \  | | |             )| |  ))
#>                     | | | |             || |  '   [endless.horse]
#>                     | | | |             || |

"rainbow" is the same as c("red", "orange", "yellow", "green", "blue", "purple"). Saves you a bit of typing.

say(what = "foobar",
    by = "shark",
    what_color = "rainbow",
    by_color = c("rainbow", "rainbow", "rainbow"))
#> Colors cannot be applied in this environment :( Try using a terminal or RStudio.
#> 
#>  -------------- 
#> foobar 
#>  --------------
#>     \
#>       \
#>         \
#>               /""-._
#>               .       '-,
#>                :          '',
#>                 ;      *     '.
#>                  ' *         () '.
#>                    \               \
#>                     \      _.---.._ '.
#>                     :  .' _.--''-''  \ ,'
#>         .._           '/.'             . ;
#>         ; `-.          ,                \'
#>          ;   `,         ;              ._\
#>           ;    \     _,-'                ''--._
#>           :    \_,-'                          '-._
#>           \ ,-'                       .          '-._
#>           .'         __.-'';            \...,__       '.
#>         .'      _,-'        \              \   ''--.,__  '\
#>         /    _,--' ;         \              ;           \^.}
#>         ;_,-' )     \  )\      )            ;
#>              /       \/  \_.,-'             ;
#>             /                              ;
#>          ,-'  _,-'''-.    ,-.,            ;      PFA
#>       ,-' _.-'        \  /    |/'-._...--'
#>      :--``             )/
#>   '
#> 

The main advantage of using crayon functions instead of color strings is the ability to combine styles together.

library(crayon)

say(what = "fortune",
    by = "egret",
    what_color = bgBlue$white$italic,
    by_color = bold$green)
#> Colors cannot be applied in this environment :( Try using a terminal or RStudio.
#> 
#>  ----- 
#> I'm always thrilled when people discover what lexical scoping really means.
#>  Robert Gentleman
#>  Statistical Computing 2003, Reisensburg
#>  June 2003 
#>  ------ 
#>     \   
#>      \  
#>       \
#>        \   _,
#>       -==<' `
#>           ) /
#>          / (_.
#>         |  ,-,`\
#>          \\   \ \
#>           `\,  \ \
#>            ||\  \`|,
#>  jgs      _|| `=`-'
#>          ~~`~`