gob/format/align.go

157 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

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 (
"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)
}