TeX Alchemist Online

TeX のこと,フォントのこと,Mac のこと

TikZ の current page と jsclasses との相性問題

日本で主流であろう,(u)pLaTeX + jsclasses + dvipdfmx のワークフローにおいて,TikZ の remember picture を使う際に発生する相性問題について,一つの解決策の提案です。

【追記】
この問題は,現在は bxpgfcurpage パッケージをロードすることで一括解決されるようになりました。

remember picture を dvipdfmx で使うには

TikZ 標準の dvipdfmx ドライバファイルでは,remember picture を用いた図形間結合(inter-picture connections)など,TikZ の一部の機能が使用できません。 しかし,次の記事でZRさんが作成された pxpgfmarkパッケージ を使うと,dvipdfmx でも remember picture を使用することが可能になります。

d.hatena.ne.jp

current page によるページ上の絶対配置

TikZ で remember picture を使うと,current page というノードが使えるようになります。例えば,ページの中央は (current page.center) のようにして取得することができます。

current page は,通常 overlay オプションと一緒に用いられ,「ページの背景に何かを書き込む」という用途に使われます。(正しく座標を取得するために2回コンパイルが必要です。)

使用例1:ページ中央にウォーターマークを入れる

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{lipsum}
\begin{document}
\begin{tikzpicture}[remember picture, overlay]
\node[color=red!30!white,draw,line width=10pt,
rectangle,font=\gtfamily,scale=10,rotate=30]
 at (current page.center) {部外秘};
\end{tikzpicture}
\lipsum
\end{document}

f:id:doraTeX:20160322111227p:plain

使用例2:ページ中央に壁紙を配置

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{lipsum}
\begin{document}
\begin{tikzpicture}[remember picture, overlay]
\node at (current page.center) 
  {\includegraphics{tiger.pdf}};
\end{tikzpicture}
\lipsum
\end{document}

f:id:doraTeX:20160322111247p:plain

jsclasses やトンボとの相性

jsclasses は,10pt 以外のフォントサイズで用いたとき,\mag による拡大縮小が入ります。また,tombo や tombow オプションを用いると,用紙が一回り大きくなってトンボが入ります。これらの機能は TikZ の current page との相性が悪く,同時に使うとおかしな結果をもたらします。

以下のサンプルでは,\test を次のように定義します。

\def\test{%
\begin{tikzpicture}[remember picture, overlay]
\coordinate (NE) at (current page.north east);
\coordinate (NW) at (current page.north west);
\coordinate (SE) at (current page.south east);
\coordinate (SW) at (current page.south west);
\coordinate (C) at (current page.center);
\draw[blue,line width=8pt] (SW) rectangle (NE);
\draw[red,line width=4pt]
  (NE) circle (1)
  (NW) circle (1)
  (SE) circle (1)
  (SW) circle (1)
  (C)  circle (1);
\draw
  (current page.south) -- (current page.north)
  (current page.west) -- (current page.east);
\end{tikzpicture}}

問題発生事例1:jsarticle + 14pt + a5j + papersize

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[14pt,a5j,dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322111707p:plain

問題発生事例2:jsarticle + 9pt + b4j + landscape + tombo + papersize

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[9pt,b4j,landscape,tombo,dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322111917p:plain

問題発生事例3:jsarticle + 9pt + geometry パッケージ

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[9pt,dvipdfmx]{jsarticle}
\usepackage[papersize={10truecm,20truecm},dvipdfm]{geometry}
\usepackage{tikz}
\usepackage{pxpgfmark}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322112426p:plain

相性問題の解決法

この相性問題を解決しようと考えました。次の3パターンが考慮対象です。

  1. jsclasses でフォントサイズ・用紙サイズを指定,トンボなし,papersize オプションで dvipdfmx に用紙サイズを伝える。
  2. jsclasses でフォントサイズ・用紙サイズを指定,トンボあり,papersize オプションで dvipdfmx に用紙サイズを伝える。
  3. jsclasses でフォントサイズを指定,トンボなし,geometry パッケージで用紙サイズを指定,geometry パッケージの dvipdfm オプションで dvipdfmx に用紙サイズを伝える。

次のコードで修正できたと思います。

gist.github.com

これで作成した fixpageforjs パッケージ で先の3事例が解決したかどうか,確かめてみましょう。

事例1:jsarticle + 14pt + a5j + papersize

% pLaTeX + pxpgfmark.sty + fixpageforjs.sty + dvipdfmx
\documentclass[14pt,a5j,dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{fixpageforjs}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322114333p:plain

事例2:jsarticle + 9pt + b4j + landscape + tombo + papersize

% pLaTeX + pxpgfmark.sty + fixpageforjs.sty + dvipdfmx
\documentclass[9pt,b4j,landscape,tombo,dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{fixpageforjs}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322114410p:plain

事例3:jsarticle + 9pt + geometry パッケージ

% pLaTeX + pxpgfmark.sty + fixpageforjs.sty + dvipdfmx
\documentclass[9pt,dvipdfmx]{jsarticle}
\usepackage[papersize={10truecm,20truecm},dvipdfm]{geometry}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{fixpageforjs}
% \test の定義(略)
\begin{document}
\test
\end{document}

f:id:doraTeX:20160322114448p:plain

ページ上の絶対位置を正しくおさえることができていますね!

ただし,この解決策は,試行錯誤の末に導き出したものなので,何か見落としや副作用があるかもしれません。より良い解決策がありましたらご教示願えれば幸いです。