% \iffalse
%<*never>
\documentclass{ltxdoc}

\AtBeginDocument{\CodelineIndex\EnableCrossrefs}
\AtEndDocument{\PrintIndex}
\GetFileInfo{stack.cls}
\def\pack#1{\texttt{#1}}
\begin{document}
\def\docdate{2002/01/20}
\CheckSum{12}
\DocInput{stack.dtx}
\end{document}
%</never>
% \fi
% \iffalse 
%
% (c) 2002 Benjamin BAYART. Freely redistributable under lppl.
%
% \fi
% \CheckSum{110}
% \DoNotIndex{\edef,\advance,\else,\csname,\endcsname,\expandafter}
% \DoNotIndex{\ifx,\fi,\input,\ifnum,\relax,\newcount,\romannumeral}
% \DoNotIndex{\the,\typeout,\xdef,\global,\newcommand,\RequirePackage}
% \DoNotIndex{\PackageError,\ProvidesPackage,\gdef}
%% \CharacterTable
%%  {Upper-case    \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
%%   Lower-case    \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
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%
% \title{Using stacks independently from \TeX's one}
% \author{Benjamin \textsc{Bayart}}
% \date{\filedate}
% \maketitle
% \begin{abstract}
% This package is aimed to provide a new stack mechanisme independent
% from the \TeX\ stack itself. The first use was to have a system where
% |\input| become directory recursive. I.e.~to provide a kind of
% |\chdir| command: when you include a file ``\emph{a}'', it's directory become
% the current one, until the end of ``\emph{a}''. See the ``sample package''
% section for full explanation.
% 
% This package by itself is of no use, except for some macro-developpers.
% \end{abstract}
% \tableofcontents
% 
% \section{User's guide}
%
% \subsection{The \pack{stack} package}
%
% All of the macros provided by this package are supposed for
% package developpers (the is no meaning for a stack in a final
% document, only to be used in a package), so, all of those macros
% have capital letters in their names, following old guidelines
% for \LaTeX3 project.
%
% The first macro is the one to create a new stack:\newline
% \cs{NewStack}\marg{stack}\marg{default}\newline
% Well, it just initializes all the required data for the stack.
% \emph{default} is the value of the top of the stack if the stack is
% empty.
%
% The second one is the macro to push a new value on top of the
% stack:\newline
% \cs{Push}\marg{stack}\marg{value}\newline
%
% The third one is to remove the value on the top (i.e. to pop):\newline
% \cs{Pop}\marg{stack}
%
% Finally, the most usefull one is the command to obtain the value
% on the top of the stack:\newline
% \cs{Stack}\marg{stack}
%
% Another one is provided, but only for debugging purpose, it will
% |\typeout| the current value on the top of the stack:\newline
% \cs{ShowTop}\marg{stack}
%
% \subsection{The \pack{relinput} package}
%
% |relinput| provides only one macro which syntax is:\newline
% \cs{relinput}\marg{directory}\marg{file}.
%
% This will move the ``current directory'' into \emph{directory},
% from there include \emph{file}, and then go back to what was
% the current directory before you call the macro.
%
% A good way to understand it is to try to split a large document
% in a large number of files. Say a first level of directories
% for the parts, a second one for the chapters, a third one for
% the sections, and in each one a file per subsection. 
% 
% So, we will have this kind of directory tree:
%    \begin{macrocode}
%<*never>
part-one/
part-one/thepart.tex
part-one/chapter-one/
part-one/chapter-one/thechapter.tex
part-one/chapter-one/section-one/
part-one/chapter-one/section-one/thesection.tex
part-one/chapter-one/section-one/subsec1.tex
part-one/chapter-one/section-one/subsec2.tex
part-one/chapter-one/section-two/
part-one/chapter-one/section-three/
part-one/chapter-two/
part-one/chapter-two/thechapter.tex
part-two/
part-two/thepart.tex
part-two/chapter-one/
part-two/chapter-one/thechapter.tex
%    \end{macrocode}
% 
% And so on.
%
% The main file only says:
%    \begin{macrocode}
\relinput{part-one}{thepart.tex}
\relinput{part-two}{thepart.tex}
%    \end{macrocode}
%
% The file |part-one/thepart.tex| states:
%    \begin{macrocode}
\relinput{chapter-one}{thechapter.tex}
\relinput{chapter-two}{thechapter.tex}
%    \end{macrocode}
% 
% And so on for the other files, untill 
% |part-one/chapter-one/section-one/thesection.tex| which says:
%    \begin{macrocode}
\relinput{.}{subsec1.tex}
\relinput{.}{subsec2.tex}
%</never>
%    \end{macrocode}
% 
% With such a scheme, when you work on a chapter, you don't have to
% remember in which directory it is, and, even better, if you
% decide to rename the |chapter-one| directory to |introduction|
% you have only one file to modify.
%
% By using the usual \LaTeX\ mechanism you would have to edit the
% same file, plus all the files in this directory which include
% others (that's a rather large number of files).
% 
% \section{Test file}
%
% The test application for |stack| is a ``relative dir input''. The basic
% macro is |\relinput| which takes two arguments: first a directory
% where to go (from the previous one) and then a file to include.
%
% In your main file (|./file.tex|) if you do |\relinput{dir}{file2.tex}|
% then \TeX\ will include |./dir/file2.tex|. If, in |file2|, you do
% |\relinput{dir2}{file3.tex}|, then, \TeX\ will include |./dir/dir2/file3.tex|.
% 
% Really interesting if you have a large document with a lot of files
% in which case you can move a directory and have only minors corrections
% to do in a few files, and, anyway, no corrections in the files \emph{in}
% this directory, but only to files \emph{out} of the directory.
%
% This test file is provided as a small package |relinput|.
%    \begin{macrocode}
%<*test>
\ProvidesPackage{relinput}[2002/01/20 v1.00 Relative input]
\RequirePackage{stack}
\NewStack{reldir}{.}
%    \end{macrocode}
% \begin{macro}{\relinput}
%    \begin{macrocode}
\newcommand\relinput[2]{%
  \Push{reldir}{\Stack{reldir}/#1}%
  \input{\Stack{reldir}/#2}%
  \Pop{reldir}%
}
%</test>
%    \end{macrocode}
% \end{macro}
%
% \StopEventually{}
%
% \section{Code for the \pack{stack} package}
%
% \subsection{Identification}
%
%    \begin{macrocode}
%<*package>
\ProvidesPackage{stack}[2002/01/20 v1.0 Multi-stack system]
%    \end{macrocode}
%
% \subsection{Macros by itself}
%
% In the following code, to use only one counter (in the \TeX\ meaning)
% we store the various values in macros, and use only the counter when
% we need to do computations.
%
% \begin{macro}{\tmp@stack}
%    \begin{macrocode}
\newcount\tmp@stack
%    \end{macrocode}
% \end{macro}
%
%  Creating a new stack is, essentially, creating a new counter-like
%  macro, initializing it to 0, and creating the macro for stack-top
%  evaluation.
% 
% \begin{macro}{\NewStack}
%  This stack-top evaluation macro is required due to an ugly trick.
%  During the push, we ``evaluate'' the value to push with an
%  |\edef|, because one might want to push something which contain the
%  previous top of the stack (see the example package provided).
%  If the |\Stack| macro computes the real value on the top of the
%  stack, then, the expanded definition in |\Push| will contain more
%  or less the \emph{content} of |\Stack| and not the value.
%
%  Another way would be to have a |\csname...\endcsname| pair within
%  another one in an |\ifx| condition, which doesn't work.
%
%    \begin{macrocode}
\newcommand\NewStack[2]{%
  \expandafter\gdef\csname #1@count\endcsname{0}%
  \expandafter\do@stack@macro\csname #1@count\endcsname{#1}{#2}%
}
\newcommand\do@stack@macro[3]{%
  \expandafter\newcommand\expandafter*%
  \csname stack@#2\endcsname{%
    \expandafter\ifx\csname #2@\romannumeral#1\endcsname\relax
      #3%
    \else
      \csname #2@\romannumeral#1\endcsname
    \fi
  }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Stack}
% I'd rather remove the ``check'' code, but, well, it would suppose
% the end-user of the macro is a fair developper, which is not
% realistic.
% 
% If the stack has been properly created, we call the top-stack evaluation
% macro.
%
%    \begin{macrocode}
\newcommand\Stack[1]{%
  \ifx\csname #1@count\endcsname\relax
    \PackageError{stack}{Undefined stack #1}{You should first create the
    stack with \NewStack}%
  \else
    \csname stack@#1\endcsname
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Push}
% \begin{macro}{\Pop}
% The |\Push| macro is one of the most complex ones.
%
% First, we check if the stack is properly defined.
%    \begin{macrocode}
\newcommand\Push[2]{%
  \ifx\csname #1@count\endcsname\relax
    \PackageError{stack}{Undefined stack #1}{You should first create the
    stack with \NewStack}%
  \else
%    \end{macrocode}
%
% We store the new top-value in a macro, just because one might do
% |\Push{stack}{\Stack{stack}.ext}| in witch case the expansion of
% the value to push is something rather tricky.
%
% Then, we step the depth of the stack (put the depth in the scractch
% counter, advance this counter, have the value back in the macro).
%
% Only after that the value to be pushed is stored in the corresponding
% slot.
%    \begin{macrocode}
    \edef\stack@newtop{#2}%
    \tmp@stack\csname #1@count\endcsname\relax
    \global\advance\tmp@stack by 1\relax
    \expandafter\xdef\csname #1@count\endcsname{\the\tmp@stack}%
    \expandafter\xdef\csname #1@\romannumeral\tmp@stack\endcsname
      {\stack@newtop}%
  \fi
}
%    \end{macrocode}
%
% The |\Pop| macro is more simple: if the stack is properly defined and
% the depth is more than zero, then down-step the depth.
%    \begin{macrocode}
\newcommand\Pop[1]{%
  \ifx\csname #1@count\endcsname\relax
    \PackageError{stack}{Undefined stack #1}{You should first create the
    stack with \NewStack}%
  \else
    \tmp@stack\csname #1@count\endcsname\relax
    \ifnum\tmp@stack>0\relax
      \advance\tmp@stack by -1\relax
      \expandafter\xdef\csname #1@count\endcsname{\the\tmp@stack}%
    \fi
  \fi
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% Now, a debug only macro.
% \begin{macro}{ShowTop}
%    \begin{macrocode}
\newcommand\ShowTop[1]{%
  {\edef\top{\Stack{#1}}%
   \typeout{The top of #1: \top}}}
%    \end{macrocode}
% \end{macro}
%
% That's all folks.
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
% \end{document}
