Skip to content

Commit

Permalink
add support for named colors
Browse files Browse the repository at this point in the history
  • Loading branch information
Misterio77 committed Oct 23, 2021
1 parent 56a0627 commit 306f624
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
3 changes: 2 additions & 1 deletion docs/source/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ Color and displayname
---------------------

- You can set a color for each task list by creating a ``color`` file containing
a color code in the hex format: ``#RRGGBB``.
either a named ANSI color (such as ``red``, ``bright blue``, etc) or a color
code in hex format: ``#RRGGBB`` (the latter requires 24-bit color support).
- A file named ``displayname`` indicates how the task list should be named and
is needed when there are multiple directories sharing a name, e.g.: when using
multiple $CloudInstances. The default is the directory name.
Expand Down
16 changes: 9 additions & 7 deletions tests/test_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from tests.helpers import pyicu_sensitive
from todoman.cli import cli
from todoman.formatters import rgb_to_ansi
from todoman.formatters import colour_to_ansi


@pyicu_sensitive
Expand Down Expand Up @@ -155,12 +155,14 @@ def test_formatting_parsing_consitency(default_formatter):
assert default_formatter.parse_datetime(formatted) == dt


def test_rgb_to_ansi():
assert rgb_to_ansi(None) is None
assert rgb_to_ansi("#8ab6d") is None
assert rgb_to_ansi("#8ab6d2f") == "\x1b[38;2;138;182;210m"
assert rgb_to_ansi("red") is None
assert rgb_to_ansi("#8ab6d2") == "\x1b[38;2;138;182;210m"
def test_colour_to_ansi():
assert colour_to_ansi(None) is None
assert colour_to_ansi("#8ab6d") is None
assert colour_to_ansi("#8ab6d2f") == "\x1b[38;2;138;182;210m"
assert colour_to_ansi("#8ab6d2") == "\x1b[38;2;138;182;210m"
assert colour_to_ansi("red") == "\x1b[31m"
assert colour_to_ansi("bright cyan") == "\x1b[36;1m"
assert colour_to_ansi("salmon") is None


def test_format_multiple_with_list(default_formatter, todo_factory):
Expand Down
30 changes: 26 additions & 4 deletions todoman/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
from todoman.model import TodoList


def rgb_to_ansi(colour: Optional[str]) -> Optional[str]:
def rgb_to_ansi(colour: str) -> Optional[str]:
"""
Convert a string containing an RGB colour to ANSI escapes
"""
if not colour or not colour.startswith("#"):
return None

r, g, b = colour[1:3], colour[3:5], colour[5:7]

Expand All @@ -34,6 +32,30 @@ def rgb_to_ansi(colour: Optional[str]) -> Optional[str]:
return f"\33[38;2;{int(r, 16)!s};{int(g, 16)!s};{int(b, 16)!s}m"


def colour_to_ansi(colour: Optional[str]) -> Optional[str]:
"""
Convert a string containing a colour (either RGB or a standard colour name)
"""
if not colour:
return None
if colour.startswith("#"):
return rgb_to_ansi(colour)

bright = "bright" in colour

colour = colour.replace("bright ", "")

colours = ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"]

try:
ansi_number = colours.index(colour)
except ValueError:
return None

suffix = ";1" if bright else ""
return f"\33[3{ansi_number}{suffix}m"


class DefaultFormatter:
def __init__(
self,
Expand Down Expand Up @@ -227,7 +249,7 @@ def _parse_datetime_naive(self, dt: str) -> date:

def format_database(self, database: TodoList):
return "{}@{}".format(
rgb_to_ansi(database.colour) or "", click.style(database.name)
colour_to_ansi(database.colour) or "", click.style(database.name)
)


Expand Down

0 comments on commit 306f624

Please sign in to comment.