%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'loops.sty', version 1.1, October 2012.                     %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or any later version. The latest      %
% version of this license is in http://www.latex-project.org/lppl.txt      %
% and version 1.3 or later is part of all distributions of LaTeX           %
% version 2005/12/01 or later.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com).                  %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\begingroup
\catcode035 06 % #
\catcode064 11 % @
\catcode123 01 % {
\catcode125 02 % }
\catcode044 12 % ,
\def\skv@prova{\endgroup
  \def\do##1,{%
    \ifx\do##1\else
      \catcode##1\string=\the\catcode##1\relax
      \expandafter\do
    \fi
  }%
  \edef\loops@restorecodes{\do035,064,123,125,061,059,\do,}%
}
\skv@prova
\catcode035 06 % #
\catcode064 11 % @
\catcode123 01 % {
\catcode125 02 % }
\catcode061 12 % =
\catcode044 12 % ,
\def\do#1=#2,{%
  \ifx#1\do\else
    \edef\loops@restorecodes{%
      \loops@restorecodes
      \catcode#1=\the\catcode#1\relax
    }%
    \catcode#1=#2\relax
    \expandafter\do
  \fi
}
\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/14 v1.1 Loops and list processors (AM)]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]

% This is the way to load 'skeyval-for-core' here, otherwise we
% can't access some of the needed commands from 'skeyval-core':

\@ifpackageloaded{skeyval}{}{\RequirePackage{skeyval}}

\skvnewlet\ltxkernelfor\@for
\skvnewlet\ltxkerneltfor\@tfor

% \skvusetwoprev{<parser>}{<list>}{<target.item>}{<do.on.target>}
%
% Example:
%
%  \skvusetwoprev{,}{a,b,c,d,e,f}{e}{}
%
\skvrobustdef*\skvusetwoprev#1#2#3#4{%
  \skvifin{#1#3#1}{#1#2#1}{}{%
    \skv@err{There is not '\detokenize{#3}' in the list}\@ehd
  }%
  \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
  }%
  \skv@do#2#1\skv@nnil#1%
}

% A version of D.E. Knuth's \loop:
%
\skvnewdef\dekloop#1\repeat{\skv@dekloop{#1}}
\skvnewdef\skv@dekloop#1{%
  #1\relax
    \expandafter\skv@dekloop
  \else
    \expandafter\@gobble
  \fi
  {#1}%
}

% A version of D.E. Knuth's \loop that can be nested.
% Credit: David P. Carlisle.
%
% \carlisleloop\a
%   \carlisleloop\b
%     ...
%     \if...
%   \repeat\b
%   ...
%   \if...
% \repeat\a
%
\let\repeat\fi
\skvrobustdef*\carlisleloop#1{%
  \long\def\skv@carlisleloop##1##2\repeat#1{%
    \long\def##1{##2\relax\expandafter##1\fi}%
    ##1\let##1\relax
  }%
  \expandafter\skv@carlisleloop
  \csname skv@carlisleloop@\string#1\endcsname
}

% A version of D.E.Knuth's \loop that can be nested naturally.
%
% 1. As a design constraint, this doesn't accept \par.
%
% 2. ak=Wilhelm Ackermann, ter=Rózsa Péter; in honour of these
%    mathematicians.
%
% \akterloop
%   \akterloop
%     ...
%     \if...
%   \repeat
%   ...
%   \if...
% \repeat
%
\skvnewregister\toks\skv@aktertoks
\skvnewdef*\skv@aktercnt{0}
\skvrobustdef*\skv@akter@defloop{%
  \def\skv@tempa##1##2##3{%
    \def\skv@tempa{##1}%
    \def\skv@tempb{##2}%
    \let##2\fi
    \gdef##1####1##2{%
      \def##3{####1\relax\expandafter##3\fi}%
      ##3\let##3\relax
    }%
  }%
  \def\x##1{%
    \skvnoexpandcs{skv@akter@##1@\skvrom\skv@aktercnt}%
  }%
  \edef\x{\x{loop}\x{repeat}\x{iterate}}%
  \expandafter\skv@tempa\x
}
\skvrobustdef*\akterloop{%
  \begingroup
  \everyeof{EOF}\def\skv@aktercnt{0}%
  \skv@aktertoks{\dekloop}%
  \skv@akterpush
}
\skvrobustdef*\skv@akterpush{\futurelet\next\skv@akterpush@a}
% Use star variant of \skvrobustdef here, to catch \par:
\skvrobustdef*\skv@akterpush@a#1{%
  \skvifntype{#1}{%
    \skvifx{#1}\akterloop{%
      \skvadvanceno\skv@aktercnt\@ne
      \skv@akter@defloop
      \skv@aktertoks\expandafter
        {\the\expandafter\skv@aktertoks\skv@tempa}%
      \skv@akterpush
    }{%
      \skvifstrcmp{#1}\repeat{%
        \skvifnum\skv@aktercnt=\skvz@{%
          \expandafter\endgroup\the\skv@aktertoks\repeat
        }{%
          \skv@aktertoks\expandafter
            {\the\expandafter\skv@aktertoks\skv@tempb}%
          \skvadvanceno\skv@aktercnt\m@ne
          \skv@akterpush
        }%
      }{%
        \skvifx\next\@sptoken{%
          \skv@aktertoks\expandafter
            {\the\expandafter\skv@aktertoks\@space#1}%
        }{%
          \skv@aktertoks\expandafter{\the\skv@aktertoks#1}%
        }%
        \skv@akterpush
      }%
    }%
  }{%
    \skvifstrcmp{#1}{EOF}{%
      \skv@err{'\string\repeat' not found: endless loop}\@ehd
    }{%
      \skvifx\next\@sptoken{%
        \skv@aktertoks\expandafter
          {\the\expandafter\skv@aktertoks\space{#1}}%
      }{%
        \skv@aktertoks\expandafter{\the\skv@aktertoks{#1}}%
      }%
      \skv@akterpush
    }%
  }%
}

% Expandable comma loop. List is not normalized prior to parsing, and
% it is not possible to terminate the loop prematurely.
%
% \skvfor{<list>}<callback.macro>
%
% Example:
%
% \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}
% \show\x -> \let\cmda\cmda@ii \let\cmdb\cmdb@ii
%
\skvnewdef\skvfor#1#2{\skv@for@a{#2}#1,\skv@for@nil,}
\skvnewdef\skv@for@a#1#2,{%
  \skvifblank{#2}{%
    \skv@for@a{#1}%
  }{%
    \skvifstrcmp{#2}\skv@for@nil{}{#1{#2}\skv@for@a{#1}}%
  }%
}

% Process non-separated (token-wise) list:
%
% \ayeloop{<list>}\do{<1.parameter.callback>}
% \ayeloop*{<listcmd>}\do{<1.parameter.callback>}
%
%  \ayeloop abcd\do{%
%    \def\nr{0}%
%    \ayeloop 12345\do{%
%      \typeout{Doing #1--##1}%
%      \skvpushnumber\nr
%      \ifnum\nr>3\relax\skvbreakloop\fi
%    }%
%  }%
%
% \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
  \skvsavestate\ayeloop{\do\skv@ayeloop}\skv@csvdepth
  \def\skv@ayeloop##1{%
    \skvifstrcmp{##1}\skv@tfor@nil{%
      \skvbreakloopfalse
    }{%
      #2\relax
      \ifskvbreakloop
        \skvbreakloopfalse
        \begingroup
        \def\skv@ayeloop####1\skv@tfor@nil{%
          \endgroup
          \edef\skvremainder{\unexpanded{####1}}%
        }%
      \fi
      \skv@ayeloop
    }%
  }%
  \skvbreakloopfalse
  \expandafter\skv@ayeloop\skv@tempa\skv@tfor@nil
  \skvrestorestate\ayeloop\skv@csvdepth
}

% Robust, outer-brace-preserving, multi-level, general-purpose
% non-separated values list (nsv) processor.
%
% \sifakaloop{<list>}{<1.parameter.callback>}
% \sifakaloop*{<listcmd>}{<1.parameter.callback>}
%
\skvnewdef*\skv@tsvnil{\skv@tsvnil}
\skvrobustdef*\sifakaloop{\skv@testst\skv@sifakaparse@a}
\skvrobustdef*\skv@sifakaparse@a#1#2{%
  \skv@usetempst{#1}\skv@sifakaarg
  \skvsavestate\sifakaloop{\do\skv@user@do}\skv@csvdepth
  \def\skv@user@do##1{#2}%
  \edef\skv@sifakaarg{%
    \expandafter\skvtsvnormalize\expandafter{\skv@sifakaarg}%
  }%
  \skvbreakloopfalse
  \skvifempty\skv@sifakaarg{%
    \ifskvprocessempty\skv@user@do{}\fi
  }{%
    \expandafter\skv@sifakaparse@b\skv@sifakaarg\skv@tsvnil
  }%
  \skvrestorestate\sifakaloop\skv@csvdepth
  \ifnum\skv@csvdepth=\skvz@\skvundef\skv@user@do\fi
}
\skvrobustdef*\skv@sifakaparse@b{%
  \begingroup
  \let\bgroup\relax
  \skvifnextchar\skv@orig@bgroup{%
    \let\skv@next\skv@orig@bgroup
    \skv@sifakaparse@c
  }{%
    \let\skv@next\relax
    \skv@sifakaparse@c
  }%
}
\skvrobustdef*\skv@sifakaparse@c#1{%
  \skvifx\skv@next\skv@orig@bgroup{%
    \endgroup
    \edef\skv@sifakaarg{{\unexpanded{#1}}}%
  }{%
    \endgroup
    \edef\skv@sifakaarg{\unexpanded{#1}}%
  }%
  \skvifx\skv@sifakaarg\skv@tsvnil{%
    \skvbreakloopfalse
  }{%
    \skvifx\skv@sifakaarg\skv@listbreakertoks{%
      \skvbreakloop
    }{%
      \skvifempty\skv@sifakaarg{%
        \ifskvprocessempty\skv@user@do{}\fi
      }{%
        \expandafter\skv@user@do\expandafter{\skv@sifakaarg}\relax
      }%
      \skvifdefbool{skvbreakloop}{%
        \skvbreakloopfalse
        \begingroup
        \def\skv@prova##1\skv@tsvnil{%
          \endgroup
          \edef\skvremainder{\unexpanded{##1}}%
        }%
        \skv@prova
      }{%
        \skv@sifakaparse@b
      }%
    }%
  }%
}

% Processing both csv and tsv/nsv lists with \foxloop.
%
% \foxloop[<options>]{<list>}{<parametered.callback>}
% \foxloop*[<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.
%
% 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.
%
% 5. \subcallback is meant for callbacks with hash characters that may be
%    confused with the parameters of the main <callback>. It can be defined
%    outside <callback> and called within <callback>.
%
% 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}

% Define \foxloop 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{skvfoxloop}{%
  parser/{,}/
    \def\skv@foreach@parser{#1}
    \skvstripouterbraces{2}\skv@foreach@parser
  ;
  list is a macro,macro list/true/
    \edef\skv@foreach@listismacro{0\skvifstrcmp{#1}{true}01}
    /true,false
  ;
  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};
  normalize list/true/
    \edef\skv@foreach@normalizelist{0\skvifstrcmp{#1}{true}01}
    /true,false
  ;
  use empty,use empty items/true/
    \edef\skv@foreach@useempty{0\skvifstrcmp{#1}{true}01}
    /true,false
  ;
  .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
    \fi
  ;
  item counter,counter/\@nil/
    \def\skv@foreach@itemcounter{#1}
  ;
  % This default value of 'link' is required by \skv@foreach@filllist:
  .exec/\def\skv@foreach@link{\@nil};
  link/\@nil/
    \ifskvindef\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{\skvifstrcmp{#1}{left}{right}{left}}%
        \skvcsedef{skv@foreach@grow\skv@prova}{01}%
      \fi
    \fi
    /left,right
  ;
  .exec/
    \def\skv@foreach@growleft{01}%
    \def\skv@foreach@growright{01}%
  ;
  grow left/true/
    \ifskvindef\else
      \edef\skv@foreach@growleft{0\skvifstrcmp{true}{#1}01}%
      \edef\skv@foreach@growright{0\skvifstrcmp{true}{#1}10}%
    \fi
    /true,false
  ;
  grow right/true/
    \ifskvindef\else
      \edef\skv@foreach@growright{0\skvifstrcmp{true}{#1}01}%
      \edef\skv@foreach@growleft{0\skvifstrcmp{true}{#1}10}%
    \fi
    /true,false
  ;
  % Keep the decimals in rounded numbers or dimensions when list is
  % auto-completed. The value value of this key is 'true'.
  keep decimals/true/
    \edef\skv@foreach@keepdecimals{0\skvifstrcmp{true}{#1}01}%
    /true,false
  ;
  keep high decimals,keep only high decimals/true/
    \edef\skv@foreach@keephighdecimals{0\skvifstrcmp{true}{#1}01}%
    /true,false
  ;
  expand before fill/true/
    \edef\skv@foreach@expandbeforefill{0\skvifstrcmp{true}{#1}01}%
    /true,false
  ;
  % Eg, 'evaluate = #1 as \x using \numexpr#1*2'.
  % Since the parameters haven't assumed arguments, we defer the
  % call to \skv@fox@parseevaluate until the arguments are known.
  evaluate/\@nil/
    \skv@foreach@ifacceptkv{#1}{%
      \skv@fox@parseevaluate{#1}%
    }%
  ;
  % Eg,
  %    'count in = \p all #1 satisfying \ifnum#1>4\fi initially 2'
  %    'count in = \p all #1 satisfying \ifnum#1>4\fi'
  count in,count/\@nil/
    \skv@foreach@ifacceptkv{#1}{%
      \skv@fox@parsecountin{#1}%
    }%
  ;
  % Eg, remember=#1 as \y initially A
  remember/\@nil/
    \skv@foreach@ifacceptkv{#1}{%
      \skv@fox@parseremember{#1}%
    }%
  ;
  reverse list,reverse/true/
    \edef\skv@foreach@reverselist{0\skvifstrcmp{true}{#1}01}%
    /true,false
  ;
}

% Set up \foxloop defaults:
\quickkeys.set{skvfoxloop}{%
  parser={,},
  list is a macro=false,
  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,
}

% Parser for 'evaluate' key:
%
% Eg, 'evaluate = #1 as \x using \numexpr#1*2'.
%
% \skv@fox@parseevaluate differs from \skv@foreach@parseevaluate
% because #1 here is likely to be a non-macro.
%
\skvrobustdef*\skv@fox@parseevaluate#1{%
  \begingroup
  \def\skv@tempxifin##1##2{%
    \skvxifin{\detokenize{##1}}{\detokenize{##2}}%
  }%
  \def\skv@tempd{}%
  % <formula> #3 can be empty. So we don't test for its emptiness here.
  \def\skv@tempa##1as##2using##3\skv@nil{%
    \edef\skv@prova{\skvtrimspace{##1}}%
    \edef\skv@provb{\skvtrimspace{##2}}%
    \edef\skv@provc{\skvtrimspace{##3}}%
    \ifx\skv@prova\@empty
      \skv@err{Value of key 'evaluate':
         \MessageBreak no quantity to evaluate}\@ehd
    \fi
    \ifx\skv@provb\@empty
      \skv@err{Value of key 'evaluate' has no receiving macro,
        \MessageBreak i.e., after 'as'}\@ehd
    \else
      \expandafter\skvifescaped\expandafter{\skv@provb}{}{%
        \skv@err{Value of key 'evaluate': receiving macro
          \MessageBreak \skvoxdetok\skv@provb not escaped}\@ehd
      }%
    \fi
    \ifx\skv@provc\@empty
      \skv@err{Value of key 'evaluate' has no formula}\@ehd
    \fi
    \skv@tempxifin{\pgfmathparse}{##3}{%
      \def\skv@tempc####1\pgfmathparse####2\skv@nil{%
        \ifx\@nnil####1\@nnil
          \ifdefined\pgfmathparse
            \skv@foreach@swatrue
          \else
            \skv@err{\noexpand\pgfmathparse isn't defined;
              \MessageBreak maybe 'pgfmath' isn't loaded}\@ehd
          \fi
        \else
          \skv@err{Invalid token \detokenize{####1}
            \MessageBreak before \string\pgfmathparse}\@ehd
        \fi
      }%
      \expandafter\skv@tempc\skv@provc\skv@nil
    }{%
      \skv@foreach@swafalse
      \skv@tempxifin{\numexpr}{##3}{%
        \def\skv@tempd{\relax}%
      }{%
        \skv@tempxifin{\dimexpr}{##3}{%
          \def\skv@tempd{\relax}%
        }{%
          \def\skv@tempd{}%
        }%
      }%
    }%
  }%
  \skv@tempxifin{using}{#1}{%
    \skv@tempxifin{as}{#1}{%
      % 'as' and 'using' are present: there is a formula.
      \skv@foreach@swbtrue
      \skv@tempa#1\skv@nil
    }{%
      \skv@err{Value of key 'evaluate':
        \MessageBreak there is 'using', but no 'as'}\@ehd
    }%
  }{%
    % No formula given:
    \skv@foreach@swbfalse
    \skv@tempxifin{as}{#1}{%
      \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
        \else
          \ifx\@nnil##2%
            \skv@err{Value of key 'evaluate' has no receiving macro}\@ehd
          \else
            \skv@tempa##1as##2using##1\skv@nil
          \fi
        \fi
      }%
      \skv@tempb#1{\@nnil}\skv@nil
    }{%
      % No 'as' or 'using'. In \foxloop, #1 is not guaranteed
      % to be a macro. Hence raise error here:
      \skv@err{Value of key 'evaluate' has no 'as'}\@ehd
    }%
  }%
  \skv@foreach@addtocallback{pre}{%
    \ifskv@foreach@swa
      % Here, <formula> may have the syntax \pgfmathresult{<token>}.
      \skvexpandonce\skv@provc
      \let\skvexpandonce\skv@provb\noexpand\pgfmathresult
    \else
      % Here, <formula> may have the syntax \numexpr\x*2 or \dimexpr\x*2.
      \edef\skvexpandonce\skv@provb{%
        \ifskv@foreach@swb\noexpand\the\fi
        \skvexpandonce\skv@provc\skvexpandonce\skv@tempd
      }%
    \fi
  }%
  \skvaftergroupdef\skv@foreach@precallback\endgroup
}

% Eg, 'count in \y all #1 satisfying \ifnum#1>2\fi initially 0'.
%
% 1. <condition> must be a balanced and valid TeX or LaTeX (2-fork)
%    conditional, like
%
%    \ifnum\x>2\fi, \ifx\x\@empty\fi
%
% 2. The aim is to allow general conditions (not only those involving
%    numerals) to be submitted.
%
% 3. PGF's \foreach doesn't have this feature; it has only a general
%    counter, eg,
%
%    '\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:
%
%    \iflastfox\typeout{Processing last entry of the list} \fi
%
\skvrobustdef*\skv@fox@parsecountin#1{%
  \begingroup
  \def\skv@tempxifin##1##2{%
    \skvxifin{\detokenize{##1}}{\detokenize{##2}}%
  }%
  \def\skv@tempa##1\skv@nil{%
    \skv@tempxifin{initially}{##1}{%
      \skv@tempb##1\skv@nil
    }{%
      \skv@tempb##1initially\skv@nil
    }%
  }%
  \def\skv@tempb##1all##2satisfying##3initially##4\skv@nil{%
    \edef\skv@prova{\skvtrimspace{##1}}%
    \edef\skv@provb{\skvtrimspace{##2}}%
    \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
    \else
      \expandafter\skvifescaped\expandafter{\skv@prova}{}{%
        \skv@err{Value of key 'count':\MessageBreak
          counter macro \skvoxdetok\skv@prova not escaped}\@ehd
      }%
    \fi
    \ifx\skv@provd\@empty
      \expandafter\def\skv@prova{0}%
    \else
      \skvifinteger\skv@provd{%
        \expandafter\let\skv@prova\skv@provd
      }{%
        \skv@err{Value of key 'count':\MessageBreak
          initial \skvoxdetok\skv@provd not an integer}\@ehd
      }%
    \fi
    \skv@foreach@swafalse
    \ifx\skv@provc\@empty
      % No tester but there may be a quantity to test. The quantity,
      % on its own, isn't sufficient to conduct a test:
      \let\skv@foreach@itemcounter\skv@prova
    \else
      % If there isn't a quantity to test, then no test is possible:
      \ifx\skv@provb\@empty\else
        \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
      \fi
    \fi
  }%
  \skv@tempxifin{satisfying}{#1}{%
    \skv@tempxifin{all}{#1}{%
      % 'all' and 'satisfying' are present:
      \skv@tempa#1\skv@nil
    }{%
      \skv@err{Value of key 'count':
        \MessageBreak there is 'satisfying', but no 'all'}\@ehd
    }%
  }{%
    \skv@tempxifin{all}{#1}{%
      \skv@tempa#1satisfying\skv@nil
    }{%
      % 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
      \else
        \skvifntype{#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
        }%
      \fi
    }%
  }%
  \ifskv@foreach@swa
    \skv@foreach@addtocallback{pre}{%
      \noexpand\ifnum\noexpand\foreachitemcount=\@ne
        \def\skvexpandonce\skv@prova{\number\skv@prova}%
      \noexpand\fi
      \skvexpandonce\skv@tester{%
        \noexpand\skvpushnumber\skvexpandonce\skv@prova
      }{}%
    }%
  \fi
  \skvexpanded{\endgroup
    \ifskv@foreach@swa
      \skvcmdexit\skv@foreach@precallback
    \else
      \skvcmdexit\skv@foreach@itemcounter
    \fi
  }%
}

% remember=<holder.macro> as <child.macro> initially <value>
%
\skvrobustdef*\skv@fox@parseremember#1{%
  \begingroup
  \def\skv@tempxifin##1##2{%
    \skvxifin{\detokenize{##1}}{\detokenize{##2}}%
  }%
  \skv@tempxifin{(}{#1}{%
    \skv@err{Value of key 'remember': '(' found.
      \MessageBreak I don't accept this PGF format.
      \MessageBreak remove the parenthesis '()'}\@ehd
  }{}%
  \def\skv@tempa##1as##2initially##3\skv@nil{%
    \edef\skv@prova{\skvtrimspace{##1}}%
    \edef\skv@provb{\skvtrimspace{##2}}%
    \edef\skv@provc{\skvtrimspace{##3}}%
    \skv@foreach@swafalse
    \ifx\skv@prova\@empty
      \skv@err{Value of key 'remember' has no value to remember}\@ehd
    \fi
    \ifx\skv@provb\@empty
      \skv@err{Value of key 'remember' has no child macro;
        \MessageBreak i.e., no macro after 'as'}\@ehd
    \else
      \expandafter\skvifescaped\expandafter{\skv@provb}{%
        \skv@foreach@swatrue
      }{%
        \skv@err{Value of key 'remember':
          \MessageBreak child \skvoxdetok\skv@provb not escaped}\@ehd
      }%
    \fi
  }%
  \skv@tempxifin{initially}{#1}{%
    \skv@tempxifin{as}{#1}{%
      \skv@tempa#1\skv@nil
    }{%
      \skv@err{Value of key 'remember':
        \MessageBreak there is 'initially', but no 'as'}\@ehd
    }%
  }{%
    \skv@tempxifin{as}{#1}{%
      \skv@tempa#1initially\skv@nil
    }{%
      % 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
        % holder macros.
        \skv@err{Value of key 'remember' is incomplete: no 'as'}\@ehd
      \fi
    }%
  }%
  \ifskv@foreach@swa
    % Initially:
    \skv@foreach@addtocallback{pre}{%
      % Don't remove this \ifnum, otherwise the initial assignment
      % will be overwritten on subsequent returns:
      \noexpand\ifnum\noexpand\foreachitemcount=\@ne
        \edef\skvexpandonce\skv@provb{%
          \noexpand\unexpanded{\skvexpandonce\skv@provc}%
        }%
      \noexpand\fi
    }%
    \skv@foreach@addtocallback{post}{%
      \edef\skvexpandonce\skv@provb{%
        \noexpand\unexpanded{\skvexpandonce\skv@prova}%
      }%
    }%
  \fi
  \skvexpanded{\endgroup
    \ifskv@foreach@swa
      \skvcmdexit\skv@foreach@precallback
      \skvcmdexit\skv@foreach@postcallback
    \fi
  }%
}

\skvnewdef*\skv@foxloop@kvlist{}
% \setupfoxloop{<kvlist>}
\skvrobustdef*\setupfoxloop#1{%
  \skvifblank{#1}{}{%
    \skvaddtolist\skv@foxloop@kvlist{#1}%
  }%
}
\skvrobustdef*\skv@foxloop@setkeys#1{%
  \def\reserved@a{\quickkeys.set{skvfoxloop}}%
  \expandafter\reserved@a\expandafter{\skv@foxloop@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{%
  \ifskv@tempst
    \def\skv@foreach@st{00}%
  \else
    \def\skv@foreach@st{01}%
  \fi
  \skv@foreach@pushstate
  \skv@foreach@latehookerr
  \def\foreachitemcount{0}%
  \def\skv@foreach@callback{}%
  \def\skv@foreach@precallback{}%
  \def\skv@foreach@postcallback{}%
  \def\skv@foreach@onlyinitially{}%
  \skv@foxloop@setkeys{#1}%
  \if\skv@foreach@st\else
    \if\skv@foreach@listismacro
      \def\skv@foreach@st{00}%
    \else
      \def\skv@foreach@st{01}%
    \fi
  \fi
  \edef\skv@foreach@userlist{%
    \if\skv@foreach@st
      \expandafter\skvexpandonce
    \else
      \expandafter\unexpanded
    \fi
    {#2}%
  }%
  \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachdepth}%
  \edef\reserved@a{%
    \skvexpandonce\skv@foreach@precallback
    \ifx\skv@foreach@onlyinitially\@empty\else
      \noexpand\ifnum\noexpand\foreachitemcount=\@ne
        \skvexpandonce\skv@foreach@onlyinitially
      \noexpand\fi
    \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
  }%
  \expandafter\reserved@b\expandafter{\reserved@a}%
  \skvxifstrcmp\skv@foreach@listtype{csv}{%
    \def\skv@foreach@lookahead@a##1{%
      \def\skv@foreach@continue{##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@a##1{%
      \let\skv@foreach@continue##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@b{%
    \skvifx\skv@foreach@next[{%
      \skv@foreach@parenthtrue\skv@foreach@lookahead@c
    }{%
      \skvifx\skv@foreach@next({%
        \skv@foreach@parenthtrue\skv@foreach@lookahead@d
      }{%
        \skv@foreach@parenthfalse\skv@foreach@continue
      }%
    }%
  }%
  \skvbreakloopfalse\lastfoxfalse
  \def\reserved@a##1{%
    \skv@setupgetnextfox{##1}%
    \skvxifstrcmp\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}%
      }%
      \skvifempty\skv@foreach@userlist{}{%
        \expandafter\skv@foreach@filllist\expandafter
          {\skv@foreach@parser}\skv@foreach@userlist
        \if\skv@foreach@reverselist\skvafterfi
          \expandafter\skv@foreach@doreverselist\expandafter
            {\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@normalizelist
        \edef\skv@foreach@userlist{%
          \skvexpbracenext\skvtsvnormalize\skv@foreach@userlist
        }%
      \fi
      \def\skv@foreach@do{%
        \let\bgroup\relax
        \futurelet\skv@foreach@next\skv@foreach@do@a
      }%
      \def\skv@foreach@do@a####1####2\skv@foxloop@stop{%
        \let\bgroup\skv@orig@bgroup
        \ifskv@foreach@parenth
          \edef\currentfox{\unexpanded{####1}}%
        \else
          \skvifx\skv@foreach@next\bgroup{%
            \edef\currentfox{{\unexpanded{####1}}}%
          }{%
            \edef\currentfox{\unexpanded{####1}}%
          }%
        \fi
        \skv@foxloop@a{}{####2}{tsv}%
      }%
      \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do
        \skv@foreach@userlist\skv@foxloop@nil\skv@foxloop@stop
    }%
  }%
  \expandafter\reserved@a\expandafter{\skv@foreach@parser}%
  \skvcsuse{skv@foreach@atendhook@\romannumeral\foreachdepth}%
  \skv@foreach@popstate
}
% \skv@setupgetnextfox<parser>
\skvrobustdef*\skv@setupgetnextfox#1{%
  \skvxifstrcmp\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{%
      \begingroup
      \let\bgroup\relax
      \futurelet\skv@foreach@next\skv@foreach@g@tnext
    }%
    \def\skv@foreach@g@tnext##1##2\skv@foxloop@stop{%
      \let\bgroup\skv@orig@bgroup
      \ifskv@foreach@parenth
        \edef\nextfox{\unexpanded{##1}}%
      \else
        \skvifx\skv@foreach@next\bgroup{%
          \edef\nextfox{{\unexpanded{##1}}}%
        }{%
          \edef\nextfox{\unexpanded{##1}}%
        }%
      \fi
    }%
  }%
}
% \skv@foxloop@a<parser><remainder><list.type>
\skvrobustdef*\skv@foxloop@a#1#2#3{%
  \skvifx\currentfox\skv@foxloop@nnil{%
    \skvbreakloopfalse\lastfoxfalse
  }{%
    \skvifx\currentfox\skv@listbreakertoks{%
      \skv@foxloop@getrm{#1}{#2}%
    }{%
      \skvifx\currentfox\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}}%
        \skvxifstrcmp\@gtempa{x}{%
          \skv@foxloop@getrm{#1}{#2}%
        }{%
          \skv@foxloop@b{#1}{#2}{#3}%
        }%
      }{%
        \skv@foxloop@b{#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{}%
  \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
  \fi
  \skvifempty\currentfox{%
    \if\skv@foreach@useempty
      \expandafter\skv@foreach@callback\expandafter\foreacheov
    \fi
  }{%
    % Tes for \listpauser, in case the user decides to continue
    % after \listpauser has been picked:
    \skvifx\currentfox\skv@listpausertoks{}{%
      \skvifx\skv@foreach@paramlist\skv@simplearg{%
        \expandafter\skv@foreach@callback\expandafter
          {\currentfox}\foreacheov
      }{%
        \expandafter\skv@foreach@callback\currentfox\foreacheov
      }%
    }%
  }%
  \skv@foreach@exittester{\skvbreakloop}{}%
  \skvifdefbool{skvbreakloop}{%
    \skvbreakloopfalse\lastfoxfalse
    \skv@foxloop@getrm{#1}{#2}%
  }{%
    \skv@foreach@lookahead@a\skv@foreach@do#2\skv@foxloop@stop
  }%
}
% \skv@foxloop@getrm<parser><remaining.items>
\skvrobustdef*\skv@foxloop@getrm#1#2{%
  \begingroup
  \def\reserved@a##1\skv@foxloop@nil#1{%
    \endgroup
    \edef\foxlistremainder{\unexpanded{##1}}%
  }%
  \reserved@a#2%
}

% \cicadaloop[<parser>]{<list>}<\if...>\fi{<1.parameter.code>}
% \cicadaloop*[<parser>]{<listcmd>}<\if...>\fi{<1.parameter.code>}
%
% 1. When the conditional <\if...> isn't true, the regular code
%    will be executed for every member of the list.
% 3. \ifskvbreakloop may be used as the conditional in <\if...>.
% 5. The boolean \iflastcicada is available for accessing the last item
%    of the list. There are also the macros \currentcicada, \lastcicada,
%    \cicadacount, and the counter \cicadaloopdepth.
% 6. \cicadaloop can be nested.
%
% Example:
%
%  \let\romn\romannumeral
%  \@tempcnta\z@
%  \def\blist{{X};{Y};Z;\fi}
%  \def\stack{}
%  \cicadaloop{{a},{b},c,\if}\if01\fi{%
%    \advance\@tempcnta\@ne
%    \@tempcntb\z@
%    \@tempswafalse
%    \cicadaloop*[;]\blist\if@tempswa\fi{%
%      \advance\@tempcntb\@ne
%      \typeout{Doing \romn\@tempcnta,\romn\@tempcntb: \detokenize{#1,##1}}%
%      \edef\stack{%
%        \unexpanded\expandafter{\stack}\noexpand\do
%        {\romn\@tempcnta,\romn\@tempcntb}{\unexpanded{#1;##1}}%
%      }%
%      \ifnum\@tempcntb>\@ne
%        \@tempswatrue
%        \skvcsedef{cmd@\romn\cicadaloopdepth}{\lastcicada,\cicadacount}%
%      \fi
%    }%
%  }
% \show\stack
%
\skvnewregisters\bool{\iflastcicada}
\skvbuildmacrostack\skv@cicada@state{%
  \do\skv@cicada@do\do\skv@cicada@userlist\do\currentcicada
  \do\nextcicada\do\cicadacount\do\lastcicada\do\skv@cicada@callback
  \do\skv@cicada@getnext\do\ifskvprocessempty
}\skv@stackdepthlimit

\skvnewnumbers{cicadaloopdepth}
\skvnewlet\skv@cicada@nil\relax
\skvnewdef*\skv@cicada@nnil{\skv@cicada@nil}
\skvnewlet\breakcicada\skvbreakloop

\skvrobustdef*\cicadaloop{\skv@teststopt\skv@cicadaloop,}
\skvrobustdef*\skv@cicadaloop[#1]#2#3\fi#4{%
  \let\if@cicada@st\ifskv@tempst
  \skvpushstate\skv@cicada@state\cicadaloopdepth
  \let\ifskv@tempst\if@cicada@st
  \skv@usetempst{#2}\skv@cicada@userlist
  \skv@foreach@normalize[#1]\skv@cicada@userlist
  \def\skv@cicada@callback##1{#4}%
  \def\lastcicada{}%
  \def\skv@cicada@getnext##1#1##2\skv@cicada@stop{%
    \edef\nextcicada{\skvexpandonce{\@gobble##1}}%
    \ifx\nextcicada\skv@cicada@nnil
      \lastcicadatrue
      \def\nextcicada{}%
    \fi
  }%
  \chardef\cicadacount\skvz@
  \def\skv@cicada@do##1#1##2\skv@cicada@stop{%
    \edef\currentcicada{\skvexpandonce{\@gobble##1}}%
    \skvifx\currentcicada\skv@cicada@nnil{%
      \skvbreakloopfalse\lastcicadafalse
    }{%
      \skvifx\currentcicada\skv@listbreakertoks{%
        \skvbreakloopfalse\lastcicadafalse
      }{%
        \edef\cicadacount{\the\numexpr\cicadacount+1}%
        \skv@cicada@lookahead\skv@cicada@getnext##2\skv@cicada@stop
        \skvexpandbracenext\skv@cicada@callback\currentcicada\relax
        \skvifnotcond#3\fi{}\skvbreakloop
        \skvifdefbool{skvbreakloop}{%
          \skvbreakloopfalse\lastcicadafalse
          \begingroup
          \def\skv@prova####1\skv@cicada@nil#1{%
            \endgroup
            \edef\skvremainder{\unexpanded{####1}}%
          }%
          \skv@prova##2%
        }{%
          \let\lastcicada\currentcicada
          \skv@cicada@lookahead\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{%
    \ifx\skv@next[%
      \expandafter\skv@cicada@lookahead@b
    \else
      \ifx\skv@next(%
        \expandafter\expandafter\expandafter\skv@cicada@lookahead@c
      \else
        \expandafter\expandafter\expandafter\skv@cicada@continue
      \fi
    \fi
  }%
  \def\skv@cicada@lookahead@b[##1]{\skv@cicada@continue[{##1}]}%
  \def\skv@cicada@lookahead@c(##1){\skv@cicada@continue({##1})}%
  \skvbreakloopfalse\lastcicadafalse
  \skvifx\skv@cicada@userlist\@empty{%
    \ifskvprocessempty\skv@cicada@callback{}\fi
  }{%
    \skvexpandnext{\skv@cicada@lookahead\skv@cicada@do}%
      \skv@cicada@userlist#1\skv@cicada@nil#1\skv@cicada@stop
  }%
  \skvpopstate\skv@cicada@state\cicadaloopdepth
}

% \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
% 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.
%
\skvrobustdef*\cicadiloop{\skv@teststopt\skv@cicadiloop,}
\skvrobustdef*\skv@cicadiloop[#1]#2#3\fi#4{%
  \skvexpandsecond
    {#4\relax\skv@cicadiloop}{\ifskv@tempst*\fi}%
    [#1]{#2}#3\fi
}

% \lpchangelistseparator
%  {<original.parser>}{<orig.listcmd>}{<new.parser>}{<new.listcmd>}
%
% Example:
%  \def\alist{{a/1,a/2};b;c}
%  \lpchangelistseparator{;}\alist{,}\blist
%
\skvrobustdef*\lpchangelistseparator#1#2#3#4{%
  \def#4{}%
  \cicadaloop*[#1]{#2}\if01\fi{}{}{%
    \edef#4{%
      \skvexpandonce#4{\unexpanded{##1}}%
      \iflastcicada\else#3\fi
    }%
  }%
}

\loops@restorecodes
\endinput
