texjporg / tex-jp-build

Minimum source repository to build Japanese TeX processing tools
23 stars 6 forks source link

upTeX で内部コードが euc/sjis の場合の日本語ファイル名 #136

Closed h20y6m closed 1 year ago

h20y6m commented 2 years ago

upTeX で内部コードを euc/sjis にしている場合に日本語ファイル名を正しく扱えないことに気づきました。

upTeX を内部コード euc/sjis で使う人なんていないとは思いますが、https://github.com/texjporg/ptex-manual/issues/4#issuecomment-868380122 の「「内部コードが euc/sjis の upTeX」を pTeX の代わりに起動すれば」のような話もあるので pTeX がサポートする範囲で動くようにしておきたい。

h20y6m commented 2 years ago

パッチ https://github.com/h20y6m/tex-jp-build/commit/3ad14cf95a0583568b9640b28b71ff17048804b9 を書いてみました。

-progname もチェックすべき?)

h-kitagawa commented 2 years ago

明日以降に時間が取れたら調べますが,

euptex -ini -etex -kanji-internal=euc -jobname=euptex-euc ptex.ini
euptex -fmt=euptex-euc あ.tex

とフォーマット側でのみ kanji-internal-enc を設定した状態で日本語ファイル名を指定してもダメですね.

同様の現象は

eptex -ini -etex -kanji-internal=sjis -jobname=eptex-sjis ptex.ini
eptex -fmt=eptex-sjis あ.tex # ==> ! I can't find file `^^a4^^a2.tex'.
eptex -fmt=eptex-sjis '\message{あ}' # ==> ^^a4^^a2

でも見られます. 「フォーマットを読んで kanji-internal-enc が確定した後に 1 行目の内容を読み直す」 処理がいる?

h-kitagawa commented 2 years ago

「フォーマットを読んで kanji-internal-enc が確定した後に 1 行目の内容を読み直す」 処理がいる?

自己レスです.

virtex 用には「フォーマットファイルを読み込んだら,buffer の中身をコード変換する」ルーチンが必要なのかもしれません.

h-kitagawa commented 2 years ago

とりあえず https://github.com/h-kitagawa/tex-jp-build/tree/ptex_cmdline でデバッグコード付きで色々試し中です(時間がないので全部網羅していはいません).

h20y6m commented 2 years ago

フォーマットの作成時の -kanji-internal が優先されるのですね。

そのためコマンドラインの解析前に内部コードを確定することはできず、フォーマットを読み込んだ後に変換するしかないと……

win32 の場合コマンドラインを UTF-8 で取得するために get_command_line_args_utf8 を呼び出すと kpathsea がファイル名を UTF-8 で扱うようになるようなので、これより前に内部コードが確定できればよかったのですが…… win32 でもファイル名の文字コード変換が必要になりそうですね……


-jobname, -output-directory 等の文字コードも変換が必要になるかもしれません。

aminophen commented 2 years ago

フォーマットの作成時の -kanji-internal が優先される

upTeX では古くからあった挙動で,pTeX も同じ挙動にしたのは https://github.com/texjporg/tex-jp-build/issues/55 の時です。

h-kitagawa commented 2 years ago

-jobname, -output-directory 等の文字コードも変換が必要になるかもしれません。

あと -fmt とかもそうですね.理想は「フォーマット読み込み後にそれぞれ変換し直す」ですが,できるかなあ…….

h20y6m commented 2 years ago

-jobname, -output-directory 等の文字コードも変換が必要になるかもしれません。

output_directory は openclose.c で UTF-8 に変換した後のファイル名と concat しているので変換しないほうがよさそうですね。

-fmt とかも

フォーマット名 (DUMP_VAR?) はデフォルトまたは -kanji-internal で指定したエンコードでしょうか。 フォーマット読み込み後に使わないのなら再変換はいらなさそう?

h-kitagawa commented 2 years ago

フォーマット名については,「コマンドラインで &foo 形式の引数」による指定以外は h-kitagawa@7e4423a20 で対応したつもりです. % 3/6 10:47 edit. ↑記述修正.

~「入力の先頭が &foo 形式である」場合はまだですが,pack_buffered_name の末尾に「内部コードに変換する」処理を加えれば良さそうです.~

t-tk commented 1 year ago

こちらも長い間放置して申し訳ありません。 h-kitagawa@7e4423a20 を現在のここの master に当ててみました。 さらに、ptexenc 内の関数名を _付きにしました。(その方が読みやすいと思い。) デバッグコードは残ったままです。

https://github.com/texjporg/tex-jp-build/issues/125 も同時に直ったような気がします。 デバッグコードを取り除いて TeX Live にコミットしようかと思っています。

t-tk commented 1 year ago

テスト (https://github.com/texjporg/tex-jp-build/commit/2fc1dd710458fb21fbb1178acb79c92198e77a15) を入れて WindowsのMingw64でも試しています。 Linux (WSLのubuntu) ではきちんと動いています。 Mingw64 の (2) は使えるようにしたいところです。


engine internel-enc Ubuntu Mingw
ptex sjis
ptex euc × (1)
uptex sjis × (2)
uptex euc × (3)
uptex uptex

(1) \input で "! I can't find file fnさざ波.tex."

(2) \input で "! I can't find file fnさざ波.tex." コマンドラインの fnさざ波.tex は見つかるが、メッセージは文字化け

(3) \input で "! I can't find file fnさざ波.tex." コマンドラインの fnさざ波.tex は見つかるが、メッセージは文字化け

(2) のメッセージ

This is upTeX, Version 3.141592653-p4.1.0-u1.29 (utf8.sjis) (TeX Live 2023/dev) (INITEX)
 restricted \write18 enabled.
(../../../texk/web2c/ptexdir/tests/fn縺輔*豕^^a2.tex
JOB[fn縺輔*豕^^a2] :: We are in fnさざ波.tex
 )
No pages of output.
Transcript written on fn縺輔*豕^^a2.log.

(3) のメッセージ

This is upTeX, Version 3.141592653-p4.1.0-u1.29 (utf8.euc) (TeX Live 2023/dev) (INITEX)
 restricted \write18 enabled.
(../../../texk/web2c/ptexdir/tests/fn^^e3^^81^^95^^e3^^81^^96羈^^a2.tex
JOB[fn^^e3^^81^^95^^e3^^81^^96羈^^a2] :: We are in fnさざ波.tex
 )
No pages of output.
Transcript written on fn^^e3^^81^^95^^e3^^81^^96羈^^a2.log.
h-kitagawa commented 1 year ago

Windows はろくな検証環境がない&私がよくわかっていないので,ほったらかしています,すみません. Mingw の結果は Linux 上でも Wine で確認しましたが,VC++ だとまた結果が違いそうな予感がします.

t-tk commented 1 year ago

ごちゃごちゃいじっていたら https://github.com/texjporg/tex-jp-build/issues/136#issuecomment-1356059746 の (2) が command_line_encoding=none と Shift_JIS でとりあえず動くようになりました。WindwosでEUCは動かなくても充分な気がします。もう少し手元でやってみて整理してからここに上げようと思います。 Windows と Linux(UNIX系) の違いはいろいろあって、文字コード関係とファイル入出力関係とPOSIX・VC等の移植性に関する話とがごちゃごちゃに入り組んでいてややこしく、上手にやっても実装が複雑になりがち、下手をするとスパゲッティ化まっしぐら… 似たような問題は pdfTeX と Latin-1 でも発生しそうな気がします。どうなっているんでしょう。できれば統一的な対策にしたい。

私の環境は今、メインが WSLの Ubuntu Linux, Windows系は MSYS2+mingw64 ですが、TeX Live svn のテストスクリプトが大体動いてたまにFAILするようです。FAILの理由は多分 test script がプラットフォームの違いを吸収できていないだけだと思います。 GitHub actionsMingw が動いて自動化できると嬉しいと思いつつ、実力と気力が伴わず手を出していません。 角藤さんのところの VC移植ほどソースに手が入るレベルではテスト自動化は難しいと思います。 一方、mingwとVCの違いも詳細は知らないもののmingwで動けば大筋いけると思っています。

t-tk commented 1 year ago

(重複コメントを削除しました)

https://github.com/texjporg/tex-jp-build/commit/985d420da73635ee5929f46461fa1a5eb2bcfad8 の状態で、pTeX, upTeX ともに期待した範囲では想定通りに動いているようです。 Windows の (2) は、command_line_encoding の設定の影響を受けていました。test側を修正したらエンジンの方は触らずに動くようになりました。


engine file-enc internel-enc Ubuntu Mingw
ptex sjis,euc,jis,utf8 sjis
ptex sjis,euc,jis,utf8 euc × (1)
uptex (ptex互換mode) sjis,euc,jis,utf8 sjis ◎ (2)
uptex (ptex互換mode) sjis,euc,jis,utf8 euc × (3)
uptex utf8 uptex

(1)(3) Windowsでは、ファイル名の文字列EUCではファイルがopenできない。Windowsでは想定外なので無問題。 (2) Windows では、command_line_encoding=none の設定が必要。

気になる点が見つかりました。文字列の後ろの方にゴミが残る。 例えば ptests/fnさざ波-utf8-euc.log で Ubuntu で **fnさざ波-utf8.tex^^Mex のように。以前からこうだったのかもしれません。

This is pTeX, Version 3.141592653-p4.1.0 (utf8.euc) (TeX Live 2023/dev) (INITEX)  18 DEC 2022 14:37
 restricted \write18 enabled.
 %&-line parsing enabled.
**fnさざ波-utf8.tex^^Mex
(../../../texk/web2c/ptexdir/tests/fnさざ波-utf8.tex
JOB[fnさざ波-utf8-euc] :: We are in fnさざ波-utf8.tex
\openout0 = `fnさざ波-utf8-euc.txt'.

 )
No pages of output.
h-kitagawa commented 1 year ago

気になる点が見つかりました。文字列の後ろの方にゴミが残る。 例えば ptests/fnさざ波-utf8-euc.log で Ubuntu で **fnさざ波-utf8.tex^^Mex のように。以前からこうだったのかもしれません。

ptenc_conv_first_line で「1 行目の入力」を文字コード変換した際に,limit も更新しないといけないのを忘れていました.https://github.com/texjporg/tex-jp-build/commit/861becf8caec36af4785244b73bc0105560883e4 でどうでしょうか.

t-tk commented 1 year ago

ありがとうございます。ゴミが消えたことを確認しました。

波ダッシュ問題(変換表の揺らぎの問題)が少々気になりますが、おそらくこうなっているという予想を書いておきます。 Windowsではソースを眺める限り、file openに関係しそうな変換表は Windows のものを使うことになるので、問題は発生しない。 Linux では、EUC-JP→UTF-8の変換は、通常 ptexenc 内のテーブルが使われる。それと合わない想定だった場合、file openできないかも。

https://github.com/texjporg/tex-jp-build/issues/45#issuecomment-391374929 に書いたポリシーを若干修正して、今はこう考えています。

h20y6m commented 1 year ago

command_line_encoding=utf8 の場合 (e)ptex 以外では get_command_line_args_utf8 でコマンドライン引数を UTF-8 で取得していますが、この時 kpathsea でファイル名を UTF-8 として扱う(kpse->File_system_codepage = CP_UTF8)ように設定されます。Win32ではファイル名の文字コードを変換していないので内部コード sjis の uptex では日本語ファイル名を開けません。

逆に command_line_encoding=none の場合は(get_command_line_args_utf8 が何もしないので)コマンドライン引数やファイル名は OS コードページ(日本語 Windows の場合はほぼ CP932 (sjis))になるので、内部コード uptex の uptex では日本語ファイル名を正しく扱えなくなります。

ptex互換モード(内部コード sjis)のときは command_line_encoding=none(または get_command_line_args_utf8 を呼び出さない)、uptex のときは command_line_encoding=utf8get_command_line_args_utf8 を呼び出すように切り替えればどちらも大丈夫になるとは思います。

問題はフォーマットを読み込んだ後に内部コードが sjis だと分かった場合で、この時はすでに command_line_encoding=utf8get_command_line_args_utf8 が呼び出されたあとなのでどうしたらいいのか分かりません……

command_line_encoding=utf8 なら Win32 でもコマンドライン引数やファイル名を UTF-8 で扱うことにして UTF-8 な Linux のように内部コード(sjis/euc)⇔UTF-8変換をするようにするというのも考えられますが、これだと platex で「①」などがファイル名に使えなくなるので悩ましいです……

t-tk commented 1 year ago

@h20y6m さん、コメントありがとうございます。 以下は、Windows限定の話です。 command_line_encoding を導入した当初の目標は、

  1. pTeXで command_line_encoding=none の設定で JIS X 0208の範囲でちゃんと動く
  2. upTeXでcommand_line_encoding=utf8 の設定で Unicodeの範囲でちゃんと動く

というものでした。なので、

  1. upTeXの pTeX互換モード (内部sjis) でcommand_line_encoding=none の設定で JIS X 0208の範囲でちゃんと動く

が出来ていれば合格だと思っています。 また、さっきソースを眺めていたら command_line_encoding=none の場合 fopen 関係の文字コード変換は何もしないので、CP932の機種依存文字の ①.tex は、従来のplatexでも、これから変えようとしている upTeXのpTeX互換モード上のplatex でもコマンドライン引数では動くような気がします。CP932の ①.tex だと思って動作する。 ファイル内の \input ①.tex は、ファイルをSJISで書いてUTF8→SJISの変換を不要にすれば動くかもしれません。 texmf.cnf で command_line_encoding.platex=none をdefaultとして定義しておけば、upTeXのpTeX互換モード上のplatex でも期待通りに動くような気がします。それを engine で uptexdir/kanji.c の init_default_kanji_select() あたりで強制することは可能だと思いますが、どうしたものでしょう。

t-tk commented 1 year ago

そもそも、現在 Windows 上の pTeX/pLaTeX では command_line_encoding を導入しておらず、UTF-8周りの文字コード変換はptexenc にお任せになっていたはずです。 ファイル入出力に近い部分では Windows の CP932 のテーブルで変換していたはずです。 これから入れようとしている upTeX-sjis 上の pLaTeX でも command_line_encoding=none ならば pTeX-sjis 上の pLaTeX と何ら変わらないようにしてあったはず。 初期値の問題だけのように思います。

t-tk commented 1 year ago

試してみました。https://github.com/texjporg/tex-jp-build/commit/23ee5ea1d509ff0d88eacb34a9905b7d0d1f9bf0 私の予想通り、Windows で upTeX-sjis と command_line_encoding=none の組み合わせで、CP932の機種依存文字を含むファイル名 (コマンドラインの読み込み fn①㎝Ⅶ閒ア-sjis.tex とファイル内の \input fn①㎝Ⅶ閒ア-sjis.txt) は、 pTeX-sjis ではもちろん、upTeX-sjis でも動きました。 ただ、端末への表示部分は ptexenc の SJIS→UTF-8変換を使っているせいで、pTeX-sjis, upTeX-sjis ともにファイル名の表記が文字化けしています。

このテストはLinuxでは動かないはずです。

t-tk commented 1 year ago

CP932の機種依存文字も入れると、現状こんな感じです。

engine file-enc internel-enc Ubuntu Mingw note
ptex sjis,euc,jis,utf8 sjis Linuxでサポート対象外
ptex sjis,euc,jis,utf8 euc × (1) Windowsでサポート対象外
uptex (ptex互換mode) sjis,euc,jis,utf8 sjis ◎ (2) Linuxでサポート対象外
uptex (ptex互換mode) sjis,euc,jis,utf8 euc × (3) Windowsでサポート対象外
uptex utf8 uptex
ptex CP932 sjis × 端末出力は文字化け。サポート対象外
uptex (ptex互換mode) CP932 sjis × ○ (2) 端末出力は文字化け。サポート対象外

(1)(3) Windowsでは、ファイル名の文字列EUCではファイルがopenできない。Windowsでは想定外なので無問題。 (2) Windows では、command_line_encoding=none の設定が必要。

t-tk commented 1 year ago

https://github.com/texjporg/tex-jp-build/commit/3de05657ce8dbe33ee185470dca2060a66ddf36b CP932 の全角チルダのテストも追加しました。 (コマンドラインの読み込み fn①㎝Ⅶ閒ア~-sjis.tex とファイル内の \input fn①㎝Ⅶ閒ア~-sjis.txt) 予想通り、WindowsではCP932の変換表に従ったUnicodeと整合が取れていればファイルの入出力関係は動きます。

変換表の揺らぎ問題では、Linuxでも同様に、変換表と整合が取れている範囲で動くはず。 しかし、これ以上の努力はしないことにしようと思います。


上記で話題の件、コマンドラインのファイル名、\inputのファイル名、jobname は私のテストでテスト出来ていると思いますが、-fmt , output_directory, 「コマンドラインで &foo 形式の引数」は出来ていないと思います。 どうしましょうかね。 目立つ部分は私としては一応調べつくしたので、これより先は、問題が見つかったらそのとき対応を考える、でいいような気がしています。

h20y6m commented 1 year ago

いろいろありがとうございます。

texmf.cnf で command_line_encoding.platex=none をdefaultとして定義しておけば、upTeXのpTeX互換モード上のplatex でも期待通りに動くような気がします。

command_line_encoding=uft8
command_line_encoding.platex=none

こうしておけば platex という名前で起動したときはのときは command_line_encoding=none、uplatex という名前で起動したときは command_line_encoding=uft8 になるのでどちらも期待通りの動きになるというわけですね。

問題が見つかったらそのとき対応を考える

それでいいと思います。

t-tk commented 1 year ago

パイプ経由のテストを追加し、さらに https://github.com/texjporg/tex-jp-build/commit/ef44d36055aaf6fa5d634c0d7e5bff2cb5eafe29 で非JIS X 0208のutf8を一応試してみたので表に追加します。 p(La)TeX で非JIS X 0208のutf8のファイル名は、現状、もろもろの障害があって動きませんが https://github.com/texjporg/tex-jp-build/issues/147 とか https://github.com/texjporg/tex-jp-build/issues/149 とかをごちゃごちゃやれば実現可能と思います。私としては、pLaTeX 向けに非JIS X 0208のutf8を頑張るのは割に合わない気がして意欲が湧かなかったのですが、pLaTeX on npTeX 向けならばリソースを割いてもいいかな、と思い始めています。 もう少し整理したらTeX Live svnにコミットします。

engine file-enc internel-enc Ubuntu Mingw note
ptex sjis,euc,jis,utf8 sjis Linuxでサポート対象外
ptex sjis,euc,jis,utf8 euc × (1) Windowsでサポート対象外
uptex (ptex互換mode) sjis,euc,jis,utf8 sjis ◎ (2) Linuxでサポート対象外
uptex (ptex互換mode) sjis,euc,jis,utf8 euc × (3) Windowsでサポート対象外
uptex utf8 uptex
ptex CP932 sjis × 端末出力は文字化け。サポート対象外
uptex (ptex互換mode) CP932 sjis × ○ (2) 端末出力は文字化け。サポート対象外
ptex utf8(JIS外) sjis × × JIS X 0208外はサポート対象外
ptex utf8(JIS外) euc × × JIS X 0208外はサポート対象外
uptex (ptex互換mode) utf8(JIS外) sjis × × JIS X 0208外はサポート対象外
uptex (ptex互換mode) utf8(JIS外) euc × × JIS X 0208外はサポート対象外

(1)(3) Windowsでは、ファイル名の文字列EUCではファイルがopenできない。Windowsでは想定外なので無問題。 (2) Windows では、command_line_encoding=none の設定が必要。

t-tk commented 1 year ago

TeX Live svn r65330, ついでに、pdftex, xetexでの utf-8 のファイル名のテストも追加しました。r65331 ここは閉じます。

t-tk commented 1 year ago

今の master で テスト ptexdir/tests/fnさざ波-euc.tex を使ったテストの中で EUC-JP で書かれたファイル名 \input fn±×÷§¶-utf8.tex を kpathsearch経由で探すようになっていて ptex --kanji-internal=eucuptex --kanji-internal=euc とどちらも file open に成功しますが、 端末のlogが後者で文字化けしてしまうようです。 logだけの問題ならもう諦めてもいいかと思いますが、 もしfixする元気のある方がいればと思い再openしておきます。 → (2022/12/29) なぜか再現しないのでまた閉じます。

ptests/fnさざ波-euc-euc-term.log

(../../../texk/web2c/ptexdir/tests/fnさざ波-euc.tex
JOB[fnさざ波-euc-euc] :: We are in fnさざ波-euc.tex
(|cat fnさざ波-euc-tmp.tex) (./fnさざ波-euc-tmp.tex)
(../../../texk/web2c/ptexdir/tests/fn±×÷§¶-utf8.tex
JOB[fnさざ波-euc-euc] :: We are in fn±×÷§¶-utf8.tex
 ) )

uptests/fnさざ波-euc-euc-term.log

(../../../texk/web2c/ptexdir/tests/fnさざ波-euc.tex
JOB[fnさざ波-euc-euc] :: We are in fnさざ波-euc.tex
(|cat fnさざ波-euc-tmp.tex) (./fnさざ波-euc-tmp.tex)
(../../../texk/web2c/ptexdir/tests/fn±×÷§¶-utf8.tex
JOB[fnさざ波-euc-euc] :: We are in fn賊^^c3^^97歎則其-utf8.tex
 ) )