1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| //Fonction pour éclater la chaîne selon les tableaux (gestion de l'imbrication infinie)
function split_imbricated_table(&$contents)
{
$contents = preg_split('`\[table( style="[^"]+")?\]((?:[^[]|\[(?!/?table(?: style="[^"]+")?\])|(?R))+)\[/table\]`', $contents, -1, PREG_SPLIT_DELIM_CAPTURE);
//1 élément représente les inter tableaux, un le style du tableau et l'autre le contenu
$nbr_occur = count($contents);
for( $i = 0; $i < $nbr_occur; $i++)
{
if( $i % 3 === 2 && preg_match('`\[table(?: style="[^"]+")?\].+\[/table\]`s', $contents[$i]) )
{
//C'est le contenu d'un tableau, il contient un sous tableau donc on éclate
split_imbricated_table($contents[$i]);
}
}
}
//Fonction qui parse les tableaux dans l'ordre inverse à l'ordre hiérarchique
function parse_imbricated_table(&$contents)
{
if( is_array($contents) )
{
$string_contents = '';
$nbr_occur = count($contents);
for($i = 0; $i < $nbr_occur; $i++)
{
//Si c'est le contenu d'un tableau on le parse
if( $i % 3 === 2 )
{
//On parse d'abord les sous tableaux éventuels
parse_imbricated_table($contents[$i]);
//On parse le tableau concerné (il doit commencer par [row] puis [col] ou [head] et se fermer pareil moyennant espaces et retours à la ligne sinon il n'est pas valide)
if( preg_match('`^(?:\s|<br />)*\[row(?: rowspan="[0-9]+")?\](?:\s|<br />)*\[(?:col|head)(?: colspan="[0-9]+")?(?: style="[^"]+")?\].*\[/col|head\](?:\s|<br />)*\[/row\](?:\s|<br />)*$`s', $contents[$i]) )
{
//On nettoie les caractères éventuels (espaces ou retours à la ligne) entre les différentes cellules du tableau pour éviter les erreurs xhtml
$contents[$i] = preg_replace('`^(?:\s|<br />)*(\[row\].*\[/row\])(?:\s|<br />)*$`s', '$1', $contents[$i]);
$contents[$i] = preg_replace('`(\[/?(?:col|row|head)(?: colspan="[0-9]+")?(?: style="[^"]+")?\])(\s|<br />)+(\[/?(?:col|row|head)(?: colspan="[0-9]+")?(?: style="[^"]+")?\])`U', '$1$3', $contents[$i]);
//Parsage de row, col et head
$contents[$i] = preg_replace('`\[row\](.*)\[/row\]`sU', '<tr>$1</tr>', $contents[$i]);
$contents[$i] = preg_replace('`\[col((?: rowspan="[0-9]+")?(?: colspan="[0-9]+")?(?: style="[^"]+")?)?\](.*)\[/col\]`sU', '<td class="bb_table_col"$1>$2</td>', $contents[$i]);
$contents[$i] = preg_replace('`\[head((?: colspan="[0-9]+")?(?: style="[^"]+")?)?\](.*)\[/head\]`sU', '<th class="bb_table_head"$1>$2</th>', $contents[$i]);
//parsage réussi (tableau valide), on rajoute le tableau devant
$contents[$i] = '<table class="bb_table"' . $contents[$i - 1] . '>' . $contents[$i] . '</table>';
}
else
{
//le tableau n'est pas valide, on met des balises temporaires afin qu'elles ne soient pas parsées au niveau inférieur
$contents[$i] = str_replace(array('[col', '[row', '[/col', '[/row', '[head', '[/head'), array('[\col', '[\row', '[\/col', '[\/row', '[\head', '[\/head'), $contents[$i]);
$contents[$i] = '[table' . $contents[$i - 1] . ']' . $contents[$i] . '[table]';
}
}
//On concatène la chaîne finale si ce n'est pas le style du tableau
if( $i % 3 !== 1 )
$string_contents .= $contents[$i];
}
$contents = $string_contents;
}
}
function parse_table(&$contents)
{
//Cette ligne n'est à mettre que si vous avez passé un htmlentities à votre code au préalable
$contents = preg_replace_callback('`\[(?:table|col|row|head)(?: colspan="[0-9]+")?(?: rowspan="[0-9]+")?( style="(?:[^&]+)")?\]`U', create_function('$matches', 'return str_replace(\'"\', \'"\', $matches[0]);'), $contents);
split_imbricated_table($contents);
parse_imbricated_table($contents);
//On remet les tableaux invalides tels qu'ils étaient avant
$contents = str_replace(array('[\col', '[\row', '[\/col', '[\/row', '[\head', '[\/head'), array('[col', '[row', '[/col', '[/row', '[head', '[/head'), $contents);
} |
Partager