package format import ( "fmt" "strings" "gitea.zaclys.com/bvaudour/gob/collection" ) const ( formatTpl = "\033[%sm%s\033[m" escTpl = "\033[%sm" ) // Format permet d’appliquer des styles et des couleurs à des chaînes dans un terminal de type UNIX. type Format struct { fg Color bg Color styles []Style } // Background retourne la couleur d’arrière-plan. func (f Format) Background() Color { return f.bg } // Foreground retourne la couleur de police. func (f Format) Foreground() Color { return f.fg } // Styles retourne les styles appliqués. func (f Format) Styles() []Style { out := make([]Style, len(f.styles)) copy(out, f.styles) return out } // SetBg définit la couleur d’arrière-plan au formateur. func (f *Format) SetBg(c Color) Format { if !c.IsForeground() { f.bg = c } return *f } // RemoveBg supprime la couleur d’arrière-plan du formatteur. func (f *Format) RemoveBg() Format { return f.SetBg(Color{}) } // SetFg définit la couleur de police du formateur. func (f *Format) SetFg(c Color) Format { if !c.IsBackground() { f.fg = c } return *f } // RemoveFg supprime la couleur de police du formateur. func (f *Format) RemoveFg() Format { return f.SetFg(Color{}) } // SetColor ajoute la couleur au formateur (arrière-plan ou police). func (f *Format) SetColor(c Color) Format { if c.IsBackground() { return f.SetBg(c) } else if c.IsForeground() { return f.SetFg(c) } return *f } // AddStyles ajoute des styles au formateur. func (f *Format) AddStyles(st ...Style) Format { for _, s := range st { if s.IsDefined() { f.styles = append(f.styles, s) } } return *f } // RemoveStyles supprime les styles du formateur. func (f *Format) RemoveStyles(st ...Style) Format { f.styles = collection.Diff(f.styles, st) return *f } // Push ajoute des styles et des couleurs au formateur selon les noms donnés. // Pour plus de détail, lire la documentation sur StyleOf et ColorOf. func (f *Format) Push(names ...string) Format { for _, n := range names { if st := StyleOf(n); st.IsDefined() { f.AddStyles(st) } else if c := ColorOf(n); c.IsDefined() { f.SetColor(c) } } return *f } // Pop supprime les styles et les couleurs selon les noms donnés. // Pour plus de détail, lire la documentation sur StyleOf et ColorOf. func (f *Format) Pop(names ...string) Format { for _, n := range names { if st := StyleOf(n); st.IsDefined() { f.RemoveStyles(st) } else if c := ColorOf(n); c.IsDefined() { if c.IsBackground() { f.RemoveBg() } else { f.RemoveFg() } } } return *f } // Reset réinitialise le formateur. func (f *Format) Reset() Format { f.fg = Color{} f.bg = Color{} f.styles = []Style{} return *f } // String retourne la chaîne d’échappement ASCII du formateur. func (f Format) String() string { var args []string var is_bold bool for _, s := range f.styles { args = append(args, s.String()) if s.IsNormal() || (s.IsBold() && s.IsCancel()) { is_bold = false } else if s.IsBold() { is_bold = true } } if f.fg.IsDefined() { args = append(args, f.fg.String(is_bold)) } if f.bg.IsDefined() { args = append(args, f.bg.String()) } return strings.Join(args, ";") } // Esc retourne l’échappement complet func (f Format) Esc() string { return fmt.Sprintf(escTpl, f.String()) } // Format formate le texte selon la configuration du formateur. func (f Format) Format(text string) string { return fmt.Sprintf(formatTpl, f, text) } // FormatOf retourne un formateur selon les noms de styles et de couleurs à appliquer. func FormatOf(formats ...string) (f Format) { return f.Push(formats...) } // Apply formate le texte donné avec les styles/couleurs donnés (par nom). func Apply(text string, formats ...string) string { return FormatOf(formats...).Format(text) }