diff --git a/Makefile b/Makefile
index ab5a324..a589117 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
-.PHONY: install install-lib phony
+.PHONY: install install-lib phony test
WEECHAT_HOME ?= $(HOME)/.weechat
PREFIX ?= $(WEECHAT_HOME)
+PYTHON ?= python
lib := $(patsubst matrix/%.py, $(DESTDIR)$(PREFIX)/python/matrix/%.py, \
$(wildcard matrix/*.py))
@@ -15,3 +16,6 @@ phony:
$(DESTDIR)$(PREFIX)/python/matrix/%.py: matrix/%.py phony
install -Dm644 $< $@
+
+test:
+ $(PYTHON) -m pytest
diff --git a/matrix/_weechat.py b/matrix/_weechat.py
new file mode 100644
index 0000000..d207ce7
--- /dev/null
+++ b/matrix/_weechat.py
@@ -0,0 +1,93 @@
+def color(color_name):
+ # type: (str) -> str
+ # yapf: disable
+ weechat_base_colors = {
+ "black": "0",
+ "red": "1",
+ "green": "2",
+ "brown": "3",
+ "blue": "4",
+ "magenta": "5",
+ "cyan": "6",
+ "default": "7",
+ "gray": "8",
+ "lightred": "9",
+ "lightgreen": "10",
+ "yellow": "11",
+ "lightblue": "12",
+ "lightmagenta": "13",
+ "lightcyan": "14",
+ "white": "15"
+ }
+
+ escape_codes = []
+ reset_code = "0"
+
+ def make_fg_color(color):
+ return "38;5;{}".format(color)
+
+ def make_bg_color(color):
+ return "48;5;{}".format(color)
+
+ attributes = {
+ "bold": "1",
+ "-bold": "21",
+ "reverse": "27",
+ "-reverse": "21",
+ "italic": "3",
+ "-italic": "23",
+ "underline": "4",
+ "-underline": "24",
+ "reset": "0",
+ "resetcolor": "39"
+ }
+
+ short_attributes = {
+ "*": "1",
+ "!": "27",
+ "/": "3",
+ "_": "4"
+ }
+
+ colors = color_name.split(",", 2)
+
+ fg_color = colors.pop(0)
+
+ bg_color = colors.pop(0) if colors else ""
+
+ if fg_color in attributes:
+ escape_codes.append(attributes[fg_color])
+ else:
+ chars = list(fg_color)
+
+ for char in chars:
+ if char in short_attributes:
+ escape_codes.append(short_attributes[char])
+ elif char == "|":
+ reset_code = ""
+ else:
+ break
+
+ stripped_color = fg_color.lstrip("*_|/!")
+
+ if stripped_color in weechat_base_colors:
+ escape_codes.append(
+ make_fg_color(weechat_base_colors[stripped_color]))
+
+ elif stripped_color.isdecimal():
+ num_color = int(stripped_color)
+ if num_color >= 0 and num_color < 256:
+ escape_codes.append(make_fg_color(stripped_color))
+
+
+ if bg_color in weechat_base_colors:
+ escape_codes.append(make_bg_color(weechat_base_colors[bg_color]))
+ else:
+ if bg_color.isdecimal():
+ num_color = int(bg_color)
+ if num_color >= 0 and num_color < 256:
+ escape_codes.append(make_bg_color(bg_color))
+
+ escape_string = "\033[{}{}m".format(reset_code, ";".join(escape_codes))
+
+ return escape_string
diff --git a/matrix/colors.py b/matrix/colors.py
index 21ed444..4c83f31 100644
--- a/matrix/colors.py
+++ b/matrix/colors.py
@@ -542,23 +542,26 @@ def colour_find_rgb(r, g, b):
def color_html_to_weechat(color):
# type: (str) -> str
+ # yapf: disable
first_16 = {
- (0, 0, 0): "black", # 0
- (128, 0, 0): "red", # 1
- (0, 128, 0): "green", # 2
- (128, 128, 0): "brown", # 3
- (0, 0, 128): "blue", # 4
- (128, 0, 128): "magenta", # 5
- (0, 128, 128): "cyan", # 6
- (192, 192, 192): "default", # 7
- (128, 128, 128): "gray", # 8
- (255, 0, 0): "lightred", # 9
- (0, 255, 0): "lightgreen", # 11
- (255, 255, 0): "yellow", # 12
- (0, 0, 255): "lightblue", # 13
- (255, 0, 255): "lightmagenta", # 14
- (0, 255, 255): "lightcyan", # 15
+ (0, 0, 0): "black", # 0
+ (128, 0, 0): "red", # 1
+ (0, 128, 0): "green", # 2
+ (128, 128, 0): "brown", # 3
+ (0, 0, 128): "blue", # 4
+ (128, 0, 128): "magenta", # 5
+ (0, 128, 128): "cyan", # 6
+ (192, 192, 192): "default", # 7
+ (128, 128, 128): "gray", # 8
+ (255, 0, 0): "lightred", # 9
+ (0, 255, 0): "lightgreen", # 10
+ (255, 255, 0): "yellow", # 11
+ (0, 0, 255): "lightblue", # 12
+ (255, 0, 255): "lightmagenta", # 13
+ (0, 255, 255): "lightcyan", # 14
+ (255, 255, 255): "white", # 15
}
+ # yapf: enable
try:
rgb_color = webcolors.html5_parse_legacy_color(color)
@@ -573,24 +576,25 @@ def color_html_to_weechat(color):
def color_weechat_to_html(color):
# type: (str) -> str
+ # yapf: disable
first_16 = {
- "black": "black", # 0
- "red": "maroon", # 1
- "green": "green", # 2
- "brown": "olive", # 3
- "blue": "navy", # 4
- "magenta": "purple", # 5
- "cyan": "teal", # 6
- "default": "silver", # 7
- "gray": "grey", # 8
- "lightred": "red", # 9
- "lightgreen": "lime", # 11
- "yellow": "yellow", # 12
- "lightblue": "fuchsia", # 13
- "lightmagenta": "aqua", # 14
- "lightcyan": "white", # 15
+ "black": "black", # 0
+ "red": "maroon", # 1
+ "green": "green", # 2
+ "brown": "olive", # 3
+ "blue": "navy", # 4
+ "magenta": "purple", # 5
+ "cyan": "teal", # 6
+ "default": "silver", # 7
+ "gray": "gray", # 8
+ "lightred": "red", # 9
+ "lightgreen": "lime", # 11
+ "yellow": "yellow", # 12
+ "lightblue": "blue", # 13
+ "lightmagenta": "fuchsia", # 14
+ "lightcyan": "aqua", # 15
+ "white": "white", # 15
}
- #yapf: disable
hex_colors = {
"0": "#000000",
"1": "#800000",
diff --git a/matrix/globals.py b/matrix/globals.py
index c3e15fa..9c125b7 100644
--- a/matrix/globals.py
+++ b/matrix/globals.py
@@ -21,9 +21,12 @@ import sys
from matrix.utf import WeechatWrapper
from matrix.plugin_options import PluginOptions
-import weechat
-
-W = weechat if sys.hexversion >= 0x3000000 else WeechatWrapper(weechat)
+try:
+ import weechat
+ W = weechat if sys.hexversion >= 0x3000000 else WeechatWrapper(weechat)
+except ImportError:
+ import matrix._weechat as weechat
+ W = weechat
OPTIONS = PluginOptions() # type: PluginOptions
SERVERS = dict() # type: Dict[str, MatrixServer]
diff --git a/tests/color_test.py b/tests/color_test.py
new file mode 100644
index 0000000..73772a8
--- /dev/null
+++ b/tests/color_test.py
@@ -0,0 +1,26 @@
+import webcolors
+from hypothesis import given
+from hypothesis.strategies import sampled_from
+
+from matrix.colors import (Formatted, color_html_to_weechat,
+ color_weechat_to_html)
+
+html_prism = ("Test")
+
+weechat_prism = (
+ u"\x1b[038;5;1mT\x1b[039m\x1b[038;5;9me\x1b[039m\x1b[038;5;3ms\x1b[039m\x1b[038;5;11mt\x1b[039m"
+)
+
+first_16_html_colors = list(webcolors.HTML4_HEX_TO_NAMES.values())
+
+
+def test_prism():
+ formatted = Formatted.from_html(html_prism)
+ assert formatted.to_weechat() == weechat_prism
+
+
+@given(sampled_from(first_16_html_colors))
+def test_color_conversion(color_name):
+ assert color_weechat_to_html(
+ color_html_to_weechat(color_name)) == color_name