Version: | 0.3.0 |
---|---|
Founder: | Justine Alexandra Roberts Tunney |
Copyright: | Copyright 2016 The Fabulous Authors. All rights reserved. |
License: | Apache 2.0 / OFL |
Support: | Python 2.6, 2.7, 3.3, 3.4, 3.5, and pypy |
Source: | github.com/jart/fabulous |
Fabulous is a Python library (and command line tools) designed to make the output of terminal applications look fabulous. Fabulous allows you to print colors, images, and stylized text to the console (without curses.) Fabulous also offers features to improve the usability of Python’s standard logging system.
The following prerequisites should be installed, but they are not mandatory. They help Fabulous run faster and make the full feature set available:
sudo apt-get install gcc python-imaging
Fabulous can be installed from CheeseShop:
sudo pip install fabulous
Fabulous can also be installed manually from the source archive:
wget https://github.com/jart/fabulous/releases/download/0.3.0/fabulous-0.3.0.tar.gz
tar -xvzf fabulous-0.3.0.tar.gz
cd fabulous-0.3.0
sudo python setup.py install
Once installed, run the demo:
fabulous-demo
4-bit colors and styles are standard and work almost everywhere. They are useful in helping make your program output easier to read:
from fabulous.color import bold, magenta, highlight_red
print bold(magenta('hello world'))
print highlight_red('DANGER WILL ROBINSON!')
print bold('hello') + ' ' + magenta(' world')
assert len(bold('test')) == 4
8-bit color works in most modern terminals, such as gnome-terminal and Terminal.app:
from fabulous import fg256, bg256
print fg256('#F0F', 'hello world')
print fg256('magenta', 'hello world')
This is something neat you can use when you program starts up to display its name with style:
from fabulous import text
print text.Text("Fabulous!", color='#0099ff', shadow=True, skew=5)
Fabulous lets you print images, which is more fun than useful. Fabulous’ unique method of printing images really shines when used with semi-transparent PNG files. When blending backgrounds, Fabulous assumes by default that your terminal has a black background. Don’t worry if your image is huge, it’ll be resized by default to fit your terminal:
from fabulous import utils, image
print image.Image("balls.png")
# adjust for a white background
utils.term.bgcolor = 'white'
print image.Image("balls.png")
Image printing may perform slowly depending on whether or not Fabulous is able to compile ~/.xterm256.so on the fly. This is a tiny library that makes color quantization go much faster. The pure Python version of the algorithm is really slow because it’s implemented as a brute force nearest neighbor over Euclidean distance search. Although an O(1) version of this algorithm exists with slightly less correctness. Your humble author simply hasn’t had the time to implement it in this library.
If you like this image printing feature, then please check out hiptext which is a C++ program written by the same author as Fabulous. It offers a much richer version of this same functionality. It can even play videos in the terminal. Also be sure to check out rickrollrc.
Usage: fabulous-text [options]
Options:
-h, --help show this help message and exit
-l, --list List available fonts
-S SKEW, --skew=SKEW Apply skew effect (measured in pixels) to make it look
extra cool. For example, Fabulous' logo logo is
skewed by 5 pixels. Default: none
-C COLOR, --color=COLOR
Color of your text. This can be specified as you
would using HTML/CSS. Default: #0099ff
-B TERM_COLOR, --term-color=TERM_COLOR
If you terminal background isn't black, please change
this value to the proper background so semi-
transparent pixels will blend properly.
-F FONT, --font=FONT Name of font file, or absolute path to one. Use the
--list flag to see what fonts are available. Fabulous
bundles the NotoSans-Bold and NotoEmoji-Regular fonts,
which are guaranteed to work. Default: NotoSans-Bold
-Z FSIZE, --size=FSIZE
Size of font in points. Default: 23
-s, --shadow Size of font in points. Default: False
Usage: fabulous-image [options]
Options:
-h, --help show this help message and exit
-w WIDTH, --width=WIDTH
Width of printed image in characters. Default: none
Displays a demo showing what Fabulous can do.
The fabulous-gotham command is a gothic poetry generator. It is a gimmick feature that uses a simple mad lib algorithm. It has no concept of meter or rhyme. Users wanting a proper poetry generator should consider poemy2 which uses markov chains and isledict. It’s also written by the same author as Fabulous.
The fabulous-rotatingcube command is another gimmick feature that animates a wireframe rotating cube in the terminal. It runs until you hit Ctrl+C.
The color module provides an object-oriented abstraction for stylized text inside the terminal. This includes things like bold text, blinking text, 4-bit ANSI colors and 8-bit xterm256 colors.
Abstract base class for stylized string-like objects.
Subclasses make it possible to compose stylized text:
>>> str(red("hello"))
'\x1b[31mhello\x1b[39m'
>>> str(bold(red("hello")))
'\x1b[1m\x1b[31mhello\x1b[39m\x1b[22m'
>>> str(plain("hello ", bold("world")))
'hello \x1b[1mworld\x1b[22m'
These objects also provide string length without taking into consideration the ANSI escape codes:
>>> len(red("hello"))
5
>>> len(str(red("hello")))
15
>>> len(bold(red("hello")))
5
>>> len(bold("hello ", red("world")))
11
A more readable way to say unicode(color).encode('utf8')
Base class for 256-color stylized string-like objects.
See the fg256, bg256, highlight256, and complement256 classes for more information.
xterm256 background color wrapper
This class creates a string-like object that has an xterm256 color. The color is specified as a CSS color code, which is automatically quantized to the available set of xterm colors.
These colors are more dependable than the 4-bit colors, because 8-bit colors don’t get changed by the terminal theme. They will consistently be the requested color.
However it is worth noting that in Terminal.app on Mac OS, 8-bit background colors are ever so slightly different than their foreground equivalent. Therefore Terminal.app has effectively 512 colors.
Example usage:
from fabulous import bg256, plain
print bg256('#F00', 'i have a red background!')
print bg256('#FF0000', 'i have a red background!')
print bg256('magenta', 'i have a', ' magenta background!')
print plain('hello ', bg256('magenta', 'world'))
The ANSI escape codes look as follows:
>>> str(bg256('red', 'hello'))
'\x1b[48;5;196mhello\x1b[49m'
Black foreground text wrapper
This class creates a string-like object containing text with a black foreground.
Example usage:
from fabulous.color import black
print black('i am black!')
print plain('hello ', black('world'))
Text can be made dark grey by using bold:
from fabulous.color import bold, black
print bold(black('i am dark grey!'))
The ANSI escape codes are as follows:
>>> str(black("hello"))
'\x1b[30mhello\x1b[39m'
Black background text wrapper
This class creates a string-like object containing text with a black background. On properly configured terminals, this will do nothing.
Example usage:
from fabulous.color import black_bg
print black_bg('i have a black background!')
print plain('hello ', black_bg('world'))
The ANSI escape codes are as follows:
>>> str(black_bg("hello"))
'\x1b[40mhello\x1b[49m'
Blinking text wrapper
This class creates a string-like object containing blinking text. This is supported by SOME terminals, as documented in the terminal support section.
Example usage:
from fabulous.color import blink
print blink('i am underlined!')
print plain('hello ', blink('world'))
The ANSI escape codes are as follows:
>>> str(blink("hello"))
'\x1b[5mhello\x1b[25m'
Blue foreground text wrapper
This class creates a string-like object containing text with a blue foreground.
Example usage:
from fabulous.color import blue
print blue('i am dark blue!')
print plain('hello ', blue('world'))
Text can be made sky blue by using bold:
from fabulous.color import bold, blue
print bold(blue('i am sky blue!'))
The ANSI escape codes are as follows:
>>> str(blue("hello"))
'\x1b[34mhello\x1b[39m'
Blue background text wrapper
This class creates a string-like object containing text with a blue background.
Example usage:
from fabulous.color import blue_bg
print blue_bg('i have a blue background!')
print plain('hello ', blue_bg('world'))
The ANSI escape codes are as follows:
>>> str(blue_bg("hello"))
'\x1b[44mhello\x1b[49m'
Bold text wrapper
This class creates a string-like object containing bold or bright text. It also brightens the foreground and background colors. This is supported by all terminals that support ANSI color codes.
Example usage:
from fabulous.color import bold
print bold('i am bold!')
print plain('hello ', bold('world'))
The ANSI escape codes are as follows:
>>> str(bold("hello"))
'\x1b[1mhello\x1b[22m'
Calculates polar opposite of color
This isn’t guaranteed to look good >_> (especially with brighter, higher intensity colors.) This will be replaced with a formula that produces better looking colors in the future.
>>> complement('red')
(0, 255, 76)
>>> complement((0, 100, 175))
(175, 101, 0)
Highlighted 8-bit color text
This class composes bold, flip, and bg256. Then it invokes complement() to supply the polar opposite fg256 color.
This looks kind of hideous at the moment. We’re planning on finding a better formula for complementary colors in the future.
Cyan foreground text wrapper
This class creates a string-like object containing text with a cyan foreground.
Example usage:
from fabulous.color import cyan
print cyan('i am cyan!')
print plain('hello ', cyan('world'))
Text can be made bright cyan by using bold:
from fabulous.color import bold, cyan
print bold(cyan('i am bright cyan!'))
The ANSI escape codes are as follows:
>>> str(cyan("hello"))
'\x1b[36mhello\x1b[39m'
Cyan background text wrapper
This class creates a string-like object containing text with a cyan background.
Example usage:
from fabulous.color import cyan_bg
print cyan_bg('i have a cyan background!')
print plain('hello ', cyan_bg('world'))
The ANSI escape codes are as follows:
>>> str(cyan_bg("hello"))
'\x1b[46mhello\x1b[49m'
Produces an ANSI escape code string from a list of integers
This is a low level function that is abstracted by the other functions and classes in this module.
xterm256 foreground color wrapper
This class creates a string-like object that has an xterm256 color. The color is specified as a CSS color code, which is automatically quantized to the available set of xterm colors.
These colors are more dependable than the 4-bit colors, because 8-bit colors don’t get changed by the terminal theme. They will consistently be the requested color, which is calculated using a simple math formula.
However it is worth noting that in Terminal.app on Mac OS, 8-bit colors appear to be designed rather than formulaic, so they look much nicer.
Example usage:
from fabulous import fg256, plain
print fg256('#F00', 'i am red!')
print fg256('#FF0000', 'i am red!')
print fg256('magenta', 'i am', ' magenta!')
print plain('hello ', fg256('magenta', 'world'))
The ANSI escape codes look as follows:
>>> str(fg256('red', 'hello'))
'\x1b[38;5;196mhello\x1b[39m'
Flips background and foreground colors
For example:
from fabulous.color import flip, red
print flip(red('hello'))
Is equivalent to the following on a black terminal:
from fabulous.color import black, red_bg
print red_bg(black('hello'))
The ANSI escape codes are as follows:
>>> str(flip("hello"))
'\x1b[7mhello\x1b[27m'
Green foreground text wrapper
This class creates a string-like object containing text with a green foreground.
Example usage:
from fabulous.color import green
print green('i am green!')
print plain('hello ', green('world'))
Text can be made bright green by using bold:
from fabulous.color import bold, green
print bold(green('i am bright green!'))
The ANSI escape codes are as follows:
>>> str(green("hello"))
'\x1b[32mhello\x1b[39m'
Green background text wrapper
This class creates a string-like object containing text with a green background.
Example usage:
from fabulous.color import green_bg
print green_bg('i have a green background!')
print plain('hello ', green_bg('world'))
The ANSI escape codes are as follows:
>>> str(green_bg("hello"))
'\x1b[42mhello\x1b[49m'
Prints bold text with line beneath it spanning width of terminal
Highlighted 8-bit color text
Dark grey highlight text wrapper
Blue highlight text wrapper
Cyan highlight text wrapper
Green highlight text wrapper
Hot pink highlight text wrapper
Red highlight text wrapper
White highlight text wrapper
Yellow highlight text wrapper
Italic text wrapper
This class creates a string-like object containing italic text, which is supported by almost no terminals.
The ANSI escape codes are as follows:
>>> str(italic("hello"))
'\x1b[3mhello\x1b[23m'
Purple/magenta foreground text wrapper
This class creates a string-like object containing text with a magenta foreground. Although in many terminals, it’s going to look more purple.
Example usage:
from fabulous.color import magenta
print magenta('i am magenta purplish!')
print plain('hello ', magenta('world'))
Text can be made hot pink by using bold:
from fabulous.color import bold, magenta
print bold(magenta('i am hot pink!'))
The ANSI escape codes are as follows:
>>> str(magenta("hello"))
'\x1b[35mhello\x1b[39m'
Magenta background text wrapper
This class creates a string-like object containing text with a magenta background.
Example usage:
from fabulous.color import magenta_bg
print magenta_bg('i have a magenta background!')
print plain('hello ', magenta_bg('world'))
The ANSI escape codes are as follows:
>>> str(magenta_bg("hello"))
'\x1b[45mhello\x1b[49m'
Turns a color into an (r, g, b) tuple
>>> parse_color('white')
(255, 255, 255)
>>> parse_color('#ff0000')
(255, 0, 0)
>>> parse_color('#f00')
(255, 0, 0)
>>> parse_color((255, 0, 0))
(255, 0, 0)
>>> from fabulous import grapefruit
>>> parse_color(grapefruit.Color((0.0, 1.0, 0.0)))
(0, 255, 0)
Plain text wrapper
This class is useful for concatenating plain strings with ColorString objects. For example:
from fabulous.color import plain
>>> len(plain("hello ", bold("kitty")))
11
Red foreground text wrapper
This class creates a string-like object containing text with a red foreground.
Example usage:
from fabulous.color import red
print red('i am red!')
print plain('hello ', red('world'))
Text can be made bright red by using bold:
from fabulous.color import bold, red
print bold(red('i am bright red!'))
The ANSI escape codes are as follows:
>>> str(red("hello"))
'\x1b[31mhello\x1b[39m'
Red background text wrapper
This class creates a string-like object containing text with a red background.
Example usage:
from fabulous.color import red_bg
print red_bg('i have a red background!')
print plain('hello ', red_bg('world'))
The ANSI escape codes are as follows:
>>> str(red_bg("hello"))
'\x1b[41mhello\x1b[49m'
Helper function for testing demo routines
Strike-through text wrapper
This class creates a string-like object containing strike-through text, which is supported by very few terminals.
Example usage:
from fabulous.color import strike
print strike('i am stricken!')
print plain('hello ', strike('world'))
The ANSI escape codes are as follows:
>>> str(strike("hello"))
'\x1b[9mhello\x1b[29m'
Underline text wrapper
This class creates a string-like object containing underline text. This is supported by SOME terminals, as documented in the terminal support section.
Example usage:
from fabulous.color import underline
print underline('i am underlined!')
print plain('hello ', underline('world'))
The ANSI escape codes are as follows:
>>> str(underline("hello"))
'\x1b[4mhello\x1b[24m'
Alternative underline text wrapper
See also: underline.
The ANSI escape codes are as follows:
>>> str(underline2("hello"))
'\x1b[21mhello\x1b[24m'
White foreground text wrapper
This class creates a string-like object containing text with a light grey foreground.
Example usage:
from fabulous.color import white
print white('i am light grey!')
print plain('hello ', white('world'))
Text can be made true white by using bold:
from fabulous.color import bold, white
print bold(white('i am bold white!'))
The ANSI escape codes are as follows:
>>> str(white("hello"))
'\x1b[37mhello\x1b[39m'
White background text wrapper
This class creates a string-like object containing text with a white background.
Example usage:
from fabulous.color import white_bg
print white_bg('i have a white background!')
print plain('hello ', white_bg('world'))
The ANSI escape codes are as follows:
>>> str(white_bg("hello"))
'\x1b[47mhello\x1b[49m'
Yellow foreground text wrapper
This class creates a string-like object containing text with a “yellow” foreground, which in many terminals is actually going to look more brownish.
Example usage:
from fabulous.color import yellow
print yellow('i am yellow brownish!')
print plain('hello ', yellow('world'))
Text can be made true bright yellow by using bold:
from fabulous.color import bold, yellow
print bold(yellow('i am bright yellow!'))
The ANSI escape codes are as follows:
>>> str(yellow("hello"))
'\x1b[33mhello\x1b[39m'
Yellow background text wrapper
This class creates a string-like object containing text with a yellow background.
Example usage:
from fabulous.color import yellow_bg
print yellow_bg('i have a yellow background!')
print plain('hello ', yellow_bg('world'))
The ANSI escape codes are as follows:
>>> str(yellow_bg("hello"))
'\x1b[43mhello\x1b[49m'
The xterm256 module provides support for the 256 colors supported by xterm as well as quantizing 24-bit RGB color to xterm color ids.
Color quantization may perform slowly depending on whether or not Fabulous is able to compile ~/.xterm256.so on the fly. This is a tiny library that makes color quantization go much faster. The pure Python version of the algorithm is really slow because it’s implemented as a brute force nearest neighbor over Euclidean distance search. Although an O(1) version of this algorithm exists with slightly less correctness. Your humble author simply hasn’t had the time to implement it in this library.
Tries to compile/link the C version of this module
Like it really makes a huge difference. With a little bit of luck this should just work for you.
You need:
The text module makes it possible to print TrueType text to the terminal. This functionality is available on the command line:
jart@compy:~$ fabulous-text --help
jart@compy:~$ fabulous-text --skew=5 --shadow 'Fabulous!'
jart@compy:~$ python -m fabulous.text --help
Or as a Python library:
from fabulous import text
print text.Text("Fabulous!", color='#0099ff', shadow=True, skew=5)
To make things simple, Fabulous bundles the following Google Noto Fonts which look good and are guaranteed to work no matter what:
For other fonts, Fabulous will do its best to figure out where they are stored. If Fabulous has trouble finding your font, try using an absolute path with the extension. It’s also possible to put the font in the ~/.fonts directory and then running fc-cache -fv ~/.fonts.
You can run fabulous-text --list to see what fonts are available.
I get raised when the font-searching hueristics fail
This class extends the standard ValueError exception so you don’t have to import me if you don’t want to.
Renders TrueType Text to Terminal
I’m a sub-class of fabulous.image.Image. My job is limited to simply getting things ready. I do this by:
For example:
>>> assert Text("Fabulous", shadow=True, skew=5)
>>> txt = Text("lorem ipsum", font="NotoSans-Bold")
>>> len(str(txt)) > 0
True
>>> txt = Text(u"😃", font="NotoSans-Bold")
>>> len(str(txt)) > 0
True
Parameters: |
|
---|
Returns a list of all font files we could find
Returned as a list of dir/files tuples:
get_font_files() -> {'FontName': '/abs/FontName.ttf', ...]
For example:
>>> fonts = get_font_files()
>>> 'NotoSans-Bold' in fonts
True
>>> fonts['NotoSans-Bold'].endswith('/NotoSans-Bold.ttf')
True
Main function for fabulous-text.
Turns font names into absolute filenames
This is case sensitive. The extension should be omitted.
For example:
>>> path = resolve_font('NotoSans-Bold')
>>> fontdir = os.path.join(os.path.dirname(__file__), 'fonts')
>>> noto_path = os.path.join(fontdir, 'NotoSans-Bold.ttf')
>>> noto_path = os.path.abspath(noto_path)
>>> assert path == noto_path
Absolute paths are allowed:
>>> resolve_font(noto_path) == noto_path
True
Raises FontNotFound on failure:
>>> try:
... resolve_font('blahahaha')
... assert False
... except FontNotFound:
... pass
The image module makes it possible to print images to the terminal.
This module is available as a command line tool:
jart@compy:~$ fabulous-image foo.png
jart@compy:~$ python -m fabulous.image foo.png
Printing image files to a terminal
I use PIL to turn your image file into a bitmap, resize it so it’ll fit inside your terminal, and implement methods so I can behave like a string or iterable.
When resizing, I’ll assume that a single character on the terminal display is one pixel wide and two pixels tall. For most fonts this is the best way to preserve the aspect ratio of your image.
All colors are are quantized by fabulous.xterm256 to the 256 colors supported by modern terminals. When quantizing semi-transparant pixels (common in text or PNG files) I’ll ask TerminalInfo for the background color I should use to solidify the color. Fully transparent pixels will be rendered as a blank space without color so we don’t need to mix in a background color.
I also put a lot of work into optimizing the output line-by-line so it needs as few ANSI escape sequences as possible. If your terminal is kinda slow, you’re gonna want to buy me a drink ;) You can use DebugImage to visualize these optimizations.
The generated output will only include spaces with different background colors. In the future routines will be provided to overlay text on top of these images.
Yields xterm color codes for each pixel in image
Converts color codes into optimized text
This optimizer works by merging adjacent colors so we don’t have to repeat the same escape codes for each pixel. There is no loss of information.
Parameters: | colors – Iterable yielding an xterm color code for each pixel, None to indicate a transparent pixel, or 'EOL' to indicate th end of a line. |
---|---|
Returns: | Yields lines of optimized text. |
Resizes image to fit inside terminal
Called by the constructor automatically.
Returns size of image
Main function for fabulous-image.
Utilities for transient logging.
This is very useful tool for monitoring what your Python scripts are doing. It allows you to have full verbosity without drowning out important error messages:
import time, logging
from fabulous import logs
logs.basicConfig(level='WARNING')
for n in range(20):
logging.debug("verbose stuff you don't care about")
time.sleep(0.1)
logging.warning("something bad happened!")
for n in range(20):
logging.debug("verbose stuff you don't care about")
time.sleep(0.1)
Standard Python logging Handler for Transient Console Logging
Logging transiently means that verbose logging messages like DEBUG will only appear on the last line of your terminal for a short period of time and important messages like WARNING will scroll like normal text.
This allows you to log lots of messages without the important stuff getting drowned out.
This module integrates with the standard Python logging module.
Shortcut for setting up transient logging
I am a replica of logging.basicConfig which installs a transient logging handler to stderr.
Widget library using terminate.
p = ProgressBar(‘spam’) # create bar p.update(0, ‘starting spam’) # start printing it out p.update(50, ‘spam almost ready’) # progress p.update(100, ‘spam complete’)
returns None or string
p = ProgressBar(‘spam’) # create bar p.update(0, ‘starting spam’) # start printing it out p.update(50, ‘spam almost ready’) # progress p.update(100, ‘spam complete’)
ETA 12:23
Terminal abstraction layer.
Provides standard capabilites to a variety of terminals. Support information is being worked on.
import os
os.stdout.write('spam' +
display('bright','yellow','white') +
'eggs' +
display('default') + os.linesep)
Warning: on IPython setting sys.stdout to stdout will break readline
Caveat: Failure to flush after ouput can cause weird ordering behaviour when writing to stdout and stderr simutaniously. This should fix the worst of it, but application developers should be warned not to rely on the state of things between call between one method call and another
Returns an ANSI display code. This is useful when writing to an Term
# give bright blue foreground and white background with underline
display(('bright','underline'),'blue','white')
# gives a blue foreground
display(fg='blue')
# resets the color to the default.
display('default')
Avoid using black or white. Depending on the situation the default background/foreground is normally black or white, but it’s hard to tell which. Bare terminals are normally white on black, but virtual terminals run from X or another GUI system are often black on white. This can lead to unpredicatble results. If you want reversed colours, use the ‘reverse’ code, and if you want to set the colors back to their original colors, use the ‘default’ code.
Also, be prudent with your use of ‘hidden’ and ‘blink’. Several terminals do not support them (and for good reason too), they can be really annoying and make reading difficult.
A file-like object which also supports terminal features.
This is a base class for dumb terminals. It supports almost nothing.
Causes the computer to beep
Use sparingly, it is mainly to alert the user if something potentialy bad may be happening.
clears part of the screen
The valid values for scope are:
N.b. this is not the same as deleting. After a place is cleared it should still be there, but with nothing in it. Also, this should not change the position of the cursor.
Not for public consumption (yet)
Just use display() and stdout.write() for now.
run this at the beginning:
(codes, fg, bg) = Magic.displayformat(codes, fg, bg)
Returns the stream’s file descriptor as an integer
Ensure the text is ouput to the screen.
The write() method will do this automatically, so only use this when using self.stream.write().
Get the width and height of the terminal.
Returns either a tuple of two integers or None. If two integers are returned, the first one is the number of columns (or width) and the second value is the number of lines (or height). If None is returned, then the terminal does not support this feature. If you still need to have a value to fall back on (75, 25) is a fairly descent fallback.
Don’t use this yet
It doesn’t belong here but I haven’t yet thought about a proper way to implement this feature and the features that will depend on it.
Returns True if the terminal is a terminal
This should always be True. If it’s not somebody is being rather nauty.
Move cursor position
The valid values for place are:
Don’t use this yet
It doesn’t belong here but I haven’t yet thought about a proper way to implement this feature and the features that will depend on it.
Sets the title of the terminal
Parses text and prints proper output to the terminal
This method will extract escape codes from the text and handle them as well as possible for whichever platform is being used. At the moment only the display escape codes are supported.
Write out a sequence of strings
Note that newlines are not added. The sequence may be any iterable object producing strings. This is equivalent to calling write() for each string.
Windows version of terminal control
This class should not be used by itself, use either Win32Terminal or WinCTypesTerminal classes that subclasses of this class.
This class makes extensive use of the Windows API
The official documentation for the API is on MSDN (look for ‘console functions’)
see doc in Term class
According to http://support.microsoft.com/kb/99261 the best way to clear the console is to write out empty spaces
Displays codes using Windows kernel calls
see doc in Term class
Don’t use this yet
It doesn’t belong here but I haven’t yet thought about a proper way to implement this feature and the features that will depend on it.
see doc in Term class
PyWin32 version of Windows terminal control.
Uses the PyWin32 Libraries <http://sourceforge.net/projects/pywin32/>.
ActiveState has good documentation for them:
Main page: http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/pywin32/PyWin32.html Console related objects and methods: http://aspn.activestate.com/ASPN/docs/ActivePython/2.4/pywin32/PyConsoleScreenBuffer.html
CTypes version of Windows terminal control.
It requires the CTypes libraries <http://sourceforge.net/projects/ctypes/>
As of Python 2.5, CTypes is included in Python by default. User’s of previous version of Python will have to install it if they what to use this.
Readline related stuff.
A base class for completers.
Child classes should implement the completelist method.
The actual completion method
This method is not meant to be overridden. Override the completelist method instead. It will make your life much easier.
For more detail see documentation for readline.set_completer
Returns a list.
The list contains a series of strings which are the suggestions for the given string text. It is valid to have no suggestions (empty list returned).
A class that does completion based on a predefined list.
Does completion based on file paths.
Return a list of potential matches for completion
n.b. you want to complete to a file in the current working directory that starts with a ~, use ./~ when typing in. Paths that start with ~ are magical and specify users’ home paths
To find matches that start with prefix.
For example, if prefix = ‘~user’ this returns list of possible matches in form of [‘~userspam’,’~usereggs’] etc.
matchuserdir(‘~’) returns all users
This is a gimmick feature that generates silly gothic poetry.
This uses a simple mad lib algorithm. It has no concept of meter or rhyme. If you want a proper poetry generator, check out poemy2 which uses markov chains and isledict. It’s written by the same author as Fabulous.
This module can be run as a command line tool:
jart@compy:~$ fabulous-gotham
jart@compy:~$ python -m fabulous.gotham
Cheesy Gothic Poetry Generator
Uses Python generators to yield eternal angst.
When you need to generate random verbiage to test your code or typographic design, let’s face it... Lorem Ipsum and “the quick brown fox” are old and boring!
What you need is something with flavor, the kind of thing a depressed teenager with a lot of black makeup would write.
Names your poem
I provide a command-line interface for this module
Command for animating a wireframe rotating cube in the terminal.
Canvas object for drawing a frame to be printed
Rotating cube program
How it works:
- Create two imaginary ellipses
- Sized to fit in the top third and bottom third of screen
- Create four imaginary points on each ellipse
- Make those points the top and bottom corners of your cube
- Connect the lines and render
- Rotate the points on the ellipses and repeat
The debug module provides the ability to print images as ASCII. It isn’t a good ASCII representation like cacalib. This module is mostly intended for debugging purposes (hence the name.)
Visualize optimization techniques used by Image
I provide a command-line interface for this module
Miscellaneous utilities for Fabulous.
Quick and easy access to some terminal information
I’ll tell you the terminal width/height and it’s background color.
You don’t need to use me directly. Just access the global term instance:
>>> assert term.width > 0
>>> assert term.height > 0
It’s important to know the background color when rendering PNG images with semi-transparency. Because there’s no way to detect this, black will be the default:
>>> term.bgcolor
(0.0, 0.0, 0.0, 1.0)
>>> from fabulous import grapefruit
>>> isinstance(term.bgcolor, grapefruit.Color)
True
If you use a white terminal, you’ll need to manually change this:
>>> term.bgcolor = 'white'
>>> term.bgcolor
(1.0, 1.0, 1.0, 1.0)
>>> term.bgcolor = grapefruit.Color.NewFromRgb(0.0, 0.0, 0.0, 1.0)
>>> term.bgcolor
(0.0, 0.0, 0.0, 1.0)
Returns terminal dimensions
Don’t save this information for long periods of time because the user might resize their terminal.
Returns: | Returns (width, height). If there’s no terminal to be found, we’ll just return (79, 40). |
---|
Returns height of terminal in lines
Returns file descriptor number of terminal
This will look at all three standard i/o file descriptors and return whichever one is actually a TTY in case you’re redirecting i/o through pipes.
Returns width of terminal in characters
A very simple memoize decorator to optimize pure-ish functions
Don’t use this unless you’ve examined the code and see the potential risks.
Check for PIL library, printing friendly error if not found
We need PIL for the fabulous.text and fabulous.image modules to work. Because PIL can be very tricky to install, it’s not listed in the setup.py requirements list.
Terminal | default | bright | dim | underline | blink | reverse | hidden |
---|---|---|---|---|---|---|---|
xterm | yes | yes | yes | yes | yes | yes | yes |
linux | yes | yes | yes | bright | yes | yes | no |
rxvt | yes | yes | no | yes | bright | yes | no |
Windows [0] | yes | yes | yes | no | no | yes | yes |
PuTTY [1] | yes | yes | no | yes | [2] | yes | no |
Cygwin SSH [3] | yes | yes | no | [4] | [4] | [2] | yes |
Terminal | default | bright | dim | underline | blink | reverse | hidden |
---|---|---|---|---|---|---|---|
dtterm | yes | yes | yes | yes | reverse | yes | yes |
teraterm | yes | reverse | no | yes | rev/red | yes | no |
aixterm | kinda | normal | no | yes | no | yes | yes |
Mac Terminal | yes | yes | no | yes | yes | yes | yes |
[0] | The default windows terminal, cmd.exe does not set the TERM variable, so detection is done by checking if the string 'win32' is in sys.platform. This This method has some limitations, particularly with remote terminal. But if you’re allowing remote access to a Windows computer you probably have bigger problems. |
[1] | Putty has the TERM variable set to xterm by default |
[2] | (1, 2) Makes background bright |
[3] | Cygwin’s SSH support’s ANSI, but the regular terminal does not, check for win32 first, then check for cygwin. That should give us the cases when cygwin is used through SSH or telnet or something. (TERM = cygwin) |
[4] | (1, 2) Sets foreground color to cyan |
Here’s how Fabulous compares to other similar libraries:
Fabulous code and documentation are licensed Apache 2.0:
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The bundled Google Noto Fonts are licensed under the SIL Open Font License, Version 1.1:
This Font Software is licensed under the SIL Open Font License,
Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font
creation efforts of academic and linguistic communities, and to
provide a free and open framework in which fonts may be shared and
improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply to
any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software
components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to,
deleting, or substituting -- in part or in whole -- any of the
components of the Original Version, by changing formats or by porting
the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed,
modify, redistribute, and sell modified and unmodified copies of the
Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in
Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the
corresponding Copyright Holder. This restriction only applies to the
primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created using
the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.