gob/format/align.go

157 lines
3.9 KiB
Go
Raw Normal View History

2023-09-23 19:42:21 +00:00
package format
import (
"strings"
"unicode/utf8"
)
// Tab crée une tabulation dune longueur donnée.
func Tab(size int) string {
return strings.Repeat(" ", size)
}
// TabulateLeft ajoute <tabsize> espaces à gauche.
func TabulateLeft(str string, tabSize int) string {
return Tab(tabSize) + str
}
// TabulateRight ajoute <tabsize> espaces à droite.
func TabulateRight(str string, tabSize int) string {
return str + Tab(tabSize)
}
// Tabulate ajoute <leftSize> espaces à gauche et <rightSize> espaces à droite.
func Tabulate(str string, leftSize, rightSize int) string {
return Tab(leftSize) + str + Tab(rightSize)
}
// AlignmentType représente un type dalignement.
type AlignmentType int
const (
LEFT AlignmentType = iota
RIGHT
CENTER
)
// Alignment permet daligner des chaînes selon des caractérisques prédéfinies.
type Alignment struct {
t AlignmentType
l int
}
// NewAlignement retourne un aligneur de type t (gauche, droit ou centré) et de longueur définie.
// Ainsi un aligneur gauche défini à 10 caractères transformera une chaîne de la façon suivante :
// - si la chaîne fait plus de 10 caractères, elle est tronquée à droite
// - sinon, des espaces sont rajoutées à droite de sorte que la chaîne de sortie fasse 10 caractères.
// Un aligneur droit procède de la même manière mais de lautre côté.
// Un aligneur centré équilibre de sorte que la chaîne dentrée reste au milieu.
func NewAlignment(t AlignmentType, size int) Alignment {
if size <= 0 {
panic("Size of alignment must be positive")
}
return Alignment{
t: t,
l: size,
}
}
func size(str string) int { return utf8.RuneCountInString(str) }
// Formate aligne la chaîne dentrée selon les paramètres
// prédéfinis de laligneur.
func (a Alignment) Format(str string) string {
l := size(str)
if l == a.l {
return str
}
d := a.l - l
runes := []rune(str)
switch a.t {
case RIGHT:
if d > 0 {
return TabulateLeft(str, d)
}
return string(runes[-d:])
case CENTER:
if d > 0 {
left := d >> 1
right := d - left
return Tabulate(str, left, right)
}
left := (-d) >> 1
return string(runes[left : left+a.l])
default:
if d > 0 {
return TabulateRight(str, d)
}
return string(runes[:a.l])
}
}
// Align align la chaîne selon le type dalignement donné,
// de sorte que la chaîne de sortie ait la longueur spécifiée.
func Align(str string, align AlignmentType, size int) string {
a := NewAlignment(align, size)
return a.Format(str)
}
// Left aligne à gauche.
func Left(str string, size int) string {
return Align(str, LEFT, size)
}
// Right aligne à droite.
func Right(str string, size int) string {
return Align(str, RIGHT, size)
}
// Center centre la chaîne.
func Center(str string, size int) string {
return Align(str, CENTER, size)
}
// ColumnSet permet de formater les entrées dun tableau.
// Chaque entrée correspond à un aligneur de colonne.
type ColumnSet []Alignment
// NewColumnSet retourne un formateur de tableaux.
func NewColumnSet(aligns ...Alignment) ColumnSet {
return aligns
}
// Normalize formate les colonnes spcéfiées en entrées.
// Le nombre de colonnes doit être identique au nombre de laligneurs
// du formateur de colonnes.
func (cs ColumnSet) Normalize(columns []string) (out []string) {
if len(cs) != len(columns) {
panic("Number of columns must be equal to number of column set")
}
out = make([]string, len(columns))
for i, a := range cs {
out[i] = a.Format(columns[i])
}
return out
}
// Line formate une ligne de tableau, avec :
// - columns : liste des colonnes de la ligne
// - sep : séparateur de colonnes
// - prefix : préfixe de ligne
// - suffix : suffixe de ligne
func (cs ColumnSet) Line(columns []string, sep, prefix, suffix string) string {
out := cs.Normalize(columns)
if prefix != "" || suffix != "" {
for i, c := range out {
out[i] = prefix + c + suffix
}
}
return strings.Join(out, sep)
}