# 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
    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 :

- La fin de ligne est au niveau de la marge droite et la ligne suivante commence à la marge gauche
- La position courante se déplace juste à la fin du texte

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.