eptex (100201) | 2010-02-01 07:10 |
eptex-test (110315) | 2011-03-15 08:56 |
ptex-qtrip (110227) | 2011-02-27 22:32 |
日本語ファイル名でエラー | 2018-05-20 23:30 |
日本語のファイル名でエラーが起こることがあります。 ptex2pdf -l -ot "-synctex=1 -file-line-error" 名称未設... | (无) |
\pdfsavepos と \mag | 2016-12-20 02:32 |
TeX & LaTeX Advent Calendar 2016 の VoD氏の記事に詳細が報告されていますように,\mag が用いられたときの \pdfsavep... | (无) |
TeX Live 2020 には pTeX p3.8.3 と e-pTeX 191112 が収録されています. 本ページでは昨年の TeX Live 2019 (pTeX p3.8.2, e-pTeX 190131) からの変更点についてざっと説明します.
なお,TeX Live 2019 の (e-)(u)pTeX は 2019-05-30 (r51236) でリビルドが行われました(Acetaminophen さんのブログ記事でもこの件が触れられています). このリビルドですでに取り込まれた修正については見出しに【R】マークをつけています.
欧文文字トークンと異なり,和文文字トークンについては一般に
という挙動になっています.
しかし,TeX Live 2019 当初の pTeX では
というソースから X が出力されていました.これは和文文字トークンを \let した際に和文カテゴリーコードが保存されるため,(1) の \ifcat では次が比較されたことによるものです:
TeX Live 2019 では 2019-05-30 のリビルド後の pTeX p3.8.2,及び TeX Live 2020 の pTeX p3.8.3 では,
という挙動で統一させるため,\if, \ifcat の修正を行いました.これによって,pTeX p3.8.3 では,上記ソースの (1) の \ifcat では
と,「和文カテゴリーコード 17 の『あ』」同士が比較され,結果は O となります.
TeX では \if(文字コードの比較)や \ifcat(カテゴリーコードの比較)において,制御綴を
として扱っています.pTeX ではこれで問題ないのですが,upTeX 1.24 では
が存在するため,これと \relax が \if で等価と判定されてしまいました.
以上の症状の改善のため,upTeX 1.25(TeX Live 2019 では 2019-05-30 のリビルド以降)では制御綴を
として扱うことにしました.これに合わせ,pTeX p3.8.3 では「制御綴の文字コード」を 65536 と扱うようにしていますが,これに伴う pTeX の挙動の変化は起こらないはずです.
TeX でときどき使われる整数の使い方として,` の後に文字トークンを直接続けるか,` の後に欧文1文字の制御綴(\C, \% など)を続けるというものがあります.
昔の pTeX では ` の後に続けられるものの判定が甘く,`\AA がなぜか通ってしまうという症状がありました.2012 年に上の「前段階」で判定を厳しくしたのですが,まだその判定は不完全であったことが 2019 年 7 月にわかりました. 具体的には,TeX Live 2019 の pTeX では,下のソースの「和文文字トークンを \let した」制御綴 \EE に対して,その内部コードが `\EE として得られてしまいます.
pTeX 3.8.3 では,` の後に続けられるものの判定を更に厳しくし,文字トークンか欧文1文字の制御綴しか許容しないようにしました.
現行(TeX Live 2019 以前も,2020 も)の pTeX では,例えば
のように,ß (U+00DF, C3 9F in UTF-8) を出力すると,
のように出力されます. この出力自体に不思議な点はある(tex-jp-build/81)のですが,TeX Live 2019 以前の ptexenc で問題なのは,z.out を \input すると,結果が
のように,単独バイト <C3> が化けてしまうことにありました.
これは,
ということによるものでした.TeX Live 2020 の ptexenc では,不正な UTF-8 シーケンスは(JIS X 0208 範囲外の Unicode 文字と同じく) ^^ 記法に直して pTeX に渡すようにしています.
報告元から引用しますが,次のソースが高確率で free(): double free detected などのエラーで落ちるというものです.
\endlinechar=128 \immediate\openout10=xout.tex \immediate\closeout10 \end
このエラーは,ファイル名を UTF-8 から pTeX の内部エンコーディングに変換する ptexenc の ptenc_from_utf8_string_to_internal_enc 関数中のミスが原因でした.結果を格納する buffer = buf という 2 配列は,長さが足りなくなりそうなときに xrealloc で長さを増やして再確保されますが,そのとき buffer のみが再確保されてしまう(buf は古いアドレスのまま残る)コードになっていました. TeX Live にはすぐ上の修正と同時に取り込まれました.
\kansujichar は代入できるのになぜか取得できないようになっていたのですが,pTeX p3.8.3 では取得が可能になりました. \count123=\kansujichar45 のような不正な引数については,\kansujichar を無視した \count123=45 と同義になります. これは \kansujichar の代入時の挙動に合わせたもので,TeX82 の他の命令とは少々異なります(「I changed this one to zero.」と引数を 0 と扱って進むのが一般的なようです).
元々 LaTeX のフォーマットファイルは 4 MB 強程度の容量があったのですが,LaTeX 2020-02-02 で expl3 がプリロードされることになったことに伴い,latex フォーマット (pdfTeX) は 8.3 MB,platex フォーマット (e-pTeX) は 10.6 MB と大幅に増大してしまいました*2.
この容量増加を少しでも食い止めるために,TeX Live 2020 では (e-)(u)pTeX, pdfTeX (, e-TeX) でフォーマットファイルを zlib によって圧縮するようにしています.zlib フォーマット圧縮自体は XeTeX, LuaTeX が以前から取り入れており,今回はその処理を上に挙げたエンジンにも適用するように拡張したというわけです.これにより,例えば platex フォーマット (e-pTeX) は 2.4 MB と 1/4 にまで抑えることができました.
なお,zlib を使う理由は「既に TeX Live に含まれているから」です(pTeX 系列にも,zlib は SyncTeX のため既にリンクされています).個人的には,SSD での使用を考慮し,展開スピードが速い lz4(圧縮は lz4hc)の方が向いていると思いますが,TeX Live 上流ではわざわざライブラリを増やすことのデメリットの方が大きいようです.
発端となった jsclasses/53 は,LaTeX の \do@subst@correction が和文に対応していない関係で,「和文フォントを選択する」制御綴が「欧文フォントを選択する」ものに置き換わってしまうという症状です.この症状への対応の議論の過程で,\font, \jfont, \tfont による「フォントを選択する」制御綴(fontdef トークン)が,和文・横組用和文・縦組用和文のどのフォントを選択するのか容易にはわからないということが話題に挙がりました.例えば \meaning\tenmin と \meaning を使っても 「select font min10」と TFM 名が返されるだけですし,e-TeX 拡張の \iffontchar は欧文フォントに対して文字コード 0--255 しか許容しないようになった(本ページ内の対応箇所)ので使えません.
そこで,fontdef トークンの選択するフォントが横組用和文フォントか否か・縦組用和文か否かを判定する \ifjfont, \iftfont プリミティブがあると便利そうだ,となり実装されたというわけです.実際,以下のソースできちんと判定できていることがわかります.
- %#!ptex
- \font\tenrm=cmr10 % 欧文フォント
- \jfont\tenmin=min10 % 和文横組用
- \tfont\tentmin=tmin10 % 和文縦組用
- \def\FX#1{%
- <\meaning#1: %
- \ifjfont#1JY\else\iftfont#1JT\else AL\fi\fi>%
- }
- \message{\FX\tenrm} % ==> <select font cmr10: AL>
- \message{\FX\tenmin} % ==> <select font min10: JY>
- \message{\FX\tentmin}% ==> <select font tmin10: JT>
- \bye
ちなみに,2020-02-09 現在検討中の実装 では e-TeX 拡張を使う代わりに \ifjfont, \iftfont プリミティブを使わない方針になっています.
従来,\input プリミティブでファイル名として許される文字は
でした.Web2C ではこれに加え
という仕様が加わりました.これによって,例えば
は両者とも 「h o g e.tex a」というファイルを読み込むようになっています*3.
一方,LuaTeX では \input プリミティブの段階でブレースで囲まれたファイル名指定が可能になっています.この場合,ブレースで囲まれた引数の中の「"」はファイル名の一部となります.
今回の TeX Live 2020 における変更は,LuaTeX 以外のエンジンでも上記のような \input プリミティブでブレースで囲まれたファイル名指定を利用可能にするものです.
一方,LaTeX では ltfiles.dtx において,次のように \input が再定義され,マクロレベルでブレースで囲まれたファイル名指定を利用可能にしています.
ブレース内にファイル名を指定した場合の詳細については,ltfiles.dtx の「Safe Input Macros」節を参照して下さい.
- \ifx\@@input\@undefined\let\@@input\input\fi
- ...
- \def\input{\@ifnextchar\bgroup\@iinput\@@input}
- \def\@iinput#1{%
- \InputIfFileExists{#1}{}%
- {\filename@parse\@curr@file
- \edef\reserved@a{\noexpand\@missingfileerror
- {\filename@area\filename@base}%
- {\ifx\filename@ext\relax tex\else\filename@ext\fi}}%
- \reserved@a}}
なお,上記の定義からわかるとおり LaTeX でも
とブレースで囲まずファイル名を指定した場合はプリミティブの \input が呼び出されます.
プリミティブとしての \input と LaTeX で再定義された \input の違いとして目につくのは存在しないファイル名を指定したときの状況です.例えば次の入力を考えます.
\csname...\endcsname の中で判定が実行されれば真,そうでなければ偽となる条件文です.以下が実行例となります.
元々は pdfTeX に実装されたものであり,XeTeX, LuaTeX にも実装されていましたが,e-pTeX だけ未実装でした(e-pTeX 190709 で実装).
\ifincsname を e-pTeX に実装することになったのは,LaTeX 2019-10-01 における Unicode 対応改善(ラベル中に Unicode 文字を扱えるように)の開発版コードで \ifincsname が使われたためです.\expanded プリミティブ(e-pTeX には TeX Live 2019 で追加)と同様に,LaTeX team によるリクエストと言っても良いでしょう.
TeX Live 2019 の e-pTeX では,\iffontchar, \fontchar?? (??: wd, ht, dp, ic) について ptex-manual/3 の親記事にかかれていたように不統一でした.
e-pTeX 190709 では,次のように挙動が拡張・統一されました.なお \iffontchar, \fontchar?? は,いずれも \iffontchar\tenmin`あ のように対象となるフォント ⟨font⟩ と整数 ⟨number⟩ をとります.
e-TeX の拡張プリミティブ \readline の和文対応処理が抜けていたことが判明したので,e-pTeX 190908 で修正されました. それより前の e-pTeX では,次のソースで 2 つめの \Y の実行結果が [漢字‚] ではなく [ťÁżú‚] に化けてしまいます.
pTeX には
というプリミティブが,また upTeX には
というプリミティブがあります.
前者 2 つの状態は \showmode プリミティブを使えば
> auto spacing mode; > auto xspacing mode.のように端末やログに出力されますが,\show などと同様にタイプセットが一旦停止してしまいます. また,最後の \(enable|disable|force)cjktoken の状態を返すプリミティブはありませんでした.
e-TeX には \currentgrouplevel などの「現在の状態」を取得して内部整数を返すプリミティブがあります. これらとの類似で, e-pTeX 191112 には
が追加されました.(2020-12-19 誤記修正)
XeTeX, LuaTeX ある同名のプリミティブが由来です,大雑把な使い方は
というもので,\edef 内などの展開限定文脈で文字コードから文字トークンを作り出すために利用できます(通常の \char は展開可能ではないので,この目的には使えません).
正確に述べると,次のようになります.
なお,欧文文字,つまり文字コードが 0--255 に限られる場合は,同様のことはマクロで行なえます(上に挙げた ZR さんの Twitter,StackExchange の記事中のコメントを参照). TeX Live 2020,およびそれ以前の pTeX 系列ではこれをトリッキーに使うことにより「和文版 \Uchar」を実装することができます:
- %#!eptex
- \input expl3-generic % for \char_generate:nn
- \ExplSyntaxOn
- \cs_generate_variant:Nn \cs_to_str:N { c }
- \cs_new:Npn \tkchar #1 {
- \cs_to_str:c {
- \char_generate:nn % upper byte
- { \int_div_truncate:nn { #1 } { 256 } }
- { 12 }
- \char_generate:nn % lower byte
- { \int_mod:nn { #1 } { 256 } } { 12 }
- }
- }
- \ExplSyntaxOff
- \edef\A{\tkchar{`漢}\tkchar{`字}}
- \message{\meaning\A}% ==> macro:->漢字
- \bye
しかし,将来このトリッキーな使い方が封じられる可能性 があるため,そうなる前に e-pTeX で \Uchar, \Ucharcat が実装されたことになります.