Last active
July 10, 2020 10:51
-
-
Save yoichi/4c5f90aacede9f84422da794e1a945a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Convert truecolor escape sequence to 256 color escape sequence | |
* \x1b[38;2;{red};{green};{blue}m -> \x1b[38;5;{color}m (foreground) | |
* \x1b[48;2;{red};{green};{blue}m -> \x1b[48;5;{color}m (background) | |
where 0 <= red, green, blue <= 255 represents 24-bit color | |
and 16 <= color <= 231 | |
The logic is based on the colour_find_rgb() in tmux/colour.c | |
Original copyright notice is: | |
Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> | |
Copyright (c) 2016 Avi Halachmi <avihpit@yahoo.com> | |
Permission to use, copy, modify, and distribute this software for any | |
purpose with or without fee is hereby granted, provided that the above | |
copyright notice and this permission notice appear in all copies. | |
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | |
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | |
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
""" | |
import re | |
def to_6(n): | |
"256 color to 6" | |
if n < 48: | |
return 0 | |
if n < 114: | |
return 1 | |
return (n-35) // 40 | |
def from_6(q): | |
"6 to 256" | |
q2c = [0, 95, 135, 175, 215, 255] | |
return q2c[q] | |
def dist_sq(a, b): | |
return sum((p-q)*(p-q) for p, q in zip(a, b)) | |
def truecolor_to_256(s): | |
pattern = re.compile(r"\x1b\[([34]8);2;(\d+);(\d+);(\d+)((;\d+)*)m") | |
def repl(m): | |
r, g, b = map(int, (m[2], m[3], m[4])) | |
# 6x6x6 | |
qr = to_6(r) | |
qg = to_6(g) | |
qb = to_6(b) | |
# grey | |
grey_avg = (r + g + b) // 3 | |
if grey_avg > 238: | |
grey_idx = 23 | |
else: | |
grey_idx = (grey_avg - 3) // 10 | |
grey = grey_idx*10 + 8 | |
# use closer one | |
d = dist_sq(map(from_6, (qr, qg, qb)), (r, g, b)) | |
if dist_sq((grey, grey, grey), (r, g, b)) < d: | |
c = grey_idx + 232 | |
else: | |
c = qr*36 + qg*6 + qb + 16 | |
return f'\x1b[{m[1]};5;{c}{m[5]}m' | |
return re.sub(pattern, repl, s) | |
if __name__ == '__main__': | |
import sys | |
sys.stdout.write(truecolor_to_256(sys.stdin.read())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment