Liens et texte en mode flot

Ce tutoriel explique comment insérer des liens (internes et externes) et montre un nouveau mode d'écriture du texte. Il contient également un parseur HTML rudimentaire.

<?php
define('FPDF_FONTPATH','font/');
require(
'fpdf.php');

class
PDF extends FPDF
{
var
$B;
var
$I;
var
$U;
var
$HREF;

function
PDF($orientation='P',$unit='mm',$format='A4')
{
    
//Appel au constructeur parent
    
$this->FPDF($orientation,$unit,$format);
    
//Initialisation
    
$this->B=0;
    
$this->I=0;
    
$this->U=0;
    
$this->HREF='';
}

function
WriteHTML($html)
{
    
//Parseur HTML
    
$html=str_replace("\n",' ',$html);
    
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
    foreach(
$a as $i=>$e)
    {
        if(
$i%2==0)
        {
            
//Texte
            
if($this->HREF)
                
$this->PutLink($this->HREF,$e);
            else
                
$this->Write(5,$e);
        }
        else
        {
            
//Balise
            
if($e{0}=='/')
                
$this->CloseTag(strtoupper(substr($e,1)));
            else
            {
                
//Extraction des attributs
                
$a2=explode(' ',$e);
                
$tag=strtoupper(array_shift($a2));
                
$attr=array();
                foreach(
$a2 as $v)
                    if(
ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
                        
$attr[strtoupper($a3[1])]=$a3[2];
                
$this->OpenTag($tag,$attr);
            }
        }
    }
}

function
OpenTag($tag,$attr)
{
    
//Balise ouvrante
    
if($tag=='B' or $tag=='I' or $tag=='U')
        
$this->SetStyle($tag,true);
    if(
$tag=='A')
        
$this->HREF=$attr['HREF'];
    if(
$tag=='BR')
        
$this->Ln(5);
}

function
CloseTag($tag)
{
    
//Balise fermante
    
if($tag=='B' or $tag=='I' or $tag=='U')
        
$this->SetStyle($tag,false);
    if(
$tag=='A')
        
$this->HREF='';
}

function
SetStyle($tag,$enable)
{
    
//Modifie le style et sélectionne la police correspondante
    
$this->$tag+=($enable ? 1 : -1);
    
$style='';
    foreach(array(
'B','I','U') as $s)
        if(
$this->$s>0)
            
$style.=$s;
    
$this->SetFont('',$style);
}

function
PutLink($URL,$txt)
{
    
//Place un hyperlien
    
$this->SetTextColor(0,0,255);
    
$this->SetStyle('U',true);
    
$this->Write(5,$txt,$URL);
    
$this->SetStyle('U',false);
    
$this->SetTextColor(0);
}
}

$html='Vous pouvez maintenant imprimer facilement du texte mélangeant
différents styles : <B>gras</B>, <I>italique</I>, <U>souligné</U>, ou
<B><I><U>tous à la fois</U></I></B> !<BR>Vous pouvez aussi insérer des
liens sous forme textuelle, comme <A HREF="http://www.fpdf.org">
www.fpdf.org</A>, ou bien sous forme d\'image : cliquez sur le logo.'
;

$pdf=new PDF();
//Première page
$pdf->AddPage();
$pdf->SetFont('Arial','',20);
$pdf->Write(5,'Pour découvrir les nouveautés de ce tutoriel, cliquez ');
$pdf->SetFont('','U');
$link=$pdf->AddLink();
$pdf->Write(5,'ici',$link);
$pdf->SetFont('');
//Seconde page
$pdf->AddPage();
$pdf->SetLink($link);
$pdf->Image('logo.png',10,10,30,0,'','http://www.fpdf.org');
$pdf->SetLeftMargin(45);
$pdf->SetFontSize(14);
$pdf->WriteHTML($html);
$pdf->Output();
?>

La nouvelle méthode pour imprimer du texte est Write(). Elle est très proche de MultiCell() ; les différences sont les suivantes : Elle permet donc d'écrire une portion de texte, de modifier la police, puis de reprendre à partir de l'endroit où on était resté. Par contre on ne peut plus justifier.

La méthode est utilisée sur la première page pour mettre un lien pointant sur la seconde. Le début de la phrase est écrit en style normal, puis on passe en souligné pour terminer. Le lien est créé grâce à la méthode AddLink(), qui renvoie l'identifiant du lien. Cet identifiant est passé en troisième paramètre à Write(). Après avoir créé la seconde page, on utilise SetLink() pour faire pointer le lien sur le début de la page courante.

On place ensuite une image avec un lien externe dessus. Un lien externe pointe sur une URL (HTTP, mailto...). L'URL est simplement transmise en dernier paramètre de Image(). A noter que les liens externes ne fonctionnent pas lorsque le PDF est affiché dans le plug-in de Netscape.

Enfin, la marge gauche est déplacée après l'image grâce à SetLeftMargin() et du texte au format HTML est imprimé. Un parseur HTML est utilisé pour cela, reposant sur la fonction de découpage avec expression régulière preg_split() et l'option PREG_SPLIT_DELIM_CAPTURE (introduite en PHP 4.0.5) qui permet de récupérer les séparateurs (c'est-à-dire ici les balises). Si vous utilisez une version antérieure, remplacez la ligne par celle-ci :

$a=preg_split('/[<>]/',$html);

qui est moins rigoureuse mais donne les mêmes résultats avec de l'HTML bien formé.
Les balises reconnues sont <B>, <I>, <U>, <A> et <BR> ; les autres sont ignorées. Le parseur utilise lui aussi la méthode Write(). Le lien externe se pose de la même façon que l'interne (troisième paramètre de Write()). A noter que Cell() permet également de poser des liens.