diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:57:59 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:57:59 +0000 |
commit | b0882e53e534505395ed35fc829a1948fde36e89 (patch) | |
tree | bcd51a803f0e6b381ac7ad994fd62fdf80145df1 /Master/texmf-dist/source/latex/stack | |
parent | 0c1ec2fcfdc0762e8cd9e3bf6339ef819450dc9a (diff) |
trunk/Master/texmf-dist/source/latex/stack
git-svn-id: svn://tug.org/texlive/trunk@526 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/stack')
-rw-r--r-- | Master/texmf-dist/source/latex/stack/stack.dtx | 332 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/stack/stack.ins | 5 |
2 files changed, 337 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/stack/stack.dtx b/Master/texmf-dist/source/latex/stack/stack.dtx new file mode 100644 index 00000000000..0cc08580738 --- /dev/null +++ b/Master/texmf-dist/source/latex/stack/stack.dtx @@ -0,0 +1,332 @@ +% \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} diff --git a/Master/texmf-dist/source/latex/stack/stack.ins b/Master/texmf-dist/source/latex/stack/stack.ins new file mode 100644 index 00000000000..186e1432a31 --- /dev/null +++ b/Master/texmf-dist/source/latex/stack/stack.ins @@ -0,0 +1,5 @@ +\input docstrip +\keepsilent +\generate{\file{stack.sty}{\from{stack.dtx}{package}} + \file{relinput.sty}{\from{stack.dtx}{test}}} +\endbatchfile |