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

[upTeX] ofm読み込みと符号位置 256 以上の欧文文字トークン・ノード #170

Open
t-tk opened this issue Jun 23, 2024 · 54 comments

Comments

@t-tk
Copy link
Collaborator

t-tk commented Jun 23, 2024

upTeX で欧文用に ofm を読めるようにして符号位置 256 以上の欧文文字トークンと符号位置 256 以上の欧文文字ノードを扱えるようにする、という構想です。
少し前↓で述べたことの続きです。
#153 (comment)

まだ実験レベルですがとりあえず手元でそれなりに動いているので紹介します。
スジは結構いいように感じていますが、完成度はまだまだです。


  • 目指すところは「upTeX の拡張、 dvi出力」「(和文・欧文どちらも) Unicode 1 文字から 1 トークンができる」「和文はJFMで組む」「欧文の本文は8bit TFMまたは16bit OFMで組む」
  • kcatcode 14 (latin_ucs) を新設。
    UTF-8の入力バッファで8 bit 文字コード列が正規のUTF-8として U+2E7F 以下と読み取れるとき、Unicodeの欧文であると解釈して符号位置 0x80~0x2E7F の欧文文字ノードを生成する。
  • OFM を読み込めるようにする。符号位置 0~0x2E7F の欧文文字ノードのメトリックはこれで扱う。
    和文は従来と変わらず JFM で扱う。
  • 256~0x2E7F の文字コードは dvi には set2, put2 で書き込む。
  • 0x2E80以上の Unicode文字は、upTeXでは欧文扱いしない。
    dviware側で必要な場合はvirtual fontで何とかする。
  • \catcode, \lccode, \uccode, \sfcode の扱う欧文文字コードの最大値は 0x2E7F とする。(kcatcode=14,15両方)
  • kcatcode=14のとき \char, \chardef は0~0x2E7F の欧文文字が扱える。
  • kcatcode=14のとき eupTeXでは \Uchar, \Ucharcat, \iffontchar, \fontcharwd \fontcharht \fontchardp \fontcharic は0~0x2E7F の欧文文字が扱える。
  • ^^^^xyzw の書式は欧文ノードを生成する。(kcatcode=14,15両方) 8d3be7e

内部ノードの文字コードは以下。

legacy latin  (kcatcode=not_cjk (15), charcode=0xZWXY )
01 :: 0x00 01 ZW XY  left_brace
02 :: 0x00 02 ZW XY  right_brace
..
12 :: 0x00 0C ZW XY  other_char
13 :: 0x00 0D ZW XY  active_char

ucs latin     (kcatcode=latin_ucs (14), charcode=0xZWXY )
01 :: 0x01 00 ZW XY  left_brace
02 :: 0x02 00 ZW XY  right_brace
..
12 :: 0x0C 00 ZW XY  other_char
13 :: 0x0D 00 ZW XY  active_char

CJK           (kcatcode>15, charcode=0xUVZWXY )
16 :: 0x10 UV ZW XY  kanji
17 :: 0x11 UV ZW XY  kana
18 :: 0x12 UV ZW XY  other_kchar
19 :: 0x13 UV ZW XY  hangul
20 :: 0x14 UV ZW XY  modifier
(N.A.)
24 :: 0x18 UV ZW XY  kanji_ivs  VS49 .. VS127
25 :: 0x19 UV ZW XY  kanji_ivs VS128 .. VS191
26 :: 0x1A UV ZW XY  kanji_ivs VS192 .. VS240
27 :: 0x1B UV ZW XY  kanji_ivs VS241 .. VS256
t-tk added a commit that referenced this issue Jun 23, 2024
@t-tk
Copy link
Collaborator Author

t-tk commented Jun 23, 2024

現状のパッチは OFM level=0 は読めますが、OFM level=1 は読めません。
また、updvitype は工事中で OFM を読み始めることは出来ていますが、まだ正しくすべてを読めるようにはなっていません。

\delcode は、そもそも使い方を知らず、拡張の必要性も理解していないのでまだ拡張していません。
欧文文字の文字コードの最大値を 0x2E7F にしたのは、0xFFFF や 0x10FFFF にするとあちこちメモリーの拡張の必要性が増えて、過剰な割に無駄遣いのような気がして制限しています。

t-tk added a commit that referenced this issue Jun 23, 2024
@h20y6m
Copy link
Collaborator

h20y6m commented Jun 23, 2024

ofm_flag=0 のとき? 以下の font_level が未初期化になっているようです。

if font_level=1 then begin


個人的に気になるのはやはり文字コード 128--255 の扱いでしょうか。
この範囲の文字を kcatcode=14 に設定してしまうと UTF-8 を構成するバイト列と衝突します。
(和文文字の U+0080--U+00FF と同じ問題が今度は欧文文字どうしで起こる)

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 23, 2024

コメントありがとうございます。

文字コード 128--255 の扱い
この範囲の文字を kcatcode=14 に設定してしまうと UTF-8 を構成するバイト列と衝突します。
(和文文字の U+0080--U+00FF と同じ問題が今度は欧文文字どうしで起こる)

使い方としては、kcatcode=14 に設定したらコンパイルの最後までそのブロック内(\bgroup...\egroup内)ではそれを貫くことを想定しています。
なので、kcatcode=14 を設定した後は、常に 「UTF-8 ⇔ Unicodeコードポイント」の対応関係になります。
また、catcode+charcode の token の場合は、kcatcode=14 由来の場合は 0x0100zwxy 以上に、kcatcode=15由来の場合は 0x000F00xy 以下になるため、混在しても衝突しません。
なので、おそらく大丈夫と思っています。
catcode=0 かつ 0x7F<charcode<0x100 の token は区別できませんが、例えば、kcatcode=14 かつ charcode 0x80 以上禁止にすれば回避できるように思います。

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 23, 2024

このissueのやり方を思いついたときのcommentを貼っておきます。
#150 (comment)

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 24, 2024

font_level が未初期化

55f68df で修正。

文字コード 128--255 の扱い

6a2a3a2 にて
kcatcode=14 で生成される latin_ucs のノードには 0x800000 のフラグを立てるようにしてみました。
kcatcode=14 由来の場合は 0x0080 zwxy ~ 0x0f80 zwxy となるので catcodeによらず CJKのノード (0x1000 0000以上)とも従来の 8bit Latin のノード (0x0000 00xy ~ 0x000f 00xy )とも衝突しなくなったはずです。

@aminophen
Copy link
Member

\char, \chardef は0~0x2E7F の欧文文字が扱える。

これについては,従来の upTeX 仕様から非互換な変更になるので注意です。0x100〜0x2E7F で従来は和文フォントで出ていたところ,欧文フォントで出るようになることによる影響(→欧文フォントが未対応で文字が出なくなる等)?

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 24, 2024

コメントありがとうございます。

0x100〜0x2E7F で従来は和文フォントで出ていたところ,欧文フォントで出るようになることによる影響

その文字ブロックが kcatcode=14 になっていない限り latin_ucs と判定されないよう check_echar_range で見ているので、非互換性には配慮出来ていると思います。

function check_echar_range(@!c:integer):integer;
begin
if (c>=0)and(c<256)then
check_echar_range:=1
else if (c>=256)and(c<max_latin_val)and(kcat_code(kcatcodekey(c))=latin_ucs)then
check_echar_range:=1
else check_echar_range:=0;

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 25, 2024

e2e161c
で動いているようです。

\jfont\jpy=umin10
\jpy
\font\uctt=uctt10
\uctt

\kcatcode"152=16
\char"152 % -> 和文

\kcatcode"152=14
\catcode"152=11
\char"152 % -> 欧文

\kcatcode"152=15
\catcode"152=11
\char"152 % -> 和文

\bye

image

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 25, 2024

^^^^zwxy 書式は基本的に常に欧文で出ますが、catcode未設定だと出力されません。
予想通りですし、これでよいと思います。

\jfont\jpy=umin10
\jpy
\font\uctt=uctt10
\uctt

\kcatcode"152=16
\char"152 % → 和文
^^^^0152 % catcode未設定なので出力されない

\catcode"152=11
\char"152 % → 和文
^^^^0152 % → 欧文

\kcatcode"152=14
\catcode"152=11
\char"152 % → 欧文
^^^^0152 % → 欧文

\kcatcode"152=15
\catcode"152=11
\char"152 % → 和文
^^^^0152 % → 欧文

\bye

t-tk added a commit that referenced this issue Jun 26, 2024
@t-tk
Copy link
Collaborator Author

t-tk commented Jun 26, 2024

0fa0c33
kcatcode=14 で生成される latin_ucs のノードには 0x800000 のフラグを立てるというのをやめました。
今更ながら TeX by Topic を段ボール箱の奥から引っ張り出してきて読み返し、
catcode=0の文字がトークンになることはない、と理解しました。
なので、0x800000 のフラグがなくても legacy latin のトークンと ucs latin のトークンは区別されます。

@aminophen
Copy link
Member

ありがとうございます。他,従来成り立っていた仕様について

  • \if による文字コード比較では,同じ文字コードを持てば true(一方が欧文トークンで他方が和文トークンでも true になる場合がある)
  • \ifcat によるカテゴリーコードの比較では,欧文トークンなら catcode を読み出し,和文トークンなら kcatcode を読み出して比較する
  • \ifx では上記2点を同時に比較する

新設された欧文トークン kcatcode 14 の扱いについても,上の仕様範囲内に収まると理解しました。

ほかに気付いた点は

  • \Uchar でトークン生成する場合も \char のノード生成と同じ規則に統一してはどうか(つまり,文字コード 0x100〜0x2E7Fでも kcatcode 14 なら欧文トークンを生成)
  • \Ucharcat で 0x100〜0x2E7F の文字コードもカテゴリーコード 1--4, 6--8, 10--13 も許してはどうか(従来は 16--19 しか指定できなかった)

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 28, 2024

\ifcat はまともに動いていなかったらしく、 ec9887c でよくなったと思います。
新設された欧文トークン kcatcode 14 の扱いについても,上記の仕様範囲内に収まったと思います。
ただし、legacy latin と ucs latin の差が無さすぎて、それでいいのか少々心配です。

\Uchar, \Ucharcat26505ebcheck_echar_range() を見に行くようにしてみました。

\meaning はまともに動いていなかったらしく、 664e90c で修正してみました。
ただし、本来 legacy latin と ucs latin の差を把握して文字コードを切り替えたいところですが、その場の kcatcode=14 を見に行く方法になっています。
kcatcode=14 と kcatcode=15 をゴニョゴニョ切り替えて使っている場合は正しくない結果が出ると思います。
1b09af9 で修正したつもりがNGだったので戻しました。kcatcode=14 と kcatcode=15 を切り替えながら使うと正しくない可能性があります。

@t-tk
Copy link
Collaborator Author

t-tk commented Jun 29, 2024

\Uchar, \Ucharcat は大体まともに動くようになったと思います。 254f9cf

以下、多分こういう風になっているはず、の仕様案です。

% \Uchar <chr_code>
%  0--255:常に欧文文字トークン
%  256--0x2E7F:kcatcode=14のとき欧文文字トークン、それ以外内部コードで許される値のとき和文文字トークン
%  0x2E80以上の,内部コードで許される値:常に和文文字トークン
% \Ucharcat <chr_code> <catcode>
% <chr_code> in [0,128): 欧文文字トークンを生成.<catcode> in {1..4, 6..8, 10..13}
% <chr_code> in [128,256)
%    e-pTeX の場合:欧文文字トークンを生成.<catcode> in {1..4, 6..8, 10..13}
%    e-upTeX の場合:欧文/和文文字トークンを生成.<catcode> in {1..4, 6..8, 10..13, 16..20}
% <chr_code> in [256,0x2E80)
%    e-pTeX の場合:和文文字トークンを生成.  (??有効な内部コードが無い??)
%    e-upTeX の場合:欧文/和文文字トークンを生成.<catcode> in {1..4, 6..8, 10..13, 16..20}
% <chr_code> >=256: 和文文字トークンを生成.
%    e-pTeX の場合: <catcode> in {16..18}
%    e-upTeX の場合:<catcode> in {16..20}

@h20y6m
Copy link
Collaborator

h20y6m commented Jun 29, 2024

ec9887c 以降で LaTeX のフォーマット作成が通らなくなっています。

\if \relax \noexpand \UndefinedCS が false になってしまっているようです。
また 256 以降の欧文文字とプリミティブのコード?が衝突している気がします。

とりあえず以下のパッチで通るようになったきがしますが、max_latin_val でいいのか max__cjk_val にすべきかよくわかっていません。ほかにもまだ抜けているところがあるかもしれません。

diff --git a/source/texk/web2c/uptexdir/uptex-m.ch b/source/texk/web2c/uptexdir/uptex-m.ch
index 634c0fb4e..3970207c5 100644
--- a/source/texk/web2c/uptexdir/uptex-m.ch
+++ b/source/texk/web2c/uptexdir/uptex-m.ch
@@ -212,6 +212,14 @@ else if (kcode_pos=1)or((kcode_pos>=@'11)and(kcode_pos<=@'12))
 @d partoken_name=set_enable_cjk_token+1 {set |par_token| name}
 @z
 
+@x
+@d single_base=active_base+256 {equivalents of one-character control sequences}
+@d null_cs=single_base+256 {equivalent of \.{\\csname\\endcsname}}
+@y
+@d single_base=active_base+max_latin_val {equivalents of one-character control sequences}
+@d null_cs=single_base+max_latin_val {equivalent of \.{\\csname\\endcsname}}
+@z
+
 @x
 @d cat_code_base=auto_xspacing_code+1
   {table of 256 command codes (the ``catcodes'')}
@@ -333,6 +341,12 @@ primitive("kchar",kchar_num,0);@/
 @!@:kchar_}{\.{\\kchar} primitive@>
 @z
 
+@x
+primitive("relax",relax,256); {cf.\ |scan_file_name|}
+@y
+primitive("relax",relax,max_latin_val); {cf.\ |scan_file_name|}
+@z
+
 @x
 char_num: print_esc("char");
 @y
@@ -641,6 +655,12 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
     begin cur_cmd:=t div max_char_val; cur_chr:=t mod max_char_val;
 @z
 
+@x
+@d no_expand_flag=257 {this characterizes a special variant of |relax|}
+@y
+@d no_expand_flag=max_latin_val+1 {this characterizes a special variant of |relax|}
+@z
+
 @x get_token
   if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then {|wchar_token|}
     cur_tok:=cur_chr
@@ -656,6 +676,12 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
 
+@x
+  begin eq_define(cur_cs,relax,256); {N.B.: The |save_stack| might change}
+@y
+  begin eq_define(cur_cs,relax,max_latin_val); {N.B.: The |save_stack| might change}
+@z
+
 @x
   if check_kanji(info(p)) then {|wchar_token|}
     begin buffer[j]:=Hi(info(p)); buffer2[j]:=1; incr(j); buffer2[j]:=1;
@@ -1526,6 +1552,14 @@ adjust(char_base); adjust(width_base); adjust(lig_kern_base);
     dvi_out(BYTE3(jc)); dvi_out(BYTE4(jc));
 @z
 
+@x
+@d span_code=256 {distinct from any character}
+@d cr_code=257 {distinct from |span_code| and from any character}
+@y
+@d span_code=max_latin_val {distinct from any character}
+@d cr_code=max_latin_val+1 {distinct from |span_code| and from any character}
+@z
+
 @x
 hmode+kanji,hmode+kana,hmode+other_kchar: goto main_loop_j;
 hmode+char_given:

t-tk added a commit to texjporg/ptex-manual that referenced this issue Sep 22, 2024
Ref.
[upTeX] ofm読み込みと符号位置 256 以上の欧文文字トークン・ノード
texjporg/tex-jp-build#170
t-tk added a commit that referenced this issue Oct 20, 2024
t-tk added a commit that referenced this issue Oct 20, 2024
t-tk added a commit that referenced this issue Oct 20, 2024
@t-tk
Copy link
Collaborator Author

t-tk commented Oct 20, 2024

もうregressionの問題は発見できないレベルになり、CIのテストは充分に入れたと思うので
ptexenc 1.5.1/dev, upTeX version 2.00, eupTeX u2.00-241020 というバージョンにして
TeX Live svn にコミットしました。r72599 r72600 r72601 r72602 r72603
また、ここのmasterにマージしました。 2d900cb

とはいえ、upTeX ver0.0x の頃以来の大改造になるので、根拠のない不安は残っています。
心配なので upTeX 1.35 が作れるまま最新に追従するようなブランチを作ってしばらく残そうかとも考えています。
何か見つけたらお知らせください。

今後の構想。

  • uptex-base を upTeX u2.00 の内容に合わせて更新して CTANへ投稿する。 → 2024/12/28投稿済み
  • uptex-fonts に SVS を入れて、来春のコードフリーズ後に CTANへ投稿する。(主に u1.35対応)
  • ptex-manual を eupTeX u2.00-241020 の内容に合わせて更新して 来春のコードフリーズ後に CTANへ投稿する。
  • 宣伝。TeX forum へ投稿する。
  • Latin Modern の Unicodeエンコーディングの fd (できれば ofm, ovp, ovfも) を作成して配布する。

t-tk added a commit to t-tk/tex-jp-build that referenced this issue Oct 26, 2024
t-tk added a commit to t-tk/tex-jp-build that referenced this issue Oct 26, 2024
t-tk added a commit to t-tk/tex-jp-build that referenced this issue Oct 26, 2024
@t-tk
Copy link
Collaborator Author

t-tk commented Oct 26, 2024

master は eupTeX u2.00-241020 にしましたが、
regression testのために eupTeX u1.35-240930 が作れる状態にして uptex_ofm ブランチを当面の間続けようと思います。
masterの方で ptexenc, uptex, euptex を触るタイミングで同時に作業して、手間を掛けずに続けられる範囲でやります。

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 4, 2025

master (2863401) の euptex で以下のソースをタイプセットすると

\kcatcode"3B1=14
\catcode"3B1=1
\catcode"3B2=2
\catcode"3B3=3
\catcode"3B4=4
\catcode"3B5=6
\catcode"3B6=7
\catcode"3B7=8
\catcode"3B8=11
\catcode"3B9=12
\immediate\write16{\meaning α.}
\immediate\write16{\meaning β.}
\immediate\write16{\meaning γ.}
\immediate\write16{\meaning δ.}
\immediate\write16{\meaning ε.}
\immediate\write16{\meaning ζ.}
\immediate\write16{\meaning η.}
\immediate\write16{\meaning θ.}
\immediate\write16{\meaning ι.}
\end

以下のような不穏な出力になります。

begin-group character I can't write on file `.
end-group character '..
math shift character .tex.
alignment tab character ; default file extension is `.
macro parameter character Please type another .
superscript character *** (job aborted, file error in nonstop mode).
subscript character .dvi.
the letter file name for output.
the character texput.

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 4, 2025

ご指摘ありがとうございます。
U+100 で既に異常のようです。
おそらく原因は、欧文0xFF超えの拡張をomegaを参考にしながら行った際に、対応漏れがあったのだろうと思います。

\kcatcode"C1=14
\catcode"C1=1
\catcode"FF=1
\immediate\write16{\meaning Á.}
\immediate\write16{\meaning ÿ.}

\kcatcode"100=14
\catcode"100=1
\catcode"101=1
\catcode"102=1
\catcode"103=1
\catcode"104=1
\immediate\write16{\meaning Ā.}
\immediate\write16{\meaning ā.}
\immediate\write16{\meaning Ă.}
\immediate\write16{\meaning ă.}
\immediate\write16{\meaning Ą.}

\kcatcode"3B1=14
\catcode"3B1=1
%\catcode"3B2=2
%\catcode"3B3=3
%\catcode"3B4=4
%\catcode"3B5=6
%\catcode"3B6=7
%\catcode"3B7=8
%\catcode"3B8=11
%\catcode"3B9=12
\immediate\write16{\meaning α.}
%\immediate\write16{\meaning β.}
%\immediate\write16{\meaning γ.}
%\immediate\write16{\meaning δ.}
%\immediate\write16{\meaning ε.}
%\immediate\write16{\meaning ζ.}
%\immediate\write16{\meaning η.}
%\immediate\write16{\meaning θ.}
%\immediate\write16{\meaning ι.}
\end

logの一部 ::

entering extended mode
(./fuon01.tex(guessed encoding #3: UTF-8 = utf8)
begin-group character Á.
begin-group character ÿ.
begin-group character .6.
begin-group character .2.
begin-group character .00.
begin-group character buffer size.
begin-group character pool size.
begin-group character I can't write on file `.
 )

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 4, 2025

euptex-pool.c の poolfilearr を見てしまっているようです。

#define EXTERN extern
#include "euptexd.h"
#include <stdio.h>
#include <string.h>

static const char *poolfilearr[] = {
  ".6",
  ".2",
  ".00",
  "buffer size",
  "pool size",
  "number of strings",
  "" "?" "?" "?",
  "m2d5c2l5x2v5i",
  "End of file on the terminal!",

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 7, 2025

おそらく原因は、欧文0xFF超えの拡張をomegaを参考にしながら行った際に、対応漏れがあったのだろうと思います。

euptex-pool.c の poolfilearr を見てしまっているようです。

print_chr_cmdchr_cmdprint_ASCIIprint と呼び出されて文字コード256以上はstring poolの文字列が出力されているみたいです。

(string pool の先頭は一文字の文字列が入っていて "string number" と文字コードがイコールになっていて、その後に poolfilearr の文字列が入っているみたいです。poolfilearr の文字列が入るのは(eup)texでは256からですが、omegaでは(xetexでも?)65536?に拡張されているではないかと思います。)

多分xetexのBMP越えの文字への対策と同じようなことをeuptexでは文字コード256以上の文字にする必要があるんだと思います。

ちなみにxetex.webの chr_cmd は以下のように @"10000 以上の文字の対策があります。

@d chr_cmd(#)==begin print(#);
   if chr_code < @"10000 then print_ASCII(chr_code)
   else print_char(chr_code); {non-Plane 0 Unicodes can't be sent through |print_ASCII|}
  end

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 7, 2025

ありがとうございます。ご指摘の chr_cmd(#) に手を入れてみました。まだ少ししかテストしていません。8311ee1

@x
@d chr_cmd(#)==begin print(#); print_ASCII(chr_code);
  end
@y
@d chr_cmd(#)==begin print(#);
   if chr_code < @"100 then print_ASCII(chr_code)
   else print_kanji(chr_code);
  end
@z

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 8, 2025

カテゴリコード6のときがまだおかしいようです。

@<Display the token ...@>=mac_param, out_param, match のときの print も対処がいりそうです。
あと match_chrASCII_code から変更がいりそうです。

ただし、そもそも \meaning でカテゴリコード12になっているはずなのでここを通ること自体がおかしいです。
カテゴリコード6以外の文字の場合もどうもカテゴリコード12ではなく元のカテゴリコードに戻ってしまっているようです。
get_token, get_x_token, x_token などでカテゴリコードが再評価?されているような気がします。


ところで #170 (comment) の例にある

\catcode"3B2=2 % β
\immediate\write16{\meaning β.}

の部分は

\immediate\write16{\meaning }.}

と同じはずなのでエラーになるはずですよね?

U+100 以上の文字のカテゴリコードの扱いがいろいろ怪しい気がしています。

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 11, 2025

とりあえず、
@<Display the token ...@>=mac_param, out_param, match のときの print 対処、match_chrASCII_code から変更してみました。c42a7ba

下記のテストで euptex では
catcodeの動作そのものは、1,2,3,4,7,8,11,12は正しいように見えます。(しかし、11,12の違いは未テスト)
catcodeの動作は、6 が異常。
\meaning の挙動はかなり改善されました。しかし catcode 1,2,6 で異常のようです。
aleph では期待通り動きます。
どこが悪いのか見当がつきません。

%% (e)uptex or aleph

\ifx\kcatcode\undefined\else
% for (e)upTeX
  \kcatcode"C0=14  % Latin-1 Supplement
  \kcatcode"100=14 % Latin Extended-A
\fi
\ifx\ocp\undefined\else
% for aleph
  \ocp\ORGin=inutf8
  \InputTranslation currentfile \ORGin
\fi
\font\x=eu3-lmr10 \x

% Latin Extended-A
\catcode"100=4
\catcode"101=1
\catcode"102=2
\catcode"103=3
\catcode"104=4
\catcode"105=6
\catcode"106=7
\catcode"107=8
\catcode"108=11
\catcode"109=12
\immediate\write16{\meaning Ā.}% alignment tab character
%\immediate\write16{\meaning ā.}% begin-group character
%\immediate\write16{\meaning Ă.}% end-group character
\immediate\write16{\meaning ă.}% math shift character
\immediate\write16{\meaning Ą.}% alignment tab character
\immediate\write16{\meaning ą.}% macro parameter character
\immediate\write16{\meaning Ć.}% superscript character
\immediate\write16{\meaning ć.}% subscript character
\immediate\write16{\meaning Ĉ.}% the letter
\immediate\write16{\meaning ĉ.}% the characer


% catcode 1,2 : begin-group, end-group character
\catcode"F2=1
\catcode"F3=2
\catcode"102=1
\catcode"103=2
òabcó Ădefă {ghió òjkl} {mnoă Ăpqr}

% catcode 11,12 : the letter, the characer
\catcode"F2=11
\catcode"F3=12
\catcode"102=11
\catcode"103=12
òabcó Ădefă {ghió òjkl} {mnoă Ăpqr}

% catcode 3 : math shift character
\catcode"F4=3
\catcode"104=3
$E=mc^2$ $E=mc^2ô ĄE=mc^2$ ôE=mc^2Ą

% catcode 7,8 : superscript, subscript character
\catcode"FC=7
\catcode"FD=8
\catcode"10C=7
\catcode"10D=8
$a_nx^m$ $aýnxüm$ $ačnxČm$

% catcode 4 : alignment tab character
\catcode"F6=4
\catcode"106=4
\halign{# & # & # \cr
  aaa & bbb & ccc \cr
  ddd ö eee ö fff \cr
  ggg Ć hhh Ć iii \cr}

% catcode 6 : macro parameter character
\catcode"F5=6
\catcode"105=6
\def\oXzõ1{o{õ1}z}\relax
\oXz{r}
\def\oYzą1{o{ą1}z}\relax
\oYz{r}

\end

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 13, 2025

\meaning で一度 catcode=12 になった後、引数として読まれたとき?に戻ってしまっているようです。

\kcatcode"100=14
\catcode"100=3
\show $
% > math shift character $.
\show Ā
% > math shift character Ā.

% #1:math #2:shift #3:character 
\def\tmp#1 #2 #3 {\show}
\expandafter\tmp\meaning $
% > the character $.
\expandafter\tmp\meaning Ā
% > the character Ā.

% #1:math #2:shift #3:character #4
\def\tmp#1 #2 #3 #4{\show#4}
\expandafter\tmp\meaning $
% > the character $.
\expandafter\tmp\meaning Ā
% > math shift character Ā.

\def\tmp{\show}
\expandafter\tmp\string $
% > the character $.
\expandafter\tmp\string Ā
% > the character
% .

\def\tmp#1{\show#1}
\expandafter\tmp\string $
% > the character $.
\expandafter\tmp\string Ā
% > the character
% .

\meaning のほうは以下の部分を戻すととりあえず動いていそうです。

diff --git a/source/texk/web2c/uptexdir/uptex-m.ch b/source/texk/web2c/uptexdir/uptex-m.ch
index c43c96909..9852840a7 100644
--- a/source/texk/web2c/uptexdir/uptex-m.ch
+++ b/source/texk/web2c/uptexdir/uptex-m.ch
@@ -833,7 +833,7 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
@@ -874,7 +874,7 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
@@ -889,7 +889,7 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z

ただし、この部分を戻すと \csname 周りがおかしくなるようです。
とはいえ、ここはすでにcatcodeが確定したトークンが再度取得されるときにも通るところだと思うので、ここでcatcodeが再評価されるのはまずい気がします。

\string のほうは以下で KANJI(cx)=0 になっていて print_char が呼ばれているからのようですが、kcatcode=14 のときに KANJI(cx)<>0 が入っているべきなのかどうかがわかりません。
(なぜ cur_cmd+cur_chr でなく cx を使っているのか?)

uptexdir/ptex-base.ch(2798)                 | string_code:if cur_cs<>0 then sprint_cs(cur_cs)
uptexdir/ptex-base.ch(2799)                 |   else if KANJI(cx)=0 then print_char(cur_chr)
uptexdir/ptex-base.ch(2800)                 |   else print_kanji(cx);

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 13, 2025

ただし、この部分を戻すと \csname 周りがおかしくなるようです。

以下ならよさそう?

diff --git a/source/texk/web2c/uptexdir/uptex-m.ch b/source/texk/web2c/uptexdir/uptex-m.ch
index c43c96909..a0bd9d227 100644
--- a/source/texk/web2c/uptexdir/uptex-m.ch
+++ b/source/texk/web2c/uptexdir/uptex-m.ch
@@ -833,8 +833,10 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
+  else if check_echar_range(cur_chr)=1 then
+      cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
 
@@ -874,8 +876,10 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
+  else if check_echar_range(cur_chr)=1 then
+      cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
 
@@ -889,8 +893,10 @@ if cat=other_kchar then k:=k-multilenbuffchar(cur_chr)+1; {now |k| points to fir
       cur_tok:=(kanji_ivs*max_cjk_val)+cur_chr
     else
       cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
-  else if (cur_cmd=latin_ucs)or(check_echar_range(cur_chr)=1) then
+  else if cur_cmd=latin_ucs then
       cur_tok:=(cat_code(cur_chr)*max_cjk_val)+cur_chr
+  else if check_echar_range(cur_chr)=1 then
+      cur_tok:=(cur_cmd*max_cjk_val)+cur_chr
   else cur_tok:=(cur_cmd*max_char_val)+cur_chr
 @z
 

@h20y6m
Copy link
Collaborator

h20y6m commented Jan 13, 2025

【メモ】マクロの match トークンは match_token(=@"D0000)+cur_chr

tex.web(9357)                               | @ @<If the next character is a parameter number...@>=
tex.web(9358)                               | begin s:=match_token+cur_chr; get_token;

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 15, 2025

fbae6ab はご提案のものと同等。
7512e89#170 (comment) のテストを make check で走るようにしてみたものですが、数式フォントの設定が足りず一部コメントアウトしています。テストの最後、catcode 6 : macro parameter character のところが相変わらず動かない状態ですが、テストは走らないようにしています。
同じテストが aleph では予定通り走ります。

match_token(=@"D0000) を何とかすればよくなるのか、文字コードのコンフリクトをかわす手が何かあれば改善するのか、よく分かっていません。

@t-tk
Copy link
Collaborator Author

t-tk commented Jan 16, 2025

あまりよく分かっていませんが、
tex.web の
@d end_match=14 {end of parameters to macro}
と uptex-m.ch の
@d latin_ucs=14 {is not cjk characters in ucs code}
がコンフリクトしているのが悪いのかもしれません。
基本設計がよろしくなくて回避が難しい問題なのかもしれません。
そうだとすると、これはknown issueの制限事項としてあきらめるか?

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

No branches or pull requests

4 participants