ponysay/ponysay.py
2013-07-29 19:56:31 +02:00

80 lines
3.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import os, sys, random
from os.path import dirname, realpath, exists
import argparse, textwrap
try:
import re2 as re
except:
import re
# (oneline, multiline, bottom, top, linkl, linkr)
# {one,multi}line := (left, right)
# {left,right} := (top, middle, bottom)
balloonstyles= {'cowsay': (((' ', '', '< '), (' ', '', '> ')), ((' /', '|', '\\ '), (' \\', '|', '/ ')), '-', '_', '\\', '/'),
'cowsay.think': (((' ', '', '( '), (' ', '', ') ')), ((' (', '(', '( '), (' )', ')', ') ')), '-', '_', 'o', 'o'),
'ascii': (((' /|', '', '\\ '), (' \\|', '', '/ ')), ((' /|', '|', '|\\'), (' \\|', '|', '|/')), '_', '_', '\\', '/'),
'ascii.think': (((' ((', '', '( '), (' ))', '', ') ')), ((' ((', '(', '(('), (' ))', ')', '))')), '_', '_', 'o', 'o'),
'unicode': ((('┌││', '', '│└ '), ('┐││', '', '│┘ ')), (('┌││', '', '││└'), ('┐││', '', '││┘')), '', '', '', ''),
'round': ((('╭││', '', '│╰ '), ('╮││', '', '│╯ ')), (('╭││', '', '││╰'), ('╮││', '', '││╯')), '', '', '', ''),
'linux-vt': ((('┌││', '', '│└ '), ('┐││', '', '│┘ ')), (('┌││', '', '││└'), ('┐││', '', '││┘')), '', '', '\\', '/')}
ponypath=realpath(dirname(__file__)+'/ponies')
if not exists(ponypath):
ponypath=realpath(dirname(__file__)+'/../../ponies')
def list_ponies(markQuotes=False):
quotes = lambda n: ' (quotes)' if markQuotes and exists(ponypath+'/'+n+'.quotes') else ''
return [ f[:-5]+quotes(f[:-5]) for f in os.listdir(ponypath) if not f.endswith('quotes') ]
def list_ponies_with_quotes(markQuotes=False):
return [ f[:-7] for f in os.listdir(ponypath) if f.endswith('quotes') ]
def load_pony(name):
return open(ponypath+'/'+name+'.pony').readlines()
def random_quote(name):
quotepath=ponypath+'/'+name+'.quotes'
if exists(quotepath):
return random.choice(open(quotepath).read().split('\n\n'))
else:
return None
def render_balloon(text, balloonstyle, minwidth=0, maxwidth=40, pad=str.center):
if text is None:
return []
(oneline, multiline, bottom, top, linkl, linkr) = balloonstyle
lines = [ ' '+wrapline+' ' for textline in text.center(minwidth).split('\n') for wrapline in textwrap.wrap(textline, maxwidth) ]
width = max([ len(line) for line in lines ]+[minwidth])
side = lambda top, middle, bottom: top + middle*(len(lines)-2) + bottom
leftside, rightside = oneline if len(lines) == 1 else multiline
topextra, bottomextra = len(leftside[0])-2, len(leftside[2])-2
leftside, rightside = side(*leftside), side(*rightside)
lines = [top*width] + [' '*width]*topextra + [ pad(line, width) for line in lines ] + [' '*width]*bottomextra + [bottom*width]
return [ l+m+r for l,m,r in zip(leftside, lines, rightside) ]
def render_pony(name, text, balloonstyle, width=80, center=False, centertext=False):
pony = load_pony(name) #CAUTION: these lines already end with '\n'
balloon = link_l = link_r = ''
if text:
[link_l, link_r] = balloonstyle[-2:]
for i,line in enumerate(pony):
match = re.search('\$balloon([0-9]*)\$', line)
if match:
minwidth = int(match.group(1) or '0')
pony[i:i+1] = render_balloon(text, balloonstyle, minwidth=minwidth, maxwidth=int(width/2), pad=str.center if centertext else str.ljust)
break
try:
first = pony.index('$$$\n')
second = pony[first+1:].index('$$$\n')
pony[first:] = pony[first+1+second+1:]
except:
pass
pony = [ line.replace('$\\$', link_l).replace('$/$', link_r) for line in pony ]
indent = ''
if center:
ponywidth = max([ len(re.sub(r'\x1B\[[0-9;]+m|\$.*\$', '', line)) for line in pony ])
indent = ' '*int((width-ponywidth)/2)
wre = re.compile('((\x1B\[[0-9;]+m)*.){0,%s}' % width)
return ''.join([ indent+wre.search(line).group()+'\n' for line in pony ])