diff options
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r-- | Master/texmf-dist/source/latex/dialogl/dialogl.dtx | 1429 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/dialogl/dialogl.ins | 92 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/dialogl/grabhedr.dtx | 513 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/dialogl/listout.dtx | 5061 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/dialogl/menus.dtx | 983 |
5 files changed, 8078 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/dialogl/dialogl.dtx b/Master/texmf-dist/source/latex/dialogl/dialogl.dtx new file mode 100644 index 00000000000..105a2494dd4 --- /dev/null +++ b/Master/texmf-dist/source/latex/dialogl/dialogl.dtx @@ -0,0 +1,1429 @@ +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "dialogl.dtx", +%%% version = "1.99a", +%%% date = "2013/01/24", +%%% author = "Michael Downes", +%%% copyright = "This file is part of the dialogl package, released +%%% under the LPPL; see dialogl.ins for details." +%%% keywords = "TeX, dialog", +%%% supported = "no", +%%% abstract = "This file provides macros 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.", +%%% } +%%% ==================================================================== +% +% \iffalse +%<*driver> +\input{dia-driv.tex} +%</driver> +% \fi +% +% \section{History} +% This file, \fn{dialog.sty}, was born out of a utility called +% \fn{listout.tex} that I wrote for my personal use. The purpose of +% \fn{listout.tex} was to facilitate printing out plain text +% files\Dash electronic mail, program source files in various +% programming languages, and, foremost, \tex/ macro files and log +% files. An important part of my \tex/ programming practice is to +% print out a macro file on paper and read it through, marking +% corrections along the way, then use the marked copy as a script +% for editing the file. (For one thing, this allows me to analyze +% and mark corrections while riding the bus to work, or +% sitting out in the back yard to supervise the kids.) The output I +% normally desired was two `pages' per sheet of U.S. letter-size +% paper printed landscape, in order to conserve paper. +% +% Once created, \fn{listout.tex} quickly became my favorite means +% of printing out plain text files, not to mention an indispensable +% tool in my debugging toolbox: I turn on \cw{tracingmacros} and +% \cw{tracingcommands}, then print out the resulting log file so +% that I can see several hundred lines of the log at once (by +% spreading out two or three pages on my desk with 100+ lines per +% page); then I trace through, cross things out, label other +% things, draw arrows, and so forth. +% +% I soon added a filename prompting loop to make it convenient to +% print multiple files in a single run. In the process of +% perfecting this simple prompting routine\Dash over two or three +% years\Dash and adding the ability to optionally specify things like +% number of columns at run time, eventually I wrote so much +% dialog-related macro code that it became clear this code should +% be moved out of \fn{listout.tex} into its own module. The result +% was \fn{dialog.sty}. +% +% Before getting into the macro definitions and technical +% commentary, here are descriptions from the user's +% perspective of the functions defined in this file. +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Message-sending functions} +% +%\begin{usage} +%\mesj{<text>} +%\end{usage} +% Sends the message verbatim: category 12 for all special +% characters except braces, tab characters, and carriage returns: +% +%^^V { } ^^I ^^M +% +% Naturally, the catcode changes are effective only if \cw{mesj} is +% used directly, not inside a macro argument or definition +% replacement text. +% +% Multiple spaces in the argument of \cw{mesj} print as multiple +% spaces on screen. A tab character produces always eight spaces; +% `smart' handling of tabs is more complicated than I would care to +% attempt. +% +% Line breaks in the argument of \cw{mesj} will produce line breaks +% on screen. That is, you don't need to enter a special sequence +% such as \ctrl{J}\qc{\%} to get line breaks. See the technical +% commentary for \cw{mesjsetup} for details. Even though curly +% braces are left with their normal catcodes, they can be printed +% in a message without any problem, if they occur in balanced +% pairs. If not, the message should be sent using \cw{xmesj} +% instead of \cw{mesj}. +% +% Because of its careful handling of the message text, \cw{mesj} is +% extremely easy to use. The only thing you have to worry about is +% having properly matched braces. Beyond that, you simply type +% everything exactly as you want it to appear on screen. +% +%\begin{usage} +%\xmesj{<text>} +%\end{usage} +% This is like \cw{mesj} but expands embedded control sequences +% instead of printing them verbatim. All special characters have +% category 12 except backslash, percent, braces, tab, return, and +% ampersand: +% +%^^V \ % { } ^^I ^^M & +% +% The first four have normal \tex/ catcodes to make it possible to +% use most normal \tex/ commands, and comments, in the message +% text. \ctrl{I} and \ctrl{M} are catcode 13 and behave as +% described for \cw{mesj}. The \qc{\&} is a special convenience, an +% abbreviation for \cw{noexpand}, to use for controlling expansion +% inside the message text. +% +% Doubled backslash \cs{\\} in the argument will produce a single +% category 12 backslash character\Dash thus, \verb'\\xxx' can be used +% instead of \cw{string}\cw{xxx} or \cw{noexpand}\cw{xxx} (notice +% that this works even for outer things like \cw{bye} or +% \cw{newif}). Similarly \cs{\%}, \cs{\{}, \cs{\}} and \cs{\&} +% produce the corresponding single characters. +% +% Category 12 space means that you cannot write something like +% +%^^V \ifvmode h\else v\fi rule +% +% in the argument of \cw{xmesj} without getting a space after the +% \cw{ifvmode}, \cw{else}, and \cw{fi}.%^^A +%^^A +%\footnote{Well, actually, you could replace each space by +%\qc{\%}\meta{newline} to get rid of it. But that makes the message +%text harder to read for the programmer.} +%^^A +% Since occasionally this may be troublesome, \cs{\.} is defined +% inside the argument of \cw{xmesj} to be a `control word +% terminator': If the expansion of \cw{foo} is \verb'abc', then +% \verb'\foo\.xyz' produces \verb'abcxyz' on screen (as opposed to +% \verb'\foo xyz' which would produce \verb'abc xyz'). Thus the +% above conditional could be written as +% +%^^V \ifvmode\.h\else\.v\fi\.rule +% +% Even though the catcode changes done by \cw{xmesj} setup have no +% effect if \cw{xmesj} is used inside an argument or definition +% replacement text, I find it convenient occasionally to use +% \cw{xmesj} in those contexts, in order to get other aspects of the +% \cw{xmesj} setup. For instance, if you need to embed a message +% that contains a percent sign inside a definition, you can write +% +%^^V \def\foo{... +%^^V \xmesj{... this is a percent +%^^V sign: \% (sans backslash) ...} +%^^V ...} +% +% To further support such uses of \cw{xmesj}, the following changes +% are also done by \cw{xmesj} setup: the backslash-space control +% symbol {\tt\bslash\char32} is made equivalent to \cw{space}; +% \cs{\^^J} and \cs{\^^M} are defined to produce a \cw{newlinechar}; +% and active tilde \qc{\~} will produce a category-12 tilde. +% +% Among other things, this setup makes it easier to obtain +% newlines and multiple spaces in an embedded message. For example, +% in the following definition the message will have a line break on +% screen for each backslash at the end of a line, and the third +% line will be indented four spaces. +% +%^^V \def\bar{... +%^^V \xmesj{First line\ +%^^V Second line\ +%^^V \ \ \ \ Indented line\ +%^^V Last line}% +%^^V ...} +% +% The alternative of defining a separate message function +% \cw{barfoo} with \cw{f[x]mesj} and calling \cw{barfoo} inside of +% \cw{bar} would allow more natural entry of the newlines and the +% multiple spaces, but would be slightly more expensive in string +% pool and hash table usage. +% +%\begin{usage} +%\promptmesj{<text>} +%\promptxmesj{<text>} +%\end{usage} +% These are like \cw{mesj}, \cw{xmesj} but use \cw{message} rather +% than \cw{immediate}\cw{write}\verb'16' internally, thus if the +% following operation is a \cw{read}, the user will see the cursor +% on screen at the end of the last line, as may be desired when +% prompting for a short reply, rather than at the beginning of the +% next line. The character \qc{\!} is preempted internally for +% newlinechar, for these two functions only, +% which means that it cannot be actually printed in +% the message text. Use of a visible character such as \qc{\!}, +% rather than the normal \cw{newlinechar} \ctrl{J}, is necessary +% for robustness because of the fact that the \cw{message} +% primitive was unable to use an `invisible' character (outside the +% range 32--126) for newlines up until \tex/ version 3.1415, which +% some users do not yet have (at the time of this writing\Dash July +% 1994). +% +%\begin{usage} +%\storemesj\foo{<text>} +%\storexmesj\foo{<text>} +%\end{usage} +% These functions are similar to \cw{mesj}, \cw{xmesj} but store the +% given text in the control sequence \cw{foo} instead of immediately +% sending the message. Standard \tex/ parameter syntax can be used +% to make \cw{foo} a function with arguments, e.g. after +% +%^^V \storemesj\foo#1{...#1...} +% +% then you can later write +% +%^^V \message{\foo{\the\hsize}} +% +% and get the current value of \cw{hsize} into the middle of the +% message text. Consequently also in the x-version \cw{storexmesj} a +% category-12 \qc{\#} character can be obtained with \cs{\#}. +% +%\begin{usage} +%\fmesj\foobar#1#2...{...#1...#2...} +%\end{usage} +% Defines \cw{foobar} as a function that will take the given +% arguments, sow them into the message text \verb"{...}", and send +% the message. In the message text all special characters are +% category 12 except for braces, \qc{\#}, tab, and carriage return. +% +% If an unmatched brace or a \qc{\#} must be printed in the message +% text \cw{fxmesj} must be used instead. (\arg{#} could be used to +% insert a single category-6 \qc{\#} token into the message text, and +% \tex/ would print it without an error, but both \cw{message} and +% \cw{write} would print it as two \arg{#} characters, even though +% it's only a single token internally.) +% +%\begin{usage} +%\fxmesj\foobar#1#2...{...#1...#2...} +%\end{usage} +% Combination of \cw{xmesj} and \cw{fmesj}. Defines \cw{foobar} like +% \cw{fmesj}, but with full expansion of the replacement text and +% with normal category codes for backslash, percent, braces, and hash +% \qc{\#}. The control symbols \cs{\\} \cs{\%} \cs{\{} \cs{\}} +% \cs{\&} and \cs{\.} can be used as in \cw{xmesj}, with also \cs{\#} +% for printing a \qc{\#} character of category 12. +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Reading functions} +% +%\begin{usage} +%\readline{<default>}\answer +%\end{usage} +% This reads a line of input from the user into the macro +% \cw{answer}. (The macro name can be anything chosen by the +% programmer, not just \cw{answer}.) Before reading, all special +% characters are deactivated, so that the primitive \cw{read} will +% not choke if the user happens to enter something like \cw{newif} +% or {\sc control-l} or \qc{\}}. Depending on the operating +% system, certain characters\Dash e.g., {\sc control-c}, {\sc +% control-z}, {\sc control-d}, {\sc control-h}\Dash might have +% special effects instead of being entered into the replacement +% text of \cw{answer}, regardless of the catcode changes. To +% take the most obvious example, under most +% operating systems, typing {\sc control-h} (the Rubout or +% Backward-Delete key) will delete the previous character from the +% user's response, instead of entering an \ascii/ character 8 +% into \cw{answer}. +% +% There is one significant exception from the catcode changes that +% are done for \cw{readline}: spaces and tabs retain their normal +% catcode of 10, so that multiple spaces in an answer will be +% reduced to a single space, and macros with normal space-delimited +% arguments will work when applied to the answer. (I can't think of +% any likely scenario where category 12 for spaces would be +% useful.) Also, the catcode of \ctrl{M} is set to 9 (ignore) so +% that an empty line\Dash meaning that the user just pressed the +% carriage return/enter key\Dash will result in an empty \cw{answer}. +% If the answer is empty, the given default string will be +% substituted. The default string can be empty. +% +%\begin{usage} +%\xreadline{<default>}\answer +%\end{usage} +% Like \cw{readline} but the answer is read as executable tokens; +% the usual catcodes of the \tex/ special characters remain in +% effect while reading the answer. A few common outer things +% (\cw{bye}, \cs{\+}, \cw{newif}, \ctrl{L}, among others) are +% neutralized before the \cw{read} is done, but the user can still +% cause problems by entering some other outer control sequence or +% unbalanced braces. I doubt there's any bulletproof solution, if +% the tokens are to remain executable, short of the usual last +% resort: reading the answer using \cw{readline}, writing it to a +% file, then inputting the file. +% +%\begin{usage} +%\readchar{<default>}\answer +%\end{usage} +% This is like \cw{readline} but it reduces the answer to its first +% character. \meta{default} is either a single character or empty. +% +%\begin{usage} +%\readChar{<default>}\answer +%\end{usage} +% This is like \cw{readchar} and also uppercases the answer. +% +%\begin{usage} +%\changecase\uppercase\answer +%\end{usage} +% The function \cw{changecase} redefines its second argument, which +% must be a macro, to contain the same text as before, but +% uppercased or lowercased according to the first argument. Thus +% \cw{readChar}\verb'{Q}'\cw{answer} is equivalent to +% +%^^V \readchar{q}\answer +%^^V \changecase\uppercase\answer +% +% It might sometimes be desirable to force lower case before using +% a file name given by the user, for example. +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Checking functions} +% +%\begin{usage} +%\checkinteger\reply\tempcount +%\end{usage} +% To read in and check an answer that is supposed to be an integer, +% use \cw{readline}{}\cw{reply} and then apply \cw{checkinteger} to +% the \cw{reply}, supplying a count register, not necessarily named +% \cw{tempcount}, wherein \cw{checkinteger} will leave the validated +% integer. If \cw{reply} does not contain a valid integer the +% returned value will be \verb'-'\cw{maxdimen}. +% +% At the present time only decimal digits are handled; +% some valid \tex/ numbers such as \verb'"AB', \verb'`\@', +% \cw{number}\cw{prevgraf}, or a count register name, will not be +% recognized by \cw{checkinteger}. There seems to be no bulletproof +% way to allow these possibilities. +% +% Tests that hide \cw{checkinteger} under the hood, such as a +% \cw{nonnegativeinteger} test, are not provided because as often as +% not the number being prompted for will have to be tested to see if +% it falls inside a more specific range, such as 0\dash 255 for an +% 8-bit number or 1\dash 31 for a date, and it seems common sense to +% omit overhead if it would usually be redundant. It's easy enough to +% define such a test for yourself, if you want one. +% +%\begin{usage} +%\checkdimen\reply\tempdim +%\end{usage} +% Analog of \cw{checkinteger} for dimension values. If \cw{reply} +% does not contain a valid dimension the value returned in +% \cw{tempdim} will be \verb'-'\cw{maxdimen}. +% +% Only explicit dimensions with decimal digits, optional decimal +% point and more decimal digits, followed by explicit units +% \verb'pt' \verb'cm' \verb'in' or whatever are checked for; some +% valid \tex/ dimensions such as \cw{parindent}, +% \verb'.3'\cw{baselineskip}, or \cw{fontdimen}\verb'5'\cw{font} +% will not be recognized by \cw{checkdimen}. +% +% \subsection*{What good is all this?} +% What good is all this stuff, practically speaking?\Dash you may +% ask. Well, a typical application might be something like: At the +% beginning of a document, prompt interactively to find out if the +% user wants to print on A4 or US letter-size paper, or change the +% top or left margin. Such a query could be done like this: +% +%^^V \promptxmesj{ +%^^V Do you want to print on A4 or US letter paper? +%^^V Enter u or U for US letter, anything else for A4: } +%^^V \readChar{A}\reply % default = A4 +%^^V \if U\reply \textheight=11in \textwidth=8.5in +%^^V \else \textheight=297mm \textwidth=210mm \fi +%^^V % Subtract space for 1-inch margins +%^^V \addtolength{\textheight}{-2in} +%^^V \addtolength{\textwidth}{-2in} +%^^V +%^^V \promptxmesj{ +%^^V Left margin setting? [Return = keep current value, +%^^V \the\oddsidemargin]: } +%^^V \readline{\the\oddsidemargin}\reply +%^^V \checkdimen\reply{\dimen0} +%^^V \ifdim\dimen0>-\maxdimen +%^^V \setlength\oddsidemargin{\dimen0}% +%^^V \xmesj{OK, using new left margin of % +%^^V \the\oddsidemargin.} +%^^V \else +%^^V \xmesj{Sorry, I don't understand % +%^^V that reply: `\reply'.\ +%^^V Using default value: \the\oddsidemargin.} +%^^V \fi +% +% Although \latex/'s \cw{typeout} and \cw{typein} functions can +% be used for this same task, they are rather more awkward, and +% checking the margin value for validity would be quite difficult. +% +% \StopEventually{} +% +% \section{Implementation} +% Standard package identification: +% \begin{macrocode} +%<*2e> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{dialog}[1994/11/08 v0.9y] +%</2e> +% \end{macrocode} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Preliminaries} +% +% \begin{macrocode} +%<*2e> +\RequirePackage{grabhedr} +%</2e> +% \end{macrocode} +% +% If \fn{grabhedr.sty} is not already loaded, load it now. The +% \cw{trap.input} function is explained in \fn{grabhedr.doc}. +% \begin{macrocode} +%<*209> +\csname trap.input\endcsname +\input grabhedr.sty \relax +\fileversiondate{dialog.sty}{0.9y}{1994/11/08}% +%</209> +% \end{macrocode} +% +% The functions \cw{localcatcodes} and \cw{restore\-catcodes} are +% defined in \fn{grabhedr.sty}. We use them to save and restore +% catcodes of any special characters needed in this file whose +% current catcodes might not be what we want them to be. Saving and +% restoring catcode of at-sign \qc{\@} makes this file work equally +% well as a \latex/ documentstyle option or as a simple input file in +% other contexts. The double quote character \qc{\"} might be active +% for German and other languages. Saving and restoring tilde \qc{\~}, +% hash \qc{\#}, caret \qc{\^}, and left quote \qc{\`} catcodes is +% normally redundant but reduces the number of assumptions we must +% rely on. (The following catcodes are assumed: \qc{\\} 0, \qc{\{} 1, +% \qc{\}} 2, \qc{\%} 14, {\tt a}\dash {\tt z} {\tt A}\dash {\tt Z} +% 11, {\tt 0}\dash {\tt 9} \qc{\.} \qc{\-} 12. Also note that +% \cw{endlinechar} is assumed to have a non-null value.) +% \begin{macrocode} +%% The line break is significant here: +\localcatcodes{\@{11}\ {10}\ +{5}\~{13}\"{12}\#{6}\^{7}\`{12}} +% \end{macrocode} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Definitions} +% +% \begin{macro}{\otherchars} +% +% For deactivating characters with special catcodes during +% \cw{readline} we use, instead of \cw{dospecials}, a more +% bulletproof (albeit slower) combination of \cw{otherchars}, +% \cw{controlchars}, and \cw{highchars} that covers all characters in +% the range 0\dash 255 except letters and digits. Handling the +% characters above 127 triples the overhead done for each read +% operation or message definition but seems mandatory for maximum +% robustness.^^A +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \footnote{If you are using \fn{dialog.sty} functions on a slow +% computer, you might want to try setting \cw{highchars} = empty to +% see if that helps the speed.} +%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \cw{otherchars} includes the thirty-three nonalphanumeric visible +% characters (counting space as visible). It is intended as an +% executable list like \cw{dospecials} but, as an exercise in +% memory conservation, it is constructed without the \cw{do}s. For +% the usual application of changing catcodes, the list can still be +% executed nicely as shown below. Also, if we arrange to +% make sure that each character token gets category 12, it's not +% necessary to use control symbols such as \cs{\%} in place of +% those few special characters that would otherwise be difficult to +% place inside of a definition. This avoids a problem that would +% otherwise arise if we included \cs{\+} in the list and tried to +% process the list with a typical definition of \cs{do}: \cs{\+} is +% `outer' in plain \tex/ and would cause an error message when +% \cw{do} attempted to read it as an argument. (As a matter of fact +% the catcode changes below show a different way around that +% problem, but a list of category-12 character tokens is a fun +% thing to have around anyway.) +% +% \begin{macrocode} +\begingroup +% \end{macrocode} +% First we start a group to localize \cw{catcode} changes. Then we +% change all relevant catcodes to 12 except for backslash, open +% brace, and close brace, which can be handled by judicious +% application of \cw{escapechar}, \cw{string}, \cw{edef}, and +% \cw{xdef}. By defining \cw{do} in a slightly backward way, so that +% it doesn't take an argument, we don't need to worry about the +% presence of \cs{\+} in the list of control symbols. Notice the +% absence of \cs{\`} from the list of control symbols; it was already +% catcoded to 12 in the \cw{localcatcodes} declaration at the +% beginning of this file\Dash otherwise it would be troublesome to +% make the definition of \cw{do} bulletproof (consider the +% possibilities that \qc{\`} might have catcode 0, 5, 9, or 14). +% +% \begin{macrocode} +\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 +% \end{macrocode} +% To handle backslash and braces, we define \cs{\\}, +% \cs{\{}, and \cs{\}} to produce the corresponding category-12 +% character tokens. Setting \cw{escapechar} to $-1$ means that +% \cw{string} will omit the leading backslash that it would +% otherwise produce when applied to a control sequence. +% \begin{macrocode} +\escapechar -1 +\edef\\{\string\\} +\edef\{{\string\{}\edef\}{\string\}} +% \end{macrocode} +% Space and percent are done last. Then, with almost all the +% special characters now category 12, it's rather easy to define +% \cw{otherchars}. +% \begin{macrocode} +\catcode`\ =12\catcode`\%=12 +\xdef\otherchars +{ !"#$%&'()*+,-./:;<=>?[\\]^_`\{|\}~} +\endgroup % ^ ^ ^ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlchars} +% +% \cw{controlchars} is another list for the control characters +% \ascii/ 0\dash 31 and 127. The construction of this list is similar +% to the construction of \cw{otherchars}. We need to turn off +% \cw{endlinechar} because the catcode of \ctrl{M} is going to be +% changed. The \ctrl{L} inside the \cw{gdef} is not a problem (as it +% might have been, due to the usual outerness of \ctrl{L}) because +% the catcode is changed from 13 to 12 before that point. +% +% \begin{macrocode} +\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 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\highchars} +% And finally, the list \cw{highchars} contains characters +% 128\dash 255, the ones that have the eighth bit set. +% +% \begin{macrocode} +\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 +% \end{macrocode} +%\verbdots\iffalse +\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 +%\fi +% \begin{macrocode} +\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% +% \end{macrocode} +%\verbdots\iffalse +^^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% +%\fi +% \begin{macrocode} +^^f9^^fa^^fb^^fc^^fd^^fe^^ff} +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\actively} +% +% The function \cw{actively} makes a given character active and +% carries out the assignment given as the first argument. The +% assignment can be embedded in the replacement text of a macro +% definition without requiring any special setup to produce an active +% character in the replacement text. The argument should be a control +% symbol, e.g. \cw{@} or \cs{\#} or \cs{\^^M}, rather than a single +% character. (Except that \qc{\+} is safer than \cs{\+} in +% \plaintex/.) If the assignment is a definition (\cw{def}, +% \cw{edef}, \cw{gdef}, \cw{xdef}) it is allowed to take arguments in +% the normal \tex/ way. Prefixes such as \cw{global}, \cw{long}, or +% \cw{outer} must go inside the first argument rather than before +% \cw{actively}. +% +% Usage: +%\begin{usage} +%\actively\def\?{<replacement text>} +%\actively\def\%#1#2{<replacement text>} +%\actively{\global\let}\^^@=\space +%\end{usage} +% One place where this function can be put to good use is in +% making \ctrl{M} active in order to get special action at the end +% of each line of input. The usual way of going about this would be +% to write +% +%^^V \def\par{something}\obeylines +% +% \noindent which is a puzzling construction to the \tex/ novice +% who doesn't know what \cw{obeylines} does with \cw{par}. The same +% effect could be gotten a little more transparently with +% +%^^V \actively\def\^^M{something} +% +% In the definition of \cw{actively} we use the unique properties +% of \cw{lowercase} to create an active character with the right +% character code, overlapping with a \cw{begingroup} \cw{endgroup} +% structure that localizes the necessary lc-code change. +% \begin{macrocode} +\def\actively#1#2{\catcode`#2\active + \begingroup \lccode`\~=`#2\relax + \lowercase{\endgroup#1~}} +% \end{macrocode} +% \end{macro} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \begin{macro}{\mesjsetup} +% +% The \cw{mesjsetup} function starts a group to localize catcode +% changes. The group will be closed eventually by a separate +% function that does the actual sending or stores the message text +% for later retrieval. +% +% We want to change the catcode of each character in the three +% lists \cw{otherchars}, \cw{controlchars}, and \cw{highchars} to +% 12. After giving \cw{do} a recursive definition, we apply it to +% each of the three lists, adding a suitable element at the end of +% the list to make the recursion stop there. This allows +% leaving out the \cw{do} tokens from the character lists, without +% incurring the cost of an if test at each recursion step. +% \begin{macrocode} +\def\mesjsetup{\begingroup \count@=12 + \def\do##1{\catcode`##1\count@ \do}% +% \end{macrocode} +% The abbreviation \cw{xp@} = \cw{expandafter} is from +% \fn{grabhedr.sty}. +% \begin{macrocode} + \xp@\do\otherchars{a11 \@gobbletwo}% + \xp@\do\controlchars{a11 \@gobbletwo}% + \xp@\do\highchars{a11 \@gobbletwo}% +% \end{macrocode} +% Make the tab character produce eight spaces: +% \begin{macrocode} + \actively\edef\^^I{ \space\space\space + \space\space\space\space}% +% \end{macrocode} +% The convenient treatment of newlines in the argument of \cw{mesj} +% (every line break produces a line break on screen) is achieved by +% making the \ctrl{M} character active and defining it to produce a +% category-12 \ctrl{J} character. Although for \cw{mesj} it would +% have sufficed to make \ctrl{M} category 12 and locally set +% \cw{newlinechar} = \ctrl{M} while sending the message, it turns out +% to be useful for other functions to have the \ctrl{M} character +% active, so that it can be remapped to an arbitrary function for +% handling new lines (e.g., perhaps adding extra spaces at the +% beginning of each line). And if \cw{mesj} treats \ctrl{M} the same, +% we can arrange for it to share the setup routines needed for the +% other functions. +% \begin{macrocode} + \endlinechar=`\^^M\actively\let\^^M=\relax + \catcode`\{=1 \catcode`\}=2 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sendmesj} +% +% In \cw{sendmesj} we go to a little extra trouble to make sure +% \ctrl{M} produces a newline character, no matter what the value of +% \cw{newlinechar} might be in the surrounding environment. The +% impending \cw{endgroup} will restore \cw{newlinechar} to its +% previous value. One reason for using \ctrl{J} (instead of, say, +% \ctrl{M} directly) is to allow e.g. \cw{mesj}\verb'{xxx^^Jxxxx}' to +% be written inside a definition, as is sometimes convenient. This +% would be difficult with \ctrl{M} instead of \ctrl{J} because of +% catcodes. +% +% \begin{macrocode} +\def\sendmesj{\newlinechar`\^^J% + \actively\def\^^M{^^J}% + \immediate\write\sixt@@n{\mesjtext}\endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mesj} +% +% Given the support functions defined above, the definition of +% \cw{mesj} is easy: Use \cw{mesjsetup} to clear all special +% catcodes, then set up \cw{sendmesj} to be triggered by the next +% assignment, then read the following balanced-braces group into +% \cw{mesjtext}. As soon as the definition is completed, \tex/ will +% execute \cw{sendmesj}, which will send the text and close the +% group that was started in \cw{mesjsetup} to localize the catcode +% changes. +% +% \begin{macrocode} +\def\mesj{\mesjsetup \afterassignment\sendmesj + \def\mesjtext} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sendprompt} +% +% The \cw{sendprompt} function is just like \cw{sendmesj} except +% that it uses \cw{message} instead of \cw{write}, as might be +% desired when prompting for user input, so that the on-screen +% cursor stays on the same line as the prompt instead of hopping +% down to the beginning of the next line. In order for newlines to +% work with \cw{message} we must use a visible character instead of +% \ctrl{J}. When everyone has \tex/ version 3.1415 or later this +% will no longer be true. The choice of \qc{\!} might be construed +% (if you wish) as editorial comment that \qc{\!} should not be +% shouted at the user in a prompt. +% +% \begin{macrocode} +\def\sendprompt{% + \newlinechar`\!\relax \actively\def\^^M{!}% + \message{\mesjtext}\endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\promptmesj} +% +% This function is like \cw{mesj} but uses \cw{sendprompt} instead of +% \cw{sendmesj}. +% +% \begin{macrocode} +\def\promptmesj{\mesjsetup + \afterassignment\sendprompt \def\mesjtext} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\storemesj} +% +% Arg \arg{1} of \cw{storemesj} is the control sequence under which +% the message text is to be stored. +% \begin{macrocode} +\def\storemesj#1{\mesjsetup + \catcode`\#=6 % to allow arguments if needed + \afterassignment\endgroup + \long\gdef#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fmesj} +% +% While \cw{storemesj}\cw{foo}\verb"{...}" is more or less the +% same as \cw{def}\cw{foo}\verb"{...}" with special catcode +% changes, \cw{fmesj}\cw{foo}\verb"{...}" corresponds to +% \cw{def}\cw{foo}\qc{\{}\cw{mesj}\verb"{...}}", that is, after +% \cw{fmesj}\cw{foo} the function \cw{foo} can be executed directly +% to send the message. Thus \cw{storemesj} is typically used for +% storing pieces of messages, while \cw{fmesj} is used for storing +% entire messages. +% +% To read the parameter text \arg{2}, we use the peculiar +% \verb'#{' feature of \tex/ to read everything up to the opening +% brace. +% \begin{macrocode} +\def\fmesj#1#2#{\mesjsetup + \catcode`\#=6 % restore to normal +% \end{macrocode} +% The parameter text \arg{2} must be stored in a token register +% rather than a macro to avoid problems with \qc{\#} characters. +% The \cw{long} prefix is just to admit the (unlikely) possibility +% of using \cw{fmesj} to define something such as an error message +% saying `You can't use \arg{1} here' where one of the +% possibilities for \arg{1} is \cw{string}\cw{par}. +% \begin{macrocode} + \toks@{\long\gdef#1#2}% +% \end{macrocode} +% Define \cw{@tempa} to put together the first two arguments and +% [pseudo]argument \arg{3} and make the definition of \arg{1}. +% \begin{macrocode} + \def\@tempa{% + \edef\@tempa{% + \the\toks@{% +% \end{macrocode} +% The abbreviation \cw{nx@} = \cw{noexpand} is from +% \fn{grabhedr.sty}. +% \begin{macrocode} + \begingroup\def\nx@\mesjtext{\the\toks2 }% + \nx@\sendmesj}% + }% + \@tempa + \endgroup % Turn off the \mesjsetup catcodes + }% + \afterassignment\@tempa + \toks2=} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xmesjsetup} +% +% \cw{xmesjsetup} is like \cw{mesjsetup} except it prepares to allow +% control sequence tokens and normal comments in the message text. +% For \tex/nicians' convenience certain other features are +% thrown in. +% +% Here, unlike the setup for \cw{xreadline}, I don't bother to +% remove the outerness of \cw{bye}, \cw{newif}, etc., because I +% presume the arguments of \cw{xmesj}, \cw{fxmesj}, +% \cw{storexmesj}, \cw{fxmenu}, etc.\ are more likely to be written +% by a \tex/nician than by an average end user, whereas +% \cw{xreadline} is designed to handle arbitrary input from +% arbitrary users. +% +% \begin{macrocode} +\def\xmesjsetup{\mesjsetup +% \end{macrocode} +% Throw in pseudo braces just in case we are inside an \cw{halign} +% with \cs{\\} let equal to \cw{cr} at the time when \cw{xmesjsetup} +% is called. (As might happen in \amstex/.) +% \begin{macrocode} + \iffalse{\fi + \catcode`\\=0 \catcode`\%=14 +% \end{macrocode} +% Define {\def~{\spacefactor1500 \space}% +% \cs{\%}~\cs{\\}~\cs{\{}~\cs{\}}~\cs{\&}} to produce the +% corresponding single characters, category 12. The \cw{lowercase} +% trick here allows these definitions to be nonglobal. +% \begin{macrocode} + \begingroup \lccode`\0=`\\\lccode`\1=`\{% + \lccode`\2=`\}\lccode`\3=`\%% + \lowercase{\endgroup \def\\{0}\def\{{1}% + \def\}{2}\def\%{3}}% + \iffalse}\fi + \edef\&{\string &}% +% \end{macrocode} +% Let \qc{\&} \qc{\=} \cw{noexpand} for expansion control inside the +% argument text; let active \ctrl{M} \qc{\=} \cw{relax} so that +% newlines will remain inert during the expansion. +% \begin{macrocode} + \actively\let\&=\noexpand + \actively\let\^^M=\relax +% \end{macrocode} +% Define \cs{\.} to be a noop, for terminating a control word when +% it is followed by letters and no space is wanted. +% \begin{macrocode} + \def\.{}% +% \end{macrocode} +% Support for use of \cw{xmesj} inside a definition replacement +% text or macro argument: control-space +% \verb*"\ " = \cw{space}, tilde \qc{\~} prints as itself, +% \cs{\^^M} (i.e., a lone backslash at the end of a line) will +% produce a newline, also \cs{\^^J}, while finally \cw{par} \qc{\=} +% blank line translates to two newlines. +% \begin{macrocode} + \def\ { }\edef~{\string ~}% +% \end{macrocode} +% Define \cs{\^^M} to produce an active \ctrl{M} character, which (we +% hope) will be suitably defined to produce a newline or whatever. +% \begin{macrocode} + \begingroup \lccode`\~=`\^^M% + \lowercase{\endgroup \def\^^M{~}}% + \let\^^J\^^M \def\par{\^^M\^^M}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xmesj} +% +% \cw{xmesj} uses \cw{xmesjsetup} and \cw{edef}. +% \begin{macrocode} +\def\xmesj{\xmesjsetup \afterassignment\sendmesj + \edef\mesjtext} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\promptxmesj} +% +% \cw{promptxmesj} is analogous to \cw{promptmesj}, but with +% expansion. +% \begin{macrocode} +\def\promptxmesj{\xmesjsetup + \afterassignment\sendprompt \edef\mesjtext} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\storexmesj} +% +% And \cw{storexmesj} is like \cw{storemesj}, with expansion. Since +% we allow arguments for the function being defined, we also must +% define \cs{\#} to produce a single category-12 \qc{\#} character so +% that there will be a way to print \qc{\#} in the message text. +% \begin{macrocode} +\def\storexmesj#1#2#{\xmesjsetup + \catcode`\#=6 % to allow arguments if needed + \edef\#{\string##}% + \afterassignment\endgroup + \long\xdef#1#2} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fxmesj} +% +% And \cw{fxmesj} is the expansive analog of \cw{fmesj}. +% \begin{macrocode} +\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@=} +% \end{macrocode} +% \end{macro} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Reading functions} +% +% \begin{macro}{\readline} +% The \cw{readline} function gets one line of input from the user. +% Arguments are: \arg{1} default to be used if the user response is +% empty (i.e., if the user just pressed the return/enter key), +% \arg{2} macro to receive the input. +% +% \begin{macrocode} +\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}% +% \end{macrocode} +% Make spaces and tabs normal instead of category 12. +% \begin{macrocode} + \catcode`\ =10 \catcode`\^^I=10 % + \catcode`\^^M=9 % ignore +% \end{macrocode} +% Reset end-of-line char to normal, just in case. +% \begin{macrocode} + \endlinechar`\^^M +% \end{macrocode} +% We go to a little trouble to avoid \cw{gdef}-ing \arg{2}, in order +% to prevent save stack buildup if the user of \cw{readline} carries +% on unaware doing local redefinitions of \arg{2} after the initial +% read. +% \begin{macrocode} + \read\m@ne to#2% + \edef#2{\def\nx@#2{#2}}% + \xp@\endgroup #2% + \ifx\@empty#2\def#2{#1}\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xreadline} +% +% \cw{xreadline} is like \cw{readline} except that it leaves almost +% all catcodes unchanged so that the return value is executable +% tokens instead of strictly character tokens of category 11 or 12. +% \begin{macrocode} +\def\xreadline#1#2{% + \begingroup +% \end{macrocode} +% Render some outer control sequences innocuous. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\readchar} +% +% \cw{readchar} reduces the user response to a single character. +% \begin{macrocode} +\def\readchar#1#2{% + \readline{#1}#2% +% \end{macrocode} +% If the user's response and the default response are both empty, +% we need something after \arg{1} to keep \cw{@car} from running +% away, so we add an empty pair of braces. +% \begin{macrocode} + \edef#2{\xp@\@car#2#1{}\@nil}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\readChar} +% +% \cw{readChar} reduces the user response to a single uppercase +% character. (This is useful to simplify testing the response +% later with \cw{if}.) +% +% \begin{macrocode} +\def\readChar#1#2{% + \readline{#1}#2% + \changecase\uppercase#2% +% \end{macrocode} +% Reduce \arg{2} to its first character, or the first character of +% \arg{1}, if \arg{2} is empty. The extra braces \verb'{}' are to +% prevent a runaway argument error from \cw{@car} if \arg{2} and +% \arg{1} are both empty. +% \begin{macrocode} + \edef#2{\xp@\@car #2#1{}\@nil}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\changecase} +% The function \cw{changecase} uppercases or lowercases the +% replacement text of its second argument, which +% must be a macro. The first argument should be \cw{uppercase} or +% \cw{lowercase}. +% \begin{macrocode} +\def\changecase#1#2{\@casetoks\xp@{#2}% + \edef#2{#1{\def\nx@#2{\the\@casetoks}}}#2} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@casetoks} +% We allocate a token register just for the use of \cw{changecase} +% because it might be used at a low level internally where we don't +% want to interfere with other uses of the scratch token registers +% 0\dash 9. +% \begin{macrocode} +\newtoks\@casetoks +% \end{macrocode} +% \end{macro} +% +% A common task in reading user input is to verify, when an answer +% of a certain kind was requested, that the response has indeed the +% desired form\Dash for example, if a nonnegative integer is required +% for subsequent processing, it behooves us to verify that we have +% a nonnegative integer in hand before doing anything that might +% lead to inconvenient error messages. However, it's not easy to +% decide how best to handle such verification. One possibility +% might be to have a function +% +%^^V \readnonnegativeinteger\foo +% +% to do all the work of going out and fetching a number from the +% user and leaving it in the macro \cw{foo}. Another possibility +% would be to read the response using \cw{readline} and then apply +% a separate function that can be used in combination with \cw{if}, +% for example +% +%^^V \readline{}\reply +%^^V \if\validnumber\reply ... \else ... \fi +% +% For maximum flexibility, a slightly lower-level approach is +% chosen here. The target syntax is +% +%^^V \readline{}\reply +%^^V \checkinteger\reply\tempcount +% +% where \cw{tempcount} will be set to \verb'-'\cw{maxdimen} if +% \cw{reply} does {\em not\/} contain a valid integer. (Negative +% integers are allowed, as long as they are greater than +% \verb'-'\cw{maxdimen}.) Then the function that calls +% \cw{checkinteger} is free to make additional checks on the range +% of the reply and give error messages tailored to the +% circumstances. And the handling of an empty \cw{reply} can be +% arbitrarily customized, something that would tend to be +% inconvenient for the first method mentioned. +% +% The first and second approaches can be built on top of the third +% if desired, e.g.\ (for the second approach) +% +%^^V \def\validnumber#1{TT\fi +%^^V \checkinteger#1\tempcount% +%^^V \ifnum\tempcount>-\maxdimen } +% +% The curious \verb'TT\fi'\verbdots\cw{ifnum} construction is from +% \TeXhax{} 1989, no.~20 and no.~38 (a suggestion of D. E. Knuth in +% reply to a query by S. von Bechtolsheim). +% +% \begin{macro}{\checkinteger} +% +% The arguments of \cw{checkinteger}'s are: \arg{2}, a count register +% to hold the result; \arg{1}, a macro holding zero or more arbitrary +% characters of category 11 or 12. +% +% \begin{macrocode} +\def\checkinteger#1#2{\let\scansign@\@empty + \def\scanresult@{#2}% + \xp@\scanint#1x\endscan} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scanint} +% +% To validate a number, the function \cw{scanint} must first scan +% away leading \qc{\+} or \qc{\-} signs (keeping track in +% \cw{scansign@}), then look at the first token after that: if it's +% a digit, fine, scan that digit and any succeeding digits into the +% given count register (\cw{scanresult@}), ending with \cw{endscan} +% to get rid of any following garbage tokens that might just +% possibly show up. +% +% Typical usage of \cw{scanint} includes initializing \cw{scansign@} +% to empty, as in the definition of \cw{checkinteger}. +%\begin{usage} +%\let\scansign@\@empty +%\def\scanresult@{\tempcount}% +%\xp@\scanint\reply x\endscan +%\end{usage} +% Assumption: \cw{reply} is either empty or contains only category +% 11 or 12 characters (which it will if you used \cw{readline}!). If +% a separate check is done earlier to trap the case where \cw{reply} +% is empty\Dash for example, by using a nonempty default for +% \cw{readline}\Dash then the \verb'x' before \cw{endscan} is +% superfluous. +% +% Arg \arg{1} = next character from the string being tested. +% The test whether \arg{1} is a decimal digit is similar in spirit +% to the test \verb'\if!#1!' to see if an argument is empty +% (\TB, Appendix~D, p.~376). +% \begin{macrocode} +\def\scanint#1{% + \ifodd 0#11 % +% \end{macrocode} +% Is \arg{1} a decimal digit? If so read all digits into +% \cw{scanresult@} with the sign prefix. +% \begin{macrocode} + \def\@tempa{\afterassignment\endscan + \scanresult@=\scansign@#1}% + \else + \if -#1\relax +% \end{macrocode} +% Here we flipflop the sign; watch closely. +% \begin{macrocode} + \edef\scansign@{% + \ifx\@empty\scansign@ -\fi}% + \def\@tempa{\scanint}% + \else +% \end{macrocode} +% A plus sign can just be ignored. +% \begin{macrocode} + \if +#1\relax + \def\@tempa{\scanint}% + \else % not a valid number + \def\@tempa{% + \scanresult@=-\maxdimen\endscan}% + \fi\fi\fi + \@tempa +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\endscan} +% The \cw{endscan} function just gobbles any remaining garbage. It +% uses its own name as the argument delimiter. +% \begin{macrocode} +\def\endscan#1\endscan{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dimenfirstpart} +% \begin{macro}{\dimentoks} +% \cw{dimenfirstpart}, a count register, receives the digits, if +% any, preceding the decimal point. \cw{dimentoks}, a token +% register, receives any digits after the decimal point. +% \begin{macrocode} +\newcount\dimenfirstpart +\newtoks\dimentoks +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\scandimen} +% +% \cw{scandimen} is similar to \cw{scanint} but has to call some +% auxiliary functions to scan the various subcomponents of a +% dimension (leading digits, decimal point, fractional part, and +% units, with optional {\tt true}, in addition to the sign). The +% minimum requirements of \tex/'s syntax for dimensions are a digit +% or decimal point \qc{\+} the units; all the other components are +% optional (\TB, Exercise~10.3, p.~58). +% +% When scanning for the digits of a fractional part, we can't throw +% away leading zeros; therefore we don't read the fractional part +% into a count register as we did for the digits before the decimal +% point; instead we read the digits one by one and store them in +% \cw{dimentoks}. +% +% The function that calls \cw{scandimen} should initialize +% \cw{scansign@} to \cw{@empty}, \cw{dimenfirstpart} to \cw{z@}, +% \cw{dimentoks} to empty \verb'{}', and \cw{dimentrue@} to +% \cw{@empty}. +% +% Test values: {\tt 0pt}, {\tt 1.1in}, {\tt -2cm}, {\tt .3mm}, {\tt +% 0.4dd}, {\tt 5.cc}, {\tt.10000000009pc}, \cw{hsize}, {\tt em}. +% +% \begin{macrocode} +\def\scandimen#1{% + \ifodd 0#11 + \def\@tempa{\def\@tempa{\scandimenb}% + \afterassignment\@tempa + \dimenfirstpart#1}% + \else +% \end{macrocode} +% +% The following test resolves to true if \arg{1} is either a period +% or a comma (both recognized by \tex/ as decimal point +% characters). +% +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scandimenb} +% +% Scan for an optional decimal point. +% +% \begin{macrocode} +\def\scandimenb#1{% + \if \if,#1.\else#1\fi.% + \def\@tempa{\scandimenc}% + \else +% \end{macrocode} +% If the decimal point is absent, we need to put back \arg{2} and +% rescan it to see if it is the first letter of the units. +% \begin{macrocode} + \def\@tempa{\scanunitsa#1}% + \fi + \@tempa +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scandimenc} +% +% Scan for the fractional part: digits after the decimal point. +% +% \begin{macrocode} +\def\scandimenc#1{% +% \end{macrocode} +% If \arg{1} is a digit, add it to \cw{dimentoks}. +% \begin{macrocode} + \ifodd 0#11 \dimentoks\xp@{% + \the\dimentoks#1}% + \def\@tempa{\scandimenc}% + \else +% \end{macrocode} +% Otherwise rescan \arg{1}, presumably the first letter of the +% units. +% \begin{macrocode} + \def\@tempa{\scanunitsa#1}% + \fi + \@tempa +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scanunitsa} +% +% \begin{macrocode} +\def\scanunitsa#1\endscan{% +% \end{macrocode} +% Check for \verb'true' qualifier. +% \begin{macrocode} + \def\@tempa##1true##2##3\@tempa{##2}% +% \end{macrocode} +% +% The peculiar nature of \cw{lowercase} is evident here as we are +% able to apply it to only the test part of the conditional without +% running into brace-matching problems. (Compare the braces in this +% example to something like \cw{message}\qc{\{}\cw{iffalse} +% \verb"A}"\cw{else} \verb"B}"\cw{fi}.) +% +% \begin{macrocode} + \lowercase{% + \xp@\ifx\xp@\end + \@tempa#1true\end\@tempa + }% +% \end{macrocode} +% No \verb'true' was found: +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\scanunitsb} +% +% Scan for the name of the units and complete the assignment of the +% scanned value to \cw{scanresult@}. Notice that, because of the way +% \cw{scanunitsb} picks up \arg{1} and \arg{2} as macro arguments, +% \verb"p t" is allowed as a variation of \verb"pt". Eliminating +% this permissiveness doesn't seem worth the speed penalty +% that would be incurred in \cw{scanunitsb}. +% +% The method for detecting a valid units string is to define the +% scratch function \cw{@tempa} to apply \tex/'s parameter-matching +% abilities to a special string that will yield a boolean value +% of true if and only if the given string is a valid \tex/ unit. +% \begin{macrocode} +\def\scanunitsb#1#2{% + \def\@tempa##1#1#2##2##3\@nil{##2}% + \def\@tempb##1{T\@tempa + pcTptTcmTccTemTexTinTmmTddTspT##1F\@nil}% +% \end{macrocode} +% Force lowercase just in case the units were entered with +% uppercase letters (accepted by \tex/, so we had better accept +% uppercase also). +% \begin{macrocode} + \lowercase{% + \if\@tempb{#1#2}% + }% + \scanresult@=\scansign@ + \number\dimenfirstpart.\the\dimentoks + \dimentrue@#1#2\relax + \else + \scanresult@=-\maxdimen + \fi +% \end{macrocode} +% Call \cw{endscan} to gobble garbage tokens, if any. +% \begin{macrocode} + \endscan +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\checkdimen} +% +% Argument \arg{2} must be a dimen register; \arg{1} is expected to +% be a macro holding zero or more arbitrary characters of category 11 +% or 12. +% \begin{macrocode} +\def\checkdimen#1#2{% + \let\scansign@\@empty \def\scanresult@{#2}% + \let\dimentrue@\@empty + \dimenfirstpart\z@ \dimentoks{}% + \xp@\scandimen#1xx\endscan +} +% \end{macrocode} +% \end{macro} +% +% Finish up. +% \begin{macrocode} +\restorecatcodes +\endinput +% \end{macrocode} +% +% \CheckSum{858} +% \Finale diff --git a/Master/texmf-dist/source/latex/dialogl/dialogl.ins b/Master/texmf-dist/source/latex/dialogl/dialogl.ins new file mode 100644 index 00000000000..91fe3beaf7e --- /dev/null +++ b/Master/texmf-dist/source/latex/dialogl/dialogl.ins @@ -0,0 +1,92 @@ +% Copyright 1994 Michael John Downes +% Copyright 2013 TeX Users Group +% This file is part of the dialogl package, released under the LPPL. +% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "unmaintained". +%% +%% The list of all files belonging to the distribution is +%% given in the file `manifest.txt'. +%% +%% The list of derived (unpacked) files belonging to the distribution +%% and covered by LPPL is defined by the unpacking scripts (with +%% extension .ins) which are part of the distribution. +% +\NeedsTeXFormat{LaTeX2e}% +\def\batchfile{dialogl.ins} +\input docstrip.tex + +\keepsilent +\askforoverwritefalse + +\preamble +This is a generated file. + +Copyright 1994 Michael John Downes +Copyright 2013 TeX Users Group. + +It may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1 +of this license or (at your option) any later version. +The latest version of this license is in + http://www.latex-project.org/lppl.txt +and version 1.3 or later is part of all distributions of LaTeX +version 2003/12/01 or later. + +This file has the LPPL maintenance status "unmaintained". + +The list of all files belonging to the distribution is given in the file +`manifest.txt'. + +The list of derived (unpacked) files belonging to the distribution +and covered by LPPL is defined by the unpacking scripts (with +extension .ins) which are part of the distribution. +\endpreamble + +% Fix up catcodes of the upper 128 characters just in case someone +% has an early release of LaTeX2e. (pre June 1994 patch-level 2) +{\makeatletter +\def\do{\global\catcode\count@\@tempa \advance\count@\@ne + \ifnum\count@>\@cclv \expandafter\@gobble\fi \do}% +\count@=128 \chardef\@tempa=12 \do} + +\csname newtoks\endcsname\filesmsg +\def\dofile#1#2#3{\generateFile{#1}{t}{\from{#2}{#3}}% + \filesmsg\expandafter{\the\filesmsg \Msg{* \space\space#1}}} + +\dofile{dialog.sty}{dialogl.dtx}{2e} +\dofile{menus.sty}{menus.dtx}{2e} +\dofile{grabhedr.sty}{grabhedr.dtx}{2e} +% listout.tex incorporates copies of grabhedr.sty, dialog.sty, +% menus.sty with certain inconvenient lines removed, so that a single +% version of listout.tex will run equally well under plain TeX, LaTeX +% 209, or LaTeX2e. (And it runs slightly faster as it doesn't need to +% find those files at run-time). +\generateFile{listout.tex}{t}{% + \from{grabhedr.dtx}{}% + \from{dialogl.dtx}{}% + \from{menus.dtx}{}% + \from{listout.dtx}{}% +}% +\filesmsg\expandafter{\the\filesmsg \Msg{* \space\space listout.tex}} + +\ifToplevel{ +\Msg{******************************************************************} +\Msg{*} +\Msg{* To finish the installation you need to move the following files} +\Msg{* to a LaTeX input files area (the name of this area will vary} +\Msg{* depending on your system):} +\Msg{*} +\the\filesmsg +\Msg{*} +\Msg{******************************************************************} +} + +\endinput diff --git a/Master/texmf-dist/source/latex/dialogl/grabhedr.dtx b/Master/texmf-dist/source/latex/dialogl/grabhedr.dtx new file mode 100644 index 00000000000..8feaf337342 --- /dev/null +++ b/Master/texmf-dist/source/latex/dialogl/grabhedr.dtx @@ -0,0 +1,513 @@ +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "grabhedr.dtx", +%%% version = "1.99a", +%%% date = "2013/01/24", +%%% author = "Michael Downes", +%%% copyright = "This file is part of the dialogl package, released +%%% under the LPPL; see dialogl.ins for details." +%%% keywords = "TeX, file header, +%%% supported = "no", +%%% abstract = "This file defines a macro \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.", +%%% } +%%% ==================================================================== +% +% \iffalse +%<*driver> +\input{dia-driv.tex} +%</driver> +% \fi +% +% \section{Introduction} +% This file defines a function \cw{inputfwh} to be used instead of +% \cw{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. Usage: +%\begin{usage} +%\inputfwh{file.nam} +%\end{usage} +% Functions \cw{localcatcodes} and \cw{restorecatcodes} for +% managing catcode changes are also defined herein, as well as a +% handful of utility functions, many of them borrowed from +% \fn{latex.tex}: \cw{@empty}, \cw{@gobble}, \cw{@gobbletwo}, +% \cw{@car}, \cw{@@input}, \cw{toks@}, \cw{afterfi}, +% \cw{fileversiondate}, \cw{trap.input}. +% +% The use of \cw{inputfwh}, \cw{fileversiondate}, and +% \cw{trap.input} as illustrated in \fn{dialog.sty} is cumbersome +% klugery that in fact would better be handled by appropriate +% functionality built into the format file. But none of the major +% formats have anything along these lines yet. (It would also help +% if \tex/ made the current input file name accessible, like +% \cw{inputlineno}.) +% +% \StopEventually{} +% +% \section{Implementation} +% Standard package identification: +% \begin{macrocode} +%<*2e> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{grabhedr}[1994/11/08 v0.9j] +%</2e> +% \end{macrocode} +% +% By enclosing this entire file in a group, saving and restoring +% catcodes `by hand' is rendered unnecessary. This is perhaps the +% best way to locally change catcodes, better than the +% \cw{localcatcodes} function defined below. But it tends to be +% inconvenient for the \tex/ programmer: every time you add +% something you have to remember to make it global; if you're like +% me, you end up making every change twice, with an abortive test +% run of \tex/ in between, in which you discover that a certain +% control sequence is undefined because you didn't assign it +% globally. (Using \cw{globaldefs} = 1 is dangerous in my experience; +% you have to take care not to accidentally change any variables that +% you don't want to be changed globally.) +% \begin{macrocode} +\begingroup +% \end{macrocode} +% Inside this group, enforce normal catcodes. All definitions must +% be global in order to persist beyond the \cw{endgroup}. +% \begin{macrocode} +\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 +% \end{macrocode} +% Make \qc{\@} a letter for use in `private' control sequences. +% \begin{macrocode} +\catcode`\@=11 +% \end{macrocode} +% +% \section{Preliminaries} +% For \cw{@empty}, \cw{@gobble}, \ldots{} we use the \latex/ names so +% that if \fn{grabhedr.sty} is used with \latex/ we won't waste hash +% table and string pool space. +% +% \begin{macro}{\@empty} +% Empty macro, for \cw{ifx} tests or initialization of variables. +% \begin{macrocode} +\gdef\@empty{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@gobble} +% \begin{macro}{\@gobbletwo} +% \begin{macro}{\@gobblethree} +% Functions for gobbling unwanted tokens. +% \begin{macrocode} +\long\gdef\@gobble#1{} +\long\gdef\@gobbletwo#1#2{} +\long\gdef\@gobblethree#1#2#3{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@car} +% The function \cw{@car}, though not really needed by +% \fn{grabhedr.sty}, is needed by the principal customers of +% \fn{grabhedr.sty} (e.g., \fn{dialog.sty}). +% \begin{macrocode} +\long\gdef\@car#1#2\@nil{#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@input} +% To define \cw{@@input} as in \latex/ we want to let it equal to +% the primitive \cw{input}. But if a \latex/ format is being used +% we don't want to execute that assignment because by now +% \cw{input} has changed its meaning. And if some other format is +% being used it behooves us to check, before defining \cw{@@input}, +% whether \cw{input} still has its primitive meaning. Otherwise +% there's a good chance \cw{inputfwh} will fail to work properly. +% \begin{macrocode} +\ifx\UndEFiNed\@@input % LaTeX not loaded. +% \end{macrocode} +% This code shows a fairly easy way to check whether the meaning of a +% primitive control sequence is still the original meaning. +% \begin{macrocode} + \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 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\toks@} +% Scratch token register. +% \begin{macrocode} +\global\toksdef\toks@=0 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\afterfi} +% Sonja Maus's function for throwing code over the \cw{fi} (``An +% Expansion Power Lemma'', \TUB{} vol 12 no 2 June 1991). (Except +% that she called this function \cw{beforefi}.) +% +% \begin{macrocode} +\long\gdef\afterfi#1\fi{\fi#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nx@} +% We will be using \cw{noexpand} a lot; this abbreviation improves +% the readability of the code. +% \begin{macrocode} +\global\let\nx@\noexpand +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xp@} +% Another convenient abbreviation. +% \begin{macrocode} +\global\let\xp@\expandafter +% \end{macrocode} +% \end{macro} +% +% \section{Reading standard file headers} +% The function \cw{inputfwh} (`input file with header') inputs +% the given file, checking first to see if it starts with a +% standardized file header; if so, the filename, version and date +% are scanned for and stored in a control sequence. +% +% For maximum robustness, we strive to rely on the fewest possible +% assumptions about what the file that is about to be input might +% contain. +% +% Assumption 1: Percent character \qc{\%} has category 14. I.e., if +% the first line of the file to be input starts with \qc{\%}, it is +% OK to throw away that line. +% +% \begin{macro}{\@percentchar} +% \begin{macrocode} +\begingroup \lccode`\.=`\%% +\lowercase{\gdef\@percentchar{.}}% +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fileversiondate} +% The function \cw{fileversiondate} is not only a useful support +% function for \cw{inputfwh}, it can also be used by itself at the +% beginning of a file to set file name, version, and date correctly +% even if the file is input by some means other than +% \cw{inputfwh}\Dash assuming that the arguments of the +% \cw{fileversiondate} command are kept properly up to date. +% \begin{macrocode} +\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}% +} +% \end{macrocode} +% And now apply \cw{fileversiondate} to this file. +% \begin{macrocode} +%<*209> +\fileversiondate{grabhedr.sty}{0.9j}{1994/11/08} +%</209> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@filehdrstart} +% \fn{filehdr.el} by default adds a string of equal signs (with an +% initial comment prefix) at the very top of a file header. This +% string must be scanned away first before we can start looking for +% the real information of the file header. +% \begin{macrocode} +\xdef\@filehdrstart{% + \@percentchar\@percentchar\@percentchar\space + ==================================% + ==================================} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@scanfileheader} +% The purpose of this function is just to scan up to the opening +% brace that marks the beginning of the file header body. +% Everything before that is ignored, not needed for our present +% purposes. +% \begin{macrocode} +\gdef\@scanfileheader#1@#2#{\@xscanfileheader} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@xscanfileheader} +% Throw in some dummy values of version and date at the end so that +% all we require from a file header is that the filename field must +% be present. +% \begin{macrocode} +\long\gdef\@xscanfileheader#1{% + \@yscanfileheader#1{} version = "??", + date = "??",\@yscanfileheader} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@yscanfileheader} +% This function assumes that filename, version, and date of a file +% are listed in that order (but not necessarily adjacent). It's +% possible for the version and date to be missing, or out of order, +% but the corresponding \tex/ variables \cw{fileversion} and +% \cw{filedate} will not get set properly unless the order is: +% filename, [\ldots,] version, [\ldots,] date. Trying to handle +% different orderings would be desirable but I haven't yet been +% struck by a suitable flash of insight on how to do it without +% grubby, time-consuming picking apart of the entire file header. +% \begin{macrocode} +\long\gdef\@yscanfileheader + #1 filename = "#2",#3 version = "#4",% + #5 date = "#6",#7\@yscanfileheader{% + \endgroup + \csname fileversiondate\endcsname{#2}{#4}{#6}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@readfirstheaderline} +% This function has to look at the first line of the file to see if +% it has the expected form for the first line of a file header. +% \begin{macrocode} +\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 +% \end{macrocode} +% Double quote and equals sign need to be category 12 in order for +% the parameter matching of \cw{@xscanfileheader} to work, and +% space needs its normal catcode of 10. +% \begin{macrocode} + \catcode`\ =10 \catcode`\==12 \catcode`\"=12 + \xp@\@scanfileheader + \else + \message{(* Missing file header? *)}% + \afterfi\endgroup + \fi} +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@xinputfwh} +% An auxiliary function. +% \begin{macrocode} +\gdef\@xinputfwh{% + \ifx\next\@readfirstheaderline +% \end{macrocode} +% Sanitize a few characters. Otherwise an unmatched brace or other +% special character might cause a problem in the process of reading +% the first line as a macro argument. +% \begin{macrocode} + \catcode`\%=12 \catcode`\{=12 \catcode`\}=12 + \catcode`\\=12 \catcode`\^^L=12 + \catcode`\^=12 +% Unique terminator token for the first line. + \catcode`\^^M=3\relax + \else \endgroup\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@inputfwh} +% Auxiliary function, carries out the necessary \cw{futurelet}. +% \begin{macrocode} +\gdef\@inputfwh{\futurelet\next\@xinputfwh} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\inputfwh} +% Strategy for (almost) bulletproof reading of the first line of +% the input file is like this: Give the percent sign a special +% catcode, then use \cw{futurelet} to freeze the catcode of the +% first token in the input file. If the first token is {\em not\/} +% a percent character, then fine, just close the group wherein the +% percent character had its special catcode, and proceed with +% normal input; the first token will have its proper catcode +% because we did not change anything except the percent character. +% Otherwise, we still proceed with `normal' input execution, but by +% making \qc{\%} active and defining it suitably, we can carry out +% further tests to see if the first file line has the expected form +% (three percent signs plus lots of equal signs). +% \begin{macrocode} +\gdef\inputfwh#1{% + \begingroup\catcode`\%=\active + \endlinechar`\^^M\relax + \lccode`\~=`\%\relax + \lowercase{\let~}\@readfirstheaderline + \xp@\@inputfwh\@@input #1\relax +} +% \end{macrocode} +% \end{macro} +% +% \section{Managing catcode changes} +% +% A survey of other methods for saving and restoring catcodes would +% be more work than I have time for at the moment. The method +% given here is the best one I know (other methods use up one extra +% control sequence name per file, or don't robustly +% handle multiple levels of file nesting). +% +% \begin{macro}{\localcatcodes} +% The \cw{localcatcodes} function changes catcodes according to the +% character/catcode pairs given in its argument, saving the +% previous catcode values of those characters on a stack so that +% they can be retrieved later with \cw{restorecatcodes}. Example: +%\begin{usage} +%\localcatcodes{\@{11}\"\active} +%\end{usage} +% to change the catcode of \cs{\@} to 11 (letter) and the catcode +% of \qc{\"} to 13 (active). In \plaintex/ you'd better be careful +% to use \qc{\+} instead of \cs{\+} in the argument of +% \cw{localcatcodes} because of the outerness of \cs{\+}. +% +% This function works by using token registers 0 and 4 +% to accumulate catcode assignment statements: in \cw{toks0} we put +% the statements necessary to restore catcodes to their previous +% values, while in \cw{toks 4} we put the statements necessary to +% set catcodes to their new values. +% \begin{macrocode} +\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}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@catcodestack} +% Init the stack with an empty element; otherwise popping the +% next-to-last element would wrongly remove braces from the last +% element. But as a matter of fact we could just as well initialize +% \cw{@catcodestack} to empty because \cw{localcatcodes} is careful +% to add an empty final element if necessary. +% \begin{macrocode} +\gdef\@catcodestack{{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\restorecatcodes} +% The function \cw{restorecatcodes} has to pop the stack and +% execute the popped code. +% \begin{macrocode} +\gdef\restorecatcodes{% + \begingroup + \ifx\@empty\@catcodestack + \errmessage{Can't pop catcodes; + \nx@\@catcodestack = empty}% + \endgroup + \else + \def\do##1##2\do{% + \gdef\@catcodestack{##2}% +% \end{macrocode} +% Notice the placement of \arg{1} after the \cw{endgroup}, so that +% the catcode assignments are local assignments. +% \begin{macrocode} + \endgroup##1}% + \xp@\do\@catcodestack\do + \fi +} +% \end{macrocode} +% \end{macro} +% +% \section{Trapping redundant input statements} +% The utility \fn{listout.tex} calls \fn{menus.sty}, which calls +% \fn{dialog.sty}, and all three of these files start by loading +% \fn{grabhedr.sty} in order to take advantage of its functions +% \cw{fileversiondate}, \cw{localcatcodes}, and \cw{inputfwh}. But +% consequently, when \fn{listout.tex} is used there will be two +% redundant attempts to load \fn{grabhedr.sty}. The straightforward +% way to avoid the redundant input attempts would be to surround +% them with an \cw{ifx} test: +% +%^^V \ifx\undefined\fileversiondate +%^^V \input grabhedr.sty \relax +%^^V \fileversiondate{foo.bar}{0.9e}{10-Jun-1993} +%^^V \fi +% +% This method has a few drawbacks, however: (1)~the conditional +% remains open throughout the processing of everything in +% \fn{grabhedr.sty} and the \cw{fileversiondate} statement, which +% makes any \cw{else} or \cw{fi} mismatch problems harder to debug; +% (2)~if \cw{undefined} becomes accidentally defined the \cw{ifx} +% test will fail; (3)~choosing the right control sequence to test +% against \cw{undefined} requires a little care. +% +% In a situation where we know that the file to be input has had +% \cw{fileversiondate} applied to it, if it was already input, then +% we have a failsafe control sequence that we can test to find out +% whether the file has already been input\Dash the name +% of the file. Assuming a standard form for the input statement +% (one that will work with either plain \tex/ or \latex/, and makes +% as few assumptions as possible), we can write a function that +% will trap input statements and execute them only if the given +% file has not yet been loaded: +% +%^^V \csname trap.input\endcsname +%^^V \input grabhedr.sty \relax +%^^V \fileversiondate{foo.bar}{1.2}{1993-Jun-07} +% +% \begin{macro}{\trap.input} +% The function \cw{trap.input} scans for an input statement in +% canonical form and executes it if and only if the file has not yet +% been input (more precisely, if the control sequence consisting of +% the file name is undefined, which means that it has not had +% \cw{fileversiondate} applied to it). The canonical form +% that I consider to be the best is \cw{input} \meta{full file +% name}{\tt\char32 }\cw{relax}. Having the \cw{relax} means that the +% input statement will not try to expand beyond the end of the line +% if \cw{endlinechar} is catcoded to 9 (ignore), as is done rather +% frequently now by progressive \tex/ programmers. The \cw{relax} +% would ordinarily render the space after the file name unnecessary, +% but I prefer leaving the space in to avoid interfering with +% redefinitions of \cw{input} to take a space-delimited argument +% that are occasionally done to achieve other special effects (see, +% for example, ``Organizing a large collection of stylefiles'', by +% Angelika Binding, {\sl Cahiers GUTenberg}, num\'ero 10--11, +% septembre 1991, p.~175.) \latex/'s argument form +% \cw{input}\verb"{...}" cannot, unfortunately, be the +% canonical form if \plaintex/ compatibility is required. +% \begin{macrocode} +\expandafter\gdef\csname trap.input\endcsname + \input#1 \relax{% + \expandafter\ifx\csname#1\endcsname\relax + \afterfi\inputfwh{#1}\relax + \fi} +% \end{macrocode} +% \end{macro} +% +% End the group that encloses this entire file, and then call +% \cw{endinput}. +% \begin{macrocode} +\endgroup +\endinput +% \end{macrocode} +% +% \CheckSum{294} +% \Finale diff --git a/Master/texmf-dist/source/latex/dialogl/listout.dtx b/Master/texmf-dist/source/latex/dialogl/listout.dtx new file mode 100644 index 00000000000..fe31daa54e3 --- /dev/null +++ b/Master/texmf-dist/source/latex/dialogl/listout.dtx @@ -0,0 +1,5061 @@ +%%% ==================================================================== +%%% @TeX-file{ +%%% filename = "listout.dtx", +%%% version = "1.99a", +%%% date = "2013/01/24", +%%% author = "Michael Downes", +%%% copyright = "This file is part of the dialogl package, released +%%% under the LPPL; see dialogl.ins for details." +%%% 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.", +%%% } +%%% ==================================================================== +% +% \iffalse +%<*driver> +\documentstyle[doc,dialogl-doc]{article} +\title{Verbatim file printing: {\tt listout.tex}} +\author{Michael Downes} +\def\PrintMacroName#1{} +\setlength{\MacroTopsep}{\MacrocodeTopsep} +\setlength{\MacroIndent}{0pt} +\def\MacroFont{\Vbtmfont}% doc.sty uses \MacroFont +\DontCheckModules +\multicoldefaultlayout +\begin{document} +\maketitle +\begin{multicols}{2} +\hDocInput{listout.dtx} +\end{multicols} +\ifdim\textwidth>\textheight +\typeout{^^JWarning: remember to print using LANDSCAPE orientation^^J} +\fi +\end{document} +%</driver> +%\fi +% +%^^A Actual code lines are broken up to be 50 characters or less in +%^^A order to fit within narrow column widths in two-column style. +% +% \section*{Introduction} +% +% The tool \fn{listout.tex} has two purposes: +% +% (1)~Verbatim printing of text files such as +% e-\unpenalty mail, \tex/ log files, \tex/ macro files, or other +% programming source code or, in general, any \ascii/ text, with +% certain nice features that most printers and printer drivers +% lack: reasonably good, and somewhat customizable, handling of tab +% characters or other nonprinting characters; highly customizable +% handling of overlong lines; absolute control over margins, number +% of columns, intercolumn space, and line spacing; optional line +% numbering; customizable running heads and running feet; not to +% mention a few other things. +% +% (2)~To serve as a proving ground for ideas and functions from +% \fn{dialog.sty} and \fn{menus.sty}. \fn{Listout.tex} 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). +% +% \fn{Listout} was originally written for \plaintex/. It seems to +% work with \latex/ as well in the limited tests that I have done. +% +%^^A Use of \latex/ would require among other +%^^A things the following adjustments: Use \cs{c@page} instead of +%^^A \cs{pageno}; (nfss2) load math fonts and do other +%^^A \begin{document} processing. +% +% \fn{Listout} is a part of a package that goes by the name of +% {\bf dialogl}, which also includes the aforementioned +% \fn{dialog.sty} and \fn{menus.sty}. The {\bf dialogl} package is +% available on the Internet by anonymous ftp from {\sc ctan} +% (Comprehensive \tex/ Archive Network), \eg., \fn{ftp.shsu.edu} +% (USA), or \fn{ftp.dante.de} (Europe). +% +% For maximum portability, \fn{listout} uses in its menus only +% lowest-common-denominator ordinary printable \ascii/ characters +% in the range 32\ndash 126. +% +% Normal usage: +% +%^^V tex listout +% +% You will be prompted for the names of the files to be printed. But +% first, you will be offered a chance to enter the \fn{listout} menu +% system, which allows you to change options interactively at +% run-time. (If you want to save a set of option settings for later +% re-use, see selection \qc{\E} in the main menu.) +% +% \subsection*{Notation} +% +% Double-hat notation such as \verb'^^J' is used in this article +% for control characters, as in \texbook/. 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. +% +% In the beginning \fn{listout.tex} was written without any private +% control sequences. Eventually avoiding the use of private control +% sequences became too inconvenient so I abandoned that restriction. +% If it were redone from scratch I would privatize many of the +% control sequences defined here to better support the future +% possibility of using \fn{listout.tex} within arbitrary documents +% where name conflicts might arise. +% +% \section{Preliminaries} +% We begin by loading \fn{menus.sty}. As a matter of fact we won't +% really input the file: The following few lines are for information +% only, they will replaced by the contents of \fn{menus.sty} (and the +% subordinate files \fn{dialog.sty} and \fn{grabhedr.sty} during the +% generation of the executable file by docstrip. The reason is mainly +% to make it possible to have a single version of \fn{listout.tex} +% that runs under plain \tex/, \latex/ 2.09, and \latex/2e, but also +% (a little bit) to avoid the speed cost of searching for input files +% at run-time. +% \begin{macrocode} +%<*ignore> +\inputfwh{menus.sty} +\fileversiondate{listout.tex}{1.4r}{1994/12/02} +\ProvidesFile{listout.tex}[1994/11/10 v1.4r] +%</ignore> +% \end{macrocode} +% +% \mjd{Check if more catcodes must be added here:} +% \begin{macrocode} +\localcatcodes{\@{11}\~{13}\"{12}\:{12}} +% \end{macrocode} +% +% \section{Miscellaneous utility functions} +% +% The file \fn{dialog.sty} (called by \fn{menus.sty}) defines +% \cw{actively}, \cw{afterfi}, \cw{controlchars}, and +% \cw{otherchars}. +% +% \begin{macro}{\xmeaning} +% \cw{xmeaning} is a useful tool to convert the contents of a macro +% to all category 12 characters. This is applied to filenames when +% printing them to prevent problems from special characters such as +% \qc{\$} or \qc{\_} that might occur in a file name. +% +% The argument \qarg{1} should be a macro. +% \begin{macrocode} +\def\xmeaning#1{\xp@\xmeaningtrim\meaning#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xmeaningtrim} +% \begin{macrocode} +\def\xmeaningtrim#1->{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TRUE} +% \begin{macro}{\FALSE} +% \cw{TRUE} and \cw{FALSE} are Boolean constants. After +% \cw{let}\cw{sometest}\qc{\=}\cw{TRUE}, the variable \cw{sometest} +% can be used with \cw{if}. +% \begin{macrocode} +\def\TRUE{TT} +\def\FALSE{TF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@empty} +% \begin{macro}{\@iden} +% Borrow a couple of things from \latex/. +% \begin{macrocode} +\def\@empty{} +\def\@iden#1{#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Date and time} +% +% Some macros to help construct various date options. +% \begin{macro}{\datesepchar} +% \begin{macrocode} +\def\datesepchar{ } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\keepleadingzeros} +% \begin{macrocode} +\let\keepleadingzeros\FALSE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\twodigits} +% \cw{twodigits} adds a leading zero to a number if the number is +% less than 10. The \cw{expandafter} and \cw{ident} are to stop the +% scanning of \cw{number} so that something like +% \cw{twodigits}\verb'{35}' will not gobble a following space. (When +% the argument of \cw{twodigits} is a count register or similar +% complete integer according to \tex/'s scanning rules, this +% precaution is superfluous.) +% \begin{macrocode} +\def\twodigits#1{\ifnum#1<10 0\fi + \xp@\@iden\xp@{\number#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\themonth} +% \begin{macro}{\theday} +% \cw{themonth}, \cw{theday}, and similar macros must be +% reinitialized after the \fn{default.los} file is read, in case +% the value of \cw{keepleadingzeros} changes. +% \begin{macrocode} +\edef\themonth{\number\month} +\edef\theday{\number\day} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\theyear} +% \begin{macro}{\yearmodC} +% \begin{macrocode} +\edef\theyear{\number\year} +\edef\yearmodC{\xp@\@gobbletwo\number\year} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\Jan}\begin{macro}{\Feb}\begin{macro}{\Mar} +% \begin{macro}{\Apr}\begin{macro}{\May}\begin{macro}{\Jun} +% \begin{macro}{\Jul}\begin{macro}{\Aug}\begin{macro}{\Sep} +% \begin{macro}{\Oct}\begin{macro}{\Nov}\begin{macro}{\Dec} +% Month names. The default names are in English because that's this +% author's native language. Month names for other languages are not +% currently provided, perhaps in some future version. However +% alternate names can be gotten by hand editing the \fn{.los} file +% (`listout option settings') to change the definitions of +% \cw{Jan}, \cw{Feb}, etc. \begin{macrocode} +\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} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% +% \begin{macro}{\datesetup} +% Define \cw{monthname}, \cw{themon}, \cw{theMON} using the +% value of \cw{month}. +% \begin{macrocode} +\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}% +% \end{macrocode} +% Construct three-letter abbreviations. +% \begin{macrocode} + \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 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateA} +% Date form A: 1992-09-09. The hyphen can be changed to some other +% character by modifying \cw{datesepchar}. +% \begin{macrocode} +\def\dateA{% + \theyear\datesepchar\themonth\datesepchar\theday} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateB} +% Date form B: 92-09-09 +% \begin{macrocode} +\def\dateB{% + \yearmodC\datesepchar\themonth\datesepchar\theday} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateC} +% Date form C: 09-09-92. This one is ambiguous. Since the author is +% United-Statesian, let's go with the U.S. convention of month +% first. +% \begin{macrocode} +\def\dateC{% + \themonth\datesepchar\theday\datesepchar\yearmodC} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateD} +% Date form D: 09-09-1992 +% \begin{macrocode} +\def\dateD{% + \themonth\datesepchar\theday\datesepchar\theyear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateE} +% Date form E: 09-Sep-92 +% \begin{macrocode} +\def\dateE{% + \theday\datesepchar\themon\datesepchar\yearmodC} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateF} +% Date form F: 09-Sep-1992 +% \begin{macrocode} +\def\dateF{% + \theday\datesepchar\themon\datesepchar\theyear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateG} +% Date form G: 09-SEP-92 +% \begin{macrocode} +\def\dateG{% + \theday\datesepchar\theMON\datesepchar\yearmodC} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateH} +% Date form H: 09-SEP-1992 +% \begin{macrocode} +\def\dateH{% + \theday\datesepchar\theMON\datesepchar\theyear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateI} +% Date form I: September 9, 1992 (\cw{datesepchar} not used) +% \begin{macrocode} +\def\dateI{% + \themonthname\space\number\day, \theyear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dateJ} +% Date form J: 9 September 1992 (assuming \cw{datesepchar} set to +% space). +% \begin{macrocode} +\def\dateJ{% + \theday\datesepchar\themonthname\datesepchar\theyear} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\todaysdate} +% \cw{todaysdate} is assigned with \cw{def} rather than \cw{let} to +% facilitate writing out the information to an \fn{.los} file. +% \begin{macrocode} +\def\todaysdate{\dateJ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\thehour} +% Create \cw{thehour} holding two-digit number 00\ndash 23, number of +% hours from \cw{time}. +% \begin{macrocode} +\count@=\time \divide\count@ 60 +\edef\thehour{\twodigits\count@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\theminute} +% Create \cw{theminute} holding two-digit number 00\ndash 59, number +% of minutes from \cw{time} after subtracting $60*\cw{thehour}$. +% \begin{macrocode} +\multiply\count@ -60 \advance\count@\time +\edef\theminute{\twodigits\count@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ampmpunct} +% \begin{macrocode} +\def\ampmpunct{.} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ampm} +% \begin{macro}{\thehourmodtwelve} +% Define \cw{ampm} to be \verb"a" or \verb"p" (or +% \verb"noon"\meta{gobble} or \verb"midnight"\meta{gobble}), and +% define \cw{thehourmodtwelve} suitably. Notice that, unlike +% \cw{thehour}, \cw{thehourmodtwelve} omits a leading zero. +% \begin{macrocode} +\count@=\thehour\relax +\ifnum\count@>11 \def\ampm{p}% + \ifnum\count@>12 +% \end{macrocode} +% Convert hours in the range 13\ndash 23 to the range 1\ndash 11. +% \begin{macrocode} + \begingroup \advance\count@ -12 + \aftergroup\edef\aftergroup\thehourmodtwelve + \aftergroup{\xp@ + \endgroup \number\count@}% + \else + \edef\thehourmodtwelve{12}% + \fi +\else + \def\ampm{a}% +% \end{macrocode} +% Hour 0 needs to be translated to 12:?? a.m. +% \begin{macrocode} + \ifnum\count@=0 \count@=12 \fi + \edef\thehourmodtwelve{\number\count@}% +\fi +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\AMPM} +% Note that \cw{AMPM} should not be written to the \fn{.los} file: +% it needs to be recomputed at run-time using the current value of +% \cw{time}. The function \cw{changecase} is from \fn{dialog.sty}. +% \begin{macrocode} +\let\AMPM\ampm \changecase\uppercase\AMPM +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\midnoon} +% If the current time is midnight or noon, \cw{midnoon} prints the +% appropriate word and gobbles the `a.m.' or `p.m.' string. +% \begin{macrocode} +\def\midnoon#1{\ifnum\time=0 midnight\else + \ifnum\time=720 noon\else#1\fi\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timesepchar} +% \begin{macrocode} +\def\timesepchar{:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeA} +% Time form A: 1947 +% \begin{macrocode} +\def\timeA{\thehour\theminute} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeB} +% Time form B: 19:47 +% \begin{macrocode} +\def\timeB{\thehour\timesepchar\theminute} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeC} +% Time form C: 7:47 pm +% \begin{macrocode} +\def\timeC{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\ampm m}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeD} +% Time form D: 7:47 p.m. +% \begin{macrocode} +\def\timeD{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\ampm\ampmpunct m\ampmpunct}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeE} +% Time form E: 7:47 PM +% \begin{macrocode} +\def\timeE{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\AMPM M}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\timeF} +% Time form F: 7:47 P.M. +% \begin{macrocode} +\def\timeF{\thehourmodtwelve\timesepchar\theminute + \space\midnoon{\AMPM\ampmpunct M\ampmpunct}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nowtime} +% \cw{nowtime} is assigned with \cw{def} for the same reason as +% \cw{todaysdate}. +% \begin{macrocode} +\def\nowtime{\timeB} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Output routine} +% +% \begin{macro}{\curcol} +% \begin{macro}{\totalcols} +% \cw{curcol} is a counter to keep track of the current column +% number; \cw{totalcols} is a variable that indicates how many +% columns are desired. +% \begin{macrocode} +\chardef\curcol=1 +\chardef\totalcols=2 +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\firstpageno} +% \begin{macro}{\lastpageno} +% For multi-column output, a `page' number is associated to each +% column. At the time when a running head is attached to a column, +% the current `page' number is always \cw{lastpageno}. +% \begin{macrocode} +\countdef\firstpageno=1 +\countdef\lastpageno=2 +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prevcolsbox} +% When the number of columns $n$ is greater than 1, columns $1$, +% $\ldots$, $n-1$ are accumulated in \cw{prevcolsbox} before being +% shipped out. +% \begin{macrocode} +\newbox\prevcolsbox +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\paht} +% \begin{macro}{\pawd} +% Paper height and width. +% \begin{macrocode} +\newdimen\paht \newdimen\pawd +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\fullwd} +% The `full width' is the width of all the $n$ columns plus $(n-1) +% * \btext{intercolumn}\linebreak[0]\btext{space}$. Normally it is +% computed at run time from paper size, number of columns and +% intercolumn space. +% \begin{macrocode} +\newdimen\fullwd +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\colwd} +% Column width is computed from number of columns, paper size, +% margins, and intercolumn space, unless it is explicitly set to a +% given width by the user, in which case \cw{fullwd} is computed from +% number of columns, column width, and intercolumn space, and a +% warning is given if \cw{fullwd} plus the margins exceeds paper +% width. In other words, in the system of equations +% \xdef\restorearraycolsep{\arraycolsep \the\arraycolsep\relax}% +% \arraycolsep1pt\relax +% \begin{eqnarray} +% \cw{rightmargin} &=& \cw{leftmargin}\label{rl}\\ +% \cw{fullwd} &=& \cw{paperwd} - \cw{leftmargin}\nonumber\\ +% &&{} - \cw{rightmargin}\\ +% \cw{colwd} &=& \frac{\cw{fullwd} +% + \cw{intercolspace}}{\cw{totalcols}}\nonumber\\ +% &&{} - \cw{intercolspace} +% \end{eqnarray} +% \restorearraycolsep +% the variables on the left-hand side in each equation are the +% dependent variables. If the user sets the right margin +% explicitly, we delete equation (\ref{rl}) from the system; or if +% the user sets column width explicitly, we change the status of +% the \cw{colwd} variable from dependent to independent, which may +% be thought of as switching to the equations +% \xdef\restorearraycolsep{\arraycolsep \the\arraycolsep\relax}% +% \arraycolsep0pt\relax +% \begin{eqnarray} +% \cw{fullwd} &=& ((\cw{colwd} +\cw{intercolspace})\nonumber\\ +% && {}\times \cw{totalcols})\nonumber\\ +% && {}- \cw{intercolspace}\\ +% \cw{rightmargin} &=& \cw{paperwd} - \cw{leftmargin}\nonumber\\ +% && {}- \cw{fullwd} +% \end{eqnarray} +% \restorearraycolsep +% +% \begin{macrocode} +\newdimen\colwd +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dependentcolwd} +% \begin{macrocode} +\let\dependentcolwd\TRUE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\leftmargin} +% \begin{macro}{\rightmargin} +% \begin{macrocode} +\newdimen\leftmargin +\newdimen\rightmargin +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\dependentrightmargin} +% \begin{macrocode} +\let\dependentrightmargin\TRUE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\computerfc} +% \mjd{Maybe change this and related names to computeRFC (caps)?} +% Function to find \cw{rightmargin}, \cw{fullwd}, and \cw{colwidth}. +% \begin{macrocode} +\def\computerfc{\relax \rightmargin=\leftmargin + \computefc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\computefc} +% +% Find \cw{fullwd} and \cw{colwd} but leave \cw{rightmargin} as is. +% \begin{macrocode} +\def\computefc{\fullwd=\pawd + \advance\fullwd-\leftmargin + \advance\fullwd-\rightmargin + \colwd\fullwd + \advance\colwd \intercolspace + \divide\colwd \totalcols + \advance\colwd -\intercolspace +% \end{macrocode} +% \cw{columnwidth} is the version of \cw{colwd} reported to the user. +% If it is set explicitly, the original form is retained, otherwise a +% width value given by the user as `5cm' would be reported as +% `142.26378pt'. But here we are computing the column width, so +% we do not try to make the raw points value more presentable. +% \begin{macrocode} + \edef\columnwidth{\the\colwd}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\computefr} +% +% Find \cw{fullwd} and \cw{rightmargin} from a specified column +% width. +% \begin{macrocode} +\def\computefr{\fullwd\colwd + \advance\fullwd \intercolspace + \multiply\fullwd \totalcols + \advance\fullwd -\intercolspace + \rightmargin\pawd + \advance\rightmargin-\leftmargin + \advance\rightmargin-\fullwd +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\colht} +% Unless explicitly set to a given value by the user, bottom margin +% and column height are computed from paper size and top margin, +% starting with bottom margin = top margin and then rounding the +% column height to an integral number of lines (with the usual +% adjustment for \cw{topskip}). +% \begin{macrocode} +\newdimen\colht +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\intercolspace} +% \begin{macro}{\overrun} +% \begin{macrocode} +\newdimen\intercolspace \newdimen\overrun +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\runheadht} +% \begin{macro}{\runfootht} +% \cw{runheadht} is the height of the running head, including space +% below it. \cw{runfootht} is similar. +% \begin{macrocode} +\newdimen\runheadht \newdimen\runfootht +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bottommargin} +% \begin{macro}{\topmargin} +% \begin{macrocode} +\newdimen\bottommargin \newdimen\topmargin +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\computebc} +% \begin{macrocode} +\def\computebc{\bottommargin=\topmargin \computec} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\computec} +% \mjd{Maybe this should be named computeHB (height/bottom)} +% This function is called if the user sets a new top or bottom +% margin, because in that case we need to recompute \cw{colht} to +% compensate. +% \begin{macrocode} +\def\computec{% +% \end{macrocode} +% Find $\cw{colht} = \cw{paperht} - \cw{topmargin} - +% \cw{bottommargin}$, rounded off to nearest multiple of the line +% spacing. +% \begin{macrocode} + \colht\paht \advance\colht -\topmargin + \advance\colht -\bottommargin + \advance\colht -\runheadht + \advance\colht -\runfootht + \roundcolht +% \end{macrocode} +% Adjust \cw{bottommargin} to fit with the new \cw{colht}. +% \begin{macrocode} + \bottommargin\paht + \advance\bottommargin -\topmargin + \advance\bottommargin -\colht +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\roundcolht} +% \cw{roundcolht} rounds \cw{colht} to the nearest integer multiple +% of the line spacing. +% \begin{macrocode} +\def\roundcolht{% + \advance\colht .5\baselineskip + \divide\colht\baselineskip + \edef\columnheight{\number\colht\space lines}% + \multiply\colht\baselineskip +% \end{macrocode} +% Compensate for \cw{topskip}: +% \begin{macrocode} + \advance\colht\topskip + \advance\colht -\baselineskip +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\dependentcolht} +% \begin{macro}{\dependentbottommargin} +% \begin{macrocode} +\let\dependentcolht\TRUE +\let\dependentbottommargin\TRUE +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\computeb} +% The function \cw{computeb} is called to recompute \cw{colht} and +% \cw{bottommargin} if the user gives an explicit value for +% \cw{colht}. +% \begin{macrocode} +\def\computeb{% +% \end{macrocode} +% Round \cw{colht} off to nearest multiple of the line spacing. +% \begin{macrocode} + \roundcolht +% \end{macrocode} +% Adjust \cw{bottommargin} to fit with the new \cw{colht}. +% \begin{macrocode} + \bottommargin\paht + \advance\bottommargin -\topmargin + \advance\bottommargin -\colht +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pageno} +% If \latex/ is being used, \cw{pageno} will be undefined; we then +% provide a suitable definition. +% \begin{macrocode} +\ifx\UndEFiNed\pageno \countdef\pageno=0 \fi +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pagenumber} +% We retain \cw{pageno} as the number of shipouts (\ie., sheets +% of paper, if printing normally). The logical `page' number within +% the file being printed, at the time \cw{pagenumber} is called, is +% always \cw{lastpageno}. +% \begin{macrocode} +\def\pagenumber{[\number\pageno]\thinspace{% + \csname\pagenumberfont + \pagenumberfontsize\endcsname + \number\lastpageno}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\landscape} +% Switch for portrait versus landscape. +% \begin{macrocode} +\let\landscape=\TRUE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pagenumbermessage} +% A message to show at run-time how the pages are being put +% together. In the simplest case, when there is only one text +% column per sheet of paper, this message would be silly, so we +% wrap it in a condition. +% \begin{macrocode} +\def\pagenumbermessage{% + \ifnum\totalcols>\@ne + \message{% +Printing `pages' \the\firstpageno--\the\lastpageno +\space on \if\landscape landscape \fi sheet +\the\pageno}% +% \end{macrocode} +% Here I wanted to add the following line, but nay, let it be +% omitted to support the unlikely, but not totally unreasonable, +% possibility that different files in the same run might have +% different number of columns per page. +% \begin{macrocode} +% \else \gdef\pagenumbermessage{}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Ncols} +% +% \begin{macrocode} +\def\Ncols{\relax + \ifnum\curcol=\totalcols + \pagenumbermessage + \shipout\hbox to\fullwd{% + \unhbox\prevcolsbox\curcolbox}% +% \end{macrocode} +% \cw{pageno} is the number of the actual sheet of paper on which +% we are currently printing. +% \begin{macrocode} + \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 +% \end{macrocode} +% Maximum number of columns = 20. The preliminary \cw{edef} +% step is necessary because \cw{mathchardef} makes \cw{curcol} = +% \cw{relax} before scanning the number on the right-hand side of +% the assignment, so that it would choke the \cw{ifcase}. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\runhead} +% \begin{macro}{\runfoot} +% We use \cw{runhead} and \cw{runfoot} instead of \cw{headline} and +% \cw{footline}, to reduce the possibility of conflict if this +% utility is used in conjunction with some other output routine. +% (Future possibility, not yet implemented: allow calling of this +% utility from within \latex/ or another macro package with its own +% output routine.[mjd,20-Sep-1993]) +% \begin{macrocode} +\newtoks\runhead \newtoks\runfoot +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\loheadline} +% The test at the beginning here is to avoid problems when the +% headline is wider than the column width; in that case only print +% one headline over all the columns instead of a headline for each +% column. If \qarg{1} = \cw{colwd}, it means that the headline fits +% within \cw{colwd}: print a headline for each column; otherwise +% print a headline only if \cw{curcol} = 1, and let it overlap over +% all the columns. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lofootline} +% As for the headline, we print a single footline across all +% columns if the footline width is greater than \cw{colwd}. +% \begin{macrocode} +\def\lofootline#1{\relax + \if \ifdim#1=\colwd T\else + \ifnum\curcol=1 T\else F\fi\fi T% + \nointerlineskip +% \end{macrocode} +% The \cw{vfil} pushes the footline to the bottom of the vbox; the +% \cw{vfilneg}\cw{vss} at the end is just a compact way of writing +% \cw{vskip} {\tt 0pt minus1fil}, meaning let the footline hang out +% the bottom of the box if necessary, without giving an overfull +% vbox message. +% \begin{macrocode} + \vbox to\runfootht{\vfil\rlap{\hbox to#1{% + \csname\runheadfont\runheadfontsize\endcsname + \the\runfoot}}\kern-\prevdepth + \vfilneg\vss}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\setupheadlineandfootline} +% Define how headline and footline are applied. If the running head +% or running foot is too wide to fit within \cw{colwd}, then +% \cw{hfwd} (headline/footline width) is defined to be \cw{fullwd}. +% Cf.\ the comments for \cw{loheadline}. +% \begin{macrocode} +\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 +% \end{macrocode} +% Print \cw{null} box for the headline rather than nothing, so that +% the \cw{vtop} in \cw{curcolbox} will work. +% \begin{macrocode} + \gdef\curcolbox{% + \vtop{\null\unvbox255 }}% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Tab handling} +% +% Well, at first I was only going to make tabs expand to a fixed +% number of spaces regardless of where they happened to fall in the +% line. This would work fine for tabs that fall at the beginning of a +% line. But there are certain other reasonable possibilities in +% program source code, e.g. assembly-language style comments that +% start in column 40 or so, or tables of information. +% The alignment in such cases can be preserved by setting a +% box at the beginning of each line and then, when a tab comes +% along, measuring the width of the line so far to figure out how +% many characters it contains. Of course this is impossible unless +% the font being used is monospace. But given that, and +% given a specified width in characters of each tab, it's possible to +% find the distance remaining to the next tab stop. +% +% \begin{macro}{\tableaderbox} +% Box used with \cw{leaders} to represent tab characters. +% \begin{macrocode} +\newbox\tableaderbox +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\spacespertab} +% The most common convention for printing tabs is eight spaces. +% Some people may prefer printing fewer. +% \begin{macrocode} +\chardef\spacespertab=8 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabwidth} +% \cw{tabwidth} is the width to be used for tab characters. Usually +% a multiple of (monospaced-font) character width and +% \cw{spacespertab}. +% \begin{macrocode} +\newdimen\tabwidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\printtaba} +% The function \cw{printtaba} is called when we are in the middle +% of typesetting an \cw{hbox} to \cw{hsize} (cf +% \cw{newunnumberedline}). +% \begin{macrocode} +\def\printtaba{% +% \end{macrocode} +% Finish the hbox. The \cw{hfil} is just to prevent an underfull +% hbox message, it will be removed next. Using \cw{hfil} to supress +% the message seems to be better than using \cw{hbadness}, because +% the current box is being set to \cw{hsize} instead of natural +% size so it will have to be reboxed anyway (therefore the +% \cw{unskip} step costs little); and if \cw{hbadness} were set to +% 10000 then overfull messages would also be suppressed, which is +% unnecessary and even slightly undesirable. +% \begin{macrocode} + \hfil\egroup + \setbox\z@\hbox{\unhbox\z@ \unskip}% +% \end{macrocode} +% Compute \cw{dimen@}, the distance remaining to the next tab stop +% (the next integer multiple of \cw{tabwidth} that is greater than +% the width of box 0). +% \begin{macrocode} + \dimen@\wd\z@ \divide\dimen@\tabwidth + \multiply\dimen@\tabwidth + \advance\dimen@\tabwidth + \advance\dimen@ -\wd\z@ +% \end{macrocode} +% Restart the line, adding leaders to the appropriate width. +% \begin{macrocode} + \setbox\z@\hbox to \hsize\bgroup \unhbox\z@ + \spacebreak\hbox to\dimen@{% + \leaders\copy\tableaderbox\hfil}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newfileprinttab} +% Print a message when a tab is encountered in the current file. +% But after the first tab, don't send any more messages, until a +% new file is started. +% \begin{macrocode} +\def\newfileprinttab{\printtaba + \message{% +Say, this file contains a tab character}% + \global\let\printtab\printtaba} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\printtab} +% \begin{macrocode} +\let\printtab=\newfileprinttab +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\charwidth} +% Variable to hold the width of one character in the current font. +% (Monospace font assumed.) +% \begin{macrocode} +\newdimen\charwidth +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\inittabs} +% \cw{inittabs} assumes that the proper font has already been +% selected. +% \begin{macrocode} +\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. +% \end{macrocode} +% The plus and minus for the first hskip are to avoid underfull +% hbox messages from rounding errors in summing the em dimensions. +% \begin{macrocode} + \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. +% \end{macrocode} +% The font used for the small letters is always 5pt roman\mdash no +% user choice here. +% \begin{macrocode} + \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 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tabstyle} +% \begin{macrocode} +\def\tabstyle{\ifcase\tabselect blank space\or + dots\or dashed lines\or horizontal rules\else + tiny TABs\fi} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Printing non-printable characters} +% The `invisible' control characters \ascii/ 0\ndash 31 and 127 need +% special handling if they occur in the text being printed. For +% \ascii/ 9 and 13, tab and carriage return, there is a generally +% accepted way to print them, but for the others there are no +% standards. So the chosen method here is to print a boxed letter: +% boxed A for \ctrl{A}, boxed B for \ctrl{B}, and so forth. One +% other exception seems to be convenient: \ctrl{L} (form feed) is +% defined to act as a `newpage' command (`newcolumn' if +% \cw{totalcols} is greater than 1). +% +% For characters 128\ndash 255 there are generally accepted ways to +% print them. The trouble is, there are too many different +% generally accepted ways: the Macintosh way, the IBM PC codepage +% ways (several different codepages), the DC font encoding way, the +% DEC multinational character set way, the KOI-8 way, and many many +% others. And most of these ways would require their own font, as +% they include characters not found in the \fn{cmtt} character set. +% Therefore I do not attempt here to do anything very useful with +% characters $>$ 127, but only set them up to print a boxed +% question mark and a warning about `unspecified character'. +% If you're interested in helping me expand the capabilities of +% \fn{listout} in this area, particularly regarding the font +% complications, let me know. +% +% \begin{macro}{\charboxsidekern} +% \begin{macro}{\charboxstrut} +% \cw{charboxstrut} is initialized in \cw{listout} after the font +% is set. +% \begin{macrocode} +\newdimen\charboxsidekern +\charboxsidekern=.3pt +\newbox\charboxstrut +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\characterbox} +% Function to print a box around a given character. +% \begin{macrocode} +\def\characterbox#1{% +% \end{macrocode} +% The width of the hbox is set to preserve alignment of characters +% across lines if we have a normal tt font with the width of all +% characters = .5\units{em}. In order for the enclosed character +% to be slightly more readable, we allow the vertical rules to +% partly overlap outside the .5\units{em} space instead of lapping +% them entirely inward. +% \begin{macrocode} + \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 +% \end{macrocode} +% A vertical strut is inserted to ensure a certain minimum height +% of the box even if say the enclosed character has practically no +% height (\eg. underscore). +% \begin{macrocode} + \copy\charboxstrut}% + \dimen4 \prevdepth + \advance\dimen4 \charboxsidekern + \advance\dimen@ \dimen4 + \hrule depth\dimen@ height -\dimen4 + }% + \kern\dimen@ii\vrule width\dimen@\hss}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlchara} +% Define the control characters \ascii/ 0\ndash 31 and 127 to print a +% warning and a boxed letter. \ctrl{I}, \ctrl{L}, \ctrl{M} (tab, +% formfeed, carriage return) will receive overriding definitions +% later. +% \begin{macrocode} +\def\controlchara#1{% + \message{Warning: +Invisible control character, printing boxed letter}% + \characterbox{#1}% + \gdef\controlchar##1{% + \message{@}\characterbox{##1}}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlchar} +% \begin{macrocode} +\def\controlchar{\controlchara} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlcharassignments} +% \begin{macrocode} +\newtoks\controlcharassignments +% \end{macrocode} +% \end{macro} +% +% Start a group to localize the changes to lccodes, \cw{do}, etc. +% \begin{macrocode} +\begingroup +% \end{macrocode} +% For \eg. \ctrl{A} we want to issue a warning message and print a +% boxed capital A character. To get the cap A from the control +% character \ctrl{A} which \cw{controlchars} provides, we turn it +% into a number and add 64, then use the result with \cw{lccode} to +% get a category-12 character inside the definition being +% constructed. +% \begin{macrocode} +\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{.}}}}% +} +% \end{macrocode} +% +% \begin{macrocode} +\xp@\do\controlchars{a \@gobbletwo} +\endgroup +% \end{macrocode} +% +% \begin{macro}{\unknownchar} +% \begin{macro}{\unknownchara} +% +% Define characters in the range \ascii/ 128\ndash 255 to print as a +% boxed question mark, with a warning. Those who have DC fonts or +% other fonts with 256 characters instead of 128 might want to change +% this behavior, but the default is chosen so as not to cause trouble +% for those who are currently handicapped with 128-character fonts +% (including myself \ldots). There is also the problem that in an +% arbitrary file being printed, the original intended interpretation +% of characters above \ascii/ 127 may vary widely, and more often +% than not, perhaps, will not correspond properly to the characters +% in the high 128 positions of the currently selected font. For +% example, it's not clear how useful it would be to print out a file +% coded for Russian characters in the high 128 with a font that uses +% the DC character set. +% +% \begin{macrocode} +\def\unknownchara{% + \xmesj{Warning: Unspecified character + (system-dependent interpretation);\ + printing question mark instead}% + \characterbox{?}% + \gdef\unknownchar{\message{?}\characterbox{?}}% +} +% +\def\unknownchar{\unknownchara} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eightbitaction} +% \begin{macrocode} +\def\eightbitaction{B} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\highASCIIassignments} +% \begin{macro}{\highBSCIIassignments} +% \begin{macrocode} +\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 +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{File name titles} +% +% \begin{macro}{\thisfilename} +% Variable to hold the name of the current file being printed. To +% be determined at run-time. +% \begin{macrocode} +\def\thisfilename{??} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\printtitles} +% If \cw{printtitles} is true then the name of each file is printed +% at the beginning of each file as a centered title, with some +% space above and below. +% \begin{macrocode} +\let\printtitles=\TRUE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@dogobble} +% Auxiliary function to help in ending a recursive \cs{do} +% operation. +% \begin{macrocode} +\def\@dogobble#1\do{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nonttfont} +% If \cw{titlefont} is not a tt font, then \qc{\_} will not print +% properly; to get around this we print the title in math mode with +% \cw{textfont}1 = \cw{titlefont}, just so that we can use +% \cw{mathcode}"8000 to make the underscore pseudo-active. This is +% convenient because all characters of \cw{thisfilename} were +% converted to category 12 by \cw{xmeaning}, and mathcode "8000 +% allows us to use any underscore characters already present +% instead of replacing them by active characters. The alternative +% would be to pick apart \cw{thisfilename} looking for \qc{\_} +% characters and replace them by active \qc{\_} or by \cs{\_}; but +% that seems like more work. For certain other characters (less +% likely to occur in file names) there is the same problem. +% \begin{macrocode} +\def\nonttfont#1{% +% \end{macrocode} +% Reset mathcodes of all nonalphanumeric visible characters, since +% some of them (\eg., period) have mathcodes that point to +% unexpected font positions. Yes, this is overkill, but it's +% simpler to program and more likely to be robust against unknown +% future changes in font layouts. +% \begin{macrocode} + \def\do##1{\mathcode`##1`##1 \do}% + \xp@\do\otherchars{.`.\relax \@dogobble}% +% \end{macrocode} +% Furthermore, the characters \qc{\<} \qc{\>} \verb*" " (space) +% \qc{\_} \qc{\{} \qc{\|} \qc{\}} \qc{\~} do not have adequate +% representatives in their \ascii/ positions in normal \tex/ text +% fonts (other than \fn{cmtt}). So we mathcode them to pull some +% reasonable approximations out of \cw{textfont2} (\fn{cmsy10}), +% except for underscore, which we mathcode to \verb/"8000/ (active) +% and define to produce a horizontal rule, and space, which we +% leave alone. +% \begin{macrocode} + \mathcode`\<"268 \mathcode`\>"269 + \mathcode`\\"26E \mathcode`\_"8000 + \mathcode`\{"266 \mathcode`\|"26A + \mathcode`\}"267 \mathcode`\~"218 +% \end{macrocode} +% Finally, we make the double-quote character active so that it +% will produce a double-prime symbol rather than a directional +% close-quotes character, which would be ambiguous with two single +% apostrophes. +% \begin{macrocode} + \mathcode`\""8000 +% \end{macrocode} +% Change the definition of active \qc{\_} to produce a thicker and +% wider rule. +% \begin{macrocode} + \actively\def\_{% + \leavevmode\kern.06em\vbox{% + \hrule width.4em height.06em}}% +% \end{macrocode} +% Define active \qc{\"} character to produce double-prime. +% \begin{macrocode} + \actively\def\"{^{\prime\prime}}% + \textfont\z@ + \csname\titlefont\titlefontsize\endcsname +% \end{macrocode} +% On general principles we initialize \cw{everymath} and +% \cw{mathsurround} to make sure they don't do anything abnormal. +% \begin{macrocode} + \everymath{}\mathsurround\z@ + $\fam\z@#1$% +} +% \end{macrocode} +% \end{macro} +% +% The list of system types and associated directory separator +% characters is determined arbitrarily as the systems that I happen +% to have experience with. If you want to see your favorite system +% added to the list write to me at the e-mail address given above +% \ldots +% +% \begin{macro}{\DOSdirsepchar} +% \begin{macrocode} +\escapechar=-1 +\edef\DOSdirsepchar{\string\\} +\escapechar=`\\ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Macintoshdirsepchar} +% \begin{macrocode} +\def\Macintoshdirsepchar{:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Unixdirsepchar} +% \begin{macrocode} +\def\Unixdirsepchar{/} +\xp@\def\csname VAX/VMSdirsepchar\endcsname{]} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\chopname} +% +% The function \cw{chopname} chops up a filename looking for the +% characters that separate directory components from filename +% components; this is in order to add an \cw{allowbreak} between +% directory and filename if an explicit directory is included in +% the given file name, so that when printing the file name in a +% title, it will break into two lines if there isn't enough room +% for the whole thing to fit on one line. +% +% \cw{chopname} is intended to be called only after \cw{xmeaning} has +% been applied to convert all constituent characters of \qarg{1} to +% category 12. +% +% Test cases: +% +%^^V \def\systemtype{Unix} +%^^V \def\test{goo/bar/flab/rtex} +%^^V \chopname\test \show\test +%^^V \def\test{rtex} +%^^V \chopname\test \show\test +%^^V +%^^V \def\systemtype{VAX/VMS} +%^^V \def\test{goo:[bar.flab]rtex} +%^^V \chopname\test\show\test +%^^V \def\test{rtex} +%^^V \chopname\test\show\test +% +% \begin{macrocode} +\def\chopname#1{% + \edef\dirsepchar{% + \csname\systemtype dirsepchar\endcsname}% + \edef\@tempa{% + \def\nx@\do####1\dirsepchar}% + \@tempa +% \end{macrocode} +% What we get here from \cw{@tempa} is something like +% the following line. +% \begin{macrocode} +% \def\do##1/% + ##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@ +% \end{macrocode} +% And finally, if \cw{dirprefix} is not empty, add it. +% \begin{macrocode} + \ifx\@empty\dirprefix + \else + \edef#1{\xmeaning\dirprefix\allowbreak#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\printtitle} +% Function to typeset the title of the current file. +% \begin{macrocode} +\def\printtitle{% +% \end{macrocode} +% This \cw{bigskip} will be discarded following \tex/'s normal rules +% if each file starts on a new page or column. +% \begin{macrocode} + \bigskip + \centerline{% + \csname\titlefont\titlefontsize\endcsname +% \end{macrocode} +% Add an \cw{allowbreak} between directory and filename if an +% explicit directory is included in the given file name. +% \begin{macrocode} + \chopname\thisfilename +% \end{macrocode} +% If the interword stretch of \cw{titlefont} is 0, then it is +% [almost surely] a tt font. But otherwise, special handling is +% required in order to make sure that the characters +% \verb/_ < > \ { | } ~/ print OK. +% \begin{macrocode} + \ifdim\fontdimen3\font=\z@ + \csname\titlecase\endcsname + \xp@{\thisfilename}% + \else + \csname\titlecase\endcsname + \xp@{\xp@ + \nonttfont\xp@{\thisfilename}}% + \fi + }% end \centerline +% \end{macrocode} +% If new file doesn't start a new column, use a smaller space below +% the title than would otherwise be used. +% \begin{macrocode} + \if S\newfileoption \smallskip + \else\bigskip\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newfileoption} +% Variable that selects the desired action at the beginning of a +% new file. +% \begin{macrocode} +\def\newfileoption{P} +% \end{macrocode} +% \end{macro} +% +% \mjd{Is \cw{eject} defined in LaTeX?} +% \begin{macro}{\newfileS} +% Option S (space): Tack on the next file immediately after the +% previous one, without even ending the current column (unless +% there are only a couple of lines of space left on it). Assumes +% that \cw{printtitle} will add some vertical space. +% \begin{macrocode} +\def\newfileS{% + \dimen@\pagegoal \advance\dimen@-\pagetotal + \ifdim\dimen@<3\baselineskip + \xp@\eject\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newfileC} +% Option C: Finish the current column. +% \begin{macrocode} +\def\newfileC{\vfil\eject} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newfileP} +% Option P: Force a new page (= sheet of paper). +% \begin{macrocode} +\def\newfileP{% + \vfil\eject + \loop +% \end{macrocode} +% Repeat until \cs{curcol} resets to 1. +% \begin{macrocode} + \ifnum\curcol>\@ne + \hbox to\colwd{% + \vrule width\z@ depth\vsize\hfil}% + \eject + \repeat +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newfileR} +% Option R: Force right-hand column (\cw{totalcols} = 2 assumed). +% \begin{macrocode} +\def\newfileR{\vfil\eject + \ifnum\curcol=\@ne + \hbox to\colwd{% + \vrule width\z@ depth\vsize\hfil}% + \xp@\eject + \fi +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Line numbering} +% +% \begin{macro}{\linenumberfreq} +% \begin{macro}{\linecount} +% \begin{macro}{\linesubcount} +% \begin{macrocode} +\newcount\linenumberfreq \linenumberfreq=1 +\newcount\linecount +\newcount\linesubcount +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\printlinenumber} +% +% \begin{macrocode} +\def\printlinenumber{\llap{% + \global\advance\linecount\@ne + \global\advance\linesubcount\@ne + \ifnum\linesubcount=\linenumberfreq + \lnfnt \the\linecount\space + \global\linesubcount\z@ + \fi +}}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\spacebreak} +% \begin{macrocode} +\def\spacebreak{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\markedbreak} +% \begin{macrocode} +\def\markedbreak{\penalty\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\noextralinebreaks} +% \begin{macrocode} +\let\noextralinebreaks=\TRUE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newunnumberedline} +% \begin{macrocode} +\def\newunnumberedline{\hskip\rightskip \egroup + \box\z@ \controlLbreak + \setbox\z@\hbox to\hsize\bgroup}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\newnumberedline} +% \begin{macrocode} +\def\newnumberedline{% + \newunnumberedline\printlinenumber}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\unnumberedbreakingline} +% \begin{macrocode} +\def\unnumberedbreakingline{\relax +% \end{macrocode} +% \cw{noindent} \cw{unhbox}0 \cw{endgraf} produces only \cw{parskip} +% if box 0 is empty, when what we really want is a full baselineskip +% (a blank line) because box 0 empty means two consecutive \ctrl{M} +% characters; so we check if box0 is empty by looking at +% \cw{lastpenalty} to see if it is the same as the penalty that we +% added at the beginning and if so throw in a \cw{null} to make sure +% the line won't disappear. +% \begin{macrocode} + \ifnum\lastpenalty=\@ne \null\fi + \hskip\rightskip\egroup + \hfuzz \p@ + \noindent\unhbox\z@ % +% \end{macrocode} +% Notice that the normal \tex/ action at end of paragraph will +% remove the \cw{hskip} that was added before the \cw{egroup} of the +% \cw{setbox} operation. We also employ a hangindent of 1em to give +% some indication of line breaks, if they occur. +% \begin{macrocode} + {\hangindent1em + \parfillskip\z@ plus1fil \endgraf}% +% \end{macrocode} +% We need to prevent overfull rules from being added inside at the +% end of the \cw{hbox}, because there's no way to break off the rule +% from the end of the horizontal list once it gets in there. +% \begin{macrocode} + \hfuzz\maxdimen + \controlLbreak + \setbox\z@\hbox to\hsize\bgroup \penalty\@ne +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\numberedbreakingline} +% +% \begin{macrocode} +\def\numberedbreakingline{% + \unnumberedbreakingline\printlinenumber} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@sptoken} +% +% \begin{macrocode} +\lowercase{\let\@sptoken= } % +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CR} +% Action performed at end of line. Can vary according to whether +% line numbers are wanted and whether overlong lines are allowed to +% break. +% \begin{macrocode} +\let\CR\newunnumberedline +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\CRSPsetup} +% +% Setup for carriage returns and spaces. We need to prevent spaces +% from disappearing at the beginning of a line, and also optionally +% prevent line breaks. +% +% \begin{macrocode} +\def\CRSPsetup{% + \setupbreakingchars + \if\noextralinebreaks + \overrun\rightmargin +% \end{macrocode} +% NOTE: the space after the \qc{\=} is mandatory because of the way +% \cw{@sptoken} is defined: +% \begin{macrocode} + \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 +% \end{macrocode} +% Parfillskip not needed, \cw{rightskip} suffices. +% \begin{macrocode} + \parfillskip\z@skip +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Main printing function} +% +% \begin{macro}{\listout} +% The \cw{listout} function takes a file name argument, the name of +% a file to be printed verbatim. +% \begin{macrocode} +\def\listout#1{\endgraf + \begingroup +% \end{macrocode} +% Setup that may not need to be done for each file. If +% \cw{interactive} is \cw{TRUE}, this is reset to no-op since it's +% not possible for the user to change any settings between files. +% \begin{macrocode} + \listoutsetup +% \end{macrocode} +% Convert \qarg{1} to all category 12 characters using \cw{meaning}. +% This prevents problems when we print the file name if it contains +% things like \qc{\$} or \qc{\_} characters. +% \begin{macrocode} + \gdef\thisfilename{#1}% + \xdef\thisfilename{\xmeaning\thisfilename}% + \if\printtitles \printtitle \fi +% \end{macrocode} +% Setup up needing to be redone for each file, or that only applies +% to the body of the file, not to the title. +% \begin{macrocode} + \listoutmoresetup + \CRSPsetup + \hfuzz\maxdimen + \setbox\z@\hbox to\hsize\bgroup \penalty\@ne + \input#1 \hfil\egroup +% \end{macrocode} +% Ignore the final contents of box 0 since they are just the (null) +% material between the file-ending \qc{\^^M} and the above +% \cs{egroup}. +% +% Reset \cw{hfuzz} to normal in case temporary value of +% \cw{maxdimen} persists somehow. +% \begin{macrocode} + \hfuzz\p@ +% \end{macrocode} +% Add a penalty to force \cw{pagetotal} to be updated with the +% height of the preceding line. +% \begin{macrocode} + \penalty0 % + \csname newfile\newfileoption\endcsname +% \end{macrocode} +% Ensure that everything gets shipped out even if this is the last +% file in a noninteractive use of \fn{listout.tex} (where control may +% return after the \cw{endgroup} to a different output routine). +% This is a complicated question. The \cw{patchoutput} possibility +% to make this work from inside a larger macro package is commented +% out until such time as it can be done right.[mjd,21-Sep-1993] +% \begin{macrocode} + \ifvoid\prevcolsbox + \else + \savelistoutimage +%{\tracingonline=1 \showboxbreadth=\maxdimen +% \showboxdepth=9 \showbox\prevcolsbox}% +% \afterfi\patchoutput + \fi + \endgroup } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\patchedoutputroutine} +% +% \begin{macrocode} +%\let\patchedoutputroutine\FALSE +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\patchoutput} +% +% \begin{macrocode} +%\def\patchoutput#1{% #1 to remove the \endgroup +% \endgroup +% \relax\if\patchedoutputroutine +% \else +% \global\let\patchedoutputroutine\TRUE +% \edef\next{% +% \output{% +% \box\prevcolsbox +% \global\holdinginserts\the\holdinginserts\relax +% \unvbox255 \relax +% \global\let\nx@\patchedoutputroutine\nx@\FALSE +%% 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}}. +% \toks@{\the\output}% +% \global\nx@\xp@\output\nx@\the\toks@ +% }% +%%\showthe\output +% }% +% \global\holdinginserts1 +% \fi +% \next} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\savelistoutimage} +% For \cw{listoutimage} we only need to save those parameters that +% are used when shipping out a page. +% \begin{macrocode} +\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 + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reportlayout} +% Some of the line breaks in the following code are merely to +% facilitate printing the documentation in narrow columns. +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\listoutsetup} +% +% \begin{macrocode} +\def\listoutsetup{% + \output{\Ncols}% + \loadfonts + \csname\mainfont\mainfontsize\endcsname +% \end{macrocode} +% Preexpand line number font for faster execution, since it is +% repeated on every line if line numbering is turned on. +% \begin{macrocode} + \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@ +% \end{macrocode} +% Reduce the size of \cw{overfullrule} so that if a too-long line +% overprints, there is a better chance to read what lies underneath +% at the end. But we still get visual identification of overlong +% lines. +% \begin{macrocode} + \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 +% \end{macrocode} +% If extra line breaks are allowed, we want to avoid page breaks in +% the middle of something that was originally one line. Setting +% \cw{clubpenalty} and \cw{widowpenalty} to these values means that a +% line will have to break into four lines or more before a page +% break will be allowed, and always the first two and last two line +% pieces will remain together. But we don't prohibit page breaks +% within a broken line entirely (\cw{interlinepenalty} = 10000) +% because that might be undesirable in extreme cases. +% \begin{macrocode} + \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 +% \end{macrocode} +% Standard disablement of \verb/?`/ and \verb/!`/ ligatures found in +% \fn{cmtt} fonts: +% \begin{macrocode} + \actively\def\`{\kern\z@`}% + \hfuzz\p@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\linespaceL} +% \begin{macrocode} +\def\linespaceL{\message{Found a ^L character}\CR} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ejectL} +% \begin{macrocode} +\def\ejectL{% + \message{Found a ^L character}% + \gdef\controlLbreak{\eject}\CR\global\let\controlLbreak\relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlLbreak} +% \begin{macrocode} +\let\controlLbreak\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\controlLaction} +% \begin{macrocode} +% Define form-feed to do a `newcolumn' operation. Remove outerness +% at the same time. Possible actions for \cw{controlLaction} are B, +% L, N: print boxed character, print one-line space, or start new +% column/page. +% \begin{macrocode} +\def\controlLaction{N} +\actively\let\^^L=\ejectL +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\listoutmoresetup} +% \begin{macrocode} +\def\listoutmoresetup{% + \global\linecount\z@ \global\linesubcount\z@ + \ifnum\totalcols>\@ne + \global\firstpageno\@ne + \global\lastpageno\@ne + \fi + \relax + \frenchspacing +% \end{macrocode} +% Define tab to be visible. +% \begin{macrocode} + \global\let\printtab\newfileprinttab + \actively\def\^^I{\printtab}% + \langnohyphens +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DVImesj} +% \cw{DVImesj} remains null unless the test at the +% entry point for the menu system to see if \fn{listout} is being +% run interactively returns true. +% \begin{macrocode} +\def\DVImesj{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\landscapereminder} +% Here once again a couple of extra line breaks will be observed in +% the printed documentation, introduced to avoid margin overrun in +% narrow-column printing. +% \begin{macrocode} +\fxmesj\landscapereminder{% +********************************************% +*********************** +* REMINDER: print in LANDSCAPE mode % + * +********************************************% +***********************} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\listoutfinish} +% +% \begin{macrocode} +\def\listoutfinish{% +% \end{macrocode} +% If part of the last file is pending in \cw{prevcolsbox}, we need +% to make sure we print it here. +% \begin{macrocode} + \ifvoid\prevcolsbox + \else + \wlog{Clearing out previous file}% + \begingroup +% \end{macrocode} +% Reset parameters that were turned off by the \cw{endgroup} in +% \cw{listout}. +% \begin{macrocode} + \listoutimage \output{\Ncols}% +% \end{macrocode} +% Change newfile action to `new page', then run it, so that we fill +% out the page with blank columns if necessary. +% \begin{macrocode} + \def\newfileoption{P}% + \hbox to\colwd{}% + \csname newfile\newfileoption\endcsname +% \end{macrocode} +% Message about the name of the DVI file +% \begin{macrocode} + \DVImesj +% \end{macrocode} +% If \cw{landscape} switch is true, reminder to use the `landscape' +% switch of the DVI driver. +% \begin{macrocode} + \if\landscape +% \end{macrocode} +% For those drivers that can handle it (\fn{dvips}, \ldots ?), this +% \cw{special} command is convenient to have in every job. +% \begin{macrocode} +% \cw{special}{landscape}% + \landscapereminder + \fi + \endgroup + \fi +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Fonts} +% \begin{macro}{\xfont} +% \begin{macrocode} +\def\xfont#1={% + \xp@\font\csname#1\endcsname=} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ftypewriter}\begin{macro}{\fbold} +% \begin{macro}{\froman}\begin{macro}{\fitalic} +% \begin{macro}{\fsansserif} +% \begin{macrocode} +\def\ftypewriter{cmtt} +\def\fbold{cmbx} +\def\froman{cmr} +\def\fitalic{cmti} +\def\fsansserif{cmss} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} +% +% \begin{macro}{\loadfont} +% Load the given font. Args \qarg{1} and \qarg{2} are the +% descriptive name and the type size, respectively. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\loadscaledfont} +% \begin{macrocode} +\def\loadscaledfont#1#2{\global\xfont#1#2=#1 scaled #2\relax} +% \end{macrocode} +% \end{macro} +% +% Default font is cmtt8. Note that cmtt7 and cmtt6 are not +% standardly available to all users. +% +% \begin{macrocode} +\loadfont{typewriter}{8} % for main text +\loadfont{bold}{10} % for titles +\loadfont{roman}{5} % for line numbers +\loadfont{roman}{6} % for running heads +% \end{macrocode} +% +% \begin{macro}{\mainfont} +% \begin{macro}{\mainfontsize} +% \begin{macrocode} +\def\mainfont{typewriter} +\def\mainfontsize{8} +\csname\mainfont\mainfontsize\endcsname +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\titlefont} +% \begin{macro}{\titlefontsize} +% \begin{macrocode} +\def\titlefont{bold} +\def\titlefontsize{10} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\linenumberfont} +% \begin{macro}{\linenumberfontsize} +% \begin{macrocode} +\def\linenumberfont{typewriter} +\def\linenumberfontsize{8} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\pagenumberfont} +% \begin{macro}{\pagenumberfontsize} +% \begin{macrocode} +\def\pagenumberfont{bold} +\def\pagenumberfontsize{7} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\runheadfont} +% \begin{macro}{\runheadfontsize} +% \begin{macrocode} +\def\runheadfont{roman} +\def\runheadfontsize{7} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\runfootfont} +% \begin{macro}{\runfootfontsize} +% \begin{macrocode} +\def\runfootfont{roman} +\def\runfootfontsize{7} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\loadfonts} +% \cw{loadfonts} is called just before the start of typesetting, to +% ensure that any needed fonts will be loaded. In fact, for maximum +% flexibility, it is called at the beginning of each file that is +% printed, so that if you use this utility in non-interactive mode +% with a sequence of \cw{listout} commands you could conceivably +% change fonts between files. +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Miscellaneous} +% +% Trace memory statistics to see how close to typical limits we are +% coming. +% +% \begin{macrocode} +\tracingstats=1 +% \end{macrocode} +% +% Language with no hyphenation patterns, to inhibit hyphenation. +% \begin{macrocode} +\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 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\setupbreakingchars} +% Function to make the characters specified by \cw{breakingchars} +% active. The break penalty goes after the character. +% \begin{macrocode} +\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 +% \end{macrocode} +% No line breaks allowed after hyphens. +% \begin{macrocode} + \exhyphenpenalty\@M +} +% \end{macrocode} +% +% \begin{macro}{\iwlos} +% Function to write a line to the \fn{.los} file. The argument +% \qarg{1} may vary in order to achieve special effects. +% \begin{macrocode} +\def\iwlos#1{\immediate\write#1} +% \end{macrocode} +% +% \begin{macrocode} +\storexmesj\losfirstline{% +\% &\losname.los &\todaysdate &\nowtime +\% Option settings for listout.tex.}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\addmonth} +% An auxiliary function to add month names to \cw{toks2}. +% \begin{macrocode} +\def\addmonth#1{% + \toks4 \xp@{#1}% + \edef\next{\the\toks2 + \string\def\string#1{\the\toks4 }}% + \toks2 \xp@{\next}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\begingroup +\endlinechar13 \catcode\endlinechar13 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\logoptionsettings} +% \begin{macrocode} +\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} +% \end{macrocode} +% \cw{storemesj} is use here instead of \cw{def}, to prevent +% potential problems from, \eg., +% +%^^V \def\dirprefix{c:\test\} +% +% \noindent with {\sc PC DOS} directory name ending with a backslash. +% \begin{macrocode} + \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 +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Default option settings} +% These defaults will be used only if \fn{default.los} cannot +% be loaded for some reason. +% +% \begin{macrocode} +% Option settings for listout.tex, 1994/11/4 15:45 +\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 +% \end{macrocode} +% +% Read in the option settings file. +% +% In order to make do in narrow column width, we print a doctored +% version of the following source code, with a few extra line +% breaks thrown in. The comment at the end of the \cw{input} line, +% seen here on two lines, is really all on one line in the source. +% +%^^V \immediate\write16{% +%^^V Reading option settings from `default.los' . . .} +%^^V \input default.los % try entering "nul" if +%^^V % file not found +% +% \iffalse +% \begin{macrocode} +\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 +% \end{macrocode} +% \fi +% +% Now transfer \cw{normalbaselineskip} value to \cw{baselineskip}. +% \begin{macrocode} +\normalbaselines +% \end{macrocode} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Test for interactive mode} +% If interactive mode is detected, then the possibility of entering +% the menu system will be offered to the user. Otherwise we will +% skip all the loading of the menu system, to save time and main +% memory. +% +% If \cw{interactive} is undefined {\em and\/} \cw{jobname} does +% not equal \verb"listout", then we set the \cw{interactive} switch +% to \cw{FALSE}. Otherwise we set it to \cw{TRUE}. +% \begin{macrocode} +\ifx\undefined\interactive +% \end{macrocode} +% If \cw{interactive} was not predefined, then check to see if +% jobname = \verb"listout". In that case assume \cw{interactive} +% mode is wanted. +% \begin{macrocode} + \def\next{listout}% +% \end{macrocode} +% Convert the letters inside \cw{next} to category 12, for +% comparison to \cw{jobname}. +% \begin{macrocode} + \edef\next{\xmeaning\next}% + \edef\jobname{\jobname}% + \ifx\next\jobname + \let\interactive\TRUE + \else + \let\interactive\FALSE + \fi +\else + \let\interactive\TRUE +\fi +% \end{macrocode} +% +% Note that the following \cw{fi} must be on the same line as the +% \cw{endinput}. +% \begin{macrocode} +\if\interactive +\else \restorecatcodes \endinput \fi +% \end{macrocode} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \newpage +% \section{Final preparations} +% +% \begin{macro}{\printfiles} +% If the menu system is not needed, we want to skip all the loading +% of it. So we define a function \cw{printfiles} which can be +% executed either before or after loading the menu +% system. If the user doesn't choose to enter the menu system, then +% executing \cw{printfiles} will carry the current \tex/ run to +% completion and the remainder of \fn{listout.tex}, comprising all +% the menu system, will be ignored. Otherwise \cw{printfiles} will be +% called later, after leaving the menu system. +% \begin{macrocode} +\def\printfiles{%\reportlayout + \mesj{OK, let's print some files.}% + \begingroup +% \end{macrocode} +% Execute and clear \cw{listoutsetup} to avoid unnecessary +% repetition in multiple-file runs. +% \begin{macrocode} + \listoutsetup \let\listoutsetup\relax +% \end{macrocode} +% Prompt for file names and print files until the user enters an +% empty file name. +% \begin{macrocode} + \fileloop + \endgroup + \listoutfinish +% \end{macrocode} +% Execute \latex/ \cw{@@end} first; if it is not defined, then \tex/ +% will proceed to execute the other \cw{end}. This enables +% the \fn{listout} utility to work both with \latex/ and plain \tex/. +% \begin{macrocode} + \csname \string @\string @end\endcsname + \end +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\numberoffiles} +% Keep track of the number of files printed so that an +% informational message can be sent at the end of the run. +% \begin{macrocode} +\newcount\numberoffiles +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fileloop} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DVImesj} +% If \cw{jobname} = \fn{listout} then the final star in the middle +% line will line up properly. +% \begin{macrocode} +\fxmesj\DVImesj{% +******************************************************************* +* DVI file name is \jobname.dvi * +*******************************************************************} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\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{:?: } +% \end{macrocode} +% +% Don't put up the full menu unless it's requested. Use +% \cw{expandafter} to throw the \cw{printfiles} command beyond the +% \cw{fi}, since it will end the job. +% \begin{macrocode} +\readChar{X}\reply +\if M\reply \else\xp@\printfiles\fi +% \end{macrocode} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \begin{macrocode} +\message{Starting up the listout.tex menu system . . .} +% \end{macrocode} +% +% \section{Menu system startup} +% Some of the following definitions merely reiterate defaults from +% \fn{menus.sty}, for the record. +% \begin{macro}{\menuprefix} +% \begin{macrocode} +\storexmesj\menuprefix{ +====================================================================== +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menusuffix} +% \begin{macrocode} +\storexmesj\menusuffix{ + Q Quit X Exit ? Help +====================================================================== +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\inmenuA} +% \begin{macro}{\inmenuB} +% \begin{macrocode} +\storexmesj\inmenuA{ +} +\storexmesj\inmenuB{ +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\menuhelpmesj} +% +% Add more to the standard help message defined by \fn{menus.sty}. +% +% \begin{macrocode} +\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 . . .} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\confirm} +% +% \begin{macrocode} +\def\confirm#1{\xmesj{\ +* #1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mainmenu} +% +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moption} +% The command \cw{moption} without any menu-letter suffixes is the +% main menu presentation function. +% \begin{macrocode} +\def\moption{\mainmenu \readChar{Q}\reply + \let\prevmenu\@empty \let\curmenu\@empty \optionexec\reply} +% \end{macrocode} +% \end{macro} +% +% \write16{Page \thepage: full menu printout begins here; you might} +% \write16{want to omit these pages when printing, to save paper.} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option A} +% +% \begin{macro}{\menuA} +% Submenu for selecting various new file actions. +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionA} +% \begin{macrocode} +\def\moptionA{\menuA{\newfileoption}% + \readChar{Q}\reply \optionexec\reply} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionAS} +% \begin{macrocode} +\def\moptionAS{\def\newfileoption{S}% + \confirm{% + Each file will start immediately after the preceding file, with\ +* some intervening blank space.}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionAC} +% \begin{macrocode} +\def\moptionAC{\def\newfileoption{C}% + \confirm{% + Each file will start at the top of the next column.}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionAP} +% \begin{macrocode} +\def\moptionAP{\def\newfileoption{P}% + \confirm{% + Each file will start on a new page.}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionAR} +% +% \begin{macrocode} +\def\moptionAR{\def\newfileoption{R}% + \confirm{% + Each file will start on a new page, in the right-hand column.} + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option B} +% +% \begin{macro}{\menuBtest} +% Line breaking. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuB} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionB} +% \begin{macrocode} +\def\moptionB{\lettermenu{B}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionBS} +% \begin{macrocode} +\def\moptionBS{% + \let\spacebreak\markedbreak \let\breakingchars\@empty + \overrun\rightmargin \let\noextralinebreaks\FALSE + \confirm{\menuBtest}\popoptions\moptionQ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionBN} +% \begin{macrocode} +\def\moptionBN{% + \let\spacebreak\@empty \let\breakingchars\@empty + \overrun=\rightmargin + \confirm{\menuBtest}\popoptions\moptionQ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionBO} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionBC} +% One reason for automatically adding the space character to the +% list of breaking chars is that otherwise we would have to caution +% the user against typing the space at the end of the line when +% responding to the prompt; since \tex/ removes character 32 at the +% end of a line, we have no way of finding out whether one was +% typed there or not. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option C} +% +% \begin{macro}{\menuC} +% \cw{columnwidth} is the value as originally given, including the +% original units; may be a dimension variable or a character +% string. The corresponding internal variable is \cw{colwd}. If we +% did not maintain \cw{columnwidth} separately from \cw{colwd}, we +% could not later echo the original units on-screen to the user, +% since that information is lost in the act of storing the width in +% \cw{colwd}. Similarly for \cw{columnheight}. +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionC} +% \begin{macrocode} +\def\moptionC{\lettermenu C} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCW} +% \begin{macrocode} +\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 +% \end{macrocode} +% A misspelled unit name, \eg. {\tt im} instead of {\tt in}, will +% lead to this branch; maybe we should try to check whether the +% answer contained letters after the digits and if so attempt an +% explanation about possibly misspelled unit name. On the other +% hand maybe that's too much work. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCWA} +% \begin{macrocode} +\def\moptionCWA{% + \confirm{Column width set to \columnwidth.}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCWB} +% \begin{macrocode} +\def\moptionCWB{% + \confirm{Column width set to \columnwidth\space (= \the\colwd)}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCH} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCHA} +% \begin{macrocode} +\def\moptionCHA{% + \confirm{Column height set to \columnheight.\ +* (Bottom margin adjusted to \the\bottommargin.)}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCHB} +% +% \begin{macrocode} +\def\moptionCHB{% + \confirm{Column height set to \columnheight\space (= \the\colht)\ +* (Bottom margin adjusted to \the\bottommargin.)}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionCI} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option D} +% +% \begin{macro}{\menuD} +% \begin{macrocode} +\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'. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionD} +% +% \begin{macrocode} +\def\moptionD{\lettermenu D} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuDD} +% +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionDD} +% +% Valid responses to this menu are \qc{\A}--\qc{\J}, \qc{\Q}, +% \qc{\X}, or \qc{\?}. Rather than define submenus \cw{moptionDDA}, +% \cw{moptionDDB}, \ldots, we use \tex/'s \verb'`'\meta{character} +% feature to convert the character in \cw{reply} to a number, so +% that a simple numeric test can be used to see if the reply is in +% range. +% +% \begin{macrocode} +\def\moptionDD{\menuDD \readChar{Q}\reply + \count@=\xp@`\reply\relax +% \end{macrocode} +% A = 65 \ascii/, J = 74 \ascii/ +% \begin{macrocode} + \ifnum\count@>64 \ifnum\count@<75 +% \end{macrocode} +% We use \cw{def} rather than \cw{let} here so that we can record +% the current date format in the \fn{.los} file with +% \cw{expandafter}\cw{string} (see \cw{logoptionsettings}). +% Otherwise we would probably have to use a separate variable just +% to keep track of the date format letter. +% \begin{macrocode} + \xp@\def\xp@\todaysdate\xp@{\csname date\reply\endcsname}% + \confirm{New date form: \todaysdate}% + \def\reply{Q}% + \fi\fi + \optionexec\reply +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionDS} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionDZ} +%\mjd{Maybe date-time-reset doesn't need to do \themonth,\theday?} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuDT} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionDT} +% If the user's reply to the time menu is one of the valid letters +% (A\ndash F), we define \cw{nowtime} to be \cw{timeX}, where {\tt +% X} represents the reply letter. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionDTZ} +% \begin{macrocode} +\def\moptionDTZ{\confirm{New time format: \nowtime}% + \popoptions\moptionQ} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option E} +% +% \begin{macro}{\menuE} +% \begin{macrocode} +\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'). +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionE} +% \begin{macrocode} +\def\moptionE{\lettermenu{E}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\losname} +% \begin{macro}{\losdir} +% \begin{macrocode} +\def\losname{default} +\def\losdir{} +% \end{macrocode} +% \end{macro} +% \end{macro} + +% \begin{macro}{\lossorrymessage} +% \begin{macrocode} +\def\lossorrymessage{\message{% +? Could not create `\losdir\losname.los'; +maybe there was a system problem.}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\currentdir} +% Default for \cw{currentdir} is empty, to avoid creating problems +% for less-knowledgeable users. +% \begin{macrocode} +\def\currentdir{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionES} +% \begin{macrocode} +\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 +% \end{macrocode} +% Check to make sure the file was created. +% \begin{macrocode} + \openin15=\losdir\losname.los \relax + \ifeof15 \lossorrymessage +% \end{macrocode} +% If \fn{xxxxx.los} exists and is nonempty, it's still not certain +% that we have not opened some other file named \fn{xxxxx.los}, such +% as a default version located somewhere else in the tex-inputs +% search path. We check this possibility by looking at the first +% line, which has embedded the date and time of the \tex/ run that +% produced the file. +% \begin{macrocode} + \else \testlocation \fi + \closein15 \relax + \fi + \popoptions\moptionQ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\testlocation} +% \begin{macrocode} +\def\testlocation{% + \begingroup + \catcode`\%=12 \catcode`\\=12 \catcode\endlinechar=9 + \read15 to\next + \ifx\next\losfirstline + \confirm{% +New `\losname.los' file successfully created}% +% \end{macrocode} +% There is one other possibility left to be checked: if the current +% directory is excluded from the tex-inputs search path (\eg., +% under Unix typically `\qc{\.}' must be explicitly included in the +% search path to always have the current directory searched) then +% it is possible that the option settings file will be created OK +% but will not be accessible to \fn{listout.tex} through \cw{input}. +% \begin{macrocode} + \ifx\losdir\@empty + \testinputtable + \else + \message{% +(in location `\losdir')}% + \fi + \else + \lossorrymessage + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\testinputtable} +% This function tests if the \fn{.los} file written to the default +% directory is inputtable. The method is to make the percent +% character temporarily active (there is a +% \cw{begingroup}\ldots\cw{endgroup} pair enclosing the +% \cw{testinputtable} call) and define it to read the first line of +% the \fn{.los} file, compare it to the expected string, and issue +% a warning message if it doesn't match. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionEL} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionED} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option F} +% +% \begin{macro}{\menuF} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionF} +% +% \begin{macrocode} +\def\moptionF{\lettermenu F} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\genfontmenu} +% +% \begin{macrocode} +\fxmenu\genfontmenu{ +&\firstpart +Font choices: +}{ +R Roman +B Bold +I Italic +T Typewriter +S Sans serif +}{ +Current choice is `&\fonttoget'. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getfont} +% \cw{getfont} is a higher-level function to call \cw{genfontmenu}. +% The arguments required by \cw{getfont} are \qarg{1} font style +% control sequence, \ie. something like \cw{linenumberfont} whose +% definition is `bold' or `italic' or `typewriter'; \qarg{2} text to +% add above the basic list of font choices, \qarg{3} font description +% such as `Main' or `Line number'. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionFF} +% +% \begin{macrocode} +\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}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\wholepointsizes} +% +% \begin{macrocode} +\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. +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\getfontsize} +% +% \begin{macrocode} +\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}% +% \end{macrocode} +% No \cw{else} branch here: If $\cw{count@}=0$, leave \cw{reply} +% unchanged. This will lead to a `don't understand' message and a +% repeat of the same menu. +% \begin{macrocode} + \fi + \fi + \optionexec\reply +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionFS} +% \begin{macrocode} +\def\moptionFS{\getfontsize\mainfontsize{main text}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionFL} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuFT} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionFT} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\testload} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuFN} +% \begin{macrocode} +\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\%, ...). +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionFN} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option G} +% +% \begin{macro}{\menuGa} +% \begin{macro}{\menuGb} +% \begin{macrocode} +\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 . . .} + +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\moptionG} +% \begin{macrocode} +\def\moptionG{\menuGa\readline{}\reply\menuGb\readline{}\reply \moptionQ} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option H} +% +% \begin{macro}{\menuH} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionH} +% \begin{macrocode} +\def\moptionH{\lettermenu H} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionHT} +% \begin{macrocode} +\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 +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionHF} +% +% \begin{macrocode} +\def\moptionHF{\getfont\titlefont{}{Title}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionHS} +% +% \begin{macrocode} +\def\moptionHS{\getfontsize\titlefontsize{titles}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuHC} +% \begin{macrocode} +\fxmenu\menuHC{ +Title capitalization choices: +}{ +N None +L Lowercase +U Uppercase +}{ +Current choice is &\titlecase. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionHC} +% +% \begin{macrocode} +\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} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option I} +% +% \begin{macro}{\menuIa} +% \begin{macrocode} +\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: } +% \end{macro} +% +% \begin{macro}{\menuIb} +% \begin{macrocode} +\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: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionI} +% \begin{macrocode} +\def\moptionI{\menuIa \readline{}\reply \menuIb + \readChar{Q}\reply \optionexec\reply} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option L} +% +% \begin{macro}{\menuL} +% \begin{macrocode} +\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% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionL} +% +% \begin{macrocode} +\def\moptionL{\lettermenu L} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionLT} +% When line numbering is toggled off, pop back up to the main menu. +% But when line numbering is turned on, redisplay menu L in case +% the user wants next to change the font or numbering frequency. +% Also check \cw{leftmargin} (and \cw{intercolspace}, if +% $\cw{totalcols}>1$) to see if they seem likely to provide enough +% room. +% \begin{macrocode} +\def\moptionLT{% + \if\linenumbers + \let\linenumbers\FALSE + \else + \let\linenumbers\TRUE + \fi + \confirm{Line numbers are switched \if\linenumbers on\else off\fi.}% +% \end{macrocode} +% This \cw{if} statement must be near the bogglitude record for \tex/ +% conditionals. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionLF} +% +% \begin{macrocode} +\def\moptionLF{\getfont\linenumberfont{}{Line number}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionLS} +% +% \begin{macrocode} +\def\moptionLS{\getfontsize\linenumberfontsize{line numbers}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionLN} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option M} +% +% \begin{macro}{\menuM} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionM} +% +% \begin{macrocode} +\def\moptionM{\lettermenu M} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuMB} +% \begin{macrocode} +\fxmesj\menuMB#1{ +Current bottom margin is #1. +% \end{macrocode} +% +% \begin{macrocode} +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:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionMB} +% +% \begin{macrocode} +\def\moptionMB{\menuMB{\the\bottommargin}% + \readline{}\reply + \ifx\@empty\reply + \let\dependentbottommargin\TRUE + \if\dependentcolht + \computebc +% \end{macrocode} +% Otherwise \cw{bottommargin} should already have the correct value, +% no extra computation needed. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuML} +% +% \begin{macrocode} +\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:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionML} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuMR} +% +% \begin{macrocode} +\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:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionMR} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuMT} +% +% \begin{macrocode} +\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:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionMT} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option N} +% +% \begin{macro}{\menuN} +% \begin{macrocode} +\fxmesj\menuN#1{ +Number of columns: #1. +<return> to keep the current value, or enter a new value +(a number greater than 0):} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionN} +% \begin{macrocode} +\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 +% \end{macrocode} +% The \cw{specialhelp} function defines its first argument (in this +% case, \cw{reply}) to be \qc{\?} and locally redefines +% \cw{menuhelpmesj} to substitute the given text. +% \begin{macrocode} + \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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option O} +% +% \begin{macro}{\menuO} +% \begin{macrocode} +\fxmenu\menuO{ +Current orientation: &\if&\landscape\.landscape.&\else\.portrait&\fi +}{ +P Switch to portrait orientation +L Switch to landscape orientation +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionO} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option P} +% +% \begin{macro}{\menuP} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionP} +% +% \begin{macrocode} +\def\moptionP{\lettermenu P} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionPW} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionPH} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionPU} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionPA} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option R} +% +% \begin{macro}{\menuR} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionR} +% +% \begin{macrocode} +\def\moptionR{\lettermenu R} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuRH} +% +% \begin{macrocode} +\fmenu\menuRHorF#1{}{ +C Change running #1 contents +F Change running #1 font +S Change running #1 font size +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRH} +% +% \begin{macrocode} +\def\moptionRH{\menuRHorF{head}\readChar{Q}\reply \optionexec\reply} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuRHC} +% +% \begin{macrocode} +\fxmesj\menuRHC{ +Current running head contents: +&\the&\runhead +Enter new running head contents (to turn off running heads, +just press <return>):} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRHC} +% +% Since the user response here can be arbitrary text, we need to do +% some manual checking for the \qc{\?} \qc{\X} and \qc{\Q} +% possibilities with \cw{xoptiontest} instead of calling +% \cw{optionexec}. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRHF} +% +% \begin{macrocode} +\def\moptionRHF{\getfont\runheadfont{}{Running head}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRHS} +% \begin{macrocode} +\def\moptionRHS{\getfontsize\runheadfontsize{running heads}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRF} +% \begin{macrocode} +\def\moptionRF{\menuRHorF{foot}\readChar{Q}\reply \optionexec\reply} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuRFC} +% \begin{macrocode} +\fxmesj\menuRFC{ +Current running foot contents: +&\the&\runfoot +Enter new running foot contents (to turn off running feet, +just press <return>):} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRFC} +% +% Since the user response here can be arbitrary text, we need to do +% some manual checking for the \qc{\?} \qc{\X} and \qc{\Q} +% possibilities instead of calling \cw{optionexec}. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRFF} +% +% \begin{macrocode} +\def\moptionRFF{\getfont\runfootfont{}{Running foot}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionRFS} +% +% \begin{macrocode} +\def\moptionRFS{\getfontsize\runfootfontsize{running feet}} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option S} +% +% \begin{macro}{\menuS} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionS} +% \begin{macrocode} +\def\moptionS{\lettermenu{S}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuSS} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionSS} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuSD} +% Directory prefix to be added in front of each filename title, +% when printing multiple files. \tex/ version 3.x does not provide +% a way to get at any part of a filename except \cw{jobname}. +% Therefore in order for a directory name to be printed, it has to +% be entered by the user somewhere along the line. +% \begin{macrocode} +\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.)} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionSD} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option T} +% +% \begin{macro}{\menuT} +% \begin{macrocode} +\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 +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionT} +% +% \begin{macrocode} +\def\moptionT{\lettermenu T} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuTT} +% +% \begin{macrocode} +\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'. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\reportnewtabstyle} +% +% \begin{macrocode} +\def\reportnewtabstyle#1{% + \chardef\tabselect=#1 \relax + \confirm{Tab style is now `\tabstyle'}% + \def\reply{Q}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionTT} +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionTN} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \subsection{Option V} +% +% \begin{macro}{\menuV} +% \begin{macrocode} +\fmenu\menuV{}{ + 8 Treatment of 8-bit characters + L Treatment of Control-L characters +}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionV} +% \begin{macrocode} +\def\moptionV{\lettermenu{V}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuVL} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionVL} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuV8} +% \begin{macrocode} +\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. +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionV8} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Here perhaps I should clear out the memory used by the menus +% since it is no longer needed. But so far I haven't had any pages +% complex enough to exceed 64K main mem even after loading full +% \fn{listout.tex} with the menu system. [mjd,25-Sep-1993] +% \begin{macrocode} +\moption +\printfiles +% \end{macrocode} +% +% And a final \cw{endinput} to make docstrip skip the garbage below, +% otherwise docstrip would choke on \ctrl{B} saying it's an invalid +% character. +% \begin{macrocode} +\endinput +% \end{macrocode} +% +%^^A Undefine FORMFEED (control-L) and DEL (control-?) so they will +%^^A not cause the macrocode environment to choke. +% +%\catcode`\^^L=12 \catcode`\^^?=12 +%% +\begin{macrocode} +Test of special characters (if listout.tex is used to print itself). +% +The NUL character is missing (Control-@) because apparently Unix Emacs +can't or won't preserve the character when saving the file. Put it +back in with your editor if you can. Control-J and Control-M are +printed at the end of their lines to avoid commenting out any +following characters (depending on the native file format of the +user's operating system). Control-Z is printed at the end of the file +to avoid premature file termination if the operating system is DOS. +The tab character (control-I) should show up as a dotted line 8 +characters wide under the default settings of \spacespertab and +\tabstyle. And the formfeed character (control-L) should cause a page +break. +% +Control-@: , +Control-A: , Control-B; , Control-C: , +Control-D: , Control-E: , Control-F: , +Control-G: , Control-H: , + Control-I: , Control-J: +, Control-K: , Control-L: , Control-M: +, Control-N: , Control-O: , Control-P: , Control-Q: , +Control-R: , Control-S: , Control-T: , Control-U: , +Control-V: , Control-W: , Control-X: , Control-Y: , +Control-Z: (printed at end of file, below) +Control-[: , Control-\: , Control-]: , Control-^: , +Control-_: , Control-?: . +ASCII 128: , ASCII 131: , ASCII 137: , ASCII 139: , +ASCII 149: , ASCII 151: , ASCII 157: , ASCII 163: , +ASCII 167: , ASCII 173: , ASCII 179: , ASCII 181: , +ASCII 191: , ASCII 193: , ASCII 197: , ASCII 199: , +ASCII 211: , ASCII 223: , ASCII 227: , ASCII 229: , +ASCII 233: , ASCII 239: , ASCII 241: , ASCII 251: , +ASCII 255: . +% +Control-Z: . +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/dialogl/menus.dtx b/Master/texmf-dist/source/latex/dialogl/menus.dtx new file mode 100644 index 00000000000..641b3732192 --- /dev/null +++ b/Master/texmf-dist/source/latex/dialogl/menus.dtx @@ -0,0 +1,983 @@ +%%% ==================================================================== +%%% @LaTeX-style-file{ +%%% filename = "menus.dtx", +%%% version = "1.99a", +%%% date = "2013/01/24", +%%% author = "Michael Downes", +%%% copyright = "This file is part of the dialogl package, released +%%% under the LPPL; see dialogl.ins for details." +%%% keywords = "TeX, menus", +%%% supported = "no", +%%% 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.", +%%% } +%%% ==================================================================== +% +% \iffalse +%<*driver> +\input{dia-driv.tex} +%</driver> +% \fi +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Function descriptions} +% +%\begin{usage} +%\fmenu\foobar{ +% <preliminary text> +%}{ +% <menu lines> +%}{ +% <following text> +%} +%\end{usage} +% Defines \cw{foobar} as a function that puts the preliminary text, +% the menu lines (list of choices), and the after text on screen. +% Normal usage: +% +%^^V \foobar % print the menu on screen +%^^V \readline{}\reply % read the answer +% +% (See the description of \cw{readline} in \fn{dialog.doc}.) In the +% various text parts all special characters have category 12 except +% for braces, as with \cw{mesj}. Note the recommended placement of +% the braces: no closing brace falls at the end of a line, except +% the very last one. Because of the special catcodes in effect when +% reading the final three arguments, a \ctrl{M} or \qc{\%} between +% arguments would be read as an active character or category-12 +% character respectively, instead of being ignored. But actually, +% after some rather difficult programming, I managed to make it +% possible to write just about anything (except brace characters) +% between the arguments and have it be ignored, so the recommended +% style is not mandatory. The first and last newline of each +% argument are stripped off anyway in order to produce consistent +% clean connections with \cw{menuprefix} etc.; see below. +% +% Menu functions created by \cw{fmenu} are allowed optionally to +% have arguments, like functions created with \cw{fmesj} (from +% \fn{dialog.sty}), so that pieces of text can be inserted at the +% time of use. This makes it possible for several similar menus to +% share the same menu function if there are only minor variations +% between them. +% +%\begin{usage} +%\menuprefix, \menusuffix +%\inmenuA, \inmenuB +%\end{usage} +% The text \cw{menuprefix} will be added at the beginning of each +% menu; \cw{menusuffix} will be added at the end. The text +% \cw{inmenuA} and \cw{inmenuB} will be added between the first and +% second, respectively second and third parts of the menu; their +% default values produce a blank line on screen. (But +% \cw{inmenuA} will be omitted if the first part is empty, and +% \cw{inmenuB} will be omitted if the last part is empty.) To change +% any of these texts, use \cw{storemesj} or \cw{storexmesj}. For +% example: +% +%^^V\storemesj\menuprefix{********* MENU **********} +% +%\begin{usage} +%\menuprompt +%\end{usage} +% Furthermore, the function \cw{menuprompt} is called at the very +% end of the menu, so that for example a standard prompt such as +% \verb'Enter a number:' could be applied at the end of all menus, +% if desired. To change \cw{menuprompt}, use \cw{fmesj} or +% \cw{fxmesj}. +% +%\begin{usage} +%\menuline, \endmenuline +%\menutopline, \menubotline +%\end{usage} +% Each line in the middle argument of \cw{fmenu} (the list of +% choices) is embedded in a statement +% \cw{menuline}\verbdots\cw{endmenuline}. The default definition of +% \cw{menuline} is to add two spaces at the beginning and a newline +% at the end. Lines in the top or bottom part of the menu are +% embedded in \cw{menutopline}\verbdots\cw{endmenuline} or +% \cw{menubotline}\verbdots\cw{endmenuline} respectively. (Notice +% that all three share the same ending delimiter; if different +% actions are wanted at the end of a top or bottom line as opposed +% to a middle menu line, they must be obtained by defining +% \cw{menutopline} or \cw{menubotline} to read the entire line as +% an argument and perform the desired processing.) +% +% An enclosing box for a menu can be obtained by +% defining \cw{menuline} and its relatives appropriately and using +% \cw{fxmenu} (see below). +% +%\begin{usage} +%\fxmenu\foobar{ +% <preliminary text> +%}{ +% <menu lines> +%}{ +% <following text> +%} +%\end{usage} +% Similar to \cw{fmenu} but with full expansion in each part of the +% text, as with \cw{xmesj}. +% +% To get an enclosing box for a menu, write \cs{\.} at the end of +% each menu line (to protect the preceding spaces from \tex/'s +% propensity to remove character 32 at the end of a line, +% regardless of its catcode), and then make sure that \cw{menuline} +% and \cw{endmenuline} put in the appropriate box-drawing +% characters on either side. I.e.: +% +%^^V \fxmenu\foobar{ +%^^V First line \. +%^^V Second line \. +%^^V }{ +%^^V Third line \. +%^^V ... +%^^V }{ +%^^V Last line \. +%^^V } +% +% With the \verb'/o' option of em\tex/, you can use the box-drawing +% characters in the standard PC DOS character set. +% +%\begin{usage} +%\nmenu\Alph\foobar#1{ +% <preliminary text> +%}{ +% <menu lines> +%}{ +% <following text> +%} +%\end{usage} +% \cw{nmenu} and \cw{nxmenu} are like \cw{fmenu}, \cw{fxmenu} +% except that they automatically number each line of the middle +% part of the menu. (This allows menu choices to be added or deleted +% without tedious renumbering.) The first argument indicates the +% type of numbers to be used: \cw{alph}, \cw{Alph}, \cw{arabic}, +% \cw{roman}, \cw{Roman} (following \latex/). {\em These are not yet +% implemented.} +%^^A [15-May-1993,mjd] +% +% The function \cw{menunumber} (taking one argument) is applied to +% each automatically generated number. The default value is to add +% brackets and a space after: +% +%^^V \def\menunumber#1{[#1] } +% +% but by redefining \cw{menunumber} you can add parentheses or extra +% spaces or what have you around each number. Internally a line of +% an autonumbered menu is stored as +% +%^^V \menuline\menunumber{5}Text text ...\endmenuline +% +%\begin{usage} +%\optionexec\answer +%\end{usage} +% This is a companion function for \cw{readChar} and the menu +% functions: it checks to see if the answer is equal to any one of +% the characters \qc{\?} \qc{\Q} \qc{\q} \qc{\X} \qc{\x}, and if so +% executes \cw{moption?} or \cw{moptionQ} or \cw{moptionX} +% respectively, otherwise executes +% +%^^V \csname moption\curmenu C\endcsname +% +% where \qc{\C} means the character that was read and \cw{curmenu} is +% a string identifying the current location in the menu system. +% (\cw{optionexec} pushes and pops \cw{curmenu} when going between +% menus, to keep it up to date.) If this control sequence is +% undefined, \cw{optionexec} gives a generic ``Sorry, I don't +% understand'' message and repeats the current menu. +% +% Thus the major work involved in making a menu system is to define +% the menu screens using \cw{fmenu}, \cw{fxmenu}, and then define +% corresponding functions \cw{moptionXXX} that display one of the +% menu screens, read a menu choice, and call \cw{optionexec} to +% branch to the next action. +% +%\begin{usage} +%\specialhelp\answer{Substitute message} +%\end{usage} +% As it turns out, it is sometimes desirable to substitute some +% other message in place of the generic ``Sorry, I don't +% understand'' message given by \cw{optionexec}. For instance, +% suppose a given menu choice leads to a secondary prompt where you +% ask the user to enter a number of columns for printing some data. +% If the user accidentally mistypes \verb'0', it would be better to +% respond with something like +% +%^^V Number of columns must be greater than 0. +% +% than with the generic message. The function \cw{specialhelp} +% allows you to do this. The first argument is the name of the +% macro that will be passed to \cw{optionexec}. \cw{specialhelp} +% modifies that macro to a flag value that will trigger the +% substitute message. (But does it carefully, so that you can still +% use the macro naturally in the substitute message text.) +% +%\begin{usage} +%\optionfileexec\answer +%\end{usage} +% Like \cw{optionexec}, but gets the next menu from a file instead +% of from main memory, if applicable. This is not yet +% implemented. +%^^A [mjd,24-May-1993] +% The technical complications involved in managing the menu files +% are many\Dash for example: How do you prevent the usual file name +% message of \tex/ from intruding on your carefully designed menu +% screens, if \cw{input} is used to read the next menu file? +% Alternatively if you try to use \cw{read} to read the next menu +% file, how do you deal with catcode changes? +% +%\begin{usage} +%\lettermenu{MN} +%\end{usage} +% This is an abbreviation for +% +%^^V \menuMN \readChar{Q}\reply \optionexec\reply +% +% It calls the menu function associated with the menu name \verb"MN", +% reads a single uppercase letter into \cw{reply}, and then calls +% \cw{optionexec} to branch to the case selected by the reply. +% +%\begin{usage} +%\if\xoptiontest\answer ... \else ... \fi +%\end{usage} +% The function \cw{xoptiontest} is for use with \cw{readline} or +% \cw{xreadline}, to trap the special responses \verb'? Q q X x' +% before executing some conditional code. It returns a `true' value +% suitable for \cw{if} testing, if and only if the replacement text +% of \cw{answer} is a single character matching one of those +% listed. This is used when you are prompting for a response that +% can be an arbitrary string of characters, but you want to allow +% the user still to get help or quit with the same one-character +% responses that are recognized in other situations. +% +% \StopEventually{} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \section{Implementation} +% Standard package identification: +% \begin{macrocode} +%<*2e> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{menus}[1994/11/08 v0.9x] +% \end{macrocode} +% Load the dialog package if necessary. +% \begin{macrocode} +\RequirePackage{dialog} +%</2e> +% \end{macrocode} +% +% This file requires \fn{grabhedr.sty} and \fn{dialog.sty}. If +% \fn{grabhedr.sty} is not already loaded, load it now and call +% \cw{fileversiondate}, since it's too late to apply \cw{inputfwh} +% to {\em this\/} file. See the documentation of \cw{trap.input} in +% \fn{grabhedr.doc}. +% \begin{macrocode} +%<*209> +\csname trap.input\endcsname +\input grabhedr.sty \relax +\fileversiondate{menus.sty}{0.9x}{1994/11/08} +% \end{macrocode} +% +% \begin{macrocode} +\inputfwh{dialog.sty} +%</209> +% \end{macrocode} +% +%\section{Definitions} +% +% We start by using the \cw{localcatcodes} function from +% \fn{grabhedr.sty} to save current catcodes and set new catcodes +% for certain significant characters, as explained at more length +% in \fn{dialog.doc}. +% +% \begin{macrocode} +\localcatcodes{\@{11}% + \~{13}\"{12}\#{6}\^{7}\`{12}\${3}\:{12}} +% \end{macrocode} +% +%\begin{macro}{\menuprefix} +% \cw{menuprefix} is a string added at the beginning of each menu to +% pretty it up a little (or uglify it a little, depending on your +% taste). The length of the default string is 70 characters, not +% counting the two newline characters. By using \cw{storexmesj} we +% get embedded newlines corresponding to the ones seen here. [That +% is, except for the extra line break (where the newline character is +% commented out), needed to make this fit in the current column +% width.] +% +%\iftrue +%^^V \storexmesj\menuprefix{ +%^^V ===================================% +%^^V =================================== +%^^V } +% +%\else +% \begin{macrocode} +\storexmesj\menuprefix{ +====================================================================== +} +% \end{macrocode} +%\fi +% \end{macro} +% +% \begin{macro}{\menusuffix} +% The default value for \cw{menusuffix} is the same as for +% \cw{menuprefix}. +% \begin{macrocode} +\let\menusuffix=\menuprefix +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\inmenuA} +% \begin{macro}{\inmenuB} +% The default for \cw{inmenuA} and \cw{inmenuB} is a single +% newline, which will produce a blank line on screen because they +% will occur after an \cw{endmenuline}, which also +% contains a newline. +% \begin{macrocode} +\storemesj\inmenuA{ +} +\storemesj\inmenuB{ +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +%\begin{macro}{\menuline} +% The default value for \cw{menuline} is two spaces. This means +% that each line in the middle section of a menu defined by +% \cw{fmenu} or \cw{fxmenu} will be indented two spaces. +% \begin{macrocode} +\storemesj\menuline{ } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menutopline} +% \begin{macro}{\menubotline} +% By default, no spaces are added at the beginning of a line in the +% top or bottom section of a menu: +% \begin{macrocode} +\def\menutopline{} +\def\menubotline{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\endmenuline} +% \cw{endmenuline} is just a newline. +% \begin{macrocode} +\storemesj\endmenuline{ +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menunumber} +% This definition of \cw{menunumber} adds square brackets and a +% following space around each item number. +% \begin{macrocode} +\def\menunumber#1{[#1] } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuprompt} +% This definition of \cw{menuprompt} is suitable for the purposes +% of \fn{listout.tex} but will probably need to be no-op'd or +% changed for other applications. +% \begin{macrocode} +\def\menuprompt{\promptmesj{Your choice? }} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menufirstpart} +% \begin{macro}{\menuchoices} +% \begin{macro}{\menulastpart} +% Each of the three pieces of a menu gets its own token register. +% \begin{macrocode} +\newtoks\menufirstpart +\newtoks\menuchoices +\newtoks\menulastpart +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\fmenu} +% +% The `arguments' of \cw{fmenu} are \arg{1} menu name, \arg{2} +% optional argument specifiers, \arg{3} preliminary text, \arg{4} +% list of menu choices, \arg{5} following text. But at first we read +% only the first two because we want to change some catcodes before +% reading the others. The auxiliary function \cw{fxmenub} is shared +% with \cw{fxmenu}. +% +% Because of the catcode changes done by \cw{mesjsetup}, newlines, +% spaces, or percent signs between the three final arguments will +% not be ignored. To get around this, we use the peculiar +% \verb'#{' feature of \tex/, in intermediate scratch functions +% called \cw{@tempa}, to read and discard anything that may occur +% between one closing brace and the next opening brace. Token +% register assignments are used to read the arguments proper. +% +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% Before proceeding to define \cw{fxmenub}, we must deal with a +% subproblem. What we will have to work with is three pieces of text +% in the token registers \cw{menufirstpart}, \cw{menuchoices}, and +% \cw{menulastpart}, containing active \ctrl{M} characters to mark +% line breaks, including possibly but not necessarily \ctrl{M} at the +% beginning and at the end of each piece. What we would like to do, +% for each piece, is to remove the first \ctrl{M}, if there is one, +% and the last one, if there is one. The function \cw{stripcontrolMs} +% does this. +% +% If you are one of those rare \tex/ hackers who might actually +% want to understand the workings of \cw{stripcontrolMs}, the best +% way is probably to watch it in action with \cw{tracingmacros} = +% \cw{tracingcommands} = 2, rather than attempt to follow my labored +% commentary below. +% \begin{macrocode} +\begingroup % localize \lccode change +\lccode`\~=`\^^M +% \end{macrocode} +% The functions \cw{stripM}, \cw{stripMa}, \cw{stripMb}, \ldots\ are +% auxiliary functions for \cw{stripcontrolMs}. They all carry along +% an extra last argument, the name of the token register originally +% given to \cw{stripcontrolMs}, so that when we finally reach +% \cw{stripMd} we can carry out the assignment of the token +% register. +% +% When \cw{stripM} is called, it should be called like this: +%\begin{verbatim} +% \expandafter\stripM\expandafter$\the\sometoks +% $^^M$$\stripM\sometoks +%\end{verbatim} +% That is, \qc{\$} should be added at the beginning and \verb'$^^M$$' +% at the end of the text to be processed. And \cw{expandafter}'s +% should be added to pre-expand the token register. +% +% These examples illustrate the possible contents of (e.g.\@) +% \cw{menufirstpart}, before processing +%\begin{enumerate}\renewcommand{\theenumi}{\alph{enumi}} +%\renewcommand{\labelenumi}{(\theenumi)} +% \item \label{mmm} +% \verb'^^Maaa^^Mbbb^^M' +% \item \verb'aaa^^Mbbb' +% \item \verb'^^Maaa^^Mbbb' +% \item \verb'aaa^^Mbbb^^M' +%\end{enumerate} +% The processing of example (\ref{mmm}) would proceed as follows. +% Call \cw{stripM}, adding \qc{\$} at the beginning and \verb'$^^M$$' +% at the end. +%\begin{verbatim} +% \stripM $^^Maaa^^Mbbb^^M$^^M$$\stripM +%\end{verbatim} +% This finds a match with the \verb'$^^M' at the beginning. The +% remaining text is passed on to \cw{stripMb}. We know that there is +% now an extra \verb'$^^M$$' at the end, but we don't know if the +% first \qc{\$} is preceded by \ctrl{M}. +%\begin{verbatim} +% \stripMb aaa^^Mbbb^^M$^^M$$\stripMb +%\end{verbatim} +% If it turns out that \arg{2} = \qc{\$}, then there was {\em not\/} +% a \ctrl{M} at the end of the original text, and we need to strip +% off a last remaining \qc{\$} sign. Otherwise we are finished if we +% just discard \arg{2} and \arg{3} (the remaining \ctrl{M} and +% \qc{\$} characters of the ones that we added). +% +% We use \qc{\$} as a marker since any \qc{\$} characters that +% happen to occur in the menu text will have category 12 and thus +% not match the category-3 \qc{\$} used in the definition of +% \cw{stripMa} etc. A control sequence could also be used as a +% marker if we took care to give it a bizarre name that would never +% arise in the menu text (\cw{fxmenub} is used not just by +% \cw{fmenu} but also by \cw{fxmenu}, which might have arbitrary +% control sequences in its arguments); but that means using up one +% more hash table entry and additional string pool. +% +% \begin{macro}{\stripM} +% \begin{macrocode} +\lowercase{% +\long\gdef\stripM#1$~#2#3\stripM#4{% + \ifx$#2% + \stripMa#1\stripMa#4% + \else + \stripMb#2#3\stripMb#4% + \fi +} +}% end lowercase +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stripMa} +% \begin{macrocode} +\lowercase{% +\long\gdef\stripMa $#1\stripMa#2{% + \stripMb#1$~$$\stripMb#2} +}% end lowercase +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stripMb} +% \begin{macrocode} +\lowercase{% +\long\gdef\stripMb#1~$#2#3\stripMb#4{% + \ifx$#2% + \stripMc#1\stripMc#4% + \else + \stripMd#1\stripMd#4% + \fi +} +}% end lowercase +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stripMc} +% \begin{macrocode} +\long\gdef\stripMc#1$#2\stripMc#3{% + \stripMd#1\stripMd#3} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\stripMd} +% \begin{macrocode} +\long\gdef\stripMd#1\stripMd#2{#2{#1}} +\endgroup +% \end{macrocode} +% \end{macro} +% +% Some tests. +%\begin{verbatim} +% %\lowercase{\def\test#1{\stripM $#1$~$$\stripM} +% %\tracingmacros=2 \tracingcommands=2 \tracingonline=1 +% %\test{~aaa~bbb~} +% %\test{aaa~bbb} +% %\test{~aaa~bbb} +% %\test{aaa~bbb~} +% %\tracingmacros=0 \tracingcommands=0 \tracingonline=0 +% %}% end lowercase +%\end{verbatim} +% +% \begin{macro}{\stripcontrolMs} +% The argument of \cw{stripcontrolMs} is a token register. The text +% of the token register will be stripped of a leading and trailing +% \ctrl{M} if either or both are present, and the remainder text will +% be left in the token register. +% +% \begin{macrocode} +\begingroup \lccode`\~=`\^^M +\lowercase{% +\gdef\stripcontrolMs#1{\xp@\stripM + \xp@$\the#1$~$$\stripM#1} +}% end lowercase +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\addmenulines} +% \begin{macrocode} +\lowercase{% +\gdef\addmenulines#1#2#3{% +% \end{macrocode} +% Add \arg{2} at the beginning and \arg{3} at the end of every line +% of token register \arg{1}. +% \begin{macrocode} + \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 ~ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fxmenub} +% +% The function \cw{fxmenub} is the one that does most of the hard +% work for \cw{fmenu} and \cw{fxmenu}. Argument \arg{4} is the name +% of the menu, \arg{5} is the argument specifiers (maybe empty). +% Arguments \arg{1}\arg{2}\arg{3} are assignment type, extra setup, +% and expansion control; specifically, these arguments are +% \cw{gdef} \cw{begingroup} \cw{empty} for \cw{fmenu} or \cw{xdef} +% \cw{xmesjsetup} and an extra \cw{noexpand} for \cw{fxmenu}. +% +% That this function actually works should probably be regarded as +% a miracle rather than a result of my programming efforts.^^A +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \footnote{Let's see, three miracles is a prerequisite for sainthood +% in the Catholic church\Dash only two more needed for Don +% Knuth to be a candidate \dots} +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \begin{macrocode} +\def\fxmenub#1#2#3#4#5{% + \stripcontrolMs\menufirstpart + \stripcontrolMs\menulastpart + \stripcontrolMs\menuchoices + \addmenulines\menuchoices\menuline\endmenuline + \actively\let\^^M\relax % needed for \xdef +% \end{macrocode} +% Define \arg{4}. Expansion control is rather tricky because of the +% possibility of parameter markers inside \cw{menufirstpart}, +% \cw{menuchoices} or \cw{menulastpart}. +% \begin{macrocode} + \toks@{\long#1#4#5}% e.g. \xdef\foo##1##2 +% \end{macrocode} +% If \cw{menufirstpart} is empty, we don't add the separator +% material \cw{inmenuA}. +% \begin{macrocode} + \edef\@tempa{\the\menufirstpart}% + \ifx\@tempa\@empty + \let\nxa@\@gobble + \else + \addmenulines\menufirstpart + \menutopline\endmenuline + \let\nxa@\nx@ + \fi +% \end{macrocode} +% If \cw{menulastpart} is empty, we don't add the separator +% material \cw{inmenuB}. +% \begin{macrocode} + \edef\@tempa{\the\menulastpart}% + \ifx\@tempa\@empty + \let\nxb@\@gobble + \else + \addmenulines\menulastpart + \menubotline\endmenuline + \let\nxb@\nx@ + \fi +% \end{macrocode} +% Set up the definition statement that will create the new menu. +% \arg{2} = \cw{begingroup} or \cw{xmesjsetup}. +% \begin{macrocode} +\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 }% +% \end{macrocode} +% Temporarily \cw{relax}ify \cw{menuline} etc. in order to prevent +% their premature expansion if \cw{xdef} is applied. +% \begin{macrocode} + \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 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fxmenu} +% +% Expanding analog of \cw{fmenu}. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\notyet} +% +% \begin{macrocode} +\def\notyet#1{% + \errmessage{Not yet implemented: \string#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\nmenu} +% \begin{macro}{\nxmenu} +% These two functions aren't implemented yet. +%^^A [mjd,24-May-1993] +% \begin{macrocode} +\long\def\nmenu#1#2#3#4#5{\notyet\nmenu} +\long\def\nxmenu#1#2#3#4#5{\notyet\nxmenu} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \section{Menu traversal functions} +% +% For reliable travel up and down the menu tree, we need to push +% and pop the value of \cw{curmenu} as we go along. Among other +% things, \cw{curmenu} is used to repeat the current menu after a +% help message. +% +% \begin{macro}{\optionstack} +% \begin{macrocode} +\newtoks\optionstack +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\curmenu} +% \begin{macrocode} +\let\curmenu\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\estart} +% Start of a stack element. +% \begin{macrocode} +\let\estart\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eend} +% End of a stack element. +% \begin{macrocode} +\let\eend\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pushoptions} +% \begin{macrocode} +\def\pushoptions#1{% + \edef\pushtemp{\estart + \def\nx@\curmenu{\curmenu}% + \eend + \the\optionstack}% + \global\optionstack\xp@{\pushtemp}% + \edef\curmenu{\curmenu#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\popoptions} +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionX} +% +% The \qc{\X} option is a total exit from the menu maze, as +% compared to \cw{moptionQ}, which returns you to the previous menu +% level. +% +% \begin{macrocode} +\fmesj\moptionX{Exiting . . .} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\repeatoption} +% \begin{macrocode} +\def\repeatoption{% + \csname moption\curmenu\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionQ} +% \begin{macrocode} +\def\moptionQ{\popoptions \repeatoption} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\badoptionmesj} +% The sole reason for using \cw{fxmesj} rather than \cw{fmesj} here +% is to use \qc{\%} to comment out the initial newline, as the line +% break was needed only for convenient printing of this +% documentation within a narrow column width. +% \begin{macrocode} +\fxmesj\badoptionmesj#1{% +?---I don't understand "#1".} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\optionexec} +% +% The function \cw{optionexec} takes one argument, which it uses +% together with \cw{curmenu} to determine the next action. The +% argument is expected to be a macro containing a single letter, +% the most recent menu choice received from the user. +% +% Common options such as \qc{\?}, \qc{\Q}, or \qc{\X} that may +% occur at any level of the menu system are handled specially, to +% cut down on the number of control sequence names needed for a +% csname implementation of the menus. +% \begin{macrocode} +\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 +% \end{macrocode} +% Because special characters, including backslash, are deactivated +% by \cw{readChar}, we can apply \cw{csname} without fearing problems +% from responses such as \cw{relax}. +% \begin{macrocode} + \xp@\let\xp@\@tempa + \csname moption\curmenu#1\endcsname + \ifx\@tempa\relax + \badoptionmesj{#1}\let\@tempa\repeatoption + \else + \pushoptions{#1}% + \fi + \fi\fi\fi +% \end{macrocode} +% We save up the next action in \cw{@tempa} and execute it last, to +% get tail recursion. +% \begin{macrocode} + \@tempa +} +% \end{macrocode} +% \end{macro} +% +% Really big menu systems could get around \tex/ memory limits by +% storing individual menus or groups of menus in separate files and +% using \cw{optionfileexec} in place of \cw{optionexec} to +% retrieve the menu text from disk storage instead of from main +% memory. However there are a number of technical complications and +% I probably won't get around to working on them in the near future. +%^^A [mjd,24-May-1993] +% +% \begin{macro}{\optionfileexec} +% \begin{macrocode} +\def\optionfileexec#1{\notyet\optionfileexec} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xoptiontest} +% The function \cw{xoptiontest} must return true if and only if the +% macro \arg{1} consists entirely of one of the one-letter +% responses \verb"? Q q X x" that correspond to special menu +% actions. The rather cautious implementation with \cw{aftergroup} +% avoids rescanning the contents of \verb"#1", just in case it +% contains anything that's \cw{outer}. +% \begin{macrocode} +\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 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\menuhelpmesj} +% +% Default help message, can be redefined if necessary. The extra +% newlines commented out with \qc{\%} are here only for convenient +% printing within a narrow column width. +% +% \begin{macrocode} +\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: +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionhelp} +% \begin{macrocode} +\def\moptionhelp{% + \menuhelpmesj \readline{}\reply \repeatoption} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moptionhelp} +% \cw{moptionhelp} is the branch that will be taken if the user +% enters a question mark in response to a menu. +% \begin{macrocode} +\def\moptionhelp{% + \menuhelpmesj \readline{}\reply \repeatoption} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\moption?} +% \begin{macrocode} +\xp@\def\csname moption?\endcsname{% + \moptionhelp} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\specialhelp} +% The function \cw{specialhelp} can be used to provide a one-time +% alternate help message tailored to a specifc response given by +% the user. It defines the first argument (the macro containing the +% response) to contain \qc{\?}, then redefines \cw{menuhelpmesj} to +% use the message text given in arg \arg{2}. +% \begin{macrocode} +\def\specialhelp#1#2{% + \let\specialhelpreply=#1\def#1{?}\begingroup + \def\menuhelpmesj{\let#1\specialhelpreply + \promptxmesj{#2\ +Press <return> to continue:}\endgroup}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\specialhelpreply} +% Init. +% \begin{macrocode} +\def\specialhelpreply{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lettermenu} +% This is a convenient abbreviation for an often-used combination. +% \begin{macrocode} +\def\lettermenu#1{% + \csname menu#1\endcsname + \readChar{Q}\reply \optionexec\reply +} +% \end{macrocode} +% \end{macro} +% +% Restore any catcodes changed locally, and depart. +% \begin{macrocode} +\restorecatcodes +\endinput +% \end{macrocode} +% +% \CheckSum{513} +% \Finale |