diff --git a/fastcore/style.py b/fastcore/style.py index 65112ffd..59aabcf2 100644 --- a/fastcore/style.py +++ b/fastcore/style.py @@ -8,7 +8,7 @@ _base = 'red green yellow blue magenta cyan' _regular = f'black {_base} light_gray' _intense = 'dark_gray ' + ' '.join('light_'+o for o in _base.split()) + ' white' -_fmt = dict(bold=1,dim=2,underline=4,reverse=7,hidden=8) +_fmt = 'bold dim italic underline blink invert hidden strikethrough' # %% ../nbs/10_style.ipynb 4 class StyleCode: @@ -30,8 +30,9 @@ def _mk_codes(s, start, typ, fmt=None, **kwargs): **_mk_codes(_intense, 90, 'fg'), **_mk_codes(_regular, 40, 'bg', '{}_bg', default_bg=49), **_mk_codes(_intense, 100, 'bg', '{}_bg'), - **_mk_codes(_fmt, 0, 'fmt'), + **_mk_codes(_fmt, 1, 'fmt'), **_mk_codes(_fmt, 21, 'reset', 'reset_{}', reset=0, reset_bold=22)} +style_codes = {k:v for k,v in style_codes.items() if '' not in k} # %% ../nbs/10_style.ipynb 9 def _reset_code(s): @@ -44,10 +45,12 @@ class Style: "A minimal terminal text styler." def __init__(self, codes=None): self.codes = [] if codes is None else codes def __dir__(self): return style_codes.keys() - def __getattr__(self, k): return Style(self.codes+[style_codes[k]]) + def __getattr__(self, k): + try: return Style(self.codes+[style_codes[k]]) + except KeyError: return super().__getattr__(k) def __call__(self, obj): set_ = ''.join(str(o) for o in self.codes) - reset = ''.join('' if o is None else str(o) for o in set(_reset_code(o) for o in self.codes)) + reset = ''.join(sorted('' if o is None else str(o) for o in set(_reset_code(o) for o in self.codes))) return set_ + str(obj) + reset def __repr__(self): nm = type(self).__name__ diff --git a/nbs/10_style.ipynb b/nbs/10_style.ipynb index 0c566ec9..5de6fe20 100644 --- a/nbs/10_style.ipynb +++ b/nbs/10_style.ipynb @@ -44,7 +44,7 @@ "_base = 'red green yellow blue magenta cyan'\n", "_regular = f'black {_base} light_gray'\n", "_intense = 'dark_gray ' + ' '.join('light_'+o for o in _base.split()) + ' white'\n", - "_fmt = dict(bold=1,dim=2,underline=4,reverse=7,hidden=8)" + "_fmt = 'bold dim italic underline blink invert hidden strikethrough'" ] }, { @@ -116,8 +116,9 @@ " **_mk_codes(_intense, 90, 'fg'),\n", " **_mk_codes(_regular, 40, 'bg', '{}_bg', default_bg=49),\n", " **_mk_codes(_intense, 100, 'bg', '{}_bg'),\n", - " **_mk_codes(_fmt, 0, 'fmt'),\n", - " **_mk_codes(_fmt, 21, 'reset', 'reset_{}', reset=0, reset_bold=22)}" + " **_mk_codes(_fmt, 1, 'fmt'),\n", + " **_mk_codes(_fmt, 21, 'reset', 'reset_{}', reset=0, reset_bold=22)}\n", + "style_codes = {k:v for k,v in style_codes.items() if '' not in k}" ] }, { @@ -146,10 +147,12 @@ " \"A minimal terminal text styler.\"\n", " def __init__(self, codes=None): self.codes = [] if codes is None else codes\n", " def __dir__(self): return style_codes.keys()\n", - " def __getattr__(self, k): return Style(self.codes+[style_codes[k]])\n", + " def __getattr__(self, k):\n", + " try: return Style(self.codes+[style_codes[k]])\n", + " except KeyError: return super().__getattr__(k)\n", " def __call__(self, obj):\n", " set_ = ''.join(str(o) for o in self.codes)\n", - " reset = ''.join('' if o is None else str(o) for o in set(_reset_code(o) for o in self.codes))\n", + " reset = ''.join(sorted('' if o is None else str(o) for o in set(_reset_code(o) for o in self.codes)))\n", " return set_ + str(obj) + reset\n", " def __repr__(self):\n", " nm = type(self).__name__\n", @@ -261,7 +264,7 @@ { "data": { "text/plain": [ - "'\\x1b[34m\\x1b[1m\\x1b[4mhello world\\x1b[21m\\x1b[39m\\x1b[24m'" + "'\\x1b[34m\\x1b[1m\\x1b[4mhello world\\x1b[22m\\x1b[24m\\x1b[39m'" ] }, "execution_count": null, @@ -291,7 +294,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[34m\u001b[1m\u001b[4mhello world\u001b[21m\u001b[39m\u001b[24m\n" + "\u001b[34m\u001b[1m\u001b[4mhello world\u001b[22m\u001b[24m\u001b[39m\n" ] } ], @@ -317,7 +320,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m\u001b[34mkey\u001b[39m = value \u001b[21m\u001b[37m \u001b[4m# With a comment\u001b[24m\u001b[39m and unstyled text\n" + "\u001b[1m\u001b[34mkey\u001b[39m = value \u001b[22m\u001b[37m \u001b[4m# With a comment\u001b[24m\u001b[39m and unstyled text\n" ] } ], @@ -335,7 +338,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[34mthis \u001b[1mis\u001b[21m a test\u001b[39m\n" + "\u001b[34mthis \u001b[1mis\u001b[22m a test\u001b[39m\n" ] } ], @@ -413,16 +416,22 @@ "\u001b[105m105 light_magenta_bg\u001b[49m\n", "\u001b[106m106 light_cyan_bg \u001b[49m\n", "\u001b[107m107 white_bg \u001b[49m\n", - "\u001b[1m 1 bold \u001b[21m\n", + "\u001b[1m 1 bold \u001b[22m\n", "\u001b[2m 2 dim \u001b[22m\n", + "\u001b[3m 3 italic \u001b[23m\n", "\u001b[4m 4 underline \u001b[24m\n", - "\u001b[7m 7 reverse \u001b[27m\n", + "\u001b[5m 5 blink \u001b[25m\n", + "\u001b[7m 7 invert \u001b[27m\n", "\u001b[8m 8 hidden \u001b[28m\n", - "\u001b[21m 21 reset_bold \n", + "\u001b[9m 9 strikethrough \u001b[29m\n", + "\u001b[22m 22 reset_bold \n", "\u001b[22m 22 reset_dim \n", + "\u001b[23m 23 reset_italic \n", "\u001b[24m 24 reset_underline \n", - "\u001b[27m 27 reset_reverse \n", + "\u001b[25m 25 reset_blink \n", + "\u001b[27m 27 reset_invert \n", "\u001b[28m 28 reset_hidden \n", + "\u001b[29m 29 reset_strikethrough\n", "\u001b[0m 0 reset \n" ] }