dvipdfmx の20110311版を使っています。
10万ページの英文dviファイルをpdfに変換しようと思っているのですが、
なぜか3万ページほどで循環してしまい、すべて変換できません。
これは仕様なのか、設定次第で何か変わるのか教えて頂けないでしょうか。
阿部様のインストーラでインストールしてから設定は変更していません。
コマンドは dvipdfm -p a5 sample.dvi
としています。
条件が足りなければすみません。
よろしくお願いします。
追試してみたので報告します.環境は TeX Live 2011 on Linux (x86_64) です.
dvipdfmx のバージョンは同じく 20110311 のようです.
\documentclass{article}
\begin{document}
\newcount\hogecnt
\hogecnt=1
\def\hoge{\ifnum\hogecnt<100000a\newpage\advance\hogecnt1\expandafter\hoge\fi}
\hoge
\end{document}
で10万ページ出して,dvipdfmx にかけました.
dvi の出力は platex と latex (pdflatex -output-format=dvi) を両方試しましたが,
どちらも結果は同じで,34464ページ出力されました.
出力を見ると,65537ページから先が出力されているようです.
dvipdfmx のバージョンは同じく 20110311 のようです.
\documentclass{article}
\begin{document}
\newcount\hogecnt
\hogecnt=1
\def\hoge{\ifnum\hogecnt<100000a\newpage\advance\hogecnt1\expandafter\hoge\fi}
\hoge
\end{document}
で10万ページ出して,dvipdfmx にかけました.
dvi の出力は platex と latex (pdflatex -output-format=dvi) を両方試しましたが,
どちらも結果は同じで,34464ページ出力されました.
出力を見ると,65537ページから先が出力されているようです.
20万ページでも試してみましたが,こちらも196609ページから先の3392ページが出力されました.
196609=65536*3+1 ですね.
unsigned short 絡みの問題と推測します.
英文ということなので,とりあえずの解決策としては pdflatex を使うのが早いでしょう.
こちらはちゃんと10万ページ出力できています.
196609=65536*3+1 ですね.
unsigned short 絡みの問題と推測します.
英文ということなので,とりあえずの解決策としては pdflatex を使うのが早いでしょう.
こちらはちゃんと10万ページ出力できています.
> これは仕様なのか
という問いに答えていなかったので,dvipdfmx のソースコードも見て調べてみましたが,
おそらくDVIというフォーマットにしたがった仕様である,というのが答えだと思われます.
以下,ちょっと技術的な話になります.
http://akagi.ms.u-tokyo.ac.jp/dvi.html
に DVI フォーマットの仕様が書かれていますが,これを読むと DVI には「全ページ数」という
情報が含まれていることがわかります.
ポストアンブルに
> t[2] 全ページ数
という問いに答えていなかったので,dvipdfmx のソースコードも見て調べてみましたが,
おそらくDVIというフォーマットにしたがった仕様である,というのが答えだと思われます.
以下,ちょっと技術的な話になります.
http://akagi.ms.u-tokyo.ac.jp/dvi.html
に DVI フォーマットの仕様が書かれていますが,これを読むと DVI には「全ページ数」という
情報が含まれていることがわかります.
ポストアンブルに
> t[2] 全ページ数
とあります.2というのは 2bytes という意味です.
つまり,全ページ数の上限は65535であるということになります.
dvipdfmx はこの情報を元に何ページ出力するかを決めています.
また,65535ページを超えて出力しようとするとエラーを出すコードも含まれています
(pdfdoc.c の355行目).
しかし,先ほど生成した10万ページのDVIファイルには,全ページ数の情報が間違っているだけで
ちゃんと10万ページ分の情報が含まれています.
つまり,全ページ数の上限は65535であるということになります.
dvipdfmx はこの情報を元に何ページ出力するかを決めています.
また,65535ページを超えて出力しようとするとエラーを出すコードも含まれています
(pdfdoc.c の355行目).
しかし,先ほど生成した10万ページのDVIファイルには,全ページ数の情報が間違っているだけで
ちゃんと10万ページ分の情報が含まれています.
したがって,全ページ数の情報を無視するように dvipdfmx の仕様を変更すれば10万ページの
DVIをPDFに変換することも可能だと考えられます.
DVIをPDFに変換することも可能だと考えられます.
ちょっと試しに dvi.c の get_page_info() でページ数 (num_pages) を無理矢理10万にして,
pdfdoc.c にある上記エラー処理を外してみたところ,実際に10万ページ分の変換を
行うことができました.
どうかはわかりません.
pdfdoc.c にある上記エラー処理を外してみたところ,実際に10万ページ分の変換を
行うことができました.
一般的に65535ページ以上のDVIファイルに対応させるためには,dvipdfmx.c の724行目
から始まるループを実際に含まれているページ数分回すように変更すればよいのですが,
そうした変更をしたパッチを作ったとしてそれが本家のコードに取り込んでもらえるかから始まるループを実際に含まれているページ数分回すように変更すればよいのですが,
どうかはわかりません.
> 全ページ数の情報を無視するように dvipdfmx の仕様を
> 変更すれば10万ページのDVIをPDFに変換することも可能だと
> 考えられます.
とりあえずパッチを作ってみました.
(先ほど投稿したのですが,そちらは dviluatex で作った DVI が
うまく処理できなかったので削除しました)
t[2] が実際のページ数と mod 65536 で等しいことを利用しています.
こちらの環境(x86_64-linux)で 65ページ・20万ページの DVI を
処理させた限りでは,うまく動いている気がしています.
> 変更すれば10万ページのDVIをPDFに変換することも可能だと
> 考えられます.
とりあえずパッチを作ってみました.
(先ほど投稿したのですが,そちらは dviluatex で作った DVI が
うまく処理できなかったので削除しました)
t[2] が実際のページ数と mod 65536 で等しいことを利用しています.
こちらの環境(x86_64-linux)で 65ページ・20万ページの DVI を
処理させた限りでは,うまく動いている気がしています.
tex.web に
> If |total_pages>=65536|, the \.{DVI} file will lie.
> dvi_out((total_pages div 256) mod 256); dvi_out(total_pages mod 256);@/
とある(12752, 12772行目)ので,
「DVI への出力はサポートするけど,その DVI の面倒はそっちで見てね」
という扱いなのでは.
> ちなみに,
>> dviluatex で作った DVI がうまく処理できなかったので
> とあるのは,dviluatex が出力する DVI は従来の TeX エンジンが出力する DVI とは
> 何か違うということですか?
DVI のプリアンブルに書かれているコメント文の長さが異なっています.
> pre(247) で始まり,寸法の単位や,DVIを作成したTeXのコメント文がある(例)
> pre i[1] num[4] den[4] mag[4] k[1] x[k] (15+k) byte
> k[1] コメント文の長さ(0 - 255)
> x[k] コメント文
以前のパッチでは,(結果的に)コメント文の長さを決め打ちしていました.
具体的には,TeX, pTeX, pdfTeX, Aleph 等では
> ' TeX output 2012.01.27:0706'
となっているようですが,LuaTeX では
> ' LuaTeX output 2012.01.27:0706'
となっています.
これらは dvitype に DVI ファイルを渡すことで確認できます.
> If |total_pages>=65536|, the \.{DVI} file will lie.
> dvi_out((total_pages div 256) mod 256); dvi_out(total_pages mod 256);@/
とある(12752, 12772行目)ので,
「DVI への出力はサポートするけど,その DVI の面倒はそっちで見てね」
という扱いなのでは.
> ちなみに,
>> dviluatex で作った DVI がうまく処理できなかったので
> とあるのは,dviluatex が出力する DVI は従来の TeX エンジンが出力する DVI とは
> 何か違うということですか?
DVI のプリアンブルに書かれているコメント文の長さが異なっています.
> pre(247) で始まり,寸法の単位や,DVIを作成したTeXのコメント文がある(例)
> pre i[1] num[4] den[4] mag[4] k[1] x[k] (15+k) byte
> k[1] コメント文の長さ(0 - 255)
> x[k] コメント文
以前のパッチでは,(結果的に)コメント文の長さを決め打ちしていました.
具体的には,TeX, pTeX, pdfTeX, Aleph 等では
> ' TeX output 2012.01.27:0706'
となっているようですが,LuaTeX では
> ' LuaTeX output 2012.01.27:0706'
となっています.
これらは dvitype に DVI ファイルを渡すことで確認できます.
試したところ,dviout は次のような挙動を示すようです(3.18.3 ALPHA6 で確認).
32767ページ: 問題なし.
32768ページ: Input correct DVI file (Reading Illegal Integer)
65535ページ: Input correct DVI file (Reading Illegal Integer)
65536ページ: Input correct DVI file (Reading Illegal Integer)
65537ページ: 65537ページだけが表示される.
この挙動で察しがつくと思いますが,ポストアンブルの全ページ数の情報を signed short で
読んで,0以下だとエラー,正の場合でもそのページ数しか表示できない仕様ですね.
unsigned short を signed short だと思って読むと
32768 -> -32768
65535 -> -1
65536 -> 0
65537 -> 1
ですので.
というわけで,パッチを作ってみました.
ついでに Jump の Top page と Bottom page の意味が50000ページ増減する意味になって
いて,50002ページ以上あると Top page と Bottom page に正しく飛んでくれなかったので,
これも修正してあります.
動作は VC++ 2010 Express でコンパイルして,Windows 7 (64bit) 環境で確認しました
(VC++ は久々に使いました).
ちなみに,VC++ 2010 Express でコンパイルするときに
fatal error RC1015: cannot open include file 'afxres.h'
とか出るときは,dviout.rc の10行目の
#include "afxres.h"
をコメントアウトして,
#include <windows.h>
#define IDC_STATIC -1
を追加すると通るらしいです.
32767ページ: 問題なし.
32768ページ: Input correct DVI file (Reading Illegal Integer)
65535ページ: Input correct DVI file (Reading Illegal Integer)
65536ページ: Input correct DVI file (Reading Illegal Integer)
65537ページ: 65537ページだけが表示される.
この挙動で察しがつくと思いますが,ポストアンブルの全ページ数の情報を signed short で
読んで,0以下だとエラー,正の場合でもそのページ数しか表示できない仕様ですね.
unsigned short を signed short だと思って読むと
32768 -> -32768
65535 -> -1
65536 -> 0
65537 -> 1
ですので.
32768〜65535ページの DVI を表示できないのはバグと言ってもいいのかもしれません.
というわけで,パッチを作ってみました.
ついでに Jump の Top page と Bottom page の意味が50000ページ増減する意味になって
いて,50002ページ以上あると Top page と Bottom page に正しく飛んでくれなかったので,
これも修正してあります.
動作は VC++ 2010 Express でコンパイルして,Windows 7 (64bit) 環境で確認しました
(VC++ は久々に使いました).
ちなみに,VC++ 2010 Express でコンパイルするときに
fatal error RC1015: cannot open include file 'afxres.h'
とか出るときは,dviout.rc の10行目の
#include "afxres.h"
をコメントアウトして,
#include <windows.h>
#define IDC_STATIC -1
を追加すると通るらしいです.
説明が少し不足していましたが,上のコメントのパッチは65535ページまで対応させるものです.
65536ページ以上に対応させるパッチも作ったので上げておきます.
ただ,65537ページや65538ページのときに Jump > Bottom page がうまく動きません
(なぜか10万ページだとうまく動きます).他にも何かバグがあるかもしれません.
dvi->total_page の計算は北川さんの方法と同じですが,make_page_index() 内で
インデックスを作るのと同時に計算させようとするとエラーが出てうまくいかなかったので,
read_post() 内で独立に計算させるという少し非効率なことになってしまっています.
65536ページ以上に対応させるパッチも作ったので上げておきます.
ただ,65537ページや65538ページのときに Jump > Bottom page がうまく動きません
(なぜか10万ページだとうまく動きます).他にも何かバグがあるかもしれません.
dvi->total_page の計算は北川さんの方法と同じですが,make_page_index() 内で
インデックスを作るのと同時に計算させようとするとエラーが出てうまくいかなかったので,
read_post() 内で独立に計算させるという少し非効率なことになってしまっています.
dviout3183a6-20111008-unsigned_total_page.patch
を developing sources に反映させておきました:
http://tug.org/svn/dviout/
を developing sources に反映させておきました:
http://tug.org/svn/dviout/
"dvipdfmx を画像キャッシュで高速化" の話題の方に関連して、初めて知ったのですが
dvipdfmxの開発元のWeb siteまで昨年末ぐらいに閉鎖されていたのですね。
活発だった開発元が一つ活動を止めたのかと思うと少々寂しい思いです。
これまで大変お世話になり感謝しています。
私からの一つのご提案です。
こちらのスレッドで話題だった「最大ページ数」パッチですが、
せっかくの成果物ですし、埋もれてしまわないようにTeX Liveの方に入れてもらう方向にしませんか。
私が活動しましょうか。
最近 xdvi-jp の方で、せっかくの便利な成果物が日本ローカルのまま世界標準の環境に取り込まれる機会を失ってきた悲しい事例を目の当たりにしているので。
dvipdfmxの開発元のWeb siteまで昨年末ぐらいに閉鎖されていたのですね。
活発だった開発元が一つ活動を止めたのかと思うと少々寂しい思いです。
これまで大変お世話になり感謝しています。
私からの一つのご提案です。
こちらのスレッドで話題だった「最大ページ数」パッチですが、
せっかくの成果物ですし、埋もれてしまわないようにTeX Liveの方に入れてもらう方向にしませんか。
私が活動しましょうか。
最近 xdvi-jp の方で、せっかくの便利な成果物が日本ローカルのまま世界標準の環境に取り込まれる機会を失ってきた悲しい事例を目の当たりにしているので。
どこに返信するのか迷ったのですが、とりあえず。
昨夜 ChoF さんと、別のメールアドレスで連絡がつきました。dvipdfmx のメンテナンスはもうやっていないとのことでした。ノルベルトさんの言うとおり、texlive のレポジトリが dvipdfmx の最新版なんですね。完全に権限移譲されたと理解しました。
http://project.ktug.or.kr/dvipdfmx/ は Google のキャッシュによると2013年3月14日には残っていたことになってたんですが、もっと前からの動きなんですね。
昨夜 ChoF さんと、別のメールアドレスで連絡がつきました。dvipdfmx のメンテナンスはもうやっていないとのことでした。ノルベルトさんの言うとおり、texlive のレポジトリが dvipdfmx の最新版なんですね。完全に権限移譲されたと理解しました。
http://project.ktug.or.kr/dvipdfmx/ は Google のキャッシュによると2013年3月14日には残っていたことになってたんですが、もっと前からの動きなんですね。