Pas mal de prises de tête au final pour injecter des méta-données dans des PDFs.
Surtout sur le champ du milieu.
Sujet.
Après avoir hésité sur la méthodologie je me suis rendu à l’évidence que le meilleur outil pour faire cela programmatiquement (par script) est bel et bien ExifTool. Le grand ExifTool, ce puissant et capricieux outil multi-platteforme. Mais à vrai dire, est-ce son caprice ou bien celui qui s’introduit malignement dans mon esprit à trop me demander pourquoi les turpides d’affichage de ces même méta-données dans Adobe Reader et Acrobat sont si perturbantes. Ou bien les méandres de l’histoire sont liées à l’age de cette technologie et à l’évolution des techniques disponibles.
Reste qu’Adobe nous fout un bon gros bordel en place. Je pourrais cracher mon venin sur ces bureaucrates et l’informatique et les maudire longtemps encore, et parfois même aller jusqu’à douter de la qualité du travail d’ExifTool mais non, voici donc ma solution en ligne de commande.
Je commence par faire le vide dans les métadonnées car l’empilement des différentes couches devient vite problématique. Je fais donc simplement:
exiftool -overwrite_original -all= monfichier.pdf
Ensuite j’injecte un fichier XMP que j’aurai rempli avec mes métadonnées selon la distribution suivante (je remplis le XML en DOM Javascript ou un LibXML Perl).
<?xpacket begin=’?’ id=’W5M0MpCehiHzreSzNTczkc9d’?>
<x:xmpmeta xmlns:x= »adobe:ns:meta/ »>
<rdf:RDF xmlns:rdf= »http://www.w3.org/1999/02/22-rdf-syntax-ns# »>
<rdf:Description rdf:about= » » xmlns:dc= »http://purl.org/dc/elements/1.1/ »>
<dc:creator>
<rdf:Seq>
<rdf:li>None</rdf:li>
</rdf:Seq>
</dc:creator>
<dc:description>
<rdf:Alt>
<rdf:li xml:lang= »x-default »>références</rdf:li>
</rdf:Alt>
</dc:description>
<dc:format>application/pdf</dc:format>
<dc:subject>
<rdf:Bag><rdf:li>baratin</rdf:li></rdf:Bag>
</dc:subject>
<dc:title>
<rdf:Alt>
<rdf:li xml:lang= »x-default »>circonscription électorale des Etats-Unis d’Amérique</rdf:li>
</rdf:Alt>
</dc:title>
</rdf:Description>
<rdf:Description rdf:about= » » xmlns:pdf= »http://ns.adobe.com/pdf/1.3/ »>
<pdf:Author>None</pdf:Author>
<pdf:Keywords>baratin</pdf:Keywords>
<pdf:PDFVersion>1.4</pdf:PDFVersion>
</rdf:Description>
<rdf:Description rdf:about= » » xmlns:xmp= »http://ns.adobe.com/xap/1.0/ »>
<xmp:CreateDate>Wed Jan 21 2015 16:43:41 GMT+0100</xmp:CreateDate>
<xmp:MetadataDate>Wed Jan 21 2015 16:43:41 GMT+0100</xmp:MetadataDate>
<xmp:ModifyDate>Wed Jan 21 2015 16:43:41 GMT+0100</xmp:ModifyDate>
</rdf:Description>
<rdf:Description rdf:about= » » xmlns:xmpRights= »http://ns.adobe.com/xap/1.0/rights/ »>
<xmpRights:WebStatement>http://www.legicrack.org</xmpRights:WebStatement>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end=’w’?>
Plusieurs notes à ce propos. Bien respecter les format de date et UUID, bien diviser la valeur du champ Mots-Clés selon les virgules et les points-vigules afin d’en répéter le contenu depuis <pdf:Keywords> pour sa totalité littérale vers <dc:subject>/<rdf:Bag> et autant de <rdf:li> que la division vous donnera. Cela semble nécessaire même si le paradoxe viendra plus loin.
Pour injecter cela, on utilisera la commande suivante:
exiftool -overwrite_orginal -tags_from_file monxmp.xmp monpdf.pdf
Reste le champ Subject ou Description ou Sujet, comme vous voulez, à force je l’appelle le champ du milieu. Comme vous le voyez dans le XML précédent il y a différents namespace dans les métadonnées donc il faut pas se rater.
Ma solution est la suivante, avec l’option -L en plus si vous êtes sous Windows et que vous voulez mettre une valeur avec accents:
exiftool -overwrite_orginal -pdf:subject= »Mon champ du milieu » -xmp:subject= » » monpdf.pdf
Ils ont le même nodename mais dans des espaces de noms différents et pourtant il faut les injecter avec des valeurs radicalement différentes.
Après ces trois étapes, j’arrive à mes fins, et mon résultat dans les produits Adobe est conforme, avec juste le petit itch qui est que la valeur des mots-clés est encadrée de quotes, ce qui peut arriver même quand on saisit à la main, à moins qu’un lecteur ou moi ne finisse par trouver une solution programmatique.