Hatena::ブログ(Diary)

アセトアミノフェンの気ままな日常

2015-06-30

最近やったこと(TeX 関連)

長らく放置しているものを再び掘り出してきていじるということを最近やっている。特に tcpdfcrop と chemobabel を再検討している。

tcpdfcrop の“勝手改変版”だが、いま公開しているものは複数ページ処理で冗長な TeX コードを吐く。TeX 処理のプロセスは早いが、なんだか見た目が良くないと思い、もう少しすっきりした TeX コードを吐くようにしたバージョンを作ってみた(未公開)。しかしそうするとなぜかバッチファイルの処理が遅い… 「バッチで文字列を解析する」のと「TeX で文字列を解析する」のとどちらが早いのかイマイチよくわからない。

chemobabel については長らく懸念材料であった「LaTeX ユーザに \catcode を書かせざるを得ない実装方式」を克服すべく、久々に引っ張り出した。目標は「\smilesobabel の引数1は通常通り扱い、引数2, 3は verbatim に扱う」という処理。一方、今の実装は「基本的にすべて通常通り扱い、一時的にユーザが \catcode を使えばその分だけ異なる扱いになる」という状態。これは不便なので xparse を使おうかという話が出ていたのだが、動かなくなる TeX 環境を考慮して避けたいと思っていた。とりあえず、「すべての引数を verbatim に扱う」やりかたは分かっている(未公開)のだが、引数によって違う処理を施すのは難しい…

2015-06-29

xcolor と color が難しい件(その2)

昨日の続き)

僕のパッチが大丈夫かどうか理解するには、\PassOptionsToPackage なるコマンドがどういう影響を及ぼすか調べる必要がある。いままでの単純な xcolor と color の組み合わせ (1a)-(1d') およびパッチ前の hyperref と xcolor の組み合わせ (2a)-(2d) では登場しなかったが、ここでちゃんと確かめておこう。

とはいえ、hyperref は依存パッケージが多すぎて状況が分かりづらいので、単純化する。次のような mycolor.sty を作成する。これは単に color パッケージを呼び出すだけの機能を持つが、dvipdfmx オプションが指定された場合には color パッケージに \PassOptionsToPackage によって dvipdfmx オプションを引き渡す。

%%
%% This is file `mycolor.sty',
%%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{mycolor}
          [2015/06/28 test for color]
\DeclareOption{dvipdfmx}{%
  \PassOptionsToPackage{dvipdfmx}{color}%
}
\ProcessOptions
\RequirePackage{color}
\endinput
%%
%% End of file `mycolor.sty'.

これは“パッチ済み hyperref”の colorlinks=true 指定時とほとんど同じ構図にしたつもりである。この mycolor パッケージを使い、前回の

どういう状況なら color が読まれ、またある状況なら読まれないのだろう?

という疑問をもう少し考察する。

と、その前にいったん脱線(?)。Option clash なるエラーについての正しい理解が欠かせない。

「初回の \usepackage または \RequirePackage で“直接”指定されたオプション」(これを仮にリスト1と呼ぶ)と「n回目(n>1)以降に \usepackage または \RequirePackage で“直接”指定されたオプション」のリスト(リストnと呼ぶ)を比較し、リストnがリスト1の部分集合なら可、もし一つでもリスト1に含まれないオプションがあれば不可とみなしてエラーを返す

ということである。このあたりの仕様は例えば TeX/LaTeX Stack Exchange の

を読めばわかる。この“直接”というのが意外に重要で、クラスオプションで指定されたオプションは比較対象のリストに含まれない。これこそが、前回の xcolor 使用時にクラスオプションだけを与えた例(1b)

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage{xcolor}   % xcolor のリストは空→読む(クラスで正常)、color のリスト1は空→読まない
\usepackage{color}    % color のリスト2も空→OK

が Option clash にならないのに、個別にオプションを与えた(1d)

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}  % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage[dvipdfmx]{color}   % color のリスト2は dvipdfmx→増えた!

あるいは新出の例としてクラスオプションと個別オプションの併用(1e)

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage{xcolor}     % xcolor のリストは空→読む(クラスで正常)、color のリスト1は空→読まない
\usepackage[dvipdfmx]{color}   % color のリスト2は dvipdfmx→増えた!

で Option clash のエラーが出る理由である*1

さて、本題に戻ろう。mycolor パッケージは「パッケージを読ませる」こと以外の処置を何も施していないので、xcolor と color の関係性に関する挙動がみてとれるはずだ。

まずは、個別の dvipdfmx オプションで xcolor 使用時は(3a)

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}   % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage[dvipdfmx]{mycolor}  % 後で考察予定;結果的に color のリスト1,2はともに dvipdfmx→OK!?

この場合の \listfiles は

 *File List*
 article.cls    2014/09/29 v1.4h Standard LaTeX document class
  size10.clo    2014/09/29 v1.4h Standard LaTeX file (size option)
  xcolor.sty    2007/01/21 v2.11 LaTeX color extensions (UK)
   color.cfg    2007/01/18 v1.5 color configuration of teTeX/TeXLive
dvipdfmx.def    2015/03/26 v4.04 LaTeX color/graphics driver for dvipdfmx (TeX Live/ChoF)
 mycolor.sty    2015/06/28 test for color
 ***********

となり、color が呼ばれていない。一方、個別の dvipdfmx オプションで xcolor 不使用の場合(3b)

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{mycolor}  % 後で考察予定;結果的に color のリストは dvipdfmx→読む

この場合の \listfiles は

 *File List*
 article.cls    2014/09/29 v1.4h Standard LaTeX document class
  size10.clo    2014/09/29 v1.4h Standard LaTeX file (size option)
 mycolor.sty    2015/06/28 test for color
   color.sty    2014/10/28 v1.1a Standard LaTeX Color (DPC)
   color.cfg    2007/01/18 v1.5 color configuration of teTeX/TeXLive
dvipdfmx.def    2015/03/26 v4.04 LaTeX color/graphics driver for dvipdfmx (TeX Live/ChoF)
dvipsnam.def    2014/10/14 v3.0j Driver-dependent file (DPC,SPQR)
 ***********

こちらは color が呼ばれてドライバ指定が働く。

もし仮に、mycolor.sty が \PassOptionsToPackage ではなく \RequirePackage で指定されるオプションを持っていたらどうだろうか?

%%
%% This is file `mycolor2.sty',
%%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{mycolor2}
          [2015/06/28 test for color 2]
\RequirePackage[dvipdfmx]{color}
\endinput
%%
%% End of file `mycolor2.sty'.

この場合、\usepackage{mycolor2} は \usepackage[dvipdfmx]{color} と等価になるので以下のソースが Option clash を引き起こす(3c)。

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}   % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage{mycolor2}           % color のリスト2は dvipdfmx→増えた!

つまり、xcolor が color を読み込み済みとみなしたにもかかわらず後からオプションが増えたので、Option clash となったらしい。

(3c)は前回までの結果から想像に難くないが、(3a), (3b)は若干分かりにくい。いろいろ考えてみたのだが、挙動から推測される結論としては

  • \PassOptionsToPackage はその前にパッケージが既に読まれていればリストに追記する
  • \PassOptionsToPackage はその後にパッケージが読み込まれるのを検知すると“直接”オプションを渡す

らしい。

一つ目は、color を3回もいろいろなドライバで読ませようとするいわゆる“ドライバ詐称”なソースによる実験結果と矛盾しない(4a):

\listfiles
\documentclass{article}
\usepackage{color}              % color のリスト1は空→読む(異常だがここでは気にしない)
\usepackage[dvipdfmx]{mycolor}  % color のリスト1に dvipdfmx を追記、リスト2は dvipdfmx→OK
\usepackage[dvipdfmx]{color}    % color のリスト3は dvipdfmx→OK

この場合、Option clush を起こすことなく以下のファイルが読まれる:

  • color.sty
  • color.cfg
  • dvips.def
  • dvipsnam.def
  • mycolor.sty

いま仮に \PassOptionsToPackage の挙動がわからないとしよう。ソースをみる限り「最初のリスト1が空であり、リスト3は dvipdfmx を含む」ことは明らかである。にもかかわらず Option clash を起こさないということは、リスト1にどこかで dvipdfmx が追記されていなければならない。(3c)の場合に Option clash が起きたこととあわせて考えると、その役割を担ったのは \PassOptionsToPackage であろう。

二つ目も、color を2回読ませるソースによる実験結果と矛盾しない(4b):

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{mycolor}  % color のリスト1は dvipdfmx→読む(正常)
\usepackage[dvipdfmx]{color}    % color のリスト2は dvipdfmx→OK

この場合も、Option clush を起こすことなく以下のファイルが読まれる:

  • mycolor.sty
  • color.sty
  • color.cfg
  • dvipdfmx.def
  • dvipsnam.def

もし仮に \PassOptionsToPackage がクラスオプションと同様、すなわち“直接”指定でなかったとすればリスト1が空になっているはずで、リスト2の dvipdfmx について Option clash するはずである。すなわち、\PassOptionsToPackage は“直接”指定にあたるであろうと推察できるわけだ。

今までの(すべてが挙動から導かれる推察にすぎない)知見をまとめると

  1. xcolor が読まれると、color はとりあえず「オプション無しで読み込み済み」とみなされる
  2. その後で color が \usepackage または \RequirePackage される場合、増えた“直接”オプションがなければ無視するが、増えた“直接”オプションがあれば黙殺できずに Option clash する
  3. \PassOptionsToPackage はその前にパッケージが既に読まれていればリストに追記する
  4. \PassOptionsToPackage はその後にパッケージが読み込まれるのを検知すると“直接”オプションを渡す

ということになっているように見える。

以上の知見から得られる興味深い例をいくつか。

\listfiles
\documentclass{article}
\usepackage{color}
\usepackage[dvipdfmx]{color}

が Option clash を起こすのに対して

\listfiles
\documentclass{article}
\usepackage{color}
\PassOptionsToPackage{dvipdfmx}{color}
\usepackage[dvipdfmx]{color}

が Option clash を起こさないことである。理由はもちろん(4a)と同じで、それ以前の xcolor の時点で「オプション無しで読み込み済み」と決まったはずのリストに dvipdfmx が加えられているのだろう。もちろん

\listfiles
\documentclass{article}
\PassOptionsToPackage{dvipdfmx}{color}
\usepackage{color}
\usepackage[dvipdfmx]{color}

も(4b)と同じ理由で最初のリストが“直接”オプションによって作られているのである。

結局、どうやら \PassOptionsToPackage はそれ以前と以後の両方のリストにオプションを加えるはたらきをしているようで、

  • mycolor.sty では前のリストにも後のリストに dvipdfmx が加えるので問題ない
  • mycolor2.sty では後のリストだけに dvipdfmx を加えるのでエラー

ということだろうか。

何とも不思議な気がするが、こんなことでいいのだろうか? 一つありがたいのは、僕のシンプルな mycolor で hyperref と同じ現象を確認したことで、hyperref の面倒くさいコードを読みに行く手間が完全に省けたことである*2

以上の考察はコードをほとんど読むことなく、実際の現象からの推察にすぎないが、あくまでなんとなくだが \PassOptionsToPackage は都合が良いっぽい…?

ちなみに、一つだけ注意すべきなのは、「オプションがリストに加わることと、実際に実行されることとは必ずしも一致しない」ということである。例えば

\listfiles
\documentclass{article}
\usepackage{color}
\PassOptionsToPackage{dvipdfmx}{color}
\usepackage[dvipdfmx]{color}

の場合、\PassOptionsToPackage は dvipdfmx オプションをその手前の color のリストに加えこそすれ、実際には dvipdfmx.def を読ませるはたらきをしない。だから Option clash を起こさない一方で dvips.def だけが読まれるという期待外れの結果になる。リストと実際にはたらくオプションが違うことは忘れがちだが、非常に重要である。

*1:xcolor によって color が「読み込み済み」扱いにされるのはどうやら正しいようである。しかし、このとき color には“直接”指定されたオプションが無い状態になっている。一つ目のソースはその後 color を読み込むが、クラスオプションはリストに影響しないためリスト1もリスト2も空となっているのでエラーは出ない。二つ目や三つめのソースはリスト1に dvipdfmx が無いのにリスト2に dvipdfmx が入ってしまうので、リストが増えたことになってエラーが生じる。

*2:ちなみに hyperref の中での color.sty は、実際に hyperref.sty が読まれた直後に典型的な「依存パッケージの一つ」としての呼ばれるのではなく、かなり後になって \AtBeginDocument らしき場所で呼ばれるという特徴があるが、今回の件には影響しないはず。

2015-06-28

xcolor と color が難しい件(その1)

昨日の答えに関連して、LaTeX + dvipdfmx で処理する場合について、color と xcolor の両パッケージがどのような挙動を示すか調べてみた(あとで出てくる「リスト」の予想をコメントでソース中に書き込んだ)。

クラスオプションでドライバ指定した場合

まずはもっとも一般的な方法(1a)。

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage{color}     % color のリスト1は空→読む(クラスで正常)
\usepackage{xcolor}    % xcolor のリストは空→読む(クラスで正常)、color のリスト2も空→OK

だと \listfiles の結果は

  • color.sty
  • color.cfg
  • dvipdfmx.def
  • dvipsnam.def
  • xcolor.sty
  • color.cfg

が順に読まれる。ここで color.cfg が2回読まれるのは \InputIfFileExists{color.cfg}{}{} が使われているから。一方順序を入れ替えて(1b)

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage{xcolor}    % xcolor のリストは空→読む(クラスで正常)、color のリスト1は空→読まない
\usepackage{color}     % color のリスト2も空→OK

だと \listfiles の結果を見る限り

  • xcolor.sty
  • color.cfg
  • dvipdfmx.def

だけが順に読まれる。

パッケージに個別にドライバ指定した場合

こちらもよく見かける方法(1c)。

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{color}   % color のリスト1は dvipdfmx→読む
\usepackage[dvipdfmx]{xcolor}  % xcolor のリストは dvipdfmx→読む、color のリスト2は空→OK

この場合はクラスオプションの場合と同じで

  • color.sty
  • color.cfg
  • dvipdfmx.def
  • dvipsnam.def
  • xcolor.sty
  • color.cfg

となる。ところが順序を入れ替えた(1d)

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}  % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage[dvipdfmx]{color}   % color のリスト2は dvipdfmx→増えた!

なら LaTeX のエラーが発生する。さらに h を入力してヘルプを表示すると

 ! LaTeX Error: Option clash for package color.
 
 See the LaTeX manual or LaTeX Companion for explanation.
 Type  H <return>  for immediate help.
  ...
 
 l.6 \begin
           {document}
 ? h
 The package color has already been loaded with options:
   []
 There has now been an attempt to load it with options
   [dvipdfmx]
 Adding the global options:
   ,dvipdfmx
 to your \documentclass declaration may fix this.
 ?

ん? xcolor を読んだ時点で、color は読まれていないのに「オプション無しで読み込み済み」かのように扱われているらしい。このまま無理やり Enter で継続させると、一応 DVI ファイルが生成する。\listfiles の結果をみると color の読み込みは結局行われず

  • xcolor.sty
  • color.cfg
  • dvipdfmx.def

だけが読まれていることがわかる。ということは(1d')

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}  % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage{color}             % color のリスト2も空→OK

と書けば、「オプション無しで読み込み済み」と矛盾しないのでエラーは発生しないことになる。何とも不思議である。

hyperref を使った場合

ところで、先日の hyperref の件について。hyperref は colorlinks=true を有効にすると color.sty を読むはずである。そうすると、上で起きたのと同じ現象が確認できるはずで、僕が提案している「\DeclareVoidOption{dvipdfmx}{...} に \PassOptionsToPackage{dvipdfmx}{color} を加える」というパッチを施すと Option clash が起きそうな気がしてきたので、確認することに*1

まず、パッチ前の hyperref について、クラスオプションでドライバ指定した場合(2a)。

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage{xcolor}     % xcolor のリストは空→読む(クラスで正常)、color のリスト1は空→読まない
\usepackage[colorlinks=true]{hyperref}                             % color のリスト2も空→OK

この場合、hyperref によって color が呼ばれることはなかった。

  • xcolor.sty
  • color.cfg
  • dvipdfmx.def

続いて、このソースで xcolor を読まないようにすると(2b)

\listfiles
\documentclass[dvipdfmx]{article}
\usepackage[colorlinks=true]{hyperref}   % color のリストは空→読む(クラスで正常)

この場合は hyperref によって color が呼ばれる。クラスオプションを付けているのでドライバは dvipdfmx.def が渡る。

  • color.sty
  • color.cfg
  • dvipdfmx.def
  • dvipsnam.def

今度は、クラスオプションを除去し、個別にドライバ指定してみる(2c)。

\listfiles
\documentclass{article}
\usepackage[dvipdfmx]{xcolor}  % xcolor のリストは dvipdfmx→読む、color のリスト1は空→読まない
\usepackage[dvipdfmx,colorlinks=true]{hyperref}                  % color のリスト2も空→OK

この場合は color が呼ばれず、dvips.def が読まれる問題とも無縁だった。このソースで xcolor を読まないようにすると(2d)

\listfiles
\documentclass{article}
\usepackage[dvipdfmx,colorlinks=true]{hyperref}   % color のリストは空→読む(異常)

こちらはクラスオプションもリストも存在しないので、color が dvips.def を誤って使ってしまうので異常である。これがまさに先日の検証どおりで、問題である。

  • color.sty
  • color.cfg
  • dvips.def
  • dvipsnam.def

ここに僕が提案しているパッチを施した場合を実験してみると、クラスオプションの場合・個別オプションの場合ともに

  • xcolor ありの場合:Option clash かと思いきや、実際には color は呼ばれず正常
  • xcolor なしの場合:color に正しく dvipdfmx ドライバ指定が渡り正常

となることがわかる。あのパッチで問題はなさそうで安心したが、xcolor と color の関係がイマイチつかめない。どういう状況なら color が読まれ、またある状況なら読まれないのだろう? というわけで、再現がより簡単な「パッチ後の hyperref」を単純化した例で確認してみたい。

続く

*1:従来の hyperref は dvipdfmx ドライバ指定時にオプション無しで color を呼ぶ仕様だったので、xcolor が前の段階で読まれていて「color はオプション無しで読み込み済み」という扱いでも問題が起きることはなかった。今危惧しているのは「color がオプション無しで読み込み済み」扱いにされた状況で hyperref が dvipdfmx オプション付きで color を呼ぼうとしたとき、Option clash しそうだという恐れである。

2015-06-27

「LaTeX でエラーが発生、しかし出力は正常」な例

とある問題

問題:「LaTeXにエラーを起こさせた上で、かつ期待通りの正常な出力を得るソース例を提示してください。」 #LaTeX クイズ

の解答をしばらく考えていたのだが、やっと一つ思いついた。そんなことを考えていた理由は、TeX2img の「少々のエラーは無視して画像化を強行する」というオプションを廃止すべきかどうかという論題に対して、これが存在するメリットを探すこと。実際、TeX2img ユーザから期待外れの出力に戸惑った報告を受けたこともあり、筋の良いオプションとはいえないことは確かであるが、ずっと気になっていたのである。

解答例は doraTeX さんの Issue 15 にもう書き込んでおいた。

続く

2015-06-26

hyperref パッケージの改善案

TeX Wiki の hyperref の項目を眺めていて、注意点に「hyperref と graphicx の組み合わせでエラー」というのがあった。コメントが付いていないので、3年近くにわたり誰も検証していないらしく、チョット調べてみた*1

hyperref の colorlinks=true オプションの調査

例示ソースは報告があったページのとおり。これを pLaTeX + dvipdfmx で処理しようとすると、エラーが出て pLaTeX が止まる。\listfiles でファイル一覧を見ると

   *File List*
   pldefs.ltx    2000/07/13 v1.2 pLaTeX Kernel (Default settings)
    jy1mc.fd    1997/01/24 v1.3 KANJI font defines
    jy1gt.fd    1997/01/24 v1.3 KANJI font defines
    jt1mc.fd    1997/01/24 v1.3 KANJI font defines
    jt1gt.fd    1997/01/24 v1.3 KANJI font defines
  kinsoku.tex
  article.cls    2014/09/29 v1.4h Standard LaTeX document class
   size10.clo    2014/09/29 v1.4h Standard LaTeX file (size option)
 hyperref.sty    2012/11/06 v6.83m Hypertext links for LaTeX
 hobsub-hyperref.sty    2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO)
 hobsub-generic.sty    2012/05/28 v1.13 Bundle oberdiek, subset generic (HO)
   hobsub.sty    2012/05/28 v1.13 Construct package bundles (HO)
 infwarerr.sty    2010/04/08 v1.3 Providing info/warning/error messages (HO)
  ltxcmds.sty    2011/11/09 v1.22 LaTeX kernel commands for general use (HO)
 ifluatex.sty    2010/03/01 v1.3 Provides the ifluatex switch (HO)
   ifvtex.sty    2010/03/01 v1.5 Detect VTeX and its facilities (HO)
  intcalc.sty    2007/09/27 v1.1 Expandable calculations with integers (HO)
    ifpdf.sty    2011/01/30 v2.3 Provides the ifpdf switch (HO)
 etexcmds.sty    2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO)
 kvsetkeys.sty    2012/04/25 v1.16 Key value parser (HO)
 kvdefinekeys.sty    2011/04/07 v1.3 Define keys (HO)
 pdftexcmds.sty    2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO)
 pdfescape.sty    2011/11/25 v1.13 Implements pdfTeX's escape features (HO)
 bigintcalc.sty    2012/04/08 v1.3 Expandable calculations on big integers (HO)
   bitset.sty    2011/01/30 v1.1 Handle bit-vector datatype (HO)
 uniquecounter.sty    2011/01/30 v1.2 Provide unlimited unique counter (HO)
 letltxmacro.sty    2010/09/02 v1.4 Let assignment for LaTeX macros (HO)
  hopatch.sty    2012/05/28 v1.2 Wrapper for package hooks (HO)
 xcolor-patch.sty    2011/01/30 xcolor patch
 atveryend.sty    2011/06/30 v1.8 Hooks at the very end of document (HO)
 atbegshi.sty    2011/10/05 v1.16 At begin shipout hook (HO)
 refcount.sty    2011/10/16 v3.4 Data extraction from label references (HO)
  hycolor.sty    2011/01/30 v1.7 Color options for hyperref/bookmark (HO)
   keyval.sty    2014/10/28 v1.15 key=value parser (DPC)
  ifxetex.sty    2010/09/12 v0.6 Provides ifxetex conditional
  auxhook.sty    2011/03/04 v1.3 Hooks for auxiliary files (HO)
 kvoptions.sty    2011/06/30 v3.11 Key value format for package options (HO)
   pd1enc.def    2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO)
 hyperref.cfg    2002/06/06 v1.2 hyperref configuration of TeXLive
      url.sty    2013/09/16  ver 3.4  Verb mode for urls, etc.
 hdvipdfm.def    2012/11/06 v6.83m Hyperref driver for dvipdfm
 rerunfilecheck.sty    2011/04/15 v1.7 Rerun checks for auxiliary files (HO)
 graphicx.sty    2014/10/28 v1.0g Enhanced LaTeX Graphics (DPC,SPQR)
 graphics.sty    2014/10/28 v1.0p Standard LaTeX Graphics (DPC,SPQR)
     trig.sty    1999/03/16 v1.09 sin cos tan (DPC)
 graphics.cfg    2010/04/23 v1.9 graphics configuration of TeX Live
 dvipdfmx.def    2015/03/26 v4.04 LaTeX color/graphics driver for dvipdfmx (TeX Live/ChoF)
    color.sty    2014/10/28 v1.1a Standard LaTeX Color (DPC)
    color.cfg    2007/01/18 v1.5 color configuration of teTeX/TeXLive
    dvips.def    2014/10/14 v3.0j Driver-dependent file (DPC,SPQR)
 dvipsnam.def    2014/10/14 v3.0j Driver-dependent file (DPC,SPQR)
  nameref.sty    2012/10/27 v2.43 Cross-referencing by name of section
 gettitlestring.sty    2010/12/03 v1.4 Cleanup title references (HO)
 colorlinks-test.out
 colorlinks-test.out
  ***********

ああっ! dvipdfmx.def のあとに dvips.def が読まれているではないか! つまり構図としては有名な ZR さんの記事と同じで

  1. graphicx のドライバ指定が dvipdfmx なので dvipdfmx.def が読み込まれる。
  2. hyperref が colorlinks=true の場合には、最後に内部で color を読み込む。
  3. このとき、たとえ hyperref に dvipdfmx ドライバ指定しても color にはそれが渡らないため、dvips.def が間違って読み込まれる。

ここで注意すべきなのが、graphicx と color はドライバファイルを共有しているという事実。つまり、画像読み込みマクロが dvipdfmx 用から dvips 用に上書きされてしまう。上の失敗例のソースで「拡張子を明記すると成功し、省略すると失敗」なのは

dvipdfmx.def でせっかく定義された「拡張子省略時に PDF -> PNG -> JPG -> EPS の順に探す」という処理が、dvips.def で上書きされたせいで「拡張子省略時は EPS を探す」という処理に変更されてしまうため

だと思う。これは dvipdfmx オプションを hyperref に与えても起こるので、さすがに筋が悪い… というわけで、ありきたりな対処法*2TeX Wiki に書いた後、Forum に訊いてみたのだが、どうも埒が明かない気がした(直すとしても日本人ではない)ので、TUG の tex-live メーリスに投げた。いま英語で応戦中で、ようやく参加者の一部に意図が伝わり始めた感触がある。

追記 (2015-12-27):まだ解決していないので積み残しリストに追加

追記 (2016-05-19):hyperref の GitHub repository ができたことを知り、早速 Pull request してみたらめでたく merge された

続く

*1:よくあるドライバの話だと検討はつくのに、なんで詳細を調べずにあんなところにリンクだけ貼るのだろう…

*2:グローバルオプションで dvipdfmx ドライバ指定 or 事前に color に dvipdfmx ドライバ指定を明記する。

2015-06-25

色の感覚を鍛えたい…

Facebook 等で突如話題になっている「色覚テスト」。短時間でできて楽しいと好評のようななのでやってみたところ、5回挑戦して自己ベストは30だった。その後、スクリーンショットをとりながらテストしようと思ってもう2回挑戦し、35までは到達。

最後にできなかった問題。
f:id:acetaminophen:20150626004507p:image

よく見ると分かるが、制限時間15秒で見えなかった…ちなみに僕は「群青色系」と「黄土色系」の区別が特に苦手なようだ。で、答えが分かりやすいように“ペイント”でちょこっと編集。スポイトツールで左上のセルの色を“吸い取り”、その色の直線を書くセルに重なるように引くと、一つのセルだけ直線と背後のセルの色が違うのが目立つ。
f:id:acetaminophen:20150626004506p:image

RGB
周辺の色168173203
一つだけ異なる色174179209

ペイントの機能で色の RGB 値を表示するとこんな感じ。

色合い鮮やかさ明るさ
周辺の色15460175
一つだけ異なる色15466180

もう一つの指標、色合い・鮮やかさ・明るさも。色合いは同じようだ。

ところで、この色覚は男女で異なるという報告がある。2012年のニュースをたどっていくと、海外のニュースにたどりつき、さらにオープンアクセスジャーナルの論文に行き着く。

そういえば、今日の講義資料を Twitter で晒したが、なかなかあれはヒドイ。色覚異常検査グラフと揶揄されるとおり、配色が色覚異常の方にとっては見分けのつかない組み合わせである。赤と青の明度が近すぎるうえ、暖房と冷房のイメージとも逆。なんでこうなったのか…

2015-06-24

「LaTeX マクロ」による文書のメンテナンス性という話

個人ブログでほぼ触れたことがないが、僕は「東大 TeX 愛好会」の会員である。
latex.ltx リーディング”にも“リーディングリーディング”にも参加していないので外から見守っているのだが、この前の日曜に初めて会合に参加した(食事会のみ)。TeX/LaTeX の話題であんなに盛り上がる集会という時点で相当である… が、楽しい時間を過ごした。

順番が回ってきたので「今週のマクロ」を月曜に投稿した。

同時に、TeX Wiki の「LaTeX 入門/LaTeX マクロの作成」もゼロから書いた。この2つは元々連動させる予定だったうえ、以前メインブログに出した入門記事の続編でもある*1

そもそも「LaTeX 入門」は一か月かけて再構築した。Wiki 設立当初から LaTeX の基礎的な解説であるにもかかわらず「TeX 入門」として作成されていて、誤解を助長していたと思われる。その一方でただ一つ「TeX 入門/マクロの作成」だけがカテゴリーコードをはじめとする LaTeX とは無縁な解説をしていて、これまた LaTeX マクロまで難解なものだという誤解を助長していたはずだ。これら二重の問題を解消すべく、5月からTeX 入門」を一斉に「LaTeX 入門」に名称変更して完全分離を図った。そのとき

  • TeX 入門/マクロの作成」だけは「TeX 入門」に残す
  • 新たに「LaTeX 入門/LaTeX マクロの作成」を新設

という処置により、LaTeX マクロの重要性ととっつきやすさを前面に押し出した。ついでに LaTeX 入門では、図表の取り扱いの解説を充実させ、さらに相互参照とリンク・文献引用・索引作成の3項目を新設または増強した。これで、個人的には LaTeX 入門に関してはリニューアルできたと確信している。あとは読者に戻ってきてもらうのみ。

*1:あのとき「フォントの変更」という例を挙げてしまったのも、実は一つの理由に「LaTeX マクロのメリット」に関する記事をどこかで書くつもりでいたからというのがある。そのため、何としても「マクロを作らない意味論・構造化」を例にしたかったのである… 結局うまい説明が見当たらず、中途半端になってしまった感があるが。

2015-06-23

久々に早く帰宅

雨が降りそうだったので18:30にラボを出て帰宅。帰り着いて1時間も経たないうちに大雨と雷…なんか近くに落ちた気がする。今日もまた雨には濡れずラッキー。

早く帰ったのでレポートを進める。論文をA4一枚に要約するの、結構難しいんですが…

2015-06-22

有機合成の検討中

うちのラボでは有機合成なんてやる機会はまずないのだが、今ほしい試薬が高額すぎるので合成を検討中。論文を漁って予備調査。学生実験の講義以来で、しかも手本なしで論文を再現しなければならない… というわけでしばらくラボでは忙しくなりそう。

2015-06-21

molconvert と Open Babel

Open Babel の 2D 画像生成機能が貧弱だという件。僕のブログでも実際に活用してはいるが、画像が残念なのはまったくもってその通りである。ただし、代わりになる便利ツールが存在しないので、仕方なく使っているのが現状。
では代替がまったくないのかというとそうではなく、一応 Marvin Sketch(こちらも紹介済みに付属している molconvert というバッチファイルまたはシェルスクリプトが使える。もちろん僕も存在は把握していて、実際に使ったこともあるが、ドキュメントが少ない。とはいえ、明らかに綺麗な画像を作ってくれるし、直接 PDF 画像を出力できる点も魅力である。Twitter参考になりそうなリンクを挙げていただいたのでメモしておく。

ただ、ややこしいのが「Windows の場合、Java の bin ディレクトリのパスがバージョン番号を含んでいるため、Java アップデートの度に変わってしまう」という問題。一応 molconvert などの Marvin 付属スクリプトでは java.ini というファイルに Java のbin ディレクトリを格納することになっているので、java.ini を手動で書き変えることで対応可能ではある。とはいえ、いちいち書き変えるのが面倒…(これは明らかに Java が悪い)。
それと、Marvin のライセンスの「スタンドアロン」が何を意味するのかよく把握していなくて、TeX から呼び出したり自分で書いたスクリプトから呼び出したりという molconvert の利用が許されるのかわかっていない…

2015-06-20

TeX2img FAQ を作りました

先日思い立ったばかりだが、早速作ってみた。このサブブログで TeX2img タグを付けていた記事をさかのぼると結構書いてあったので、メモしておいた甲斐があった。最近 Twitter で拾ってランダムに答えていた部分も活用し、少しずつ充実させていきたい。

従来公式サイトにあったものも順次移行したいと思っていて、手始めにいくつかスクリーンショットとともに掲示した。公式サイトではスクリーンショットのみで多少不便を感じていたので、TeX Wiki のほうではソースをテキストでコピペできるようにしておいた。もちろん color パッケージに dvipdfmx ドライバオプションがわたるように修正してある。

2015-06-19

TeX Wiki の改訂中

この一週間で、また大規模な改訂を実施した。作業途中の部分もあるので、ここで忘れないようにメモしておく…

  • TeX入手法:プラットフォームによらず大まかな流れは一緒なので、冒頭で説明を加えた。合わせて、よくある勘違いやトラブルシューティングも末尾に載せてみた。
  • TeX のディレクトリ構成:作り始めてからしばらく放置していたので、作業を再開。teTeX の時代に書かれたドキュメントは外部サイトでいくつか見つかったが、TeX Live や W32TeX についてはあまり書かれていないようだったので最新情報にすべく執筆中。
  • PDFの作り方:Word で PDF を作る際に、わざわざ最近は非推奨のフォントを埋め込まない方法を説明していた。2005年ごろに書かれたらしい記述で、たぶん一項目にたくさん書かれすぎていて見落とされてきたのではないかという印象。Microsoft Office に移転して少し修正した。
  • TeXShop/設定:これは従来の記述だと、大半の人(特に初心者)にとって必要のない記述が上のほうにあって邪魔だった。latexmk を使う方法をいちいち醜い全角空白による GUI 再現していたり、TeXShop 付属シェルスクリプトをわざわざ展示していたりしたので、これらを削除。シェルスクリプトについては、TeXworks などの項目で示されていたバッチファイルと併せてスクリプトへ移転。

それから、試しに LaTeXiTスクリーンショットを入れてみた。やっぱり画像のほうが見やすいと思う。ただし、コピペできるようにテキストも書いておくのが親切だろう。

で、やっぱり TeX Wiki には必要なことがちゃんと書かれていて、問題なのはやっぱり書かれている順番や場所だと思う。編集していると思いがけず知らないことを発見するし、それを本来あるべき場所に配置しなおすだけでも勉強になるというわけだ。これだから、編集に携わることをやめられないのである。

(なお、ここのメモはあくまで個人の意見です。)

2015-06-18

kpsewhich と「実際に使われるファイル」が必ずしも一致しない件(続)

この前、気づいたことを書いただけで続きを忘れていたのをふと思い出した。

kpsewhich の結果の復習

W32TeX には「jarticle.cls」「jbook.cls」「jreport.cls」が2つずつあって、何も気にせずに kpsewhich して返ってくるのは

 $ kpsewhich jarticle.cls
 c:/w32tex/share/texmf-dist/tex/jlatex/base/jarticle.cls

すなわち NTTjTeX のものであるのに対し、pLaTeX や upLaTeX でタイプセットしたときに実際に使われるのは、ログを見る限り

 c:/w32tex/share/texmf-dist/tex/platex/base/jarticle.cls

すなわちアスキー pTeX のものになる。

これは「kpathsea は(プログラムが指定されない場合は)ディレクトリをアルファベット順に検索している」と考えれば自然であろう。そして、おそらく pLaTeX や upLaTeX でタイプセットした場合のみ、TEXMFDIST/tex/platex 以下を優先的に探すという仕組みになっていると想像できる。この件については仕様書 "Kpathsea library" (kpathsea.pdf) に書かれている。

目的のファイルを返すには?

では、W32TeX の kpsewhich で pLaTeX や upLaTeX の使うファイルを探すにはどうすればよいかというと、単純にプログラム名を -progname= で指定すればよい。すなわち

 $ kpsewhich -progname=platex jarticle.cls
 c:/w32tex/share/texmf-dist/tex/platex/base/jarticle.cls

となる。もちろん -progname=uplatex とすれば同じアスキー pTeX のものが返ってくるが、もし -progname=pdflatex とすれば NTTjTeX のものが返ってくる。

同じ TEXMF ツリーの中に同一ファイル名があってよいのかと思うかもしれないが、TeX のディレクトリ構成 (TDS) では「名前は同じだが内容は違う」というファイルが存在してもよい(どちらが使われるかは検索パスによる)*1ことが、こちらは "Directory Structure for TeX Files" (tds.pdf) に書かれている。

*1:ただし、例外は「TEXMF/tex と TEXMF/tex/generic の1番目のレベルの下位ディレクトリの中ではファイル名はユニークでなければならない」と定められている。

2015-06-17

梅雨?

けっこう前に梅雨入りしたはずだけど、雨が少ない。真夏によくある夕立ち程度で、短時間に猛烈な雨が降る印象。梅雨ってこんなもんじゃなかったよなあ。野菜の値上がりが心配。

夜は鳥貴族でラボ飲み。店で飲むのは久しぶりすぎる。

2015-06-16

帰り着いたら雨

今日は進学振り分け前のガイダンスなるものがあったので、久々に駒場へ。うちの学科だけ手伝いで参加した先輩学生の数が多すぎた…しかも全員男で威圧感ハンパないw

帰りに渋谷の TSUTAYA に寄って、聴くだけ聴いて帰ってきた(いつも通り)。夜10時半くらい。帰り着いてしばらくしたら雨が降り出して、一気に強くなって雷まで鳴っていた。Twitter のタイムラインを見ていたら、本当に西から一気に崩れたらしい。僕は間に合ってラッキー。そういえば先日タイムラインで雨男どうしのバトル(?)があったけど、そんなのとは無縁で昔からずっと晴れ男です。

2015-06-15

TeX2img FAQ でも作ろうかなあ

本題の前に、やっぱり LuaTeX-ja の横組み専用仮名の問題が解決したというコメントをいただいたので試したくなってやってしまった*1無事解決していて良かった*2

Twitter で「TeX2img が使い物にならない」と言われてしまって気になったので返事したら、ただ数式環境に入れていないだけだった。
ん? そういえばさっきのスクリーンショット、なんで画像できたんだろう? \frac って本文で使えたっけ? 普通 "! Missing $ inserted." とかいろいろ怒られるんじゃないの?

というわけでちょっと考えたら、たぶん「少々のエラーは無視して画像化を強行する」を ON にしているのかな(というか絶対そうだ)。僕のところでも再現してみた。

f:id:acetaminophen:20150616004744p:image

いかんなあ、このオプションあまり好きじゃない…はたしてメリットはあるのか?
追記 (2015-06-20):TeX Wiki 内に TeX2img FAQ を早速公開
追記 (2015-06-28):エラーが生じ、かつ正常な出力になる例を思いついた
追記 (2015-08-04):画像化を強行した場合に警告を出すように改善

そういえば、LuaTeX-ja の expert の問題は h7k さんが Twitter で拾ったと書いていた… こんな感じでいつも見られているのだろうか?(僕も TeX2img のツイートをよく拾っているけど、h7k さんは Twitter にいないよなあ…)

*1:朝にはやらないと言ったくせに…

*2:もう一つまた投げてしまってゴメンナサイ…

2015-06-14

年に一度の TeX Live 祭り終了

TeX Live 2015 (Windows) と MacTeX-2015 をインストールしたので、メインブログ更新。dvipdfmx まわりはかなり改善したような気がする。でもやっぱり TeX は (ry

ところで、まだ最近の TeX 周辺の懸念が解消していない。

まだやることは多そうだ。

追記:LuaTeX-ja の問題は解消。ありがとうございました。

2015-06-13

化学の読みたい本メモ

読んでみたいと思いつつ、余裕が無くて忘れそうなのでここでメモ。

ちょっと古い本だが、最近 Twitter で挿絵が回ってきた。これだけでも十分面白そう。調べてみると、昔ケムステでも昔紹介されていた。

おもしろいといえば、クリスチャン分析化学も確かに面白い。

クリスチャン分析化学〈1〉基礎編

クリスチャン分析化学〈1〉基礎編

この本は手元にあって、分析化学の講義のために購入した。全部を読んでいるわけではないが、指定された教科書では詳しくないところがあって、やむなく読むということがあった。ただし、そんなに読みやすいわけではない…分析化学のいい教科書、本当に少ない。

2015-06-12

kpsewhich と「実際に使われるファイル」が必ずしも一致しない件

今日、フォーラムの質問で「jreport.cls を使ってタイトルページを作らず、かつ \chapter ごとの改ページも抑制したい」という要望が。中途半端にしか解っていない状態にもかかわらず一応の回答を送ってしまったので、もしかしたら危ないかもしれないとちと反省。で、試していて jsbook.cls の report オプションを初めて使ったときに疑問が生じてしまい、また逆に質問を投げてしまった

W32TeX には jclasses が2つずつある!

さて、jreport.cls についてだが、実は W32TeX には「jarticle.cls」「jbook.cls」「jreport.cls」が2つずつある。一つは NTTjTeX の付属品、もう一つはアスキー pTeX の付属品。ほとんどの人が使っているのはもちろんアスキー pTeX の方。ちょっと勘違いしやすいのは、W32TeX で kpsewhich して返ってくるのが

 $ kpsewhich jarticle.cls
 c:/w32tex/share/texmf-dist/tex/jlatex/base/jarticle.cls

であり、すなわち NTTjTeX のものであるということ。一方、pLaTeX を使ってタイプセットしたときに実際に使われるのは、ログを見る限り

 c:/w32tex/share/texmf-dist/tex/platex/base/jarticle.cls

である。普段 jsclasses (jsarticle.cls, jsbook.cls) しか使わないので考えたこともなかった… もちろん TeX Live には NTTjTeX が入っていないので

 $ kpsewhich jarticle.cls
 c:/texlive/2015/texmf-dist/tex/platex/base/jarticle.cls

アスキー pTeX のものが返ってくる。

ん、2015? …そう、今日 TeX Live 2015 が出たので早速 Windows/Mac ともにインストールした。ちなみに先日の挙動確認テストTeX Live 2013 を美文書 DVD からインストールし、さらに TeX Live 2014 もネットワークインストールたため、手元では

  • W32TeX: 2012-11-04, 2014-12-27, 2015-06-11
  • TeX Live (Windows): 2013, 2014, 2015
  • TeX Live (Cygwin): 2014
  • MacTeX (OS X): 2014, 2015

が使える状態になった。

続く

2015-06-11

W32TeX でいろいろなエラーに見舞われる件(笑)

僕は W32TeX を毎月 TeX インストーラ 3 を使って「定例アップデート」することにしている*1。しかし、特に TeX Live のメンテナンス期である毎年4月から6, 7月にかけてはどうしてもディストリが不安定になりがちなのかもしれない。今年度に入ってから3回目のアップデートを今日行ったのだが、そのうち2回はエラーに見舞われた。こういう時のためにいつも「旧環境を C:\w32tex-old という名前のフォルダに丸ごと複製してから C:\w32tex を差分アップデートする」という方法を取っていることが功を奏する。

(1) W32TeX 更新時のエラーその1

1回目は2015年4月23日にアップデートしたとき。ミラーサイトにあるアーカイブが過渡期だったせいか、実行ファイルのうちいくつかが kpathsea620.dll に、残りのいくつかが kpathsea621.dll に依存しているというちぐはぐな状態になっていた。というわけで、不足している dll に依存した実行ファイルでは以下のようなエラー画面が出現…*2

f:id:acetaminophen:20150612004108p:image

このときは、ミラーが更新されるのを待ってから翌日再度アップデートすると正常になった。めでたしめでたし。

(2) W32TeX 更新時のエラーその2

2回目は今日。なんだか mktexlsr で今までと ls-R の場所が違うなあと思っていたら…

f:id:acetaminophen:20150612004107p:image

実害がないかと思いきや、texdoc コマンドでエラー発生。texdoc graphicx のようにすると graphicx パッケージのドキュメントが出てくるはずが

[string "c:/w32tex/share/texmf-dist/scripts/texdoc/sea..."]:432: attempt to concatenate local 'TEXMFPROJECTS' (a nil value)

なるエラーが。texdocc コマンドなら問題なくドキュメントを読めるのだが、どうやら従来の TEXMFPROJECTS なる変数が TEXMFPROJECT なる名称に変更されていたらしい。僕にはどうしようもないので早速質問。ちょっと不便なので、明日回答を期待。→追記 (2015-06-12):W32TeX で変数名を変更した際に、関係するファイルのうち一つ (search.tlu) に変更漏れがあったそうな。手元で修正して解消(公式も即修正済み)。

(3) ispell 更新時のエラー

ついでに、TeX インストーラ 3 で ispell を更新しようとしたときにも「不明なエラーが出てしまったので、ログを見に行くと

ispellの情報取得開始
ispell::get_info : C:/abtexinst/lib/ruby/site_ruby/1.8/vr/vruby.rb(490) undefined method `>' for true:TrueClass

だそうな。試行錯誤の結果(自分しか必要ないのでテキトー)

 flist.reject!{|f| not /ispell.*-w32\.tar\.xz/ =~ f["file"]}

 flist.reject!{|f| not /ispell-3.4.00-w32\.tar\.xz/ =~ f["file"]}

に書き変えて無理やり ispell をアップデートした。→追記 (2015-07-11):今度こそ真面目にプラグインを fix した。本家に取り込んでもらう予定→本日公開され、解消。

(4) LuaTeX-ja で横組み専用仮名が文字化け

もう一つついでに、LuaTeX-ja を使って「横組み専用仮名」を埋め込んだ PDF を Adobe Reader などで開き、コピペしようとすると文字化けするという現象も耳にした。僕も実際に MacTeX-2014 でやってみると、(u)pLaTeX + dvipdfmx なら \usepackage[expert]{otf} としても大丈夫なのに、lualatex なら \usepackage[hiragino-pron,expert]{luatexja-preset} として失敗。同じ作業を W32TeX でも試した(僕は Windows 環境に hiragino-pron を持っていないので、同じく OpenType フォントである kozuka-pr6n を使った)ところ、やはり再現する。ちなみに、Windows でよく使われる ipa や ipaex のようなフォントを指定しても「横組み専用仮名」は使われない(そもそもこれらの TrueType フォントにはグリフがない)。代わりに

* fontspec warning: "icu-feature-not-exist-in-font"
* OpenType feature 'Style=HorizontalKana' (+hkna) not available for font 'IPAExMincho' with script 'Latin' and language 'Default'.

なる警告が出るので、そもそもこの「横組み専用仮名」問題とは無縁。というわけで、文字化けの原因はいまだ不明である。今度もう少し調べてみたいのでメモ。→追記 (2015-06-15):早速対応していただいた。こちらのコメント参照。

…検討課題がどんどん積もっていく。→追記のとおり、全部解消しました!

*1Windows Update は無視するくせに…

*2:なお、画像が残っていなかったので今日無理やり再現キャプチャ。

2015-06-10

破線のパス変形(Xpdf の pdftops が有用そうな件)

ここまでの検証で、破線への対応が案外難しいことが分かってきた… そこで逆に「pdfiumdraw の PDF → EMF 変換の段階で対策するのではなく、PDF にパス変形の前処理をする」という対策はありえないのか考えてみた。
パス変形をコマンドで行うとなると、PostScript コードを手で書き換える処理が必要になる。しかし、既に gs9.15 以降の eps2write で作った EPS(および ps2write で作った PS)には「ソースに LZW バイナリが含まれる」ことがわかっているので、簡単には書き換えられない。いま把握している方法で使える可能性があるものを列挙する:

候補1:Ghostscript を使って EPS に変換

eps2write に -dCompressPages=false オプションを付けると、EPS ソース中の「ページ記述部分」すなわち setdash などのパスを表すコマンドを圧縮しないようだ。これは、TeX2img の動作条件の範囲内で済むというメリットがあるが、まだバイナリが一部だけ取り残されたままなのが心配だ(以前の考察より)。

候補2:QPDF を使って QDF に変換

QPDF を使うと PDF のストリームを QDF という形式に変換でき、これはテキスト形式で読める。ページ記述部分は PostScript コードなので、読み書きは可能であろう。しかし、問題は QDF から元の PDF に戻す fix-qdf なるコマンドが Perl スクリプトであることと、そもそも W32TeX に入ってはいるが TeX Live に入っていないことである。

候補3:Xpdf または Poppler に付属の pdftops で EPS に変換

この pdftops コマンドは Ghostscript と違ってバイナリを含まない PS/EPS ファイルを出力する。この PostScript コードを編集して PDF に戻せばよいかもしれない。これはどうやら TeX Live にも W32TeX にも(Xpdf 由来のものが)入っているらしいので、最も有望。

…と挙げてはみたが

以上3つの方法が思いつくが、いずれも結局 PostScript コードを書き換えないといけない(破線パターンを座標に全て置き換える数値計算…)。PostScript については先日の記事で簡単に説明したが、具体的には

 [0.99628 1.19553] 0 d
 10 M
 172.73 215.961 m
 172.73 228.418 l
 S
 [0.99628 1.19553] 0 d
 152.406 215.864 m
 146.031 226.422 l
 S

という変形前のコードを見て

 [] 0 d
 10 M
 172.73 215.961 m
 172.73 216.957 l
 172.73 218.153 m
 172.73 219.149 l
 172.73 220.344 m
 172.73 221.34 l
 172.73 222.539 m
 172.73 223.535 l
 172.73 224.731 m
 172.73 225.727 l
 172.73 226.922 m
 172.73 227.918 l
 S
 152.406 215.864 m
 151.891 216.715 l
 151.273 217.739 m
 150.758 218.59 l
 150.141 219.614 m
 149.625 220.469 l
 149.008 221.493 m
 148.492 222.344 l
 147.875 223.368 m
 147.359 224.219 l
 146.742 225.243 m
 146.227 226.098 l
 S

に計算しなおせばいいわけである。…といっても見てのとおり相当面倒であるし、こんなのが EPS ファイルの各所に点在しているわけなので、かなり手間がかかりそうだ*1

追記 (2015-12-06):Ghostscript を使えば EPS に対して破線のパス変形を自動化できることを発見!

ただ、先日 TeX Forum にあった「Office に EPS を貼り付けられない」という問題には、Xpdf の pdftops を通すだけでも対処できる*2ので、検討の価値はあるかも。

*1:ちなみに、ここで挙げた3つの方法のうち「パスの書き変えに最も適していそうな“素性のよい”EPS ファイル」を作るのは pdftops である。GhostScript のようにバイナリを含まず、QPDF のように xref テーブルを持たないので、書き変えが必要な部分が破線パターンを含む領域に絞られるからである。

*2:Office 2010 で試したところ、PS ファイルは表示できないが、EPS ファイルは表示できるようである。幸い、パス変形という厄介な作業は不要で、コマンド一発で対処できて便利そう。

2015-06-09

pdfiumdraw の EMF 出力(解決へ向けて…)

(またまた前回から続く)

再び pdfiumdraw へ

以上でわかった「破線の描画方法依存性」という点について、pdfiumdraw 開発当時に苦戦した改善点のうち心当たりがあるのが…

abenori さんの説明 (GitHub Issues) より一部抜粋
pdfium は GDI という Windows の描画の仕組みを通じて PDF を描画することができます.ウィンドウへの描画はもちろん,EMF を作る際にもこの仕組みが利用できます(というか EMF の中身は GDI の命令っぽい?)この命令群は整数値で場所をやりとりするので,小さい図形ではどうしても汚くなってしまうようです.(小数→整数としたときに誤差が出るので.)そこで,この縦横の整数値を 2000 倍に伸ばせば(つまり,それまでの 1 という長さが 2000 になる),より綺麗に描けているということのようです.原理的には増やせばもっと綺麗になるのではないかと思います.…

要するに、デフォルトの1倍では EMF でパスが綺麗にならなかったので、精度よく描画するために拡大することにしたというわけ。これが pdfiumdraw では最終的に縦横1000倍拡大*1ということで落ち着き、3月にリリースした。

しかし、今回僕が試した範囲内での現象から推測するに、どうやら破線を表示する際にこの1000倍があだとなって数値オーバーフローしたらしい。というのも、PDF 上で全く同じに見える破線を四隅に配置したとき「拡大率によっては右下に置いた破線だけが異常*2になり、拡大率を徐々に大きくすると異常が全体に広がっていく」という現象がみられたからである。ということで、拡大率をオーバーフローしない範囲内に設定しさえすれば良いのではないかという感触をつかんだ。

ではなぜ破線だけこのようなオーバーフローが発生するのかは依然謎である。前回の解析から考えられる可能性としては「PostScript の setdash で破線パターンを用いて書かれている場合、PDF ライブラリ側が両端以外の座標を補間しなければならない」ということである。パターンを解釈するために反復計算量が多いうえ、それを拡大されては困るということなのだろうか?

しかし、まだ拡大率が小さい場合にも失敗する場合が見つかっていて、必ずしも小さければいいというわけでもないらしい…(続く

*1:pdfiumdraw.cpp のソースでいうところの SetWindowExtEx にあたる。

*2:具体的には A4 サイズの PDF を変換したとき、拡大率70の時点で既に右下の破線だけ異常になる。

2015-06-08

pdfiumdraw の EMF 出力(より詳しい解析)

昨日の説明で「Inkscape を使ってパス変形する」という“一応の解決策”は提示できた。しかし、もう少し詳しく描画コマンドを知るために、TeX Wiki の QPDF の項目を参考に qpdf で PDF の中身を覗いてみた。

QPDF を用いて PDF の中身を見る方法

qpdf は幸い W32TeX に入っているのでこれを使う(今回は使わないが、qpdf の fix-qdf は Perl スクリプトなので、別途 Perl インタプリタをインストールしておく必要あり)。

 $ qpdf --qdf input.pdf output.qdf

とすると、PDF のストリームがテキストに変換されて出てくる。output.qdf の中身のページ描画部分は PostScript 言語なので、読んでみることに。参考にするのは…

こんな詳しい日本語マニュアルがあるとは…

実際に PDF のソース(=PostScript コード)を読む

昨日の「TikZ 依存の XyMTeX で化学構造式を描き、TeX2img でアウトライン化した PDF」を使う。解読を簡単にするため、まずはこれを Inkscape で破線に該当する部分以外削除しておこう(今回の場合は5本の破線だけになる)。

f:id:acetaminophen:20150609004453p:image

破線のパスを変形する前の状態を qpdf で覗いてみると…

 %% Original object ID: 3 0
 5 0 obj
 <<
   /Length 6 0 R
 >>
 stream
 q
 0 0 0 RG /a0 gs
 1.59404 w
 0 J
 0 j
 [ 0.99628 1.19553] 0 d
 10 M 172.73 215.961 m 172.73 228.418 l S
 [ 0.99628 1.19553] 0 d
 152.406 215.864 m 146.031 226.422 l S
 [ 0.99628 1.19553] 0 d
 126.402 95.61 m 126.402 83.157 l S
 [ 0.99628 1.19553] 0 d
 109.363 85.34 m 109.363 72.887 l S
 [ 0.99628 1.19553] 0 d
 91.227 117.227 m 78.773 123.602 l S
 Q
 endstream
 endobj

一方、Inkscape で破線のパスを変形した後は…

 %% Original object ID: 3 0
 5 0 obj
 <<
   /Length 6 0 R
 >>
 stream
 q
 0 0 0 RG /a0 gs
 1.59404 w
 0 J
 0 j
 [] 0.0 d
 10 M 172.73 215.961 m 172.73 216.957 l 172.73 218.153 m 172.73 219.149 l 172.73
  220.344 m 172.73 221.34 l 172.73 222.539 m 172.73 223.535 l 172.73 224.731
  m 172.73 225.727 l 172.73 226.922 m 172.73 227.918 l S
 152.406 215.864 m 151.891 216.715 l 151.273 217.739 m 150.758 218.59 l 
 150.141 219.614 m 149.625 220.469 l 149.008 221.493 m 148.492 222.344 l 
 147.875 223.368 m 147.359 224.219 l 146.742 225.243 m 146.227 226.098 l S
 126.402 95.61 m 126.402 94.614 l 126.402 93.418 m 126.402 92.422 l 126.402
  91.227 m 126.402 90.231 l 126.402 89.035 m 126.402 88.039 l 126.402 86.844
  m 126.402 85.848 l 126.402 84.653 m 126.402 83.653 l S
 109.363 85.34 m 109.363 84.344 l 109.363 83.149 m 109.363 82.153 l 109.363
  80.957 m 109.363 79.961 l 109.363 78.766 m 109.363 77.77 l 109.363 76.575
  m 109.363 75.578 l 109.363 74.383 m 109.363 73.387 l S
 91.227 117.227 m 90.34 117.68 l 89.277 118.223 m 88.391 118.676 l 87.328
  119.223 m 86.441 119.676 l 85.375 120.223 m 84.488 120.676 l 83.426 121.219
  m 82.539 121.676 l 81.473 122.219 m 80.59 122.672 l 79.523 123.219 m 78.773
  123.602 l S
 Q
 endstream
 endobj

となっている。ここで、PostScript の破線の描き方を復習する。

[上掲の参考文献の要約]
全く切れ目のない実線 (solid line) の場合に対し、線と切れ目を交互に繰り返す破線 (dashed line) ではその線と切れ目のパターン、すなわち「破線パターン」(dash pattern) が指定される。この破線パターンが切れ目を含まない特別な場合が実線というわけだ。
破線パターンの指定は「破線配列」(dash array) によって表現する。破線配列は線の長さと切れ目の長さを交互に並べたもので、例えば「線の長さ40、間隔の長さ20、オフセット0(単位は pt)」なら [ 40 20 ] 0 setdash と書く。オフセットは、破線パターンのどの位置から描画を開始するかを指定する。これを実線に戻したい場合は [] 0 setdash のように空配列を書けばよい。…

これを踏まえて上の qdf の中身を見ると、パス変形前のものは破線配列を指定してあるのに対し、パス変形後のものは破線配列が空になっていて、代わりに m や l で細かく指定されている(m は move to の略、l は lineto の略)。すなわち、変形後は実線を細かく配置して“見た目”の破線を構成しているのである。そして、今のところ EMF への描画で失敗しているのが「破線パターンの解釈」だろうという推測が導かれるのである。

(また続く

2015-06-07

pdfiumdraw の EMF 出力(一応の解決策?)

昨日の続き。
少し分かってきたことがあるので、忘れる前にメモしておこうと思う。

PDF における破線:(La)TeX の描画法の違い

TeX が出力する PDF への破線の描画は、大きく分けて2通りあるらしい。一つは LaTeX 標準の picture 環境の範囲内で「正方形(長方形)を並べる」という描画方式。この方式は直感どおりで、点線や破線は単なる四角形の集まりと原理的に区別がつかない。これを TeX2img のスキームでアウトライン化 PDF に変換して pdfiumdraw で EMF 出力すると、すべて正常(= PDF のときと同じ見た目)の EMF が得られる。
f:id:acetaminophen:20150608044038p:image
もう一つは LaTeX の範囲を超えた拡張機能による「真の破線・点線の描画」である。これは実際には両端の2点だけにノードがあり、間の部分はいわば“パターン”のようなもので破線のパスを形成している。この補間解釈はおそらく表示・変換するソフトウェアのほうに任せられていて、EMF に変換するとただのストロークになったり点の間隔が変わったりする傾向が顕著にみられる。実際、TikZ による破線を TeX2img のスキームでアウトライン化 PDF に変換して pdfiumdraw で EMF 出力するとそもそも破線が消滅する*1
f:id:acetaminophen:20150608045616p:image

PDF の破線表示のプログラム依存性?

一方、この EMF 変換を Inkscape で行うとすべて塗られたストロークになる。このことからどうやら描画プログラム依存性がありそうだ。
f:id:acetaminophen:20150608045755p:image

実際に2通りの描画方法を Inkscape でパス解析すると一目瞭然である(上は細かい四角形ごとにノードが切れているのが分かるが、下は点線全体でノード2つになっている)。
f:id:acetaminophen:20150608045838p:image
f:id:acetaminophen:20150608045857p:image

(一応の)対処法:事前にパスを手動で変形

では2番目の「真の破線・点線の描画」を EMF に書き込むことはできないのだろうか。一応の解決法の案をここで提示する(僕の手元には Inkscape 0.48.4 を入れているので、最新版では微妙に違うかも)。

  1. TeX2img でアウトライン化 PDF を作成する。
  2. Inkscape で開き「グループ解除」
  3. 破線のパーツを選択し、メニューから「エクステンション」→「パスの変形」→「破線に変換」(下図参照;ノードが増える!)
  4. すべて変換し終えたら保存
  5. pdfiumdraw で EMF に変換

f:id:acetaminophen:20150608050050p:image
f:id:acetaminophen:20150608050051p:image

この方法なら正常(= PDF のときと同じ見た目)な EMF が得られた!*2
f:id:acetaminophen:20150608050509p:image
パスの変形という方法は Inkscape のバグレポートを参考にした。おそらく処理としては Illustrator CS3 以降が対応しているという「破線のアウトライン化」でも類似の結果が得られると思われる(ただし Inkscape の場合はアウトライン化にはなっていない)。

追記 (2015-12-06):同等の処理を Ghostscript で行う方法を発見した!

続く

*1:破線と同時に文字の一部が欠落するのは謎。

*2:破線の正常化と同時に文字の一部欠落という問題も雲散霧消するのは謎。

2015-06-06

pdfiumdraw の EMF 出力検証

メインブログ更新。XyMTeX が昨年の Advent Calendar で話題になった時に半分くらい書いたものが公開しないまま眠っていたので、後半部分の eepic, pict2e, bxeepic について新たに書きおろして公開。XyMTeX にかぎらず「内部的に PSTricks や TikZ を呼び出すパッケージ」は多数あるはずなので、他のパッケージを使うときにも描画機能に関する正しい知識は役に立つかも。

EMF で「破線が消える」

さて、今回使った XyMTeX ソースを TeX2img 付属ツールである pdfiumdraw で EMF に変換してみた。この付属ツールに焦点を当てた記事最近公開した際に、環境によって挙動が異なるなどの謎が多く検証不十分だった pdfiumdraw についてテストを呼びかけたわけだが、早速情報が寄せられた

今日は TeX2img 付属ツールのpdfiumdrawでPDFをemf(拡張メタファイル)に変換するのを試していて、結局Postscriptでsetdashで描いた破線がemfにすると描画されてくれないことがわかった(徒労感

破線が表示されないというので、今回の XyMTeX の出力を通してみたわけだが、なるほど破線だけきれいに消える(下図は xymtexpdf を使ったソースから platex + dvipdfmx を使って PDF を作成し、pdfiumdraw で EMF に変換したもの)。
f:id:acetaminophen:20150607010041p:image
全く同じ処理で PNG に変換しても、破線が消えるようなことはない(下は pdfiumdraw で PNG に変換したもの)。
f:id:acetaminophen:20150607010511p:image
どうやって描画したかに関わらず、pdfiumdraw で変換すると破線だけが EMF で描画されない。不思議なこともあるものだ。

というわけで検証を始めたが、Inkscape も pstoedit も EMF にうまく書き込めないことがわかってきた(破線でなくなったり、点の間隔が勝手に変わったりする…)。今のところ完璧な変換法がわからない…EMF の仕様が謎である。

明日もやってみる)

2015-06-05

TA 終了

今期の TA の任務が終わって晴れ晴れした気分。後輩に教えるのも楽しいけれど、実験手順を教えるだけなので収穫が少ない気がしてしまう。鋭い質問とかもらえると面白いのだけれど、決まりきった実験だとそんなに無いよなあ。とりあえず無事に終わったのは良かった。
今日は雨とは思っていなかったので、不意打ちにあった気分。気温も下がったし…

2015-06-04

レポート用の論文を読み始めて

月末提出のレポートのために指定された論文を読み始めたのだが、専門外の上、そこまで「スゴイ!」という印象が持てず困っている。まあその方が、「地道に先行研究を元にこうすれば良くなると思ったので、そのためにこっちの文献の方法を参照して組み合わせたらうまくいきました」という筋を理解しやすいから、要約せよという課題には向いていそうだが、いかんせん感動が薄い。まあ普通にまとめれば済むのだけれど。

2015-06-03

高分子物理、学習中

最近、高分子物性について勉強会で読んでいるので、エントロピー弾性という2年前に学んだ概念を再確認している。改めて読み返すと面白いものだ。授業で習ったときは数式が板書で流れていくだけで、その意味を考える余裕があまりなかったが、今になって少しずつ理解できているのが気持ちよい。他の科目もそろそろ読み返してみたくなってきた。専門外の分野もおもしろいなあ。

2015-06-02

ブログ更新し忘れ(笑)

メインブログ更新
TeX2img の画像変換処理を見直した3月末の時点で記事の大枠は完成していたのに、整形するのを忘れていて更新していなかった。でもまだ InkscapeX11 非依存版はあまり有名になっていないし、pdfiumdraw は TeX2img ユーザの中でも意識したことのある人はほとんどいないはず。この手の記事は「情報の正確さ」が重要であって、速報性はそれほど求められないと信じている。サブブログ「アセトアミノフェンの気ままな日常」は比較的“てきとーブログ”で、時々作業メモが載るくらいだが、メインブログは相当真面目に書いているつもり。

そういえばまだ、TeX2img for Windows の最新版で「/batch オプションの stop について /timeout で時間を指定できるようになった」ということをブログに追記していないことも思い出した。GUI 版の中断ボタンもまだだっけ…今度書く。

2015-06-01

早くも6月

先週から急に暑くなったのだが、衣替えが終わっていなかったからようやくタンスの中をひっくり返した。髪も切ってさっぱり。2ヶ月ぶりw
さて、今月は月末締切のレポートがたくさんあるので、コツコツ始めなければ絶対に終わらない。大学院の講義では試験のある科目を履修しなかった(たまたま)ので、全部レポートか出席。レポートは論文を自分で探して読んで要約せよというものがほとんど。専門外の論文を探すのはかなりハードルが高い…