Skip to main content

Python Cowsay

Repository PyPi License

A rewrite of cowsay in python. Allows for parsing of existing .cow files.

Install

pip install python-cowsay

Usage

CLI

Installing python-cowsay adds cowsay and cowthink terminal programs. These work similarly to the classic cowsay CLIs.

See cowsay --help or cowthink --help for more info.

> cowsay --help 
usage: cowsay [-h] [-e eye_string] [-f cowfile] [-l] [-n] [-T tongue_string]
↪ [-W column] [-b] [-d] [-g] [-p] [-s] [-t] [-w] [-y] [--random] [message]

Generates an ASCII image of a cow saying the given text

positional arguments:
  message           The message to include in the speech bubble. If not given, 
                    stdin is used instead.

options:
  -h, --help        show this help message and exit
  -e eye_string     An eye string. This is ignored if a preset mode is given
  -f cowfile        Either the name of a cow specified in the COWPATH, or a 
                    path to a cowfile (if provided as a path, the path must 
                    contain at least one path separator)
  -l                Lists all cows in the cow path and exits
  -n                If given, text in the speech bubble will not be wrapped
  -T tongue_string  A tongue string. This is ignored if a preset mode is given
  -W column         Width in characters to wrap the speech bubble (default 40)
  --random          If provided, picks a random cow from the COWPATH.
                    Is superseded by the -f option

Mode:
  There are several out of the box modes which change the appearance of the cow.
  If multiple modes are given, the one furthest down this list is selected

  -b                Borg
  -d                dead
  -g                greedy
  -p                paranoid
  -s                stoned
  -t                tired
  -w                wired
  -y                young

Programmatic Execution

The classic cowsay text can be generated by the cowsay or cowthink functions:

from cowsay import cowsay

message = """
The most remarkable thing about my mother is that for thirty years she served
the family nothing but leftovers.  The original meal has never been found.
		-- Calvin Trillin
""".strip()
print(cowsay(message))

Will yield:

 __________________________________________ 
/ The most remarkable thing about my       \
| mother is that for thirty years she      |
| served the family nothing but leftovers. |
| The original meal has never been found.  |
|                                          |
\ -- Calvin Trillin                        /
 ------------------------------------------ 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

The parameters for these functions are:

  • message – a string to wrap in the text bubble
  • cow='default' – the name of the cow (valid names from list_cows)
  • preset=None – the original cowsay presets: -bgpstwy
  • eyes=Option.eyes – A custom eye string
  • tongue=Option.tongue – A custom tongue string
  • width=40 – The width of the text bubble
  • wrap_text=True – Whether text should be wrapped in the bubble
  • cowfile=None – A custom string representing a cow

Other Functions

The available builtin cows can be found with list_cows. A cow can be chosen randomly from this list with get_random_cow.

Using Your Own Cows

A custom .cow file can be parsed using the read_dot_cow function which takes a TextIO stream. I.e., You can either create a TextIO from a string or read a file.

The read_dot_cow will look for the first heredoc in the steam and extract the heredoc contents. If no heredoc exists, the whole stream is used instead. Escape characters are then escaped. The default escape characters can be changed by passing in an optional escape dictionary parameter mapping escape codes to their chars.

For example:

from io import StringIO

from cowsay import read_dot_cow, cowthink

cow = read_dot_cow(StringIO("""
$the_cow = <<EOC;
         $thoughts
          $thoughts
           ___
          (o o)
         (  V  )
        /--m-m-
EOC
"""))
message = """
Nothing is illegal if one hundred businessmen decide to do it.
        -- Andrew Young
""".strip()
print(cowthink(message, cowfile=cow))

Will yield:

 ___________________________________ 
( Nothing is illegal if one hundred )
( businessmen decide to do it.      )
(                                   )
( -- Andrew Young                   )
 ----------------------------------- 
         o
          o
           ___
          (o o)
         (  V  )
        /--m-m-

Parsing .cow Files

.cow files are just files containing Perl code. This causes some issues for more advanced .cow files that do things like define additional variables that get used in the cow heredoc. Most notably, this happens when using tools like Charc0al's cowsay file converter.

python-cowsay does not fully support Perl .cow files but has accounted for this one case. When parsing .cow files, python-cowsay will look for any string variable declarations at the start of each line and the cow heredoc. If any string variables are found, these are inlined in the resulting cow.

Changing the Cows

python-cowsay will attempt to retrieve a COWPATH environment variable, if found, the path this variable references will be used instead of the default that is installed with python-cowsay.

If you wish to change the default cows, set the COWPATH environment variable in your shell profile:

export COWPATH=path/to/cows

Full-Width Characters

A bit of a hack at the moment, but if any full-width characters are found in the message string, all characters in the thought bubble are converted to full-width. For example:

 ____________ 
( 喵喵喵。我是一只猫。 )
 ------------ 
   o
    o

     |\_/|
     |o o|__
     --*--__\
     C_C_(___)

This works fine when all characters in the message are full-width, but does not work so well when there is a mix of full- and neutral-width characters:

 _________________ 
( 喵喵喵。I am a cat. )
 ----------------- 
   o
    o

     |\_/|
     |o o|__
     --*--__\
     C_C_(___)

Each full-width character still only counts as one character when setting the text width. For example:

from cowsay import cowthink

message = "喵喵喵。我是一只猫。我想吃鱼和喝牛奶。"
print(cowthink(message, cow="kitten", width=10))

Will yield:

 ____________ 
( 喵喵喵。我是一只猫。 )
( 我想吃鱼和喝牛奶。  )
 ------------ 
   o
    o

     |\_/|
     |o o|__
     --*--__\
     C_C_(___)

Related projects

Notes

The cow files that are installed by default in this package are taken from the original cowsay repository

The cows provided in this package, save for minor edits to resolve issues with parsing cow files, are otherwise provided as they were in the original cowsay repository.

Metadata

Release files for python-cowsay 1.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-cowsay 1.2.2
File Size Uploaded
python_cowsay-1.2.2.tar.gz 31.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-cowsay 1.2.2
File Interpreter ABI Platform
python_cowsay-1.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 69.1 kB

Release files / python_cowsay-1.2.2.tar.gz

Download URL python_cowsay-1.2.2.tar.gz
Size 31.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e2700075e3814dd3d3da40d678f04abfc7916dc8c4ea289449b5d91481061988
BLAKE2b-256 checksum
How to use checksums
dff82e25454128939d984b94789b1ad60bba2851db21981e8d3652a202bf2ab9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / python_cowsay-1.2.2-py3-none-any.whl

Download URL python_cowsay-1.2.2-py3-none-any.whl
Size 37.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0da51568721cf4a921171e825896489b0b304d7843e1ef51c89c8c52994f1d2
BLAKE2b-256 checksum
How to use checksums
c1790a8fbb511331b70c739c21280f4c6d85b39a3f64bd0af9ef86cde249c2eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

1.2.2 This release

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page