summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/loops
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-02-12 23:53:37 +0000
committerKarl Berry <karl@freefriends.org>2013-02-12 23:53:37 +0000
commitb00ddd78e03236a73df3113f75cb0c607654d5a6 (patch)
treeabe63d734ede6c61983c4e8ebb8175859651b1ad /Master/texmf-dist/tex/latex/loops
parentdcf4eb75b6ae8a7d1ebab1fc40af55709bfd8139 (diff)
loops (12feb13)
git-svn-id: svn://tug.org/texlive/trunk@29090 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/loops')
-rw-r--r--Master/texmf-dist/tex/latex/loops/loops.sty678
1 files changed, 367 insertions, 311 deletions
diff --git a/Master/texmf-dist/tex/latex/loops/loops.sty b/Master/texmf-dist/tex/latex/loops/loops.sty
index 351205fdd4e..bd11a44a18f 100644
--- a/Master/texmf-dist/tex/latex/loops/loops.sty
+++ b/Master/texmf-dist/tex/latex/loops/loops.sty
@@ -1,5 +1,5 @@
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
-% This is file 'loops.sty', version 1.1, 2012/10/16. %
+% This is file 'loops.sty', 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, %
@@ -15,7 +15,7 @@
% implied warranties of merchantability and fitness for a particular %
% purpose. %
% %
-% Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). %
+% Copyright (c) 2012-2013 Ahmed Musa (amusa22@gmail.com). %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\begingroup
@@ -53,7 +53,7 @@
\do 032=10,033=12,036=03,038=04,040=12,041=12,042=12,043=12,%
059=12,045=12,047=12,058=12,063=12,091=12,093=12,126=13,\do=,%
-\ProvidesPackage{loops}[2012/10/16 v1.1 Loops and list processors (AM)]
+\ProvidesPackage{loops}[2013/02/10 v1.2 Loops and list processors (AM)]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
% This is the way to load 'skeyval-for-core' here, otherwise we
@@ -66,45 +66,81 @@
\directkeys*{
.every unknown option={
- \PackageWarning{loops}{Unknown option '\CurrentOption' ignored}%
+ \@onelevel@sanitize\CurrentOption
+ \PackageWarning{loops}{Unknown option '\CurrentOption' ignored}
},
- .prefix=SKV,
- .family=loops,
+ .path=SKV/loops,
.holder prefix=lps@,
.initialize keys after define,
.new options={
.bool/verbose/true/\iflps@verbose\skv@verbosetrue\fi,
},
- .copy class options and process options,
+ .copy class options and process options
}
-% \skvusetwoprev{<parser>}{<list>}{<target.item>}{<do.on.target>}
-%
-% Example:
-%
-% \skvusetwoprev{,}{a,b,c,d,e,f}{e}{}
-%
-\skvrobustdef*\skvusetwoprev#1#2#3#4{%
- \skvifinTF{#1#3#1}{#1#2#1}{}{%
- \skv@err{There is not '\detokenize{#3}' in the list}\@ehd
+% \lpsdocsvlist{<parser>}{<list>}{<callback>}
+%
+% Execute <callback> on each item of <list>. The user has access to
+% \firstprevitem, \secondprevitem, \currentitem, \firstnextitem,
+% \secondnextitem (some of which may be empty), and \iflpslastitem.
+%
+% Examples:
+%
+% \def\aitems{}
+% \lpsdocsvlist{,}{a,b,c,d,e,f}{%
+% \def\do##1{\ifx##1\@empty\let##1\@gobble\fi}%
+% \do\secondprevitem\do\firstprevitem\do\firstnextitem
+% \edef\aitems{%
+% \skvexpandonce\aitems\ifx\aitems\@empty\else,\fi
+% \secondprevitem,\firstprevitem,\currentitem,%
+% \firstnextitem,\secondnextitem
+% }%
+% }
+%
+\skvnewregister\bool{\iflpslastitem}
+\skvnewlet\lpsbreakloop\skvbreaklooptrue
+\skvrobustdef*\lpsdocsvlist#1#2#3{%
+ \skvpushfunctions\lpsdocsvlist{%
+ \do\lpsuserlist\do\firstprevitem\do\secondprevitem\do\currentitem
+ \do\firstnextitem\do\secondnextitem\do\lps@do\do\skv@callback
+ }\skv@csvdepth
+ \let\firstprevitem\@empty
+ \let\secondprevitem\@empty
+ \edef\lpsuserlist{\unexpanded{#2}}%
+ \edef\skv@callback{\unexpanded{#3}}%
+ \skvcsvnormalize[#1]\lpsuserlist
+ \def\lps@do##1#1##2#1##3#1{%
+ \edef\currentitem{\unexpanded{##1}}%
+ \skvifxTF\currentitem\skv@nnil{%
+ \skvbreakloopfalse
+ }{%
+ \skvifdefboolTF{skvbreakloop}{%
+ \skvbreakloopfalse
+ \def\lps@do####1\skv@nil#1\skv@nil#1\skv@nil#1{%
+ \edef\lpsremainder{\unexpanded{####1}}%
+ }%
+ }{%
+ \edef\firstnextitem{\unexpanded{##2}}%
+ \ifx\firstnextitem\skv@nnil
+ \lpslastitemtrue
+ \let\firstnextitem\@empty
+ \fi
+ \edef\secondnextitem{\unexpanded{##3}}%
+ \ifx\secondnextitem\skv@nnil
+ \let\secondnextitem\@empty
+ \fi
+ \lps@callback\relax
+ \let\secondprevitem\firstprevitem
+ \let\firstprevitem\currentitem
+ }%
+ \lps@do##2#1##3#1%
+ }%
}%
- \let\firstprev\@empty
- \let\secondprev\@empty
- \def\skv@tempa{#3}%
- \def\skv@do##1#1{%
- \ifx\skv@nnil##1\else
- \def\current{##1}%
- \ifx\current\skv@tempa
- #4\relax
- \def\skv@do####1\skv@nnil#1{}%
- \else
- \let\secondprev\firstprev
- \let\firstprev\current
- \fi
- \expandafter\skv@do
- \fi
+ \skvbreakloopfalse
+ \skvifemptyTF\lpsuserlist{}{%
+ \expandafter\lps@do\lpsuserlist#1\skv@nil#1\skv@nil#1\skv@nil#1%
}%
- \skv@do#2#1\skv@nnil#1%
+ \skvpopfunctions\lpsdocsvlist\skv@csvdepth
}
% Remove one element from a list. Only the first occurence of the
@@ -112,7 +148,10 @@
%
% \lpsremovefromlist<parser>{<element to remove>}<listcmd>
%
-% Eg, \def\x{1,2,3,4} \lpsremovefromlist{,}7\x
+% Example:
+%
+% \def\x{1,2,3,4}
+% \lpsremovefromlist{,}7\x
%
\skvrobustdef\lpsremovefromlist#1#2#3{%
\begingroup
@@ -180,7 +219,7 @@
% \if...
% \repeat
%
-\skvnewregister\toks\skv@aktertoks
+\skvnewregister\toks{\skv@aktertoks}
\skvnewdef*\skv@aktercnt{0}
\skvrobustdef*\skv@akter@defloop{%
\def\skv@tempa##1##2##3{%
@@ -236,7 +275,7 @@
}%
}{%
\skvifstrcmpTF{#1}{EOF}{%
- \skv@err{'\string\repeat' not found: endless loop}\@ehd
+ \skv@err{'\string\repeat' not found: endless loop}\skv@ehd
}{%
\skvifxTF\next\@sptoken{%
\skv@aktertoks\expandafter
@@ -252,17 +291,17 @@
% Expandable comma loop. List is not normalized prior to parsing, and
% it is not possible to terminate the loop prematurely.
%
-% \skvfor{<list>}<callback.macro>
+% \lpsfor{<list>}<callback.macro>
%
% Example:
%
-% \skvnewregister\count\nr\nr=\tw@
+% \skvnewregister\count{\nr}\nr=\tw@
% \def\do#1{%
% \let\noexpand#1%
% \expandafter\noexpand\csname\skvremovescape{#1}@%
% \romannumeral\nr\endcsname
% }
-% \edef\x{\skvfor{\cmda,\cmdb}\do}
+% \edef\x{\lpsfor{\cmda,\cmdb}\do}
% \show\x -> \let\cmda\cmda@ii \let\cmdb\cmdb@ii
%
\skvnewdef\skvfor#1#2{\skv@for@a{#2}#1,\skv@for@nil,}
@@ -273,8 +312,9 @@
\skvifstrcmpTF{#2}\skv@for@nil{}{#1{#2}\skv@for@a{#1}}%
}%
}
-
-% Process non-separated (token-wise) list:
+\skvnewlet\lpsfor\skvfor
+% Process non-separated (token-wise) list. \ayeloop is like \skvtfor
+% but uses parameter characters directly, instead of a holder macro.
%
% \ayeloop{<list>}\do{<1.parameter.callback>}
% \ayeloop*{<listcmd>}\do{<1.parameter.callback>}
@@ -288,9 +328,6 @@
% }%
% }%
%
-% \ayeloop is like \skvtfor but uses parameter characters directly,
-% instead of a holder macro.
-%
\skvrobustdef*\ayeloop{\skv@testst\skv@ayeloop}
\skvrobustdef*\skv@ayeloop#1\do#2{%
\skv@usetempst{#1}\skv@tempa
@@ -317,7 +354,7 @@
}
% Robust, outer-brace-preserving, multi-level, general-purpose
-% non-separated values list (nsv) processor.
+% non-separated values list (nsv/tsv) processor.
%
% \sifakaloop{<list>}{<1.parameter.callback>}
% \sifakaloop*{<listcmd>}{<1.parameter.callback>}
@@ -385,20 +422,20 @@
}%
}
-% Processing both csv and tsv/nsv lists with \foxloop.
+% Processing both csv and tsv/nsv lists with \foreachfox.
%
-% \foxloop[<options>]{<list>}{<parametered.callback>}
-% \foxloop*[<options>]{<listcmd>}{<parametered.callback>}
+% \foreachfox[<options>]{<list>}{<parametered.callback>}
+% \foreachfox*[<options>]{<listcmd>}{<parametered.callback>}
%
% 1. The <callback> is at least a one-parameter token list.
%
-% 2. \breakfoxloop can be used to break out of the loop.
+% 2. \breakforeachfox can be used to break out of the current nest loop.
+% \breakallforeachloops can be used to break out of all current loops.
%
% 3. When the argument is more than one (say, #1#2), the last one
% must be delimited by the user-suggested <arg delimiter>.
%
-% 4. To permit nesting we use a stack involving the counter \foreachdepth,
-% with alias \foxloopdepth.
+% 4. To permit nesting we use a stack involving the counter \foreachnestdepth.
%
% 5. \subcallback is meant for callbacks with hash characters that may be
% confused with the parameters of the main <callback>. It can be defined
@@ -406,41 +443,37 @@
%
% 6. Outer braces around the list items are preserved in the parsing.
%
-% 7. 'fox' is used here to represent an item. Eg, \currentfox, \nextfox,
-% \foxcount.
-%
-\skvnewdef*\skv@foxloop@nnil{\skv@foxloop@nil}
-\skvnewbools{lastfox}
-\skvnewlet\breakfoxloop\skvbreaklooptrue
-\skvnewdef*\foxloopdepth{\foreachdepth}
-\skvnewdef*\foxcount{\foreachitemcount}
-\skvnewdef*\currentfox{\foreachcurrentitem}
-\skvnewdef*\nextfox{\foreachnextitem}
-\skvnewdef*\previousfox{\foreachprevitem}
-\skvnewdef*\foxlistremainder{\foreachlistremainder}
-\skvnewdef*\prependtobeginfoxloop{\prependtobeginforeach}
-\skvnewdef*\appendtobeginfoxloop{\appendtobeginforeach}
-\skvnewdef*\prependtoendfoxloop{\prependtoendforeach}
-\skvnewdef*\appendtoendfoxloop{\appendtoendforeach}
+% 7. The following are available here, as in \newforeach:
+%
+% \foreachcurrentitem, \foreachnextitem, \foreachitemcount,
+% \foreachcurrentitem, \foreachnextitem, \foreachitemcount,
+% \foreachprevitem, \prependtobeginforeach, \appendtobeginforeach
+% (=\atbeginforeach), \prependtoendforeach, \appendtoendforeach
+% (=\atendforeach), \ifforeachlastitem, \foreachnestdepth,
+% \foreachlistremainder, \skvforeachonlyinitially.
+%
+\skvnewregisters\bool{\iflastfox}
+\skvnewlet\breakforeachfox\skvbreaklooptrue
+% \atbeginforeachfox[<depth>]{<code>}
+\skvnewlet\atbeginforeachfox\atbeginforeach
+% \atendforeachfox[<depth>]{<code>}
+\skvnewlet\atendforeachfox\atendforeach
-% Define \foxloop keys. Name all the macros with 'foreach' prefix so
+% Define \foreachfox keys. Name all the macros with 'foreach' prefix so
% that we can avoid new command names and use the list auto-completion
% scheme of \newforeach.
-\quickkeys.define{loops/foxloop}{%
+\quickkeys.define{loops/foreachfox}{%
parser/{,}/
\def\skv@foreach@parser{#1}
\skvstripouterbraces{2}\skv@foreach@parser
;
- list type/csv/
- \def\skv@foreach@listtype{#1}
- /csv,kv,tsv,nsv
- ;
+ list type/csv/\def\skv@foreach@listtype{#1}/csv,kv,tsv,nsv;
arg,args,arg pattern/##1/
\edef\skv@foreach@paramlist{\unexpanded{#1}}
\skvstripouterbraces{1}\skv@foreach@paramlist
;
- list breaker/\listbreaker/\def\skv@listbreakertoks{#1};
- list pauser/\listpauser/\def\skv@listpausertoks{#1};
+ list breaker/\skvlistbreaker/\def\skv@listbreakertoks{#1};
+ list pauser/\skvlistpauser/\def\skv@listpausertoks{#1};
normalize list/true/
\edef\skv@foreach@normalizelist{0\skvifstrcmpTF{#1}{true}01}
/true,false
@@ -449,42 +482,50 @@
\edef\skv@foreach@useempty{0\skvifstrcmpTF{#1}{true}01}
/true,false
;
- .exec/
- \let\skv@foreach@exittester\@secondoftwo
+ .exec/\let\skv@foreach@exittester\@secondoftwo;
+ 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
;
- 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
- \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@
;
- item counter,counter/\@nil/
- \def\skv@foreach@itemcounter{#1}
+ 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
+ }%
+ ;
+ process up to,process up to number//
+ \skviflacus#1\then\else
+ \skvensureinteger{process up to}{#1}%
+ \def\skv@foreach@processupto{#1}%
+ \skvstripouterbraces{2}\skv@foreach@processupto
+ \fi
;
% This default value of 'link' is required by \skv@foreach@filllist:
.exec/\def\skv@foreach@link{\@nil};
link/\@nil/
- \ifskvindef\else
+ \edef\skv@prova{\unexpanded{#1}}
+ \ifx\skv@prova\@nnil\else
\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
;
@@ -493,17 +534,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
@@ -535,10 +572,10 @@
;
% Eg, 'evaluate = #1 as \x using \numexpr#1*2'.
% Since the parameters haven't assumed arguments, we defer the
- % call to \skv@foxloop@parseevaluate until the arguments are known.
+ % call to \skv@foreachfox@parseevaluate until the arguments are known.
evaluate/\@nil/
\skv@foreach@ifacceptkv{#1}{%
- \skv@foxloop@parseevaluate{#1}%
+ \skv@foreachfox@parseevaluate{#1}%
}%
;
% Eg,
@@ -546,13 +583,13 @@
% 'count in = \p all #1 satisfying \ifnum#1>4\fi'
count in,count/\@nil/
\skv@foreach@ifacceptkv{#1}{%
- \skv@foxloop@parsecountin{#1}%
+ \skv@foreachfox@parsecountin{#1}%
}%
;
% Eg, remember=#1 as \y initially A
remember/\@nil/
\skv@foreach@ifacceptkv{#1}{%
- \skv@foxloop@parseremember{#1}%
+ \skv@foreachfox@parseremember{#1}%
}%
;
reverse list,reverse,reflect/true/
@@ -560,22 +597,12 @@
/true,false
;
}
-
-% Set up \foxloop defaults:
-\quickkeys.set{loops/foxloop}{%
- parser={,},
- list type=csv,
- arg=#1,
- list breaker=\listbreaker,
- list pauser=\listpauser,
- normalize list=true,
- use empty=false,
- keep decimals=true,
- keep high decimals=false,
- expand before fill=false,
- reverse list=false,
- expand list once=false,
- expand list twice=false,
+\quickkeys.preset{loops/foreachfox}{%
+ parser={,},list type=csv,arg=#1,loop stopper,
+ list breaker=\skvlistbreaker,list pauser=\skvlistpauser,
+ normalize list=true,use empty=false,keep decimals=true,
+ keep high decimals=false,expand before fill=false,
+ reverse list=false,expand list once=false,expand list twice=false,
expand list fully=false,
}
@@ -583,10 +610,10 @@
%
% Eg, 'evaluate = #1 as \x using \numexpr#1*2'.
%
-% \skv@foxloop@parseevaluate differs from \skv@foreach@parseevaluate
+% \skv@foreachfox@parseevaluate differs from \skv@foreach@parseevaluate
% because #1 here is likely to be a non-macro.
%
-\skvrobustdef*\skv@foxloop@parseevaluate#1{%
+\skvrobustdef*\skv@foreachfox@parseevaluate#1{%
\begingroup
\def\skv@tempxifin##1##2{%
\skvxifinTF{\detokenize{##1}}{\detokenize{##2}}%
@@ -599,19 +626,19 @@
\edef\skv@provc{\skvtrimspace{##3}}%
\ifx\skv@prova\@empty
\skv@err{Value of key 'evaluate':
- \MessageBreak no quantity to evaluate}\@ehd
+ \MessageBreak no quantity to evaluate}\skv@ehd
\fi
\ifx\skv@provb\@empty
\skv@err{Value of key 'evaluate' has no receiving macro,
- \MessageBreak i.e., after 'as'}\@ehd
+ \MessageBreak i.e., after 'as'}\skv@ehd
\else
\expandafter\skvifescapedTF\expandafter{\skv@provb}{}{%
\skv@err{Value of key 'evaluate': receiving macro
- \MessageBreak \skvoxdetok\skv@provb not escaped}\@ehd
+ \MessageBreak \skvoxdetok\skv@provb not escaped}\skv@ehd
}%
\fi
\ifx\skv@provc\@empty
- \skv@err{Value of key 'evaluate' has no formula}\@ehd
+ \skv@err{Value of key 'evaluate' has no formula}\skv@ehd
\fi
\skv@tempxifin{\pgfmathparse}{##3}{%
\def\skv@tempc####1\pgfmathparse####2\skv@nil{%
@@ -620,11 +647,11 @@
\skv@foreach@swatrue
\else
\skv@err{\noexpand\pgfmathparse isn't defined;
- \MessageBreak maybe 'pgfmath' isn't loaded}\@ehd
+ \MessageBreak maybe 'pgfmath' isn't loaded}\skv@ehd
\fi
\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
@@ -648,7 +675,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:
@@ -657,10 +684,10 @@
\def\skv@tempb##1as##2##3\skv@nil{%
\ifx\@nnil##1\@nnil
\skv@err{Value of key 'evaluate' has no
- \MessageBreak quantity to evaluate}\@ehd
+ \MessageBreak quantity to evaluate}\skv@ehd
\else
\ifx\@nnil##2%
- \skv@err{Value of key 'evaluate' has no receiving macro}\@ehd
+ \skv@err{Value of key 'evaluate' has no receiving macro}\skv@ehd
\else
\skv@tempa##1as##2using##1\skv@nil
\fi
@@ -668,14 +695,14 @@
}%
\skv@tempb#1{\@nnil}\skv@nil
}{%
- % No 'as' or 'using'. In \foxloop, #1 is not guaranteed
+ % No 'as' or 'using'. In \foreachfox, #1 is not guaranteed
% to be a macro. Hence raise error here:
- \skv@err{Value of key 'evaluate' has no 'as'}\@ehd
+ \skv@err{Value of key 'evaluate' has no 'as'}\skv@ehd
}%
}%
\skv@foreach@addtocallback{pre}{%
\ifskv@foreach@swa
- % Here, <formula> may have the syntax \pgfmathresult{<token>}.
+ % Here, <formula> may have the syntax \pgfmathparse{<token>}.
\skvexpandonce\skv@provc
\let\skvexpandonce\skv@provb\noexpand\pgfmathresult
\else
@@ -704,15 +731,15 @@
%
% '\foreach \x [count=\xi from 2] in {a,...,e}'.
%
-% Generic counting is available in \foxloop by default, without
-% user request. The macros \currentfox, \foxcount, \nextfox are
-% always available on each nesting level. The boolean \iflastfox
-% is also always available, to indicate when the last item of
-% the list has been reached:
+% Generic counting is available in \foreachfox by default, without
+% user request. The macros \foreachcurrentitem, \foreachitemcount,
+% \foreachnextitem are always available on each nesting level.
+% The boolean \ifforeachlastitem is also always available, to indicate
+% when the last item of the list has been reached:
%
-% \iflastfox\typeout{Processing last entry of the list} \fi
+% \ifforeachlastitem\typeout{Processing last entry of the list} \fi
%
-\skvrobustdef*\skv@foxloop@parsecountin#1{%
+\skvrobustdef*\skv@foreachfox@parsecountin#1{%
\begingroup
\def\skv@tempxifin##1##2{%
\skvxifinTF{\detokenize{##1}}{\detokenize{##2}}%
@@ -730,11 +757,11 @@
\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}{}{%
\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
@@ -744,7 +771,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
@@ -758,7 +785,7 @@
\skv@foreach@swatrue
% \skv@tester is the second argument of \skv@foreach@maketester,
% which is used below:
- \skvexpbracenext\skv@foreach@maketester\skv@provc\skv@tester
+ \skvexpbracenext\skv@foreach@maketester\skv@provc\skv@tester\skvz@
\fi
\fi
}%
@@ -768,7 +795,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}{%
@@ -776,14 +803,14 @@
}{%
% No 'all' and 'satisfying': #1 should be only the counter macro:
\ifx\@nnil#1\@nnil
- \skv@err{Value of key 'count': no counter macro}\@ehd
+ \skv@err{Value of key 'count': 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
}%
@@ -809,7 +836,7 @@
% remember=<holder.macro> as <child.macro> initially <value>
%
-\skvrobustdef*\skv@foxloop@parseremember#1{%
+\skvrobustdef*\skv@foreachfox@parseremember#1{%
\begingroup
\def\skv@tempxifin##1##2{%
\skvxifinTF{\detokenize{##1}}{\detokenize{##2}}%
@@ -817,7 +844,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 around '(<your input>)'}\skv@ehd
}{}%
\def\skv@tempa##1as##2initially##3\skv@nil{%
\edef\skv@prova{\skvtrimspace{##1}}%
@@ -825,17 +852,17 @@
\edef\skv@provc{\skvtrimspace{##3}}%
\skv@foreach@swafalse
\ifx\skv@prova\@empty
- \skv@err{Value of key 'remember' has no value to remember}\@ehd
+ \skv@err{Value of key 'remember' has no value to remember}\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
}%
@@ -844,7 +871,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}{%
@@ -853,9 +880,9 @@
% No 'as' and 'initially':
\ifx\@nnil#1\@nnil\else
% Unlike in \newforeach, we can't create an automatic retainer
- % macro here, since \foxloop uses parameters instead of
+ % macro here, since \foreachfox uses parameters instead of
% holder macros.
- \skv@err{Value of key 'remember' is incomplete: no 'as'}\@ehd
+ \skv@err{Value of key 'remember' is incomplete: no 'as'}\skv@ehd
\fi
}%
}%
@@ -884,40 +911,62 @@
}%
}
-\skvnewdef*\skv@foxloop@kvlist{}
-% \setupfoxloop{<kvlist>}
-\skvrobustdef*\setupfoxloop#1{%
+\skvnewdef*\skv@foreachfox@kvlist{}
+% \setupforeachfox{<kvlist>}
+\skvrobustdef*\setupforeachfox#1{%
\skvifblankTF{#1}{}{%
- \skvaddtolist\skv@foxloop@kvlist{#1}%
+ \skvaddtolist\skv@foreachfox@kvlist{#1}%
}%
}
-\skvrobustdef*\skv@foxloop@setkeys#1{%
- \def\reserved@a{\quickkeys.set{loops/foxloop}}%
- \expandafter\reserved@a\expandafter{\skv@foxloop@kvlist,#1}%
+\skvrobustdef*\skv@foreachfox@setkeys#1{%
+ \def\reserved@a{\quickkeys.set{loops/foreachfox}}%
+ \expandafter\reserved@a\expandafter{\skv@foreachfox@kvlist,#1}%
}
-
-% \atbeginfoxloop[<depth>]{<code>}
-\skvnewlet\atbeginfoxloop\atbeginforeach
-% \atendfoxloop[<depth>]{<code>}
-\skvnewlet\atendfoxloop\atendforeach
-
-\skvrobustdef*\foxloop{\skv@teststopt\skv@foxloop{}}
-\skvnewlet\foreachfox\foxloop
-\skvrobustdef*\skv@foxloop[#1]#2#3{%
+\skvrobustdef*\foreachfox{%
+ \skvifnextchar i{%
+ \skv@foreachfox@prescan@a
+ }{%
+ \skv@teststopt\skv@foreachfox@prescan@b{}%
+ }%
+}
+\skvrobustdef*\skv@foreachfox@prescan@a#1#2{%
+ \skvifstrcmpTF{#1#2}{in}{%
+ \skv@teststopt\skv@foreachfox@prescan@b{}%
+ }{%
+ \skv@err{I have found 'i' before opening brace or
+ \MessageBreak bracket, but no 'in'}\skv@ehd
+ }%
+}
+\skvrobustdef*\skv@foreachfox@prescan@b[#1]{%
+ \skvifnextchar i{%
+ \skv@foreachfox@prescan@c[#1]%
+ }{%
+ \skv@foreachfox@a[#1]%
+ }%
+}
+\skvrobustdef*\skv@foreachfox@prescan@c[#1]#2#3{%
+ \skvifstrcmpTF{#2#3}{in}{%
+ \skv@foreachfox@a[#1]%
+ }{%
+ \skv@err{I have found 'i' after '[]', but no 'in'}\skv@ehd
+ }%
+}
+\skvrobustdef*\skv@foreachfox@a[#1]#2#3{%
\edef\skv@foreach@seenstar{0\ifskv@tempst0\else1\fi}%
\skv@foreach@pushstate
\skv@foreach@latehookerr
\def\foreachitemcount{0}%
- \def\skv@foreach@callback{}%
- \def\skv@foreach@afterprecallback{}%
- \def\skv@foreach@precallback{}%
- \def\skv@foreach@postcallback{}%
- \def\skv@foreach@onlyinitially{}%
- \skv@foxloop@setkeys{#1}%
+ \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
+ \skv@foreachfox@setkeys{#1}%
\if\skv@foreach@seenstar
\def\skv@foreach@expandlistonce{00}%
\fi
\ifcase0%
+ % Take only one case:
\if\skv@foreach@expandlistonce\else
\if\skv@foreach@expandlisttwice\else
\if\skv@foreach@expandlistfully\else 1\fi\fi\fi\relax
@@ -928,8 +977,7 @@
\ifskv@verbose
\skv@warn{One-item list '\detokenize{#2}' is a macro.
\MessageBreak If your list is indeed a macro, you can
- \MessageBreak either put star (*) after
- \detokenize{\foxloop or \foreachfox}
+ \MessageBreak either put star (*) after \noexpand\foreachfox
\MessageBreak or use the key 'expand list once'
\MessageBreak or 'expand list twice' or 'list is a macro', etc}%
\fi
@@ -953,7 +1001,9 @@
\fi
{#2}%
}%
- \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachdepth}%
+ \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachnestdepth}%
+ \skvifdefTF\foreachprevitem{}{\def\foreachprevitem{}}%
+ % Define the loop callback:
\edef\reserved@a{%
\skvexpandonce\skv@foreach@precallback
\ifx\skv@foreach@onlyinitially\@empty\else
@@ -961,10 +1011,18 @@
\skvexpandonce\skv@foreach@onlyinitially
\noexpand\fi
\fi
- \unexpanded{#3}%
- \skvexpandonce\skv@foreach@postcallback
+ \ifx\skv@foreach@continuetester\@secondoftwo
+ \noexpand\skv@foreach@continuetester
+ \else
+ % We want to expose the parameter characters in
+ % \skv@foreach@continuetester:
+ \skvexpandonce\skv@foreach@continuetester
+ \fi
+ {}{%
+ \unexpanded{#3}%
+ \skvexpandonce\skv@foreach@postcallback
+ }%
}%
- % Define the user callback:
\edef\reserved@b{%
\def\noexpand\skv@foreach@callback\skvexpandonce
\skv@foreach@paramlist\noexpand\foreacheov
@@ -972,18 +1030,21 @@
\expandafter\reserved@b\expandafter{\reserved@a}%
\skvxifstrcmpTF\skv@foreach@listtype{csv}{%
\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@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})}%
}{%
+ % Token list (nsv/tsv):
\def\skv@foreach@lookahead@a##1{%
- \let\skv@foreach@continue##1%
+ \let\skv@foreach@picknext##1%
\futurelet\skv@foreach@next\skv@foreach@lookahead@b
}%
- \def\skv@foreach@lookahead@c[##1]{\skv@foreach@continue{[##1]}}%
- \def\skv@foreach@lookahead@d(##1){\skv@foreach@continue{(##1)}}%
+ % These \skv@foreach@lookahead@c and \skv@foreach@lookahead@d
+ % differ from those for 'csv' list (above):
+ \def\skv@foreach@lookahead@c[##1]{\skv@foreach@picknext{[##1]}}%
+ \def\skv@foreach@lookahead@d(##1){\skv@foreach@picknext{(##1)}}%
}%
\def\skv@foreach@lookahead@b{%
\skvifxTF\skv@foreach@next[{%
@@ -992,20 +1053,23 @@
\skvifxTF\skv@foreach@next({%
\skv@foreach@parenthtrue\skv@foreach@lookahead@d
}{%
- \skv@foreach@parenthfalse\skv@foreach@continue
+ \skv@foreach@parenthfalse\skv@foreach@picknext
}%
}%
}%
- \skvbreakloopfalse\lastfoxfalse
+ \ifnum\foreachnestdepth=\skvz@
+ \breakallforeachloopsfalse
+ \fi
+ \skvbreakloopfalse\foreachlastitemfalse\lastfoxfalse
\def\reserved@a##1{%
\skv@setupgetnextfox{##1}%
\skvxifstrcmpTF\skv@foreach@listtype{csv}{%
\if\skv@foreach@normalizelist
\skv@foreach@normalize[##1]\skv@foreach@userlist
\fi
- \def\skv@foreach@do####1##1####2\skv@foxloop@stop{%
- \edef\currentfox{\skvexpandonce{\@gobble####1}}%
- \skv@foxloop@a{##1}{####2}{csv}%
+ \def\skv@foreach@do@a####1##1####2\skv@foreach@stop{%
+ \edef\foreachcurrentitem{\skvexpandonce{\@gobble####1}}%
+ \skv@foreachfox@b{##1}{####2}{csv}%
}%
\skvifemptyTF\skv@foreach@userlist{}{%
\expandafter\skv@foreach@filllist\expandafter
@@ -1015,135 +1079,141 @@
{\skv@foreach@parser}\skv@foreach@userlist
\fi
}%
- % If \skv@foreach@userlist is empty, \currentfox in
- % \skv@foxloop@b will terminate the loop.
- \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do
- \skv@foreach@userlist##1\skv@foxloop@nil##1\skv@foxloop@stop
+ % If \skv@foreach@userlist is empty, \foreachcurrentitem in
+ % \skv@foreachfox@c will terminate the loop.
+ \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do@a
+ \skv@foreach@userlist##1\skv@foreach@nil##1\skv@foreach@stop
}{%
- \if\skv@foreach@normalizelist
+ \if\skv@foreach@normalizelist\skvafterfi
\edef\skv@foreach@userlist{%
\skvexpbracenext\skvtsvnormalize\skv@foreach@userlist
}%
\fi
- \def\skv@foreach@do{%
+ \def\skv@foreach@do@a{%
\let\bgroup\relax
- \futurelet\skv@foreach@next\skv@foreach@do@a
+ \futurelet\skv@foreach@next\skv@foreach@do@b
}%
- \def\skv@foreach@do@a####1####2\skv@foxloop@stop{%
+ \def\skv@foreach@do@b####1####2\skv@foreach@stop{%
\let\bgroup\skv@orig@bgroup
\ifskv@foreach@parenth
- \edef\currentfox{\unexpanded{####1}}%
+ \edef\foreachcurrentitem{\unexpanded{####1}}%
\else
\skvifxTF\skv@foreach@next\bgroup{%
- \edef\currentfox{{\unexpanded{####1}}}%
+ \edef\foreachcurrentitem{{\unexpanded{####1}}}%
}{%
- \edef\currentfox{\unexpanded{####1}}%
+ \edef\foreachcurrentitem{\unexpanded{####1}}%
}%
\fi
- \skv@foxloop@a{}{####2}{tsv}%
+ \skv@foreachfox@b{}{####2}{tsv}%
}%
- \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do
- \skv@foreach@userlist\skv@foxloop@nil\skv@foxloop@stop
+ \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do@a
+ \skv@foreach@userlist\skv@foreach@nil\skv@foreach@stop
}%
}%
\expandafter\reserved@a\expandafter{\skv@foreach@parser}%
- \skvcsuse{skv@foreach@atendhook@\romannumeral\foreachdepth}%
+ \skvcsuse{skv@foreach@atendhook@\romannumeral\foreachnestdepth}%
\skv@foreach@popstate
}
% \skv@setupgetnextfox<parser>
\skvrobustdef*\skv@setupgetnextfox#1{%
\skvxifstrcmpTF\skv@foreach@listtype{csv}{%
- \def\skv@foreach@getnext##1#1##2\skv@foxloop@stop{%
- \edef\nextfox{\skvexpandonce{\@gobble##1}}%
- % See \skv@foxloop@b for \lastfoxtrue.
+ \def\skv@foreach@getnext##1#1##2\skv@foreach@stop{%
+ \edef\foreachnextitem{\skvexpandonce{\@gobble##1}}%
+ % See \skv@foreachfox@c for \foreachlastitemtrue.
}%
}{%
\def\skv@foreach@getnext{%
- \begingroup
\let\bgroup\relax
\futurelet\skv@foreach@next\skv@foreach@g@tnext
}%
- \def\skv@foreach@g@tnext##1##2\skv@foxloop@stop{%
+ \def\skv@foreach@g@tnext##1##2\skv@foreach@stop{%
\let\bgroup\skv@orig@bgroup
\ifskv@foreach@parenth
- \edef\nextfox{\unexpanded{##1}}%
+ \edef\foreachnextitem{\unexpanded{##1}}%
\else
\skvifxTF\skv@foreach@next\bgroup{%
- \edef\nextfox{{\unexpanded{##1}}}%
+ \edef\foreachnextitem{{\unexpanded{##1}}}%
}{%
- \edef\nextfox{\unexpanded{##1}}%
+ \edef\foreachnextitem{\unexpanded{##1}}%
}%
\fi
}%
}%
}
-% \skv@foxloop@a<parser><remainder><list.type>
-\skvrobustdef*\skv@foxloop@a#1#2#3{%
- \skvifxTF\currentfox\skv@foxloop@nnil{%
- \skvbreakloopfalse\lastfoxfalse
+% \skv@foreachfox@b<parser><remainder><list.type>
+\skvrobustdef*\skv@foreachfox@b#1#2#3{%
+ \skvifxTF\foreachcurrentitem\skv@foreach@nnil{%
+ \skvbreakloopfalse\foreachlastitemfalse\lastfoxfalse
}{%
- \skvifxTF\currentfox\skv@listbreakertoks{%
- \skv@foxloop@getrm{#1}{#2}%
+ \skvifxTF\foreachcurrentitem\skv@listbreakertoks{%
+ \skv@foreachfox@getrm{#1}{#2}%
}{%
- \skvifxTF\currentfox\skv@listpausertoks{%
+ \skvifxTF\foreachcurrentitem\skv@listpausertoks{%
\message{^^J! List pause:
^^JType x or X to quit, or <RETURN> to proceed^^J}%
\bgroup\endlinechar\m@ne\global\read-1 to\@gtempa\egroup
\skvexpandarg\lowercase{\def\noexpand\@gtempa{\@gtempa}}%
\skvxifstrcmpTF\@gtempa{x}{%
- \skv@foxloop@getrm{#1}{#2}%
+ \skv@foreachfox@getrm{#1}{#2}%
}{%
- \skv@foxloop@b{#1}{#2}{#3}%
+ \skv@foreachfox@c{#1}{#2}{#3}%
}%
}{%
- \skv@foxloop@b{#1}{#2}{#3}%
+ \skv@foreachfox@c{#1}{#2}{#3}%
}%
}%
}%
}
-% \skv@foxloop@b<parser><remainder><list.type>
-\skvrobustdef*\skv@foxloop@b#1#2#3{%
- \skv@foreach@lookahead@a\skv@foreach@getnext#2\skv@foxloop@stop
- \ifx\nextfox\skv@foxloop@nnil
- \lastfoxtrue\def\nextfox{}%
+% \skv@foreachfox@c<parser><remainder><list.type>
+\skvrobustdef*\skv@foreachfox@c#1#2#3{%
+ \skv@foreach@lookahead@a\skv@foreach@getnext#2\skv@foreach@stop
+ \ifx\foreachnextitem\skv@foreach@nnil
+ \foreachlastitemtrue\lastfoxtrue
+ \def\foreachnextitem{}%
\fi
\edef\foreachitemcount{\the\numexpr\foreachitemcount+1}%
- \ifnum0=\numexpr
- \ifx\skv@foreach@itemcounter\@undefined-1\else+0\fi
- \ifx\skv@foreach@itemcounter\@empty-1\else+0\fi
- \ifx\skv@foreach@itemcounter\@nnil-1\else+0\fi\relax\relax
- \expandafter\let\skv@foreach@itemcounter\foreachitemcount
+ \ifx\skv@foreach@itemcounter\@empty\else
+ \expandafter\let\skv@foreach@itemcounter\foreachitemcount
\fi
- \skvifemptyTF\currentfox{%
- \if\skv@foreach@useempty
- \expandafter\skv@foreach@callback\expandafter\foreacheov
+ \skvifemptyTF\foreachcurrentitem{%
+ \if\skv@foreach@useempty\skvafterfi
+ \skv@foreach@callback\foreacheov
\fi
}{%
- % Tes for \listpauser, in case the user decides to continue
- % after \listpauser has been picked:
- \skvifxTF\currentfox\skv@listpausertoks{}{%
+ % Test for \skvlistpauser, in case the user decides to continue
+ % after \skvlistpauser has been picked:
+ \skvifxTF\foreachcurrentitem\skv@listpausertoks{}{%
\skvifxTF\skv@foreach@paramlist\skv@simplearg{%
- \expandafter\skv@foreach@callback\expandafter
- {\currentfox}\foreacheov
+ \skvexpbracenext\skv@foreach@callback\foreachcurrentitem\foreacheov
}{%
- \expandafter\skv@foreach@callback\currentfox\foreacheov
+ % Incomplete items like 3 in {1/a,2/b,3} can't be handled by
+ % \foreachfox; see \newforeach.
+ \expandafter\skv@foreach@callback\foreachcurrentitem\foreacheov
}%
+ \let\foreachprevitem\foreachcurrentitem
}%
}%
- \skv@foreach@exittester{\skvbreakloop}{}%
+ \ifx\skv@foreach@processupto\@empty\else
+ \ifnum\foreachitemcount<\skv@foreach@processupto\relax\else
+ \skvbreakloop
+ \fi
+ \fi
\skvifdefboolTF{skvbreakloop}{%
- \skvbreakloopfalse\lastfoxfalse
- \skv@foxloop@getrm{#1}{#2}%
+ \ifbreakallforeachloops\else
+ \skvbreakloopfalse
+ \fi
+ \foreachlastitemfalse\lastfoxfalse
+ \skv@foreachfox@getrm{#1}{#2}%
}{%
- \skv@foreach@lookahead@a\skv@foreach@do#2\skv@foxloop@stop
+ \skv@foreach@lookahead@a\skv@foreach@do@a#2\skv@foreach@stop
}%
}
-% \skv@foxloop@getrm<parser><remaining.items>
-\skvrobustdef*\skv@foxloop@getrm#1#2{%
+% \skv@foreachfox@getrm<parser><remaining.items>
+\skvrobustdef*\skv@foreachfox@getrm#1#2{%
\begingroup
- \def\reserved@a##1\skv@foxloop@nil#1{%
+ \def\reserved@a##1\skv@foreach@nil#1{%
\endgroup
- \edef\foxlistremainder{\unexpanded{##1}}%
+ \edef\foreachlistremainder{\unexpanded{##1}}%
}%
\reserved@a#2%
}
@@ -1222,7 +1292,7 @@
\skvbreakloopfalse\lastcicadafalse
}{%
\edef\cicadacount{\the\numexpr\cicadacount+1}%
- \skv@cicada@lookahead\skv@cicada@getnext##2\skv@cicada@stop
+ \skv@cicada@lookahead@a\skv@cicada@getnext##2\skv@cicada@stop
\skvexpandbracenext\skv@cicada@callback\currentcicada\relax
\skvifcondFT#3\fi{}\skvbreakloop
\skvifdefboolTF{skvbreakloop}{%
@@ -1235,33 +1305,33 @@
\skv@prova##2%
}{%
\let\lastcicada\currentcicada
- \skv@cicada@lookahead\skv@cicada@do##2\skv@cicada@stop
+ \skv@cicada@lookahead@a\skv@cicada@do##2\skv@cicada@stop
}%
}%
}%
}%
- \def\skv@cicada@lookahead##1{%
- \def\skv@cicada@continue{##1.}%
- \futurelet\skv@next\skv@cicada@lookahead@a
+ \def\skv@cicada@lookahead@a##1{%
+ \def\skv@cicada@picknext{##1.}%
+ \futurelet\skv@next\skv@cicada@lookahead@b
}%
- \def\skv@cicada@lookahead@a{%
+ \def\skv@cicada@lookahead@b{%
\ifx\skv@next[%
- \expandafter\skv@cicada@lookahead@b
+ \expandafter\skv@cicada@lookahead@c
\else
\ifx\skv@next(%
- \expandafter\expandafter\expandafter\skv@cicada@lookahead@c
+ \expandafter\expandafter\expandafter\skv@cicada@lookahead@d
\else
- \expandafter\expandafter\expandafter\skv@cicada@continue
+ \expandafter\expandafter\expandafter\skv@cicada@picknext
\fi
\fi
}%
- \def\skv@cicada@lookahead@b[##1]{\skv@cicada@continue[{##1}]}%
- \def\skv@cicada@lookahead@c(##1){\skv@cicada@continue({##1})}%
+ \def\skv@cicada@lookahead@c[##1]{\skv@cicada@picknext[{##1}]}%
+ \def\skv@cicada@lookahead@d(##1){\skv@cicada@picknext({##1})}%
\skvbreakloopfalse\lastcicadafalse
\skvifxTF\skv@cicada@userlist\@empty{%
\ifskvprocessempty\skv@cicada@callback{}\fi
}{%
- \skvexpandnext{\skv@cicada@lookahead\skv@cicada@do}%
+ \skvexpandnext{\skv@cicada@lookahead@a\skv@cicada@do}%
\skv@cicada@userlist#1\skv@cicada@nil#1\skv@cicada@stop
}%
\skvpopstate\skv@cicada@state\cicadaloopdepth
@@ -1270,11 +1340,12 @@
% \cicadiloop[<parser>]{<list>}<\if...>\fi{<ini-code>}{<1.parameter.code>}
% \cicadiloop*[<parser>]{<listcmd>}<\if...>\fi{<ini-code>}{<1.parameter.code>}
%
-% It is easy to forget to turn conditional #3 off before commencing
+% It is easy to forget to turn conditional <\if...> off before commencing
% the loop, especially if it is a boolean. The conditional might have
% been set true before calling \cicadaloop, and this may invalidate
-% later tests to terminate the loop prematurely. #4 can be used to turn
-% the condtional off before commencing the loop.
+% later tests to terminate the loop prematurely. <ini-code> can be used
+% to turn the condtional off before commencing the loop. This forces the
+% user to heed this term.
%
\skvrobustdef*\cicadiloop{\skv@teststopt\skv@cicadiloop,}
\skvrobustdef*\skv@cicadiloop[#1]#2#3\fi#4{%
@@ -1306,7 +1377,7 @@
%
% \lpsdeclarelistnormalizer<normalizer.cmd>{<parser>}
%
-% Eg,
+% Example:
%
% \lpsdeclarelistnormalizer\lpscommanormalize{,}
%
@@ -1314,7 +1385,7 @@
%
\skvrobustdef*\lpsdeclarelistnormalizer#1#2{%
\skvifescapedTF{#1}{}{%
- \skv@err{Token \detokenize{#1} isn't escaped}\@ehd
+ \skv@err{Token \detokenize{#1} isn't escaped}\skv@ehd
}%
\def\reserved@a{\lps@declarelistnormalizer{#1}}%
\expandafter\reserved@a\expandafter{\string#2}%
@@ -1355,14 +1426,16 @@
\lpsdeclarelistnormalizer\lpsslashnormalize{/}
% Declare an expandable csv list parser. No premature stopping of the loop
-% is possible by this scheme. To use, first do
+% is possible by this scheme. To use this scheme, first do
%
% \lpsdeclareexpandablelistparser<processor.cmd><processor.func>{<parser>}
-% \def<processor.function>{<1-parameter callback>}
+% \def<processor.func>{<1-parameter callback>}
%
% and then call
%
-% <processor.cmd><list> or <processor.cmd>*<listcmd>.
+% <processor.cmd><list> or <processor.cmd>*<listcmd>
+%
+% <list> or <listcmd> will be normalized before being parsed.
%
% Example:
%
@@ -1399,38 +1472,21 @@
}%
}%
}
-
-\skvrobustdef*\lpsAtBeginEnvironment#1{%
- \skvaftercs\skvappendtomacro{lps@atbegin@#1@hook}%
-}
-\skvrobustdef*\lpsAtEndEnvironment#1{%
- \skvaftercs\skvappendtomacro{lps@atend@#1@hook}%
-}
-
-\skvpatchcmd\begin
- {\csname#1\endcsname}
- {\skvcsuse{lps@atbegin@#1@hook}\csname#1\endcsname}
- {}
- {\skv@err{Patching '\string\begin' failed!\MessageBreak
- '\string\lpsAtBeginEnvironment' will not work\@gobble}\@ehd
- }
-
-\skvpatchcmd\end
- {\csname end#1\endcsname}
- {\skvcsuse{lps@atend@#1@hook}\csname end#1\endcsname}
- {}
- {\skv@err{Patching '\string\end' failed!\MessageBreak
- '\string\lpsAtEndEnvironment' will not work\@gobble}\@ehd
- }
-
-% Without the following patch, drawing intructions like
+% Unfortunately, without the following patch, drawing instructions like
+%
+% \draw[blue] (p) \newforeach \p in {1,...,8}{...};
+%
+% will not work, because of the way TikZ hardwires \foreach for this type
+% of task (ie, when \draw precedes \newforeach or \foreachfox). The fact
+% here is that in this case, both \newforeach and \foreachfox can't work
+% but leave everything for \foreach. This can be a problem when \newforeach
+% or \foreachfox is called to avoid a known bug in \foreach, such as at
%
-% \draw[blue] (p) \newforeach \p in {1,...,8}{...};
+% <http://tex.stackexchange.com/questions/79586/foreach-has-a-problem%
+% -with-initially-argument-in-remember-part/79644#79644>
%
-% will not work, because of the way tikZ hardwires \foreach
-% for this type of task.
%
-\lpsAtBeginEnvironment{tikzpicture}{%
+\skvAtBeginEnvironment{tikzpicture}{%
\def\tikz@handle@more{%
\ifx\@let@token a\let\@next=\tikz@arcA\else
\ifx\@let@token e\let\@next=\tikz@e@char\else