157 lines
3.9 KiB
Go
157 lines
3.9 KiB
Go
package format
|
||
|
||
import (
|
||
"strings"
|
||
"unicode/utf8"
|
||
)
|
||
|
||
// Tab crée une tabulation d’une 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 d’alignement.
|
||
type AlignmentType int
|
||
|
||
const (
|
||
LEFT AlignmentType = iota
|
||
RIGHT
|
||
CENTER
|
||
)
|
||
|
||
// Alignment permet d’aligner 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 l’autre côté.
|
||
// Un aligneur centré équilibre de sorte que la chaîne d’entré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 d’entrée selon les paramètres
|
||
// prédéfinis de l’aligneur.
|
||
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 d’alignement 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 d’un 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 l’aligneurs
|
||
// 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)
|
||
}
|