summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-02-13 00:03:06 +0000
committerKarl Berry <karl@freefriends.org>2013-02-13 00:03:06 +0000
commitfee6ae63b6689ddbae970ff9114c6ed976bf1dab (patch)
tree939a7748a57f664be54e21ea64d2168617f5d07c /Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
parent4abc207ecf013eb27bf9f83c29b8a82408c9cd71 (diff)
skeyval (12feb13)
git-svn-id: svn://tug.org/texlive/trunk@29092 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex')
-rw-r--r--Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex823
1 files changed, 425 insertions, 398 deletions
diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
index 309a5649c93..a61c4f0c499 100644
--- a/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
+++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
@@ -1,5 +1,5 @@
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
-% This is file 'skeyval-for', version 1.1a, 2012/10/16. %
+% This is file 'skeyval-for.tex', version 1.2, 2013/02/10. %
% %
% This package and accompanying files may be distributed and/or %
% modified under the conditions of the LaTeX Project Public License, %
@@ -23,7 +23,7 @@
% skeyval-pstkey.sty, skeyval-pstkey.tex, skeyval-testclass.cls, %
% and skeyval-testpkg.sty. %
% %
-% Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). %
+% Copyright (c) 2010-2013 Ahmed Musa (amusa22@gmail.com). %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\begingroup%
@@ -59,16 +59,21 @@
\expandafter\let\csname skeyval-for-loaded\endcsname\endinput
\ifx\ProvidesFile\@undefined
- \message{File 'skeyval-for.tex' 2012/10/16 v1.1a
+ \message{File 'skeyval-for.tex' 2013/02/10 v1.2
Loops for skeyval package (AM)}
\else
\ProvidesFile{skeyval-for.tex}
- [2012/10/16 v1.1a Loops for skeyval package (AM)]
+ [2013/02/10 v1.2 Loops for skeyval package (AM)]
\@addtofilelist{skeyval-for.tex}
\fi
-\skvrobustdef*\skv@nostackerr{\skv@err{You've called an empty stack}\@ehd}
-% \skvsavestate<base-fn>{<fn-list>}<counter>
+\skvrobustdef*\skv@nostackerr{%
+ \skv@err{You've called an empty stack}\skv@ehd
+}
+% \skvsavestate<base-fn>{<fn-list>}<counter-number>
+%
+% See file skeyval-core.tex for \skvpushfunctions and \skvpopfunctions.
+%
\skvrobustdef*\skvsavestate#1#2#3{%
\skvgadvanceno#3\@ne
\begingroup
@@ -80,13 +85,13 @@
\def\do##1{\let\skvnoexpandcs{\skv@prova{##1}}\noexpand##1}%
\edef\reserved@a{\endgroup#2}\reserved@a
}
-% \skvrestorestate<base-fn><counter>
+% \skvrestorestate<base-fn><counter-number>
\skvrobustdef*\skvrestorestate#1#2{%
\begingroup
\let\nostack\skv@nostackerr
\edef\skv@elt{\skvnoexpandcs{\skvremovescape#1@skv@stack}}%
\expandafter\ifx\skv@elt\relax
- \skv@err{Stack of '\noexpand#1' is undefined}\@ehd
+ \skv@err{Stack of '\noexpand#1' is undefined}\skv@ehd
\fi
\edef\skv@prova{\skvexpandtwice\skv@elt}%
\edef\skv@provb##1##{\endgroup##1\gdef\skvexpandonce\skv@elt}%
@@ -95,60 +100,78 @@
}
\skvnewregisters\bool{%
- \ifskvbreakloop\ifforeachlastitem
- \ifskvprocessempty\ifskv@foreach@swa
- \ifskv@foreach@swb\ifskv@foreach@parenth
+ \ifbreakallforeachloops,\ifskvbreakloop,\ifforeachlastitem,
+ \ifskvprocessempty,\ifskv@foreach@swa,\ifskv@foreach@swb,
+ \ifskv@foreach@parenth,\ifskv@useemptylist
}
-\skvnewnumbers[skv@]{csvdepth,dolistcnt}
-
-\skvrobustdef*\skv@usetempst#1#2{%
- \edef#2{\skvifdefboolTF{skv@tempst}\skvexpandonce\unexpanded{#1}}%
+\skvnewlet\skvbreakloop\skvbreaklooptrue
+\skvnewlet\breaknewforeach\skvbreaklooptrue
+% \breakallforeachloops will break all current loops (inner and outer):
+\skvnewdef*\breakallforeachloops{%
+ \skvbreaklooptrue\breakallforeachloopstrue
}
+
+\skvnewnumbers[skv@]{csvdepth,dolistdepth}
%
% \skvdolist{<parser>}{<list>}<holdercmd>{<callback>}
% \skvdolist*{<parser>}{<listcmd>}<holdercmd>{<callback>}
-%
-% 1. \skvdolist can process both csv and tsv/nsv lists.
-% 2. This can be nested to any depth, with different parsers on each
-% level.
-% 3. This will not process an empty list; see \skvecommaloop.
+% \skvparselist{<parser>}{<list>}<holdercmd>{<callback>}
+% \skvparselist*{<parser>}{<listcmd>}<holdercmd>{<callback>}
+% \skvprocesslist{<parser>}{<list>}<holdercmd>{<callback>}
+% \skvprocesslist*{<parser>}{<listcmd>}<holdercmd>{<callback>}
+%
+% 1. These macros can process both csv and tsv/nsv lists. Use empty
+% <parser> for tsv lists.
+% 2. These macros can be nested to any depth, with different parsers
+% on each level.
+% 3. \skvdolist and \skvparselist will not process an empty list, but
+% \skvprocesslist will do so.
% 4. For comma lists, \skvcommaloop and \skvcommaparse are faster.
% See later.
-% 5. For processing kv lists, use \skvkvparse.
+% 5. For processing kv lists, use \skvparsekvlist.
%
-\skvrobustdef*\skvdolist{\skv@testst\skv@dolist}
+\skvrobustdef*\skvdolist{\skv@useemptylistfalse\skv@testst\skv@dolist}
\skvrobustdef*\skv@dolist#1#2#3#4{%
- \skvgadvanceno\skv@dolistcnt\@ne
+ % \skvlistcount is used by listkeys.
+ \skvsavestate\skvdolist{%
+ \do\skv@dolist@callback
+ \do\skv@dolist@a\do\skvlistcount\do\ifskv@useemptylist
+ }\skv@dolistdepth
\skv@usetempst{#2}#3%
- \def\skv@dolist@a{skv@dolist@\skvrom\skv@dolistcnt}%
- \skvcsdef{\skv@dolist@a}##1##2##3#1{%
- \skvifstrcmpTF{##3}{\skv@dolist@nil}{%
+ \edef\skv@dolist@callback{\unexpanded{#4}}%
+ \def\skvlistcount{0}%
+ \def\skv@dolist@a##1##2#1{%
+ \skvifstrcmpTF{##2}{\skv@dolist@nil}{%
% To allow nesting of loop:
\skvbreakloopfalse
}{%
- \edef##1{\unexpanded{##3}}%
- ##2\relax
+ \edef##1{\unexpanded{##2}}%
+ \edef\skvlistcount{\the\numexpr\skvlistcount+1}%
+ \skv@dolist@callback\relax
\ifskvbreakloop
\skvbreakloopfalse
\begingroup
- \skvcsdef{\skv@dolist@a}####1\skv@dolist@nil#1{\endgroup}%
+ \def\skv@dolist@a####1####2\skv@dolist@nil#1{%
+ \endgroup
+ \edef\skvremainder{\unexpanded{####2}}%
+ }%
\fi
- \@nameuse{\skv@dolist@a}##1{##2}%
+ \skv@dolist@a{##1}%
}%
}%
- \skvifemptyTF#3{}{%
- \edef\reserved@a{\unexpanded{\@nameuse{\skv@dolist@a}#3{#4}}}%
- \expandafter\reserved@a#3#1\skv@dolist@nil#1%
+ \ifskv@useemptylist
+ \def\reserved@a##1##2##3{##3}%
+ \else
+ \let\reserved@a\skvifemptyTF
+ \fi
+ \reserved@a#3{}{%
+ \expandafter\skv@dolist@a\expandafter#3#3#1\skv@dolist@nil#1%
}%
- \skvgadvanceno\skv@dolistcnt\m@ne
+ \skvrestorestate\skvdolist\skv@dolistdepth
}
-
% First normalize the list before parsing.
-%
-% \skvparselist{<parser>}{<list>}<holdercmd>{<callback>}
-% \skvparselist*{<parser>}{<listcmd>}<holdercmd>{<callback>}
-%
-\skvrobustdef*\skvparselist{\skv@testst\skv@parselist}
+\skvrobustdef*\skvparselist{\skv@useemptylistfalse\skv@testst\skv@parselist}
+\skvrobustdef*\skvprocesslist{\skv@useemptylisttrue\skv@testst\skv@parselist}
\skvrobustdef*\skv@parselist#1#2#3{%
\skv@usetempst{#2}#3%
\skvcsvnormalize[#1]#3%
@@ -156,14 +179,11 @@
\skv@dolist{#1}#3#3%
}
-\skvifdefinable\listbreaker{\let\listbreaker\relax}
-\skvifdefinable\listpauser{\let\listpauser\relax}
-\skvnewdef*\skv@listbreakertoks{\listbreaker}
-\skvnewdef*\skv@listpausertoks{\listpauser}
-
+\skvnewlet\foreachlistbreaker\relax
+\skvnewlet\foreachlistpauser\relax
+\skvnewdef*\skv@listbreakertoks{\foreachlistbreaker}
+\skvnewdef*\skv@listpausertoks{\foreachlistpauser}
\skvnewlet\skvprocessempty\skvprocessemptytrue
-\skvletmanytocmd{\skvbreakloop\interruptloop\skvbreakforeach
- \interruptforeach}\skvbreaklooptrue
% Reversing tokens:
\skvnewdef*\skvreverse#1{\skv@reverse#1\skv@reverse@stop}
@@ -217,14 +237,14 @@
}
% A version of LaTeX's \@tfor that can parse undoubled parameter
-% characters.
+% characters and terminate the loop by using \skvbreakloop.
%
% \skvtfor<holder.cmd>:={<list>}\do{<callback>}
% \skvtfor*<holder.cmd>:={<listcmd>}\do{<callback>}
%
% Example:
%
-% \skvnewregister\count\nr
+% \skvnewregister\count{\nr}
% \skvtfor\x:=a \ifx {\def\x#1{#1}} \fi\do{%
% \nr\z@
% \skvtfor\y:=12345\do{%
@@ -239,7 +259,7 @@
\skvrobustdef*\skv@tfor#1:={\skv@tf@r#1 }
\skvrobustdef\skv@tf@r#1#2\do#3{%
\edef#1{\skvtrimspace{#2}}%
- \edef#1{\skvifboolTF{skv@tempst}\skvexpandtwice\skvexpandonce{#1}}%
+ \edef#1{\skvifdefboolTF{skv@tempst}\skvexpandtwice\skvexpandonce{#1}}%
\skvifemptyTF#1{}{%
\skvbreakloopfalse
\expandafter\skv@tforloop#1\skv@tfor@nil\skv@tfor#1{#3}%
@@ -266,23 +286,29 @@
%+++++++++++++++ Non-expandable comma loops ++++++++++++++%%
%
% 1. These follow from \skvdolist and \skvparselist, but they are
-% specialized for comma lists and they are faster.
-% 2. They can be nested.
-% 3. \skvecommaloop needs \skv@c@mmaloop.
+% specialized for comma lists and they are faster, since they don't
+% stack any state.
+% 2. There is no fear of parameter characters in <callback> being mixed
+% with those of \skv@commaloop@picknext.
+% 2. They can be nested to any depth.
%
% \skvcommaloop{<list>}<holder-cmd>{<callback>}
% \skvcommaloop*{<listcmd>}<holder-cmd>{<callback>}
%
+% Example:
+%
+% \skvcommaloop{x#1,y#1}\tempa{\edef\xx#1{#1\tempa}}
+%
\skvrobustdef*\skvcommaloop{\skv@testst\skv@commaloop}
\skvrobustdef\skv@commaloop#1#2#3{%
\skv@usetempst{#1}#2%
% Don't put \skvcsvnormalize#2 here. Use \skvcommaparse instead.
% Some callers of \skvcommaloop already have their lists normalized.
\skvifxTF#2\@empty{}{%
- \skvexpandnext{\skv@c@mmaloop#2{#3}}#2,\skv@commaloop@nil,%
+ \skvexpandnext{\skv@commaloop@picknext#2{#3}}#2,\skv@commaloop@nil,%
}%
}
-\skvrobustdef\skv@c@mmaloop#1#2#3,{%
+\skvrobustdef\skv@commaloop@picknext#1#2#3,{%
\skvifstrcmpTF{#3}{\skv@commaloop@nil}{%
\skvbreakloopfalse
}{%
@@ -291,9 +317,12 @@
\ifskvbreakloop
\skvbreakloopfalse
\begingroup
- \long\def\skv@c@mmaloop##1\skv@commaloop@nil,{\endgroup}%
+ \long\def\skv@commaloop@picknext##1##2##3\skv@commaloop@nil,{%
+ \endgroup
+ \edef\skvremainder{\unexpanded{##3}}%
+ }%
\fi
- \skv@c@mmaloop#1{#2}%
+ \skv@commaloop@picknext#1{#2}%
}%
}
%
@@ -306,7 +335,7 @@
%
\skvrobustdef\skvecommaloop{\skv@testst\skv@ecommaloop}
\skvrobustdef\skv@ecommaloop#1#2#3{%
- \edef#2{\unexpanded{\skv@c@mmaloop#2{#3}}}%
+ \edef#2{\unexpanded{\skv@commaloop@picknext#2{#3}}}%
\ifskv@tempst\expandafter\expandafter\fi#2#1,\skv@commaloop@nil,%
}
%
@@ -325,30 +354,17 @@
% \skvkvparse{<list>}<cmd>{<callback>}
% \skvkvparse*{<listcmd>}<cmd>{<callback>}
%
-% \skvkvparse is as \skvcommaloop but will first normalize <list> using
-% \skvkvnormalize.
+% 1. \skvkvparse is as \skvcommaloop but will first normalize <list> using
+% \skvkvnormalize.
+% 2. It is meant for processing key-value lists.
%
\skvrobustdef*\skvkvparse{\skv@testst\skv@kvparse}
-\skvnewlet\skvparsekeyvals\skvkvparse
+\skvnewlet\skvparsekvlist\skvkvparse
\skvrobustdef\skv@kvparse#1#2#3{%
\skv@usetempst{#1}#2%
\skvkvnormalize#2%
\skvcommaloop*#2#2{#3}%
}
-% \skvcommaprocess{<list>}<holder.cmd>
-% \skvcommaprocess*{<listcmd>}<holder.cmd>
-%
-% If <list> or <listcmd> is a single item, then no looping is required.
-%
-\skvrobustdef*\skvcommaprocess{\skv@testst\skv@commaprocess}
-\skvrobustdef*\skv@commaprocess#1#2#3{%
- \skv@usetempst{#1}#2%
- \skvxifinTF{,}{\skvoxdetok#2}{%
- \skvcommaparse*#2#2{#3}%
- }{%
- \skvdespacecontent#2#3%
- }%
-}
% \skvcountelements[<parser>]{<list>}{<return.cmd>}
% \skvcountelements*[<parser>]{<listcmd>}{<return.cmd>}
\skvrobustdef*\skvcountelements{\skv@teststopt\skv@countelements,}
@@ -402,14 +418,20 @@
%
% 3. Elements of the form (a,b) and [a,b] are grabbed together.
%
-% 4. Use \interruptforeach to break out of the loop prematurely.
+% 4. Use \breaknewforeach to break out of the loop prematurely.
%
% 5. \newforeach can be nested.
-
-% \skv@foreach@sisterdepth must be different from \foreachdepth,
+%
+% 6. The star (*) variant of \newforeach is equivalent to using the
+% key 'list is a macro' (or *) in <options>.
+%
+% \skv@foreach@holderdepth must be different from \foreachnestdepth,
% to avoid confusing two different stacks.
-\skvnewnumbers{foreachdepth,skv@foreach@sisterdepth,skv@foreach@nra,%
- skv@warnsubparser}
+\skvnewnumbers{foreachnestdepth,skv@foreach@holderdepth,%
+ skv@foreach@nra,skv@warnsubparser}
+% \newforeach will not accept \skvifstreq or \skvifstrcmpTF because
+% they don't start with '\if'. So we introduce \ifforeachstrcmp:
+\skvnewlet\ifforeachstrcmp\skvifstreq
\skvnewdef*\skv@foreach@onlyinitially{}
\skvrobustdef*\skvforeachonlyinitially#1{%
\edef\skv@foreach@onlyinitially{%
@@ -496,9 +518,9 @@
\appendtoendforeach[#1]{#2}%
}
-% \skv@foreach@fi must use \detokenize. Don't change to \string!
-\skvnewedef*\skv@foreach@fi{\detokenize{\fi}}
-\skvnewedef*\skv@foreach@if{\string\if}
+% \skv@foreach@fi@toks must use \detokenize. Don't change to \string!
+\skvnewedef*\skv@foreach@fi@toks{\detokenize{\fi}}
+\skvnewedef*\skv@foreach@if@toks{\string\if}
% \skv@foreach@ifacceptkv and \skv@foreach@maketester must come
% before the initialization of keys:
@@ -508,7 +530,7 @@
\edef\skv@prova{\unexpanded{#1}}%
\ifnum0>\numexpr0\ifx\skv@prova\@empty-1\else
\ifx\skv@prova\@nnil-1\else+0\fi\fi\relax\relax
- \skv@err{Invalid syntax '\detokenize{#1}'}\@ehd
+ \skv@err{Invalid syntax '\detokenize{#1}'}\skv@ehd
\else
\edef\next{\unexpanded{#2}}%
\fi
@@ -522,12 +544,12 @@
}{%
\skv@err{Value of key '#1' must
\MessageBreak be escaped: the holder macro
- \MessageBreak to be evaluated}\@ehd
+ \MessageBreak to be evaluated}\skv@ehd
}%
}{%
\skv@err{Value of key '#1' must
\MessageBreak be only one token: the holder
- \MessageBreak macro to be evaluated}\@ehd
+ \MessageBreak macro to be evaluated}\skv@ehd
}%
}
% \skv@foreach@maketester{<cond>}<cond.tester.cmd>{<flag>}
@@ -536,7 +558,14 @@
% are allowed. Restricting the type of allowed conditionals is
% necessary for auto syntax checking.
% 2. <flag> is either 0 or 1, signifying whether or not the condition
-% should be entered in postcallback.
+% should be entered in postcallback. This is because
+% \skv@foreach@maketester is called (by key 'loop stopper') for
+% formating the premature exit condition and (in
+% \skv@foreach@parsecountin and \skv@foreachfox@parsecountin) for the
+% condition for counting an item of the list. In the latter case,
+% there is no need to enter the formated
+% condition in the postcallback, since it it is entered in the
+% 'afterprecallback' or (in the case of \foreachfox) in 'precallback'.
%
% Examples: \ifnum\x>10\fi, \ifx\x\cmd\fi.
%
@@ -546,10 +575,11 @@
\begingroup
\edef\skv@prova{\detokenize{#1}}%
\skvifblankTF{#1}{%
- \skv@err{A blank conditional given in \string\newforeach}\@ehd
+ \skv@err{A blank conditional has been given in
+ \MessageBreak\string\newforeach or a similar command}\skv@ehd
}{%
- \skvxifinTF{\skv@foreach@fi\relax}{\detokenize{#1}\relax}{%
- \skvxifinTF{\relax\skv@foreach@if}{\relax\detokenize{#1}}{%
+ \skvxifinTF{\skv@foreach@fi@toks\relax}{\detokenize{#1}\relax}{%
+ \skvxifinTF{\relax\skv@foreach@if@toks}{\relax\detokenize{#1}}{%
\edef#2{\noexpand\skvifconditionTF\unexpanded{#1}}%
\ifnum#3=\@ne
\skv@foreach@addtocallback{post}{%
@@ -561,7 +591,7 @@
{Invalid, possibly unbalanced, conditional '\skv@prova'}%
}%
}{%
- \skv@err{Invalid conditional '\skv@prova'}\@ehd
+ \skv@err{Invalid conditional '\skv@prova'}\skv@ehd
}%
}%
\skvexpanded{\endgroup
@@ -602,30 +632,26 @@
\def\skv@foreach@subparser{/}
;
parser/{,}/
- \ifskvindef\else
- \edef\skv@foreach@parser{\unexpanded{#1}}
- \skvstripouterbraces{2}\skv@foreach@parser
- \skvxifntypeTF{\detokenize{#1}}{%
- \begingroup
- % It is assumed that every n-type parser and subparser
- % must have catcode 12:
- \skvexpandnext{\catcode`}\skv@foreach@parser=12\relax
- \skv@rescan\skv@foreach@parser
- \skvaftergroupdef\skv@foreach@parser\endgroup
- }{}
- \fi
+ \edef\skv@foreach@parser{\unexpanded{#1}}
+ \skvstripouterbraces{2}\skv@foreach@parser
+ \skvxifntypeTF{\detokenize{#1}}{%
+ \begingroup
+ % It is assumed that every n-type parser and subparser
+ % must have catcode 12:
+ \skvexpandnext{\catcode`}\skv@foreach@parser=12\relax
+ \skvrescan\skv@foreach@parser
+ \skvaftergroupdef\skv@foreach@parser\endgroup
+ }{}
;
subparser/{/}/
- \ifskvindef\else
- \edef\skv@foreach@subparser{\unexpanded{#1}}
- \skvstripouterbraces{2}\skv@foreach@subparser
- \skvxifntypeTF{\detokenize{#1}}{
- \begingroup
- \skvexpandnext{\catcode`}\skv@foreach@subparser=12\relax
- \skv@rescan\skv@foreach@subparser
- \skvaftergroupdef\skv@foreach@subparser\endgroup
- }{}
- \fi
+ \edef\skv@foreach@subparser{\unexpanded{#1}}
+ \skvstripouterbraces{2}\skv@foreach@subparser
+ \skvxifntypeTF{\detokenize{#1}}{
+ \begingroup
+ \skvexpandnext{\catcode`}\skv@foreach@subparser=12\relax
+ \skvrescan\skv@foreach@subparser
+ \skvaftergroupdef\skv@foreach@subparser\endgroup
+ }{}
;
terminator,callback terminator/{;}/
\edef\skv@foreach@terminator{\unexpanded{#1}}%
@@ -633,27 +659,40 @@
;
% process up to = <nr>
% Maximum number of items to process:
- process up to,process up to number/\@nil/
- \ifskvindef\else
+ process up to,process up to number//
+ \skviflacus#1\then\else
+ \skvensureinteger{process up to}{#1}%
\def\skv@foreach@processupto{#1}%
- \ifx\skv@foreach@processupto\@nnil\else
- \skv@ensureinteger{process up to}{#1}%
- \fi
+ \skvstripouterbraces{2}\skv@foreach@processupto
\fi
;
process empty list/true/
\edef\skv@foreach@processempty{0\skvifstrcmpTF{true}{#1}01}%
/true,false
;
- % Eg, exit when=\ifnum\x=20\fi
+ % 'break=<condition>'
+ % Break list processing when <condition> is satisfied. <condition> must
+ % be a balanced plain TeX conditional. Eg, 'exit when={\ifnum\x=20\fi}'.
+ % Notice the use of outer braces in '{\ifnum\x=20\fi}'. This avoids
+ % conflicting the two equality signs: for the key-value and for number
+ % testing.
.exec/\let\skv@foreach@exittester\@secondoftwo;
- loop stopper,exit when/\if01\fi/
- \ifskvindef\else
- \edef\skv@tempa{\unexpanded{#1}}%
- \skvstripouterbraces{2}\skv@tempa
- \expandafter\skv@foreach@maketester\expandafter
- {\skv@tempa}\skv@foreach@exittester\@ne
- \fi
+ break,loop stopper,exit when/\if01\fi/
+ \edef\skv@tempa{\unexpanded{#1}}%
+ \skvstripouterbraces{2}\skv@tempa
+ \skvexpbracenext\skv@foreach@maketester\skv@tempa
+ \skv@foreach@exittester\@ne
+ ;
+ % Java-type of continue: If the user wants to ignore the callback for
+ % some items, he can instantiate the key 'condition=<condition>'.
+ % <condition> must be a balanced plain TeX conditional. Eg,
+ % continue={\ifnum\x=20\fi}.
+ .exec/\let\skv@foreach@continuetester\@secondoftwo;
+ continue,ignore callback/\if01\fi/
+ \edef\skv@tempa{\unexpanded{#1}}%
+ \skvstripouterbraces{2}\skv@tempa
+ \skvexpbracenext\skv@foreach@maketester\skv@tempa
+ \skv@foreach@continuetester\skvz@
;
% Eg, 'evaluate = \x as \z using \numexpr\x*2'. 'as' and 'using', and the
% tokens after them, can be missing, but the formula must be complete.
@@ -724,39 +763,28 @@
\skv@foreach@parserecall{#1}%
}%
;
- item counter,counter/\@nil/
- \ifskvindef\else
- \edef\skv@prova{\unexpanded{#1}}%
- \ifx\skv@prova\@nnil
- \skv@err{Invalid empty value for key 'item counter'}\@ehd
- \else
- \skvifescapedTF{#1}{%
- \let\skv@foreach@itemcounter\skv@prova
- }{%
- \skv@err{Non-escaped value '\detokenize{#1}'
- \MessageBreak for key 'item counter'}\@ehd
- }%
- \fi
- \fi
+ item counter,counter/\foreachdefaultitemcounter/
+ \skvifescapedTF{#1}{%
+ \def\skv@foreach@itemcounter{#1}%
+ }{%
+ \skv@err{Non-escaped value '\detokenize{#1}'
+ \MessageBreak for key 'item counter'}\skv@ehd
+ }%
;
- list breaker/\listbreaker/
- \ifskvindef\else
- \edef\skv@prova{\unexpanded{#1}}%
- \ifx\skv@prova\@empty
- \skv@err{Invalid empty value for key 'list breaker'}\@ehd
- \else
- \let\skv@listbreakertoks\skv@prova
- \fi
+ list breaker/\foreachlistbreaker/
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifx\skv@prova\@empty
+ \skv@err{Invalid empty value for key 'list breaker'}\skv@ehd
+ \else
+ \let\skv@listbreakertoks\skv@prova
\fi
;
- list pauser/\listpauser/
- \ifskvindef\else
- \edef\skv@prova{\unexpanded{#1}}%
- \ifx\skv@prova\@empty
- \skv@err{Invalid empty value for key 'list pauser'}\@ehd
- \else
- \let\skv@listpausertoks\skv@prova
- \fi
+ list pauser/\foreachlistpauser/
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifx\skv@prova\@empty
+ \skv@err{Invalid empty value for key 'list pauser'}\skv@ehd
+ \else
+ \let\skv@listpausertoks\skv@prova
\fi
;
% Remember outside the loop the holder values. Of course, this
@@ -768,25 +796,20 @@
% This default value of 'link' is required by \skv@foreach@filllist:
.exec code/\def\skv@foreach@link{\@nil};
link/\@nil/
- \ifskvindef\else
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifcase0%
+ \ifx\skv@prova\@empty 1\fi
+ \ifx\skv@prova\@nnil 1\fi\relax
\edef\skv@foreach@link{\unexpanded{#1}}%
\skvstripouterbraces{2}\skv@foreach@link
- \ifnum0>\numexpr0\ifx\skv@foreach@link\@empty-1\else
- \ifx\skv@foreach@link\@nnil-1\else+0\fi\fi\relax\relax
- \skv@err{The key 'link' doesn't accept empty/blank values}\@ehd
- \fi
\fi
;
grow/\@nil/
- \ifskvindef\else
- \edef\skv@prova{\unexpanded{#1}}%
- \ifx\skv@prova\@nnil
- \skv@err{Value required for key 'grow'}\@ehd
- \else
- \skvcsedef{skv@foreach@grow#1}{00}
- \edef\skv@prova{\skvifstrcmpTF{#1}{left}{right}{left}}%
- \skvcsedef{skv@foreach@grow\skv@prova}{01}%
- \fi
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifx\skv@prova\@nnil\else
+ \skvcsedef{skv@foreach@grow#1}{00}
+ \edef\skv@prova{\skvifstrcmpTF{#1}{left}{right}{left}}%
+ \skvcsedef{skv@foreach@grow\skv@prova}{01}%
\fi
/left,right
;
@@ -795,17 +818,13 @@
\def\skv@foreach@growright{01}
;
grow left/true/
- \ifskvindef\else
- \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}01}
- \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}10}
- \fi
+ \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}01}
+ \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}10}
/true,false
;
grow right/true/
- \ifskvindef\else
- \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}01}
- \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}10}
- \fi
+ \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}01}
+ \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}10}
/true,false
;
% Keep the decimals in rounded numbers or dimensions when list is
@@ -829,17 +848,17 @@
\edef\skv@foreach@expandlistbeforefill{0\skvifstrcmpTF{true}{#1}01}
/true,false
;
- expand list once,*,list is a macro,macro list/true/
+ expand list once,x1,list is a macro,macro list/true/
\edef\skv@foreach@expandlistonce{0\skvifstrcmpTF{true}{#1}01}%
/true,false
;
- expand list twice/true/
+ expand list twice,x2/true/
\edef\skv@foreach@expandlisttwice{0\skvifstrcmpTF{true}{#1}01}%
/true,false
;
% Don't use 'expand' for this key, to avoid confusing it with
% the 'expand' for holder macros:
- expand list,fully expand list,expand list fully/true/
+ expand list,fully expand list,expand list fully,xx/true/
\edef\skv@foreach@expandlistfully{0\skvifstrcmpTF{true}{#1}01}%
/true,false
;
@@ -847,38 +866,22 @@
\edef\skv@foreach@reverselist{0\skvifstrcmpTF{true}{#1}01}
/true,false
;
- reverse list,reverse,reflect/true/
- \edef\skv@foreach@reverselist{0\skvifstrcmpTF{true}{#1}01}
- /true,false
- ;
}
-% The following keys don't need a default value:
-%
-% link,evaluate,*evaluate,evaluate num,*evaluate num,
-% evaluate dim,*evaluate dim,expand,*expand,count in,*count in,
-% loop stopper,process up to,grow
-%
-\skvinitializeqkeys{skeyval/foreach}{%
- parser,
- subparser,
- callback terminator,
- process up to,
- process empty list=false,
- item counter,
- list breaker,
- list pauser,
- recover holder values=false,
- grow left=false,
- grow right=false,
- keep decimals=true,
- keep high decimals=false,
- inherit=false,
- expand before fill=false,
- reverse list=false,
- expand list once=false,
- expand list twice=false,
- expand list fully=false,
+% The following keys don't need presetting. The user must supply
+% values when they are called. In internal loops, their values will
+% have to be revised from those of the outer loop.
+%
+% link,evaluate,,evaluate num,evaluate dim,expand,count in,
+% process up to,grow
+%
+\quickkeys.preset{skeyval/foreach}{%
+ parser,subparser,loop stopper,callback terminator,process up to,
+ process empty list=false,item counter,list breaker,list pauser,
+ recover holder values=false,grow left=false,grow right=false,
+ keep decimals=true,keep high decimals=false,inherit=false,
+ expand before fill=false,reverse list=false,expand list once=false,
+ expand list twice=false,expand list fully=false,
}
\skvnewdef*\skv@foreach@kvlist{}
@@ -926,36 +929,36 @@
\edef\skv@provb{\skvtrimspace{##2}}%
\edef\skv@provc{\skvtrimspace{##3}}%
\ifx\skv@prova\@empty
- \skv@err{Value of key 'evaluate' has no holder macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no holder macro}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@prova}{%
\expandafter\skvifntypeTF\expandafter{\skv@prova}{}{%
\skv@err{Value of key 'evaluate': more than 1
\MessageBreak token \skvoxdetok\skv@prova.
- \MessageBreak I can't find holder macro}\@ehd
+ \MessageBreak I can't find holder macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'evaluate':
- \MessageBreak holder macro \skvoxdetok\skv@prova not escaped}\@ehd
+ \MessageBreak holder macro \skvoxdetok\skv@prova not escaped}\skv@ehd
}%
\fi
\ifx\skv@provb\@empty
- \skv@err{Value of key 'evaluate' has no child macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no child macro}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@provb}{%
\expandafter\skvifntypeTF\expandafter{\skv@provb}{}{%
\skv@err{Value of key 'evaluate': more than 1
\MessageBreak token \skvoxdetok\skv@provb.
- \MessageBreak I can't find child macro}\@ehd
+ \MessageBreak I can't find child macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'evaluate':
- \MessageBreak child \skvoxdetok\skv@provb not escaped}\@ehd
+ \MessageBreak child \skvoxdetok\skv@provb not escaped}\skv@ehd
}%
\fi
\ifx\skv@provc\@empty
\skv@err{Value of key 'evaluate' has no formula or
- \MessageBreak holder macro to be expanded}\@ehd
+ \MessageBreak holder macro to be expanded}\skv@ehd
\fi
\skv@tempxifin{\pgfmathparse}{##3}{%
\def\skv@tempc####1\pgfmathparse####2\skv@nil{%
@@ -963,7 +966,7 @@
\skv@foreach@swatrue
\else
\skv@err{Invalid token \detokenize{####1}
- \MessageBreak before \string\pgfmathparse}\@ehd
+ \MessageBreak before \string\pgfmathparse}\skv@ehd
\fi
}%
\skv@tempc##3\skv@nil
@@ -986,7 +989,7 @@
\skv@tempa#1\skv@nil
}{%
\skv@err{Value of key 'evaluate':
- \MessageBreak there is 'using', but no 'as'}\@ehd
+ \MessageBreak there is 'using', but no 'as'}\skv@ehd
}%
}{%
% No formula given. Maybe the key is 'expand' or still 'evaluate'
@@ -995,10 +998,10 @@
\skv@tempxifin{as}{#1}{%
\def\skv@tempb##1as##2##3\skv@nil{%
\ifx\@nnil##1\@nnil
- \skv@err{Value of key 'evaluate' has no holder macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no holder macro}\skv@ehd
\else
\ifx\@nnil##2%
- \skv@err{Value of key 'evaluate' has no child macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no child macro}\skv@ehd
\else
\skv@tempa##1as##2using##1\skv@nil
\fi
@@ -1008,7 +1011,7 @@
}{%
% No 'as' or 'using': #1 should be only the holder macro:
\ifx\@nnil#1\@nnil
- \skv@err{Value of key 'evaluate' has no holder macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no holder macro}\skv@ehd
\else
\skvifntypeTF{#1}{%
% Expand the holder macro:
@@ -1016,7 +1019,7 @@
}{%
\skv@err{Value of key 'evaluate': more than 1
\MessageBreak token '\detokenize{#1}'.
- \MessageBreak I can't find holder macro}\@ehd
+ \MessageBreak I can't find holder macro}\skv@ehd
}%
\fi
}%
@@ -1047,7 +1050,7 @@
\skvrobustdef*\skv@foreach@parsepgfmathparse#1{%
\begingroup
\ifdefined\pgfmathparse\else
- \skv@err{No \string\pgfmathparse; 'pgfmath' module not loaded}\@ehd
+ \skv@err{No \string\pgfmathparse; 'pgfmath' module not loaded}\skv@ehd
\fi
\def\skv@tempxifin##1##2{%
\skvxifinTF{\detokenize{##1}}{\detokenize{##2}}%
@@ -1058,36 +1061,36 @@
\edef\skv@provb{\skvtrimspace{##2}}%
\edef\skv@provc{\skvtrimspace{##3}}%
\ifx\skv@prova\@empty
- \skv@err{Value of key 'pgfmath parse' has no holder macro}\@ehd
+ \skv@err{Value of key 'pgfmath parse' has no holder macro}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@prova}{%
\expandafter\skvifntypeTF\expandafter{\skv@prova}{}{%
\skv@err{Value of key 'pgfmath parse': more than 1
\MessageBreak token \skvoxdetok\skv@prova.
- \MessageBreak I can't find holder macro}\@ehd
+ \MessageBreak I can't find holder macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'pgfmath parse':
- \MessageBreak holder macro \skvoxdetok\skv@prova not escaped}\@ehd
+ \MessageBreak holder macro \skvoxdetok\skv@prova not escaped}\skv@ehd
}%
\fi
\ifx\skv@provb\@empty
- \skv@err{Value of key 'pgfmath parse' has no child macro}\@ehd
+ \skv@err{Value of key 'pgfmath parse' has no child macro}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@provb}{%
\expandafter\skvifntypeTF\expandafter{\skv@provb}{}{%
\skv@err{Value of key 'pgfmath parse': more than 1
\MessageBreak token \skvoxdetok\skv@provb.
- \MessageBreak I can't find child macro}\@ehd
+ \MessageBreak I can't find child macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'pgfmath parse':
- \MessageBreak child \skvoxdetok\skv@provb not escaped}\@ehd
+ \MessageBreak child \skvoxdetok\skv@provb not escaped}\skv@ehd
}%
\fi
\ifx\skv@provc\@empty
\skv@err{Value of key 'pgfmath parse' has no formula or
- \MessageBreak holder macro to be expanded}\@ehd
+ \MessageBreak holder macro to be expanded}\skv@ehd
\fi
\skv@tempxifin{\pgfmathparse}{##3}{%
\def\skv@tempc####1\pgfmathparse####2\skv@nil{%
@@ -1095,18 +1098,18 @@
\skv@foreach@swatrue
\else
\skv@err{Invalid token \detokenize{####1}
- \MessageBreak before \string\pgfmathparse}\@ehd
+ \MessageBreak before \string\pgfmathparse}\skv@ehd
\fi
}%
\expandafter\skv@tempc\skv@provc\skv@nil
}{%
\skv@tempxifin{\numexpr}{##3}{%
\skv@err{Value of key 'pgfmath parse':
- \MessageBreak\noexpand\numexpr not allowed}\@ehd
+ \MessageBreak\noexpand\numexpr not allowed}\skv@ehd
}{%
\skv@tempxifin{\dimexpr}{##3}{%
\skv@err{Value of key 'pgfmath parse':
- \MessageBreak\noexpand\dimexpr not allowed}\@ehd
+ \MessageBreak\noexpand\dimexpr not allowed}\skv@ehd
}{%
\skv@foreach@swatrue
\edef\skv@provc{\noexpand\pgfmathparse{\skvexpandonce\skv@provc}}%
@@ -1120,16 +1123,16 @@
\skv@tempa#1\skv@nil
}{%
\skv@err{Value of key 'pgfmath parse':
- \MessageBreak there is 'using', but no 'as'}\@ehd
+ \MessageBreak there is 'using', but no 'as'}\skv@ehd
}%
}{%
\skv@tempxifin{as}{#1}{%
\def\skv@tempb##1as##2##3\skv@nil{%
\ifx\@nnil##1\@nnil
- \skv@err{Value of key 'pgfmath parse' has no holder macro}\@ehd
+ \skv@err{Value of key 'pgfmath parse' has no holder macro}\skv@ehd
\else
\ifx\@nnil##2%
- \skv@err{Value of key 'pgfmath parse' has no child macro}\@ehd
+ \skv@err{Value of key 'pgfmath parse' has no child macro}\skv@ehd
\else
\skv@tempa##1as##2using##1\skv@nil
\fi
@@ -1139,7 +1142,7 @@
}{%
% No 'as' or 'using': #1 should be only the holder macro:
\ifx\@nnil#1\@nnil
- \skv@err{Value of key 'pgfmath parse' has no holder macro}\@ehd
+ \skv@err{Value of key 'pgfmath parse' has no holder macro}\skv@ehd
\else
\skvifntypeTF{#1}{%
% Evaluate the holder macro:
@@ -1147,7 +1150,7 @@
}{%
\skv@err{Value of key 'pgfmath parse': more than 1
\MessageBreak token '\detokenize{#1}'.
- \MessageBreak I can't find holder macro}\@ehd
+ \MessageBreak I can't find holder macro}\skv@ehd
}%
\fi
}%
@@ -1204,17 +1207,17 @@
\edef\skv@provc{\skvtrimspace{##3}}%
\edef\skv@provd{\skvtrimspace{##4}}%
\ifx\skv@prova\@empty
- \skv@err{Value of key 'count' has no counter macro}\@ehd
+ \skv@err{Value of key 'count' has no counter macro}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@prova}{%
\expandafter\skvifntypeTF\expandafter{\skv@prova}{}{%
\skv@err{Value of key 'count in': more than 1
\MessageBreak token \skvoxdetok\skv@prova.
- \MessageBreak I can't find counter macro}\@ehd
+ \MessageBreak I can't find counter macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'count':\MessageBreak
- counter macro \skvoxdetok\skv@prova not escaped}\@ehd
+ counter macro \skvoxdetok\skv@prova not escaped}\skv@ehd
}%
\fi
\ifx\skv@provd\@empty
@@ -1224,7 +1227,7 @@
\expandafter\let\skv@prova\skv@provd
}{%
\skv@err{Value of key 'count':\MessageBreak
- initial \skvoxdetok\skv@provd not an integer}\@ehd
+ initial \skvoxdetok\skv@provd not an integer}\skv@ehd
}%
\fi
\skv@foreach@swafalse
@@ -1240,11 +1243,11 @@
\expandafter\skvifntypeTF\expandafter{\skv@provb}{}{%
\skv@err{Value of key 'count in': more than 1
\MessageBreak token \skvoxdetok\skv@provb.
- \MessageBreak I can't find holder macro}\@ehd
+ \MessageBreak I can't find holder macro}\skv@ehd
}%
}{%
\skv@err{Value of key 'count':\MessageBreak
- holder macro \skvoxdetok\skv@provb not escaped}\@ehd
+ holder macro \skvoxdetok\skv@provb not escaped}\skv@ehd
}%
\skv@foreach@swatrue
% \skv@tester is the second argument of \skv@foreach@maketester.
@@ -1259,7 +1262,7 @@
\skv@tempa#1\skv@nil
}{%
\skv@err{Value of key 'count':
- \MessageBreak there is 'satisfying', but no 'all'}\@ehd
+ \MessageBreak there is 'satisfying', but no 'all'}\skv@ehd
}%
}{%
\skv@tempxifin{all}{#1}{%
@@ -1267,14 +1270,14 @@
}{%
% No 'all' or 'satisfying': #1 should be only the counter macro:
\ifx\@nnil#1\@nnil
- \skv@err{Value of key 'count' has no counter macro}\@ehd
+ \skv@err{Value of key 'count' has no counter macro}\skv@ehd
\else
\skvifntypeTF{#1}{%
\skv@tempa#1all satisfying\skv@nil
}{%
\skv@err{Value of key 'count in': more than 1
\MessageBreak token '\detokenize{#1}'.
- \MessageBreak I can't find counter macro}\@ehd
+ \MessageBreak I can't find counter macro}\skv@ehd
}%
\fi
}%
@@ -1308,7 +1311,7 @@
\skv@tempxifin{(}{#1}{%
\skv@err{Value of key 'remember': '(' found.
\MessageBreak I don't accept this PGF format.
- \MessageBreak remove the parenthesis '()'}\@ehd
+ \MessageBreak Remove the parenthesis '(<your input>)'}\skv@ehd
}{}%
\def\skv@tempa##1as##2initially##3\skv@nil{%
\edef\skv@prova{\skvtrimspace{##1}}%
@@ -1317,22 +1320,22 @@
\skv@foreach@swafalse
\ifx\skv@prova\@empty
\skv@err{Value of key 'remember' has no holder macro:
- \MessageBreak i.e., no macro that holds input}\@ehd
+ \MessageBreak i.e., no macro that holds input}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@prova}{}{%
\skv@err{Value of key 'remember':
- \MessageBreak Holder macro \skvoxdetok\skv@prova not escaped}\@ehd
+ \MessageBreak Holder macro \skvoxdetok\skv@prova not escaped}\skv@ehd
}%
\fi
\ifx\skv@provb\@empty
\skv@err{Value of key 'remember' has no child macro;
- \MessageBreak i.e., no macro after 'as'}\@ehd
+ \MessageBreak i.e., no macro after 'as'}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@provb}{%
\skv@foreach@swatrue
}{%
\skv@err{Value of key 'remember':
- \MessageBreak Child \skvoxdetok\skv@provb not escaped}\@ehd
+ \MessageBreak Child \skvoxdetok\skv@provb not escaped}\skv@ehd
}%
\fi
}%
@@ -1341,7 +1344,7 @@
\skv@tempa#1\skv@nil
}{%
\skv@err{Value of key 'remember':
- \MessageBreak There is 'initially', but no 'as'}\@ehd
+ \MessageBreak There is 'initially', but no 'as'}\skv@ehd
}%
}{%
\skv@tempxifin{as}{#1}{%
@@ -1350,6 +1353,7 @@
% No 'as' and 'initially':
\edef\skv@prova{\skvtrimspace{#1}}%
\ifx\skv@prova\@empty\else
+ % Go and raise error in \skv@tempa:
\skv@tempa#1as initially\skv@nil
\fi
}%
@@ -1391,7 +1395,7 @@
\skv@tempxifin{(}{#1}{%
\skv@err{Value of key 'recall': '(' found.
\MessageBreak I don't accept this PGF format.
- \MessageBreak remove the parenthesis '()'}\@ehd
+ \MessageBreak remove the parenthesis '()'}\skv@ehd
}{}%
\skv@foreach@swafalse
\def\skv@tempa##1initially##2\skv@nil{%
@@ -1399,7 +1403,7 @@
\edef\skv@provb{\skvtrimspace{##2}}%
\ifx\skv@prova\@empty
\skv@err{Value of key 'recall' has no holder macro:
- \MessageBreak i.e., no macro that holds input}\@ehd
+ \MessageBreak i.e., no macro that holds input}\skv@ehd
\else
\expandafter\skvifntypeTF\expandafter{\skv@prova}{%
\expandafter\skvifescapedTF\expandafter{\skv@prova}{%
@@ -1420,11 +1424,11 @@
}%
}{%
\skv@err{Value of key 'recall':
- \MessageBreak \detokenize{#1} is not escaped}\@ehd
+ \MessageBreak \detokenize{#1} is not escaped}\skv@ehd
}%
}{%
\skv@err{Value of key 'recall':
- \MessageBreak \detokenize{#1} is not one token}\@ehd
+ \MessageBreak \detokenize{#1} is not one token}\skv@ehd
}%
\fi
}%
@@ -1432,7 +1436,7 @@
\skv@err{Value of key 'recall': invalid 'as' found.
\MessageBreak This key doesn't expect 'as' since
\MessageBreak it automatically builds a retainer macro
- \MessageBreak of the form \<foreachlast><holder.name>}\@ehd
+ \MessageBreak of the form \<foreachlast><holder.name>}\skv@ehd
}{%
\skv@tempxifin{initially}{#1}{%
\skv@tempa#1\skv@nil
@@ -1486,60 +1490,48 @@
\endgroup
}%
\skvletmanytocmd{%
- \prependtobeginforeach\appendtobeginforeach\atbeginforeach
- \prependtoendforeach\appendtoendforeach\atendforeach
+ \prependtobeginforeach,\appendtobeginforeach,\atbeginforeach,
+ \prependtoendforeach,\appendtoendforeach,\atendforeach
}\skv@foreach@latehook
}
\skvrobustdef*\skv@foreach@pushstate{%
\skvsavestate\skv@foreach@stack{%
- \do\skv@foreach@seenstar
- \do\skv@foreach@parser\do\skv@foreach@subparser
- \do\skv@foreach@listisamacro
+ \do\skv@foreach@seenstar\do\skv@foreach@parser
+ \do\skv@foreach@subparser\do\skv@foreach@listisamacro
\do\skv@foreach@processupto\do\skv@foreach@processempty
- \do\skv@foreach@exittester
- \do\skv@foreach@grow\do\skv@foreach@growleft
- \do\skv@foreach@growright
+ \do\skv@foreach@exittester\do\skv@foreach@continuetester
+ \do\skv@foreach@grow\do\skv@foreach@growleft\do\skv@foreach@growright
\do\skv@foreach@terminator\do\skv@foreach@recoverholders
- \do\skv@foreach@callback
- \do\skv@foreach@auxcallback
- \do\skv@foreach@precallback
- \do\skv@foreach@afterprecallback
- \do\skv@foreach@postcallback
+ \do\skv@foreach@normalizelist\do\skv@foreach@callback
+ \do\skv@foreach@auxcallback\do\skv@foreach@precallback
+ \do\skv@foreach@afterprecallback\do\skv@foreach@postcallback
\do\skv@foreach@onlyinitially
\do\foreachlistremainder\do\skv@foreach@mainloop
- \do\skv@foreach@getnext\do\skv@foreach@getrm
+ \do\skv@foreach@getnext\do\skv@foreach@picknext\do\skv@foreach@getrm
\do\skv@foreach@do@a\do\skv@foreach@do@b
- \do\skv@foreach@paramlist
- \do\skv@foreach@holderlist
- \do\skv@foreach@userlist
- \do\skv@foreach@inherit
- \do\skv@foreach@keepdecimals
- \do\skv@foreach@keephighdecimals
- \do\skv@foreach@itemcounter
- \do\skv@foreach@link
+ % Macros '...lookahead...' need stacking in \foreachfox and when
+ % \newforeach is nested with \foreachfox:
+ \do\skv@foreach@lookahead@a\do\skv@foreach@lookahead@b
+ \do\skv@foreach@lookahead@c\do\skv@foreach@lookahead@d
+ \do\skv@foreach@paramlist\do\skv@foreach@holderlist
+ \do\skv@foreach@userlist\do\skv@foreach@inherit
+ \do\skv@foreach@keepdecimals\do\skv@foreach@keephighdecimals
+ \do\skv@foreach@itemcounter\do\skv@foreach@link
\do\skv@foreach@expandlistbeforefill\do\skv@foreach@expandlistonce
\do\skv@foreach@expandlisttwice\do\skv@foreach@expandlistfully
\do\skv@listbreakertoks\do\skv@listpausertoks
- \do\skv@foreach@reverselist
- \do\foreachcurrentitem
- \do\foreachnextitem
- \do\foreachitemcount
- \do\foreachprevitem
+ \do\skv@foreach@reverselist\do\foreachcurrentitem
+ \do\foreachnextitem\do\foreachitemcount\do\foreachprevitem
% The following commands are disabled on entry into the loop.
% Hence they need to be stacked here:
- \do\prependtobeginforeach
- \do\appendtobeginforeach
- \do\atbeginforeach
- \do\prependtoendforeach
- \do\appendtoendforeach
- \do\atendforeach
- }\foreachdepth
+ \do\prependtobeginforeach\do\appendtobeginforeach\do\atbeginforeach
+ \do\prependtoendforeach\do\appendtoendforeach\do\atendforeach
+ }\foreachnestdepth
}
\skvrobustdef*\skv@foreach@popstate{%
- \skvrestorestate\skv@foreach@stack\foreachdepth
+ \skvrestorestate\skv@foreach@stack\foreachnestdepth
}
-\skvnewdef*\foreachnestdepth{\foreachdepth}
\skvnewlet\skv@foreach@nil\relax
\skvnewdef*\skv@foreach@nnil{\skv@foreach@nil}
\skvrobustdef*\newforeach{\skv@testst\skv@newforeach@beginprescan}
@@ -1560,11 +1552,11 @@
}{%
\skvifnextchar i{%
\endgroup
- \skv@err{\string\newforeach: no holder macro seen}\@ehd
+ \skv@err{\string\newforeach: no holder macro seen}\skv@ehd
}{%
\skvifnextchar\skv@orig@bgroup{%
\endgroup
- \skv@err{\string\newforeach: no holder macro seen}\@ehd
+ \skv@err{\string\newforeach: no holder macro seen}\skv@ehd
}{%
\skv@foreach@collectholders
}%
@@ -1591,7 +1583,7 @@
}
\skvrobustdef*\skv@foreach@endprescan#1[#2]{%
\skvifblankTF{#1}{%
- \skv@err{\string\newforeach: no holder macros seen}\@ehd
+ \skv@err{\string\newforeach: no holder macros seen}\skv@ehd
}{%
\skv@foreach@scanarg[#2]#1%
}%
@@ -1602,18 +1594,17 @@
\skv@foreach@latehookerr
% \foreachitemcount must be a macro, not a counter, because it is stacked:
\def\foreachitemcount{0}%
- % Don't confuse item counters of various depths:
- \skvundef\skv@foreach@itemcounter
- \skvundef\skv@foreach@processupto
- \def\skv@foreach@callback{}%
- \def\skv@foreach@auxcallback{}%
- \def\skv@foreach@precallback{}%
- \def\skv@foreach@afterprecallback{}%
- \def\skv@foreach@postcallback{}%
- \def\skv@foreach@onlyinitially{}%
+ % Don't confuse macros of various depths; reset them here:
+ \def\do##1{\def##1{}}%
+ \do\skv@foreach@itemcounter\do\skv@foreach@processupto
+ \do\skv@foreach@callback\do\skv@foreach@auxcallback
+ \do\skv@foreach@precallback\do\skv@foreach@afterprecallback
+ \do\skv@foreach@postcallback\do\skv@foreach@onlyinitially
% The keys have to be set here, to determine if the list is a macro, etc.
% Since \skv@foreach@precallback are initialized in each nest, the
- % keys have to be reset here.
+ % keys have to be reset here. Reset all keys: they might have been
+ % fixed by the outer loop and the inner loop might assume the default
+ % values of the keys are those being used.
\skv@foreach@setkeys{#1}%
% We've set the keys; let's overrule \skv@foreach@expandlistonce if
% we had seen a star suffix. Don't overrule \skv@foreach@expandlisttwice
@@ -1622,9 +1613,10 @@
\def\skv@foreach@expandlistonce{00}%
\fi
\ifcase0%
- \if\skv@foreach@expandlistonce0\else
- \if\skv@foreach@expandlisttwice0\else
- \if\skv@foreach@expandlistfully0\else 1\fi\fi\fi\relax
+ % Take only one case:
+ \if\skv@foreach@expandlistonce\else
+ \if\skv@foreach@expandlisttwice\else
+ \if\skv@foreach@expandlistfully\else 1\fi\fi\fi\relax
\def\skv@foreach@listisamacro{00}%
\else
\def\skv@foreach@listisamacro{01}%
@@ -1647,7 +1639,7 @@
\skvifescapedTF{#1}{%
\skv@err{Token '\noexpand#1' cannot be a subparser;
\MessageBreak it seems to be a holder macro. I expected
- \MessageBreak the subparser to be the token here.}\@ehd
+ \MessageBreak the subparser to be the token here.}\skv@ehd
}{%
\edef\skv@prova{\skvtrimspace{#1}}%
\let\elt\skvexpandonce
@@ -1662,6 +1654,7 @@
\MessageBreak I have used '\elt\skv@prova', but please submit
\MessageBreak '\elt\skv@prova' as the value of the key
'subparser'
+ \MessageBreak so that I can stop giving this warning.
}%
\fi
\let\skv@foreach@subparser\skv@prova
@@ -1671,7 +1664,7 @@
\else
\skvifescapedTF{#1}{}{%
\skv@err{Token '\noexpand#1' is not escaped
- \MessageBreak and can't be a holder macro}\@ehd
+ \MessageBreak and can't be a holder macro}\skv@ehd
}%
\fi
\advance\skv@cnta\@ne
@@ -1687,13 +1680,13 @@
\skvifstrcmpTF{#1#2}{in}{%
\skv@foreach@scanarg@d
}{%
- \skv@err{I have seen 'i' but no expected 'in'}\@ehd
+ \skv@err{I have seen 'i' but no expected 'in'}\skv@ehd
}%
}
\skvrobustdef*\skv@foreach@scanarg@d{%
\ifx\skv@foreach@holderlist\@empty
\skv@err{No item holder macros before 'in'
- \MessageBreak or before left brace}\@ehd
+ \MessageBreak or before left brace}\skv@ehd
\fi
\skvifnextchar\skv@orig@bgroup{%
\skv@foreach@scanarg@e
@@ -1707,7 +1700,7 @@
\noexpand\newforeach or key 'expand list once', etc.,
\MessageBreak is missing.}%
}{%
- \let\skv@tempehd\@ehd
+ \let\skv@tempehd\skv@ehd
}%
\skv@err{I expected a left brace for beginning of list,
\MessageBreak since you haven't told me that your
@@ -1734,7 +1727,7 @@
\skvifnextchar\skv@orig@bgroup
\skv@foreach@scanarg@h\skv@foreach@scanarg@g
}{%
- \skv@err{I have seen 'd' but no the expected 'do'}\@ehd
+ \skv@err{I have seen 'd' but no the expected 'do'}\skv@ehd
}%
}
% We've exhausted all options for grabbing the callback, so now
@@ -1775,7 +1768,7 @@
\skv@prova
}%
% In case callback terminator is currently active, rescan it.
- \skv@rescan\skv@foreach@terminator
+ \skvrescan\skv@foreach@terminator
\expandafter\skv@prova\expandafter{\skv@foreach@terminator}%
}
% #1: callback
@@ -1812,16 +1805,19 @@
{#2}%
}%
% Initial code, if any:
- \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachdepth}%
+ \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachnestdepth}%
\skvifdefTF\foreachprevitem{}{\def\foreachprevitem{}}%
- \expandafter\skv@foreach@normalize\expandafter
- [\skv@foreach@parser]\skv@foreach@userlist
- \expandafter\skv@foreach@normalize\expandafter
- [\skv@foreach@subparser]\skv@foreach@userlist
+ \expandafter\skv@foreach@normalize\expandafter[\skv@foreach@parser]%
+ \skv@foreach@userlist
+ \expandafter\skv@foreach@normalize\expandafter[\skv@foreach@subparser]%
+ \skv@foreach@userlist
+ \ifnum\foreachnestdepth=\skvz@
+ \breakallforeachloopsfalse
+ \fi
\skvbreakloopfalse
\foreachlastitemfalse
\def\skv@foreach@lookahead@a##1{%
- \def\skv@foreach@continue{##1.}%
+ \def\skv@foreach@picknext{##1.}%
\futurelet\skv@foreach@next\skv@foreach@lookahead@b
}%
\def\skv@foreach@lookahead@b{%
@@ -1831,12 +1827,12 @@
\ifx\skv@foreach@next(%
\expandafter\expandafter\expandafter\skv@foreach@lookahead@d
\else
- \expandafter\expandafter\expandafter\skv@foreach@continue
+ \expandafter\expandafter\expandafter\skv@foreach@picknext
\fi
\fi
}%
- \def\skv@foreach@lookahead@c[##1]{\skv@foreach@continue[{##1}]}%
- \def\skv@foreach@lookahead@d(##1){\skv@foreach@continue({##1})}%
+ \def\skv@foreach@lookahead@c[##1]{\skv@foreach@picknext[{##1}]}%
+ \def\skv@foreach@lookahead@d(##1){\skv@foreach@picknext({##1})}%
\def\skv@foreach@mainloop##1{%
\def\skv@foreach@getnext####1##1####2\skv@foreach@stop{%
\edef\foreachnextitem{\skvexpandonce{\@gobble####1}}%
@@ -1874,21 +1870,17 @@
}%
\def\skv@foreach@do@b####1{%
\edef\foreachitemcount{\the\numexpr\foreachitemcount+1}%
- \ifcase0%
- \ifx\skv@foreach@itemcounter\@undefined 1\fi
- \ifx\skv@foreach@itemcounter\@empty 1\fi
- \ifx\skv@foreach@itemcounter\@nnil 1\fi\relax
+ \ifx\skv@foreach@itemcounter\@empty\else
\expandafter\let\skv@foreach@itemcounter\foreachitemcount
\fi
\skv@foreach@lookahead@a\skv@foreach@getnext####1\skv@foreach@stop
- % In case the user decides to continue after \listpauser:
+ % If the user decides to continue after \foreachlistpauser is picked up,
+ % don't use \foreachlistpauser as an item:
\skvifxTF\foreachcurrentitem\skv@listpausertoks{}{%
- \expandafter\skv@foreach@callback\expandafter{\foreachcurrentitem}%
+ \skvexpbracenext\skv@foreach@callback\foreachcurrentitem
+ \let\foreachprevitem\foreachcurrentitem
}%
- \let\foreachprevitem\foreachcurrentitem
- \ifcase0%
- \ifx\skv@foreach@processupto\@undefined 1\fi
- \ifx\skv@foreach@processupto\@nnil 1\fi\relax
+ \ifx\skv@foreach@processupto\@empty\else
\ifnum\foreachitemcount<\skv@foreach@processupto\relax\else
\skvbreakloop
\fi
@@ -1900,7 +1892,9 @@
}%
}%
\def\skv@foreach@getrm####1{%
- \skvbreakloopfalse
+ \ifbreakallforeachloops\else
+ \skvbreakloopfalse
+ \fi
\foreachlastitemfalse
\def\skv@prova########1\skv@foreach@nil##1{%
\edef\foreachlistremainder{\unexpanded{########1}}%
@@ -1909,7 +1903,9 @@
\skv@prova####1%
}%
\skvifxTF\skv@foreach@userlist\@empty{%
- \if\skv@foreach@processempty\skv@foreach@callback{}\fi
+ \if\skv@foreach@processempty\skvafterfi
+ \skv@foreach@callback{}%
+ \fi
}{%
\expandafter\skv@foreach@filllist\expandafter
{\skv@foreach@parser}\skv@foreach@userlist
@@ -1924,16 +1920,16 @@
\skv@foreach@makeprecode{#1}%
\if\skv@foreach@recoverholders\else
\expandafter\skvsavestate\expandafter\skv@foreach@holderstate
- \expandafter{\skv@foreach@holderlist}\skv@foreach@sisterdepth
+ \expandafter{\skv@foreach@holderlist}\skv@foreach@holderdepth
\fi
\skv@foreach@makeauxcallback{#3}%
\skvexpandbracenext\skv@foreach@mainloop\skv@foreach@parser
- \skvcsuse{skv@foreach@atendhook@\skvrom\foreachdepth}%
+ \skvcsuse{skv@foreach@atendhook@\skvrom\foreachnestdepth}%
\if\skv@foreach@recoverholders\else
- \skvrestorestate\skv@foreach@holderstate\skv@foreach@sisterdepth
+ \skvrestorestate\skv@foreach@holderstate\skv@foreach@holderdepth
\fi
\skv@foreach@popstate
- \ifnum\foreachdepth=\skvz@
+ \ifnum\foreachnestdepth=\skvz@
\def\skv@warnsubparser{0}%
\fi
}
@@ -1957,7 +1953,7 @@
\ifx\skv@prova\skv@foreach@subparser
\ifnum\skv@cnta=\skvz@
\skv@err{Subparser '\skvoxdetok\skv@foreach@subparser' can't come
- first in the list\MessageBreak of holder macros}\@ehd
+ first in the list\MessageBreak of holder macros}\skv@ehd
\else
% Eg, if subparser is slash (/), \skv@foreach@paramlist will have
% the syntax: ##1/##2/...:
@@ -2010,6 +2006,20 @@
\skvcmdexit\skv@foreach@precallback
}%
}
+% Example (*):
+%
+% This example demonstrates why \skv@foreach@continuetester must be
+% located delicately, at where it is currently.
+%
+% \def\ditem{D}
+% \newforeach [
+% continue=\ifx\x\ditem\fi,remember=\x as \rx initially A
+% ] \x in {
+% B,(C1),D,E,[F1],G,H
+% }{%
+% $\overrightarrow{\rx\x}$\ifforeachlastitem.\else,\space\fi
+% }
+%
% #1: callback
\skvrobustdef*\skv@foreach@makeauxcallback#1{%
\begingroup
@@ -2022,25 +2032,37 @@
% Add extra subparsers in case some items aren't subparser-complete:
\edef\skv@tempa{\skv@generatesubparser{1}}%
\let\foreacheov\relax
- \let\\\noexpand
+ \let\do\noexpand
\skvexpanded{\endgroup
% Define auxiliary callback:
- \def\\\skv@foreach@auxcallback\skv@foreach@paramlist\foreacheov{%
+ \def\do\skv@foreach@auxcallback\skv@foreach@paramlist\foreacheov{%
% Holder macro assignments:
\skvexpandonce\skv@foreach@precallback
% User tests/tasks, eg, if requested from 'evaluate' key:
\skvexpandonce\skv@foreach@afterprecallback
- \\\ifnum\\\foreachitemcount=\@ne
- \\\skv@foreach@onlyinitially
- \\\fi
- \unexpanded{#1}%
- % User tests/tasks, eg, if requested from the keys 'remember',
- % 'exit when', etc:
- \skvexpandonce\skv@foreach@postcallback
+ \do\ifnum\do\foreachitemcount=\@ne
+ \do\skv@foreach@onlyinitially
+ \do\fi
+ \ifx\skv@foreach@continuetester\@secondoftwo
+ \noexpand\skv@foreach@continuetester
+ \else
+ % Expose the parameter characters in \skv@foreach@continuetester:
+ \skvexpandonce\skv@foreach@continuetester
+ \fi
+ {%
+ \relax
+ }{%
+ % If the user wants to ignore the callback for some items, he can
+ % use the key 'continue=<condition>':
+ \unexpanded{#1}%
+ % User tests/tasks, eg, if requested from the keys 'remember',
+ % 'exit when', etc:
+ \skvexpandonce\skv@foreach@postcallback
+ }%
}%
% Define the real callback:
- \def\\\skv@foreach@callback####1{%
- \\\skv@foreach@auxcallback####1\skvxonce\skv@tempa\foreacheov
+ \def\do\skv@foreach@callback####1{%
+ \do\skv@foreach@auxcallback####1\skvxonce\skv@tempa\foreacheov
}%
}%
}
@@ -2132,7 +2154,7 @@
\skvifdefTF\skv@foreach@link{%
\skvifxFT\skv@foreach@link\@nnil
}{%
- \skv@err{List auto-completion: 'link' is undefined}\@ehd
+ \skv@err{List auto-completion: 'link' is undefined}\skv@ehd
}%
}%
\skvexpanded{%
@@ -2158,8 +2180,7 @@
\skv@foreach@normalize[#1]\skv@foreach@filledlist
}{%
\edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist
- \skvtrimspace{##1}%
+ \skvaddlist{#1}\skv@foreach@filledlist\skvtrimspace{##1}%
}%
}%
}%
@@ -2168,10 +2189,10 @@
% \skv@foreach@filllist@b{<parser>}{<list>}
\skvrobustdef*\skv@foreach@filllist@b#1#2{%
\skvxiffound{\relax...}\in{\relax\detokenize{#2}}\then
- \skv@err{I can't find lower limit before '...'}\@ehd
+ \skv@err{I can't find lower limit before '...'}\skv@ehd
\else
\skvxiffound{\relax\detokenize{#1}...}\in{\relax\detokenize{#2}}\then
- \skv@err{I can't find lower limit before '...'}\@ehd
+ \skv@err{I can't find lower limit before '...'}\skv@ehd
\fi
\fi
% \newforeach format is '<parser>...<parser>':
@@ -2180,7 +2201,7 @@
\def\skv@prova##1#1##2#1...#1##3#1##4#1##5\skv@nil{%
\skvifblankTF{##3}{%
\skv@err{I can't find upper limit number or dimension,
- \MessageBreak i.e., after symbool '...'}\@ehd
+ \MessageBreak i.e., after symbool '...'}\skv@ehd
}{%
% \skv@foreach@filllist@a may be reentered. Hence accumulate
% filled list:
@@ -2198,7 +2219,7 @@
\expandafter\skv@prova\skv@tempa#1#1\skv@nil
}{%
% Not \newforeach format: try PGF's \foreach format:
- \skv@foreach@trypgfformat{#1}{#2}%
+ \skv@foreach@trypgflikeformat{#1}{#2}%
}%
}
@@ -2247,7 +2268,7 @@
\MessageBreak or both directions are 'true'.}
{Try one of the keys 'grow=left or right',
\MessageBreak 'grow left=true or false',
- 'grow right=true or false'}\@ehd
+ 'grow right=true or false'}\skv@ehd
\fi
\begingroup
\def\skv@prova##1{%
@@ -2260,7 +2281,7 @@
\ifskv@foreach@swa\else
\edef\skv@provb{\ifx\@nnil#2\@nnil\else\unexpanded{#2}, \fi}%
\skv@err{No link '##1' in one of
- '\detokenize\expandafter{\skv@provb#3, #4}'}\@ehd
+ '\detokenize\expandafter{\skv@provb#3, #4}'}\skv@ehd
\fi
\def\skv@prova####1##1####2\skv@nil{%
\if\skv@foreach@growright
@@ -2269,9 +2290,9 @@
\edef\skv@prova{\skvtrimspace{##1####2}}%
\fi
\def\do########1{{\skvtrimspace{########1}}}%
- % \skv@foreach@trypgfformat@a<parser><guide><lower1><lower2><upper>
+ % \skv@foreach@trypgflikeformat@a<parser><guide><lower1><lower2><upper>
\skvexpanded{\endgroup
- \noexpand\skv@foreach@trypgfformat@a
+ \noexpand\skv@foreach@trypgflikeformat@a
{\unexpanded{#1}}{\skvexpandonce\skv@prova}\do{#2}\do{#3}\do{#4}%
}%
}%
@@ -2291,7 +2312,7 @@
% {A_1,B_1,..._1,E_1} : <guide> = _1
% {1--,4--,...--,16--} : <guide> = --
% {1pt,4pt,...pt,10pt} : <guide> = pt
-% {A_2pt,A_4pt,A_...pt,A_10pt} : <guide> = A_, pt
+% {A_2pt,A_4pt,A_...pt,A_10pt} : <guide> = A_ and pt
%
% skeyval formats:
% {a^1,a^3,a^...,a^9} : no additional info. required
@@ -2308,14 +2329,14 @@
%
% The items prior to the last 2 items before '<guide>...' or before '...'
% are called 'before-the-last-2' (BL2). Collect in \skv@tempa BL2 items,
-% together with the rest of the list. Save in \skv@foreach@filledlist
-% the BL2 items.
+% together with the rest of the list. Save the BL2 items in
+% \skv@foreach@filledlist.
%
% Return \skv@foreach@filledlist and \skv@tempa.
%
\skvrobustdef*\skv@foreach@splitonguide#1#2{%
% First count all the elements before '<guide>,...'. We're already
- % sure that #2 contains '<guide>,...' or '...':
+ % sure that #2 contains '<guide><parser>...' or '...':
\begingroup
\skv@cnta\skvz@
\def\do##1#1{%
@@ -2350,7 +2371,7 @@
\else
\ifnum\skv@cnta=\skvz@
\skv@err{List <<\detokenize{#2}>>\MessageBreak
- contains symbol '...' but not a lowerbound}\@ehd
+ contains symbol '...' but not a lowerbound}\skv@ehd
\fi
\fi
\fi
@@ -2360,16 +2381,21 @@
}%
}
-% \skv@foreach@trypgfformat{<parser>}{<list>}
+% \skv@foreach@trypgflikeformat{<parser>}{<list>}
+%
+% When we say 'try PGF-like format', we don't actually mean the
+% PGF format with left and right guides, as in,
+%
+% {A_2pt,A_4pt,A_...pt,A_10pt} : <guide> = 'A_(left)' and 'pt(right)' (*)
%
-% When we say, 'try PGF format', we don't actually mean the PGF format with
-% left and right guides, but the syntax '<guide>...' (ie, having only the
-% left-hand-side or only the right-hand-side guide). For example,
+% but the syntax '<guide>...' (ie, having only the left-hand-side or only
+% the right-hand-side guide). For example,
%
% {A_2pt,A_4pt,A_...,A_10pt} or {1pt,4pt,...pt,10pt}
%
-% \skv@foreach@trypgfformat will auto-complete this list without
-% knowledge of the values of the keys 'link' and 'grow'.
+% \skv@foreach@trypgflikeformat will auto-complete this list without
+% knowledge of the values of the keys 'link' and 'grow'. The syntax at (*)
+% above isn't recognized by the auto-completion scheme of skeyval.
%
% skeyval formats:
%
@@ -2382,15 +2408,15 @@
%
% {A_2pt,A_4pt,A_...pt,A_10pt}
%
-% is illegal here, because the skeyval-for package uses the location
+% is illegal here, because the file skeyval-for.tex uses the location
% of the guide (left or right of ...) to determine the direction of growth.
%
-\skvrobustdef*\skv@foreach@trypgfformat#1#2{%
+\skvrobustdef*\skv@foreach@trypgflikeformat#1#2{%
\skv@foreach@splitonguide{#1}{#2}%
\def\skv@prova##1#1##2#1##3...##4#1##5#1##6#1##7\skv@nil{%
\skvifblankTF{##5}{%
\skv@err{I can't find upper limit number or dimension,
- \MessageBreak i.e., after symbool '...'}\@ehd
+ \MessageBreak i.e., after symbool '...'}\skv@ehd
}{%
% \skv@foreach@filllist@a may be reentered. Hence
\skviflacus{##1}\then\else
@@ -2403,12 +2429,12 @@
\skvifblankTF{##3}{%
\skvifblankTF{##4}{%
\skv@err{No direction of growth before and/or after
- \MessageBreak symbol '...'}\@ehd
+ \MessageBreak symbol '...'}\skv@ehd
}{%
\def\skv@foreach@growleft{00}%
\def\skv@foreach@growright{01}%
\skvexpanded{%
- \skv@foreach@trypgfformat@a
+ \skv@foreach@trypgflikeformat@a
{\unexpanded{#1}}\do{##4}\do{##1}\do{##2}\do{##5}%
}%
}%
@@ -2417,17 +2443,17 @@
\def\skv@foreach@growright{00}%
\def\skv@foreach@growleft{01}%
\skvexpanded{%
- \skv@foreach@trypgfformat@a
+ \skv@foreach@trypgflikeformat@a
{\unexpanded{#1}}\do{##3}\do{##1}\do{##2}\do{##5}%
}%
}{%
- \skv@err{Having both '\detokenize{##3 and ##4}' in an
+ \skv@err{Having both '\detokenize{'##3' and '##4'} in an
\MessageBreak ellipsis list is illegal in
- \MessageBreak\noexpand\newforeach and \noexpand\newforeach.
+ \MessageBreak\noexpand\newforeach and \noexpand\foreachfox.
\MessageBreak I know that PGF's \noexpand\foreach needs it,
\MessageBreak but I don't need it. I can
\MessageBreak auto-fill your list with information
- \MessageBreak on only one side.}\@ehd
+ \MessageBreak on only one side of <<...>>.}\skv@ehd
}%
}%
% In case the list is folded on ellipsis (...):
@@ -2437,7 +2463,8 @@
\expandafter\skv@prova\skv@tempa#1#1#1\skv@nil
}
%
-% \skv@foreach@trypgfformat@a{<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
+% \skv@foreach@trypgflikeformat@a
+% {<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
%
% 1. Use the <guide> to get the contant and variable parts of the
% elements.
@@ -2448,7 +2475,7 @@
% 4. Call the relevant macro to fill the list.
% 5. <lower1> has already been saved in \skv@foreach@filledlist.
%
-\skvrobustdef*\skv@foreach@trypgfformat@a#1#2#3#4#5{%
+\skvrobustdef*\skv@foreach@trypgflikeformat@a#1#2#3#4#5{%
\skv@foreach@swafalse
\skviflacus#3\then\else
\skvxifinTF{#2}{#3}{}\skv@foreach@swatrue
@@ -2459,7 +2486,7 @@
\skv@err{Guide token '\detokenize{#2}' not found in some
\MessageBreak of the elements: I can't complete
\MessageBreak the current list. This may be
- \MessageBreak due to wrong direction of growth}\@ehd
+ \MessageBreak due to wrong direction of growth}\skv@ehd
\fi
% Get from the left or right of 'link' (#2) the components that should be
% grown, without the link:
@@ -2516,7 +2543,7 @@
\skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
\else
\skv@err{The tokens '\detokenize\expandafter{\skv@lowerlower#4, #5}'
- \MessageBreak aren't of the same type}\@ehd
+ \MessageBreak aren't of the same type}\skv@ehd
\fi
}{%
\skv@foreach@ifupperalpha{#4}{%
@@ -2541,7 +2568,7 @@
\skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
\else
\skv@err{The tokens '\detokenize\expandafter{\skv@lowerlower#4, #5}'
- \MessageBreak aren't of the same type}\@ehd
+ \MessageBreak aren't of the same type}\skv@ehd
\fi
}{%
\skv@foreach@swatrue
@@ -2552,7 +2579,7 @@
\let\skv@foreach@origunit\skv@dimunit
\skvifdimensionable{#5}{}\skv@foreach@swafalse
\ifx\skv@foreach@origunit\skv@dimunit\else
- \skv@err{The units on \detokenize{'#4', '#5'} are different}\@ehd
+ \skv@err{The units on \detokenize{'#4', '#5'} are different}\skv@ehd
\fi
\ifskv@foreach@swa
\ifx\@nnil#3\@nnil
@@ -2571,7 +2598,7 @@
}\skv@templist
\skv@foreach@strippoint{#1}\skv@templist
% Attach the constant part to the elements of the completed list.
- % <lower1> was saved earlier in \skv@foreach@trypgfformat, and
+ % <lower1> was saved earlier in \skv@foreach@trypgflikeformat, and
% <lower2> and <upper> have been saved while filling the list.
% Always strip point and restore original unit here.
\skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
@@ -2605,7 +2632,7 @@
'\detokenize\expandafter{\skv@lowerlower#4, #5}'
\MessageBreak are unparsable. I have given up on them.
\MessageBreak Did you miss something syntactic?
- \MessageBreak See manual for acceptable syntaxes}\@ehd
+ \MessageBreak See manual for acceptable syntaxes}\skv@ehd
\fi
\fi
}%
@@ -2666,13 +2693,13 @@
\ifdim#3\skv@foreach@unit>#2\skv@foreach@unit\relax
\skv@err{Step '\skv@foreach@step' is negative but upperbound
\MessageBreak '\detokenize{#3}' is greater than lowerbound
- '\detokenize{#2}'}\@ehd
+ '\detokenize{#2}'}\skv@ehd
\fi
\else
\ifdim#3\skv@foreach@unit<#2\skv@foreach@unit\relax
\skv@err{Step '\skv@foreach@step' is nonnegative but upperbound
\MessageBreak '\detokenize{#3}' is less than lowerbound
- '\detokenize{#2}'}\@ehd
+ '\detokenize{#2}'}\skv@ehd
\fi
\fi
% The bounds may have decimal places. So the calculation has to be
@@ -2711,7 +2738,7 @@
\edef\reserved@a{\if-\skv@foreach@step\else\skv@foreach@step\fi}%
\skvoifinteger\reserved@a{}{%
\skv@err{List is '\skv@type' type but\MessageBreak
- step '\skv@foreach@step' isn't an integer}\@ehd
+ step '\skv@foreach@step' isn't an integer}\skv@ehd
}%
\skv@foreach@addtolist{#1}{#2}#4%
\skvifstrcmpTF{#2}{#3}{}{%