ベースライン補正が 0 でないときの tabular 環境の垂直位置について
考えていたのですが,その過程で
文中数式モードでは自動的に全体にベースライン補正がかかり,
その結果 $\hbox{漢字ABC}$ では「漢字」に一重,
「ABC」に二重にベースライン補正が適用される
という pTeX の仕様について疑問を持ったので,実験してみました.
(参考:qa: 54286)
手元で「数式中の explicit なボックスは,
自動で入るベースライン補正を打ち消すように垂直位置をずらす」
というパッチを作り,次のソースで試してみました.
添付ファイルの黒が現行の pTeX の挙動,薄青がパッチ後の挙動です.
%%%%%%%%
\ifdefined\enablecjktoken
\documentclass[uplatex]{jsarticle}
\else
\documentclass{jsarticle}
\fi
\usepackage{amsmath}
\textwidth300pt
\begin{document}
\ybaselineshift=10pt
\noautoxspacing
\def\R{\vrule height 0.4pt depth 0pt width 10pt}
あいうえおABC$%
\hbox{漢X\R}\vbox{\hsize=3em 字Y\hss}\R xyz\frac{\text{漢X\R}\R213}{s}
\displaystyle\int_{0}^{\text{漢X\R}\R1}
$\vrule height 50pt depth 40pt
qa:54286
\begin{equation}
y = f(x)= x^2+2x+1 + \int_{0}^{\pi} \frac{1+tx^2}{1-t^2}\,dt
\end{equation}
\end{document}
%%%%%%%%
「地の数式」中に配置したボックスについては良さそうに
思えますが,逆に,分数や添字中に \hbox を配置した場合は
欧文のベースラインが揃わなくなっています.
(折衷案としては,「\textstyle, \displaystyle のみ打ち消す」?)
何か感想や意見などがありましたらお願い致します.
> 逆に,分数や添字中に \hbox を配置した場合は
> 欧文のベースラインが揃わなくなっています.
ここ,なんだかおかしな表現になっていますね,すみません.
> 折衷案としては,「\textstyle, \displaystyle のみ打ち消す」?
作ってみました.同じものを ptex-base.ch へのパッチも含めて
https://github.com/h-kitagawa/plext_test/tree/master/ptex_bls_math
に置いています.
横組では \ybaselineshift = 0 pt の場合が多いと思うので
そんなに影響はないでしょうけど,やっぱり副作用が気になります…….
> 欧文のベースラインが揃わなくなっています.
ここ,なんだかおかしな表現になっていますね,すみません.
> 折衷案としては,「\textstyle, \displaystyle のみ打ち消す」?
作ってみました.同じものを ptex-base.ch へのパッチも含めて
https://github.com/h-kitagawa/plext_test/tree/master/ptex_bls_math
に置いています.
横組では \ybaselineshift = 0 pt の場合が多いと思うので
そんなに影響はないでしょうけど,やっぱり副作用が気になります…….
おかげさまで TeX を便利に使わせていただいています。
ユーザーの一人として感謝しています。
さて、そもそもの pTeX の baselineshift の仕組みは、
和文フォントと欧文フォントのデザイン上のミスマッチを補正するのが目的だったと思います。
そうすると、シフトする対象を和文中の欧文と和文中の数式ボックスとするのではなく、
シフトの対象は欧文フォントや数式シンボルフォント自体とするのが合理的ではないかと思います。
フォント自体をシフトするにはバーチャルフォントを使っても実現できると思いますが、
それだとシフト量をマクロレベルで簡単に変えられないので、
次のような仕組みが考えられないでしょうか。
それは、フォントごとのシフト量を pTeX に保持させて、
新しいプリミティブで個別のフォントのシフト量を変更できるようにする仕組みです。
私には pTeX を改変する技術はないので、いうだけになってしまって申し訳ないのですが、
中に和文を含むかもしれないような数式ボックスをボックスごとシフトしてしまうことで
問題が複雑化しているのが、この方針で一気に解消できるように思いました。
pTeXの実装はよくわからないのですが、
内部でフォントの高さや深さを利用するところすべてを変更する必要があるのかもしれないので、
そうするとかなりの大改造になりそうなのが心配です。
と、書いた後で思ったのですが、数式の axis のシフト量はどうすべきか悩ましいですね。
ユーザーの一人として感謝しています。
さて、そもそもの pTeX の baselineshift の仕組みは、
和文フォントと欧文フォントのデザイン上のミスマッチを補正するのが目的だったと思います。
そうすると、シフトする対象を和文中の欧文と和文中の数式ボックスとするのではなく、
シフトの対象は欧文フォントや数式シンボルフォント自体とするのが合理的ではないかと思います。
フォント自体をシフトするにはバーチャルフォントを使っても実現できると思いますが、
それだとシフト量をマクロレベルで簡単に変えられないので、
次のような仕組みが考えられないでしょうか。
それは、フォントごとのシフト量を pTeX に保持させて、
新しいプリミティブで個別のフォントのシフト量を変更できるようにする仕組みです。
私には pTeX を改変する技術はないので、いうだけになってしまって申し訳ないのですが、
中に和文を含むかもしれないような数式ボックスをボックスごとシフトしてしまうことで
問題が複雑化しているのが、この方針で一気に解消できるように思いました。
pTeXの実装はよくわからないのですが、
内部でフォントの高さや深さを利用するところすべてを変更する必要があるのかもしれないので、
そうするとかなりの大改造になりそうなのが心配です。
と、書いた後で思ったのですが、数式の axis のシフト量はどうすべきか悩ましいですね。
> 確かにそうですね.
> ABCあ$\underline{\hbox{漢X}213}$%
> ABCあ$\underline{\hbox{漢X}}$
> だけでも違いが確認できますね,やっぱりまだ甘かったです.
\underline などにも効くようにしてみました.
(添付ファイル中,黒が現行の pTeX の挙動,薄青がパッチ後の挙動)
\displaystyle, \textstyle での明示的なボックスの「シフト打ち消し」量を
指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
\scriptbaselineshiftfactor(標準値は 700: 0.7倍),
\scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
利用者が設定できるようにしています.
いずれも 0 にすると,現行の pTeX の挙動と一致するはずです.
なお,$あ$ のように数式モードの中で直に書かれた和文文字に対しては
何もしていません.
> ABCあ$\underline{\hbox{漢X}213}$%
> ABCあ$\underline{\hbox{漢X}}$
> だけでも違いが確認できますね,やっぱりまだ甘かったです.
\underline などにも効くようにしてみました.
(添付ファイル中,黒が現行の pTeX の挙動,薄青がパッチ後の挙動)
\displaystyle, \textstyle での明示的なボックスの「シフト打ち消し」量を
指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
\scriptbaselineshiftfactor(標準値は 700: 0.7倍),
\scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
利用者が設定できるようにしています.
いずれも 0 にすると,現行の pTeX の挙動と一致するはずです.
なお,$あ$ のように数式モードの中で直に書かれた和文文字に対しては
何もしていません.
> \displaystyle, \textstyle での明示的なボックスの「シフト打ち消し」量を
> 指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
> \scriptbaselineshiftfactor(標準値は 700: 0.7倍),
> \scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
> 利用者が設定できるようにしています.
> 指定する \textbaselineshiftfactor(標準値は 1000: 1倍)と,同様の
> \scriptbaselineshiftfactor(標準値は 700: 0.7倍),
> \scriptscriptbaselineshiftfactor(標準値は 500: 0.5倍)を作り,
> 利用者が設定できるようにしています.
> いずれも 0 にすると,現行の pTeX の挙動と一致するはずです.
ビルドしてみました。いまのところ変な結果は出ていません。
[D or T] : [S] : [SS] = 1000 : 700 : 500
の規定値はフォントサイズ由来という理解でよければ
「和文フォントと欧文フォントのデザイン上のミスマッチを補正する」
という観点からも素晴らしいと思います。
> LaTeX のロゴの「A」が徐々に上がらなくなっていく
PDF を作ったので添付します。ソースは「2016年 03月 01日(火曜日) 18:39」
に例示したものです。作成環境は
TeX Live 2015 + LaTeX 2016/02/01 + pLaTeX 2006/11/10
です。TeXを使ってみよう(upTeX版)
http://glc.l.u-tokyo.ac.jp/texonweb/
も使ってみましたが(jarticle → ujarticle)、まったく同じです。
This is e-pTeX, Version 3.14159265-p3.6-141210-2.6 (utf8.euc) (TeX Live 2015)
pLaTeX2e <2006/11/10> (based on LaTeX2e <2016/02/01> patch level 0)
2016年 03月 01日(火曜日) 18:39
のコメントで
> (これはパッチをあてる前と後で同じです)
と書いているとおり、パッチによって qa:54286 で報告されている
「\hbox に二重のベースライン補正が効く現象」
は修正されたはずなので qa:54286 や qa:54294 とは違うと思います。
パッチをあててもなお、LaTeX のロゴが変になるということを私は
不思議に思っています。
パッチが不十分なのだろうか、それとも \vbox がだめなのだろうか?
→ 追記:よく考えてみると、これは A が \vbox に入れられているから
でしょうね。「\vbox の中の \hbox」なので、再び \hbox の中ではベース
ライン補正が効くということでしょう。お騒がせしました。
あまり話についていけていませんが,試しに横組で
\documentclass{jarticle}
\def\T#1{%
\ybaselineshift#1%
\sbox0T%
shift #1: ht \the\ht0, dp \the\dp0}
\begin{document}
\T{0pt}
\T{1pt}
\T{6pt}
\T{7pt}
\T{10pt}
\end{document}
とすると,結果は次のようになりました:
shift 0pt: ht 6.83331pt, dp 0.0pt
shift 1pt: ht 5.83331pt, dp 1.0pt
shift 6pt: ht 0.83331pt, dp 6.0pt
shift 7pt: ht 0.0pt, dp 7.0pt
shift 10pt: ht 0.0pt, dp 10.0pt
これは仕様通りなのでしょうか.
\documentclass{jarticle}
\def\T#1{%
\ybaselineshift#1%
\sbox0T%
shift #1: ht \the\ht0, dp \the\dp0}
\begin{document}
\T{0pt}
\T{1pt}
\T{6pt}
\T{7pt}
\T{10pt}
\end{document}
とすると,結果は次のようになりました:
shift 0pt: ht 6.83331pt, dp 0.0pt
shift 1pt: ht 5.83331pt, dp 1.0pt
shift 6pt: ht 0.83331pt, dp 6.0pt
shift 7pt: ht 0.0pt, dp 7.0pt
shift 10pt: ht 0.0pt, dp 10.0pt
これは仕様通りなのでしょうか.
「LaTeX のロゴの『A』」のところから話が追えていませんが……,
> shift 0pt: ht 6.83331pt, dp 0.0pt
> shift 1pt: ht 5.83331pt, dp 1.0pt
> shift 6pt: ht 0.83331pt, dp 6.0pt
> shift 7pt: ht 0.0pt, dp 7.0pt
> shift 10pt: ht 0.0pt, dp 10.0pt
> これは仕様通りなのでしょうか.
pTeX は「欧文をずらす」という実装になっているので,
「和文ベースラインを基準にした時のボックスの寸法」と考えれば
そんなに不自然ではないように思えます.
「高さ(深さ)が負になる」ことはあってもいいかもしれませんが,
TeX82 の \raise, \lower とかでシフトされる場合も
高さや深さは 0 にならないので,それをに合わせたのだと思います.
> shift 0pt: ht 6.83331pt, dp 0.0pt
> shift 1pt: ht 5.83331pt, dp 1.0pt
> shift 6pt: ht 0.83331pt, dp 6.0pt
> shift 7pt: ht 0.0pt, dp 7.0pt
> shift 10pt: ht 0.0pt, dp 10.0pt
> これは仕様通りなのでしょうか.
pTeX は「欧文をずらす」という実装になっているので,
「和文ベースラインを基準にした時のボックスの寸法」と考えれば
そんなに不自然ではないように思えます.
「高さ(深さ)が負になる」ことはあってもいいかもしれませんが,
TeX82 の \raise, \lower とかでシフトされる場合も
高さや深さは 0 にならないので,それをに合わせたのだと思います.
本題と関係ないことを知りつつ続けると,\LaTeX の例は,今の仕様だと
\sbox\z@ T から \ht\z@ の値を参照して文字の高さを取得するような
コードに対して,\ybaselineshift が 0pt でない場合に意図しない動作を
引き起こす場合があることを示唆しているのではないかと思います.
今の仕様でうまく \LaTeX を出そうとすると,例えばこんな感じでしょうか.
縦組のほうは \tbaselineshift を引かないといけない理由がよく理解できていませんが…….
\documentclass{jarticle}
\makeatletter
\DeclareRobustCommand{\LaTeX}{L\kern-.36em%
{\def\@tempa{\check@mathfonts
\fontsize\sf@size\z@
\math@fontsfalse\selectfont
A}%
\begingroup
\ybaselineshift0pt%
\tbaselineshift0pt%
\sbox\z@ T%
\@tempdima\ht\z@
\sbox\z@\@tempa
\global\advance\@tempdima-\ht\z@
\endgroup
\iftdir
\advance\@tempdima-\tbaselineshift % なぜ?
\fi
\raise\@tempdima\hbox{\@tempa}}%
\kern-.15em%
\TeX}
\makeatother
\begin{document}
\LaTeX ロゴ
\ybaselineshift20pt
\LaTeX ロゴ
\end{document}
\sbox\z@ T から \ht\z@ の値を参照して文字の高さを取得するような
コードに対して,\ybaselineshift が 0pt でない場合に意図しない動作を
引き起こす場合があることを示唆しているのではないかと思います.
今の仕様でうまく \LaTeX を出そうとすると,例えばこんな感じでしょうか.
縦組のほうは \tbaselineshift を引かないといけない理由がよく理解できていませんが…….
\documentclass{jarticle}
\makeatletter
\DeclareRobustCommand{\LaTeX}{L\kern-.36em%
{\def\@tempa{\check@mathfonts
\fontsize\sf@size\z@
\math@fontsfalse\selectfont
A}%
\begingroup
\ybaselineshift0pt%
\tbaselineshift0pt%
\sbox\z@ T%
\@tempdima\ht\z@
\sbox\z@\@tempa
\global\advance\@tempdima-\ht\z@
\endgroup
\iftdir
\advance\@tempdima-\tbaselineshift % なぜ?
\fi
\raise\@tempdima\hbox{\@tempa}}%
\kern-.15em%
\TeX}
\makeatother
\begin{document}
\LaTeX ロゴ
\ybaselineshift20pt
\LaTeX ロゴ
\end{document}
> \LaTeX の例は,今の仕様だと
> \sbox\z@ T から \ht\z@ の値を参照して
> 文字の高さを取得するようなコードに対して,
> \ybaselineshift が 0pt でない場合に意図
> しない動作を引き起こす場合がある
これと同じ理由で意図しない動作になる例を探していて、
「\AA」も同じだと気づきました。これは縦組の場合、
デフォルトが
\tbaselineshift=3.41666pt
になっているので、○がAに重なります。
\documentclass{tarticle}
\begin{document}
あ\AA あ % ==> 異常
\tbaselineshift0pt % 比較用
あ\AA あ % ==> 正常
\end{document}
以下、私の理解:
\AA の ltplain.dtx での定義は
\def \AA {\r A}
さらに ltoutenc.dtx での定義により
\DeclareTextAccent{\r}{OT1}{23}
これは要するに
\DeclareTextCompositeCommand{\r}{OT1}{A}
{\leavevmode\setbox\z@\hbox{!}\dimen@\ht\z@\advance\dimen@-1ex%
\rlap{\raise.67\dimen@\hbox{\char23}}A}
となる。
> \sbox\z@ T から \ht\z@ の値を参照して
> 文字の高さを取得するようなコードに対して,
> \ybaselineshift が 0pt でない場合に意図
> しない動作を引き起こす場合がある
これと同じ理由で意図しない動作になる例を探していて、
「\AA」も同じだと気づきました。これは縦組の場合、
デフォルトが
\tbaselineshift=3.41666pt
になっているので、○がAに重なります。
\documentclass{tarticle}
\begin{document}
あ\AA あ % ==> 異常
\tbaselineshift0pt % 比較用
あ\AA あ % ==> 正常
\end{document}
以下、私の理解:
\AA の ltplain.dtx での定義は
\def \AA {\r A}
さらに ltoutenc.dtx での定義により
\DeclareTextAccent{\r}{OT1}{23}
これは要するに
\DeclareTextCompositeCommand{\r}{OT1}{A}
{\leavevmode\setbox\z@\hbox{!}\dimen@\ht\z@\advance\dimen@-1ex%
\rlap{\raise.67\dimen@\hbox{\char23}}A}
となる。
> これと同じ理由で意図しない動作になる例を探していて、
> 「\AA」も同じだと気づきました。これは縦組の場合、
> デフォルトが
> \tbaselineshift=3.41666pt
> になっているので、○がAに重なります。
pLaTeX 用にコードを書いてみました.
一回ベースライン補正なしの状態で組んで,
全体を後からずらすという方法をとっています.
\documentclass{tarticle}
\makeatletter
\def\@text@composite#1#2#3#{%
\begingroup
\setbox\z@=\hbox\bgroup%
\ybaselineshift\z@\tbaselineshift\z@
\expandafter\@text@composite@x
\csname\string#1-\string#2\endcsname}
\def\@text@composite@x#1#2{%
\ifx#1\relax
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
#1{#2}\egroup
\leavevmode
\expandafter\lower\iftdir
\ifmdir\ybaselineshift\else\tbaselineshift\fi
\else\ybaselineshift\fi\box\z@
\endgroup}
\makeatother
\begin{document}
漢字ABCf\AA\/DEF 漢字
\end{document}
なお,LuaTeX-ja でも同様の症状が再現しますが,
そちらについてはまた考えます.
> 「\AA」も同じだと気づきました。これは縦組の場合、
> デフォルトが
> \tbaselineshift=3.41666pt
> になっているので、○がAに重なります。
pLaTeX 用にコードを書いてみました.
一回ベースライン補正なしの状態で組んで,
全体を後からずらすという方法をとっています.
\documentclass{tarticle}
\makeatletter
\def\@text@composite#1#2#3#{%
\begingroup
\setbox\z@=\hbox\bgroup%
\ybaselineshift\z@\tbaselineshift\z@
\expandafter\@text@composite@x
\csname\string#1-\string#2\endcsname}
\def\@text@composite@x#1#2{%
\ifx#1\relax
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
#1{#2}\egroup
\leavevmode
\expandafter\lower\iftdir
\ifmdir\ybaselineshift\else\tbaselineshift\fi
\else\ybaselineshift\fi\box\z@
\endgroup}
\makeatother
\begin{document}
漢字ABCf\AA\/DEF 漢字
\end{document}
なお,LuaTeX-ja でも同様の症状が再現しますが,
そちらについてはまた考えます.
# 脱線ではなく本題のほう…だと思ったのですが
# 以下はまだ脱線なのか本題なのかよくわかっていません…
なんだかあらさがししているみたいで申し訳ないですが
%#!platex
\documentclass{jarticle}
\begin{document}
\ybaselineshift5pt
\parindent0pt
\xkanjiskip0pt
あ$a\sqrt[2]{a}$\par
あ$a\sqrt{a}$\par
\end{document}
まだ万全ではないのかもしれません。
(添付画像:新 pTeX でも冪根の数字だけ二重シフトする)
たいして問題にはなりませんが一応報告だけです。
# 以下はまだ脱線なのか本題なのかよくわかっていません…
なんだかあらさがししているみたいで申し訳ないですが
%#!platex
\documentclass{jarticle}
\begin{document}
\ybaselineshift5pt
\parindent0pt
\xkanjiskip0pt
あ$a\sqrt[2]{a}$\par
あ$a\sqrt{a}$\par
\end{document}
まだ万全ではないのかもしれません。
(添付画像:新 pTeX でも冪根の数字だけ二重シフトする)
たいして問題にはなりませんが一応報告だけです。