Xqt has submitted this change and it was merged.
Change subject: Add background colors and a script to show color combinations (colors.py)
......................................................................
Add background colors and a script to show color combinations (colors.py)
Modify background colors support introduced in:
59e9544e68bc77ee9545d317bac4bc94f813259b
No backward compatibility considered, as unlikely someone as used it yet.
Modify tool._ColorFormatter to support background colors.
Add utility to show possible background/foreground combinations, in
preparation for possibility for user to select default use.
Bug: T135984
Change-Id: Iecb648176b41c9ea3a2cc4ce879526f20d75bfde
---
M pywikibot/diff.py
M pywikibot/tools/formatter.py
M pywikibot/userinterfaces/terminal_interface_base.py
M pywikibot/userinterfaces/terminal_interface_unix.py
M pywikibot/userinterfaces/terminal_interface_win32.py
A scripts/maintenance/colors.py
M tests/tools_formatter_tests.py
M tests/ui_tests.py
8 files changed, 95 insertions(+), 15 deletions(-)
Approvals:
Xqt: Looks good to me, approved
Merlijn van Deen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/diff.py b/pywikibot/diff.py
index 6ea3acd..4a1872c 100644
--- a/pywikibot/diff.py
+++ b/pywikibot/diff.py
@@ -59,8 +59,8 @@
'-': 'lightred',
}
self.bg_colors = {
- '+': 'Blightgreen',
- '-': 'Blightred',
+ '+': 'lightgreen',
+ '-': 'lightred',
}
self.diff = list(self.create_diff())
@@ -187,7 +187,7 @@
if char != ' ':
apply_color = self.colors[color]
else:
- apply_color = self.bg_colors[color]
+ apply_color = 'default;' + self.bg_colors[color]
char_tagged = color_format('{color}{0}',
char, color=apply_color)
color_closed = False
diff --git a/pywikibot/tools/formatter.py b/pywikibot/tools/formatter.py
index a571ee4..c53d80a 100644
--- a/pywikibot/tools/formatter.py
+++ b/pywikibot/tools/formatter.py
@@ -68,6 +68,9 @@
"""Special string formatter which skips colors."""
colors = set(colors)
+ # Dot.product of colors to create all possible combinations of foreground
+ # and background colors.
+ colors |= set(['%s;%s' % (c1, c2) for c1 in colors for c2 in colors])
def __init__(self):
"""Create new instance and store the stack
depth."""
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py
b/pywikibot/userinterfaces/terminal_interface_base.py
index 3cda2cf..bb30c1c 100755
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -47,11 +47,10 @@
'lightpurple',
'lightyellow',
'white',
- 'Blightgreen',
- 'Blightred',
]
-colorTagR = re.compile('\03{(?P<name>%s|previous)}' %
'|'.join(colors))
+_color_pat = '%s|previous' % '|'.join(colors)
+colorTagR = re.compile('\03{((:?%s);?(:?%s)?)}' % (_color_pat, _color_pat))
if __debug__ and not PY2:
raw_input = NotImplemented # pyflakes workaround
@@ -60,6 +59,8 @@
class UI(object):
"""Base for terminal user interfaces."""
+
+ split_col_pat = re.compile('(\w+);?(\w+)?')
def __init__(self):
"""
@@ -127,6 +128,17 @@
raise NotImplementedError('The {0} class does not support '
'colors.'.format(self.__class__.__name__))
+ @classmethod
+ def divide_color(cls, color):
+ """
+ Split color label in a tuple.
+
+ Received color is a string like 'fg_color;bg_color' or
'fg_color'.
+ Returned values are (fg_color, bg_color) or (fg_color, None).
+
+ """
+ return cls.split_col_pat.search(color).groups()
+
def _write(self, text, target_stream):
"""Optionally encode and write the text to the target
stream."""
if PY2:
@@ -145,8 +157,11 @@
# Therefore we need this stack.
color_stack = ['default']
text_parts = colorTagR.split(text) + ['default']
- for index, (text, next_color) in enumerate(zip(text_parts[::2],
- text_parts[1::2])):
+ # match.split() includes every regex group; for each matched color
+ # fg_col:b_col, fg_col and bg_col are added to the resulting list.
+ len_text_parts = len(text_parts[::4])
+ for index, (text, next_color) in enumerate(zip(text_parts[::4],
+ text_parts[1::4])):
current_color = color_stack[-1]
if next_color == 'previous':
if len(color_stack) > 1: # keep the last element in the stack
@@ -161,7 +176,7 @@
if '\n' in text: # Normal end of line
text = text.replace('\n', ' ***\n', 1)
colored_line = False
- elif index == len(text_parts) // 2 - 1: # Or end of text
+ elif index == len_text_parts - 1: # Or end of text
text += ' ***'
colored_line = False
diff --git a/pywikibot/userinterfaces/terminal_interface_unix.py
b/pywikibot/userinterfaces/terminal_interface_unix.py
index 9f37d58..789f319 100755
--- a/pywikibot/userinterfaces/terminal_interface_unix.py
+++ b/pywikibot/userinterfaces/terminal_interface_unix.py
@@ -9,6 +9,7 @@
__version__ = '$Id$'
+import re
import sys
from pywikibot.userinterfaces import terminal_interface_base
@@ -31,8 +32,6 @@
'lightpurple': chr(27) + '[95m', # Light Purple tag (Magenta)
'lightaqua': chr(27) + '[96m', # Light Aqua tag (Cyan)
'white': chr(27) + '[97m', # White start tag (Bright White)
- 'Blightgreen': chr(27) + '[102m', # Background Light Red tag
- 'Blightred': chr(27) + '[101m', # Background Light Green tag
}
@@ -44,9 +43,19 @@
"""Return that the target stream supports
colors."""
return True
+ def make_unix_bg_color(self, color):
+ """Obtain background color from foreground
color."""
+ code = re.search('(?<=\[)\d+', color).group()
+ return chr(27) + '[' + str(int(code) + 10) + 'm'
+
def encounter_color(self, color, target_stream):
"""Write the unix color directly to the stream."""
- self._write(unixColors[color], target_stream)
+ fg, bg = self.divide_color(color)
+ fg = unixColors[fg]
+ self._write(fg, target_stream)
+ if bg is not None:
+ bg = unixColors[bg]
+ self._write(self.make_unix_bg_color(bg), target_stream)
def _write(self, text, target_stream):
"""Optionally encode and write the text to the target
stream."""
diff --git a/pywikibot/userinterfaces/terminal_interface_win32.py
b/pywikibot/userinterfaces/terminal_interface_win32.py
index 7c3ed10..c2b0299 100755
--- a/pywikibot/userinterfaces/terminal_interface_win32.py
+++ b/pywikibot/userinterfaces/terminal_interface_win32.py
@@ -38,8 +38,6 @@
'lightpurple': 13,
'lightyellow': 14,
'white': 15,
- 'Blightgreen': 32, # background color green.
- 'Blightred': 64, # background color red.
}
@@ -74,8 +72,13 @@
def encounter_color(self, color, target_stream):
"""Set the new color."""
+ fg, bg = self.divide_color(color)
+ windows_color = windowsColors[fg]
+ # Merge foreground/backgroung color if needed.
+ if bg is not None:
+ windows_color = windowsColors[bg] << 4 | windows_color
ctypes.windll.kernel32.SetConsoleTextAttribute(
- target_stream._hConsole, windowsColors[color])
+ target_stream._hConsole, windows_color)
def _raw_input(self):
data = self.stdin.readline()
diff --git a/scripts/maintenance/colors.py b/scripts/maintenance/colors.py
new file mode 100644
index 0000000..b388e75
--- /dev/null
+++ b/scripts/maintenance/colors.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""Utility to show pywikibot colors."""
+#
+# (C) Pywikibot team, 2016
+#
+# Distributed under the terms of the MIT license.
+#
+from __future__ import absolute_import, unicode_literals
+
+import pywikibot
+
+from pywikibot.tools.formatter import color_format
+from pywikibot.tools import itergroup
+from pywikibot.userinterfaces.terminal_interface_base import colors as colors
+
+
+def main():
+ """Main function."""
+ fg_colors = [col for col in colors if col != 'default']
+ bg_colors = fg_colors[:]
+ n_fg_colors = len(fg_colors)
+ fg_colors.insert(3 * int(n_fg_colors / 4), 'default')
+ fg_colors.insert(2 * int(n_fg_colors / 4), 'default')
+ fg_colors.insert(int(n_fg_colors / 4), 'default')
+ fg_colors.insert(0, 'default')
+
+ # Max len of color names for padding.
+ max_len_fg_colors = len(max(fg_colors, key=len))
+ max_len_bc_color = len(max(bg_colors, key=len))
+
+ for bg_col in bg_colors:
+ # Three lines per each backgoung color.
+ for fg_col_group in itergroup(fg_colors, n_fg_colors / 4 + 1):
+ line = ''
+ for fg_col in fg_col_group:
+ line += ' '
+ line += color_format('{color}{0}{default}',
+ fg_col.ljust(max_len_fg_colors),
+ color='%s;%s' % (fg_col, bg_col))
+
+ line = '{0} {1}'.format(bg_col.ljust(max_len_bc_color), line)
+ pywikibot.output(line)
+
+ pywikibot.output('')
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/tools_formatter_tests.py b/tests/tools_formatter_tests.py
index 73a377b..21de181 100644
--- a/tests/tools_formatter_tests.py
+++ b/tests/tools_formatter_tests.py
@@ -32,6 +32,7 @@
self.assertEqual(outputter.format_list(), '\nfoo\nbar\n')
+# TODO: add tests for background colors.
class TestColorFormat(TestCase):
"""Test color_format function in bot module."""
diff --git a/tests/ui_tests.py b/tests/ui_tests.py
index 7dbf363..bbb9de7 100644
--- a/tests/ui_tests.py
+++ b/tests/ui_tests.py
@@ -689,6 +689,7 @@
self.assertEqual(lines, [u'Alpha', u'Bετα', u'Гамма',
u'دلتا', u''])
+# TODO: add tests for background colors.
class FakeUITest(TestCase):
"""Test case to allow doing uncolorized general UI
tests."""
--
To view, visit
https://gerrit.wikimedia.org/r/291571
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Iecb648176b41c9ea3a2cc4ce879526f20d75bfde
Gerrit-PatchSet: 14
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>