64 lines
1.9 KiB
Python
Executable File
64 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
import re
|
|
from typing import Tuple
|
|
import colorsys
|
|
|
|
|
|
def invert_rgb_luma(r: float, g: float, b: float) -> Tuple[float, float, float]:
|
|
h, l, s = colorsys.rgb_to_hls(r, g, b)
|
|
return colorsys.hls_to_rgb(h, (1-l)**(6/10), s)
|
|
|
|
|
|
def byte2hex(byte: int) -> str:
|
|
return ('0'*3+hex(byte)[2:])[-2:]
|
|
|
|
|
|
def invert_color_hex(text: re.Match) -> str:
|
|
read_hex: str = text.group(1).upper()
|
|
transparency = ''
|
|
if len(read_hex) == 8:
|
|
transparency = read_hex[:2]
|
|
if transparency == 'FF':
|
|
return f'#{read_hex.upper()}'
|
|
read_hex = read_hex[2:]
|
|
elif len(read_hex) != 6:
|
|
raise ValueError()
|
|
inverted_rgb: Tuple[int, int, int] = tuple(
|
|
map(round, map((255.0).__mul__, invert_rgb_luma(
|
|
int(read_hex[0:2], 16)/255,
|
|
int(read_hex[2:4], 16)/255,
|
|
int(read_hex[4:6], 16)/255,
|
|
))))
|
|
return f'#{transparency}{byte2hex(inverted_rgb[0])}{byte2hex(inverted_rgb[1])}{byte2hex(inverted_rgb[2])}'.upper()
|
|
|
|
|
|
def do_invert_xml(source: Path, destination: Path):
|
|
if not source.is_file():
|
|
raise FileNotFoundError(source)
|
|
if not destination.parent.exists():
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
elif destination.parent.exists() and not destination.parent.is_dir():
|
|
raise NotADirectoryError(destination.parent)
|
|
inverted = re.sub(r'#([0-9a-fA-F]+)',
|
|
invert_color_hex,
|
|
source.read_text('utf-8'),
|
|
)
|
|
print(inverted)
|
|
destination.write_text(inverted, 'utf-8')
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print(
|
|
f'Usage:\n {sys.argv[0]} <path/to/source/colors.xml> <path/to/destination/colors.xml>', file=sys.stderr)
|
|
else:
|
|
do_invert_xml(Path(sys.argv[1]), Path(sys.argv[2]))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|