gob/format/color.go

228 lines
4.4 KiB
Go
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package format
import (
"fmt"
"strings"
"gitea.zaclys.com/bvaudour/gob/option"
)
// Color permet de colorer une chaîne dans un terminal de type UNIX.
type Color struct {
option.Option[int]
}
const (
black int = iota
red
green
yellow
blue
majenta
cyan
white
light = 1 << 3
background = 1 << 4
dark = ^light
foreground = ^dark
)
var colors = map[string]int{
"black": black,
"red": red,
"green": green,
"yellow": yellow,
"blue": blue,
"majenta": majenta,
"cyan": cyan,
"white": white,
}
var prefixes = []string{
"fg_l_",
"fg_",
"l_",
"bg_l_",
"bg_",
}
var prefixFuncs = map[string]func(string) Color{
"fg_l_": fgLightColor,
"fg_": fgColor,
"l_": fgLightColor,
"bg_l_": bgLightColor,
"bg_": bgColor,
}
// IsLight retourne vrai si la couleur est claire.
func (c Color) IsLight() bool {
v, ok := c.Get()
return ok && v&light != 0
}
// IsDark retourne vrai si la couleur est foncée.
func (c Color) IsDark() bool {
v, ok := c.Get()
return ok && v&light == 0
}
// IsBackground retourne vrai si cest une couleur darrière-plan.
func (c Color) IsBackground() bool {
v, ok := c.Get()
return ok && v&background != 0
}
// IsForeground retourne vrai si cest une couleur de police.
func (c Color) IsForeground() bool {
v, ok := c.Get()
return ok && v&background == 0
}
// Light retourne léquivalent clair de la couleur.
func (c Color) Light() Color {
if v, ok := c.Get(); ok {
return Color{option.Some(v | light)}
}
return c
}
// Dark retourne léquivalent foncé de la couleur.
func (c Color) Dark() Color {
if v, ok := c.Get(); ok {
return Color{option.Some(v & dark)}
}
return c
}
// Background retourne la couleur équivalente darrière-plan.
func (c Color) Background() Color {
if v, ok := c.Get(); ok {
return Color{option.Some(v | background)}
}
return c
}
// Foreground retourne la couleur équivalente de police.
func (c Color) Foreground() Color {
if v, ok := c.Get(); ok {
return Color{option.Some(v & foreground)}
}
return c
}
// Color retourne la composante couleur de base de la couleur.
func (c Color) Color() Color {
if v, ok := c.Get(); ok {
return Color{option.Some(v & white)}
}
return c
}
// Color retourne la composante couleur foncée/claire de la couleur .
func (c Color) Base() (out option.Option[int]) {
v, ok := c.Get()
if !ok {
return
}
b := 30 + (v & white)
if c.IsBackground() {
b += 10
}
if c.IsLight() {
b += 60
}
return option.Some(b)
}
// String retourne la valeur déchappement ASCII de la couleur.
func (c Color) String(force ...bool) string {
b, ok := c.Base().Get()
if !ok {
return ""
}
s := fmt.Sprint(b)
if len(force) > 0 && force[0] && !c.IsLight() && !c.IsBackground() {
s = "2;" + s
}
return s
}
// Esc retourne léchappement ASCII complet.
func (c Color) Esc(force ...bool) string {
return fmt.Sprintf(escTpl, c.String(force...))
}
// Format colore la chaîne donnée selon la couleur spécifiée.
func (c Color) Format(text string) string {
if !c.IsDefined() {
return text
}
return fmt.Sprintf(formatTpl, c.String(), text)
}
func colorOf(name string) (c Color) {
if v, ok := colors[name]; ok {
c = Color{option.Some(v)}
}
return
}
func fgDarkColor(name string) Color {
return colorOf(name)
}
func fgLightColor(name string) (c Color) {
return colorOf(name).Light()
}
func fgColor(name string) Color {
if strings.HasPrefix(name, "l_") {
n := strings.TrimPrefix(name, "l_")
return fgLightColor(n)
}
return fgDarkColor(name)
}
func bgDarkColor(name string) Color {
return colorOf(name).Background()
}
func bgLightColor(name string) (c Color) {
return colorOf(name).Background().Light()
}
func bgColor(name string) Color {
if strings.HasPrefix(name, "l_") {
n := strings.TrimPrefix(name, "l_")
return bgLightColor(n)
}
return bgDarkColor(name)
}
// ColorOf retourne la couleur au nom demandé.
// Les noms possibles sont:
// - white
// - black
// - red
// - green
// - blue
// - yellow
// - magenta
// - cyan
// Le préfixe l_ peut être rajouté à la couleur pour forcer le mode clair.
// Le préfixe bg_ ou fg_ peut être ajouté pour forcer, respectivement la couleur
// darrière-plan ou de police (mode par défaut).
func ColorOf(name string) Color {
for _, prefix := range prefixes {
if strings.HasPrefix(name, prefix) {
n := strings.TrimPrefix(name, prefix)
return prefixFuncs[prefix](n)
}
}
return colorOf(name)
}