diff options
Diffstat (limited to 'Master/texmf-dist/doc/latex/skeyval/README')
-rw-r--r-- | Master/texmf-dist/doc/latex/skeyval/README | 445 |
1 files changed, 413 insertions, 32 deletions
diff --git a/Master/texmf-dist/doc/latex/skeyval/README b/Master/texmf-dist/doc/latex/skeyval/README index 5a43e018146..00977c54e35 100644 --- a/Master/texmf-dist/doc/latex/skeyval/README +++ b/Master/texmf-dist/doc/latex/skeyval/README @@ -6,7 +6,7 @@ Ahmed Musa VERSION -Version 1.1a, October 16, 2012. +Version 1.2, February 10, 2013. LOCATION ON CTAN @@ -14,7 +14,7 @@ macros/latex/contrib/skeyval LICENSE -Copyright (c) 2010-2012 Ahmed Musa +Copyright (c) 2010-2013 Ahmed Musa This software is author-maintained. Permission is granted to copy, distribute and/or modify this software under the terms of the @@ -60,19 +60,18 @@ The 's' in skeyval means 'skeleton keys' or 'master keys'. The skeyval package provides commands for compactly defining and initializing all types of key (ordinary, command, boolean, style, choice, -etc). It attempts to combine the features of ltxkeys package (which has -the syntax of the xkeyval package) and pgfkeys package. One of the powers -of pgfkeys package lies in its use of handlers. But the way handlers -are used in pgfkeys package does add to computational complexity and -overheads. Family or key filtering in pgfkeys is particularly complex -and inefficient. Nesting of family or key filtering is, in particular, -not recommended. +etc). It attempts to combine the features of xkeyval package and +pgfkeys package. One of the powers of pgfkeys package lies in its use +of handlers. But the way handlers are used in pgfkeys package does add +to computational complexity and overheads. Family or key filtering in +pgfkeys is particularly complex and inefficient. Nesting of family or +key filtering is, in particular, not recommended. In pgfkeys package, handlers come at the end of the key name, so that if a key isn't defined, the system tests to find if the key has a handler at its end. If a handler is found and defined, the handler's callback (called 'code' by pgfkeys package) is executed on the -current path. +current path. The required search overhead isn't insignificant. The skeyval package puts handlers at the beginning of the key (or a set of keys) and uses the handler to process the key (or a set @@ -81,12 +80,58 @@ complexity. Key processing, including filtering, can be nested naturally and efficiently. The skeyval package also maintains and, in fact, greatly extends the -functionality and syntaxes of the ltxkeys package. Very few examples -of the functionality of skeyval package are +functionality and syntaxes of the xkeyval and ltxkeys packages. -** The callbacks of keys can be readily modified using commands - like \skvaddtocallback, \skvprependtocallback, \skvappendtocallback, - or the handlers .prepend code, .append code, .add code. +Some of the features of skeyval vs. xkeyval are as follows. All the +features listed below could be incorporated in xkeyval package but +at a great expense. + +* xkeyval's use of the rather expensive selective sanitization + scheme of Uwe Kern; + +* xkeyval strips three levels of outer braces in the values of keys; + +* the impossibility of parsing unbalanced conditionals in key values + while using xkeyval; + +* xkeyval requires a large payload for defining many keys in the + same family; + +* when using xkeyval, existing keys could be easily overridden + (there is nothing like \newcommand functionality); + +* key macros, once defined by xkeyval, are difficult to modify/patch; + +* key macros defined by xkeyval can't accept more than one argument; + +* xkeyval provides no machinery for deploying style (subject/observer) + keys; + +* xkeyval offers no direct tools for key-commands and key-environments; + +* xkeyval can't be loaded before \documentclass (eg, in the past the + fontspec package needed this feature); + +* skeyval offers 'list processor keys' (called 'listkeys'). + + +Very few examples of the functionality of skeyval package are given in +the following. + +** Ordinary, command/store, boolean, toggle, and choice keys can be + defined and set. For example, + + \skvordkeys[KV]{fam}{key1,key2}[default value]{% + \def\testcmd##1##2{#1+##1+##2}% + } + \skvoptionkeys[KV]{fam}{key1} + \skvnonoptionkeys[KV]{fam}{key2} + + \skvchoicekeys[KV]{fam}[mp@]{key1,key2}[\val\nr]{% + center.do=\def\vala{#1}, + right.do=\def\valb{#1}, + left.do=\def\valc{#1} + }[center]{\def\x##1{#1*##1}} ** Apart from the usual keys in xkeyval and ltxkeys packages, it is now possible to define a rather weird key like @@ -112,6 +157,40 @@ of the functionality of skeyval package are evaluate (\x) as (\pgfmathresult) using (\pgfmathparse{\x^10}) } +** Default prefix can be set by + + \skvsetdefaultprefix{<pref>} + + For a fixed prefix, this can be used to avoid repeated entry of the + key prefix in many of the commands of the skeyval package. Note, + however, that the first '[]' in + + \skvordkey[KV]{fam}{key1}[deafult value]{} + + still can't be used for any other thing than the key prefix. + + With + + \skvsetdefaultprefix{myprefix} + + we can do + + \skvordkey{fam}{key1}[deafult1]{} + \skvcmdkey{fam}[mp@]{key2}[deafultx,defaulty]{% + \def\cmd##1{#1+#2+##1}% + } + \skvassignargs{fam}[.expanded]{key2}{#1,#2} + + and much later + + \def\valuex{valuex} + \def\valuey{valuey} + \skvsetkeys[myprefix]{fam}{key1=value1,key2={\valuex,\valuey}} + +** The callbacks of keys can be readily modified using commands + like \skvaddtocallback, \skvprependtocallback, \skvappendtocallback, + or the handlers .prepend code, .append code, .add code. + ** Handlers The skeyval package has many handlers. The handlers of @@ -126,7 +205,7 @@ of the functionality of skeyval package are introduced. \skvappendstyles[KV]{fam}{key1,key2}{keya=.expanded{\vala},keyb=valb} - [defaultof 1&2]{\def\y##1{#1*##1}} + [default of key1&2]{\def\y##1{#1*##1}} Here the subjects are key1 and key2, while the observers are keya and keyb. For now, the only thing the subject does is to set the given values @@ -146,12 +225,13 @@ of the functionality of skeyval package are \skvassignargs[KV1,KV2]{fam1,fam2}[x1]{keya,keyb}{#1/#2} \skvsetkeys[KV1]{fam2}{keya=vala/valb} - 'x1' here means expand argument once at setting keys. + 'x1' here means 'expand argument once at setting keys'. + +** \directkeys command: \directkeys{% .exec code=\def\avalue{a+b}, - .prefixes={KV1,KV2}, - .families={fam1,fam2}, + .paths={KV1/fam1,KV1/fam2,KV2/fam1,KV2/fam2}, .holder prefix=mp@, .initialize keys after define, .define keys={ @@ -175,7 +255,7 @@ of the functionality of skeyval package are \directkeys{ .default prefix=KV, % The prefix for 'famx' will be 'KV'. - .paths={KV3/fam3,famx}, + .paths={KV3/fam3,KV3/famx}, .new keys={ .initialize keys after define=false, .ord/keya/defa/\def\ya##1{#1*##1*#2}, @@ -207,7 +287,7 @@ of the functionality of skeyval package are .prepend code={ keyb=\def\pre##1{#1+##1}, }, - .styles{ + .slots{ key1/keya=value1, key2/keyb=value2 }, @@ -219,6 +299,26 @@ of the functionality of skeyval package are }, } +** Handlers and letting handlers + + The skeyval has many handlers and many tools for creating handlers. + A full listing of handlers and their meaning will be provided in + the user manual. + + .define handlers, .define handler + .new handlers, .new handler + .new reserved handlers, .new reserved handler, + .define reserved handlers, .define reserved handler + .define narg handler,.define narg handlers + .new narg handler,.new narg handlers + .new reserved narg handler,.new reserved narg handlers, + .define reserved narg handler,.define reserved narg handlers + .handlers let, .handler let + .handlers let*, .handler let*, .force handler let + .handlers let reserved, .handler let reserved + .reserve handlers + + ** Prepending and appending to key names and callbacks at definition time: @@ -237,16 +337,15 @@ of the functionality of skeyval package are ** Several new features are introduced by the skeyval package. For - example, we now have 'style' and 'link' keys in the context of - ltxkeys syntax. For example, to link keys via .link or .style - handler: + example, we now have 'slot' and 'link' keys. For example, to link + keys via .link or .slot handler, we can do: \directkeys{% .link={key1, key2}/keya, .link={key3, key4}/{keya, keyb}, - .append style expand twice={key3, key4}/keyf=\valuea, - .prepend style expanded={key5, key6}/{keyc=#1, keyd=#1}, - .prepend style={key7, key8}/{keyd=#1, keye=#1}, + .append slot expand twice={key3, key4}/keyf=\valuea, + .prepend slot expanded={key5, key6}/{keyc=#1, keyd=#1}, + .prepend slot={key7, key8}/{keyd=#1, keye=#1}, .allowed values expanded=keye/{ center.do=\def\curralign##1{\hfil##1\hfil}, right.do=\def\curralign##1{\hfill##1}, @@ -314,8 +413,12 @@ of the functionality of skeyval package are ** Keys can be 'made', as in \skvmakekeys[ - .prefix=KVA, .families={fam1,fam2}, .holder prefix=mp@, - .all are new, .define in all families, .initialize after define + .prefix=KVA, + .families={fam1,fam2}, + .holder prefix=mp@, + .all are new, + .define in all families, + .initialize after define ]{% .ord/{keya,keyb}/{default-a}, .arg/keyb/{#1+#2}, @@ -360,7 +463,7 @@ of the functionality of skeyval package are \fi } \newcommand*\drawcoloredarrows[1]{% - \foreacfox {#1}{% + \foreachfox {#1}{% \draw[\usecolor{##1},-stealth] (0,-##1)--(2,-##1); } } @@ -370,7 +473,184 @@ of the functionality of skeyval package are \end{tikzpicture} \end{document} -** Keys defined in families can be viewed in files using the package +** Arguments of keys: + + Argument of keys can be prescribed + + 1. Within the key's callback by using the pointers + + .arg, .arg unexpanded, .arg expand once, .arg expand twice, + .arg expanded. + + Example: + + \def\somemethod#1#2{% + \begingroup + \color{#1}% + Using \ifskvnovalue default\else user \fi value of `\skvcurrentkey'. + \endgraf + Argument-2 of key: #2% + \endgroup + } + % Test arguments given inside the callback: + \skvcmdkeys[KV]{fam}{keya}[red/default]{% + .arg expanded{#1/#2}% + \somemethod{#1}{#2}% + } + \begin{document} + \def\aval{blue/Some stuff} + \skvsetkeys[KV]{fam}{keya=\aval} + \end{document} + + 2. By calling the command \skvassignargs. + + 3. By using the following handlers within \directkeys or within + \skvdefinekeys + + .arg, .arg unexpanded, .arg expand once, .arg expand twice, + .arg expanded + + +** Listkeys + + List processor keys. The key's value is considered a csv list + and each of its element is used as the argument of the key's callback. + The user of a listkey doesn't have to define his own list processor, + or define one key for each list item. The list separator can be + arbitrary; it can be specified in the key's callback as the + argument of the dummy commands \listsep and \listparser. The default + list separator is comma (,). + + \makeatletter + \def\somemethod#1#2{% + \begingroup + \color{#1}% + \ifskvnovalue + \ifnum\skvlistcount=\@ne + \endgraf + Using default value of `\skvcurrentkey': + \fi + \else + \ifnum\skvlistcount=\@ne + \endgraf + Using user value of `\skvcurrentkey': + \fi + \fi + \endgroup + \endgraf + Processing item no. \skvlistcount: #2% + } + + % Use comma (,), the default list separator, as the list + % separator for keya and keyb: + \skvlistkeys[KV]{fam}{keya,keyb}[default1,default2]{% + \somemethod{blue}{#1}% + % Process only four (4) items of the list/value for keya and keyb: + \ifnum\skvlistcount=4\relax + \skvstopprocessinglistkey + \fi + } + %\skvshowcs{KV/fam/keya.@cbk} + + % Use semicolon (;) as the list separator for keyc and keyd: + \skvlistkeys[KV]{fam}{keyc,keyd}[default1;default2]{% + % The next line gives error, as expected, since a list key + % can't have an assigned argument that isn't simple. + % .arg{#1,#2}% + \listsep{;}\somemethod{red}{#1}% + } + \makeatother + + \begin{document} + \parindent0pt + % No values for keya and keyb; use their default values: + \skvsetkeys[KV]{fam}{keya,keyb} + \par\bigskip + \skvsetkeys[KV]{fam}{% + keya={item1A,item1B,item1C,item1D,item1E,item1F}, + keyb={item2A,item2B,item2C,item2D,item2E,item2F} + } + \par\bigskip + % Set keyc and keyd with their default values: + \skvsetkeys[KV]{fam}{keyc,keyd} + \par\bigskip + \skvsetkeys[KV]{fam}{% + keyc={item1A;item1B;item1C;item1D}, + keyd={item2A;item2B;item2C;item2D} + } + \end{document} + +** Make any key a listkeys at key-setting time + + You can use the pointers '.process list' on any key's value at + key-setting time to temporarily turn that key into a listkey. + Its current value will be processed as a list, ie, the key's + callback will be applied to every element of the current value. + This scheme is costlier than defining the key as a listkey, + using \skvlistkey, but it is more versatile. This allows any + key to accept and process a value that is a list, irrespective + of its argument pattern. + + Example 1: + + \skvordkeys[KV]{fam}{key1,key2}[default]{\def\xx##1{##1*#1}} + \skvsetkeys[KV]{fam}{% + key1=val1,key2=.process list{val2a,val2b} + } + + Example 2: + + \skvordkeys[KV]{fam}{key1,key2}[default]{% + .arg expanded{#1/#2}% + \def\x##1{##1*#1*#2}% + } + \def\aval{val1a/val1b} + \def\bval{val2a/val2b,val2c/val2d} + \skvsetkeys[KV]{fam}{% + % Because of '.arg expanded' in the key's callback, \aval + % will be expanded at setting keys: + key1=\aval, + % \bval will be expanded before its content is processed + % as a list. Because of '.arg expanded' in the key's callback, + % each element in \bval will be expanded at setting keys: + key2=.expand once process list{\bval} + } + + Example 3: + + \skvordkeys[KV]{fam}{key1}[default]{\def\x##1{##1*#1}} + \def\aval{val1a,val1b,val1c,val1d} + \def\bval{\aval} + \def\cval{\bval} + \skvsetkeys[KV]{fam}{% + key1=.expand once process list{\aval}, + key1=.expand twice process list{\bval}, + key1=.expand process list{\cval} + } + + +** Disabling keys: + + Message type to be issued when a disabled key is called: + + \skvmessagetypefordisabledkey{<message type>} + + <message type> can be 'warning', 'error', or 'nothing'. The default is + 'warning'. + + The key(s) may be disabled long before \skvmessagetypefordisabledkey + is called. + + Disabling keys locally: + + \skvdisablekeys[<pref>]{<fam>}{<key list>} + + Disabling keys globally: + + \skvgdisablekeys[<pref>]{<fam>}{<key list>} + + +** Keys defined in families can be 'viewed' in files using the package 'skeyval-view'. The functionality of 'skeyval-view' is greater than that of xkeyval-view package. @@ -383,5 +663,106 @@ of the functionality of skeyval package are module. It is a generalization of PGF's \foreach macro for arbitrary parsers and list separators, including active parsers. +** For a package 'foobar', you can access its options by + + \csname opt@foobar.sty\endcsname + + To get the options that were actually found/defined and instantiated + during the processing of options, the skeyval package offers + \skvpackagelist and '.poxkeys' (processed options). + + If 'option1' and 'option2' (but not 'option3') are recognized + options of foobar.sty, then after + + \usepackage[option1,option2,option3]{foobar} + + you can issue + + \show\skvpackagelist -> foobar.sty{option1,option2} + + \expandafter\show\csname foobar.sty.poxkeys\endcsname + -> option1, option2 + +** Key filtering + + The handlers for key filtering are + + .prefix, .change prefix, .family, .change family, .families, + .change families, .add family, .add families, .ignore family, + .ignore families, .restore family, .restore families, .paths, + .change path, .change paths, .add paths, .ignore paths, .restore paths, + .ignore keys, .restore keys + + \newcommand{\storecontent}{} + \newcommand{\usecontent}{% + \ifx\storecontent\@empty + \@@warning{\noexpand\storecontent is empty}% + \else + \storecontent + \fi + } + \directkeys{% + % Define keys in two families: + .families={family1,family2}, + .define ordinary keys={ + store//\skvappendtomacro\storecontent{#1}, + remove//\skvpatchcmd\storecontent{#1}{}{}{ + \@@warning{No token '\detokenize{#1}' in command \string\storecontent} + } + } + } + \def\savpar{\par} + \def\bigvskip{\par\bigskip} + \def\showfam{Family: \skvcurrentfamily\savpar} + + \begin{document} + \directkeys{% + % Set keys in only family1: + .family=family1, + .set keys={ + store={\showfam first test\bigvskip}, + store={\showfam second test\bigvskip} + }, + .exec code=\usecontent{\color{red}\savpar\hrule\bigvskip}, + % Set keys in only family2: + .family=family2, + .set keys={ + remove={\showfam first test\bigvskip}, + remove={\showfam second test\bigvskip}, + store={\showfam third test\bigvskip}, + store={\showfam fourth test\bigvskip} + }, + .exec code=\usecontent + } + \end{document} + +** Inheritance of keys + + There are \skvkeyslet with the syntax + + \skvkeyslet[<pref>]{<family>}{<list>} + <list> -> {<newkey1>,<newkey2>,...,<newkey-n>}={<oldkey>} + + and the handler .inherit. + + \directkeys{ + .prefix=KV, + .family=fam, + .define ordinary keys={ + key1/def1/\def\cmd##1{#1*##1}, + key2/def2 + }, + .inherit={ + {key3,key4}={key1}, + } + } + \skvshowcs{KV/fam/key3.@cbk} + +** Defining and setting keys on fixed prefix and family + + \skvsetprefix{KV} + \skvsetfamily{fam} + \skvdefineordkey{key1}[def1]{\def\cmd##1{#1*##1}} + \skvprocesskeys{key1=value1} -% End of readme file
\ No newline at end of file +% End of readme file of skeyval package. |