Fancy Printing with Python
Box Printing and More!
From time to time, I need to print something nice and fancy, like say a box in a terminal:
================= = Hello, world! = =================
But, the task of printing these things becomes tedious, especially if you want to say, center the text:
============================== = Hello, world! = ==============================
But what if you wanted to change all of that: not have it in a box, specify arbitrary widths, specify filler characters, specify line characters, margins, padding, etc?
Here's the output of: fancyPrinter('Hello, world!', centered = True, width = 50, char = '*', mode = 'box', filler = 'X', margin = 1, padding = 1):
************************************************** *XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX* *XXXXXXXXXXXXXXXX Hello, world! XXXXXXXXXXXXXXXXX* *XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX* **************************************************
Or what about multiple lines? That are longer than your width?
Try this out: fancyPrinter('Wow, this sure is a lot of text.\nQuite a bit of text, actually.\nWhy would anyone have this much text to output?', centered = True, width = 20)
==================== = Wow, this sure = = is a lot of = = text. = = Quite a bit of = = text, = = actually. = = Why would = = anyone have = = this much text = = to output? = ====================
And here's the same thing, not centered, with no width specified:
=================================================== = Wow, this sure is a lot of text. = = Quite a bit of text, actually. = = Why would anyone have this much text to output? = ===================================================
Then you would need my fancyPrinter() method:
def fancyPrinter(text, filler = ' ', char = None, centered = False, width = None, margin = None, padding = None, mode = 'box', output = sys.stdout):
'''
Copyright 2011 Sebastian Weigand, released under the GPLv3
Print text in a fancier fashion.
print >> output, text in a fancier fashion.
Accepts multiple lines, and will fit a box (if that is the mode) around it, and truncate
each line which is over the specified width (maximum of terminal, or specified; minimum
of the longest word in the text).
'''
textLength = max(map(len, text.splitlines()))
textArray = text.split()
maxWordLength = max(map(len, textArray))
rows, columns = os.popen('stty size', 'r').read().split()
termWidth = int(columns)
modes = ['box', 'overline', 'underline', 'simple']
if mode not in modes:
raise TypeError('\'' + mode + '\' is an invalid mode for boxprint >> output, er().')
if 'line' in mode:
if not char:
char = '-'
elif mode == 'center':
if not char:
char = ' '
centered = True
if not width:
width = termWidth
else:
if not char:
char = '='
if centered and not width:
width = termWidth
if width:
if width < maxWordLength + 4:
width = maxWordLength + 4
else:
width = textLength + 4
# Set maximum width to that of terminal:
if textLength >= termWidth + 4 or width >= termWidth + 4:
width = termWidth
lines = []
# Chop up lines to fit within confines of width, or max width (terminal):
if width < textLength + 4:
for line in text.splitlines():
sentence = ''
for word in line.split():
word = word + ' '
newSentence = sentence + word
if len(newSentence) < width - 4:
sentence = newSentence
else:
if len(sentence) > 0:
lines.append(sentence)
sentence = word
lines.append(sentence)
else:
lines = (text + ' ').splitlines()
if margin:
print >> output, '\n' * (margin - 1)
if centered:
if mode == 'box' or mode == 'overline':
print >> output, char * width
if padding:
for i in xrange(0, padding):
if 'box' in mode:
print >> output, char + filler * (width - 2) + char
else:
print >> output, filler * width
for line in lines:
# "line" is text + :
spacing = (width - len(line) - 2)
# Prefer extra right spaces when width is not even:
leftSpacing = (spacing / 2) + (spacing % 2) - 1
rightSpacing = (spacing / 2)
if mode == 'box':
print >> output, char + (filler * leftSpacing) + ' ' + line + (filler * rightSpacing) + char
else:
# Extra padding, as there's no preceeding char:
print >> output, (filler * (leftSpacing + 1)) + ' ' + line + (filler * (rightSpacing + 1))
if padding:
for i in xrange(0, padding):
if 'box' in mode:
print >> output, char + filler * (width - 2) + char
else:
print >> output, filler * width
if mode == 'box' or mode == 'underline':
print >> output, char * width
else:
if mode == 'box' or mode == 'overline':
print >> output, char * width
if padding:
for i in xrange(0, padding):
if 'box' in mode:
print >> output, char + filler * (width - 2) + char
else:
print >> output, filler * width
for line in lines:
if mode == 'box':
print >> output, char + ' ' + line + filler * (width - len(line) - 3) + char
else:
print >> output, ' ' + line
if padding:
for i in xrange(0, padding):
if 'box' in mode:
print >> output, char + filler * (width - 2) + char
else:
print >> output, filler * width
if mode == 'box' or mode == 'underline':
# This will produce a line which is slighlty longer on the right,
# but it looks nice in underline.
print >> output, char * width
if margin:
print >> output, '\n' * (margin - 1)I hope you enjoy :)