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

otfパッケージ付属のTFMを使用すると約物周りの組み方が変になる #15

Closed
yudai-nkt opened this issue Dec 15, 2017 · 24 comments

Comments

@yudai-nkt
Copy link
Contributor

以下のソースをpLaTeXでタイプセットすると和文約物とラテン文字の間に不自然なアキが入りますが,これはJLREQ 3.2.6

句点類(cl-06),読点類(cl-07)若しくは終わり括弧類(cl-02)の前,又は始め括弧類(cl-01)の後ろに欧字・アラビア数字がくる場合は,その字間はベタ組とする.

に準拠していないように見受けられます.jartcile, jsarticle, bxjsarticle の3クラスではベタ組になりました.

\documentclass[article]{jlreq}
\usepackage{otf}
\begin{document}
(f,o.o】
\end{document}

mwe_white

jlreqクラスとotfパッケージのどちらに原因があるのかはよく分からないのですが,欧文のarticleクラスを用いてもベタ組になったのでotf パッケージが和文用文書クラスとして jlreqを考慮し損ねているということでもなさそうです.ただ,バンドルされていないTFMを使っている以上はサポートの対象外でしょうか?

@yudai-nkt
Copy link
Contributor Author

説明不足だったので追記しますと,noreplaceオプションを付けてotfパッケージを読み込めばこの問題は解消します.ただ厄介なことにnoreplacebold, expert, deluxeの各オプションと排反なため,jlreqクラスで縦組専用仮名を使いたい場合や多書体化させたい場合にnoreplaceオプションが指定できなくなり,結果としてアキが入ったままになります(私個人としてはどちらも不要ではありますが).

@aminophen
Copy link

アキの原因は \xkanjiskip 挿入によるようです。pLaTeX などのデフォルトは

\inhibitxspcode`(=2

なのですが,jlreq クラスでは(otf パッケージに関係なく)これが 1 になっているような気がします。試しに 2 に戻してみると, の右側は正常になります。おそらく諸々の禁則設定が逆なのではないでしょうか。

\documentclass{jlreq}
\usepackage{otf}
\begin{document}

\the\inhibitxspcode`(

(f,o.o】\par

\inhibitxspcode`(=2

\the\inhibitxspcode`(

(f,o.o】\par

\end{document}

@yudai-nkt
Copy link
Contributor Author

私の手元では,

  1. \xkanjiskip = 5zw\relaxなどとしても出力が変わらない
  2. noreplaceオプションで直った

ことからTFM由来のグルーなのかなと思っていましたが,たしかに示していただいたコードで正常になりますね.1の方についてはプリアンブルではなくて本文中で変更したらなぜか効くようになりました(こんな仕組みでしたっけ?).

ただ,禁則設定の間違いに起因するのならばnoreplaceオプションを指定するだけで直るのも不可解に感じます.

@aminophen
Copy link

aminophen commented Dec 15, 2017

1の方についてはプリアンブルではなくて本文中で変更したらなぜか効くようになりました(こんな仕組みでしたっけ?).

otf パッケージが,\AtBeginDocument で \xkanjiskip を変更する仕様ためのようです。以下のコードを実行してみたり,そのうち \usepackage{otf} を消してみたりするとわかります。

\documentclass{jlreq}
\usepackage{otf}
\showthe\xkanjiskip
\begin{document}
\showthe\xkanjiskip

禁則設定の間違いに起因するのならばnoreplaceオプションを指定するだけで直るのも不可解に感じます.

こちらはまだ私も理由の説明ができる状態ではありません。

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

\xkanjiskip = 5zw\relaxなどとしても出力が変わらない

とりあえずこの点だけですが,jlreq内でフォントサイズの変更がおこなわれるたびに\xkanjiskipを設定しなおす処理をしています.おそらくどっかで\normalsizeとか実行されて,その際に元々の設定に戻ったのだと思います.

\inhibitxspcodeの件,後で確認します.

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

あれotfも何かしているのか.

@yudai-nkt
Copy link
Contributor Author

yudai-nkt commented Dec 15, 2017

otfパッケージなしでも2.5pt plus 2.5pt minus 1.25ptと出るので,その場合は

jlreq内でフォントサイズの変更がおこなわれるたびに\xkanjiskipを設定しなおす処理をしています.

というのが原因のようです.otfが本文開始時に\xkanjiskipを弄るのも覚えておきます.

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

(関係ない方だけ答えていますが)再設定するxkanjiskipは\jlreq@xkanjiskipというマクロに入っているので,これを再定義することで一応変更が可能です.

@aminophen
Copy link

otf パッケージが,\AtBeginDocument で \xkanjiskip を変更する

は間違いでしたね。abenori さんがおっしゃる通りです。

先ほどの例示ソースで 2 回目の \showthe が otf の有無によって変わるのは,「\document の中にある \normalsize 実行中に \xkanjiskip=\jlreq@xkanjiskip が実行される。その時点では otf パッケージのメトリックが有効だと \zw の値が標準とは変化している」ということでした。

本題の方の「なぜ \inhibitxspcode`(=1 というおそらく間違いの設定なのに noreplace で治るのか」ですが,これは「jlreq.tfm などの JFM の作り方が良いから」のようです。jlreq.tfm を pTFtoPL でデコンパイルして PL source を作ってみると

(GLUEKERN
… 中略 …
   (LABEL O 1)
   (GLUE O 0 R 0.0 R 0.0 R 0.0)

が入っていることがわかります。つまり「開き括弧類(jlreq.tfm において TYPE 1 へ分類される文字)の右側に欧文文字 (未分類すなわち TYPE 0 の文字)が来た場合,ゼロ幅の JFM グルーが挿入される」という設定です。pTeX の仕様として,「メトリックグルーが(たとえゼロでも)挿入される箇所では \kanjiskip や \xkanjiskip の自動挿入処理は行わない」というものがあるので,\inhibitxspcode がどうなっていようとそこには pTeX 由来の \xkanjiskip グルーが挿入されないようになっています。otf パッケージの JFM はこのような「ゼロのグルー挿入」を行っていないので,崩れたと言えるでしょう。(正しい設定のもとでは起こりえないので,otf パッケージの問題とまでは言えないと思いますし,JIS メトリックなど他のほとんどの JFM も otf パッケージと同じ状態です。)

@aminophen
Copy link

luatexja-ja.pdf によると,jaxspmode パラメタについて

このパラメータはpTEX の\inhibitxspcode プリミティブと似ているが,互換性はない.

とありました。1 と 2 が逆のような振る舞いをするようですから,現状の実装の \jlreq@setjaxspmode のようにまとめてしまうと,片方が合って片方が間違ったことになる…ということみたいです。

@yudai-nkt
Copy link
Contributor Author

詳細な調査ありがとうございます.じつのところTFMの具体的な中身をまったく知らないのですが何が起きているのかは把握できましたし,教えていただいたことに基づいてminijsパッケージを読み込んでみたら予想どおり\xkanjiskipが入りました.

LuaTeX-jaのjaxspmodeがpTeXの\inhibitxspcodeと互換でない件は

jlreq/jlreq.cls

Lines 865 to 866 in b7dba14

{preonly}{\inhibitxspcode`#1=1}
{postonly}{\inhibitxspcode`#1=2}
の対応を入れ替えれば\jlreq@setjaxspmodeで統一的に扱えそうです.

@aminophen
Copy link

対応を入れ替えれば \jlreq@setjaxspmode で統一的に扱えそうです.

そうですね。ついでにそのあとの {\inhibitxspcode`#1=#2} も潰して(つまり数字を受け付けないようにして)おかないと,今後の jlreq.cls の実装次第ではまた同じことが起きるかも,という気がします。

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

\jlreq@setjaxspmodeの件は単純に間違いです…….

JFMの方ですが,ある(JLReqの意味での)文字クラスXに対して,前X後ろ19の空きと,前X後ろ27の空き(19は漢字,27は欧文用文字です)が完全に一致する場合には,JRM内でglueを定義しています.そうでない場合には,\kanjiskip\xkanjiskipに頼る……ということにしていた気がします.もちろんXが後ろの場合も同様です.

inhibitxspcodeに関しては,X=1の場合には\kanjiskip\xkanjiskipに頼る必要はありません.従って,そもそもinhibitxspcode等を変更する必要も無いので,「余計なことはしない」という態度をとるならばそもそもコードを消した方がよさそうです.

という風に思ってJFM自身などを見直してみるといろいろと変です…….直します.

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

おそらく諸々の禁則設定が逆なのではないでしょうか。

禁則は関係ないと思うのですが,間違いですか?

@abenori
Copy link
Owner

abenori commented Dec 15, 2017

ただ,バンドルされていないTFMを使っている以上はサポートの対象外でしょうか?

これは厳密に言うと「はい」になります.JLReqの表を実現していないJFMではJLReqの仕様は再現できないので(当たり前だ……)

とはいえ今回のはバグとして良いと思いますが.

@aminophen
Copy link

おそらく諸々の禁則設定が逆なのではないでしょうか。

禁則は関係ないと思うのですが,間違いですか?

\inhibitxspcode は kinsoku.tex で設定されているパラメータだという意味であって,本来の意味での「禁則」の意味では使っていませんでした。pLaTeX 関連の文書では \jcharwidowpenalty などのパラメータも「禁則」と呼ばれるなど,JLreq 等とはずれていることが多いです。

@abenori
Copy link
Owner

abenori commented Dec 17, 2017

JFMを見直してみました( b7dba14 ).jaxspmodeの件も直したので,とりあえず上記の件は解消されていると思います.JFM自身はJLReqの表と何度か見比べただけなので,変な点が残っていたら教えてください.

@yudai-nkt
Copy link
Contributor Author

最新版を試したところ,(推奨されるかはさておき)otfパッケージを読み込んだ状態でも正常な結果になりました.JFMはまだ見ていないのですが,JLReqの表というのはこのPDFのことでしょうか?

@yudai-nkt
Copy link
Contributor Author

yudai-nkt commented Dec 18, 2017

またサードパーティ製のパッケージ絡みですみません,修正版とcleverefパッケージの併用が上手くいかないようです.

\documentclass{jlreq}
\usepackage{cleveref}
\begin{document}
\section{ほげ}\label{sec:hoge}
\end{document}

をpLaTeXで処理すると,2017-12-02(手元のバージョンは2017-08-29だったので今回の修正は無関係でした. 3d326d5 以降で発生しますが,こちらへ報告すべきか否かもう少し精査したあとに別のissueを立てます)版だとauxファイルの中身が

\relax 
\providecommand\zref@newlabel[2]{}
\zref@newlabel{jlreq@[email protected]}{\jlreq@page{1}}
\@writefile{toc}{\contentsline {section}{\numberline {1}ほげ}{1}}
\newlabel{sec:hoge}{{1}{1}}
\newlabel{sec:hoge@cref}{{[section][1][]1}{1}}

となって2回目のタイプセット以降も正しく処理されますが,修正版だと

\relax 
\providecommand\zref@newlabel[2]{}
\@writefile{toc}{\contentsline {section}{\numberline {1}ほげ}{1}}
\newlabel{\relax }{{1}{1}}
\newlabel{\relax @cref}{{[section][1][]1}{1}}

\newlabelの第一引数に展開不能なトークンが含まれており,結果として! Missing \endcsname inserted.が発生します.

! Missing \endcsname inserted.
<to be read again>
                   \relax
l.4 \newlabel{\relax }{{1}{1}}

?

まだ詳しく見ていないのですが,取り急ぎご報告まで.

@abenori
Copy link
Owner

abenori commented Dec 19, 2017

@abenori
Copy link
Owner

abenori commented Dec 19, 2017

またサードパーティ製のパッケージ絡みですみません,修正版とcleverefパッケージの併用が上手くいかないようです.

今回の修正ではなく,仰るとおりもう少し前の修正です.大体原因はわかりましたが,どうするかは今から考えます.

@abenori
Copy link
Owner

abenori commented Dec 19, 2017

とりあえず 7d172c0 でエラーが発生しないようにはしました.

ただし,cleverrefパッケージ利用時には

\section{}\label{label}
\subsection{}

というような時に\section\subsectionが連続されていると認識されないと思います.従って\SetBlockHeadingSpacesによる指定が効きません.汎用的な対処は難しそうです…….

@yudai-nkt
Copy link
Contributor Author

関係ない問題を混ぜてしまいましたが,対応ありがとうございます.エラーが解消されたのを手元で確認しました.

LaTeX標準の相互参照関連をいろいろ書き換えてるせいでcleverefと他パッケージとの衝突も多いようですが,ひとまずエラーじゃなくなっただけでも非常にありがたいです.

@abenori
Copy link
Owner

abenori commented Dec 21, 2017

1f86b41
単に\label[<オプション>]{引数}...{引数}という形を見つけたらスキップするようにしてみました.cleverefと\SetBlockHeadingSpacesが共存できるようになったかと思います.

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

No branches or pull requests

3 participants