-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathchapitre11.tex
2399 lines (1965 loc) · 80.9 KB
/
chapitre11.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
\chapter{新玩具}
\begin{epigraphe}{《圣经·雅歌》7:11}
我属我的良人,他也恋慕我。\\我的良人,来吧,你我可以往田间去。你我可以在村庄住宿!\\我们早晨起来往葡萄园去,\\看看葡萄发芽开花没有,石榴放蕊没有。\\我在那里要将我的爱情给你。
\end{epigraphe}
在本章,我会介绍专为本书创建的工具。为了看懂本章定义的大部分指令和环境,你需要阅读过第9章和第10章的内容……本章中,我们会涉及带有``危险''标记的提示的创建方法、各章开头的首字下沉、摘要、术语字典、带有当前章号的标签,以及并列展示\LaTeX 代码和效果的环境。
\section{一些小手工}
\subsection{参数和排版转换}
在涉及信息语言的文档中,需要突出显示参数、指令,以及函数。例如,我们需要这类效果:
\begin{codelist}[11.1]{
为了编译文件\codereplace{文件}:
\begin{flushleft}
\ttfamily latex \codereplace{文件}
\end{flushleft}
}
\begin{verbatim}
为了编译文件\bwarg{文件}:
\begin{flushleft}
\ttfamily latex \bwarg{文件}
\end{flushleft}\end{verbatim}
\end{codelist}
指令\verb|\bwmarg|可以以\textsl{倾斜字体}来输出其参数,并且置于``⟨''和``⟩''之间。这种括号可以在数学模式下分别由指令\verb|\langle|、\verb|\rangle|生成。此外,你无疑注意到了,我们可以使用下标符号,就像这样:
\begin{codelist}[11.2]{
复制文件:
\begin{flushleft}\ttfamily
cp \codereplace{文件$_1$} ...
\codereplace{文件$_n$}
\codereplace{文件$_{dst}$}
\end{flushleft}
}
\begin{verbatim}
复制文件:
\begin{flushleft}\ttfamily
cp \bwarg[1]{文件} ...
\bwarg[n]{文件}
\bwarg[dst]{文件}
\end{flushleft}\end{verbatim}
\end{codelist}
指令\verb|\bwarg|\jz{
这个名称代表``黑白''参数(« black \& white » argument)……
}的定义如下:
\begin{dmd}
\begin{verbatim}
\newcommand{\marg}[2][]{%
{\normalfont%
\textsl{$\langle$#2%
% 如果选用了可选参数
\ifthenelse{\equal{#1}{}}{}
{$_\mathit{#1}$}% 显示下标
$\rangle$}}}%\end{verbatim}
\end{dmd}
指令\verb|\normalfont|的效果是回到文档的默认字体。这解释了为什么示例11.1中的``\codereplace{文件}''没有使用打字机字体显示。
在本文档的电子版(也就是需要通过屏幕阅读的版本)中,我们决定使用\emph{颜色}而不是字符``⟨''和``⟩''。这样一来,可以定义指令\verb|\colarg|:
\begin{dmd}
\begin{verbatim}
\newcommand{\colarg}[2][]{{%
\normalfont\color{blue!90}#2% 蓝色
\ifthenelse{\equal{#1}{}}{}{$_\mathit{#1}$}}}\end{verbatim}
\end{dmd}
接下来,借助一个巧妙放置的布尔值\celan{\S 9.3.1},我们可以定义一个通用的指令\verb|\marg|,以调用其中的一个版本(黑白版本或彩色版本):
\begin{dmd}
\begin{verbatim}
\ifversionenligne
\let\marg\colarg
\else
\let\marg\bwarg
\fi\end{verbatim}
\end{dmd}
这个结构调用了\TeX 的指令\verb|\let|,在9.2.3小节有明确的介绍。
\subsection{关于索引的生成}
本书中,凡是行文中提到指令、环境、包、文档类型等时,都会调用对应的特殊指令,来自动在索引中插入一条入口\yz{
怎么不早说。算了先不做索引了,全书翻译完之后再调整吧。
}。举例来说,这样一来的效果为:
\begin{codelist}[11.3]{
借助包\textsf{varioref},可以
使用指令\dm{\backslash vref}……
}
\begin{verbatim}
借助包\ltxpack{varioref},可以
使用指令\ltxcom{vref}……\end{verbatim}
\end{codelist}
指令\verb|\ltxpack|的定义如下。首先,以下内容定义的指令\verb|\ltx@pack|可以以非衬线字体展示包名:
\begin{dmd}
\begin{verbatim}
\newcommand{\ltx@pack}[1]{%
\upshape\textsf{#1}}\end{verbatim}
\end{dmd}
接下来,我们像这样定义:
\begin{dmd}
\begin{verbatim}
\newcommand{\ltxpack}[1]{%
\ltx@pack{#1}%
\protect\index{扩展们!\protect\texttt{#1}}%
\protect\index{#1@\protect\textsf{#1 扩展}}}\end{verbatim}
\end{dmd}
其中调用了前面定义的指令,并在索引中插入了两个入口,一个遵循``\codereplace{包名}扩展''的格式,另一个作为``扩展们''的\celan{\S 6.3}子入口。这里,指令\verb|\protect|的作用是避免指令\verb|\ltxpack|本身作为作为另一条指令的参数时带来的麻烦。遵循同样的思路,我们可以定义指令\verb|\ltxcom|。首先:
\begin{dmd}
\begin{verbatim}
\newcommand{\ltx@com}[1]{%
\texttt{\symbol{92}#1}}\end{verbatim}
\end{dmd}
以上指令可以以打字机字体生成指令名,并在前面加上字符\dm{\backslash}。\verb|\symbol|是\LaTeX 指令,此处用于插入所选字体下的第92个字符(恰好为反斜杠)。因此,我们最终有如下定义:
\begin{dmd}
\begin{verbatim}
\newcommand{\ltxcom}[1]{%
\ltx@com{#1}%
\index{#1@\protect\texttt{\symbol{92}#1}}}\end{verbatim}
\end{dmd}
该指令调用了上一条指令,在索引中插入一个入口。此处需要提炼出的思想是,定义可以自动在索引中插入入口的指令可能很有帮助。举例来说,我们也许可以定义这样一条指令:
\begin{dmd}
\begin{verbatim}
\newcommand{\jargonanglais}[1]{%
\emph{#1}%
\index{#1}}\end{verbatim}
\end{dmd}
该指令可以在设置英文术语格式的同时将其插入索引——比如某个特殊的索引。同样,如果在文档中经常出现,我们就可以定义一条指令,将其插到索引中。例如,在本书中,我们有这样的定义:
\begin{dmd}
\begin{verbatim}
\newcommand{\postscript}{%
PostScript%
\protect\index{PostScript}}\end{verbatim}
\end{dmd}
\subsection{跳转提示}
本书的纸质版中四处分散着跳转阅读的提示,例如这个提醒你去看\celan{\S D.3.5}术语字典(glossaire)的提示——幸亏我们这里在说跳转阅读,否则这个术语字典就这里的内容毫无关联了\jz{
如果你没完全跟上的话,我是想说,这里其实没有术语字典的什么事……
}。实现跳转提示符号的指令被赐名为\verb|\voir|,接收两个参数:
\begin{dmd}
\backslash voir\{\codereplace{目标标签}\}\{\codereplace{跳转对象文本}\}
\end{dmd}
例如,前面的跳转是这样生成的:
\begin{dmd}
\verb|\voir{chap-glossaire}{glossaire}|
\end{dmd}
这个指令的设计过程中,全部的``难点''在于怎样让三角形根据页面奇偶性来改变朝向。借助包\textsf{chngpage},这一难点得以功课。请参阅9.3.3小节。
余下的工作就是展示三角形。为了达成这一目的,我们定义了两个指令,分别生成侧栏的跳转提示和正文中的标记。由此,\verb|\voir|的格式如下:
\begin{dmd}
\begin{verbatim}
\newcommand{\voir}[3][\S]{%
\checkoddpage%
\ifcpoddpage
\v@irpageimpaire{#1}{#2}{#3}}{% 奇数页的跳转提示
\else
\v@irpagepaire{#1}{#2}{#3}}} % 偶数页的跳转提示
\fi\end{verbatim}
\end{dmd}%TODO 此处括号似乎不配对
我们注意到,除了两个必需的参数外,该指令还可以接收一个可选参数,它默认定义为段落标记(\S)。指令\verb|\v@irpageimpaire|和\verb|\v@irpagepaire|是对称的,作用如下:
\begin{enumerate}
\item 将``朝向正确''的三角形放置在文本中,作为跳转提示对象;
\item 在侧栏生成带有跳转目标的注解。
\end{enumerate}
三角形可以从包\textsf{amssymb}中包含的符号中获取:
\begin{codelist}[11.4]{
天啊,那些``蟀爆了''的三角形:
$\blacktriangleleft$和
$\blacktriangleright$!
}
\begin{verbatim}
天啊,那些``蟀爆了''的三角形:
$\blacktriangleleft$和
$\blacktriangleright$!\end{verbatim}
\end{codelist}
如下所示,是针对在偶数页实现跳转提示的指令的最终版本:
\begin{dmd}
\begin{verbatim}
\newcommand{\v@irpageimpaire}[3]{%
{\tiny$\blacktriangleright$}#3% 文本中的跳转提示
\marginpar{%
\parbox[t]{.9\marginparwidth}{%
{\footnotesize\sffamily%
\hfill#1~\ref{#2}}~{\small$\blacktriangleleft$}\\
{\footnotesize\sffamily%
\mbox{}\hfill p.~\pageref{#2}\hfill\mbox{}}}}\end{verbatim}
\end{dmd}% TODO 括号配对
注意到,在侧栏的跳转内容包含于一个\verb|\parbox|\celan{\S 4.4.3},其中分两行展示章节编号和页码\yz{
中文版没做。%TODO 页码
}。对于奇数页,需要做与偶数页相同的事情,只不过需要考虑到它是奇数页\dm{:-)}
在``在线''版本中,跳转提示可以像超文本链接(lien hypertexte)那样呈现。这可以简单地通过指令\verb|\hyperref|(对应包同名)来实现。因此,我们可以编写出这类指令:
\begin{dmd}
\begin{verbatim}
\newcommand{\voir}[3][\S]{%
\hyperref[#2]{#3}}\end{verbatim}
\end{dmd}
其中的可选参数没有过多的用处,只是为了与``纸质''版本中的指令\verb+\voir+兼容。
\subsection{更改侧栏}
在本文中,我多次临时改变了侧栏的样子,尤其是针对用于并列展示\LaTeX 代码和其效果,或需要展示题记等内容%TODO 是题记吗?
的情况。为了实现这种效果,维护\LaTeX 法文问答社区的玛丽-保罗·克卢特(Marie-Paul Kluth)\jz{
这位似乎有个命中注定的姓[lom prédestilé;\textsl{译注}:将nom prédestiné中的n替换为了l。此处是在调侃此人的姓(Kluth)与发明\TeX 的高德纳的姓(Knuth)仅有一个字母的区别]……
}提议使用一种集成环境,如下所示:
\begin{dmd}
\begin{verbatim}
\newenvironment{changemargin}[2]%
{\begin{list}{}{%
\setlength{\listparindent}{\parindent}%
\setlength{\itemindent}{\parindent}%
\setlength{\leftmargin}{#1}%
\setlength{\rightmargin}{#2}%
}\item }%
{\end{list}}\end{verbatim}
\end{dmd}
其中的思路是定义一个列表,而我们修改其中的侧栏。该环境接收的两个参数分别代表左侧和右侧的边距尺寸。这样的思路可以让环境产生很有趣的结果:边距会根据页面的奇偶性而实用不同的尺寸。这样的环境可以定义如下:
\begin{dmd}
\begin{verbatim}
\newenvironment{agrandirmarges}[2]{%
\begin{list}{}{%
\setlength{\topsep}{0pt}%
\setlength{\listparindent}{\parindent}%
\setlength{\itemindent}{\parindent}%
\setlength{\parsep}{0pt plus 1pt}%
\checkoddpage%
\ifcpoddpage
\setlength{\leftmargin}{-#1}
\setlength{\rightmargin}{-#2}
\else
\setlength{\leftmargin}{-#2}
\setlength{\rightmargin}{-#1}
\fi}\item }%
{\end{list}}\end{verbatim}
\end{dmd}
\newenvironment{agrandirmarges}[2]{%
\begin{list}{}{%
\setlength{\topsep}{0pt}%
\setlength{\listparindent}{\parindent}%
\setlength{\itemindent}{\parindent}%
\setlength{\parsep}{0pt plus 1pt}%
\checkoddpage%
\ifcpoddpage
\setlength{\leftmargin}{-#1}
\setlength{\rightmargin}{-#2}
\else
\setlength{\leftmargin}{-#2}
\setlength{\rightmargin}{-#1}
\fi}\item }%
{\end{list}}
注意,这里我们使用了指令\verb|\isodd|来测试页面的奇偶性。图\ref{fig:11.1}展示了使用这种环境的示例,其代码如下:
\begin{figure}[bt]
\centering
\newcommand{\graphtex}{%
\includegraphics[height=2cm]{img/knuth-tex}}
\begin{agrandirmarges}{1cm}{2cm}
\begin{center}
\graphtex\graphtex\graphtex\graphtex\graphtex%
\graphtex\graphtex\graphtex\graphtex\graphtex%
\graphtex\graphtex\graphtex\graphtex\graphtex%
\graphtex\graphtex\graphtex\graphtex%
\end{center}
\caption{一幅内容完全不重要的图。它的出现只是为了说明我们可以在需要额外空间的时候临时修改左边距和右边距……}
\label{fig:11.1}
\end{agrandirmarges}
\end{figure}
\begin{dmd}
\begin{verbatim}
\begin{figure}[tb]
\begin{agrandirmarges}{1cm}{2cm}
% 这里1cm针对``订口''侧
% 2cm针对``切口''侧
...
\caption{一幅内容完全不重要的……}
\end{agrandirmarges}
\end{figure}\end{verbatim}
\end{dmd}
\section{各种提示}
提示中可以见到的符号来源于``剪贴画''(……)。在图\ref{fig:11.2}中以3 cm的宽度展示了这些符号。在文档对应位置插入这些符号的``提示''由鄙人定义的环境生成。环境基于\TeX 层面的一项功能,而这项功能正是我勤勉地阅读\TeX Book是发现的,那就是指令\verb|\parshape|。该指令可以为段落指定任意形状:
\begin{codelist}[11.5]{
\parshape=5
1.5cm 2.5cm
1.5cm 2.5cm
1cm 2cm
1cm 2cm
0pt \textwidth
a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a
}
\begin{verbatim}
\parshape=5
1.5cm 2.5cm
1.5cm 2.5cm
1cm 2cm
1cm 2cm
0pt \textwidth
a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a \end{verbatim}
\end{codelist}
\begin{figure}[htb]
\begin{center}
\includegraphics[width=3cm]{img/fmb-important}\quad%
\includegraphics[width=3cm]{img/fmb-note}\quad%
\includegraphics[width=3cm]{img/fmb-question}
\end{center}
\caption{手册中使用的符号}
\label{fig:11.2}
\end{figure}
符号``=''后面的数字用于指明我们想要变形的行数。接下来,成对出现的数字用于指明缩进和该行变形后的长度。对于上述示例,有:
\begin{itemize}
\item 最先出现的两行缩进1.5 cm,并且每行长2.5 cm;
\item 接下来的两行缩进1 cm,并且每行长2 cm;
\item 第五行(也是最后一次指明内容)可以决定接下来所有行的风格,即缩进0 cm且行长等于事先定义的长度\verb|\textwidth|。
\end{itemize}
因此,想要在段落中插入提示,我们可以借助该指令将前两行错位:
% \newlength{\larnota}
% \newlength{\largligne}
\begin{codelist}[11.6]{
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne
\larnota\largligne
0pt\textwidth
\noindent 注意,这个段落唯一的
作用,就是用来证明我们确实可以
将段落中的两行内容错后一些,并
让随后的内容如同什么都没有发生
一样继续……
}
\begin{verbatim}
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne
\larnota\largligne
0pt\textwidth
\noindent 注意,这个段落唯一的
作用,就是用来证明我们确实可以
将段落中的两行内容错后一些,并
让随后的内容如同什么都没有发生
一样继续……\end{verbatim}
\end{codelist}
好了,接下来要做的事情就是在指令\verb|\parshape|留下的``洞口''中放上图片,让我们来简单地尝试一下:
\begin{codelist}[11.7]{
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\includegraphics[width=\larnota]{%
img/fmb-important}
注意,这个段落唯一的作用,就是
用来证明我们确实可以将段落中的
两行内容错后一些,并让随后的内
容如同什么都没有发生一样继续……
}
\begin{verbatim}
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\includegraphics[width=\larnota]{%
\ficnota}
注意,这个段落唯一的作用,就是
用来证明我们确实可以将段落中的
两行内容错后一些,并让随后的内
容如同什么都没有发生一样继续……\end{verbatim}
\end{codelist}
显然,这里的图像像其他字符一样放置在行上。我们将其放入宽度为零的字盒中,这样可以让字盒的内容右对齐:
\begin{codelist}[11.7]{
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}%
\parshape=3
\larnota\largligne\larnota\largligne%
0pt\textwidth\noindent%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
img/fmb-important}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]
}
\begin{verbatim}
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}%
\parshape=3
\larnota\largligne\larnota\largligne%
0pt\textwidth\noindent%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
\ficnota}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]\end{verbatim}
\end{codelist}
接下来要做的是为这个图标施加竖直方向的位移(实际上,这个图标是正方形的,因此我们可以使用尺寸\verb|\indnota|):
\begin{codelist}[11.9]{
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota}{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
img/fmb-important}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]
}
\begin{verbatim}
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota}{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
\ficnota}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]\end{verbatim}
\end{codelist}
得,还是不行。需要让\LaTeX 相信我们所移动的字盒的尺寸为零:
\begin{codelist}[11.10]{
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota}[0pt][0pt]{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
img/fmb-important}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]
}
\begin{verbatim}
\setlength{\larnota}{.9cm}
\setlength{\largligne}{%
\textwidth-\larnota}
\parshape=3
\larnota\largligne\larnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota}[0pt][0pt]{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
\ficnota}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]\end{verbatim}
\end{codelist}
我们就快要达到目的了。接下来需要做两处调整。
\begin{itemize}
\item 字盒太低了些,这是因为参考线是文本行的底端。因此,我们可以在位移时抬升\dm{1ex}(字符的高度)。
\item 在图标和文档之间添加一些空间是个不错的想法。为此,我们定义一个长度\verb|\padnota|。
\end{itemize}
% \newlength{\padnota}
% \newlength{\indnota}
\begin{codelist}[11.11]{
\setlength{\padnota}{5pt}
\setlength{\larnota}{.9cm}
\setlength{\indnota}{\larnota+\padnota}
\setlength{\largligne}{%
\textwidth-\indnota}
\parshape=3
\indnota\largligne\indnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota+2.2ex}[0pt][0pt]{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
img/fmb-important}%
\hspace*{\padnota}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]
}
\begin{verbatim}
\setlength{\padnota}{5pt}
\setlength{\larnota}{.9cm}
\setlength{\indnota}{\larnota+\padnota}
\setlength{\largligne}{%
\textwidth-\indnota}
\parshape=3
\indnota\largligne\indnota\largligne
0pt\textwidth\noindent%
\raisebox{-\larnota+2.2ex}[0pt][0pt]{%
\makebox[0pt][r]{%
\includegraphics[width=\larnota]{%
\ficnota}%
\hspace*{\padnota}}}%
注意,这个美观的段落唯一的作用
,就是用来证明我们确实可以将段
落中的两行内容错后一些 [...]\end{verbatim}
\end{codelist}
当当当当!接下来将这些代码修改成可以创建新环境的样子就可以了。这里使用的技巧基于9.5节介绍的环境\dm{list}。环境的完整代码如下:
\begin{dmd}
\begin{verbatim}
% 为参数传入文件名
\newenvironment{pictonote}[1]{%
\begin{list}{}{%
\setlength{\labelsep}{0pt}%
\setlength{\rightmargin}{15pt}}
\item%
\setlength{\indentationnota}{%
\@totalleftmargin+\largeurnota+\paddingnota}%
\setlength{\largeurlignenota}{%
\linewidth-\largeurnota-\paddingnota}%
\parshape=3%
\indentationnota\largeurlignenota%
\indentationnota\largeurlignenota%
\@totalleftmargin\linewidth%
\raisebox{-\largeurnota+2.2ex}[0pt][0pt]{%
\makebox[0pt][r]{%
\includegraphics[width=\largeurnota]{#1}%
\hspace{\paddingnota}}}%
\ignorespaces}{%
\end{list}}\end{verbatim}
\end{dmd}
\begin{exclamation}
注意,使用尺寸\verb|\@totalleftmargin|可以获取列表左侧边距的宽度,并将可能出现的嵌套纳入考虑。实际上,列表中的尺寸\verb|\leftmargin|代表了\emph{相对于}包含该列表的环境的做边距。
\end{exclamation}
接下来,我们可以使用此环境,并为其传入特殊的文件作为参数。更好的方案是,我们可以去定义新的环境,例如:
\begin{dmd}
\verb+\newenvironment{nota}{%+\\
\verb+ \begin{pictonote}{+\codereplace{你的文件}\verb+}}{\end{pictnote}}+
\end{dmd}
\begin{qquestion}
作为本节的结尾,需要知道,这个环境有些问题:如果提示中包含新的段落,那么会多出一块为图标预留的空白。%TODO
没错,没错,就像这里展示的一样。你也看到了,段首为图标留出了一块空白,但这里我们并不需要,对吧?为了避免这种麻烦,需要借助下面的咒语,在\TeX 的层面重新初始化缩进:
\begin{dmd}
\verb|\par\parshape=1\@totalleftmargin\linewidth|
\end{dmd}
这段内容可以作为一个指令的对象,在各个新段落的段首手动插入,就像我刚刚做的那样\dm{:-)}
\end{qquestion}
\section{引文}
\subsection{题记}
本书中,我将生成各章首那些有煽动性的题记的环境命名为\dm{epigraphe}。例如,在第2章的\LaTeX 原代码中,我们可以找到:
\begin{dmd}
\begin{verbatim}
\chapter{需要了解的知识}
\label{chap-savoir}
\begin{epigraphe}{《圣经·箴言》\textbf{21} 11}
亵慢的人受刑罚,愚蒙的人就得智慧。
智慧人受训诲,便得知识。
\end{epigraphe}\end{verbatim}
\end{dmd}
环境\dm{epigraphe}的定义如下:
\begin{dmd}
\begin{verbatim}
\newenvironment{epigraphe}[1]
{% begin条目
\vspace*{-1.5cm}%
\small\sffamily% 突出显示
\savebox{\nomepigraphe}{#1}% 存储引文来源
% 的字盒
\slshape% 将内容设为倾斜
\begin{changemargin}{0pt}{-2cm}% 设置宽度
\begin{flushright}}% 将文字推到右侧
{% end文牧
\\[4pt]\usebox{\nomepigraphe}.% 插入来源
\end{flushright}%
\end{changemargin}\par\vspace*{0.6cm}}\end{verbatim}
\end{dmd}
其中,需要\celan{\S 4.4.5}声明用于储存引文来源的字盒:
\begin{dmd}
\verb|\newsavebox{\nomepigraphe}|
\end{dmd}
该环境首尾插入的竖直方向的空白(\verb|\vspace|)可以使题记正确地固定在章首和微型目录中间。
\subsection{引用内容}
本书各处散步着各式各样的引用内容(citation),它们由手工制作的环境生成:
\definecolor{coulcitation}{rgb}{0.90,0.75,0.20}%
\newenvironment{citationzero}[1][]{%
\ifthenelse{\equal{#1}{}}{%
\setboolean{auteurcitationpresent}{false}}{%
\setboolean{auteurcitationpresent}{true}%
\savebox{\auteurcitation}{#1}}% on le sauve si nécessaire
\begin{lrbox}{\boitecitation}
\begin{minipage}{.8\linewidth}%
\setlength{\parindent}{10pt}%
\small\slshape«\ignorespaces}% on passe en petit et penché
{\unskip»
\ifthenelse{\boolean{auteurcitationpresent}}%
{\par\nopagebreak\hfill\usebox{\auteurcitation}}
{}% sinon on ne fait rien...
\end{minipage}
\end{lrbox}
\begin{center}
\setlength{\fboxsep}{10pt}%
\colorbox{coulcitation}{\usebox{\boitecitation}}
\end{center}}
%
\begin{codelist}[11.12]{%TODO
xxxxxxxxxxxxx
\begin{citationzero}[乔治·巴塔伊]
老去的恐惧无穷无尽地延续着。
衰老将未完成的存在重置为开端。
我隐约在坟墓的边缘看见的开端是
死亡和侮辱都不能杀死的心中的
\emph{猪肉}。坟墓边缘的恐惧是
神授予的,我堕落于作为孩子的恐
惧之中。
\end{citationzero}
xxxxxxxxxxxxxxx
}
\begin{verbatim}
xxxxxxxxxxxxx
\begin{unecitation}[乔治·巴塔伊]
老去的恐惧无穷无尽地延续着。
衰老将未完成的存在重置为开端。
我隐约在坟墓的边缘看见的开端是
死亡和侮辱都不能杀死的心中的
\emph{猪肉}。坟墓边缘的恐惧是
神授予的,我堕落于作为孩子的恐
惧之中。
\end{unecitation}
xxxxxxxxxxxxxxx\end{verbatim}
\end{codelist}
我们将会一步一步地创建这个环境。在创建过程中,可以预见\LaTeX 会抛给我们一些经典的问题。我们会基于9.6节和4.5.2小节的环境来定义可以生成引文和作者的引文环境:
\begin{dmd}
\begin{verbatim}
% 为引文的作者准备字盒
\newsavebox{\auteurcitation}
\newsavebox{\boitecitation}
\newenvironment{citationi}[1]{% begin条目
% 存储带有作者信息的参数1
\savebox{\auteurcitation}{#1}%
\begin{lrbox}{\boitecitation}
\begin{minipage}{.8\linewidth}
\small\slshape}% 设为小字号斜体
{% end条目:将引文作者推至右侧
\par\mbox{}\hfill\usebox{\auteurcitation}
\end{minipage}
\end{lrbox}
\begin{center}
\usebox{\boitecitation}
\end{center}\end{verbatim}
\end{dmd}
这样的效果是:
\newenvironment{citationi}[1]{% begin条目
% 存储带有作者信息的参数1
\savebox{\auteurcitation}{#1}%
\begin{lrbox}{\boitecitation}
\begin{minipage}{.8\linewidth}
\small\slshape}% 设为小字号斜体
{% end条目:将引文作者推至右侧
\par\mbox{}\hfill\usebox{\auteurcitation}
\end{minipage}
\end{lrbox}
\begin{center}
\usebox{\boitecitation}
\end{center}}
\begin{codelist}[11.13]{
前文 前文 前文 前文 前文 前文 前文
前文 前文 前文 前文 前文 前文 前文
\begin{citationi}{米歇尔·巴库尼, 1845}
在几乎所有的国家,女性都是奴隶。
只要她们没有完全得到解放,我们
自身的自由就不可能实现。
\end{citationi}
后文 后文 后文 后文 后文 后文 后文
后文 后文 后文 后文 后文 后文 后文
}
\begin{verbatim}
前文 前文 前文 前文 前文 前文 前文
前文 前文 前文 前文 前文 前文 前文
\begin{citationi}{米歇尔·巴库尼, 1845}
在几乎所有的国家,女性都是奴隶。
只要她们没有完全得到解放,我们
自身的自由就不可能实现。
\end{citationi}
后文 后文 后文 后文 后文 后文 后文
后文 后文 后文 后文 后文 后文 后文\end{verbatim}
\end{codelist}
我们也可以在环境中修改程度\verb|\parindent|的值,来修改微型页面中段落的缩进(在该环境中,默认为\dm{0pt}):
\begin{dmd}
...\\
\verb|\begin{lrbox}{\boitecitation}|\\
\verb| \begin{minipage}{.8\linewidth}%|\\
\verb| \setlength{\parindent}{10pt}%|\quad $\leftarrow$\textsf{缩进第1行}\\
...
\end{dmd}
接下来,可以插入引言首尾的引号,代码如下:
\begin{dmd}
\begin{verbatim}
...
\begin{minipage}{.8\linewidth}%
\setlength{\parindent}{10pt}%
\small\slshape« \ignorspaces}% 设为小字号斜体
{\unskip »
\par\mbox{}\hfill\usebox{\auteurcitation}
...\end{verbatim}
\end{dmd}
对于指令\verb|\ignorespaces|和\verb|\unskip|的含义,可以参考9.2.1小节。目前的效果如下:
\newenvironment{citationiii}[1]{%
% on sauve l'argument 1 pour l'auteur
\savebox{\auteurcitation}{#1}%
\begin{lrbox}{\boitecitation}
\begin{minipage}{.8\linewidth}%
\setlength{\parindent}{10pt}%
\small\slshape«\ignorespaces}% on passe en petit et pench�
{\unskip»
% on saute un paragraphe et on pousse l'auteur de la citation � droite
\par\mbox{}\hfill\usebox{\auteurcitation}
\end{minipage}
\end{lrbox}
\begin{center}
\usebox{\boitecitation}
\end{center}}
\begin{codelist}[11.14]{
前文 前文 前文 前文 前文 前文 前文
前文 前文 前文 前文 前文 前文 前文
\begin{citationiii}{
米歇尔·巴库尼, 1845}
在几乎所有的国家,女性都是奴隶。
只要她们没有完全得到解放,我们
自身的自由就不可能实现。
\end{citationiii}
后文 后文 后文 后文 后文 后文 后文
后文 后文 后文 后文 后文 后文 后文
}
\begin{verbatim}
前文 前文 前文 前文 前文 前文 前文
前文 前文 前文 前文 前文 前文 前文
\begin{citationiii}{
米歇尔·巴库尼, 1845}
在几乎所有的国家,女性都是奴隶。
只要她们没有完全得到解放,我们
自身的自由就不可能实现。
\end{citationiii}
后文 后文 后文 后文 后文 后文 后文
后文 后文 后文 后文 后文 后文 后文\end{verbatim}
\end{codelist}
我们快要达到目的了。接下来,我们将代表``引言作者''的参数设置为可省略项,从而达到在需要时不显示作者的效果。实现的思路是声明一个布尔值来表明引言(citation)的作者(auteur)是否出现(présent):
\begin{dmd}
\verb|\newboolean{auteurcitationpresent}|
\end{dmd}
接下来,修改环境定义如下:
\begin{dmd}
\begin{verbatim}
% 参数默认为空:
\newenvironment{unecitation}[1][] {%
% begin条目:
% 记录是否出现了引言作者
\ifthenelse{\equal{#1}{}}{%
\setboolean{auteurcitationpresent}{false}}{%
\setboolean{auteurcitationpresent}{true}%
\savebox{\auteurcitation}{#1}}% 在必要时存储作者
...\end{verbatim}
\end{dmd}
接下来,修改环境的end条目,只在作者参数出现时插入作者:
\begin{dmd}
\begin{verbatim}
{»% 环境的end条目
% 如果具有作者,我们将其推至右侧
\ifthenelse{\boolean{auteurcitation}}%
{\par\nopagebreak\hfill\usebox{\auteurcitation}}
{}% 否则,什么也不做……\end{verbatim}
\end{dmd}
最终,我们为引言添加底纹。例如,我们可以借助包\textsf{xcolor}定义这个颜色:
\begin{dmd}
\verb+\definecolor{coulcitation}{rgb}{0.90,0.75,0.20}%+
\end{dmd}
只需将end条目中的指令\verb|\usebox|替换为以下内容:
\begin{dmd}
\begin{verbatim}
\setlength{\fboxsep}{10pt}%
\colorbox{coulcitation}{\usebox{\boitecitation}}\end{verbatim}
\end{dmd}
最终的效果为:
% \newboolean{auteurcitationpresent}
% \definecolor{coulcitation}{rgb}{0.90,0.75,0.20}%
\newenvironment{citationiv}[1][]{%
\ifthenelse{\equal{#1}{}}{%
\setboolean{auteurcitationpresent}{false}}{%
\setboolean{auteurcitationpresent}{true}%
\savebox{\auteurcitation}{#1}}% on le sauve si nécessaire
\begin{lrbox}{\boitecitation}
\begin{minipage}{.8\linewidth}%
\setlength{\parindent}{10pt}%
\small\slshape«\ignorespaces}% on passe en petit et penché
{\unskip»
\ifthenelse{\boolean{auteurcitationpresent}}%
{\par\nopagebreak\hfill\usebox{\auteurcitation}}
{}% sinon on ne fait rien...
\end{minipage}
\end{lrbox}
\begin{center}
\setlength{\fboxsep}{10pt}%
\colorbox{coulcitation}{\usebox{\boitecitation}}
\end{center}}
%
\begin{codelist}[11.15]{
前文 前文 前文 前文 前文 前文 前文
\begin{citationiv}[皮埃尔·德普罗热]
他是如此痴迷,以至于最终甚至
不吃饭。
\end{citationiv}
后文 后文 后文 后文 后文 后文 后文
}
\begin{verbatim}
前文 前文 前文 前文 前文 前文 前文
\begin{citationiv}[皮埃尔·德普罗热]
他是如此痴迷,以至于最终甚至
不吃饭。
\end{citationiv}
后文 后文 后文 后文 后文 后文 后文\end{verbatim}
\end{codelist}
\section{首字下沉}
注重排版的文档往往会实现称作\emph{首字下沉}的效果,也就是根据排版学中使用的规则,将各章的首字母放大,并对其后续的单词或词组做类似的处理。例如:
\begin{codelist}[11.16]{
\lettrine{L}{es documents} soignés font
souvent appel aux lettrines, qui selon
les règles d'usage en typographie...
}
\begin{verbatim}
\lettrine{Les documents} soignés font
souvent appel aux lettrines, qui selon
les règles d'usage en typographie...\end{verbatim}
\end{codelist}
从中已经可见实现该效果的两个难点。
\begin{itemize}
\item 如何针对指令参数的首字母进行处理。
\item 如何让各行文本向后错位来为下沉的首字留出空间。我们可以像提示(\S 11.2)中那样使用指令\verb|\parshape|来实现这一点。
\end{itemize}
\subsection{指令\texttt{\backslash glurps},迈向\TeX 的一步}
在\LaTeX 层面,创建新指令的指令是\verb|\newcommand|。对于指令的创建来说,\LaTeX 的一大短板就是限制参数的符号只能为\dm{\{}和\dm{\}}。正如我们稍后会看到的,在\TeX 层面,这中限制不复存在。实际上,想要使用\TeX 创建指令,可以这样编写:
\begin{codelist}[11.17]{
\def\bidule{一些内容}
\bidule{} 和 \bidule
}
\begin{verbatim}
\def\bidule{一些内容}
\bidule{} 和 \bidule\end{verbatim}
\end{codelist}
对于带有一个即以上参数的情况,可以这样写:
\begin{codelist}[11.18]{
\def\bidule#1#2{(1=#1) 和 (2=#2)}
\bidule{甲乙}{丙丁}
}
\begin{verbatim}
\def\bidule#1#2{(1=#1) 和 (2=#2)}
\bidule{甲乙}{丙丁}\end{verbatim}
\end{codelist}
注意到,在\TeX 中,我们在定义中按顺序写下参数。有趣的是,对于首字下沉,我们将会探索类似以下示例展示的指令\verb|\bidule|的用法:
\begin{codelist}[11.19]{
\def\bidule#1#2{(1=#1) 和 (2=#2)}
\bidule abcd
\bidule ab cd
}
\begin{verbatim}
\def\bidule#1#2{(1=#1) 和 (2=#2)}
\bidule abcd
\bidule ab cd\end{verbatim}
\end{codelist}