これは「TeX & LaTeX Advent Calendar 2020」の 1 日目の記事です。2 日目はbd_gfngfnさんの記事の予定です。
本記事は LuaLaTeX で pdfx パッケージを使い PDF/A に準拠した PDF を作る方法を紹介します。台風で中止となり幻に終わったTeXConf 2019一般講演「原ノ味フォントと ToUnicode CMap」のアブストラクトや発表資料を PDF/A-2u 準拠にするためにやったことをまとめ、TeXLive 2020 環境で動作するように更新したものです。
はじめに
PDF/A は長期保存を目的としたPDFの規格です。PDF/A に準拠した PDF は、現在の PDF ビュアー(たとえば Adobe Acrobat Reader DC 2020)だけでなく、将来リリースされる PDF ビュアーにおいても、同じように表示したり、同じように取り扱ったりできることが期待できます。印刷を前提とせず、PDFをファイルのまま扱って、どんな環境でも同じように表示したり取り扱ったりできるし、長期間保存後の将来の未知の環境でも同じように表示したり取り扱ったりできる、ということになろうかと思います。
似たような規格に PDF/X というものもあり、こちらは印刷目的の規格です。TeX & LaTeX Advent Calendar 2018の 14 日目にp_typoさんの「LuaLaTeXでPDF/X-4やPDF/X-1aなPDF生成する」など、PDF/X を作る解説記事をいくつか見たことがありますが、PDF/A を作る解説記事は少ないようです。昨年、試行錯誤した結果 LuaLaTeX で PDF/A を作ることができるようになったので、TeXConf 2019一般講演「原ノ味フォントと ToUnicode CMap」のアブストラクトや発表資料を PDF/A-2u 準拠にしてみました。これらのソース等は当時から公開済ですが、ここでどのようにしたのかまとめておきます。
PDF/A とは
PDF/A は ISO 19005 規格になっているのですが、残念ながら規格書は有料なので私は見たことがありません。詳しいことは参考になりそうなサイトがいくつかあるので、そちらをご覧いただければと思います1。一応、ベースになる PDF 規格に対して制限として、やらなければならないこと、やってはいけないこと、などを加えるものになっているようです。
最初に策定された PDF/A-1 (ISO 19005-1) は、PDF 1.4 規格をベースとしたものです。ベースの PDF 1.4 規格は ISO 規格になっていませんし、PDF 1.5 で導入されたオブジェクトストリームが使えないため圧縮率が悪く、電子署名も SHA-256 が PDF 1.6 以降でないと使えないので、少々苦しい感じがします。次に策定された PDF/A-2 (ISO 19005-2) は PDF 1.7 (ISO 32000-1:2008) をベースにしているので、オブジェクトストリームも使えますし SHA-256 で電子署名できますから、こちらの方がよさそうです。2020 年現在、PDF/A-3 (ISO 19005-3) まで策定されているようですが、これは PDF 1.7 ベースという点で PDF/A-2 と変わらないですし、LuaLaTeX で PDF/A を作る場合にいいことがあるわけでもなさそうです。
そこで、PDF/A-2 を作ることにします。PDF/A-2 は、さらに 3 種類に分かれます。そのうち一番条件が厳しい PDF/A-2a はタグ付き PDF でなければならないようで、LuaLaTeX で出力するのは難しそうです。残るは PDF/A-2b と PDF/A-2u なんですが、この違いは、テキストを Unicode で抽出できるか、要するに PDF からテキストをコピペできるか否かということになります。PDF/A-2b はテキスト抽出できなくて構いませんが、PDF/A-2u はテキスト抽出できなければなりません。そこで、テキスト抽出可能な PDF/A-2u を作ることにします。
pdfx パッケージ
PDF/A を作るにはpdfx パッケージを使います。pdfTeX, LuaTeX, XeTeX に対応していて、pTeX や upTeX では使えないため、普通に日本語を使うなら LuaTeX 一択ということになります。TeX Live に収録されていますので、TeX Live が使える環境であれば既にインストールされているハズです。
pdfx パッケージは「この PDF は PDF/A に準拠している」ことを示すメタデータを PDF に埋め込むことができるものですが、本当に準拠しているかどうかを保証することはできません。単に pdfx パッケージを使っただけだと、「この PDF は PDF/A に準拠している」と主張しているけど、実は全然準拠していない PDF になってしまっているかもしれません。そこで、PDF を作ったら、本当に PDF/A に準拠しているか否かを検証する必要があります。検証ツールにはオープンソースで配布されているveraPDFを使うことができますので、インストールしましょう。
veraPDF
veraPDFは Java で書かれているので、Java の環境がなければ適当な OpenJDK をインストールしましょう2。
OpenJDK がインストールできたら veraPDF をインストールしましょう。veraPDFのサイトを開いたら「Explore」をクリックします。すると一番上にいくつかのリンクが出るので、その中から「Software」をクリックします。すると「veraPDF for Windows」「veraPDF for Mac」「veraPDF for Linux」という 3 つのリンクが見えるので、そこからダウンロードしましょう3。
ダウンロードした verapdf-installer.zip
を解凍して、中にあるインストーラを実行します。私は Windows 環境なので、コマンドプロンプトで java.exe
に PATH を通し、verapdf-install.bat
を実行しました。すると GUI でインストーラが起動するので、指示に従ってインストールすれば OK です4。
インストールできたら起動してみましょう。私は Windows 環境なので、コマンドプロンプトで java.exe
に PATH を通してから、インストール先にある verapdf-gui.bat
を実行します。以下のような画面になれば成功です。
TeX Live
TeX Live 2020 をインストールしておきましょう。本記事は TeX Live 2020 の、
- pdfx パッケージ Version 1.6.3 (2019-02-27)
- LuaTeX Version 1.12.0
を前提とします。
PDF/A を作ってみる
以下のソース simple.tex
を LuaLaTeX でコンパイルしてみます5。
% -*- coding: utf-8 mode:latex -*-
% PDF/A のメタデータ
\begin{filecontents*}{\jobname.xmpdata}
\Title{タイトル}
\Author{著者1\sep 著者2\sep 著者3}
\Language{ja-JP}
\Keywords{キーワード\sep きーわーど\sep key words}
\Publisher{出版者}
\end{filecontents*}
\documentclass{ltjsarticle}
% pdfx.sty で PDF/A-2u の作成を指定
\usepackage[a-2u]{pdfx}
\begin{document}
\section{節}
本文。
\end{document}
以下のようにコンパイルします。2 回実行しているのは、pdfx パッケージが内部で hyperref パッケージを読み込んでおり、PDF の「しおり」あるいは「ブックマーク」と呼ばれる部分を正常に生成するためです。
$ lulalatex simple.tex
$ lulalatex simple.tex
すると、simple.pdf
の他に、お馴染みの simple.aux
, simple.log
と、hyperref パッケージを使った際に出力される simple.out
が出力され、さらに simple.xmpdata
, pdfa.xmpi
が生成されます。このうち、simple.xmpdata
は、simple.tex
の冒頭に記載した filecontents*
環境の中身が出力されたものですが、困ったことにこのファイルが存在すると simple.tex
をコンパイルしても一切上書きしてくれないため、 filecontents*
環境の中身が更新されても変わってくれません。ですので、コンパイル前には simple.xmpdata
を消すようにした方がいいでしょう。pdfa.xmpi
はこの後の「メタデータ」で説明します。
veraPDF で検証
simple.pdf
が本当に PDF/A-2u に準拠しているか検証してみましょう。veraPDF を起動します。
「Choose PDF」ボタンを押して simple.pdf
を選び、「Execute」ボタンを押します。
少し待つと、結果として緑で「PDF file is compliant with Validation Profile requirements」と出てきてました。つまり PDF/A に準拠していることが確認できました。
詳細な結果を見るには「Reports」の中にある「View HTML」ボタンを押してみましょう。するとブラウザで「Validation Report」が表示されて、
Validation Profile: PDF/A-2U validation profile
PDF/A compliance: Passed
のような表示があり、PDF/A-2u の検証に通過したことがわかります。
一応、Poppler の pdfinfo でも確認してみましょう。
$ pdfinfo simple.pdf
(省略)
PDF version: 1.4
PDF subtype: PDF/A-2u:2010
Title: ISO 19005 - Electronic document file format for long-term preservation (PDF/A)
Abbreviation: PDF/A-2
Subtitle: Part 2: Use of ISO 32000-1
Standard: ISO 19005-2
Conformance: Level U, Unicode support
$
これでも PDF/A-2u に準拠していることがわかりますね。でも、PDF version が 1.4 になっています。PDF 1.4 だと、オブジェクトストリームが使えませんし、SHA-256 で電子署名できません。
pdfx で PDF バージョンを指定
pdfx パッケージのオプションで PDF バージョンを指定してみます。パッケージオプション pdf17
を追加してあります。
% -*- coding: utf-8 mode:latex -*-
% PDF/A のメタデータ
\begin{filecontents*}{\jobname.xmpdata}
\Title{タイトルあああ}
\Author{著者1\sep 著者2\sep 著者3}
\Language{ja-JP}
\Keywords{キーワード\sep きーわーど\sep key words}
\Publisher{出版者}
\end{filecontents*}
\documentclass{ltjsarticle}
% pdfx.sty で PDF/A-2u, PDF 1.7 の作成を指定
\usepackage[a-2u,pdf17]{pdfx}
\begin{document}
\section{節}
本文。
\end{document}
これをコンパイルして veraPDF で検証すると、ちゃんと PDF/A-2u に準拠していることがわかりました。ですが、 pdfinfo すると…
$ pdfinfo simple17.pdf
(省略)
PDF version: 1.4
PDF subtype: PDF/A-2u:2010
Title: ISO 19005 - Electronic document file format for long-term preservation (PDF/A)
Abbreviation: PDF/A-2
Subtitle: Part 2: Use of ISO 32000-1
Standard: ISO 19005-2
Conformance: Level U, Unicode support
$
PDF 1.4 のままですね…。pdfx パッケージの PDF バージョン指定が効いてません…。これ、どうも pdfTeX や古い LuaTeX のプリミティブでバージョンを指定しようとしていて、現在の LuaTeX ではうまくいかないようです。そこで、現在の LuaTeX でも古い LuaTeX のプリミティブをエミュレーションする luatex85 パッケージを使います。
% -*- coding: utf-8 mode:latex -*-
% PDF/A のメタデータ
\begin{filecontents*}{\jobname.xmpdata}
\Title{タイトルあああ}
\Author{著者1\sep 著者2\sep 著者3}
\Language{ja-JP}
\Keywords{キーワード\sep きーわーど\sep key words}
\Publisher{出版者}
\end{filecontents*}
\documentclass{ltjsarticle}
% LuaLaTeX で pdfx.sty の PDF バージョン指定が効くようにする
\usepackage{luatex85}
% pdfx.sty で PDF/A-2u, PDF 1.7 の作成を指定
\usepackage[a-2u,pdf17]{pdfx}
\begin{document}
\section{節}
本文。
\end{document}
これもコンパイルして veraPDF で検証すると、ちゃんと PDF/A-2u に準拠しています。そして pdfinfo してみると…。
$ pdfinfo simple17fix.pdf
(省略)
PDF version: 1.7
PDF subtype: PDF/A-2u:2010
Title: ISO 19005 - Electronic document file format for long-term preservation (PDF/A)
Abbreviation: PDF/A-2
Subtitle: Part 2: Use of ISO 32000-1
Standard: ISO 19005-2
Conformance: Level U, Unicode support
$
ちゃんと PDF 1.7 になりましたね。
PDF/A に違反してみる
さて、次は試しに PDF/A に準拠しない PDF を作ってみましょう。CMYK の色を使ってみます。
% -*- coding: utf-8 mode:latex -*-
% PDF/A のメタデータ
\begin{filecontents*}{\jobname.xmpdata}
\Title{タイトルあああ}
\Author{著者1\sep 著者2\sep 著者3}
\Language{ja-JP}
\Keywords{キーワード\sep きーわーど\sep key words}
\Publisher{出版者}
\end{filecontents*}
\documentclass{ltjsarticle}
% 色指定用
\usepackage{xcolor}
% LuaLaTeX で pdfx.sty の PDF バージョン指定が効くようにする
\usepackage{luatex85}
% pdfx.sty で PDF/A-2u, PDF 1.7 の作成を指定
\usepackage[a-2u,pdf17]{pdfx}
% カラーモデルを変換無しにする
\selectcolormodel{natural}
\begin{document}
\section{節}
{\color[cmyk]{1,0,0,0}C}
{\color[cmyk]{0,1,0,0}M}
{\color[cmyk]{0,0,1,0}Y}
{\color[cmyk]{0,0,0,1}K}
\end{document}
これをコンパイルすると、 pdfinfo では、以下の通り PDF/A-2u に準拠している、となります。
$ pdfinfo cmyk.pdf
(省略)
PDF version: 1.7
PDF subtype: PDF/A-2u:2010
Title: ISO 19005 - Electronic document file format for long-term preservation (PDF/A)
Abbreviation: PDF/A-2
Subtitle: Part 2: Use of ISO 32000-1
Standard: ISO 19005-2
Conformance: Level U, Unicode support
$
ですが、 veraPDF で確認してみると…。
赤で「PDF file is not compliant with Validation Profile requirements」と出ました。「View HTML」ボタンを押すと、規格のどの項目を満たしていないのか、などが表示されます6。
この PDF は、pdfinfo では PDF/A-2u 準拠と出ますし、Adobe Acrobat Reader で開くと「このファイルは PDF/A 規格に準拠している可能性があり、…」などと表示されますが、これは PDF に含まれているメタデータが PDF/A-2u に準拠していますと名乗っているだけ、ということです。veraPDF で本当に準拠しているか確かめてみると、全然準拠しておらず PDF/A 違反であることがわかります。
この例では CMYK を使ったので違反になりましたが7、他にも引っかかるところはいろいろとあるようなので、PDF/A を作ったら必ず検証した方がよいでしょう。
また、\includegraphics
で図として PDF を挿入する場合、その PDF で PDF/A 違反になるようなことをしている(例えば RGB と CMYK を両方使っている)と、それを読み込んだら PDF 全体としても PDF/A 違反になってしまいます。LuaTeX も pdfx パッケージも、特に準拠になるように変換してくれませんから、事前に違反にならないような図 PDF を用意しておく必要があります。カラーモデルの変換程度であれば、Ghostscript を使えばできます。例えば、CMYK の figure_cmyk.pdf を RGB の figure_rgb.pdf に変換するなら、以下のようにします。
$ gs -dSAFER -dBATCH \
-dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite \
-dCompatibilityLevel=1.7 \
-dColorConversionStrategy=/RGB \
-dProcessColorModel=/DeviceRGB \
-sOutputFile=figure_rgb.pdf \
figure_cmyk.pdf
同じく、Gray の figure_gray.pdf に変換するなら、以下のようにします。
$ gs -dSAFER -dBATCH \
-dNOPAUSE -dNOCACHE -sDEVICE=pdfwrite \
-dCompatibilityLevel=1.7 \
-dColorConversionStrategy=/Gray \
-dProcessColorModel=/DeviceGray \
-sOutputFile=figure_gray.pdf \
figure_cmyk.pdf
メタデータ
pdfx パッケージは、PDF/A に関するメタデータを PDF に埋め込みます。XMP と呼ばれる形式になっていて、LuaLaTeX 実行時に生成される pdfa.xmpi
ファイルに埋め込んだ内容が保存されています。また、PDF になっていても pdfinfo を使って以下のようにして取り出すことができます。
$ pdfinfo -meta simple17fix.pdf
試しに、pdfa.xmpi
と pdfinfo の出力で diff を取ってみましたが、最後の改行以外はまったく同じでした。
さて、この XMP ですが、中身を見てみると PDF/A を作りたい「だけ」ならあまり関係なさそうな PDF/X や PDF/UA のことが書いてあるなど、余計なところもありそうです。また、XMP は一つの PDF につき一つしか入れられないため、PDF/A 以外のメタデータも含ませたい場合8には、うまい具合にマージしてやる必要があります。そこで、この XMP メタデータをカスタマイズする方法をご紹介します。
pdfx パッケージは、自分が持っている pdfa.xmp
を元に XMP メタデータを生成します。pdfa.xmp
がどこにあるかは、以下のコマンドで探すことができます。
$ kpsewhich pdfa.xmp
/usr/share/texmf-dist/tex/latex/pdfx/pdfa.xmp
$
この場合は、/usr/share/texmf-dist/tex/latex/pdfx/pdfa.xmp
にあります。中を覗いてみると、XMP のベースになる内容と \ifx
など TeX 言語で置き換えやらなにやらの制御をしているような感じの記述が混ざっているのが見えます。
つまり、pdfx パッケージの XMP メタデータは以下の方法で生成されているようです。まず、simple17fix.tex
をコンパイルすると、冒頭の filecontents*
環境の中身が simple17fix.xmpdata
として出力されます。pdfx パッケージは、この simple17fix.xmpdata
と自分が持っている pdfa.xmp
を処理することでマクロの置き換えなどによりタイトルや著者などを XMP へ反映、その結果を pdfa.xmpi
に出力し、これを XMP メタデータとして PDF に埋め込んでいるようです。
ということは、カレントディレクトリにカスタマイズした pdfa.xmp
を置いておけば、そっちを使ってくれるのでは?ということでやってみたところうまくいきました。「原ノ味フォントと ToUnicode CMap」のアブストラクトや発表資料では、使わなそうなところを削除し、Creative Commons のメタデータを混ぜています。ソースの中にカスタマイズした pdfa.xmp
と、元の pdfx パッケージが持っていた pdfa.xmp
との差分を pdfa.xmp.diff
として置いてありますのでご興味があればご覧ください。
どのようにカスタマイズするかは、XMP の仕様を調べる必要があります。探すといくつか読めるものがあるようなので、参考にするとよいと思います。何をどう置き換えるか考えるには TeX 言語の知識も必要になりそうです。また、いじりすぎるとおかしくなるので、作った PDF を veraPDF で確認する必要があるでしょう。もちろん veraPDF で確認できるのはあくまでも PDF/A として問題ないか否かだけなので、PDF/A とは関係ない部分に問題があっても検出してくれないでしょう。
おわりに
本記事は LuaLaTeX で pdfx パッケージを使い PDF/A に準拠した PDF を作るとともに、正しく PDF/A に準拠しているか否か検証する方法を紹介しました。PDF/A に準拠させるには少々手間がかかりますが、PDF/A は長期間保存後の将来の未知の環境でも同じように表示したり取り扱ったりできる、ことが期待できます。資料として保管する PDF については PDF/A に準拠させることが重要になってくるものと思いますので、本記事がそのお役に立てれば幸いです。
-
veraPDF のドキュメントは、規格書に書いてあることが何となく透けて見えるような感じがして、かなり参考になると思います。 ↩
-
OpenJDK はいろいろなところが配布しているようなので、好きなものをインストールすればよいと思います。Linux 環境だったら、お使いの Linux ディストリビューションが提供している OpenJDK のパッケージをインストールするのが簡単だと思います。Windows や Mac では、OpenJDK インストールの解説記事があるようなので、そういうものを読んでもいいと思います。私は、今のところ Windows 環境で Oracle OpenJDK のアーカイブ から 11.0.2 (build 11.0.2+9) の Windows 64-bit の
openjdk-11.0.2_windows-x64_bin.zip
をダウンロードして、C:\usr\local
に解凍し、使いたいときだけコマンドプロンプトでPATH C:\usr\local\jdk-11.0.2\bin;%PATH%
を実行してパスを通してから使う(環境変数JAVA_HOME
は設定していませんが、とりあえず veraPDF のインストールと利用だけなら差し支えありませんでした)という方法を取っていますが、お勧めはしません。 ↩ -
3 環境分のリンクがありますが、どれも同じファイルを指しているように見えるんですよね…。 ↩
-
私がダウンロードしたインストーラは veraPDF 1.16.1 のものだったので、インストール先の指定では「Browse」ボタンでフォルダ名指定ダイアログを出して
C:\usr\local
まで辿り、ダイアログ内を右クリックして「New Folder」を選択して新しいフォルダverapdf-1.16.1
を作成して、そこを選択しました。つまりインストール先はC:\usr\local\verapdf-1.16.1
になります。また、インストールする packs は、デフォルト選択のまま(veraPDF GUI と veraPDF Batch files が必須で選択済、veraPDF Documentation が選択済、veraPDF Corpus and Validation model と veraPDF Sample Plugins が非選択)としました。 ↩ -
TeX Live 2019 では
\pdfvariable omitcidset=1
を入れないと PDF/A-2 に準拠しませんでしたが、TeX Live 2020 なら入れなくても大丈夫です。 ↩ -
どうやら規格書の文言を引用しているようなので、規格書が読めなくてもかなり参考になります。 ↩
-
PDF/A で CMYK が禁止されているわけではありません。pdfx パッケージはデフォルトで sRGB のカラープロファイルを埋め込むのですが、CMYK を使うとこれと矛盾するために違反になるようです。 ↩
-
例えば、Creative Commons のメタデータを入れたい、等。 ↩