summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/dialogl
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/dialogl
Initial commit
Diffstat (limited to 'macros/latex/contrib/dialogl')
-rw-r--r--macros/latex/contrib/dialogl/Makefile52
-rw-r--r--macros/latex/contrib/dialogl/README158
-rw-r--r--macros/latex/contrib/dialogl/cnvunits.tex139
-rw-r--r--macros/latex/contrib/dialogl/codialog.pdfbin0 -> 408508 bytes
-rw-r--r--macros/latex/contrib/dialogl/default.los82
-rw-r--r--macros/latex/contrib/dialogl/dia-driv.pdfbin0 -> 297137 bytes
-rw-r--r--macros/latex/contrib/dialogl/dia-driv.tex236
-rw-r--r--macros/latex/contrib/dialogl/dialogl-doc.sty536
-rw-r--r--macros/latex/contrib/dialogl/dialogl.dtx1429
-rw-r--r--macros/latex/contrib/dialogl/dialogl.ins92
-rw-r--r--macros/latex/contrib/dialogl/diatest.tex167
-rw-r--r--macros/latex/contrib/dialogl/fontmenu.lg31
-rw-r--r--macros/latex/contrib/dialogl/fontmenu.tex72
-rw-r--r--macros/latex/contrib/dialogl/grabhedr.dtx513
-rw-r--r--macros/latex/contrib/dialogl/listout.dtx5061
-rw-r--r--macros/latex/contrib/dialogl/manifest.txt14
-rw-r--r--macros/latex/contrib/dialogl/menus.dtx983
17 files changed, 9565 insertions, 0 deletions
diff --git a/macros/latex/contrib/dialogl/Makefile b/macros/latex/contrib/dialogl/Makefile
new file mode 100644
index 0000000000..713542232f
--- /dev/null
+++ b/macros/latex/contrib/dialogl/Makefile
@@ -0,0 +1,52 @@
+# Copyright 2013 TeX Users Group.
+# This file is part of the dialogl package, released under the LPPL;
+# see dialogl.ins for details.
+
+pkg = dialogl
+dtx = $(pkg).dtx grabhedr.dtx listout.dtx menus.dtx
+#
+srcfiles = Makefile README
+srcfiles += $(pkg).ins $(dtx)
+srcfiles += cnvunits.tex dia-driv.tex
+srcfiles += dialogl-doc.sty
+srcfiles += fontmenu.tex fontmenu.lg # doc
+srcfiles += diatest.tex
+derivedfiles =
+
+opt = --interaction=nonstopmode --file-line-error
+latex = latex $(opt)
+pdflatex = pdflatex $(opt)
+#
+%.pdf: %.tex
+ $(pdflatex) $<
+ $(pdflatex) $<
+
+default: all
+all: dist
+
+derivedfiles += default.los
+default.los: dialogl.dtx
+
+derivedfiles += codialog.pdf
+codialog.pdf: codialog.tex
+ echo P | pdflatex $<
+ echo P | pdflatex $<
+
+derivedfiles += dia-driv.pdf
+dia-driv.pdf: dialogl-doc.sty
+
+# doesn't really depend on dialog.sty for running, but we want to make
+# sure the .ins works.
+dia-driv.pdf: dialog.sty
+dialog.sty grabhedr.sty listout.tex menus.sty: $(pkg).ins $(dtx)
+ yes | head -100 | latex $<
+# \askforoverwritefalse seemingly has no effect.
+
+dist: $(pkg).zip
+$(pkg).zip: manifest.txt $(srcfiles) $(derivedfiles)
+ chmod a+rw $^
+ rm -f $@; zip $@ $^
+
+manifest.txt: $(srcfiles)
+ chmod a+rw $^
+ echo $@ $^ | tr ' ' '\n' >$@
diff --git a/macros/latex/contrib/dialogl/README b/macros/latex/contrib/dialogl/README
new file mode 100644
index 0000000000..92227b458a
--- /dev/null
+++ b/macros/latex/contrib/dialogl/README
@@ -0,0 +1,158 @@
+Copyright 1994 Michael John Downes
+Copyright 2013 TeX Users Group
+
+This file is part of the dialogl package, released under the LPPL;
+see dialogl.ins for details.
+
+This package was written by Michael Downes, who passed away in 2003. He
+released it under a custom license, now considered nonfree. In October
+2012, his heirs (his children Zoe, Elizabeth, and Mia Downes) have all
+agreed to re-releasing his work under any version of the LaTeX Public
+Project License. Therefore, the package is now released under the LPPL,
+version 1 or (at your option) any later version.
+
+The only changes in this release are to the license, to remove examples
+lacking known-free licenses, and to remove the .stp files for plain TeX
+(which were apparently manually created by editing the .sty's).
+The actual code is the same as Michael's last release.
+
+
+The `dialogl' collection Michael Downes, 10-Nov-1994
+
+The purpose of the `dialogl' collection is to gather together in one
+place a lot of information and examples---probably more than you really
+wanted---about how to write TeX macros to carry on dialog with the user.
+The centerpiece of the package is the file `dialog.sty', which makes it
+easy to add bits of dialog to a LaTeX document; it can also be used with
+non-LaTeX macro packages, if they are plain.tex compatible. Another
+file, listout.tex, has a menu system built with the functions defined in
+menus.sty, which you may enjoy trying out. listout.tex was originally
+written to work with plain TeX; my later attempts to retrofit LaTeX
+compatibility may have some gaps, but it seems to work in the simple
+tests that I have done.
+
+The total size of the dialogl collection is approximately 580K.
+
+INSTALLATION:
+
+LATEX: The .sty files and listout.tex should go into your
+LaTeX input files area, wherever that may be on your system. The
+remaining files can go wherever you want.
+
+
+Suggested usage:
+
+(1) Try using listout.tex to print out some e-mail or program source
+files (e.g. TeX macros), eight or ten pages: Give the command
+
+ tex listout
+
+Navigate through the menu system, try to break it by giving bizarre
+answers, look for other kinds of deficiencies. Find and try out the
+`tiny tabs' option. Find out how to make Control-L characters produce a
+`newpage' effect in the printout.
+
+(2) Print pages 1--5 of the documentation for dialog.sty (dia-driv.tex,
+~25 pages total, see below). You will need doc.sty to do this. Look at
+the user functions described in the documentation to see which ones you
+might want to use.
+
+(4) If you are interested, print out codialog.tex (29 pages): it gives
+a technical overview of TeX's capabilities for dialog, with various
+examples. Further technical discussion is found in the .dtx files, which
+can be printed out individually or using the driver file dia-driv.tex.
+
+ dialogl.dtx 11 pages
+ menus.dtx 9 pages
+ grabhedr.dtx 4 pages
+ listout.dtx 40 pages (includes a full listing of menus at the end)
+
+FUTURE ENHANCEMENTS NEEDED
+
+---Add \nmenu, \nxmenu.
+
+---Adapt further for LaTeX2e. `menus' might perhaps better be done as a
+package option of the dialog package:
+
+ \usepackage[menus]{dialog}
+
+to cut down on the number of different files required.
+
+---Add support for reading menus from disk to cut down on memory
+consumption (currently latex2e+listout.tex uses more than 65K,
+producing `TeX capacity exceeded' error for small TeXs).
+
+---Provide better documentation about what is available for use in the
+running heads/feet (\todaysdate, \nowtime, (\TeXdate \TeXtime?),
+\thisfilename, \dirprefix, etc. Also \folio should be separated into
+\columnfolio and \pagefolio or maybe \pagefolio and \sheetfolio so that
+they can be put in different places separately.
+
+---Provide better support for printing characters in the range 0-31,
+127-255 if suitable fonts are available. (Where the meaning of
+`suitable' is system-dependent and language-dependent.)
+
+---Provide support for embedding `listout' fragments in parent
+documents. Output routine complications make this difficult for
+fragments more than one page long, unless they are restricted to single
+column format. But even that much would be useful.
+
+---Add an index for listout.dtx.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+File list:
+
+INSTALLATION
+
+ README
+ dialogl.ins (for LaTeX2e)
+ diatest.tex (test file)
+
+UTILITIES
+
+ dialog.sty
+ menus.sty
+ grabhedr.sty
+
+ listout.tex
+
+DOCUMENTATION
+
+ Main File Subfiles
+ ---------------------------
+ dia-driv.tex dialogl.dtx
+ menus.dtx
+ grabhedr.dtx
+
+ listout.dtx default.los
+
+ codialog.tex cnvunits.tex
+ fontmenu.tex
+ fontmenu.lg
+
+ dialogl-doc.sty
+
+DIA-DRIV.TEX
+
+This is the driver file for printing out the documentation of
+dialog.sty, menus.sty, and grabhedr.sty. Run it through standard
+LaTeX.
+
+CODIALOG.TEX
+
+This is a substantially revised and augmented version of the paper
+`Dialog with TeX' that appeared in the Proceedings of the 1991 TUG
+Conference at Dedham, Massachusetts (TUGboat vol 12 no 3, December
+1991, Part 2). [In other words: I was dissatisfied with the first
+published version, so I am `publishing' here a better organized
+version with some nice added examples.]
+
+The following files that are printed in the appendixes of the paper are
+included in electronic form in case any finds some use for them.
+
+---fontmenu.tex shows how the token-deletion option of TeX's
+error recovery mechanism can be used to implement a crude menu
+facility.
+
+---cnvunits.tex contains some routines that demonstrate conversion of
+point units to inch units.
diff --git a/macros/latex/contrib/dialogl/cnvunits.tex b/macros/latex/contrib/dialogl/cnvunits.tex
new file mode 100644
index 0000000000..19b8be4463
--- /dev/null
+++ b/macros/latex/contrib/dialogl/cnvunits.tex
@@ -0,0 +1,139 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+
+\newdimen\zdim \newdimen\tempdim \newdimen\tempdima
+
+% Conversion factors:
+%
+% According Scaled Rational Prime
+% Unit to TeX Points Form Factorization
+%-----------------------------------------------------------------
+% 1 sp 0.00002 pt 1 1/65536 pt 1 / 2^16
+% 1 mm 2.84526 pt 186467 7227/2540 pt 3*3*11*73 / 2*2*5*127
+% 1 cm 28.45274 pt 1864679 7227/254 pt 3*3*11*73 / 2*127
+% 1 pt 1.0 pt 65536 100/7227 in 2*2*5*5 / 3*3*11*73
+% 1 pc 12.0 pt 786432 12/1 pt
+% 1 dd 1.07 pt 70124 1238/1157 pt 2*619 / 13*89
+% 1 cc 12.8401 pt 841489 14856/1157 pt 2*2*2*3*619 / 13*89
+% 1 bp 1.00374 pt 65781 803/800 pt 11*73 / 2*2*2*2*2*5*5
+% [1/72 in]
+% 1 in 72.2699 pt 4736286 7227/100 pt 3*3*11*73 / 2*2*5*5
+% [2.54 cm] [254/100 cm]
+
+\def\points#1#2#3{\tempdim#2\relax
+ \edef#3{\csname cnvunits#1\expandafter\endcsname\the\tempdim}%
+}
+
+\def\inches#1#2#3{%
+ \tempdim=#2\relax
+ \tempdima=\ifdim\tempdim<\zdim -\fi\tempdim % absolute value
+ \roundup\tempdima{#1}{in}%
+% In the interest of maximum accuracy we push \tempdima as near
+% to \maxdimen as possible before dividing, using the prime
+% factorization of the fraction 7227/100 which is the
+% points/inches conversion factor.
+ \ifdim\tempdima<.01\maxdimen
+ \multiply\tempdima 100 \divide\tempdima 7227
+ \else
+ \ifdim\tempdima<.1\maxdimen
+ \multiply\tempdima 10 \divide\tempdima 11
+ \multiply\tempdima 10 \divide\tempdima 657
+ \else
+ \divide\tempdima 9 \multiply\tempdima 5
+ \divide\tempdima 803 \multiply\tempdima 20
+ \fi
+ \fi
+ \tempdim=\ifdim\tempdim<\zdim -\fi \tempdima
+ \edef#3{%
+ \csname cnvunits#1\expandafter\endcsname\the\tempdim}%
+}
+
+% Function \roundup for rounding upward. #1 must be a dimension
+% register. If it holds a negative value it will be rounded
+% `outward' away from zero rather than `upward' toward zero. #3
+% is a TeX units string such as "pt" or "in". If #2 = 0 then
+% this will round up to the nearest tenth; if #2 = 00, nearest
+% hundredth; and so forth (up to 5 zeros). If #2 is empty then
+% full accuracy up to TeX's limits will be used.
+%
+% The rounded result will be returned in the dimension register
+% #1.
+
+\def\roundup#1#2#3{%
+ \if .#2.\else
+ \begingroup
+ \ifdim#1>\zdim
+ \advance#1-\maxdimen \advance#1.#25#3\relax
+ \fi
+ \ifdim#1<\zdim
+ \endgroup
+ \advance#1.#25#3
+ \else
+ \endgroup
+ \fi
+ \fi
+}
+
+\begingroup
+\catcode`\P=12 \catcode`\T=12
+\lowercase{%
+\expandafter\gdef\csname cnvunits\endcsname#1PT{#1}
+\expandafter\gdef\csname cnvunits0\endcsname#1.#2PT{%
+ #1.\takeone#20\takeone}
+\expandafter\gdef\csname cnvunits00\endcsname#1.#2PT{%
+ #1.\taketwo#200\taketwo}
+\expandafter\gdef\csname cnvunits000\endcsname#1.#2PT{%
+ #1.\takethree#2000\takethree}
+\expandafter\gdef\csname cnvunits0000\endcsname#1.#2PT{%
+ #1.\takefour#20000\takefour}
+\expandafter\gdef\csname cnvunits00000\endcsname#1.#2PT{%
+ #1.\takefive#200000\takefive}
+}%
+\endgroup
+
+\def\takeone#1#2\takeone{#1}
+\def\taketwo#1#2#3\taketwo{#1#2}
+\def\takethree#1#2#3#4\takethree{#1#2#3}
+\def\takefour#1#2#3#4#5\takefour{#1#2#3#4}
+\def\takefive#1#2#3#4#5#6\takefive{#1#2#3#4#5}
+
+\def\showinches#1{\inches{00}{#1}\converted
+ \immediate\write16{%
+ #1 = (after conversion) \converted\space inches}}
+
+\showinches{0in} \showinches{1in} \showinches{2.0in}
+\showinches{2.2in} \showinches{8.5in} \showinches{1pc}
+\showinches{6pc} \showinches{1cm} \showinches{1mm}
+\showinches{1bp} \showinches{72bp} \showinches{1cc}
+\showinches{1dd} \showinches{72dd} \showinches{5000pt}
+\showinches{-5000pt} \showinches{\maxdimen}
+\showinches{-\maxdimen} \showinches{.999\maxdimen}
+\showinches{1pt} \showinches{.01pt}
+
+\endinput
+
+% From the TeX log:
+
+0in = (after conversion) 0.00 inches
+1in = (after conversion) 1.00 inches
+2.0in = (after conversion) 2.00 inches
+2.2in = (after conversion) 2.20 inches
+8.5in = (after conversion) 8.50 inches
+1pc = (after conversion) 0.17 inches
+6pc = (after conversion) 1.00 inches
+1cm = (after conversion) 0.39 inches
+1mm = (after conversion) 0.04 inches
+1bp = (after conversion) 0.01 inches
+72bp = (after conversion) 1.00 inches
+1cc = (after conversion) 0.18 inches
+1dd = (after conversion) 0.01 inches
+72dd = (after conversion) 1.07 inches
+5000pt = (after conversion) 69.18 inches
+-5000pt = (after conversion) -69.18 inches
+\maxdimen = (after conversion) 226.70 inches
+-\maxdimen = (after conversion) -226.70 inches
+.999\maxdimen = (after conversion) 226.48 inches
+1pt = (after conversion) 0.01 inches
+.01pt = (after conversion) 0.00 inches
diff --git a/macros/latex/contrib/dialogl/codialog.pdf b/macros/latex/contrib/dialogl/codialog.pdf
new file mode 100644
index 0000000000..b992e79cbb
--- /dev/null
+++ b/macros/latex/contrib/dialogl/codialog.pdf
Binary files differ
diff --git a/macros/latex/contrib/dialogl/default.los b/macros/latex/contrib/dialogl/default.los
new file mode 100644
index 0000000000..21f850ebb7
--- /dev/null
+++ b/macros/latex/contrib/dialogl/default.los
@@ -0,0 +1,82 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+
+% 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\eightbitaction{B}
+\def\systemtype{DOS}
+\def\losdir{}
+\storemesj\dirprefix{}
+\chardef\spacespertab=8\relax
+\chardef\tabselect=1\relax
+
diff --git a/macros/latex/contrib/dialogl/dia-driv.pdf b/macros/latex/contrib/dialogl/dia-driv.pdf
new file mode 100644
index 0000000000..ab82b9ce85
--- /dev/null
+++ b/macros/latex/contrib/dialogl/dia-driv.pdf
Binary files differ
diff --git a/macros/latex/contrib/dialogl/dia-driv.tex b/macros/latex/contrib/dialogl/dia-driv.tex
new file mode 100644
index 0000000000..c0f6b9d06e
--- /dev/null
+++ b/macros/latex/contrib/dialogl/dia-driv.tex
@@ -0,0 +1,236 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+%
+% Originally published in TUGboat with ltugboat documentstyle.
+% Switched to generic article/twocolumn afterward.
+% Does not work with either LaTeX2e or LaTeX 2.09 compatibility mode :(.
+\documentstyle[doc,dialogl-doc]{article}
+
+\title{Interaction tools: {\tt dialog.sty} and {\tt menus.sty}}
+\author{Michael Downes}
+\date{November 3, 1994}
+
+% one latex2e command gets used.
+\def\ensuremath#1{\ifmmode #1\else $#1$\fi\relax}
+
+\hyphenation{pro-duces}
+
+\renewcommand{\thepart}{\arabic{part}}
+\renewcommand{\thesection}{\thepart.\arabic{section}}
+
+% Some customizations of doc.sty parameters.
+\def\PrintMacroName#1{}
+%
+%\renewcommand{\PrintDescribeMacro}[1]{}
+%\renewcommand{\PrintDescribeEnv}[1]{}
+
+\setlength{\MacroIndent}{0pt}
+\def\MacroFont{\verbatimfont}% doc.sty uses \MacroFont
+
+% No modules in the files to be processed; so don't bother checking.
+\DontCheckModules
+
+\multicoldefaultlayout
+\begin{document}
+\jobswitch % print only selected parts if \jobname so indicates; see
+ % dialog.sty
+\maketitle
+\thispagestyle{empty}
+
+\begin{multicols}{2}
+\section*{Introduction}
+
+\ifall
+This article describes
+\fn{dialog.sty} and \fn{menus.sty}, which
+provide functions for printing messages or menus on screen and reading
+users' responses. The file \fn{dialog.sty} contains basic message and
+input-reading functions; \fn{menus.sty} takes \fn{dialog.sty} for its
+base and uses some of its functions in defining more complex menu
+construction functions. These two files are set up in the form of
+\LaTeX{} documentstyle option files, but in writing them I spent some
+extra effort to try to make them usable with \plaintex/ or other
+common macro packages that include \plaintex/ in their base, such as
+\AmSTeX{} or \eplain/.
+
+The appendix describes \fn{grabhedr.sty}, required by \fn{dialog.sty},
+which provides two useful file-handling features: (1)~a command
+\cw{inputfwh} that when substituted for \cw{input} makes it possible to
+grab information such as file name, version, and date from standardized
+file headers in the style promoted by Nelson Beebe\Dash and to grab it
+in the process of first inputting the file, as opposed to inputting the
+file twice, or \cw{read}ing the information separately (unreliable due
+to system-dependent differences in the equivalence of \tex/'s \cw{input}
+search path and \cw{openin} search path). And (2)~functions
+\cw{localcatcodes} and \cw{restorecatcodes} that make it possible for
+\fn{dialog.sty} (or any file) to manage internal catcode changes
+properly regardless of the surrounding context.
+
+These files and a few others are combined in
+\else
+This package is part of
+\fi
+a suite of files that goes
+by the name of {\bf dialogl}, available on the Internet by anonymous ftp
+from CTAN (Comprehensive \tex/ Archive Network), e.g., \fn{ftp.shsu.edu}
+(USA), or \fn{ftp.uni-stuttgart.de} (Europe).
+%
+\ifall
+The file \fn{listout.tex} is a utility for verbatim printing of plain
+text files, with reasonably good handling of overlong lines, tab
+characters, other nonprinting characters, etc. It uses \fn{menus.sty} to
+present an elaborate menu system for changing options (like font size,
+line spacing, or how many spaces should be printed for a tab character).
+\else
+It includes the packages \pkg{dialog}, \pkg{menus}, and \pkg{grabhedr}
+and a utility file \fn{listout.tex} for verbatim printing of plain text
+files.
+\fi
+
+\ifmenus
+Here's an example from the menu system of \fn{listout.tex} to
+demonstrate the use of some features from \fn{dialog.sty} and
+\fn{menus.sty}. First, the menu that you would see if you wanted to
+change the font or line spacing:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% This funny way of calling \samepage is (I think) the most
+% convenient way to avoid turning off page breaks for the preceding
+% paragraph.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\next{\begin{verbatim}\samepage}\next
+===============================================
+ F Change font
+ S Change font size
+ L Change line spacing
+
+Current settings: typewriter 8 / 10.0pt.
+
+ Q Quit X Exit ? Help
+===============================================
+
+Your choice?
+\end{verbatim}
+Suppose you wanted to change line spacing to 9 points, so you entered
+\qc{\l} (lowercase \qc{\L}) and then \verb'9pt', except that on your
+first attempt you accidentally mistyped \verb'9pe' instead of
+\verb'9pt'. Here's what you would see on screen:
+\begin{verbatim}
+Your choice? l
+Desired line spacing [TeX units] ? 9pe
+?---I don't understand "9pe".
+Desired line spacing [TeX units] ? 9pt
+
+* New line spacing: 9.0pt
+\end{verbatim}
+Both lowercase \verb'l' and capital \verb'L' are acceptable responses,
+and the value given for line spacing is checked to make sure it's a
+valid \tex/ dimension. Before continuing, the internalized version of
+the user's value is echoed on screen to confirm that the entered value
+was read correctly.
+
+Now here's how the above menu is programmed in \fn{listout.tex}.
+A function \cw{menuF} is constructed using \cw{fxmenu}:
+\begin{verbatim}
+\fxmenu\menuF{}{
+F Change font
+S Change font size
+L Change line spacing
+}{
+Current settings: &\mainfont &\mainfontsize / %
+&\the&\normalbaselineskip.
+}
+%
+\def\moptionF{\lettermenu F}
+\end{verbatim}
+In the definition of \cw{moptionF}, \cw{lettermenu} is a high-level
+function from \fn{menus.sty} that prints \cw{menuF} on screen (given
+the argument \verb'F'), reads a line of input from the user, extracts
+the first character and forces it to uppercase, then branches to
+the next menu as determined by that character. The response of
+\verb'l' causes a branch to the function \cw{moptionFL}:
+\begin{verbatim}
+\def\moptionFL{%
+ \promptmesj{%
+ Desired line spacing [TeX units] ? }%
+ \readline{Q}\reply
+\end{verbatim}
+If \verb'Q', \verb'X', or \verb'?' was entered, the test
+\cw{xoptiontest} will return `true'; then we should skip the dimension
+checking and go directly to \cw{optionexec}, which knows what to do
+with those responses:
+\begin{verbatim}
+ \if\xoptiontest\reply
+ \else
+\end{verbatim}
+Otherwise we check the given dimension to make sure it's usable. If so,
+echo the new value as confirmation.
+\begin{verbatim}
+ \checkdimen\reply\dimen@
+ \ifdim\dimen@>\z@
+ \normalbaselineskip\dimen@\relax
+ \normalbaselines
+ \confirm{New line spacing:
+ \the\normalbaselineskip}%
+ \def\reply{Q}%
+ \fi
+\end{verbatim}
+If \cw{reply} was changed to \verb'Q' during the above step,
+\cw{optionexec} will pop back up to the previous menu level (normal
+continuation); otherwise \cw{reply} retains its prior definition\Dash
+e.g., \verb'9pe'\Dash to which \cw{optionexec} will simply say ``I
+don't understand that'' and repeat the current prompt.
+\begin{verbatim}
+ \fi
+ \optionexec\reply
+}
+\end{verbatim}
+
+For maximum portability, \fn{listout.tex} uses in its menus only
+lowest-common-denominator ordinary printable ASCII characters in the
+range 32\dash 126. Fancier menus can be obtained at a cost of forgoing
+system independence, for instance by using em\tex/'s \verb'/o' option
+to output the box-drawing characters in the standard PC DOS character
+set.
+\fi
+
+\subsection*{Notation}
+
+Double-hat notation such as \verb'^^J' is used herein for
+control characters, as in \TB{}, although occasionally the alternate
+form `{\sc control}-J' is used when the emphasis is away from the
+character's tokenized state inside \tex/. A couple of abbreviations
+from \fn{grabhedr.sty} are used frequently in the macro code: \cw{xp@}
+= \cw{expandafter}, and \cw{nx@} = \cw{noexpand}. Standard
+abbreviations from \fn{plain.tex} such as \cw{z@} or \cw{toks@} are
+used without special comment.
+
+\ifall
+\part{Basic dialog functions: \fn{dialog.sty}}
+\fi
+\ifdialog\hDocInput{dialogl.dtx}\fi
+
+\ifall
+\part{Menu functions: \fn{menus.sty}}
+\setcounter{section}{0}
+\fi
+\ifmenus\hDocInput{menus.dtx}\fi
+
+\ifall
+% It's hard to make this part title come out right without assuming
+% \partname is defined.
+\part*{Appendix\penalty-10000
+Miscellaneous support functions:
+\fn{grabhedr.sty}}
+\setcounter{section}{0}
+\renewcommand{\thepart}{A} % for use in \thesection
+\fi
+\ifgrabhedr\hDocInput{grabhedr.dtx}\fi
+
+\end{multicols}
+
+\ifdim\textwidth>\textheight
+\typeout{^^JWarning: remember to print using LANDSCAPE orientation^^J}
+\fi
+\end{document}
diff --git a/macros/latex/contrib/dialogl/dialogl-doc.sty b/macros/latex/contrib/dialogl/dialogl-doc.sty
new file mode 100644
index 0000000000..3077de1d65
--- /dev/null
+++ b/macros/latex/contrib/dialogl/dialogl-doc.sty
@@ -0,0 +1,536 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+%
+% Customizations for the articles/documentation codialog.tex,
+% dia-driv.tex, lis-driv.tex.
+%
+% Here is the main problem. I want to allow users to print out this
+% document on US letter-size paper (8.5x11 inches) or on A4 paper
+% (210x297 mm). And in order to fit maximum text on minimum paper
+% (save the trees) I want to print with small margins and
+% two-column layout (or even three-column, in the case of landscape
+% printing, if that were feasible; but I don't want to assume that
+% the user has Frank's multicol package). But the verbatim examples
+% in the document consist in many cases of lines from TeX screen
+% output, which can be up to 79 characters in length. It is
+% difficult to give two columns wide enough to accommodate
+% 80-character lines printed in cmtt unless the size is cut down
+% very small. Then we encounter the difficulty that the
+% lowest-common-denominator set of TeX fonts includes cmtt10,
+% cmtt9, cmtt8, but not cmtt7 or any smaller sizes of cmtt. Well,
+% perhaps that's just as well since things start to get a little
+% hard to read anyway once you get down that small.
+%
+% But anyway there it is: How to fit two columns of text, each of
+% minimum width approximately 80 cmtt characters, into the
+% rectangles provided by US letter paper and A4 paper, while trying
+% to keep a decent line length for readability in the neighborhood
+% of two or three alphabets.
+%
+% It seems that one part of the answer is to print the 80-character
+% verbatim lines in a smaller point size than the main text.
+
+% 8.5in = 614.295pt.
+% 11in = 794.96999pt.
+% 210mm = 597.50787pt.
+% 297mm = 845.04684pt.
+
+% 80 characters, cmtt10: 419.99634pt.
+% 80 characters, cmtt8: 340.00488pt.
+% 76 characters, cmtt8: 323.00464pt.
+% 70 characters, cmtt8: 297.50427pt.
+
+% Assume that minimum margins all around are 22pt, approx 8mm /
+% 0.3in. And that desired gutter margin between columns is 6pt.
+% Then subtract 50pt from paper width and divide by 2 to get
+% available column width: 210mm 274pt, 8.5in 282pt, 11in 372pt,
+% 297mm 397pt.
+%
+% Standard \headheight, \headsep are 12pt, 25pt. So next we look for
+% minimum bounding rectangle for landscape, two-column printing:
+% textheight limited by A4 short dimension = 210mm = 598pt.
+% Subtract 44pt for margins, then another 37pt for running head,
+% that leaves textheight of 517pt.
+%
+% Similarly for textwidth: Limited by the 11in long dimension of US
+% letter size paper; subtract 50pt for margins and gutter, that
+% leaves 745pt, or 372pt per column.
+
+\newcommand{\notthatsloppy}{\tolerance9999 \pretolerance3333
+ \hbadness\tolerance
+% The tolerance settings will eliminate most hyphenation unless we
+% ameliorate the hyphen penalties.
+ \hyphenpenalty-100 \exhyphenpenalty-150
+ \emergencystretch 3pc }
+
+% But then we'd better patch \raggedright up a litt.e
+\toks@\expandafter{\raggedright \hyphenpenalty100 \exhyphenpenalty150 }
+\edef\raggedright{\the\toks@}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\pagestyle{headings}
+\let\sectionmark\@gobble
+\def\@oddhead{\hfil{\small\rhtitle}\hfil\thepage}
+\let\@evenhead\@oddhead
+\def\title#1{\gdef\@title{#1}\uppercase{\gdef\rhtitle{#1}}}
+
+% Default layout is twocolumn, landscape, squeeze inside A4/US
+% constraints
+\def\defaultlayout{%
+% \hoffset and \voffset are assumed to be -1in (see below)
+% 210mm is A4 width, 11in is US-letter paper height
+ \textwidth11in \textheight210mm
+ \oddsidemargin30pt \evensidemargin\oddsidemargin
+ \advance\textwidth -2\oddsidemargin
+ \topmargin25pt
+ \advance\textheight-2\topmargin
+ \advance\textheight-\headheight \advance\textheight -\headsep
+ \let\Huge\large \let\huge\large \let\LARGE\large \let\Large\large
+% \scaleup \normalsize
+ \@twocolumntrue
+}
+
+% Twocolumn, portrait, squeeze inside A4/US
+% constraints
+\def\portraitlayout{%
+% \hoffset and \voffset are assumed to be -1in (see below)
+% 210mm is A4 width, 11in is US-letter paper height
+ \textheight11in \textwidth210mm
+ \oddsidemargin30pt \evensidemargin\oddsidemargin
+ \advance\textwidth -2\oddsidemargin
+ \topmargin25pt
+ \advance\textheight-2\topmargin
+ \advance\textheight-\headheight \advance\textheight -\headsep
+ \let\Huge\large \let\huge\large \let\LARGE\large \let\Large\large
+% \scaleup \normalsize
+ \@twocolumntrue
+ \def\vffont{\footnotesize\tt}%
+ \def\verbatimfont{\small\tt}%
+}
+
+% If the multicol package is loaded (via the doc package) we want to
+% use that instead of the standard twocolumn option.
+\def\multicoldefaultlayout{\defaultlayout\@twocolumnfalse}
+\def\multicolportraitlayout{\portraitlayout\@twocolumnfalse}
+
+% Cancel the margins normally supplied by DVI drivers:
+\hoffset-1in \voffset-1in
+
+% Set \hfuzz higher than normal in preference to dealing with
+% insoluble hyphenation/line-breaking problems.
+\hfuzz20pt
+
+% Set sloppiness of paragraphs very high because of the narrow
+% column width and the frequency of difficult to break terms, but
+% not so carelessly high as LaTeX's \sloppy command would give.
+\notthatsloppy
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def\scaleup{%
+ \let\tiny\scriptsize \let\scriptsize\footnotesize
+ \let\footnotesize\small \let\small\normalsize
+ \let\normalsize\large \let\large\Large
+}
+
+\def\scaledown{%
+ \let\Huge\large \let\huge\large
+ \let\LARGE\large \let\Large\normalsize
+ \let\large\normalsize \let\normalsize\small
+ \let\small\footnotesize \let\footnotesize\scriptsize
+ \let\scriptsize\tiny
+}
+%
+% Add protection built-in for \TeX and others
+\newcommand{\ams}{{\the\textfont2 A\kern-.1667em%
+ \lower.5ex\hbox{M}\kern-.125emS\kern.05em}}
+\def\tex/{\protect\TeX\@}
+\def\amstex/{\protect\ams-\tex/}
+\def\latex/{\protect\LaTeX\@}
+\def\plaintex/{{\sc plain}\thinspace\tex/}
+\def\eplain/{{\sc Eplain}}
+\def\texbook/{{\it The \tex/book}}
+\def\tugboat/{{\it TUGboat}}
+\def\return/{{\sc return}}
+\def\mf/{{\sf METAFONT\@}}
+\def\mfbook/{{\it The \mf/book}}
+\def\ascii/{{\sc ascii}}
+
+\newcommand{\ndash}{--}
+\newcommand{\mdash}{---}
+\newcommand{\btext}{\mbox}
+
+\newcommand{\5}{\penalty500 }
+\newcommand{\underscore}{{\ntt\string _}}
+
+% Define some ltugboat.sty commands
+\let\Dash\mdash
+\let\dash\ndash
+\def\TB{\texbook/}
+\def\TUB{{\sl TUGboat\/}}
+\def\TeXhax{{\ntt TeXhax}}
+
+\@ifundefined{selectfont}{%
+ \def\normalfont{}%
+}{%
+ \@ifundefined{default@family}{%
+ \@ifundefined{normalfont}{%
+ \def\normalfont{}% ?? don't think this case can ever happen.
+ }{}%
+ }{%
+ \def\normalfont{\fontfamily\default@family
+ \fontseries\default@series \fontshape\default@shape \selectfont}%
+ }%
+}
+
+% Maybe I should now change instances of \normalshape to \upshape.
+% But this is what was used before.
+\@ifundefined{normalshape}{%
+ \@ifundefined{upshape}{%
+ \newcommand{\normalshape}{\rm}%
+ }{%
+ \newcommand{\normalshape}{\upshape}%
+ }%
+}{}
+
+\def\ntt{\protect\normalfont\protect\tt}
+
+% Function called at the beginning of \cw etc. to allow line
+% breaks if several such objects occur contiguously.
+\newcommand{\prebreak}{\leavevmode\ifmmode\hbox\else
+ \ifdim\lastskip=\z@\penalty9999 \fi\fi}
+
+% The \ifhmode test here is primarily to guard against math mode,
+% where an attempt to set \spacefactor would cause a TeX error.
+\newcommand{\postx}{\ifhmode\@\fi}
+
+% Control word
+\newcommand{\cw}[1]{\protect\prebreak{\ntt\bslash#1\protect\postx}}
+% Control symbol
+\newcommand{\cs}[1]{\protect\prebreak{\ntt\string#1}\protect\postx}
+\chardef\bslash=`\\
+
+% Quoted character
+\newcommand{\qc}[1]{%
+ \protect\prebreak{\ntt\escapechar-1 \string#1}\protect\postx}
+% Control character
+\newcommand{\ctrl}[1]{%
+ \protect\prebreak{\ntt\string ^\string ^#1}\protect\postx}
+% Argument marker. Apply \string to #1 just in case it might be #
+% instead of a number 1--9.
+\renewcommand{\arg}[1]{%
+ \protect\prebreak{\ntt\string ##\string#1}\protect\postx}
+\let\qarg\arg
+% File name.
+\newcommand{\fn}[1]{\leavevmode{\ntt#1}\protect\postx}
+\let\pkg\fn
+% Verbatim version of \ldots.
+\newcommand\verbdots{\leavevmode{\ntt...}\protect\postx}
+
+\newcommand{\units}[1]{\thinspace#1}
+
+% For `meta' angle bracket notation.
+\newcommand\m[1]{{\protect\the\textfont2 h{\it#1}i}}
+% For definitions of terminology.
+\newcommand{\term}[1]{\leavevmode{\it#1}}
+
+\def\eg.{e.g.\@}
+\def\ie.{i.e.\@}
+
+%\def\mjd#1{\errhelp{#1}\errmessage{\the\errhelp}}
+\def\mjd#1{}
+
+% ^^V at the beginning of a line serves as a substitute for
+% \begin{verbatim} ... \end{verbatim} in this documentation. Partly
+% done as an exercise to see if it was feasible; originally
+% motivated by the way I had converted comments in non-doc form to
+% doc form.
+\catcode`\^^V\active % for verbatim
+\def ^^V{\Vbtm}
+
+\def\activedef#1{\catcode`#1\active
+ \begingroup\lccode`\~=`#1\lowercase{\endgroup \def ~}}
+
+\def\Vbtmsetup{\let\do\@makeother
+% Abandon \dospecials since it's too hard to make sure that it
+% includes things like @, |, +.
+ \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\'\do\"%
+ \do\,\do\<\do\.\do\>\do\/\do\?\do\ \do\^^M\do\^^I\do\^^J\do\^^L%
+ \activedef\ {\kern.5em}%
+ \activedef\'{\char`\'\kern\z@}%
+ \Vbtmfont \frenchspacing
+}
+%
+\def\Vbtm{\par
+ \begingroup \Vbtmsetup
+ \activedef\^^M{\catcode`\%9 \catcode`\^7
+ \futurelet\next\moreVbtm}%
+ \def\VbtmVbtm{\Vbtm}% for comparison with active ^^V.
+ \def\moreVbtm{%
+ \ifx\next \VbtmVbtm
+ \def\next{\egroup\penalty9999 }%
+ \else
+ \def\next{\egroup\endgroup \futurelet\next\endVbtm}%
+ \fi \next}%
+% Locally change \Vbtm to omit the above setup and just process a
+% single line.
+ \def\Vbtm{\hbox\bgroup}%
+ \Vbtmspace \Vbtmextra \Vbtm}
+%
+\def\endVbtm{%
+ \begingroup
+% If the next token is a \par token, gobble it with \let.
+ \ifx\next\par \aftergroup\let \aftergroup\next \fi
+ \Vbtmspace \everypar{}\parskip0pt \noindent\endgroup
+}%
+
+\def\Vbtmfont{\verbatimfont}
+%
+\def\Vbtmspace{\medskip}
+\def\Vbtmextra{}
+%
+% Define a `usage' environment to draw a box around its contents,
+% for examples illustrating the usage of salient functions.
+\def\usage{\par \begingroup \Vbtmsetup \normalsize\tt
+% Requires definition of \meta from doc.sty:
+ \activedef\<##1>{\meta{##1}}%
+ \activedef\^^M{\catcode`\%9\catcode`\\\z@ \catcode`\{11 \catcode`\}11
+ \futurelet\next\moreusage}%
+ \if@inlabel\leavevmode\fi \ifhmode\unskip \par\fi
+ \addvspace\medskipamount
+ \global\setbox\@ne\vbox\bgroup \everypar{}%
+ \bgroup}
+%
+\expandafter\def\expandafter\moreusage\expandafter{%
+ \expandafter\ifx\csname end{usage}\endcsname\next
+ \egroup\egroup
+ \fboxsep1.7pt \noindent\fbox{\box\@ne}%
+ \endgroup
+ \else
+ \egroup
+ \hbox\bgroup\expandafter\string
+ \fi}%
+%
+\expandafter\def\csname end{usage}\endcsname{\end{usage}}
+\def\endusage{\par\nobreak\vskip\medskipamount
+% Since \endusage is called via \end, which adds an \endgroup, we
+% need to throw these two items beyond the \endgroup in order for
+% their local assignments not to be lost (\if@afterindent,
+% \everypar):
+ \aftergroup\@afterindentfalse
+ \aftergroup\@afterheading}
+
+\def\verbatimfont{\tt}
+\def\vffont{\small\tt}
+
+% Change verbatim environment to use \verbatimfont.
+
+\def\@verbatim{\trivlist \item[]\if@minipage\else\vskip\parskip\fi
+ \leftskip\@totalleftmargin\rightskip\z@
+ \parindent\z@\parfillskip\z@ plus\columnwidth minus\columnwidth
+ \parskip\z@skip
+ \@@par
+ \@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par
+ \penalty\interlinepenalty}%
+ \obeylines
+ \linepenalty\@M
+ \verbatimfont \normalbaselineskip1.1em\relax \normalbaselines
+ \catcode``=13 \@noligs \let\do\@makeother \dospecials}
+
+% Define a verbatim input command for printing example files.
+\def\verbatiminput#1{\begingroup
+ \@verbatim \frenchspacing\@vobeyspaces
+ \exhyphenpenalty\@M \hyphenpenalty\@M
+% Turn \hfuzz up high; if some lines in the file are a little long,
+% we don't want to hear about it.
+ \hfuzz 5em\relax \vffont
+ \input{#1}%
+ \endverbatim
+ \endgroup}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Misc.
+\setcounter{secnumdepth}{2}
+\newcommand{\secref}[1]{\S\ref{#1}}
+\renewcommand{\thetable}{\Alph{table}}
+
+% Change \l@section so we can allow wider room for `Appendix A' in
+% the appendix section of the table of contents.
+\renewcommand{\l@section}[2]{%
+ \ifnum\c@tocdepth>\z@
+ \addpenalty{\@secpenalty}\addvspace{1.0emplus\p@}%
+ \setlength\@tempdima{\tocsecwd}\begingroup \parindent\z@
+ \rightskip\@pnumwidth \parfillskip-\@pnumwidth \leavevmode \bf
+ \advance\leftskip\@tempdima \hskip-\leftskip #1\nobreak \hfil\nobreak
+ \hbox to\@pnumwidth{\hss#2}\par \endgroup
+ \fi}
+\def\tocsecwd{1.5em}
+
+\toks@\expandafter{\appendix
+ \addtocontents{toc}{\protect\changesecwd{6.5em}}}
+\edef\appendix{\the\toks@}
+\def\changesecwd{\gdef\tocsecwd}
+
+\def\resetleftmargin#1{\dimen@\@totalleftmargin
+ \linewidth\columnwidth \advance\linewidth-\@totalleftmargin
+ \edef\@tempa{\parshape2 \the\dimen@\space \the\linewidth\space}%
+ \@totalleftmargin#1\relax
+ \linewidth\columnwidth \advance\linewidth-\@totalleftmargin
+ \@tempa \@totalleftmargin\linewidth \relax}
+
+% For raggedright parbox in tabular.
+\newcommand{\rp}{\let\PBS\\\raggedright\let\\\PBS}
+
+% \readnumber reads a number into #1, default #2.
+\def\readnumber#1#2{\begingroup
+ \def\do##1##2{\catcode\fam=##2 \ifnum\fam<##1 \advance\fam 1
+ \expandafter\do \else\expandafter\@gobbletwo\fi{##1}{##2}}%
+ \fam=0 \do{255}{9}\fam=`\0\relax \do{`\9}{12}%
+ \global\read-1 to#1\endgroup
+ \ifx#1\@empty\gdef#1{#2}\fi
+}
+
+\def\thebibliography#1{%
+ \section*{References}%
+ \small
+ \list{\@biblabel{\arabic{enumiv}}}{%
+ \settowidth\labelwidth{\@biblabel{#1}}
+ \leftmargin2em
+ \usecounter{enumiv}\let\p@enumiv\@empty
+ \renewcommand\theenumiv{\arabic{enumiv}}}%
+ \sloppy
+ \clubpenalty4000\widowpenalty4000\sfcode`\.=\@m}
+
+% \writepage{Example} or \writepage{Table}
+\newcommand{\writepage}[1]{%
+ \edef\temp{\write16{#1 \@currentlabel: Page \noexpand\thepage}}%
+ \temp
+}
+
+% \reqspace{2in} means start a new page if the current page does not
+% have at least 2in of space available
+\newcommand{\reqspace}[1]{\vskip#1plus.2\textheight
+ \penalty0\vskip-#1plus-.2\textheight\penalty0 }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Use {example}'s instead of {figure}'s.
+\let\example\figure
+\let\endexample\endfigure
+\expandafter\let\csname example*\expandafter\endcsname
+ \csname figure*\endcsname
+\expandafter\let\csname endexample*\expandafter\endcsname
+ \csname endfigure*\endcsname
+\@namedef{fnum@figure}{Example \thefigure}
+
+\def\theexample{\thefigure}
+
+\newenvironment{examplebox}%
+{% Can't use LaTeX \framebox because of embedded verbatim; can't
+%% embed this inside definition of \example without too much work.
+ \vbox\bgroup\hrule
+ \hbox to\hsize\bgroup\vrule \hfil
+ \vbox\bgroup\advance\hsize-2em
+}{%
+ \endgraf
+ \kern3pt\egroup\hfil\vrule\egroup\hrule\egroup % finish off the frame
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Ordinary \DocInput doesn't handle standardized file headers
+% unless you enclose them in \iffalse ... \fi which I don't care to
+% do. So instead here's an alternate version of \DocInput, called
+% \hDocInput.
+
+\def\hDocInput#1{\MakePercentIgnore
+ \begingroup \begingroup \lccode`\~=`\@
+ \lowercase{\endgroup\long\def ~}##1##{%
+ \catcode`\==12 \skipfileheader{##1}}%
+ \catcode`\@=\active \catcode`\==14 % comment
+ \@@input#1 \MakePercentComment}
+
+\def\skipfileheader#1#2 {\endgroup
+ \begingroup\catcode`\==9 \catcode`\ =9 \futurelet\0\endgroup
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Loosen up the float placement restrictions.
+\def\textfraction{0.02}
+\def\bottomfraction{0.98}
+\def\topfraction{0.98}
+\let\dbltopfraction=\topfraction
+\def\floatpagefraction{0.8}
+\let\dblfloatpagefraction=\floatpagefraction
+\setcounter{bottomnumber}{3}
+\setcounter{topnumber}{3}
+\setcounter{dbltopnumber}{3}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\allowtthyphens{%
+ {\small\tt\hyphenchar\font=45 \normalsize\tt\hyphenchar\font=45
+ \footnotesize\tt\hyphenchar\font=45 }}
+
+%%\renewcommand{\cw}[1]{\protect\prebreak{\ntt\bslash#1}\protect\postx
+%% \sh{#1}}
+%%% Control symbol
+%%\renewcommand{\cs}[1]{\protect\prebreak{\ntt\string#1}\protect\postx
+%% \sh{#1}}
+%%\renewcommand{\fn}[1]{\leavevmode{\ntt#1}\protect\postx\sh{#1}}
+%%\def\sh{\protect\showhyphens}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Fix up catcodes of the upper 128 characters just in case someone
+% has an early release of LaTeX2e. (pre June 1994 patch-level 2)
+\def\do{\catcode\count@\@tempa \advance\count@\@ne
+ \ifnum\count@>\@cclv \expandafter\@gobble\fi \do}
+
+\count@=128 \chardef\@tempa=12 \do
+
+\def\mstrip#1->{}
+\def\jobswitch{%
+ \def\@tempa{dia-driv}%
+ \edef\@tempa{\expandafter\mstrip\meaning\@tempa}%
+ \edef\@tempb{\jobname}%
+ \ifx\@tempa\@tempb
+ \dialogtrue \menustrue \grabhedrtrue
+ \alltrue
+ \else
+ \csname\jobname true\endcsname
+ \title{The {\tt\jobname} package}%
+ \fi
+}
+
+\newif\ifdialog \newif\ifall \newif\ifmenus \newif\ifgrabhedr
+
+\endinput
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Some old stuff from codialog.tex
+\typeout{%
+This document offers three printing options:^^J%
+(1) A4 (297 x 210 mm), two columns, landscape orientation,^^J%
+(2) US letter (11 x 8.5 inches), two columns, landscape orientation.^^J%
+(3) US letter (8.5 x 11 inches), one column, portrait orientation.^^J%
+}
+
+% \readnumber is defined in dialogm.sty
+\message{Enter the number for your choice (default 2): }
+\readnumber{\answer}{2}
+
+% \adjustlayout is defined in dialogm.sty
+\ifcase \answer\relax
+ \typeout{Defaulting to US letter, landscape ...}% 0
+ \adjustlayout{11in}{8.5in}%
+ \or \typeout{OK, using A4 layout ...}% 1
+ \adjustlayout{297mm}{210mm}%
+ \or \typeout{OK, using 11x8.5 layout ...}% 2
+ \adjustlayout{11in}{8.5in}%
+ \or \typeout{OK, using 8.5x11 layout ...}% 3
+ \adjustlayout{8.5in}{11in}%
+ \else % 4,5,...
+ \typeout{Defaulting to US letter, landscape ...}%
+ \adjustlayout{11in}{8.5in}%
+\fi
+
+% Maybe better to offer the choices USL, USP, A4L, A4P?
diff --git a/macros/latex/contrib/dialogl/dialogl.dtx b/macros/latex/contrib/dialogl/dialogl.dtx
new file mode 100644
index 0000000000..105a2494dd
--- /dev/null
+++ b/macros/latex/contrib/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/macros/latex/contrib/dialogl/dialogl.ins b/macros/latex/contrib/dialogl/dialogl.ins
new file mode 100644
index 0000000000..91fe3beaf7
--- /dev/null
+++ b/macros/latex/contrib/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/macros/latex/contrib/dialogl/diatest.tex b/macros/latex/contrib/dialogl/diatest.tex
new file mode 100644
index 0000000000..a6eb0c2801
--- /dev/null
+++ b/macros/latex/contrib/dialogl/diatest.tex
@@ -0,0 +1,167 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+
+% Test of the `menus' package. You can run this file with (at least)
+% plain TeX, LaTeX (2e), and old LaTeX (2.09).
+%
+% Some chicanery to make this file work in several different contexts.
+\ifx\undefined\documentclass
+ \def\NeedsTeXFormat#1{}\def\RequirePackage#1{\input #1.sty \relax}
+ \def\ProvidesPackage#1[#2]{}
+ \ifx\undefined\documentstyle
+ \def\startup{\input menus.sty \relax}
+ \else
+ \def\startup{\documentstyle[menus]{article}}
+ \fi
+\else
+ \def\startup{%
+ \documentclass{article}%
+ \usepackage{menus}%
+ }
+\fi
+
+\startup
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\mesj{
+The following series of tests is designed to cover most of the
+features that are provided by dialog.sty. If you compare what you
+see on screen with the contents of the file diatest.tex you will
+see how they correspond.
+
+Press the Return or Enter key to continue:}
+\readline{}\xyz
+
+\promptmesj{
+
+Testing \mesj:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\mesj{Give ~ me %^^L an &|
+ \newif #}
+
+\promptmesj{
+Testing \xmesj:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\xmesj{Do we have \{\}\\ characters?
+And \iftrue\.true\else\.false\fi.
+Not to mention ampersand \&, since \string\iftrue.}
+
+\promptmesj{
+Testing \xmesj inside of a \def:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\def\next{\xmesj{Abc space:\ , control-M: \^^M, and percent:\%\
+and another line break.}}
+\next
+
+\promptmesj{
+Testing \promptmesj:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\promptmesj{Enter this or that: }
+\readline{}\xyz
+
+\promptmesj{
+Testing \storemesj:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\storemesj\foo{This is a fine old message, isn't it?:
+\mesj{Give ~ me %^^L an &|
+ \newif }}
+\xmesj{\foo}
+
+\promptmesj{
+Testing \storexmesj now with an arg:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\storexmesj\foo#1{This is a fine old message, isn't it?:
+\\mesj{Give ~ me \%^^L an \&|#1
+ \\newif \#}}
+\xmesj{\foo{KABLOO}}
+
+\promptmesj{
+Testing \fmesj:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\fmesj\foo{This is a fine old message, isn't it?:
+\mesj{Give ~ me %^^L an &|
+ \newif}}
+\foo
+
+\promptmesj{
+Testing \fxmesj now with an arg:
+Press return to continue: }
+\readline{}\xyz\mesj{}
+\fxmesj\foo#1{This is a fine old message, isn't it?:
+\\mesj{Give ~ me \%^^L an \&|#1
+ \\newif \#}}
+\foo{KABLOO}
+
+\promptmesj{
+Would you like to try out \readline? [yes or no]: }
+\readline{}\answer
+\xmesj{Well, if I understood you correctly, you answered `\answer'}
+
+\promptmesj{
+OK, now try give me an executable answer, such as
+"\iftrue yes\else no\fi": }
+\xreadline{}\answer
+\xmesj{Well, and now if I try to execute that: "\answer"}
+
+\promptmesj{
+OK, now let's try \readchar. Give me an arbitrary answer of
+one or more characters: }
+\readchar{}\answer
+\xmesj{Taking the first character from your answer, I get: "\answer"}
+
+\promptmesj{
+OK, now let's try \readChar. Give me an arbitrary answer of
+one or more letters: }
+\readChar{}\answer
+\xmesj{Taking the first character from your answer, and
+uppercasing it, I get: "\answer"}
+
+\promptmesj{
+OK, give me a number then, so that I can
+check it with \checkinteger: }
+\readline{}\answer
+\checkinteger\answer\fam
+\xmesj{\ifnum\fam=-\maxdimen%
+Gee, I don't think that was\else\.Got\fi%
+ a valid number: "\answer"}
+
+\def\dimtest#1{\promptxmesj{#1}%
+ \readline{}\answer
+ \ifx\empty\answer
+ \else
+ \checkdimen\answer\vfuzz
+ \ifdim\vfuzz=-\maxdimen%
+ \xmesj{Sorry, that doesn't look like a TeX dimen to me: "\answer"}%
+ \else
+ \xmesj{Looks like a valid TeX dimen: "\answer" = \the\vfuzz}%
+ \fi
+ \expandafter\dimtestb
+ \fi
+}
+
+\def\dimtesta{\dimtest{\
+OK, give me a dimen then, so that I can\
+check it with \\checkdimen:\
+}}
+
+\def\dimtestb{\dimtest{\
+How about another dimen: }}
+
+\def\empty{}
+
+% Iterate once with one prompt, then several times with a shorter
+% prompt.
+\dimtesta
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\csname stop\endcsname
+\end
diff --git a/macros/latex/contrib/dialogl/fontmenu.lg b/macros/latex/contrib/dialogl/fontmenu.lg
new file mode 100644
index 0000000000..c15a6f3fb2
--- /dev/null
+++ b/macros/latex/contrib/dialogl/fontmenu.lg
@@ -0,0 +1,31 @@
+This is emTeX, Version 3.0 [3a] (preloaded format=plain 93.9.20)
+ 30 OCT 1993 23:41
+**&plain fontmenu
+(fontmenu.tex
+
+ .......................................
+ .......................................
+
+ Select the font base you wish to use:
+
+ [1] Computer Modern [4] Malibu
+ [2] Garamond [5] Times
+ [3] Helvetica
+
+ (Default: Times)
+
+ ........................................
+ ........................................
+
+l.56
+ % Enter a number (1...5) and press Return TWICE
+? 4
+l.60 \Malibu
+ % Press Return to continue
+?
+> \fontbase=macro:
+->Malibu.
+l.66 \show\fontbase
+
+? x
+No pages of output.
diff --git a/macros/latex/contrib/dialogl/fontmenu.tex b/macros/latex/contrib/dialogl/fontmenu.tex
new file mode 100644
index 0000000000..8812fab1fa
--- /dev/null
+++ b/macros/latex/contrib/dialogl/fontmenu.tex
@@ -0,0 +1,72 @@
+% Copyright 1994 Michael John Downes
+% Copyright 2013 TeX Users Group
+% This file is part of the dialogl package, released under the LPPL;
+% see dialogl.ins for details.
+
+\def\ComputerModern{\gdef\fontbase{Times}\gobble}
+\def\Garamond{\gdef\fontbase{Computer Modern}\gobble}
+\def\Helvetica{\gdef\fontbase{Garamond}\gobble}
+\def\Malibu{\gdef\fontbase{Helvetica}\gobble}
+\def\Times{\gdef\fontbase{Malibu}\gobble}
+
+\def\gobble#1\endgobble{}
+
+% Make sure we have a reasonable \newlinechar
+\newlinechar=`\^^J \catcode\newlinechar=12
+
+\begingroup
+\catcode`\<=1 \catcode`\ =2\relax
+\gdef\menustart{\errmessage<%
+....................................... }%
+\endlinechar\newlinechar\catcode`\ =12\relax
+\gdef\menutext{
+ .......................................
+ .......................................
+
+ Select the font base you wish to use:
+
+ [1] Computer Modern [4] Malibu
+ [2] Garamond [5] Times
+ [3] Helvetica
+
+ (Default: Times)}%
+\endgroup% percent here to avoid extra \newlinechar
+
+\begingroup
+\immediate\write16{\menutext}
+% If the user accidentally types 33 instead of 3 they will get past
+% all the legitimate menu choices. So to keep that from causing
+% trouble, we throw in a bunch of ~ characters below to perform
+% error recovery. The standard maximum number of tokens that TeX
+% will delete at one time is 99.
+\catcode`\~=\active % just to make sure
+\def~{\newlinechar`\^^J% restore normal value
+ \message{%
+Whoops! Well, you got Times as your font base, I think}%
+ \gobble}
+% Minimize unwanted error context (note: setting
+% this to -1 doesn't suppress any more information)
+\errorcontextlines 0
+\newlinechar=`\! % to hide the automatic ! from \errmessage
+\gdef\fontbase{Times}
+% Inside the next group we make the space character
+% active so that we can use it to call \menustart,
+% and then we use \expandafter so that the first
+% space on the next line gets that catcode before
+% the \endgroup makes it revert to normal. All this
+% so that the user does not see `\menustart' on
+% screen, only a space.
+\begingroup
+\catcode`\ =\active\let =\menustart\expandafter\endgroup%
+ % Enter a number (1...5) and press Return TWICE
+\ComputerModern% Press Return to continue
+\Garamond% Press Return to continue
+\Helvetica% Press Return to continue
+\Malibu% Press Return to continue
+\Times% Press Return to continue
+\gobble%
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
+\endgobble\endgroup%
+\show\fontbase
+\end
diff --git a/macros/latex/contrib/dialogl/grabhedr.dtx b/macros/latex/contrib/dialogl/grabhedr.dtx
new file mode 100644
index 0000000000..8feaf33734
--- /dev/null
+++ b/macros/latex/contrib/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/macros/latex/contrib/dialogl/listout.dtx b/macros/latex/contrib/dialogl/listout.dtx
new file mode 100644
index 0000000000..fe31daa54e
--- /dev/null
+++ b/macros/latex/contrib/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/macros/latex/contrib/dialogl/manifest.txt b/macros/latex/contrib/dialogl/manifest.txt
new file mode 100644
index 0000000000..f6ab4df8bf
--- /dev/null
+++ b/macros/latex/contrib/dialogl/manifest.txt
@@ -0,0 +1,14 @@
+manifest.txt
+Makefile
+README
+dialogl.ins
+dialogl.dtx
+grabhedr.dtx
+listout.dtx
+menus.dtx
+cnvunits.tex
+dia-driv.tex
+dialogl-doc.sty
+fontmenu.tex
+fontmenu.lg
+diatest.tex
diff --git a/macros/latex/contrib/dialogl/menus.dtx b/macros/latex/contrib/dialogl/menus.dtx
new file mode 100644
index 0000000000..641b373219
--- /dev/null
+++ b/macros/latex/contrib/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