summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/xfor
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/xfor
Initial commit
Diffstat (limited to 'macros/latex/contrib/xfor')
-rw-r--r--macros/latex/contrib/xfor/CHANGES20
-rw-r--r--macros/latex/contrib/xfor/README25
-rw-r--r--macros/latex/contrib/xfor/xfor.dtx485
-rw-r--r--macros/latex/contrib/xfor/xfor.ins33
-rw-r--r--macros/latex/contrib/xfor/xfor.pdfbin0 -> 118215 bytes
5 files changed, 563 insertions, 0 deletions
diff --git a/macros/latex/contrib/xfor/CHANGES b/macros/latex/contrib/xfor/CHANGES
new file mode 100644
index 0000000000..23010df08c
--- /dev/null
+++ b/macros/latex/contrib/xfor/CHANGES
@@ -0,0 +1,20 @@
+xfor change log:
+
+v1.05 (5 February 2009):
+ changed \@forloop to \@xforloop to avoid conflict caused
+ by new syntax.
+
+v1.04 (25 January 2009):
+ rewrite of internals to improve loop efficiency
+ (code provided by Morten H\o gholm)
+
+v1.03 (21 August 2007):
+ fixed license text
+
+v1.02 (16 August 2007):
+ added look ahead facility
+
+v1.01 (11 July 2007):
+ made \@iforgatherrest and \@forgatherrest \long
+
+v1.0 (27 June 2007): Initial release
diff --git a/macros/latex/contrib/xfor/README b/macros/latex/contrib/xfor/README
new file mode 100644
index 0000000000..f5f98515d2
--- /dev/null
+++ b/macros/latex/contrib/xfor/README
@@ -0,0 +1,25 @@
+LaTeX Package : xfor
+
+Last Modified : 5 February 2009
+Version : 1.05
+Author : Nicola Talbot
+
+This package redefines \@for so that it is possible to
+prematurely terminate the loop. There is also a look ahead
+facility to access the next element before moving on to the
+next iteration.
+
+The package is supplied using the TeX Directory Structure (TDS).
+Files in texmf directory should go in the corresponding
+$LOCALTEXMF directories.
+
+*Remember to refresh TeX's database*
+
+The package and documentation source code is also supplied as a
+dtx and ins file located in texmf/source.
+
+This material is subject to the LaTeX Project Public License.
+See http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html for the details of that license.
+
+http://theoval.cmp.uea.ac.uk/~nlct/
+
diff --git a/macros/latex/contrib/xfor/xfor.dtx b/macros/latex/contrib/xfor/xfor.dtx
new file mode 100644
index 0000000000..1157d19057
--- /dev/null
+++ b/macros/latex/contrib/xfor/xfor.dtx
@@ -0,0 +1,485 @@
+%\iffalse
+% xfor.dtx generated using makedtx version 0.94b (c) Nicola Talbot
+% Command line args:
+% -src "xfor.sty\Z=>xfor.sty"
+% -src "sample.tex\Z=>sample.tex"
+% -doc "xfor-manual.tex"
+% -author "Nicola Talbot"
+% -dir "source"
+% xfor
+% Created on 2009/2/5 16:02
+%\fi
+%\iffalse
+%<*package>
+%% \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 \~}
+%</package>
+%\fi
+% \iffalse
+% Doc-Source file to use with LaTeX2e
+% Copyright (C) 2009 Nicola Talbot, all rights reserved.
+% \fi
+% \iffalse
+%<*driver>
+\documentclass[a4paper]{ltxdoc}
+\usepackage{xfor}
+\usepackage{ifthen}
+\usepackage{alltt}
+\usepackage[colorlinks,
+ bookmarks,
+ hyperindex=false,
+ pdfauthor={Nicola L.C. Talbot},
+ pdftitle={xfor: redefinition of \string\@for},
+ pdfkeywords={LaTeX,package development}]{hyperref}
+
+\CheckSum{197}
+\PageIndex
+\RecordChanges
+\newcommand*{\sty}[1]{\textsf{#1}}
+
+\begin{document}
+\DocInput{xfor.dtx}
+\end{document}
+%</driver>
+%\fi
+%\MakeShortVerb{"}
+%
+% \title{xfor v1.05: Reimplementation of \cs{@for} to allow
+%premature termination of the loop}
+% \author{Nicola L.C. Talbot\\[10pt]
+%School of Computing Sciences\\
+%University of East Anglia\\
+%Norwich. Norfolk\\
+%NR4 7TJ. United Kingdom.\\
+%\url{http://theoval.cmp.uea.ac.uk/~nlct/}}
+%
+%\date{5th February 2009}
+%\maketitle
+%\tableofcontents
+%
+%\section{Introduction}
+%\changes{1.0}{2007 June 27}{Initial version}
+%The \sty{xfor} package redefines \cs{@for} so that the loop can
+%be prematurely terminated, akin to C/Java's \texttt{break} statement
+%except that the loop will terminate at the \emph{end} of the
+%current iteration. The syntax for \DescribeMacro{\@for}\cs{@for}
+%remains the same:
+%\begin{quote}
+%\cs{@for}\meta{cmd}":="\meta{list}"\do"\marg{body}
+%\end{quote}
+%where \meta{cmd} is a command name that is assigned to the current
+%element of the list given by \meta{list} at each iteration.
+%
+%To terminate the loop at the end of the current
+%iteration, use the command \DescribeMacro{\@endfortrue}\cs{@endfortrue}.
+%This command may be used anywhere in \meta{body}, but will only
+%take effect at the end of the current iteration.
+%The remainder of the list is stored in
+%\DescribeMacro{\@forremainder}\cs{@forremainder}. You can test
+%whether the loop was prematurely terminated using the conditional
+%\DescribeMacro{\if@endfor}\cs{if@endfor}.
+%
+%As from version 1.02, there is also provision for looking ahead.
+%At each iteration in the loop, the next element is stored in
+%\cs{@xfor@nextelement}\DescribeMacro{\@xfor@nextelement}.
+%On the last iteration, this value
+%will be \cs{@nil}, and so can be checked using
+%\begin{verbatim}
+% \ifx\@xfor@nextelement\@nnil
+% % last iteration
+% \else
+% % not last iteration
+% \fi
+%\end{verbatim}
+%
+%\subsection{Example (ordered insertion)}
+%
+%Suppose you have list of sorted numbers stored in the command
+%\cs{mylist}, e.g.:
+%\begin{verbatim}
+%\def\mylist{1,3,5,7,8,12,15,20}
+%\end{verbatim}
+%and you want to insert a new value given by the command
+%\cs{newval}, e.g.
+%\begin{verbatim}
+%\def\newval{11}
+%\end{verbatim}
+%in the correct order. You can use \cs{@for} to iterate through
+%each element in the sorted list, testing the value against the
+%new value to be inserted. Once the new value has been inserted,
+%the loop can be terminated, and any remaining elements can be
+%appended to the new list. The following
+%defines the command \cs{insertinto}\marg{new val}\marg{list}
+%which uses this method:
+%\begin{verbatim}
+% \newcommand{\insertinto}[2]{%
+% \def\nlst{}% new list initially empty
+% \@for\n:=#2\do{%
+% % store new list in \toks@
+% \expandafter\toks@\expandafter{\nlst}%
+% % test current value against new value
+% \ifnum\n>#1\relax
+% % new value needs to be inserted before current value
+% \edef\newstuff{\number#1,\n}%
+% % end for loop at the end of this iteration
+% \@endfortrue
+% \else
+% \edef\newstuff{\n}%
+% \fi
+% % append new stuff to new list
+% \ifx\nlst\@empty
+% \edef\nlst{\newstuff}%
+% \else
+% \edef\nlst{\the\toks@,\newstuff}%
+% \fi
+% }%
+% % check to see if for loop was prematurely terminated
+% \if@endfor
+% % loop may have been terminated during final iteration, in
+% % which case \@forremainder is empty.
+% \ifx\@forremainder\@empty
+% % do nothing
+% \else
+% % loop prematurely ended, append remainder of original list
+% % to new list
+% \expandafter\toks@\expandafter{\nlst}%
+% \edef\nlst{\the\toks@,\@forremainder}%
+% \fi
+% \else
+% % wasn't prematurely terminated, so new value hasn't been added
+% % so add now.
+% \expandafter\toks@\expandafter{\nlst}%
+% \ifx\nlst\@empty
+% \edef\nlst{\number#1}%
+% \else
+% \edef\nlst{\the\toks@,\number#1}%
+% \fi
+% \fi
+% \let#2=\nlst
+% }
+%\end{verbatim}
+%The \cs{insertinto} macro can then be used as follows:
+%\begin{verbatim}
+%\def\mylist{1,2,5,9,12,15,18,20}%
+%\def\newval{11}%
+%Original list: \mylist. New value: \newval.
+%
+%\insertinto{\newval}{\mylist}
+%New list: \mylist.
+%\end{verbatim}
+%
+%\subsection{Example (numerical insertion sort)}
+%
+%Care needs to be taken when nesting \cs{@for}-loops.
+%Suppose you have a list of unsorted numbers, say
+%\begin{verbatim}
+%\def\mylist{4,2,7,1,10,11,20,15}
+%\end{verbatim}
+%and you want to sort the list in numerical order using an insertion
+%sort method. To do this, a macro needs to be defined which iterates
+%through each element in the unordered list, and the element
+%is then inserted into an ordered list. The previous example
+%described the macro \cs{insertinto} which does this, but this results
+%in nested \cs{@for} commands. The \cs{insertinto} command will need
+%to be grouped to avoid errors:
+%\begin{verbatim}
+%\newcommand*{\insertionsort}[1]{%
+%\def\sortedlist{}%
+%\@for\val:=#1\do{{\insertinto{\val}{\sortedlist}}}%
+%\let#1=\sortedlist
+%}
+%\end{verbatim}
+%This won't work with the definition of \cs{insertinto} as
+%given in the previous section, as the grouping causes the
+%definition of the sorted list to be localised to that group.
+%Replacing
+%\begin{verbatim}
+%\let#2=\nlst
+%\end{verbatim}
+%with
+%\begin{verbatim}
+%\global\let#2=\nlst
+%\end{verbatim}
+%at the end of the definition of \cs{insertinto} will fix that.
+%
+%\subsection{Example (looking ahead)}
+%
+%This example checks the next value to determine if the loop
+%is on the last iteration, if it is, it does nothing, otherwise
+%it does a semi-colon:
+%\begin{verbatim}
+%\makeatletter
+%\def\mylist{1,2,3,4,5}%
+%\@for\val:=\mylist\do{\val
+%\ifx\@xfor@nextelement\@nnil \else ;\fi}
+%\makeatother
+%\end{verbatim}
+%which produces:
+%\makeatletter
+%\def\mylist{1,2,3,4,5}\relax
+%\@for\val:=\mylist\do{\val
+%\ifx\@xfor@nextelement\@nnil \else ;\fi}
+%\makeatother
+%
+%\section{Acknowledgements}
+%
+%Many thanks to Morten~H\o gholm for providing code to improve
+%efficiency.
+%
+% \StopEventually{\phantomsection
+%\addcontentsline{toc}{section}{Change History}
+%\PrintChanges\phantomsection
+%\addcontentsline{toc}{section}{Index}
+%\PrintIndex}
+%
+%
+%
+%\section{The Code}
+%\iffalse
+% \begin{macrocode}
+%<*xfor.sty>
+% \end{macrocode}
+%\fi
+% Note that the internal macros used by \cs{@for} have changed
+% in version 1.04.
+%
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{xfor}[2009/02/05 v1.05 (NLCT)]
+% \end{macrocode}
+%\begin{macro}{\if@endfor}
+% Define a switch to determine if the for loop should be
+% stopped prematurely.
+% \begin{macrocode}
+\newif\if@endfor
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@gobbleseven}
+%\changes{1.04}{2009 January 25}{added by Morten H\o gholm}
+% Ignore seven arguments.
+% \begin{macrocode}
+\long\def\@gobbleseven#1#2#3#4#5#6#7{}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@for}
+% \cs{@for}\meta{cmd}":="\meta{list}\cs{do}\marg{body}
+% test if the list is empty and then re-arrange
+%\changes{1.04}{2009 January 25}{Modified by Morten H\o gholm to
+% improve efficiency}
+% \begin{macrocode}
+\long\def\@for#1:=#2\do{%
+% \end{macrocode}
+% Initialise
+% \begin{macrocode}
+ \@endforfalse
+ \def\@forremainder{}%
+ \expandafter\def\expandafter\@fortmp\expandafter{#2}%
+% \end{macrocode}
+% If list is empty do nothing
+% \begin{macrocode}
+ \ifx\@fortmp\@empty
+ \expandafter\@gobbleseven
+ \fi
+ \expandafter\@@for\expandafter#1\expandafter{#2}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@@for}
+% Initialise for loop
+%\changes{1.04}{2009 January 25}{Added by Morten H\o gholm}
+% \begin{macrocode}
+\long\def\@@for#1#2#3{%
+ \@xforloop#1{#3}#2,\@nil,\@nil,%
+ \@xfor@endmarker% magic end marker
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@xfornoop}
+%\changes{1.04}{2009 January 25}{second and third arguments dropped (MH)}
+%\changes{1.04}{2009 January 25}{\cs{@fornoop} replaced by
+% \cs{@xfornoop} to prevent conflict with \cs{@tfor}}
+% Read up until magic end marker.
+% \begin{macrocode}
+\long\def\@xfornoop#1\@xfor@endmarker{}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@xforloop}
+%\cs{@forloop}\marg{var}\marg{action}
+%\changes{1.04}{2009 January 25}{Modified by Morten H\o gholm to
+% improve efficiency}
+%\changes{1.05}{2009 February 5}{\cs{@forloop} replaced by
+% \cs{@xforloop} to prevent conflict with other packages that
+% use \cs{@forloop}}
+% \begin{macrocode}
+\long\def\@xforloop#1#2#3,#4,{%
+ \def#1{#3}%
+ \ifx#1\@nnil
+% \end{macrocode}
+% Grab the \cs{@xfor@endmarker} at the very end
+% \begin{macrocode}
+ \expandafter\@xfornoop
+ \fi
+% \end{macrocode}
+% Removed |\@xfor@storenext#4,\@nil|. Instead store next element
+% in \cs{@xfor@nextelement}.
+% \begin{macrocode}
+ \def\@xfor@nextelement{#4}%
+ #2%
+ \if@endfor
+ \expandafter\@iforgatherrest
+ \fi
+ \@xforloop#1{#2}{#4},%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@iforgatherrest}
+% Gather the remainder (and store in \cs{@forremainder})
+%\changes{1.01}{2007 July 11}{made long}%
+%\changes{1.04}{2009 January 25}{argument syntax changed (MH)}
+% \begin{macrocode}
+\long\def\@iforgatherrest \@xforloop#1#2#3,#4\@xfor@endmarker{%
+ \def\@fortmp{#3}%
+ \ifx\@fortmp\@nnil
+ \def\@forremainder{}%
+ \else
+ \@forgatherrest{#3},#4\@xfor@endmarker%
+ \fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\@forgatherrest}
+% Get remainder of list (stored in \cs{@forremainder}):
+%\changes{1.01}{2007 July 11}{made long}%
+%\changes{1.04}{2009 January 25}{argument syntax changed (MH)}
+% \begin{macrocode}
+\long\def\@forgatherrest#1,\@nil,\@nil,\@xfor@endmarker{%
+ \def\@forremainder{#1}%
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\changes{1.02}{2007 August 16}{Added \cs{@xfor@storenext}}%
+%\changes{1.04}{2009 January 25}{Removed \cs{\@xfor@storenext}}%
+%\changes{1.04}{2009 January 25}{removed \cs{@iforloop}}
+
+%\iffalse
+% \begin{macrocode}
+%</xfor.sty>
+% \end{macrocode}
+%\fi
+%\iffalse
+% \begin{macrocode}
+%<*sample.tex>
+% \end{macrocode}
+%\fi
+%\section{Sample Document (sample.tex)}
+% \begin{macrocode}
+\listfiles
+\documentclass{article}
+
+\usepackage{xfor}
+
+\makeatletter
+
+% \insertinto{new value}{list}
+
+\newtoks\tmptok
+
+\newcommand{\insertinto}[2]{%
+\def\nlst{}%
+\@for\n:=#2\do{%
+% store new list in \tmptok
+\expandafter\tmptok\expandafter{\nlst}%
+% test current value against new value
+\ifnum\n>#1\relax
+ \edef\newstuff{\number#1,\n}%
+ % end for loop at the end of this iteration
+ \@endfortrue
+\else
+ \edef\newstuff{\n}%
+\fi
+% append new stuff to new list
+\ifx\nlst\@empty
+ \edef\nlst{\newstuff}%
+\else
+ \edef\nlst{\the\tmptok,\newstuff}%
+\fi
+}%
+% check to see if for loop was prematurely terminated
+\if@endfor
+ % loop may have been terminated during final iteration, in
+ % which case \@forremainder is empty.
+ \ifx\@forremainder\@empty
+ % do nothing
+ \else
+ % loop prematurely ended, append remainder of original list
+ % to new list
+ \expandafter\tmptok\expandafter{\nlst}%
+ \edef\nlst{\the\tmptok,\@forremainder}%
+ \fi
+\else
+ % wasn't prematurely terminated, so new value hasn't been added.
+ % Add now.
+ \expandafter\tmptok\expandafter{\nlst}%
+ \ifx\nlst\@empty
+ \edef\nlst{\number#1}%
+ \else
+ \edef\nlst{\the\tmptok,\number#1}%
+ \fi
+\fi
+\global\let#2=\nlst
+}
+
+% \insertionsort{list}
+% replaces list with sorted list
+
+\newcommand{\insertionsort}[1]{%
+\def\sortedlist{}%
+\@for\val:=#1\do{{\insertinto{\val}{\sortedlist}}}%
+\let#1=\sortedlist}
+
+\makeatother
+
+\begin{document}
+Unsorted list:
+\def\mylist{4,2,7,1,10,11,20,15}\mylist.
+
+\insertionsort{\mylist}%
+Sorted list: \mylist.
+
+Iterate through the list (next element in parentheses):
+\makeatletter
+\@for\n:=\mylist\do{%
+\n
+\ifx\@xfor@nextelement\@nnil
+ % last iteration
+\else
+ (\@xfor@nextelement);
+\fi
+}.
+\end{document}
+% \end{macrocode}
+%\iffalse
+% \begin{macrocode}
+%</sample.tex>
+% \end{macrocode}
+%\fi
+%\Finale
+\endinput
diff --git a/macros/latex/contrib/xfor/xfor.ins b/macros/latex/contrib/xfor/xfor.ins
new file mode 100644
index 0000000000..3615cd61b0
--- /dev/null
+++ b/macros/latex/contrib/xfor/xfor.ins
@@ -0,0 +1,33 @@
+% xfor.ins generated using makedtx version 0.94b 2009/2/5 16:02
+\input docstrip
+
+\preamble
+
+ xfor.dtx
+ Copyright 2009 Nicola Talbot
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either version 1.3
+ of this license of (at your option) any later version.
+ The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of LaTeX
+ version 2005/12/01 or later.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ The Current Maintainer of this work is Nicola Talbot.
+
+ This work consists of the files xfor.dtx and xfor.ins and the derived files xfor.sty, sample.tex.
+
+\endpreamble
+
+\askforoverwritefalse
+
+\generate{\file{xfor.sty}{\usepreamble\defaultpreamble
+\usepostamble\defaultpostamble\from{xfor.dtx}{xfor.sty,package}}
+\file{sample.tex}{\usepreamble\defaultpreamble
+\usepostamble\defaultpostamble\from{xfor.dtx}{sample.tex,package}}
+}
+
+\endbatchfile
diff --git a/macros/latex/contrib/xfor/xfor.pdf b/macros/latex/contrib/xfor/xfor.pdf
new file mode 100644
index 0000000000..4d9c7bf290
--- /dev/null
+++ b/macros/latex/contrib/xfor/xfor.pdf
Binary files differ