Convertir tableau wikicode en html [Résolu]

Signaler
-
 PixelReveur -
Bonjour,

J'ai besoin de créer une fonction pour convertir du wikicode vers du html.
Je m'en sort pas trop mal mais les tableaux me posent pas mal de soucis...

En gros à partir de ce genre d'entrée :
{| CLASS="ClassTableau"
|+ Contenu caption
|- CLASS="ClassLigne1"
| Contenu cellule 1 || Contenu cellule 2
|- CLASS="ClassLigne2"
| CLASS="ClassCellule3" | Contenu cellule 3
| CLASS="ClassCellule4" | Contenu cellule 4
|-
| CLASS="ClassCellule5" | Contenu cellule 5
| CLASS="ClassCellule6" | Contenu cellule 6
|}

Il me faut ressortir ce genre de code :
<table CLASS="ClasseTableau">
<caption>Contenu caption</caption>
<tr CLASS="ClassLigne1">
<td>Contenu cellule 1</td><td>Contenu cellule 2</td>
</tr><tr CLASS="ClassLigne3">
<td CLASS="ClassCellule3">Contenu cellule 3</td>
<td CLASS="ClassCellule4">Contenu cellule 4</td>
</tr><tr>
<td CLASS="ClassCellule5">Contenu cellule 5</td>
<td CLASS="ClassCellule6">Contenu cellule 6</td>
</tr>
</table>

Je me doute que ça va passer par du preg_replace mais j'ai du mal a sortir quelque chose de propre...

Quelqu'un à ce qu'il faut dans ses cartons ?

Merci

3 réponses

Salut,
essayer simplement d'écrire un algorithme.
Après ce "genre d'entrée" comme vous dites c'est du texte. Effectivement si vous voulez décomposer un texte en valeurs/variables vous devez repérer d'abord les 'bornes' indiquant les différents éléments.
Voir aussi la notion de tableau(array) en programmation(et aussi ça parce que preg_replace n'a rien à faire ici(vous ne voulez pas remplacer quoique ce soit mais lister des données et leur type) et c'et à partir de cette liste que vous pouvez écrire le résultat à afficher(un tableau HTML):
https://www.php.net/manual/fr/ref.strings.php
)

Il y a un problème qui me semble important:
_les données que vous avez n'ont aucune séparation, il serait évidemment mieux d'avoir une source de type CSV ou JSON (voire XML ou autre format ) qui sont des formats de manipulation de données.
Solutions:
  • soit lors de l'acquisition des données dans le système(la meilleure façon de faire) vous vous débrouiller pour écrire dans un format adéquat(ou même un objet ou des tableaux de variables).
  • la plus mauvaise solution: vous lisez ligne par ligne en fixant les règles afin de convertir dans un format exploitable... et encore ça ne semble pas faisable sur votre exemple.


Ensuite puisque le format indiquera les séparations (et donc les différents éléments) vous n'avez qu'à interpréter celui ci dans une boucle.

Problèmes majeurs:

=> Dans le cas que vous présentez sur la ligne 4 il n'y aucun moyen de différencier qu'il s'agit de 2 contenus, sinon pour toutes les autres lignes on peut trouver une manière d'obtenir le contenu des cellules (il sont entre le symbole | sur chaque ligne et la fin de la ligne)ou le nom des class(après le mot CLASS un symbole '=' et entre des guillemets).

=> Si on peut pallier au premier problème il y en a un qui n'a pas de solution(sauf à revoir la façon dont vous acquérez les données dans votre système d'informations).
En effet une table ce sont des lignes et des colonnes. Ici il n'y aucun moyen de savoir si les données sont sur la m^me ligne ou quand changer de ligne.
Vous êtes donc restreint à un tableau sur une seule ligne sans aucun nom de colonnes ou indication sur ces colonnes/lignes. Dans ce cas cela revient à utiliser une chaîne de caractéres(string):
<?
echo ( '<p>'.$mot1.' séparateur'.$mot2.' séparateur'.$mot3.'séparateur'.$mot4.'</p>' );

?>

Bien sûr vous aurez des possibilités de faire autrement mais elles seront sales et surtout complexes et inadaptées car vous perdez des données(en tout cas si vous avez besoin des données fournies) et que non seulement le format des données est à extraire ligne par ligne(au lieu d'être repéré par des éléments comme des 'balises/repères/séparateur' simples à traiter pour un programme) mais le système doit acquérir les données 2 fois(au lieu d'une en ayant directement un JSON/XML ou CSV dès le départ) mais surtout la moindre différence(une valeur située sur une autre ligne, le nombre de contenus à afficher) va enrayer la machine et cela ne fonctionnera plus...à moins de faire un script différent pour chaque cas et on perds complétement l'utilité d'un traitement automatisé par ordinateur car il y aura une infinité de cas possibles à traiter...et écrire une infinités de codes pour une seule action aussi simple vous prendra un temps infini.

Bref plutôt que de chercher une solution dans l'écriture cherchez plutôt à améliorer comment vous obtenez les données.
Justement un wikicode c'est une syntaxe proche de HTML, pourquoi convertir l'un dans l'autre? Mieux vaut utiliser les données brutes(lors de l'extraction comme de l'affichage) et c'est quand vous devez les afficher que vous vous vous en servez.

Pour ça il suffit de faire des variables (voir array ou même l'objet) qui contiennent toutes les informations:

_la classe du tableau
_la liste des contenus avec leur catégories et les classes utilisées(chacune des valeurs doit être associée). $contenus[['blabla', 'classCSS' ,'catégorie'], ['boulouboulou', 'classCSS','catégorie']]

Ici chaque catégorie sera le nom des colonnes. Donc on peut connaître le nombres de colonnes à afficher en les comptant. Ce qui n'est pas possible dans l'exemple que vous fournissez. Idem pour le nombre de lignes.
Messages postés
29558
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
17 septembre 2020
2 779
Bonjour,

il va falloir utiliser les REGEX.
Sachant que tu as :
"
" pour le finir.
"|+" début de "caption"
"|-" début de "tr"
"|" début de "td"

On pourrait donc avoir une regex du genre
^{\|\sCLASS="(.+)"((?s).+)\|}$

Pour identifier la partie "tableau" et sa class.
Ensuite, faut faire la même chose pour les TR et les TD...




Bon, c'est loin d'être parfait mais je suis parvenu à faire quelque chose qui fonctionne :
$texte = preg_replace("#{\|(.+?)\|#s", "<table $1>|", $texte);
$texte = str_replace("|}", "</table>", $texte);
$texte = preg_replace("#\|\+(.+?)\|#s", "<caption>$1</caption>|", $texte);
$texte = str_replace("|-|", "</td></tr><tr>|", $texte);
$texte = preg_replace("#\|-(.+?)\|#s", "</td></tr><tr $1>|", $texte);
$texte = preg_replace("#\| ROWSPAN=(.+?)\|#is", '</td><td ROWSPAN=$1>|' , $texte);
$texte = preg_replace("#\| COLSPAN=(.+?)\|#is", '</td><td COLSPAN=$1>|' , $texte);
$texte = preg_replace("#\| CLASS=(.+?)\|#is", '</td><td CLASS=$1>' , $texte);
$texte = str_replace("||", "|", $texte);
$texte = str_replace("|", "</td><td>", $texte);