diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-09 00:44:40 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-09 00:44:40 +0000 |
commit | b4fc5f639874db951177ec539299d20908adb654 (patch) | |
tree | 52f08823ca58fffe3db6a9b075635038c567626c /Master/texmf-dist/doc/latex/dialogl | |
parent | dec3d98ebe442d7ea93efbaa8dd2e2be8149a467 (diff) |
doc 4
git-svn-id: svn://tug.org/texlive/trunk@80 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/latex/dialogl')
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/animals.tex | 217 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/animals2.tex | 26 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/cnvunits.tex | 134 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/codialog.tex | 2461 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/dia-driv.tex | 246 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/diatest.tex | 162 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/fontmenu.tex | 67 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/dialogl/listout.tex | 3130 |
8 files changed, 6443 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/dialogl/animals.tex b/Master/texmf-dist/doc/latex/dialogl/animals.tex new file mode 100644 index 00000000000..dcce0c32029 --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/animals.tex @@ -0,0 +1,217 @@ +% Animals (in TeX, no less!!!) +% +% This is the program that uses a binary tree of questions to +% guess the type of animal of which the user is thinking. +% +% Andrew Marc Greene, March-April 1988 +% +%%% modified May 1991, Michael Downes: +%%% ---removed path names to leave bare file names +%%% ---added animals2.tex so that you can repeat without +%%% restarting TeX +%%% ---added code so that lowercase and uppercase user +%%% responses will both be recognized. +% +% Moral support (i.e., ``You can't do that! Show us!'') +% provided by the Student Information Processing Board +% of MIT. +% +% Instructions on running this program: +% +% tex animals +% +% Think of an animal. The program will try to guess your animal. +% +% You will be asked a whole bunch of yes/no questions. This is a +% spartan implementation, so answer with a capital Y or N. When +% the program finishes going through its tree, it will either have +% guessed your animal or it will ask you to enter a question that +% it can ask to differentiate between your animal and its guess. +% It will then ask you which one is `yes.' + +% Here's where I declare all my variables, etc. +% +% ``curcode'' is the current index into the data file. +% ``temp'' is a temporary holding variable. +% ``lc'' is a loop counter +% ``ifamg'' is a general-purpose flag. amg are my initials. +% ``ifreploop'' controls loop repetitions. +% ``ifmainlooprep'' controls repetitions of the main loop. +% ``inp'' is the input file. +% ``outp'' is the output file. +% ``amgY'' and ``amgN'' are character constants. Why I did it this way I +% don't remember. +% +\newcount\curcode\curcode=1\newcount\temp\temp=0\newcount\lc +\newif\ifamg\newif\ifyn\newif\ifreploop\newif\ifmainlrep +\newread\inp\newwrite\outp\def\foo{} +\def\amgY{Y}\def\amgN{N} + +% The data file consists of records stored in the following format: +% +% Record Number <newline> +% Question <newline> +% If-Yes-Goto-Record Number <newline> +% If-No-Goto-Record Number <newline> +% +% The following routine scans the data file until it reaches the +% record requested in \curcode +% +\def\Scan{% +{\loop + \global\read\inp to \foo + \ifnum\foo=\curcode\amgfalse\else\amgtrue\fi + \ifamg\read\inp to \foo\read\inp to \foo\read\inp to \foo +\repeat}} + +% The following routine displays the question and waits for a Y or N +% answer +% +\def\Query{% +{\read\inp to \foo +\immediate\write16{}% +\message{\foo}% +\GetYN +\ifyn + \read\inp to \foo\global\curcode=\foo\read\inp to \foo +\else + \read\inp to \foo\read\inp to \foo\global\curcode=\foo +\fi +}} + +% The following routines deal with the user's input. +% \vread (verbatim read) ignores <newline>s and makes <space>s normal +% \GetYN gets input and repeats until it gets a Y or N response. +% +\def\vread#1{{\catcode`\^^M=9\catcode`\ =12\global\read-1 to #1}} +\def\first#1#2\end{#1} +% +\def\GetYN{% +{\loop +\vread{\bar}% +\edef\bar{\uppercase{\def\noexpand\bar{% + \expandafter\first\bar\empty\end}}}\bar +\reploopfalse +\if Y\bar\global\yntrue\else + \if N\bar\global\ynfalse\else\replooptrue\fi\fi +\ifreploop +\immediate\write16{Hey, you! Answer Y or N, please.}% +\message{Please enter Y or N --> }% +\repeat +}} + +% The following routine is called if the ``Goto-Record'' is -1, +% meaning that the program didn't guess correctly and is clueless. +% It gets the new animal and the differentiating question, and +% modifies the data file. Actually, it makes a modified copy of +% the file, then copies the temporary new one over the old outdated +% one. +% +\def\NewAnimal{ +\immediate\write16{Well, I'm stumped. What animal did you have in mind?} +\vread{\usersanimal} +\immediate\write16{OK. What question would let me tell the difference?} +\vread{\userquery} +\immediate\write16{Is the answer to that question Yes or No if I ask about} +\message{\usersanimal? } +\GetYN +\curcode=-1 +\Scan +\read\inp to \lastcode\lc=\lastcode +\closein\inp +% +% Open up the files. These names are system-dependent. *FLAG* +% +\openin\inp=animal.dat +\ifeof\inp \errmessage{Unable to open animal.dat!}\fi +\immediate\openout\outp=newaniml.dat +% +% Read through the inp file, copying all records that don't need to +% be changed, outputting modified versions of the changed ones (and +% discarding the old), and appending the new records. +% +{\loop + \read\inp to \foo + \amgtrue + \ifnum\foo=\temp\amgfalse\fi + \ifnum\foo=-1 \amgfalse\fi + \ifamg\immediate\write\outp{\foo}% + \read\inp to \foo\immediate\write\outp{\foo}% + \read\inp to \foo\immediate\write\outp{\foo}% + \read\inp to \foo\immediate\write\outp{\foo}% + \amgtrue + \else\ifnum\foo=\temp + \immediate\write\outp{\foo}% + \immediate\write\outp{\userquery}% + \immediate\write\outp{\number\lc}% + \global\advance\lc by 1 + \immediate\write\outp{\number\lc}% + \read\inp to \animal\read\inp to \foo\read\inp to \foo + \amgtrue + \else + \lc=\lastcode + \ifyn\WriteUsers\WriteAnimal + \else\WriteAnimal\WriteUsers + \amgfalse\fi + \fi\fi + \ifamg +\repeat} +\closein\inp +\immediate\write\outp{-1} +\immediate\write\outp{\number\lc} +\immediate\closeout\outp +% +% Now copy the temporary file over the original one +% +% These filenames are also system-dependent. *FLAG* +% +\openin\inp=newaniml.dat +\ifeof\inp \errmessage{Unable to open newaniml.dat!}\fi +\immediate\openout\outp=animal.dat +{\endlinechar=-1 + \loop + \read\inp to \foo + \immediate\write\outp{\foo} + \amgtrue + \ifeof\inp\amgfalse\fi + \ifamg\repeat} +\immediate\closeout\outp +} +% +% This routine is called by NewAnimal and writes the record for +% the user's new animal +% +\def\WriteUsers{ +\immediate\write\outp{\number\lc} +\immediate\write\outp{Is it \usersanimal?} +\immediate\write\outp{0} +\immediate\write\outp{-1} +\global\advance\lc by 1 } + +% This one writes the modified old animal +% +\def\WriteAnimal{ +\immediate\write\outp{\number\lc} +\immediate\write\outp{\animal} +\immediate\write\outp{0} +\immediate\write\outp{-1} +\global\advance\lc by 1 } + +% Now we get into the main routine. +% It simply repeats the scan-query loop until it gets a 0 (right answer) +% or a -1 (wrong answer, I'm stumped), and calls the appropriate routine. +% +\def\maybecontinue{\input animals2.tex + \maybecontinue} + +\maybecontinue + +% Ah, the joys of a job well-done. We can now exit to the system, knowing +% that the world is a slightly better place for our efforts. +% +% The following line of code, probably the most profound in the entire +% program, sums up this philosophy of life in four characters. The +% Puritan work ethic is embodied in this amazingly meaning-laden +% command designed by Donald Knuth. + +\end diff --git a/Master/texmf-dist/doc/latex/dialogl/animals2.tex b/Master/texmf-dist/doc/latex/dialogl/animals2.tex new file mode 100644 index 00000000000..5096c1a55d9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/animals2.tex @@ -0,0 +1,26 @@ +\openin\inp=animal.dat +\ifeof\inp \errmessage{Unable to open animal.dat!}\fi +\loop + \temp=\curcode + \Scan + \Query + \mainlreptrue + \ifnum\curcode=0 + \immediate\write16{% + Thank you for using Animals. I'm glad I got it right.} + \mainlrepfalse + \else + \ifnum\curcode=-1 \NewAnimal\mainlrepfalse\fi + \fi +\ifmainlrep +\repeat + +\closein\inp +\message{Wanna go again? }% +\GetYN +\ifyn + \curcode=1 % initialization +\else + \def\maybecontinue{}% +\fi +\endinput diff --git a/Master/texmf-dist/doc/latex/dialogl/cnvunits.tex b/Master/texmf-dist/doc/latex/dialogl/cnvunits.tex new file mode 100644 index 00000000000..adf6e79165e --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/cnvunits.tex @@ -0,0 +1,134 @@ +\newdimen\zdim \newdimen\tempdim \newdimen\tempdima + +% Conversion factors: +% +% According Scaled Rational Prime +% Unit to TeX Points Form Factorization +%----------------------------------------------------------------- +% 1 sp 0.00002 pt 1 1/65536 pt 1 / 2^16 +% 1 mm 2.84526 pt 186467 7227/2540 pt 3*3*11*73 / 2*2*5*127 +% 1 cm 28.45274 pt 1864679 7227/254 pt 3*3*11*73 / 2*127 +% 1 pt 1.0 pt 65536 100/7227 in 2*2*5*5 / 3*3*11*73 +% 1 pc 12.0 pt 786432 12/1 pt +% 1 dd 1.07 pt 70124 1238/1157 pt 2*619 / 13*89 +% 1 cc 12.8401 pt 841489 14856/1157 pt 2*2*2*3*619 / 13*89 +% 1 bp 1.00374 pt 65781 803/800 pt 11*73 / 2*2*2*2*2*5*5 +% [1/72 in] +% 1 in 72.2699 pt 4736286 7227/100 pt 3*3*11*73 / 2*2*5*5 +% [2.54 cm] [254/100 cm] + +\def\points#1#2#3{\tempdim#2\relax + \edef#3{\csname cnvunits#1\expandafter\endcsname\the\tempdim}% +} + +\def\inches#1#2#3{% + \tempdim=#2\relax + \tempdima=\ifdim\tempdim<\zdim -\fi\tempdim % absolute value + \roundup\tempdima{#1}{in}% +% In the interest of maximum accuracy we push \tempdima as near +% to \maxdimen as possible before dividing, using the prime +% factorization of the fraction 7227/100 which is the +% points/inches conversion factor. + \ifdim\tempdima<.01\maxdimen + \multiply\tempdima 100 \divide\tempdima 7227 + \else + \ifdim\tempdima<.1\maxdimen + \multiply\tempdima 10 \divide\tempdima 11 + \multiply\tempdima 10 \divide\tempdima 657 + \else + \divide\tempdima 9 \multiply\tempdima 5 + \divide\tempdima 803 \multiply\tempdima 20 + \fi + \fi + \tempdim=\ifdim\tempdim<\zdim -\fi \tempdima + \edef#3{% + \csname cnvunits#1\expandafter\endcsname\the\tempdim}% +} + +% Function \roundup for rounding upward. #1 must be a dimension +% register. If it holds a negative value it will be rounded +% `outward' away from zero rather than `upward' toward zero. #3 +% is a TeX units string such as "pt" or "in". If #2 = 0 then +% this will round up to the nearest tenth; if #2 = 00, nearest +% hundredth; and so forth (up to 5 zeros). If #2 is empty then +% full accuracy up to TeX's limits will be used. +% +% The rounded result will be returned in the dimension register +% #1. + +\def\roundup#1#2#3{% + \if .#2.\else + \begingroup + \ifdim#1>\zdim + \advance#1-\maxdimen \advance#1.#25#3\relax + \fi + \ifdim#1<\zdim + \endgroup + \advance#1.#25#3 + \else + \endgroup + \fi + \fi +} + +\begingroup +\catcode`\P=12 \catcode`\T=12 +\lowercase{% +\expandafter\gdef\csname cnvunits\endcsname#1PT{#1} +\expandafter\gdef\csname cnvunits0\endcsname#1.#2PT{% + #1.\takeone#20\takeone} +\expandafter\gdef\csname cnvunits00\endcsname#1.#2PT{% + #1.\taketwo#200\taketwo} +\expandafter\gdef\csname cnvunits000\endcsname#1.#2PT{% + #1.\takethree#2000\takethree} +\expandafter\gdef\csname cnvunits0000\endcsname#1.#2PT{% + #1.\takefour#20000\takefour} +\expandafter\gdef\csname cnvunits00000\endcsname#1.#2PT{% + #1.\takefive#200000\takefive} +}% +\endgroup + +\def\takeone#1#2\takeone{#1} +\def\taketwo#1#2#3\taketwo{#1#2} +\def\takethree#1#2#3#4\takethree{#1#2#3} +\def\takefour#1#2#3#4#5\takefour{#1#2#3#4} +\def\takefive#1#2#3#4#5#6\takefive{#1#2#3#4#5} + +\def\showinches#1{\inches{00}{#1}\converted + \immediate\write16{% + #1 = (after conversion) \converted\space inches}} + +\showinches{0in} \showinches{1in} \showinches{2.0in} +\showinches{2.2in} \showinches{8.5in} \showinches{1pc} +\showinches{6pc} \showinches{1cm} \showinches{1mm} +\showinches{1bp} \showinches{72bp} \showinches{1cc} +\showinches{1dd} \showinches{72dd} \showinches{5000pt} +\showinches{-5000pt} \showinches{\maxdimen} +\showinches{-\maxdimen} \showinches{.999\maxdimen} +\showinches{1pt} \showinches{.01pt} + +\endinput + +% From the TeX log: + +0in = (after conversion) 0.00 inches +1in = (after conversion) 1.00 inches +2.0in = (after conversion) 2.00 inches +2.2in = (after conversion) 2.20 inches +8.5in = (after conversion) 8.50 inches +1pc = (after conversion) 0.17 inches +6pc = (after conversion) 1.00 inches +1cm = (after conversion) 0.39 inches +1mm = (after conversion) 0.04 inches +1bp = (after conversion) 0.01 inches +72bp = (after conversion) 1.00 inches +1cc = (after conversion) 0.18 inches +1dd = (after conversion) 0.01 inches +72dd = (after conversion) 1.07 inches +5000pt = (after conversion) 69.18 inches +-5000pt = (after conversion) -69.18 inches +\maxdimen = (after conversion) 226.70 inches +-\maxdimen = (after conversion) -226.70 inches +.999\maxdimen = (after conversion) 226.48 inches +1pt = (after conversion) 0.01 inches +.01pt = (after conversion) 0.00 inches diff --git a/Master/texmf-dist/doc/latex/dialogl/codialog.tex b/Master/texmf-dist/doc/latex/dialogl/codialog.tex new file mode 100644 index 00000000000..75d144f20d9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/codialog.tex @@ -0,0 +1,2461 @@ +%%% ==================================================================== +%%% @LaTeX-file{ +%%% filename = "codialog.tex", +%%% version = "1.1a", +%%% date = "2-Dec-1994", +%%% time = "15:24:21 EST", +%%% checksum = "06649 2461 14834 104289", +%%% author = "Michael Downes", +%%% address = "49 Weeks Street +%%% North Smithfield, RI 02986, USA", +%%% email = "mjd@math.ams.org (Internet)", +%%% docstring = "The checksum field above contains: CRC-16 +%%% checksum, number of lines, number of words, and number of +%%% characters, as produced by Robert Solovay's checksum utility.", +%%% } +%%% ==================================================================== +\documentstyle[dialogl% +,draft% +]{article} + +\title{Carrying on Dialog with \TeX} +\author{Michael J. Downes\\ +49 Weeks Street\\ +North Smithfield, RI 02895\\ +E-mail: {\tt mjd@math.ams.org}} +\date{November 1994} + +\hyphenation{ams-tex back-slash-char base-line-skip circle circlew + cnv-units con-trol-seq end-line-char err-help err-mes-sage + error-con-text-lines escape-char Hel-vet-ica hyphen-char + hyphen-pen-alty include-only lcircle lcirclew new-line-char + open-out par-fill-skip report-math-code show-box-depth show-prog-ress + show-hyphens tables} +\allowtthyphens + +\typeout{} +\typeout{% +--- This document can be printed in landscape or portrait orientation;} +\typeout{% +--- landscape is recommended for better presentation of the examples.} +\typein[\answer]{% +--- If you need portrait, enter P; otherwise, just press <return> now:} + +\def\p{p}\def\P{P} +\ifx\p\answer \let\answer=\P\fi +\ifx\P\answer + \portraitlayout +\else + \defaultlayout % defined in dialogl.sty +\fi + +\begin{document} + +\maketitle +\thispagestyle{empty} + +\tableofcontents + +% If we don't have at least half of the current column open, go to +% the next page. +\reqspace{.5\textheight} + +\section{Introduction} + +A common task in any programming language is to send a question to the +user, and to read (and act on) the user's response. In \tex/, this +usually involves the \cw{read}, \cw{message}, and \cw{write} commands. +The use of these commands, however, is beset at every turn by odd +hindrances and technical stumbling blocks, so that even experienced +macro writers, faced with an application that requires a bit of +dialog, usually find it troublesome to make that bit of dialog +good-looking, reliable, convenient for the user, and tolerant of +typical human mistakes such as minor mistyping in a response. The +purpose of this article is to analyze the capabilities that \tex/ has +for dialog and survey all the best relevant macro-writing techniques +that fall within the scope of my experience and research.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{This is an overhauled and amplified version of my paper +``Dialog with \tex/'' in {\sl TUGboat}, vol~12 no~3, Part 2, December +1991 (proceedings of the 1991 TUG conference in Dedham, +Massachusetts).} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +In \texbook/, near the end of Chapter 20, Knuth writes + \begin{quote} It's easy to have dialogs with the user, by using + \cw{read} together with the \cw{message} command + \end{quote} +and there follows a brief example involving reading the user's name +into a macro \verb"\myname". It's clear from this passage that Knuth +means, by \term{dialog}, ordinary communication between computer programs +and users at the early-1980s level of technology: printing +character-based information on a video screen, displaying menus, asking +questions, and handling user responses. (Speech recognition and voice +synthesis are not part of the picture for most \tex/ users, yet.) For the +purposes of this article, I define \term{dialog} as any communication +between \tex/ and the user that takes place while \tex/ is running. +Forms of communication that do not take place while \tex/ is running +are excluded: for example, the black box that \tex/ prints to indicate +an overfull line in a paragraph is useful information, but not dialog +because the communication occurs after \tex/ has stopped running.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{This distinction is blurring, however, with +the advent of software like Blue Sky Research's Lightning Textures.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +On the other hand, the {\tt Overfull \string\hbox} message +printed on screen whenever \tex/ adds a black box to the +current paragraph {\em is} dialog, because it does occur while \tex/ is +running. + +Since the entire section of \texbook/ where Knuth's dialog example appears +is marked off with double dangerous bend signs, it seems that Knuth +didn't intend his words ``It's easy'' to be taken completely +literally---particularly when we look at the next thing in that +section, Exercise 20.18, which reads, + \begin{quote} + The \cw{myname} example just given doesn't work quite right, because the + $\langle$return$\rangle$ at the end of the line gets translated + into a space. Figure out how to fix that glitch. + \end{quote} +That line-ending space is only one of a number of complications that +can hamper the efforts of macro writers to write dialog for practical +applications. In fact, the word {\em easy} is far from the first +adjective that comes to mind when I remember my own early attempts at +writing dialogical macros. Though my thrashing and floundering for +the most part took place behind the scenes, invisible to others, it +eventually reached the point of threatening my secret belief that I +was a hot-shot macro writer. That spurred me to start paying special +attention to anything related to the idea of dialog in \tex/, and +accumulating scraps and pieces of assorted useful techniques. This +article is more or less a survey of what I've learned so far. +Sections \ref{s:messages} and~\ref{s:receiving} review the functions +\tex/ provides to support dialog; sections~\ref{s:stumblewrite} +and~\ref{s:stumbleread} discuss common difficulties and how to handle +them. + +\subsection{Terminology} +Rather than assume all readers know well enough the meaning of terms +like \term{primitive}, \term{token}, or \term{control word} that will +be bandied about hereinafter, I offer a quick review of some standard +\tex/ terminology, to aid those who want it, and to be skipped by the +rest of you. + +A \tex/ command is either a \term{control sequence}---a string of +characters starting with an \term{escape character}---or a single +\term{active character}, such as \verb|~|. The usual escape character +is the \term{backslash}, \verb|\|. A control sequence that consists of +a backslash plus one nonletter character is called a \term{control +symbol}; a control sequence that consists of a backslash plus one or +more letters is called a \term{control word}. Spaces are ignored after +a control word, but not after a control symbol. A control sequence is +either a \term{\tex/ primitive}---a command built into the \tex/ +program---or a macro: a composition of primitives or other macros, +defined by the user or by a \term{macro package} such as \latex/ or +\plaintex/. A control sequence may require one or more following +\term{arguments}; an argument is a piece of text that is grabbed up by +the control sequence in order to do something with it. Arguments +typically are enclosed in \term{curly braces} \verb|{| and \verb|}|. +For example, the command \cw{sqrt} is a macro with one argument, and +is used thus: \verb|\sqrt{x^2+y^2}|, producing the printed output +$\sqrt{x^2+y^2}$. + +Macros are \term{expandable}; some primitives are +expandable, more are not. An expandable control +sequence will be replaced by its expansion if it is used inside the +argument of a \cw{message} command, or anywhere else where \tex/ is +in an expansive mood (\cw{write}, \cw{errmessage}, \cw{edef}, +\cw{xdef}, \cw{mark}, \cw{special} [\texbook/, p216]). + +The term \term{parameter} is used to mean a numeric or dimensional +variable such as \cw{hyphenpenalty}, \cw{hsize}, or \cw{baselineskip}. A +\term{token} is eithera character (with associated catcode) or a control +sequence, {\em after\/} it has been read by \tex/ from some file and +entered into \tex/'s active memory. Character tokens can only have +category codes 1--4, 6--8, or 10--13; there's no such thing as a +`character token' with category code 0, 5, 9, 14, or 15: those catcodes +only control the process of creating tokens, they aren't designed for +permanent association to a token. + +Under normal circumstances, each line in a file is understood by +\tex/ to have a \ctrl{M} character, {\sc ascii} 13, at the end of it, +even if your text editor actually puts some other character, or +no character, at the end of a line when you press the \return/ or +{\sc enter} key. + +\subsection{Basic dialog principles} +It's not hard to identify a number of principles that make for good +dialog: +\begin{enumerate} +\item When asked a yes/no question, users should +be able to enter \verb|y|, \verb|yes|, or even \verb|ye|, +in lowercase, uppercase, or even mixed case, and have the +answer understood to be ``yes''. + +\item For any menu or question, a default answer +should be provided (when this makes sense), and the default +answer should be made as easy as possible to select. + +\item Users' answers should be repeated back to them, +to allow them to verify that the program's impression +of the answer entered by the user is indeed correct. + +\item Users should be given a chance to undo mistakes, +\eg., by going back to a specified point earlier in the +dialog and starting over from there. For example, it shouldn't be necessary to +stop \tex/ and restart just to fix a typing error. + +\item When practical, users' answers should be checked to make sure +they're not nonsense; for example, if a program requests an integer, +it should check the response to make sure the user didn't enter +something else entirely, rather than assume an integer was entered and +start to perform operations on it. In \tex/ this would create a risk +of losing control to low-level errors such as +{\tt Missing number, treated as~0} or {\tt Arithmetic overflow}. + +\item Information given to users should be provided in the ``best +possible form'', where the meaning of ``best possible'' must be +determined by common sense from the circumstances of a particular +application and the targeted user group. For example, a +straightforward use of the \cw{the} command to report the value of a +\tex/ dimension parameter such as \cw{vsize} to the user will produce +the value in points, down to five or six decimal places. It will +normally be more useful to report the value rounded to the nearest +whole point, or to report it in picas, inches, or +centimeters---whatever is most convenient for the user. A +typographical designer or compositor would probably prefer picas, +while someone with little knowledge of typography would probably +prefer inches or centimeters. + +\end{enumerate} + +\section{\tex/'s Message-Sending Capabilities} +\label{s:messages} + +Table~\ref{t:sending} lists the various means in \tex/ for sending +messages to the user. + +\begin{table*} +\vspace{-\medskipamount} % needed because \caption has wrong spacing + % when used at the top rather than the bottom + % of a float environment. +\caption[]{\label{t:sending}Commands that can be used for +sending messages} +\writepage{Table} +\vskip1pc +\def\hline{\noalign{\vskip3pt\hrule\vskip2pt\relax}} +\tabskip0pt +\halign to\hsize{#\hfil\tabskip1em plus.2\hsize minus0.7em& + #\hfil& \parbox[t]{.6\hsize}{\rightskip0pt plus2em\relax#}\cr +\hline +Command& Example& Result\cr +\hline +\cw{message}& \verb'\message{Hey you}'& {\tt ... Hey you ...}\cr +\hline +\cw{write}& \verb'\immediate\write{Hey you}'& {\tt ...\newline +Hey you\newline +...}\cr +\hline +\cw{errmessage}& \verb'\errmessage{Hey you}'& +{\tt !\ Hey you.\newline +l.217 \string\errmessage\string{Hey you\string}}\cr +\hline +\cw{show}& \verb'\show\footnote'& +{\tt> \string\footnote=macro:\newline +->\string\@ifnextchar\space [\string{\string\@xfootnote\space +\string} ...\newline +l.218 \string\show\string\footnote}\cr +\hline +\cw{showthe}& \verb'\showthe\textwidth'& +{\tt> 570.93257pt.\newline +l.219 \string\showthe\string\textwidth}\cr +\hline +\cw{showbox}& \verb'\showbox 0'& +{\tt> \string\box0=\newline +\string\hbox(0.0+0.0)x15.0\newline +\null\newline +!\ OK.\newline +l.220 \string\showbox 0}\cr +\hline +\cw{showlists}& \verb'\showlists'& +\tt +\string#\string#\string# vertical mode entered at line 0\newline +\string#\string#\string# current page:\newline +\string\glue(\string\topskip) 3.75\newline +...\newline +total height 403.47491 plus 14.64996 minus~8.77498\newline + goal height 751.60756\newline +prevdepth 0.0, prevgraf 2 lines\newline +\null\newline +! OK.\newline +l.221 \string\showlists\cr +\hline +\crcr} +\end{table*} + +Although it could be argued that the token register \cw{errhelp} is +another way of sending a message, it is excluded from +Table~\ref{t:sending} on the grounds that it is passive rather than +active, unlike the other commands listed. To put it another way, +\cw{errhelp} is merely a storage area associated with \cw{errmessage}, +where auxiliary text can be placed; the user won't ever see +\cw{errhelp} except by way of \cw{errmessage}. + +\subsection{The \cw{message} primitive}\label{ss:message} + +The \cw{message} command is a \tex/ primitive that prints its argument +on screen. If the current screen position is not at the beginning of +a line, \tex/ will add a blank space at the beginning of the message +text to separate it from the preceding material---except that if there +isn't enough room on the current line to fit the entire message text, +then \tex/ will go to the next line before starting to print the +message, and not add an extra blank at the beginning. The maximum +length of message lines is controlled by the constant {\it +max\underscore print\underscore line}, which is compiled into \tex/; +the normal value is 79. (In a windowing environment the width of the +current window may also affect the maximum length of message lines.) + +Thus one way to force a message to start on a new line is to add lots +of \cw{space}'s at the end. But a better way to start a message on a +new line, or break up a long message into lines, is to indicate line +breaks with the current \cw{newlinechar} character. For example, +we can set the newline character to be \verb|+| and use it in +a message as follows: +\def\next{\begin{verbatim}\string\begingroup{ }\string\newlinechar=`+% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Use of \cw{+} instead of {\tt+} here would normally be +recommended but the outerness of \cw{+} in \plaintex/ makes this an +exception.}% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endgraf}% +\next +\message{+This is a+three-line+message ...} +\endgroup +\end{verbatim} + which produces on screen (regardless of the length of any immediately +preceding message) +\begin{verbatim} +This is a +three-line +message ... +\end{verbatim} + In any one message, a given character +can either produce newlines, or represent itself, but not both. +As a consequence, if we wanted a plus character in a message +to actually print on screen instead of causing a line break, +we would have to set \cw{newlinechar} to some other value +before sending the message. From this knowledge it's a short step +to the insight that for general message-sending purposes it would +be convenient to set \cw{newlinechar} to the character that +is least likely to be needed in a message text. The nonprinting +ASCII characters in the range 0--31 are obvious candidates. + +But here we encounter an inconvenient idiosyncrasy of \tex/: A control +character---such as control-J, or \verb|^^J| (using \tex/'s double +caret notation), which is the default value for \cw{newlinechar} in +\amstex/ and \latex/---doesn't ever produce line breaks +in a \cw{message}, even if it is currently selected as +\cw{newlinechar}.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Or rather, it didn't up until version 3.141 or so of \tex/. +See also the mention of em\tex/'s {\tt/r} option (which allows you to +use control characters for output purposes) in \secref{ss:8bit}.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Instead, it will always be printed as three characters using the +double caret convention.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{This suggests the following experiment: set +\cw{newlinechar=`\string\^} and send a \cw{message} containing a +\ctrl{J} character.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Therefore, if you want to use \cw{message} as your normal +message-sending function, you should choose one of the seldom-used +printable characters as your default \cw{newlinechar}. One possibility +would be to use the double quote character for this purpose, since +single quote characters can normally be substituted +for double quote characters in message texts. \fn{Testfont.tex} +\cite{testfont} uses the {\tt @} character. + +Unlike \cw{message}, however, the \cw{write} command is capable of +using a control character as a newline character (see +\S\ref{ss:write}). By using \cw{write} for multiline messages, and +making \verb|^^J| the default newline character, \amstex/ and +\latex/ avoid taking any of the printable characters out of +circulation for dialog purposes. + +If no line breaks are indicated in a \cw{message} that is longer than +{\it max\underscore print\underscore line}, \tex/ will introduce +arbitrary breaks at the screen column equal to {\it max\underscore +print\underscore line}, which usually means + \[\settowidth{\dimen0}{\tt random brea} +\parbox{\dimen0}{\tt +random brea\\ +ks in the m\\ +iddle of wo\\ +rds.}\] +Those of you who use \cw{tracingmacros} will have noticed that its +output also has line breaks like this. Which can make it rather +difficult to search for instances of a given string in the trace log; +to find all instances of {\tt xyz} you need a regular expression +something like +\begin{verbatim} +x\n?y\n?z +\end{verbatim} +(\verb'\n' meaning `newline', {\tt?\@} meaning 0 or 1 occurrences of +the preceding subpattern). + +\subsection{The \cw{write} primitive} +\label{ss:write} +The \cw{write} command, like \cw{message}, just prints a message. But +the message doesn't necessarily appear on screen, because +communication with the user is not the purpose for which +\cw{write} was originally designed: Its initial purpose was to send index or +table of contents information, including the associated page number, +to an auxiliary file for later processing. Because this kind of use is +closely linked to page numbering, \cw{write} commands on the current +page are normally saved up to be executed when the page is actually +shipped out, after the page break has been determined. If such +postponement is not wanted, \cw{write} must be used with the +\cw{immediate} prefix. + +In order to allow intersequential writing to different output files, +the \cw{write} command takes an extra first argument, a number +between $-1$ and $16$ inclusive, to indicate the output file to which +the text should be sent. Output files 0--15 can be associated with a +particular file on your system by the \cw{openout} command; output +file $-1$ is the \tex/ log file, and output file $16$ is the user's +terminal screen (echoed in the log file as well). + +Line breaks in the argument of a \cw{write} command can be obtained by +inserting \cw{newlinechar} characters; unlike \cw{message} +(\secref{ss:message}) and \cw{errmessage} (\secref{ss:errmessage}), +\cw{write} will always start a new line for each newline character, +even when it is a control character such as \verb|^^J|. Also, the text +of a \cw{write} command always starts on a new line and finishes on a +new line. The existence of the final newline may be observed in the +on-screen result of a \cw{message} following a \cw{write}: the message +text will always start on the next line regardless of the total length +of the \cw{message} and \cw{write} texts, whereas a \cw{message} +following another \cw{message} or one of \tex/'s internally generated +messages (such as input file names) will not start on a new line +unless there isn't enough room remaining on the current line. + +Corollary: If you prompt the user for some input and you want the +user's input to appear on the same line as the prompt text, use +\cw{message} instead of \cw{write} to send the prompt text---or at +least the last line of the prompt text. + +\subsubsection{Nonimmediate \cw{write} messages} +Sometimes it's useful to leave off +the \cw{immediate} prefix of a \cw{write} command +even when not writing information to an index file or +table of contents file: For instance, if you are working on page breaks in +a long document and want to find out, without previewing or printing, +if a nonforcing pagebreak command had the effect that you wanted, you +could insert a nonimmediate \cw{write16} just before and just after the +intended page break: + \begin{verbatim} +\write16{Before the attempted pagebreak.} +\penalty-9999 +\write16{After the attempted pagebreak.} +\end{verbatim} + The message from a nonimmediate \cw{write16} will appear before the +closing \verb|]| of the \verb|[|\thinspace\nobreak\verb|]| pair that enclose the relevant +page number. So if all went well, one of the above messages will +appear with one page number and the next message with the +next page number, like this: + \begin{verbatim} +[4] [5 +Before the attempted pagebreak. +] [6 +After the attempted pagebreak. +] [7] [8] [9] ... +\end{verbatim} + +In producing this article (using \latex/) I had some trouble getting +good placement for the floating tables and examples; to help me +experiment, I added some code that would print on screen the page +numbers. At the beginning of Example~2 (for example) there is +a line that says +\begin{verbatim} +\write16{Example 2: Page \thepage}% +\end{verbatim} +The \cw{immediate} prefix must be omitted in order to +get the page number correct. + +\subsection{The \cw{errmessage} primitive} +\label{ss:errmessage} +The \cw{errmessage} command prints its argument on screen, starting on a +new line, with an exclamation point and a space added at the beginning, +and a period added at the end. For example, +\cw{errmessage}\verb|{Surprise}| produces +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{verbatim} +! Surprise. +\end{verbatim} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + on screen. \cw{errmessage} also shows the {\em current context}, +which means the current line from the current input file, along with +the line number, and additional information if there is any (such as +the surrounding parts of current macro expansions).% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{If the parameter \cw{errorcontextlines} is set high enough.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +So the {\tt Surprise} error message would show additional information +on screen. Suppose we define +\begin{verbatim} +\def\test{\errmessage{Surprise}\relax} +\end{verbatim} +Then the additional information will look something like: +\begin{verbatim} +! Surprise. +\test ->\errmessage {Surprise} + \relax +l.454 \test + and some more text. +? +\end{verbatim} +This example may be interpreted as follows: Line 454 of the current +file consists of +\begin{verbatim} +\test and some more text. +\end{verbatim} +The line break in the context listing +means that \tex/ is processing \cw{test} and has not yet +started to typeset the word `\verb"and"'. +Above the \verb"l.454", the expansion +of \cw{test} is shown. The line break after \verb"{Surprise}" +indicates that \tex/ has not yet executed the \cw{relax} command. + + The behavior of \cw{errmessage} with respect to newline characters +and control characters is the same as for \cw{message}---i.e., +\cw{errmessage} will start a new line for each \cw{newlinechar} in +its argument [unless the current value of +\cw{newlinechar} is outside the visible {\sc ascii} range +32--126 and the version of \tex/ is less than 3.141]. + +At the end of an error message, the user is presented with +a question-mark prompt, and a choice of several possible responses. These +will be discussed later in the section on \tex/'s capabilities +for receiving user input (\S\ref{s:error-recov}). + +\subsection{The \cw{show} and \cw{showthe} primitives} + +The \cw{show} command, used for showing the current meaning of a +control sequence (or indeed of any token), is rather similar to +the \cw{errmessage} command in what it produces on screen. The +prefix is a greater-than character instead of an exclamation +point. Here's the result of \verb|\newcount\C| \verb|\show\C|: + \begin{verbatim} +> \C=\count78. +l.1 \newcount\C \show\C + +? +\end{verbatim} + As with \cw{errmessage}, \tex/ displays the surrounding context of a +\cw{show} command; it also offers the same question-mark +prompt with the same range of possible responses (well, almost---the +\verb|H| option only gives a generic help message about \cw{show}, not +specific help about the item being shown.). + +The \cw{showthe} command is like \cw{show}, but is applied +to certain kinds of things such as count registers and +token registers, that have not only a meaning but also a current value. +For instance, here's the result of \verb|\C=5| \verb|\showthe\C|, using the +counter defined above: + \begin{verbatim} +> 5. +l.3 \C=5 \showthe\C + +? +\end{verbatim} + +\subsection{The \cw{showbox} and \cw{showlists} primitives} The +commands \cw{showbox} and \cw{showlists} are similar to \cw{show} in +what they produce on screen (see Table~\ref{t:sending}). Because of +their specialized nature they don't ordinarily have much application +in dialog between \tex/ and the user. + +\subsection{Piggybacking} +Many messages printed on screen by \tex/ do not +involve any of the commands listed in Table~\ref{t:sending}. +These other messages +are emitted directly by \tex/, outside the control of +the macro writer. However, with a little imagination, +you can often find ways to attach useful information +to those ``inaccessible'' messages. This is what I mean +by \term{piggybacking}. + +For example, whenever \tex/ inputs a file, a message is printed on +screen containing the name of the file, enclosed in parentheses. So +one way to send a short message would be to create an empty file +whose name was equal to the desired message, and then input the file. + +File name messages, apart from the parentheses, behave the same as +messages produced by the \cw{message} command: in particular, a file name +message will be appended to the current line, with +a preceding space, unless the length of the +message (including the two parentheses) will cause it +to cross the {\it max\underscore print\underscore line} boundary. + +If your computer system allows longer file names +you could actually get pretty fancy with a filename message. +For example, on a Unix system suppose you have a file named +\fn{test.tex} whose contents are +\begin{verbatim} +\newwrite\msgfile +\immediate\openout\msgfile=Fred.your.fly.is.open +\immediate\write\msgfile{\relax} +\immediate\closeout\msgfile +\input Fred.your.fly.is.open +\end +\end{verbatim} +When \fn{test.tex} is processed by \tex/ the screen output will be +something like: +\begin{verbatim} +This is TeX, C Version 3.1 (format=plain 91.1.4) ... +(test.tex (Fred.your.fly.is.open) ) +No pages of output. +\end{verbatim} +However, getting spaces in the message would be problematic since +\tex/ treats a space as a file name terminator. And if your message +doesn't include a period, \tex/ is likely to add \fn{.tex} at the end +of the file name when \cw{openout} is invoked. Not to mention that +this method would quickly lead to inconvenient file clutter since +\tex/ can't delete files, only create new files or change the contents +of pre-existing ones. + +Or consider the count registers 1--9; if any of +these is nonzero, its value is reported on screen whenever \tex/ +ships out a page. One way of using this feature might be to report +the accumulation of index terms for a document, by having each index command +increment count register number~1: +\begin{verbatim} +\countdef\indexcount=1 +\def\index{... + \global\advance\indexcount 1 ...} +\end{verbatim} +Incrementing count~1 like that would result in \tex/ displaying on +screen something like +\begin{verbatim} +[1.2] [2.7] [3.14] [4.15] [5.27] [6.38] ... +\end{verbatim} +instead of the more usual +\begin{verbatim} +[1] [2] [3] [4] [5] [6] ... +\end{verbatim} +as each page is shipped out. + +These two examples don't seem extremely practical---the total number of +index terms reported in the latter example won't necessarily be correct +page for page, until the end of the document, because ordinary means +for incrementing the counter are immediate in their effect rather than +synchronized with the \cw{write} commands used for creating the index +file---but the point is to realize that the messages coming out of +\tex/'s innards aren't totally beyond reach, and they can sometimes +provide a better way of achieving a given result than ordinary methods. +A couple of better-known examples, from the hands of Donald E. Knuth, can +be found in the \cw{showhyphens} command and in {\tt hyphen.tex} at the +point where \cw{patterns} is called. + +\subsubsection{The \cw{showhyphens} command} +The \cw{showhyphens} command (defined in {\tt plain.tex}) +works by exploiting \tex/'s messages about underfull boxes. +When an underfull line +of a paragraph is reported, \tex/ prints on screen the elements of that +line, including any discretionary hyphens inserted by \tex/ +while attempting to find good line breaks. +The key insight for thinking up the \cw{showhyphens} +command is to realize that if you can typeset a one-line +paragraph, and make sure that the line is underfull, then +any word in that line will have its hyphenation points +displayed on screen. That's exactly what Knuth +defined \cw{showhyphens} to do: +\begin{verbatim} +\def\showhyphens#1{\setbox0\vbox{\parfillskip\z@skip + \hsize\maxdimen \tenrm \pretolerance\m@ne \tolerance\m@ne + \hbadness0\showboxdepth0\ #1}} +\end{verbatim} +The settings of \cw{parfillskip} and \cw{hsize} ensure that the paragraph will +be all on one line, and underfull. (For extra bullet-proofing, +\begin{verbatim} + \leftskip\z@skip \rightskip\z@skip +\end{verbatim} +should probably be included too.) + +The switch to font \cw{tenrm} makes sure---or at least reasonably +sure---that the current font is not one for which hyphenation has been +inhibited by setting \cw{hyphenchar} to an out-of-range value. The +settings of \cw{pretolerance} and \cw{tolerance} ensure that +hyphenation points will be added (in making up a paragraph, \tex/ +normally tries first to get by without adding hyphenation points, if +it can find good line breaks using only the stretchability and +shrinkability of interword glue). The setting of \cw{hbadness} ensures +that an {\tt Underfull \string\hbox} message will be sent (otherwise, +if the surrounding environment had $\hbox{\cw{hbadness}}=10000$ when +\cw{showhyphens} was called, the message would be suppressed). +The setting of \cw{showboxdepth} limits the information in the +message to top level; otherwise compound structures like accented +letters or special composites (\eg. \cw{AA}) would be shown in +full detail---more detail than the user normally wants to see. +And finally the \verb*+\ + command forces entry into horizontal mode +and, more importantly, provides a glue item before the first word, +without which it would not be hyphenated (see the rules by which +\tex/ looks for hyphenatable words, \texbook/, Appendix~H). + +Note that the values of \cw{language}, \cw{lefthyphenmin}, and +\cw{righthyphenmin} are inherited from context; and this is probably +what you want for the \cw{showhyphens} command (perhaps indeed the +current font should also be inherited from context instead of being set +always to \cw{tenrm}). + +\subsubsection{Using error context to send messages} +\label{ss:errcontextcomments} +The standard \fn{hyphen.tex} containing U.S. English hyphenation +patterns has a comment after the \cw{patterns} command:% + \begin{verbatim} +\patterns{ % just type <return> if you're not using INITEX +\end{verbatim} + Ordinarily the macro writer can't use comments to communicate +with the user, because comments within the text of a macro +are discarded by \tex/ +as the macro is defined. The beauty of the comment in \fn{hyphen.tex} +is that it appears precisely when needed, because of the +way \tex/ displays context with error messages: if you \cw{input} +\fn{hyphen.tex} when not using {\sc initex}, \tex/ will give an +error message when it encounters the \cw{patterns} command, +and as usual, will show the context around the point of the +error, like this: +\par\reqspace{3\baselineskip} + \begin{verbatim} +! Patterns can be loaded only by INITEX. +l.2 \patterns + { % just type <return> if you're not using INITEX +? +\end{verbatim} +Since learning this technique, I've had occasion more than once to +apply it in similar situations. One such application had to do with +the \latex/ circle fonts. I had an assignment to create a +\latex/ documentstyle whose installation procedures involved +rebuilding the \latex/ format file, which meant calling +for the \fn{.tfm} files of the circle fonts. +However, there was at that time (1990--1991) a bit of +confusion surrounding the names; the trend among distributors of \tex/ +appears to be away from the original names \fn{circle10} +and \fn{circlew10} and toward the names +\fn{lcircle10} and \fn{lcirclew10}. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%\footnote{Starting with the standard Unix distribution of \tex/, +%from the University of Washington.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +The \fn{.tfm} files are the same under either names, but +I had to deal with the possibility that some users of the +documentstyle I was working on would have the fonts under the older +names, while others would have them under the new names. + +My solution was to use the newer names \fn{lcircle10} and \fn{lcirclew10} +and put comments on the same lines as the font assignments, so that +the comments would appear to the user if \tex/ were unable +to find the \fn{.tfm} files and emitted an error message. + \begin{verbatim} +\font\tencirc= +lcircle10\relax% Type x to exit; see sei.prl for further info. +\end{verbatim} +Additional comments in the file \fn{sei.prl} explained +how to change the font names to their older variants. +The \cw{relax} is necessary so that \tex/ won't proceed to +the next line, bypassing the comment, in the process of looking +for a modifier such as \verb|scaled| or \verb|at|. +And the reason for the line break after the equals sign is to fit a +few more characters in the comment, which would be elided by \tex/ +if too long. +\section{Ways for \tex/ to receive messages from the user} +\label{s:receiving} + +Table~\ref{t:receiving} lists the various means in \tex/ for reading +input from the user. The primary input facility is the \cw{read} +command; the others are special cases applicable only under limited +circumstances. + +\begin{table} +\vspace{-\medskipamount} % needed because \caption has wrong spacing + % when used at the top rather than the bottom + % of a float environment. +\caption[]{\label{t:receiving}Receiving} +\writepage{Table} +\vspace{-\medskipamount} +\begin{center} +\begin{tabular}[t]{p{.35\columnwidth}|p{.55\columnwidth}} +\hline +Method & Prompt displayed by \tex/\\ +\hline +\cw{read}& \cw{controlseq=}\\[3pt] +\rp error message interaction& \verb|?|\\[3pt] +\rp `show' message interaction& \verb|?|\\[3pt] +\rp input file not found& +\tt\rp Please type another input file name:\\[3pt] +\rp output file not writable& +\tt\rp Please type another output file name:\\[3pt] +interrupt key& none +\end{tabular} +\end{center} +\end{table} + +The purpose of getting input from the user is essentially always the +same: to give the user an opportunity to change the outcome of the \tex/ +run, which would otherwise be totally predetermined by the contents of +the files read by \tex/. (Well, and perhaps by a few system variables +such as \cw{time}, \cw{day}, etc.) + +\subsection{The \cw{read} primitive}\label{ss:readprim} +The form of the \cw{read} command is + \begin{verbatim} +\read 16 to \controlseq +\end{verbatim} +where the number 16 is the input stream number, +which might be any value from $-1$ to 16; +a number between 0 and 15 would indicate reading from a file +stored on disk, while 16 and $-1$ indicate reading from the user's +keyboard. \cw{controlseq} can be any control sequence +chosen by the macro writer. If the input stream number is +16, \tex/ will display a prompt of + \begin{verbatim} +\controlseq= +\end{verbatim} +If the input stream is $-1$, this prompt will be omitted. In either +case, a \cw{read 16} or \cw{read -1} command should normally be +preceded by a message that lets the user know what kind of input to +provide. + +The action of the \cw{read} command is similar to that +of the \cw{def} primitive. Both of them create a new +macro containing an unexpanded token list, which +must contain balanced braces. The balancing required +in the response to a \cw{read} command, however, +is slightly different than for a \cw{def}; as long +as there an equal number of opening and closing +braces, it doesn't matter how they're distributed---\tex/ +will be perfectly happy with the response + \begin{verbatim} +a}}}b{{c}{{ +\end{verbatim} + as can be verified using \cw{show}\cw{answer} after reading the +above string into \cw{answer}.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{See also \secref{ss:readouter}. +I questioned the behavior of \cw{read} with respect to extra closing +braces and outer control sequences in a letter to +Donald Knuth (December 1991); +his response was to make a change in \tex/ (version 3.141?) +that causes a \cw{read} operation to terminate decisively if an extra +{\tt\char`\}} or outer control sequence is encountered. So backwards +balancing of braces will no longer be permitted.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\tex/ will read more than one line, if +necessary, if the first line contains an unmatched brace. This is a +useful property if you {\em want\/} to read more than one line at a +time, as is sometimes the case: write the information in the form +\verb|{| \ldots \verb|}|, and you can have as many lines +between the curly braces as you want. + +\tex/ always reads line by line, rather than character by character; +unlike some other programming languages, \tex/ provides no way to read a +single character and act on it immediately; the user must always press +the \return/ key before anything will happen. + +\subsection{Error recovery}\label{s:error-recov} + As mentioned earlier, after an error message \tex/ presents the user +with a question-mark prompt. Typing a second question mark in reply +to the prompt will cause \tex/ to list the options that are +available: + \begin{verbatim} +! Error message. + ... +? ? +Type <return> to proceed, S to scroll future error messages, +R to run without stopping, Q to run quietly, +I to insert something, E to edit your file, +1 or ... or 9 to ignore the next 1 to 9 tokens of input, +H for help, X to quit. +? +\end{verbatim} + Choosing the {\tt H} option causes \tex/ to print a help message +containing additional information related to the error message. +If the error message was generated using \cw{errmessage}, then +the help message will consist of the current contents of the +token register \cw{errhelp} (which should be filled with something +useful by the macro writer, immediately before the call +to \cw{errmessage}). Otherwise, for a built-in error message, +the corresponding built-in help message (from \fn{tex.pool}) is +displayed. + +The intended use of the insertion ({\tt I}) and token deletion ({\tt +1...9}) options is for error recovery; after you look at the context +of an error, you may be able to temporarily repair the damage and +continue processing the remainder of the document, by removing some +tokens and/or inserting others. Then if any other errors are uncovered +later, they can be fixed at the same time as the first error, instead +of requiring a second \tex/ run to find them. Example~\ref{e:recovery} +illustrates this. You can actually delete up to 99 tokens at a time in +all implementations of \tex/ that I know of, even though the help +message suggests that 9 is the maximum. + +\begin{example} +\begin{examplebox}% +% +\caption[]{Using error interaction possibilities to +get past a potentially bad error: a missing {\tt\string\\} before an +\cw{hline} in a \latex/ {\tt tabular} environment.}\label{e:recovery}% +\writepage{Example} + +\begin{verbatim} +! Misplaced \noalign. +\hline ->\noalign + {\ifnum 0=`}\fi \hrule... +l.120 \hline + +? +\end{verbatim} +Let's see what the help information is: +\begin{verbatim} +? h +I expect to see \noalign only after the \cr of an alignment. +Proceed, and I'll ignore this case. + +? +\end{verbatim} +Let's try skipping one token to verify what \latex/ is going +to process next: +\begin{verbatim} +? 1 + +\hline ->\noalign { + \ifnum 0=`}\fi \hrule... +l.120 \hline + +? +\end{verbatim} +All right, the opening curly brace has just gone by. We need +to insert the \verb|\\| that was forgotten, and also replace the two tokens +\cw{noalign} and \verb|{| that have slipped by. +\begin{verbatim} +? i\\ \noalign{ +\end{verbatim} +And now \latex/ will be able to continue with the rest of the table. +\end{examplebox} +\end{example} + +The token deletion option can also serve as the basis of a crude menu +facility. The idea is to use \cw{errmessage} to present a menu with +choices labeled by numbers. If the user responds by entering, say, +\verb;3; to choose item~3, then we must arrange things so that after +\cw{errmessage} does its normal thing of deleting three tokens, the +following token that was not deleted should do something to ensure +that item~3 will be selected. This isn't too hard if we use something +like the following sequence: +\begin{verbatim} +\errmessage{...}\0\1\2\3\4\5\6\7 ...\stop +\end{verbatim} +Clearly the deletion of three tokens after the error message will leave +\verb;\3; as the next command to be executed, and so if we define +\verb;\3; to do the right thing and then skip over the following +\verb;\4\5...; corresponding to unselected menu choices, we get what we +want. + +If the user just presses \return/ without entering a number, it will +be \verb;\0; that is executed---therefore \verb|\0| should be defined +to produce the default selection. + +One thing that makes me call this crude is the fact that \tex/ pauses +after any token deletion operation instead of barging ahead. This means +that if the user chooses anything other than the default selection, +they will have to press \return/ twice after typing the number, instead +of just once. + +Some other crudities are introduced by the bits and pieces of an +\cw{errmessage} that cannot be suppressed. These include: +\begin{itemize} +\item Exclamation point and space at the beginning of the error message. +\item Period at the end of the error message. + +\item The expansion of the current macro (if the error message is + contained in a macro), on two lines with the line break immediately + after the token that was last processed by \tex/. This includes, at + the beginning, the macro name followed either by \verb"->", if the + first part of the expansion text is relatively short, or by ellipsis + dots \verb"..." plus the tail end of the first part of the expansion + text. + +\item The current line of the current file, on two lines with the break + immediately after the token that was last processed by \tex/. +\item The question mark and space prompting the user for a response. +\end{itemize} + +I would have hoped that setting \cw{errorcontextlines} to $0$ or $-1$ +would cause the `innermost' two lines of the error context to be +suppressed but apparently there is no value for \cw{errorcontextlines} +that will suppress them. The following example illustrates all of the +nonsuppressable parts. +\begin{verbatim} +! Error. +\CM ->\errmessage {Error} + \CM +l.38 \CM + % A comment in the file, line 38 +? x +\end{verbatim} +Except for the ellipsis dots alternative, that is. Here's how that +looks: +\begin{verbatim} +! Longer message text, forcing elision. +\CM ...sage {Longer message text, forcing elision} + \CM +l.38 \CM + % A comment in the file, line 38 +? +\end{verbatim} +Although the exact number can vary (depending on how your particular +version of \tex/ is configured at compile time), the maximum +length of the first line of context is normally between 40 and 50 +characters, and if the expansion text would make the line longer +than this, it is truncated at the beginning and the ellipsis +dots are inserted. + +Very well then. Since we have \verb"!", \verb".", and \verb"->" or +\verb"..." in the first two lines (the lines that will be nearest our +menu text), and we cannot get rid of them, the next best thing is to +camouflage them. One possibility is setting +\cw{newlinechar}\verb"=`\!" just before sending the \cw{errmessage}, +so that the \verb"!" character will cause a blank line rather than +printing on screen, and then putting a bunch of periods in the menu +text to camouflage the other periods. + +\ref{a:menu} exhibits \fn{fontmenu.tex}, a more extensive +working-out of this idea in which I tried to pound the recalcitrant +\cw{errmessage} into the most presentable shape possible, using every +macro hack I could think of. + +\subsection{Show message `recovery'} + +After a \cw{show}, \cw{showthe}, \cw{showbox}, or \cw{showlists} +command, \tex/ offers a question-mark prompt, and the same menu of +options as after an error message. There is only one slight +difference: The {\tt H} option provides no access to the \cw{errhelp} +token register; only a generic help message about the \cw{show...} +commands is available. + +\subsection{``Please type another input file name:''} + +When you see this prompt, displayed by \tex/ when it's unable to find +an input file, you have strayed into one of the less friendly byways +of \tex/. If you can't think up a good file name to give as an answer, +you could get stuck in an endless loop. Even simply pressing the {\sc +return} key causes \tex/, on most computer systems, to look for a file +called `\fn{.tex}' which will most likely be nonexistent. Power users +know that on many systems you can enter a file name of `\fn{nul}' to +cause \tex/ to read in an empty file named \fn{nul.tex}. But it is +precisely power users who are likely to know other ways of getting +past this prompt (for example, on some systems typing a \ctrl{Z} or +\ctrl{D} character also does something useful), and it is precisely +the users with no other clue what to try next who won't know about +\fn{nul.tex}. + +It seems that it would be useful for all standard distributions of +\tex/ to provide files named \fn{.tex}, \fn{h.tex}, \fn{help.tex}, and +\fn{?.tex} in the standard \tex/ inputs path, so that when users type +\verb'h' or \verb'help' or \verb'?' or just press \return/, they will +get the corresponding file. (Unfortunately, most operating systems +don't permit the question mark in file names, which means that only +the other three files will normally be viable.) \fn{Help.tex} and its +clones could contain something as simple as: + \begin{verbatim} +\errmessage{Type ? to see your options; X to exit} +\end{verbatim} + which would give the user access to the full menu of normal error +recovery options.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{This idea is discussed at greater length in a recent \tugboat/ +article of mine (to appear, late 1994).} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\subsubsection{A menu trick} + The {\tt Please type another input file name} prompt is used to +implement a sort of menu in the file \fn{lfonts.new} of the +Mittelbach/Sch\"opf font selection scheme (\latex/ version), which +has a statement \cw{input} \fn{fontdef.tex}, where the file +\fn{fontdef.tex} is normally missing, intentionally, and the user is +supposed to substitute another file name such as \fn{fontdef.ori} or +\fn{fontdef.max}. The idea of comments designed to appear through +\tex/'s display of error context (\secref{ss:errcontextcomments}) +could be used to good advantage here, to +tell the user what other file names are likely +candidates: + \begin{verbatim} +\input fontdef.tex % Try fontdef.ori or fontdef.max +\end{verbatim} +In this kind of application, additional help information in a message +preceding the \cw{input} statement could also be useful. + +\subsection{Interrupt key} + The interrupt key is a key (system-dependent, but \ctrl{C} on many +systems) that allows you to interrupt +\tex/ when it is in the middle of doing something else. The normal +reaction of \tex/ when the interrupt key is pressed is to print a +message + \begin{verbatim} +! Interruption. +... % current context +? +\end{verbatim} + in the same form as an error message, complete with a question-mark +prompt, with the usual options available to the user. + +It's stretching the concept a bit to claim that the interrupt key is +a way for users to send information to \tex/; it has the flavor of the +story about the farmer who had to whack his mule over the head with +an axe handle ``just to get his attention''. When you interrupt +\tex/ you could easily find yourself in the middle of some +complex macro where it would be inadvisable to do anything except use +the \verb|X| option to exit. However, this in itself is frequently +useful. + +\section{Stumbling blocks in the use of \cw{write} and \cw{message}} +\label{s:stumblewrite} + +\subsection{Line breaking} + +As explained elsewhere (\secref{ss:message}) it is impossible to use a +control character as a newline character in the argument of a +\cw{message} or \cw{errmessage} command. +{\em[Note (30-Oct-1993): that's no longer true, as of \tex/ version 3.141.]} +\latex/ and \amstex/ +use \cw{immediate}\cw{write} instead of \cw{message} in their +all-purpose message macros (\cw{typeout} and \cw{W@}), which allows +them to have \verb"^^J" as the default newline character, +thus leaving all of the printable characters usable in message texts. +(If a given character is the current \cw{newlinechar}, there really +is no way for \tex/ to print it on screen. Try setting +\cw{newlinechar}\verb|=`\(| and see what happens to the file name +messages for input files.) + +There is a minor inconvenience with the use of \ctrl{J} as the newline +character. Under current conditions (as of 1993), it is usually wise to +limit the length of all lines in a macro file to 72 characters, in +order to avoid truncation problems that occasionally occur in, \eg., +electronic mail transmission. When constructing a long message, if you +leave \cw{endlinechar} at its normal value of \verb;^^M; and put +\verb;^^J;'s at the end of each message line, you get four extra +characters at the end of each line, three for the \verb;^^J;% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Although the {\tt\string ^\string ^J} combination will be +resolved to a single character by \tex/, it is three characters when +writing it and when sending it through mail. Assuming, that is, that +you use \tex/'s double caret notation and don't try to insert a +\ctrl{J} byte directly (not a good idea, because of system-dependent +interpretation of \ctrl{J}).} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +and one for a percent sign to eliminate the space that would otherwise +be produced on screen at the beginning of the next message line, by the +\verb;^^M;. This means that the effective limit on the length of each +message line is 68 characters rather than 72. + +But the clutter of four extra characters at the end of a line can be +avoided by temporarily assigning \cw{endlinechar} \verb;=; +\cw{newlinechar} while a message is being constructed. This is +assuming, however, that a useful value of \cw{newlinechar} has been +established and that the same value will be in effect when the +message is sent. If the construction and sending are simultaneous, +the code can be as simple as this: + \begin{verbatim} +\begingroup \endlinechar=\newlinechar +\immediate\write16{Line 1 +Line 2 +Line 3 +}% +\endgroup% this percent sign is necessary +\end{verbatim} + And then the actual message text in each line +can run to the full 72-character length if necessary. +If a useful value of \cw{newlinechar} has not been established +(\eg., when using \plaintex/ without modifications), then +rewrite the first line above as: +\begin{verbatim} +\begingroup \newlinechar=\endlinechar +\catcode\endlinechar=12 % Make it 'other' +\end{verbatim} +Here we make the reasonable +assumption that \cw{endlinechar} has its normal value +of 13 (\verb;^^M;); even this assumption could +be done without by adding the statement \cw{endlinechar} \verb;=; +\verb;13; before the other assignments. + +The percent sign is necessary after the \cw{endgroup} in the first +variant, because the endline character for a given line is added when +the line is initially read, before \tex/ begins to execute the line. +Therefore by the time \tex/ processes the \cw{endgroup} and reverts +to the previous value of \cw{endlinechar}, it is too late to prevent +getting a newline character at the end of the current line. + +For the same reason, a percent sign is not needed +after the line that contains +\begin{verbatim} +\endlinechar=\newlinechar +\end{verbatim} +The endline character for that line has already been tacked on +by \tex/ and cannot be changed by any statements within that line. +(The \cw{catcode}, however, +of the \cw{endlinechar} can be changed by statements within the line.) + +\subsection{Expanding control sequences}\label{s:excs} + +In messages to a \tex/ user it's frequently necessary to refer +to control sequences or characters that have special category codes. +This can sometimes be problematic because of the expansion that is +done in the argument of a \cw{message} or \cw{write} command. For +example, the line + \begin{verbatim} +\message{Beware of \footnote in a \message!} +\end{verbatim} +will typically generate a hundred or so error messages when +\tex/ reaches \cw{footnote}. (Although \plaintex/, \amstex/, \latex/, +and other macro packages define \cw{footnote} differently, +all the definitions are equally explosive inside a \cw{message}.) +And the line +\begin{verbatim} +\message{Beware of \endinput in a \message!} +\end{verbatim} + will cause the current input file to terminate immediately! +(\cw{endinput} is an {\em expandable} control sequence, for +reasons that are too technical +to be worth discussing here.) + +Thus to talk about an expandable control sequence in a message, you +must do something to inhibit the expansion. Ordinarily +you apply \cw{string} or \cw{noexpand} to the control sequence; +or you could put it into a token register and use +\cw{the}\m{token register} in the message. +Nonexpandable +control sequences can be printed in a message without special +protection, except that, if you do nothing to avoid it, you will +always get an extra space after a control word, even in +some cases where it is undesirable, as when the next +thing is punctuation. For example, the message +\begin{verbatim} +\message{Enter desired value for \hangindent: } +\end{verbatim} +will print on screen with a space before the colon: +\begin{verbatim} +Enter desired value for \hangindent : +\end{verbatim} + +Table~\ref{t:expansion} shows what happens to various sorts of things +in a \cw{message} or \cw{write} argument, as well as various methods +for suppressing expansion. + +\begin{table*} +\caption[]{Expansion of \cw{message} and \cw{write} arguments% +\label{t:expansion}} +\writepage{Table} +\smallskip +\noindent +\[\begin{tabular}{|r|l|} +\hline +This input\ \ \ & Produces this on screen\\ +\hline +\verb|\message{E}|& \verb|E|\\ +\verb|\message{&}|& \verb|&|\\ +\verb|\message{#}|& \verb|##|\\ +\verb|\message{[\relax]}|& \verb|[\relax ]|\\ +\verb|\message{[\string\relax]}|& \verb|[\relax]|\\ +\verb|\message{[\empty]}|& \verb|[]|\\ +\verb|\message{[\noexpand\empty]}|& \verb|[\empty ]|\\ +\verb|\message{[\string\empty]}|& \verb|[\empty]|\\ +\verb|\message{[\space]}|& \verb|[ ]|\\ +\verb|\message{[ ]}|& \verb|[ ]|\\ +\verb|\def\spaces{\space\space\space\space|&\\ +\verb|\space\space\space\space}|&\\ +\verb|\message{[\spaces ]}|& \verb|[ ]|\\ +\verb|\message{[\romannumeral 37]}|& \verb|[xxxvii]|\\ +\verb|\message{[\uppercase{a}]}|& \verb|[\uppercase {a}]|\\ +\verb|\message{[~]}|& \verb|[\penalty \@M \ ]|\\ +\verb|\message{[\ifnum\time<600 Too early for me|&\\ + \verb|\else Let's go\fi]}|& \verb|[Too early for me]|\\ +\hline +\end{tabular}\] +\end{table*} + +\subsection{Collapsing spaces} + +If you want to print on screen a menu or similar message consisting +of multiple columns nicely arranged, you have to deal with the fact +that \tex/ normally condenses multiple spaces and tab characters +to a single +space. The easiest way to handle this difficulty is to change the +catcode of the space character to, say, 12 +before reading the argument of a +\cw{message} or \cw{write} command. + +\subsection{Special characters} + +The space character is but one example of a larger class: +`special' characters, that is, ones that don't have category 11 or 12. +An obvious +question to ask is, ``What other special characters are difficult to +use in a message?'' Table~\ref{t:expansion} shows how a few special +characters are affected by the expansion process in a message: an +\verb;&; (category 4) passes through unharmed, a \verb;#; (category +6) gets doubled, and a \verb;~; (category 13) gets expanded.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{To be more precise, an active character like {\tt\string ~} +will be treated like a control sequence; it will be expanded if +expandable, otherwise it will be printed as is. After an +assignment such as +\cw{newcount}{ \tt\string ~}, or \cw{let}{ \tt\string ~ =} \cw{relax}, +the {\tt\string ~} is not expandable.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Table~\ref{t:specchars} is a complete list +of the various categories of characters, +along with ways to produce those characters that cannot simply be +used as is. A few categories deserve more extensive comment. + \begin{description} + \item[Category 0---Escape Character] It's normally not a problem to +print an escape character because it usually occurs as part of a +control sequence, which can be printed using \cw{string} (and even +that may not be necessary if the control sequence is nonexpandable). +Even when the escape character is not, logically speaking, part of a +control sequence, it can be sent in a message by letting it combine +from \tex/'s point of view with the following character(s). For +example, to send the message {\tt Commands in TeX normally begin with +a `\string\' character}, the backslash doesn't need to be treated as +an isolated character; combined with the following apostrophe, it +forms a control symbol to which \cw{string} can be applied. + + The only time this fails is when the backslash must be sent as the +very last character of a message. Although this case is +extremely unlikely, the solution involves a rather useful +little macro: +\begin{verbatim} +\def\xstring{\expandafter\gobble\string} +\def\gobble#1{}% if this is not already defined +\end{verbatim} +With this definition,% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Cf.\ the answer to Exercise 7.10 in \texbook/. The implicit +assumption that \cw{escapechar} is in the range 0--255 may not be +completely reliable.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\cw{xstring} not only turns a control sequence into a string of +characters, it also removes the leading backslash, so that +\cw{xstring}{\tt\string\\} will produce a single backslash +character, as desired. +Another solution that involves setting \cw{escapechar} +temporarily to $-1$ would also be possible, provided that the remainder +of the message doesn't need to use \cw{string} in a normal way, +with a printable escape character. +\begin{verbatim} +\begingroup \escapechar=-1 +\message{ ...\string\\}% +\endgroup +\end{verbatim} +On the other hand, +it might be useful to have a category-12 +backslash character always available through a macro, +not only for messages but for other purposes as well: +\begin{verbatim} +\edef\backslashchar{\xstring\\} +\end{verbatim} +Then \cw{backslashchar} could be used in a message instead of +\cw{xstring}{\tt\string\\}. If you needed to use it frequently you +would presumably give it a shorter name. + +\item[Categories 1 and 2] Characters of category 1 and 2 can be +printed without any problem in a message {\em if they occur +in matching pairs}. For these purposes, character codes are irrelevant; +\verb;];$_1$ and \verb;*;$_2$ match up as well +as \verb;{;$_1$ and \verb;};$_2$. +If a single, unmatched character of one of these categories +must be printed on screen, \cw{xstring} can be used with the +corresponding +control symbol, \eg., \cw{xstring}{\tt\string\{} or +\cw{xstring}{\tt\string\}}. + +\item[Categories 5, 9, 14, 15] These categories are similar to category +0. Characters of category 0 (escape), category 5 (end-of-line), 9 +(ignored), 14 (comment), and 15 (invalid character) cannot enter a +token list [\texbook/, Exercise 7.3], so that, actually, it doesn't make much +sense to ask what happens to them in the argument of a \cw{message} or +\cw{write} command, which do not deal with raw characters from an input +stream but with token lists. The question is not how to print a +character token of category 14 in a message (since that is impossible) +but, how to produce a category-12 \verb;%; when the normal catcode of +\verb;%; is 14. The answer is to +use \cw{xstring} with the corresponding control symbol, \eg., +\cw{xstring}{\tt\string\%}. + +\end{description} + +Then again, a better idea might be to pick one character, make it +active (probably {\tt\string ~} since it's already active in most +macro packages), and define it to produce category-12 +characters by their hexadecimal value. With preliminary +definitions such as: +\begin{verbatim} +\escapechar=-1 +\def\twelvechar#1#2{\csname hex#1#2\endcsname} +\expandafter\edef\csname hex5c\endcsname{\string\\} +\expandafter\edef\csname hex25\endcsname{\string\%} +\expandafter\edef\csname hex7e\endcsname{\string\~} +... +\escapechar=`\\ +\end{verbatim} +it would become possible to write, for example, +\begin{verbatim} +\begingroup +\let~=\twelvechar +\message{Printing backslash ~5e, percent ~25, and tilde ~7e.} +\endgroup +\end{verbatim} +and thus send all manner of special characters by substituting a +three-character sequence starting with {\tt\string~}. + +\begin{table} +\caption[]{Methods for incorporating various +categories of characters in a \cw{message} +or \cw{write} argument\label{t:specchars}} +\writepage{Table} +\smallskip +% +\begin{tabular}{|rrp{.57\columnwidth}|} +\hline +Catcode& Example& Method\\ +\hline +0& \verb;\;& Normally handled as part of a control +sequence, except at the very end of a message, in which case use +\cw{xstring}{\tt\string\\}\\ +% Using \mbox here to suppress a line-breaking problem +% until/unless I can get around to fixing it.{28-Nov-1992 mjd} +1& \verb;{;& \mbox{\cw{xstring}{\tt\string\{}} if unmatched\\ +2& \verb;};& \mbox{\cw{xstring}{\tt\string\}}} if unmatched\\ +3& \verb;$;& as is\\ +4& \verb;&;& as is\\ +5& \verb;^^M;& \mbox{\cw{xstring}}\verb;\^^M; (see the note below)\\ +6& \verb;#;& \mbox{\cw{string}}\verb;#; to avoid doubling, or + \cw{xstring}{\tt\string\#}\\ +7& \verb;^;& as is (except in rare combinations + like \verb;^^>;)\\ +8& \verb;_;& as is\\ +9& \verb;^^@;& \mbox{\cw{xstring}}\verb;\^^@; (see the note below)\\ +10& space& as is, except use \cw{space}'s to + produce multiple spaces\\ +11& a& as is\\ +12& /& as is\\ +13& \verb;~;& \mbox{\cw{string}{\tt\string ~}}, \cw{noexpand}\verb;~;\\ +14& \verb;%;& \mbox{\cw{xstring}{\tt\string\%}}\\ +15& \verb;^^?;& \mbox{\cw{xstring}}\verb;\^^?; (see the note below)\\ +\hline +\end{tabular} +\par +\smallskip +\small +Note: Because of the way \cw{string} operates, something like +\cw{xstring}{\tt\string\^^@} will not produce a single +character but three category-12 characters, +{\tt \string^ \string^ @}. This may normally be what you want, but it +won't be satisfactory if +the character in question has a special purpose---perhaps to cause a +newline, or to print on-screen as an accented letter. + +\end{table} + +\subsection{Space after a control word} + +In \secref{s:excs} it was pointed out that an unwanted space may be +printed at the end of a control word under some circumstances. It's +equally possible that a wanted space at the end of a control word may +disappear under other circumstances. For example, it is not uncommon +to see macro writers use +the combination \cw{string}\cw{controlseq}\cw{space} when a +control word occurs as an isolated word in the middle of a message; +the final \cw{space} is necessary because a plain space after +\cw{controlseq} would simply disappear according to \tex/'s normal +rules for finding the end of a control sequence name. + +The solution to both of these difficulties is easy: use \cw{string} +if you don't want a space after the control word, and use +\cw{noexpand} if you do want a space.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{I hadn't noticed the usefulness of \cw{noexpand} for this +purpose until Michael Spivak drew it to my attention, in a +conversation at the 1991 TUG meeting in Boston.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Note: The character tokens produced by \verb|\string| can be passed +without harm through any number of subsequent steps, including +expansion via \cw{edef} or similar operators, while \cw{noexpand} +only protects an expandable macro through the first expansion step. + +\subsection{Outer Control Sequences} +\label{ss:outer} +You can't send an \cw{outer} control sequence in a \cw{message} +unless you do something to get around the outerness. +To illustrate, I present +a transcript of \tex/'s reaction to the following line: +\begin{verbatim} +\message{Control-L: ^^L} +\end{verbatim} +along with various attempts to recover from the resulting error +message. (\ctrl{L} is defined as an active character with the `outer' +attribute in both \plaintex/ and \latex/.) +\begin{verbatim} +Runaway text? +Control-L: +! Forbidden control sequence found while scanning text of \message. +<inserted text> + } +<to be read again> + ^^L +l.149 \message{Control-L: ^^L + } +? 1 +Type <return> to proceed, S to scroll future error messages, +R to run without stopping, Q to run quietly, +I to insert something, E to edit your file, +H for help, X to quit. +? h +I suspect you have forgotten a `}', causing me +to read past where you wanted me to stop. +I'll try to recover; but if the error is serious, +you'd better type `E' or `X' now and fix your file. +? +\end{verbatim} + +Notice that when I tried to type a \verb;1; to delete the offending +\cw{outer} token, I got instead a help message indicating that token +deletion is not an option at this point. (The reason behind this lack +of token deletion is fairly technical: \tex/ was in the middle of a +procedure called {\it get\_token} when it stumbled over the \ctrl{L} +character; but since token deletion itself involves calling {\it +get\_token}, allowing token deletion here would mean calling +{\it get\_token} +from inside itself---something it was not designed for.) + +\subsection{Semi-verbatim alternative} +An alternative way of handling message texts, that eliminates the +need to remember special methods for various kinds of +message elements, is to temporarily change the +catcodes of all special +characters while reading the argument of +a message. With the following definitions: +\begin{verbatim} +\def\verbwrite{\begingroup + \def\do##1{\catcode`##1=12}% + \do\ \dospecials + \catcode\endlinechar=12 + \newlinechar=\endlinechar + \verbcontinue} +\begingroup \lccode`\/=`\\ +\lowercase{\endgroup +\def\verbcontinue##1/}endverbwrite{% + \immediate\write16{#1}\endgroup} +\end{verbatim} +you could send messages like +\begin{verbatim} +\verbwrite !#$%$%#^%&*~@^^"<?:}{>|+ +_^+\footnote_|)\\90\ +\bye ^^L \endinput +\endverbwrite +\end{verbatim} +without regard to the contents. The main limitation of this approach +is that in order for the handling of the special characters to work, +\cw{verbwrite} has to be executed directly in a file; it cannot be +embedded in a macro. Furthermore, the message text is unalterable: it +cannot contain a context-dependent part, as in a message to display +the current font name on screen: +\begin{verbatim} +\message{Current font is \fontname\font.} +\end{verbatim} +This message could not be generated with \cw{verbwrite} because +\cw{verbwrite} would not expand \cw{fontname}. + +\subsection{Presenting information in the best possible form} + +Example: In reporting a dimension to the user, it is usually +desirable to report the value rounded to tenths or hundredths, in +units that are convenient for the user: points for a font size or +line spacing value; centimeters, picas, or inches for the height or +width of a page or of an included figure. + +The file \fn{cnvunits.tex} gives some examples of what is possible in +this vein, including conversions from points to picas, inches, and +centimeters. The conversions from points to other units are the most +important ones because when \cw{the} is applied to a dimension or +skip register \tex/ always reports the value in \verb;pt; units. (Not +counting \cw{muskip} registers, where the reported unit is \verb;mu;.) + +\reqspace{1.5in} +\verbatiminput{cnvunits.tex} + +Another example: if you want to report the \cw{mathcode} of a +particular character to the user, \cw{number}\cw{mathcode`}\cw{x} or +\cw{the}\cw{mathcode`}\cw{x} aren't too great, because they produce a +decimal number, when it would be more +convenient to get a hexadecimal number filled out to four digits, so +that the class, math family, and font position information can be +read off directly. +Extending some ideas from \fn{testfont.tex} \cite{testfont}, we can +write a quite friendly \cw{reportmathcode} function: +\begin{verbatim} +% When \meaning is applied to a \mathchar, it produces +% \mathchar"<digits> where <digits> are 1 to 4 hexadecimal digits. +% The function \gethex strips off the prefix and leaves only the +% digits. +\def\gethex#1"{} +% The function \reportmathcode takes a character or control symbol +% argument and reports the associated mathcode in hexadecimal +% form, filling out to four digits with leading zeros, if +% necessary. +\def\reportmathcode#1{% + \begingroup + \mathchardef\temp=\mathcode`#1 \relax + \edef\temp{\expandafter\gethex\meaning\temp}% + \count@="\temp\relax + \edef\temp{% +% Fill in leading zeros + \ifnum\count@<"1000 0% + \ifnum\count@<"100 0% + \ifnum\count@<"10 0\fi\fi\fi + \temp}% + \message{The mathcode of \string#1 is: "\temp}% + \endgroup} +\end{verbatim} + +\begin{example} +\begin{examplebox}% +\caption[]{The \cw{printoptions} command of \amstex/ version 1.1. +\cw{W@} is the \amstex/ abbreviation for +\cw{immediate}\cw{write}{\tt 16}}\label{amstex/syntax}% +\writepage{Example} +\hfuzz=2em +\begin{verbatim} +\def\S@{S } \def\G@{G } \def\P@{P } +\newif\ifbadans@ +\def\printoptions{\W@{Do you want S(yntax check), + G(alleys) or P(ages)?^^JType S, G or P, follow by <return>: }% + \loop \read\m@ne to\ans@ + \xdef\next@{\def\noexpand\Ans@{\ans@}}% + \uppercase\expandafter{\next@}% + \ifx\Ans@\S@\badans@false\syntax\else + \ifx\Ans@\G@\badans@false\galleys\else + \ifx\Ans@\P@\badans@false\else + \badans@true\fi\fi\fi + \ifbadans@\W@{Type S, G or P, follow by <return>: }% + \repeat} +\end{verbatim} + +\end{examplebox}% +\end{example} + +\section{Stumbling blocks in the use of \cw{read}} +\label{s:stumbleread} + +\subsection{An example: \amstex/'s \cw{printoptions} command} + +Consider the \cw{printoptions} command of \amstex/ 1.1 +(Example~\ref{amstex/syntax}): +The definition of this command shows one way of dealing +with the extra space at the end of a macro created using \cw{read}: +Define some macros consisting of the expected answers, with the extra +space included, and then use \verb|\ifx| to compare them to the +user's response. It also shows how to uppercase the user's response +so that lower- and uppercase responses will be treated identically. +This is the second method given in the answer to \texbook/'s Exercise +20.19. One more noteworthy feature of \cw{printoptions} is that it +runs a loop that doesn't quit until the user gives an acceptable +answer. + +In \cw{printoptions} since \verb|\W@| is defined to be +\verb|\immediate|\5\verb|\write16|, and the \cw{write} command always +starts a new line after its message text, we can see that the reply +typed by the user will appear on the next line instead of immediately +after the colon. This brings up the question: what if we want the +user's reply to appear on the same line? + +One way to do this is to use \cw{message} to send the last line of +the prompt message, and use \cw{write} to send the previous line(s). +For example: + \begin{verbatim} +\W@{Do you want S(yntax check), G(alleys) or P(ages)?}% +\message{Type S, G or P, follow by <return>: }% +\end{verbatim} + This idea is used in the \latex/ option \fn{checknum.sty} +\cite{checknum}. An alternative would be to put the whole prompt in a +single \cw{message} with embedded newline characters (as long as you +are careful to select a character for \cw{newlinechar} that is not +needed in the text of the message). + +\subsection{{\ntt{\char94}{\char94}M} at the end of a line} +In \label{s:endlinechar} +\cw{printoptions} separate macros \cw{S@}, \cw{G@}, and +\cw{P@} are defined for each legitimate response. If the menu +becomes more extensive, this technique is rather wasteful +of hash size, main memory, and other useful commodities. +The problem here is that the +\verb|^^M| character at the end of the user's response +is included by \cw{read} in the macro being read. +Under normal conditions +\verb|^^M| is converted to a space; however, another +possibility\Dash if the user just enters \return/ without +typing any response\Dash is that the \verb|^^M| will produce a \cw{par} +token (following the general rule that an empty line is +equivalent to \cw{par}). The best approach is +to prevent the \verb|^^M| character from getting into the +read macro in the first place. This can be done in two ways: +setting the catcode of \verb|^^M| to 9 (``ignore''), or +setting \cw{endlinechar} to $-1$. + +Unfortunately, this immediately raises another difficulty: we want to keep +the catcode change or \cw{endlinechar} change local so that it will +affect only the \cw{read}. This could be accomplished by +saving the current catcode or \cw{endlinechar} (just in case) +and restoring it after the \cw{read} is done, but it's +simpler to enclose the \cw{read} in a group: +\begin{verbatim} +\begingroup +\endlinechar=-1 +\global\read16 to\answer +\endgroup +\end{verbatim} +Here the \cw{global} prefix makes \cw{answer} +retain its definition beyond the \cw{endgroup}. + +With this modification the tests done by \cw{printoptions} could be +simplified to +\begin{verbatim} +\if\Ans@ S ...\else +\if\Ans@ G ...\else +\if\Ans@ P ...\else +... +\end{verbatim} +which renders the macros \verb|\S@|, \verb|\G@|, \verb|\P@| unnecessary. + +On the other hand, we have advanced to some splendid new +complications: \verb|\Ans@| might now be completely empty, if the +user just pressed the \return/ key, and an empty \verb|\Ans@| would +bollix up the \verb|\if| tests. This case is easy to handle, though: +add an extra branch \verb|\ifx\Ans@\empty...| at the beginning. +We have the opposite problem if the user types more than one +letter: on the true branch (the `none-of-the-above' branch, unless +the user's first two letters happen to be identical), the extra +characters could potentially cause spurious typesetting activity. As +it happens, we can kill two birds with one stone, as we'll see +in \secref{s:defaults}. + +\subsection{Uppercasing input} + +Next let's look at the procedure used by \cw{printoptions} for +uppercasing the user's reply: after reading \verb|\ans@|, \cw{xdef} +and \cw{uppercase} are applied to it as follows: + \begin{verbatim} +\xdef\next@{\def\noexpand\Ans@{\ans@}}% +\uppercase\expandafter{\next@}% +\end{verbatim} + A more economical version of the same technique would be: + \begin{verbatim} +\xdef\ans@{\uppercase{% + \gdef\noexpand\ans@{\ans@}}}% +\ans@ +\end{verbatim} + If \verb|\ans@| contains \verb|s| +to begin with, then after the \cw{xdef} has been completed, the +definition of \verb|\ans@| is \verb|\uppercase{\def\ans@{s}}|. Then calling +\verb|\ans@| causes it to redefine itself, but not before the tokens in the +argument of \cw{uppercase} are suitably uppercased.% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Only the \verb|s| is +affected because \cw{uppercase} operates only on letters, not +on control sequences or nonletters. Well, to be more precise: only on +characters that have a nonzero \cw{uccode}; they don't have to have +catcode 11.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +With this change, the auxiliary macro \verb|\Ans@| is no longer needed. + +To simplify the structure of macros using this uppercasing process, +it could be embodied in a dedicated function of its own: +\begin{verbatim} +\def\uppermac#1{\xdef#1{\uppercase{\gdef\noexpand#1{#1}}}% + #1} +\end{verbatim} + +A nonglobal alternative may sometimes be desirable, however. +Also the full expansion may not be wanted in some cases when +the contents of the macro being uppercased are `fragile'. +An alternative that is safer with respect to expansion: +\begin{verbatim} +\def\uppermac#1{% + \uppercase\expandafter\expandafter\expandafter{% + \expandafter\toks@\expandafter{#1}}% + \edef#1{\the\toks@}} +\end{verbatim} + +\subsection{Default responses} +One \label{s:defaults} +last refinement in \cw{printoptions} would be to provide +a default response if the user's response is empty (that is, +the user only hit +the \return/ key). One method involves an auxiliary +macro like the \latex/ macro \verb|\@car|: + \begin{verbatim} +\def\@car#1#2\@nil{#1} +\end{verbatim} + +A more descriptive name (for those whose knowledge of Lisp is nil) +would be \cw{firsttoken}:% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\footnote{Using {\tt\string @} as the ending +delimiter is pretty safe if we make sure that it has catcode 11 at the +time \cw{firsttoken} is defined and some other catcode at the time of +reading user input.} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + \begin{verbatim} +\def\firsttoken#1#2@{#1} +\end{verbatim} +Then, if we want \verb|\ans@| to be +given a default value of P when it comes back empty from the user, we +do this: + \begin{verbatim} +\xdef\ans@{\expandafter\firsttoken\ans@ P@} +\end{verbatim} +At the critical intermediate step, the following cases will arise: + \begin{quote} + \begin{tabular}{l|l} +\hline +User input& Critical step\\\hline +s& \verb|\firsttoken|\,\,\verb|s|\,\verb|P|\,\verb|@|\\ +P& \verb|\firsttoken|\,\,\verb|P|\,\verb|P|\,\verb|@|\hphantom{\tt syn}\\ +\m{return}& \verb|\firsttoken|\,\,\verb|P|\,\verb|@|\\ +\hline +\end{tabular} +\end{quote} + This gives exactly what we want. + +The application of \cw{firsttoken} also gives us a nice way around the +difficulty mentioned earlier if the user types more than one character. +The case +\begin{quote} +\begin{tabular}{l|l} +\hline +synt& \verb|\firsttoken|\,\,\verb|s|\,\verb|y|\,\verb|n|\,\verb|t|\,% +\verb|P|\,\verb|@|\\ +\hline +\omit\hphantom{User input}\kern2\tabcolsep\cr +\end{tabular} +\end{quote} + will produce the same result as the first case above, because +everything after the first \verb|s|, up to the category-11 \verb|@| character, +will be discarded. + +\subsection{A new \cw{printoptions}} + +By noticing that the \cw{xdef}'s used in +the \cw{firsttoken} step and the \cw{uppercase} +step can be combined, and putting together everything +discussed so far, we come up with a new, improved version +of \cw{printoptions}: + \begin{verbatim} +\def\printoptions{% + \W@{Do you want S(yntax check), G(alleys) or P(ages)?}% + \message{Type S, G or P, follow by <return>: }% + \begingroup \endlinechar\m@ne + \global\read\m@ne to\ans@ + \endgroup + \xdef\ans@{\uppercase{% + \def\noexpand\ans@{% +% Default to `P': + \expandafter\firsttoken\ans@ P@}% + }}% +% Execute \ans@ to uppercase itself: + \ans@ + \if S\ans@ \syntax\else + \if G\ans@ \galleys\else + \if P\ans@ % fine, no action needed + \else \message{Unknown option: \ans@; + `pages' option will be used}\fi + \fi\fi +} +\end{verbatim} + The loop has been discarded in favor of simply taking the normal +default action if the user's reply is unintelligible. + +\subsection{Matching braces} +\label{ss:readbrace} +The \cw{read} command normally reads only one line, but if the first +line does not contain an equal number of left and right braces, \tex/ +will continue to read additional lines until equality is achieved +(cf.~\secref{ss:readprim}). +This could be trouble in interactive use of \cw{read}, if the user +doesn't understand what has happened---it's difficult to extricate +yourself except by getting the braces right. + + +On the other hand, if you {\em want} to enter more than one line +at a time, you can do it by entering an opening brace on the first +line and the matching closing brace on the last line; this +is illustrated in Example~\ref{ex:readbrace}. +In the example there are two things worthy of note: +(1)~The braces appear in the replacement text of the macro \cw{name}; +this may be undesirable, depending on the intended use of the +information. (2)~There's no space between +Frank and Henry in \cw{name}. + +The loss of the space has two causes. First, \cw{endlinechar} was set to +$-1$ (so that an empty line will not produce a \cw{par}---see +\secref{s:endlinechar}), and +second, the space that was typed at the beginning of the second +line of the response didn't register either, following \tex/'s +usual rule of ignoring spaces at the beginning of a line +(\texbook/, Chapter~8, double dangerous bends). + +\begin{example*} +\begin{examplebox} +\caption[]{Reading multiple lines with a single \cw{read} command}% +\label{ex:readbrace}% +\writepage{Example} +First, the input file: +\begin{verbatim} +\begingroup \newlinechar=`\& \endlinechar=-1 +\message{&Please enter your name: }\global\read-1 to\name +\message{&And your Social Security number: }\global\read-1 to\ssno +\endgroup +\show\name \show\ssno +... +\end{verbatim} +Now the log file, including the responses (a \return/ was typed after +{\tt Frank}): +\begin{verbatim} +Please enter your name: {Joe Bob Willie Clark Mark Raphael Ferguson Frank + Henry James Percival Emerson Elmo Davenport, Jr.} + +And your Social Security number: 360-60-6000 +> \name=macro: +->{Joe Bob Willie Clark Mark Raphael Ferguson FrankHenry James Percival Emerson + Elmo Davenport, Jr.}. +l.7 \show\name + \show\ssno +? +> \ssno=macro: +->360-60-6000. +l.7 \show\name \show\ssno + +? +\end{verbatim} +\end{examplebox} +\end{example*} + +\subsection{Outer macros}\label{ss:readouter} + +{\em[This section is partly obsolete as of \tex/ version 3.141; see +\secref{ss:readprim}.]} + +If you enter an \cw{outer} macro in response to a \cw{read} prompt, +\tex/ will inform you in an error message +that it has inserted a closing brace. +Unfortunately, this is rather unhelpful, since you will then have the +matching brace problem described in the previous section; your answer +now contains an unmatched right brace, and if you don't type `x' at the +question-mark prompt to exit, you could get stuck. +Fortunately, it is unlikely for anyone to ever enter an outer macro in +response to a prompt, since in \plaintex/ the set of such macros is +small and used relatively infrequently, and in \latex/ there are almost +no \cw{outer} macros at all; accidental typing of a \verb;^^L; +character (which is active and outer, in \plaintex/ and \latex/) is +perhaps the least unlikely possibility. + + +\begin{example} +\begin{examplebox} +\caption[]{Outer control sequence choking a \cw{read} operation. Compare +this to the behavior of \ctrl{L} inside \cw{message} as discussed in \secref{ss:outer}.} +\label{ex:outerread}% +\writepage{Example} +Input file: +\begin{verbatim} +\read16 to\x \show\x +\end +\end{verbatim} + +Log file: +\def\next{\begin{verbatim}\rightskip0pt plus100pt minus 100pt +\linepenalty 500 } +\next +\x=^^L +Runaway definition? +-> +! Forbidden control sequence found while scanning definition of \x. +<inserted text> + } +<read *> ^^L + +l.1 \read16 to\x + +? h +I suspect you have forgotten a `}', causing me +to read past where you wanted me to stop. +I'll try to recover; but if the error is serious, +you'd better type `E' or `X' now and fix your file. + +? 1 +Type <return> to proceed, S to scroll future error messages, +R to run without stopping, Q to run quietly, +I to insert something, E to edit your file, +H for help, X to quit. +? +a +\ +# +{ +> \x=macro: +-> } \par a \^^M## { . +l.2 \show\x + +? +\end{verbatim} + +\end{examplebox} +\end{example} + +Some observations: + +---If the user checks the help message and stops to ponder the +situation, they have the opportunity, at least, to realize that E or +X to exit is indeed the wise choice. They're not {\em really\/} +stuck unless they carelessly try to continue. + +---If the user doesn't avail him/herself of the E or X option, just +about anything else that they try will be ineffective. On some +systems even the interrupt key won't help here; that leaves +essentially two ways out: match up the closing brace, or type another +outer thing to get back to the \verb;?; prompt and the associated +error recovery opportunity. + + +\subsection{Catcodes} + +The treatment of a user's response depends on the use to which it +will be put. \latex/'s \cw{typein} command is designed to take the +response and execute it, and therefore reads the user's response +using normal category codes. On the other hand, \fn{testfont.tex} +\cite{testfont} +changes the category codes of the special characters to 12 when +reading a user response, because the response will not be executed +but will be processed as simple character data. This approach is +probably the better one for most applications, since it avoids the +possibility of problems with things like mismatched braces or outer +control sequences, and since the \cw{read} command is used more often +to read strings of ordinary characters than to read executable control +sequences. + + +\subsection{\fn{Latex.tex}: \cw{typeout} and \cw{typein}} + +An interesting aspect of the \cw{typeout} and \cw{typein} commands in +\latex/ is that they aren't private control sequences (with \verb|@| +characters in their names); they are available for use in ordinary +document files. One of the uses suggested in the \latex/ manual is for +entering an \cw{includeonly} command interactively each time a +multipart document is processed. More commonly, however, \cw{typeout} +and \cw{typein} are used internally in documentstyle files, or in +special applications such as \fn{docstrip.tex} [Mittelbach, 1991] +where the distinction between private and public control sequences is +irrelevant. + +The purpose of \cw{typein} is (a)~to print a message on screen, and +(b)~to +read a response (one line) from the user, either into the internal +macro \cw{@typein}, or into a macro chosen by the macro writer. If +\cw{@typein} is used to receive the response, it will be executed as +\cw{typein}'s final action. Otherwise the response will be stored in +the designated alternate macro, without execution. (Cf.\ the \latex/ +manual, \S4.6.) + +I found the definition of \cw{typein} in \fn{latex.tex} more difficult +to understand than almost anything else of comparable length that I +have looked at. All the complications in the definition serve two +goals: (1)~If the user simply presses the {\sc return} key, the +resulting \cw{par} token needs to be discarded, leaving the macro that +holds the user reply empty; and (2)~if the user reply is not empty, it +will usually, but not always, contain a final space which needs to be +trimmed off. The fact that the final space might be missing is the +crucial problem. + +A simpler version of \cw{@xtypein} could be written using +a temporary deassignment of \cw{endlinechar}: +\begin{verbatim} +\def\@xtypein[#1]#2{\typeout{#2}\let\@typein\relax + \begingroup \endlinechar\m@ne \global\read\z@ to#1\endgroup + \@typein} +\end{verbatim} +This solves both the \cw{par} problem and the trailing space problem. + +However, much of the initial development of \latex/ took place in 1982 +and 1983, before the ultimate release of \tex/82, version~1.0 +(officially: December 3, 1983), and in old \TeX{} there was no access +to \cw{endlinechar}. (In fact many features of \tex/82 were added by +Knuth in response to reports from Lamport about various limitations of +the language that he ran into in the course of \latex/'s development.) +If Lamport noticed later that \cw{endlinechar} could be applied in +\cw{@xtypein}, he probably invoked the principle `If it ain't broke, +don't fix it' and left it alone. + +\subsection{\fn{Docstrip.tex}: \cw{typeout}, \cw{typein}, progress reports} + +As an example of the use of \cw{typeout} and \cw{typein}, +consider \fn{docstrip.tex} +\cite{docstrip}. This is a \latex/ +utility used for processing a documented macro file to remove +comments (the stripped-down version of a large macro file +will load significantly faster at run-time, at least on +less powerful computers). The use of +\cw{typeout} in \fn{docstrip.tex} is mainly a convenience, +to avoid the more cumbersome phrase +\cw{immediate}\cw{write16}, but \cw{typein} has a more +significant advantage---it takes care of removing a space +at the end of the user response, if present. + +In the following fragment from \fn{docstrip.tex}, the user is +informed that an auxiliary file named \fn{docstrip.cmd} has been +detected, and is asked whether it should be used. The response is +read into the macro \cw{answer}. + \begin{verbatim} +\typeout{*************************************************} +\typeout{* Batch file docstrip.cmd found. Use it ? (y/n) *} +\typein[\answer] + {*************************************************} +\def\@tempa{y}% +\ifx\@tempa\answer \process@batchfile \fi + \end{verbatim} +An analysis of the technique in this fragment brings +out a few noteworthy observations. + \begin{itemize} + \item In the prompt (line 2) the acceptable responses are +listed: \verb;y; or \verb;n;. + \item Since \cw{typein} doesn't change the case +of the user's response, and there's no code here in +\fn{docstrip.tex} to change case, we can deduce that a +response of \verb;Y; will be treated as a No. + \item If the user response is \verb;yes;, then \cw{answer} +and \cw{@tempa} will have different definitions, and the +\cw{ifx} test will be false. + \item If the user is expected to enter only a single letter, +we might ask, why is an \cw{ifx} test necessary? Why not +just use \cw{if} \verb|y|\cw{answer}\cw{process@batchfile} +and omit the extra step \cw{def}\cw{@tempa}\verb|{y}|? +However, this would invite trouble if the user pressed +{\sc return} without typing anything. Then \cw{answer} would +be empty (because of the special handling with \cw{@defpar} +in \cw{typein}) and before completing the evaluation of +the \cw{if}, \tex/ would continue beyond \cw{answer} +to expand \cw{process@batchfile} in search of a character +to compare with the \verb;y;. Although this would give a correct +result for the \cw{if} test, because the +first nonexpandable +token in the definition of \cw{process@batchfile} +is not a \verb;y;, the trouble is that the token will be +absorbed by the \cw{if} operation, which will throw a wrench +into subsequent processing. + +\end{itemize} + +{\it Note.} The version of \fn{docstrip.tex} from which I took these +examples was an early, unperfected version with an explicit +disclaimer from the author that it was a quick hack, and should not be +considered an example of his best macro writing. I discuss the early +version here, however, precisely because it illustrates so well some +of the typical difficulties in writing \tex/ dialog. + +An interesting feature of \fn{docstrip} is the ability to see on +screen the progress being made in processing the current file. If +this feature is turned on (with a \cw{showprogress} command), then +\fn{docstrip} prints on screen a percent sign for each comment +removed and a period for each line of code that is kept. This kind of +visual feedback is not just frippery and ornamentation, bells and +whistles. A typical user begins to get nervous if a running program +allows several seconds to pass by without any observable change on +screen. On a fast system, it's straightforward to deduce that such a +pause means something has gone wrong, whereupon the user can press an +interrupt key to investigate the problem without wasting time. But on +a slow system the poor user faces the dilemma: Abort unnecessarily, +and a restart will be required, with all the time consumed so far +wasted; or continue waiting when the program might simply be spinning +its wheels and accomplishing nothing. So when a task might take +more than, say, five seconds, it's good programming practice to give +some sort of progress reports. + +The progress reports of \fn{docstrip} use \cw{message} which, +as discussed earlier, adds a space between consecutive messages if +the second message is not too long to fit on the current line. So +what you see on screen is something like +\begin{verbatim} +% % % % % % % % % % . . . % % . . . . . % % % . . % . % % . % . % +. . . % % . % . % % % % % % % % % . . % . % % . % % % % . . . % . +. . . +\end{verbatim} +produced by repeated \cw{message}\verb"{%}" or \cw{message}\verb"{.}". +Recalling the newline behavior of \cw{immediate}\cw{write}, picture +what would happen if it were used instead of \cw{message} to see +why \cw{message} is necessary for this application. + +\section{Miscellaneous} + +\subsection{Checking a response for validity} +Here is the (slightly condensed) text of Brian Hamilton Kelly's UK\tex/ +post that contained \fn{checknum.sty} \cite{checknum}, which asks the +user for a number and checks to make sure that a valid number was +entered. + +\verbatiminput{uktex91.1x} + +\subsection{em\tex/ 8-bit output}\label{ss:8bit} +One interesting feature of em\tex/ \cite{emtex} is the 8-bit output +option. On PCs, the characters between 176 and 223 are box-drawing +characters; with the 8-bit output option of em\tex/, putting these +characters into a \cw{message} or \cw{write} command allows you to +draw some fairly elaborate boxes on screen, for embellishing menus and +other bits of dialog. I have only experimented with this a very little. + +\subsection{User Help} +There is a good deal of room for improvement in the amount and +kind of help information available to the user from within \tex/. +Help information provided externally through general help facilities +such as Unix man pages is well and good, but any help system +that's not \tex/-based has one disadvantage: lack of +portability across the whole spectrum of computer systems that +can run \tex/. + +\begin{itemize} \item Any program should have an announcement near +the beginning of how to quit without destructive side effects; for +\tex/ this means, among other things, that each version of the \tex/ +program should have in its opening message instructions on how to +break out of an infinite loop or in general how to interrupt \tex/ +before it has finished its current run. In {\it Textures\/} this +requirement is satisfied by the `Pause' button, always visible. In +DOS versions of \tex/ the interrupt key is normally the +Control-Break or Control-C key (depending partly on the particular implementation +of \tex/); in VAX/VMS it is Control-C or Control-Y, with the latter +reserved for emergency use only, since it will leave you without a +log file for reference. + +\item Response to the prompt +\[\parbox{.9\columnwidth}{\tt\raggedright +I can't find file xxx. Please type another input file name:\endgraf}\] +The novice user should be able to type the +reasonable guesses \fn{help} and \fn{h} and \fn{?}; the easiest way +to do this would be to put files \fn{help.tex}, \fn{h.tex} or +\fn{?.tex} in the \tex/ inputs directory/folder/area. (Except that +many OS's don't allow \fn{?.tex} as a file name). Already many +systems have a file \fn{null.tex} or \fn{nul.tex} to allow you to +abort reasonably gracefully if you know enough to enter {\tt null} or +{\tt nul} in response to the prompt. Very +few \tex/ users, however, will ever think of entering \fn{nul} without reading +about it in the documentation or hearing about it from a more +experienced user. + +\item Some of \tex/'s {\em built-in\/} error/help messages are +specific to \fn{plain.tex}. Some big macro packages such as \latex/ +might prefer to change some of the wording at least. For example, +there are references in some of \tex/'s compiled-in help messages to +things like \cw{def} and \cw{eqalign} that are documented nowhere in +the \latex/ book. And if you press \return/ at a \verb'*' prompt after +getting into \tex/'s interactive mode (intentionally or accidentally), +\tex/ urges you to enter a command or type \cw{end}---the latter being +worse than useless in \latex/ (where \cw{stop} or +\verb|\end{document}| are what is required): after typing \cw{end} and +\return/, nothing happens because \latex/ is waiting for the argument +of the \cw{end} command. + +\item Long help and error messages use string pool and main memory. +Storing them in external files would provide more space (at the cost +of slower access; but of course, once you get an error message, +processing speed is scarcely relevant any longer). + +\end{itemize} + +\section{Summary} + +\subsection{Sending messages} + +Recommendations: Until versions of \tex/ earlier than 3.141 are +sufficiently phased out, you had better use \cw{immediate}\cw{write} +rather than \cw{message} for generic message-sending macros, so that +all ``printable'' characters remain available for use in the message +text. Use \cw{message} instead of \cw{immediate}\cw{write} for +producing a prompt if you want the user's response to appear on the +same line. Uncatcode all special characters while constructing the +text of a message, if the message text is completely invariant between +one use and the next. Use \cw{string} if you don't want a space after +a control word, and use \cw{noexpand} if you do want a space. + +\subsection{Reading user input} + +Recommendations: Set the catcode of \cw{endlinechar} temporarily to +$9$ while reading a response, to avoid getting an extra space at the +end from the \ctrl{M}. Uncatcode all special characters, especially +opening and closing braces. If it is not uncatcoded, remove the +outerness from \verb;^^L;, at least while reading a user response, and +similarly, if the backslash is not uncatcoded and you want to be +supremely cautious, remove the outerness from any other outer control +sequences (\eg., \cw{newif}) if they might reasonably, or even +unreasonably, turn up in a user's response. + +\begin{thebibliography}{x} + +\bibitem[Cowan, 1987]{tables} Cowan, Ray. \fn{tables.sty}. 1987. This is +derived from \fn{tables.tex}; I found it at +\fn{sun\-.soe\-.clarkson\-.edu}, directory: \fn{pub\slash tex\slash +latex-style}. + +\bibitem[Greene, 1989]{animals} Greene, Andrew Marc. +``\tex/reation\Dash Playing games with \tex/'s mind.'' +\tugboat/ 10(4), pages 691\dash 705, 1989. Includes a listing +of \fn{animals.tex}. + +\bibitem[Greene, 1990]{basix} Greene, Andrew Marc. +``BaSiX: An interpreter written in \tex/.'' \tugboat/ 11(3), +pages 381\dash 392, 1990. + +\bibitem[Hamilton Kelly, 1991]{checknum} +{Hamilton Kelly}, Brian. \fn{checknum.sty}. {\it UK\tex/} +91(1), 4 January 1991. + +\bibitem[Knuth, 1986b]{TeX} Knuth, Donald E. {\sl \tex/: The program}. +Reading, Mass.: Addison-Wesley, 1986. + +\bibitem[Knuth, 1986c]{testfont} Knuth, Donald E. \fn{testfont.tex}. +{\sl The META\-FONT\-book}, Appendix H, section 4. Reading, Mass.: +Addison-Wesley, 1986. This file is included in all standard +distributions of \mf/. + +\bibitem[Lamport, 1985]{latex} Lamport, Leslie. \fn{latex.tex}. +Version 2.09 (1985--1992). Main source file for \latex/, included with +any standard distribution. + +\bibitem[Mattes, 1992]{emtex} Mattes, Eberhard. +em\tex/. Version 3.1415. +A comprehensive suite of programs including \tex/, +\mf/, printer drivers, previewers, Bib\tex/, \dots. +Available by anonymous ftp from \fn{niord.shsu.edu} (USA) or +\fn{ftp.uni-stuttgart.de} (Europe) and other fine archives. + +\bibitem[Mittelbach, 1991]{docstrip} Mittelbach, Frank. +\fn{docstrip.tex}. Version 1.1l, 1991. This file is part of the +\fn{multicol} package available by anonymous FTP from many archives, +including \fn{ftp.uni-stuttgart.de} and +\fn{ymir.claremont.edu}. + +\end{thebibliography} + +\appendix +\renewcommand{\thesection}{Appendix \Alph{section}} +\renewcommand{\thesubsection}{\Alph{section}.\arabic{subsection}} + +\section{Animals.tex} +This I have cleaned up a bit by making uppercase and lowercase +responses equally acceptable, and by making a loop so that +you can repeat the game without restarting \tex/ each time. +Source credit is in the bibliography \cite{animals}. + +\subsection{animals.tex} +\verbatiminput{animals.tex} + +\subsection{animals2.tex} + +\verbatiminput{animals2.tex} + +\subsection{animal.dat} +A typical file \fn{animal.dat} is shown here, in part. But the nature +of the game is for you to create your own version of this file based +on the answers that you give while playing. +\begin{verbatim} +1 +Does it have four legs? +2 +3 +2 +Is it an amphibian? +4 +5 +3 +Does it have six legs? +6 +7 +4 +Does it have a tail? +36 +37 +5 +Is it a big kind of cat? +10 +11 +6 +Does it have big hind legs used for jumping? +40 +41 +7 +Is it a fish? +8 +9 +8 +... +\end{verbatim} + +\section{Basix.tex} + +Another effort by Andrew Marc Greene, with clear relevance to the +subject of dialog in \tex/, is his prototype Basic interpreter +described in \cite{basix}. I had planned to give here a closer study +of the dialog concepts used by \fn{basix.tex} but it seems I will not +have enough time. + +\section{Tables.tex} + +The file \fn{tables.tex} \cite{tables} +provides table macros with the unique property that a preamble +line specifying the format of each row is not required; the +format is determined automatically by an analysis of the table +contents. The dialog part consists of a message such as +\begin{verbatim} +[Nrows=9, Ncols=2] +\end{verbatim} +that is printed on screen for each table. This provides confirmation +at run-time for the user of the general structure of each table. +In the worst case, if the number of rows or columns is +wildly wrong, the user can press the interrupt +key and go fix up the table before trying again. + +\section{Fontmenu.tex}\label{a:menu} + +The file \fn{fontmenu.tex} demonstrates a crude menu system based on +the token deletion option after an error message. There are five +tokens \cw{ComputerModern}, \cw{Garamond}, etc., corresponding to the +five font choices. They are so defined and arranged that if the user +enters, say, 2 to select Garamond fonts, then the deletion of two +tokens will leave the \cw{Garamond} token showing on screen (as the +last token deleted by the user), and then the next token +(\cw{Helvetica}) will define the font base to be `Garamond' and gobble +the remainder of the list. The effect of this arrangement is that the +user sees the '\cw{Garamond}' on screen as a confirmation of their +selection after they enter the number and before they press the +\return/ key a second time. + +\verbatiminput{fontmenu.tex} + +And here is screen output of a typical run through \fn{fontmenu.tex}: + +\verbatiminput{fontmenu.log} + +\ifdim\textwidth>\textheight +\typeout{^^J% +*******************************************************************^^J% +[*[*[*[*[ DON'T FORGET: print using LANDSCAPE orientation ]*]*]*]*]^^J% +*******************************************************************^^J% +} +\fi + +\end{document} diff --git a/Master/texmf-dist/doc/latex/dialogl/dia-driv.tex b/Master/texmf-dist/doc/latex/dialogl/dia-driv.tex new file mode 100644 index 00000000000..ed4d83d1c9d --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/dia-driv.tex @@ -0,0 +1,246 @@ +%%% ==================================================================== +%%% @LaTeX-file{ +%%% filename = "dia-driv.tex", +%%% version = "1.0h", +%%% date = "2-Dec-1994", +%%% time = "15:21:37 EST", +%%% checksum = "35247 246 1122 9059", +%%% author = "Michael Downes", +%%% address = "49 Weeks Street +%%% North Smithfield, RI 02986, USA", +%%% email = "mjd@math.ams.org (Internet)", +%%% docstring = "The checksum field above contains: CRC-16 +%%% checksum, number of lines, number of words, and number of +%%% characters, as produced by Robert Solovay's checksum utility.", +%%% } +%%% ==================================================================== +% +% Originally published in TUGboat with ltugboat documentstyle. +% Switched to generic article/twocolumn afterward. +\documentstyle[doc,dialogl]{article} + +\title{Interaction tools: {\tt dialog.sty} and {\tt menus.sty}} +\author{Michael Downes} +%\address{49 Weeks Street\\North Smithfield, RI 02895\\U.S.A} +%\netaddress{mjd@math.ams.org} +\date{November 3, 1994} + +\hyphenation{pro-duces} + +\renewcommand{\thepart}{\arabic{part}} +\renewcommand{\thesection}{\thepart.\arabic{section}} + +% Some customizations of doc.sty parameters. +\def\PrintMacroName#1{} +% +%\renewcommand{\PrintDescribeMacro}[1]{} +%\renewcommand{\PrintDescribeEnv}[1]{} + +\setlength{\MacroIndent}{0pt} +\def\MacroFont{\verbatimfont}% doc.sty uses \MacroFont + +% No modules in the files to be processed; so don't bother checking. +\DontCheckModules + +\multicoldefaultlayout +\begin{document} +\jobswitch % print only selected parts if \jobname so indicates; see + % dialogl.sty +\maketitle +\thispagestyle{empty} + +\begin{multicols}{2} +\section*{Introduction} + +\ifall +This article describes +\fn{dialog.sty} and \fn{menus.sty}, which +provide functions for printing messages or menus on screen and reading +users' responses. The file \fn{dialog.sty} contains basic message and +input-reading functions; \fn{menus.sty} takes \fn{dialog.sty} for its +base and uses some of its functions in defining more complex menu +construction functions. These two files are set up in the form of +\LaTeX{} documentstyle option files, but in writing them I spent some +extra effort to try to make them usable with \plaintex/ or other +common macro packages that include \plaintex/ in their base, such as +\AmSTeX{} or \eplain/. + +The appendix describes \fn{grabhedr.sty}, required by \fn{dialog.sty}, +which provides two useful file-handling features: (1)~a command +\cw{inputfwh} that when substituted for \cw{input} makes it possible to +grab information such as file name, version, and date from standardized +file headers in the style promoted by Nelson Beebe\Dash and to grab it +in the process of first inputting the file, as opposed to inputting the +file twice, or \cw{read}ing the information separately (unreliable due +to system-dependent differences in the equivalence of \tex/'s \cw{input} +search path and \cw{openin} search path). And (2)~functions +\cw{localcatcodes} and \cw{restorecatcodes} that make it possible for +\fn{dialog.sty} (or any file) to manage internal catcode changes +properly regardless of the surrounding context. + +These files and a few others are combined in +\else +This package is part of +\fi +a suite of files that goes +by the name of {\bf dialogl}, available on the Internet by anonymous ftp +from CTAN (Comprehensive \tex/ Archive Network), e.g., \fn{ftp.shsu.edu} +(USA), or \fn{ftp.uni-stuttgart.de} (Europe). +% +\ifall +The file \fn{listout.tex} is a utility for verbatim printing of plain +text files, with reasonably good handling of overlong lines, tab +characters, other nonprinting characters, etc. It uses \fn{menus.sty} to +present an elaborate menu system for changing options (like font size, +line spacing, or how many spaces should be printed for a tab character). +\else +It includes the packages \pkg{dialog}, \pkg{menus}, and \pkg{grabhedr} +and a utility file \fn{listout.tex} for verbatim printing of plain text +files. +\fi + +\ifmenus +Here's an example from the menu system of \fn{listout.tex} to +demonstrate the use of some features from \fn{dialog.sty} and +\fn{menus.sty}. First, the menu that you would see if you wanted to +change the font or line spacing: +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% This funny way of calling \samepage is (I think) the most +% convenient way to avoid turning off page breaks for the preceding +% paragraph. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\next{\begin{verbatim}\samepage}\next +=============================================== + F Change font + S Change font size + L Change line spacing + +Current settings: typewriter 8 / 10.0pt. + + Q Quit X Exit ? Help +=============================================== + +Your choice? +\end{verbatim} +Suppose you wanted to change line spacing to 9 points, so you entered +\qc{\l} (lowercase \qc{\L}) and then \verb'9pt', except that on your +first attempt you accidentally mistyped \verb'9pe' instead of +\verb'9pt'. Here's what you would see on screen: +\begin{verbatim} +Your choice? l +Desired line spacing [TeX units] ? 9pe +?---I don't understand "9pe". +Desired line spacing [TeX units] ? 9pt + +* New line spacing: 9.0pt +\end{verbatim} +Both lowercase \verb'l' and capital \verb'L' are acceptable responses, +and the value given for line spacing is checked to make sure it's a +valid \tex/ dimension. Before continuing, the internalized version of +the user's value is echoed on screen to confirm that the entered value +was read correctly. + +Now here's how the above menu is programmed in \fn{listout.tex}. +A function \cw{menuF} is constructed using \cw{fxmenu}: +\begin{verbatim} +\fxmenu\menuF{}{ +F Change font +S Change font size +L Change line spacing +}{ +Current settings: &\mainfont &\mainfontsize / % +&\the&\normalbaselineskip. +} +% +\def\moptionF{\lettermenu F} +\end{verbatim} +In the definition of \cw{moptionF}, \cw{lettermenu} is a high-level +function from \fn{menus.sty} that prints \cw{menuF} on screen (given +the argument \verb'F'), reads a line of input from the user, extracts +the first character and forces it to uppercase, then branches to +the next menu as determined by that character. The response of +\verb'l' causes a branch to the function \cw{moptionFL}: +\begin{verbatim} +\def\moptionFL{% + \promptmesj{% + Desired line spacing [TeX units] ? }% + \readline{Q}\reply +\end{verbatim} +If \verb'Q', \verb'X', or \verb'?' was entered, the test +\cw{xoptiontest} will return `true'; then we should skip the dimension +checking and go directly to \cw{optionexec}, which knows what to do +with those responses: +\begin{verbatim} + \if\xoptiontest\reply + \else +\end{verbatim} +Otherwise we check the given dimension to make sure it's usable. If so, +echo the new value as confirmation. +\begin{verbatim} + \checkdimen\reply\dimen@ + \ifdim\dimen@>\z@ + \normalbaselineskip\dimen@\relax + \normalbaselines + \confirm{New line spacing: + \the\normalbaselineskip}% + \def\reply{Q}% + \fi +\end{verbatim} +If \cw{reply} was changed to \verb'Q' during the above step, +\cw{optionexec} will pop back up to the previous menu level (normal +continuation); otherwise \cw{reply} retains its prior definition\Dash +e.g., \verb'9pe'\Dash to which \cw{optionexec} will simply say ``I +don't understand that'' and repeat the current prompt. +\begin{verbatim} + \fi + \optionexec\reply +} +\end{verbatim} + +For maximum portability, \fn{listout.tex} uses in its menus only +lowest-common-denominator ordinary printable ASCII characters in the +range 32\dash 126. Fancier menus can be obtained at a cost of forgoing +system independence, for instance by using em\tex/'s \verb'/o' option +to output the box-drawing characters in the standard PC DOS character +set. +\fi + +\subsection*{Notation} + +Double-hat notation such as \verb'^^J' is used herein for +control characters, as in \TB{}, although occasionally the alternate +form `{\sc control}-J' is used when the emphasis is away from the +character's tokenized state inside \tex/. A couple of abbreviations +from \fn{grabhedr.sty} are used frequently in the macro code: \cw{xp@} += \cw{expandafter}, and \cw{nx@} = \cw{noexpand}. Standard +abbreviations from \fn{plain.tex} such as \cw{z@} or \cw{toks@} are +used without special comment. + +\ifall +\part{Basic dialog functions: \fn{dialog.sty}} +\fi +\ifdialog\hDocInput{dialog.dtx}\fi + +\ifall +\part{Menu functions: \fn{menus.sty}} +\setcounter{section}{0} +\fi +\ifmenus\hDocInput{menus.dtx}\fi + +\ifall +% It's hard to make this part title come out right without assuming +% \partname is defined. +\part*{Appendix\penalty-10000 +Miscellaneous support functions: +\fn{grabhedr.sty}} +\setcounter{section}{0} +\renewcommand{\thepart}{A} % for use in \thesection +\fi +\ifgrabhedr\hDocInput{grabhedr.dtx}\fi + +\end{multicols} + +\ifdim\textwidth>\textheight +\typeout{^^JWarning: remember to print using LANDSCAPE orientation^^J} +\fi +\end{document} diff --git a/Master/texmf-dist/doc/latex/dialogl/diatest.tex b/Master/texmf-dist/doc/latex/dialogl/diatest.tex new file mode 100644 index 00000000000..4310bf1d6b6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/diatest.tex @@ -0,0 +1,162 @@ +% Test of the `menus' package. You can run this file with (at least) +% plain TeX, LaTeX (2e), and old LaTeX (2.09). +% +% Some chicanery to make this file work in several different contexts. +\ifx\undefined\documentclass + \def\NeedsTeXFormat#1{}\def\RequirePackage#1{\input #1.sty \relax} + \def\ProvidesPackage#1[#2]{} + \ifx\undefined\documentstyle + \def\startup{\input menus.sty \relax} + \else + \def\startup{\documentstyle[menus]{article}} + \fi +\else + \def\startup{% + \documentclass{article}% + \usepackage{menus}% + } +\fi + +\startup + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\mesj{ +The following series of tests is designed to cover most of the +features that are provided by dialog.sty. If you compare what you +see on screen with the contents of the file diatest.tex you will +see how they correspond. + +Press the Return or Enter key to continue:} +\readline{}\xyz + +\promptmesj{ + +Testing \mesj: +Press return to continue: } +\readline{}\xyz\mesj{} +\mesj{Give ~ me %^^L an &| + \newif #} + +\promptmesj{ +Testing \xmesj: +Press return to continue: } +\readline{}\xyz\mesj{} +\xmesj{Do we have \{\}\\ characters? +And \iftrue\.true\else\.false\fi. +Not to mention ampersand \&, since \string\iftrue.} + +\promptmesj{ +Testing \xmesj inside of a \def: +Press return to continue: } +\readline{}\xyz\mesj{} +\def\next{\xmesj{Abc space:\ , control-M: \^^M, and percent:\%\ +and another line break.}} +\next + +\promptmesj{ +Testing \promptmesj: +Press return to continue: } +\readline{}\xyz\mesj{} +\promptmesj{Enter this or that: } +\readline{}\xyz + +\promptmesj{ +Testing \storemesj: +Press return to continue: } +\readline{}\xyz\mesj{} +\storemesj\foo{This is a fine old message, isn't it?: +\mesj{Give ~ me %^^L an &| + \newif }} +\xmesj{\foo} + +\promptmesj{ +Testing \storexmesj now with an arg: +Press return to continue: } +\readline{}\xyz\mesj{} +\storexmesj\foo#1{This is a fine old message, isn't it?: +\\mesj{Give ~ me \%^^L an \&|#1 + \\newif \#}} +\xmesj{\foo{KABLOO}} + +\promptmesj{ +Testing \fmesj: +Press return to continue: } +\readline{}\xyz\mesj{} +\fmesj\foo{This is a fine old message, isn't it?: +\mesj{Give ~ me %^^L an &| + \newif}} +\foo + +\promptmesj{ +Testing \fxmesj now with an arg: +Press return to continue: } +\readline{}\xyz\mesj{} +\fxmesj\foo#1{This is a fine old message, isn't it?: +\\mesj{Give ~ me \%^^L an \&|#1 + \\newif \#}} +\foo{KABLOO} + +\promptmesj{ +Would you like to try out \readline? [yes or no]: } +\readline{}\answer +\xmesj{Well, if I understood you correctly, you answered `\answer'} + +\promptmesj{ +OK, now try give me an executable answer, such as +"\iftrue yes\else no\fi": } +\xreadline{}\answer +\xmesj{Well, and now if I try to execute that: "\answer"} + +\promptmesj{ +OK, now let's try \readchar. Give me an arbitrary answer of +one or more characters: } +\readchar{}\answer +\xmesj{Taking the first character from your answer, I get: "\answer"} + +\promptmesj{ +OK, now let's try \readChar. Give me an arbitrary answer of +one or more letters: } +\readChar{}\answer +\xmesj{Taking the first character from your answer, and +uppercasing it, I get: "\answer"} + +\promptmesj{ +OK, give me a number then, so that I can +check it with \checkinteger: } +\readline{}\answer +\checkinteger\answer\fam +\xmesj{\ifnum\fam=-\maxdimen% +Gee, I don't think that was\else\.Got\fi% + a valid number: "\answer"} + +\def\dimtest#1{\promptxmesj{#1}% + \readline{}\answer + \ifx\empty\answer + \else + \checkdimen\answer\vfuzz + \ifdim\vfuzz=-\maxdimen% + \xmesj{Sorry, that doesn't look like a TeX dimen to me: "\answer"}% + \else + \xmesj{Looks like a valid TeX dimen: "\answer" = \the\vfuzz}% + \fi + \expandafter\dimtestb + \fi +} + +\def\dimtesta{\dimtest{\ +OK, give me a dimen then, so that I can\ +check it with \\checkdimen:\ +}} + +\def\dimtestb{\dimtest{\ +How about another dimen: }} + +\def\empty{} + +% Iterate once with one prompt, then several times with a shorter +% prompt. +\dimtesta + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\csname stop\endcsname +\end diff --git a/Master/texmf-dist/doc/latex/dialogl/fontmenu.tex b/Master/texmf-dist/doc/latex/dialogl/fontmenu.tex new file mode 100644 index 00000000000..575a8344f3e --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/fontmenu.tex @@ -0,0 +1,67 @@ +\def\ComputerModern{\gdef\fontbase{Times}\gobble} +\def\Garamond{\gdef\fontbase{Computer Modern}\gobble} +\def\Helvetica{\gdef\fontbase{Garamond}\gobble} +\def\Malibu{\gdef\fontbase{Helvetica}\gobble} +\def\Times{\gdef\fontbase{Malibu}\gobble} + +\def\gobble#1\endgobble{} + +% Make sure we have a reasonable \newlinechar +\newlinechar=`\^^J \catcode\newlinechar=12 + +\begingroup +\catcode`\<=1 \catcode`\ =2\relax +\gdef\menustart{\errmessage<% +....................................... }% +\endlinechar\newlinechar\catcode`\ =12\relax +\gdef\menutext{ + ....................................... + ....................................... + + Select the font base you wish to use: + + [1] Computer Modern [4] Malibu + [2] Garamond [5] Times + [3] Helvetica + + (Default: Times)}% +\endgroup% percent here to avoid extra \newlinechar + +\begingroup +\immediate\write16{\menutext} +% If the user accidentally types 33 instead of 3 they will get past +% all the legitimate menu choices. So to keep that from causing +% trouble, we throw in a bunch of ~ characters below to perform +% error recovery. The standard maximum number of tokens that TeX +% will delete at one time is 99. +\catcode`\~=\active % just to make sure +\def~{\newlinechar`\^^J% restore normal value + \message{% +Whoops! Well, you got Times as your font base, I think}% + \gobble} +% Minimize unwanted error context (note: setting +% this to -1 doesn't suppress any more information) +\errorcontextlines 0 +\newlinechar=`\! % to hide the automatic ! from \errmessage +\gdef\fontbase{Times} +% Inside the next group we make the space character +% active so that we can use it to call \menustart, +% and then we use \expandafter so that the first +% space on the next line gets that catcode before +% the \endgroup makes it revert to normal. All this +% so that the user does not see `\menustart' on +% screen, only a space. +\begingroup +\catcode`\ =\active\let =\menustart\expandafter\endgroup% + % Enter a number (1...5) and press Return TWICE +\ComputerModern% Press Return to continue +\Garamond% Press Return to continue +\Helvetica% Press Return to continue +\Malibu% Press Return to continue +\Times% Press Return to continue +\gobble% +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% +\endgobble\endgroup% +\show\fontbase +\end diff --git a/Master/texmf-dist/doc/latex/dialogl/listout.tex b/Master/texmf-dist/doc/latex/dialogl/listout.tex new file mode 100644 index 00000000000..9e225ebd058 --- /dev/null +++ b/Master/texmf-dist/doc/latex/dialogl/listout.tex @@ -0,0 +1,3130 @@ +%% +%% This is file `listout.tex', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% grabhedr.dtx +%% dialog.dtx +%% menus.dtx +%% listout.dtx + +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "grabhedr.sty", +%%% version = "0.9j", +%%% date = "1994/11/08", +%%% time = "16:15:00 EST", +%%% author = "Michael Downes", +%%% email = "mjd@math.ams.org (Internet)", +%%% keywords = "TeX, file header, +%%% supported = "yes", +%%% abstract = "This file defines a function \inputfwh +%%% to be used instead of \input, to allow TeX to grab +%%% information from standardized file headers in the form +%%% proposed by Nelson Beebe during his term as president of the +%%% TeX Users Group. Of which all this here is an example.", +%%% checksum = "60397 519 2589 19482", +%%% docstring = "The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the equivalent of +%%% the standard UNIX wc (word count) utility output of lines, +%%% words, and characters. This is produced by Robert Solovay's +%%% checksum utility.", +%%% } +%%% ==================================================================== +\begingroup +\catcode96 12 % left quote +\catcode`\= 12 +\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 +\catcode`\$=3 \catcode`\~=13 \catcode`\^=7 +\catcode`\_=8 \catcode`\^^M=5 \catcode`\"=12 +\catcode`\@=11 +\gdef\@empty{} +\long\gdef\@gobble#1{} +\long\gdef\@gobbletwo#1#2{} +\long\gdef\@gobblethree#1#2#3{} +\long\gdef\@car#1#2\@nil{#1} +\ifx\UndEFiNed\@@input % LaTeX not loaded. + \edef\0{\meaning\input}\edef\1{\string\input}% + \ifx\0\1% + \global\let\@@input\input + \else + \errhelp{% +Grabhedr.sty needs to know the name of the +\input primitive in order to define \inputfwh +properly. Consult a TeXnician for help.} + \errmessage{% + Non-primitive \noexpand\input detected}% + \fi +\fi +\global\toksdef\toks@=0 +\long\gdef\afterfi#1\fi{\fi#1} +\global\let\nx@\noexpand +\global\let\xp@\expandafter +\begingroup \lccode`\.=`\%% +\lowercase{\gdef\@percentchar{.}}% +\endgroup +\gdef\fileversiondate#1#2#3{% + \xp@\xdef\csname#1\endcsname{#2 (#3)}% + \def\filename{#1}\def\fileversion{#2}% + \def\filedate{#3}% + \message{#1 \csname#1\endcsname}% +} +\xdef\@filehdrstart{% + \@percentchar\@percentchar\@percentchar\space + ==================================% + ==================================} +\gdef\@scanfileheader#1@#2#{\@xscanfileheader} +\long\gdef\@xscanfileheader#1{% + \@yscanfileheader#1{} version = "??", + date = "??",\@yscanfileheader} +\long\gdef\@yscanfileheader + #1 filename = "#2",#3 version = "#4",% + #5 date = "#6",#7\@yscanfileheader{% + \endgroup + \csname fileversiondate\endcsname{#2}{#4}{#6}% +} +\begingroup +\lccode`\$=`\^^M +\lowercase{\gdef\@readfirstheaderline#1$}{% + \toks@{#1}% + \edef\@tempa{\@percentchar\the\toks@}% + \ifx\@tempa\@filehdrstart + \endgroup \begingroup + \catcode`\%=9 \catcode`\^^M=5 \catcode`\@=11 + \catcode`\ =10 \catcode`\==12 \catcode`\"=12 + \xp@\@scanfileheader + \else + \message{(* Missing file header? *)}% + \afterfi\endgroup + \fi} +\endgroup +\gdef\@xinputfwh{% + \ifx\next\@readfirstheaderline + \catcode`\%=12 \catcode`\{=12 \catcode`\}=12 + \catcode`\\=12 \catcode`\^^L=12 + \catcode`\^=12 + \catcode`\^^M=3\relax + \else \endgroup\fi +} +\gdef\@inputfwh{\futurelet\next\@xinputfwh} +\gdef\inputfwh#1{% + \begingroup\catcode`\%=\active + \endlinechar`\^^M\relax + \lccode`\~=`\%\relax + \lowercase{\let~}\@readfirstheaderline + \xp@\@inputfwh\@@input #1\relax +} +\gdef\localcatcodes#1{% + \ifx\@empty\@catcodestack + \gdef\@catcodestack{{}}% + \fi + \def\do##1##2{% + \ifnum##2>\z@ + \catcode\number`##1 \space + \number\catcode`##1\relax + \expandafter\do\fi}% + \xdef\@catcodestack{{\do#1\relax\m@ne}% + \@catcodestack}% + \def\do##1##2{\catcode`##1 ##2\relax\do}% + \do#1\ {\catcode32\let\do}% +} +\gdef\@catcodestack{{}} +\gdef\restorecatcodes{% + \begingroup + \ifx\@empty\@catcodestack + \errmessage{Can't pop catcodes; + \nx@\@catcodestack = empty}% + \endgroup + \else + \def\do##1##2\do{% + \gdef\@catcodestack{##2}% + \endgroup##1}% + \xp@\do\@catcodestack\do + \fi +} +\expandafter\gdef\csname trap.input\endcsname + \input#1 \relax{% + \expandafter\ifx\csname#1\endcsname\relax + \afterfi\inputfwh{#1}\relax + \fi} +\endgroup +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "dialog.sty", +%%% version = "0.9y", +%%% date = "1994/11/08", +%%% time = "13:31:30 EST", +%%% checksum = "20801 1436 7278 54732", +%%% author = "Michael Downes", +%%% email = "mjd@math.ams.org (Internet)", +%%% codetable = "ISO/ASCII", +%%% keywords = "TeX, dialog", +%%% supported = "yes", +%%% abstract = "This file provides functions for writing +%%% messages and menus on screen, and reading user responses. It +%%% can be used with LaTeX as a documentstyle option, or in +%%% other forms of TeX by a standard \input statement.", +%%% docstring = "The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the equivalent of +%%% the standard UNIX wc (word count) utility output of lines, +%%% words, and characters. This is produced by Robert Solovay's +%%% checksum utility.", +%%% } +%%% ==================================================================== +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% The line break is significant here: +\localcatcodes{\@{11}\ {10}\ +{5}\~{13}\"{12}\#{6}\^{7}\`{12}} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begingroup +\def\do{12 \catcode`} +\catcode`\~\do\!\do\@\do\#\do\$\do\^\do\& +\do\*\do\(\do\)\do\-\do\_\do\=\do\[\do\] +\do\;\do\:\do\'\do\"\do\<\do\>\do\,\do\. +\do\/\do\?\do\|12\relax +\escapechar -1 +\edef\\{\string\\} +\edef\{{\string\{}\edef\}{\string\}} +\catcode`\ =12\catcode`\%=12 +\xdef\otherchars +{ !"#$%&'()*+,-./:;<=>?[\\]^_`\{|\}~} +\endgroup % ^ ^ ^ +\begingroup +\endlinechar = -1 +\def\do{12 \catcode`} +\catcode`\^^@\do\^^A\do\^^B\do\^^C +\do\^^D\do\^^E\do\^^F\do\^^G\do\^^H\do\^^I +\do\^^J\do\^^K\do\^^L\do\^^M\do\^^N\do\^^O +\do\^^P\do\^^Q\do\^^R\do\^^S\do\^^T\do\^^U +\do\^^V\do\^^W\do\^^X\do\^^Y\do\^^Z\do\^^[ +\do\^^\\do\^^]\do\^^^\do\^^_\do\^^? 12\relax +\gdef\controlchars{^^@^^A^^B^^C^^D^^E^^F^^G + ^^H^^I^^J^^K^^L^^M^^N^^O^^P^^Q^^R^^S^^T + ^^U^^V^^W^^X^^Y^^Z^^[^^\^^]^^^^^_^^?} +\endgroup +\begingroup +\def\do{12 \catcode`} +\catcode`\^^80\do\^^81\do\^^82\do\^^83\do\^^84 +\do\^^85\do\^^86\do\^^87\do\^^88\do\^^89\do\^^8a +\do\^^8b\do\^^8c\do\^^8d\do\^^8e\do\^^8f +\do\^^90\do\^^91\do\^^92\do\^^93\do\^^94\do\^^95 +\do\^^96\do\^^97\do\^^98\do\^^99\do\^^9a\do\^^9b +\do\^^9c\do\^^9d\do\^^9e\do\^^9f +\do\^^a0\do\^^a1\do\^^a2\do\^^a3\do\^^a4\do\^^a5 +\do\^^a6\do\^^a7\do\^^a8\do\^^a9\do\^^aa\do\^^ab +\do\^^ac\do\^^ad\do\^^ae\do\^^af +\do\^^b0\do\^^b1\do\^^b2\do\^^b3\do\^^b4\do\^^b5 +\do\^^b6\do\^^b7\do\^^b8\do\^^b9\do\^^ba\do\^^bb +\do\^^bc\do\^^bd\do\^^be\do\^^bf +\do\^^c0\do\^^c1\do\^^c2\do\^^c3\do\^^c4\do\^^c5 +\do\^^c6\do\^^c7\do\^^c8\do\^^c9\do\^^ca\do\^^cb +\do\^^cc\do\^^cd\do\^^ce\do\^^cf +\do\^^d0\do\^^d1\do\^^d2\do\^^d3\do\^^d4\do\^^d5 +\do\^^d6\do\^^d7\do\^^d8\do\^^d9\do\^^da\do\^^db +\do\^^dc\do\^^dd\do\^^de\do\^^df +\do\^^e0\do\^^e1\do\^^e2\do\^^e3\do\^^e4\do\^^e5 +\do\^^e6\do\^^e7\do\^^e8\do\^^e9\do\^^ea\do\^^eb +\do\^^ec\do\^^ed\do\^^ee\do\^^ef +\do\^^f0\do\^^f1\do\^^f2\do\^^f3\do\^^f4\do\^^f5 +\do\^^f6\do\^^f7\do\^^f8\do\^^f9\do\^^fa\do\^^fb +\do\^^fc\do\^^fd\do\^^fe\do\^^ff 12\relax +\gdef\highchars{% +^^80^^81^^82^^83^^84^^85^^86^^87^^88% +^^89^^8a^^8b^^8c^^8d^^8e^^8f% +^^90^^91^^92^^93^^94^^95^^96^^97^^98% +^^99^^9a^^9b^^9c^^9d^^9e^^9f% +^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8% +^^a9^^aa^^ab^^ac^^ad^^ae^^af% +^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8% +^^b9^^ba^^bb^^bc^^bd^^be^^bf% +^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8% +^^c9^^ca^^cb^^cc^^cd^^ce^^cf% +^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8% +^^d9^^da^^db^^dc^^dd^^de^^df% +^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8% +^^e9^^ea^^eb^^ec^^ed^^ee^^ef% +^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8% +^^f9^^fa^^fb^^fc^^fd^^fe^^ff} +\endgroup +\def\actively#1#2{\catcode`#2\active + \begingroup \lccode`\~=`#2\relax + \lowercase{\endgroup#1~}} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\mesjsetup{\begingroup \count@=12 + \def\do##1{\catcode`##1\count@ \do}% + \xp@\do\otherchars{a11 \@gobbletwo}% + \xp@\do\controlchars{a11 \@gobbletwo}% + \xp@\do\highchars{a11 \@gobbletwo}% + \actively\edef\^^I{ \space\space\space + \space\space\space\space}% + \endlinechar=`\^^M\actively\let\^^M=\relax + \catcode`\{=1 \catcode`\}=2 } +\def\sendmesj{\newlinechar`\^^J% + \actively\def\^^M{^^J}% + \immediate\write\sixt@@n{\mesjtext}\endgroup} +\def\mesj{\mesjsetup \afterassignment\sendmesj + \def\mesjtext} +\def\sendprompt{% + \newlinechar`\!\relax \actively\def\^^M{!}% + \message{\mesjtext}\endgroup} +\def\promptmesj{\mesjsetup + \afterassignment\sendprompt \def\mesjtext} +\def\storemesj#1{\mesjsetup + \catcode`\#=6 % to allow arguments if needed + \afterassignment\endgroup + \long\gdef#1} +\def\fmesj#1#2#{\mesjsetup + \catcode`\#=6 % restore to normal + \toks@{\long\gdef#1#2}% + \def\@tempa{% + \edef\@tempa{% + \the\toks@{% + \begingroup\def\nx@\mesjtext{\the\toks2 }% + \nx@\sendmesj}% + }% + \@tempa + \endgroup % Turn off the \mesjsetup catcodes + }% + \afterassignment\@tempa + \toks2=} +\def\xmesjsetup{\mesjsetup + \iffalse{\fi + \catcode`\\=0 \catcode`\%=14 + \begingroup \lccode`\0=`\\\lccode`\1=`\{% + \lccode`\2=`\}\lccode`\3=`\%% + \lowercase{\endgroup \def\\{0}\def\{{1}% + \def\}{2}\def\%{3}}% + \iffalse}\fi + \edef\&{\string &}% + \actively\let\&=\noexpand + \actively\let\^^M=\relax + \def\.{}% + \def\ { }\edef~{\string ~}% + \begingroup \lccode`\~=`\^^M% + \lowercase{\endgroup \def\^^M{~}}% + \let\^^J\^^M \def\par{\^^M\^^M}% +} +\def\xmesj{\xmesjsetup \afterassignment\sendmesj + \edef\mesjtext} +\def\promptxmesj{\xmesjsetup + \afterassignment\sendprompt \edef\mesjtext} +\def\storexmesj#1#2#{\xmesjsetup + \catcode`\#=6 % to allow arguments if needed + \edef\#{\string##}% + \afterassignment\endgroup + \long\xdef#1#2} +\def\fxmesj#1#2#{\xmesjsetup + \catcode`\#=6 % restore to normal + \edef\#{\string##}% + \toks@{\long\xdef#1#2}% + \def\@tempa{% + \edef\@tempa{% + \the\toks@{\begingroup + \def\nx@\nx@\nx@\mesjtext{\the\toks\tw@}% + \nx@\nx@\nx@\sendmesj}}% + \@tempa % execute the constructed xdef + \endgroup % restore normal catcodes + }% + \afterassignment\@tempa + \toks\tw@=} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\readline#1#2{% + \begingroup \count@ 12 % + \def\do##1{\catcode`##1\count@ \do}% + \xp@\do\otherchars{a11 \@gobbletwo}% + \xp@\do\controlchars{a11 \@gobbletwo}% + \xp@\do\highchars{a11 \@gobbletwo}% + \catcode`\ =10 \catcode`\^^I=10 % + \catcode`\^^M=9 % ignore + \endlinechar`\^^M + \read\m@ne to#2% + \edef#2{\def\nx@#2{#2}}% + \xp@\endgroup #2% + \ifx\@empty#2\def#2{#1}\fi +} +\def\xreadline#1#2{% + \begingroup + \xp@\let\csname bye\endcsname\relax + \xp@\let\csname newif\endcsname\relax + \xp@\let\csname newcount\endcsname\relax + \xp@\let\csname newdimen\endcsname\relax + \xp@\let\csname newskip\endcsname\relax + \xp@\let\csname newmuskip\endcsname\relax + \xp@\let\csname newtoks\endcsname\relax + \xp@\let\csname newbox\endcsname\relax + \xp@\let\csname newinsert\endcsname\relax + \xp@\let\csname +\endcsname\relax + \actively\let\^^L\relax + \catcode`\^^M=9 % ignore + \endlinechar`\^^M% reset to normal + \read\m@ne to#2% + \toks@\xp@{#2}% + \edef\@tempa{\def\nx@#2{\the\toks@}}% + \xp@\endgroup \@tempa + \ifx\@empty#2\def#2{#1}\fi +} +\def\readchar#1#2{% + \readline{#1}#2% + \edef#2{\xp@\@car#2#1{}\@nil}% +} +\def\readChar#1#2{% + \readline{#1}#2% + \changecase\uppercase#2% + \edef#2{\xp@\@car #2#1{}\@nil}% +} +\def\changecase#1#2{\@casetoks\xp@{#2}% + \edef#2{#1{\def\nx@#2{\the\@casetoks}}}#2} +\newtoks\@casetoks +\def\checkinteger#1#2{\let\scansign@\@empty + \def\scanresult@{#2}% + \xp@\scanint#1x\endscan} +\def\scanint#1{% + \ifodd 0#11 % + \def\@tempa{\afterassignment\endscan + \scanresult@=\scansign@#1}% + \else + \if -#1\relax + \edef\scansign@{% + \ifx\@empty\scansign@ -\fi}% + \def\@tempa{\scanint}% + \else + \if +#1\relax + \def\@tempa{\scanint}% + \else % not a valid number + \def\@tempa{% + \scanresult@=-\maxdimen\endscan}% + \fi\fi\fi + \@tempa +} +\def\endscan#1\endscan{} +\newcount\dimenfirstpart +\newtoks\dimentoks +\def\scandimen#1{% + \ifodd 0#11 + \def\@tempa{\def\@tempa{\scandimenb}% + \afterassignment\@tempa + \dimenfirstpart#1}% + \else + \if \if,#1.\else#1\fi.% + \def\@tempa{\scandimenc}% + \else + \if -#1% then flipflop the sign + \edef\scansign@{% + \ifx\@empty\scansign@ -\fi}% + \def\@tempa{\scandimen}% + \else + \if +#1% then ignore it + \def\@tempa{\scandimen}% + \else % not a valid dimen + \def\@tempa{% + \scanresult@=-\maxdimen\endscan}% + \fi\fi\fi\fi + \@tempa +} +\def\scandimenb#1{% + \if \if,#1.\else#1\fi.% + \def\@tempa{\scandimenc}% + \else + \def\@tempa{\scanunitsa#1}% + \fi + \@tempa +} +\def\scandimenc#1{% + \ifodd 0#11 \dimentoks\xp@{% + \the\dimentoks#1}% + \def\@tempa{\scandimenc}% + \else + \def\@tempa{\scanunitsa#1}% + \fi + \@tempa +} +\def\scanunitsa#1\endscan{% + \def\@tempa##1true##2##3\@tempa{##2}% + \lowercase{% + \xp@\ifx\xp@\end + \@tempa#1true\end\@tempa + }% + \let\dimentrue@\@empty + \def\@tempa{\scanunitsb#1\endscan}% + \else + \def\dimentrue@{true}% + \def\@tempa##1true##2\@tempa{% + \def\@tempa{##1}% + \ifx\@tempa\@empty + \def\@tempa{\scanunitsb##2\endscan}% + \else + \def\@tempa{\scanunitsb xx\endscan}% + \fi}% + \@tempa#1\@tempa + \fi + \@tempa +} +\def\scanunitsb#1#2{% + \def\@tempa##1#1#2##2##3\@nil{##2}% + \def\@tempb##1{T\@tempa + pcTptTcmTccTemTexTinTmmTddTspT##1F\@nil}% + \lowercase{% + \if\@tempb{#1#2}% + }% + \scanresult@=\scansign@ + \number\dimenfirstpart.\the\dimentoks + \dimentrue@#1#2\relax + \else + \scanresult@=-\maxdimen + \fi + \endscan +} +\def\checkdimen#1#2{% + \let\scansign@\@empty \def\scanresult@{#2}% + \let\dimentrue@\@empty + \dimenfirstpart\z@ \dimentoks{}% + \xp@\scandimen#1xx\endscan +} +\restorecatcodes +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "menus.sty", +%%% version = "0.9x", +%%% date = "1994/11/08", +%%% time = "13:32:59 EST", +%%% checksum = "38585 989 4295 33156", +%%% keywords = "TeX, menus", +%%% author = "Michael Downes", +%%% email = "mjd@math.ams.org (Internet)", +%%% supported = "yes", +%%% abstract = "This file provides functions for writing +%%% messages and menus on screen, and reading user responses. It +%%% can be used with LaTeX as a documentstyle option, or in +%%% other forms of TeX by a standard \input statement.", +%%% docstring = "The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the equivalent of +%%% the standard UNIX wc (word count) utility output of lines, +%%% words, and characters. This is produced by Robert Solovay's +%%% checksum utility.", +%%% } +%%% ==================================================================== +\localcatcodes{\@{11}% + \~{13}\"{12}\#{6}\^{7}\`{12}\${3}\:{12}} +\storexmesj\menuprefix{ +====================================================================== +} +\let\menusuffix=\menuprefix +\storemesj\inmenuA{ +} +\storemesj\inmenuB{ +} +\storemesj\menuline{ } +\def\menutopline{} +\def\menubotline{} +\storemesj\endmenuline{ +}% +\def\menunumber#1{[#1] } +\def\menuprompt{\promptmesj{Your choice? }} +\newtoks\menufirstpart +\newtoks\menuchoices +\newtoks\menulastpart +\def\fmenu#1#2#{\mesjsetup + \catcode`\#=6 % for parameters + \toks@{\fxmenub{\gdef}{\begingroup}{}#1{#2}}% + \def\@tempa##1##{% + \def\@tempa####1####{% + \def\@tempa{\the\toks@}% + \afterassignment\@tempa \menulastpart}% + \afterassignment\@tempa \menuchoices}% + \afterassignment\@tempa \menufirstpart +} +\begingroup % localize \lccode change +\lccode`\~=`\^^M +\lowercase{% +\long\gdef\stripM#1$~#2#3\stripM#4{% + \ifx$#2% + \stripMa#1\stripMa#4% + \else + \stripMb#2#3\stripMb#4% + \fi +} +}% end lowercase +\lowercase{% +\long\gdef\stripMa $#1\stripMa#2{% + \stripMb#1$~$$\stripMb#2} +}% end lowercase +\lowercase{% +\long\gdef\stripMb#1~$#2#3\stripMb#4{% + \ifx$#2% + \stripMc#1\stripMc#4% + \else + \stripMd#1\stripMd#4% + \fi +} +}% end lowercase +\long\gdef\stripMc#1$#2\stripMc#3{% + \stripMd#1\stripMd#3} +\long\gdef\stripMd#1\stripMd#2{#2{#1}} +\endgroup +\begingroup \lccode`\~=`\^^M +\lowercase{% +\gdef\stripcontrolMs#1{\xp@\stripM + \xp@$\the#1$~$$\stripM#1} +}% end lowercase +\lowercase{% +\gdef\addmenulines#1#2#3{% + \def ~##1~##2{% + #1\xp@{\the#1#2##1#3}% + \ifx\end##2\xp@\@gobbletwo\fi~##2}% + \edef\@tempa{\nx@~\the#1\nx@~}#1{}% + \@tempa\end} +}% end lowercase +\endgroup % restore lccode of ~ +\def\fxmenub#1#2#3#4#5{% + \stripcontrolMs\menufirstpart + \stripcontrolMs\menulastpart + \stripcontrolMs\menuchoices + \addmenulines\menuchoices\menuline\endmenuline + \actively\let\^^M\relax % needed for \xdef + \toks@{\long#1#4#5}% e.g. \xdef\foo##1##2 + \edef\@tempa{\the\menufirstpart}% + \ifx\@tempa\@empty + \let\nxa@\@gobble + \else + \addmenulines\menufirstpart + \menutopline\endmenuline + \let\nxa@\nx@ + \fi + \edef\@tempa{\the\menulastpart}% + \ifx\@tempa\@empty + \let\nxb@\@gobble + \else + \addmenulines\menulastpart + \menubotline\endmenuline + \let\nxb@\nx@ + \fi +\edef\@tempa{{#3\nx@#3#2% + \def#3\nx@#3\mesjtext{% + #3\nx@#3\menuprefix + \the\menufirstpart #3\nxa@#3\inmenuA + \the\menuchoices #3\nxb@#3\inmenuB + \the\menulastpart #3\nx@#3\menusuffix}% + #3\nx@#3\sendmesj + #3\nx@#3\menuprompt}}% + \toks2 \xp@{\@tempa}% + \edef\@tempa{\the\toks@\the\toks2 }% + \let\menutopline\relax \let\menuline\relax + \let\menubotline\relax \let\endmenuline\relax + \let\menunumber\relax + \@tempa % finally, execute the \gdef or \xdef + \endgroup % matches \mesjsetup done by \fxmenu +}% end \fxmenub +\def\fxmenu#1#2#{\xmesjsetup + \toks@{\fxmenub{\xdef}{\xmesjsetup}\nx@#1{#2}}% + \def\@tempa##1##{% + \def\@tempa####1####{% + \def\@tempa{\the\toks@}% + \afterassignment\@tempa \menulastpart}% + \afterassignment\@tempa \menuchoices}% + \afterassignment\@tempa \menufirstpart +} +\def\notyet#1{% + \errmessage{Not yet implemented: \string#1}} +\long\def\nmenu#1#2#3#4#5{\notyet\nmenu} +\long\def\nxmenu#1#2#3#4#5{\notyet\nxmenu} +\newtoks\optionstack +\let\curmenu\@empty +\let\estart\relax +\let\eend\relax +\def\pushoptions#1{% + \edef\pushtemp{\estart + \def\nx@\curmenu{\curmenu}% + \eend + \the\optionstack}% + \global\optionstack\xp@{\pushtemp}% + \edef\curmenu{\curmenu#1}% +} +\def\popoptions{% + \edef\@tempa{\the\optionstack}% + \ifx\@empty\@tempa + \errmessage{Can't pop empty stack + (\string\optionstack)}% + \else + \def\estart##1\eend##2\@nil{% + \global\optionstack{##2}% + \let\estart\relax##1}% + \the\optionstack\@nil + \fi +} +\fmesj\moptionX{Exiting . . .} +\def\repeatoption{% + \csname moption\curmenu\endcsname} +\def\moptionQ{\popoptions \repeatoption} +\fxmesj\badoptionmesj#1{% +?---I don't understand "#1".} +\def\optionexec#1{% + \if ?#1\relax \let\@tempa\moptionhelp + \else \if Q#1\relax + \ifx\curmenu\@empty \let\@tempa\moptionX + \else \let\@tempa\moptionQ \fi + \else \if X#1\relax \let\@tempa\moptionX + \else + \xp@\let\xp@\@tempa + \csname moption\curmenu#1\endcsname + \ifx\@tempa\relax + \badoptionmesj{#1}\let\@tempa\repeatoption + \else + \pushoptions{#1}% + \fi + \fi\fi\fi + \@tempa +} +\def\optionfileexec#1{\notyet\optionfileexec} +\def\xoptiontest#1{TT\fi + \begingroup \def\0{?}\def\1{Q}% + \def\2{q}\def\3{x}\def\4{X}% + \aftergroup\if\aftergroup T% + \ifx\0#1\aftergroup T% + \else\ifx\1#1\aftergroup T% + \else\ifx\2#1\aftergroup T% + \else\ifx\3#1\aftergroup T% + \else\ifx\4#1\aftergroup T% + \else \aftergroup F% + \fi\fi\fi\fi\fi + \endgroup +} +\fxmesj\menuhelpmesj{&\menuprefix% +A response of Q will usually send you back to % +the previous menu. +A response of X will get you entirely out of % +the menu system. +&\menusuffix% +Press the <Return> key ( Enter ) to continue: +} +\def\moptionhelp{% + \menuhelpmesj \readline{}\reply \repeatoption} +\def\moptionhelp{% + \menuhelpmesj \readline{}\reply \repeatoption} +\xp@\def\csname moption?\endcsname{% + \moptionhelp} +\def\specialhelp#1#2{% + \let\specialhelpreply=#1\def#1{?}\begingroup + \def\menuhelpmesj{\let#1\specialhelpreply + \promptxmesj{#2\ +Press <return> to continue:}\endgroup}% +} +\def\specialhelpreply{} +\def\lettermenu#1{% + \csname menu#1\endcsname + \readChar{Q}\reply \optionexec\reply +} +\restorecatcodes +%%% ==================================================================== +%%% @TeX-file{ +%%% filename = "listout.tex", +%%% version = "1.4r", +%%% date = "1994/12/02", +%%% time = "15:22:30 EST", +%%% author = "Michael Downes", +%%% address = "49 Weeks Street +%%% North Smithfield, RI 02986, USA", +%%% email = "mjd@math.ams.org (Internet)", +%%% checksum = "55045 5069 16082 147112", +%%% keywords = "tex, verbatim", +%%% abstract = "The purpose of this macro file is to print +%%% verbatim listings of arbitrary text files, fitting as much +%%% text per sheet of paper as possible. The default settings +%%% are for US letter size paper 8.5 x 11 inches, two `pages' +%%% per sheet, landscape mode, but extensive customization +%%% facilities are provided. To conserve even more paper, you +%%% should take advantage of any two-sided capabilities your +%%% printer may happen to have.", +%%% docstring = "The checksum field above contains a CRC-16 +%%% checksum as the first value, followed by the equivalent of +%%% the standard UNIX wc (word count) utility output of lines, +%%% words, and characters. This is produced by Robert Solovay's +%%% checksum utility.", +%%% } +%%% ==================================================================== +\localcatcodes{\@{11}\~{13}\"{12}\:{12}} +\def\xmeaning#1{\xp@\xmeaningtrim\meaning#1} +\def\xmeaningtrim#1->{} +\def\TRUE{TT} +\def\FALSE{TF} +\def\@empty{} +\def\@iden#1{#1} +\def\datesepchar{ } +\let\keepleadingzeros\FALSE +\def\twodigits#1{\ifnum#1<10 0\fi + \xp@\@iden\xp@{\number#1}} +\edef\themonth{\number\month} +\edef\theday{\number\day} +\edef\theyear{\number\year} +\edef\yearmodC{\xp@\@gobbletwo\number\year} +\def\Jan{January} \def\Feb{February} +\def\Mar{March} \def\Apr{April} +\def\May{May} \def\Jun{June} +\def\Jul{July} \def\Aug{August} +\def\Sep{September} \def\Oct{October} +\def\Nov{November} \def\Dec{December} +\def\datesetup{% + \edef\themonthname{% + \ifcase\month ?% case 0---THIS CAN'T HAPPEN + \or\Jan\or\Feb\or\Mar\or\Apr\or\May\or\Jun + \or\Jul\or\Aug\or\Sep\or\Oct\or\Nov\or\Dec + \else ?\fi}% + \def\do##1##2##3##4\od{##1##2##3}% + \edef\themon{\xp@\do\themonthname\od}% + \let\theMON\themon \changecase\uppercase\theMON + \if\keepleadingzeros + \edef\themonth{\twodigits\month}% + \edef\theday{\twodigits\day}% + \else + \edef\themonth{\number\month}% + \edef\theday{\number\day}% + \fi +} +\datesetup +\def\dateA{% + \theyear\datesepchar\themonth\datesepchar\theday} +\def\dateB{% + \yearmodC\datesepchar\themonth\datesepchar\theday} +\def\dateC{% + \themonth\datesepchar\theday\datesepchar\yearmodC} +\def\dateD{% + \themonth\datesepchar\theday\datesepchar\theyear} +\def\dateE{% + \theday\datesepchar\themon\datesepchar\yearmodC} +\def\dateF{% + \theday\datesepchar\themon\datesepchar\theyear} +\def\dateG{% + \theday\datesepchar\theMON\datesepchar\yearmodC} +\def\dateH{% + \theday\datesepchar\theMON\datesepchar\theyear} +\def\dateI{% + \themonthname\space\number\day, \theyear} +\def\dateJ{% + \theday\datesepchar\themonthname\datesepchar\theyear} +\def\todaysdate{\dateJ} +\count@=\time \divide\count@ 60 +\edef\thehour{\twodigits\count@} +\multiply\count@ -60 \advance\count@\time +\edef\theminute{\twodigits\count@} +\def\ampmpunct{.} +\count@=\thehour\relax +\ifnum\count@>11 \def\ampm{p}% + \ifnum\count@>12 + \begingroup \advance\count@ -12 + \aftergroup\edef\aftergroup\thehourmodtwelve + \aftergroup{\xp@ + \endgroup \number\count@}% + \else + \edef\thehourmodtwelve{12}% + \fi +\else + \def\ampm{a}% + \ifnum\count@=0 \count@=12 \fi + \edef\thehourmodtwelve{\number\count@}% +\fi +\let\AMPM\ampm \changecase\uppercase\AMPM +\def\midnoon#1{\ifnum\time=0 midnight\else + \ifnum\time=720 noon\else#1\fi\fi} +\def\timesepchar{:} +\def\timeA{\thehour\theminute} +\def\timeB{\thehour\timesepchar\theminute} +\def\timeC{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\ampm m}} +\def\timeD{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\ampm\ampmpunct m\ampmpunct}} +\def\timeE{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\AMPM M}} +\def\timeF{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\AMPM\ampmpunct M\ampmpunct}} +\def\nowtime{\timeB} +\chardef\curcol=1 +\chardef\totalcols=2 +\countdef\firstpageno=1 +\countdef\lastpageno=2 +\newbox\prevcolsbox +\newdimen\paht \newdimen\pawd +\newdimen\fullwd +\newdimen\colwd +\let\dependentcolwd\TRUE +\newdimen\leftmargin +\newdimen\rightmargin +\let\dependentrightmargin\TRUE +\def\computerfc{\relax \rightmargin=\leftmargin + \computefc } +\def\computefc{\fullwd=\pawd + \advance\fullwd-\leftmargin + \advance\fullwd-\rightmargin + \colwd\fullwd + \advance\colwd \intercolspace + \divide\colwd \totalcols + \advance\colwd -\intercolspace + \edef\columnwidth{\the\colwd}% +} +\def\computefr{\fullwd\colwd + \advance\fullwd \intercolspace + \multiply\fullwd \totalcols + \advance\fullwd -\intercolspace + \rightmargin\pawd + \advance\rightmargin-\leftmargin + \advance\rightmargin-\fullwd +} +\newdimen\colht +\newdimen\intercolspace \newdimen\overrun +\newdimen\runheadht \newdimen\runfootht +\newdimen\bottommargin \newdimen\topmargin +\def\computebc{\bottommargin=\topmargin \computec} +\def\computec{% + \colht\paht \advance\colht -\topmargin + \advance\colht -\bottommargin + \advance\colht -\runheadht + \advance\colht -\runfootht + \roundcolht + \bottommargin\paht + \advance\bottommargin -\topmargin + \advance\bottommargin -\colht +} +\def\roundcolht{% + \advance\colht .5\baselineskip + \divide\colht\baselineskip + \edef\columnheight{\number\colht\space lines}% + \multiply\colht\baselineskip + \advance\colht\topskip + \advance\colht -\baselineskip +} +\let\dependentcolht\TRUE +\let\dependentbottommargin\TRUE +\def\computeb{% + \roundcolht + \bottommargin\paht + \advance\bottommargin -\topmargin + \advance\bottommargin -\colht +} +\ifx\UndEFiNed\pageno \countdef\pageno=0 \fi +\def\pagenumber{[\number\pageno]\thinspace{% + \csname\pagenumberfont + \pagenumberfontsize\endcsname + \number\lastpageno}} +\let\landscape=\TRUE +\def\pagenumbermessage{% + \ifnum\totalcols>\@ne + \message{% +Printing `pages' \the\firstpageno--\the\lastpageno +\space on \if\landscape landscape \fi sheet +\the\pageno}% + \fi} +\def\Ncols{\relax + \ifnum\curcol=\totalcols + \pagenumbermessage + \shipout\hbox to\fullwd{% + \unhbox\prevcolsbox\curcolbox}% + \global\advance\pageno\@ne + \global\chardef\curcol \z@ + \ifnum\totalcols>\@ne + \global\advance\lastpageno \@ne + \global\firstpageno\lastpageno + \fi + \else + \global\setbox\prevcolsbox\hbox{% + \unhbox\prevcolsbox\curcolbox + \hskip\intercolspace plus1fil\relax}% + \ifnum\totalcols>\@ne + \global\advance\lastpageno \@ne + \fi + \fi + \edef\next{\global\mathchardef\curcol= + \ifcase\curcol + 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\or 9\or + 10\or 11\or 12\or 13\or 14\or 15\or 16\or + 17\or 18\or 19\or 20% + \else "7FFF\fi\relax + }% + \next +} +\newtoks\runhead \newtoks\runfoot +\def\loheadline#1{\relax + \if\ifdim#1=\colwd T\else + \ifnum\curcol=\@ne T\else F\fi\fi T% + \vbox to\runheadht{\rlap{\hbox to#1{% + \csname\runheadfont\runheadfontsize\endcsname + \the\runhead}}\vss}% + \nointerlineskip + \fi +} +\def\lofootline#1{\relax + \if \ifdim#1=\colwd T\else + \ifnum\curcol=1 T\else F\fi\fi T% + \nointerlineskip + \vbox to\runfootht{\vfil\rlap{\hbox to#1{% + \csname\runheadfont\runheadfontsize\endcsname + \the\runfoot}}\kern-\prevdepth + \vfilneg\vss}% + \fi +} +\def\setupheadlineandfootline{% + \gdef\hfwd{\colwd}% + \if\runheads + \setbox\z@\hbox{% + \csname\runheadfont\runheadfontsize\endcsname + \the\runhead}% + \ifdim\wd\z@>\colwd \gdef\hfwd{\fullwd}\fi + \fi + \if\runfeet + \setbox\z@\hbox{% + \csname\runfootfont\runfootfontsize\endcsname + \the\runfoot}% + \ifdim\wd\z@>\colwd \gdef\hfwd{\fullwd}\fi + \fi + \if\runheads + \if\runfeet + \gdef\curcolbox{\vtop{\loheadline\hfwd + \vbox to\vsize{\unvbox255 \vss}% + \lofootline\hfwd}}% + \else + \gdef\curcolbox{% + \vtop{\loheadline\hfwd \vtop{\unvbox255 }}}% + \fi + \else + \if\runfeet + \gdef\curcolbox{\vtop{\null\nointerlineskip + \vbox to\vsize{\unvbox255 \vss}% + \lofootline\hfwd}}% + \else + \gdef\curcolbox{% + \vtop{\null\unvbox255 }}% + \fi + \fi +} +\newbox\tableaderbox +\chardef\spacespertab=8 +\newdimen\tabwidth +\def\printtaba{% + \hfil\egroup + \setbox\z@\hbox{\unhbox\z@ \unskip}% + \dimen@\wd\z@ \divide\dimen@\tabwidth + \multiply\dimen@\tabwidth + \advance\dimen@\tabwidth + \advance\dimen@ -\wd\z@ + \setbox\z@\hbox to \hsize\bgroup \unhbox\z@ + \spacebreak\hbox to\dimen@{% + \leaders\copy\tableaderbox\hfil}% +} +\def\newfileprinttab{\printtaba + \message{% +Say, this file contains a tab character}% + \global\let\printtab\printtaba} +\let\printtab=\newfileprinttab +\newdimen\charwidth +\def\inittabs{% + \setbox\z@\hbox{m}\charwidth\wd\z@ + \tabwidth\spacespertab\charwidth + \ifcase\tabselect % case 0: blank tabs option. + \setbox\tableaderbox\hbox to\charwidth{}% + \or % case 1: dots option. + \setbox\tableaderbox\hbox to.2em{% + \hskip\z@ plus2\p@ minus3\p@ + \mathhexbox 201% \cdot character + \kern.1em }% + \or % case 2: dashed option. + \setbox\tableaderbox\hbox to.3em{% + \hskip-.1em plus2sp minus2sp% + \vrule width.25em height.25em\kern.15em }% + \or % case 3: hrule option. + \setbox\tableaderbox\hbox{% + \vrule width\charwidth height2\p@ depth-1.5\p@}% + \else % case 4: tiny TAB option. + \setbox\tableaderbox\hbox to.5em{\hss + \vbox to6\p@{% + \offinterlineskip\csname roman5\endcsname + \hbox to7\p@{T\hss}\vss + \hbox to7\p@{\hss\kern-.1em A\hss}\vss + \hbox to7\p@{\hss B}\kern-2\p@}% + \hss}% + \fi + \let\printtab\newfileprinttab + } +\def\tabstyle{\ifcase\tabselect blank space\or + dots\or dashed lines\or horizontal rules\else + tiny TABs\fi} +\newdimen\charboxsidekern +\charboxsidekern=.3pt +\newbox\charboxstrut +\def\characterbox#1{% + \hbox to.5em{\hss + \dimen@.22\p@ \dimen@ii -.11\p@ + \vrule width\dimen@ \kern\dimen@ii + \vbox{\hrule height\dimen@ + \kern\charboxsidekern + \hbox{\kern\charboxsidekern + #1\kern\charboxsidekern + \copy\charboxstrut}% + \dimen4 \prevdepth + \advance\dimen4 \charboxsidekern + \advance\dimen@ \dimen4 + \hrule depth\dimen@ height -\dimen4 + }% + \kern\dimen@ii\vrule width\dimen@\hss}} +\def\controlchara#1{% + \message{Warning: +Invisible control character, printing boxed letter}% + \characterbox{#1}% + \gdef\controlchar##1{% + \message{@}\characterbox{##1}}% +} +\def\controlchar{\controlchara} +\newtoks\controlcharassignments +\begingroup +\def\do#1{\count@=`#1 \next \do} +\def\next{\lccode`\~=\count@ \advance\count@ 64 + \ifnum\count@>127 \advance\count@ -128 \fi + \lccode`\.=\count@ + \lowercase{\let~\relax + \global\controlcharassignments\xp@{% + \the\controlcharassignments + \def~{\controlchar{.}}}}% +} +\xp@\do\controlchars{a \@gobbletwo} +\endgroup +\def\unknownchara{% + \xmesj{Warning: Unspecified character + (system-dependent interpretation);\ + printing question mark instead}% + \characterbox{?}% + \gdef\unknownchar{\message{?}\characterbox{?}}% +} +\def\unknownchar{\unknownchara} +\def\eightbitaction{B} +\newtoks\highASCIIassignments +\newtoks\highBSCIIassignments +\highASCIIassignments{% + \def\do{\catcode\count@=12 \advance\count@\@ne + \ifnum\count@>\@cclv \expandafter\@gobble\fi\do}% + \count@=128 \do} +\begingroup +\def\do{% + \global\catcode\count@\active + \lccode`\~\count@ + \lowercase{\global\highBSCIIassignments + \xp@{\the\highBSCIIassignments + \def~{\unknownchar}}}% + \ifnum\count@<255\relax + \advance\count@ 1\relax + \xp@\do % tail recursion + \fi} +\count@=128\relax \do \endgroup +\def\thisfilename{??} +\let\printtitles=\TRUE +\def\@dogobble#1\do{} +\def\nonttfont#1{% + \def\do##1{\mathcode`##1`##1 \do}% + \xp@\do\otherchars{.`.\relax \@dogobble}% + \mathcode`\<"268 \mathcode`\>"269 + \mathcode`\\"26E \mathcode`\_"8000 + \mathcode`\{"266 \mathcode`\|"26A + \mathcode`\}"267 \mathcode`\~"218 + \mathcode`\""8000 + \actively\def\_{% + \leavevmode\kern.06em\vbox{% + \hrule width.4em height.06em}}% + \actively\def\"{^{\prime\prime}}% + \textfont\z@ + \csname\titlefont\titlefontsize\endcsname + \everymath{}\mathsurround\z@ + $\fam\z@#1$% +} +\escapechar=-1 +\edef\DOSdirsepchar{\string\\} +\escapechar=`\\ +\def\Macintoshdirsepchar{:} +\def\Unixdirsepchar{/} +\xp@\def\csname VAX/VMSdirsepchar\endcsname{]} +\def\chopname#1{% + \edef\dirsepchar{% + \csname\systemtype dirsepchar\endcsname}% + \edef\@tempa{% + \def\nx@\do####1\dirsepchar}% + \@tempa + ##2{% + \toks@\xp@{\next@}% + \ifx\end##2% then just add ##1 at the end + \edef\next@{\the\toks@##1}% + \else + \edef\next@{\the\toks@##1% + \dirsepchar\nx@\allowbreak}% + \afterfi\do##2% + \fi + }% + \edef\@tempa{\toks@{}\def\nx@\next@{}% + \nx@\do#1\dirsepchar\nx@\end}% + \@tempa + \let#1\next@ + \ifx\@empty\dirprefix + \else + \edef#1{\xmeaning\dirprefix\allowbreak#1}% + \fi +} +\def\printtitle{% + \bigskip + \centerline{% + \csname\titlefont\titlefontsize\endcsname + \chopname\thisfilename + \ifdim\fontdimen3\font=\z@ + \csname\titlecase\endcsname + \xp@{\thisfilename}% + \else + \csname\titlecase\endcsname + \xp@{\xp@ + \nonttfont\xp@{\thisfilename}}% + \fi + }% end \centerline + \if S\newfileoption \smallskip + \else\bigskip\fi +} +\def\newfileoption{P} +\def\newfileS{% + \dimen@\pagegoal \advance\dimen@-\pagetotal + \ifdim\dimen@<3\baselineskip + \xp@\eject\fi +} +\def\newfileC{\vfil\eject} +\def\newfileP{% + \vfil\eject + \loop + \ifnum\curcol>\@ne + \hbox to\colwd{% + \vrule width\z@ depth\vsize\hfil}% + \eject + \repeat +} +\def\newfileR{\vfil\eject + \ifnum\curcol=\@ne + \hbox to\colwd{% + \vrule width\z@ depth\vsize\hfil}% + \xp@\eject + \fi +} +\newcount\linenumberfreq \linenumberfreq=1 +\newcount\linecount +\newcount\linesubcount +\def\printlinenumber{\llap{% + \global\advance\linecount\@ne + \global\advance\linesubcount\@ne + \ifnum\linesubcount=\linenumberfreq + \lnfnt \the\linecount\space + \global\linesubcount\z@ + \fi +}}% +\def\spacebreak{} +\def\markedbreak{\penalty\z@} +\let\noextralinebreaks=\TRUE +\def\newunnumberedline{\hskip\rightskip \egroup + \box\z@ \controlLbreak + \setbox\z@\hbox to\hsize\bgroup}% +\def\newnumberedline{% + \newunnumberedline\printlinenumber}% +\def\unnumberedbreakingline{\relax + \ifnum\lastpenalty=\@ne \null\fi + \hskip\rightskip\egroup + \hfuzz \p@ + \noindent\unhbox\z@ % + {\hangindent1em + \parfillskip\z@ plus1fil \endgraf}% + \hfuzz\maxdimen + \controlLbreak + \setbox\z@\hbox to\hsize\bgroup \penalty\@ne +}% +\def\numberedbreakingline{% + \unnumberedbreakingline\printlinenumber} +\lowercase{\let\@sptoken= } % +\let\CR\newunnumberedline +\def\CRSPsetup{% + \setupbreakingchars + \if\noextralinebreaks + \overrun\rightmargin + \actively\let\ = \@sptoken\relax + \if\linenumbers + \let\CR\newnumberedline + \else + \let\CR\newunnumberedline + \fi + \else + \actively\edef\ {\spacebreak\space}% + \if\linenumbers + \let\CR\numberedbreakingline + \else + \let\CR\unnumberedbreakingline + \fi + \fi + \actively\let\^^M\CR + \rightskip\z@ plus\hsize minus\overrun + \parfillskip\z@skip +} +\def\listout#1{\endgraf + \begingroup + \listoutsetup + \gdef\thisfilename{#1}% + \xdef\thisfilename{\xmeaning\thisfilename}% + \if\printtitles \printtitle \fi + \listoutmoresetup + \CRSPsetup + \hfuzz\maxdimen + \setbox\z@\hbox to\hsize\bgroup \penalty\@ne + \input#1 \hfil\egroup + \hfuzz\p@ + \penalty0 % + \csname newfile\newfileoption\endcsname + \ifvoid\prevcolsbox + \else + \savelistoutimage + \fi + \endgroup } +%% Restore the previous output routine. Interestingly, +%% \cw{the}\cw{output} returns an extra pair of braces +%% (as hinted at in the \tex/book); so the extra step +%% with \cw{toks@} here is slightly better than simply +%% \cw{global}\cw{output}{\cw{the}\cw{output}}. +%%\showthe\output +\def\savelistoutimage{% + \xdef\listoutimage{% + \let\nx@\landscape% + \if\landscape\nx@\TRUE + \else\nx@\FALSE\fi + \pawd\the\pawd \paht\the\paht + \topmargin\the\topmargin + \bottommargin\the\bottommargin + \leftmargin\the\leftmargin + \rightmargin\the\rightmargin + \normalbaselineskip\the\normalbaselineskip + \normalbaselines + \mathchardef\curcol\number\curcol\relax + \chardef\totalcols\number\totalcols\relax + \colwd\the\colwd \colht\the\colht + \fullwd\the\fullwd + \intercolspace\the\intercolspace + \overrun\the\overrun + \def\nx@\todaysdate{\todaysdate}% + \def\nx@\nowtime{\nowtime}% + \def\nx@\pagenumberfont{\pagenumberfont}% + \def\nx@\pagenumberfontsize{% + \pagenumberfontsize} + \pageno\the\pageno + \lastpageno\the\lastpageno + \firstpageno\the\firstpageno + \def\nx@\hfwd{\hfwd}% + \def\nx@\thisfilename{\thisfilename}% + \let\nx@\runheads% + \if\runheads\nx@\TRUE + \else\nx@\FALSE\fi + \runhead{\the\runhead}% + \def\nx@\runheadfont{\runheadfont}% + \def\nx@\runheadfontsize{% + \runheadfontsize}% + \runheadht\the\runheadht + \let\nx@\runfeet% + \if\runfeet\nx@\TRUE + \else\nx@\FALSE\fi + \runfoot{\the\runfoot}% + \def\nx@\runfootfont{\runfootfont}% + \def\nx@\runfootfontsize{% + \runfootfontsize}% + \runfootht\the\runfootht + \hoffset\the\hoffset \voffset\the\voffset + \relax + }% +} +\fxmesj\reportlayout{ +Using paper size &\the&\pawd x &\the&\paht% + (&\paperwidth x &\paperheight), +&\number&\totalcols columns, intercolumnspace% + = &\the&\intercolspace, +column width = &\the&\colwd, column height% + = &\the&\colht, +top margin = &\the&\topmargin, left margin% + = &\the&\leftmargin. +} +\def\listoutsetup{% + \output{\Ncols}% + \loadfonts + \csname\mainfont\mainfontsize\endcsname + \xp@\let\xp@\lnfnt + \csname\linenumberfont + \linenumberfontsize\endcsname + \normalbaselines + \if\dependentcolht + \if\dependentbottommargin \computebc + \else \computec\fi + \else + \computeb + \fi + \vsize\colht + \parskip \z@\relax + \if\dependentcolwd + \if\dependentrightmargin \computerfc + \else \computefc \fi + \else + \computefr + \fi + \hsize\colwd + \parindent\z@ + \ifdim\overfullrule>\z@ \overfullrule 2\p@\fi + \setupheadlineandfootline + \datesetup + \voffset\m@ne truein \hoffset\voffset + \advance\voffset\topmargin \advance\hoffset\leftmargin + \setbox\charboxstrut\hbox{% + \vrule height.5emwidth\z@}% + \inittabs + \clubpenalty\@M \widowpenalty\@M + \count@12\relax + \def\do##1{\catcode`##1\count@ \do}% + \xp@\do\otherchars{a11 \@gobbletwo}% + \count@\active + \xp@\do\controlchars{a11 \@gobbletwo}% + \the\controlcharassignments + \global\let\controlchar\controlchara + \if L\controlLaction + \actively\let\^^L\linespaceL + \else + \if N\controlLaction + \actively\let\^^L\ejectL + \fi + \fi + \the\csname high\eightbitaction SCIIassignments\endcsname + \global\let\unknownchar\unknownchara + \actively\def\`{\kern\z@`}% + \hfuzz\p@ +} +\def\linespaceL{\message{Found a ^L character}\CR} +\def\ejectL{% + \message{Found a ^L character}% + \gdef\controlLbreak{\eject}\CR\global\let\controlLbreak\relax +} +\let\controlLbreak\relax +\def\controlLaction{N} +\actively\let\^^L=\ejectL +\def\listoutmoresetup{% + \global\linecount\z@ \global\linesubcount\z@ + \ifnum\totalcols>\@ne + \global\firstpageno\@ne + \global\lastpageno\@ne + \fi + \relax + \frenchspacing + \global\let\printtab\newfileprinttab + \actively\def\^^I{\printtab}% + \langnohyphens +} +\def\DVImesj{} +\fxmesj\landscapereminder{% +********************************************% +*********************** +* REMINDER: print in LANDSCAPE mode % + * +********************************************% +***********************} +\def\listoutfinish{% + \ifvoid\prevcolsbox + \else + \wlog{Clearing out previous file}% + \begingroup + \listoutimage \output{\Ncols}% + \def\newfileoption{P}% + \hbox to\colwd{}% + \csname newfile\newfileoption\endcsname + \DVImesj + \if\landscape + \landscapereminder + \fi + \endgroup + \fi +} +\def\xfont#1={% + \xp@\font\csname#1\endcsname=} +\def\ftypewriter{cmtt} +\def\fbold{cmbx} +\def\froman{cmr} +\def\fitalic{cmti} +\def\fsansserif{cmss} +\def\loadfont#1#2{% + \relax\ifnum#2>100 \loadscaledfont{#1}{#2}% + \else + \global\xfont#1#2=\csname f#1\endcsname + \ifnum#2=14 10 scaled\magstep2 + \else\ifnum#2=12 10 scaled\magstep1 + \else\ifnum#2=11 10 scaled\magstephalf + \else#2\fi\fi\fi + \relax + \fi +} +\def\loadscaledfont#1#2{\global\xfont#1#2=#1 scaled #2\relax} +\loadfont{typewriter}{8} % for main text +\loadfont{bold}{10} % for titles +\loadfont{roman}{5} % for line numbers +\loadfont{roman}{6} % for running heads +\def\mainfont{typewriter} +\def\mainfontsize{8} +\csname\mainfont\mainfontsize\endcsname +\def\titlefont{bold} +\def\titlefontsize{10} +\def\linenumberfont{typewriter} +\def\linenumberfontsize{8} +\def\pagenumberfont{bold} +\def\pagenumberfontsize{7} +\def\runheadfont{roman} +\def\runheadfontsize{7} +\def\runfootfont{roman} +\def\runfootfontsize{7} +\def\loadfonts{\relax + \xp@\ifx\csname\mainfont\mainfontsize\endcsname\relax + \loadfont\mainfont\mainfontsize + \fi + \xp@\ifx\csname\pagenumberfont + \pagenumberfontsize\endcsname\relax + \loadfont\pagenumberfont\pagenumberfontsize + \fi + \if\printtitles + \xp@\ifx\csname\titlefont + \titlefontsize\endcsname\relax + \loadfont\titlefont\titlefontsize + \fi + \fi + \if\linenumbers + \xp@\ifx\csname\linenumberfont + \linenumberfontsize\endcsname\relax + \loadfont\linenumberfont\linenumberfontsize + \fi + \fi + \if\runheads + \xp@\ifx\csname\runheadfont + \runheadfontsize\endcsname\relax + \loadfont\runheadfont\runheadfontsize + \fi + \fi + \if\runfeet + \xp@\ifx\csname\runfootfont + \runfootfontsize\endcsname\relax + \loadfont\runfootfont\runfootfontsize + \fi + \fi +} +\tracingstats=1 +\ifx\undefined\language + \def\langnohyphens{\hyphenchar\font\m@ne} +\else + \xp@\ifx\csname newlanguage\endcsname\relax + \def\langnohyphens{\language\@cclv} + \else + \csname newlanguage\endcsname + \nohyphenslanguage + \def\langnohyphens{% + \language\nohyphenslanguage}% + \fi +\fi +\def\setupbreakingchars{% + \ifx\breakingchars\@empty + \ifx\spacebreak\@empty + \let\noextralinebreaks\TRUE + \else + \let\noextralinebreaks\FALSE + \fi + \else + \let\noextralinebreaks\FALSE + \def\do##1{\ifx\end##1\else + \xp@\actively\xp@ + \def\csname##1\endcsname{##1\markedbreak}% + \xp@\do\fi}% + \xp@\do\breakingchars\end + \let\spacebreak\markedbreak + \fi + \exhyphenpenalty\@M +} +\def\iwlos#1{\immediate\write#1} +\storexmesj\losfirstline{% +\% &\losname.los &\todaysdate &\nowtime +\% Option settings for listout.tex.}% +\def\addmonth#1{% + \toks4 \xp@{#1}% + \edef\next{\the\toks2 + \string\def\string#1{\the\toks4 }}% + \toks2 \xp@{\next}% +} +\begingroup +\endlinechar13 \catcode\endlinechar13 +\gdef\logoptionsettings#1{\begingroup% + \newlinechar13\relax\actively\let\^^M\relax% + \toks2 {}% + \addmonth\Jan \addmonth\Feb \addmonth\Mar% + \toks2 \xp@{\the\toks2\relax + }% + \addmonth\Apr \addmonth\May \addmonth\Jun% + \toks2 \xp@{\the\toks2\relax + }% + \addmonth\Jul \addmonth\Aug \addmonth\Sep% + \toks2 \xp@{\the\toks2\relax + }% + \addmonth\Oct \addmonth\Nov \addmonth\Dec% + \iwlos{#1}{% + \losfirstline + \the\toks2\relax + }% + \iwlos{#1}{% + \string\let\string\landscape=% + \if\landscape\string\TRUE + \else\string\FALSE\fi + \string\pawd=\the\pawd + \string\def\string\paperwidth{\paperwidth} + \string\paht=\the\paht + \string\def\string\paperheight{\paperheight} + \string\topmargin=\the\topmargin + \string\bottommargin=\the\bottommargin + \string\leftmargin=\the\leftmargin + \string\rightmargin=\the\rightmargin + \string\normalbaselineskip=% + \the\normalbaselineskip\string\relax + \string\def\string\mainfontsize{\mainfontsize} + \string\def\string\mainfont{\mainfont} + \string\chardef\string\totalcols=% + \number\totalcols\string\relax + \string\colwd=\the\colwd + \string\def\string\columnwidth{\columnwidth} + \string\let\string\dependentcolwd=% + \if\dependentcolwd\string\TRUE + \else\string\FALSE\fi + \string\let\string\dependentrightmargin=% + \if\dependentrightmargin\string\TRUE + \else\string\FALSE\fi + \string\colht=\the\colht + \string\def\string\columnheight{\columnheight} + \string\let\string\dependentcolht=% + \if\dependentcolht\string\TRUE + \else\string\FALSE\fi + \string\let\string\dependentbottommargin=% + \if\dependentbottommargin\string\TRUE + \else\string\FALSE\fi + \string\intercolspace=\the\intercolspace + \string\overrun=\the\overrun + \string\fullwd=\the\fullwd + }% + \iwlos{#1}{% + \string\def\string\newfileoption{% + \newfileoption} + \string\let\string\printtitles=% + \if\printtitles\string\TRUE + \else\string\FALSE\fi + \string\def\string\titlefont{\titlefont} + \string\def\string\titlefontsize{% + \titlefontsize} + \string\def\string\titlecase{\titlecase} + \string\def\string\datesepchar{\datesepchar} + \string\def\string\todaysdate{% + \xp@\string\todaysdate} + \string\def\string\nowtime{% + \xp@\string\nowtime} + \string\def\string\timesepchar{\timesepchar} + \string\def\string\ampmpunct{\ampmpunct} + \string\let\string\keepleadingzeros=% + \if\keepleadingzeros\string\TRUE + \else\string\FALSE\fi + \string\def\string\linenumberfontsize{% + \linenumberfontsize} + \string\def\string\linenumberfont{% + \linenumberfont} + \string\let\string\linenumbers=% + \if\linenumbers\string\TRUE + \else\string\FALSE\fi + \string\linenumberfreq=% + \number\linenumberfreq\string\relax + \string\def\string\pagenumberfont{% + \pagenumberfont} + \string\def\string\pagenumberfontsize{% + \pagenumberfontsize} + \string\let\string\runheads=% + \if\runheads\string\TRUE + \else\string\FALSE\fi + \string\runhead={\the\runhead} + \string\def\string\runheadfont{\runheadfont} + \string\def\string\runheadfontsize{% + \runheadfontsize} + \string\runheadht=\the\runheadht + \string\let\string\runfeet=% + \if\runfeet\string\TRUE\else\string\FALSE\fi + \string\runfoot={\the\runfoot} + \string\def\string\runfootfont{\runfootfont} + \string\def\string\runfootfontsize{% + \runfootfontsize} + \string\runfootht=\the\runfootht + \string\def\string\spacebreak{\spacebreak} + \string\def\string\breakingchars{% + \breakingchars} + \string\let\string\noextralinebreaks=% + \if\noextralinebreaks\string\TRUE + \else\string\FALSE\fi + \string\def\string\controlLaction{\controlLaction} + \string\def\string\eightbitaction{\eightbitaction} + \string\def\string\systemtype{\systemtype} + \string\def\string\losdir{\losdir} + \string\storemesj\string\dirprefix{\dirprefix} + \string\chardef\string\spacespertab=% + \number\spacespertab\string\relax + \string\chardef\string\tabselect=% + \number\tabselect\string\relax +}\endgroup}% +\endgroup% percent to avoid catcode 12 endlinechar +\def\Jan{January}\def\Feb{February}\def\Mar{March}\relax +\def\Apr{April}\def\May{May}\def\Jun{June}\relax +\def\Jul{July}\def\Aug{August}\def\Sep{September}\relax +\def\Oct{October}\def\Nov{November}\def\Dec{December}\relax +\let\landscape=\TRUE +\pawd=794.96999pt +\def\paperwidth{11in} +\paht=614.295pt +\def\paperheight{8.5in} +\topmargin=18.06749pt +\bottommargin=19.22751pt +\leftmargin=21.68121pt +\rightmargin=21.68121pt +\normalbaselineskip=10.0pt\relax +\def\mainfontsize{10} +\def\mainfont{typewriter} +\chardef\totalcols=2\relax +\colwd=369.38373pt +\def\columnwidth{369.38373pt} +\let\dependentcolwd=\TRUE +\let\dependentrightmargin=\TRUE +\colht=577.0pt +\def\columnheight{64 lines} +\let\dependentcolht=\TRUE +\let\dependentbottommargin=\TRUE +\intercolspace=12.0pt +\overrun=21.68121pt +\fullwd=751.60756pt +\def\newfileoption{P} +\let\printtitles=\TRUE +\def\titlefont{bold} +\def\titlefontsize{10} +\def\titlecase{none} +\def\datesepchar{/} +\def\todaysdate{\dateA} +\def\nowtime{\timeB} +\def\timesepchar{:} +\def\ampmpunct{.} +\let\keepleadingzeros=\TRUE +\def\linenumberfontsize{5} +\def\linenumberfont{roman} +\let\linenumbers=\FALSE +\linenumberfreq=1\relax +\def\pagenumberfont{bold} +\def\pagenumberfontsize{7} +\let\runheads=\TRUE +\runhead={\todaysdate \space \nowtime \space \hfil + \thisfilename \space \hfil \pagenumber } +\def\runheadfont{roman} +\def\runheadfontsize{7} +\runheadht=24.0pt +\let\runfeet=\FALSE +\runfoot={} +\def\runfootfont{roman} +\def\runfootfontsize{6} +\runfootht=24.0pt +\def\spacebreak{\penalty \z@ } +\def\breakingchars{} +\let\noextralinebreaks=\FALSE +\def\controlLaction{N} +\def\systemtype{DOS} +\def\losdir{} +\storemesj\dirprefix{} +\chardef\spacespertab=8\relax +\chardef\tabselect=1\relax +\def\losname{default} +\edef\losfile{\losdir\losname.los } +\openin15=\losfile \relax +\ifeof15 \closein15 \expandafter\@gobbletwo +\else +\immediate\write16{Reading option settings from `\losname.los' . . .} +\closein15 \fi +\input\losfile % try entering "nul" if file not found +\datesetup +\normalbaselines +\ifx\undefined\interactive + \def\next{listout}% + \edef\next{\xmeaning\next}% + \edef\jobname{\jobname}% + \ifx\next\jobname + \let\interactive\TRUE + \else + \let\interactive\FALSE + \fi +\else + \let\interactive\TRUE +\fi +\if\interactive +\else \restorecatcodes \endinput \fi +\def\printfiles{%\reportlayout + \mesj{OK, let's print some files.}% + \begingroup + \listoutsetup \let\listoutsetup\relax + \fileloop + \endgroup + \listoutfinish + \csname \string @\string @end\endcsname + \end +}% +\newcount\numberoffiles +\def\fileloop{% + \promptmesj{!File name? (<return> to stop): }% + \readline{}\reply + \ifx\reply\@empty + \else + \global\advance\numberoffiles 1 \relax + \afterfi + \xp@\listout\xp@{\reply}% + \fileloop + \fi +} +\fxmesj\DVImesj{% +******************************************************************* +* DVI file name is \jobname.dvi * +*******************************************************************} +\mesj{ +:--------------------------------------------------------------------- +: This is listout.tex: a tool for printing out `verbatim' listings of +: text files with reasonably robust, and customizable, handling of +: overlong lines, tab characters and other special characters, number +: of columns, font size/line spacing, et cetera. +:--------------------------------------------------------------------- +: For additional information (e.g., about noninteractive use), or to +: change option settings, enter +: m or M +: to enter the listout.tex menu system. Otherwise just press the +: <return> key to continue: +:} +\message{:?: } +\readChar{X}\reply +\if M\reply \else\xp@\printfiles\fi +\message{Starting up the listout.tex menu system . . .} +\storexmesj\menuprefix{ +====================================================================== +} +\storexmesj\menusuffix{ + Q Quit X Exit ? Help +====================================================================== +} +\storexmesj\inmenuA{ +} +\storexmesj\inmenuB{ +} +\fxmesj\menuhelpmesj{% +====================================================================== +--- <return> means the carriage return, or `Enter', key. +--- When selecting items from a menu with letter labels, you can enter +your choice in lowercase or uppercase. +--- A prompt that asks for `TeX units' requires in response a +measurement using the units recognized by TeX, for example + + cm mm in pt pc dd cc + +--- A response of Q will usually send you back to the previous menu. +--- A response of X will get you entirely out of the menu system. +====================================================================== +To continue, press the <return> key . . .} +\def\confirm#1{\xmesj{\ +* #1}} +\fmenu\mainmenu{ + MAIN MENU +}{ +A Action for new files L Line numbers +B Breaking lines M Margins +C Column width/height N Number of columns +D Date/time form O Orientation +E Expectoration P Paper size +F Font, line spacing R Running heads/feet +G General information S System info +H Heading/title for each file T Tab treatment +I Info about current settings V Various other things +}{} +\def\moption{\mainmenu \readChar{Q}\reply + \let\prevmenu\@empty \let\curmenu\@empty \optionexec\reply} +\fmenu\menuA#1{ +The various actions possible at the beginning of a new file are: +}{ +S Space (one line of blank space, but not a new column, + at the beginning of each new file) +C New column +P New page +R New page and right-hand column +}{ +These options are mutually exclusive. The currently selected option +is #1. See also option H in the main menu. +} +\def\moptionA{\menuA{\newfileoption}% + \readChar{Q}\reply \optionexec\reply} +\def\moptionAS{\def\newfileoption{S}% + \confirm{% + Each file will start immediately after the preceding file, with\ +* some intervening blank space.}% + \popoptions\moptionQ} +\def\moptionAC{\def\newfileoption{C}% + \confirm{% + Each file will start at the top of the next column.}% + \popoptions\moptionQ} +\def\moptionAP{\def\newfileoption{P}% + \confirm{% + Each file will start on a new page.}% + \popoptions\moptionQ} +\def\moptionAR{\def\newfileoption{R}% + \confirm{% + Each file will start on a new page, in the right-hand column.} + \popoptions\moptionQ} +\def\menuBtest{% + \ifx\spacebreak\@empty + \ifx\breakingchars\@empty +Long lines will not be broken.% + \else +Extra line breaks will be allowed after the characters\ +\ +\ \ \ \ \ \breakingchars\ + \ifdim\overrun=\z@ + \else\ +(with overrun of \the\overrun\space allowed).% + \fi + \fi + \else + \ifx\breakingchars\@empty +Extra line breaks will be allowed at spaces.% + \else +Extra line breaks will be allowed at spaces and\ +after the characters\ +\ +\ \ \ \ \ \breakingchars\ + \fi + \ifdim\overrun=\z@ + \else\ +(with overrun of \the\overrun\space allowed).% + \fi + \fi +} +\fxmenu\menuB{ +Files being printed sometimes contain unusually long lines. +You can choose the action that will be taken for overlong lines: +}{ +N No line breaking allowed +S Allow breaks at spaces only +C Allow line breaks at other characters +O Change the overrun amount +}{ +Current setting: &\menuBtest +} +\def\moptionB{\lettermenu{B}} +\def\moptionBS{% + \let\spacebreak\markedbreak \let\breakingchars\@empty + \overrun\rightmargin \let\noextralinebreaks\FALSE + \confirm{\menuBtest}\popoptions\moptionQ +} +\def\moptionBN{% + \let\spacebreak\@empty \let\breakingchars\@empty + \overrun=\rightmargin + \confirm{\menuBtest}\popoptions\moptionQ +} +\def\moptionBO{% + \promptmesj{Desired overrun value [TeX units] ? }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \overrun\reply\relax + \confirm{New overrun value = \the\overrun.}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\def\moptionBC{% + \xmesj{% +Enter a list of characters. Line breaks will be allowed after any\ +character in the list.\ +Note: if this list is nonempty breaks will be allowed at spaces,\ +even if you didn't include a space in the list.}% + \readline{}\breakingchars + \ifx\@empty\breakingchars + \else \let\spacebreak\markedbreak\fi + \let\noextralinebreaks\FALSE + \overrun=\rightmargin + \confirm{\menuBtest}% + \popoptions\moptionQ +} +\fxmenu\menuC{ +Column width is normally computed automatically, from the specified +paper width, number of columns, margins, and intercolumn space. +However, if you provide an explicit value for column width it will +be used and the right margin will be adjusted as necessary. +Similarly, column height is computed automatically from the +paper height and the top and bottom margins, unless you provide an +explicit value. +}{ +W Change column width +H Change column height +I Change intercolumn space +}{ +Current column width: &\columnwidth. +Current column height: &\columnheight. +Current intercolumn space: &\the&\intercolspace. +} +\def\moptionC{\lettermenu C} +\def\moptionCW{% + \xmesj{% +For width in characters, enter just a number; otherwise enter a\ +measurement using standard TeX units. To revert to automatic computing\ +of the column width, give an empty reply (i.e., just press <return>).}% + \message{Column width: }% + \readline{}\reply + \ifx\reply\@empty + \let\dependentcolwd\TRUE + \if\dependentrightmargin \computerfc \else \computefc \fi + \def\reply{A}% report new value through \moptionCWA + \fi + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \checkinteger\reply\count@ + \ifnum\count@=-\maxdimen + \else + \colwd.5em \multiply\colwd\count@\relax + \edef\columnwidth{\the\count@\space characters}% + \let\dependentcolwd\FALSE + \def\reply{A}% + \fi + \else + \colwd\dimen@ \let\columnwidth\reply \let\dependentcolwd\FALSE + \def\reply{B}% + \fi + \fi + \optionexec\reply +} +\def\moptionCWA{% + \confirm{Column width set to \columnwidth.}% + \popoptions\moptionQ} +\def\moptionCWB{% + \confirm{Column width set to \columnwidth\space (= \the\colwd)}% + \popoptions\moptionQ} +\def\moptionCH{% + \xmesj{% +For height in lines, enter just a number; otherwise enter a\ +measurement using standard TeX units. To revert to automatic computing\ +of the column height, give an empty reply (i.e., just press <return>).}% + \message{Column height: }% + \readline{}\reply + \ifx\reply\@empty + \let\dependentcolht\TRUE + \if\dependentbottommargin \computebc \else \computec \fi + \def\reply{A}% report new value through \moptionCWA + \fi + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \checkinteger\reply\count@ + \ifnum\count@=-\maxdimen + \else + \let\dependentcolht\FALSE + \colht\baselineskip \multiply\colht\count@ + \advance\colht -\baselineskip \advance\colht\topskip + \computeb + \edef\columnheight{\the\count@\space lines}% + \def\reply{A}% + \fi + \else + \colht\dimen@ \let\columnheight\reply + \let\dependentcolht\FALSE \computeb + \def\reply{B}% + \fi + \fi + \optionexec\reply +} +\def\moptionCHA{% + \confirm{Column height set to \columnheight.\ +* (Bottom margin adjusted to \the\bottommargin.)}% + \popoptions\moptionQ} +\def\moptionCHB{% + \confirm{Column height set to \columnheight\space (= \the\colht)\ +* (Bottom margin adjusted to \the\bottommargin.)}% + \popoptions\moptionQ} +\def\moptionCI{% + \promptmesj{Enter desired intercolumn space [TeX units]: }% + \readline{Q}\reply + \ifx\optiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \intercolspace=\dimen@ + \confirm{% +Intercolumn space set to \reply\space (= \the\intercolspace).}% + \if\linenumbers\ifdim\intercolspace<12\p@ + \confirm{\ +* Warning: small intercolumn space, might not be big enough\ +* for line numbers to fit ...}% + \fi\fi + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmenu\menuD{}{ +D Change date format +S Change separator character +Z &\if&\keepleadingzeros\.Omit&\else\.Add&\fi % +leading zeros in the day and month +T Change time format +}{ +Current date and time format is `&\todaysdate &\nowtime'. +} +\def\moptionD{\lettermenu D} +\fxmenu\menuDD{ +Date options: +}{ +A &\dateA +B &\dateB +C &\dateC +D &\dateD +E &\dateE +F &\dateF +G &\dateG +H &\dateH +I &\dateI +J &\dateJ +}{ +Current date format is &\todaysdate. +} +\def\moptionDD{\menuDD \readChar{Q}\reply + \count@=\xp@`\reply\relax + \ifnum\count@>64 \ifnum\count@<75 + \xp@\def\xp@\todaysdate\xp@{\csname date\reply\endcsname}% + \confirm{New date form: \todaysdate}% + \def\reply{Q}% + \fi\fi + \optionexec\reply +} +\def\moptionDS{\promptmesj{!% +Current separator character between the parts of a date is +`\datesepchar'.!% +New separator: }% + \readchar{}\reply + \if Q\reply + \confirm{Date separator char unchanged.}% + \else + \if ?\reply + \else + \if X\reply + \confirm{Date separator char unchanged.}% + \else + \let\datesepchar\reply + \confirm{New date format: \todaysdate.}% + \def\reply{Q}% + \fi + \fi + \fi + \optionexec\reply +} +\def\moptionDZ{% + \if\keepleadingzeros + \let\keepleadingzeros\FALSE + \edef\themonth{\number\month}\edef\theday{\number\day}% + \else + \let\keepleadingzeros\TRUE + \edef\themonth{\twodigits\month}\edef\theday{\twodigits\day}% + \fi + \confirm{Leading zeros will + \if\keepleadingzeros NOT \else \fi + be omitted in day and month numbers}% + \def\reply{Q}\optionexec\reply +} +\fxmenu\menuDT{ +Time format options: +}{ +A &\timeA (HoursMinutes, 24-hour cycle) +B &\timeB (Hours:Minutes, 24-hour cycle) +C &\timeC (12-hour cycle) +D &\timeD +E &\timeE +F &\timeF +}{ +Current time format is &\nowtime. +} +\def\moptionDT{\menuDT \readChar{Q}\reply + \if A\if B\reply A\else\if C\reply A\else\if D\reply A\else + \if E\reply A\else\if F\reply A\else\reply\fi\fi\fi\fi\fi + \xp@\def\xp@\nowtime\xp@{\csname time\reply\endcsname}% + \def\reply{Z}% + \fi + \optionexec\reply +} +\def\moptionDTZ{\confirm{New time format: \nowtime}% + \popoptions\moptionQ} +\fmenu\menuE{ +This option allows you to save all the current option settings in a +file for later reuse. If you use the file name `default.los' the saved +settings will be used as defaults for future runs. Or you can use +different file names to have multiple saved sets of option settings. +}{ +S Save settings +L Load saved settings from file +D Specify a default directory/folder for .los files +}{ +The last option allows you to specify a location if you want to +keep listout.tex and all its .los files in a particular directory or +folder. This works best if the given location is one searched +automatically by TeX (e.g., by being included in the `TeX inputs path'). +} +\def\moptionE{\lettermenu{E}} +\def\losname{default} +\def\losdir{} + +\def\lossorrymessage{\message{% +? Could not create `\losdir\losname.los'; +maybe there was a system problem.}} +\def\currentdir{} +\def\moptionES{\xmesj{\ +Enter the desired file name. The default name (if you just press the\ +<return> key) is `default'. A file extension `.los' will be added\ +automatically:}% + \readline{default}\reply + \edef\losname{\reply}% + \def\next##1.los##2##3\next{\ifx\relax##2\else + \def\losname{##1}\fi} + \xp@\next\losname.los\relax\next + \confirm{% +File name: `\losname.los' ---OK? If not, enter n or N to cancel:}% + \readChar{Y}\reply + \if Y\reply + \edef\losfirstline{\xp@\@gobble\string +\% Option settings for listout.tex, \todaysdate\space\nowtime}% + \immediate\openout15=\losdir\losname.los \relax + \logoptionsettings{15}% + \immediate\closeout15 \relax + \openin15=\losdir\losname.los \relax + \ifeof15 \lossorrymessage + \else \testlocation \fi + \closein15 \relax + \fi + \popoptions\moptionQ +} +\def\testlocation{% + \begingroup + \catcode`\%=12 \catcode`\\=12 \catcode\endlinechar=9 + \read15 to\next + \ifx\next\losfirstline + \confirm{% +New `\losname.los' file successfully created}% + \ifx\losdir\@empty + \testinputtable + \else + \message{% +(in location `\losdir')}% + \fi + \else + \lossorrymessage + \fi + \endgroup +} +\def\testinputtable{% + \actively\def\%##1@{% + \edef\next{\xp@\@gobble\string\%##1}% + \ifx\next\losfirstline + \else + \message{% +... but guess what: it seems to be inaccessible for \nx@\input by TeX% + }% + \fi + \endinput}% + \endlinechar`\@ \relax + \input\losname.los \relax +} +\def\moptionEL{\xmesj{\ +Enter the name of the desired option file:}% + \readline{}\reply + \ifx\@empty\reply + \else + \def\next##1.los##2##3\next{\ifx\relax##2\else + \def\reply{##1}\fi} + \xp@\next\reply.los\relax\next + \xmesj{\ +Attempting to load \reply.los . . .}% + \input\reply.los\space\relax + \fi + \def\reply{Q}\optionexec\reply +} +\def\moptionED{\xmesj{\ +Current location name is `\losdir'.\ +Enter a new location name (directory or folder or whatever, depending\ +on your system). For Unix or DOS, make sure you include the final\ +slash. (For DOS, use slashes instead of backslashes.) Just press\ +<return> if you want to leave the current location unchanged:}% + \readline{}\reply + \ifx\@empty\reply + \else + \let\losdir\reply + \confirm{Location name is now: `\losdir'}% + \fi + \def\reply{Q}\optionexec\reply +} +\fxmenu\menuF{}{ +F Change font +S Change font size +L Change line spacing +T Test font availability +N Add new font +}{ +Current settings: &\mainfont &\mainfontsize / &\the&\baselineskip. +} +\def\moptionF{\lettermenu F} +\fxmenu\genfontmenu{ +&\firstpart +Font choices: +}{ +R Roman +B Bold +I Italic +T Typewriter +S Sans serif +}{ +Current choice is `&\fonttoget'. +} +\def\getfont#1#2#3{% + \let\fonttoget#1\def\firstpart{#2}% + \genfontmenu \readChar{Q}\reply + \edef\next{\if R\reply roman% + \else\if B\reply bold% + \else\if I\reply italic% + \else\if S\reply sansserif% + \else\if T\reply typewriter% + \fi\fi\fi\fi\fi}% + \ifx\next\@empty + \else + \let#1\next \def\reply{Q}% + \confirm{#3 font is now `#1'.}% + \fi + \optionexec\reply +} +\def\moptionFF{\getfont\mainfont{% +Note: Font style `typewriter' is recommended for printing computer\ +program code verbatim because the character set of most non-typewriter\ +fonts lacks certain characters such as { } | \string~ and \\ .}% +{Main}} +\fmesj\wholepointsizes{ +Note: Currently only whole point sizes are supported; the fractional +part in a fractional point size will be ignored. If a font/size +combination is not available on your system there will be an error +message later on when we try to load the font. +}% +\def\getfontsize#1#2{\wholepointsizes + \mesj{Current #2 font size is #1.}% + \promptmesj{Desired font size? }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkinteger\reply\count@ + \ifnum\count@>\z@ + \edef#1{\the\count@}% + \confirm{New font size for #2: #1}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\def\moptionFS{\getfontsize\mainfontsize{main text}} +\def\moptionFL{\promptmesj{Desired line spacing [TeX units] ? }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@>\z@ + \normalbaselineskip\dimen@\relax \normalbaselines + \confirm{New line spacing: \the\normalbaselineskip}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmenu\menuFT{ +Font to test load? +}{ +M main font +T title font +L line number font +P page number font +H running head font +F running foot font +A all of the above +}{} +\def\moptionFT{\menuFT + \readChar{Q}\reply + \if M\reply + \testload\mainfont\mainfontsize + \def\reply{Q}% + \else\if T\reply + \testload\titlefont\titlefontsize + \def\reply{Q}% + \else\if L\reply + \testload\linenumberfont\linenumberfontsize + \def\reply{Q}% + \else\if P\reply + \testload\pagenumberfont\pagenumberfontsize + \def\reply{Q}% + \else\if H\reply + \testload\runheadfont\runheadfontsize + \def\reply{Q}% + \else\if F\reply + \testload\runfootfont\runfootfontsize + \def\reply{Q}% + \else\if A\reply + \testload\mainfont\mainfontsize + \testload\pagenumberfont\pagenumberfontsize + \testload\titlefont\titlefontsize + \testload\linenumberfont\linenumberfontsize + \testload\runheadfont\runheadfontsize + \testload\runfootfont\runfootfontsize + \def\reply{Q}% + \fi\fi\fi\fi\fi\fi\fi + \optionexec\reply +} +\def\testload#1#2{\loadfont#1#2\relax + \xp@\ifx\csname#1#2\endcsname\nullfont + \confirm{Unsuccessful font load...}% + \else + \confirm{Font successfully loaded.}% + \fi +} +\fxmesj\menuFN{ +To use a custom font you must give two pieces of information: the +name of the font metrics file (.tfm file), not including the .tfm +extension, and a magnification (using TeX's standard notation: 1000 = +100\%, 1200 = 120\%, ...). +} +\def\moptionFN{\menuFN + \promptmesj{OK, first give the font name: }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \let\mainfont\reply + \def\reply{Q}% + \promptmesj{Font magnification? [default=1000]: }% + \readline{1000}\reply + \if\xoptiontest\reply + \else + \checkinteger\reply\count@ + \ifnum\count@>100 % + \let\mainfontsize\reply + \def\reply{Q}% + \fi + \fi + \xmesj{\ +Attempting to load new font `\mainfont\ scaled \mainfontsize'; if you\ +get an error message, press RETURN to continue, and try again.\ + }% + \testload\mainfont\mainfontsize + \fi + \optionexec\reply +} +\fmesj\menuGa{ +: General information on a couple of subjects: +: +: ---Non-interactive usage: Create a driver file containing +: +: \input listout +: % Change options here, if desired +: \listout{first.file} +: \listout{second.file} +: ... +: \listoutfinish +: \end +: +: The \listoutfinish command is required to support the possibility +: where multiple files are printed running together without intervening +: page breaks. To find out how to change options, look at the file +: default.los. +: +: Press <return> to continue . . .} +\fmesj\menuGb{ +: ---Treatment of control characters and eight-bit characters: The +: default behavior is to assume no knowledge about the meaning of +: characters in the range 0--31 and 127--255, because depending on the +: source, the intended meaning of one of these characters in a given +: file can vary widely. And the default main font (cmtt) can't handle +: characters above 127 anyway. In order to preserve vertical alignment +: when printing with a monospace font (the usual case) control +: characters aren't printed as multicharacter sequences (e.g. ^^F), but +: as boxed letters. The first control character encountered in a file +: will generate a warning/explanatory message on screen. Similarly, +: characters above ASCII 126 are printed simply as boxed question +: marks. This behavior can be overridden by changing the main font to a +: 256-character font and choosing the 8-bit option in the V menu. +: +: Press <return> to continue . . .} + +\def\moptionG{\menuGa\readline{}\reply\menuGb\readline{}\reply \moptionQ} +\fxmenu\menuH{}{ +T Turn filename titles&\if&\printtitles off&\else on&\fi +F Change font of titles +S Change font size +C Change capitalization +}{ +Current settings: % +&\titlefont &\titlefontsize, capitalization = &\titlecase. +} +\def\moptionH{\lettermenu H} +\def\moptionHT{% + \if\printtitles \let\printtitles\FALSE + \else \let\printtitles\TRUE \fi + \confirm{% +The name of each file \if\printtitles WILL \else will NOT \fi +be printed as a title at the\ +* beginning of the file. +}% + \if\printtitles\else\popoptions\fi + \moptionQ +}% +\def\moptionHF{\getfont\titlefont{}{Title}} +\def\moptionHS{\getfontsize\titlefontsize{titles}} +\fxmenu\menuHC{ +Title capitalization choices: +}{ +N None +L Lowercase +U Uppercase +}{ +Current choice is &\titlecase. +} +\def\moptionHC{\menuHC \readChar{Q}\reply + \if L\reply + \def\titlecase{lowercase}% + \confirm{Capitalization is now: lowercase.}% + \def\reply{Q}% + \else\if U\reply + \def\titlecase{uppercase}% + \confirm{Capitalization is now: uppercase.}% + \def\reply{Q}% + \else\if N\reply + \def\titlecase{none}% + \confirm{Capitalization is now: none.}% + \def\reply{Q}% + \fi\fi\fi + \optionexec\reply} +\fxmesj\menuIa{ +Current option settings: +Orientation: &\if&\landscape landscape&\else portrait&\fi +Paper size: &\paperwidth x &\paperheight (&\the\pawd x &\the\paht) +Margins: Top &\the\topmargin, bottom &\the\bottommargin, + left &\the\leftmargin, right &\the\rightmargin +&\number\totalcols columns, column width = &\columnwidth (&\the\colwd), +Column height: &\columnheight (&\the\colht) +Intercolumn space: &\the\intercolspace +Full width of text area: &\the\fullwd +Main font: &\mainfont &\mainfontsize +Linespacing: &\the\normalbaselineskip +Each new file starts% +&\if\.S&\newfileoption% + immediately after the previous file. +&\else&\if\.C&\newfileoption% + at the top of a new column. +&\else&\if\.P&\newfileoption% + on a new page. +&\else&\if\.R&\newfileoption% + on the right-hand-side of a new page. +&\else ??? unknown. +&\fi&\fi&\fi&\fi% +File names are &\if&\printtitles&\else\.not&\fi% + printed as titles at the beginning of each file. +&\if&\printtitles% +File name font: &\titlefont &\titlefontsize +File name capitalization: &\titlecase +&\fi% +Date and time print in the form &\todaysdate and &\nowtime. +Line numbers are turned% +&\if&\linenumbers ON, font &\linenumberfont &\linenumberfontsize, + every &\number\linenumberfreq line% +&\ifnum&\linenumberfreq=1 &\else s&\fi +&\else OFF&\fi +Press <return> to continue: } +\fxmesj\menuIb{ +Page number font: &\pagenumberfont&\pagenumberfontsize +Running heads are turned &\if&\runheads ON: + &\the\runhead, + font &\runheadfont &\runheadfontsize, + runhead takes up &\the\runheadht from column height. +&\else OFF &\fi +Running feet are turned &\if&\runfeet ON: + &\the\runfoot, + font &\runfootfont &\runfootfontsize, + runfoot takes up &\the\runfootht from column height. +&\else OFF &\fi +Tabs are printed &\number\spacespertab characters wide, % +in style `&\tabstyle'. +&\if&\noextralinebreaks% +Line breaks are preserved exactly as in the original file. +&\else% +Extra line breaks are allowed at spaces and/or other characters. +Text is allowed to overrun right margin by &\the\overrun. +&\fi% +Control-L is defined to &\if\.N&\controlLaction% +end the current column. +&\else print as &\if\.L&\controlLaction% +a one-line vertical space. +&\else% +a boxed L. +&\fi&\fi% +System type is set to &\systemtype. +Directory for .los files: &\losdir +Directory prefix for file name titles: &\dirprefix +Press <return> to continue: } +\def\moptionI{\menuIa \readline{}\reply \menuIb + \readChar{Q}\reply \optionexec\reply} +\fxmenu\menuL{}{ +T Turn line numbers&\if&\linenumbers off&\else on&\fi +F Change font of line numbers +S Change font size of line numbers +N Change numbering frequency +}{&\if&\linenumbers +Current settings: &\linenumberfont &\linenumberfontsize, % +numbering every&\ifnum&\linenumberfreq=1 line% +&\else &\the&\linenumberfreq lines&\fi.% +&\fi% +} +\def\moptionL{\lettermenu L} +\def\moptionLT{% + \if\linenumbers + \let\linenumbers\FALSE + \else + \let\linenumbers\TRUE + \fi + \confirm{Line numbers are switched \if\linenumbers on\else off\fi.}% + \if\if\linenumbers\ifdim\leftmargin<12\p@ T + \else\ifnum\totalcols>\@ne + \ifdim\intercolspace<12\p@ T\else F\fi + \else F\fi\fi\else F\fi T% + \confirm{\ +* You might want to check the left margin and/or intercolspace\ +* to make sure there's enough room for the line numbers.}% + \else\popoptions\fi + \moptionQ +} +\def\moptionLF{\getfont\linenumberfont{}{Line number}} +\def\moptionLS{\getfontsize\linenumberfontsize{line numbers}} +\def\moptionLN{% + \xmesj{% +Current line numbering frequency is every +\ifnum\linenumberfreq=1 line% +\else\ \number\linenumberfreq\ lines\fi.\ +New line numbering frequency? (1 = every line, 2 = every 2 lines,\ +and so forth):}% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkinteger\reply\count@ + \ifnum\count@>\z@ + \linenumberfreq=\count@ + \confirm{New line numbering frequency: \the\linenumberfreq}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmenu\menuM{ +Current margin settings: top &\the&\topmargin, left &\the&\leftmargin, +bottom &\the&\bottommargin, right &\the&\rightmargin. +}{ +L Change left margin +T Change top margin +B Change bottom margin +R Change right margin +}{} +\def\moptionM{\lettermenu M} +\fxmesj\menuMB#1{ +Current bottom margin is #1. +If you specify a new bottom margin, column height will be recomputed to +come as close as possible to the desired value (nearest integer multiple +of line spacing), taking the currently specified paper height and top +margin into consideration. To revert to automatic computing of bottom +margin, give an empty reply (i.e., just press the <return> key). +Otherwise enter a measurement using TeX units:} +\def\moptionMB{\menuMB{\the\bottommargin}% + \readline{}\reply + \ifx\@empty\reply + \let\dependentbottommargin\TRUE + \if\dependentcolht + \computebc + \fi + \def\reply{Q}% + \else + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen % not a valid dimension + \else + \bottommargin\dimen@ + \computec + \confirm{New column height: \the\colht\ +* New bottom margin: \the\bottommargin}% + \def\reply{Q}% + \fi + \fi + \fi + \optionexec\reply +} +\fxmesj\menuML#1{ +Current left margin is #1 (measured from the left edge of the +paper to the left edge of the text). +<return> to keep the current value, or enter a new value:} +\def\moptionML{\menuML{\the\leftmargin}% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \leftmargin\dimen@ + \confirm{New left margin: \the\leftmargin}% + \if\linenumbers\ifdim\leftmargin<12\p@ + \confirm{\ +* Warning: small left margin, might not be big enough for line\ +* numbers to fit ...}% + \fi\fi + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmesj\menuMR#1{ +Current right margin is #1 (measured from the right edge of the +paper to the right edge of the text). To revert to automatic +computation of the right margin, give an empty reply; or enter a new +value using TeX units (or enter Q or X or ? to quit/exit/get-help). +New right margin:} +\def\moptionMR{\menuMR{\the\rightmargin}% + \readline{}\reply + \ifx\@empty\reply + \let\dependentrightmargin\TRUE + \rightmargin=\leftmargin + \confirm{New right margin: \the\rightmargin}% + \def\reply{Q}% + \fi + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \rightmargin\dimen@ + \confirm{New right margin: \the\rightmargin}% + \let\dependentrightmargin\FALSE + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmesj\menuMT#1{ +Current top margin is #1 (measured from the top edge of the +paper to the top of the running head or the text). +<return> to keep the current value, or enter a new value:} +\def\moptionMT{\menuMT{\the\topmargin}% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \topmargin\dimen@ + \confirm{New top margin: \the\topmargin}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmesj\menuN#1{ +Number of columns: #1. +<return> to keep the current value, or enter a new value +(a number greater than 0):} +\def\moptionN{\menuN{\number\totalcols}% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkinteger\reply\count@ + \ifnum\count@=-\maxdimen + \else + \if\ifnum\count@>\z@ + \ifnum\count@<\sixt@@n T\else F\fi\else F\fi T% + \chardef\totalcols=\count@ + \if\dependentcolwd + \if\dependentrightmargin \computerfc \else \computefc \fi + \else + \computefr + \fi + \confirm{% + Number of columns: \number\totalcols\space + (column width: \the\colwd, % +\ifnum\totalcols>\@ne intercolumn space: \the\intercolspace,\ +* \fi total width: \the\fullwd)} + \def\reply{Q}% + \else + \ifnum\count@>20 + \specialhelp\reply + {Maximum number of columns is 20, sorry...}% + \else + \specialhelp\reply + {Number of columns must be greater than 0}% + \fi + \fi + \fi + \fi + \optionexec\reply +} +\fxmenu\menuO{ +Current orientation: &\if&\landscape\.landscape.&\else\.portrait&\fi +}{ +P Switch to portrait orientation +L Switch to landscape orientation +}{} +\def\moptionO{\menuO \readChar{Q}\reply + \if P\reply + \if\landscape \let\landscape\FALSE + \dimen@\paht \paht\pawd \pawd\dimen@ + \fi + \confirm{Orientation is now: portrait}% + \def\reply{Q}% + \else + \if L\reply + \if\landscape \else \let\landscape\TRUE + \dimen@\paht \paht\pawd \pawd\dimen@ + \fi + \confirm{Orientation is now: landscape}% + \def\reply{Q}% + \fi + \fi + \optionexec\reply +} +\fxmenu\menuP{ +Current paper size: &\paperwidth x &\paperheight +}{ +W Change paper width +H Change paper height +U U.S. letter size paper: 8.5in x 11in +A A4 paper: 21cm x 29.7cm +}{} +\def\moptionP{\lettermenu P} +\def\moptionPW{\promptmesj{New paper width: }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \ifdim\dimen@>1cm + \let\paperwidth\reply + \pawd\dimen@ + \confirm{New paper width: \paperwidth\space(\the\pawd)}% + \def\reply{Q}% + \else + \specialhelp\reply{% +Sorry, I can't believe you really want a width of \reply!}% + \fi + \fi + \fi + \optionexec\reply +} +\def\moptionPH{\promptmesj{New paper height: }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkdimen\reply\dimen@ + \ifdim\dimen@=-\maxdimen + \else + \ifdim\dimen@>1cm + \let\paperheight\reply + \paht\dimen@ + \confirm{New paper height: \paperheight\space(\the\paht)}% + \def\reply{Q}% + \else + \specialhelp\reply{% +Sorry, I can't believe you really want a height of \reply!}% + \fi + \fi + \fi + \optionexec\reply +} +\def\moptionPU{% + \if\landscape + \paht=8.5truein \pawd=11truein + \def\paperheight{8.5in}\def\paperwidth{11in}% + \else + \paht=11truein \pawd=8.5truein + \def\paperheight{11in}\def\paperwidth{8.5in}% + \fi + \confirm{New paper width: \paperwidth\space(\the\pawd)\ +* New paper height: \paperheight\space(\the\paht)% +\if\landscape\ +(landscape)\fi}% + \moptionQ +} +\def\moptionPA{% + \if\landscape + \paht=21cm \pawd=29.7cm + \def\paperheight{21cm}\def\paperwidth{29.7cm}% + \else + \paht=29.7cm \pawd=21cm + \def\paperheight{29.7cm}\def\paperwidth{21cm}% + \fi + \confirm{New paper width: \paperwidth\space(\the\pawd)\ +* New paper height: \paperheight\space(\the\paht)% + \if\landscape\ + (landscape)\fi}% + \moptionQ +} +\fxmenu\menuR{ +Running heads are turned &\if&\runheads\.on. +Running head contents: +&\the&\runhead +&\else\.off. +&\fi% +Running feet are turned &\if&\runfeet\.on. +Running foot contents: +&\the&\runfoot +&\else\.off. +&\fi% +}{ +H Change running heads +F Change running feet +}{} +\def\moptionR{\lettermenu R} +\fmenu\menuRHorF#1{}{ +C Change running #1 contents +F Change running #1 font +S Change running #1 font size +}{} +\def\moptionRH{\menuRHorF{head}\readChar{Q}\reply \optionexec\reply} +\fxmesj\menuRHC{ +Current running head contents: +&\the&\runhead +Enter new running head contents (to turn off running heads, +just press <return>):} +\def\moptionRHC{\menuRHC + \xreadline{}\reply + \if\xoptiontest\reply + \else + \global\runhead\xp@{\reply}% + \ifx\reply\@empty + \global\let\runheads\FALSE + \else + \global\let\runheads\TRUE + \confirm{New running head:\ + \the\runhead}% + \fi + \def\reply{Q}% + \fi + \optionexec\reply +} +\def\moptionRHF{\getfont\runheadfont{}{Running head}} +\def\moptionRHS{\getfontsize\runheadfontsize{running heads}} +\def\moptionRF{\menuRHorF{foot}\readChar{Q}\reply \optionexec\reply} +\fxmesj\menuRFC{ +Current running foot contents: +&\the&\runfoot +Enter new running foot contents (to turn off running feet, +just press <return>):} +\def\moptionRFC{\menuRFC + \xreadline{}\reply + \if\xoptiontest\reply + \else + \global\runfoot\xp@{\reply}% + \ifx\reply\@empty + \global\let\runfeet\FALSE + \else + \global\let\runfeet\TRUE + \confirm{New running foot:\ + \the\runfoot}% + \fi + \def\reply{Q}% + \fi + \optionexec\reply +} +\def\moptionRFF{\getfont\runfootfont{}{Running foot}} +\def\moptionRFS{\getfontsize\runfootfontsize{running feet}} +\fxmenu\menuS{ +System information. Current system type is &\systemtype; +directory prefix to be used for all files printed in this run is +&\ifx&\@empty&\dirprefix\.null.&\else +&\dirprefix&\fi +}{ +S Change system type +D Change directory prefix +}{} +\def\moptionS{\lettermenu{S}} +\fxmenu\menuSS{ +System type options: +}{ +D DOS +M Macintosh +U Unix +V VAX/VMS +O Other +}{ +Currently this information is only used to help in printing directory +names that may occur in the titles printed at the beginning of each +file. Current system type is &\systemtype. +} +\def\moptionSS{\menuSS + \readChar{Q}\reply + \if D\reply \def\systemtype{DOS}\def\currentdir{./}\def\reply{Q}% + \else\if M\reply + \def\systemtype{Macintosh}\def\currentdir{}\def\reply{Q}% + \else\if U\reply + \def\systemtype{Unix}\def\currentdir{./}\def\reply{Q}% + \else\if V\reply + \def\systemtype{VAX/VMS}% + \edef\currentdir{sys\string $disk:[]}\def\reply{Q}% + \else \def\systemtype{other}\def\currentdir{}\def\reply{Q}% + \fi\fi\fi\fi + \optionexec\reply +} +\fxmesj\menuSD{ +Current directory/folder prefix for all file names is +&\ifx&\@empty&\dirprefix\.null.&\else + `&\dirprefix' +&\fi +Enter the new directory prefix below. +(Enter Q to quit without changing the prefix.)} +\def\moptionSD{% + \menuSD + \readline{}\reply + \let\next\reply \changecase\uppercase\next + \if\xoptiontest\next + \let\reply\next + \else + \let\dirprefix\reply + \ifx\dirprefix\@empty + \confirm{Directory prefix is now null.}% + \else + \confirm{New directory name:\ + \dirprefix\ + }% + \fi + \def\reply{Q}% + \fi + \optionexec\reply +} +\fxmenu\menuT{ +Currently tabs will print as &\tabstyle. +The horizontal extent of each tab will be % +&\number&\spacespertab spaces. +}{ +T Change tab representation +N Change the number of spaces per tab +}{} +\def\moptionT{\lettermenu T} +\fmenu\menuTT#1{ +Tab representation choices: +}{ +B Blank space +. Dots +- Dashed line +H Hrulefill +T Tiny`TAB's fill +}{ +These are better understood by trying them out than by having them +explained in words. Current tab style is `#1'. +} +\def\reportnewtabstyle#1{% + \chardef\tabselect=#1 \relax + \confirm{Tab style is now `\tabstyle'}% + \def\reply{Q}% +} +\def\moptionTT{\menuTT\tabstyle + \readChar{Q}\reply + \if B\reply + \reportnewtabstyle{0}% + \else\if .\reply + \reportnewtabstyle{1}% + \else\if -\reply + \reportnewtabstyle{2}% + \else\if H\reply + \reportnewtabstyle{3}% + \else\if T\reply + \reportnewtabstyle{4}% + \fi\fi\fi\fi\fi + \optionexec\reply +} +\def\moptionTN{% + \promptmesj{Enter the desired number of spaces per tab: }% + \readline{Q}\reply + \if\xoptiontest\reply + \else + \checkinteger\reply\count@ + \ifnum\count@=-\maxdimen + \else + \ifnum\count@<256 + \chardef\spacespertab=\count@ + \confirm{% + The number of spaces per tab is now \number\spacespertab.}% + \def\reply{Q}% + \else + \mesj{Sorry, spaces per tab cannot be more than 255.}% + \def\reply{}% repeat the prompt + \fi + \fi + \fi + \optionexec\reply +} +\fmenu\menuV{}{ + 8 Treatment of 8-bit characters + L Treatment of Control-L characters +}{} +\def\moptionV{\lettermenu{V}} +\fxmenu\menuVL{ +Three choices are offered for the treatment of Control-L characters: +}{ + B Print a boxed L (same treatment as other control characters) + L Print one line of space + N End current text column, start a new column +}{ +Current setting is &\controlLaction. +} +\def\moptionVL{\menuVL + \readChar{Q}\reply + \if B\reply + \let\controlLaction\reply + \confirm{Control-L characters will print as boxed L's}% + \else\if L\reply + \let\controlLaction\reply + \confirm{Control-L characters will print as a one-line space}% + \else\if N\reply + \let\controlLaction\reply + \confirm{% +Control-L characters will perform a `formfeed' [new column] action}% + \fi\fi\fi + \def\reply{Q}\optionexec\reply +} +\expandafter\fxmenu\csname menuV8\endcsname{ +Two choices are offered for the treatment of 8-bit characters, that +is, characters in the range 128--255: +}{ + A Print according to the current font + B Print a boxed question mark +}{ +Current setting is &\eightbitaction. +For option A, you must be careful to also select a font that is capable +of printing 8-bit characters (see option F in the main menu); otherwise, +8-bit characters will disappear silently from the printed output with +nothing more than a warning in the TeX log. +} +\expandafter\def\csname moptionV8\endcsname{% + \csname menuV8\endcsname + \readchar{Q}\reply + \if A\reply \def\eightbitaction{A}% + \else\if B\reply \def\eightbitaction{B}% + \fi\fi + \def\reply{Q}\optionexec\reply +} +\moption +\printfiles +\endinput +%% +%% End of file `listout.tex'. |