% Utility macros, by Bert Bos <bert@let.rug.nl>, 18 Aug 1992
% $Header: /w3ccvs/WWW/People/Bos/Argo/utility.tex,v 1.1 2007/11/23 14:11:26 bbos Exp $

\ifx\utilityloaded\relax \endinput \else \let\utilityloaded=\relax \fi

%%%%%%%%%% Category codes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The macros \storecat and \restorecat (by Victor Eijkhout)
%  store the \catcode of a letter and reset it to the saved value,
%  respectively. After \storecat@, @ has \catcode 12.

\chardef\other=12
\newcount\tempcounta
\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
\def\csargarg#1#2#3{\expandafter#1\expandafter#2\csname#3\endcsname}
\def\storecat#1{\tempcounta=\escapechar \escapechar=-1
  \csarg\edef{restorecat\string#1}{%
    \catcode`\string#1=\the\catcode\expandafter`\string#1}%
  \catcode\expandafter`\string#1=\other\relax \escapechar\tempcounta}
\def\restorecat#1{\tempcounta\escapechar \escapechar-1
  \csname restorecat\string#1\endcsname \escapechar\tempcounta}

%%%%%%%%%% Category of @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The macros \makeatletter and \restoreat respectively make the @-sign
%  into a letter and set it back to its previous category.

\def\makeatletter{\storecat\@ \catcode`\@=11}
\def\restoreat{\restorecat\@}

\makeatletter

%%%%%%%%%% No tracing %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \tracingoff is the reverse of \tracingall
%  \notrace#1 executes #1 without tracing
%
\def\tracingall{\tracingonline\@ne
  \tracingstats\tw@ \tracingpages\@ne \tracingoutput\@ne
  \tracinglostchars\@ne \tracingmacros\tw@ \tracingparagraphs\@ne
  \tracingrestores\@ne \showboxbreadth\maxdimen \showboxdepth\maxdimen
  \errorstopmode \tracingcommands\tw@}

\def\tracingoff{\tracingonline0 \tracingcommands0 \tracingstats-1
  \tracingpages0 \tracingoutput0 \tracinglostchars0
  \tracingmacros0 \tracingparagraphs0 \tracingrestores0
  \showboxbreadth5 \showboxdepth0}

\def\notrace#1{\edef\@restoretrace{\tracingonline\the\tracingonline
  \tracingstats\the\tracingstats
  \tracingpages\the\tracingpages \tracingoutput\the\tracingoutput
  \tracinglostchars\the\tracinglostchars
  \tracingmacros\the\tracingmacros
  \tracingparagraphs\the\tracingparagraphs
  \tracingrestores\the\tracingrestores
  \showboxbreadth\the\showboxbreadth
  \showboxdepth\the\showboxdepth
  \tracingcommands\the\tracingcommands}%
  \tracingoff #1\@restoretrace}

%%%%%%%%%% \TeX macro %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \TeX is redefined to set the spacefactor correctly.
%
\let\@TeX=\TeX
\def\TeX{\@TeX\spacefactor\@m}

%%%%%%%%%% \raggedleft %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \raggedleft is like \raggedright, but sets \parfillskip as well
%
\def\raggedleft{\leftskip=\z@ plus2em \spaceskip=.3333em
  \xspaceskip.5em\relax \parfillskip=\z@}

%%%%%%%%%% Default rule thickness %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Default rule thickness can be set with \rulethickness.
%  Other rules can still be made, since
%  \hrule height 1pt height 2pt is legal and will cause
%  TeX to apply the last height (2 pt).

\newdimen\rulethickness \rulethickness=0.4pt
\let\@hrule=\hrule \def\hrule{\@hrule height\rulethickness}
\let\@vrule=\vrule \def\vrule{\@vrule width\rulethickness}

%%%%%%%%%% Undefined macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \@checkdefined checks if the next token (a control sequence) is
%  defined or not and sets the macro \if@defined to \iftrue or
%  \iffalse
%
\newif\if@defined
\def\@checkdefined#1{\csarg\ifx{#1}\relax \@definedfalse
  \else \@definedtrue \fi}

%%%%%%%%%% Emphasis %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \em toggles italics and roman and automatically inserts the italic
%  correction.
%
\def\@ItalicEmphasis{\notrace{\it}\aftergroup\/\let\pem=\@RomanEmphasis}
\def\@RomanEmphasis{\ifhmode \count@\spacefactor \@tempskipa\lastskip
    \unskip \/\hskip\@tempskipa \spacefactor\count@ \fi
  \rm \let\pem=\@ItalicEmphasis}
\let\pem=\@ItalicEmphasis
\def\em{\tracingall\protect\pem}
\let\protect=\relax

\let\em=\it

%%%%%%%%%% Non-outer allocations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Non-outer allocations can be made with \innernew...

\def\innernewcount{\alloc@0\count\countdef\insc@unt}
\def\innernewtoks{\alloc@5\toks\toksdef\@cclvi}

%%%%%%%%%% Force odd page %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \ForceOddPage makes sure the pagenumber is odd, by adding an empty
%  page if necessary.
%
\def\ForceOddPage{\ifodd\pageno\else \leavevmode \vfil \eject \fi}

%%%%%%%%%% Paragraph indentation/skip %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Paragraph indentation/skip scheme is invented by Victor Eijkhout
%  (See "TeX by Topic")
%  \ifNeedIndent controls the normal paragraph indentation, i.e.,
%  true = always indent, false = never indent.
%  \ifneedindent controls the indentation of the next paragraph only.
%  \ifParskipNeedsRestoring can be used for environments, see below.
%
%  Since this uses \everypar, \everypar cannot be used for other
%  purposes anymore.

\newskip\@TempParskip
\newif\ifNeedIndent \NeedIndenttrue
\newif\ifneedindent \needindenttrue
\newif\ifParskipNeedsRestoring
\def\@ControlledIndentation{%
  \ifNeedIndent \ifneedindent\else \@RemoveIndentation \needindenttrue \fi
  \else \ifneedindent \needindentfalse \else \@RemoveIndentation \fi \fi}
\def\@RemoveIndentation{{\setbox\z@\lastbox}}
\def\@ControlledParskip{\ifParskipNeedsRestoring \parskip\@TempParskip
    \ParskipNeedsRestoringfalse \fi}
\everypar{\@ControlledIndentation \@ControlledParskip}

%%%%%%%%%% Conditional vertical space %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The \vspace macro adds vertical space, taking into account any vertical
%  space that is already present.

\newskip\@tempskipa
\def\vspace#1{\@tempskipa#1\relax \ifvmode
    \ifdim\@tempskipa<\lastskip \else \vskip-\lastskip \vskip\@tempskipa \fi
  \else \vskip\@tempskipa \fi}

%%%%%%%%%% Environments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Environments (parts of a text that have a different layout from
%  text above and below it) can be bracketed with \begin{foo} and \end{foo}
%  Each environment should have associated \fooBeginskip, \fooEndskip
%  and \fooParskip glue registers, for the whitespace before, after
%  and inside the environment.
%
%  It is not necessary to define macros \foo and \endfoo, so if
%  no processing is necessary at the start or end of the environment
%  the macros can be left undefined.
%
%  The primitive control sequence \end is saved in \halt
%  and \bye is redefined.
%
\newtoks\@CurEnv
\newtoks\@EndEnv

\let\halt=\end
\def\bye{\par\vfill\supereject\halt}

\def\begin#1{\@checkdefined{#1Beginskip}%
  \if@defined \csarg\vspace{#1Beginskip}\fi
  \begingroup \@checkdefined{#1Parskip}%
  \if@defined \csarg\@TempParskip{#1Parskip}\fi \parskip\z@
  \ParskipNeedsRestoringtrue \@CurEnv={#1}%
  \@checkdefined{#1}%
  \if@defined
    \let\next=\relax \expandafter\let\expandafter\next\csname #1\endcsname
  \else
    \errmessage{Environment #1 not defined.}\let\next=\relax
  \fi
  \next}
\def\end#1{\@checkdefined{#1Endskip}%
  \if@defined \csarg\vspace{#1Endskip}\fi \@EndEnv={#1}
  \if\@CurEnv\@EndEnv\else
    \errmessage{\string\begin{\the\@CurEnv} doesn't match \string\end{#1}}\fi
  \csname end#1\endcsname \endgroup
  \ifParskipNeedsRestoring\else \@TempParskip\parskip \parskip\z@
    \ParskipNeedsRestoringtrue \fi}

%%%%%%%%%% Struts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Extra struts that are .5 ex higher or deeper than the normal strut
%  are convenient inside tables or in other places where a rule needs
%  to be pushed a little higher or lower.

\def\deepstrut{\lower.5ex\copy\strutbox}
\def\highstrut{\raise.5ex\copy\strutbox}
\def\Strut{\deepstrut \highstrut}

%%%%%%%%%% White lines %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The \whiteline inserts a \bigskip and prevents the next paragraph
%  from being indented.

\def\whiteline{\vspace\bigskipamount \needindentfalse}

%%%%%%%%%% Representations of numbers %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Macros for decimal and other representations of counters: arabic,
%  roman lowercase, roman uppercase, lowercase letters, uppercase letters.

\let\arabic=\number
\let\roman=\romannumeral
\def\Roman#1{\expandafter\uppercase\expandafter{\romannumeral#1}}
\def\alph#1{\ifcase#1 0\or a\or b\or c\or d\or e\or f\or g\or h\or i\or
  j\or k\or l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or
  x\or y\or z\else\errormessage{Counter #1 exceeded "z" (=26)}\fi}
\def\Alph#1{\ifcase#10 \or A\or B\or C\or D\or E\or F\or G\or H\or I\or
  J\or K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or
  X\or Y\or Z\else\errormessage{Counter #1 exceeded "Z" (=26)}\fi}

%%%%%%%%%% Counters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Counters are created and incremented with the following macros.
%  Every count can have one or more sub-counts, which are reset to
%  zero when the master count is incremented.
%  \newsubcount#1#2#3 creates a subcounter #2 for master counter #1,
%  using style #3.
%  \newcounter{foo}\roman creates a counter foo and a cs \thefoo, that
%  expands to the roman numeral for the counter's value.

\def\newcounter#1#2{\expandafter\innernewcount\csname #1:counter\endcsname
  \expandafter\innernewtoks\csname #1:sub\endcsname
  \csarg\def{the#1}{\csarg#2{#1:counter}}}
\def\increment#1{\advance\csname #1:counter\endcsname 1\relax
  \let\@next=\\\let\\=\resetcounter \csarg\the{#1:sub}\let\\=\@next}
\def\decrement#1{\advance\csname #1:counter\endcsname -1\relax
  \let\@next=\\\let\\=\resetcounter \csarg\the{#1:sub}\let\\=\@next}
\def\resetcounter#1{\csname #1:counter\endcsname=0\relax}
\def\newsubcounter#1#2#3{\newcounter{#2}{#3}\csarg\AddToList{#1:sub}{#2}}
\def\AddToList#1#2{\let\@next=\\\let\\=\relax
  \edef\@ct{\noexpand #1={\the #1\\{#2}}}\@ct \let\\=\@next}
\def\newcounterstyle#1#2{\csarg\def{the#1}{\csarg#2{#1:counter}}}

%%%%%%%%%% centering the last line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \weirdtitle sets a paragraph with its last line centered.
%
\long\def\weirdtitle#1{\setbox0=\vbox{#1}%
   \setbox1=\vbox{\unvbox0 \setbox2=\lastbox \nointerlineskip
   \hbox to \hsize{\hfill \unhbox2 \hfill}}%
   \unvbox1}

%%%%%%%%%% Change all catcodes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The command \@sanitize changes the catcode of all special
%  characters except for braces to 'other'.  It can be used for
%  commands like \index that want to write their arguments verbatim.
%  Needless to say, this command should only be executed within a
%  group, or chaos will ensue.
%
\def\@makeother#1{\catcode`#1=\other\relax}
\def\@sanitize{\@makeother\ \@makeother\\\@makeother$\@makeother\&%
  \@makeother\#\@makeother\^\@makeother^^K\@makeother\_\@makeother^^A%
  \@makeother\%\@makeother\~\@makeother\|\@makeother\!\@makeother @}

%%%%%%%%%% Backspace hack %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  To make sure an \index command doesn't interfere with the normal
%  processing of words and spaces, LaTeX's macros \@bsphack and
%  \@ebsphack are used.
%
\newdimen\@savsk
\newcount\@savsf
\def\@bsphack{\@savsk=\lastskip \ifhmode \@savsf=\spacefactor \fi}
\def\@esphack{\relax \ifhmode \spacefactor=\@savsf
    {}\ifdim \@savsk>\z@ \ignorespaces \fi \fi}

%%%%%%%%%% Verbatim %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \ttverbatim switches \tt, \obeyspaces and \obeylines and removes
%  the special meaning of all characters
%
\def\newpar{\par\leavevmode}
\let\oldobeylines=\obeylines
{\catcode`\^^M=\active % these lines must end with `%'
  \gdef\obeylines{\catcode`\^^M=\active \let^^M=\newpar}}
\def\ttverbatim{\tt \let\do=\@makeother \dospecials \obeyspaces
  \obeylines \spaceskip=\fontdimen\tw@\font \xspaceskip=\spaceskip}
{\obeyspaces\global\let =~} % \obeyspaces now gives ~, not \space

%%%%%%%%%% Auxiliary file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  The macro \@readaux \input's the aux-file, if it hasn't been read before.
%  It warns the user if the aux-file doesn't exist. Macros that write
%  to the aux-file should call \@readaux first.
%
%  \condinput can be used to \input a file. It gives a message when
%  the file doesn't exist.
%
\newwrite\auxfile
\newread\@tmpfile
\newif\if@auxfileProcessed
\def\condinput#1{\immediate\openin\@tmpfile=#1
  \ifeof\@tmpfile \message{(File #1 not found)}%
  \else \closein\@tmpfile \input #1 \fi}
\def\@readaux{\if@auxfileProcessed\else \@auxfileProcessedtrue
    \makeatletter \condinput{\jobname.aux}\restoreat
    \openout\auxfile=\jobname.aux \fi}
\def\WriteAux{\@readaux \Write\auxfile}
\def\WritePAux{\@readaux \WriteP\auxfile}

%%%%%%%%%% \input'ing a macro file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \inputmac allows \inputting a macro file that contains control
%  sequences with `@' in their names.
%
\def\inputmac#1 {\chardef\@savecat=\catcode`\@%
  \catcode`\@=11 \input #1 \catcode`\@=\@savecat}

%%%%%%%%%% Writing without expanding %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \Write#1#2 writes #2 to file #1 without expanding arguments.
%  \WriteP does the same thing, but adds the page number (\folio) in
%  braces at the end.
%
\newtoks\@temptoksa
\def\WriteP#1#2{\@temptoksa={#2}\write#1{\the\@temptoksa{\folio}}}
\def\Write#1#2{\@temptoksa={#2}\write#1{\the\@temptoksa}}

\def\WriteP#1#2{\def\next{#2}\edef\next{\@meaning\next}%
  \expandafter\@write\expandafter#1\next{\folio}\@@}
\def\Write#1#2{\def\next{#2}\edef\next{\@meaning\next}%
  \expandafter\@write\expandafter#1\next\@@}
\def\@write#1#2\@@{\write#1{#2}}
\def\@meaning{\expandafter\@PruneMeaning\meaning}
\def\@PruneMeaning#1->{}

%%%%%%%%%% Two columns %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \twocolumns switches to two column mode, \onecolumn balances the
%  columns and switches back to single column mode. The dimen \ColumnSep
%  determines the space between the columns; default 5 mm.
%
\newdimen\ColumnSep \ColumnSep=5mm
\newskip\BeforeColumnSkip \BeforeColumnSkip=\bigskipamount
\newskip\AfterColumnSkip \AfterColumnSkip=\bigskipamount

\def\@bye{\ifx L\@LR \par \vfill \eject \leavevmode \fi \@SavedBye}
\newdimen\@FullWidth \newdimen\@FullHeight \newdimen\@ColumnWidth
\newdimen\@tempdima \newbox\@LeftColumn \newbox\@PartialPage
\newtoks\@SaveOutput
\def\twocolumns{\par \@SaveOutput=\expandafter{\the\output}%
  \output={\global\setbox\@PartialPage=\vbox{%
      \unvbox\@cclv \vspace\BeforeColumnSkip}}\eject
  \@FullHeight=\vsize \advance\vsize by -\ht\@PartialPage
  \global\output={\@TwoColumnOutput}\let\@LR=L\@FullWidth=\hsize
  \advance\hsize by -\ColumnSep \divide\hsize by 2\relax \@ColumnWidth=\hsize
  \let\@SavedBye=\bye \let\bye=\@bye}
\def\onecolumn{\par\vfill \global\output=\expandafter{\the\@SaveOutput}%
  \hsize=\@FullWidth \vsize=\@FullHeight \@BalanceColumns
  \vspace\AfterColumnSkip
  \ifx\@SavedBye\undefined\else \let\bye=\@SavedBye \fi}
\def\@BalanceColumns{\begingroup \splittopskip=\topskip
  \splitmaxdepth=\maxdepth \vbadness\@M \tempcounta=0
  \ifx R\@LR \ifnum\outputpenalty<\@M \tempcounta=\outputpenalty \fi \fi
  \global\setbox\z@=\vbox{}%
  \output={\global\setbox\z@=\vbox{\unvbox\@cclv}}\eject
  \setbox2=\vbox{\unvbox\@LeftColumn \penalty\tempcounta \unvbox\z@}%
  \dimen@=\ht2 \divide\dimen@ by 2
  \loop \setbox\@ne\copy\tw@ \setbox\z@\vsplit\@ne to\dimen@
    \ifdim\ht\@ne>\dimen@ \advance\dimen@\p@ \repeat
  \unvbox\@PartialPage \wd\z@=\@ColumnWidth \wd\@ne=\@ColumnWidth
  \noindent\valign{##\vss\cr
    \box\z@\cr \noalign{\kern\ColumnSep} \box\@ne\cr}\endgroup}
\def\@TwoColumnOutput{\ifx L\@LR \global\let\@LR=R
    \global\setbox\@LeftColumn=\vbox to\vsize{\columncontents}
  \else \global\let\@LR=L \hsize=\@FullWidth
    \setbox\@cclv=\twocolumnbody
    \global\vsize=\@FullHeight \the\@SaveOutput \hsize=\@ColumnWidth
  \fi}
\def\twocolumnbody{\vbox to\@FullHeight{\boxmaxdepth=\maxdepth
  \twocolumncontents}}
\def\twocolumncontents{\unvbox\@PartialPage
  \setbox\z@\hbox to\@FullWidth{\box\@LeftColumn \hss
    \vbox to\vsize{\columncontents}}\dimen@=\dp\z@ \box\z@
  \ifvoid\footins\else \vskip\skip\footins \footnoterule \unvbox\footins \fi
  \ifr@ggedbottom \kern-\dimen@ \vfil \fi}
\def\columncontents{\ifvoid\topins\else \unvbox\topins \fi \unvbox\@cclv}

%%%%%%%%%% A short text in two columns %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Use \balance... \endbalance only for a short text, since it will
%  produce a \vbox, with two columns inside.
%
\newskip\balanceBeginSkip
\newskip\balanceEndSkip
\newskip\balanceParskip

\def\balance{\setbox\tw@=\vbox\bgroup \advance\hsize-\ColumnSep
    \divide\hsize\tw@ \multiply\tolerance\tw@}
\def\endbalance{\egroup
  \begingroup \splittopskip=\topskip
  \splitmaxdepth=\maxdepth \vbadness=\@M \tempcounta=\z@
  \@ColumnWidth=\hsize \advance\@ColumnWidth-\ColumnSep
  \divide\@ColumnWidth\tw@ \dimen@=\ht\tw@ \divide\dimen@\tw@
  \loop \setbox\@ne\copy\tw@ \setbox\z@\vsplit\@ne to\dimen@
    \ifdim\ht\@ne>\dimen@ \advance\dimen@\p@ \repeat
  \wd\z@=\@ColumnWidth \wd\@ne=\@ColumnWidth
  \noindent\valign{##\vss\cr
    \box\z@\cr \noalign{\kern\ColumnSep}\box\@ne \cr}\endgroup}

%%%%%%%%%% Date, with English names of months %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\def\monthname{\ifcase\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\fi\relax}
\def\today{\number\day~\monthname~\number\year}

%%%%%%%%%% Appending lists %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \@appendlist#1#2 appends the tokens in #2 at the end of #1, which
%  must be a token register.
%
\def\@appendlist#1#2{\toks0={#2}%
  \edef\next{\noexpand#1={\the#1\the\toks0}}\next}

%%%%%%%%%% Overlapping %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \overlap#1#2 creates a box with the arguments #1 and #2 centered
%  over each other. The dimensions are the maximum of #1 and #2.
%  The arguments are put into \hbox'es
%
\def\overlap#1#2{\begingroup
  \setbox1=\hbox{#1}%
  \setbox2=\hbox{#2}%
  \dimen1=\wd1 \ifdim\wd2>\dimen1 \dimen1=\wd2 \fi
  \dimen2=\ht1 \ifdim\ht2>\dimen2 \dimen2=\ht2 \fi
  \dimen3=\dp2 \ifdim\dp2>\dimen3 \dimen3=\dp2 \fi
  \advance\dimen2 by\dimen3
  \vbox to \dimen2{%
    \vbox to 0pt{%
      \vbox to \dimen2{%
        \vss
	\hbox to \dimen1{\hss \box2 \hss}%
	\vss}
      \vss}%
    \vss
    \hbox to \dimen1{\hss \box1 \hss}%
    \vss}%
  \endgroup}

%%%%%%%%%% Vertically centered text boxes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  \textvcenter works like \vcenter, but it can be used outside of
%  math mode as well
%
\def\textvcenter{\begingroup
  \ifmmode \let\force@math=\relax \else \let\force@math=$\fi
  \everyvbox{\everyvbox{}\bgroup \aftergroup\@centerIt}%
  \force@math \vcenter}
\def\@centerIt{\egroup \force@math \endgroup}

%%%%%%%%%% Finale %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Restore the @-sign to its previous category

\restoreat

