This is the README file for the 'skeyval' package. AUTHOR Ahmed Musa VERSION Version 1.1a, October 16, 2012. LOCATION ON CTAN macros/latex/contrib/skeyval LICENSE Copyright (c) 2010-2012 Ahmed Musa This software is author-maintained. Permission is granted to copy, distribute and/or modify this software under the terms of the LaTeX Project Public License, version 1.3 or higher. This software is provided 'as it is', without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for any particular purpose. FILES The following files constitute the skeyval bundle and must be distributed as a whole: 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. The skeyval package can be used by LaTeX and non-LaTeX users. LaTeX users should load the package via \usepackage[]{skeyval} or, in class files and packages, \RequirePackage[]{skeyval} Plain TeX users can do \input skeyval-core Users of pre-version-1.0 of skeyval package can access the former version by entering the option 'compatibility' in above. This option will automatically load version 0.73 (the version just before 1.0) of skeyval package. From version 1.0, the package has changed radically. SUMMARY 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. 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. 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 of keys). This speeds up key processing and reduces the computational 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 ** The callbacks of keys can be readily modified using commands like \skvaddtocallback, \skvprependtocallback, \skvappendtocallback, or the handlers .prepend code, .append code, .add code. ** Apart from the usual keys in xkeyval and ltxkeys packages, it is now possible to define a rather weird key like \skvpntkey[KV]{fam}{evaluate (?) as (?) using (?)}{\edef#2{#3}} The key name here is 'evaluate (?) as (?) by (?)'. It has three arguments, indicated by the closed parenthesis. The mark '?' can be replaced by any character or characters, and the key could have up to 9 arguments. This key can be set as \skvsetkeys[KV]{fam}{evaluate (\x) as (\y) using (\numexpr\x*2)} We can also define the same key with the default values specified: \skvpntkey[KV]{fam}{evaluate (?) as (?) using (?)}[\x\y{\numexpr\x*2}]{% \def\argone{#1}\def\argtwo{#2}\def\argthree{#3}% } and set it as follows (if pgfmath package is loaded): \skvsetkeys[KV]{fam}{% evaluate (\x) as (\pgfmathresult) using (\pgfmathparse{\x^10}) } ** Handlers The skeyval package has many handlers. The handlers of start with a dot (.), as in pgfkeys package. Unlike in pgfkeys package, when 'expand' or 'expanded' is found in a handler, the expansion will invariably be done when the key is set, not when it's being defined. ** Subject-observer keys (called 'style keys' in pgfkeys) can be readily introduced. \skvappendstyles[KV]{fam}{key1,key2}{keya=.expanded{\vala},keyb=valb} [defaultof 1&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 of the observers on the current path. In the future, we intend to extend the subject-observer functionality to include more features of the observer pattern found in other programming paradigms. We foresee that subjects will be able to publish their services, and observer keys will be able to subscribe for notification from subjects. And rather than 'notify messages' simply setting observer keys with prior prescribed observer values, as is currently the obtainable, observers may be able to do more with such messages (such as change observer state patterns). ** The parameters/arguments of callbacks of keys can be easily changed by calling \skvdefinekeys, \skvmakekeys, \skvassignargs or \directkeys. \skvordkeys[KV1]{fam2}{keya,keyb}[default-a]{\def\x##1{#1*##1}} \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. \directkeys{% .exec code=\def\avalue{a+b}, .prefixes={KV1,KV2}, .families={fam1,fam2}, .holder prefix=mp@, .initialize keys after define, .define keys={ .ord/keya/def-a/\def\xa##1{#1*##1*#2}, .arg/keya/#1+#2, .cmd/.value required{keyb}/def-b/\def\cmdb##1{##1@#1}, }, .initial values={ keya=ini-value, }, .ignore family=fam2, .set keys={ keya=.expanded{\avalue} }, ** Nested \directkeys. The current path is put on stack and restored later, so that the nest is independent of its surrounding topology (prefix and family). But the default prefix survives outside \directkeys. \directkeys{ .default prefix=KV, % The prefix for 'famx' will be 'KV'. .paths={KV3/fam3,famx}, .new keys={ .initialize keys after define=false, .ord/keya/defa/\def\ya##1{#1*##1*#2}, .arg/keya/#1+#2, .choice/keyc/center/{right,left,center,justified}, .arg expanded/keyc/#1, .bool/keyd/true, .cmd/.forbid value{keye}/defe/\def\ye##1{#1*##1}, }, }, .try set keys={ .paths={KV1/fam1,KV3/fam3}, .try=2, .goal=1, .kv list={keyc=left,keyd=false}, }, .ignore path=KV1/fam1, .exec=\def\cvalue{center}, .search also set keys={ .add prefix=KV3, .add families={fam3,fam4}, .max attempts=4, .goal=2, .kv list={keyc=.expand once{\cvalue}}, }, .append values={ keya=\def\y##1{#1+##1}, keyb=\def\w##1{#1+##1}, }, .prepend code={ keyb=\def\pre##1{#1+##1}, }, .styles{ key1/keya=value1, key2/keyb=value2 }, .inherit code={ key1/keyb, key2/keyd }, .preset keys={ key1,key2 }, } ** Prepending and appending to key names and callbacks at definition time: \directkeys*{ .path=claudio/color, .hp=claudio@col@, .define keys={ .prepend to every key name=X@, .append to every key name=@Y, .prepend to every callback=\def\X##1{#1*##1}, .append to every callback=\def\Y##1{##1**#1}, .ord/{1,2,3,4,5,6}/red, } } \skvusekeys[.path=claudio/color]{X@1@Y,X@2@Y} ** 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: \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}, .allowed values expanded=keye/{ center.do=\def\curralign##1{\hfil##1\hfil}, right.do=\def\curralign##1{\hfill##1}, left.do=\def\curralign##1{##1\hfill}, justified.do=\let\curralign\@iden }, } ** Bipolar boolean keys \skvbiboolkeys[KV]{fam}[mp@]{.forbid value{keya},keyb}[true]{% \ifmp@keya\def\xa##1{##1}\fi }{% \ifmp@keyb\def\xb##1{##1}\fi }% \skvsetkeys[KV]{fam}{keya} The value of keya is frozen as 'true'. Hence whenever keya is called, the value 'true' will be used for it. Since keya and keyb are bipolar, the value of keyb will be 'false' whenever keya is called. \skvbiboolkeys+[KV]{fam}[mp@]{keya,keyb}[true]{% \ifmp@keya\def\xa##1{##1}\fi }{% \ifmp@keyb\def\xb##1{##1}\fi }{% \skv@warn{Value '#1' is invalid}% } \skvsetkeys[KV]{fam}{keya=xtrue} ** The concepts of 'trying' to set a key with 'goals' is introduced. The handler '.goal' can be interpreted in the sense of \pagegoal, but applied to setting a key. See an example above. Then there is 'search also' set keys. ** 'Quick keys' are a new concept. They're quite fast to define and set, but they can't carry pointers. \quickkeys.define{}[]{} \quickkeys.set{}[]{} When defining keys, the syntax of is: {}/{}/{}/{}/{} ;...; {}/{}/{}/{}/{} Example: \quickkeys.define{fam}[mp@]{% keya/true/\def\x##1{#1*##1}/true,false; keyb; keyc,keyd/aaa+bbb/\def\y##1{#1*##1*#2}/.na/#1+#2; } '.na' means a missing entry that isn't empty but should be ignored. can be used to restrict the user-values of the key or keys. means the argument pattern for the key or keys. ** 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 ]{% .ord/{keya,keyb}/{default-a}, .arg/keyb/{#1+#2}, .cmd/{keyc,keyd}/, .zcmd/key e/\def\cmde##1{##1}/ \edef\y{\detokenize\expandafter{\thp@keye}}\def\x##1{#1*key e*##1}, .choice/keyf/center/{center.do=\def\x##1{#1*##1},left,right}, .zbool/show center/true/\edef\cmd{\ifthp@showcenter Yes\else No\fi} } 'z-keys' are keys whose names are zapped (ie, spaces are removed) internally. This is to allow holder/store macros to be used without spaces in their names, while maintaining key names with spaces. ** Keys can be set using \skvsetkeys, \directkeys (with the handlers .set keys, .try, etc.), or \skvusekeys: \krdusekeys[ .prefix=KVA, .families={fam1,fam2}, .set in all families, .save unknown keys ]{% keya,keyb } \directkeys*{ .path=user/color, .hp=user-col-, .define keys={ .cmd/{1,2,3,4,5,6}/red } } \newcommand*\setcolorlist[1]{\skvusekeys[.path=user/color]{#1}} \setcolorlist{1=red,2=blue,3=cyan,4=green,5=magenta,6=purple} \newcommand*\usecolor[1]{% \skvifcsname user-col-#1\then \csname user-col-#1\endcsname \else black% \fi } \newcommand*\drawcoloredarrows[1]{% \foreacfox {#1}{% \draw[\usecolor{##1},-stealth] (0,-##1)--(2,-##1); } } \begin{document} \begin{tikzpicture} \drawcoloredarrows{1,...,4} \end{tikzpicture} \end{document} ** 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. ** Files skeyval-pstkey.sty and skeyval-pstkey.tex are provided for PSTricks developers and users, as did xkeyval package. ** Some new and versatile looping macros are introduced in the skeyval package. In fact, the powerful \newforeach list processor of the 'loops' package has its roots in the 'skeyval-for' module. It is a generalization of PGF's \foreach macro for arbitrary parsers and list separators, including active parsers. % End of readme file