\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{2sidedoc}[1999/01/24]

\newif\ifTSD@setpdimens \TSD@setpdimensfalse
\let\TSD@showdimen=\@gobble

\DeclareOption{setpagedimens}{\TSD@setpdimenstrue}
\DeclareOption{showdimens}{%
   \def\TSD@showdimen#1{%
      \dimen@=0.35146#1%
      \immediate\write\sixt@@n{#1: \strip@pt\dimen@ mm}%
   }%
}

\ProcessOptions\relax

\if@twoside
   \normalmarginpar
   \@mparswitchtrue
   
   \ifTSD@setpdimens
   %    The total width of the part of the page on which text should be 
   %    allowed to appear is the width of 94 characters in the current 
   %    \MacroFont. (20 in the margin, 72 in the main text (whose width 
   %    is \textwidth), and 2 separating them.)
      \ifdim\z@>\textwidth
         % If the \textwidth is negative at this point, the negation of 
         % that value is used, to allow for further configuration.
         \setlength\textwidth{-\textwidth}%
         % \marginparsep is left unchanged.
      \else
         \ifcase\@ptsize
            % 10pt, computed using cmtt9 at 9pt
            \setlength\textwidth{340.2pt}
            \setlength\marginparsep{9.4499pt} % 2*4.72495pt
         \or
            % 11pt, computed using cmtt10 at 10pt
            \setlength\textwidth{378.0pt}
            \setlength\marginparsep{10.4999pt} % 2*5.24995pt
         \or
            % 12pt, computed using cmtt10 at 10.95pt
            \setlength\textwidth{414pt}
            \setlength\marginparsep{11.49738pt} % 2*5.74869pt
         \else
            % Assume \@ptsize is the main font size, but compute the width 
            % as if \MacroFont includes a \small setting which reduces the 
            % size of everything by "\magstep-0.5" (that is, by a factor 
            % 1.2^{-0.5}, and assume the metrics of the font coincide with 
            % those of cmtt8.
            \setlength\textwidth{34.91781pt}
            \setlength\textwidth{\@ptsize\textwidth}
            \setlength\marginparsep{0.96994pt}
            \setlength\marginparsep{\@ptsize\marginparsep}
         \fi
      \fi
      \ifdim 3truecm>\paperwidth
         \PackageError{twosidedoc}{Your \protect\paperwidth\space is %
            ridiculously small}\@ehd
         \dimen@=2truecm
         \advance\dimen@ \marginparsep
         \ifdim \dimen@<\paperwidth \else
            \PackageError{twosidedoc}{You have an infinite loop ahead}%
               {You really should type X to quit now.}
         \fi
      \fi
      \dimen@ii=\p@
      \loop
         \dimen@=\paperwidth
         \advance\dimen@ -\marginparsep
         \advance\dimen@ -1.27778\textwidth
      \ifdim 2truecm<\dimen@ \else
         % This gets dangerously close to the physical margins. Shrink 
         % the \textwidth by 5%.
         \setlength\textwidth{0.95\textwidth}
         \dimen@ii=0.95\dimen@ii
      \repeat
      \ifdim\dimen@ii<\p@
         \dimen@=72\dimen@
         \dimen@ii=100\dimen@ii
         \ifdim\dimen@ii<90\p@
            \expandafter\PackageWarningNoLine
         \else
            \expandafter\PackageInfo
         \fi{twosidedoc}{%
            The width of the text has been shrunk\MessageBreak
            to \strip@pt\dimen@ii\@percentchar\space of its original %
            size.\MessageBreak
            This is approximately \strip@pt\dimen@\space characters.%
         }
      \fi
      % Now at last \textwidth is established. The other values follow easily.
      \setlength\marginparwidth{0.27778\textwidth}
      % Margins are calculated as follows: 1 cm is reserved at each side 
      % and what remains is split 1:2 between inner and outer margin.
      \dimen@=\paperwidth
      \advance\dimen@ -\textwidth
      \advance\dimen@ -\marginparsep
      \advance\dimen@ -\marginparwidth
      \advance\dimen@ -2truecm
      \divide\dimen@ \thr@@
      \setlength\oddsidemargin{\dimen@}
      \setlength\evensidemargin{2\dimen@}
      \advance\oddsidemargin 1truecm
      \advance\oddsidemargin -1truein
      \advance\evensidemargin \marginparsep
      \advance\evensidemargin \marginparwidth
      \advance\evensidemargin 1truecm
      \advance\evensidemargin -1truein
   \else
      % Otherwise only the margins are changed.
      \setlength\evensidemargin{\oddsidemargin}
      \setlength\oddsidemargin{\paperwidth}
      \advance\oddsidemargin -\textwidth
      \advance\oddsidemargin -2truein
      \advance\oddsidemargin -\evensidemargin
      \advance\marginparsep 5\p@
      \dimen@=\evensidemargin
      \advance\dimen@ 1truein
      \advance\dimen@ -1truecm
      \advance\dimen@ -\marginparsep
      \setlength\marginparwidth{\dimen@}
   \fi
\else
   \advance\marginparsep 5\p@
   \dimen@=\oddsidemargin
   \advance\dimen@ 1truein
   \advance\dimen@ -1truecm
   \advance\dimen@ -\marginparsep
   \setlength\marginparwidth{\dimen@}
\fi

\TSD@showdimen\textwidth
\TSD@showdimen\oddsidemargin
\TSD@showdimen\evensidemargin
\TSD@showdimen\marginparwidth
\TSD@showdimen\marginparsep
\TSD@showdimen\marginparpush
\TSD@showdimen\jot



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Modifications of macro etc.
%
\newcount\macro@line@cnt
\macro@line@cnt=\z@
  % \macro@cnt keeps track of how many macro names have been printed.
  % \macro@line@cnt keeps track of how many lines it has taken.
\def\TSD@prevgraf{1}
  % The last stored value of \prevgraf.
\newif\ifTSD@rightmargin@
  % Should macro/environment name be formatted for printing in the
  % right margin? (false = for left margin).
  
\def\PrintMacroName#1{%
   \expandafter\TSD@print@name \expandafter{\string#1}%
}
\def\PrintDescribeMacro#1{%
   \expandafter\TSD@print@name \expandafter{\expandafter\strut
      \string#1\strut}%
}
\def\PrintEnvName#1{\TSD@print@name{#1}}
\def\PrintDescribeEnv#1{\TSD@print@name{\strut#1\strut}}

   
\def\TSD@print@name#1{%
   \raise 1ex\hbox{%
      \MacroFont
      \lower 1ex\vtop{%
         \everypar={}% Very important!!!!
         \hsize=\marginparwidth
         \parindent=\z@
         \parskip=\z@skip
         \baselineskip=\normalbaselineskip
         \lineskiplimit=-\maxdimen
         \ifTSD@rightmargin@
            \TSD@macro@format@right{#1}%
         \else
            \TSD@macro@format@left{#1}%
         \fi
         \xdef\TSD@prevgraf{\the\prevgraf}%
      }%
   }%
}
% #1 is the macro/enviroment; it has already been \string:ed.
\def\TSD@macro@format@right#1{%
   \leftskip=\z@\@plus 1fill\relax
   \hskip-\leftskip
   \rightskip=\z@\@plus\fontdimen\tw@\font\relax
   \parfillskip=\z@\@plus 1fil\relax
   \TSD@one@letter@words{#1}%
   \@@par
}
\def\TSD@macro@format@left#1{%
   \hskip\z@\@plus 1fill\relax
   \leftskip=\z@skip
   \rightskip=\z@\@plus\fontdimen\tw@\font\relax
   \parfillskip=\z@\@plus 1fil\relax
   \TSD@one@letter@words{#1}%
   \@@par
}
\def\TSD@letter@space{\hskip\z@skip}
\def\TSD@one@letter@words#1{\TSD@one@letter@words@i#1\relax}
\def\TSD@one@letter@words@i#1{%
   \ifx#1\relax\else
      #1\TSD@letter@space
      \expandafter\TSD@one@letter@words@i
   \fi
}

\newcounter{MacroEnvironment}
\setcounter{MacroEnvironment}{0}

\def\TSD@correct@side{%
   \begingroup
   \edef\@tempa{%
      \write\@auxout{%
         \if@twoside
            \ifodd\c@page
               \noexpand\TSD@correct@odd
            \else
               \noexpand\TSD@correct@even
            \fi
         \else
            \noexpand\TSD@correct@even
         \fi{\the\c@MacroEnvironment}%
      }%
   }%
   \@tempa
   \endgroup
}
\def\TSD@correct@odd#1{%
   \if@twoside
      \ifodd\c@page
         \@percentchar
      \else
         \string\TSD@nameglet{TSD@#1}\string\@secondoftwo
      \fi
   \else
      \string\TSD@nameglet{TSD@#1}\string\@secondoftwo
   \fi
}
\def\TSD@correct@even#1{%
   \if@twoside
      \ifodd\c@page
         \string\TSD@nameglet{TSD@#1}\string\@firstoftwo
      \else
         \@percentchar
      \fi
   \else
      \@percentchar
   \fi
}
\def\TSD@nameglet#1{\global\expandafter\let\csname#1\endcsname}


\long\def\m@cro@#1#2{\endgroup
   \topsep\MacroTopsep
   \trivlist
   \setlength\labelsep{\z@}%
   \refstepcounter{MacroEnvironment}%
   \@ifundefined{TSD@\the\c@MacroEnvironment}{%
      \if@twoside
         \ifodd\c@page
            \TSD@rightmargin@true
         \else
            \TSD@rightmargin@false
         \fi
      \else
         \TSD@rightmargin@false
      \fi
   }{%
      \@nameuse{TSD@\the\c@MacroEnvironment}%
         \TSD@rightmargin@true \TSD@rightmargin@false
   }%
   \edef\saved@macroname{\string#2}%
   \if@inlabel
      \def\@tempa{{%
         \noexpand\MacroFont
         \dimen@=\macro@line@cnt\baselineskip
         \advance\dimen@ \macro@cnt\jot
         \vskip\dimen@
      }}%
   \else
      \let\@tempa\@empty
      \macro@cnt\z@
   \fi
   \edef\makelabel##1{%
      \noexpand\hb@xt@\z@{%
         \ifTSD@rightmargin@
            \hskip\textwidth\hskip\marginparsep
         \else
            \hss
         \fi
         \vtop to\z@{\noexpand\null
            \vskip-\baselineskip\@tempa
            \hbox{\noexpand\TSD@correct@side##1}%
            \vss
         }%
         \ifTSD@rightmargin@
            \hss
         \else
            \hskip\marginparsep
         \fi
      }%
   }%
   \edef\@tempa{%
      \noexpand\item[%
         #1%
            \noexpand\PrintMacroName
         \else
            \noexpand\PrintEnvName
         \fi
         {\string#2}%
      ]%
   }%
   \@tempa
   \advance\macro@cnt \@ne
   \advance\macro@line@cnt \TSD@prevgraf\relax
   \global\advance\c@CodelineNo\@ne
   #1%
      \SpecialMainIndex{#2}\nobreak
      \DoNotIndex{#2}%
   \else
      \SpecialMainEnvIndex{#2}\nobreak
   \fi
   \global\advance\c@CodelineNo\m@ne
   \ignorespaces
}


\def\Describe@Macro#1{\endgroup
   \marginpar%
      [%
         \TSD@rightmargin@false\noindent
         \PrintDescribeMacro{#1}]%
      {%\tracingmacros=\@ne
         \TSD@rightmargin@true\noindent
         \PrintDescribeMacro{#1}}%
   \SpecialUsageIndex{#1}%
   \@esphack\ignorespaces
}
\def\Describe@Env#1{\endgroup
   \marginpar%
      [\TSD@rightmargin@false\noindent
         \PrintDescribeEnv{#1}]%
      {\TSD@rightmargin@true\noindent
         \PrintDescribeEnv{#1}}%
   \SpecialEnvIndex{#1}%
   \@esphack\ignorespaces
}
% The \noindent:s are necessary, since \marginpar forms a \vtop, not an 
% \hbox. This is important if \PrintDescribeMacro/Env starts with \raise.


\let\ifTSD@setpdimens\relax
\let\TSD@setpdimenstrue\relax
\let\TSD@setpdimensfalse\relax

\endinput