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(preg_match('/([^=]*)=["\']?([^"\']*)/',$v,$a3))
                        $attr[strtoupper($a3[1])]=$a3[2];
                }
                $this->OpenTag($tag,$attr);
            }
        }
    }
}

function OpenTag($tag,$attr)
{
    //Balise ouvrante
    if($tag=='B' || $tag=='I' || $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' || $tag=='I' || $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><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,12,30,0,'','http://www.fpdf.org');
$pdf->SetLeftMargin(45);
$pdf->SetFontSize(14);
$pdf->WriteHTML($html);
$pdf->Output();
?>

[Démo]

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().

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 très simple est utilisé pour cela, basé sur les expressions régulières. 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.