%% file: TXSmacs.tex TeXsis version 2.15 % $Revision: 15.20 $ : $Date: 92/08/03 17:45:58 $ : $Author: myers $ %========================================================================* % TXSmacs - main macros for TeXsis % This file mainly contains macros used in other macros, but the % following are useful in manuscripts: % \draft prints "draft" with the date and time at the % bottom of the page % \singlespaced sets single spacing. % \doublespaced sets double (actually 1.5 times) spacing. % \triplespaced sets triple spacing for drafts. % \widenspacing increases spacing by 1.25. % All of these also set spacing in tables. % \quoteon Automatic opening and closing " by making " an % active character. % \quoteoff Turn \quoteon off %========================================================================* % TeXsis -- Main Macros : This file is a part ot TeXsis % (C) Copyright 1989, 1992 by Eric Myers and Frank E. Paige %======================================================================* \message{TeXsis main macros.} \catcode`@=11 % @ is a letter here \let\XA=\expandafter % shorthand for \expandafter is \XA \let\NX=\noexpand % shorthand for \noexpand is \NX %--------------------------------------------------* % ERROR REPORTING: % \emsg writes the message "#1", ON A NEW LINE, on the terminal % and in the log. Various \things are turned off. \def\emsg#1{% write an error/information message to the scren \begingroup % disable special characters \def\@quote{"}% % to output " \def\TeX{TeX}\def\label##1{}\def\use{\NX\use}% \def\ { }\def~{ }% \def\tt{\NX\tt}\def\bf{}\def\Tbf{}\def\tbf{}% \def\break{}\def\n{\NX\n}% \immediate\write16{#1}% \endgroup} % \@errmark writes a short error message in the right margin \newif\ifmarkerrors \markerrorsfalse % default is off \def\@errmark#1{\ifmarkerrors % only if \markerrorstrue \vadjust{\vbox to 0pt{% % vbox with no height \kern-\baselineskip % insert text next to line \line{\hfil\rlap{{\tt\ <-#1}}}% % in right margin \vss}}\fi}% % end \vbox and \vadjust % \draft marks the bottom of the page with "Preliminary Draft", % date and time, and turns on error marking. \def\draft{% puts DRAFT marks on footer lines of document \def\draftline{{\tentt Preliminary Draft \hfill % DRAFT stamp at -~\folio~- \hfill \runtime}}\footline={\draftline}% bottom of page \eqnotracetrue % equation tracing enabled \markerrorstrue % DO mark errors in right margin \overfullrule=1em} % marks overfull \hbox! % \runtime gets the current time and date in the form hh:mm mm/dd/yy \def\runtime{% % current time of run \count255=\time\divide\count255 by 60 % get hours \the\count255:\relax % hours hh: \multiply\count255 by -60 \advance\count255 by\time % get minutes \ifnum 10 > \count255 {0}\fi % leading zero for minutes < 10 \the\count255 % minutes mm \qquad\the\month/\the\day/\the\year}% and month, day, year %--------------------------------------------------* % \bye -- end of job processing % A slightly modified version of \bye will \checktags at end of job % \checktags comes from TXStags.tex. Also, \endmode can be used % to close any outstanding mode, as in a \letter or \memo \outer\def\bye{% slightly revised version of \bye \endmode % ends any special modes \par\vfill\supereject % as usual, from Plain TeX \checktags % How many undefined tags? \end} \def\endmode{\relax} % default does nothing \def\checktags{\relax} % TXStags will define this... %--------------------------------------------------* % INTERLINE SPACING. \def\singlespaced{% sets interline spacing to \normalbaselineskip \baselineskip=\normalbaselineskip % reset interline \setRuledStrut % set ruled table spacing \setTableskip} % set table spacing \def\singlespace{\singlespaced} % synonym for \singlespaced \def\doublespaced{% sets interline spacing to 1.5 the \normalbaselineskip \baselineskip=\normalbaselineskip % increase interline \multiply\baselineskip by 150 % spacing by 1.50 \divide\baselineskip by 100 % of normal \setRuledStrut % set ruled table spacing \setTableskip} % set table spacing \def\doublespace{\doublespaced} % synonym for \doublespaced \def\TrueDoubleSpacing{% sets interline spacing to twice \normalbaselineskip \baselineskip=\normalbaselineskip % increase interline \multiply\baselineskip by 2 % spacing by 2.0 \setRuledStrut % set ruled table spacing \setTableskip} % set table spacing \def\truedoublespacing{\TrueDoubleSpacing} % synonym for \TrueDoubleSpacing \def\triplespaced{% sets interline spacing to 3.0 the \normalbaselineskip \baselineskip=\normalbaselineskip % increases interline \multiply\baselineskip by 3 % spacing by 3.0 \setRuledStrut % set ruled table spacing \setTableskip} % set table spacing \def\widenspacing{% increases the interline spacing by 1.25 \multiply\baselineskip by 125 % increase the interline \divide\baselineskip by 100 % spacing by a factor of 1.25 \setRuledStrut % set ruled table spacing \setTableskip} % set ``nice'' table spacing \def\whitespaced{\widenspacing} % synonym for \widenspacing \def\whitespace{\widenspacing} % synonym for \widenspacing % \Footnote is like \footnote, but the text is \singlespaced in \FootFont % and the reference mark is automatically put in a superscript. The % superscript is \smash'ed so it does not change the interline spacing. % \Vfootnote is like \vfootnote, but singlespaced in \Footfont also. % How this works: to use the same tricks with \vfootnote as used by % \footnote (see \vfootnote in Appendix B of the TeXbook) we begin a % group in which \FootFont and single spacing are invoked, then change % the definition of \@foot (which ends the \vfootnote) so that it also % closes the extra group we've opened. \def\Footnote#1{% singlespaced \footnote \let\@sf\empty % assume no scale factor \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % unless h-mode ${}^{\hbox{\smash{#1}}}$\@sf % smashed superscript mark \Vfootnote{#1}} % do it with \Vfootnote \def\Vfootnote#1{% singlespaced \vfootnote \begingroup % Following changes temporary \def\@foot{\strut\egroup\endgroup}% % change how to end \vfootnote \tenpoint % default to 10pt type \baselineskip=\normalbaselineskip % default single spaced \parskip=0pt % no space between paragraphs \FootFont % change to ``footnote'' font \vfootnote{${}^{\hbox{#1}}$}} % superscript mark in footnote \def\FootFont{\rm} % default footnote typestyle % \setRuledStrut creates a vertical strut to hold the interline % spacing in ruled tables. It is defined in ruled.tex, so we just % make an empty definition here. \def\setRuledStrut{\relax} %-------------------------* % MISC. useful stuff: % \undertext underscores any text \def\undertext#1{$\relax\underline{\hbox{#1}}$} \def\n{\hfil\break} % \n is newline \def\nl{\hfil\break} % \nl is newline (alternate) \def\newpage{\vfill\eject} % skip to next page %-------------------------* (OLD TeXsis 2.13, \Tablebody) % \Tableskipsize is the spacing for "nice" tables, using \Tablebody. % It is 2pt for single spacing (as in TechRpt) and grows with \baselineskip. \newdimen\Tableskipsize \Tableskipsize=2pt % for 10pt \def\setTableskip{% sets table skips for \Tablebody (OLD) \Tableskipsize=\baselineskip % current skip \advance \Tableskipsize by -\normalbaselineskip % subtract normal \advance \Tableskipsize by 2pt % and add 2pt %-------------------------* % Un-TeX: how to undo things that only get turned on in plain TeX % \unobeylines turns off \obeylines (if you didn't enclose it in {...} ) \def\unobeylines{\catcode`\^^M=5} % make ^^M just % same idea for \unobeyspaces {\obeyspaces\gdef\unobeyspaces{\catcode`\ =10}} % same idea for \unraggedright \def\unraggedright{\rightskip=\z@\spaceskip=0pt\xspaceskip=0pt} %--------------------------------------------------* % EASY QUOTES. Makes " an active character, which knows when to % be an open quote or a close quote \catcode`\"=\active \newcount\@quoteflag \@quoteflag=\z@ % keep track of quotes \def"{\@quote} % generic name for " \def\@quote{% gives `` for first quote, '' for second quote \ifnum\@quoteflag=\z@ % \@quoteflag=\@ne {``}% % \else % \@quoteflag=\z@ {''}% % \fi} \def\quoteon{\catcode`\"=\active} % turns on ``easy quotes'' \def\quoteoff{\catcode`\"=12} % turns off ``easy quotes'' \def\@checkquote#1{\ifnum\@quoteflag=\@ne\message{#1}\fi} % Default is \quoteoff. Turn quotes on only in \texsis % (so it won't interfer with any internal uses for ") \quoteoff % Must turn quotes off while scanning the next def \def\checkquote{{\quoteoff\@checkquote{> Unbalanced "}}} % checks balanced "'s %--------------------------------------------------* % \@obsolete marks obsolete macros \def\@obsolete#1#2{% \emsg{> =========================================================}% \emsg{> \NX#1 is now obsolete! It may soon disappear!} \emsg{> Please use \NX#2 instead.} \emsg{> =========================================================}% %--------------------------------------------------* % \DUMP - \dump for VMS % VMS translates command line arguments to uppercase, % so ``initex texsis \dump'' won't work unless \DUMP is defined. \let\DUMP=\dump %--------------------------------------------------* % \setcnt\counter{value} sets the counter \counter % to the given value, but only temporarily in this group. % After you leave the group the counter is set back to it's % value before you call \setcnt. Useful for figure captions % in the ``wrong'' group and other such wierd things. \def\setcnt#1#2{% set a counter to a value in a group \edef\th@value{\the#1}% % evaluate counter \aftergroup\global\aftergroup#1 % \global\counter= \aftergroup=\relax % \XA\@ftergroup\th@value\endafter % all tokens the in counter \global#1=#2\relax} % set the value in this group % \@ftergroup assigns \next the next token and % then calls \@ftertoken to put that token on the \aftergroup list \def\@ftergroup{\futurelet\next\@ftertoken} \long\def\@ftertoken#1{ \ifx\next\endafter\relax % \endafter ends \let\next=\relax % so just do nothing \else\aftergroup#1\relax % put the token on the list \let\next=\@ftergroup % and get next token \fi\next} % do what's \next %--------------------------------------------------* % \ATlock makes "@" a non-letter to protect internal control sequences % \ATunluck makes "@" a letter so you can get at them \def\ATlock{\catcode`@=12} % makes @ not a letter \def\ATunlock{\catcode`@=11} % makes @ a letter \ATunlock % If someone tries to read a source or style file without having % said \ATunlock they will get all sorts of errors, most notably % that \@ is undefined. So we make \@ produce an error message: \newhelp\AThelp{@: You've apparantly tried to use a macro which begins with ``@''.^^J% These macros are usually for internal TeXsis functions and should^^J% not be used casually. If you really want to use the macro try first^^J% saying \string\ATunlock. If you got this message by pure accident^^J% then something else is wrong.} \def\@{\begingroup \errhelp=\AThelp % longer help message \newlinechar=10 % ^^J is line break \errmessage{Are you tring to use an internal @-macro?}\relax \endgroup} %--------------------------------------------------* % Alternate definition of ~ makes it the same as \0 in math mode. % You can use it as a space which is the width of a digit, and it % is a single character in the manuscript file. It behaves as usual % (a tie, or required space) in non-math mode. \def~{\ifmmode\phantom{0}\else\penalty10000\ \fi} % tie in math mode too \def\0{\phantom{0}} % \0 is phantom 0 in any font %%%-------------------------* \setdigitwid (TO BE REMOVED!) %%\newdimen\digitwid % \digitwid is width of digit %%\def\setdigitwid{\setbox0=\hbox{0}\digitwid=\wd0}% sets \digitwid %%\setdigitwid % do it now %%%-------------------------* % thinskip (hmode). This def allows \, to be used in both math % and nonmath mode \def\,{\relax\ifmmode\mskip\the\thinmuskip\else\thinspace\fi} % Use \topspace in place of \vskip to add space at top of a page % (a \vskip by itself is discarded at the top of an empty page). \def\topspace{\hrule height \z@\vskip} %--------------------------------------------------* % COMMENTS: How to ignore large pieces of text. % Use \comment to turn most anything into nothing (must have balanced {}!). % Usage: % \comment/* */ % the /* and */ are required! \long\def\comment#1/*#2*/{\relax} % just read args and do nothing % \Ignore and \endIgnore are almost the same, but an \endIgnore without % an \Ignore first is just ignored. Got that? \long\def\Ignore#1\endIgnore{\relax} % read arg to \endIgnore and do nothing \def\endIgnore{\relax} % if actually executed, just do nothing % \@comment is for writing % to a file. It expands to '% '. {\catcode`\%=11 \gdef\@comment{% }} % \REV is used for keeping track of revisions. Usually it is just a % speciallized comment, but by changing the definition we print out % the revision record in the Appendix. \def\REV{\begingroup % Revisions \def\endcomment{\endgroup}% % to close the \begingroup \catcode`\|=12 % turn off "TeX quotes" \catcode`(=12 \catcode`)=12 % make ( and ) \catcode`[=12 \catcode`]=12 % and [ and ] "other" \comment} % treat text like a comment %-------------------------* % Simple \begin .. \end support (like in LaTeX, yuk): % There is a conspiracy to preserve job security for typists by making % sure one has to type \begin{thing} and \end{thing} everywhere. In % TeXsis it's just \thing and \endthing, but to make these people happy % we just make \begin{thing} become \thing and similarly for \end{thing}. % The \begin starts a group, so that after the \end{thing} \end goes % back to it's normal definition. % Note: we don't check that you begin and end the same thing. After all, % you might want to say \begin{midfigure} followed by \end{figure}. \def\begin#1{% \begin{foo} just becomes \foo \begingroup % changes to \end are temporary! \let\end=\endbegin % in this group \end will end the \begin \expandafter\ifx\csname #1\endcsname\relax\relax % is \thing defined? \def\next{\beginerror{#1}}% NO: flag an error \else % \def\next{\csname #1\endcsname}% YES: just invoke it \fi\next} \def\endbegin#1{% \end{foo} just becomes \endfoo \endgroup % now \end goes back to normal \expandafter\ifx\csname end#1\endcsname\relax\relax % is \endthing defined? \def\next{\begingroup\beginerror{end#1}}% % NO: flag an error \else % \def\next{\csname end#1\endcsname}% YES: just invoke it \fi\next} \newhelp\beginhelp{begin: The \string\begin\space or \string\end\space marked above is for a % non-existant^^J% environment. Check for spelling errors and such.} \def\beginerror#1{% \begin{foo} or \end{foo} fail if no \foo or \endfoo \endgroup % make sure \end is back to normal \errhelp=\beginhelp % longer help message \newlinechar=10 % ^^J is line break \errmessage{Undefined environment for \string\begin\space or \string\end}} %--------------------------------------------------* % \spine{text} makes a boxed label for the spine of a 3 ring binder % This is printed in \Landscape mode, 24pt type, and with a ruled box % around it. The box will be at least 15cm long, but will extend % if the text requires more space. Instructions for installing the % label in the spine of a binder are printed, but if more than one % label is created the instructions are only printed once. \def\spine#1{\spineSetup \setbox0=\hbox{\twentyfourpoint\bf\quad #1\quad}% \dimen0=\wd0 % \ifdim\wd0<15cm \dimen0=15cm\fi % Minimum size 15cm \vskip 1cm plus 2cm % \tightboxit{\vbox to 1in{\vfill % \hbox to \dimen0{\hfil\box0\hfil}% % \vfill}}% % \vskip 1cm plus 2cm} % \def\spineSetup{% once-only setup for \spine \Landscape % Landscape mode \headline={\LandscapeSpecial}% % and force it every page \vbox{\hsize=15cm % \bigskip\bigskip % \tenpoint\parskip=\smallskipamount % \noindent % How to install the spine label on a binder: \item{1.} Cut out the label around the outside of the bounding ruled box. Leave extra paper (about 1.5cm or so) on the RIGHT side. \item{2.} Obtain a long thin plastic ruler or similar object which can slide down the pocket on the binder spine. \item{3.} Put the label along the ruler, face up, and fold the extra tab of paper on the right of the label over the end of the ruler. \item{4.} Slide the ruler, with the label on it, down the spine of the binder. When the label is in place remove the ruler. The label will remain. \bigskip\bigskip \gdef\spineSetup{\relax} % only show once }} %--------------------------------------------------* % Macros to do an unexpanded write. This is like \write except that % the second argument is not expanded -- \noexpand is put in front of % every token in #2. This works by using \aftergroup to add to a list % of things on a stack, which are then dumped out together after the % \endgroup. This is slightly modified from TechRpt. BE VERY CAREFUL % IF YOU MODIFY THIS IN ANY WAY, IT IS RATHER SENSITIVE. -EAM \def\\{\global\let\@stoken= }\\ \long\def\unexpandedwrite#1#2{% write tokens #2 to #1 but do not expand them \def\@finwrite{\immediate\write#1}% % to write to the file \begingroup % begin collecting tokens on stack \aftergroup\@finwrite % \aftergroup{\relax % put \write{ on the stack \@sanitize#2\endsanity % now process the argument list \aftergroup}\relax % put closing } on the stack \endgroup % now dump token list on stack! % \writeNX is the same as \unexpandedwrite but without the \immediate \long\def\writeNX#1#2{% write tokens #2 to #1 but do not expand them \def\@finwrite{\write#1}% % to write to the file \begingroup % begin collecting tokens on stack \aftergroup\@finwrite % \aftergroup{\relax % put \write{ on the stack \@sanitize#2\endsanity % puts \NX\token on stack from #2 \aftergroup}\relax % put closing } on the stack \endgroup % now dump token list from stack! % Saying \@sanitize \endsanity will take all the tokens % in and put them on the stack, with control sequences % prefaced by \noexpand \def\@sanitize{\futurelet\next\@sanswitch} \def\@sanswitch{% decides what to do with various types of tokens \ifx\next\endsanity\relax % if \endsanity then we'll quit \else\ifcat\noexpand\next\@stoken % if token is a space, \aftergroup\space\let\next=\@eat% write \space and eat token \else\ifcat\noexpand\next\bgroup % if token is \bgroup \aftergroup{\let\next=\@eat % write { and eat it \else\ifcat\noexpand\next\egroup % if token is \egroup \aftergroup}\let\next=\@eat % write a } and eat it \else % otherwize \let\next=\@copytoken % just copy to the stack with \NX \fi\fi\fi\fi \next} % do it to the token % \@eat ignores the \next token and goes on to the % next one in the argument list \def\@eat{\afterassignment\@sanitize\let\next= } % \@copytoken copies one token to the stack with \aftergroup, % then calls \@sanitize to get the next one following. \long\def\@copytoken#1{% write token to stack, unexpanded \ifcat\noexpand#1\relax % if token is a control sequence \aftergroup\noexpand % preface with \noexpand \else\ifcat\noexpand#1\noexpand~\relax % if token is an active character \aftergroup\noexpand % preface with \noexpand \fi\fi % \aftergroup#1\relax % put the next token on the list \@sanitize} % do next token from argument... \def\endsanity\endsanity{} % just marks the end of token list %======================================================================* % CHECKPOINT / RESTART - (C) copyright 1986 by Eric Myers % The \checkpoint and \restart macros allow you to save important information % like the page number, chapter number, equation number, etc... and then % begin with those values on a new run. % Dependencies: TXSmacs.tex % ---------------------------- \message{Checkpoint/Restart.} % I/O initialization: \newwrite\checkpointout % output for checkpoint/restart % ---------------------------- % \checkpoint writes all restart info to the file #1.chk \def\checkpoint#1{\emsg{\@comment\NX\checkpoint --> #1.chk}% \immediate\openout\checkpointout= #1.chk \@checkwrite{\pageno}% \@checkwrite{\chapternum}% \@checkwrite{\corollarynum}% \@checkwrite{\definitionnum}% \@checkwrite{\eqnum}% \@checkwrite{\fignum}% \@checkwrite{\lemmanum} \@checkwrite{\refnum}% \@checkwrite{\sectionnum}% \@checkwrite{\subsectionnum}% \@checkwrite{\tabnum}% \@checkwrite{\theoremnum}% \immediate\closeout\checkpointout}% % \@checkwrite writes the value of #1 to the file, such that the value % is restored when the file is read with \Input \def\@checkwrite#1{\edef\tnum{\the #1}% \immediate\write\checkpointout{\NX #1 = \tnum}}% % ---------------------------- % \restart{filename} reloads the checkpoint from the file #1.chk \def\restart#1{\relax \immediate\closeout\checkpointout % close file, just in case \ATunlock % make sure @ sign is a letter \Input #1.chk \relax % read .CHK file in \@firstrefnum=\refnum % get reference number and \advance\@firstrefnum by \@ne % set first ref counter \ATlock} % @ is protected again \let\restore=\restart % alternate name for \restart % ---------------------------- % \endstat prints out pertinent restart info on the terminal and % in the .log file. Useful at the end of a run. \def\endstat{% \emsg{\@comment LAST PAGE NUMBER IS \the\pageno.}% \emsg{\@comment LAST CHAPTER NUMBER IS \the\chapternum.}% \emsg{\@comment LAST EQUATION NUMBER IS \the\eqnum.}% \emsg{\@comment LAST FIGURE NUMBER IS \the\fignum.}% \emsg{\@comment LAST REFERENCE NUMBER IS \the\refnum.}% \emsg{\@comment LAST SECTION NUMBER IS \the\sectionnum.}% \emsg{\@comment LAST TABLE NUMBER IS \the\tabnum.}% \tracingstats=1}% % \@comment is for writing % to a file. It expands to '% ' {\catcode`\%=11 \gdef\@comment{% }} %======================================================================* % RANDOM USEFUL MACROS. Most of these are useful only to hackers and are % used by macros in this package. Some of them are just general little % goodies that don't seem to fit anywhere else. % \theBlank creates a blank line to fill in ``the blank'' \def\theBlank#1{\nobreak\hbox{\vbox{\hrule width #1\relax}}} % \Romannumeral gives uppercase roman numerals, of course \def\Romannumeral#1{\uppercase\expandafter{\romannumeral #1}} % \monthname{n} gives the English name for month number n \def\monthname#1{\ifcase#1 \errmessage{0 is not a month} \or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\else \errmessage{#1 is not a month}\fi} % \leftpar makes an argument into a raggedleft paragraph % uses the same technique as figure captions \def\leftpar#1{% \setbox\@capbox=\vbox{\normalbaselines \noindent #1\par \global\@caplines=\prevgraf}% \ifnum \@ne=\@caplines \leftline{#1}\else \hbox to\hsize{\hss\box\@capbox\hss}\fi} % We've added a few more active characters, so we have to modify \dospecials \def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&\do\"\do\(\do\)\do\[\do\]% \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~} % \loosebox put a loose box around a box. \def\loosebox#1{% \vbox{\vskip\jot \hbox{\hskip\jot #1\hskip\jot}% \vskip\jot}} % \tightbox draws a rule box around the box #1 without any added space \def\tightbox#1{\vbox{\hrule\hbox{\vrule\vbox{#1}\vrule}\hrule}} \let\tightboxit=\tightbox % synonym % global loop: \def\gloop#1\repeat{\gdef\body{#1}\iterate} % \apply a macro to a list of arguments % Usage: % \apply\macro{list of arguments, separated by commas} % It is possible to determine whether your at the last argument with % \iflastarg true text \else false text \fi % Since \apply uses global definitions, \apply's can't be nested % \empty is defined as {} in PLAIN \newif\iflastarg\lastargfalse \def\car#1,#2;{\gdef\@arg{#1}\gdef\@args{#2}} \def\@apply{% \iflastarg \else \XA\car\@args;% get first argument \islastarg \XA\@fcn\XA{\@arg}% \@apply \fi} \def\apply#1#2{% \gdef\@args{#2,}\let\@fcn#1% \islastarg \@apply } \def\islastarg{\ifx \@args\empty\lastargtrue\else\lastargfalse\fi}% % miscelaneous stuff: \def\@seppuku{\errmessage{Interwoven alignment preambles are not allowed.}\end} \Ignore %--------------------------------- % \uppercase takes place in TeX's stomach, so it can be difficult to % make the VALUE of a control sequence uppercase. The following code % will do so, defining \tok to contain the uppercase value of the argument % which may be a control sequence. \def\@UC#1{\uppercase{\def\tok{#1}}} \def\UC#1{\XA\@UC\XA{#1}} \def\@LC#1{\lowercase{\def\tok{#1}}} \def\LC#1{\XA\@LC\XA{#1}} \endIgnore %>>> EOF TXSmacs.tex <<<