texjporg / tex-jp-build

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

バイト列と和文文字トークンの区別 #81

Closed h-kitagawa closed 2 years ago

h-kitagawa commented 5 years ago

80 について調べていた中で考えた話題ですが,話が拡散しそうなので別 issue を立てます.私が調べた限りだと,次の①〜③のような挙動になっています:

\def\A{^^c5^^bf ſ 顛}\A とすると,dvi中 では Å£ Å£ 顛 のようにしっかり「2つの欧文文字トークン^^c5^^bf」「和文文字トークン 」が区別されています.

②しかし, \edef\B{\meaning\A} とすると,まず \meaning により

 (m)(a)(c)(r)(o)(:)(-)(>)("C5)["BF]( )("C5)["BF]("C5)["BF]

と文字列化(selector=new_string の状態で print_... が呼ばれる)され,それが str_toks() により

(m)(a)(c)(r)(o)(:)(-)(>)(顛)( )(顛)( )(顛)

とトークン化されます.従って \B の実行結果は macro:->顛 顛 顛 となります.

\message{\A} を考えると,同様に展開結果のトークン列が

("C5)["BF]( )("C5)["BF]("C5)["BF]

と文字列化され,それが slow_print によりバイト列として端末・ログに出力されます.この過程で ptexenc によるコード変換が起こり,

顛 顛 顛

という端末・ログへの出力結果になります.


さて,platex/#84 を考えると,\message{\A} の結果は ſ ſ 顛 となるのが望ましいと私は思っています. ただ,③を見ると文字列化の過程で "C5"BF というバイト列に「欧文文字トークン由来」「和文文字トークン由来」というマーキングが必要と思っており,どうしようか……と悩んでいる状況です.

h-kitagawa commented 5 years ago

書き忘れました.kitagawa_printkanji ブランチでは str_toks() などにわざと余計な print() を入れ,どのように文字列化されるかがわかるようにしています(かなり見にくいですが……).`

t-tk commented 5 years ago

質問です。 ("C5)["BF] のように ()[] の書き方を区別しているのは何の違いですか?

分かっていないのですが、欧文TeX で \meaning とした場合、catcode はどうなるのですか? 多分欧文TeX ではそれが catcode の無い素の8bitのバイト列なのかと思います。 そうすると、あくまで例えばですが「和文文字トークン由来」を「素のバイト列」で表現するときに("100C5)["100BF]みたいにするとか? そうすると、改造量が多くなって、「本当に pTeX でそこをピカピカに磨く必要があるの??」という疑問も出てきます。

aminophen commented 5 years ago

("C5)["BF] のように ()と[] の書き方を区別しているのは何の違いですか?

こちらは @h-kitagawa さんにお任せします。

「本当に pTeX でそこをピカピカに磨く必要があるの??」

本件は結局 upTeX にも波及していて,

%#!uptex
\font\x=ec-lmr10\x
\jfont\y=upjisr-h\y

[^^e3^^81^^82]\par
\message{^^e3^^81^^82}
\def\A{^^e3^^81^^82}\meaning\A

\bye

の結果が一行目は "[ãĄĆ]" なのに,二行目の \message は "あ" で三行目は "macro:->あ" になってしまっています。私もこれは整合性がないと思っています。

t-tk commented 5 years ago

本件は結局 upTeX にも波及していて,

なるほど、そうですか。 そうすると、 @h-kitagawa さんコメントの ①〜③ のうち ③ で何かするのは無理で、pTeX, upTeX共通で ②に達する前に「欧文文字トークン由来」「和文文字トークン由来」の区別を導入する必要があるということですね。

h-kitagawa commented 5 years ago

("C5)["BF] のように ()と[] の書き方を区別しているのは何の違いですか?

[] は和文文字トークンが str_toks によって文字列化されたときの 2 文字目を表したつもりです.(C5)(BF), (C5)[BF] は str_pool[] 内のバイト列としては同じですが,こちらで作業しているときにデバッグ用の出力から「2 つの欧文文字トークン ^^c5^^bf`` の文字列化」「和文文字トークン顛`文字列化」を判断できるようにするためです.

t-tk commented 5 years ago

コメント有難うございます。ということはやはり↓で②に達する時点で「欧文文字トークン」「和文文字トークン」が区別出来なくなっている、ということですね。

②しかし, \edef\B{\meaning\A} とすると,まず \meaning により

 (m)(a)(c)(r)(o)(:)(-)(>)("C5)["BF]( )("C5)["BF]("C5)["BF]

と文字列化(selector=new_string の状態で print_... が呼ばれる)され

(u)pTeX で素の8bitバイト列で「欧文文字トークン」「和文文字トークン」の混乱が起こる場所って、今回の事例以外にはありますか?

t-tk commented 5 years ago

あくまで案ですが、

  1. 「和文文字トークン由来」を「素のバイト列」で表現するときに("100C5)["100BF]みたいにする
  2. 「和文文字トークン由来」を「素のバイト列」で表現するときに("FFFF)("C5)["BF]みたいにする。"FFFF は後続(EUCなら2バイト, UTF-8なら可変バイト)が「和文文字トークン」を示すマーカー。

「欧文文字トークン」「和文文字トークン」の混乱が起こる場所が限定的なのならば 2 の方が楽かもしれません。

h-kitagawa commented 5 years ago

こちらこそありがとうございます.

(u)pTeX で素の8bitバイト列で「欧文文字トークン」「和文文字トークン」の混乱が起こる場所って、今回の事例以外にはありますか?

今思いつく限りでは今回の件だけです(全部調べたわけではありませんが).

「和文文字トークン由来」を「素のバイト列」で表現するときに("FFFF)("C5)["BF]みたいにする。"FFFF は後続(EUCなら2バイト, UTF-8なら可変バイト)が「和文文字トークン」を示すマーカー。

今,次の方針を試しています(まだうまく動きませんが):

  1. 「欧文文字トークン由来」の 0x80 以降のバイトには ("FF)("C5)("FF)("BF) のように ("FF) を前置する
t-tk commented 5 years ago

確かに 0xFF は Shift-JIS にも EUC にも UTF-8 にも現れないので、その案3が一番明快ですね。賛成です。 欧文文字トークン由来の("FF)は("FF)("FF)で表せますね。

h-kitagawa commented 5 years ago

ファイル名の扱いについてよく分かっていない(個人的には ASCII の範囲しか使わないのもあって)ので素朴な疑問です.unix-like OS で ptex -jobname=あſ hoge.tex としたとき,

  1. \jobname で展開されるトークンは,バイト列の ^^e3^^81^^82^^c5^^bf ,「あ」を EUC 化した ^^a1^^a2^^c5^^bf ,あるいは あ^^c5^^bf なのか,どれが「望ましい」でしょうか?
  2. \message{\jobname} の出力は あſ が期待される?
  3. 生成される dvi は(あ^^c5^^bf.dvi でなく) あſ .dvi が期待される?
h-kitagawa commented 5 years ago

80 のエラーについてですが,utf8.def 中に

\PackageError{inputenc}{Unicode character \expandafter
                        \UTFviii@splitcsname\string#1\relax

というコードを見つけました. 例えば pTeX だと

 \顛  \csname ^^c5^^bf\endcsname  \csname 顛\endcsname

\stringするとみな \顛 になるので,これが直接的な原因だと思います.

この件は upTeX でも \csname ^^e3^^81^^82\endcsname\あ を同一視するか,という点で関わってきますが,さてどうしましょうか.

t-tk commented 5 years ago

ファイル名の取り扱いについて、pTeX + unix-like OS では pTeX/upTeX の日本語ファイル名(#45) の頃に触った記憶があります。方針としては、「pTeX エンジン内部ではプラットフォームにかかわらず pTeX の内部コード(unix-like OSならばEUC)で扱う。ロケールがUTF-8の場合に限り、コマンドライン読み込みの際にUTF-8→EUC変換を行い、ファイルオープンの際 web2c/lib/openclose.c の open_input() の中でptexencの関数を呼び出し EUC→UTF8 変換を行う。」だったと思います。関連するコミットは、r47967 だと記憶しています。 その他のケースは基本的に何もしていません。 pTeX + unix-like OS + ロケールがUTF-8以外の場合、何もしていない結果、内部コード(通常EUC)とロケール(ja_JP.eucJP等)が一致している場合のみ動くはずです。 upTeX + unix-like OS の場合、何もしていない結果、内部コードUTF-8でロケールがUTF-8という現在一般的な環境では動いているはずです。

pTeXかつunix-like OS かつロケールがUTF-8の場合、 ptex -jobname=あſ hoge.tex としたときは、 コマンドライン読み込みで、内部コードでは「あ」のEUCコード ("a4)("a2) と ^^c5^^bf になると思います。再度実際にオープンするファイル名については EUC→UTF-8 に戻すのが r47967 の方針でしたが、 ^^c5^^bf を"ſ" に戻すかどうかは考えていませんでした。 pTeX かつ Windows の場合、 ptex -jobname=あſ hoge.tex と入力すると、現状ではコマンドライン読み込みで何もしていない(日本語WindowsではコマンドラインをUTF-8ではなくCP932の文字列と仮定して処理する)ので"ſ" を "^^c5^^bf " に変換する機能が働かないと思います。なので、 ptex -jobname=あſ hoge.tex の例で "ſ" は想定外であり、「pTeXでは基本的にJIS X 0208の第1,2水準以外はサポートしない」を貫けばよいと思います。

t-tk commented 5 years ago

もう一つ漠然と思うことです。 「pTeX でJIS X 0208の第1,2水準以外のUTF-8の文字を ^^ab 形式にして pTeX 内に流し込む」という機能は pTeX の入出力で UTF-8 をサポートする際に入力の利便性のために入れたオマケ的な機能だと思っています(強力な機能でもありますが)。pTeX のファイル名問題は、どんなに頑張っても簡明な策は無くどうしても弥縫策になってしまうので、どこかで線を引くべきと思います。

t-tk commented 5 years ago

追伸。 pTeXかつunix-like OS かつロケールがUTF-8以外のレガシーエンコーディング(例えばja_JP.eucJP等)の場合、ptex -jobname=あſ hoge.tex と入力すること自体が困難です。 やはり、 ptex -jobname=あſ hoge.tex の例で "ſ" は想定外であり、「pTeXでは基本的にJIS X 0208の第1,2水準以外はサポートしない」が私の結論です。

h-kitagawa commented 5 years ago

ファイル名の取り扱いについて 「pTeXでは基本的にJIS X 0208の第1,2水準以外はサポートしない」

コメントありがとうございます.あ^^c5^^bf.dvi という出力ファイル名を見たときはびっくりしましたが,この原則に則って,何もいじらないことにします.

t-tk commented 5 years ago

upTeX でも \csname ^^e3^^81^^82\endcsname\あ を同一視するか

正直考えていませんでした。 欧文TeXとの互換性を重視した場合、\csname ^^e3^^81^^82\endcsname\あ と同一視されてしまうと困る場合がある、ということですね。 欧文 TeX では \ に8bit 3byte の "E3 "81 "82 が後続した文字列になるべきで、それが \あ では無い。 現状のupTeXは \あ と同一視している。

仕様案1は、UTF-8の入力文字列をCJKトークンと欧文トークンに振り分ける場合にならって「\csname ^^e3^^81^^82\endcsname, \csname あ\endcsname ともに、UTF-8 で 0xE3 0x81 0x82 (U+3042) の kcatcode が15ならば 欧文 TeX と同じ、kcatcode が15以外ならば \あ と同一視する。」 あるいは、仕様案2「\csname ^^e3^^81^^82\endcsname は、常に欧文 TeX と同じ。UTF-8で書かれた\csname あ\endcsname\あ と同一。 」 どちらが自然、あるいは便利でしょうか。あるいは、別の案?

hideak-t commented 5 years ago

欧文でどうなっているか気になったので、試してみました。

{^^00^^fc}
\message{^^00^^fc}
\def\U{^^00^^fc}
\message{\U}
\meaning\U
\expandafter\edef\csname ^^00^^fc\endcsname{testA}
\csname ^^00^^fc\endcsname
\expandafter\edef\csname ü\endcsname{testB}
\csname ^^00^^fc\endcsname
\csname ü\endcsname
%\ü <- error

このコード、etex, ptex, uptex では ¥message では ü (u umlaut) が出力されますが、 tex では ¥message で ^^fc が出力される。etex 拡張で ¥message では ü (u umlaut) が出力されるようになったということでしょうか。でも、etex 拡張後でも csname で使われる場合は同一視されていないんですね。面白いです。

hideak-t commented 5 years ago

おっと、失礼いたしました。uptex では ¥message で出力されるのは ^^fc の方ですね。

hideak-t commented 5 years ago

不勉強なので、もう少し試してみました。etex, ptex で \message{^^fc} で u umlaut が出るのは、etex 拡張で非ASCII も ¥message でそのまま出力するようになった結果ということでしょうか。と考えると、etex, ptex で \message{^^e3^^81^^82} で「あ」が出力されるのは仕様の範囲?

hideak-t commented 5 years ago

以下は、いずれの処理系でも

\expandafter\edef\csname ü\endcsname{testA}
\expandafter\edef\csname ^^00^^fc\endcsname{testB}
\expandafter\edef\csname ^^fc\endcsname{testC}
\csname ü\endcsname
\csname ^^00^^fc\endcsname
\csname ^^fc\endcsname

testA testC testC と typeset されるので、いずれの処理系でも ^^00 は単純に無視されているんですね。

h-kitagawa commented 5 years ago

etex 拡張で ¥message では ü (u umlaut) が出力されるようになった

私も完全に理解しているわけではありませんが,TCX ファイルというもののおかげのようです(Web2C のドキュメント (texdoc web2c) や マクロツイーターの記事 参照).

TeX Live では,fmtutil.cnf

etex pdftex language.def -translate-file=cp227.tcx *etex.ini
latex pdftex language.dat -translate-file=cp227.tcx *latex.ini

とあるように,cp227.tcx という TCX ファイルが標準で使われます.この cp227.tcx をみると

This file makes all characters with code >= 128 printable for TeX.
TeX itself makes all codes in the range of 32 to 127 printable.

とあり,確かに etex '\message{^^e3^^81^^82}\bye' からは「^^e3^^81^^82」でなく「あ」が出力されます.

一方,pdftex -ini -etex -jobname=etex-notcx etex.ini と TCX ファイルを使わないようにフォーマットを作り直した場合は,pdftex -fmt=etex-notcx '\message{^^e3^^81^^82}\bye' から「^^e3^^81^^82」が出力されました.

h-kitagawa commented 5 years ago

仕様案1は、UTF-8の入力文字列をCJKトークンと欧文トークンに振り分ける場合にならって「\csname ^^e3^^81^^82\endcsname, \csname あ\endcsname ともに、UTF-8 で 0xE3 0x81 0x82 (U+3042) の kcatcode が15ならば 欧文 TeX と同じ、kcatcode が15以外ならば \あ と同一視する。」 あるいは、仕様案2「\csname ^^e3^^81^^82\endcsname は、常に欧文 TeX と同じ。UTF-8で書かれた\csname あ\endcsname は \あ と同一。 」 どちらが自然、あるいは便利でしょうか。あるいは、別の案?

仕様案 2 だと,\string するときにどうするか,という論点もあります.整理するとこんな感じでしょうか?

仕様案 1 はまだ試していません.もし仕様案 2 をとるのならば,欧文 TeX との互換性と \西暦 などの和文の制御綴も使われていることから [2-3] になるのかなあ,という気がしています.

h-kitagawa commented 5 years ago

仕様案 1 をさらに別の kitagawa_printkanji_1 ブランチで入れてみました.このブランチの upTeX では \^^e1^^81^^82\あ が内部で別の制御綴に扱われますが,UTF-8 環境下ではそれが端末や log からわからなくなり,よくないように思えてきました.

%#! euptex
\catcode"E3=11 \catcode"81=11 \catcode"82=11 %"
\def\^^e3^^81^^82{hoge}\def\あ{piyo}
\message{\^^e3^^81^^82 \あ}               % ==> hogepiyo
\message{\string\^^e3^^81^^82 \string\あ} % ==> \あ\あ
\bye
t-tk commented 5 years ago

考えがまとまっていませんが 取り敢えずおしまいの問題についてだけ、欧文 TeX で考えてみます。以下の例で

%#! etex
\catcode"C2=11 \catcode"AA=11 %"
\def\^^c2^^aa{hoge}
\message{\^^c2^^aa}        % ==> hoge
\message{\string\^^c2^^aa} % ==> \ª
\bye

^^c2^^aa の 8ビット2バイトの列のエンコーディングは UTF-8 であると保証されているはずはなく T1等かもしれないのに端末出力に UTF-8 前提で U+00AA (ª, UTF-8で0xc2 0xaa) が表示されるのは「正しい」動作なのでしょうか? おそらくそこは TCX ファイルの動作であって、(e)TeX 自体の責任では無いと理解しています。

(e)upTeX で\^^e1^^81^^82\あ を区別した仕様でかつ TCX を介さない場合に

\message{\string\^^e3^^81^^82 \string\あ} % ==> \^^e3^^81^^82\あ

とすることがもし出来るのならば UTF-8 環境下でも(TCX無しとすることで)区別できそうに思います。

t-tk commented 5 years ago

疑問です。 Omega/Aleph, XeTeX, LuaTeX では \csname ^^c2^^aa\endcsname\csname ^^^^00aa\endcsname は区別される? \string\^^c2^^aa\string\^^^^00aa は区別される?

h-kitagawa commented 5 years ago

\message{\string\^^e3^^81^^82 \string\あ} % ==> \^^e3^^81^^82\あ

なるほど,こういう方法は思いつきませんでした,しばらく考えてみます.

Omega/Aleph, XeTeX, LuaTeX では \csname ^^c2^^aa\endcsname と \csname ^^^^00aa\endcsname は区別される? \string\^^c2^^aa と \string\^^^^00aa は区別される?

区別されるようです.

\catcode"C2=11
\catcode"AA=11
\expandafter\def\csname ^^^^00aa\endcsname{piyo}
\expandafter\def\csname ^^c2^^aa\endcsname{hoge}
\message{%
  \string\^^^^00aa, \string\^^c2^^aa,
  \csname ^^^^00aa\endcsname, \csname ^^c2^^aa\endcsname}
\bye
% pdftex: \^^^^00aa, \ª, piyo, hoge (番外)
% aleph: \^^aa, \^^c2^^aa, piyo, hoge
% xetex: \ª, \ª, piyo, hoge
% luatex: \ª, \ª, piyo, hoge
t-tk commented 5 years ago

言い換えると

(e)upTeX では、「欧文の部分は8bit欧文TeXと同じ」という建前なのでpdfTeXに近い仕様がよいことになりますが、仕様が破綻しそうですね…

h-kitagawa commented 5 years ago

(e)upTeX で\^^e1^^81^^82 と \あ を区別した仕様でかつ TCX を介さない場合に

\message{\string\^^e3^^81^^82 \string\あ} % ==> \^^e3^^81^^82\あ

とすることがもし出来るのならば UTF-8 環境下でも(TCX無しとすることで)区別できそうに思います。

引き続き kitagawa_printkanji_1 でいじっていて,↑が可能なようにしました.

雑感ですが,encTeX の \xprncode(printable かどうかを指定)だけを引っ張ってくるのもあり?

t-tk commented 5 years ago

これで合っていますか? 言い回しなど変なところがあればご指摘お願いします。よく分かっていません。

ややこしいですが、一応辻褄は合っていて、欧文TeX互換と(u)pTeXのCJK拡張部分との両立も出来ているような気がします。

まだよく分かっていません。pTeX ではどうなるのでしょうか? 本issueの冒頭の問題はどうなっているのでしょうか?

encTeX の \xprncode(printable かどうかを指定)だけを引っ張ってくるのもあり?

すみません。よく分かりません。

t-tk commented 5 years ago

疑問というか質問というか確認です。

h-kitagawa commented 5 years ago

いずれきちんとドキュメント化しないといけないと思っていますが,すぐに答えられるものだけ…….

  1. 0x80未満のASCII領域の場合も制御綴りのstring poolに格納するのは^^ffを付与した形になる?
  2. 欧文TeX と (e)upTeX(検討中)での欧文扱いとの間で制御綴りのstring pool内の並びが ^^ff の有無の差が出来るが、その非互換性が問題になることは無い?
  3. 制御綴りに8bit欧文と和文の混在は許される?
  1. なりません.0x80 以上限定です.
  2. 問題ないと信じています(が,引き続き調べます). \scantokens で問題が見つかったので,調査します (6/28 16:52).
  3. 許容されます.\ああ, \^^e3^^81^^82^^e3^^81^^82, \あ^^e3^^81^^82, \^^e3^^81^^82あ はすべて区別されます.

これで合っていますか? 言い回しなど変なところがあればご指摘お願いします。

表の形にしました.表の各セルは \message{\string...} で出力された形(TCX なし)状態です.


engine \^^c2^^aa \^^aa \^^^^0aa \csname ^^^^00aa \endcsname 備考
pdfTeX \^^c2^^aa \^^c2^^aa \^^aa *1 *2
Aleph \^^c2^^aa \^^c2^^aa \^^aa \^^aa \^^aa
XeTeX \^^aa \^^c2^^aa \^^aa \^^aa \^^aa
LuaTeX \^^aa \^^c2^^aa \^^aa \^^aa \^^aa
e-upTeX(従来版) \�*4 *1 *2
e-upTeX(検討中) \^^c2^^aa*3 \^^c2^^aa*3 \^^aa *1 *2 ª の catcode が 15
e-upTeX(検討中) \^^c2^^aa*3 \^^aa *1 *2 ª の catcode が 16 以上

1: 制御綴 \^^^ + 5トークン ^00aa 2: (^^^)^00aa (6トークン) 3: string pool には ^^ff^^c2^^ff^^aa として格納 4: 内部的には \^^aa だが,\message で出力したときには 0xaa が直に

h-kitagawa commented 5 years ago

pTeX ではどうなるのでしょうか?

engine \^^e6^^8d^^89 \捉 \^^c2^^aa 備考
e-pTeX(従来版) \�^^8d^^89*1 \捉 \捉
e-upTeX(従来版) \捉 \捉
e-pTeX(検討中) \^^e6^^8d^^89 \捉 \^^c2^^aa
e-upTeX(検討中) \^^e6^^8d^^89 \^^e6^^8d^^89 \^^c2^^aa 捉 の catcode が 15
e-upTeX(検討中) \^^e6^^8d^^89 \捉 \^^c2^^aa 捉 の catcode が 16 以上

*1: 最初のバイトは 0xe6

本issueの冒頭の問題はどうなっているのでしょうか?

tcx なしの状態と(TeX Live 標準の)cp227.tcx 読み込み時とでは,端末やファイルへの出力時に ^^80--^^ff が ^^80 のように ^^ 表現で出力されるか,それとも バイトとして出力されるかだけです.検討中の (e-)(u)pTeX では,和文文字トークンに由来するバイト列は tcx に関係なくそのまま ptexenc に渡すようにしているので,tcx なしの状態では

\def\A{^^c5^^bf ſ 顛}\message{A} % ==> ^^c5^^bf ^^c5^^bf 顛
\edef\B{\meaning\A}\message{\meaning\B} % ==> macro:->macro:->^^c5^^bf ^^c5^^bf 顛

のようになります.

t-tk commented 5 years ago

実現可能性はよく分かりませんが以下の案はいかがでしょう。

制御綴りのstring pool で1バイトに 0x100 以上を保存できるようにし、和文文字トークン由来は 0x100 以上にUnicodeスカラー値のまま保存する。0x80以上0xff以下の和文文字トークン由来は、Unicodeで単独で現れることのない 0xdf80〜0xdfff あたりに移して保存する。欧文文字トークン由来は 0x00〜0xff のまま保存する。

こうすれば欧文文字トークン由来は欧文TeXと同じになるはず。

h-kitagawa commented 5 years ago

制御綴りのstring pool で1バイトに 0x100 以上を保存できるようにし、

欧文 TeX との互換性を考えればこちらの方が安全ですね.個人で fork していろいろ試してみることにします.

t-tk commented 5 years ago

ブレインストーミング用に前回の案と若干異なる別案です。あまり良くないかも知れません。

制御綴りのstring pool で1バイトに 0x100 以上を保存できるようにし、和文文字トークン由来は 0x100 以上にUnicodeスカラー値のまま保存する。欧文文字トークン由来は 0x00〜0xff のまま保存する。0x80以上0xff以下の和文文字トークン由来は、従来のupTeXの通り欧文文字トークン由来と区別しない。

「Unicodeで単独で現れることのない 0xdf80〜0xdfff あたりに移す」のような気持ち悪いことをしなくて済む反面、和文トークン由来と欧文トークン由来が区別出来ない問題がU+0080..00FFの和文トークンでは残ります。仕様的にはこっちの方が中途半端で気持ち悪い感じもします。

h-kitagawa commented 5 years ago

こちらも https://github.com/h-kitagawa/tex-jp-build/tree/printkanji_16bit で試している方法を載せておきます.

制御綴の string pool には 1 要素に 0x00〜0x1ff を保存できるようにする(実際の型は unsigned short).欧文文字トークン由来は 0x00〜0xff のままとし,和文文字トークン由来は 0x100〜0x1ff と 0x100 を増やした値を保存する.例えば「\あ」は(EUC の)pTeX では 0x1a4 0x1a2 となる.

欧文由来か和文由来の 1 ビットを加えるだけ(Unicode スカラー値をそのまま格納するのではなく)としているのは,こちらのほうが変更量が少なそうかも,という単純な理由です.

aminophen commented 5 years ago

メモ:printkanji_16bit ブランチのビルド中に aleph のビルドでエラーが出たので,そのミスを修正するには以下のようにする。

diff --git a/source/texk/web2c/lib/texmfmp.c b/source/texk/web2c/lib/texmfmp.c
index 0c88a59..f225835 100644
--- a/source/texk/web2c/lib/texmfmp.c
+++ b/source/texk/web2c/lib/texmfmp.c
@@ -3007,7 +3007,7 @@ gettexstring (strnumber s)
   {
   poolpointer i;
   /* Don't use strncpy.  The strpool is not made up of chars. */
-#if defined (IS_pTeX)
+#if IS_pTeX
   for (i=0; i<len; i++) name[i] =  0xFF&strpool[i+strstart[s]];
 #else
   for (i=0; i<len; i++) name[i] =  strpool[i+strstartar[s - 65536L]];
aminophen commented 5 years ago

@h-kitagawa さんの printkanji_16bit (16f6df4) を試し始めて,pLaTeX のフォーマットを作ってみたのですが,\newlinechar が -1 になってしまうようです。(本来の pLaTeX なら 10)

h-kitagawa commented 5 years ago

\newlinechar が -1 になってしまう

c05a1c2 で直しました.print() 内で「new_line_char を -1 に設定→復帰」という箇所がありますが,復帰を忘れていた場所がありました.

aminophen commented 5 years ago

\newlinechar

ありがとうございます。

今度は \scantokens ですが,どうなるのが正解なんでしょうか。

% eptex
\font\x=ec-lmr10\x
[あ^^c5^^bf^^a4顛]
\scantokens{[あ^^c5^^bf^^a4顛]}
\end
20191017-scantokens

(utf8.euc) の場合,現行 pTeX でも printkanji_16bit でも上の画像になりましたが,うーん。

h-kitagawa commented 5 years ago

\scantokens

私も悩んでいるので,あえてそのままにしています.

\scantokens は引数のトークン列を文字列化したものを疑似ファイル入力として扱います.同じ [あ^^c5^^bf^^a4顛] でもソース中に直に書いた場合と \scantokens 由来の場合とでは,TeX が入力の各行として認識するバイト列が次のように異なります:

[5b][a4][a2][5e][5e][63][35][5e][5e][62][66][5e][5e][61][34][c5][bf][5d] % 2 行目
[5b][a4][a2][c5][bf][a4][c5][bf][5d] % \scantokens 由来の疑似ファイル

そして,例によって疑似ファイル中の [c5][bf] というバイト列を和文文字トークン「顛」として読み取る,というわけです.


文字列化の結果でつけた和文・欧文の区別を疑似ファイルに引き継ぐのがいいか悩む理由は,upTeX の \kcatcode が絡んだ場合です.

\font\a=ec-lmtt10\a
\def\C{[あ\kcatcode"3042=15 い\kcatcode"3042=16]}
\C
\scantokens\expandafter{\C}
\C
\bye

例えば上の 4 行目の処理結果を考えると,

和文・欧文の区別は入力バイト列の時点ではないはず(トークン化の際に起こるべき)と思っているので.個人的には前者かな,と思っています.

aminophen commented 5 years ago

\scantokens

わかったようなわからないような…。まだ悩んでみます。

今度はこんなテストを作ってみましたが, \unexpanded のところ (???) をつけた行はこれでいいのでしょうか。 → 一文字タイポしていたミスが原因でした。無視してください。 (edit)

%#!eptex
\immediate\openout8=xxfileA.tex\relax
\immediate\write8{\string\def\string\あああ{^^c5^^bf}}%
\immediate\closeout8
\input xxfileA.tex
\show\あああ % => 現在「顛」開発版「^^c5^^bf」

\immediate\openout8=xxfileAA.tex\relax
\immediate\write8{\string\def\string\あああ{顛}}%
\immediate\closeout8
\input xxfileAA.tex
\show\あああ % => 現在「顛」開発版「顛」

\immediate\openout8=xxfileB.tex\relax
\immediate\write8{\noexpand\def\noexpand\あああ{^^c5^^bf}}%
\immediate\closeout8
\input xxfileB.tex
\show\あああ % => 現在「顛」開発版「^^c5^^bf」

\immediate\openout8=xxfileBB.tex\relax
\immediate\write8{\noexpand\def\noexpand\あああ{顛}}%
\immediate\closeout8
\input xxfileBB.tex
\show\あああ % => 現在「顛」開発版「顛」

\immediate\openout8=xxfileC.tex\relax
\immediate\write8{\unexpanded{\def\あああ{^^c5^^bf}}}%
\immediate\closeout8
\input xxfileC.tex
\show\あああ % => 現在「顛」開発版「^^c5^^bf」

\immediate\openout8=xxfileCC.tex\relax
\immediate\write8{\unexpanded{\def\あああ{顛}}}%
\immediate\closeout8
\input xxfileCC.tex
\show\あああ % => 現在「顛」開発版「顛」

\scantokens{\def\あああ{^^c5^^bf}}
\show\あああ % => 現在「顛」開発版「顛」

\scantokens{\def\あああ{顛}}
\show\あああ % => 現在「顛」開発版「顛」

\end
aminophen commented 5 years ago

すぐ上のコメントはこちらのミスですみませんでした。一方今度は upTeX の \kansuji です。

\kansujichar1=`A
\expandafter\show\kansuji1
\end

現行 upTeX は > the character A. ですが,printkanji_16bit では > kanji character A. になってしまいます。これは #36 で議論していた

  • 文字コードが0~127の“和文文字”(ノード)は存在する。
    • \kchar"41で和文のU+0041が出力される。
  • 一方で、文字コードが0~127の“和文文字トークン”は存在しない。

に反しています。

h-kitagawa commented 5 years ago

一方で、文字コードが0~127の“和文文字トークン”は存在しない。

再トークン化 (str_toks) にそのようなコードを仕込みました (c8baec295).

aminophen commented 5 years ago

一方で、文字コードが0~127の“和文文字トークン”は存在しない。

再トークン化 (str_toks) にそのようなコードを仕込みました (c8baec2).

ありがとうございます。

次のは極めてどうでもいい例ですが,一応。

\tracingonline1
\epTeXinputencoding utf八\relax
\epTeXinputencoding utf\kansuji8\relax
\end

現行は2回とも

Unknown encoding `utf八'
Unknown encoding `utf八'

ですが,printkanji_16bit では2回とも

Unknown encoding `utfȬ'
Unknown encoding `utfȬ'

になりました。

aminophen commented 5 years ago

\epTeXinputencoding の Unknown encoding 警告

0c773d5 で大丈夫でした。ありがとうございます。


私が思いつく限りの「おかしな入力」は以上で,あとは実際の既存パッケージやドキュメントで,何か変なことが起きないか試すしかないように思います。

aminophen commented 5 years ago

ビルドが間違っていたらすみませんが,期待と違ったので一応:

\input ^^80^^80\relax
\end

従来の pTeX でのログ:

$ ptex inp
This is pTeX, Version 3.14159265-p3.8.3 (utf8.euc) (TeX Live 2020/dev) (preloaded format=ptex)
 restricted \write18 enabled.
(./inp.tex
! I can't find file `^^80^^80'.
<to be read again> 
                   \relax 
l.1 \input ^^80^^80\relax

(Press Enter to retry, or Control-D to exit)
Please type another input file name:

新しい pTeX (printkanji_16bit) でのログ:

$ ptex-beta inp
This is pTeX, Version 3.14159265-p3.8.90 (utf8.euc) (TeX Live 2020/dev) (preloaded format=ptex-beta)
 restricted \write18 enabled.
(./inp.tex
! I can't find file `??'.
<to be read again> 
                   \relax 
l.1 \input ^^80^^80\relax

(Press Enter to retry, or Control-D to exit)
Please type another input file name:

警告は ^^80 形式のままが良い気がします。

h-kitagawa commented 5 years ago

b1f39aefeb で次のように TCX 依存にしました:

入力 (inp.tex)

\input ^^80^^80あ^^81^^c5^^bf\relax
\end

ログ (empty.tcx)

 $ eptex-beta --translate-file=empty.tcx inp
This is e-pTeX, Version 3.14159265-p3.8.90-190908-2.6 (utf8.euc) (TeX Live 2020/dev) (preloaded format=eptex-beta)
 restricted \write18 enabled.
 (/opt/texlive/2019/texmf-dist/web2c/empty.tcx)
entering extended mode
(./inp.tex
! I can't find file `^^80^^80あ^^81^^c5^^bf'.
<to be read again>
                   \relax
l.1 \input ^^80^^80あ^^81^^c5^^bf\relax

ログ(cp227.tcx,TeX Live 標準の TCX)

$ eptex-beta --translate-file=cp227.tcx inp
This is e-pTeX, Version 3.14159265-p3.8.90-190908-2.6 (utf8.euc) (TeX Live 2020/dev) (preloaded format=eptex-beta)
 restricted \write18 enabled.
 (/opt/texlive/2019/texmf-dist/web2c/cp227.tcx)
entering extended mode
(./inp.tex
! I can't find file `��あ�ſ'.
<to be read again>
                   \relax
l.1 \input ^^80^^80あ^^81^^c5^^bf\relax
aminophen commented 5 years ago

ああそうでした,上の方で TCX の出力可能性の話が出ていたのを忘れていました。

aminophen commented 5 years ago

「現行の pTeX と開発版 pTeX で何が変わるのか」を手早くテストするために,l3build の仕組みを使うことを模索しています。 https://github.com/texjporg/texjporg-testing

を走らせるための設定 (build.lua) を作ってあります。構想としては,

  1. 沢山のテストソース(.lvt ファイル)を用意し,それに対応する標準化ログ(.tlg ファイル)を **現行の pTeX(TeX Live subversion にあるもの)で作成
  2. 開発版 pTeX で cd dev-plain && texlua build.lua check あるいは cd dev-latex && texlua build.lua check を実行し,fail したテストが意図通りの変化なのか確認

というのが出来ればいいな,とおもっています。