Skip to content

Instantly share code, notes, and snippets.

@spajak
Last active June 3, 2022 01:20
Show Gist options
  • Save spajak/4fdddb5313caf97ee1b603ac1e7b414d to your computer and use it in GitHub Desktop.
Save spajak/4fdddb5313caf97ee1b603ac1e7b414d to your computer and use it in GitHub Desktop.
Generate console colors scheme for Windows Console, Windows Terminal and Putty in a form of .reg files (Windows Registry) and json
# Console colors for Windows
# --------------------------
# Script outputs console color scheme files for Windows in the followng formats:
# <win>.reg file - Windows legancy console colors
# <putty>.reg file - Putty console colors
# <concfg>.json - concfg.json scheme
# <wt>.json - Windows Terminal color scheme
#
# Windows reg file is for default console. Putty sessions are configurable below, see: `puttySessions` variable.
# Feel free to change the colors. Provided palette is a simple and reasonable default for dark background.
# The script does not modify the system's files/registry in any way, you have to register resulted `.reg` files manually.
# Use "demo" as an argument to test the colors.
# Color scheme
# -------------------------------------------------------------
# name: normal, bright
palette = {
'black': (( 0, 0, 0), (136,136,136)),
'red': ((244, 80, 80), (255,108,108)),
'green': (( 44,216, 44), ( 92,255, 92)),
'yellow': ((238,210, 46), (255,242,112)),
'blue': (( 80,160,248), (124,196,255)),
'magenta': ((230, 78,246), (250,126,255)),
'cyan': (( 32,210,208), ( 84,255,244)),
'white': ((218,218,218), (252,252,252))
}
defaultBgColor = ( 25, 25, 25)
defaultFgColor = (218,218,218)
# Windows legancy console settings
# -------------------------------------------------------------
winBgColor = defaultBgColor
winFgColor = defaultFgColor
winScreenBgColorIndex = 0
winScreenFgColorIndex = 7
winPopupBgColorIndex = 7
winPopupFgColorIndex = 5
winFileName = "win.reg"
# Putty settings
# -------------------------------------------------------------
puttySessions = ('session1', 'session2')
puttyBgColor = defaultBgColor
puttyFgColor = defaultFgColor
puttyBoldBgColor = ( 96, 96, 96)
puttyBoldFgColor = (244,244,244)
puttyCursorColor = (0,255,0)
puttyCursorTextColor = (0,0,0)
puttyFileName = "putty.reg"
# concfg settings
# -------------------------------------------------------------
# https://github.com/lukesampson/concfg
concfgScreenColors = "white,black"
concfgPopupColors = "dark_magenta,white"
concfgFileName = "concfg.json"
# Windows Terminal settings
# -------------------------------------------------------------
wtBgColor = defaultBgColor
wtFgColor = defaultFgColor
wtCursorColor = (250,250,250)
wtSelectionBgColor = (250,250,250)
wtFileName = "wt.json"
# --- CODE ----------------------------------------------------
import sys, json
def main():
if len(sys.argv) > 1:
if sys.argv[1] == 'demo':
demo()
elif len(sys.argv) > 2:
if sys.argv[1] == 'hex2rgb':
print(hex2rgb(sys.argv[2]))
elif sys.argv[1] == 'rgb2hex':
c = [int(x.strip()) for x in sys.argv[2].split(',')]
print(rgb2hex(c))
else:
create_win()
create_putty()
create_concfg()
create_wt()
print("Color scheme files created")
def getColor(name, b):
if name not in palette:
raise Exception(f'Color name "{name}" is not defined')
if b not in (0, 1):
raise Exception(f'Bold/bright flag value {b} is unexpected. Expecting 0 or 1')
return palette[name][b]
def rgb2hex(c):
r, g, b = list(c) + [0] * (3 - len(c))
return f"#{r:0>2x}{g:0>2x}{b:0>2x}"
def hex2rgb(value):
h = value.lstrip('#')[:6].ljust(6, '0')
return tuple(int(h[i] + h[i+1], 16) for i in range(0, 5, 2))
'''
Reference table:
name fg bg | vga vga (b) | win putty
-------------------------------------------------------------
Black 30 40 | 0, 0, 0 85, 85, 85 | 0( 8) 6( 7)
Red 31 41 | 170, 0, 0 255, 85, 85 | 4(12) 8( 9)
Green 32 42 | 0,170, 0 85,255, 85 | 2(10) 10(11)
Yellow 33 43 | 170, 85, 0 255,255, 85 | 6(14) 12(13)
Blue 34 44 | 0, 0,170 85, 85,255 | 1( 9) 14(15)
Magenta 35 45 | 170, 0,170 255, 85,255 | 5(13) 16(17)
Cyan 36 46 | 0,170,170 85,255,255 | 3(11) 18(19)
White 37 47 | 170,170,170 85,255,255 | 7(15) 20(21)
'''
winColorMap = {
0: ('black', 0),
1: ('blue', 0),
2: ('green', 0),
3: ('cyan', 0),
4: ('red', 0),
5: ('magenta', 0),
6: ('yellow', 0),
7: ('white', 0),
8: ('black', 1),
9: ('blue', 1),
10: ('green', 1),
11: ('cyan', 1),
12: ('red', 1),
13: ('magenta', 1),
14: ('yellow', 1),
15: ('white', 1)
}
def create_win():
def rhex(r, g, b):
return f"00{b:0>2x}{g:0>2x}{r:0>2x}"
with open(winFileName, 'w') as file:
file.write("Windows Registry Editor Version 5.00\n")
file.write("\n")
file.write("[HKEY_CURRENT_USER\\Console]\n")
file.write(f'"DefaultBackground"=dword:{rhex(*winBgColor)}\n')
file.write(f'"DefaultForeground"=dword:{rhex(*winFgColor)}\n')
file.write(f'"ScreenColors"=dword:000000{winScreenBgColorIndex:x}{winScreenFgColorIndex:x}\n')
file.write(f'"PopupColors"=dword:000000{winPopupBgColorIndex:x}{winPopupFgColorIndex:x}\n')
for i, value in winColorMap.items():
r, g, b = getColor(value[0], value[1])
file.write(f'"ColorTable{i:0>2d}"=dword:{rhex(r, g, b)}\n')
puttyColorMap = {
6: ('black', 0),
7: ('black', 1),
8: ('red', 0),
9: ('red', 1),
10: ('green', 0),
11: ('green', 1),
12: ('yellow', 0),
13: ('yellow', 1),
14: ('blue', 0),
15: ('blue', 1),
16: ('magenta', 0),
17: ('magenta', 1),
18: ('cyan', 0),
19: ('cyan', 1),
20: ('white', 0),
21: ('white', 1)
}
def create_putty():
specialColors = (
puttyFgColor,
puttyBoldFgColor,
puttyBgColor,
puttyBoldBgColor,
puttyCursorTextColor,
puttyCursorColor
)
with open(puttyFileName, 'w') as file:
file.write("Windows Registry Editor Version 5.00\n")
for session in puttySessions:
file.write("\n")
file.write(f"[HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions\\{session}]\n")
for i, color in enumerate(specialColors):
file.write(f'"Colour{i}"="{color[0]},{color[1]},{color[2]}"\n')
for i, value in puttyColorMap.items():
r, g, b = getColor(value[0], value[1])
file.write(f'"Colour{i}"="{r},{g},{b}"\n')
concfgColorMap = {
'black': ('black', 0),
'dark_gray': ('black', 1),
'dark_red': ('red', 0),
'red': ('red', 1),
'dark_green': ('green', 0),
'green': ('green', 1),
'dark_yellow': ('yellow', 0),
'yellow': ('yellow', 1),
'dark_blue': ('blue', 0),
'blue': ('blue', 1),
'dark_magenta': ('magenta', 0),
'magenta': ('magenta', 1),
'dark_cyan': ('cyan', 0),
'cyan': ('cyan', 1),
'gray': ('white', 0),
'white': ('white', 1)
}
def create_concfg():
with open(concfgFileName, 'w') as file:
result = {}
result['screen_colors'] = concfgScreenColors
result['popup_colors'] = concfgPopupColors
for name, (pname, bright) in concfgColorMap.items():
color = getColor(pname, bright)
result[name] = rgb2hex(color)
file.write(json.dumps(result, indent=4))
wtNameMap = {
'magenta': 'purple'
}
def create_wt():
with open(wtFileName, 'w') as file:
result = {}
result["name"] = "Custom"
result["foreground"] = rgb2hex(wtFgColor)
result["background"] = rgb2hex(wtBgColor)
result["cursorColor"] = rgb2hex(wtCursorColor)
result["selectionBackground"] = rgb2hex(wtSelectionBgColor)
for name, (cn, cb) in palette.items():
if name in wtNameMap:
name = wtNameMap[name]
result[name] = rgb2hex(cn)
result['bright' + name.title()] = rgb2hex(cb)
file.write(json.dumps(result, indent=4))
# 0 - reset
# 1 - bright
# 2 - dim
# 22 - normal
ansiColors = {
'black': ("\033[0;22;30m", "\033[0;1;30m"),
'red': ("\033[0;22;31m", "\033[0;1;31m"),
'green': ("\033[0;22;32m", "\033[0;1;32m"),
'yellow': ("\033[0;22;33m", "\033[0;1;33m"),
'blue': ("\033[0;22;34m", "\033[0;1;34m"),
'magenta': ("\033[0;22;35m", "\033[0;1;35m"),
'cyan': ("\033[0;22;36m", "\033[0;1;36m"),
'white': ("\033[0;22;37m", "\033[0;1;37m")
}
def demo():
try:
import colorama
except ModuleNotFoundError:
print('colorama package is not installed')
return
colorama.init(autoreset=True)
for name, (cn, cb) in ansiColors.items():
print(f'{cn}Sample text: {name}')
print(f'{cb}Sample text: {name} bright')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment