#!/usr/bin/env python3 """Emite el símbolo de takana como arte de terminal, al estilo de los `*fetch`. Se DERIVA del SVG de `docs/marca/`, no se dibuja a mano: una copia dibujada aparte se desincroniza del símbolo el día que la marca cambie, y nadie se entera. Tres formas, de más a menos fiel: --medio (default) MEDIOS BLOQUES: `▀` con color de frente y de fondo, así cada renglón de terminal lleva DOS filas de píxeles. Es lo que usan los fetch modernos y lo que permite subir la escala sin que el dibujo se vuelva un ladrillo. Trae la placa de fondo y la celda de espacio libre que pide la hoja de marca. --bloques BLOQUES ENTEROS: `██` por celda. Sin fondo. Para terminales que renderizan mal los medios bloques. --plano ASCII de densidad, sin color. Para pipes, `TERM` tonto y consolas que no hablan 24-bit. **No se interpola ni se suaviza el gradiente.** El símbolo ES una retícula tocapu de cuadrados; difuminarlo sería «recolorear y deformar», que la hoja de marca prohíbe explícitamente. Subir `--escala` repite píxeles (vecino más cercano) y mantiene el borde duro. """ import re, sys, pathlib RAIZ = pathlib.Path(__file__).resolve().parent.parent SVG = RAIZ / "docs/marca/simbolo-fondo-oscuro.svg" OBSIDIANA = "#17130E" # el fondo de la hoja de marca DENSIDAD = {"#A63A25": "#", "#DF6B2A": "*", "#E3A63D": "+", "#FFF6DE": "@"} def rgb(h): return int(h[1:3], 16), int(h[3:5], 16), int(h[5:7], 16) def grilla(): """La retícula {(fila, col): color} leída del SVG.""" s = SVG.read_text() # El SVG trae un manifiesto C2PA enorme en ; los rects van después. cuerpo = s[s.rfind("") + 11:] if "" in s else s celdas = {} for m in re.finditer( r'= 3 celdas, filas, cols = grilla() alto, ancho = filas * escala + 2 * margen, cols * escala + 2 * margen m = [[None] * ancho for _ in range(alto)] lleno = escala - 1 if juntas else escala for (r, c), f in celdas.items(): for dr in range(lleno): for dc in range(lleno): m[margen + r * escala + dr][margen + c * escala + dc] = f return m def medio(escala=3, margen=1): """`▀`: color de frente = píxel de arriba, de fondo = el de abajo.""" m = pixeles(escala, margen) if len(m) % 2: m.append([None] * len(m[0])) out = [] for y in range(0, len(m), 2): linea = [] for x in range(len(m[0])): ar, ab = m[y][x] or OBSIDIANA, m[y + 1][x] or OBSIDIANA fr, fg, fb = rgb(ar) br, bg, bb = rgb(ab) linea.append(f"\x1b[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m▀") out.append("".join(linea) + "\x1b[0m") return "\n".join(out) def bloques(): celdas, filas, cols = grilla() out = [] for r in range(filas): linea = [] for c in range(cols): f = celdas.get((r, c)) if f is None: linea.append(" ") else: rr, gg, bb = rgb(f) linea.append(f"\x1b[38;2;{rr};{gg};{bb}m██\x1b[0m") out.append("".join(linea).rstrip()) return "\n".join(out) def plano(): celdas, filas, cols = grilla() return "\n".join( "".join(DENSIDAD[celdas[(r, c)]] * 2 if (r, c) in celdas else " " for c in range(cols)).rstrip() for r in range(filas) ) if __name__ == "__main__": a = sys.argv[1:] esc = int(next((x.split("=")[1] for x in a if x.startswith("--escala=")), 3)) if "--regenerar" in a: (RAIZ / "docs/marca/simbolo.ansi").write_text(medio(esc) + "\n") (RAIZ / "docs/marca/simbolo-bloques.ansi").write_text(bloques() + "\n") (RAIZ / "docs/marca/simbolo.txt").write_text(plano() + "\n") print("docs/marca/simbolo{.ansi,-bloques.ansi,.txt} regenerados desde el SVG") elif "--plano" in a: print(plano()) elif "--bloques" in a: print(bloques()) else: print(medio(esc))