CSS

Explorer les possibilités des CSS pour l'impression avec Prince XML

Article par (Lyon, France)
Créé le , mis à jour le (30218 lectures)
Tags : css, xml, print, impression, pdf, princexml

Comme nous avons pu l'écrire dans le tutoriel sur les feuilles de style pour l'impression (si vous ne l'avez pas lu, c'est le moment !), les possibilités des CSS print sont intéressantes mais limitées, notamment à cause d'une implémentation très partielle par les navigateurs. Ceci devrait s'améliorer avec CSS3. Les feuilles de style pour l'impression permettent donc de rendre une page de site web ou un article imprimable, et agréable à lire sur papier, mais cela ne va pas beaucoup plus loin. Pour une mise en page complexe et plus maitrisée, le format de prédilection sera donc le PDF.

Mais générer du PDF avec une mise en page travaillée impose de produire un travail spécifique, avec un logiciel de traitement de texte ou de PAO. Ne pourrait-on pas utiliser notre page HTML pour générer du PDF? C'est ce que propose le logiciel Prince XML, qui produit du PDF à partir de documents HTML ou XML et... de feuilles de style CSS pour l'impression.

À propos de Prince XML

Prince XML est un logiciel propriétaire et payant[1] édité par la société YesLogic, dirigée par Håkon Wium Lie, un des papas des CSS et CTO (ingénieur-chef) d'Opera.

Cependant, il est possible d'utiliser une version gratuite. Cette version n'est pas particulièrement limitée, mais insère sur la première page des documents PDF générés un logo Prince XML. Celui-ci reste heureusement relativement discret, et ne sera pas présent à l'impression. On peut donc envisager l'utilisation de ce logiciel en version gratuite pour produire des documents personnels, associatifs, voire professionnels (notamment pour une petite entreprise). Et surtout, cela nous permettra de tester les possibilités de ce logiciel, et par la même occasion les possibilités des CSS print.

Liens utiles :

Petit test d'utilisation

Je n'ai pas exploré toutes les possibilités du logiciel, loin de là, mais j'étais curieux de voir ce que je pouvais obtenir avec ce logiciel. J'ai donc repris un des seuls documents web que j'avais travaillé en profondeur pour l'impression.[2] Le site en question est une version HTML du livre de Florent Latrive, Du Bon usage de la piraterie.

Le site dispose déjà d'une feuille de style pour l'impression. Celle-ci efface les éléments de navigation (via display: none;), définit le style du texte, et tente de définir le format de papier et les marges :

@page {
  size: A4 portrait;
  margin: 20mm 30mm;
}

Cependant, ces informations seront ignorées par la plupart des navigateurs. Mais pas par Prince ! Aussi peut-on se faire un peu plaisir. Lire un long texte sur une largeur de page A4, c'est fatiguant, car cela fait des lignes de texte trop longues. Et si on imprimait sur du papier A5 (la moitié d'un A4) ? Ainsi, il sera facile pour toute personne disposant d'une imprimante convenable d'imprimer deux pages de texte par feuille de papier (quatre pages en recto-verso).

Modifions donc ces informations de format !

@page {
  size: A5 portrait;
  margin: 16mm 18mm;
}

Mais on peut encore faire de nombreuses choses. Par exemple, créer des en-têtes et pied de pages dynamique. Pour ce test, j'ai créé un en-tête pour les pages de gauche contenant le texte « Du Bon usage de la piraterie », et un en-tête pour les pages de droite contenant le titre du chapitre. Enfin, on veut que la première page du document ait un en-tête vide. Cela fonctionne ainsi :

@page {
	@top {
		color: gray;
		font-size: 8pt;
		font-family: "Arial", "Helvetica", "Nimbus Sans L", sans-serif;
	} 
}
@page:left {
	@top {
		content: 'Du Bon usage de la piraterie';
		text-align: left;
	}
}
@page:right {
	@top {
		content: string(chapter);
		text-align: right;
	}
}
@page:first {
	@top {
		content: '';
	}
}

L'élément le plus « inattendu » ici est le string(chapter). Cette syntaxe est issue du module « Paged Media » de CSS 3, encore à l'état de brouillon. Quoi qu'il en soit, Prince saura quelle information aller chercher dans le document grâce à la règle suivante :

h2 span.chapitre {
  string-set: chapter content();
}

Bien sûr, chaque document n'a qu'un seul span portant la classe chapitre, et le contenu de ce span correspond bien au titre du chapitre. Voici un extrait du code HTML d'une page de chapitre :

<h2>Chapitre 5<br />
<span class="chapitre">Politique de l'immatériel</span></a></h2>

Le texte récupéré sera « Politique de l'immatériel ». Et voilà, le tour est joué. Pour les détails, vous pouvez consulter directement le fichier CSS concerné : prince.css. Il ne nous reste plus qu'à mouliner tout ceci avec Prince XML.

Passage à la moulinette

Sous Windows, Prince XML dispose d'une interface graphique, que j'ai eu l'occasion de tester rapidement. Elle est relativement simple, mais semble limitée si on veut passer des options un peu précises au logiciel (sauf erreur de ma part).

Sous Linux, il faut passer par la ligne de commande. L'utilisation de base n'est pas trop compliquée : par exemple, la commande prince monfichier.html crée un fichier monfichier.pdf en se servant de la feuille de style pour l'impression liée depuis la page HTML. Si aucune feuille de style pour l'impression n'est liée depuis la page, il suffira de l'indiquer en ligne de commande : prince -s impression.css monfichier.html. On a vu plus difficile. :)

Par défaut, Prince inclue les polices de caractères (fontes) aux fichiers PDF créés. Cela peut vite faire des fichiers assez volumineux, surtout si vous utilisez un nombre important de fontes. Il est aussi possible de ne pas inclure les fontes grâce à l'option --no-embed-fonts. À éviter si vous n'utilisez pas une « core font » comme Arial, Verdana ou Times New Roman...

Qu'est-ce que ça donne ?

Voici quelques exemples du résultat obtenu :

Une petite variation : A4 sur deux colonnes

Le problème du format A5, c'est qu'il faut que l'utilisateur pense à demander du deux pages par feuille dans les options d'impression. Sinon, il obtiendra du A5 imprimé au milieu d'une feuille A4, et bonjour le gaspillage de papier !

Une solution sympathique consiste à utiliser les propriétés CSS3 permettant de créer des colonnes pour réaliser une mise en page de type « deux pages sur une feuille A4 ». Voici ce que cela donne côté CSS (pour le détail, voir prince-alternative.css) :

@page {
  size: A4 landscape;
  margin: 24mm 20mm 18mm 20mm;
}
body {
  /* Mise en page deux colonnes pour format A4 */
  column-count: 2;
  column-fill: auto;
  column-gap: 40mm;
}

On utilise donc body comme conteneur principal, et on demande un affichage sur deux colonnes avec une largeur de colonne dynamique et un écart de quatre centimètres. On demande aussi un remplissage « automatique » (l'autre option étant « équilibré » : column-fill: balance;), colonne après colonne.

Et voici le résultat (fichiers PDF sans fontes incluses) :

Vous remarquerez quelques petites variations par rapport au code ci-dessus, variations qui m'ont permis de procéder à quelques tests de positionnement, par exemple. Les plus courageux voudront sans doute explorer la feuille de style complète (voir lien ci-dessus) pour retrouver ces détails.

Quelques précisions supplémentaires

Quelle version de CSS Prince comprend-t-il ?

Il me semble que Prince comprend la totalité (ou une très grande partie) des propriétés CSS 2.1 s'appliquant au média paginé (« Paged Media »). Pour rappel, CSS 2.1 est une spécification officielle du W3C (elle a le statut de « Candidate Recommendation » -- et ne vous laissez pas impressionner par le « candidate », il s'agit d'un statut très stable pour une spécification du W3C).

Prince utilise également des propriétés du module « Paged Media » de CSS 3. Or, ce module est à l'état de brouillon. Attention, donc : certaines propriétés, ou leur syntaxe exacte, pourraient évoluer à l'avenir !

Enfin, Prince utilise ses propres extensions, notamment des propriétés CSS « propriétaires ». Certaines peuvent être appelées de deux manières : prince-extension ou tout simplement extension. Par exemple, une propriété permettant de spécifier une zone de découpe peut s'écrire prince-bleed ou bien tout simplement bleed. Petit conseil : utilisez uniquement la version qui commence par prince-, afin de toujours garder à l'esprit qu'il ne s'agit pas d'une propriété standard CSS 2.1 ou CSS 3.

Est-ce qu'on peut utiliser la césure automatique du texte ?

J'ai testé l'activation de la césure du texte (hyphenation), via la propriété CSS 3 hyphens. Le résultat semble correct... pour des textes en langue anglaise. En effet, Prince n'inclue pas de dictionnaire de césure pour d'autres langues. Il est néanmoins possible d'appeler un dictionnaire de césure spécifique, notamment au format TeX. Pour la syntaxe exacte côté CSS, voir la documentation du logiciel.

Au sujet des dictionnaires de césure : je ne me suis pas penché plus longtemps sur le sujet, que je connais mal. Si un habitué de TeX/LaTeX voulait bien nous indiquer un dictionnaire de césure pour le français, ça serait pas mal. :)

Est-ce que Prince produit des documents PDF accessibles ?

La dernière version disponible (version 6.0r3) ne permet pas de produire des PDF accessibles. J'avoue mal connaitre le sujet, mais apparemment la prise en compte du « tagged PDF » qui permet de rendre ce format plus accessible n'est pas prévue avant la version 7.0. Affaire à suivre, donc...

Est-ce que je peux le tester sur mon serveur ?

Si vous avez les moyens, tout à fait. Mais vous aurez sans doute remarqué que Prince XML n'est pas donné : 3800 $ (USD) pour la licence serveur. Difficile donc d'imaginer la génération de PDF à la volée depuis un site web hors grosses entreprises, institutions publiques et universités. Pour une utilisation plus modeste, la seule possibilité restante est l'utilisation manuelle en monoposte, avec la version gratuite ou la version payante monoposte (495 $).

Quid de la concurrence ?

Le logiciel PDFreactor de la société RealObjects semble être un équivalent de Prince XML. Il s'agit d'un logiciel multiplateforme basé sur Java (nécessitant JRE 1.4.2 ou supérieur). La licence serveur a un cout à peu près équivalent (un peu meilleur marché). Une version de démonstration est disponible, avec des limitations semble-t-il plus importantes que pour Prince. Je n'ai pas encore testé ce logiciel.

Côté logiciels libres, à priori pas d'équivalent à ces logiciels. Citons tout de même : Apache FOP, qui permet de transformer du XML en PDF via XSL-FO, et FPDF, une classe PHP pour la génération de PDF. Hélas, chacun de ces deux outils demandera un apprentissage spécifique : celui de XSL-FO (à la facilité d'accès toute relative...) pour FOP, et celui des fonctions PHP de la classe fournie pour FPDF. De plus, FPDF n'exploite pas (une fois de plus : sauf erreur de ma part) des documents HTML ou XML existants, et il faudra indiquer en paramètre des fonctions utilisées non seulement les options de formatage du texte et de positionnement des éléments, mais aussi le contenu textuel de ces éléments.

Si vous avez connaissance d'autres outils exploitant HTML et/ou CSS pour produire du PDF, n'hésitez pas à nous les signaler.

Conclusion

Après ces premiers tests, Prince XML s'avère être un outil puissant. Il y a de nombreuses possibilités que je n'ai pas testé, et qui permettent, semble-t-il, de produire une mise en page relativement poussée.

En mai 2005, Michael Day, fondateur de YesLogic et développeur principal de Prince XML, écrivait à propos de l'utilisation de XML et CSS pour l'impression de documents :

[CSS et XSL sont] adaptés à l'impression de livres, contrats, lettres et autres documents contenant un flot de texte de longueur indéterminée devant être réparti sur plusieurs pages. Ils sont moins adaptés aux documents reposant sur une structure figée, tels que les journaux et magazines, pour lesquels la mise en page de chaque page requiert une intervention manuelle.

(Source : Printing XML: Why CSS is better than XSL, Michael Day, 2005. Traduction approximative de votre serviteur.)

Je pense que cela résume bien les possibilités et limites des CSS print lorsqu'elles sont pleinement exploitées.

Notes

[1] La licence serveur est à 3800 $ (3800 USD) et la licence professionnelle monoposte à 495 $ (495 USD).

[2] À vrai dire, il s'agit du premier « site web » digne de ce nom que j'ai jamais réalisé. Même si j'ai eu l'occasion d'y apporter quelques corrections, cela reste très imparfait. Merci donc de votre indulgence. ;)