-
Notifications
You must be signed in to change notification settings - Fork 17
/
chapter05.tex
1425 lines (1301 loc) · 73.1 KB
/
chapter05.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 -*-
% Translated by [email protected]
% Date of translated: 2018-05-21
\documentclass{book}
\input{preamble}
\setcounter{chapter}{4}
\begin{document}
%\chapter{Boxes}\label{boxes}\index{boxes|(}
\chapter{盒子}\label{boxes}\index{盒子|(}
%The horizontal and vertical boxes of \TeX\ are containers for
%pieces of horizontal and vertical lists.
%Boxes can be stored in box registers.
%This chapter treats box registers and such
%aspects of boxes as their dimensions, and the way their components
%are placed relative to each other.
\TeX 中的水平与竖直盒子分别是水平与竖直列表内容的容器。盒子可保存在盒子寄存器当中。本章讨论盒子寄存器,以及关于盒子尺寸、盒子内容相互位置的问题。
\label{cschap:hbox}\label{cschap:vbox}\label{cschap:vtop}\label{cschap:vsplit}\label{cschap:box}\label{cschap:setbox}\label{cschap:copy}\label{cschap:ifhbox}\label{cschap:ifvbox}\label{cschap:ifvoid2}\label{cschap:newbox}\label{cschap:unhbox}\label{cschap:unvbox}\label{cschap:unhcopy}\label{cschap:unvcopy}\label{cschap:ht}\label{cschap:dp}\label{cschap:wd}\label{cschap:boxmaxdepth}\label{cschap:splitmaxdepth}\label{cschap:badness}\label{cschap:hfuzz}\label{cschap:vfuzz}\label{cschap:hbadness}\label{cschap:vbadness}\label{cschap:overfullrule}\label{cschap:hsize}\label{cschap:vsize}\label{cschap:lastbox}\label{cschap:raise}\label{cschap:lower}\label{cschap:moveleft}\label{cschap:moveright}\label{cschap:everyhbox}\label{cschap:everyvbox}
\begin{inventory}
%\item [\cs{hbox}]
% Construct a horizontal box.
\item [\cs{hbox}] 构造一个水平盒子。
%\item [\cs{vbox}]
% Construct a vertical box with reference point of the last item.
\item [\cs{vbox}] 构造一个竖直盒子,其参考点(reference point)是最后一个元素。
%\item [\cs{vtop}]
% Construct a vertical box with reference point of the first item.
\item [\cs{vtop}] 构造一个竖直盒子,其参考点是第一个元素。
%\item [\cs{vcenter}]
% Construct a vertical box vertically centred
% on the math axis; this command can only be used in math mode.
\item [\cs{vcenter}] 构造一个在竖直方向于数学轴(math axis)居中的竖直盒子;该命令仅在数学模式下使用。
%\item [\cs{vsplit}]
% Split off the top part of a vertical box.
\item [\cs{vsplit}] 将竖直盒子顶部部分分离。% TODO(Liam0205): 这里翻译需校正。
%\item [\cs{box}]
% Use a box register, emptying it.
\item [\cs{box}] 使用盒子寄存器,而后清空它。
%\item [\cs{setbox}]
% Assign a box to a box register.
\item [\cs{setbox}] 将盒子赋值给一个盒子寄存器。
%\item [\cs{copy}]
% Use a box register, but retain the contents.
\item [\cs{copy}] 使用盒子寄存器,但保留其中内容而不清空。
%\item [\cs{ifhbox} \cs{ifvbox}]
%\mdqon
% Test whether a box register contains a horizontal/""vertical box.
%\mdqoff
\item [\cs{ifhbox} \cs{ifvbox}] 判断盒子寄存器中保存的是水平盒子还是竖直盒子。
%\item [\cs{ifvoid}]
% Test whether a box register is empty.
\item [\cs{ifvoid}] 判断盒子寄存器是否为空。
%\item [\cs{newbox}]
% Allocate a new box register.
\item [\cs{newbox}] 分配新的盒子寄存器。
%\item [\cs{unhbox} \cs{unvbox}]
% Unpack a box register containing a horizontal/vertical box,
% adding the contents to the current horizontal/vertical list,
% and emptying the register.
\item [\cs{unhbox} \cs{unvbox}] 将保存有水平盒子或竖直盒子的寄存器解包,并将其中内容追加到当前的水平列表或竖直列表中,而后清空寄存器。
%\item [\cs{unhcopy} \cs{unvcopy}]
% The same as \cs{unhbox}$\,$/$\,$\cs{unvbox},
% but do not empty the register.
\item [\cs{unhcopy} \cs{unvcopy}] 与 \cs{unhbox}、\cs{unvbox} 的行为相同,但不清空寄存器。
%\item [\cs{ht} \cs{dp} \cs{wd}]
% Height/depth/width of the box in a box register.
\item [\cs{ht} \cs{dp} \cs{wd}] 返回及设置盒子寄存器中盒子的高度、深度、宽度。
%\item [\cs{boxmaxdepth}]
% Maximum allowed depth of boxes.
% Plain \TeX\ default:~\cs{maxdimen}.
\item [\cs{boxmaxdepth}] 该命令表示 \TeX 所允许的盒子的最大深度。在 plain \TeX 中,它的默认值是~\cs{maxdimen}。
%\item [\cs{splitmaxdepth}]
% Maximum allowed depth of boxes generated by \cs{vsplit}.
\item [\cs{splitmaxdepth}] 该命令表示 \TeX 所允许的由 \cs{vsplit} 生成盒子的最大深度。
%\item [\cs{badness}]
% Badness of the most recently constructed box.
\item [\cs{badness}] 刚刚构造的盒子的劣度。
%\item [\cs{hfuzz} \cs{vfuzz}]
% Excess size that \TeX\ tolerates before it considers
%\mdqon
% a horizontal/""vertical box overfull.
%\mdqoff
\item [\cs{hfuzz} \cs{vfuzz}] 该命令表示水平或竖直盒子的尺寸超出指定尺寸的阈值;当超过该阈值时,\TeX 会考虑将其认定为溢出的(overfull)盒子。
%\item [\cs{hbadness} \cs{vbadness}]
% Amount of tolerance before \TeX\ reports an underfull
%\mdqon
% or overfull horizontal/""vertical box.
%\mdqoff
\item [\cs{hbadness} \cs{vbadness}] 该命令表示一个阈值;当盒子的劣度超过该阈值时,\TeX 会将相应盒子认定为欠满的(underfull)或者溢出的。
%\item [\cs{overfullrule}]
% Width of the rule that is printed to indicate
% overfull horizontal boxes.
\item [\cs{overfullrule}] 当水平盒子溢出时,\TeX 会打印一条标尺,以表明有溢出的水平盒子;该命令表示上述标尺的宽度。
%\item [\cs{hsize}]
% Line width used for text typesetting inside a vertical box.
\item [\cs{hsize}] 该命令表示在水平盒子内文本排版可用的行宽。
%\item [\cs{vsize}]
% Height of the page box.
\item [\cs{vsize}] 该命令表示页盒子(page box)的高度。
%\item [\cs{lastbox}]
% Register containing the last item added to the current list,
% if this was a box.
\item [\cs{lastbox}] 若最后追加进当前列表的内容是一个盒子,则该寄存器会保存上述盒子。
%\item [\cs{raise} \cs{lower}]
% Adjust vertical positioning of a box in horizontal mode.
\item [\cs{raise} \cs{lower}] 这两个命令用于在水平模式中调整盒子的垂直位置。
%\item [\cs{moveleft} \cs{moveright}]
% Adjust horizontal positioning of a box in vertical mode.
\item [\cs{moveleft} \cs{moveright}] 这两个命令用于在竖直模式中调整盒子的水平位置。
%\item [\cs{everyhbox} \cs{everyvbox}]
%\mdqon
% Token list inserted at the start of a horizontal/""vertical box.
%\mdqoff
\item [\cs{everyhbox} \cs{everyvbox}] 这两个命令分别用于在每个水平盒子或竖直盒子开头处插入的记号列表。
\end{inventory}
%\section{Boxes}
\section{盒子}
%In this chapter we shall look at boxes. Boxes are containers
%for pieces of horizontal or vertical lists.
%Boxes that are needed more than once can be stored in box registers.
本章我们讨论盒子。\TeX 中的水平盒子与竖直盒子分别是盒子是水平与竖直列表内容的容器。需要多次使用的盒子可以保存在盒子寄存器当中。
%When \TeX\ expects a \gr{box}, any of the following forms
%is admissible:
当 \TeX 需要接受一个盒子(\gr{box})时,\TeX 可接受以下形式:
\begin{itemize}
\item \cs{hbox}\gr{box specification}\lb\gr{horizontal material}\rb
\item \cs{vbox}\gr{box specification}\lb\gr{vertical material}\rb
\item \cs{vtop}\gr{box specification}\lb\gr{vertical material}\rb
\item \cs{box}\gr{8-bit number}
\item \cs{copy}\gr{8-bit number}
\item \cs{vsplit}\gr{8-bit number}\n{to}\gr{dimen}
\item \cs{lastbox}
\end{itemize}
%A \gr{box specification} is defined as\label{box:spec}
其中 \gr{box specification} 的定义如下\label{box:spec}
\begin{disp}\gr{box specification} $\longrightarrow$ \gr{filler}
\nl\indent$|$ \n{to} \gr{dimen}\gr{filler}
$|$ \n{spread} \gr{dimen}\gr{filler}
\end{disp}
%An \gr{8-bit number} is a number in the range~0--255.
而 \gr{8-bit number} 则是 0--255 范围内的数字。
%The braces surrounding box material define a group;
%they can be explicit characters
%of categories 1 and~2 respectively,
%or control sequences \cs{let} to such characters;
%see also below.
包围盒子内容的花括号定义了一个分组;它们可以是分类码为 1 和 2 的显式字符,也可以是通过 \cs{let} 定义的控制序列(隐式字符);见下文。
%A \gr{box} can in general be used in horizontal, vertical,
%and math mode, but see below for the \cs{lastbox}.
%The connection between
%boxes and modes is explored further in Chapter~\ref{hvmode}.
除下文提到的 \cs{lastbox} 之外,盒子通常可以用在水平、竖直和数学模式。盒子与模式之间的关系将在第~\ref{hvmode}~章中讨论。
%The box produced by \cs{vcenter} \ldash a command that is allowed only in
%math mode \rdash is not a \gr{box}. For instance,
%it can not be assigned with \verb=\setbox=; see further
%Chapter~\ref{math}.
由 \cs{vcenter} 命令(仅可在数学模式下使用)产生的盒子不是通常意义的盒子(\gr{box})。特别地,它不能赋值给 \verb=\setbox=;详见第~\ref{math}~章。
%The \cs{vsplit} operation is treated in Chapter~\ref{page:break}.
\cs{vsplit} 命令将在第~\ref{page:break}~章详细讨论。
%\section{Box registers}
\section{盒子寄存器}
%There are 256 box registers, numbered 0--255.
%Either a box register is empty (`void'), or it contains a horizontal
%or vertical box.
%This section discusses specifically box {\em registers};
%the sizes of boxes, and the way material is arranged inside them,
%is treated below.
共有 256 个盒子寄存器,它们从 0 开始编号至 255。盒子寄存器要不然是空的(void),要不然包含了一个水平盒子或一个竖直盒子。本节只讨论盒子\emph{寄存器};盒子的尺寸、内部内容的排列方式则在后续小节中讨论。
%%\spoint Allocation: \cs{newbox}
%\subsection{Allocation: \cs{newbox}}
%\spoint Allocation: \cs{newbox}
\subsection{使用 \cs{newbox} 分配盒子寄存器}
%The plain \TeX\ \csidx{newbox} macro allocates an unused
%box register:
plain \TeX 中的 \csidx{newbox} 宏可用于分配一个未被使用的盒子寄存器:
\begin{verbatim}
\newbox\MyBox
\end{verbatim}
%after which one can say
此后,我们可以这样给盒子寄存器赋值:
\begin{verbatim}
\setbox\MyBox=...
\end{verbatim}
%or
或者这样使用盒子寄存器里的内容:
\begin{verbatim}
\box\MyBox
\end{verbatim}
%and so on.
%Subsequent calls to this macro give subsequent box numbers;
%this way macro collections can allocate their own boxes
%without fear of collision with other macros.
连续调用该命令会生成的盒子寄存器的编号也是连续的;这样,宏集合(macro collections)% TODO(Liam0205): 这里翻译可能需要调整
可以各自分配盒子寄存器,而无需担心与其它宏中分配的寄存器冲突。
%The number of the box is assigned by \cs{chardef}
%(see Chapter~\ref{alloc}).
%This implies that \cs{MyBox} is equivalent to,
%and can be used as, a~\gr{number}.
%The control sequence
%\altt
%\cs{newbox} is an \cs{outer} macro.
%Newly allocated box registers are initially empty.
盒子寄存器的编号是通过 \cs{chardef} 赋值的(见第~\ref{alloc}~章)。这说明,\cs{MyBox} 等价于一个数字(\gr{number}),并且能被当做是数字使用。控制序列 \cs{newbox} 是一个外部(\cs{outer})宏。新分配的盒子寄存器初始时是空的。
%\subsection{Usage: \cs{setbox}, \cs{box}, \cs{copy}}
\subsection{\cs{setbox}、\cs{box} 和 \cs{copy} 的用法}
%A~register is filled by assigning a \gr{box}
%\cstoidx setbox\par
%to it:
我们可以将一个盒子(\gr{box})赋值给盒子寄存器\cstoidx setbox\par :
\begin{Disp}\verb>\setbox>\gr{number}\gr{equals}\gr{box}\end{Disp}
%For example, the \gr{box} can be explicit
此处的 \gr{box} 可以是显式的盒子,比如
\begin{Disp}
\verb>\setbox37=\hbox{...}>\quad or\quad \verb>\setbox37=\vbox{...}>
\end{Disp}
%or it can be a box register:
也可以是另一个盒子寄存器:
\begin{verbatim}
\setbox37=\box38
\end{verbatim}
%Usually, box numbers will have been assigned by a \cs{newbox}
%command.
一般来说,盒子寄存器的编号由 \cs{newbox} 命令分配。
%The box in a box register is appended
%by the commands \cs{box} and~\cs{copy}
%to whatever list \TeX\ is building: the call
通过 \cs{box} 和 \cs{copy},我们可以将盒子寄存器中保存的盒子追加在 \TeX 正在构建的列表当中。例如,下列命令会将编号为 38 的盒子追加到当前列表中:
\begin{verbatim}
\box38
\end{verbatim}
%appends box~38.
%To save memory space, box registers become empty by using them:
%\TeX\ assumes that after you have inserted a box by
%calling \csidx{box}$nn$ in some mode, you do not need the
%contents of that register any more and empties it.
%In case you {\em do\/} need the contents of
%a box register more than once,
%you can \csidx{copy} it. Calling \cs{copy}$nn$ is
%equivalent to \cs{box}$nn$ in all respects except that
%the register is not cleared.
为节省内存,盒子寄存器在使用后会被清空:\TeX 假设当你使用 \csidx{box}$nn$ 之后,你就不会再需要其中的内容了,于是便会清空它。如果你\emph{确实}需要重复使用盒子寄存器的内容,你可以用 \csidx{copy}$nn$ 命令。它与 \cs{box}$nn$ 的效果相同,但不会清空盒子寄存器中的内容。
%It is possible to unwrap the contents of a box register
%by `unboxing' it using the commands \cs{unhbox} and \cs{unvbox},
%and their copying versions \cs{unhcopy} and \cs{unvcopy}.
%Whereas a box can be used in any mode, the
%unboxing operations can only be used in the appropriate mode,
%since in effect they contribute a partial
%horizontal or vertical list (see also Chapter~\ref{hvmode}).
%See below for more information on unboxing registers.
通过 \cs{unhbox} 和 \cs{unvbox} 及其拷贝版本 \cs{unhcopy} 和 \cs{unvcopy} 解包盒子寄存器中的内容是可行的。不同于 \cs{box} 可以在任何模式下使用,解包盒子的操作只能用在恰当的模式下——因为解包盒子会形成一个部分的水平列表或竖直列表(参见第~\ref{hvmode}~章)。后文有关于解包盒子寄存器的更多信息。
%%\spoint Testing: \cs{ifvoid}, \cs{ifhbox}, \cs{ifvbox}
%\subsection{Testing: \cs{ifvoid}, \cs{ifhbox}, \cs{ifvbox}}
%\spoint Testing: \cs{ifvoid}, \cs{ifhbox}, \cs{ifvbox}
\subsection{关于盒子的条件判断:\cs{ifvoid}、\cs{ifhbox} 及 \cs{ifvbox}}
%Box
%registers can be tested for their contents:
通过 \cs{ifvoid} 可以判断盒子寄存器是否为空。当 \cs{box}\gr{number} 为空时,下式返回真:
\begin{disp}\cs{ifvoid}\gr{number}\end{disp}
%is true if the box register is empty.
%Note that an empty, or `void',
%box register is not the same as a register containing an empty box.
%An empty box is still either a horizontal or a vertical box;
%a~void register can be used as both.
注意,盒子寄存器为空与盒子寄存器保存了空盒子是两码事。空盒子要么是水平盒子要么是竖直盒子;空的盒子寄存器既可以作为水平盒子使用,也可以作为竖直盒子使用。
%The test
\cs{ifhbox} 和 \cs{ifvbox} 则分别用于判断一个盒子寄存器中的盒子是否为水平盒子或竖直盒子:
\begin{disp}\cs{ifhbox}\gr{number}\end{disp}
%is true if the box register contains a horizontal box;
\begin{disp}\cs{ifvbox}\gr{number}\end{disp}
%is true if the box register contains a vertical box.
%Both tests are false for void registers.
注意,若寄存器为空,则两个判断都为假。
%%\spoint[lastbox] The \cs{lastbox}
%\subsection{The \cs{lastbox}}
%\label{lastbox}
%\spoint[lastbox] The \cs{lastbox}
\subsection{\cs{lastbox}}
\label{lastbox}
%When \TeX\ has built a partial list, the last box in this
%list is accessible as the \csidx{lastbox}. This behaves
%like a box register, so you can remove the last box from the
%list by assigning the \cs{lastbox} to some box register.
%If the last item on the current list is not a box,
%the \cs{lastbox} acts like a void box register.
%It is not possible to get hold of the last box
%in the case of the main vertical list.
%The \cs{lastbox} is then always void.
当 \TeX 构建完成一个部分列表(partial list)后,此列表中的最后一个盒子可通过 \csidx{lastbox} 来访问。该命令的行为与盒子寄存器相似;因此,你可以将 \cs{lastbox} 赋值给其他盒子寄存器,以将其从列表中删除。如果列表中最后一个元素不是盒子,则 \cs{lastbox} 的行为与空寄存器相似。你无法通过 \cs{lastbox} 访问主竖直列表中的最后一个元素;在这种情况下,\cs{lastbox} 总是空寄存器。
%As an example, the statement
举例来说,下面的语句将当前列表中的最后一个盒子赋值给编号为 0 的盒子寄存器,并将其从当前列表中删除:
\begin{verbatim}
{\setbox0=\lastbox}
\end{verbatim}
%removes
%the last box from the current list, assigning it to box
%register~0. Since this assignment occurs inside a group,
%the register is cleared at the end of the group.
%At the start of a paragraph this can be used to remove the
%indentation box (see Chapter~\ref{par:start}).
%Another example of \cs{lastbox} can be found on page~\pageref{varioset}.
由于赋值过程位于分组之内,在分组结束后,寄存器会被清空。因此,在一个自然段开始之时使用这一语句,可以删除缩进盒子(见第~\ref{par:start}~章)。在第~\pageref{varioset}~页也有关于 \cs{lastbox} 的例子。
%Because the \verb-\lastbox- is always empty in external vertical mode,
%it is not possible to get hold of boxes that have been
%added to the page. However, it is possible to dissect
%the page once it is in \cs{box255}, for instance doing
由于 \cs{lastbox} 在外部竖直模式中总是为空,它不能访问追加到输出页上的盒子。但当页面保存在 \cs{box255} 中时,我们可以在输出阶段解包这个盒子,而后取得 \cs{lastbox}\liamfnote{关于这一技巧,这里有一个完整的示例:\url{https://gist.github.com/91fd658069b0d3dfb7dbd2cba69b856a}}:
\begin{verbatim}
\vbox{\unvbox255{\setbox0=\lastbox}}
\end{verbatim}
%inside the output routine.
%If boxes in vertical mode have been shifted by \cs{moveright}
%or \cs{moveleft}, or if boxes in horizontal mode have
%been raised by \cs{raise} or lowered by \cs{lower},
%any information about this
%displacement due to such a command is lost when
%the \cs{lastbox} is taken from the list.
值得一提的是,如果竖直模式中的盒子被 \cs{moveright} 或 \cs{moveleft} 调整过位置,或是水平模式中的盒子被 \cs{raise} 或 \cs{lower} 调整过位置,则使用 \cs{lastbox} 访问列表中最后一个元素时,这些位置调整信息都会丢失。
%%\point Natural dimensions of boxes
%\section{Natural dimensions of boxes}
%\point Natural dimensions of boxes
\section{盒子天然的尺寸\liamfnote{这里指的是没有其他拉伸、收缩的影响下,盒子自身的尺寸。}}
%%\spoint Dimensions of created horizontal boxes
%\subsection{Dimensions of created horizontal boxes}
%\spoint Dimensions of created horizontal boxes
\subsection{已创建的水平盒子的尺寸}
%Inside an \csidx{hbox} all constituents are lined up next to each other,
%with their reference points on the baseline of the box,
%unless they are moved explicitly in the vertical direction
%by \cs{lower} or~\cs{raise}.
\csidx{hbox} 内所有的元素都依次排在一行,并且它们的参考点会在盒子的基线(baseline)上对齐,除非显式使用 \cs{raise} 或者 \cs{lower} 调整它们竖直方向上的位置。
%The resulting width of the box is the sum of the widths
%of the components. Thus the width of
盒子的宽度是盒子内所有元素宽度之和。因此下面盒子的宽度为正
\begin{verbatim}
\hbox{\hskip1cm}
\end{verbatim}
%is positive, and the width of
而下面盒子的宽度为负
\begin{verbatim}
\hbox{\hskip-1cm}
\end{verbatim}
%is negative. By way of example,
具体举例来说:
\begin{disp}\verb>a\hbox{\kern-1em b}-->\end{disp}
%gives as output
的输出是
\begin{disp}\leavevmode\hphantom{b}a\hbox{\kern-1em b}--\end{disp}
%\message{check align input/output}
%which shows that a horizontal box can have negative
%width.
这表明,水平盒子可以有负的宽度。
%The height and depth of an \cs{hbox} are the
%maximum amount that constituent boxes project above and
%below the baseline of the box. They are non-negative when the
%box is created.
\cs{hbox} 的高度和深度是盒子内所有元素在盒子基线上方和下方的最大值。水平盒子的高度和深度都是非负的。
%The commands \cs{lower} and \cs{raise} are the only possibilities
%for vertical movement inside an \cs{hbox} (other than
%including a \cs{vbox} inside the \cs{hbox}, of course);
%a~\gr{vertical command} \ldash such as \cs{vskip} \rdash
%is not allowed in a horizontal box, and
%\cs{par}, although allowed,
%does not do anything inside a horizontal box.
\cs{raise} 和 \cs{lower} 命令是在 \cs{hbox} 内调整元素竖直位置的唯一方法(当然,除了在 \cs{hbox} 中嵌套一个新的 \cs{vbox});\TeX 不允许在水平盒子中使用竖直命令(\gr{vertical command},例如 \cs{vskip});此外,虽然我们可以在水平盒子中使用 \cs{par},但它却不会有任何作用。
%%\spoint Dimensions of created vertical boxes
%\subsection{Dimensions of created vertical boxes}
%\spoint Dimensions of created vertical boxes
\subsection{已创建的竖直盒子的尺寸}
%Inside a \csidx{vbox} vertical material is lined up with the
%\cstoidx vtop\par
%reference points on the vertical line through the reference
%point of the box,
%unless components are moved explicitly in the horizontal direction
%by \csidx{moveleft} or~\csidx{moveright}.
在 \csidx{vbox} 内,竖直元素的参考点与盒子的参考点在竖直方向上对齐,除非显式使用 \cs{moveright} 或者 \cs{moveleft} 调整它们水平方向上的位置。\cstoidx vtop\par
%The reference point of a vertical box
%is always located at the left boundary of the box.
%The width of a vertical box
%is then the maximal amount that any material in the
%box sticks to the right of the reference point.
%Material to the left of the reference point is
%not taken into account in the width.
%Thus the result of
竖直盒子的参考点总是在盒子的左边界上。竖直盒子的宽度是盒子内所有元素的右边界相对参考点向右超出距离的最大值。盒子内元素相对参考点向左超出的距离则不被计算在盒子的宽度之中。因此,与前例相对应,下列代码的结果
\begin{disp}\verb>a\vbox{\hbox{\kern-1em b}}-->\end{disp}
%is
是
\begin{disp}\leavevmode\hphantom{b}a\vbox{\hbox{\kern-1em b}}--\end{disp}
%This should be contrasted with the above example.
%The calculation of height and depth is different
%for vertical boxes constructed by \cs{vbox} and \cs{vtop}.
%The ground rule is that
%a \cs{vbox} has a reference point that lies on
%the baseline of its last component,
%and a \cs{vtop} has its reference point on the baseline of the
%first component.
%In general, the depth (height) of a \cs{vbox} (\cs{vtop})
%\alt
%can be non-zero if the last (first) item is a box or rule.
由 \cs{vbox} 和 \cs{vtop} 生成的竖直盒子在计算高度和深度时会有所不同。基本原则是,\cs{vbox} 的参考点位于最后一个元素的基线之上,而 \cs{vtop} 的参考点位于第一个元素的基线之上。一般来说,只要最后一个(第一个)元素是盒子或者标尺(rule),则 \cs{vbox}(\cs{vtop})的深度(高度)非零。
%The height of a \cs{vbox} is then the sum of the heights and
%depths of all components except the last, plus the height
%of that last component; the depth of the \cs{vbox} is the
%depth of its last component.
%The depth of a \cs{vtop}
%is the sum of the depth of the first component and the heights
%and depths of all subsequent material; its height is the
%height of the first component.
\cs{vbox} 的高度是除最后一个元素之外所有元素高度与深度之和,再加上最后一个元素的高度;\cs{vbox} 的深度则是最后一个元素的深度。\cs{vtop} 的高度是第一个元素的高度;\cs{vtop} 的深度则是除第一个元素之外所有元素高度与深度之和,再加上第一个元素的深度。%
% Liam0205:这里将下一段的最后一句话挪到此处
也就是说,对于 \cs{vtop} 来说,其深度是所包含所有元素的高度与深度之和,再减去第一个元素的高度。
%However, the actual rules are a bit
%more complicated when the first component of a \cs{vtop}
%or the last component of a \cs{vbox} is not a box or rule.
%If the last component of a \cs{vbox} is a kern or a glue,
%the depth of that box is zero; a \cs{vtop}'s
%height is zero
%unless its first component is a box or rule.
%\altt
%(Note the asymmetry in these definitions; see below for
%an example illustrating this.)
%The depth of a \cs{vtop}, then, is equal to the total
%height plus depth of all enclosed material minus
%the height of the \cs{vtop}.
如果 \cs{vtop}(\cs{vbox})的第一个元素(最后一个元素)不是盒子或标尺,那么实际规则还要更复杂一点。如果 \cs{vbox} 的最后一个元素是铅空(kern)或伸缩胶(glue),则盒子的深度为零;而若 \cs{vtop} 的第一个元素是铅空或伸缩胶,则盒子的高度为零。(注意这些定义中的不对称性;可参考后续示例)
% 此处最后一句话挪到上一段末尾处。
%There is a limit on the depth of vertical boxes:
%if the depth of a \cs{vbox} or \cs{vtop}
%calculated by the above rules would exceed
%\cstoidx boxmaxdepth\par,
%the reference point of the box
%is moved down by the excess amount.
%More precisely, the excess depth is added to the
%natural height of the box. If the box had a \n{to} or
%\n{spread} specification, any glue is set anew to take
%the new height into account.
关于竖直盒子,还有一个限制:如果 \cs{vbox} 或者 \cs{vtop} 的深度超出 \csidx{boxmaxdepth},则盒子的参考点会下移这一超出的数值。具体来说,超出限制的那一部分深度,会被加在盒子自身的高度之上。如果盒子有 \n{to} 或者 \n{spread} 声明符,则相关的伸缩胶都会被重新设置,以将追加的高度考虑在内。
%Ordinarily,
%\cs{boxmaxdepth} is set to the maximum dimension
%possible in \TeX. It is for instance reduced during some of
%the calculations in the plain \TeX\ output routine;
%see Chapter~\ref{output}.
通常,\cs{boxmaxdepth} 的值是 \TeX 能表示的最大尺寸。但在一些情况下,例如,在 plain \TeX 的输出阶段的一些计算中,它的值会被修改得小很多。详见第~\ref{output}~章。
%\subsection{Examples}
\subsection{例子}
%Horizontal boxes are relatively straightforward. Their width is the
%distance between the `beginning' and the `end' of the
%box,
%and consequently the width is not necessarily positive.
%With
水平盒子相较而言简单直接一些。水平盒子的宽度是盒子两条竖直边界之间的距离:从开始到结束,因此,水平盒子的宽度不一定是正数。例如在下例中,\cs{box1} 的宽度为零。
\begin{verbatim}
\setbox0=\hbox{aa} \setbox1=\hbox{\copy0 \hskip-\wd0}
\end{verbatim}
%the \cs{box1} has width zero;
具体来说
\begin{Disp}
\verb-/\box1/-\quad gives\quad
`{\setbox0=\hbox{aa}\setbox1=\hbox{\copy0 \hskip-\wd0}/\box1/}\kern.75em'
\end{Disp}
%The height and depth of a horizontal box cannot be negative: in
水平盒子的高度和深度则不能为负。例如在下例中,\cs{box1} 的深度是 \n{0pt} 而高度是 \n{15pt}。
\begin{verbatim}
\setbox0=\hbox{\vrule height 5pt depth 5pt}
\setbox1=\hbox{\raise 10pt \box0}
\end{verbatim}
%the \cs{box1} has depth \n{0pt} and height~\n{15pt}
%Vertical boxes are more troublesome than horizontal boxes.
%Let us first treat their width.
%After
竖直盒子相较而言就要麻烦不少。我们首先来讨论其宽度。首先,如下定义的水平盒子的宽度是 \n{10pt}。
\begin{verbatim}
\setbox0=\hbox{\hskip 10pt}
\end{verbatim}
%the box in the
%\cs{box0} register has a width of \n{10pt}. Defining
则如下定义的竖直盒子宽度是 \n{5pt}。
\begin{verbatim}
\setbox1=\vbox{\moveleft 5pt \copy0}
\end{verbatim}
%the \cs{box1} will have width \n{5pt}; material to the
%left of the reference point is not accounted for in the
%width of a vertical box. With
这是因为,在竖直盒子中,位于参考点左边的内容不计入其宽度。同样的,如下定义的竖直盒子宽度是 \n{15pt}。
\begin{verbatim}
\setbox2=\vbox{\moveright 5pt \copy0}
\end{verbatim}
%the \cs{box2} will have width \n{15pt}.
%The depth of a \cs{vbox} is the depth of the last item if
%that is a box, so
如果 \cs{vbox} 的最后一个元素是盒子,则其深度是最后一个元素的深度。因此,如下定义的 \cs{vbox} 高度为 \n{10pt} 深度为 \n{5pt}。
\begin{verbatim}
\vbox{\vskip 5pt \hbox{\vrule height 5pt depth 5pt}}
\end{verbatim}
%has height \n{10pt} and depth \n{5pt},
%and
如下定义的 \cs{vbox} 的高度则是 \n{0pt} 而深度为 \n{5pt}。
\begin{verbatim}
\vbox{\vskip -5pt \hbox{\vrule height 5pt depth 5pt}}
\end{verbatim}
%has height \n{0pt} and depth~\n{5pt}.
%With a glue or kern as the last item in the box, the resulting depth
%is zero, so
如果最后一个元素是铅空或伸缩胶,则竖直盒子的深度为零。因此,如下定义的 \cs{vbox} 高度为 \n{15pt} 深度为 \n{0pt}。
\begin{verbatim}
\vbox{\hbox{\vrule height 5pt depth 5pt}\vskip 5pt}
\end{verbatim}
%has height \n{15pt} and depth~\n{0pt};
下列 \cs{vbox} 的高度为 \n{5pt} 深度则是 \n{0pt}。
\begin{verbatim}
\vbox{\hbox{\vrule height 5pt depth 5pt}\vskip -5pt}
\end{verbatim}
%has height \n{5pt} and depth~\n{0pt}.
%The height of a \cs{vtop} behaves (almost) the same with respect to
%the first item of the box, as the depth of a \cs{vbox} does
%with respect to the last item. Repeating the above examples with
%a \cs{vtop} gives the following:
与 \cs{vbox} 的深度对应,\cs{vtop} 的高度基本上就是其第一个元素的高度。重复之前的例子,则如下定义的 \cs{vtop} 高度为 \n{0pt} 深度为 \n{15pt}。
\begin{verbatim}
\vtop{\vskip 5pt \hbox{\vrule height 5pt depth 5pt}}
\end{verbatim}
%has height \n{0pt} and depth \n{15pt},
%and
如下定义的 \cs{vtop} 高度为 \n{0pt} 深度为 \n{5pt}。
\begin{verbatim}
\vtop{\vskip -5pt \hbox{\vrule height 5pt depth 5pt}}
\end{verbatim}
%has height \n{0pt} and depth~\n{5pt};
如下定义的 \cs{vtop} 高度为 \n{5pt} 深度为 \n{10pt}。
\begin{verbatim}
\vtop{\hbox{\vrule height 5pt depth 5pt} \vskip 5pt}
\end{verbatim}
%has height \n{5pt} and depth~\n{10pt}, and
如下定义的 \cs{vtop} 高度为 \n{5pt} 深度为 \n{0pt}。
\begin{verbatim}
\vtop{\hbox{\vrule height 5pt depth 5pt} \vskip -5pt}
\end{verbatim}
%has height \n{5pt} and depth~\n{0pt}.
%%\point More about box dimensions
%\section{More about box dimensions}
%\point More about box dimensions
\section{继续讨论盒子的尺寸}
%%\spoint Predetermined dimensions
%\subsection{Predetermined dimensions}
%\spoint Predetermined dimensions
\subsection{预先指定尺寸}
%The size of a box can be specified in advance
%with a \gr{box specification}; see above for the syntax.
%Any glue
%in the box is then set in order to reach the required size.
%Prescribing the size of the box is done by
盒子的尺寸可以通过尺寸说明符(\gr{box specification})来指定;具体语法可见上文。盒子中的伸缩胶会依需求缩放,使得盒子的尺寸达到上述设定值。预先指定盒子的尺寸的方法是:
\begin{disp}
\cs{hbox} \n{to} \gr{dimen} \n{\lb...\rb},
\cs{vbox} \n{to} \gr{dimen} \n{\lb...\rb}
\end{disp}
%If stretchable or shrinkable glue is present in the box,
%it is stretched or shrunk in order to give the box the
%specified size. Associated with this glue setting is a badness value
%(see Chapter~\ref{glue}). If no stretch or shrink \ldash whichever
%is necessary \rdash is present, the resulting box will be underfull
%or overfull respectively. Error reporting for over/underfull
%boxes is treated below.
如果盒子中有可以拉伸或收缩的伸缩胶,则这些伸缩胶会被拉伸或收缩,以将盒子的尺寸调整至指定的大小。与伸缩胶伸缩相关的是所谓的劣度值(见第~\ref{glue}~章)。如果伸缩胶能够提供的拉伸或收缩值不足所需,则得到的盒子会欠满或溢出。后文有关于欠满和溢出的报错的相关讨论。
%Another command to let a box have a size other than
%the natural size is
还有一个命令可使盒子实际的尺寸异于其天然尺寸。
\begin{disp}
\cs{hbox} \n{spread} \gr{dimen} \n{\lb...\rb},
\cs{vbox} \n{spread} \gr{dimen} \n{\lb...\rb}
\end{disp}
%which tells \TeX\ to set the glue in such a way that
%the size of the box is a specified amount more than the
%natural size.
这种情况下,\TeX 会使盒子内的伸缩胶拉伸或收缩,以在盒子天然尺寸的基础上缩放 \gr{dimen}。
%Box specifications for \cs{vtop} vertical boxes are
%somewhat difficult to interpret. \TeX\ constructs a \cs{vtop}
%by first making a \cs{vbox}, including
%glue settings induced by a \gr{box specification};
%then it computes the height and depth by the above rules.
与 \cs{vtop} 配合使用尺寸说明符相对来说比较复杂。\TeX 构造 \cs{vtop} 时会先构造一个 \cs{vbox},同时会将尺寸说明符传递给该 \cs{vbox};而后再根据上述规则计算盒子的高度和深度。
%Glue setting is described in Chapter~\ref{glue}.
伸缩胶相关设置将在第~\ref{glue}~章中讨论。
%%\spoint Changes to box dimensions
%\subsection{Changes to box dimensions}
%\spoint Changes to box dimensions
\subsection{改变盒子的尺寸}
%The dimensions of a box register are accessible by the
%commands \csidx{ht}, \csidx{dp}, and~\csidx{wd};
%for instance \cs{dp13} gives the depth of box~13.
%However, not only can boxes be measured this way;
%by assigning values to these
%dimensions \TeX\ can even be fooled into thinking that
%a box has a size different from its actual.
%However, changing the dimensions of a box does not change
%anything about the contents; in particular it does not
%change the way the glue is set.
我们可以用 \csidx{ht}、\csidx{dp} 和 \csidx{wd} 来分别获得盒子寄存器的高度、深度和宽度。举例来说,\cs{dp18} 会给出 18 号盒子的深度。盒子的尺寸不光可读,还可写。通过给盒子的尺寸赋值,我们可以在某种意义上愚弄 \TeX,使得在 \TeX 看来某个盒子的尺寸不同于其真实值。不过,修改盒子尺寸并不会修改其中的内容;特别地,不会修改伸缩胶设置的方式。
%Various formats use this in `smash' macros: the macro defined by
%\cstoidx smash\par
不少格式(format)都定义了 \csidx{smash} 宏:
\begin{verbatim}
\def\smash#1{{\setbox0=\hbox{#1}\dp0=0pt \ht0=0pt \box0\relax}}
\end{verbatim}
%places its argument but annihilates its height and depth;
%\altt
%that is, the output does show the whole box, but further calculations
%by \TeX\ act as if the height and depth were zero.
在宏定义中,\cs{smash} 命令将内容保存在盒子中,但是将盒子的高度和深度都设置为零;这也就是说,最终盒子会被输出,但是后续有关盒子尺寸的计算中,\TeX 都会将高度和深度认作是零。
%Box dimensions can be changed only by setting them.
%They are \gr{box dimen}s, which can only be set
%in a \gr{box size assignment}, and not, for instance
%changed with \cs{advance}.
改变盒子尺寸只能通过为其赋值来实现:这些盒子尺寸(\gr{box dimen}s)能且只能通过盒子尺寸赋值语句(\gr{box size assignment})来设置,而不能用诸如 \cs{advance} 的命令来修改。
%Note that a \gr{box size assignment}\index{assignment!box size} is a
%\gr{global assignment}\index{assignment!global} its effect transcends
% any groups in which it occurs (see Chapter~\ref{group}). Thus the
% output of
注意,\cindextermbus{盒子尺寸}{赋值}总是\cindextermbus{全局}{赋值}。赋值的效果会超出任意限定它的分组(参见第~\ref{group}~章)。因此下列代码的输出为:「{\setbox0=\hbox{---}{\wd0=0pt}a\box0b}\kern.5em」。
\begin{verbatim}
\setbox0=\hbox{---} {\wd0=0pt} a\box0b
\end{verbatim}
%is `{\setbox0=\hbox{---}{\wd0=0pt}a\box0b}\kern.5em'.
%The limits that hold on the dimensions with which a
%box can be created (see above) do not hold for explicit changes to the
%\mdqon
%size of a box: the assignment \cs{dp0=}""\n{-2pt} for a
%\mdqoff
%horizontal box is perfectly admissible.
上述有关被创建的盒子的尺寸限制并不适用于显式修改盒子尺寸的情况。例如,对水平盒子设置 \cs{dp0=-2pt} 是合法的。
%\subsection{Moving boxes around}
\subsection{移动盒子}
%In a horizontal box all constituent elements are lined up
%\cstoidx raise\par\cstoidx lower\par
%with their reference points at the same height as the
%reference point of the box. Any box inside a horizontal
%box can be lifted or dropped using the macros
%\cs{raise} and~\cs{lower}.
在水平盒子中,所有元素的参考点与盒子自身的参考点都位于同一条水平线上。水平盒子中的盒子可用 \csidx{raise} 或 \csidx{lower} 来上移或下移。
%Similarly, in a vertical box all constituent elements
%are lined up with their reference points underneath one another,
%in line with the reference point of the box.
%Boxes can now be moved sideways by the macros
%\csidx{moveleft} and~\csidx{moveright}.
相似地,在竖直盒子中,所有元素的参考点与盒子自身的参考点都位于同一条竖直线上,且各个元素从上到下依次排列。竖直盒子中的盒子可用 \csidx{moveleft} 或 \csidx{moveright} 来左移或右移。
%Only boxes can be shifted thus; these operations cannot
%be applied to, for instance, characters or rules.
注意,上述命令只能用来移动盒子,特别地,这些命令不能用于字符或标尺。
%\subsection{Box dimensions and box placement}
\subsection{盒子的尺寸与盒子的摆放}
%\TeX\ places the components of horizontal and
%vertical lists by maintaining a reference line and a
%current position on that line. For horizontal lists
%the reference line is the baseline of the surrounding
%\cs{hbox}; for vertical lists it is the vertical line
%through the reference point of the surrounding \cs{vbox}.
在确定水平列表和竖直列表中元素的摆放位置时,\TeX 需要维护两个变量:当前参考线以及在参考线上的当前位置。对于水平列表来说,参考线是包围当前内容的 \cs{hbox} 的基线;对于竖直列表来说,参考线是穿过包围当前内容的 \cs{vbox} 的参考点的竖线。
%In horizontal mode a component is placed as follows.
%The current position coincides initially
%with the reference point of the surrounding box. After that,
%the following actions are carried out.
在水平模式中,\TeX 放置元素的逻辑如下。初始时,参考线上的当前位置即是包围当前内容的从水平盒子的参考点。此后,\TeX 会依如下步骤操作。
\begin{enumerate}
% \item If the component has been shifted by
%\cs{raise} or \cs{lower}, shift the current
%position correspondingly.
\item 如果元素被 \cs{raise} 或 \cs{lower} 上下移动了位置,则相应地调整元素的位置。
%\item If the component is a horizontal box, use
%this algorithm recursively for its contents;
%if it is a vertical box, go up by the height of this box,
%putting a new current position for the enclosed vertical list there,
%and place its components using the algorithm for vertical
%lists below.
\item 如果元素是水平盒子,则对其内容递归地调用该算法;如果元素是竖直盒子,按盒子的高度向上移动当前位置,而后按照后文所述的有关竖直盒子的算法放置盒子内竖直列表中的元素。
%\item Move the current position (on the reference line)
%to the right by the width of the component.
\item 按当前元素的宽度,沿着参考线向右移动当前位置。
\end{enumerate}
%For the list in a vertical box \TeX's current position is
%initially at the upper left corner of that box, as explained above,
%and the reference line is the vertical line through that point;
%it also runs through the reference point of the box.
%Enclosed components are then placed as follows.
对于竖直盒子中的竖直列表,\TeX 的会将当前位置初始设置在盒子的左上角,参考线则是穿过该点的竖线——这条竖线同样也会穿过盒子的参考点。竖直盒子中的元素依照如下逻辑摆放。
\begin{enumerate}
%\item If a component has been shifted using
%\cs{moveleft} or \cs{moveright}, shift the current position
%accordingly.
\item 如果元素被 \cs{moveleft} 或 \cs{moveright} 上下移动了位置,则相应地调整元素的位置。
%\item Put the component with its upper left corner at the
%current position.
\item 将元素的左上角与当前位置对齐。
%\item If the component is a vertical box, use this algorithm
%recursively for its contents; if it is a horizontal box,
%its reference point can be found below the current position
%by the height of the box. Put the current position for that
%box there, and use the above algorithm for horizontal lists.
\item 如果元素是竖直盒子,则对其内容递归地调用该算法;如果元素是水平盒子,按盒子的高度向下移动当前位置,而后按照前文所述的有关竖直盒子的算法放置盒子内水平列表中的元素。
%\item Go down by the height plus depth of the box
%(that is, starting at the upper left corner of the box)
%on the reference line,
%and continue processing vertically.
\item 按当前元素的高度与深度之和,沿着参考线向下移动当前位置。
\end{enumerate}
%Note that the above processes do not describe the construction
%of boxes. That would (for instance)
%involve for vertical boxes the insertion
%of baselineskip glue. Rather, it describes the way the components
%of a finished box are arranged in the output.
注意,上文中没有描述 \TeX 是如何构建盒子的。对于竖直盒子,构建盒子的过程还要包括插入行间距伸缩胶(行间胶,baselineskip glue)的过程。上文介绍的过程描述的是 \TeX 会如何输出一个已经构建完成的盒子中的内容。
%\subsection{Boxes and negative glue}
\subsection{盒子与反向伸缩胶}
%Sometimes it is useful to have boxes overlapping instead of
%line up. An easy way to do this is to use negative glue.
%In horizontal mode
默认情况下,盒子在一条参考线上依次摆放。但有时,让盒子互相重叠也是很有用的。让盒子互相重叠,最简单的办法是使用反向行间胶。在水平模式中,下列代码会摆放编号为 8 的盒子,但不会移动当前位置。
\begin{verbatim}
{\dimen0=\wd8 \box8 \kern-\dimen0}
\end{verbatim}
%places box 8 without moving the current location.
%More versatile are the macros \csidx{llap} and \csidx{rlap}\label{rlap},
%defined as
更实用的是使用 \csidx{llap} 和 \csidx{rlap}\label{rlap} 命令。它们的定义如下:
\begin{verbatim}
\def\llap#1{\hbox to 0pt{\hss #1}}
\def\rlap#1{\hbox to 0pt{#1\hss}}
\end{verbatim}
%that allow material to protrude left or right from the
%current location.
%The \cs{hss} glue is equivalent to \verb>\hskip 0pt plus 1fil minus 1fil>,
%which absorbs any positive or negative width
%of the argument of \cs{llap} or \cs{rlap}.
这两个命令允许其中的内容基于当前位置向左或向右突出。这里,\cs{hss} 伸缩胶等价于 \cs{hskip 0pt plus 1fil minus 1fil},它能吸收 \cs{llap} 或 \cs{rlap} 的参数中的任意正负宽度。
\begin{example}
%The sequence
下列代码
\begin{verbatim}
\llap{\hbox to 10pt{a\hfil}}
\end{verbatim}
%is effectively the same as
等价于
\begin{verbatim}
\hbox{\hskip-10pt \hbox to 10pt{a\hfil}}
\end{verbatim}
%which has a total width of~\n{0pt}.
它们的宽度都是 \n{0pt}。
\end{example}
%\section{Overfull and underfull boxes}
%\label{over/underfull}
\section{盒子的欠满与溢出}
\label{over/underfull}
%If a box has a size specification \TeX\ will
%stretch or shrink glue in the box. For glue with
%only finite stretch or shrink components the {\em badness\/}
%(see Chapter~\ref{line:break}) of stretching or shrinking
%is computed.
%In \TeX\ version~3 the badness
%\cstoidx badness\par
%\thecstoidxsub{TeX}{version 3}
%of the box most recently
%constructed is available for inspection
%by the user through the \cs{badness} parameter. Values for
%badness range 0--$10\,000$, but if the box is overfull
%it is~$1\,000\,000$.
如果盒子有尺寸说明符则 \TeX 会拉伸或收缩其中的伸缩胶。对于仅有有限伸缩能力的伸缩胶,\TeX 会计算其伸缩过程中的\emph{劣度}(见第~\ref{line:break}~章)。%
\cstoidx badness\par
在 \TeX3 中,%
\thecstoidxsub{TeX}{version 3}
用户可通过 \cs{badness} 宏来检查刚刚构建的盒子的劣度。劣度的取值范围是 $0$--$10\,000$;而如果盒子溢出了,则其劣度为~$1\,000\,000$。
%When \TeX\ considers the badness too large,
%it gives a diagnostic message. Let us first consider error reporting
%for horizontal boxes.
如果 \TeX 认为劣度过大,则会给出一条诊断信息。我们首先考虑对水平盒子的报错。
%Horizontal boxes of which the glue has to stretch are never reported if
%\cstoidx hbadness\par\cstoidx vbadness\par
%\cs{hbadness}${}\geq10\,000$; otherwise \TeX\ reports them
%as `underfull' if their badness is more than \cs{hbadness}.
若 $\text{\cs{hbadness}}\geqslant10\,000$,则 \TeX 不会对需要拉伸其中伸缩胶的水平盒子报错;否则,当水平盒子中的伸缩胶拉伸的劣度超过 \cs{hbadness} 时,\TeX 会提示盒子欠满(underfull)。
\cstoidx hbadness\par
\cstoidx vbadness\par
%Glue shrinking can lead to `overfull' boxes: a box is called
%\cstoidx hfuzz\par\cstoidx vfuzz\par
%overfull if the available shrink is less than the shrink
%necessary to meet the box specification. An overfull box
%is only reported if the difference in shrink is more than
%\cs{hfuzz}, or if \cs{hbadness}${}<100$ (and it turns out that
%using all available shrinkability has badness~$100$).
伸缩胶的收缩可能引发盒子溢出的报错:如果盒子内伸缩胶最大的收缩量不足以使盒子的宽度满足指定的宽度,则 \TeX 认为该盒子溢出了。%
\cstoidx hfuzz\par
\cstoidx vfuzz\par
当且仅当收缩量不足的量大于 \cs{hfuzz} 或者 $\text{\cs{hbadness}}<100$ 时(这会使得所有可用的收缩的劣度为 $100$),\TeX 才会报告盒子溢出的问题。
\begin{example}
%Setting \verb>\hfuzz=1pt> will let \TeX\ ignore
%boxes that can not shrink enough if they lack less than~\n{1pt}.
%In
如果盒子内伸缩胶的最大收缩量不足以使盒子的宽度减小到指定的尺寸,则若设置 \emph{\cs{hfuzz=1pt}},\TeX 会忽略上述不足的部分小于 \n{1pt} 的盒子而不报错。
\begin{verbatim}
\hbox to 1pt{\hskip3pt minus .5pt}
\hbox to 1pt{\hskip3pt minus 1.5pt}
\end{verbatim}
%only the first box will give an error message:
%it is \n{1.5pt} too big, whereas the second lacks
%\n{.5pt} which is less than \cs{hfuzz}.
这里只有第一个盒子会报错:它比目标尺寸大了 \n{1.5pt};但是第二个盒子不会报错,因为它只比目标尺寸大了 \n{0.5pt},小于 \emph{\cs{hfuzz}}。
\end{example}
%Also, boxes that shrink but that are not overfull can be reported:
%if a box is `tight', that is, if it uses at least half its
%shrinkability, \TeX\ reports this fact if the
%computed badness (which is between 13 and~100) is more than
%\cs{hbadness}.
如果一个盒子虽不至变成溢出盒子但也被收缩了,也有可能被 \TeX 报告问题:如果一个盒子比较紧凑,也就是说,如果这个盒子使用了至少一半的收缩能力,则在劣度(介于 13 到 100 之间)超过 \cs{hbadness} 时,\TeX 会报告这个问题。
%For horizontal and vertical boxes this error reporting is almost
%\cstoidx overfullrule\par
%the same, with parameters \cs{vbadness} and \cs{vfuzz}.
%The difference is that for horizontal overfull boxes
%\TeX\ will draw a rule to the right of the box that has the
%same height as the box, and width \cs{overfullrule}.
%No overfull rule ensues if
%the \cs{tabskip} glue in an \cs{halign} cannot be
%shrunk enough.
对水平盒子与竖直盒子来说,相关警告的逻辑几乎完全相同。对于竖直盒子来说,有 \cs{vbadness} 以及 \cs{vfuzz} 来控制相关报错。区别之处在于,如果一个水平盒子溢出了,则 \TeX 会在盒子右侧绘制一个高度与盒子相同宽度为 \cs{overfullrule} 的溢出标尺。%
\cstoidx overfullrule\par
此处有一个例外,在 \cs{halign} 中,如果 \cs{tabskip} 伸缩胶无法提供足够的收缩量时,\TeX 不会绘制溢出标尺。
%\section{Opening and closing boxes}
\section{盒子的开始与结束}
%The opening and closing braces of a box can be either explicit, that
%is, character tokens of category 1\index{category!1}
%and~2\index{category!2}, or implicit, a control sequence \verb=\let=
%to such a character. After the opening brace the \csidx{everyhbox} or
%\csidx{everyvbox} tokens are inserted. If this box appeared in a
%\csidx{setbox} assignment any \csidx{afterassignment} token is
%inserted even before the `everybox' tokens.
盒子的内容以花括号定界。其中,左右花括号既可以是显式字符(分类码为 1\index{category!1} 和 2\index{category!2} 的字符),也可以是使用命令 \cs{let} 定义的隐式字符。\TeX 会将记号 \csidx{everyhbox} 或者 \csidx{everyvbox} 插入在左花括号之后。如果盒子位于 \csidx{setbox} 赋值语句中,则记号 \csidx{afterassignment} 会在「everybox」记号之前插入在左花括号之后。
\begin{example} \label{every:box:assign}
\begin{verbatim}
\everyhbox{b}
\afterassignment a
\setbox0=\hbox{c}
\showbox0
\end{verbatim}
% gives
的结果是:
\begin{verbatim}
> \box0=
\hbox(6.94444+0.0)x15.27782
.\tenrm a
.\tenrm b
.\kern0.27779
.\tenrm c
\end{verbatim}
\end{example}
%Implicit braces can be used to let a box be opened or closed
%by a macro, for example:
借助隐式花括号,我们可以通过宏来开始和结束盒子。比如下面的代码就用到了这一特性:
\begin{verbatim}
\def\openbox#1{\setbox#1=\hbox\bgroup}
\def\closebox#1{\egroup\DoSomethingWithBox#1}
\openbox0 ... \closebox0
\end{verbatim}
%This mechanism can be used to scoop up paragraphs:
利用这一机制,我们可以提取整个自然段的内容\liamfnote{这是一个在 plain \TeX 下的示例,而非是 \LaTeX 下的。因此,这里的 \cs{parbox} 不是 \LaTeX 里的段落盒子。关于这一技巧,此处有一完整示例:\url{https://gist.github.com/1d8b9bd2f401eb0ea970a47693723ab1}。}:
\begin{verbatim}
\everypar{\setbox\parbox=
\vbox\bgroup
\everypar{}
\def\par{\egroup\UseBox\parbox}}
\end{verbatim}
%Here the \cs{everypar} opens the box and lets the text be
%set in the box: starting for instance
此处,\cs{everypar} 命令\liamfnote{\cs{everypar} 命令的参数,会被插入在每个开启自然段的水平列表的头部,位于缩进盒子之后。}开始了一个盒子,并且将自然段的文本内容保存在盒子中。假设段落的开头是:
\begin{verbatim}
Begin a text ...
\end{verbatim}
%gives the equivalent of
这就等价于\liamfnote{注意这里忽略了盒子开头位置的 \cs{everypar} 以及对 \cs{par} 的重定义。}
\begin{verbatim}
\setbox\parbox=\vbox{Begin a text ...
\end{verbatim}
%Inside the box \cs{par} has been redefined, so
由于在盒子中,\cs{par} 被重定义了,所以,假设段落的结尾是\liamfnote{注意这里的 \cs{par} 可以是手工插入的,也可以是输入处理器在\cstate{S} 遇见行尾符自动插入的。}:
\begin{verbatim}
... a text ends.\par
\end{verbatim}
%is equivalent to
等价于
\begin{verbatim}
... a text ends.}\Usebox\parbox
\end{verbatim}
%In this example, the \cs{UseBox} command can only treat the
%box as a whole; if the elements of the box should somehow
%be treated separately another approach is necessary.
%In
在这个例子中,\cs{UseBox} 命令只能将盒子作为一个整体对待;如果想要分别处理盒子中的元素,则需要使用新的技巧。在下列代码中,\cs{HandleLines} 可以访问自然段竖直列表中连续的元素:
\begin{verbatim}
\everypar{\setbox\parbox=
\vbox\bgroup\everypar{}%
\def\par{\endgraf\HandleLines
\egroup\box\parbox}}
\def\HandleLines{ ... \lastbox ... }
\end{verbatim}
%the macro \cs{HandleLines} can have access to successive
%elements from the vertical list of the paragraph.
%See also the example on page~\pageref{varioset}.
第~\pageref{varioset}~页还有一个相关例子。
%%\point Unboxing
%\section{Unboxing}
%\point Unboxing
\section{将盒子解包}
%Boxes can be unwrapped by the commands \csidx{unhbox} and
%\csidx{unvbox}, and by their copying versions
%\csidx{unhcopy} and \csidx{unvcopy}.
%These are horizontal and vertical commands