Skip to content

Commit

Permalink
Make Fabulous Python 2/3 compatible (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
jart authored Jul 12, 2016
1 parent d241f40 commit ddd6112
Show file tree
Hide file tree
Showing 30 changed files with 217 additions and 135 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ dist: trusty
python:
- 2.6
- 2.7
- 3.3
- 3.4
- 3.5
- pypy

addons:
Expand Down
4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
: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 source code is available at `github.com/jart/fabulous`_.

.. _github.com/jart/fabulous: https://github.com/jart/fabulous


Expand Down
6 changes: 3 additions & 3 deletions fabulous/casts.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def yes_no(value):
return True
if value.lower() in ('no','n'):
return False
raise ValueError, "value should be 'yes' or 'no'"
raise ValueError("value should be 'yes' or 'no'")


def file(value, **kwarg):
Expand All @@ -37,6 +37,6 @@ def file(value, **kwarg):
#a bit weird, but I don't want to hard code default values
try:
f = open(value, **kwarg)
except IOError, e:
raise ValueError, "unable to open %s : %s" % (path.abspath(value), e)
except IOError as e:
raise ValueError("unable to open %s : %s" % (path.abspath(value), e))
return f
15 changes: 11 additions & 4 deletions fabulous/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@
import sys
import functools

from fabulous.compatibility import printy
from fabulous import utils, xterm256, grapefruit

try:
unicode = unicode
except NameError:
unicode = str
basestring = (str, bytes)


OVERLINE = u'\u203e'

Expand Down Expand Up @@ -826,8 +833,8 @@ def h1(title, line=OVERLINE):
"""Prints bold text with line beneath it spanning width of terminal
"""
width = utils.term.width
print bold(title.center(width)).as_utf8
print bold((line * width)[:width]).as_utf8
printy(bold(title.center(width)).as_utf8)
printy(bold((line * width)[:width]).as_utf8)


def parse_color(color):
Expand Down Expand Up @@ -883,5 +890,5 @@ def section(title, bar=OVERLINE, strm=sys.stdout):
"""Helper function for testing demo routines
"""
width = utils.term.width
print >>strm, bold(title.center(width)).as_utf8
print >>strm, bold((bar * width)[:width]).as_utf8
printy(bold(title.center(width)))
printy(bold((bar * width)[:width]))
30 changes: 30 additions & 0 deletions fabulous/compatibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2016 The Fabulous Authors. All rights reserved.
#
# 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.

from __future__ import print_function

import sys


def printy(s):
"""Python 2/3 compatible print-like function"""
if hasattr(s, 'as_utf8'):
if hasattr(sys.stdout, 'buffer'):
sys.stdout.buffer.write(s.as_utf8)
sys.stdout.buffer.write(b"\n")
else:
sys.stdout.write(s.as_utf8)
sys.stdout.write(b"\n")
else:
print(s)
4 changes: 3 additions & 1 deletion fabulous/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"""

from __future__ import print_function

import sys
import itertools

Expand Down Expand Up @@ -59,7 +61,7 @@ def main():
"""
for imgpath in sys.argv[1:]:
for line in DebugImage(imgpath):
print line
print(line)


if __name__ == '__main__':
Expand Down
141 changes: 72 additions & 69 deletions fabulous/demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,27 @@
# limitations under the License.

import os
import fabulous
from fabulous.color import *

from fabulous import text, utils, image, debug, xterm256
from fabulous.color import *
from fabulous.compatibility import printy
import fabulous

try:
input = raw_input
except NameError:
pass


def wait():
raw_input("\nPress " + bold("enter") + " for more fun... ")
print ""
input("\nPress " + bold("enter") + " for more fun... ")
printy("")


def demo_image():
section("Semi-Transparent PNG")
imp = " from fabulous import image\n "
print bold(imp + 'print image.Image("balls.png")\n')
printy(bold(imp + 'print image.Image("balls.png")\n'))

balls = 'balls.png'
fabdir = os.path.dirname(fabulous.__file__)
Expand All @@ -45,78 +52,73 @@ def demo_image():
balls = 'balls.png'

for line in image.Image(balls):
print line
printy(line)
wait()

section("Yes the output is optimized (JELLY-FISH)")
imp = " from fabulous import debug\n "
print bold(imp + 'print debug.DebugImage("balls.png")\n')
printy(bold(imp + 'print debug.DebugImage("balls.png")\n'))
for line in debug.DebugImage(balls):
print line
printy(line)
wait()


def demo_text():
section('Fabulous Text Rendering')

imp = " from fabulous import text\n "
# print bold(imp + 'print text.Text("Fabulous")\n')
# print text.Text("Fabulous")
# wait()

print bold(imp + 'print text.Text("Fabulous", shadow=True, skew=5)\n')
print text.Text("Fabulous", shadow=True, skew=5)
printy(bold(imp + 'print text.Text("Fabulous", shadow=True, skew=5)\n'))
printy(text.Text("Fabulous", shadow=True, skew=5))
wait()


def demo_color_4bit():
section("Fabulous 4-Bit Colors")

print ("style(...): " +
bold("bold") +" "+
underline("underline") +" "+
flip("flip") +
" (YMMV: " + italic("italic") +" "+
underline2("underline2") +" "+
printy(("style(...): " +
bold("bold") +" "+
underline("underline") +" "+
flip("flip") +
" (YMMV: " + italic("italic") +" "+
underline2("underline2") +" "+
strike("strike") +" "+
blink("blink") + ")\n").as_utf8

print ("color(...) " +
black("black") +" "+
red("red") +" "+
green("green") +" "+
yellow("yellow") +" "+
blue("blue") +" "+
magenta("magenta") +" "+
cyan("cyan") +" "+
white("white")).as_utf8

print ("bold(color(...)) " +
bold(black("black") +" "+
red("red") +" "+
green("green") +" "+
yellow("yellow") +" "+
blue("blue") +" "+
magenta("magenta") +" "+
cyan("cyan") +" "+
white("white"))).as_utf8

print plain(
blink("blink") + ")\n"))

printy(("color(...) " +
black("black") +" "+
red("red") +" "+
green("green") +" "+
yellow("yellow") +" "+
blue("blue") +" "+
magenta("magenta") +" "+
cyan("cyan") +" "+
white("white")))

printy(("bold(color(...)) " +
bold(black("black") +" "+
red("red") +" "+
green("green") +" "+
yellow("yellow") +" "+
blue("blue") +" "+
magenta("magenta") +" "+
cyan("cyan") +" "+
white("white"))))

printy(plain(
'highlight_color(...) ',
highlight_black('black'), ' ', highlight_red('red'), ' ',
highlight_green('green'), ' ', highlight_yellow('yellow'), ' ',
highlight_blue('blue'), ' ', highlight_magenta('magenta'), ' ',
highlight_cyan('cyan'), ' ', highlight_white('white')).as_utf8

print ("bold(color_bg(...)) " +
bold(black_bg("black") +" "+
red_bg("red") +" "+
green_bg("green") +" "+
yellow_bg("yellow") +" "+
blue_bg("blue") +" "+
magenta_bg("magenta") +" "+
cyan_bg("cyan") +" "+
white_bg("white"))).as_utf8
highlight_cyan('cyan'), ' ', highlight_white('white')))

printy(("bold(color_bg(...)) " +
bold(black_bg("black") +" "+
red_bg("red") +" "+
green_bg("green") +" "+
yellow_bg("yellow") +" "+
blue_bg("blue") +" "+
magenta_bg("magenta") +" "+
cyan_bg("cyan") +" "+
white_bg("white"))))

wait()

Expand All @@ -133,19 +135,19 @@ def demo_color_8bit():
"highlight256('indigo', ' lorem ipsum ')",
"highlight256('orange', ' lorem ipsum ')",
"highlight256('orangered', ' lorem ipsum ')"]:
print "%-42s %s" % (code, eval(code))
print ''
printy("%-42s %s" % (code, eval(code)))
printy('')

# grayscales
line = " "
for xc in range(232, 256):
line += bg256(xc, ' ')
print line
printy(line)
line = " "
for xc in range(232, 256)[::-1]:
line += bg256(xc, ' ')
print line
print ''
printy(line)
printy('')

cube_color = lambda x,y,z: 16 + x + y*6 + z*6*6
for y in range(6):
Expand All @@ -154,7 +156,7 @@ def demo_color_8bit():
for x in range(6):
line += bg256(cube_color(x, y, z), ' ')
line += " "
print line.as_utf8
printy(line)

wait()

Expand All @@ -164,24 +166,24 @@ def full_chart():
line = " "
for xc in range(232, 256):
line += bg256(xc, ' ')
print line
printy(line)
line = " "
for xc in range(232, 256)[::-1]:
line += bg256(xc, ' ')
print line
print ''
printy(line)
printy('')

# cube
print ""
printy("")
cube_color = lambda x,y,z: 16 + x + y*6 + z*6*6
for y in range(6):
line = " "
for z in range(6):
for x in range(6):
line += bg256(cube_color(x, y, z), ' ')
line += " "
print line.as_utf8
print ""
printy(line)
printy("")

def f(xc):
s = highlight256(xc, "color %03d" % (xc))
Expand All @@ -200,14 +202,15 @@ def l(c1, c2):
half = width // 2
assert half > len(c1)
pad = " " * ((width // 2 - len(c1)) // 2)
print "%(pad)s%(c1)s%(pad)s%(pad)s%(c2)s" % {'pad': pad, 'c1': c1, 'c2': c2}
printy("%(pad)s%(c1)s%(pad)s%(pad)s%(c2)s" % {
'pad': pad, 'c1': c1, 'c2': c2})

width = utils.term.width
for z1, z2 in zip((0, 2, 4), (1, 3, 5)):
for y1, y2 in zip(range(6), range(6)):
for x1, x2 in zip(range(6), range(6)):
l(cube_color(x1, y1, z1), cube_color(x2, y2, z2))
print ""
printy("")


def main():
Expand Down
Loading

0 comments on commit ddd6112

Please sign in to comment.