Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pTeX の和文文字トークンのカテゴリーコード #4

Closed
aminophen opened this issue Apr 22, 2019 · 15 comments
Closed

pTeX の和文文字トークンのカテゴリーコード #4

aminophen opened this issue Apr 22, 2019 · 15 comments
Labels

Comments

@aminophen
Copy link
Member

aminophen commented Apr 22, 2019

texjporg/tex-jp-build#68 とはまた別件で…

https://twitter.com/zr_tex8r/status/1119952801952485377

\kcatcode`あ=18
\def\xA{あ}\let\yA=あ
\ifcat\xA O\else X\fi
\ifcat\yA O\else X\fi

\kcatcode`あ=17
\ifcat\xA O\else X\fi % (1)
\ifcat\yA O\else X\fi % (2)
\bye

(1) と (2) は

pTeX では和文文字トークンには kcatcode が含まれず,その都度算出されるが,upTeX では元々和文文字トークンに kcatcode も含まれる … (★)

という現象を試すためのものです。確かに upTeX では両方 X となるのですが,pTeX では (1) が O で (2) が X になります。(★)に基づくと (2) が X になるのが不思議ですが,なにか理由があるのでしょうか?

@h-kitagawa
Copy link
Member

tex.web の \let の処理のところを見ると,次のように cur_cmd, cur_chr を保存するようになっています.和文文字トークンの場合は kcatcode が cur_cmd なので,和文文字トークンを \let すると kcatcode が保存されることになります.

@ @<Assignments@>=
let:  begin n:=cur_chr;
  get_r_token; p:=cur_cs;
  ...
  if cur_cmd>=call then add_token_ref(cur_chr);
  define(p,cur_cmd,cur_chr);
  end;

あくまでも (★) を貫くとしたら,\if\ifcat の判定処理で「cur_cmd が 16, 17, 18 のどれかならば,文字コード (cur_chr) から改めて再計算」を加えることになる?

@aminophen
Copy link
Member Author

ご説明ありがとうございます。なるほど,理由は理解できました。どうするのがいいかは悩み中。

(ドキュメント化しようとすると,疑問発生は尽きないですね…。)

aminophen referenced this issue in texjporg/tex-jp-build May 6, 2019
@aminophen
Copy link
Member Author

texjporg/tex-jp-build@bdfba95 のコメント欄の続きです。


あくまでも (★) を貫くとしたら,\if や \ifcat の判定処理で「cur_cmd が 16, 17, 18 のどれかならば,文字コード (cur_chr) から改めて再計算」を加えることになる?

「pTeX 単独の挙動の一貫性」という観点からは,この方針に賛成です。ところが,

  • [1] pTeX で「カテゴリーコードが随時算出される」のは仕様なのかどうか分からない
  • [2] この変更は pTeX と upTeX の差分が増やす方向である

という2点が引っかかっています。

[2] は先のコメントに書いた通りです。

[1] は,アスキーの公式文書には「随時算出」の記載が見つからないという理由です。一方で,pTeX に詳しい方からすれば,よく知られている挙動なのでしょうか?

ptex-manual.tex:

  \item 欧文文字は\TeX82と同様に1つの文字トークンはカテゴリーコード$c$と文字コード$s$の組
    み合わせ($256c+s$)で表現されていた.\pTeX では和文文字トークンは文字コードのみで表現さ
    れ,そのカテゴリーコードは随時算出されるようになっている
    \footnote{\upTeX では和文文字トークンについてもそのカテゴリーコードの情報が
    含まれるようになった.}.

uptex-base/01uptex_doc_utf8.txt:

<10> 従来のpTeXでは、kcatcodeの参照を文字コードからkcatcodeの表を引き
   間接的に行う方法を行っている。この方法を
   ファイルなどからの読み込み時と内部処理時の両方で行っている。
   upTeXでは、ファイルなどからの読み込み時は同様であるが、
   内部処理時には、<9>でCJKトークン毎に振ったkcatcodeを読み込むように
   変更した。たとえ同じ文字コードでもkcatcodeの途中変更を行えば、
   CJKトークン毎に異なるkcatcodeを割り当てることが出来るようになる。

@t-tk
Copy link

t-tk commented May 6, 2019

「随時算出」という仕様として書かれているわけではありませんが関連する記述としては

ASCII社のweb archiveの kcatcode関連のところ (ドワンゴgithubの同ページ)に

なお、pTeXでは、2バイト文字のカテゴリコードを変更することはできません。なぜなら、pTeXは2バイト文字のカテゴリコードを、その文字の1バイト目で 判断していますが、つぎのように、シフトJISコードの1バイト目が必ずしも、 区点コードの`区'に対応していないためです。 そのため、仮に区単位でカテゴリコードを変更できるようにしても、 SJIS版とEUC版で同じ動作が保証できなくなります。 内部コードを統一すれば不可能ではありませんが、現在は見送っております。

とあります。
「kcatcode を変更して使用することは想定外」と解釈できます。「随時算出」という実装形態を取っているかどうかの点が「仕様」なのではなく「kcatcodeは変更しない」点が仕様のようなものに当たるという風に私は認識しています。ただし、文書全体でkcatcodeがデフォルトと異なるものに固定してしまってもいい場合はASCII pTeXでもkcatcodeの変更は出来たはずです。
しかし、ASCII pTeXを離れてコミュニティ版pTeXとして考えた場合には拡張してもよい部分と思っています。ASCII社さんの「内部コードを統一すれば不可能ではありませんが、現在は見送っております。」という文も将来の拡張の可能性を匂わせる記述ですし。

@t-tk
Copy link

t-tk commented May 6, 2019

それから、現行のpTeXは内部コードがSJISの場合でも「シフトJISコードの1バイト目」ではなく「区点コードの`区'相当」で判定するようになっているはずです。ptexencかその前身のlibkanjiのどこかで実装されました。つまり「内部コードを統一すれば」は既に実現しています。

@h-kitagawa
Copy link
Member

[2] この変更は pTeX と upTeX の差分が増やす方向である

想定されていない使い方でしょうけれども,例えば

\kcatcode`あ=16
\def\X#1あ{\message{X: #1}}
\kcatcode`あ=17
\def\Y#1あ{\message{Y: #1}}
\kcatcode`あ=17
\X aあ\Y bあ\bye

を走らせると,次のように現行でも pTeX と upTeX で挙動の違いが見られます:

  • pTeX では \X, \Y の書式指定「あ」は文字コードだけしか気にしないため,「X: a Y: b」という出力になる.
  • upTeX では(内部コードを EUC にしてフォーマットを作っても)\X, \Y の書式指定「あ」には \kcatcode 情報が含まれるため,「! Forbidden control sequence found while scanning use of \X.」というエラーが発生する.

「pTeX と upTeX の差分を減らす」のならば,pTeX でも \kcatcode を和文文字トークンに含めるように改修するのがもっとも自然でしょう.ただ,個人的には「そこまでして upTeX じゃなくて pTeX にこだわる必要はあるの?」と思っていますが…….

@t-tk
Copy link

t-tk commented May 6, 2019

「素の pTeX/upTeX バイナリ」texjporg/tex-jp-build#32 で途中になっている議論にも関連し、「pTeX と upTeXのメンテを今後どうやっていく?」ということにも深く関わっていると思います。
曖昧な記憶では upTeX の開発初期の頃 pTeX の挙動を離れ kcatcode をトークンごとに振るようにするのは相当骨が折れる作業でしたが

  • Unicodeで同一の文字の「欧文扱い」「和文扱い」などを同一の文書内で変えたい場合が多々あるであろう
  • pTeXでは catcode の挙動と kcatcode の挙動がかなり異なるのに対し upTeX では kcatcode の挙動が catcode に似てくる点はメンテナンス面で有利になるだろう

ということと

  • pTeX の動作から離れて差分を増やす点でメンテナンス面は不利になるだろう

ということを天秤に掛けつつ、思い切ってやることにしました。
「将来 pTeX が upTeX の kcatcode の実装を取り込んでくれる形になればpTeX と upTeX の差分を減らすことが出来る」ということは、当時は夢のようなレベルで考えていました。

「そこまでして upTeX じゃなくて pTeX にこだわる必要はあるの?」

「こだわり」というより、今後のメンテナンス性という面で「pTeXとupTeXの差分を減らしたい」という希望はあります。しかし、もしやるとなると目前の実装や検証の手間もエンバグの恐怖も発生する訳で、「どこまで頑張るか?」あるいは「どこで頑張るか?」ですね。

@aminophen
Copy link
Member Author

皆様ありがとうございます。悩みましたが,以下のように考えるのはどうでしょうか。

  • まず, texjporg/tex-jp-build@ea452bc を以て,現在の pTeX の挙動は「pTeX マニュアル」の通りになった。これならば一貫性があるので,良しとする。
  • 一方で,この「pTeX マニュアル」は絶対ではなく,仮に将来「upTeX でエミュレートした pTeX」が登場すれば維持されない挙動である,という条件をコメントで付ける。つまり,

pTeX族のプログラムと互換性があるはず/あるつもりですが、どこまで検証するかが課題になりそう

では,この差異を無視する。

pTeX に upTeX の実装を持ち込む作業の手間とエンバグの恐怖を避けつつ,今後のメンテナンス性をなるべく損わない落とし所はこんなところかな,という一案です。

@t-tk
Copy link

t-tk commented May 13, 2019

本件に関して気になった点。

ptex-manual.tex:

  \csitem[\.{kcatcode} <character code>=<16--18>]
  |\kcatcode|はDVI中の上位バイト(すなわち,JISコードでいう区ごと)に値が設定可能である.
  初期状態では1,~2, 7--15, 85--94区の文字が18,3--6区の文字が17,16--84区の文字が16である.

欧文TeXの catcode, upTeXの kcatcode では文字ごとに {,k}catcodeが保存されていたり、グループごとに初期値を別々に設定できたり細かい制御が出来る訳ですが、それと同じノリで捉えた場合に上記の表現が誤解を生むと思いました。
先日から話の出ている、pTeX の kcatcode の「固定という前提」や「(現在の)実装」をもとにすると「初期値の変更は想定されていないし、あえて変更するならgoto型の設定変更になる」ような情報も入れたほうがよいかもしれません。
具体的な文案はまだ考えていません。

@t-tk
Copy link

t-tk commented May 13, 2019

細かいことですが、オリジナルのASCII pTeXでは内部コードがSJISのときkcatcodeはSJISの上位バイト(2区ごと)に設定可能でした。
しかし、このマニュアルのあちこちで ptexenc版の pTeX の動作を記述している箇所がいろいろあるようです。なので、むしろ、マニュアルが対象としているpTeXとはどの版なのかをどこかに明示すべきということになります。

@aminophen
Copy link
Member Author

aminophen commented May 31, 2019

upTeX のリビルドに付随して,pTeX のソースにも texjporg/tex-jp-build@ea452bc

\if や \ifcat の判定処理で「cur_cmd が 16, 17, 18 のどれかならば,文字コード (cur_chr) から改めて再計算」を加える

が反映されたことになります。上のコメントに書いたマニュアルのアップデートも後ほどやっておきます。(そのためここはまだ open にしておきます)

@aminophen
Copy link
Member Author

aminophen commented Dec 13, 2020

本件ですが,改めて動かしてみると \let\CS=あ とした制御綴 \CS を比較すると,pTeX の \ifcat では「\kcatcode 再評価」が行われるのに対し,\ifx では行われないことに気づきました。

%#!ptex
\kcatcode`あ=16\relax
\let\X=あ
\let\Z=あ
\kcatcode`あ=17\relax
\let\Y=あ

\if\X\Y    T\else F\fi
\if\X\Z    T\else F\fi
\ifcat\X\Y T\else F\fi
\ifcat\X\Z T\else F\fi
\ifx\X\Y   T\else F\fi % => why FALSE?
\ifx\X\Z   T\else F\fi

\end

つまり,\ifcat と \ifx で挙動が違う状態になっています。

一応,このパッチのようにすれば \ifx でも「\kcatcode 再評価」ができますが,pTeX と upTeX の差分を増やす方向になってしまいます。むしろ前回の変更 (texjporg/tex-jp-build@ea452bc) を元に戻して「\let\CS=和文文字 では kcatcode が保存される」としてもいいような気がしてきました。

@aminophen
Copy link
Member Author

aminophen commented May 24, 2021

#8 に絡んで発生した TeX.SX の質問に回答したところ,速攻で「\let\CS=あ」した制御綴の \ifx 挙動が一貫していないことがばれてしまいました(回答に付随するコメント欄参照)。というわけで,すぐ上のコメントの結論を出さないといけないようです。

aminophen added a commit to texjporg/tex-jp-build that referenced this issue Jun 17, 2021
to preserve consistency between \ifcat and \ifx.
see texjporg/ptex-manual#4
@aminophen
Copy link
Member Author

aminophen commented Jun 25, 2021

texjporg/tex-jp-build#120 をマージしたので

  • \let した和文文字の kcatcode を再計算しない(昔の pTeX に戻す) → r59699

に合わせてドキュメント更新しようと思います(r59701 で p3.9.1 にしています)。 → 5404284

@aminophen
Copy link
Member Author

texjporg/tex-jp-build#120 のコメントのうち関連する物:

By aminophen:

2019-05-06 付けの「pTeX (非upTeX) では和文文字トークンが kcatcode を持たないので,制御綴に \let されたものを再計算する」を意図したコードを revert するものです。意図は,この再計算が \ifcat には効いているものの \ifx には効いておらず,結果的に不整合を起こしていたため,元の挙動に戻したいということです。

「和文文字トークンは kcatcode を持たない」という仕様/挙動の一貫性については,\let された制御綴からは再計算しない(見た目も「和文文字トークン」に見えないし…)としても大して損なわれないと考え直しました。むしろ \let で kcatcode が保持される方が使い勝手は良い気がしますし,upTeX とのコード差分も減らす方向です。

By t-tk:

将来の方向性として、「pTeX (非upTeX) では和文文字トークンが kcatcode を持たない」という仕様をやめて「pTeXも(upTeXと同じように)和文文字トークンが kcatcode を持つ」ように改造する方向はいかがでしょうか。
現行pTeXエンジンとの差分は大きいというデメリットがある一方、upTeXエンジンとの差分を減らす方向ですし、既存のpTeX向けに書いたソースコードの動作には影響ないはずです。

By aminophen:

個人的には好ましい方向だと思います。一方で

  • pTeX (非upTeX) では和文文字トークンが kcatcode を持たない
  • upTeX では CJK 文字トークンが kcatcode を持つ

この差を取り除けば,もはや pTeX が独立して存在する意義はなくなると思います。ですので,いろいろな方面から意見を聞きたいです。

pTeX の仕様変更に合意された場合は,もはや実際には upTeX-1.25 の

  • Set default internal encoding EUC/SJIS if a command name is with prefix of "p" or "ep", intending to be compatible with pTeX family (ptex, eptex, pbibtex, pdvitype, ppltotf, (experimental).

という機能を活用して「内部コードが euc/sjis の upTeX」を pTeX の代わりに起動すれば十分であると思います。 texjporg/tex-jp-build#32 とも近い話で,バイナリを減らす方向ならメンテナンス性は上がりそうです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants