マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

LaTeX 文書のページ番号を“ゆきだるま化”したい話

まあ、ゆきだるま☃の話が多すぎて困ることは何もないので、軽い☃ネタを出しておく。

LaTeX 文書のページ番号を☃にしたい件

ご存知の通り、某 scsnowman パッケージでは LaTeX 文書の様々な要素(“証明終”の記号、箇条書きの記号、文書全体、など)を☃に変えられる。となると、次は LaTeX 文書のページ番号を☃にしたい、というのは自然な要求だろう。これを実現するには、ページ番号の整数値について、それを☃で表現する記法を作り出せばよいが、その際に解決すべき問題がある。

PDF 文書はメタ情報としてページ番号を持っている。PDF ビューアで文書を見たときに、UI 領域(ツールバーなど)に表示されているページ番号はこのメタ情報である。上掲の図は SumatraPDF のもので、ページ番号としてローマ数字の「iv」が示されている。このように、メタ情報のページ番号は算用数字とは限らず、任意の Unicode 文字列を使うことができる。

これを勘案すると、ページ番号の表記は以下の要件を満たすことが求められる。

  • 表記は Unicode 文字列で表せる必要がある。つまり、書体や色などの区別は番号の識別のためには使えない。
    • つまり、「☃のマフラーの色の違いで整数値を表す」といった一般的な手法が使えない。〈☃〉(U+2603)などの“ゆきだるま文字”だけで表現する必要がある。
  • 上掲の画像を見てもわかるが、ページ番号の文字列は非常に短いことが想定されている。
    • ゆえに、例えば「10 を“☃☃☃☃☃☃☃☃☃☃”で表す」のような単純な方法だと、ビューアの表示が簡単に破たんしてしまう。

非常に遺憾なことに、Unicode に収録されている“ゆきだるま文字”は 3 つしかない。

従って、これらの文字をできるだけ効率的に用いた記法を考案しなければならない。

変態な 3 進法の話

実は、この問題を解決するための概念が今年の年始に考案されている。某 ZR 氏のアレな勘違いを端緒にした「変態 3 進法」という変態な位取り記数法である。

この「変態 3 進法」は「0、1、2 の 3 つの文字で表す」という条件の下ではある意味で“最も効率の良い(短く表せる)”整数記法といえるだろう。

☃な変態 3 進法の話

さて、話をページ番号の記法に戻そう。そこで求められていたのは、「3 つの“ゆきだるま文字”だけを用いた効率的な整数記法」であった。「変態 3 進法」の概念はこの要求とうまく合致する。

このように数字を☃に置き換えた“☃的変態 3 進法”こそが、「ページ番号の表記を☃にする」という問題への最適な解決法といっていいだろう。

LaTeX で“☃的変態 3 進法”するパッケージ

というわけで、早速作ってみた。

scternoidal パッケージの使い方

パッケージの読込は通常通りである。

\usepackage[<オプション>]{scternoidal}

次のオプションが利用できる。

  • scsnowman(既定): ☃の文字を印字するのに scsnowman パッケージの \scsnowman 命令を利用する。
  • noscsnowman: ☃の文字を印字するのに当該の Unicode 文字をそのまま入力する。LuaLaTeX/XeLaTeX/upLaTeX 以外では utf8 入力エンコーディング(inputenc)の指定を前提とする。((つまり、\scternoidal{1} は“☃”を UTF-8 で直接ソースに書いたのと同等になる。もちろん、それで所望の文字が“出力”されるかは各種設定に依存する。))

scternoidal パッケージは以下の機能を提供する。

  • \scternoidalof{<整数>} :[頑強命令] 指定の整数を“☃的変態 3 進法”で出力する。
  • \scternoidal{<カウンタ名>} : [頑強命令] 指定のカウンタの値を“☃的変態 3 進法”で出力する(カウンタ出力命令)。
  • \pagenumbering{scternoidal} でページ番号表記が“☃的変態 3 進法”に変更される。
enumerate の項番を☃にする

\scternoidal\arabic\roman 等と同じくカウンタ出力命令の一種なので、LaTeX の通常の手続きに則って \the〜 を設定することで、任意の LaTeX カウンタの表記を☃にすることができる。まずは、enumerate の項番(enumi カウンタ)の表記を“☃的変態 3 進法”にしてみる。

% pLaTeX文書
% ↓scsnowmanを利用するのでドライバ指定が必須
\documentclass[dvipdfmx]{jsarticle}
\usepackage{scternoidal}
% 1段目enumerateの項番をscternoidalにする
\renewcommand{\theenumi}{\scternoidal{enumi}}
\begin{document}

トッテモ有益なパッケージの例:

\begin{enumerate}
\item scsnowman \label{nantoka}
\item Gotoh
\item lisp-on-tex
\item tcfaspin
\item tikzducks \label{kantoka}
\end{enumerate}

% 相互参照の番号もscternoidalになる
特に\ref{nantoka}\ref{kantoka}は重要。
\end{document}
節番号を☃にする

節番号(section カウンタ)の表記を“☃的変態 3 進法”にした例である。ここでは、hyperref を利用して PDF 文書に栞(ブックマーク)を付加して、さらに栞の中の項目にも☃な節番号が入るようにしている。

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
% LuaLaTeXなのでunicode指定が必要
% 栞にも節番号を付ける(bookmarksnumbered指定)
\usepackage[unicode,hidelinks,bookmarksnumbered]{hyperref}
\usepackage{scternoidal}
% 節番号をscternoidalにする
\renewcommand{\thesection}{\scternoidal{section}}
\begin{document}

\section{\TeX}
Knuthが作った組版ソフトウェア。超絶アレ。
\section{plain {\TeX}}
Knuthによる{\TeX}のマクロパッケージ。結局アレ。
\section{\LaTeX}
Lamportが作った{\TeX}のマクロパッケージ。微アレ。
\section{ゆきだるま}
雪玉を重ねて作るやつ。非アレ。
\section{アヒル}
……に関する言及は控えさせて頂きます。

\end{document}

\scternoidal を PDF 文字列中で用いる機能は pLaTeX ではサポートされない。その理由は、pLaTeX では JIS 外字を PDF 文字列に含める術が存在しないからである。

ページ番号表記を☃にする

それでは、本題である「ページ番号表記を“☃的変態 3 進法”にする」をやってみよう。\pagenumbering{scternoidal} を実行するだけである。((もちろん、\thepage を再定義する方法も使える。(念のため:\pagenumbering 命令の方は表記を変更するだけでなく「page カウンタをリセットする」という作用ももつ。)))

% XeLaTeX文書; UTF-8
\documentclass[xelatex,ja=standard,a4paper]{bxjsbook}
\usepackage[unicode,hidelinks]{hyperref}
\usepackage{scternoidal}
% ページ番号をscternoidalにする
\pagenumbering{scternoidal}
\usepackage{bxjalipsum}% 例のアレ
\begin{document}
\chapter{吾輩は猫である}
\jalipsum[1-16]{wagahai}
\end{document}

スバラシイ。

ただし、この「ページ番号を☃にする」件については注意すべきことがある。

ここで述べられている通り、PDF 情報のページ番号で非 ASCII 文字を使うには、hyperref の unicode 指定が必須になる。従来、upLaTeX では unicode 指定は非対応だったが、pxjahyper の 0.3a 版(上記記事で紹介されたもの)以降では使えるようになっている。従って、upLaTeX の場合は、この新しい版の pxjahyper を使う必要がある。(先述の通り、pLaTeX ではそもそも PDF 文字列全般に☃が使えない。)

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,a4paper]{jsbook}% ドライバ指定
\usepackage[unicode,hidelinks]{hyperref}% 'unicode'が必要!
\usepackage{pxjahyper}% 0.3a版以降が必須
\usepackage{scternoidal}
\pagenumbering{scternoidal}
\usepackage{bxjalipsum}
\begin{document}
\chapter{吾輩は猫である}
\jalipsum[1-16]{wagahai}
\end{document}

実は“☃的変態 3 進法”がアレな話

Unicode の“ゆきだるま文字”を有効活用した“☃的変態 3 進法”であるが、次のような致命的な欠点がある。

  • U+2603(雪あり)と U+26C4(雪なし)の識別が、特に低解像度の表示においては困難である。
  • PDF ビューアの UI で使われるフォントは、大抵の場合、文書作成者が指定することはできない。そして大抵の場合、3 つの“ゆきだるま文字”の表示に使われるフォントが異なるものになってしまう。(これは 3 つのうちの一部だけを実装したフォントが多く存在するため。)また歴史的理由のため、U+2603(雪あり)の字形が「雪なし」で実装されているフォントも存在する。それが使われた場合、表記された整数を正しく解することすら不可能になる。

実は、今まで掲載した SumatraPDF の画面キャプチャの画像は、UI 表示のフォントを「VL Pゴシック」(2.108 版)に変更した状態のものである。(SumatraPDF は常に Windows の UI 設定に従うので、実際には Windwos の UI のフォント設定を変えている。)このフォントは“ゆきだるま文字”3 つが全て揃っているため意図通りの表示が得られた。一方で、自分の環境では既定の UI 表示は以下のような酷いものになってしまう。

従って、極めて残念なことに、“☃的変態 3 進法”のような“ゆきだるま文字”の全てを活用した記法は、UI 表示に使われることを前提とする限りは実用できない、と結論せざるを得ないようである。