summaryrefslogtreecommitdiff
path: root/info/ptex-manual/ptexskip_asciimw.tex
blob: 183e3691fd56184980dde6454befd832aa552e6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
\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{<ken-na at ascii.co.jp>}):
  株式会社 アスキー 出版技術部}}
\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}<t>{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}