はじめ
Command Prompt, PowerShell, Terminalなどで色付き文字を出力する方法(ライブラリ)は多数あります。
有名どころで言えば
Colorama
from colorama import Fore
print(Fore.GREEN + "This text is green!")
termcolor
from termcolor import colored
print(colored('This text is green!', 'green'))
とかですかね。
素晴らしいライブラリ
これらは実に便利なライブラリです。簡単に色づき文字を作成したりすることができます。
ただ、実は一つ問題があります。
ネストできない
これはつまり、たとえば
(赤字の文章)(緑字の文章)(赤字の文章)
とか
(赤字の文章)(赤字で下線のある文章)(赤字の文章)
などを出力しようとすると、結構めんどくさいということです。
以下の画像における各行のようなものです。
たとえばこれをtermcolorで実装しようとすると、以下のようになるでしょう。
from termcolor import colored
print(colored('[RED]', 'red') + colored('[GREEN]', 'green') + colored('[RED]', 'red'))
print(colored('[RED]', 'red') + colored('[UNDERLINE]', 'red', attrs=['underline']) + colored('[RED]', 'red'))
ネストが深くなったり、長い文章同士を結合しようとすると毎回こういった指定をしなければならず、ちょっと大変です。そこで
スタイリングライブラリ iro
iroを使ってみましょう!
$ pip install iro
GitHub
さて、このライブラリを使うと、ネストされたスタイルをこのように表現することができます。
出力は上記の画像と全く同じです。
from iro import Iro, Color, Style
print(Iro([
Color.RED, "[RED]",
[ Color.GREEN, "[GREEN]" ],
"[RED]"
]))
print(Iro([
Color.RED, "[RED]",
[ Style.UNDERLINE, "[UNDERLINE]" ],
"[RED]"
]))
ある深さにあるstr
には、その深さまでの色・スタイルがすべて適用されます。深さが深い方が優先度が高くなるので、このように簡単に表すことができます。
また、これはネストがより深くなればなるほどわかりやすくなります。
以下の二つのコードは同等の出力をします。
print(Iro([
Color.RED, "[RED]",
[
Style.UNDERLINE, "[RED/UNDERLINE]",
[
Style.BOLD, Color.GREEN, "[GREEN/UNDERLINE/BOLD]",
[
Style.INVERT, "[GREEN/UNDERLINE/BOLD/INVERT]",
[
Style.OFF_BOLD, "[GREEN/UNDERLINE/INVERT]"
]
],
"[GREEN/UNDERLINE/BOLD]"
],
"[RED/UNDERLINE]"
]
]))
print(colored("[RED]", 'red'),
colored("[RED/UNDERLINE]", 'red', attrs=['underline']),
colored("[GREEN/UNDERLINE/BOLD]", 'green', attrs=['underline', 'bold']),
colored("[GREEN/UNDERLINE/BOLD/ITALIC]", 'green', attrs=['underline', 'bold', 'reverse']),
colored("[GREEN/UNDERLINE/ITALIC]", 'green', attrs=['underline', 'reverse']),
colored("[GREEN/UNDERLINE/BOLD]", 'green', attrs=['underline', 'bold']),
colored("[RED/UNDERLINE]", 'red', attrs=['underline']), sep=''
)
Iro
のほうはあえて見やすさのために大量に改行などしてますが、非常に分かりやすくなっているのではないでしょうか?
これだけでなく、Iro
は8-bitカラーや、RGBカラーを使用することもできます。
print(Iro([
[ Color256(135), Color256(217, bg=True), " SEXY COLOR " ],
[ ColorRGB.from_color_code("EEA47F"), ColorRGB(0, 83, 156, bg=True), " AND THIS IS SICK " ],
[ Color.BRIGHT_YELLOW, Color.BG_YELLOW, " BRIGHT!! " ]
], disable_rgb=False))
デフォルトではdisable_rgb
はTrue
で、ColorRGB
をそれに最も近しいColor256
に変換して出力します。
RGBカラーに対応していないコンソールも時々あるので、その時はdisable_rgb
をTrue
のままにしておきましょう。True
にするとこのようになります。
確かによく見てみると、上の写真と下の写真、中央の色が違いますね!(その程度の差なので、結構精度は高い)
Styleも豊富で
RESET
BOLD
DIM
ITALIC
UNDERLINE
SLOW_BLINK
RAPID_BLINK
INVERT
HIDE
STRIKE
BLACKLETTER_FONT
DOUBLY_UNDERLINE
OFF_INTENSITY
OFF_BOLD
OFF_DIM
OFF_ITALIC
OFF_UNDERLINE
OFF_BLINK
OFF_INVERT
OFF_HIDE
OFF_STRIKE
OFF_COLOR
OFF_BG_COLOR
OFF_OVERLINE
などが使えます。
Iro([text...], optimize_level=1)
とすることで最適化が行われ描画が高速になる可能性がありますが、端末によっては最適化によって動作が不安定になる場合があります。ただ、この効果は大きく、GitHubのQ&Aを見ると
value = [
Color.RED, "[RED]",
[
Style.UNDERLINE, "[RED/UNDERLINE]",
[
Style.BOLD, Color.GREEN, "[GREEN/UNDERLINE/BOLD]",
[
Style.INVERT, "[GREEN/UNDERLINE/BOLD/INVERT]",
[
Style.OFF_BOLD, "[GREEN/UNDERLINE/INVERT]"
]
],
"[GREEN/UNDERLINE/BOLD]"
],
"[RED/UNDERLINE]"
]
]
print(repr(Iro(value, optimize_level=1).text))
# '\x1b[31m[RED]\x1b[4m[RED/UNDERLINE]\x1b[1m\x1b[32m[GREEN/UNDERLINE/BOLD]\x1b[7m[GREEN/UNDERLINE/BOLD/INVERT]
# \x1b[22m[GREEN/UNDERLINE/INVERT]\x1b[1m\x1b[27m[GREEN/UNDERLINE/BOLD]\x1b[22m\x1b[31m[RED/UNDERLINE]
# \x1b[24m\x1b[39m\x1b[0m'
print(repr(Iro(value, optimize_level=0).text))
# '\x1b[31m[RED]\x1b[31m\x1b[4m[RED/UNDERLINE]\x1b[31m\x1b[4m\x1b[1m\x1b[32m[GREEN/UNDERLINE/BOLD]
# \x1b[31m\x1b[4m\x1b[1m\x1b[32m\x1b[7m[GREEN/UNDERLINE/BOLD/INVERT]
# \x1b[31m\x1b[4m\x1b[1m\x1b[32m\x1b[7m\x1b[22m[GREEN/UNDERLINE/INVERT]
# \x1b[39m\x1b[24m\x1b[22m\x1b[39m\x1b[27m\x1b[22m\x1b[31m\x1b[4m\x1b[1m\x1b[32m\x1b[7m\x1b[39m\x1b
# [24m\x1b[22m\x1b[39m\x1b[27m\x1b[31m\x1b[4m\x1b[1m\x1b[32m[GREEN/UNDERLINE/BOLD]
# \x1b[39m\x1b[24m\x1b[22m\x1b[39m\x1b[31m\x1b[4m[RED/UNDERLINE]
# \x1b[39m\x1b[24m\x1b[31m\x1b[39m\x1b[0m'
という程の変化があるようです。
おわり
是非便利にお使いください!(作者)