summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Rose <erik@mozilla.com>2011-11-16 16:10:08 -0800
committerErik Rose <erik@mozilla.com>2011-11-16 16:17:48 -0800
commit163838a93f4a4fac40ab881b6691bb1cecb6e898 (patch)
treecc3bef8c89581ec6dca2ad2242c595feb50c752d
parentd739af35d4fe4f40df8aa43ca70aa59e87863d2d (diff)
downloadblessings-163838a93f4a4fac40ab881b6691bb1cecb6e898.tar.gz
Fix simple formatting attributes not working as wrappers.
-rw-r--r--blessings/__init__.py65
-rw-r--r--blessings/tests.py2
2 files changed, 36 insertions, 31 deletions
diff --git a/blessings/__init__.py b/blessings/__init__.py
index 1a4eee4..548d5b8 100644
--- a/blessings/__init__.py
+++ b/blessings/__init__.py
@@ -170,41 +170,26 @@ class Terminal(object):
def _resolve_formatter(self, attr):
"""Resolve a sugary or plain capability name, color, or compound formatting function name into a callable string."""
- def split_into_formatters(compound):
- """Split a possibly compound format string into segments.
-
- >>> split_into_formatters('bold_underline_bright_blue_on_red')
- ['bold', 'underline', 'bright_blue', 'on_red']
-
- """
- merged_segs = []
- # These occur only as prefixes, so they can always be merged:
- mergeable_prefixes = ['on', 'bright', 'on_bright']
- for s in compound.split('_'):
- if merged_segs and merged_segs[-1] in mergeable_prefixes:
- merged_segs[-1] += '_' + s
- else:
- merged_segs.append(s)
- return merged_segs
-
- if attr in colors:
+ if attr in COLORS:
return self._resolve_color(attr)
+ elif attr in COMPOUNDABLES:
+ # Bold, underline, or something that takes no parameters
+ return FormattingString(self._resolve_capability(attr), self)
else:
formatters = split_into_formatters(attr)
- if len(formatters) > 1 and all(f in compoundables for f in formatters):
- # It's a compound formatter, like "bold_green_on_red". If we
- # wanted, we could even get crazy and combine all formatting
- # into a single escape sequence, but nobody's on a 300 baud
- # modem anymore.
+ if all(f in COMPOUNDABLES for f in formatters):
+ # It's a compound formatter, like "bold_green_on_red". Future
+ # optimization: combine all formatting into a single escape
+ # sequence
return FormattingString(''.join(self._resolve_formatter(s)
for s in formatters),
self)
else:
- return self._resolve_capability(attr)
+ return ParametrizingString(self._resolve_capability(attr))
def _resolve_capability(self, atom):
"""Return a terminal code for a capname or a sugary name, or ''."""
- return ParametrizingString(tigetstr(self._sugar.get(atom, atom)) or '')
+ return tigetstr(self._sugar.get(atom, atom)) or ''
def _resolve_color(self, color):
"""Resolve a color like red or on_bright_green into a callable string."""
@@ -223,12 +208,12 @@ class Terminal(object):
self)
-colors = set(['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'])
-colors.update(set([('on_' + c) for c in colors] +
- [('bright_' + c) for c in colors] +
- [('on_bright_' + c) for c in colors]))
+COLORS = set(['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'])
+COLORS.update(set([('on_' + c) for c in COLORS] +
+ [('bright_' + c) for c in COLORS] +
+ [('on_bright_' + c) for c in COLORS]))
del c
-compoundables = (colors |
+COMPOUNDABLES = (COLORS |
set(['bold', 'underline', 'reverse', 'blink', 'dim', 'italic',
'shadow', 'standout', 'subscript', 'superscript']))
@@ -279,7 +264,7 @@ class FormattingString(str):
class NullCallableString(str):
- """A callable string that returns '' when called with an int and itself when called otherwise."""
+ """A callable string that returns '' when called with an int and the arg otherwise."""
def __call__(self, arg):
if isinstance(arg, int):
return ''
@@ -299,6 +284,24 @@ def height_and_width():
return struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0:2]
+def split_into_formatters(compound):
+ """Split a possibly compound format string into segments.
+
+ >>> split_into_formatters('bold_underline_bright_blue_on_red')
+ ['bold', 'underline', 'bright_blue', 'on_red']
+
+ """
+ merged_segs = []
+ # These occur only as prefixes, so they can always be merged:
+ mergeable_prefixes = ['on', 'bright', 'on_bright']
+ for s in compound.split('_'):
+ if merged_segs and merged_segs[-1] in mergeable_prefixes:
+ merged_segs[-1] += '_' + s
+ else:
+ merged_segs.append(s)
+ return merged_segs
+
+
class Location(object):
"""Context manager for temporarily moving the cursor
diff --git a/blessings/tests.py b/blessings/tests.py
index 8d7508a..d9e7d85 100644
--- a/blessings/tests.py
+++ b/blessings/tests.py
@@ -104,6 +104,7 @@ def test_mnemonic_colors():
def test_formatting_functions():
"""Test crazy-ass formatting wrappers, both simple and compound."""
t = Terminal()
+ eq_(t.bold('hi'), t.bold + 'hi' + t.normal)
eq_(t.green('hi'), t.green + 'hi' + t.normal)
eq_(t.bold_green(u'boö'), t.bold + t.green + u'boö' + t.normal) # unicode
eq_(t.bold_underline_green_on_red('boo'),
@@ -116,6 +117,7 @@ def test_formatting_functions():
def test_formatting_functions_without_tty():
"""Test crazy-ass formatting wrappers when there's no tty."""
t = Terminal(stream=StringIO())
+ eq_(t.bold('hi'), 'hi')
eq_(t.green('hi'), 'hi')
eq_(t.bold_green(u'boö'), u'boö') # unicode
eq_(t.bold_underline_green_on_red('boo'), 'boo')