-
Notifications
You must be signed in to change notification settings - Fork 16
/
chapter22.tex
executable file
·2656 lines (2578 loc) · 131 KB
/
chapter22.tex
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
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% -*- coding: utf-8 -*-
\input macros
%\beginchapter Chapter 22. Alignment
\beginchapter Chapter 22. 对齐阵列
\origpageno=231
%Printers charge extra when you ask them to typeset ^{tables}, and they do so
%for good reason: Each table tends to have its own peculiarities, so it's
%necessary to give some thought to each one, and to fiddle with alternative
%approaches until finding something that looks good and communicates well.
%However, you needn't be too frightened of doing tables with \TeX, since plain
%\TeX\ has a ``tab'' feature that handles simple situations pretty much like
%you would do them on a typewriter. Furthermore, \TeX\ has a powerful
%alignment mechanism that makes it possible to cope with extremely complex
%tabular arrangements. Simple cases of these ^{alignment} operations will
%suffice for the vast majority of applications.
\1当你要求印刷工人排版表格时,他们要进行特殊处理,而且这样做也有充分的理由:
每个表格都有各自的特点,因此必须对每个都要有些侧重,并且在几种方法中%
互相比较以得到漂亮而清晰的结果。%
但是,用 \TeX\ 处理就不需要太担心,因为 plain \TeX\ 有一个``制表''命令,
即使在打字机上你也可以把简单的表格变成漂亮的格式。%
还有, \TeX\ 有一个强大的对齐方法,这使得它能够处理非常复杂的列表格式。%
这些对齐命令的简单运用就足以完成大部分工作了。
%Let's consider ^{tabbing} first. If you say `^|\settabs| $n$ ^|\columns|',
%plain \TeX\ makes it easy to produce lines that are divided into $n$~equal-size
%^{columns}. Each line is specified by typing
%\begindisplay
%|\+|\<text$_1$>|&|\<text$_2$>|&|$\,\cdots\,$|\cr|
%\enddisplay
%where \<text$_1$> will start flush with the left margin,
%\<text$_2$> will start at the left of the second column, and so on. Notice
%that `^|\+|' starts the line. The final column is followed by `^|\cr|',
%which old-timers will recognize as an abbreviation for the ``^{carriage
%return}'' operation on typewriters that had carriages. For example,
%consider the following specification:
%\begintt
%\settabs 4 \columns
%\+&&Text that starts in the third column\cr
%\+&Text that starts in the second column\cr
%\+\it Text that starts in the first column, and&&&
% the fourth, and&beyond!\cr
%\endtt
%After `|\settabs|\stretch|4\columns|' each |\+| line is divided into quarters,
%so the result~is
%\medskip
%\settabs 4 \columns
%\+&&Text that starts in the third column\cr
%\+&Text that starts in the second column\cr
%\+\it Text that starts in the first column, and&&&
% the fourth, and&beyond!\cr
%\def\tick{\kern-0.2pt % that's half the rule width
% \vbox to 0pt{\kern-36pt\leaders\hbox{\vrule height1pt\vbox to4pt{}}\vfil}}
%\vskip-\baselineskip
%\+\tick&\tick&\tick&\tick&\tick\cr
%\medskip
我们首先来讨论制表。%
如果给出`^|\settabs| $n$ ^|\columns|',
~plain \TeX\ 就生成了等分为 $n$ 栏的行。%
每行的内容用下列方法输入:
\begindisplay
|\+|\<text$_1$>|&|\<text$_2$>|&|$\,\cdots\,$|\cr|
\enddisplay
其中 \<text$_1$> 左页边对齐,\<text$_2$> 从第二栏的左边界开始,等等。%
注意,行开头是`^|\+|'。%
最后一栏要跟`^|\cr|', 它就是以前的``回车''命令。%
例如,看看下面的例子:
\begintt
\settabs 4 \columns
\+&&这段文本从第三栏开始\cr
\+&这段文本从第二栏开始\cr
\+\sl 这段文本从第一栏开始&&&第四栏&超出页面!\cr
\endtt
在`|\settabs|\stretch|4\columns|'之后,每个 |\+| 行被四等分,
因此得到的结果是
\medskip
\settabs 4 \columns
\+&&这段文本从第三栏开始\cr
\+&这段文本从第二栏开始\cr
\+\sl 这段文本从第一栏开始&&&第四栏&超出页面!\cr
\def\tick{\kern-0.2pt % that's half the rule width
\vbox to 0pt{\kern-36pt\leaders\hbox{\vrule height1pt\vbox to4pt{}}\vfil}}
\vskip-\baselineskip
\+\tick&\tick&\tick&\tick&\tick\cr
\medskip
%This example merits careful study because it illustrates several things.
%(1)~The `|&|' ^^{ampersand} is like the {\sc TAB} key on many typewriters;
%it tells \TeX\ to advance to the next tab position, where there's a tab at
%the right edge of each column. In this example, \TeX\ has set up four tabs,
%indicated by the dashed lines; a dashed line is also shown at the left
%margin, although there isn't really a tab there. (2)~But `|&|' isn't
%exactly like a mechanical typewriter {\sc TAB}, because it first backs up
%to the beginning of the current column before advancing to the next. In
%this way you can always tell what column you're tabbing to, by counting
%the number of |&|'s; that's handy, because variable-width type otherwise
%makes it difficult to know whether you've passed a tab position or not.
%Thus, on the last line of our example, three |&|'s were typed in order to
%get to column~4, even though the text had already extended into column~2
%and perhaps into column~3. (3)~You can say `|\cr|' before you have
%specified a complete set of columns, if the remaining columns are blank.
%(4)~The |&|'s are different from tabs in another way, too: \TeX\ ignores
%^{spaces} after~`|&|', hence you can conveniently finish a column by typing
%`|&|'~at the end of a line in your input file, without worrying that an
%extra blank space will be introduced there. \ (The second-last line of the
%example ends with~`|&|', and there is an implicit blank space following that
%symbol; if \TeX\ hadn't ignored that space, the words `the fourth'
%wouldn't have started exactly at the beginning of the fourth column.) \
%Incidentally, plain \TeX\ also ignores spaces after `|\+|', so that the
%first column is treated like the others. (5) The `^|\it|' in the last line
%of the example causes only the first column to be italicized, even though
%no ^{braces} were used to confine the range of italics, because \TeX\
%implicitly inserts braces around each individual entry of an alignment.
要好好研究一下这个例子,因为它说明了好几个问题。%
(1). `|&|'象许多打字机的{\sc TAB}键一样;
它指示 \TeX\ 缩进到下一个制表符的位置,在每栏的右边界有一个制表符。%
本例中, \TeX\ 设置了四个制表符,如图用虚线来表示它们;
虚线还出现在左页边,其实它不是一个制表符。%
(2). 但是`|&|'与机械打字机的{\sc TAB}不完全一样,因为在缩进到下一栏前,
它首先要回退到当前栏的开头。%
这样,通过计算 |&| 的数目,就可以知道正在制表的是哪一栏;
这很方便,因为如果宽度会变化,就很难知道你是否超过了制表符的位置。%
因此,在本例中的最后一行,为了得到第四栏,在前面输入了三个 |&|,
而不管文本是否已经超出第一栏甚至到了第三栏。%
(3). 如果本行已经输入完毕,不管是否后面还有空栏,都可以输入`|\cr|'来结束本行。%
(4). |&| 与制表符还有一个方面不同:
\1\TeX\ 忽略掉`|&|'后面的空格,因此,在输入完一栏时,可以把`|&|'放在行尾,
而不会出现额外的空格。%
(本例中的倒数第二行以`|&|'结尾,而且在此符号后面暗中跟着一个空格;
如果 \TeX\ 没有忽略掉此空格,那么文本``第四栏''就不会正好出现在第四栏的开头了。)
顺便说一下,~plain \TeX\ 还忽略掉`|\+|'后面的空格,这样第一栏就与其它栏一样了。%
(5). 在例子的最后一行中,虽然没有用大括号来界定楷体作用的范围,
但是`|\KT{10}|'只把第一栏变成楷体,这是因为 \TeX\ 在暗中在各个当前单元外围%
插入了大括号。
%\danger Once you have issued a |\settabs| command, the tabs remain set until you
%reset them, even though you go ahead and type ordinary paragraphs as usual.
%But if you enclose |\settabs| in |{...}|, the tabs defined inside a group
%don't affect the tabs outside; `^|\global||\settabs|' is not permitted.
\danger 一旦声明了命令 |\settabs|, 制表符就一直保持到你重新设置为止,
即使你输入的是象平常那样的普通段落。%
但是,如果把 |\settabs| 封装在 |{...}| 中,
定义在组中的制表符不会影响外面的制表符;
不允许使用`^|\global||\settabs|'。
%\danger Tabbed lines usually are used between paragraphs, in the same
%places where you would type ^|\line| or ^|\centerline| to get lines with
%a special format. But it's also useful to put |\+|~lines inside a |\vbox|;
%this makes it convenient to specify ^{displays} that contain aligned
%material. For example, if you type
%\begintt
%$$\vbox{\settabs 3 \columns
% \+This is&a strange&example\cr
% \+of displayed&three-column&format.\cr}$$
%\endtt
%you get the following display:
%$$\vbox{\settabs 3 \columns
% \+This is&a strange&example\cr
% \+of displayed&three-column&format.\cr}$$
%In this case the first column doesn't appear flush left, because \TeX\
%centers a box that is being displayed. Columns that end with |\cr| in
%a |\+|~line are put into a box with their natural width; so the first
%and second columns here are one-third of the |\hsize|, but the third column
%is only as wide as the word `example'. We have used |$$| ^^{dollardollar}
%in this construction even though no mathematics is involved, because |$$|
%does other useful things; for example, it centers the box, and it inserts
%space above and below.
\danger 制表的行通常用在段落之间,与使用 |\line| 或 |\centerline| 的位置一样,%
它们得到也是特殊形式的行。%
但是,把 |\+| 的行放在 |\vbox| 也是有用处的;
用它可以很方便地给出包含对齐内容的陈列公式。
例如,如果给出
\begindisplay
|$$\vbox{\settabs 3 \columns|\cr
| \+|这是|&|陈列方程|&|三栏|\cr|\cr
| \+|格式的|&|一个奇怪|&|例子。|\cr}$$|\cr
\enddisplay
你所得到的是下列陈列公式:
$$\vbox{\settabs 3 \columns
\+这是&陈列方程&三栏\cr
\+格式的&一个奇怪&例子。\cr}$$
在这种情况下,第一栏没有居左,
这是因为 \TeX\ 把陈列公式的盒子居中了。%
在 |\+| 的行中,要把以 |\cr| 结尾的栏中内容放在其自然宽度的盒子中;
因此,这里的第一和第二栏的宽度是 |\hsize| 的三分之一,
但是第三栏的宽度为文本``例子。''的宽度。%
在这个构造中,即使没有任何数学内容,我们也用了 |$$|,
这是因为 |$$| 自有其用处;例如,它把盒子居中,并且在上下插入了间距。
%People don't always want tabs to be equally spaced, so there's another
%way to set them, by typing `|\+|\<sample line>|\cr|' immediately after
%`|\settabs|'. In this case tabs are placed at the positions
%of the |&|'s in the ^{sample line}, and the sample line itself does not appear
%in the output. For example,
%\begintt
%\settabs\+\indent&Horizontal lists\quad&\cr % sample line
%\+&Horizontal lists&Chapter 14\cr
%\+&Vertical lists&Chapter 15\cr
%\+&Math lists&Chapter 17\cr
%\endtt
%causes \TeX\ to typeset the following three lines of material:
%\nobreak\medskip
%\settabs\+\indent&Horizontal lists\quad&\cr
%\+&Horizontal lists&Chapter 14\cr
%\+&Vertical lists&Chapter 15\cr
%\+&Math lists&Chapter 17\cr
%\medbreak\noindent
%The |\settabs| command in this example makes column~1 as wide as a paragraph
%^^{indention, see indentation}
%indentation; and column~2 is as wide as `Horizontal lists' plus one quad of
%space. ^^|\quad| Only two tabs are set in this case, because only two |&|'s
%appear in the sample line. \ (A sample line might as well end with~|&|,
%because the text following the last tab isn't used for anything.)
人们还希望非等分的制表阵列,因此我们提供了另一种方法:
在 `|\settabs|' 紧接着给出 `|\+|\<sample line>\allowbreak|\cr|'。
在这种情况下,制表符被放在例句中 |&| 的位置上,
并且例句自己并不出现在输出中。例如,
\begintt
\settabs\+\indent&Horizontal lists\quad&\cr % sample line
\+&Horizontal lists&Chapter 14\cr
\+&Vertical lists&Chapter 15\cr
\+&Math lists&Chapter 17\cr
\endtt
排版出下列三行内容:
\nobreak\medskip
\settabs\+\indent&Horizontal lists\quad&\cr
\+&Horizontal lists&Chapter 14\cr
\+&Vertical lists&Chapter 15\cr
\+&Math lists&Chapter 17\cr
\medbreak\noindent
\1在本例中,命令 |\settabs| 使第一栏宽度与段落的缩进一样宽;
第二栏与`Horizontal lists'加上一个 quad 间距的宽度一样。%
在本例中只设定了两个栏的宽度,因为在例句中只出现了两个 |&|。%
(例句也可以用 |&| 来结尾,因为跟着最后一个制表符的文本没起什么作用。)
%The first line of a table can't always be used as a sample line, because it
%won't necessarily give the correct tab positions. In a large table you have
%to look ahead and figure out the biggest entry in each column; the sample
%line is then constructed by typing the widest first column, the widest
%second column, etc., omitting the last column. Be sure to include some
%extra space between columns in the sample line, so that the columns
%won't touch each other.
表格的第一行并不能总是作为例句使用,
因为它有时候不能给出正确的制表符位置。%
在一个大表格中,你必须浏览一下,找出每个栏中最大的单元;
这样,例句就由最宽的第一栏,最宽的第二栏,等等,忽略掉最后一栏这样来构造。%
在例句中要确保有某些额外的间距,这样栏才不会互相紧挨着。
%\def\frac#1/#2{\leavevmode\kern.1em
% \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
% /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
%\exercise Explain how to typeset the following table [from Beck,
%Bertholle, and Child, {\sl Mastering the Art of French Cooking\/}
%(New York: Knopf, 1961)]: % p283
%^^{Beck, Simone} ^^{Bertholle, Louisette} ^^{Child, Julia}
%\nobreak\medskip
%\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
%\+&\negthinspace\it Weight&\it Servings&
% {\it Approximate Cooking Time\/}*\cr
%\smallskip
%\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
%\+&9 lbs.&7 to 8&About 2 hours\cr
%\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
%\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
%\smallskip
%\+&* For a stuffed goose,
% add 20 to 40 minutes to the times given.\cr
%\answer Notice the uses of `|\smallskip|' here to separate the table heading
%and footing from the table itself; such refinements are often worthwhile.
%\begintt
%\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
%\+&\negthinspace\it Weight&\it Servings&
% {\it Approximate Cooking Time\/}*\cr
%\smallskip
%\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
%\+&9 lbs.&7 to 8&About 2 hours\cr
%\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
%\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
%\smallskip
%\+&* For a stuffed goose,
% add 20 to 40 minutes to the times given.\cr
%\endtt
%\def\frac#1/#2{\leavevmode\kern.1em
% \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
% /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}%
%The title line specifies `|\it|' three times, because each entry between
%tabs is treated as a group by \TeX; you would get error messages galore
%if you tried to say something like \hbox{`|\+&{\it Weight&Servings&...}\cr|'}.
%The `^|\negthinspace|' in the title line is a small backspace that
%compensates for the slant in an italic {\it W\/}; the author inserted
%this somewhat unusual correction after seeing how the table looked
%without it, on the first proofs. \ (You weren't supposed to think of this,
%but it has to be mentioned.) \ See exercise 11.\fracexno\ for the `|\frac|'
%macro; it's better to say `\frac1/2' than `$1\over2$', in a cookbook.\par
%Another way to treat this table would be to display it in a vbox, instead
%of including a first column whose sole purpose is to specify indentation.
\def\frac#1/#2{\leavevmode\kern.1em
\raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
\exercise 看看怎样排版下列表格 [取自 Beck, Bertholle, and Child,
{\sl Mastering the Art of French Cooking\/}
(New York: Knopf, 1961)]:% p283
^^{Beck, Simone} ^^{Bertholle, Louisette} ^^{Child, Julia}
\nobreak\medskip
\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
\+&\negthinspace\it Weight&\it Servings&
{\it Approximate Cooking Time\/}*\cr
\smallskip
\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
\+&9 lbs.&7 to 8&About 2 hours\cr
\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
\smallskip
\+&* For a stuffed goose,
add 20 to 40 minutes to the times given.\cr
\answer 注意这里用 `|\smallskip|' 将表头和表尾与表格本身分开;
这种改进通常是值得做的。
\begintt
\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
\+&\negthinspace\it Weight&\it Servings&
{\it Approximate Cooking Time\/}*\cr
\smallskip
\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
\+&9 lbs.&7 to 8&About 2 hours\cr
\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
\smallskip
\+&* For a stuffed goose,
add 20 to 40 minutes to the times given.\cr
\endtt
\def\frac#1/#2{\leavevmode\kern.1em
\raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}%
标题行三次指定 `|\it|',是因为每个单元都被 \TeX\ 视为一个编组;
如果你试图用 \hbox{`|\+&{\it Weight&Servings&...}\cr|'},会有很多错误信息。
标题行的 `^|\negthinspace|' 是一个微小的回退空白,
用于补偿意大利体 {\it W\/} 的倾斜;在首次校对看到当时的表格后,
作者后插入这个有些不常用的校正。(不指望你会想到这个,但必须提到它。)%
见练习 11.\fracexno 中的 `|\frac|' 宏;
在食谱中用 `\frac1/2' 比用 `$1\over2$' 更好。\par
处理这个表格的另一种方法是在 vbox 中显示它,而不是包含单纯为指定缩进的第一栏。
%\ninepoint % it's all dangerous from here to end of chapter
%\danger If you want to put something ^{flush right} in its column, just type
%`^|\hfill|' before it; and be sure to type `|&|' after it, so that
%\TeX\ will be sure to move the information all the way until it touches
%the next tab. Similarly, if you want to ^{center} something in its
%column, type `|\hfill|' before it and `|\hfill&|' after it. For example,
%\begintt
%\settabs 2 \columns
%\+\hfill This material is set flush right&
% \hfill This material is centered\hfill&\cr
%\+\hfill in the first half of the line.&
% \hfill in the second half of the line.\hfill&\cr
%\endtt
%produces the following little table:\enddanger
%\nobreak\medskip
%\settabs 2 \columns
%\+\hfill This material is set flush right&
% \hfill This material is centered\hfill&\cr
%\+\hfill in the first half of the line.&
% \hfill in the second half of the line.\hfill&\cr
\ninepoint % it's all dangerous from here to end of chapter
\danger 如果要把某些内容在栏中居右,就在其前面使用`^|\hfill|';
并且在其后要有`|&|', 这样就确保了 \TeX\ 排版的是下一个制表符前面的所有内容。%
类似地,要把某些内容在栏中居中,在前面使用`|\hfill|', 在后面使用`|\hfill&|'。%
例如,
\begindisplay
|\settabs 2 \columns|\cr
|\+\hfill |此内容在前半行|&|\cr
| \hfill |此内容在后半行|\hfill&\cr|\cr
|\+\hfill |居右。|&|\cr
| \hfill |居中。|\hfill&\cr|\cr
\enddisplay
得到的是下列小表格:\enddanger
\nobreak\medskip
\settabs 2 \columns
\+\hfill 此内容在前半行&
\hfill 此内容在后半行\hfill&\cr
\+\hfill 居右。&
\hfill 居中。\hfill&\cr
%\danger The |\+| macro in Appendix~B works
%by putting the \<text> for each column that's followed by~|&|
%into an hbox as follows:
%\begindisplay
%|\hbox to |\<column width>|{|\<text>|\hss}|
%\enddisplay
%The ^|\hss| means that the text is normally flush left, and that it can
%extend to the right of its box. Since |\hfill| is ``more infinite'' than
%|\hss| in its ability to stretch, it has the effect of right-justifying or
%centering as stated above. Note that |\hfill| doesn't shrink, but |\hss|
%does; if the text doesn't fit in its column, it will stick out at the right.
%You could avoid this by adding |\hskip| |0pt| |minus-1fil|; then
%an oversize text would produce an overfull box.
%You could also center some text by putting `|\hss|' before it and just
%`|&|' after it; in that case the text would be allowed to extend to the
%left and right of its column.
% The last column of a |\+|~line (i.e., the column entry that is
%followed by |\cr|) is treated differently: The
%\<text> is simply put into an hbox with its natural~width.\looseness=-1
\danger 附录 B 中的宏 |\+| 是把跟在 |&| 后每栏的 \<text> 放在如下%
的一个 hbox 中:
\begindisplay
|\hbox to |\<column width>|{|\<text>|\hss}|
\enddisplay
|\hss| 就意味着文本在正常情况下是居左的,并且它可以延伸到盒子的右边。%
因为 |\hfill| 比 |\hss| 的伸缩能力更强,所以可以得到上面的居右或居中的效果。%
注意,~|\hfill| 不收缩,但是 |\hss| 收缩;
如果文本在栏中放不下,它将在右边伸出来。%
通过添加 |\hfilneg| 可以取消 |\hss| 的收缩性;
这样,超过尺寸的文本得到的就是一个溢出的盒子。%
你还可以把`|\hss|'放在此内容前面或其后`|&|'紧前面来把它居中;
在这种情况下,文本允许从左右两边伸出栏。%
\1|\+| 行的最后一栏(即,跟着 |\cr| 的栏单元)的处理方法不同:
只把文本放在其自然宽度的 hbox 中。
%\danger ^{Computer programs} present difficulties of a different kind, since
%some people like to adopt a style in which the tab positions change from
%line to line. For example, consider the following program fragment:
%$$\vbox{\+\bf if $n<r$ \cleartabs&\bf then $n:=n+1$\cr
% \+&\bf else &{\bf begin} ${\it print\_totals}$; $n:=0$;\cr
% \+&&{\bf end};\cr
% \+\bf while $p>0$ do\cr
% \+\quad\cleartabs&{\bf begin} $q:={\it link}(p)$;
% ${\it free\_node}(p)$; $p:=q$;\cr
% \+&{\bf end};\cr}$$
%Special tabs have been set up so that `{\bf then}' and `{\bf else}' appear
%one above the other, and so do `{\bf begin}' and `{\bf end}'. It's possible
%to achieve this by setting up a new sample line whenever a new tab position
%is needed; but that's a tedious job, so plain \TeX\ makes it a little simpler.
%Whenever you type |&| to the right of all existing tabs, the effect is to
%set a new tab there, in such a way that the column just completed will have
%its natural width. Furthermore, there's an operation `^|\cleartabs|' that
%resets all tab positions to the right of the current column. Therefore the
%computer program above can be \TeX ified as follows:
%\begindisplay
%|$$\vbox{\+\bf if $n<r$ \cleartabs&\bf then $n:=n+1$\cr|\cr
%| \+&\bf else &{\bf begin} ${\it print\_totals}$; $n:=0$;\cr|\cr
%| \+&&{\bf end};\cr|\cr
%| |\<The remaining part is left as an exercise>|}$$|\cr
%\enddisplay
\danger 计算机程序出现的是另一种不同的困难,
因为在一种格式中需要行和行之间的制表符位置不断变化。%
例如,看看下列程序片段:
$$\vbox{\+\bf if $n<r$ \cleartabs&\bf then $n:=n+1$\cr
\+&\bf else &{\bf begin} ${\it print\_totals}$; $n:=0$;\cr
\+&&{\bf end};\cr
\+\bf while $p>0$ do\cr
\+\quad\cleartabs&{\bf begin} $q:={\it link}(p)$;
${\it free\_node}(p)$; $p:=q$;\cr
\+&{\bf end};\cr}$$
要设置特殊的制表符使得`{\bf then}'出现在`{\bf else}'上面,
并且`{\bf begin}'出现在`{\bf end}'上面。%
只要需要新的制表符位置,就可以通过设置新的例句来得到它;
但是这是一项无聊的工作,因此 plain \TeX\ 给出了一种简单方法。%
只要在已经有的制表符右边给出 |&|, 就在那里设定了一个新的制表符,
用这种方法,栏都处在自然宽度的盒子中。%
还有,用命令`^|\cleartabs|'可以重新设置当前栏右边的所有制表符的位置。%
因此,上面的计算机程序可以如下用 \TeX\ 排版:
\begindisplay
|$$\vbox{\+\bf if $n<r$ \cleartabs&\bf then $n:=n+1$\cr|\cr
| \+&\bf else &{\bf begin} ${\it print\_totals}$; $n:=0$;\cr|\cr
| \+&&{\bf end};\cr|\cr
| |\<剩下的作为练习>|}$$|\cr
\enddisplay
%\dangerexercise Complete the example computer program by specifying three more
%|\+|~lines.
%\answer In such programs it seems best to type |\cleartabs| just before |&|,
%whenever it is desirable to reset the old tabs. Multiletter identifiers look
%best when set in ^{text italics} with ^|\it|, as explained in Chapter~18.
%Thus, the following is recommended:
%\begintt
%\+\bf while $p>0$ do\cr
% \+\quad\cleartabs&{\bf begin} $q:={\it link}(p)$;
% ${\it free\_node}(p)$; $p:=q$;\cr
% \+&{\bf end};\cr
%\endtt
\dangerexercise 完成上面例子中的计算机程序。
\answer 在这种程序中,看来最好是在 |&| 之前键入 |\cleartabs|,只要需要重设旧制表符。
多字母的标识符用 ^|\it| 设为意大利体是最好看,如同在第 18 章中解释的。
因此,推荐的写法如下:
\begintt
\+\bf while $p>0$ do\cr
\+\quad\cleartabs&{\bf begin} $q:={\it link}(p)$;
${\it free\_node}(p)$; $p:=q$;\cr
\+&{\bf end};\cr
\endtt
%\danger Although |\+| lines can be used in vertical boxes, you must never
%use |\+| inside of another |\+| line. The |\+| macro is intended for
%simple applications only.
\danger 虽然行 |\+| 可以用在垂直盒子中,但是不要在 |\+| 行中使用另一个 |\+|。%
宏 |\+| 只能单个使用。
%\ddanger The |\+| and |\settabs| macros of Appendix B keep track of tabs by
%maintaining register |\box|^|\tabs| as a box full of empty boxes whose
%widths are the column widths in reverse order. Thus you can examine the
%tabs that are currently set, by saying `^|\showbox||\tabs|'; this puts
%the column widths into your log file, from right to left. For example,
%after `|\settabs\+\hskip100pt&\hskip200pt&\cr\showbox\tabs|', \TeX\
%will show the lines
%\begintt
%\hbox(0.0+0.0)x300.0
%.\hbox(0.0+0.0)x200.0
%.\hbox(0.0+0.0)x100.0
%\endtt
\ddanger 附录 B 中的宏 |\+| 和 |\settabs| 是这样记录制表符的:
让盒子寄存器 |\box|^|\tabs| 以逆序包含宽度等于各栏宽度的空盒子。
因此,用 `^|\showbox||\tabs|' 可以检验当前设置的制表符;
它把栏宽度按照从右到左的顺序显示在你的日志文件中。例如,在给出
`|\settabs\+\hskip100pt&|\allowbreak|\hskip200pt&\cr\showbox\tabs|' 后,
\TeX\ 将显示出下列行:
\begintt
\hbox(0.0+0.0)x300.0
.\hbox(0.0+0.0)x200.0
.\hbox(0.0+0.0)x100.0
\endtt
%\ddangerexercise Study the |\+| macro in Appendix B and figure out how to
%change it so that tabs work as they do on a mechanical typewriter
%(i.e., so that `|&|' always moves to the next tab that lies strictly
%to the right of the current position). Assume that the user
%doesn't backspace past previous tab positions; for example, if the input is
%\hbox{`|\+&&\hskip-2em&x\cr|'}, do not bother to put `x' in the first or
%second column, just put it at the beginning of the third column. \
%(This exercise is a bit difficult.)
%\answer Here we retain the idea that |&| inserts a new tab, when there
%are no tabs to the right of the current position. Only one of the macros
%that are used to process |\+|~lines needs to be changed; but
%(unfortunately) it's the most complex one:
%\begintt
%\def\t@bb@x{\if@cr\egroup % now \box0 holds the column
% \else\hss\egroup \dimen@=0\p@
% \dimen@ii=\wd0 \advance\dimen@ii by1sp
% \loop\ifdim \dimen@<\dimen@ii
% \global\setbox\tabsyet=\hbox{\unhbox\tabsyet
% \global\setbox1=\lastbox}%
% \ifvoid1 \advance\dimen@ii by-\dimen@
% \advance\dimen@ii by-1sp \global\setbox1
% =\hbox to\dimen@ii{}\dimen@ii=-1pt\fi
% \advance\dimen@ by\wd1 \global\setbox\tabsdone
% =\hbox{\box1\unhbox\tabsdone}\repeat
% \setbox0=\hbox to\dimen@{\unhbox0}\fi
% \box0}
%\endtt
\ddangerexercise 研究一下附录 B 中的宏 |\+|,
看看怎样让它像打字机的制表符那样使用%
(即使得 `|&|' 总是移动到当前位置右边的下一个制表符处)。
假定用户不能回退到前一个制表符的位置;
例如,如果输入 \hbox{`|\+&&\hskip-2em&x\cr|'},
不用费心将 `x' 放在第一和第二栏,只需把它放在第三栏的开头。(这个练习有点难。)
\answer 这里我们保留在当前位置右边没有制表符时,用 |&| 插入新制表符的想法。
用于处理 |\+| 行的宏中只有一个需要修改;但(很不幸)它就是最复杂的那个:
\begintt
\def\t@bb@x{\if@cr\egroup % now \box0 holds the column
\else\hss\egroup \dimen@=0\p@
\dimen@ii=\wd0 \advance\dimen@ii by1sp
\loop\ifdim \dimen@<\dimen@ii
\global\setbox\tabsyet=\hbox{\unhbox\tabsyet
\global\setbox1=\lastbox}%
\ifvoid1 \advance\dimen@ii by-\dimen@
\advance\dimen@ii by-1sp \global\setbox1
=\hbox to\dimen@ii{}\dimen@ii=-1pt\fi
\advance\dimen@ by\wd1 \global\setbox\tabsdone
=\hbox{\box1\unhbox\tabsdone}\repeat
\setbox0=\hbox to\dimen@{\unhbox0}\fi
\box0}
\endtt
%\danger \TeX\ has another important way to make tables, using an operation
%called ^|\halign| (``horizontal alignment''). In this case the table format
%is based on the notion of a {\sl^{template}}, not on tabbing; the idea
%is to specify a separate environment for the text in each column.
%Individual entries are inserted into their templates, and presto, the
%table is complete.
\danger \1\TeX\ 还有制表的另一种重要方法,就是使用命令 |\halign|(``水平对齐'')。%
在这种情况下,表格的样式建立在{\KT{9}模板}的概念上,而不是制表;
思路是在每栏中给出一个单独的文本环境。%
各个单元插入到其模板中,这样很快就制作出表格了。
%\danger For example, let's go back to the Horizontal/Vertical/Math list
%example that appeared earlier in this chapter; we can specify it with
%|\halign| instead of with tabs. The new specification is
%\begintt
%\halign{\indent#\hfil&\quad#\hfil\cr
% Horizontal lists&Chapter 14\cr
% Vertical lists&Chapter 15\cr
% Math lists&Chapter 17\cr}
%\endtt
%and it produces exactly the same result as the old one. This example
%deserves careful study, because |\halign| is really quite simple once
%you get the hang of it. The first line contains the {\sl ^{preamble}\/} to
%the alignment, which is something like the sample line used to set tabs
%for~|\+|. In this case the preamble contains two templates, namely
%`|\indent#\hfil|' for the first column and `|\quad#\hfil|' for the
%second. Each template contains exactly one appearance of `|#|', ^^{sharp}
%and it means ``stick the text of each column entry in this place.''
%Thus, the first column of the line that follows the preamble becomes
%\begintt
%\indent Horizontal lists\hfil
%\endtt
%when `|Horizontal lists|' is stuffed into its template; and the second
%column, similarly, becomes `|\quad Chapter 14\hfil|'. The question is,
%why |\hfil|? Ah, now we get to the interesting point of the whole thing:
%\TeX\ reads an entire |\halign{...}| specification into its memory
%before typesetting anything, and it keeps track of the maximum width
%of each column, assuming that each column is set without stretching or
%shrinking the glue. Then it goes back and puts every entry into a box,
%setting the glue so that each box has the maximum column width. That's
%where the |\hfil| comes in; it stretches to fill up the extra space in
%narrower entries.
\danger 例如,再回头看看在本章前面出现过的水平/垂直/数学列的例子;
我们可以不用制表符,而用 |\halign| 来得到它。%
新方法是
\begintt
\halign{\indent#\hfil&\quad#\hfil\cr
Horizontal lists&Chapter 14\cr
Vertical lists&Chapter 15\cr
Math lists&Chapter 17\cr}
\endtt
并且它得到的结果与原来的一样。%
这个例子值得仔细研究,因为一旦你掌握了 |\halign| 的窍门,它实际上就相当简单了。%
第一行包含了对齐的{\KT{9}导言}, 它有点象设置 |\+| 的制表符例句。%
在本例中,导言包含两个模板,即第一栏的`|\indent#\hfil|'和%
第二栏的`|\quad#\hfil|'。%
每个模板正好出现一次`|#|',
它的意思是``每个栏单元的文本放在此处''。%
因此,当用`|Horizontal lists|'来填充其模板时,导言后面的行的第一栏就变成
\begintt
\indent Horizontal lists\hfil
\endtt
类似地,第二栏变成`|\quad Chapter 14\hfil|'。%
问题是,为什么要用 |\hfil|?
噢,现在我们渐入佳境了:
\TeX\ 在排版之前首先把整个 |\halign{...}| 的内容读入其内存,
并且确定每栏的最大宽度,假定每栏都没有设置伸缩的粘连。%
这时,它才回过头来把每个单元放在一个盒子中,
并且设定粘连使得每个盒子的栏宽度都是最大的。%
这就是为什么要用到 |\hfil|;
它在窄单元中伸长以充满额外的空间。
%\dangerexercise What table would have resulted if the template for the
%first column in this example had been `|\indent\hfil#|' instead of
%`|\indent#\hfil|'?
%\answer \par\nobreak\vskip-\baselineskip
%\halign{\indent\hfil#&\quad#\hfil\cr
%Horizontal lists&Chapter 14\cr\noalign{\nobreak}
%Vertical lists&Chapter 15\cr\noalign{\nobreak}
%Math lists&Chapter 17\qquad (i.e., the first column would be
% right-justified)\cr}
\dangerexercise 如果在本例第一栏的模板中用 `|\indent\hfil#|'
代替 `|\indent#\hfil|',得到的表格是什么样?
\answer \par\nobreak\vskip-\baselineskip
\halign{\indent\hfil#&\quad#\hfil\cr
Horizontal lists&Chapter 14\cr\noalign{\nobreak}
Vertical lists&Chapter 15\cr\noalign{\nobreak}
Math lists&Chapter 17\qquad (即第一栏将是右对齐的)\cr}
%\danger Before reading further, please make sure that you understand the
%idea of templates in the example just presented. There are several
%important differences between |\halign| and~|\+|: (1)~|\halign| calculates
%^^{halign compared to tabbing}
%the maximum column widths automatically; you don't have to guess what the
%longest entries will be, as you do when you set tabs with a sample line.
%(2)~Each |\halign| does its own calculation of column widths; you have to
%do something special if you want two different |\halign| operations to
%produce identical alignments. By contrast, the |\+| operation remembers tab
%positions until they are specifically reset; any number of paragraphs and
%even |\halign| operations can intervene between |\+|'s, without affecting
%the tabs. (3)~Because |\halign| reads an entire table in order to
%determine the maximum column widths, it is unsuitable for huge tables
%that fill several pages of a book. By contrast, the~|\+|~operation deals
%with one line at a time, so it places no special demands on \TeX's memory.
%\ (However, if you have a huge table, you should probably define your own
%special-purpose macro for each line instead of relying on the general
%|\+|~operation.) (4)~|\halign| takes less computer time than |\+|~does,
%because |\halign| is a built-in command of \TeX, while |\+|~is a macro
%that has been coded in terms of\/ |\halign| and various other primitive
%operations. (5)~Templates are much more versatile than tabs, and they can
%save you a lot of typing. For example, the Horizontal/Vertical/Math list
%table could be specified more briefly by noticing that there's common
%information in the columns:
%\begintt
%\halign{\indent# lists\hfil&\quad Chapter #\cr
% Horizontal&14\cr Vertical&15\cr Math&17\cr}
%\endtt
%You could even save two more keystrokes by noting that the chapter numbers
%all start with `|1|'\thinspace! \ (Caution: It takes more time to think of
%optimizations like this than to type things in a straightforward way;
%do it only if you're bored and need something amusing to keep up
%your interest.)\ (6)~On the other hand, templates are no substitute for
%tabs when the tab positions are continually varying, as in the
%computer program example.
\danger 在进一步读下去前,一定要理解了刚才例子中模板的思想。%
在 |\halign| 和 |\+| 之间有结果重要的差别:
(1). ~|\halign| 自动计算最大栏宽度;
不必去估计最长的单元是哪个,就象在例句中设置制表符时所做的那样。%
(2). 每个 |\halign| 要计算自己的栏宽度;
如果要让两个不同的 |\halign| 命令得到同样的对齐,就必须做特殊处理。%
相反,命令 |\+| 一直记着制表符的位置,直到它们被重新设定为止;
在 |\+| 之间插入任意个段落,甚至插入命令 |\halign| 也不影响制表符。%
(3). 因为 |\halign| 为了计算最大栏宽度要读入整个表格,
所以它不适宜用在书中横贯几页的大表格。%
相反,命令 |\+| 一次只处理一行,因此它对 \TeX\ 内存中没有什么特殊要求。%
(但是,如果要生成一个大表格,可能你要为每行定义特殊的宏而不是只靠一般的%
~|\+| 命令。)
(4). \1|\halign| 花的计算机时间比 |\+| 少,
因为 |\halign| 是 \TeX\ 的内置命令,而 |\+| 是一个宏,它由 |\halign| 和其它%
原始命令一起构成。%
(5). 模板比制表符更通用,并且节省很多输入工作量。%
例如,水平/垂直/数学列的表格中,如果注意到栏中的公共部分,就可以如下%
更简洁地输入它:
\begintt
\halign{\indent# lists\hfil&\quad Chapter #\cr
Horizontal&14\cr Vertical&15\cr Math&17\cr}
\endtt
甚至于如果注意到了章的编号以`|1|'开头,那么还可以节省两次击键!
(注意:可能象这样优化比直接输入花费的时间更多;
只有你无聊或寻乐时再用它。)
(6). 另一方面,模板不能代替制表符,因为制表符的位置是连续变化的,
就象在计算机程序的例子中一样。
%\danger Let's do a more interesting table, to get more
%experience with |\halign|. Here is another example based on the
%^{Beck}/^{Bertholle}/^{Child} book cited earlier:
%$$\vbox{\openup2pt
%\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&
% \quad\hfil#\hfil&\quad#\hfil\cr
%\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
%\noalign{\vskip-2pt}
%\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
%\noalign{\smallskip}
%Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
%Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
%Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
%Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr
%Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr
%Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr}}$$
%Note that, except for the title lines, the first column is set right-justified
%in boldface type; the middle columns are centered; the second column
%is centered and in italics; the final column is left-justified. We would
%like to be able to type the rows of the table as simply as possible; hence,
%for example, it would be nice to be able to specify the bottom row by
%typing only
%\begintt
%Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr
%\endtt
%without worrying about type styles, centering, and so on. This not only
%cuts down on keystrokes, it also reduces the chances for making typographical
%errors. Therefore the template for the first column should be
%`|\hfil\bf#|'; for the second column it should be `|\hfil\it#\hfil|' to
%get the text centered and italicized; and so on. We also need to allow
%for space between the columns, say one quad. {\it Voil\`a! La typographie
%est sur la table:\/}\looseness=-1
%\begindisplay
%|\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&|\cr
%| \quad\hfil#\hfil&\quad#\hfil\cr|\cr
%\ \<the title lines>\cr
%| Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr|\cr
%| ... Forcemeat\cr}|\cr
%\enddisplay
%As with the |\+| operation, spaces are ignored after |&|, in the preamble
%as well as in the individual rows of the table. Thus, it is convenient
%to end a long row with `|&|' when the~row takes up more than one line
%in your input file.
\danger 我们用一个更有意思的表格来进一步熟悉 |\halign|。%
下面是另一个例子:
$$\vbox{\openup2pt
\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&
\quad\hfil#\hfil&\quad#\hfil\cr
\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
\noalign{\vskip-2pt}
\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
\noalign{\smallskip}
Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr
Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr
Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr}}$$
注意,除了标题行外,第一栏的设置为居右,使用 bold 字体;
中间的栏是居中的;
第二栏居中,使用的是 italic 字体;
最后一栏是居左。%
我们希望尽可能简单地输入表格的行;
因此,例如,最好是只用输入
\begintt
Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr
\endtt
就能得到最后一行,而不用管字体,居中与否等等。%
这不但减小输入工作量,还能减少输入中的错误。%
因此,第一栏的模板应该是`|\hfil\bf#|';
第二栏的模板应该是`|\hfil\it#\hfil|', 得到的是居中的 italic 文本;
等等。%
我们还要在栏之间插入一定的间距,比如一个 quad。%
\begindisplay
|\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&|\cr
| \quad\hfil#\hfil&\quad#\hfil\cr|\cr
\ \<the title lines>\cr
| Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr|\cr
| ... Forcemeat\cr}|\cr
\enddisplay
就象 |\+| 命令一样,在导言研究表格的各个行中,~|&| 后面的空格被忽略掉。%
因此,当输入文件中表格的行要占多行时,用`|&|'来结束长的行是很方便的。
%\dangerexercise How was the `{\bf Fowl}' line typed? \ (This is too easy.)
%\answer |Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr|
\dangerexercise \1怎样输入 `{\bf Fowl}' 这行?(这太简单了。)
\answer |Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr|
%\danger The only remaining problem in this example is to specify the title
%lines, which have a different format from the others. In this case the style
%is different only because the typeface is slanted, so there's no special
%difficulty; we just type
%\begintt
%\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
%\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
%\endtt
%It is necessary to say `|\sl|' each time, because each individual entry
%of a table is implicitly enclosed in braces.
\danger 在本例中,还有一个问题,就是给出标题行,
它的格式与别的行是不一样的。%
在这种情况下,格式的差别只在于字体是 slanted, 因此没什么特别难的;
我们只需要用
\begintt
\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
\endtt
每次必须给出`|\sl|', 因为表格的每个单元都暗中封装在大括号中了。
%\danger The author used `^|\openup||2pt|' to increase the distance between
%baselines in the ^{poultry} table; a discriminating reader will notice
%that there's also a bit of extra space between the title line and the
%other lines. This extra space was inserted by typing
%`^|\noalign||{\smallskip}|' just after the title line. In general, you can say
%\begindisplay
%|\noalign{|\<vertical mode material>|}|
%\enddisplay
%just after any |\cr| in an |\halign|; \TeX\ will simply copy the vertical
%mode material, without subjecting it to alignment, and it will appear
%in place when the |\halign| is finished. You can use |\noalign| to
%insert extra space, as here, or to insert penalties that affect page
%breaking, or even to insert lines of text (see Chapter~19). Definitions
%inside the braces of\/ |\noalign{...}| are local to that group.
\danger 在上面的表格中,作者用`^|\openup||2pt|'来增加基线间的距离;
眼尖的读者还会发现在标题行和其它行之间也有额外的间距。%
这个额外的间距是由标题行紧后面的`^|\noalign||{\smallskip}|'插入的。%
一般地,在 |\halign| 的任意 |\cr| 紧后面都可以使用
\begindisplay
|\noalign{|\<vertical mode material>|}|
\enddisplay
\TeX\ 将直接重复这些垂直模式的内容,而不把它进行对齐,
并且当 |\halign| 结束时它就出现在此处。%
你可以象这里一样用 |\noalign| 插入额外间距,或者插入控制分页的惩罚,
或者还可插入文本行(见第十九章)。%
在 |\noalign| 的大括号中的定义的影响局限在此组内。
%\danger The |\halign| command also makes it possible for you to adjust
%the spacing between columns so that a table will fill a specified area.
%You don't have to decide that the ^{inter-column space} is a quad; you can
%let \TeX\ make the decisions, based on how wide the columns come out,
%because \TeX\ puts ``^{tabskip glue}'' between columns. This tabskip glue
%is usually zero, but you can set it to any value you like by saying
%`^|\tabskip||=|\<glue>'. For example,
%let's do the poultry table again, but with the beginning of the
%specification changed as follows:
%\begintt
%\tabskip=1em plus2em minus.5em
%\halign to\hsize{\hfil\bf#&\hfil\it#\hfil&\hfil#\hfil&
% \hfil#\hfil&#\hfil\cr
%\endtt
%The main body of the table is unchanged, but the |\quad| spaces have been
%removed from the preamble, and a nonzero |\tabskip| has been specified
%instead. Furthermore `|\halign|' has been changed to `|\halign
%to\hsize|'; this means that each line of the table will be put into a
%box whose width is the current value of\/ ^|\hsize|, i.e., the horizontal
%line width usually used in paragraphs. The resulting table looks like this:
%$$\vbox{\openup2pt
%\tabskip=1em plus2em minus.5em
%\halign to\hsize{\hfil\bf#&\hfil\it#\hfil&\hfil#\hfil&
% \hfil#\hfil&#\hfil\cr
%\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
%\noalign{\vskip-2pt}
%\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
%\noalign{\smallskip}
%Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
%Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
%Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
%Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr
%Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr
%Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr}}$$
\danger 命令 |\halign| 还可以用来调整栏之间的间距,
使得表格充满给定的区域。%
你不需要确定出栏间的间距是一个 quad;
可以让 \TeX\ 来决定,这是按照栏的宽度确定的,
因为 \TeX\ 在栏之间放置了``制表粘连''。%
这个制表粘连一般是零,但是你可以用`^|\tabskip||=|\<glue>'把它设置为任何所要的值。%
例如,再讨论上面的表格,但是把开头变成如下:
\begintt
\tabskip=1em plus2em minus.5em
\halign to\hsize{\hfil\bf#&\hfil\it#\hfil&\hfil#\hfil&
\hfil#\hfil&#\hfil\cr
\endtt
表格的主体没有改动,但是从导言中去掉了间距 |\quad|,
而用一个非零的 |\tabskip| 来代替。%
还有,`|\halign|'被改为`|\halign to\hsize|';
这意味着表格的每行都放在宽度为当前 |\hsize| 的值的盒子中,
即,段落中通常的水平行宽度。%
所得的结果如下:
$$\vbox{\openup2pt
\tabskip=1em plus2em minus.5em
\halign to\hsize{\hfil\bf#&\hfil\it#\hfil&\hfil#\hfil&
\hfil#\hfil&#\hfil\cr
\sl American&\sl French&\sl Age&\sl Weight&\sl Cooking\cr
\noalign{\vskip-2pt}
\sl Chicken&\sl Connection&\sl(months)&\sl(lbs.)&\sl Methods\cr
\noalign{\smallskip}
Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr
Fowl&Poule de l'Ann\'ee&10 to 12&Over 3&Stew, Fricassee\cr
Rooster&Coq&Over 12&Over 3&Soup stock, Forcemeat\cr}}$$
%\danger In general, \TeX\ puts tabskip glue before the first column, after
%the last column, and between the columns of an alignment. You can specify
%the final aligned size by saying `|\halign to|\<dimen>' or
%`|\halign spread|\<dimen>', ^^|to| ^^|spread|
%just as you can say `|\hbox to|\<dimen>' and `|\hbox spread|\<dimen>'.
%This specification governs the setting of the tabskip glue; but it does
%not affect the setting of the glue within column entries. \ (Those
%entries have already been packaged into boxes having the maximum
%natural width for their columns, as described earlier.)
\danger \1一般地, \TeX\ 把制表粘连放在第一栏之前,最后一栏之后和对齐的各栏之间。%
用`|\halign to|\<dimen>'或`|\halign spread|\<dimen>'就可以得到最后的对齐尺寸,
就象使用`|\hbox to|\<dimen>'和`|\hbox spread|\<dimen>'一样。%
这个命令控制着制表粘连的设置;
但是它不影响栏单元中粘连的设置。%
(象以前讨论过的那样,这些单元已经放在宽度为其自然宽度的盒子中了。)
%\ddanger Therefore `|\halign| |to| |\hsize|' will do nothing if the
%tabskip glue has no stretchability or shrinkability, except that it will
%cause \TeX\ to report an ^{underfull} or ^{overfull} box. An overfull box
%occurs if the tabskip glue can't shrink to meet the
%given specification; in this case you get a warning on the terminal
%and in your log file, but there is no ``^{overfull rule}'' to mark the
%oversize table on the printed output. The warning message shows a
%``^{prototype row}'' (see Chapter~27).
\ddanger 因此,如果制表粘连不能伸缩,那么`|\halign| |to| |\hsize|'得到的仅仅是%
松散或溢出的盒子而已。%
如果制表粘连不能收缩到给定尺寸,就出现了溢出的盒子;
在这种情况下,就会在终端和 log 文件中出现警告,
但是在输出结果中不会在超出尺寸的表格上标记黑方块。%
警告信息显示的是``模板行''(见第二十七章)。
%\danger The poultry example just given used the same tabskip glue
%everywhere, but you can vary it by resetting ^|\tabskip| within the
%preamble. The tabskip glue that is in force when \TeX\ reads the
%`|{|' following |\halign| will be used before the first column;
%the tabskip glue that is in force when \TeX\ reads the `|&|' after
%the first template will be used between the first and second
%columns; and so on. The tabskip glue that is in force when \TeX\
%reads the |\cr| after the last template will be used after the
%last column. For example, in
%\begintt
%\tabskip=3pt
%\halign{\hfil#\tabskip=4pt& #\hfil&
% \hbox to 10em{\hss\tabskip=5pt # \hss}\cr ...}
%\endtt
%the preamble specifies aligned lines that will consist of the following
%seven parts:
%\begindisplay
%tabskip glue $3\pt$;\cr
%first column, with template `|\hfil#|';\cr
%tabskip glue $4\pt$;\cr
%second column, with template `|#\hfil|';\cr
%tabskip glue $4\pt$;\cr
%third column, with template `|\hbox to 10em{\hss# \hss}|';\cr
%tabskip glue $5\pt$.\cr
%\enddisplay
\danger 上面给出的例子在所有地方用的都是同样的制表粘连,
但是可以在导言中重新设置 |\tabskip| 来改变它。%
\TeX\ 把在 |\halign| 后面的`|{|'前读入的制表粘连放在第一栏前面,
把第一个模板后面`|&|'前读入的制表粘连放在第一和第二栏之间;等等。%
在最后一个模板后面的 |\cr| 前读入的制表粘连放在最后一栏的后面。%
例如,在
\begintt
\tabskip=3pt
\halign{\hfil#\tabskip=4pt& #\hfil&
\hbox to 10em{\hss\tabskip=5pt # \hss}\cr ...}
\endtt
中,导言中给出了对齐的行,它包含下列七个部分:
\begindisplay
制表粘连 $3\pt$;\cr
第一栏,模板为`|\hfil#|';\cr