Acetaminophen’s diary

化学に関すること,TeXに関すること,ゆきだるまに関すること。

化学構造式をTeXで(3):補足事項

追記:新しい記事を書いたので、以下の内容は少々古い。最新はこちら:

ただし、ソフトウェアの概要やインストール方法などは以下の内容を参照。

やり残していた Mac での確認を含めて、いくつかの補足を行うのが今回の記事。具体的には

  1. Mac での Open Babel, Inkscape のインストール方法
  2. 今回用いた構造式抽出マクロ作成時に注意した点
  3. Inkscapeコマンドライン版に関連したリソース紹介
  4. Open Babel によって生成する SVG 画像と Inkscape の挙動について。

その前に、ここで1つ重要なお知らせ。

ケムステスタッフになりました。今回記事を初投稿し、Open Babel の GUI 版を Windows 上で使ってみたことについて記事にしました。あわせてよろしくお願いいたします。

 

Mac での Open Babel, Inkscape のインストールと自動処理

第1回の記事では Windows 版のインストール方法しか説明しなかったので、今回は Mac 版でも同じ作業を確認してみる。

Open Babel のインストール

Mac 版には iBabel という GUI 版があるのだが、今回は利用せずにコマンドライン版のみをインストールする。SourceForge から最新版*1をダウンロードして解凍すると、中に「OpenBabel.pkg」というパッケージが入っているので、指示に従ってインストールすると /usr/local/bin 以下にバイナリが置かれる。ターミナルから

which obabel

と入力して確認してみるとよいだろう。

Inkscape のインストール

Inkscape では Mac 用の dmg ファイルを配布しているので、ダウンロードして起動する。

f:id:acetaminophen:20141104133139p:plain

典型的なインストーラなので、Inkscape.app を Applications フォルダにドラッグアンドドロップして GUI 版のインストールは完了。

次に、コマンドライン版をターミナルから使えるように設定する。コマンドライン用バイナリは

/Applications/Inkscape.app/Contents/Resources/bin/

にあるはずだが、単に中にある inkscapeinkscape_bin にシンボリックリンクを貼る*2だけでは済まない。ちゃんと Inkscape のテーマなどを認識させるためには export PATH が必要である。すなわち ~/.bash_profile または ~/.bashrc に書き加える必要がある*3

echo "export PATH=\$PATH:/Applications/Inkscape.app/Contents/Resources/bin" >> ~/.bash_profile

これでコマンドラインから inkscape が利用可能となる。ターミナルから

which inkscape

と入力して確認してみるとよいだろう。

構造式の TeX 取り込みの自動処理

ここまで済めば、あとは第1回および第2回の方法をそのまま流用できる。ぜひ試してみてほしい。なお、今回は Inkscape を最も簡単な GUI 操作ベースの方法でインストールしたが、Inkscape のインストールは MacPorts のようなパッケージ管理からでも可能である。例えば以下の記事を参照。


MacPorts で Inkscape をインストールしてランチャを作るまで - 😃 mattintosh note 📝

 

マクロ作成時に注意すべきだった点

今回のマクロでは文字列抽出が必要であった。基本的には、単に使えそうだと思ったマクロをベースに構造式抽出用の変更を施しただけではあるが、それでもいくつかの前提知識が必要であった。それは、TeX において特別な意味を持つ文字の扱いである。これらを文字列として読ませる必要があるので

  • コントロールシーケンスを意味する \ で始まる単語の前には \string を付ける
  • 同様にパラメータを表す # にも \string を付ける

ことに注意した。詳細は TeX入門/マクロの作成 に書かれている。

 

Inkscapeコマンドライン版について

今回はオープンソースソフトウェアであるベクター画像編集ソフト Inkscape が活躍した。自動化の過程で用いたのはコマンドラインinkscape である。Mac の場合は先ほど説明したとおり GUI アプリケーションとコマンドライン用バイナリの場所が別になっているが、Windows の場合は GUI アプリケーション inkscape.exe とコンソールへの出力機能を持ったコマンドライン用ラッパーである inkscape.com が同じ場所に存在する。今回の変換工程で用いたのは inkscape.com のほうである*4

コマンドライン版は GUI 版に比べて日本語リソースが格段に少なくなるが、TeX Wiki に記述があるし、公式サイト(英語)の和訳も以下のサイトで公開されている。

また、コマンドラインでの利用例が以下のサイトに紹介されている。

 

Open Babel が生成する SVG 画像と Inkscape の挙動について

既に紹介した smiles.tex をタイプセットしたときに得ていたエタノールの図を例に説明する。復習すると

platex -shell-escape smiles.tex

を実行すると、まず obabel によって SMILES 表記が読まれて SVG ファイル smilesimg1.svg が出力される。次に、inkscape によって SVG ファイルは smilesimg1.pdf という PDF ファイルに変換される。このような作業を構造式の数だけ繰り返しているわけであった。

試しにコマンドラインから

inkscape -f smilesimg1.svg --export-pdf=smilesimg1.pdf

と入力してみてほしい。これは例の smiles.tex タイプセット時と同じ命令である。生成した smilesimg1.pdf を、今度は GUI 版の Inkscape で開いて確認してみてほしい。前回の記事で軽く触れたが、変な PDF ファイルになっている。どういうことかは1回グループ解除を行い、文字 OH の部分を選択してみるとわかる。

f:id:acetaminophen:20141105134615p:plain

下のステータスバーに「パス (32 個のノード)」と表示されている。あれ、アウトライン化されているのか? と思いきや、もう1回 OH 部分をグループ解除して動かしてみると

f:id:acetaminophen:20141105134636p:plain

f:id:acetaminophen:20141105134652p:plain

見ての通り、“32個のノードから成る縁取り”と“サンセリフ体のテキスト”に分裂した! このように、テキスト情報を保持してはいるが

「実際のテキスト」が「アウトライン化で生成したパス」で覆われた二重構造

になっているのである。

どうしてこのようなことが起こるのか理解するには、Open Babel が生成した SVG ファイルのソースを見てみる必要がある。SVG とは Scalable Vector Graphics のことで、HTML に似たマークアップ言語である XML ベースで書かれていて簡単にテキストエディタで開くことができる。そこで、エタノールSVG ファイルのソースを覗いてみよう。

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:cml="http://www.xml-cml.org/schema" width="149.282" height="100" x="0" y="0" font-family="sans-serif" stroke="rgb(0,0,0)" stroke-width="1"  stroke-linecap="round">
<rect x="0%" y="0%" width="100%" height="100%" stroke-width="0" fill="rgb(255,255,255)"  />
<line x1="98.0" y1="46.5" x2="74.6" y2="60.0" stroke="rgb(0,0,0)"  stroke-width="1.0"/>
<line x1="74.6" y1="60.0" x2="51.3" y2="46.5" stroke="rgb(0,0,0)"  stroke-width="1.0"/>
<text x="105.282032" y="48.000000" fill="rgb(102,102,102)"  stroke="rgb(102,102,102)" stroke-width="1" font-size="16" >CH</text>
<text x="129.282032" y="51.680000" fill="rgb(102,102,102)"  stroke="rgb(102,102,102)" stroke-width="1" font-size="13" >3</text>
<text x="22.000000" y="48.000000" fill="rgb(255,12,12)"  stroke="rgb(255,12,12)" stroke-width="1" font-size="16" >HO</text>
<text font-size="18.000000" fill ="black" font-family="sans-serif"
x="10.000000" y="20.000000" ></text>
<title> - OBDepict</title>
</svg>

ビジュアル要素はすべてタグで記述されている。初めの rect タグで描画領域を指定する*5のに続いて、line タグで直線を、text タグで文字を座標指定して配置している。このうち text 要素を見てみよう。ご覧のとおりフィルとストロークが両方記述されている。

フィルとは線の内側の色を塗ること、ストロークとはアウトライン線自体のことをいう。普通の用途であれば文字を白抜きにしたい訳ではないのでストロークは不要であるにもかかわらず、Open Babel による出力ではストロークも一緒に出力されてしまう。この SVG ファイルを Inkscape で PDF に変換したときにフィルから変換されたテキストの他にアウトラインのパスが含まれてしまったのは、まさにこのストロークが元となっている。

ちなみに元となっている obabel 出力の SVG ファイルを InkscapeGUI で開いてみても、ちゃんとサンセリフのテキストだけになっている。

f:id:acetaminophen:20141105135208p:plain

その状態のまま GUI 版で PDF 形式に出力してみるとどうなるか試してみたところ、出力された PDF はコマンドライン版と同様に「テキスト」が「アウトライン化で生成したパス」で覆われた二重構造となっていた*6。Open Babel の SVG depiction (svg) に関するページ

を見たが、該当するオプションは無さそうだったので、この出力は回避できそうになかった。

ちなみに僕の Windows 環境では PDF 埋め込みフォントが ArialMT になり、Mac 環境では BitstreamVeraSans-Roman になっていたが、これは SVG ファイル中でサンセリフ体を用いるように指定しているため、その OS にインストールされている中で一番優先されるフォントを用いたからであろう。この優先順位については Inkscape の設定ファイルのどこかに指定されているはずであるが、僕はここには触れないことにした。

 

もしかしたら有用かもしれない情報

実は、Inkscape には PDF/PS/EPS 形式で出力する際に LaTeX 用ソースファイルを同時に出力するオプションがある。コマンドラインから

inkscape -f smilesimg1.svg --export-pdf=smilesimg1.pdf --export-latex

と入力してみてほしい*7。すると、smilesimg1.pdf のほかに smilesimg1.pdf_tex というファイルが生成する。これを実際にタイプセットするには

\documentclass{jsarticle}
\usepackage[dvipdfmx]{xcolor}
\usepackage[dvipdfmx]{graphicx}
\begin{document}
\input{smilesimg1.pdf_tex}
\end{document}

とする。要するに、次のような処理系統になっているわけだ。

f:id:acetaminophen:20141105135704p:plain

ここで気づくのだが、文字の配置がおかしい。それもそのはず、変換元の SVG ファイルは画像形式なので、TeX ソースの出力など想定されていない。SVG のソースを見れば分かるように、下付き文字も相対的な値でなく絶対座標を用い、フォントサイズを変えて実現している。それを前提とした Inkscape も当然の結果として文字の組版に関しては無知であり、生成した smilesimg1.pdf_tex を開いてみると、以下のように書かれている。

  \begin{picture}(1,0.66987314)%
    \put(0,0){\includegraphics[width=\unitlength]{smilesimg1.pdf}}%
    \put(0.70525602,0.2143594){\color[rgb]{0.4,0.4,0.4}\makebox(0,0)[lb]{\smash{CH}}}%
    \put(0.86602558,0.18970807){\color[rgb]{0.4,0.4,0.4}\makebox(0,0)[lb]{\smash{3}}}%
    \put(0.14737209,0.2143594){\color[rgb]{1,0.04705882,0.04705882}\makebox(0,0)[lb]{\smash{HO}}}%
  \end{picture}%

これを TeX で処理すると当然ながら TeX 専用フォントが使われる以上、何らかの調整が必要になる。ただし、容易にわかるとおりフォントサイズを変えれば済むという単純な話ではない。適切なフォントを適切なサイズで使用するとともに、picture 環境の \put コマンドではなく数式用の上付き/下付き文字などのコマンドに書き換えるとなると、至難の業であろう。というわけで、今回の記事では非推奨とした。ただし、LaTeX ソースの出力が可能だということは知っていても損はない。

 

最後に

予想以上に簡単な方法が存在したことに驚いた。今回は必要なプログラムをインストールして適切に設定し、TeX としてはマクロをとってきて利用することでほとんどの作業が完結した。応用の可能性も広いので、ぜひ試してみてほしい。

 

追記:2014-11-11 Open Babel のオプションの利用

こちらの記事で「化学構造式の自動生成の補足」と題し、2次元構造最適化までを自動で行うオプションを紹介。ここまでの記事内容で構造式の不自然さに不満があった場合は、試してみるとよいかも。

*1:今回は「OpenBabel-2.3.1.mac.zip」だった。

*2:例えばターミナルから

sudo ln -s /Applications/Inkscape.app/Contents/Resources/bin/inkscape /usr/local/bin

と実行することを意味する。

*3:例えば [Mac, Linux] PATHを通す方法 | Memo on the Web 参照。

*4:古い Inkscape のバージョンではコンソール版 Inkscape を自分でコンパイルしてビルドする必要があったらしいが、現在ではその必要がなくなり、このような配置になっているようだ。

*5:Inkscape で PDF をグループ解除したときに背景に長方形オブジェクトが存在することに気づいたかもしれないが、これこそが理由である。

*6:唯一の違いは、背景を表す白い矩形がコマンドラインの場合には存在したのに対して GUI の場合には存在しなかったことである。

*7:これは GUI 版で「名前を付けて保存」の PDF 形式指定後に出てくるダイアログボックスで「PDF+LaTeX: PDF のテキストを除外して LaTeX ファイルを生成」にチェックを入れるのと同じ意味になる。