% 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.