Skip to content

Instantly share code, notes, and snippets.

@e000
Created June 23, 2012 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save e000/2976037 to your computer and use it in GitHub Desktop.
Save e000/2976037 to your computer and use it in GitHub Desktop.
"""
Matix Gen, by <venuism>, rewritten by <e>
"""
from itertools import groupby, cycle
from font import ascii_dict as d_ascii_dict
from random import sample
safe_format = '\x03%i,%02i%s'
unsafe_format = '\x03%i,%i%s'
class matixgen:
def __init__(self, ascii_dict = d_ascii_dict):
self.ascii_dict = ascii_dict
def filterChars(self, chars):
return [char for char in chars if char in self.ascii_dict]
def getWidest(self, chars):
return max(self.ascii_dict[char][0] for char in chars)
@staticmethod
def padToWidest(cw, ascii, widest):
r = (widest - cw) / 2
l = (widest - cw) - r
for line in ascii:
if len(line) == 1:
yield (line[0][0], line[0][1] + (l + r)),
else:
s, e = line[0], line[-1]
yield ((s[0], s[1] + l),) + line[1:-1] + ((e[0], e[1] + r,),)
@staticmethod
def scaleUpwards(ascii, scale):
for line in ascii:
line = [(k , v * scale) for k, v in line]
for i in xrange(scale):
yield line
def render(self, text, bg = None, fill = None, scale = 1, outline_color = 1):
"""
Returns an iterator that iterates over the lines of the rendered content!
"""
ascii_dict = self.ascii_dict
text = self.filterChars(text)
width = self.getWidest(text)
fill, bg = fill or self.rainbow(), bg or self.rainbow()
rainbow_iterator = cycle(xrange(12)).next
for char in text:
cw, ascii = ascii_dict[char]
if cw < width:
ascii = matixgen.padToWidest(cw, ascii, width)
if scale > 1:
ascii = matixgen.scaleUpwards(ascii, scale)
for line in self._transform(ascii, char, fill, bg, rainbow_iterator, outline_color):
yield line
@staticmethod
def _transform(ascii, char, fill, bg, rz, oc = 1):
digi = char.isdigit()
fmt = (safe_format if digi else unsafe_format)
for line in ascii:
offset, z, Y = 0, [], rz()
a = z.append
for k, l in line:
if k == 1:
a(''.join(bg((':', '::'), l, offset & 1, digi, Y)))
elif k == 2:
a(''.join(fill(('.', '..'), l, offset & 1, digi, Y)))
elif k == 3:
a(fmt % (oc, oc, char * l))
Y += (l+(l & 1))/2
if offset & 1 == 0 and l & 1:
Y -= 1
offset += l
yield ''.join(z)
@staticmethod
def rainbow(rbc = (4,7,8,9,3,10,11,12,2,6,13,5)):
""" Fills with rainbow blocks """
l = len(rbc)
def _rainbow(char, length, offset, digi, Y):
if offset:
length -= 1
color = rbc[Y % l]
Y += 1
if length == 0:
yield (safe_format if digi else unsafe_format) % (color, color, char[0])
else:
yield unsafe_format % (color, color, char[0])
while length > 0:
color = rbc[Y % l]
Y += 1
length -= 2
r = 0 if length < 0 else 1
if length == 0:
yield (safe_format if digi else unsafe_format) % (color, color, char[r])
else:
yield unsafe_format % (color, color, char[r])
return _rainbow
@staticmethod
def checker(colors = None):
""" Fills with checker blocks """
colors = tuple(colors or sample(xrange(15), 2))
assert len(colors) == 2 and isinstance(colors, tuple)
def _checker(char, length, offset, digi, Y):
if offset:
length -= 1
color = colors[Y & 1]
Y += 1
if length == 0:
yield (safe_format if digi else unsafe_format) % (color, color, char[0])
else:
yield unsafe_format % (color, color, char[0])
while length > 0:
color = colors[Y & 1]
Y += 1
length -= 2
r = 0 if length < 0 else 1
if length == 0:
yield (safe_format if digi else unsafe_format) % (color, color, char[r])
else:
yield unsafe_format % (color, color, char[r])
return _checker
@staticmethod
def solid(color):
""" Fills with a solid color """
def _solid(char, length, offset, digi, Y):
yield unsafe_format % (color, color, char[0] * length)
return _solid
if __name__ == '__main__':
m = matixgen()
print '\n'.join(m.render('hello', scale=2, bg = m.checker(), fill=m.rainbow()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment