aboutsummaryrefslogtreecommitdiffstats
path: root/doc/expert/exa_page
blob: 31ab1d7e5a3f283edf7bc501e8aaecb1f6b7d44e (plain) (blame)
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
@Section
   @Title { Page layout }
   @Tag { pagelayout }
@Begin
@PP
The page layout
page.layout.inpractice @SubIndex { in practice }
document.layout.page.layout. @SubIndex { page layout }
definitions given in Section {@NumberOf definitions},
although correct, are very basic.  In this section we present the
definitions used by the DocumentLayout package for laying out the pages
of books, including running page headers and footers, different formats
for odd and even pages, and so on.  The present document is produced with
these definitions.
@PP
We begin with a few definitions which permit the user to create cross
references of the `see page 27' variety which will be kept up to date
automatically.  The user marks the target page by placing
@Code {"@PageMark intro"}, for example, at the point of interest, and
refers to the marked page as @Code "@PageOf intro" elsewhere:
pageof.example @Index { @Code "@PageOf" example }
@IndentedList
@LI @Code {
"export @Tag"
"def @PageMarker right @Tag { @Null }"
}
@LI @Code {
"def @PageMark right x"
"{"
"    @PageMarker&&preceding @Tagged x"
"}"
}
@LI @Code {
"def @PageOf right x"
"{"
"    @PageMarker&&x @Open { @Tag }"
"}"
}
@EndList
We will see below that an invocation of @Code "@PageMarker" appears before
each page, with @Code "@Tag" parameter equal to the
page number.  Suppose that {@Code "@PageMark intro"}, which expands to
@ID @Code "@PageMarker&&preceding @Tagged intro"
happens to fall on page 27 of the final printed document (of course, its
value is @@Null which makes it invisible).  Then the effect of @@Tagged
is to attach @Code "intro" as an extra tag to the first invocation of
{@Code "@PageMarker"} preceding that final point, and this must be
{@Code "@PageMarker 27"}.  Therefore the expression
@ID @Code "@PageMarker&&intro @Open { @Tag }"
will open the invocation {@Code "@PageMarker 27"} and yield the value of
its @Code "@Tag" parameter, 27.  Thus, {@Code "@PageOf intro"} appearing
anywhere in the document yields 27.
@PP
Next we have some little definitions for various parts of the
page.  {@Code "@FullPlace"} will be the target of full-width body text:
@ID @Code {
"def @FullPlace { @Galley }"
}
{@Code "@ColPlace"} will be the target of body text within one column:
@ID @Code {
"def @ColPlace { @Galley }"
}
{@Code "@TopList"} will be the target of figures and tables:
@ID @Code {
"export @Tag"
"def @TopList right @Tag"
"{"
"    @Galley"
"    //@TopGap @TopList @Next @Tag"
"}"
}
We have taken a shortcut here, avoiding an unnecessary @Code "@TopPlace"
symbol.  @Code "@FootList" and {@Code "@FootSect"} define a sequence of
full-width targets at the foot of the page for footnotes,
preceded by a short horizontal line:
footsect.example @Index { @Code "@FootSect" example }
@IndentedList
@LI @Code {
"export @Tag"
"def @FootList right @Tag"
"{"
"    @Galley"
"    //@FootGap  @FootList @Next @Tag"
"}"
}
@LI @Code {
"def @FootSect"
"{"
"    @FootLen @Wide @HLine"
"    //@FootGap  @FootList 1  ||@FootLen"
"}"
}
@EndList
Similarly, @Code "@ColFootList" and @Code "@ColFootSect" provide a
sequence of targets for footnotes within one column:
@ID @Code {
"export @Tag"
"def @ColFootList right @Tag"
"{"
"    @Galley"
"    //@FootGap  @ColFootList @Next @Tag"
"}"
""
"def @ColFootSect"
"{"
"    @ColFootLen @Wide @HLine"
"    //@FootGap  @ColFootList 1  ||@ColFootLen"
"}"
}
The next definition provides a horizontal sequence of one or more columns:
collist.example @Index { @Code "@ColList" example }
@ID @Code {
"def @ColList right col"
"{"
"    def @Column"
"    {  @VExpand { @ColPlace //1rt @OneRow { //@MidGap @ColFootSect } }  }"
""
"    col @Case {"
"        Single @Yield @Column"
"        Double @Yield { @DoubleColWidth @Wide @Column  ||@ColGap  @ColList col }"
"        Multi  @Yield { @MultiColWidth @Wide @Column  ||@ColGap  @ColList col }"
"    }"
"}"
}
Each column consists of a @Code "@ColPlace" at the top and a
@Code "@FootSect" at the foot.  The @@VExpand symbol ensures that
whenever a column comes into existence, it will expand vertically so
that the bottom-justification @Code "//1rt" has as much space as
possible to work within.  The @Code "col" parameter determines whether
the result has a single column, double columns, or multiple columns.
@PP
The {@Code "@Page"} symbol places its parameter in a page of fixed width,
height, and margins:
page.example @Index { @Code "@Page" example }
@ID @Code {
"def @Page right x"
"{"
"    @PageWidth @Wide @PageHeight @High {"
"        //@PageMargin  ||@PageMargin"
"        @HExpand @VExpand x"
"        ||@PageMargin  //@PageMargin"
"    }"
"}"
}
@@HExpand and @@VExpand ensure that the right parameter occupies all the
available space; this is important when the right parameter is unusually
small.  The @@High symbol gives the page a single row mark, ensuring that
it will be printed on a single sheet of paper (page {@PageOf rootg}).
@PP
Next we have {@Code "@OnePage"}, defining a typical page of a book or
other document:
onepage.example @Index { @Code "@OnePage" example }
@ID @Code {
"def @OnePage"
"    named @Columns {}"
"    named @PageTop {}"
"    named @PageFoot {}"
"{"
"    @Page {"
"        @PageTop"
"        //@MidGap  @TopList"
"        //@MidGap  @FullPlace"
"        //@MidGap  @ColList @Columns"
"        // //1rt   @OneRow { //@MidGap @FootSect //@MidGap @PageFoot }"
"    }"
"}"
}
The page top and page foot, and the number of columns, are parameters
that will be given later when @Code "@OnePage" is invoked.  The body of
the page is a straightforward combination of previous definitions.  The
@Code "//" symbol protects the following @Code "//1rt" from deletion in
the unlikely event that all the preceding symbols are replaced by
@@Null.  The following object is enclosed in @@OneRow to ensure that
all of it is bottom-justified, not just its first component.
@PP
Before presenting the definition of a sequence of pages, we must detour
to describe how running page headers and footers (like those in the
present document) are produced.  These are based on the
@Code "@Runner" symbol:
runner.example @Index { @Code "@Runner" example }
@ID @Code {
"export @TopOdd @TopEven @FootOdd @FootEven"
"def @Runner"
"    named @TopOdd right @PageNum { @Null }"
"    named @TopEven right @PageNum { @Null }"
"    named @FootOdd right @PageNum { @Null }"
"    named @FootEven right @PageNum { @Null }"
"    named @Tag {}"
"{ @Null }"
}
The four parameters control the format of running headers and footers on
odd and even pages respectively.  Invocations of {@Code "@Runner"}, for
example
@ID @Code {
"@Runner"
"    @TopEven { @B @PageNum |1rt @I { Chapter 4 } }"
"    @TopOdd  { @I { Examples }   |1rt @B @PageNum }"
}
will be embedded in the body text of the document, and, as we will see
in a moment, are accessed by @Code "@Runner&&following" cross references
on the pages.  Notice how the @Code "@PageNum" parameter of each
parameter allows the format of the running header to be specified while
leaving the page number to be substituted later.
@PP
We may now define {@Code "@OddPageList"}, whose result is a sequence of
pages beginning with an odd-numbered page:
oddpagelist.example @Index { @Code "@OddPageList" example }
@ID @Code {
"def @OddPageList"
"    named @Columns {}"
"    right @PageNum"
"{"
"    def @EvenPageList ..."
""
"        @PageMarker @PageNum"
"    //  @Runner&&following @Open {"
"            @OnePage"
"                @Columns { @Columns }"
"                @PageTop { @TopOdd @PageNum }"
"                @PageFoot { @FootOdd @PageNum }"
"        }"
"    //  @EvenPageList"
"            @Columns { @Columns }"
"            @Next @PageNum"
"}"
}
Ignoring @Code "@EvenPageList" for the moment, notice first that the
invocation of @Code "@OnePage" is enclosed in
{@Code "@Runner&&following @Open"}.  Since {@Code "@Runner&&following"}
refers to the first invocation of @Code "@Runner" appearing after itself
in the final printed document, the symbols @Code "@TopOdd" and
@Code "@FootOdd" will take their value from the first invocation of
@Code "@Runner" following the top of the page, even though @Code "@FootOdd"
appears at the foot of the page.  Their @Code "@PageNum" parameters are
replaced by {@Code "@PageNum"}, the actual page number parameter of
{@Code "@OddPageList"}.
@PP
After producing the odd-numbered page, @Code "@OddPageList" invokes
{@Code "@EvenPageList"}:
evenpagelist.example @Index { @Code "@EvenPageList" example }
@ID @Code {
"def @EvenPageList"
"    named @Columns {}"
"    right @PageNum"
"{"
"        @PageMarker @PageNum"
"    //  @Runner&&following @Open {"
"            @OnePage"
"                @Columns { @Columns }"
"                @PageTop { @TopEven @PageNum }"
"                @PageFoot { @FootEven @PageNum }"
"        }"
"    //  @OddPageList"
"            @Columns { @Columns }"
"            @Next @PageNum"
"}"
}
This produces an even-numbered page, then passes the ball back to
@Code "@OddPageList" -- a delightful example of what computer
scientists call mutual recursion.  The two page types differ only in
their running headers and footers, but other changes could easily be made.
@PP
It was foreshadowed earlier that an invocation of @Code "@PageMarker"
would precede each page, and this has been done.  Although this @Code
"@PageMarker" is a component of the root galley, it will not cause a
page to be printed, because Basser Lout skips components of height zero.
@End @Section