25-07-2011, 11:36 AM
J'ai fait ce petit bout de code qui corrige les problemes les plus courant (oublie de fermeture de balise)
Maintenant il ne gere par l'imbrication foireuse dans tous les cas.
Par exemple:
rendra du code html mais ne sera pas valide.
Ton code ruby est il capable de corriger ca?
Code :
<?php
class WChainesHTML
{
public $debug=0;
public $nb_balise_ouvrante=0;
public $nb_balise_fermante=0;
public $Texte;
public $decalage=0;
public $Balises=array('u','a','p','i','div','span','font','b','center');
function __tostring() {return "Cette classe permet de fermer les balises html en trop.";}
//Constructeur
function __construct($texte)
{
$this->Texte=$texte;
if($this->debug==1) echo "<br>".htmlentities($this->Texte,ENT_IGNORE, "UTF-8");
//pour chaque balise qu'on vérifie
foreach($this->Balises as $balise)
{
$this->nb_balise_ouvrante = substr_count($this->Texte,'<'.$balise.'>')+substr_count($this->Texte,'<'.$balise.' ');
$this->nb_balise_fermante = substr_count($this->Texte,'</'.$balise.'>');
if($this->debug==1) echo "<br>".$balise.'/'.$this->nb_balise_ouvrante.'/'.$this->nb_balise_fermante."<br>";
if($this->nb_balise_ouvrante!=$this->nb_balise_fermante)
{
if($this->nb_balise_ouvrante>$this->nb_balise_fermante) $this->ajoute_chaine_fermante($balise);
if($this->nb_balise_ouvrante<$this->nb_balise_fermante) $this->ajoute_chaine_ouvrante($balise);
if($this->debug==1) echo "<br>".htmlentities($this->Texte,ENT_IGNORE, "UTF-8").'<hr>';
}
}
if($this->debug==1) {
echo "<br><br><br>".htmlentities($this->Texte,ENT_IGNORE, "UTF-8");
echo "<br>";
for($i=0;$i<strlen($this->Texte);$i++)
echo $i.'-'.substr($this->Texte,$i,1)."<br>";}
}
function trouve_chaine_ouvrante($texte,$balise)
{
$po=0;$POSITIONS_OUVRANTES=array();
$text_temp=$texte;
do
{
$pos_pure=strpos($text_temp,'<'.$balise.' ');
if($po>0) $pos=$pos_pure+$POSITIONS_OUVRANTES[$po-1]+2+strlen($balise);
else $pos=$pos_pure;
$text_temp=substr($text_temp,$pos_pure+2+strlen($balise),strlen($text_temp)-$pos_pure-2-strlen($balise));
if($pos>-1) {$POSITIONS_OUVRANTES[$po]=$pos; $po++;}
}
while(!strpos($text_temp,'<'.$balise.' ')===false);
$po=0;$POSITIONS_OUVRANTES2=array();
$text_temp=$texte;
do
{
$pos_pure=strpos($text_temp,'<'.$balise.'>');
if($po>0) $pos=$pos_pure+$POSITIONS_OUVRANTES2[$po-1]+2+strlen($balise);
else $pos=$pos_pure;
$text_temp=substr($text_temp,$pos_pure+2+strlen($balise),strlen($text_temp)-$pos_pure-2-strlen($balise));
if($pos>-1) {$POSITIONS_OUVRANTES2[$po]=$pos; $po++;}
}
while(!strpos($text_temp,'<'.$balise.'>')===false);
return array_merge($POSITIONS_OUVRANTES,$POSITIONS_OUVRANTES2);
}
function trouve_chaine_fermante($texte,$balise)
{
$po=0;$POSITIONS_FERMANTES=array();
$text_temp=$texte;
do
{
$pos_pure=strpos($text_temp,'</'.$balise.'>');
if($po>0) $pos=$pos_pure+$POSITIONS_FERMANTES[$po-1]+3+strlen($balise);
else $pos=$pos_pure;
$text_temp=substr($text_temp,$pos_pure+3+strlen($balise),strlen($text_temp)-$pos_pure-3-strlen($balise));
if($pos>-1) {$POSITIONS_FERMANTES[$po]=$pos; $po++;}
}
while(!strpos($text_temp,'</'.$balise.'>')===false);
return $POSITIONS_FERMANTES;
}
function ajoute_chaine_fermante($balise)
{
//on récupére les positions des balises ouvrantes et fermantes
$POSITIONS_OUVRANTES=$this->trouve_chaine_ouvrante($this->Texte,$balise);sort($POSITIONS_OUVRANTES);
if($this->debug==1) echo "<br>"; if($this->debug==1) print_r($POSITIONS_OUVRANTES);
$POSITIONS_FERMANTES=$this->trouve_chaine_fermante($this->Texte,$balise);sort($POSITIONS_FERMANTES);
if($this->debug==1) echo "<br>"; if($this->debug==1) print_r($POSITIONS_FERMANTES);
foreach($POSITIONS_OUVRANTES as $cle=>$position)
{
$pos1=$position+$this->decalage;
if(array_key_exists($cle+1,$POSITIONS_OUVRANTES)) $pos2=$POSITIONS_OUVRANTES[$cle+1]+$this->decalage;
else $pos2=0;
if($this->debug==1) echo "<br>".$pos1.'/'.$pos2;
//si il y a au moins une balise fermante
$pos_fermante=-1;
if(count($POSITIONS_FERMANTES)>0)
{foreach($POSITIONS_FERMANTES as $cle=>$positionf) if($positionf>$pos1) {$pos_fermante=$positionf+$this->decalage; break;}}
else
$pos_fermante=-2;
//si la balise fermante est entre deux balises ouvrantes, on ferme directement
if($pos_fermante>0 and $pos_fermante>$pos2)
{
$fermeture= strpos($this->Texte,'>',$pos1);
if($this->debug==1) echo "<br>".$fermeture;
$this->Texte=substr($this->Texte,0,$fermeture+1).'</'.$balise.'>'.substr($this->Texte,$fermeture+1,strlen($this->Texte)-$fermeture-1);
$this->nb_balise_fermante++;
$this->decalage+=strlen('</'.$balise.'>');
}
elseif($pos_fermante==-2)//si on est à la fin, on ferme
{
$fermeture= strpos($this->Texte,'>',$pos1);
$this->Texte=substr($this->Texte,0,$fermeture+1).'</'.$balise.'>'.substr($this->Texte,$fermeture+1,strlen($this->Texte)-$fermeture-1);
$this->nb_balise_fermante++;
$this->decalage+=strlen('</'.$balise.'>');
}
if($this->nb_balise_ouvrante==$this->nb_balise_fermante) break;
}
}
function ajoute_chaine_ouvrante($balise)
{
//on récupére les positions des balises ouvrantes et fermantes
$POSITIONS_OUVRANTES=$this->trouve_chaine_ouvrante($this->Texte,$balise);
if($this->debug==1) echo "<br>"; if($this->debug==1) print_r($POSITIONS_OUVRANTES);
$POSITIONS_FERMANTES=$this->trouve_chaine_fermante($this->Texte,$balise);
if($this->debug==1) echo "<br>"; if($this->debug==1) print_r($POSITIONS_FERMANTES);
foreach($POSITIONS_FERMANTES as $cle=>$position)
{
$pos1=$position+$this->decalage;
if(array_key_exists($cle-1,$POSITIONS_FERMANTES)) $pos2=$POSITIONS_FERMANTES[$cle-1]+$this->decalage;
else $pos2=1000000;
if($this->debug==1) echo "<br>".$pos2.'/'.$pos1;
//si il y a au moins une balise fermante
$pos_ouvr=10000000;
if(count($POSITIONS_OUVRANTES)>0)
{foreach($POSITIONS_OUVRANTES as $cle=>$positiono) if($positiono<$pos1) {$pos_ouvr=$positiono+$this->decalage; break;}}
else
$pos_ouvr=20000000;
//si la balise fermante est entre deux balises ouvrantes, on ferme directement
if($pos_ouvr<10000000 and $pos_ouvr>$pos2)
{
$this->Texte=substr($this->Texte,0,$pos1).'<'.$balise.'>'.substr($this->Texte,$pos1,strlen($this->Texte)-$pos1);
$this->nb_balise_ouvrante++;
$this->decalage+=strlen('</'.$balise.'>')-1;
}
elseif($pos_ouvr==20000000)//si on est à la fin, on ferme
{
$this->Texte=substr($this->Texte,0,$pos1).'<'.$balise.'>'.substr($this->Texte,$pos1,strlen($this->Texte)-$pos1);
$this->nb_balise_ouvrante++;
$this->decalage+=strlen('</'.$balise.'>')-1;
}
if($this->nb_balise_ouvrante==$this->nb_balise_fermante) break;
}
}
}
?>
Maintenant il ne gere par l'imbrication foireuse dans tous les cas.
Par exemple:
Code :
<p>test<font>a</p></font>
Ton code ruby est il capable de corriger ca?