[+] Recommended color alignments

This commit is contained in:
Azalea (on HyDEV-Daisy) 2022-06-19 22:37:27 -04:00
parent 59f5fd5651
commit d11796ef02
9 changed files with 132 additions and 48 deletions

View file

@ -2,7 +2,6 @@ from __future__ import annotations
from . import main
__version__ = main.VERSION

View file

@ -1,9 +1,10 @@
from __future__ import annotations
import numpy as np
from .color_util import RGB
from numpy import ndarray
from .color_util import RGB
def create_gradient_hex(colors: list[str], resolution: int = 300) -> ndarray:
"""

View file

@ -2,6 +2,7 @@ from __future__ import annotations
import colorsys
from typing import NamedTuple
from typing_extensions import Literal
from .constants import GLOBAL_CFG
@ -184,3 +185,7 @@ class RGB(NamedTuple):
"""
h, l, s = colorsys.rgb_to_hls(*[v / 255.0 for v in self])
return RGB(*[round(v * 255.0) for v in colorsys.hls_to_rgb(h, light, s)])
def set_min_light(self, light: float) -> 'RGB':
h, l, s = colorsys.rgb_to_hls(*[v / 255.0 for v in self])
return RGB(*[round(v * 255.0) for v in colorsys.hls_to_rgb(h, max(l, light), s)])

View file

@ -35,6 +35,7 @@ class GlobalConfig:
color_mode: str
override_distro: str | None
debug: bool
is_light: bool
GLOBAL_CFG = GlobalConfig(color_mode='8bit', override_distro=None, debug=False)
GLOBAL_CFG = GlobalConfig(color_mode='8bit', override_distro=None, debug=False, is_light=False)

View file

@ -5,30 +5,16 @@ import argparse
import json
import random
import re
from dataclasses import dataclass
from itertools import permutations
from typing import Iterable
from typing_extensions import Literal
from hyfetch import presets
from .color_util import AnsiMode, printc, color, clear_screen
from .color_util import printc, color, clear_screen
from .constants import CONFIG_PATH, VERSION, TERM_LEN, TEST_ASCII_WIDTH, TEST_ASCII, GLOBAL_CFG
from .neofetch_util import run_neofetch, get_distro_ascii, ColorAlignment, ascii_size
from .models import Config
from .neofetch_util import run_neofetch, get_distro_ascii, ColorAlignment, ascii_size, color_alignments
from .presets import PRESETS
from .serializer import json_stringify
@dataclass
class Config:
preset: str
mode: AnsiMode
light_dark: Literal['light', 'dark'] = 'dark'
lightness: float | None = None
color_align: ColorAlignment = ColorAlignment('horizontal')
def save(self):
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
CONFIG_PATH.write_text(json_stringify(self), 'utf-8')
def check_config() -> Config:
@ -147,6 +133,7 @@ def create_config() -> Config:
light_dark = literal_input(f'3. Is your terminal in &gf(#85e7e9)light mode&r or &gf(#c471ed)dark mode&r?',
['light', 'dark'], 'dark')
is_light = light_dark == 'light'
GLOBAL_CFG.is_light = is_light
title += f'\n&e3. Light/Dark: &r{light_dark}'
#############################
@ -265,7 +252,9 @@ def run():
parser.add_argument('--c-set-l', dest='light', help=f'Set lightness value of the colors', type=float)
parser.add_argument('-V', '--version', dest='version', action='store_true', help=f'Check version')
parser.add_argument('--debug', action='store_true', help=color(f'Debug mode'))
parser.add_argument('--test-distro', help=color(f'Test print a specific distro\'s ascii art'))
parser.add_argument('--debug-list', help=color(f'Debug recommendations'))
parser.add_argument('--test-distro', help=color(f'Test for a specific distro'))
parser.add_argument('--test-print', action='store_true', help=color(f'Test print distro ascii art only'))
args = parser.parse_args()
@ -281,6 +270,10 @@ def run():
if args.debug:
GLOBAL_CFG.debug = True
if args.test_print:
print(get_distro_ascii())
return
# Load config
config = check_config()
@ -296,6 +289,7 @@ def run():
# Override global color mode
GLOBAL_CFG.color_mode = config.mode
GLOBAL_CFG.is_light = config.light_dark == 'light'
# Get preset
preset = PRESETS.get(config.preset)
@ -308,5 +302,16 @@ def run():
if config.lightness:
preset = preset.set_light(config.lightness)
# Debug recommendations
if args.debug_list:
distro = args.debug_list
ca = color_alignments[distro]
print(distro)
GLOBAL_CFG.override_distro = distro
asciis = [ca.recolor_ascii(get_distro_ascii(distro), p).split('\n') for p in list(PRESETS.values())[:3]]
[printc(' '.join(line)) for line in zip(*asciis)]
return
# Run
run_neofetch(preset, config.color_align)

23
hyfetch/models.py Normal file
View file

@ -0,0 +1,23 @@
from __future__ import annotations
from dataclasses import dataclass
from typing_extensions import Literal
from .color_util import AnsiMode
from .constants import CONFIG_PATH
from .neofetch_util import ColorAlignment
from .serializer import json_stringify
@dataclass
class Config:
preset: str
mode: AnsiMode
light_dark: Literal['light', 'dark'] = 'dark'
lightness: float | None = None
color_align: ColorAlignment = ColorAlignment('horizontal')
def save(self):
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
CONFIG_PATH.write_text(json_stringify(self), 'utf-8')

View file

@ -10,13 +10,12 @@ from subprocess import check_output
from tempfile import TemporaryDirectory
import pkg_resources
from hyfetch.color_util import color
from typing_extensions import Literal
from hyfetch.color_util import color
from .constants import GLOBAL_CFG
from .presets import ColorProfile
RE_NEOFETCH_COLOR = re.compile('\\${c[0-9]}')
@ -38,6 +37,26 @@ def normalize_ascii(asc: str) -> str:
return '\n'.join(line + ' ' * (w - ascii_size(line)[0]) for line in asc.split('\n'))
def fill_starting(asc: str) -> str:
"""
Fill the missing starting placeholders.
E.g. "${c1}...\n..." -> "${c1}...\n${c1}..."
"""
new = []
last = ''
for line in asc.split('\n'):
new.append(last + line)
# Line has color placeholders
matches = RE_NEOFETCH_COLOR.findall(line)
if len(matches) > 0:
# Get the last placeholder for the next line
last = matches[-1]
return '\n'.join(new)
@dataclass
class ColorAlignment:
mode: Literal['horizontal', 'vertical', 'custom']
@ -45,13 +64,35 @@ class ColorAlignment:
# custom_colors[ascii color index] = unique color index in preset
custom_colors: dict[int, int] = ()
# Foreground/background ascii color index
fore_back: tuple[int, int] = ()
def recolor_ascii(self, asc: str, preset: ColorProfile) -> str:
"""
Use the color alignment to recolor an ascii art
:return Colored ascii, Uncolored lines
"""
if self.mode in ['horizontal', 'vertical']:
asc = fill_starting(asc)
if self.fore_back and self.mode in ['horizontal', 'vertical']:
fore, back = self.fore_back
# Replace foreground colors
asc = asc.replace(f'${{c{fore}}}', color('&0' if GLOBAL_CFG.is_light else '&f'))
lines = asc.split('\n')
# Add new colors
if self.mode == 'horizontal':
colors = preset.with_length(len(lines))
asc = '\n'.join([l.replace(f'${{c{back}}}', colors[i].to_ansi()) + color('&r') for i, l in enumerate(lines)])
else:
raise NotImplementedError()
# Remove existing colors
asc = re.sub(RE_NEOFETCH_COLOR, '', asc)
elif self.mode in ['horizontal', 'vertical']:
# Remove existing colors
asc = re.sub(RE_NEOFETCH_COLOR, '', asc)
lines = asc.split('\n')
@ -67,28 +108,9 @@ class ColorAlignment:
preset = preset.unique_colors()
# Apply colors
new = []
start_color = None
color_map = {ai: preset.colors[pi].to_ansi() for ai, pi in self.custom_colors.items()}
for line in asc.split('\n'):
# Line has color placeholders
if len(RE_NEOFETCH_COLOR.findall(line)) > 0:
# Get the last placeholder for the next line
last = int(RE_NEOFETCH_COLOR.findall(line)[-1][3])
# Replace placeholders
for ascii_i, c in color_map.items():
line = line.replace(f'${{c{ascii_i}}}', c)
# Add to new ascii
new.append(f'{start_color or ""}{line}')
# Change next start color
start_color = color_map[last]
else:
new.append(f'{start_color or ""}{line}')
asc = '\n'.join(new)
for ascii_i, c in color_map.items():
asc = asc.replace(f'${{c{ascii_i}}}', c)
return asc
@ -111,8 +133,9 @@ def get_distro_ascii(distro: str | None = None) -> str:
"""
if not distro and GLOBAL_CFG.override_distro:
distro = GLOBAL_CFG.override_distro
print(distro)
print(GLOBAL_CFG)
if GLOBAL_CFG.debug:
print(distro)
print(GLOBAL_CFG)
cmd = 'print_ascii'
if distro:
os.environ['CUSTOM_DISTRO'] = distro
@ -148,3 +171,14 @@ def run_neofetch(preset: ColorProfile, alignment: ColorAlignment):
# print(full_cmd)
subprocess.run(full_cmd)
# Color alignment recommendations
color_alignments = {
'fedora': ColorAlignment('horizontal', fore_back=(2, 1)),
'ubuntu': ColorAlignment('horizontal', fore_back=(2, 1)),
'nixos': ColorAlignment('custom', {1: 1, 2: 0}),
# 'arch': ColorAlignment('horizontal'),
# 'centos': ColorAlignment('horizontal'),
}

View file

@ -109,6 +109,9 @@ class ColorProfile:
"""
return ColorProfile([c.set_light(light) for c in self.colors])
def set_min_light(self, light: float):
return ColorProfile([c.set_min_light(light) for c in self.colors])
def unique_colors(self) -> ColorProfile:
"""
Create another color profile with only the unique colors

View file

@ -11614,4 +11614,17 @@ get_print_custom_ascii() {
echo "$ascii_data"
}
get_test_distro_ascii() {
# Load default config.
eval "$config"
distro="$CUSTOM_DISTRO"
ascii_distro=$distro
get_bold
get_distro_ascii
image_backend
dynamic_prompt
}
main "$@"