\documentclass{jarticle} \ProvidesFile{ptexskip.tex}[1997/08/08 v0.4 about pTeX skips] \usepackage{plext} \title{p\TeX~2.1.5における数式の前後} \author{中野 賢\footnote{Ken Nakano (\texttt{}): 株式会社 アスキー 出版技術部}} \date{1997年8月8日} \newcommand{\hex}[1]{\hskip\xkanjiskip\texttt{"#1}} \newcommand{\cs}[1]{\hskip\xkanjiskip\texttt{\char"5C #1}} %\xspcode"5C=1 \xspcode"22=2 % 2 \xspcode"27=2 % 2 \xspcode"5C=1 % 1 \xspcode"60=1 % 1 \prebreakpenalty"22=10001 % '' \prebreakpenalty"27=10002 % ' \postbreakpenalty"5C=10003 % ``, \ \postbreakpenalty"60=10004 % ` % サンプル用 \newdimen\dimenA %\tracingcommands=2 %\tracingmacros=2 %\tracingparagraphs=2 %\tracingoutput=2 \showboxbreadth=\maxdimen \showboxdepth=\maxdimen \nonstopmode \begin{document} \maketitle \section*{はじめに} p\TeX{}では、和文と欧文の間に\emph{四分アキ}と呼ばれるスペースを 自動的に挿入するようになっている。挿入される箇所は、和文と欧文の間という だけでなく、他にも次の条件が揃っていなくてはならない。 \begin{itemize} \item \cs{autoxspcode}の状態 \item \cs{xspcode}および\cs{inhibitxspcode}による抑制を受けない \item shift\_amount(移動量)がゼロである\cs{hbox}の直前、直後 \item 合字、ペナルティ、ベースライン調整量、暗黙の\cs{kern}の直前、直後 \end{itemize} 本文では多くの場合、単純に文字が並んでいるだけなので、このような条件を 知らなくても、期待している結果を得ることができる。 しかし、数式を組み立てた場合、自分ではとくに指定をしていなくても、 \TeX{}が内部処理で、文字の位置を調整したり、\cs{vbox}に入れたりするために、 四分アキが入らず、その原因もわからないということがある。 そこで、p\TeX~2.1.5では、テキスト数式の前後への四分アキの挿入方法を変更した。 この文書では、その拡張に際しての仕様の変更について簡単に説明をしている。 \section{p\TeX~2.1.4までの数式の前後} p\TeX~2.1.4で\footnote{より正確に言えば、p\TeX~2.1.5 $\beta$~6まで}、 テキスト数式の前や後に四分アキが入らない主な原因は以下の3つである。 \begin{itemize} \item \cs{xspcode}による影響の場合 \item シフトされた\cs{hbox}となる場合 \item \cs{vbox}となる場合 \end{itemize} \subsection{\cs{xspcode}による影響の場合} \cs{xspcode}および\cs{inhibitxspcode}による抑制は、たとえば、 $\alpha$や$\beta$の前後にスペースが入らないという結果をもたらす。 なぜならば、$\alpha$はcmmi10の\hex{0B}の位置、$\beta$は\hex{0C}の位置に あるからである。これら文字の\cs{xspcode}の値はゼロ、すなわち前後への 四分アキを抑制するという動作をする。 その結果、前後に四分アキが入らないのである。 \subsection{シフトされた\cs{hbox}となる場合} shift\_amountがゼロでない\cs{hbox}の例としては、 $\sum$や$\int$や$x^2$や$x_2$や$\sqrt{\hbox{Var(X)}}$などを挙げられる。 $\sum$はcmex10の\hex{50}の位置にあり、これはcmr10の``P''と同じ位置 なので\cs{xspcode}による抑制は受けない。しかし、位置の調整のために、 \cs{hbox}に入れられ、左にシフトされる。この結果、\hex{50}の文字が 一つだけにも関わらず、処理対象外の\cs{hbox}となってしまい、 前後への四分アキが入らなくなる。$\int$も同様である。 $x^2$や$x_2$などの場合は、上付き/下付き文字がシフトされた\cs{hbox}として 組み立てられているので、``$x$''の前には四分アキが入るが、 ``2''の後ろには入らないことになる。 根号記号の場合は、全体がシフトされた\cs{hbox}として組み立てられるので、 前後に四分アキが入らない。 \subsection{\cs{vbox}となる場合} その他に四分アキが入る箇所は、 合字、ペナルティ、ベースライン調整量、暗黙の\cs{kern}の直前か直後 だけである。これ以外の箇所には入らない。 数式の前後に限れば、このうちの、\cs{vbox}の前後には入らないという 制限が大きく影響をしている。たとえば、$\frac{1}{k}$といった分数や、 $x_k^2$のように上付きと下付き文字の両方を指定したときが、これに当たる。 分数の場合は、最終的に\cs{vbox}として組み立てられる。 そのため、分数の前後に四分アキが入らなくなる。 上付きと下付きの両方がある場合は、それらが\cs{vbox}に入れられるため、 入らなくなるのである。上付きと下付きの一方の場合と状況は異なるが、 結果は一緒である。 \section{p\TeX~2.1.5 $\beta7$での数式の前後} 今までの実装コードでは、数式の開始や終了のノードを見つけても、 開始/終了ノードを単純にスキップするだけで、その後、数式の内部の文字を見て、 スペースを挿入するかどうかを判断をしていた。そのために数式を囲んでいる \cs{hbox}がシフトしていたり、\cs{vbox}であったりすると前後にスペースが 入らないという結果になっていた。 そこで、$\beta7$では、数式の開始ノードを見つけたとき、次の要素が何で あるかを調べることにした。 数式の次の要素が``文字''そのものである場合、テキストの最後の文字との関係で 適切なスペースを入れる。ここで、従来の動作と異なるのは、数式内部の文字の \cs{xspcode}あるいは\cs{inhibitxspcode}の設定を無視するようにした点である。 つまり、数式内の文字とその直前との文字が和文か欧文かだけを調べて、 四分アキか漢字間スペースを挿入するようにした。 この変更で$\alpha$や$\beta$などの文字の前にスペースが入るようになる。 数式の開始ノードの次の要素が文字以外の場合は、それが何であっても 四分アキを入れる。この修正によって、数式がシフトされた\cs{hbox}や \cs{vbox}の場合であっても四分アキが入る。 このようなボックスになるときは、上付き/下付き文字、分数、数学記号を 使った場合などである。 終了ノードの時点では、この後に挿入するスペースが決まっていればそれを用いる。 すなわち、数式の最後とその後るの文字がともに和文であれば漢字間スペースを 挿入し、いずれかが欧文であれば四分アキを挿入する。 このときも、数式内部の最後の文字の\cs{xspcode}も無視するようにし、 $\alpha$や$\beta$などの後ろにも入るようにしている。 シフトされた\cs{hbox}や\cs{vbox}などで終了したときは、 前側に四分アキを入れたので、合わせる意味で後側にも四分アキを挿入する。 これで$x^2$や$\frac{dx}{dy}$や$\sqrt{3}$などの後ろにもスペースが入る。 なお、数式の直前の文字と数式内部の先頭文字がともに欧文の場合、 あるいは数式内部の最後と数式直後がともに欧文の場合は、 \TeX{}と同じであり特別なスペースを入れないのは従来と同じである。 \section{p\TeX~2.1.5 $\beta8$での数式の前後} p\TeX~2.1.5 $\beta8$では、単純にテキスト数式の前後に四分アキを入れる方法 で実装している。ただし、「(」や「)」などによる抑制を効かせるべき箇所には 四分アキは入らない。つまり ``\verb|($y=a+b$)|''は ``($y=a+b$)''となり ``(\kern\xkanjiskip$y=a+b$\kern\xkanjiskip)''とは ならないことに注意する。 `\verb|($y=a+b$)|'は `($y=a+b$)'となり `(\kern\xkanjiskip$y=a+b$\kern\xkanjiskip)'とは ならないことに注意する。 \showlists $\beta7$版と$\beta8$版との仕様の違いは、 次のように数式内の文字が漢字で始まる(あるいは終わる)ときに現れる。 \begin{verbatim} \kanjiskip=4pt \xkanjiskip=8pt □□$表面積=4\pi r^2$□□ \end{verbatim} この例をそれぞれで処理した場合、 \begin{quote} \kanjiskip=4pt \xkanjiskip=8pt □□\kern\kanjiskip$表面積=4\pi r^2$\kern\xkanjiskip □□ \quad($\beta7$\kern.25zw 版)\\ □□\kern\xkanjiskip$表面積=4\pi r^2$\kern\xkanjiskip □□ \quad($\beta8$\kern.25zw 版)\\ □□$表面積=4\pi r^2$□□ \quad\hbox{\kanjiskip=0pt\xkanjiskip=.25zw (この版)} \end{quote} となる。つまり、$\beta7$版では数式内部の文字と直前の文字を比較しているため、 前側に漢字間スペースが入り、後側に四分アキが入る。 一方、$\beta8$版では数式内部の文字に関係なく、両側に四分アキが入る。 なお、両者の違いは、次のように\cs{hbox}を用いたときにも現れる。 \begin{verbatim} \kanjiskip=4pt \xkanjiskip=8pt □□$\hbox{表面積}$□□ \end{verbatim} これを処理すると、$\beta7$版は目指すべき仕様とは異なり、 後ろに何も入らない(バグ)。$\beta8$版では仕様どおりに両側に四分アキが入る。 \begin{quote} \kanjiskip=4pt \xkanjiskip=8pt □□\kern\xkanjiskip$\hbox{表面積}$\kern0pt □□ \quad ($\beta7$\kern.25zw 版)\\ □□\kern\kanjiskip$\hbox{表面積}$\kern\kanjiskip □□ \quad\hbox{\kanjiskip=0pt($\beta7$\kern.25zw 版を修正した場合)}\\ □□\kern\xkanjiskip$\hbox{表面積}$\kern\xkanjiskip □□ \quad ($\beta8$\kern.25zw 版)\\ □□$\hbox{表面積}$□□ \quad\hbox{\kanjiskip=0pt\xkanjiskip=.25zw (この版)} \end{quote} 実際には、p\TeX, p\LaTeX のデフォルトの設定では\cs{kanjiskip}と\cs{xkanjiskip}% の値はもっと小さいので、違いはそれほど目立たないかもしれない。 しかし、縦組にした場合は、つぎのような結果となる。 \begin{quote} \begin{minipage}{16zw} △△\kern\kanjiskip$表面積=4\pi r^2$\kern\xkanjiskip\raisebox{-.25zw}{△△} \quad($\beta7$\kern.25zw 版)\\ \\ △△\kern\kanjiskip$表面積=4\pi r^2$\kern\xkanjiskip △△\\ \hfill($\beta7$\kern.25zw 版を修正した場合)\\ \\ △△\kern\xkanjiskip$表面積=4\pi r^2$\kern\xkanjiskip △△ \quad($\beta8$\kern.25zw 版)\\ \\ △△$表面積=4\pi r^2$△△ \quad\hbox{\kanjiskip=0pt\xkanjiskip=.25zw (この版)} \end{minipage} \end{quote} $\beta7$の結果を見ると文字間のスペースは仕様どおりになっている。 しかし、ベースラインの調整量が数式の後ろで戻っていないというバグがある。 たとえバグを修正したとしても、決して読みやすいとは思えない。 以上の結果を比較すると、$\beta8$の挿入方法のほうが自然で、読みやすいように 思える。また、挿入されるスペースも前後の文字、数式内の文字に関係なく、 四分アキと決まっているので結果がわかりやすい。 そこで、$\beta8$では、この節の冒頭で述べた、 \begin{center} 単純に、テキスト数式の前後に四分アキを入れる \end{center} という仕様で実装している。 \subsection{別の問題} $\beta7$の実装では、完全に数式にだけ影響するようにしていなかったため、 通常の文章内でのボックスに対する動作も変わってしまっていた。たとえば、 \begin{quote} \begin{verbatim} □□\AA △△△△\hbox to0pt{ABC\hss}○○○○\hbox{}A\hbox{}□□□□ \end{verbatim} \end{quote} が \begin{quote} \setbox0=\hbox{h}\dimenA=\ht0 \advance\dimenA-1ex □□ \leavevmode\rlap{\raise.67\dimenA\hbox{\char'27}}\kern\xkanjiskip A% \kern\xkanjiskip △△△△ \setbox0\hbox{ABC}\dimenA=\wd0\advance\dimenA-\xkanjiskip \kern\xkanjiskip ABC\kern-\dimenA ○○○○ \kern\xkanjiskip A\kern\xkanjiskip □□□□ \end{quote} となる。先ほどのリストを処理して期待する結果は、次のようだと思われる。 \begin{quote} \setbox0=\hbox{h}\dimenA=\ht0 \advance\dimenA-1ex □□ \kern\xkanjiskip \leavevmode\rlap{\raise.67\dimenA\hbox{\char'27}}\kern0pt A% \kern\xkanjiskip △△△△ \setbox0\hbox{ABC}\dimenA=\wd0% \kern\xkanjiskip ABC\kern-\dimenA ○○○○ \kern0pt A\kern0pt □□□□ \end{quote} この版では、 \begin{quote} □□\AA △△△△\hbox to0pt{ABC\hss}○○○○\hbox{}A\hbox{}□□□□ \end{quote} となる。 \AA の前に四分アキが入っていなければ、それはシフトされたボックスの前後に アキが入らないからである。$\beta7$の実装で``{\char'27}''と``A''の位置が ずれているのは、シフトされたボックスの前には入れないのは変わらないけれども、 後ろで必ず入れないようにするのをやめたためである。 また、$\beta7$では、ボックスの中身の最後が文字以外でも、空でも四分アキの 挿入に影響をさせないようにしていたため、幅がゼロのボックスを作成しても、 参照点の位置が戻らないし、処理の抑制もされなくなっていた \footnote{これらの問題は$\beta11$で修正。}。 \appendix \section{自動挿入されるスペースの種類} p\TeX{}では、日本語文書をきれいに組版するために、 和文と和文の間、和文と欧文の間に自動的にスペースを入れるように拡張している。 欧文と欧文の間は、\TeX{}のメカニズムそのままである。 和文と和文の間に入れるスペースの量は、\cs{kanjiskip}という長さレジスタに 設定をする。和文と欧文との間は\cs{xkanjiskip}という長さレジスタである。 p\TeX{}のデフォルトでは、 \begin{verbatim} \kanjiskip=0pt plus .4pt minus .4pt \xkanjiskip=.25zw plus 1pt minus 1pt \end{verbatim} となっている。この設定は、 \cs{kanjiskip}は標準でゼロポイント、場合によって$\pm0.4$ポイント分だけ伸縮、 \cs{xkanjiskip}は標準でその時点の和文フォントの幅の$1/4$、 場合によって$\pm1$ポイント分だけ伸縮しても良いということを意味している。 \cs{kanjiskip}も\cs{xkanjiskip}も、段落の終わりか、\cs{hbox}の最後の時点 の値が有効となる。したがって、ひとつの段落内や\cs{hbox}内で複数回指定を しても、その最後の指定によって処理される。 ただし「、」や「(」のように、特定の文字が連続する場合、そのまま全角幅 で並べ、間に\cs{kanjiskip}を挿入すると文字の間が離れすぎてしまう。 このときには、\cs{kanjiskip}ではなく、JFM(Japanese Font Metric)で設定 されているスペースの量が使われる。 \cs{xkanjiskip}に関しても、和文と「;」、「(」と和文、欧文と「。」、 「…」と前後の欧文のような箇所には、スペースを挿入しないほうがきれいに 見える。そこで、特定の欧文の文字に対して、\cs{xkanjiskip}の挿入を制御 するために\cs{xspcode}が用意されている。 特定の和文に対しては\cs{inhibitxspcode}を用いて制御する。 \section{スペースに関するプリミティブ} p\TeX{}で拡張した、スペースに関するプリミティブは以下のとおり。 \subsection{\cs{kanjiskip}, \cs{autospacing}, \cs{noautospacing}} \cs{kanjiskip}は、 漢字と漢字の間に自動的に挿入するスペースの量を格納する長さレジスタである。 \cs{autospacing}と\cs{noautospacing}は、 漢字と漢字の間にスペースを挿入するかどうかを指定するのに用いる。 \cs{autospacing}を指定すると自動的に挿入される。 \cs{noautospacing}を指定すると漢字間へのスペース挿入は抑制される。 \subsection{\cs{xkanjiskip}, \cs{autoxspacing}, \cs{noautoxspacing}} \cs{xkanjiskip}は、 漢字と英字の間に自動的に挿入するスペースの量を格納する長さレジスタである。 \cs{autoxspacing}と\cs{noautoxspacing}は、 漢字と英字の間にスペースを挿入するかどうかを指定するのに用いる。 \cs{autoxspacing}を指定すると自動的に挿入される。 \cs{noautoxspacing}を指定すると漢字間へのスペース挿入は抑制される。 \subsection{\cs{xspcode}} \cs{xspcode}は、指定した英字と漢字との間のスペース挿入を どのように\textgt{許可}するかの設定をするプリミティブである。 動作は、つぎのいずれかの数値で指定をする。 \begin{center} \begin{tabular}{ll} 0 & 前後の漢字との間へのスペースの挿入を禁止する。\\ 1 & 直前の漢字との間にだけスペースの挿入を許可する。\\ 2 & 直後の漢字との間にだけスペースの挿入を許可する。\\ 3 & 前後の漢字との間にスペースの挿入を許可する。\\ \end{tabular} \end{center} 初期値は、\texttt{[0-9A-Za-z]}は3、それ以外はゼロになっている。 ただし、以下の文字については、kinsoku.texで別の値に初期化されている。 括弧内はASCII文字コード(16進数)である。 \begin{center} \begin{tabular}{l@{\hspace{2.5zw}}l@{\hspace{2.5zw}}l@{\hspace{2.5zw}}l} \texttt{(}=1 (\hex{28}) & \texttt{)}=2 (\hex{29}) & \texttt{[}=1 (\hex{5B}) & \texttt{]}=2 (\hex{5D})\\ \texttt{`}=1 (\hex{60}) & \texttt{'}=2 (\hex{27}) & \texttt{;}=2 (\hex{3B}) & \texttt{,}=2 (\hex{2C})\\ \texttt{.}=2 (\hex{2E}) \\ \end{tabular} \end{center} ただし、\cs{xspcode}の設定は、文字コードに対してであり、フォントによって 異なる値を指定することはできない。したがって\hex{60}の位置にある文字は、 cmr10では``\textrm{`}'', cmmi10では``$\ell$'', cmex10では``$\coprod$''で あるが、これらの文字はすべて\cs{xspcode}=1として処理される。 \subsection{\cs{inhibitxspcode}} \cs{inhibitxspcode}は、指定した漢字と英字の間のスペース挿入を どのように\textgt{抑制}するかの設定をするプリミティブである。 動作は、つぎのいずれかの数値で指定をする。 \begin{center} \begin{tabular}{ll} 0 & 漢字と英字との間のスペースの挿入を禁止する。\\ 1 & 直前の英字との間のスペースの挿入を禁止する。\\ 2 & 直後の英字との間のスペースの挿入を禁止する。\\ 3 & 前後の英字との間のスペースの挿入を許可する。\\ \end{tabular} \end{center} 初期値は、すべての漢字について3である。 ただし、以下の文字については、kinsoku.texで別の値に初期化されている。 \begin{center} \begin{tabular}{l@{\hspace{2.5zw}}l@{\hspace{2.5zw}}l@{\hspace{2.5zw}} l@{\hspace{2.5zw}}l@{\hspace{2.5zw}}l} 、=1 & 。=1 & ,=1 & .=1 & ;=1 & ?=1\\ (=2 & )=1 & [=2 & ]=1 & {=2 & }=1\\ ‘=2 & ’=1 & “=2 & ”=1 & 〔=2 & 〕=1\\ <=2 & >=1 & 《=2 & 》=1 & 「=2 & 」=1\\ 『=2 & 』=1 & 【=2 & 】=1 & −=0 & 〜=0\\ …=0 & ¥=0 & °=0 & ′=1 & ″=1\\ \end{tabular} \end{center} \end{document}