diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex | 1061 |
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 |