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
|
% pages.tex
%
% \begin{stealth} \pspage{page_shake.ps} \end{stealth}
\chapter{How Pages are Handled in LameTeX}
If you're going to use the fancy pages included with this release of
LameTeX, but not try to design your own or make any PostScript hacks,
then you don't need to read about LameTeX pages. However, if you are
going to try your own hand at designing pages and fancy graphics, you
should learn a little bit about how LameTeX works so that things fit
together smoothly.
I'd love to hear what you've used LameTeX for. Please send e-mail to
{\tt jgm@cs.brown.edu}.
\section{Behind the Scenes of LameTeX}
\subsection{The Page Description}
A Page Description is a short program written in PostScript that
defines some standard stuff about the page that text gets placed on.
Take
% \begin{stealth} \begin{postscript}
% /Wizard LeftMarginIcon \end{postscript} \end{stealth}
a look at {\tt page\_latex.ps}, which is the standard plain
vanilla LaTeX-looking page. Here are the routines defined in this file:
\begin{description}
\item[PageShape]
is a {\bf required} routine that defines a PostScript
path for the page. A path is basically a squiggle on the page that
never gets drawn. It is a closed loop of arbitrary shape. It is pretty
% \begin{stealth} \begin{postscript}
% /Wizard LeftMarginIcon \end{postscript} \end{stealth}
easy to make a simple path out of straight lines using the PostScript
{\tt moveto} and {\tt lineto} commands, but it is possible to define a
very complex path with curves and fancy wiggles also. You can read
more about paths in the PostScript blue book, or chapter 4 of the red book.
The PageShape routine should leave a number on the stack called a {\em
setflat value}. If your path contains fancy curves, it is going to get
flattened into a series of lines using the PostScript {\bf
flattenpath} operator. Usually ``currentflat 8 mul'' works fine,
although if you want more preciseness and think your printer can
handle it, try smaller values. If you don't understand this, just use
``currenflat 8 mul'' and you should be fine.
\item[StartPage] is a {\bf required} routine that draws anything or
sets up anything required at the beginning of a page. Feel free to put
some fancy graphics here.
\item[EndPage] is a {\bf required} routine that draws anything or sets
up anything required at the end of the page. For example, the one in
{\tt page\_latex.ps} prints
\item[InitPage] is not required. It is just a simple enclosure for
defining some variables that {\em are} all required:
\begin{description}
\item[fillout] tells LameTeX whether you want to place text {\em
inside} the defined path, or {\em outside} of it. If you set fillout to true
LameTeX will not place any text inside your path.
\item[evenodd] is a fancy PostScript way of determining what is inside
and what is outside of a path. If this is true then it uses the
evenodd rules; false means use the winding rule. There's a description
of what the heck this means in the PostScript red book in Chapter 4,
section 6. Basically setting this variable to true means that every
part of the path delimits an outside-inside boundary.
\item[BM] In the event that fillout is true, this is the bottom of the
bounding rectangle that will be filled with text. If parts of the path
extend below this given number, it will be reset to be below the path.
\item[TM] In the event that fillout is true, this is the top of the
bounding rectangle that will be filled with text. If parts of the path
extend above this given number, it will be reset to be above the path.
\item[LM] In the event that fillout is true, this is the left of the
bounding rectangle that will be filled with text. If parts of the path
extend to the left of this given number, it will be reset to be to the
left of the path.
\item[RM] In the event that fillout is true, this is the right of the
bounding rectangle that will be filled with text. If parts of the path
extend to the right of this given number, it will be reset to be to
the right of the path.
\end{description}
\item[LeftMarginIcon] is not required. I just use it do define where
the left margin is, in case I want to place an Icon there.
\end{description}
\subsection{The Page Cycle}
LameTeX has three modes that it can be in:
\begin{enumerate}
\item
% \begin{stealth} \begin{postscript}
% /Wizard LeftMarginIcon \end{postscript} \end{stealth}
In-Between Pages
\item On a Page, In-Between Lines
\item On a Page, On a Line
\end{enumerate}
The cycle generally goes like this:
\begin{enumerate}
\item LameTeX starts off in ``In-Between Pages'' mode.
\item In-Between Pages mode processes commands until it encounters any
plain text or LameTeX command that might require that a new page be
started. When this happens it does the following:
\item Execute the {\tt save} command
\begin{enumerate}
\item Start a page by calling the /StartPage routine.
\item Do some internal initialization and call the /PageShape routine
\item Change to ``On a Page, In-Between Lines'' Mode.
\item On a Page, In-Between Lines mode processes commands until it
encounters any plain text or LameTeX command that might require that a
new line be started. When this happens it does the following:
\begin{enumerate}
\item Change to ``On a Page, On a Line'' mode.
\item Find a new line. NOTE: If you have broken the page up into two
or more horizontal regions (like {\tt page\_dagger.ps} does, then know
that a ``newline'' really means a new ``open space to put words''.
It's possible to have ``two new lines'' horizontally next to one
another. One goes on the left side of the dagger page description. The
next new line starts on the right side at the same horizontal
position. If you don't like this functionality, then don't define
regions that have two sides like the {\tt page\_dagger.ps}. Instead
define ``two pages'' like how {\tt page\_check.ps} works. The first
page will get filled before the second is begun.
\item Initialize a word list
that will contain information about this line. The very first item on
this word list will be a command to change to what is considered the
proper font when this line was begun.
\item If appropriate for each new word or command read in, it will
either add the word to the word list or add the {\em command itself}
to the word list. For example, a boldface command in between the words
FOO and BAR gets inserted in the word list between FOO and BAR. It
also get executed immediately.
\item Also for each new word read in, it checks to see if the word
list it is building overflows the width of the current line (as
defined in a very fancy way by the PostScript Page Definition file and
the PostScript path given by /PageShape). If there is an overflow, or
a natural end of line given by a text formatting command, then it does
the following:
\begin{enumerate}
\item Go through the word list from the beginning to the end and for each
element, either print it if it is a word, or execute it if it is a
command. Since the word list was initialized with a font-setting
command, the first thing this loop will do is choose the proper font.
Add a little space between words if text is supposed to be fully
justified.
\item If the cause of printing this line was a natural end of line,
then go to step 3.3.
\item Otherwise, create a new word list, and keep cycling in ``On a Page,
On a Line'' mode.
\end{enumerate}
\end{enumerate}
\item Eventually, going to a new line means falling off of the bottom
of the page, and a we change back to ``In-Between pages mode'', and do
the following:
\end{enumerate}
\item Execute the {\tt restore} command
\item End a Page by calling the /EndPage routine.
\item Go to step 2.
\end{enumerate}
LameTeX horizontally aligns the words by remembering all the words on
the current line, and then printing the whole line at once when the
line gets filled up. Printing all the words at once means that it can
be smart enough to justify the text to exactly match both margins.
There
% \begin{stealth} \begin{postscript}
% /Wizard LeftMarginIcon \end{postscript} \end{stealth}
is no concept of vertical alignment. Unlike LaTeX, LameTeX does {\bf not}
remember all the lines in a paragraph and then print the paragraph all
at once in the right place.
The {\bf save} and {\bf restore} commands are PostScript operators to do
memory management. Basically what happens is that when the {\tt restore}
command is encountered, the entire current memory of the printer is
replaced with what it was like when the {\tt save} command was
executed.
This means that if you set a variable in your StartPage routine, you
will be able to access that variable throughout the length of the
page, but you will not be able to access it in the EndPage routine. If
you want to have some always-changing always-remembered variable like
the page number, use the InitPage and EndPage routines instead.
Note
% \begin{stealth} \begin{postscript}
% /Wizard LeftMarginIcon \end{postscript} \end{stealth}
that the InitPage and EndPage routines are {\em outside} of the
save-restore loop. So anything that happens in these two routines
stays around forever.
\subsubsection{Which Commands Force A New Page Or A New Line?}
Check it out in {\tt Operator.C}. Yes, that's a C++ source file. Don't
be afraid of it - it won't hurt you. In this file at the top is a huge
table of command names. The first row is the command name, the second
is a boolean (either a 0 or a 1) saying whether this command is a
stealth command. The third is a boolean (either a 0 or 1) saying
whether or not a new page or new line should be started if this
command is executed In-Between Pages or Not-On-A-Line.
Also, all plain text words force On-A-Line-ness and On-A-Page-ness.
\subsubsection{Specifying the Page Description Directories}
LameTeX will look in the current directory to find page description
files or any other postscript files, but if it cannot find them you
must tell it where to look. You can use the -p command, explained in
the startup chapter, or set your environment variable LAMETEX\_PS\_PATH
to some path which will be searched for postscript files. The current
directory and the LameTeX main library directory will always be searched.
There is a great deal more about this in the PostScript chapter.
|