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 · 42 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 は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
Copy link
Collaborator Author

t-tk commented Aug 10, 2024

omlgc.ofm を読むと落ちる件は 653ba97 で直ったと思います。
character infoの読み込みが出鱈目でした。

latin modernのうち ec-lmr10.tfm をもとに、Unicodeに並べ替えた eu3-lmr10.ovp, eu3-lmr10.ofm, eu3-lmr10.ovf を作成しテストしています。
今回の改造の意図通りの動作が出来ており、不審な動作は無くなってきたと思っています。
テストは 01e852e にも入れています。

今の考えでは uptex version 2.00 として TeX Live 2025 に入れたいと思っています。
ただし、今回の大改造は一般のユーザーが普段使っている欧文8bit tfmも同じルーチンを通るなど、今回の拡張を使わなくても思わぬ影響が出ないとも限らないため、リグレッションテストは慎重に行いたいと思います。

ofm level 1 は、今の uptex-m.ch には断片的に入っていますがメモリー管理がよく分かっておらず危険なので、TeX Live 2025向けには入れず、一旦削除するつもりです。

@t-tk
Copy link
Collaborator Author

t-tk commented Aug 18, 2024

当初から予定だが気になっていた↓ですが、dvips b0db37c と dvipdfmx 6d5e8c3 で予定通り動いていることが確認できました。なので、このまま進めます。

  • 0x2E80以上の Unicode文字は、upTeXでは欧文扱いしない。
    dviware側で必要な場合はvirtual fontで何とかする。

ff, fi, fl, ffi, fflなどのリガチャはuptexの組版では0x1B..0x1F あたりを使い vf の指している先の文字コードが U+FB00..FB04 になっている状況で、Unicodeフォントの文字コード U+FB00..FB04 (ff, fi, fl, ffi, ffl) で出力できます。
dviwareで使う ofm は文字コード 0xFFFF まで使用可能ですし、Level=1も使用可能です。
これらは、omega対応で以前からサポートされている機能でして、今回の拡張ではありません。

ただし、和文vf の fallback を dviware で #99 で和文扱いしていた ofm の条件判定が緩すぎて、欧文扱いしてほしい ofm も和文判定されてしまう虞があるので和文判定の条件を厳しくしました。→ 19f63e6, b910da8

t-tk added a commit that referenced this issue Aug 25, 2024
t-tk added a commit that referenced this issue Aug 25, 2024
t-tk added a commit that referenced this issue Aug 31, 2024
@t-tk
Copy link
Collaborator Author

t-tk commented Aug 31, 2024

kcatcode=14のもとで \font in LGR\hogefont-lgr のような欧文8bit tfmへの「エンジン内部で文字コード変換」機能のテストファイルを
texjporg/uptex-base@308c42d
に置きました。
ほぼ大体ちゃんと動いているものの、予想通りフォントによって用意されているグリフの集合が異なったり、リガチャの有無が微妙に違ったりしています。特に LGR でそれが目立ちます。
そのため、全てのケースで隅々まで変換が上手くいくようにするのは困難です。
なので、気になる場合は ofm を用意してください、という方針です。

@t-tk
Copy link
Collaborator Author

t-tk commented Sep 22, 2024

#170 (comment)

今の考えでは uptex version 2.00 として TeX Live 2025 に入れたいと思っています。
ただし、今回の大改造は一般のユーザーが普段使っている欧文8bit tfmも同じルーチンを通るなど、今回の拡張を使わなくても思わぬ影響が出ないとも限らないため、リグレッションテストは慎重に行いたいと思います。

と言っていましたが、
texlive の source/texk/web2c/ptexdir/tests/*.tex にある目ぼしいテストファイルを make check や CI で走るようにしました。→ 2c50ba5
限られたフォントで動かすためにフォントの設定などを少々変更していますが、kcatcode=14やofm対応の有無にかかわらず、問題なく動いていることが確認できました。
( 見つけたkinsoku table初期化のバグは修正しました )

その他、本パッチの有無でplatexを走らせて比較し、
ptex-manual.tex (日本語、39ページ), eptexdoc.tex (日本語、25ページ)、ptex-guide-en.tex (英語、25ページ) をコンパイルしてみて出力の dvi に本質的な差分がない (コンパイル時刻の差などのみ) であることを確認しました。

現時点で、リグレッションは見つからず、もし有ったとしても発見しづらいレベルになっていると思います。
今の仕様で TeX Live 2025 に入れるつもりです。
ソースコードの更新はここまでにして、次はマニュアル類の編集に手を付けようと思います。

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へ投稿する。
  • 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 を触るタイミングで同時に作業して、手間を掛けずに続けられる範囲でやります。

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