cowsay is a command line program written in Perl. The original version had a final release in 2016 (that’s the version of many installed cowsay programs) and there’s a number of forks of that release in Perl. There are also many many versions of cowsay in other programming languages, like the one I maintain written in R, unimaginatively called cowsay.
I wrote about cowsay here back in 2014. I didn’t think this would ever be 300+ stars popular, but here we are. Given that people seem to actually use it - or at least star it - seems worth putting some more time into it.
Return to the source
I just released v1 of cowsay. At a high level, the major thing in v1 is bringing it closer to the original cowsay. That doesn’t mean in how it’s used - you still use it within R, and pass arguments to a function rather than flags to a command line program. Instead, the output is as close as I could get to the original cowsay. This goal was spurred on by an issue - cough, sneeze - from 6 years ago.
The output of v1 is much closer to the original, for example:
in R cowsay before v1:
-----
hello world
------
\ ^__^
\ (oo)\ ________
(__)\ )\ /\
||------w|
|| ||
Now in v1:
______________
< Hello world! >
--------------
\
\
^__^
(oo)\ ________
(__)\ )\ /\
||------w|
|| ||
in Perl cli cowsay
______________
< Hello world! >
--------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
By much closer I mean:
- Instead of just a top and bottom line there’s actually sides now.
- Fixed bubble top in GitHub main at least (see below note)
- The bubble expands with the text to contain it all within the bubble, for example:
library(cowsay)
library(fortunes)
say("fortune")
________________________________________________________
/ The problem, as always, is what the heck does one mean \
| by 'outlier' in these contexts. Seems to be like |
| pornography -- "I know it when I see it." Berton |
| Gunter quoting Justice Potter Stewart in a discussion |
\ about tests for outliers R-help April 2005 /
--------------------------------------------------------
\
\
^__^
(oo)\ ________
(__)\ )\ /\
||------w|
|| ||
A few notes:
- I realized in drafting this post that original cowsay uses underscores for the top of the bubble and hyphens for the bottom of the bubble whereas R cowsay was using hyphens for top and bottom. I just pushed a fix for this, so to get underscores for the bubble top install from GitHub (
pak::pak("sckott/cowsay")
). - With the refactoring of bubbles in v1, the “tail” is now above the animals b/c it was just easier that way. In a future version we’ll try to fix that to have the tail coming down farther like original cowsay.
The other thing that brings R cowsay closer to og cowsay is having think()
, which I hadn’t realized was a thing until finding the page in the Wayback Machine for the original cowsay. For example:
library(cowsay)
library(fortunes)
think("fortune")
________________________________________________________
( Dear Uwe, thank you very much for your unvaluable time )
( and effort. Javier Cano thanking Uwe Ligges for )
( solving a coding problem R-help July 2009 )
--------------------------------------------------------
o
o
^__^
(oo)\ ________
(__)\ )\ /\
||------w|
|| ||
think()
differs from say()
in having circles for the tail to the bubble and parens for the bubble sides rather than slashes.
Hand-rolled
With v1 you can now hand roll cowsay output, for example:
library(cowsay)
library(fortunes)
quote <- as.character(fortune())
chicken <- animals[["chicken"]]
z <- paste(
c(bubble_say(quote), bubble_tail(chicken, "\\"), chicken),
collapse = "\n"
)
cat(z)
_______________________________________________________
/ This is a bit like asking how should I tweak my \
| sailboat so I can explore the ocean floor. |
| Roger Koenker |
| in response to a question about tweaking the quantreg |
| package to handle probit and heckit models |
| R-help |
\ May 2013 /
-------------------------------------------------------
\
\
_
_/ }
`>' \
`| \
| /'-. .-.
\' ';`--' .'
\'. `'-./
'.`-..-;`
`;-..'
_| _|
/` /` [nosig]
A note about the refactored bubbles and tails: The tail horizontal position is now calculated based on the animal - so instead of always being in the same horizontal position, we attempt to place the tail close to the head of the animal.
Fin
Have fun!