-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #24: Output colors with say #27
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! The code generally looks good.
@@ -6,6 +6,7 @@ | |||
except ImportError: | |||
pass | |||
import textwrap | |||
import font_styles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately it's a strong goal to avoid requiring additional files. As the README says,
adventurelib.py
is a single file that can be copied into your project.
Several teachers told me how valuable it is to have this property (for as long as it is achievable).
I'm happy for the adventurelib.py file to grow to be pretty huge before I think splitting it is justified.
@@ -536,7 +537,7 @@ def start(help=True): | |||
_handle_command(cmd) | |||
|
|||
|
|||
def say(msg): | |||
def say(msg, fg='default', bg='default'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend making fg
and bg
into keyword-only arguments. This means you don't have to remember which way round it is when you see code like
say(..., 'yellow', 'black')
@@ -0,0 +1,51 @@ | |||
TEXT_WHITE = '\u001b[37;1m' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These colour codes do not work on Windows. Colorama is a package that can translate the codes to Windows - but again, adventurelib
has a goal to be one file, no dependencies, so we would have to include the translation table here.
@@ -0,0 +1,51 @@ | |||
TEXT_WHITE = '\u001b[37;1m' | |||
TEXT_BLACK = '\u001b[30;1m' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ;1
will mean that the text is both coloured and also bold - is that what you intended? I would do what it says on the tin and only do colour; boldness could be added later.
@@ -188,7 +188,7 @@ def test_say_room(): | |||
buf = StringIO() | |||
with redirect_stdout(buf): | |||
say(r) | |||
assert buf.getvalue() == 'You are standing in a hallway.\n' | |||
assert buf.getvalue() == 'You are standing in a hallway.' + u'\u001b[0m\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to update these tests; just avoid emitting the reset code unless a foreground or background color has been set.
buf = StringIO() | ||
with redirect_stdout(buf): | ||
say(r, 'yellow', 'cyan') | ||
assert buf.getvalue() == '\u001b[33;1m\u001b[46;1mYou are standing ' \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally I'd like to see it just emit \x1b[33;46m
rather than two sequences. I guess there's no practical implications to that, it just seems more parsimonious.
BG_WHITE = '\u001b[47;1m' | ||
BG_BLACK = '\u001b[40;1m' | ||
BG_RED = '\u001b[41;1m' | ||
BG_BLUE = '\u001b[44;1m' | ||
BG_CYAN = '\u001b[46;1m' | ||
BG_MAGENTA = '\u001b[45;1m' | ||
BG_GREEN = '\u001b[42;1m' | ||
BG_YELLOW = '\u001b[43;1m' | ||
|
||
RESET = '\u001b[0m' | ||
|
||
|
||
def text_color(option): | ||
switcher = { | ||
'white': TEXT_WHITE, | ||
'black': TEXT_BLACK, | ||
'red': TEXT_RED, | ||
'blue': TEXT_BLUE, | ||
'cyan': TEXT_CYAN, | ||
'magenta': TEXT_MAGENTA, | ||
'green': TEXT_GREEN, | ||
'yellow': TEXT_YELLOW | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a fair amount of redundancy here that can be eliminated - just make the global table a mapping from color name to code, eg.
FG_COLORS = {
'white': 37,
'red': 31,
...
}
and make text_color()
build the code:
return '\x1b[{}m'.format(FG_COLORS[option])
'yellow': TEXT_YELLOW | ||
} | ||
|
||
return switcher.get(option, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you will silently return no colour code for what is a programming error (an invalid colour name). You should always raise an exception in this case. As the Zen of Python says,
Errors should never pass silently.
Added
say
output coloring. It is now possible to change font color and text background color.The following color options have been implemented both for font and background:
Tests have been adjusted.
Closes #24