summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-05-16 22:30:01 +0000
committerKarl Berry <karl@freefriends.org>2013-05-16 22:30:01 +0000
commit318d628c7989d4f9ede20b1ee66471bedf447437 (patch)
treee552e9f9b6195d98f3d579088419fdce722df49c /Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
parentf297f05f92068bd7f54e8ee25ce7b8b8a83c2353 (diff)
skeyval (16may13)
git-svn-id: svn://tug.org/texlive/trunk@30509 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.tex1061
1 files changed, 575 insertions, 486 deletions
diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex
index a61c4f0c499..205c019dc67 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.tex', version 1.2, 2013/02/10. %
+% This is file 'skeyval-for.tex', version 1.3, 2013/05/15. %
% %
% This package and accompanying files may be distributed and/or %
% modified under the conditions of the LaTeX Project Public License, %
@@ -18,10 +18,11 @@
% The following files constitute the skeyval bundle and must be %
% distributed as a whole: %
% %
-% readme, skeyval.sty, skeyval-core.tex, skeyval-for.tex, %
+% README, skeyval.sty, skeyval-core.tex, skeyval-for.tex, %
% skeyval-view.sty, skeyval-ltxpatch.sty, skeyval-ltxcmds.tex, %
% skeyval-pstkey.sty, skeyval-pstkey.tex, skeyval-testclass.cls, %
-% and skeyval-testpkg.sty. %
+% skeyval-testpkg.sty, skeyval-pokayoke1, skeyval-pokayoke2, %
+% skeyval-view-pokayoke1. %
% %
% Copyright (c) 2010-2013 Ahmed Musa (amusa22@gmail.com). %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
@@ -59,11 +60,11 @@
\expandafter\let\csname skeyval-for-loaded\endcsname\endinput
\ifx\ProvidesFile\@undefined
- \message{File 'skeyval-for.tex' 2013/02/10 v1.2
+ \message{File 'skeyval-for.tex' 2013/05/15 v1.3
Loops for skeyval package (AM)}
\else
\ProvidesFile{skeyval-for.tex}
- [2013/02/10 v1.2 Loops for skeyval package (AM)]
+ [2013/05/15 v1.3 Loops for skeyval package (AM)]
\@addtofilelist{skeyval-for.tex}
\fi
@@ -98,11 +99,10 @@
\expandafter\skv@provb\skv@prova
\skvgadvanceno#2\m@ne
}
-
\skvnewregisters\bool{%
\ifbreakallforeachloops,\ifskvbreakloop,\ifforeachlastitem,
\ifskvprocessempty,\ifskv@foreach@swa,\ifskv@foreach@swb,
- \ifskv@foreach@parenth,\ifskv@useemptylist
+ \ifskv@foreach@parenthesis,\ifskv@useemptylist,\ifskv@inforeach,
}
\skvnewlet\skvbreakloop\skvbreaklooptrue
\skvnewlet\breaknewforeach\skvbreaklooptrue
@@ -129,15 +129,16 @@
% 4. For comma lists, \skvcommaloop and \skvcommaparse are faster.
% See later.
% 5. For processing kv lists, use \skvparsekvlist.
+% 6. The preservation of outer braces isn't a priority in this loop.
%
\skvrobustdef*\skvdolist{\skv@useemptylistfalse\skv@testst\skv@dolist}
\skvrobustdef*\skv@dolist#1#2#3#4{%
+ \skv@usetempst{#2}#3%
% \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%
\edef\skv@dolist@callback{\unexpanded{#4}}%
\def\skvlistcount{0}%
\def\skv@dolist@a##1##2#1{%
@@ -290,7 +291,8 @@
% 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.
+% 3. These loops can be nested to any depth.
+% 4. The preservation of outer braces isn't a priority in these loops.
%
% \skvcommaloop{<list>}<holder-cmd>{<callback>}
% \skvcommaloop*{<listcmd>}<holder-cmd>{<callback>}
@@ -305,6 +307,7 @@
% Don't put \skvcsvnormalize#2 here. Use \skvcommaparse instead.
% Some callers of \skvcommaloop already have their lists normalized.
\skvifxTF#2\@empty{}{%
+ \skvbreakloopfalse
\skvexpandnext{\skv@commaloop@picknext#2{#3}}#2,\skv@commaloop@nil,%
}%
}
@@ -601,32 +604,7 @@
\fi
}%
}
-
-\begingroup
-\catcode`P=12 \lccode`P=112
-\catcode`T=12 \lccode`T=116
-\lowercase{\endgroup
- \def\skv@foreach@strippoint#1#2{%
- \def\reserved@a##1#1\relax{\def#2{##1}}%
- \def\do##1.##2PT#1{%
- \ifx\do##1\else##1%
- \if\skv@foreach@keephighdecimals
- \ifdim.##2pt>.5pt\relax##2\fi
- \else
- \if\skv@foreach@keepdecimals
- \ifnum##2>\skvz@.##2\fi
- \fi
- \fi
- \unexpanded{#1}%
- \expandafter\do
- \fi
- }%
- \edef#2{\expandafter\do#2#1\do.PT#1}%
- \expandafter\reserved@a#2\relax
- }
-}
-
-\quickkeys.define{skeyval/foreach}{%
+\skvquickkeys.define{skeyval/foreach}{%
.exec/
\def\skv@foreach@parser{,}
\def\skv@foreach@subparser{/}
@@ -793,7 +771,7 @@
\edef\skv@foreach@recoverholders{0\skvifstrcmpTF{true}{#1}01}%
/true,false
;
- % This default value of 'link' is required by \skv@foreach@filllist:
+ % This default value of 'link' is required by \skvautocompletelist:
.exec code/\def\skv@foreach@link{\@nil};
link/\@nil/
\edef\skv@prova{\unexpanded{#1}}%
@@ -819,12 +797,10 @@
;
grow left/true/
\edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}01}
- \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}10}
/true,false
;
grow right/true/
\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
@@ -845,7 +821,7 @@
/true,false
;
expand before fill,expand list before fill/true/
- \edef\skv@foreach@expandlistbeforefill{0\skvifstrcmpTF{true}{#1}01}
+ \edef\skv@foreach@expandbeforefill{0\skvifstrcmpTF{true}{#1}01}
/true,false
;
expand list once,x1,list is a macro,macro list/true/
@@ -866,6 +842,12 @@
\edef\skv@foreach@reverselist{0\skvifstrcmpTF{true}{#1}01}
/true,false
;
+ % 'hide parameters' can be used to avoid doubling the parameter
+ % characters in the callback.
+ hide parameters/true/
+ \edef\skv@foreach@hideparameters{0\skvifstrcmpTF{true}{#1}01}
+ /true,false
+ ;
}
% The following keys don't need presetting. The user must supply
@@ -875,13 +857,13 @@
% link,evaluate,,evaluate num,evaluate dim,expand,count in,
% process up to,grow
%
-\quickkeys.preset{skeyval/foreach}{%
+\skvquickkeys.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,
+ expand list twice=false,expand list fully=false,hide parameters=false
}
\skvnewdef*\skv@foreach@kvlist{}
@@ -892,7 +874,7 @@
}%
}
\skvrobustdef*\skv@foreach@setkeys#1{%
- \def\reserved@a{\quickkeys.set{skeyval/foreach}}%
+ \def\reserved@a{\skvquickkeys.set{skeyval/foreach}}%
\expandafter\reserved@a\expandafter{\skv@foreach@kvlist,#1}%
}
@@ -1497,13 +1479,14 @@
\skvrobustdef*\skv@foreach@pushstate{%
\skvsavestate\skv@foreach@stack{%
- \do\skv@foreach@seenstar\do\skv@foreach@parser
+ \do\skv@foreach@starform\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@continuetester
\do\skv@foreach@grow\do\skv@foreach@growleft\do\skv@foreach@growright
\do\skv@foreach@terminator\do\skv@foreach@recoverholders
\do\skv@foreach@normalizelist\do\skv@foreach@callback
+ \do\skv@foreach@hideparameters\do\skv@foreach@callback@hiddenparameters
\do\skv@foreach@auxcallback\do\skv@foreach@precallback
\do\skv@foreach@afterprecallback\do\skv@foreach@postcallback
\do\skv@foreach@onlyinitially
@@ -1518,7 +1501,7 @@
\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@expandbeforefill\do\skv@foreach@expandlistonce
\do\skv@foreach@expandlisttwice\do\skv@foreach@expandlistfully
\do\skv@listbreakertoks\do\skv@listpausertoks
\do\skv@foreach@reverselist\do\foreachcurrentitem
@@ -1536,7 +1519,8 @@
\skvnewdef*\skv@foreach@nnil{\skv@foreach@nil}
\skvrobustdef*\newforeach{\skv@testst\skv@newforeach@beginprescan}
\skvrobustdef*\skv@newforeach@beginprescan{%
- \edef\skv@foreach@seenstar{0\ifskv@tempst0\else1\fi}%
+ \skv@inforeachtrue
+ \edef\skv@foreach@starform{0\ifskv@tempst0\else1\fi}%
\begingroup
\def\skv@foreach@holderlist{}%
\def\skv@tempa{%
@@ -1547,8 +1531,7 @@
}%
\let\bgroup\relax
\skvifnextchar[{%
- \endgroup
- \skv@foreach@scanarg
+ \endgroup\skv@foreach@scanarg
}{%
\skvifnextchar i{%
\endgroup
@@ -1598,6 +1581,7 @@
\def\do##1{\def##1{}}%
\do\skv@foreach@itemcounter\do\skv@foreach@processupto
\do\skv@foreach@callback\do\skv@foreach@auxcallback
+ \do\skv@foreach@callback@hiddenparameters
\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.
@@ -1609,7 +1593,7 @@
% We've set the keys; let's overrule \skv@foreach@expandlistonce if
% we had seen a star suffix. Don't overrule \skv@foreach@expandlisttwice
% and \skv@foreach@expandlistfully.
- \if\skv@foreach@seenstar
+ \if\skv@foreach@starform
\def\skv@foreach@expandlistonce{00}%
\fi
\ifcase0%
@@ -1780,7 +1764,8 @@
\skv@foreach@mainprocess
{\skvexpandonce\skv@foreach@holderlist}%
{\skvexpandonce\skv@foreach@userlist}%
- }{#1}%
+ {\skvtrimspace{#1}}%
+ }%
}
% #1: holder macros
% #2: List or list command
@@ -1809,8 +1794,10 @@
\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
+ % Why 'keep double parser' here? Think of a list like 32//13,11/23/,...
+ \skvexpbracenext\skvdefinekeepdoubleparsernormalizer
+ \skv@foreach@subparser\skv@tempa
+ \edef\skv@foreach@userlist{\skvexpbracenext\skv@tempa\skv@foreach@userlist}%
\ifnum\foreachnestdepth=\skvz@
\breakallforeachloopsfalse
\fi
@@ -1907,8 +1894,19 @@
\skv@foreach@callback{}%
\fi
}{%
- \expandafter\skv@foreach@filllist\expandafter
- {\skv@foreach@parser}\skv@foreach@userlist
+ \def\do####1{\if####1true\else false\fi}%
+ \skvexpandsecond{\skvautocompletelist*}{[%
+ % Note: the value of 'expand list once', etc., can't be
+ % transferred automatically to \skvautocompletelist since they
+ % have been used above to expand list.
+ parser={\skv@foreach@parser},
+ link={\skvexpandonce\skv@foreach@link},
+ grow left=\do\skv@foreach@growleft,
+ grow right=\do\skv@foreach@growright,
+ keep decimals=\do\skv@foreach@keepdecimals,
+ keep high decimals=\do\skv@foreach@keephighdecimals,
+ expand before fill=\do\skv@foreach@expandbeforefill
+ ]}\skv@foreach@userlist\skv@foreach@userlist
\if\skv@foreach@reverselist\skvafterfi
\expandafter\skv@foreach@doreverselist\expandafter
{\skv@foreach@parser}\skv@foreach@userlist
@@ -1932,6 +1930,7 @@
\ifnum\foreachnestdepth=\skvz@
\def\skv@warnsubparser{0}%
\fi
+ \skv@inforeachfalse
}
% \skv@foreach@makeprecode{<holder.list>}
@@ -2013,7 +2012,7 @@
%
% \def\ditem{D}
% \newforeach [
-% continue=\ifx\x\ditem\fi,remember=\x as \rx initially A
+% continue=\ifx\x\ditem\fi, remember=\x as \rx initially A
% ] \x in {
% B,(C1),D,E,[F1],G,H
% }{%
@@ -2031,9 +2030,11 @@
}%
% Add extra subparsers in case some items aren't subparser-complete:
\edef\skv@tempa{\skv@generatesubparser{1}}%
+ \edef\skv@foreach@callback@hiddenparameters{\unexpanded{#1}}%
\let\foreacheov\relax
\let\do\noexpand
\skvexpanded{\endgroup
+ \skvcmdexit\skv@foreach@callback@hiddenparameters
% Define auxiliary callback:
\def\do\skv@foreach@auxcallback\skv@foreach@paramlist\foreacheov{%
% Holder macro assignments:
@@ -2046,15 +2047,24 @@
\ifx\skv@foreach@continuetester\@secondoftwo
\noexpand\skv@foreach@continuetester
\else
- % Expose the parameter characters in \skv@foreach@continuetester:
+ % Expose the parameter characters in \skv@foreach@continuetester.
+ % If the user wants to ignore the callback for some items, he can
+ % use the key 'continue=<condition>':
\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}%
+ \if\skv@foreach@hideparameters
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {%
+ \noexpand\skv@foreach@callback@hiddenparameters
+ }{%
+ \unexpanded{#1}%
+ }%
% User tests/tasks, eg, if requested from the keys 'remember',
% 'exit when', etc:
\skvexpandonce\skv@foreach@postcallback
@@ -2082,10 +2092,6 @@
{P}{p}{16}{Q}{q}{17}{R}{r}{18}{S}{s}{19}{T}{t}{20}{U}{u}{21}{V}{v}{22}%
{W}{w}{23}{X}{x}{24}{Y}{y}{25}{Z}{z}{26}%
}
-% \skv@foreach@addtolist<parser><add.new><listcmd>
-\skvrobustdef*\skv@foreach@addtolist#1#2#3{%
- \edef#3{\skvexpandonce#3\ifx#3\@empty\else\unexpanded{#1}\fi#2}%
-}
\skvrobustdef*\skv@reverselumap#1{%
\def\skv@prova##1##2##3##4\skv@nil{%
\ifx\@nnil##1%
@@ -2098,96 +2104,134 @@
\edef#1{\expandafter\skv@prova\skv@alphamap\@nnil{}{}\skv@nil}
}
-\skvnewdef*\skv@foreach@ifloweralpha#1{%
- \skvifblankTF{#1}{%
- \@secondoftwo
- }{%
- \skvifntypeTF{#1}{%
- \skvifnumTF`#1>96{%
- \skvifnumTF`#1<123{%
- \@firstoftwo
- }{%
- \@secondoftwo
- }%
- }{%
- \@secondoftwo
- }%
- }{%
- \@secondoftwo
- }%
- }%
+
+\skvquickkeys.define{skeyval/autocomplete}{%
+ .exec/\def\skv@autocomplete@parser{,};
+ parser/{,}/
+ \edef\skv@autocomplete@parser{\unexpanded{#1}}
+ \skvstripouterbraces{2}\skv@autocomplete@parser
+ \skvxifntypeTF{\detokenize{#1}}{%
+ \begingroup
+ % It is assumed that every n-type parser and subparser
+ % must have catcode 12:
+ \skvexpandnext{\catcode`}\skv@autocomplete@parser=12\relax
+ \skvrescan\skv@autocomplete@parser
+ \skvaftergroupdef\skv@autocomplete@parser\endgroup
+ }{}
+ ;
+ % This default value of 'link' is required by \skvautocompletelist:
+ .exec code/\def\skv@autocomplete@link{\@nil};
+ link/\@nil/
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifcase0%
+ \ifx\skv@prova\@empty 1\fi
+ \ifx\skv@prova\@nnil 1\fi\relax
+ \edef\skv@autocomplete@link{\unexpanded{#1}}%
+ \skvstripouterbraces{2}\skv@autocomplete@link
+ \fi
+ ;
+ grow/\@nil/
+ \edef\skv@prova{\unexpanded{#1}}%
+ \ifx\skv@prova\@nnil\else
+ \skvcsedef{skv@autocomplete@grow#1}{00}
+ \edef\skv@prova{\skvifstrcmpTF{#1}{left}{right}{left}}%
+ \skvcsedef{skv@autocomplete@grow\skv@prova}{01}%
+ \fi
+ /left,right
+ ;
+ .exec/
+ \def\skv@autocomplete@growleft{01}
+ \def\skv@autocomplete@growright{01}
+ ;
+ grow left/true/
+ \edef\skv@autocomplete@growleft{0\skvifstrcmpTF{true}{#1}01}
+ /true,false
+ ;
+ grow right/true/
+ \edef\skv@autocomplete@growright{0\skvifstrcmpTF{true}{#1}01}
+ /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@autocomplete@keepdecimals{0\skvifstrcmpTF{true}{#1}01}
+ /true,false
+ ;
+ keep high decimals,keep only high decimals/true/
+ \edef\skv@autocomplete@keephighdecimals{0\skvifstrcmpTF{true}{#1}01}
+ /true,false
+ ;
+ expand before fill,expand list before fill/true/
+ \edef\skv@autocomplete@expandbeforefill{0\skvifstrcmpTF{true}{#1}01}
+ /true,false
+ ;
}
-\skvnewdef*\skv@foreach@ifupperalpha#1{%
- \skvifblankTF{#1}{%
- \@secondoftwo
- }{%
- \skvifntypeTF{#1}{%
- \skvifnumTF`#1>64{%
- \skvifnumTF`#1<91{%
- \@firstoftwo
- }{%
- \@secondoftwo
- }%
- }{%
- \@secondoftwo
- }%
- }{%
- \@secondoftwo
- }%
- }%
+
+% The keys 'link,grow' 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.
+%
+\skvquickkeys.preset{skeyval/autocomplete}{%
+ parser,grow left=false,grow right=false,
+ keep decimals=true,keep high decimals=false,
+ expand before fill=false
}
-% Parse list for 1,2,...,n,1,...,m. Return value in #1:
+% \skv@autocomplete@addtolist<parser><add.new><listcmd>
+\skvrobustdef*\skv@autocomplete@addtolist#1#2#3{%
+ \edef#3{\skvexpandonce#3\ifx#3\@empty\else\unexpanded{#1}\fi#2}%
+}
+% \skv@autocomplete@zerostepwarn{<lower>}{<upper>}{<pt.or.nil>}
+\skvrobustdef*\skv@autocomplete@zerostepwarn#1#2#3{%
+ \skv@warn{The tokens '\detokenize{#1}', '\detokenize{#2}'
+ give nil step; '1#3' used.\MessageBreak
+ Maybe you used the font-dependent units\MessageBreak
+ 'ex' or 'em' \ifskv@latex before \skv@begindoctoks\fi}%
+}
+% \skvautocompletelist[<kvlist>]{<list>}{<returncmd>}
+% \skvautocompletelist*[<kvlist>]{<listcmd>}{<returncmd>}
%
-% \skv@foreach@filllist{<parser>}<listcmd>
-\skvrobustdef*\skv@foreach@filllist#1#2{%
+% 1. Parse list of type {1,2,...,n,1,...,m} for auto completion.
+% Return outcome in <listcmd> or \skvcompletedlist.
+%
+\skvrobustdef*\skvautocompletelist{\skv@teststopt\skv@autocompletelist@a{}}
+\skvrobustdef*\skv@autocompletelist@a[#1]#2#3{%
+ \skv@usetempst{#2}\skv@autocomplete@userlist
+ \skvquickkeys.set{skeyval/autocomplete}{#1}%
\def\skv@inalphabetic{01}%
\def\skv@isupperalpha{01}%
- % If the list is alphabetic, original unit is nil:
- \def\skv@foreach@origunit{}%
- \def\skv@foreach@filledlist{}%
- \edef\skv@foreach@parser{\skvtrimspace{#1}}%
- \ifx\skv@foreach@parser\@empty
- \def\skv@foreach@parser{,}%
- \fi
- \def\skv@foreach@iflinkgiven{%
- \skvifdefTF\skv@foreach@link{%
- \skvifxFT\skv@foreach@link\@nnil
- }{%
- \skv@err{List auto-completion: 'link' is undefined}\skv@ehd
- }%
- }%
- \skvexpanded{%
- \noexpand\skv@foreach@filllist@a
- {\skvexpandonce\skv@foreach@parser}{\skvexpandonce{#2}}%
- }%
- \let#2\skv@foreach@filledlist
-}
-\skvnewlet\skvautofilllist\skv@foreach@filllist
-% \skv@foreach@filllist@a{<parser>}{<list>}
-\skvrobustdef*\skv@foreach@filllist@a#1#2{%
+ \def\skv@preandpostdotspresent{01}%
+ % If the list is alphabetic or numbers, original unit is nil:
+ \def\skv@autocomplete@origunit{}%
+ \def\skvcompletedlist{}%
+ \skvexpandtwoargsonce
+ \skv@autocompletelist@b\skv@autocomplete@parser\skv@autocomplete@userlist
+ \let#3\skvcompletedlist
+}
+% \skv@autocompletelist@b{<parser>}{<list>}
+\skvrobustdef*\skv@autocompletelist@b#1#2{%
\edef\skv@tempa{\unexpanded{#2}}%
\skv@foreach@normalize[#1]\skv@tempa
\def\skv@prova##1{%
\skvxifinTF{...}{\detokenize{##1}}{%
- \if\skv@foreach@expandlistbeforefill
+ \if\skv@autocomplete@expandbeforefill
\edef\skv@tempa{##1}%
\skv@foreach@normalize[#1]\skv@tempa
\else
\edef\skv@tempa{\unexpanded{##1}}%
\fi
- \skvexpandargonce{\skv@foreach@filllist@b{#1}}{\skv@tempa}%
- \skv@foreach@normalize[#1]\skv@foreach@filledlist
+ \skvexpandargonce{\skv@autocompletelist@c{#1}}\skv@tempa
+ \skv@foreach@normalize[#1]\skvcompletedlist
}{%
- \edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist\skvtrimspace{##1}%
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist\skvtrimspace{##1}%
}%
}%
}%
\expandafter\skv@prova\expandafter{\skv@tempa}%
}
-% \skv@foreach@filllist@b{<parser>}{<list>}
-\skvrobustdef*\skv@foreach@filllist@b#1#2{%
+% \skv@autocompletelist@c{<parser>}{<list>}
+\skvrobustdef*\skv@autocompletelist@c#1#2{%
\skvxiffound{\relax...}\in{\relax\detokenize{#2}}\then
\skv@err{I can't find lower limit before '...'}\skv@ehd
\else
@@ -2197,203 +2241,49 @@
\fi
% \newforeach format is '<parser>...<parser>':
\skvxifinTF{\detokenize{#1...#1}}{\detokenize{#2}}{%
- \skv@foreach@splitonguide{#1}{#2}%
+ \skv@autocomplete@splitbeforedots{#1}{#2}%
\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 '...'}\skv@ehd
}{%
- % \skv@foreach@filllist@a may be reentered. Hence accumulate
+ % \skv@autocompletelist@b may be reentered. Hence accumulate
% filled list:
\skviflacus{##1}\then\else
- \edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist\unexpanded{##1}%
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist\unexpanded{##1}%
}%
\fi
% Complete the list:
- \skv@foreach@filllist@c{#1}{##1}{##2}{##3}%
+ \skv@autocompletelist@d{#1}{##1}{##2}{##3}%
% In case the list is folded on ellipsis (...):
- \skvifblankTF{##4}{}{\skv@foreach@filllist@a{#1}{##4#1##5}}%
+ \skvifblankTF{##4}{}{\skv@autocompletelist@b{#1}{##4#1##5}}%
}%
}%
\expandafter\skv@prova\skv@tempa#1#1\skv@nil
}{%
- % Not \newforeach format: try PGF's \foreach format:
- \skv@foreach@trypgflikeformat{#1}{#2}%
+ \skv@autocompletelist@e{#1}{#2}%
}%
}
-
-% \skv@foreach@zerostepwarn{<lower>}{<upper>}{<pt.or.nil>}
-\skvrobustdef*\skv@foreach@zerostepwarn#1#2#3{%
- \skv@warn{The tokens '\detokenize{#1}', '\detokenize{#2}'
- give nil step; '1#3' used.\MessageBreak
- Maybe you used the font-dependent units\MessageBreak
- 'ex' or 'em' \ifskv@latex before \skv@begindoctoks\fi}%
-}
-
-% skv@foreach@filllist@c{<parser>}{<lower1>}{<lower2>}{<upperbound>}
+% skv@autocompletelist@d{<parser>}{<lower1>}{<lower2>}{<upperbound>}
%
% 1. No <guide> here.
%
-\skvrobustdef*\skv@foreach@filllist@c#1#2#3#4{%
- \skv@foreach@iflinkgiven{%
- % <link> has been given by the user:
- \skv@foreach@splitandgrow{#1}{#2}{#3}{#4}%
- }{%
+\skvrobustdef*\skv@autocompletelist@d#1#2#3#4{%
+ \skvifxTF\skv@autocomplete@link\@nnil{%
% No <link> has been given. The list has '...' but presumably no link.
- % Note: If there're more than 1 alpha/Alpha character, both
- % \skv@foreach@ifloweralpha and \skv@foreach@ifupperalpha will
- % return false, since double aphabetic characters can't be grown.
- % \skv@foreach@filllist@d{<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
- \skv@foreach@filllist@d{#1}{}{#2}{#3}{#4}%
- }%
-}
-
-% skv@foreach@fsplitandgrow{<parser>}{<lower1>}{<lower2>}{<upperbound>}
-%
-% {0\pi,0.5\pi,...,3\pi} : link = \pi ; grow left
-% {1--,4--,...,10--} : link = -- ; grow left
-% {2pt,4pt,...,10pt} : link = pt ; grow left (or no additional info.)
-% {A_1,C_1,...,Q_1} : link = _ ; grow left
-% {2^a,2^c,...,2^q} : link = ^ ; grow right
-%
-% 1. Automatically split and grow.
-% 2. We already know that the key 'link' will reject empty values.
-%
-\skvrobustdef*\skv@foreach@splitandgrow#1#2#3#4{%
- \ifx\skv@foreach@growleft\skv@foreach@growright
- \skv@err{I can't grow the list in both directions.
- \MessageBreak Maybe you haven't indicated the
- \MessageBreak direction of growth (left or right),
- \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'}\skv@ehd
- \fi
- \begingroup
- \def\skv@prova##1{%
- \skv@foreach@swatrue
- \skviflacus#2\then\else
- \skvifinTF{##1}{#2}{}\skv@foreach@swafalse
- \fi
- \skvifinTF{##1}{#3}{}\skv@foreach@swafalse
- \skvifinTF{##1}{#4}{}\skv@foreach@swafalse
- \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}'}\skv@ehd
- \fi
- \def\skv@prova####1##1####2\skv@nil{%
- \if\skv@foreach@growright
- \edef\skv@prova{\skvtrimspace{####1##1}}%
- \else
- \edef\skv@prova{\skvtrimspace{##1####2}}%
- \fi
- \def\do########1{{\skvtrimspace{########1}}}%
- % \skv@foreach@trypgflikeformat@a<parser><guide><lower1><lower2><upper>
- \skvexpanded{\endgroup
- \noexpand\skv@foreach@trypgflikeformat@a
- {\unexpanded{#1}}{\skvexpandonce\skv@prova}\do{#2}\do{#3}\do{#4}%
- }%
- }%
- \skv@prova#3\skv@nil
- }%
- \expandafter\skv@prova\expandafter{\skv@foreach@link}%
-}
-%
-% \skv@foreach@splitonguide{<parser>}{<list>}
-%
-% Get the two elements before '...' or '<guide>,...'. In the case of skeyval
-% format, get the two elements before '...'. The PGF format uses <guide>,
-% shown in the following examples:
-%
-% PGF formats:
-% {a^1,a^3,a^...,a^9} : <guide> = a^
-% {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_ and pt
-%
-% skeyval formats:
-% {a^1,a^3,a^...,a^9} : no additional info. required
-% {A_1,B_1,..._1,E_1} : no additional info. required
-% {1--,4--,...--,16--} : no additional info. required
-% {1pt,4pt,...pt,10pt} : no additional info. required
-% {A_2pt,A_4pt,A_...,A_10pt} : no additional info. required
-%
-% {a^1,a^3,...,a^9} : link = ^, grow = right
-% {A_1,B_1,...,E_1} : link = _, grow = left
-% {1--,4--,...,16--} : link = --, grow = left
-% {1pt,4pt,...,10pt} : link = pt, grow = left, or no addit. info.
-% {A_2pt,A_4pt,...,A_10pt} : link = _, grow = right
-%
-% 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 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><parser>...' or '...':
- \begingroup
- \skv@cnta\skvz@
- \def\do##1#1{%
- \skvifinTF{...}{##1}{%
- \def\do####1\skv@nil{}%
- }{%
- \advance\skv@cnta\@ne
- }%
- \do
- }%
- \do#2#1\skv@nil
- \ifnum\skv@cnta>\tw@
- \skvsetno\skv@foreach@nra\m@ne
- \def\do##1#1{%
- \skvadvanceno\skv@foreach@nra\@ne
- \ifnum\skv@foreach@nra=\numexpr\skv@cnta-\tw@\relax
- \def\do####1\skv@nil{\def\skv@tempa{##1#1####1}}%
- \else
- \edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist\unexpanded{##1}%
- }%
- \fi
- \do
- }%
- \do#2#1\skv@nil
- \else
- \ifnum\skv@cnta=\@ne
- \def\skv@tempa{#1#2}%
- \else
- \ifnum\skv@cnta=\tw@
- \def\skv@tempa{#2}%
- \else
- \ifnum\skv@cnta=\skvz@
- \skv@err{List <<\detokenize{#2}>>\MessageBreak
- contains symbol '...' but not a lowerbound}\skv@ehd
- \fi
- \fi
- \fi
- \fi
- \skvexpanded{\endgroup
- \skvcmdexit\skv@foreach@filledlist\skvcmdexit\skv@tempa
+ %
+ % \skv@autocompletelist@h{<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
+ \skv@autocompletelist@h{#1}{}{#2}{#3}{#4}%
+ }{%
+ % <link> has been given by the user:
+ \skv@autocomplete@splitandgrow{#1}{#2}{#3}{#4}%
}%
}
-
-% \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)' (*)
%
-% but the syntax '<guide>...' (ie, having only the left-hand-side or only
-% the right-hand-side guide). For example,
+% \skv@autocompletelist@e{<parser>}{<list>}
%
-% {A_2pt,A_4pt,A_...,A_10pt} or {1pt,4pt,...pt,10pt}
-%
-% \skv@foreach@trypgflikeformat will auto-complete this list without
+% \skv@autocompletelist@e 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.
%
@@ -2401,97 +2291,105 @@
%
% {1pt,4pt,...pt,10pt} : no additional info. required
% {A_2pt,A_4pt,A_...,A_10pt} : no additional info. required
-% {1pt,4pt,...,10pt} : link = pt, grow=right, or no addit. info.
+% {\pi0,\pi0.5,\pi...,\pi3} : no additional info. required
+% {0\pi,0.5\pi,...\pi,3\pi} : no additional info. required
+% {1pt,4pt,...,10pt} : link = pt, grow=left, or no addit. info.
% {A_2pt,A_4pt,...,A_10pt} : link =_, grow=right
%
-% The general PGF format (with left and right guides), e.g.,
+% The general PGF format with left and right guides (given as 'A_'
+% and 'pt') in
%
% {A_2pt,A_4pt,A_...pt,A_10pt}
%
-% 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.
+% is still legal in skeyval.
%
-\skvrobustdef*\skv@foreach@trypgflikeformat#1#2{%
- \skv@foreach@splitonguide{#1}{#2}%
+\skvrobustdef*\skv@autocompletelist@e#1#2{%
+ \skv@autocomplete@splitbeforedots{#1}{#2}%
+ \def\skv@checkguideinbounds##1##2{%
+ \skv@foreach@swafalse
+ \def\do####1{%
+ \ifx\do####1\else
+ \skviflacus####1\then\else
+ \skvifinTF{##1}{####1}{}\skv@foreach@swatrue
+ \fi
+ \expandafter\do
+ \fi
+ }%
+ \do##2\do
+ \ifskv@foreach@swa
+ \skv@err{Guide token '\detokenize{#1}' 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}\skv@ehd
+ \fi
+ }%
\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 '...'}\skv@ehd
}{%
- % \skv@foreach@filllist@a may be reentered. Hence
+ % \skv@autocompletelist@b may be reentered. Hence
\skviflacus{##1}\then\else
- \edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist
\skvtrimspace{##1}%
}%
\fi
- \def\do####1{{\skvtrimspace{####1}}}%
+ \let\do\unexpanded
\skvifblankTF{##3}{%
\skvifblankTF{##4}{%
\skv@err{No direction of growth before and/or after
\MessageBreak symbol '...'}\skv@ehd
}{%
- \def\skv@foreach@growleft{00}%
- \def\skv@foreach@growright{01}%
+ % Eg, {2pt_A,4pt_A,...pt_A,10pt_A}. Here ##3 is nil, grow left.
+ \def\skv@autocomplete@growleft{00}%
+ \def\skv@autocomplete@growright{01}%
\skvexpanded{%
- \skv@foreach@trypgflikeformat@a
- {\unexpanded{#1}}\do{##4}\do{##1}\do{##2}\do{##5}%
+ \skv@autocompletelist@f
+ {\do{#1}}{\do{##4}}{\do{##1}}{\do{##2}}{\do{##5}}%
}%
}%
}{%
\skvifblankTF{##4}{%
- \def\skv@foreach@growright{00}%
- \def\skv@foreach@growleft{01}%
+ % Eg, {A_2pt,A_4pt,A_...,A_10pt}. Here ##4 is nil, grow right.
+ \def\skv@autocomplete@growright{00}%
+ \def\skv@autocomplete@growleft{01}%
\skvexpanded{%
- \skv@foreach@trypgflikeformat@a
- {\unexpanded{#1}}\do{##3}\do{##1}\do{##2}\do{##5}%
+ \skv@autocompletelist@f
+ {\do{#1}}{\do{##3}}{\do{##1}}{\do{##2}}{\do{##5}}%
}%
}{%
- \skv@err{Having both '\detokenize{'##3' and '##4'} in an
- \MessageBreak ellipsis list is illegal in
- \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 of <<...>>.}\skv@ehd
+ % Eg, {A_2pt,A_4pt,A_...pt,A_10pt}.
+ \skvexpanded{%
+ \skv@autocompletelist@g
+ {\do{#1}}{\do{##3}}{\do{##4}}{\do{##1}}{\do{##2}}{\do{##5}}%
+ }%
}%
}%
% In case the list is folded on ellipsis (...):
- \skvifblankTF{##6}{}{\skv@foreach@filllist@a{#1}{##6#1##7}}%
+ \skvifblankTF{##6}{}{\skv@autocompletelist@b{#1}{##6#1##7}}%
}%
}%
\expandafter\skv@prova\skv@tempa#1#1#1\skv@nil
}
-%
-% \skv@foreach@trypgflikeformat@a
+% \skv@autocompletelist@f
% {<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
%
-% 1. Use the <guide> to get the contant and variable parts of the
+% 1. Use the <guide> to get the constant and variable parts of the
% elements.
% 2. Use the variable parts to determine if the list is Alpah, alpha or
% number type. In this format, the unit in dimension type of list may
% appear in <guide>.
% 3. Use the variable parts to work out the <step>.
% 4. Call the relevant macro to fill the list.
-% 5. <lower1> has already been saved in \skv@foreach@filledlist.
+% 5. <lower1> has already been saved in \skvcompletedlist.
%
-\skvrobustdef*\skv@foreach@trypgflikeformat@a#1#2#3#4#5{%
- \skv@foreach@swafalse
- \skviflacus#3\then\else
- \skvxifinTF{#2}{#3}{}\skv@foreach@swatrue
- \fi
- \skvxifinTF{#2}{#4}{}\skv@foreach@swatrue
- \skvxifinTF{#2}{#5}{}\skv@foreach@swatrue
- \ifskv@foreach@swa
- \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}\skv@ehd
- \fi
- % Get from the left or right of 'link' (#2) the components that should be
- % grown, without the link:
+\skvrobustdef*\skv@autocompletelist@f#1#2#3#4#5{%
+ \skv@checkguideinbounds{#2}{{#3}{#4}{#5}}%
+ % Use the 'link' (#2) to get from {<lower1>}, {<lower2>} and {<upper>}
+ % the left or right sides of the elements that should be grown:
\def\skv@prova##1#2##2\skv@nil##3{%
- \edef##3{\if\skv@foreach@growleft##1\else##2\fi}%
+ \edef##3{\if\skv@autocomplete@growleft##1\else##2\fi}%
}%
% <lower1> is empty when there is only one element before ellipsis:
\skviflacus#3\then
@@ -2503,69 +2401,105 @@
\skv@prova#5\skv@nil\skv@tempc
\let\do\skvexpandonce
\skvexpandsecond
- {\skv@foreach@filllist@d{#1}{#2}}%
+ {\skv@autocompletelist@h{#1}{#2}}%
{{\do\skv@tempa}{\do\skv@tempb}{\do\skv@tempc}}%
}
-
-% \skv@foreach@filllist@d{<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
+% \skv@autocompletelist@g
+% {<parser>}{<predots>}{<postdots>}{<lower1>}{<lower2>}{<upper>}
+\skvrobustdef*\skv@autocompletelist@g#1#2#3#4#5#6{%
+ \def\skv@preandpostdotspresent{00}%
+ \skv@checkguideinbounds{#2}{{#4}{#5}{#6}}%
+ \skv@checkguideinbounds{#3}{{#4}{#5}{#6}}%
+ % For <lower1>, <lower2> and <upper>, get the tokens between
+ % <predots> and <postdots>. They are the ones to be grown.
+ \def\skv@prova##1#2##2#3##3\skv@nil##4{%
+ \edef##4{##2}%
+ }%
+ \ifx\@nnil#4\@nnil
+ \let\skv@tempa\@empty
+ \else
+ \skv@prova#4\skv@nil\skv@tempa
+ \fi
+ \skv@prova#5\skv@nil\skv@tempb
+ \skv@prova#6\skv@nil\skv@tempc
+ % Pass <guide> as empty to \skv@autocompletelist@h. Through out, the only
+ % reason for passing <guide> to \skv@autocompletelist@h is to restore
+ % it in \skv@autocomplete@restore. But while
+ % \skv@preandpostdotspresent is true, we won't do anything in
+ % \skv@autocomplete@restore.
+ \skvexpandsecond
+ {\skv@autocompletelist@h{#1}{}}%
+ {{\skv@tempa}{\skv@tempb}{\skv@tempc}}%
+ % Restore <predots> and <postdots>:
+ \def\do##1#1{%
+ \ifx\do##1\else
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist
+ \unexpanded{#2}##1\unexpanded{#3}\skv@autocomplete@origunit
+ }%
+ \expandafter\do
+ \fi
+ }%
+ \expandafter\do\skv@completedlist@partial#1\do#1%
+}
+% \skv@autocompletelist@h{<parser>}{<guide>}{<lower1>}{<lower2>}{<upper>}
%
% 1. Use the variable parts to determine if the list is Alpah, alpha or
% number type. In this format, the unit in dimension type of list may
% appear in <guide>.
% 2. Use the variable parts to work out the <step>.
% 3. Call the relevant macro to fill the list.
-% 4. <lower1> has already been saved in \skv@foreach@filledlist.
+% 4. <lower1> has already been saved in \skvcompletedlist.
%
-\skvrobustdef*\skv@foreach@filllist@d#1#2#3#4#5{%
- \begingroup
- \def\skv@templist{}%
+\skvrobustdef*\skv@autocompletelist@h#1#2#3#4#5{%
+ \def\skv@completedlist@partial{}%
\edef\skv@lowerlower{\ifx\@nnil#3\@nnil\else\unexpanded{#3}, \fi}%
- \skv@foreach@ifloweralpha{#4}{%
+ \skvifloweralpha{#4}{%
\skv@foreach@swatrue
\ifx\@nnil#3\@nnil\else
- \skv@foreach@ifloweralpha{#3}{}\skv@foreach@swafalse
+ \skvifloweralpha{#3}{}\skv@foreach@swafalse
\fi
- \skv@foreach@ifloweralpha{#5}{}\skv@foreach@swafalse
+ \skvifloweralpha{#5}{}\skv@foreach@swafalse
\ifskv@foreach@swa
\ifx\@nnil#3\@nnil
- \def\skv@foreach@step{1}%
+ \def\skv@autocomplete@step{1}%
\else
- \edef\skv@foreach@step{\the\numexpr\lccode`#4-\lccode`#3}%
- \ifnum\skv@foreach@step=\skvz@
- \def\skv@foreach@step{1}%
- \skv@foreach@zerostepwarn{#3}{#4}{}%
+ \edef\skv@autocomplete@step{\the\numexpr\lccode`#4-\lccode`#3}%
+ \ifnum\skv@autocomplete@step=\skvz@
+ \def\skv@autocomplete@step{1}%
+ \skv@autocomplete@zerostepwarn{#3}{#4}{}%
\fi
\fi
\def\skv@isupperalpha{01}%
- % \skv@foreach@origunit remains nil on this branch:
- \skv@foreach@fillalphabetic{#1}{#4}{#5}\skv@templist
- % Also update the items already entered in \skv@foreach@filledlist.
- \skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
+ % \skv@autocomplete@origunit remains nil on this branch.
+ \skv@autocomplete@fillalphabetic{#1}{#4}{#5}\skv@completedlist@partial
+ % Also update the items already entered in \skvcompletedlist.
+ \skv@autocomplete@restore{#1}{#2}\skv@completedlist@partial
\else
\skv@err{The tokens '\detokenize\expandafter{\skv@lowerlower#4, #5}'
\MessageBreak aren't of the same type}\skv@ehd
\fi
}{%
- \skv@foreach@ifupperalpha{#4}{%
+ \skvifupperalpha{#4}{%
\skv@foreach@swatrue
\ifx\@nnil#3\@nnil\else
- \skv@foreach@ifupperalpha{#3}{}\skv@foreach@swafalse
+ \skvifupperalpha{#3}{}\skv@foreach@swafalse
\fi
- \skv@foreach@ifupperalpha{#5}{}\skv@foreach@swafalse
+ \skvifupperalpha{#5}{}\skv@foreach@swafalse
\ifskv@foreach@swa
\ifx\@nnil#3\@nnil
- \def\skv@foreach@step{1}%
+ \def\skv@autocomplete@step{1}%
\else
- \edef\skv@foreach@step{\the\numexpr\uccode`#4-\uccode`#3}%
- \ifnum\skv@foreach@step=\skvz@
- \def\skv@foreach@step{1}%
- \skv@foreach@zerostepwarn{#3}{#4}{}%
+ \edef\skv@autocomplete@step{\the\numexpr\uccode`#4-\uccode`#3}%
+ \ifnum\skv@autocomplete@step=\skvz@
+ \def\skv@autocomplete@step{1}%
+ \skv@autocomplete@zerostepwarn{#3}{#4}{}%
\fi
\fi
\def\skv@isupperalpha{00}%
- % \skv@foreach@origunit remains nil on this branch:
- \skv@foreach@fillalphabetic{#1}{#4}{#5}\skv@templist
- \skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
+ % \skv@autocomplete@origunit remains nil on this branch.
+ \skv@autocomplete@fillalphabetic{#1}{#4}{#5}\skv@completedlist@partial
+ \skv@autocomplete@restore{#1}{#2}\skv@completedlist@partial
\else
\skv@err{The tokens '\detokenize\expandafter{\skv@lowerlower#4, #5}'
\MessageBreak aren't of the same type}\skv@ehd
@@ -2576,32 +2510,30 @@
\skvifdimensionable{#3}{}\skv@foreach@swafalse
\fi
\skvifdimensionable{#4}{}\skv@foreach@swafalse
- \let\skv@foreach@origunit\skv@dimunit
+ \let\skv@autocomplete@origunit\skv@dimunit
\skvifdimensionable{#5}{}\skv@foreach@swafalse
- \ifx\skv@foreach@origunit\skv@dimunit\else
+ \ifx\skv@autocomplete@origunit\skv@dimunit\else
\skv@err{The units on \detokenize{'#4', '#5'} are different}\skv@ehd
\fi
\ifskv@foreach@swa
\ifx\@nnil#3\@nnil
- \def\skv@foreach@step{1pt}%
+ \def\skv@autocomplete@step{1pt}%
\else
- \edef\skv@foreach@step{\the\dimexpr#4-#3}%
- \ifdim\skv@foreach@step=\skvz@
- \def\skv@foreach@step{1pt}%
- \skv@foreach@zerostepwarn{#3}{#4}{pt}%
+ \edef\skv@autocomplete@step{\the\dimexpr#4-#3\relax}%
+ \ifdim\skv@autocomplete@step=\skvz@
+ \def\skv@autocomplete@step{1pt}%
+ \skv@autocomplete@zerostepwarn{#3}{#4}{pt}%
\fi
\fi
- \skvexpandsecond{%
- \skv@foreach@fillnumordim{#1}%
- }{%
- {#4}{#5}%
- }\skv@templist
- \skv@foreach@strippoint{#1}\skv@templist
+ \skvexpandsecond
+ {\skv@autocomplete@fillnumordim{#1}}{{#4}{#5}}%
+ \skv@completedlist@partial
+ \skv@autocomplete@strippoint{#1}\skv@completedlist@partial
% Attach the constant part to the elements of the completed list.
- % <lower1> was saved earlier in \skv@foreach@trypgflikeformat, and
+ % <lower1> was saved earlier in \skv@autocompletelist@e, 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
+ \skv@autocomplete@restore{#1}{#2}\skv@completedlist@partial
\else
\skv@foreach@swatrue
\ifx\@nnil#3\@nnil\else
@@ -2611,22 +2543,20 @@
\skvifdimensionable{#5pt}{}\skv@foreach@swafalse
\ifskv@foreach@swa
\ifx\@nnil#3\@nnil
- \def\skv@foreach@step{1pt}%
+ \def\skv@autocomplete@step{1pt}%
\else
- \edef\skv@foreach@step{\the\dimexpr#4pt-#3pt}%
- \ifdim\skv@foreach@step=\skvz@
- \def\skv@foreach@step{1pt}%
- \skv@foreach@zerostepwarn{#3}{#4}{pt}%
+ \edef\skv@autocomplete@step{\the\dimexpr#4pt-#3pt\relax}%
+ \ifdim\skv@autocomplete@step=\skvz@
+ \def\skv@autocomplete@step{1pt}%
+ \skv@autocomplete@zerostepwarn{#3}{#4}{pt}%
\fi
\fi
- % \skv@foreach@origunit remains nil on this branch:
- \skvexpandsecond{%
- \skv@foreach@fillnumordim{#1}%
- }{%
- {#4pt}{#5pt}%
- }\skv@templist
- \skv@foreach@strippoint{#1}\skv@templist
- \skv@foreach@restoreguideandunit{#1}{#2}\skv@templist
+ % \skv@autocomplete@origunit remains nil on this branch.
+ \skvexpandsecondonce
+ {\skv@autocomplete@fillnumordim{#1}}{{#4pt}{#5pt}}%
+ \skv@completedlist@partial
+ \skv@autocomplete@strippoint{#1}\skv@completedlist@partial
+ \skv@autocomplete@restore{#1}{#2}\skv@completedlist@partial
\else
\skv@err{Sorry, the tokens
'\detokenize\expandafter{\skv@lowerlower#4, #5}'
@@ -2637,110 +2567,62 @@
\fi
}%
}%
- \skvaftergroupdef\skv@foreach@filledlist\endgroup
-}
-
-% Restore guide and, in the case of numerical sequences, 'original unit'.
-%
-% \skv@foreach@restoreguideandunit{<parser>}{<guide>}{<listcmd>}
-\skvrobustdef*\skv@foreach@restoreguideandunit#1#2#3{%
- \def\do##1#1{%
- \ifx\do##1\else
- \edef\skv@foreach@filledlist{%
- \skvaddlist{#1}\skv@foreach@filledlist
- \if\skv@foreach@growleft
- ##1\skv@foreach@origunit\unexpanded{#2}%
- \else
- \unexpanded{#2}##1\skv@foreach@origunit
- \fi
- }%
- \expandafter\do
- \fi
- }%
- \expandafter\do#3#1\do#1%
}
-\skvrobustdef*\skv@foreach@getcomparator{%
+% \skv@autocomplete@fillnumordim<parser><lower><upper><listcmd>
+\skvrobustdef*\skv@autocomplete@fillnumordim#1#2#3#4{%
\begingroup
- % 'unit' isn't required in alphabetic sequences:
- \if\skv@inalphabetic\else
- \let\skvreversedo\@iden
- \edef\skv@provb{\skvexpbracenext\skvreverse{\skv@foreach@step}}%
- \def\skv@prova##1##2##3\skv@nil{%
- \skvxifinTF{,\detokenize{##2##1},}{,\skvoxdetok\skv@validunit,}{%
- \def\skv@foreach@unit{}%
- }{%
- \def\skv@foreach@unit{pt}%
- }%
- }%
- \expandafter\skv@prova\skv@provb\skv@nil
- \fi
- \def\skv@prova##1##2\skv@nil{%
- \edef\skv@foreach@stepisneg{0\if-##10\else1\fi}%
- }%
- \expandafter\skv@prova\skv@foreach@step\skv@nil
- \edef\skv@comparator{\if\skv@foreach@stepisneg>\else<\fi}%
- \let\do\skvcmdexit
- \skvexpanded{\endgroup
- \do\skv@foreach@stepisneg\do\skv@comparator
- \if\skv@inalphabetic\else\do\skv@foreach@unit\fi
- }%
-}
-% \skv@foreach@fillnumordim<parser><lower><upper><listcmd>
-\skvrobustdef*\skv@foreach@fillnumordim#1#2#3#4{%
- \begingroup
- \skv@foreach@getcomparator
- \if\skv@foreach@stepisneg
- \ifdim#3\skv@foreach@unit>#2\skv@foreach@unit\relax
- \skv@err{Step '\skv@foreach@step' is negative but upperbound
+ \skv@autocomplete@getcomparator
+ \if\skv@autocomplete@stepisneg
+ \ifdim#3\skv@autocomplete@unit>#2\skv@autocomplete@unit\relax
+ \skv@err{Step '\skv@autocomplete@step' is negative but upperbound
\MessageBreak '\detokenize{#3}' is greater than lowerbound
'\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
+ \ifdim#3\skv@autocomplete@unit<#2\skv@autocomplete@unit\relax
+ \skv@err{Step '\skv@autocomplete@step' is nonnegative but upperbound
\MessageBreak '\detokenize{#3}' is less than lowerbound
'\detokenize{#2}'}\skv@ehd
\fi
\fi
% The bounds may have decimal places. So the calculation has to be
% done with \dimexpr:
- \skv@foreach@addtolist{#1}{\the\dimexpr#2\skv@foreach@unit}#4%
- % Upper number:
- \edef\skv@tempa{\the\dimexpr#3\skv@foreach@unit}%
- % Lower number:
- \edef\skv@tempb{\the\dimexpr#2\skv@foreach@unit}%
- \ifdim\skv@tempa=\skv@tempb\relax\else
+ \edef\skv@upperlimit{\the\dimexpr#3\skv@autocomplete@unit}%
+ \edef\skv@lowerlimit{\the\dimexpr#2\skv@autocomplete@unit}%
+ \skv@autocomplete@addtolist{#1}\skv@lowerlimit#4%
+ \ifdim\skv@lowerlimit\skv@comparator\skv@upperlimit\relax
\def\do{%
- \edef\skv@tempb{%
- \the\dimexpr\skv@tempb+\skv@foreach@step\skv@foreach@unit\relax
+ \edef\skv@lowerlimit{%
+ \the\dimexpr\skv@lowerlimit
+ +\skv@autocomplete@step\skv@autocomplete@unit\relax
}%
- \ifdim\skv@tempb\skv@comparator\skv@tempa\relax
- \skv@foreach@addtolist{#1}{\skvexpandonce\skv@tempb}#4%
+ \ifdim\skv@lowerlimit\skv@comparator\skv@upperlimit\relax
+ \skv@autocomplete@addtolist{#1}\skv@lowerlimit#4%
\expandafter\do
\fi
}%
\do
- % The last item has to in 'pt', so that 'pt' can be stripped:
- \skv@foreach@addtolist{#1}{\the\dimexpr#3\skv@foreach@unit}#4%
+ % The last item has to in 'pt', so that 'pt' can be stripped.
+ % Hence \dimexpr.
+ \skv@autocomplete@addtolist{#1}\skv@upperlimit#4%
\fi
\skvaftergroupdef#4\endgroup
}
-
-% Fill Alpha or alpha:
-% \skv@foreach@fillalphabetic<parser><lower><upper><listcmd>
-\skvrobustdef*\skv@foreach@fillalphabetic#1#2#3#4{%
+% Fill Alpha or alpha.
+% \skv@autocomplete@fillalphabetic<parser><lower><upper><listcmd>
+\skvrobustdef*\skv@autocomplete@fillalphabetic#1#2#3#4{%
\begingroup
\def\skv@inalphabetic{00}%
- \skv@foreach@getcomparator
+ \skv@autocomplete@getcomparator
\edef\skv@type{%
\if\skv@isupperalpha Upper\else Lower\fi case alphabetic%
}%
- \edef\reserved@a{\if-\skv@foreach@step\else\skv@foreach@step\fi}%
+ \edef\reserved@a{\if-\skv@autocomplete@step\else\skv@autocomplete@step\fi}%
\skvoifinteger\reserved@a{}{%
\skv@err{List is '\skv@type' type but\MessageBreak
- step '\skv@foreach@step' isn't an integer}\skv@ehd
+ step '\skv@autocomplete@step' isn't an integer}\skv@ehd
}%
- \skv@foreach@addtolist{#1}{#2}#4%
+ \skv@autocomplete@addtolist{#1}{#2}#4%
\skvifstrcmpTF{#2}{#3}{}{%
\edef\skv@lowerlimit{#2}%
\edef\skv@upperlimit{#3}%
@@ -2752,22 +2634,229 @@
\edef\skv@upperlimit{%
\the\numexpr\skv@upperlimit-\if\skv@isupperalpha 64\else 96\fi
}%
- \edef\skv@charcase{\the\numexpr\skv@lowerlimit+\skv@foreach@step}%
+ \edef\skv@charcase{\the\numexpr\skv@lowerlimit+\skv@autocomplete@step}%
\skvrecurse
\if\skv@isupperalpha
\edef\skv@tempa{\skv@ucalpha\skv@charcase}%
\else
\edef\skv@tempa{\skv@lcalpha\skv@charcase}%
\fi
- \skv@foreach@addtolist{#1}\skv@tempa#4%
- \edef\skv@charcase{\the\numexpr\skv@charcase+\skv@foreach@step}%
+ \skv@autocomplete@addtolist{#1}\skv@tempa#4%
+ \edef\skv@charcase{\the\numexpr\skv@charcase+\skv@autocomplete@step}%
\while
\ifnum\skv@charcase\skv@comparator\skv@upperlimit\relax
\fi
- \skv@foreach@addtolist{#1}{#3}#4%
+ \skv@autocomplete@addtolist{#1}{#3}#4%
}%
\skvaftergroupdef#4\endgroup
}
+%
+% \skv@autocomplete@splitbeforedots{<parser>}{<list>}
+%
+% Get the one or two elements before '...' or before '<guide>,...'.
+%
+% {A_2pt,A_4pt,A_...pt,A_10pt} : no additional info. required
+% {a^1,a^3,a^...,a^9} : no additional info. required
+% {A_1,B_1,..._1,E_1} : no additional info. required
+% {1--,4--,...--,16--} : no additional info. required
+% {1pt,4pt,...pt,10pt} : no additional info. required
+% {A_2pt,A_4pt,A_...,A_10pt} : no additional info. required
+%
+% {a^1,a^3,...,a^9} : link = ^, grow = right
+% {A_1,B_1,...,E_1} : link = _, grow = left
+% {1--,4--,...,16--} : link = --, grow = left
+% {1pt,4pt,...,10pt} : link = pt, grow = left, or no addit. info.
+% {A_2pt,A_4pt,...,A_10pt} : link = _, grow = right
+%
+% The items prior to the two before '<guide>...' or before '...'
+% are called 'all-before-the-two' (AB2). Collect in \skv@tempa the two
+% items before '<guide>...' or before '...' together with the rest of the
+% list. Save the AB2 items in \skvcompletedlist.
+%
+% Return \skvcompletedlist and \skv@tempa.
+%
+\skvrobustdef*\skv@autocomplete@splitbeforedots#1#2{%
+ % First count all the elements before '<guide><parser>...' or '...'.
+ % We're already sure that argument #2 contains '<guide><parser>...'
+ % or '...'. \skvcompletedlist has been initialized before here.
+ \begingroup
+ \skv@cnta\skvz@
+ \def\do##1#1{%
+ \skvifinTF{...}{##1}{%
+ % Gobble the rest:
+ \def\do####1\skv@nil{}%
+ }{%
+ \advance\skv@cnta\@ne
+ }%
+ \do
+ }%
+ \do#2#1\skv@nil
+ \ifnum\skv@cnta>\tw@
+ \@tempcnta\m@ne
+ \def\do##1#1{%
+ \advance\@tempcnta\@ne
+ \ifnum\@tempcnta=\numexpr\skv@cnta-\tw@\relax
+ \def\do####1\skv@nil{\def\skv@tempa{##1#1####1}}%
+ \else
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist\unexpanded{##1}%
+ }%
+ \fi
+ \do
+ }%
+ \do#2#1\skv@nil
+ \else
+ \ifnum\skv@cnta=\@ne
+ % There is only one element before '<guide><parser>...' or '...'.
+ % Hence simply left-pad argument #2 with <parser> to give the
+ % impression of at least 2 elements:
+ \def\skv@tempa{#1#2}%
+ \else
+ \ifnum\skv@cnta=\tw@
+ \def\skv@tempa{#2}%
+ \else
+ \ifnum\skv@cnta=\skvz@
+ \skv@err{List <<\detokenize{#2}>>\MessageBreak
+ contains symbol '...' but not a lowerbound}\skv@ehd
+ \fi
+ \fi
+ \fi
+ \fi
+ \skvexpanded{\endgroup
+ \skvcmdexit\skvcompletedlist\skvcmdexit\skv@tempa
+ }%
+}
+% \skv@autocomplete@splitandgrow{<parser>}{<lower1>}{<lower2>}{<upperbound>}
+%
+% {0\pi,0.5\pi,...,3\pi} : link = \pi ; grow left
+% {1--,4--,...,10--} : link = -- ; grow left
+% {2pt,4pt,...,10pt} : link = pt ; grow left (or no additional info.)
+% {A_1,C_1,...,Q_1} : link = _ ; grow left
+% {2^a,2^c,...,2^q} : link = ^ ; grow right
+%
+% 1. Providing the link avoids the need to use the syntax of PGF's
+% \foreach, such as {0\pi,0.5\pi,...\pi,3\pi}. But skeyval can also
+% autocomplete lists like {0\pi,0.5\pi,...\pi,3\pi}.
+% 2. We already know that the key 'link' will reject empty values.
+%
+\skvrobustdef*\skv@autocomplete@splitandgrow#1#2#3#4{%
+ \ifx\skv@autocomplete@growleft\skv@autocomplete@growright
+ \skv@err{I can't grow the list in both directions.
+ \MessageBreak Maybe you haven't indicated the
+ \MessageBreak direction of growth (left or right),
+ \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'}\skv@ehd
+ \fi
+ \begingroup
+ \def\skv@prova##1{%
+ \skv@foreach@swatrue
+ \skviflacus#2\then\else
+ \skvifinTF{##1}{#2}{}\skv@foreach@swafalse
+ \fi
+ \skvifinTF{##1}{#3}{}\skv@foreach@swafalse
+ \skvifinTF{##1}{#4}{}\skv@foreach@swafalse
+ \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}'}\skv@ehd
+ \fi
+ \def\skv@prova####1##1####2\skv@nil{%
+ \if\skv@autocomplete@growright
+ \edef\skv@prova{\skvtrimspace{####1##1}}%
+ \else
+ \edef\skv@prova{\skvtrimspace{##1####2}}%
+ \fi
+ \def\do########1{{\skvtrimspace{########1}}}%
+ % \skv@autocompletelist@f<parser><guide><lower1><lower2><upper>
+ \skvexpanded{\endgroup
+ \noexpand\skv@autocompletelist@f
+ {\unexpanded{#1}}{\skvexpandonce\skv@prova}\do{#2}\do{#3}\do{#4}%
+ }%
+ }%
+ \skv@prova#3\skv@nil
+ }%
+ \expandafter\skv@prova\expandafter{\skv@autocomplete@link}%
+}
+\skvrobustdef*\skv@autocomplete@getcomparator{%
+ \begingroup
+ % <unit> isn't required in alphabetic sequences:
+ \if\skv@inalphabetic\else
+ \let\skvreversedo\@iden
+ \edef\skv@provb{\skvexpbracenext\skvreverse\skv@autocomplete@step}%
+ \def\skv@prova##1##2##3\skv@nil{%
+ \skvxifinTF{,\detokenize{##2##1},}{,\skvoxdetok\skv@validunit,}{%
+ % That is, the sequence is made up of dimensions.
+ \def\skv@autocomplete@unit{}%
+ }{%
+ \def\skv@autocomplete@unit{pt}%
+ }%
+ }%
+ \expandafter\skv@prova\skv@provb\skv@nil
+ \fi
+ % You can't use \ifnum or \ifdim here, since for alphanumeric sequences
+ % \skv@autocomplete@step isn't a dimension.
+ \def\skv@prova##1##2\skv@nil{%
+ \edef\skv@autocomplete@stepisneg{0\if-##10\else1\fi}%
+ }%
+ \expandafter\skv@prova\skv@autocomplete@step\skv@nil
+ \edef\skv@comparator{\if\skv@autocomplete@stepisneg>\else<\fi}%
+ \let\do\skvcmdexit
+ \skvexpanded{\endgroup
+ \do\skv@autocomplete@stepisneg\do\skv@comparator
+ \if\skv@inalphabetic\else\do\skv@autocomplete@unit\fi
+ }%
+}
+\begingroup
+\catcode`P=12 \lccode`P=112
+\catcode`T=12 \lccode`T=116
+\lowercase{\endgroup
+ \def\skv@autocomplete@strippoint#1#2{%
+ \def\reserved@a##1#1\relax{\def#2{##1}}%
+ \def\do##1.##2PT#1{%
+ \ifx\do##1\else##1%
+ \if\skv@autocomplete@keephighdecimals
+ \ifdim.##2pt>.5pt\relax##2\fi
+ \else
+ \if\skv@autocomplete@keepdecimals
+ \ifnum##2>\skvz@.##2\fi
+ \fi
+ \fi
+ \unexpanded{#1}%
+ \expandafter\do
+ \fi
+ }%
+ \edef#2{\expandafter\do#2#1\do.PT#1}%
+ \expandafter\reserved@a#2\relax
+ }
+}
+% \skv@autocomplete@restore{<parser>}{<guide>}{<listcmd>}
+%
+% Restore guide and, in the case of dimension sequences, 'original unit'.
+%
+\skvrobustdef*\skv@autocomplete@restore#1#2#3{%
+ \if\skv@preandpostdotspresent
+ % Leave it: <predots> and <postdots> will be restored in
+ % \skv@autocompletelist@g.
+ \else
+ \def\do##1#1{%
+ \ifx\do##1\else
+ \edef\skvcompletedlist{%
+ \skvaddlist{#1}\skvcompletedlist
+ \if\skv@autocomplete@growleft
+ ##1\skv@autocomplete@origunit\unexpanded{#2}%
+ \else
+ \unexpanded{#2}##1\skv@autocomplete@origunit
+ \fi
+ }%
+ \expandafter\do
+ \fi
+ }%
+ \expandafter\do#3#1\do#1%
+ \fi
+}
+
\skv@for@restorecatcodes
\endinput