Remplir automatiquement un tableau à l'aide d'un fichier externe (de type tableur) et de lua

Fleuron

Tu possèdes une séries de données stockées dans un tableur et tu as besoin de les afficher dans un tableau sous ConTeXt. Au lieu de remplir ton tableau à l'aide de copier-coller, voici une méthode pour automatiser la chose.

Pour ce faire nous allons utiliser lua qui est un langage de script, facilement intégrable dans ConTeXt.

Pour cette fiche nous avons besoin d'un fichier texte contenant nos données. Tu trouveras dans cette fiche comment transférer dans un fichier texte des données issues d'un tableur. Nous allons utiliser un fichier contenant les consommations de bières des participants du Grand Concours de Buveur de Bière de Knokke-Le-Zoute. Les concurrents pour faire passer la bière avaient le droit d’ingurgiter des moules et des frites, valeurs qui sont également notées dans le fichier :

;Bière en litre; Frites en kg;Moules en litre
Sophie;21;5;8
Ginette;2;6;2
Robert;12;3;7
Roland;5;9;5
Marcel;7;10;10

Les données sont séparées par des points-virgules ; le fichiers se nomme concours.txt

Pour intégrer du code lua dans un fichier ConTeXt, il faut l'encadrer par

\startluacode
. . . code lua . . .
\stopluacode

La première chose à faire est de lire notre fichier concourt.txt. Ceci ce fait par la commande lua

io.open("nom du fichier", "r")

Le "r" signifie read (lire). Tu remplaces nom du fichier par le chemin complet si le fichier est dans un autre répertoire que celui de ton fichier ConTeXt, par exemple :

io.open("/home/bebert/lua-test/concourt.txt", "r")

N'oublie pas les "

Il faut placer le fichier lu dans une variable que l'on va appeler fr (pour fichier), tu mets le nom que tu veux.

fr = assert(io.open("/home/bertrand/lua/test2.txt", "r"))

Maintenant il nous faut faire deux chose :

Le lecture ligne par ligne se fait par :

for line in fr.lines(fr) do … end

Les . . . sont à remplacer par des commandes à exécuter pour chaque ligne.

Pour découper nos lignes nous utilisons la fonction :

for c in string.gmatch(line,"%P+") do … end

Le c est une variable, moi j'ai choisi c pour cellule, mais tu mets ce que tu veux (m pour mot, par exemple). string.gmatch est la fonction de découpage. Le "%P+" est un motif (pattern en anglais et en langage informatique) qui permet de découper la ligne à chaque Ponctuation.

Attention si des éléments de ton tableau contiennent des signes de ponctuation comme des chiffres décimaux cette méthode ne va pas marcher, il faudra employer un autre pattern.

Les . . . sont à remplacer par des commandes à exécuter pour chaque cellule.

Bien nous avons toutes les commandes lua nécessaires, il ne reste plus qu'a construire le tableau. Je te renvoie à la fiche ConTeXt et les tableaux qui te donnera tous les détails sur la fabrication des tableaux sous ConTeXt. Pour rappel

Donc le code suivant :

\starttext
\bTABLE
\bTR \bTD colonne 1 ligne 1\eTD \bTD c2 l1 \eTD \bTD c3 l1 \eTD \eTR
\bTR \bTD colonne 1 ligne 2\eTD \bTD c2 l2 \eTD \bTD c3 l2 \eTD \eTR
\bTR \bTD colonne 1 ligne 3\eTD \bTD c2 l3 \eTD \bTD c3 l3 \eTD \eTR
\eTABLE
\stoptext

donne


Pour intégrer un environnement ConTeXt dans du code lua il faut le précéder de context. et suivre de ( ) vides. Donc les premières lignes d'un tableau :

context.bTABLE()
context.bTR()
… le tableau …
context.eTR()
context.eTABLE()

Le même principe s'applique à tous les environnements, par exemple les listes :

context.startitemize()
context.item("le texte du premier item")
context.item("le texte du deuxième item")
context.stopitemize()

Pour les autres commandes ou pour écrire dans le document final à partir d'une section de code lua il faut employer context() :

\starttext
\startluacode
g="Ginette c'est la plus experte."
context("Madame Michu c'est la plus têtue.")
context("\\crlf")

context(g)
\stopluacode
\stoptext

produit :


En lua toute chaine de caractère doit être encadrée de " ". Le signe = attibue une valeur à une variable comme dans g="Ginette …" . Si tu veux placer une commande ConTeXt dans une chaine de caractère tu dois la précéder de \, tu as donc 2 \\ comme pour crlf qui permet de changer de paragraphe. crlf n'est pas une variable donc doit être encadrée de " ".

Une petite remarque avant de poursuivre : en lua les commentaires débute avec -- et pas % qui provoquera des erreurs.

Passer une option à une commande ConTeXt est un peu subtil. Par exemple pour passer l'option 2 à \startitemize qui permet d'avoir les – français au lieu des • anglais il faut mettre le 2 dans les () en l'encadrand de {}, comme ceci

context.startitemize({2})

Si tu veux une liste numérotée, option n, comme ce n'est ni une variable ni un chiffre il faut en plus l'encadrée de " "

context.startitemize({"n"})

Pour des options du type clé=valeur, tu dois également des encadrer de {}, clé étant une variable, pas de "", mais valeur qui n'en est pas une en a besoin. Voici par exemple comment indiquer à un tableau de s'étaler sur plusieurs page s'il est trop grand :

context.bTABLE({split="yes"})

Avec ConTeXt il est toujours possible de programmer l'aspect des divers éléments dans l'entête, donc tu ne devrais pas avoir besoin de jongler de cette façon.

On a tous les éléments pour fabriquer notre tableau. Le début du code :

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))

\stopluacode
\stoptext

On a chargé notre fichier concours.txt dans la variable fr

Maintenant on ouvre notre tableau :

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()

\stopluacode
\stoptext

À chaque foi que l'on lit une ligne de notre fichier on crée un nouvelle ligne dans notre tableau :

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()
for line in fc.lines(fc) do

context.bTR()

end
\stopluacode
\stoptext

On sépare chaque élément de la ligne et on rempli une cellule du tableau

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()
for line in fc.lines(fc) do

context.bTR()
for c in string.gmatch(line,"%P+") do

context.bTD() context(c) context.eTD()

end …
end \stopluacode
\stoptext

On referme la ligne du tableau

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()
for line in fc.lines(fc) do

context.bTR()
for c in string.gmatch(line,"%P+") do

context.bTD() context(c) context.eTD()

end context.eTR()
end

\stopluacode
\stoptext

On ferme le tableau

\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()
for line in fc.lines(fc) do

context.bTR()
for c in string.gmatch(line,"%P+") do

context.bTD() context(c) context.eTD()

end context.eTR()
end
context.eTABLE()
\stopluacode
\stoptext

et l'on obtient le code complet qui donne après compilation :


Que l'on peut améliorer facilement par :

\setupcolors[state=start]

\setupTABLE[each][each][width=4cm,height=2em,align={middle,middle}]
\setupTABLE[r][1][background=color,backgroundcolor=gray]
\setupTABLE[c][1][background=color,backgroundcolor=gray]
\starttext

\startluacode

fc = assert(io.open("/home/bertrand/lua/concours.txt", "r"))
context.bTABLE()
for line in fc.lines(fc) do

context.bTR()
for c in string.gmatch(line,"%P+") do

context.bTD() context(c) context.eTD()

end context.eTR()
end
context.eTABLE()
\stopluacode
\stoptext

voire la fiche ConTeXt et les tableaux pour les explications.


Si ton tableau risque de s'étaler sur plusieurs pages tu ajoutes un :

\setupTABLE[split=yes]

Pour utiliser des ponctuations dans les données il faut utiliser un autre séparateur de champ. Lorsque tu transformes les données d'un tableur à un fichier texte tu choisis la tabulation comme séparateur de champ. Tu obtiens un fichiers du type :

Bière en litre Frites en kg Moules en litre
Sophie 21,5 5 8
Ginette 2 6,2 2
Robert 12 3 7
Roland 5 9 5,5
Marcel 7 10.2 10

Pour les tabulations le motif est "%C+". Donc avec le même code que ci-dessus en remplaçant

for c in string.gmatch(line,"%P+") do


par

for c in string.gmatch(line,"%C+") do


Tu obtiens :


Ce qui n'est pas terrible car il manque la première cellule vide sur la première ligne. En effet lors de la sauvegarde en fichier texte le tableur n'a pas ajouté de blanc pour indiquer une cellule vide. Il faut le rajouter à la main (indiqué par un _ dans l'exemple ci-dessous (tu ne mets pas _ dans ton texte, c'est juste pour que tu voies bien l'espace ajouté) :

_ Bière en litre Frites en kg Moules en litre Sophie 21,5 5 8 Ginette 2 6,2 2 Robert 12 3 7 Roland 5 9 5,5 Marcel 7 10.2 10

Maintenant tu obtiens bien le résultat désiré :


Un autre pattern peut être utile est celui discriminant les espaces qui est "%S+", que l'on ne peut utiliser dans l'exemple ci-dessus car il ne permet pas de créer la première cellule vide.