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

禁則テーブル,\inhibitxspcode 情報テーブルからのエントリ削除 #26

Merged
merged 4 commits into from
Sep 18, 2017

Conversation

h-kitagawa
Copy link
Member

pTeX では \prebreakpenalty, \postbreakpenalty の情報を禁則テーブルに,また \inhibitxspcode の情報を専用テーブルに格納していますが,これらはどちらも 256 文字の領域しかありません.

実用上は困らないと思いますが,「一旦テーブルに追加されるとそこから削除されることはない」という仕様が気になったので,デフォルト値(禁則ペナルティの場合は 0,\inhibitxspcode の場合は 3)を設定した場合には該当するテーブルからエントリを削除するようにしてみました.

なお,ptex-manual のコミット texjporg/ptex-manual@8f8c0ab では,本プルリクの内容も含めた記述になっています.

@aminophen
Copy link
Member

一旦テーブルに追加されるとそこから削除されることはない

なんか「私が読んだことのある pTeX の仕様」と違うな,と思ったので探すと,jtex.pdf 2.4.2 節に

この禁則テーブルからの登録の削除は、ペナルティ値 ‘0’ を設定することによって行わ れるが、グローバルレベルでの設定でなければ、このテーブルの領域は解放されないこ とに注意して欲しい。なぜなら、ローカルレベルで領域を解放してしまえば、その外側 のレベルに戻ったときに、そのレベルでの値を最設定するための領域が確保されている 保証がないからである。

とあるので,禁則ペナルティについては少なくとも,グローバルに 0 を設定すれば解放されるのが意図した挙動であり,そうでないとすると一種のバグになるのだと思います。

@h-kitagawa
Copy link
Member Author

禁則ペナルティについては少なくとも,グローバルに 0 を設定すれば解放されるのが意図した挙動

(ローカルに削除されることについては私もまだ不安ですが)少なくとも現状ではグローバルな代入でも削除されないようです.

%#!uptex
\newcount\hoge\hoge="3000
\loop\ifnum\hoge<"3090
  \message{\the\hoge}\prebreakpenalty\hoge=256
  \advance\hoge 1\relax \repeat

\global\prebreakpenalty"3001=0
\global\prebreakpenalty"4000=0
\end

もし「グローバルに 0 を設定すれば解放される」のであれば,\global\prebreakpenalty"3001=0 で "3001 のエントリは削除されるので,その後の \global\prebreakpenalty"4000=0 はエラーなく実行できるはずです.しかし,手元の upTeX では ! KINSOKU table is full!!. エラーが出ました.

@h-kitagawa
Copy link
Member Author

その外側 のレベルに戻ったときに、そのレベルでの値を最設定するための領域が確保されている保証がない

読み直して納得.ローカルに文字 A の情報を削除→その場所にグローバルに文字 B の設定,のとき,外側のグループに抜けたときに文字 A の情報が B の情報に置き換わってしまうのですね.

エントリ削除 (禁則だと define(kinsoku_base,0,0)\inhibitxspcode だと n:=0; cur_val:=0)の処理をするかどうか判定する if 文に,global フラグをつければグローバルだけに出来ます.
ただ,個人的には「ローカル代入でも,それが最も外側のグループで行われていれば,global と同じ扱い」としたいです.

@h-kitagawa
Copy link
Member Author

その外側 のレベルに戻ったときに、そのレベルでの値を最設定するための領域が確保されている保証がない

0640453 で,エントリを削除するのはグローバルな代入 or 現在のグループレベル (\currentgrouplevel in e-TeX) が 0 のときとしました.

@aminophen
Copy link
Member

aminophen commented Sep 11, 2017

個人的には「ローカル代入でも,それが最も外側のグループで行われていれば,global と同じ扱い」

私もこれと同じ意見でした。 0640453 を確認してみましたが,大丈夫そうです。

@aminophen
Copy link
Member

aminophen commented Sep 12, 2017

#11luatexja#37465 に関連して,前禁則ペナルティの合算処理の部分を

元々のペナルティが有限の場合だけ,禁則ペナルティを加味する

ようにしてみました (257ea02 683c728) 。WEB ソースを弄ったのは一昨日の #24 が初めてですが,ltj-jfmglue.lua のコードをそのまま持ってきた“つもり”です。

@aminophen
Copy link
Member

aminophen commented Sep 12, 2017

あと思ったのですが, #26 を採用した場合

禁則用ペナルティに 0 が設定されていた場合,未設定であるかのように振る舞う

はそもそも設定されていないので,先日 07e48d0 で追加された if kinsoku_penalty(kp)<>0 then コードはなくてもよいことになるのでしょうか?

→ おっと,ローカルに 0 が設定されて解放されない場合もあるのでしたね。

@h-kitagawa
Copy link
Member Author

前禁則ペナルティの合算処理

ありがとうございます.ただ,

\prebreakpenalty`い=-10000
\postbreakpenalty`あ=10000
あ\penalty5000 い

を入力すると,pTeX では

\hbox(7.77588+1.38855)x19.24432, yoko direction
.\tenmin あ
.\penalty 10000(for kinsoku)
.\penalty -10000
.\glue(\kanjiskip) 0.0 plus 0.4 minus 0.4
.\tenmin い

となり,結局「あい」間のペナルティは -10000 であるのと変わらない状況になります.これは意図した挙動でしょうか?

なお,LuaTeX-ja で同等の入力を走らせると,「5000 に (-10000+10000) = 0 を足す」計算になり,

.\norule(8.4675+1.15466)x0.0
.\tenmin あ
.\penalty 5000
.\glue 0.0 plus 0.4 minus 0.4
.\norule(8.4675+1.15466)x0.0
.\tenmin い

となります(\norule は寸法補正用に LuaTeX-ja が自動で入れるノード).

@aminophen
Copy link
Member

コードを綺麗にしていただいてありがとうございます。

\prebreakpenalty や \postbreakpenalty を負に設定する例を実用で見たことがないので,考慮していませんでした。LuaTeX-ja のような「負の無限大と正の無限大を足す」という計算は妥当かどうかを含め,どうあるのが自然なのかすぐには思いつきません。

@aminophen aminophen merged commit 0640453 into master Sep 18, 2017
@aminophen
Copy link
Member

とりあえず

グローバルな代入 or 現在のグループレベル (\currentgrouplevel in e-TeX) が 0 のとき
デフォルト値(禁則ペナルティの場合は 0,\inhibitxspcode の場合は 3)を設定した場合には該当するテーブルからエントリを削除する

を merge して TeX Live svn に commit しました (r45331) 。合算の話は別ブランチにしてありますので,別のプルリクエストに分けます。

(あと #25\hbox{・} もまだだったので r45329 で commit しておきました)

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

Successfully merging this pull request may close these issues.

2 participants