化学構造式をTeXで(2):自動化の注意点と解消法
追記:新しい記事を書いたので、以下の内容は少々古い。最新はこちら:
- 誰でも簡単! 化学構造式を LaTeX に取り込むパッケージ (2014-12-08)
ただし、ソフトウェアの概要やインストール方法などは以下の内容を参照。
前回の続きで、残しておいた「自動実行の注意点」について。
注意点1:ディレクトリ名
ディレクトリに全角文字が入っていると、たぶん Inkscape が SVG ファイルの読み込みに失敗する。したがって PDF 変換が行われず、platex から PDF ファイルが存在しないとエラーが返ってくるはずである。ユーザ名に全角文字が入っていればおそらく致命的で、この場合は手動で Inkscape を開けばたぶん PDF に保存しなおせるはず。
注意点2:自動実行プログラムの指定
前回も書いたが、-shell-escape ではセキュリティ上の問題が生じうる。例えば
など参照。もしかすると texmf.cnf を書き換えれば実行許可するプログラムを個別に設定できるかもしれないが未確認で、簡単な回避法を1つ。
前提の復習
その前に、基本的な前提知識を確認しておく。とりあえず TeX Wiki の記述を転載する*1。
W32TeX や 美文書第6版 からインストールした場合は texmf.cnf の shell_escape_commands に extractbb が指定されていて,
\usepackage[dvipdfmx]{graphicx}
のようにすると,自動的に extractbb が実行されるので,あらかじめ extractbb を実行する必要はありません。
TeX Live 2014, MacTeX-2014 では extractbb の実行は自動化されていません。
自動化したい場合は
Windows の場合は C:\texlive\texmf-local\web2c\texmf.cnf
OS X, Linux の場合は /usr/local/texlive/texmf-local/web2c/texmf.cnfを作成し
shell_escape_commands = \
bibtex,bibtex8,bibtexu,upbibtex,biber,\
kpsewhich,\
makeindex,mendex,texindy,xindy,\
mpost,upmpost,\
repstopdf,epspdf,extractbbを書き足して管理者権限で
mktexlsr
を実行します。
platex や pdflatex 実行時に -shell-escape オプションを付けると、時にユーザが意図しないプログラムさえも自動実行されてしまう。これを回避するために、通常は -shell-escape オプションではなく texmf.cnf に shell_escape_commands = として実行を許可するプログラムだけを記述することが推奨されている。この shell_escape_commands を定義した texmf.cnf は通常
- TeX Live の場合:
Windows ならC:\texlive\texmf-local\web2c\texmf.cnf
OS X, Linux なら/usr/local/texlive/texmf-local/web2c/texmf.cnf
- W32TeX の場合:
C:\w32tex\share\texmf-dist\web2c\texmf.cnf
に存在するはずであり、それぞれ
shell_escape_commands = \
で始まる数行にわたってコマンド名が列挙されている。これを見る限り、今回実行しようとしている外部プログラムである obabel や inkscape、それに rm は許可されていないわけで、これこそが先ほどまでの説明で -shell-escape オプションをつけるよう説明した理由である。
では、どう回避するか
以上を読んで「では、texmf.cnf にプログラム名を追記すればよいのではないか」と思うかもしれないが、それで済めば話は簡単である。しかし obabel や inkscape は完全に TeX とは無関係なので追加の仕方が僕には分からなかった。しかも rm はファイルをゴミ箱を介さず削除するプログラムなので、自動実行に加えるのは危険である。
そこで、\smiles や \obabel というコマンドを含んだ TeX ソースが存在するときに(前回の smiles.tex や obabel.tex でもよい)
という手順を提案する。こうすれば、実質的には texmf.cnf で指定したプログラム以外で自動実行されるのが、安全な \smiles コマンドや \obabel コマンド実行に必要な obabel や inkscape(場合によっては rm も)だけとなる。トリックは、そもそも texmf.cnf で自動実行を許可されているプログラムの中に obabel, inkscape, rm のいずれも含まれていないために、3.で -shell-escape オプションなしの実行を行うと、ここが完全に無視されて変換処理がなにも行われないことにある。それにもかかわらず \includegraphics が強要されているため、結果としてはその3.より前の段階、すなわち2.で生成した PDF が“仕方なく”読み込まれるという感じで説明がつく。
この方法の副次的なメリットとして、外部プログラムを呼び出すプロセスは中間の platex -shell-escape ChemFigFile.tex だけであるので、必要以上に obabel や inkscape を呼び出すことがなくなり、処理が高速化する。しかも、いったん生成した PDF を見て不満があれば、その都度 PDF を直接 Inkscape の GUI 操作により編集することができ、それを勝手に上書きされる心配もない*2。
これでもまだ面倒なので…
ついでに、この1.の手順は面倒なので、自動抽出コマンドを用意した。元となる TeX ソースを autoextract-smiles.tex と呼ぶことにする。プリアンブルの末尾に以下の抽出コマンドを書き加える*3:
%%%%% For the purpose of extracting codes of all SMILES figures %%%%% %%%%% Reference: http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=1411 % Necessary: definition of the intermediate output file \newwrite\ChemFigFile \immediate\openout\ChemFigFile=ChemFigFile.tex\relax \immediate\write\ChemFigFile{\string\documentclass{jsarticle}} \immediate\write\ChemFigFile{\string\usepackage[dvipdfmx]{graphicx}} % Options %% for \obabel (Delete the next line if you don't intend to use `graphvizObabel.sty'; necessary if you don't have `graphvizObabel.sty') \immediate\write\ChemFigFile{\string\usepackage{graphvizObabel}} %% for \smiles (Delete following 9 lines if you don't intend to use \smiles ; if you wish) \immediate\write\ChemFigFile{\string\newcounter{smilescounter}} \immediate\write\ChemFigFile{\string\setcounter{smilescounter}{1}} \immediate\write\ChemFigFile{% \string\newcommand{\string\smiles}[1]{% \string\immediate\string\write18{obabel -:"\string#1" -O smilesimg\string\arabic{smilescounter}.svg && inkscape -f smilesimg\string\arabic{smilescounter}.svg --export-pdf=smilesimg\string\arabic{smilescounter}.pdf || rm -f smilesimg\string\arabic{smilescounter}.pdf} \string\includegraphics{smilesimg\string\arabic{smilescounter}.pdf} \string\addtocounter{smilescounter}{1}% }% } % Necessary: read and write \immediate\write\ChemFigFile{\string\begin{document}} \AtEndDocument{% \immediate\write\ChemFigFile{\string\end{document}}% \immediate\closeout\ChemFigFile% } %% for \smiles \let\oldsmiles=\smiles \def\smiles#1{% \immediate\write\ChemFigFile{% \string\smiles{#1}% \string\newpage}% \oldsmiles{#1}} %% for \obabel \let\oldobabel=\obabel \def\obabel[#1]#2{% \immediate\write\ChemFigFile{% \string\obabel[#1]{#2}% \string\newpage}% \oldobabel[#1]{#2}} %%%%%%%%%%
抽出コマンドを書き加えて保存したら、いったん -shell-escape オプションなしで
platex autoextract-smiles.tex
を通す(TeXworks や TeXShop などを用いてもよい)。すると当然であるが obabel や inkscape が実行されないので、PDF ファイルがないというエラーが大量発生する。しかし、根気よく [Enter] しつづけると最終的には ChemFigFile.tex というファイルが同じディレクトリに生成する。これこそが \smiles や \obabel コマンドのみを自動抽出した TeX ソースであり、まさに上の1.にあたる部分を自動化したわけである。
あとは2.から4.に従うだけである。すなわち全体として
今回のソースも一応おいておく(Google):
「autoextract-smiles.tex」「autoextract-smiles.pdf」「ChemFigFile.tex」
次回は、この方法に関連していくつかの補足を行う。
*1:2014年11月3日9:20現在;一部改変。将来的には TeX Live 2015 以降 extractbb の実行の自動化が模索されているため、この記述が TeX Wiki から削除されてしまう潜在的な可能性がないわけではないため。
*2:補足:生成する PDF ファイルはテキスト情報を保持しているが、中身が少し変である(これは前回紹介した方法でも同じ)。というのも、Illustrator や Inkscape で構造式の PDF 画像を開いてみるとわかるとおり、PDF ファイルのテキスト部分は二重になっていて、「実際のテキスト」が「アウトライン化で生成したパス」で覆われたかたちである。したがって、編集の際にはこのパス部分をグループ解除で除去し、テキストだけを残すようにするとよいだろう。これに関連した点は次回説明する。
*3:このマクロは TeX Forum の質問への解答で示された例を参考に改変したものである。