# **Evaluation Ascii Art**
*Matthias Flament*
*Léo SERY*
## **Procédure d'installation :**
```
Téléchargement des différents fichiers de test : Standart.txt
Shadow.txt
Thinkertoy.txt
depuis ce lien https://github.com/01-edu/public/tree/master/subjects/ascii-art
```
##
## **Exemple d'utilisation :**
```
Pour utiliser notre programme, nous devons lancer un terminal bash pour que celui-si fonctionne.
Voici quelques exemples d'utilisation.
```

##
## **Code Source :**
```
package main
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strconv"
"strings"
)
func main() {
//fs (permet de choisir la typographie en passant le nom de cette dernière en argument)
style := "standart.txt"
if len(os.Args) >= 3 {
if os.Args[2] == "shadow" {
style = "shadow.txt"
} else if os.Args[2] == "thinkertoy" {
style = "thinkertoy.txt"
}
}
arg1 := os.Args[1]
nbrspace := 0
for u := 0; u < len(arg1); u++ { //permet de compter le nombre d'espaces dans la string qui est en argument (sert pour le cas "justifie")
if rune(arg1[u]) == ' ' {
nbrspace++
}
}
alignparam := ""
justbool := false
filename := ""
printcheck := 0
outputcheck := false
var colorizedchar Color
colorizedchar = ColorReset
for p := 0; p < len(os.Args); p++ { //naviguer dans les arguments (boucle sur chaque argument)
arg := os.Args[p]
// permet de séparaer les flags "--output" et "--aling" de leurs paramètres
for p := 0; p < len(os.Args); p++ { //boucle sur chaque lettres
arg := os.Args[p] //arg = argument actuelle
separated := strings.Split(arg, "=") // des que "=" split l'argument en 2
if separated[0] == "--output" {
filename = separated[1] //rajoute le nom du fichier juste apres le "="
} else if separated[0] == "--align" {
alignparam = separated[1] //rajoute le type d'alignement apres le "="
}
}
switch os.Args[p] { //permet de détecter les flags
case "--align=" + alignparam: //flag permettant de choisir la disposition du texte
justbool = true
case "--output=" + filename: //flag permetant de créer un fichier dans lequel ce trouvera la sortie
outputcheck = true
case "--color=red": // le flag "color" permet de choisir la couleur de la sortie
colorizedchar = red
case "--color=blue":
colorizedchar = blue
case "--color=green":
colorizedchar = green
case "--color=pink":
colorizedchar = pink
case "--color=yellow":
colorizedchar = yellow
case "--color=cyan":
colorizedchar = cyan
case "--color=orange":
colorizedchar = orange
}
if rune(arg[0]) == '-' && rune(arg[1]) == '-' { //permet de savoir si il faut print avec le flag "output" | permet de detecter les "--"
printcheck++ //eviter que il print quand "--output est le seul flag"
}
}
var lenghtstrarr []string
totalcharlen := 0
widthrest := 0
//calcul largeur terminal
if justbool {
for j := 0; j < len(arg1); j++ { //boucle sur chaque lettre de l'arg 1
//prend la largeur de lettre
lenghtstrarr = append(lenghtstrarr, ReadLine(arg1[j], 6, style, widthrest, alignparam, nbrspace)) //"lenght" - "str" - "arr" | withdrest = longeur du reste
}
for y := 0; y < len(lenghtstrarr); y++ { // addition longueur de chaque case " 1 case = 1 lettre"
totalcharlen += len(lenghtstrarr[y]) //longueur de la chaine de caractère en sortie dans le terminal
}
//longeur terminal - longueur total du mot
widthrest = int(Width()) - totalcharlen //permet de savoir la longueur restante du terminal
}
//printer + permet de faire des "/n" dans le mot.
if (len(os.Args) >= 2 && printcheck > 1) || (len(os.Args) >= 2 && outputcheck == false) { //print par defaut | 2 args = nom fichier + text en ""
sep := string(rune(92)) + "n"
stringarr := strings.Split(arg1, sep)
for i := 0; i < len(stringarr); i++ {
Printer(stringarr[i], colorizedchar, style, widthrest, alignparam, nbrspace) //print avec tout les arguments
}
}
if outputcheck == true {
//permet de créer un fichier dans lequel ce trouvera la sortie
sep := string(rune(92)) + "n"
stringarr := strings.Split(arg1, sep)
jump := 0
file, _ := os.Create(filename)
for i := 0; i < len(stringarr); i++ {
for h := 1; h <= 8; h++ {
for j := 0; j < len(stringarr[i]); j++ {
word := stringarr[i]
letter := ReadLine(word[j], h, style, widthrest, alignparam, nbrspace)
jump++
filewriter, _ := file.WriteString(letter)
if jump == len(word) && filewriter == filewriter {
jump = 0
filewriter, _ = file.WriteString("\n")
}
}
}
}
file.Sync()
}
}
func Printer(s string, couleur Color, style string, width int, param string, nbrspace int) {
compteur := 0 // sert a compter le nombre de lettre ou se trouve , pour passer a la ligne suivante dans le standart.txt
for i := 1; i <= 8; i++ { //boucle sur chaque etage "hauteur"
for j := 0; j < len(s); j++ { //boule sur la "longueur" du mot
//lier au flag "align", permet de choisir les différentes options de positionnement du texte
switch param {
case "center":
if compteur == 0 && width != 0 {
for d := 1; d <= width/2-2; d++ {
fmt.Print(" ")
}
}
case "right":
if compteur == 0 && width != 0 {
for d := 1; d <= width-2; d++ {
fmt.Print(" ")
}
}
}
if param == "justify" && nbrspace == 0 {
if compteur == 0 && width != 0 {
for d := 1; d <= width/2-2; d++ {
fmt.Print(" ")
}
}
}
compteur++
if compteur == len(s) { //passe a la ligne suivante quand
compteur = 0
Colorizeln(couleur, ReadLine(s[j], i, style, width, param, nbrspace))
} else {
Colorize(couleur, ReadLine(s[j], i, style, width, param, nbrspace))
}
}
}
}
//permet de lire les fichiers txt ligne par ligne afin de les imprimer
func ReadLine(letter byte, n int, style string, width int, param string, nbrspace int) string {
//Permet de trouver la ligne à laquelle se trouve notre caractère
line := int((rune(letter)-31)+(8*(rune(letter)-32))) + n // "rune lettre - 31" = pour commencer a regarder la bonne ligne | une lettre = 8 de hauteur , rune letter = lettre actuellement dans le mot ,// 32 = "espace en ASCII et ligne 0 du txt" | +n = pour savoir l'etage.
file, _ := os.Open(style) //pour aller dans le fichier style
stringline, _, _ := ReadChar(file, line) // lire le charactère
if param == "justify" { // savoir quand on est sur un espace | si le charactère es tun espace on met un espace
if rune(letter) == ' ' {
for i := 0; i < (width/nbrspace)-6-2; i++ { // width = taille qui reste dans le terminale divisé par le nombre d'espace - 6 = largeur en ASCII et -2 = "/n
stringline = stringline + " "
}
}
}
return stringline
}
//permet de transformer une ligne du txt en string - lire les charactères 1 par 1
func ReadChar(r io.Reader, lineNum int) (line string, lastLine int, err error) {
sc := bufio.NewScanner(r)
for sc.Scan() {
lastLine++
if lastLine == lineNum {
return sc.Text(), lastLine, sc.Err()
}
}
return line, lastLine, io.EOF
}
//Color (permet d'assigner une couleur à une constante)
type Color string
const (
black Color = "\u001b[30m"
red = "\u001b[31m"
green = "\u001b[32m"
yellow = "\u001b[33m"
blue = "\u001b[34m"
pink = "\u001b[35m"
cyan = "\u001b[36m"
orange = "\u001b[38;5;208m"
ColorReset = "\u001b[0m"
)
//permet de print une couleur sans saut de ligne
func Colorize(color Color, message string) {
fmt.Print(string(color), message, ColorReset)
}
//permet de print une couleur avec saut de ligne
func Colorizeln(color Color, message string) {
fmt.Println(string(color), message, ColorReset)
}
//retoune une string avec la largeur et la hauteur du terminal séparées pas un espace
func size() (string, error) {
cmd := exec.Command("stty", "size")
cmd.Stdin = os.Stdin
out, err := cmd.Output()
return string(out), err
}
//permet split la largeur et hauteur
func parse(input string) (uint, error) {
parts := strings.Split(input, " ")
y, err := strconv.Atoi(strings.Replace(parts[1], "\n", "", 1))
if err != nil {
return 0, err
}
return uint(y), nil
}
//retourne la largeur du terminal
func Width() uint {
output, err := size()
if err != nil {
return 0
}
width, _ := parse(output)
return width
}
```