#!/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]} ', file=sys.stderr) else: do_invert_xml(Path(sys.argv[1]), Path(sys.argv[2])) if __name__ == '__main__': main()