Hatena::ブログ(Diary)

マクロツイーター このページをアンテナに追加 RSSフィード Twitter

2012-02-06

例の10万ページのアレ

結局、フォーラムには書く機会を逃してしまった……。

(dvipdfmx を使うという前提の場合は)dviselect(のような「DVI を分割するツール」*1)を使うのが最適だと思う。しかし、一応、LaTeX 上でも「分割コンパイル」は可能なので、ネタとして紹介しておく。

といっても、生憎のところ私の手元には10万ページの原稿がない。といって、単に 1〜100000 の数を 1 ページずつ書いたものでは、完成させても虚しさが漂うだけである。そこで、次のようなパッケージを用意することにした。

このパッケージは、以前に「TeX で『ハノイの塔』を解く件について」の記事で紹介した hanoi.tex と同様の機能を提供する。しかし、それとは異なり、 1 ステップごとに 1 ページを使って状況を出力するので、大量のページをもつ文書の生成により適している。

このパッケージを使って、次のような文書を作る。

[hanoi17.tex]

% pLaTeX 用; 文字コードは pTeX の設定に合わせる
\documentclass[a4paper]{jsarticle}
\usepackage{color}
\usepackage{bxhanoi}
\usepackage[driver=none,scale=.9]{geometry}
%\usepackage      [1-50000]{pagesel} %(*1)
%\usepackage [50001-100000]{pagesel} %(*2)
%\usepackage[100001-150000]{pagesel} %(*3)
\begin{document}
  % どうしても和文を入れたいらしい ;-)
\renewcommand\tohstepname{ステップ}
\settohunitlength{5pt} % 図の「単位長」
\towerofhanoi{17} % 円盤の数
\end{document}

この文書が 217 = 131072 ページ*2を有することは容易に想像できるであろう。

これをこのまま platex組版すると、DVI のポストアンプルのページ数情報が「0」になる*3ので dvipdfms で正常に変換できない。しかし、ここで pagesel パッケージを使うと、組版結果の中の「指定した範囲」だけを DVI として出力させることができる。例えば、上掲のコードの (*1) の行を活かすと、最初の 50000 ページだけが出力される。

これを利用して、dviselect を用いた場合と同様に「多分割した DVI を各々 PDF に変換 → PDF を連結」の過程を経て目的の PDF 文書が得られる。

  • ソースを (*1) の行を活かす((*2)(*3)はコメント)ように修正。
  • platex hanoi17
  • dvipdfmx -o hanoi17_1.pdf hanoi17
  • ソースを (*2) の行を活かす((*1)(*3)はコメント)ように修正。
  • platex hanoi17
  • dvipdfmx -o hanoi17_2.pdf hanoi17
  • ソースを (*3) の行を活かす((*1)(*2)はコメント)ように修正。
  • platex hanoi17
  • dvipdfmx -o hanoi17_3.pdf hanoi17
  • 適当なソフトウェアを用いて、hanoi17_{1,2,3}.pdf を連結して hanoi17.pdf を作る。私は pdftk を用いて次のようにした。
    pdftk hanoi17_1.pdf hanoi17_2.pdf hanoi17_3.pdf output hanoi17.pdf

(注意) 相互参照などで .aux ファイルを用いる LaTeX 文書に対して、pagesel パッケージを適用する場合は、まず一度 pagesel をなしにして全体をコンパイルした時の .aux を作っておいてから、pagesel を読み込んだ状態でコンパイルする、という手順を踏む必要がある。(pagesel を読むと既定で \nofiles が指定された状態になる。)

(50001 ページ目 = 50000 手目)

f:id:zrbabbler:20120504220014p:image


10 万ページの文書の作成に興味をもつ人のために、補足しておく。

  • dviselect のページ範囲指定は、規定では表示ページ(\count0〜9 の値)を対象とする。単純に DVI を分割するという用途の場合、物理ページ指定(前に = を付す)の方が便利だろう。
    dviselect =1:50000 hanoi17.dvi hanoi17_1.dvi
  • dviselect を用いるか pagesel を用いるかに関わらず、DVI の「ページ独立性」が崩れている場合は、分割すると悪影響がありうることに注意。例えば、papersize special が最初のページにのみ出力されている場合、分割した 2 つ目以降の DVI には当該のサイズ指定が効かなくなってしまう。*4
  • hyperref とかは多分壊滅するだろう。

*1:dvicopy は全く別の用途をもつツールである。

*2:初期状態(ステップ 0)から出力するので、手数 + 1 のページ数になる。

*3:2¹⁷ は 2¹⁶(= 65536)の倍数なので。

*4:上の例で、geometry パッケージに driver=none というオプションを与えているのは、papersize special の出力を抑止するため。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/zrbabbler/20120206/1328551619