summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/latex/ltxkeys/README46
-rw-r--r--Master/texmf-dist/doc/latex/ltxkeys/ltxkeys-guide.txt530
-rw-r--r--Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty2036
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/ltxkeys.tlpsrc0
6 files changed, 2614 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/ltxkeys/README b/Master/texmf-dist/doc/latex/ltxkeys/README
new file mode 100644
index 00000000000..a0d9804f9e3
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/ltxkeys/README
@@ -0,0 +1,46 @@
+This is the README file for the ltxkeys package.
+
+SUMMARY
+
+The ltxkeys package provides facilities for creating and managing
+keys in the sense of the keyval and xkeyval packages, but it
+is intended to be more robust and faster. Its robustness emanates
+from its ability to preserve braces in key values throughout
+parsing. The need to preserve braces in key values emerges often
+in parsing keys. This is often the case in, eg, the xwatermark
+package. The package is faster than the xkeyval package because,
+among other features, it avoids character-wise parsing of key
+values (which is called selective sanitization by the xkeyval
+package).
+
+It also provides additional functionalities for defining and
+managing keys.
+
+In the ltxkeys package, the notion of 'presetting' keys differs
+from that of the xkeyval package. Only 'launched keys' are
+preset in the ltxkeys package.
+
+AUTHOR
+
+Ahmed Musa (amusa22@gmail.com)
+
+RELATED PACKAGES
+
+xkeyval.sty
+
+LICENSE
+
+Copyright (c) 2011 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.
+
+VERSION
+
+Version 0.1.0, July 2011
+
+
diff --git a/Master/texmf-dist/doc/latex/ltxkeys/ltxkeys-guide.txt b/Master/texmf-dist/doc/latex/ltxkeys/ltxkeys-guide.txt
new file mode 100644
index 00000000000..f6428e5d497
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/ltxkeys/ltxkeys-guide.txt
@@ -0,0 +1,530 @@
+This is ltxkeys-guide.tex, a minimal guide to the ltxkeys package.
+
+Version 0.1.0, July 2011
+
+Ahmed Musa (amusa22@gmail.com)
+
+
+SUMMARY
+
+The ltxkeys package provides facilities for creating and managing keys in the sense of the keyval and xkeyval packages, but it is intended to be more robust and faster than these earlier packages. Its robustness emanates from, inter alia, its ability to preserve braces in key values throughout parsing. The need to preserve braces in key values emerges often in parsing keys. This is the case in, eg, the xwatermark package. The package is faster than the xkeyval package because it avoids character-wise parsing of key values (which is called 'selective sanitization' by the xkeyval package).
+
+Anyone familiar with the implementation of the xkeyval package would have noticed that the macro \XKV@srstate, which (in order to allow \setkeys to be re-entrant) pushes and pops the states of some important functions in the package, loops over all the functions both when pushing and popping. In the ltxkeys package, pushing and popping functions together involve only one loop. And, unlike in the xkeyval package, higher order functions are undefined as soon as they are no longer needed, to avoid clogging up the stack.
+
+In setting keys, the ltxkeys package loops over not only families, as in the xkeyval package, but also over key prefixes. The same strategy applies when the xkeyval package tries to establish if a key is defined or not.
+
+Note: While many aspects of the ltxkeys package are similar to those of the xkeyval package, there are important differences in several areas of syntax, semantics, and internal implementation.
+
+The ltxkeys package also provides additional facilities (beyond the xkeyval package) for defining and managing keys. Several types of keys (including ordinary keys, command keys, style keys, choice keys, boolean and biboolean keys) can be efficiently created and managed.
+
+In the ltxkeys package, the notion of 'presetting' keys differs from that of the xkeyval package. Only 'initialized' or 'launched' keys (see \autoref{sec:xxx})' are preset in the ltxkeys package.
+
+What is the origin of 'ltxkeys'? Well, I decided to write this package as I grabbled with some practical problems of key parsing while developing version 1.5.0 of the xwatermark package. The tasks proved more challenging than I had predicted and, despite its commendable facilities, I found the xkeyval package inadequate in some respects. As mentioned earlier, the functionalities of the ltxkeys can be employed for general key management in \latex beyond the xwatermark package.
+
+
+NOTE
+
+This user manual doesn't describe the full range of features of the ltxkeys package.
+I will produce a pdf version of this guide with suitable markups in the near future, especially if someone informs me that he/she is using, or intends to use, this package. This sounds unconventional but there is no point in spending precious time now preparing a documentation that no one has a need for or is unlikely to be needed. The reason why I am releasing this documentation now is that users of the xwatermark package need an update immediately, to address some shortcomings of the current public version. But the new version of the xwatermark package relies on the ltxkeys package.
+
+
+DEFINING KEYS
+
+ In the following, quantities in square brackets --- eg '[yyy]' --- and those in parenthesis --- eg (yyy) --- are optional.
+
+1. Ordinary keys:
+
+ \ltxkeys@ordkey[<pref>]{<fam>}{<key>}[<default>]{<callback>}
+
+ This defines a macro of the form \<pref>@<fam>@<key> of one argument that holds the key function <callback>. The default value for <pref> is always KV, as in the xkeyval package. When <key> is used in a \ltxkeys@setkeys command (see \autoref{sec:}) containing key=value, the macro \<pref>@<fam>@<key> takes the value as its argument and is then executed. The given argument or key value can be accessed in <callback> by using #1 inside the function. The optional <default>, if available, will be used by \<pref>@<fam>@<key> when the user hasn't provided a value for the key at \ltxkeys@setkeys. If <default> was absent at key definition and the key user hasn't provided a value for the key, an error message will be flagged.
+
+
+2. Command keys:
+
+ \ltxkeys@cmdkey[<pref>]{<fam>}[<mp>]{<key>}[<default>]{<callback>}
+
+ The optional <mp> is called the 'macro prefix' (in the parlance of the xkeyval package). If <mp> is given, the command \<mp><key> will hold the current user input; otherwise (if <mp> is absent) the user input will be available in \cmd<pref>@<fam>@key. The command \<pref>@<fam>@key, called the \quoted{key macro} by the xkeyval package, will hold the <callback>.
+
+
+3. Style keys (keys with dependant keys):
+
+ \ltxkeys@stylekey[<pref>]{<fam>}[<mp>]{<key>}[<default>](<dependants>){<callback>}
+
+ \ltxkeys@stylekey*[<pref>]{<fam>}[<mp>]{<key>}[<default>](<dependants>){<callback>}
+
+ The <dependants> have the syntax:
+
+ {<keytype>/<keyname>/<default>/<callback>; another set of dependant; etc}
+
+ <default> and <callback> can be absent. <keytype> can be 'ord' (ordinary key), 'cmd' (command key), 'bool' (boolean key), or 'choice' (choice key).
+
+ Dependants keys always share the same key prefix <pref>, family <fam>, and macro prefix <mp> with the parent key.
+
+ If <mp> is given, the command \<mp><key> will hold the current user input for the parent key; otherwise the user input will be available in \style<pref>@<fam>@key. The command \<pref>@<fam>@key will always hold the <callback>.
+
+ If the *-form is used, all undefined dependants will be defined and set on the fly as the parent is being set. If the *-form isn't used and undefined dependants occur, then an error message will be flagged at the time the parent is being set.
+
+ At most times it is possible to access the parent key's current value with \parentval. Within <default> and <callback> of <dependants>, it is possible to refer to the parent key's callback with its full macro name (ie, \<pref>@<fam>@<key>). \parentval is always available for use as the default value of dependant keys, but it may be lost in the callbacks of dependant keys, because a dependant key, once defined, may be set independent of, and long after, the parent key has been executed. It is therefore more reliable to refer to the macro \<pref>@<fam>@<key>@value, which is recorded for only the parent key of style keys and which holds the current user input for the parent key. The macro \<pref>@<fam>@<key>@value is recorded only if it appears at least once in the attributes of dependant keys. The macro \<pref>@<fam>@<key>@value has a more unique name than \<mp>@<key> but they always contain the same value of a style key. As mentioned above, if <mp> is not given, the user input for a style key will be available in the macro \style<pref>@<fam>@key, instead of \<mp>@<key>.
+
+ Note: '#1' in the callback of parent key refers to the current value of the parent key, while '#1' in the callback of any dependant key refers to the current value of that dependant key.
+
+ Example (define and set all undefined dependants on the fly):
+
+ \ltxkeys@stylekey*[KV]{fam}[mp@]{keya}[{left}](%
+ % '#1' here refers to the value of the DEPENDANT key
+ % at the time it is being set. Use \parentkey and \parentval
+ % here to access the parent key name and its current value:
+ ord/keyb/{right}/\def\y##1{#1##1};
+ % The default of keyc is the current value of parent (keya):
+ cmd/keyc/\parentval;
+ % Because \KV@fam@keya@value appears below, it will be saved
+ % when the parent key (keya) is being set, otherwise it would be
+ % unavailable:
+ bool/keyd/true/\ifmp@keyd\edef\x##1{##1\KV@fam@keya@value}\fi
+ ){
+ % '#1' here refers to the value of the PARENT key
+ % at the time it is being set:
+ \def\x##1{##1xx#1xx}%
+ % Check the value of parent key:
+ \ltxkeys@checkchoice[\val\nr]{#1}{left,right,center}%
+ }
+
+ \ltxkeys@setkeys[KV]{fam}{keya={right}}
+
+ The braces in the values are just to exemplify the fact that braces in key values are preserved throughout key parsing. This is essential in, for example, the xwatermark package.
+
+
+4.1 Boolean keys:
+
+ \ltxkeys@boolkey[<pref>]{<fam>}[<mp>]{<key>}[<default>]{<callback>}
+
+ \ltxkeys@boolkey+[<pref>]{<fam>}[<mp>]{<key>}[<default>]{<callback>}{<fn>}
+
+ If <mp> is given, the command \<mp><key> will hold the current user input for the key at key setting time; otherwise the user input will be available in \bool<pref>@<fam>@key\footnote{This differs from the system in the xkeyval package.}. If <mp> is specified, a boolean of the form \if<mp><key> will be created at key definition, which will be set by \ltxkeys@setkeys according to the user input. If <mp> is not specified, a boolean of the form \ifbool<pref>@<fam>@key will instead be created.
+
+ The user input for boolean keys must be in the set {true | false}. The command \<pref>@<fam>@key will always hold the <callback>, which will be executed if the user input is valid.
+
+ The +-form of \ltxkeys@boolkey will execute <fn> in place of <callback> if the user input isn't in {true | false}; the plain form will issue an error in this case.
+
+
+4.2 Biboolean keys:
+
+ \ltxkeys@biboolkeys[<pref>]{<fam>}[<mp>]{<bool1>,<bool2>}
+ [<default>]{<callback1>}{<callback2>}
+
+ \ltxkeys@biboolkeys+[<pref>]{<fam>}[<mp>]{<bool1>,<bool2>}
+ [<default>]{<callback1>}{<callback2>}{<fn>}
+
+ Biboolean keys always assume opposite states: when one is true, the other is automatically toggled to false; and vice versa. Think of the options 'draft' and 'final' in a document class. Note: this is currently not the case with traditional document classes.
+
+ <callback1> belongs to the boolean key <bool1>, while <callback2> belongs to <bool2>.
+
+ The +-form of \ltxkeys@biboolkeys will execute <fn> in place of <callback1> or <callback2> if the input is not in {true | false}; the plain form will issue an error in this case.
+
+ Biboolean keys have equal symmetry (ie, they can call each other with equal propensity) and they won't bomb out in an infinite reentrance. They normally would know if they're calling each other.
+
+ Example:
+
+ \ltxkeys@biboolkeys+[KV]{fam}[mp@]{keya,keyb}[true]{%
+ \ifmp@keya\def\x##1{##1x#1x##1}\fi
+ }{%
+ \ifmp@keyb\def\y##1{##1y#1y##1}\fi
+ }{%
+ \@latex@error{Invalid value '\string#1' for keya or keyb}\@ehc
+ }
+
+
+5. Choice keys (with macro prefix, unlike in xkeyval package):
+
+ \ltxkeys@choicekey[<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<default>]{<callback>}
+
+ \ltxkeys@choicekey*+[<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<default>]{<callback>}{<fn>}
+
+ If <mp> is absent, then \ltxkeys@choicekey uses \chc<pref>@<family>@<key> to hold the user input.
+
+ <alt> is the list of nominations for the key value, ie, admissible values of the key. When <alt> has no /.code in it, it has the familiar syntax:
+
+ {choice1, choice2, etc}
+
+ while if it has /.code in it, it has the syntax:
+
+ {choice1/.code=callback1; choice2/.code=callback2; etc}
+
+ It is possible to refer to the current value of <key> as '#1' in <alt>.
+
+ The *-form will convert the user input to lowercase before checking <alt> and executing the callbacks.
+
+ The +-form will execute <fn> in place of <callback> if the user input isn't in <alt>.
+
+ <bin> has, eg, the syntax [\val\nr], where \val will hold the user input (in lowercase if the *-form of \ltxkeys@choicekey is called), and \nr will hold the serial number of the value in the list of nominations <alt>, starting from 0. If the input isn't valid, \val will still hold the user input, but \nr will be -1.
+
+ Example (defining choice key):
+
+ \ltxkeys@choicekey*+[KV]{fam}[mp@]{keya}[\val\nr]{%
+ % There are no callbacks for these simple nominations:
+ center,right,left,justified
+ }[center]{% <- default value
+ \def\x##1##2{==##1++#1++##2==}%
+ }{%
+ \@latex@error{Inadmissible value '\string#1' for keya}\@ehc
+ }
+
+ \ltxkeys@choicekey*+[KV]{fam}[mp@]{keyb}[\val\nr]{%
+ % There are callbacks for these nominations:
+ center/.code=\def\x##1{*##1*#1*##1};
+ right/.code=\edef\z{\expandcsonce\ltxkeys@tval};
+ left/.code=\edef\userinput{\cpttrimspaces{#1}};
+ justified/.code=\letcsntocs{#1@align}\relax
+ }[center]{%
+ \def\x##1##2{==##1++#1++##2==}%
+ }{%
+ \@latex@error{Inadmissible value '\string#1' for keya}\@ehc
+ }
+
+
+6. Defining boolean and command keys with one command:
+
+ More than one boolean and command keys can be defined simultaneously by the following command:
+
+ \ltxkeys@definekeys[pref]<fam>[macro-pref]{%
+ <key>=<default>/<callback>; another set of key; etc
+ }
+
+ \ltxkeys@definekeys*[pref]<fam>[macro-pref]{%
+ <key>=<default>/<callback>; another set of key; etc
+ }
+
+ <default> can be absent in the case of command keys, and <callback> can be absent for the two types of key. Boolean keys must, however, have default values {true | false}, to be distinguishable from command keys.
+
+ You can use \CheckInput in <callback> to introduce choice keys as command keys (see example below).
+
+ Ordinary keys and conventional choice keys can't be introduced directly by this command (use \ltxkeys@declarekeys instead).
+
+ The *-form can be used to define new keys (in the sense of \newcommand).
+
+ Note: Keys defined by \ltxkeys@definekeys are automatically set instantly, to provide default values for immediate use. Boolean keys are set with 'false', so that they aren't turned 'true' prematurely.
+
+ In \ltxkeys@definekeys and \ltxkeys@declarekeys every line is assumed to end with a comment sign.
+
+ Example (*-form -> new keys):
+
+ \ltxkeys@definekeys*[KV]<fam>[mp@]{%
+ % command key with callback:
+ keya={keepbraced}/\def\x##1{##1*#1*##1};
+ % boolean key:
+ keyb=true/\def\y##1{##1yyy#1};
+ % command key with no callback:
+ keyc=xxx;
+ % choice-like key:
+ keyd=center/\CheckInput{#1}{left,right,center}
+ \ifinputvalid
+ \edef\myval{\expandcsonce\userinput}
+ \edef\numberinlist{\number\nr}
+ \else
+ \@latex@error{Input '#1' not valued}\@ehd
+ \fi;
+ }
+
+
+7. Defining all types of key with one command:
+
+ \ltxkeys@declarekeys[pref]<fam>[macro-pref]{%
+ <keytype>/<keyname>/<default>/<callback>; another set of key; etc
+ }
+ \ltxkeys@declarekeys*[pref]<fam>[macro-pref]{%
+ <keytype>/<keyname>/<default>/<callback>; another set of key; etc
+ }
+
+ Here, <default> and <callback> can be absent in all cases.
+
+ <keytype> may be any one of
+
+ <ord> | <cmd> | <sty> | <sty*> | <bool> | <choice>
+
+ The star (*) in <sty*> has the same meaning as in \ltxkeys@stylekey above.
+
+ Choice keys must have their names associated with their admissible <alt> values in the format <keyname.{<alt>}> (see example below).
+
+ The *-form can be used to define new keys (in the sense of \newcommand).
+
+ Note: Keys defined by \ltxkeys@declarekeys are automatically set instantly, to provide default values for immediate use. Boolean keys are always initialized in this sense with 'false', so that they aren't turned 'true' prematurely.
+
+ Example:
+
+ \ltxkeys@declarekeys*[KV]<fam>[mp@]{%
+ cmd/keya/mm/\def\x##1{##1*#1*##1};
+ bool/keyb;
+ sty/keyc/xxx/\def\y##1{##1yyy#1};
+ sty*/keyd/blue/\def\y##1{##1#1}/
+ cmd>keye>\parentval>\def\z####1{####1+##1+####1};
+ choice/keyf.{left,right,center}/
+ \ifcase\nr\def\shoot{0}\or\def\shoot{1}\or\def\shoot{2}\fi;
+ }
+
+ Notice the >...> used for the dependant key ('keye') attributes of style key 'keyd'. The default value of the dependant key keye will in this example be whatever is submitted for keyd.
+
+
+6. Need-value keys:
+
+ Sometimes you may want to create keys for which the user must always supply his/her own values, even if the keys originally have default values. The default values of keys may not always be suitable. Take, for example, the height and width of a graphics image. For functions that are meant to handle generic images, it would certainly be inappropriate to relieve the user of the need to call picture height and width without corresponding values.
+
+ To make a key a need-value key, simply attach the pointer \needvalue to the key at definition time. This pointer can be used only when defining keys, and not when setting keys.
+
+ Example:
+
+ \ltxkeys@cmdkey[KV]{fam}[mp@]{\needvalue{keya}}[blue]{%
+ \def\x##1{##1x#1x##1}%
+ }
+ \ltxkeys@setkeys[KV]{fam}{keya}
+ % -> Error: the author of 'keya' designed it to require a user value needed
+
+ See more about key pointers in Section \autoref{sec:xxx}.
+
+
+SETTING KEYS
+
+ Keys can be set by the following utilities:
+
+1. Set defined keys:
+
+ \ltxkeys@setkeys[<pref>]{<fam>}[<na>]{<key-val>}
+ \ltxkeys@setkeys*+[<prefs>]{<fams>}[<na>]{<key-val>}
+
+ Keys in <na> are ignored. The *-form will save all undefined keys with prefix <pref> and in family <fam> in \<pref>@<fam>@rmkeys, to be set later, perhaps with \ltxkeys@setrmkeys. The +-form will search in all the prefixes in <prefs> and all families in <fams> for a key before logging the key in \<pref>@<fam>@rmkeys (if the *+-form is used) or reporting it as undefined.
+
+
+2. Set 'remaining' keys after defined keys have been set:
+
+ The command \ltxkeys@setrmkeys, which has both star (*) and plus (+) variants is the counterpart of \setrmkeys of the xkeyval package:
+
+ \ltxkeys@setkeys[<pref>]{<fam>}[<na>]
+ \ltxkeys@setkeys*+[<prefs>]{<fams>}[<na>]
+
+
+3. Set a 'main' (master) key from its 'alias' (slave):
+
+ Aliased/alias keys differ from style keys. Two keys may be aliased to each other, such that when one is set, the alias is automatically set with the same or a different value. The concept is similar to, but not identical with, that of style keys. The two aliases must all be in the same family and have the same key and macro prefixes.
+
+ \ltxkeys@setmnkey{<key>}[<value>]
+
+ Here, <value> is optional; if it is not given, <key> will be set with the current value of its alias. The commands \setmnkey and \setaliaskey are a shortened variants of \ltxkeys@setmnkey.
+
+ Example:
+
+ \ltxkeys@definekeys*[KV]<fam>[mp@]{%
+ printsign=true;
+ printmark=true/\ltxkeys@setmnkey{printsign}[false];
+ keya=$+++$;
+ keyb=star/\ltxkeys@setmnkey{keya}[$***$]
+ }
+ \ltxkeys@definekeys*[KV]<fam>[mp@]{%
+ keya=sun/\CheckInput{#1}{star,sun,moon}
+ \ifinputvalid
+ \edef\givenval{\userinput}
+ \edef\found{\ifcase\nr star@\or sun@\or moon@\fi}
+ \else
+ \@latex@error{Input '#1' not valid}\@ehd
+ \fi;
+ keyb=star/\ltxkeys@setmnkey{keya};
+ }
+
+ The macro \userinput is the value given by the user at the time of calling/using the key, always converted internally to lower case; and \nr is the serial number of the user input in the nominations, starting from 0. 'inputvalid' is an internal boolean, available to the user.
+
+ The example of 'printsign' and 'printmark' is similar, but not equivalent, to the notion of biboolean keys. Biboolean keys have equal symmetry (ie, they can call each other with equal
+ propensity) and they won't bomb out in an infinite reentrance. This is not the case with aliased keys: only slave/alias can set or call master/main key. If they both call each other, the user will be alerted to the fact that there is an infinite reentrance of keys. The notion of 'slave' and 'master' used in the ltxkeys package may be counterintuitive but in reality it is quite logical.
+
+
+4. Using key pointers:
+
+ The \savevalue and \usevalue pointers of the xkeyval package are still available at key setting time, but with increased robustness and optimization. Curly braces in values are preserved throughout, and instead of saving the value of each key tagged with \savevalue in a separate macro, we save all such keys and their values in only one macro (for each combination of <pref> and <fam>) and use a fast search technique to find the values when they are needed later (by any key tagged with \usevalue).
+
+ Here is an interesting example (and test) of use of pointers:
+
+ \ltxkeys@stylekey*[KV]{fam}{\needvalue{keya}}[{left}](%
+ % #1 here refers to the value of the dependant key
+ % at the time it is being set.
+ ord/\needvalue{keyb}/\parentval/\edef\y##1{##1xx\unexpanded{#1}};
+ cmd/keyc/{center}
+ ){%
+ % #1 here refers to the value of the parent key
+ % at the time it is being set:
+ \def\x##1{##1xx#1}
+ }
+ \ltxkeys@setkeys[KV]{fam}{\savevalue{keya}={\def\y##1{##1}},
+ \savevalue{keyb}=\usevalue{keya},keyc=\usevalue{keyb}}
+
+
+5. Accessing the saved value of a key:
+
+ As mentioned earlier, the pointers \savevalue and \usevalue are available only within \ltxkeys@setkeys. But suppose you have used \savevalue within \ltxkeys@setkeys to set the value of a key, how do you access that value outside of \ltxkeys@setkeys? You can do this by using the following \ltxkeys@storevalue command:
+
+ \ltxkeys@storevalue[<pref>]{<fam>}{<key>}<cs>
+ \ltxkeys@storevalue+[<pref>]{<fam>}{<key>}<cs><fallback>
+
+ Here, <cs> is the macro (defined or undefined) that will receive the saved value of <key>. The plain variant of this command will raise an error message if the value of the key wasn't previously saved, while the +-form will resort to the user-supplied function <fallback>. Only saved key values can be recovered by this command.
+
+ Examples:
+
+ \ltxkeys@cmdkey[KV]{fam}{\needvalue{keya}}[{left}]{%
+ \def\x##1{##1xx#1}
+ }
+ \ltxkeys@setkeys[KV]{fam}{\savevalue{keya}={\def\y##1{##1}}}
+ \ltxkeys@storevalue[KV]{fam}{keya}\tempa
+ \ltxkeys@storevalue+[KV]{fam}{keya}\tempb{%
+ \@latex@error{No value saved for key 'keya'}\@ehc
+ }
+
+
+
+INITIALIZING KEYS
+
+ \ltxkeys@initializekeys[<prefs>]{<fams>}[<na>]
+
+ This presets ALL keys previously defined in families <fams> with their default values; it ignores keys listed in <na>. If <na> is a list of key-value pairs, the key names are extracted from the list before the family keys are initialized. Any key-value pairs in <na> are not set at all. All keys defined by \ltxkeys@definekeys and \ltxkeys@declarekeys are automatically instantly initialized, except slave/alias and dependant keys.
+
+ The command \ltxkeys@initializekeys can be used to save estate when listing keys in \ltxkeys@executeoptions.
+
+
+LAUNCHING KEYS
+
+ \ltxkeys@launchkeys[<pref>]{<fam>}[<curr>]
+
+ This presets ALL keys defined in family <fam> with their default values; it ignores keys listed in <curr>. <curr> is actually the list of key-value pairs that the user wants to use as current values of keys. Their keys are to be ignored when setting up defaults, ie, when initializing the family keys. One major difference between \ltxkeys@launchkeys and \ltxkeys@initializekeys is that in \ltxkeys@launchkeys the key-value pairs in <curr> are immediately set after the family keys are initialized.
+
+ Note: Keys with multiple prefixes and from multiple families can't be launched at the same time.
+
+
+HANDLING UNDEFINED OR UNKNOWN KEYS
+
+ You can use the macro \ltxkeys@unknownkeyhandler declare to the ltxkeys package the course of action to take if, while setting keys, it discovers that a key is undefined or unknown. The syntax of this command is
+
+ \ltxkeys@unknownkeyhandler[<prefs>]{<fams>}{<callback>}
+
+ where <callback> signifies the action to take. The default <callback> is to log the keys and warn the user, in each run, of the presence of unknown keys. The same <callback> can be used across key prefixes <prefs> and families <fams>. You can use #1 (or \CurrentPref) in this macro to represent the current key prefix, #2 (or \CurrentFam) for the current family, #3 (or \CurrentKey) for the current key name, and #4 (or \CurrentVal) for the value of the current key. If \CurrentVal contains undefined macros or active characters, then attempting to print it may cause problems. Therefore, when making entries in the transcript file, it will sometimes be preferable to use \InnocentVal instead of \CurrentVal. However, \InnocentVal will give only the first eight characters of a key's value.
+
+ Example:
+
+ \ltxkeys@unknownkeyhandler[KVA,KVB]{fam1,fam2}{%
+ \@expandtwoargs\in@{,#3,}{,\myspecialkeylist,}%
+ \ifin@
+ % The reader may want to investigate what the parameter
+ % characters ##1 and ####1 here stand for:
+ \ltxkeys@ordkey[#1]{#2}{#3}[#4]{\def\x####1{####1xx##1}}%
+ \else
+ \@ltx@warn{Unknown key `#3' with value `#4' in family `#2' ignored}\@ehd
+ % \@ltx@warn{Unknown key `\CurrentKey' with value
+ % `\InnocentVal' in family `\CurrentFam' ignored}\@ehd
+ \fi
+ }
+
+ The macro \myspecialkeylist in the above example doesn't actually exist; it is only meant for illustration here. But 'handled keys' may be introduced in this way. This will be the set of keys for which a special action may apply at key setting time.
+
+ Similar to \ltxkeys@unknownkeyhandler (which applies to keys), there is also the \ltxkeys@unknownoptionhandler (which applies to package or class options---see \autoref{sec:}).
+
+
+CHECKING IF A KEY IS DEFINED
+
+ \ltxkeys@ifkeydefTF[<prefs>]{<fams>}{<key>}{<true>}{<false>}
+ \ltxkeys@ifkeydefFT[<prefs>]{<fams>}{<key>}{<false>}{<true>}
+
+ These check if <key> is defined with a prefix in <prefs> and in family in <fams>.
+
+
+
+DISABLING KEYS
+
+ \ltxkeys@disablekeys[<prefs>]{<fams>}{<keys>}
+ \ltxkeys@disablekeys*[<prefs>]{<fams>}{<keys>}
+
+ The command \ltxkeys@disablekeys causes an error to be issued when a disabled key is invoked. If the package option 'verbose' is true, undefined keys are highlighted by \ltxkeys@disablekeys with a warning message. Because it is possible to mix prefixes and families in \ltxkeys@disablekeys, undefined keys may be readily encountered. To see those undefined keys, enable the package option 'verbose'.
+
+ The plain form of \ltxkeys@disablekeys disables the given keys instantly, while the starred (*) variant disables the keys at \AtBeginDocument. Authors can use this command to bar users of their keys from calling those keys after a certain point.
+
+
+OPTION AND NON-OPTION KEYS
+
+ Sometimes you want to create keys that can only appear in \documentclass, \RequirePackage or \usepackage, and at other times you may not want the user to submit a certain set of keys via these commands. The xwatermark package, for example, uses this concept.
+
+ \option@keys[<pref>]{<fam>}{<keys>}
+ \option@keys*[<pref>]{<fam>}{<keys>}
+ \notoption@keys[<pref>]{<fam>}{<keys>}
+
+ Keys listed in \option@keys can appear only in arguments of \documentclass, \RequirePackage or \usepackage, while keys list in \notoption@keys can't appear in these macros. The *-form of \option@keys is equivalent to \notoption@keys. Only defined keys may appear in \option@keys and \notoption@keys.
+
+ \makeoption@keys[<pref>]{<fam>}
+ \makeoption@keys*[<pref>]{<fam>}
+
+ The command \makeoption@keys makes all the keys with prefix <pref> and in family <fam> options keys. The *-form of \makeoption@keys is equivalent to \makenotoption@keys.
+
+
+DECLARING AND PROCESSING OPTIONS
+
+ \ltxkeys@declareoption[<pref>]<<fam>>{<key>}[<default>]{<callback>}
+ \ltxkeys@declareoption*[<pref>]<<fam>>{<key>}[<default>]{<callback>}
+
+ The command \ltxkeys@declareoption is simply a form of \ltxkeys@ordkey, with the difference that the key family <fam> is now optional and, when specified, must be given in angled brackets. The default family name is '\@currname.\@currext', ie, the name of the class file or package and its file extension.
+
+ The starred (*) form of \ltxkeys@declareoption prescribes the default action to be taken when undefined options with prefix <pref> and in family <fam> are passed to class or package. You may use \CurrentKey and \CurrentVal within this macro to pass the unknown option and its value to another class or package or to specify other actions. In fact, you can use #1 in this macro to represent the current key prefix, #2 for the current family, #3 for the current key name, and #4 for the value of the current key. The command \ltxkeys@unknownoptionhandler is equivalent to the *-form of \ltxkeys@declareoption.
+
+ Note: The *-form of \ltxkeys@declareoption differs from the *-form of LaTeX's \DeclareOption and the *-form of xkeyval package's \DeclareOptionX.
+
+ +++
+ Examples (of use of *-form of \ltxkeys@declareoption):
+
+ \ltxkeys@declareoption*[KV]<mypackage>{%
+ \PackageWarning{mypackage}{%
+ Unknown option `\CurrentKey' with value `\CurrentVal' ignored}%
+ }
+
+ \ltxkeys@declareoption*{\PassOptionsToClass{#3}{article}}
+
+ \ltxkeys@unknownoptionhandler[KV]<mypackage>{%
+ % The macro \myextraoptions doesn't actually exist;
+ % it is only meant for illustration here:
+ \@expandtwoargs\in@{,#3,}{,\myextraoptions,}%
+ \ifin@
+ % The reader may want to investigate what the parameter characters
+ % ##1 and ####1 here stand for:
+ \ltxkeys@ordkey[#1]{#2}{#3}[#4]{\def\x####1{####1xx##1}}%
+ \else
+ \PassOptionsToClass{#3}{myclass}%
+ \fi
+ }
+ +++
+
+ \ltxkeys@declarecmdoption[<pref>]<<fam>>[<mp>]{<key>}[<default>]{<callback>}
+ \ltxkeys@declarebooloption[<pref>]<<fam>>[<mp>]{<key>}[<default>]{<callback>}
+ \ltxkeys@declarechoiceoption[<pref>]<<fam>>[<mp>]{<key>}[<default>]{<callback>}
+
+ These are equivalent to \ltxkeys@cmdkey, \ltxkeys@boolkey and \ltxkeys@choicekey, respectively, but now the family <fam> is optional and, when specified, must be given in angled brackets. The default family name is '\@currname.\@currext'.
+
+
+ \ltxkeys@executeoptions[<pref>]<<fams>>[<na>]{<key-val>}
+
+ This executes/sets the key-value pairs given in <key-val>. The optional <na> specifies the list of keys (without values) to be ignored. <fams> signifies families in which the keys suggested in <key-val> have been defined. The command \ltxkeys@executeoptions can thus be used to process keys from several families.
+
+
+ \ltxkeys@processoptions[<pref>]<<fams>>[<na>]
+ \ltxkeys@processoptions*[<pref>]<<fams>>[<na>]
+
+ The command \ltxkeys@processoptions processes the keys and values passed by the user to the class or package. The optional argument <na> can be used to specify keys that should be ignored. The optional argument <fams> can be used to specify the families that have been used to define the keys. This macro doesn't protect expandable macros in the user inputs unless the catoptions package is loaded before \documentclass, in which case it might be better using the command \XProcessOptions of the catoptions package. When used in a class file, the macro \ltxkeys@processoptions will ignore unknown keys or options. This allows the user to use global options in the \documentclass command which can be inherinted by packages loaded afterwards.
+
+ The starred (*) version \ltxkeys@processoptions works like the plain variant except that it also copies user input from the \documentclass command. When the user specifies an option in the \documentclass which also exists in the local family or families of the package issuing \ltxkeys@processoptions*, the local key too will be set. In this case, #1 in the \ltxkeys@declareoption (or a similar command) will be the value entered in the \documentclass command for this key. First the global options from \documentclass will set local keys and afterwards the local options, specified with \usepackage, \RequirePackage or \LoadClass, will set local keys, which could overwrite the global options, depending on the way the options sections are constructed.
+
+NOTES
+
+ Wherever semicolon ';' is indicated as a list parser in this guide, it can be replaced by any user-specified one character parser via the package option 'keyparser'. It is advisable to enclose the chosen character in curly braces, eg, as in
+
+ \documentclass[verbose,keyparser={|}]{article}
+
+ or
+
+ \usepackage[keyparser={|}]{ltxkeys}
+
+
+TO-DO
+
+ Patching the callback of an existing key. Sometimes you might want to modify the callback of a key defined in another style file. Rather than redefine the key with another callback, it may be possible to simply patch the callback of the key, provided the key's callback is patchable. This facility has been delayed because I am still experimenting the scannability of callbacks with doubled hash character.
+
+
+% End of ltxkeys-guide.tex % \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty b/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty
new file mode 100644
index 00000000000..62cb38a1a3a
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty
@@ -0,0 +1,2036 @@
+%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
+% %
+% This is file 'ltxkeys.sty', version 0.1.0, July 2011. %
+% %
+% This package and accompanying files may be distributed and/or %
+% modified under the conditions of the LaTeX Project Public License, %
+% either version 1.3 of this license or any later version. The latest %
+% version of this license is in http://www.latex-project.org/lppl.txt %
+% and version 1.3 or later is part of all distributions of LaTeX %
+% version 2005/12/01 or later. %
+% %
+% The LPPL maintenance status of this software is 'author-maintained'. %
+% %
+% This software is provided 'as it is', without warranty of any kind, %
+% either expressed or implied, including, but not limited to, the %
+% implied warranties of merchantability and fitness for a particular %
+% purpose. %
+% %
+% Copyright (c) 2011 Ahmed Musa (amusa22@gmail.com). %
+% %
+%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
+\RequirePackage{catoptions}[2011/07/07]
+\UseNormalCatcodes
+\StyleFilePurpose{Robust and fast key-value parser}
+\StyleFileRCSInfo
+$Id: ltxkeys.sty,v 0.1.0 2011/07/07 09:00:00 Ahmed Musa Exp $
+\ProvidesPackage{ltxkeys}[\StyleFileInfo]
+\NeedsTeXFormat{LaTeX2e}[1996/12/01]
+\SetStyleFileMessages[ltxkeys@]{info}{warn}{err}
+\newvariables{if}[ltxkeys@]{break,st,pl,sw,sv,noval,pxop,exop,kf,
+ rm,ssk,dec,dep,twk,verbose,inputvalid}[false]
+\newvariables{if}{inputvalid}[false]
+\robust@def*\SetSlaveWithMaster{\global\ltxkeys@ssktrue}
+\robust@def*\SetNoSlaveWithMaster{\global\ltxkeys@sskfalse}
+\SetNoSlaveWithMaster
+\newvariables{count}[ltxkeys@]{csvdepth,keydepth}[\z@pt]
+\newletcs\ltxkeys@nil\relax
+\new@def*\ltxkeys@nnil{\ltxkeys@nil}
+\ifdefTF\cpt@documentclass{}{%
+ \ltxkeys@err{No \string\documentclass}\@ehc
+ \emptifycsset{\cpt@documentclass,\cpt@classoptionslist}%
+}
+\robust@def*\ltxkeys@gobble@to@nil{%
+ \begingroup
+ \defpass\reserved@a##1\ltxkeys@nil{\endgroup}%
+}
+\robust@def*\ltxkeys@testst#1{\cpt@ifstar{\ltxkeys@sttrue#1}{\ltxkeys@stfalse#1}}
+\robust@def*\ltxkeys@testpl#1{\cpt@ifplus{\ltxkeys@pltrue#1}{\ltxkeys@plfalse#1}}
+\robust@def*\ltxkeys@teststpl#1{\ltxkeys@testst{\ltxkeys@testpl{#1}}}
+\robust@def*\ltxkeys@state{%
+ \ltxkeys@keys,\ltxkeys@prefs,\ltxkeys@fams,\ltxkeys@nakeys,\ltxkeys@tpref,%
+ \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\ltxkeys@tval,\ifltxkeys@st,%
+ \ifltxkeys@pl,\ifltxkeys@kf,\ifltxkeys@pxop,\ifltxkeys@exop,\CurrentKeyval,%
+ \CurrentKey,\CurrentVal
+}
+\robust@def*\ltxkeys@trimspaces{\begingroup\ltxkeys@tr@mspaces}
+\robust@def*\ltxkeys@trimspacesincs#1{\s@expandarg\ltxkeys@trimspaces{#1}#1}
+\defpass\reserved@a#1{%
+ \long\def\ltxkeys@tr@mspaces##1##2{%
+ \edef\reserved@a{%
+ \expandcsonce{\romannumeral-`\q
+ \ltxkeys@trimspace.##1\trimsp@nil#1\trimsp@nil}%
+ }%
+ \ifxTF##2\reserved@a{%
+ \cptpassacross##2\endgroup
+ }{%
+ \let##2=\reserved@a
+ \expandafter\ltxkeys@tr@mspaces\expandafter{##2}##2%
+ }%
+ }%
+ \long\def\ltxkeys@trimspace##1#1\trimsp@nil{%
+ \ltxkeys@tr@mspace##1\trimsp@nil
+ }%
+ \long\def\ltxkeys@tr@mspace##1\trimsp@nil##2{%
+ \expandafter\noexpand\@gobble##1%
+ }%
+}{ }
+\newvariables{tog}{rem@repl,rem@repl@all}
+\robust@def*\ltxkeys@removeoneelement{\cpt@testopt\ltxkeys@rem@veoneelement,}
+\robust@def\ltxkeys@rem@veoneelement[#1]#2#3{%
+ \ifcpt@check\cpt@checklistparser{#1}\relax\fi
+ \begingroup
+ \edef\parser{\detokenize{#1}}%
+ \def\ltxkeys@tempa##1{%
+ \def\ltxkeys@remove####1#1##1#1####2\remove@nil{%
+ \def#2{####1#1####2}%
+ \cpt@trimparser[#1]#2%
+ }%
+ \xifinsetTF{\detokenize{#1##1#1}}{\parser\cptoxdetok{#2}\parser}{%
+ \expandafter\ltxkeys@remove\expandafter#1#2#1\remove@nil
+ \iftogFT{rem@repl@all}{}{%
+ \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
+ }%
+ }{}%
+ }%
+ \iftogTF{rem@repl}{%
+ \edef\ltxkeys@tempb{\unexpanded{#3}}%
+ }{%
+ \cpt@sttrue\cpt@csvnormalize[#1]#2%
+ \ltxkeys@trimspaces{#3}\ltxkeys@tempb
+ }%
+ \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
+ \postgroupdef#2\endgroup
+}
+\robust@def*\ltxkeys@removeelements{\cpt@testopt\ltxkeys@rem@veelements,}
+\robust@def\ltxkeys@rem@veelements[#1]#2#3{%
+ \begingroup
+ \cpt@sttrue\cpt@csvnormalize[#1]#2%
+ \cpt@checkfalse
+ \togtrue{rem@repl}%
+ \long\def\csv@do##1{%
+ \ltxkeys@removeoneelement[#1]#2{##1}%
+ }%
+ \csv@@parse[#1]{#3}%
+ \postgroupdef#2\endgroup
+}
+% \ltxkeys@replaceoneelement[<parser>]{<cs>}{<search>}{<replace>}
+\robust@def*\ltxkeys@replaceoneelement{%
+ \cpt@testopt\ltxkeys@repl@ceoneelement,%
+}
+\robust@def\ltxkeys@repl@ceoneelement[#1]#2#3#4{%
+ \ifcpt@check\cpt@checklistparser{#1}\relax\fi
+ \begingroup
+ \edef\parser{\detokenize{#1}}%
+ \def\ltxkeys@tempa##1{%
+ \def\ltxkeys@replace####1#1##1#1####2\rep@nil{%
+ \def#2{####1#1#4#1####2}%
+ \cpt@trimparser[#1]#2%
+ }%
+ \xifinsetFT{\detokenize{#1##1#1}}{\parser\cptoxdetok#2\parser}{}{%
+ \expandafter\ltxkeys@replace\expandafter#1#2#1\rep@nil
+ \iftogFT{rem@repl@all}{}{%
+ \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
+ }%
+ }%
+ }%
+ \iftogTF{rem@repl}{%
+ \edef\ltxkeys@tempb{\unexpanded{#3}}%
+ }{%
+ \cpt@sttrue\cpt@csvnormalize[#1]#2%
+ \ltxkeys@trimspaces{#3}\ltxkeys@tempb
+ }%
+ \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
+ \postgroupdef#2\endgroup
+}
+\robust@def*\ltxkeys@replaceelements{\cpt@testopt\ltxkeys@repl@ceelements,}
+\robust@def\ltxkeys@repl@ceelements[#1]#2#3#4{%
+ \begingroup
+ \edef\ltxkeys@tempa{\unexpanded{#3}}%
+ \edef\ltxkeys@tempb{\unexpanded{#4}}%
+ \def\csv@do##1{\cpt@sttrue\cpt@csvnormalize[#1]##1}%
+ \csv@@loop[,]{#2,\ltxkeys@tempa,\ltxkeys@tempb}%
+ \def\ltxkeys@tempc##1#1##2\noboundary##3#1##4\noboundary{%
+ \ltxkeys@replaceoneelement[#1]#2{##1}{##3}%
+ \ifblankTF{##2}{}{%
+ \ifblankTF{##4}{}{%
+ \ltxkeys@tempc##2\noboundary##4\noboundary
+ }%
+ }%
+ }%
+ \cpt@checkfalse
+ \togtrue{rem@repl}%
+ \cptexpandsecond\ltxkeys@tempc{%
+ \expandcsonce\ltxkeys@tempa#1\noboundary
+ \expandcsonce\ltxkeys@tempb#1\noboundary
+ }%
+ \postgroupdef#2\endgroup
+}
+\robust@def*\ltxkeys@oneoftwo#1\endgroup{%
+ \let\@firstoftwo\relax
+ \let\@secondoftwo\relax
+ \edefpass\ltxkeys@tempa{\endgroup
+ \ifcase#1\relax
+ \if@boolTF{cpt@choicefd}\@firstoftwo\@secondoftwo
+ \or
+ \if@boolTF{cpt@choicefd}\@secondoftwo\@firstoftwo
+ \else
+ \ltxkeys@err{Invalid number '#1'}\noexpand\@ehc
+ \fi
+ }%
+}
+\robust@def*\ltxkeys@getorder#1#2{%
+ \def\ltxkeys@order{-1}%
+ \begingroup
+ \lowercase{\ltxkeys@trimspaces{#1}\ltxkeys@tempa}%
+ \@tempcnta\z@pt
+ \toks@{}%
+ \def\ltxkeys@do##1{%
+ \oifstrcmpFT\ltxkeys@tempa{##1}{}{%
+ \cptexpanded{%
+ \toks@{\def\noexpand\ltxkeys@order{\the\@tempcnta}}%
+ }%
+ \ltxkeys@breaktrue
+ }%
+ \advance\@tempcnta\@ne
+ }%
+ \ltxkeys@csvparse{#2}%
+ \expandafter\endgroup\the\toks@
+}
+\robust@def*\ltxkeys@ifeltcountTF{\cpt@testopt\ltxkeys@ifeltcount{=}}
+\robust@def*\ltxkeys@ifeltcount[#1]#2#3{%
+ \begingroup
+ \def\ltxkeys@do##1{\advance\@tempcnta by1}%
+ \@tempcnta\z@pt
+ \ltxkeys@csvloop{#2}%
+ \expandafter\endgroup\csname @\ifnum\@tempcnta#1\numexpr#3%
+ first\else second\fi oftwo\endcsname
+}
+\robust@def*\ltxkeys@nomatcherr{%
+ \ltxkeys@err{User input '\reserved@e' not in list:
+ \MsgBrk '\reserved@f'}\@ehc
+ \@gobble
+}
+% A re-implementation of xkeyval's \XKV@checkchoice for
+% arbitrary parser and more robustness:
+\robust@def*\ltxkeys@checkchoice{%
+ \cpt@teststpl{\cpt@testopt\ltxkeys@cc@a,}%
+}
+\robust@def*\ltxkeys@cc@a[#1]{%
+ \ifcpt@check\cpt@checklistparser{#1}{}\fi
+ \cpt@testopt{\ltxkeys@cc@b#1}{}%
+}
+\robust@def*\comma@cc{%
+ \cpt@teststpl{\cpt@testopt{\ltxkeys@cc@b,}{}}%
+}
+\robust@def*\CheckInput#1#2{%
+ \lowercase{\edef\nominations{\unexpanded{#2}}}%
+ \cpt@sttrue\cpt@pltrue
+ \ltxkeys@cc@b,[\userinput\nr]{#1}{#2}{%
+ \inputvalidtrue
+ }{%
+ \inputvalidfalse
+ }%
+}
+\robust@def*\ltxkeys@cc@b#1[#2]#3#4{%
+ \begingroup
+ \ifcpt@st\lowercase{\fi
+ \ltxkeys@trimspaces{#3}\user@input
+ \edef\valid@vals{\unexpanded{#4}}%
+ \ifcpt@st}\fi
+ \def\ltxkeys@ccparser{#1}%
+ \cpt@sttrue\cpt@csvnormalize[#1]\valid@vals
+ \cptexpandsecond{%
+ \ifblankTF{#2}\ltxkeys@cc@d{\ltxkeys@cc@c#2}\ltxkeys@nil
+ }{%
+ {\expandcsonce\user@input}{\expandcsonce\valid@vals}%
+ }%
+}
+\robust@def*\ltxkeys@cc@c#1#2\ltxkeys@nil#3#4{%
+ \ifblankTF{#2}{\ltxkeys@cc@d#1}{\ltxkeys@cc@e#1#2}{#3}{#4}%
+}
+\robust@def*\ltxkeys@cc@d#1#2#3{%
+ \def\reserved@a{#1}%
+ \ifxTF\reserved@a\ltxkeys@nnil{%
+ \def\ltxkeys@tempa{}%
+ }{%
+ \def\ltxkeys@tempa{\def#1{#2}}%
+ }%
+ \edef\x{\cptoxdetok\ltxkeys@ccparser}%
+ \edef\x{{\x\detokenize{#2}\x}{\x\detokenize{#3}\x}}%
+ \expandafter\ifinsetTF\x{%
+ \if@boolTF{cpt@pl}{%
+ \rightaddtocs\ltxkeys@tempa\@firstoftwo
+ }{%
+ \rightaddtocs\ltxkeys@tempa\@firstofone
+ }%
+ }{%
+ \if@boolTF{cpt@pl}{%
+ \rightaddtocs\ltxkeys@tempa\@secondoftwo
+ }{%
+ \rightaddtocs\ltxkeys@tempa{%
+ \expandafter\ltxkeys@nomatcherr\@gobble
+ }%
+ }%
+ }%
+ \cptpassexpanded{%
+ \endgroup
+ \def\noexpand\reserved@e{\expandcsonce\user@input}%
+ \def\noexpand\reserved@f{\expandcsonce\valid@vals}%
+ \expandcsonce\ltxkeys@tempa
+ }%
+}
+\robust@def*\ltxkeys@cc@e#1#2#3#4{%
+ \chardef#2\z@pt
+ \cpt@choicefdfalse
+ \def\csv@do##1{%
+ \def#1{##1}%
+ \ifstrcmpTF{##1}{#3}{%
+ \cpt@choicefdtrue\cptbreakloop
+ }{%
+ \pushnumber#2%
+ }%
+ }%
+ \expandafter\csv@@loop\expandafter[\ltxkeys@ccparser]{#4}%
+ \cptpassexpanded{%
+ \endgroup
+ \ifcpt@choicefd
+ \def\noexpand#1{\expandcsonce#1}%
+ \def\noexpand#2{\the\numexpr#2}%
+ \ifcpt@pl\noexpand\@firstoftwo\else\noexpand\@firstofone\fi
+ \else
+ \def\noexpand#1{\unexpanded{#3}}%
+ \def\noexpand#2{-1}%
+ \ifcpt@pl
+ \noexpand\@secondoftwo
+ \else
+ \def\noexpand\reserved@e{\expandcsonce\user@input}%
+ \def\noexpand\reserved@f{\expandcsonce\valid@vals}%
+ \unexpanded{\expandafter\ltxkeys@nomatcherr\@gobble}%
+ \fi
+ \fi
+ }%
+}
+
+% \ltxkeys@ifincsvlistTF*[parser](no.){sublist}{mainlist}{true}{false}
+\robust@def*\ltxkeys@ifincsvlistTF{\cpt@teststopt\ltxkeys@ifincsvlist,}
+\robust@def*\ltxkeys@ifincsvlist[#1]{%
+ \cpt@testpnopt{\ltxkeys@if@ncsvlist#1}{1}%
+}
+\robust@def*\ltxkeys@if@ncsvlist#1(#2)#3#4{%
+ \begingroup
+ \edef\parser{\detokenize{#1}}%
+ \ifcpt@st\lowercase{\fi
+ \edef\ltxkeys@tempa{\unexpanded{#3}}%
+ \edef\ltxkeys@tempb{\unexpanded{#4}}%
+ \ifcpt@st}\fi
+ \cpt@sttrue\cpt@csvnormalize[#1]\ltxkeys@tempb
+ \cpt@cnta\z@pt\def\itemspresent{}%
+ \def\csv@do##1{%
+ \xifinsetFT{\detokenize{#1##1#1}}
+ {\parser\cptoxdetok\ltxkeys@tempb\parser}{}{%
+ \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}%
+ \advance\cpt@cnta\@ne
+ }%
+ \ifnum\cpt@cnta>\numexpr#2-1\relax\cptbreakloop\fi
+ }%
+ \csv@@parse*[#1]\ltxkeys@tempa
+ \ifnum\cpt@cnta>\numexpr#2-1\relax
+ \edef\nritems{\the\cpt@cnta}%
+ \else
+ \def\itemspresent{}\def\nritems{-1}%
+ \fi
+ \cptexpandsecond\endgroup{%
+ \cpt@csexit\itemspresent\cpt@csexit\nritems
+ \ifx\itemspresent\@empty\noexpand\@secondoftwo\else
+ \noexpand\@firstoftwo\fi
+ }%
+}
+% \ltxkeys@ifintsvlistTF(no){sublist}{mainlist}{true}{false}
+\robust@def*\ltxkeys@ifintsvlistTF{%
+ \cpt@testst{\cpt@testpnopt\ltxkeys@ifintsvlist{1}}%
+}
+\robust@def*\ltxkeys@ifintsvlist(#1)#2#3{%
+ \begingroup
+ \ifcpt@st\lowercase{\fi
+ \edef\ltxkeys@tempa{\unexpanded{#2}}%
+ \edef\ltxkeys@tempb{\unexpanded{#3}}%
+ \ifcpt@st}\fi
+ \def\itemspresent{}\cpt@cnta\z@pt
+ \def\tsv@do##1{%
+ \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{%
+ \edef\itemspresent{\cptliststack{}\itemspresent\unexpanded{##1}}%
+ \advance\cpt@cnta\@ne
+ }%
+ \ifnum\cpt@cnta>\numexpr#1-1\relax\cptbreakloop\fi
+ }%
+ \s@expandarg\tsv@@parse\ltxkeys@tempa
+ \ifnum\cpt@cnta>\numexpr#1-1\relax
+ \edef\nritems{\the\cpt@cnta}%
+ \else
+ \def\itemspresent{}\def\nritems{-1}%
+ \fi
+ \cptexpandsecond\endgroup{%
+ \cpt@csexit\itemspresent\cpt@csexit\nritems
+ \ifx\itemspresent\@empty\noexpand\@secondoftwo\else
+ \noexpand\@firstoftwo\fi
+ }%
+}
+% \ltxkeys@ifinTF*(no.){sublist}{mainlist}{true}{false}
+\robust@def*\ltxkeys@ifinTF{%
+ \cpt@testst{\cpt@testpnopt\ltxkeys@ifin{1}}%
+}
+\robust@def*\ltxkeys@ifin(#1)#2#3{%
+ \begingroup
+ \ifcpt@st\lowercase{\fi
+ \edef\ltxkeys@tempa{\unexpanded{#2}}%
+ \edef\ltxkeys@tempb{\unexpanded{#3}}%
+ \ifcpt@st}\fi
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@tempa
+ \cpt@cnta\z@pt\def\itemspresent{}%
+ \def\do##1,{%
+ \ifnot@nil{##1}{%
+ \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{%
+ \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}%
+ \advance\cpt@cnta\@ne
+ }%
+ \ifnumcmpTF\cpt@cnta>\numexpr#1-1{\gobble@to@sentinel\@nil,}{\do}%
+ }%
+ }%
+ \expandafter\do\ltxkeys@tempa,\@nil,%
+ \ifnum\cpt@cnta>\numexpr#1-1\relax
+ \edef\nritems{\the\cpt@cnta}%
+ \else
+ \def\itemspresent{}\def\nritems{-1}%
+ \fi
+ \cptexpandsecond\endgroup{%
+ \cpt@csexit\itemspresent\cpt@csexit\nritems
+ \ifcsemptyTF\itemspresent{\noexpand\@secondoftwo}
+ {\noexpand\@firstoftwo}%
+ }%
+}
+\robust@def*\ltxkeys@inpkgcls#1{%
+ \ifinstylefileTF{}{%
+ \ltxkeys@err{Command '\detokenize{#1}' issued outside
+ style file}{The command '\detokenize{#1}' is available
+ only in style files.}%
+ }%
+}
+\new@def*\ltxkeys@parsestack{}
+\newletcs\ltxkeys@break\ltxkeys@breaktrue
+\robust@def*\ltxkeys@csvloop{%
+ \let\ltxkeys@nlz\cptfalse
+ \let\ltxkeys@inkv\cptfalse
+ \cpt@testst\ltxkeys@parse@a
+}
+\robust@def*\ltxkeys@csvparse{%
+ \let\ltxkeys@nlz\cpttrue
+ \let\ltxkeys@inkv\cptfalse
+ \cpt@testst\ltxkeys@parse@a
+}
+\robust@def*\ltxkeys@kvloop{%
+ \let\ltxkeys@nlz\cptfalse
+ \let\ltxkeys@inkv\cpttrue
+ \cpt@testst\ltxkeys@parse@a
+}
+\robust@def*\ltxkeys@kvparse{%
+ \let\ltxkeys@nlz\cpttrue
+ \let\ltxkeys@inkv\cpttrue
+ \cpt@testst\ltxkeys@parse@a
+}
+\robust@def*\ltxkeys@parse@a#1{%
+ \cpt@stchoose{cpt@st}{#1}\ltxkeys@arg\ltxkeys@parse@a
+ \global\advance\ltxkeys@csvdepth\@ne
+ \letcsntocsn{ifltxkeys@break@\romannumeral\ltxkeys@csvdepth}
+ {ifltxkeys@break}%
+ \letcsntocs{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}\ltxkeys@doo
+ \xdef\ltxkeys@parsestack{%
+ \letcsntocsn{ifltxkeys@break}
+ {ifltxkeys@break@\romannumeral\ltxkeys@csvdepth}%
+ \letcsntocsn{ltxkeys@doo}{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}%
+ \ltxkeys@nil{\expandcsonce\ltxkeys@parsestack}%
+ }%
+ \ifdefTF\ltxkeys@do
+ {\let\ltxkeys@doo\ltxkeys@do}{\cpt@notdeferr\ltxkeys@do}%
+ \def\ltxkeys@parse@b{%
+ \if@boolTF{ltxkeys@break}{%
+ \defpass\reserved@a####1\ltxkeys@nil,{}%
+ }{%
+ \ltxkeys@parse@c.%
+ }%
+ }%
+ \long\def\ltxkeys@parse@c##1,{%
+ \edef\ltxkeys@arg{\expandcsonce{\@gobble##1}}%
+ \ifxTF\ltxkeys@arg\ltxkeys@nnil{}{%
+ \ifxTF\@empty\ltxkeys@arg{}{%
+ \expandafter\ltxkeys@doo\expandafter{\ltxkeys@arg}\relax
+ }%
+ \ltxkeys@parse@b
+ }%
+ }%
+ \ifpsiboolTF{ltxkeys@nlz}{%
+ \cpt@sttrue
+ \usename{cpt@\if\ltxkeys@inkv kv\else csv\fi normalize}[,]\ltxkeys@arg
+ }{}%
+ \ltxkeys@breakfalse
+ \expandafter\ltxkeys@parse@b\ltxkeys@arg,\ltxkeys@nil,%
+ \def\reserved@a##1\ltxkeys@nil{##1\gdef\ltxkeys@parsestack}%
+ \expandafter\reserved@a\ltxkeys@parsestack
+ \global\advance\ltxkeys@csvdepth\m@one
+ \ifnum\ltxkeys@csvdepth=\z@pt\undefcs\ltxkeys@do\fi
+}
+\robust@def*\ltxkeys@testopt@a#1{\cpt@testopt{\ltxkeys@testopt@b#1}{KV}}
+\robust@def*\ltxkeys@testopt@b#1[#2]#3{%
+ \ltxkeys@makepf{#2}%
+ \ltxkeys@makehdr{#3}#1%
+}
+\robust@def*\ltxkeys@testopt@c#1{%
+ \begingroup
+ \catcode`\,=12\relax
+ \cpt@testopt{\ltxkeys@testopt@d#1}{KV}%
+}
+\robust@def*\ltxkeys@testopt@d#1[#2]#3{%
+ \ifltxkeys@pl\else
+ \def\temp@err##1{%
+ \ltxkeys@err{Multiple ##1 in \noexpandcsn
+ {ltxkeys@set\ifltxkeys@rm rm\fi keys}%
+ without '+' suffix}\@ehc
+ }%
+ \ltxkeys@ifeltcountTF[>]{#2}\@ne{%
+ \temp@err{prefixes}%
+ }{%
+ \ltxkeys@ifeltcountTF[>]{#3}\@ne{%
+ \temp@err{families}%
+ }{}%
+ }%
+ \fi
+ \endgroup
+ \def\ltxkeys@prefs{#2}%
+ \def\ltxkeys@fams{#3}%
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams
+ \cpt@testopt{#1}{}%
+}
+\robust@def*\ltxkeys@testopt@e#1#2{%
+ \ltxkeys@testopt@a{%
+ \cptexpandarg{\cpt@testopt{\ltxkeys@testopt@f#1}}{#2\ltxkeys@hdr}%
+ }%
+}
+\robust@def*\ltxkeys@testopt@f#1[#2]#3{%
+ \if@boolTF{ltxkeys@sw}{%
+ \cpt@ifbrack{\ltxkeys@sttrue#1{#2}{#3}}{\ltxkeys@stfalse#1{#2}{#3}[]}%
+ }{%
+ \cpt@ifbrack{\ltxkeys@bracedefault{\ltxkeys@sttrue#1{#2}{#3}}}%
+ {\ltxkeys@stfalse#1{#2}{#3}[]}%
+ }%
+}
+\robust@def*\ltxkeys@testopt@g#1#2{%
+ \cptexpandarg\ltxkeys@testopt@a{\noexpandcsn{ltxkeys@#1}{#2}}%
+}
+\robust@def*\ltxkeys@bracedefault#1[{%
+ \begingroup
+ \toks@{#1}%
+ \defpass\ltxkeys@tempa##1]{%
+ \toks1\expandafter{\@gobble##1}%
+ \cptexpandsecond{\endgroup}{\the\toks@[{\the\toks1}]}%
+ }.%
+}
+\robust@def*\ltxkeys@testopt@@a#1{\ltxkeys@testst{\ltxkeys@testopt@@b#1}}
+\robust@def*\ltxkeys@testopt@@b#1{\cpt@testopt{\ltxkeys@testopt@@c#1}{KV}}
+\robust@def*\ltxkeys@testopt@@c#1[#2]{%
+ \def\ltxkeys@prefs{#2}%
+ \cpt@testfam{\ltxkeys@testopt@@d#1}%
+}
+\robust@def*\ltxkeys@testopt@@d#1<#2>{%
+ \edef\ltxkeys@fams{#2}%
+ \cpt@testopt{#1}{}%
+}
+\robust@def*\ltxkeys@findneedvalue#1{%
+ \ltxkeys@findpointer\needvalue{#1}\ltxkeys@tkey{%
+ \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey
+ }{}%
+}
+\robust@def*\ltxkeys@findpointer#1#2#3{%
+ \def\reserved@a##1#1##2##3\ltxkeys@nil{%
+ \edef#3{\unexpanded{##2}}%
+ \ifxTF#3\ltxkeys@nnil{%
+ \edef#3{\unexpanded{##1}}%
+ \ltxkeys@trimspacesincs#3%
+ \@secondoftwo
+ }{%
+ \ltxkeys@trimspacesincs#3%
+ \@firstoftwo
+ }%
+ }%
+ \reserved@a#2#1{\ltxkeys@nil}\ltxkeys@nil
+}
+\robust@def*\ltxkeys@addtopointedkeys#1#2{%
+ \letcstocsn\reserved@a{\ltxkeys@hdr#1@keys}%
+ \ifdefTF\reserved@a{%
+ \xifinsetTF{,\cptoxdetok{#2},}{,\cptoxdetok\reserved@a,}{}{%
+ \csn@xdef{\ltxkeys@hdr#1@keys}%
+ {\cptliststack,\reserved@a\expandcsonce{#2}}%
+ }%
+ }{%
+ \csn@xdef{\ltxkeys@hdr#1@keys}{\expandcsonce{#2}}%
+ }%
+}
+\robust@def*\ltxkeys@makepf#1{%
+ \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@ttpref
+ \edef\ltxkeys@tpref{%
+ \ifcsnullTF\ltxkeys@ttpref{}{\ltxkeys@ttpref @}%
+ }%
+}
+\robust@def*\ltxkeys@makehdr#1{%
+ \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@tfam
+ \edef\ltxkeys@hdr{%
+ \ltxkeys@tpref\ifcsnullTF\ltxkeys@tfam{}{\ltxkeys@tfam @}%
+ }%
+}
+\robust@def*\ltxkeys@saveinitialkeyvals#1#2#3{%
+ \xifinsetTF{\detokenize{\savevalue}}{\cptoxdetok{#2}}{%
+ \ltxkeys@err{\noexpand\savevalue pointer not allowed
+ \MsgBrk when defining a key}\@ehc
+ }{}%
+ \ifltxkeys@twk\else
+ \ifltxkeys@sv
+ \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr initial@keyvals}%
+ \csn@xdef{\ltxkeys@hdr initial@keyvals}{%
+ \cptliststack,\ltxkeys@tempa\expandcsonce{#2}=%
+ \ifstrcmpTF{#1}{bool}{false}{\unexpanded{#3}}%
+ }%
+ \fi
+ \fi
+ \ifltxkeys@verbose
+ \wlog{Key defined: \ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey.}%
+ \fi
+}
+% \ltxkeys@ordkey[pref]{fam}{key}[dft]{fn}
+\robust@def*\ltxkeys@ordkey{%
+ \ltxkeys@svtrue\ltxkeys@swfalse
+ \ltxkeys@testopt@a\ltxkeys@ordkey@a
+}
+\robust@def*\ltxkeys@ordkey@a#1{%
+ \ltxkeys@findneedvalue{#1}%
+ \cpt@ifbrack{%
+ \ltxkeys@bracedefault
+ {\ltxkeys@sttrue\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey}%
+ }{%
+ \ltxkeys@stfalse\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey[]%
+ }%
+}
+\robust@def*\ltxkeys@ordkey@b#1[#2]#3{%
+ \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault{#1}{#2}}%
+ \ltxkeys@saveinitialkeyvals{}{#1}{#2}%
+ \csn@def{\ltxkeys@hdr#1}##1{#3}%
+}
+% \ltxkeys@cmdkey[pref]{fam}[mp]{key}[dft]{fn}
+\robust@def*\ltxkeys@cmdkey{%
+ \ltxkeys@svtrue\ltxkeys@swfalse
+ \ltxkeys@testopt@e\ltxkeys@cmdkey@a{cmd}%
+}
+\robust@def*\ltxkeys@cmdkey@a#1#2[#3]#4{%
+ \ltxkeys@findneedvalue{#2}%
+ \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault\ltxkeys@tkey{#3}}%
+ \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}%
+ \begingroup
+ \edef\ltxkeys@tempa{\endgroup\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1}%
+ \edef\ltxkeys@tempb##1{%
+ {\csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}##1}%
+ }%
+ \expandafter\ltxkeys@tempa\ltxkeys@tempb{#4}%
+}
+% \ltxkeys@boolkey[pref]{fam}[mp]{key}[dft]{fn}
+% \ltxkeys@boolkey+[pref]{fam}[mp]{key}[dft]{fn}{keyvalerr}
+\robust@def*\ltxkeys@boolkey{%
+ \ltxkeys@svtrue\ltxkeys@swtrue
+ \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@boolkey@a{bool}}%
+}
+\robust@def*\ltxkeys@boolkey@a#1#2[#3]{%
+ \ltxkeys@findneedvalue{#2}%
+ \ltxkeys@saveinitialkeyvals{bool}\ltxkeys@tkey{#3}%
+ \aftercsname{\if@boolTF{ltxkeys@pl}\ltxkeys@boolkey@c\ltxkeys@boolkey@b}%
+ {\ltxkeys@hdr\ltxkeys@tkey}{\ltxkeys@tkey}{#1\ltxkeys@tkey}{#3}%
+}
+\robust@def*\ltxkeys@boolkey@b#1#2#3#4#5{%
+ \ltxkeys@boolkey@d#1{#2}{#3}{#4}%
+ {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}}%
+}
+\robust@def*\ltxkeys@boolkey@c#1#2#3#4#5#6{%
+ \ltxkeys@boolkey@d#1{#2}{#3}{#4}%
+ {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}{#6}}%
+}
+\robust@def*\ltxkeys@boolkey@d#1#2#3#4#5{%
+ \csn@newif{#3}%
+ \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault{#2}{#4}}%
+ \cptexpandarg{\def#1##1}{%
+ \csn@def{#3}{####1}%
+ \noexpandcsn{cpt@pl\ifltxkeys@pl true\else false\fi}%
+ \unexpanded
+ {\cpt@sttrue\ltxkeys@cc@b,[\ltxkeys@resa]{##1}{true,false}#5}%
+ }%
+}
+% \ltxkeys@biboolkeys[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn}
+% \ltxkeys@biboolkeys+[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn}
+% {<fallback>}
+\robust@def*\ltxkeys@biboolkeys{%
+ \ltxkeys@svtrue\ltxkeys@swtrue
+ \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@biboolkeys@a{}}%
+}
+\robust@def*\ltxkeys@biboolkeys@a#1#2[#3]{%
+ \if@boolTF{ltxkeys@pl}\ltxkeys@biboolkeys@c\ltxkeys@biboolkeys@b
+ {#1}{#2}{#3}%
+}
+\robust@def*\ltxkeys@biboolkeys@b#1#2#3#4#5{%
+ \ltxkeys@biboolkeys@d{#1}{#2}{#3}%
+ \ltxkeys@tempa{#4}%
+ \ltxkeys@tempb{#5}%
+}
+\robust@def*\ltxkeys@biboolkeys@c#1#2#3#4#5#6{%
+ \ltxkeys@biboolkeys@d{#1}{#2}{#3}%
+ \ltxkeys@tempa{#4}{#6}%
+ \ltxkeys@tempb{#5}{#6}%
+}
+\robust@def*\ltxkeys@biboolkeys@d#1#2#3{%
+ \ltxkeys@ifeltcountTF[=]{#2}\tw@{}{%
+ \ltxkeys@err{Biboolean keys '#2' not equal to 2}\@ehc
+ \@gobble
+ }%
+ \def\ltxkeys@keys{#2}%
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys
+ \def\ltxkeys@tempa##1,##2\ltxkeys@nil##3##4{%
+ \ltxkeys@findneedvalue{##1}%
+ \let\ltxkeys@tkeya\ltxkeys@tkey
+ \ltxkeys@findneedvalue{##2}%
+ \cpt@newv@riables{tog}{\ltxkeys@hdr}{##1,##2}[false]%
+ \cptexpandsecond\ltxkeys@biboolkeys@e
+ {{\ltxkeys@tkeya}{\ltxkeys@tkey}}{#1}{#3}{##3}{##4}%
+ }%
+ \cptexpandsecond\ltxkeys@tempa
+ {\ltxkeys@keys\ltxkeys@nil{\ltxkeys@ttpref}{\ltxkeys@tfam}}%
+ \undefcs\ltxkeys@tkeya
+}
+\robust@def\ltxkeys@biboolkeys@e#1#2#3#4#5#6{%
+ \ifltxkeys@pl
+ \long\def\ltxkeys@tempa##1##2{%
+ \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{{%
+ \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}%
+ ##1\relax
+ \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}%
+ }{##2}}%
+ }%
+ \long\def\ltxkeys@tempb##1##2{%
+ \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{{%
+ \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}%
+ ##1\relax
+ \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}%
+ }{##2}}%
+ }%
+ \else
+ \long\def\ltxkeys@tempa##1{%
+ \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{%
+ \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}%
+ ##1\relax
+ \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}%
+ }%
+ }%
+ \long\def\ltxkeys@tempb##1{%
+ \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{%
+ \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}%
+ ##1\relax
+ \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}%
+ }%
+ }%
+ \fi
+}
+\robust@def\ltxkeys@biboolkeys@f#1#2#3#4#5{%
+ \iftogTF{\ltxkeys@hdr#1}{}{%
+ \settogtrue{\ltxkeys@hdr#2}%
+ \cptexpandarg{\ltxkeys@setkeys[#4]{#5}}{#2=\thebool@reverse{#3}}%
+ \settogfalse{\ltxkeys@hdr#2}%
+ }%
+}
+% \ltxkeys@stylekey[<pref>]{<fam>}[<mp>]{<key>}[<dft>](<deps>){<fn>}
+\robust@def*\ltxkeys@stylekey{%
+ \ltxkeys@svtrue\ltxkeys@swfalse
+ \ltxkeys@testst{%
+ \cpt@cnta\ifltxkeys@st1\else0\fi\relax
+ \ltxkeys@testopt@e\ltxkeys@stylekey@a{style}%
+ }%
+}
+\robust@def*\ltxkeys@stylekey@a#1#2[#3]{%
+ \cpt@testpnopt{\ltxkeys@stylekey@b{#1}{#2}{#3}}{}%
+}
+\robust@def*\ltxkeys@stylekey@b#1#2#3(#4)#5{%
+ \ltxkeys@findneedvalue{#2}%
+ \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}%
+ \ifltxkeys@st
+ \s@expandarg\ltxkeys@definedefault\ltxkeys@tkey{#3}%
+ \fi
+ \cptexpandtwoargs\cpt@in
+ {\detokenize\expandafter{\unexpanded\expandafter
+ {\csname\ltxkeys@hdr\ltxkeys@tkey @value\endcsname}}}
+ {\detokenize{#4}}%
+ \csn@edef{\ltxkeys@hdr\ltxkeys@tkey @dependants}{\unexpanded{#4}}%
+ \cptpassexpanded{%
+ \long\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1{%
+ \csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}%
+ \edef\noexpand\parentval{\noexpand\unexpanded{####1}}%
+ \ifcpt@in
+ \csn@xdef{\ltxkeys@hdr\ltxkeys@tkey @value}%
+ {\noexpand\unexpanded{####1}}%
+ \fi
+ \unexpanded{#5}\relax
+ \ltxkeys@setdependants{\number\cpt@cnta}{#1}%
+ }%
+ }%
+}
+\robust@def*\ltxkeys@setdependants#1#2{%
+ \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr\ltxkeys@tkey @dependants}%
+ \ifcsemptyTF\ltxkeys@tempa{}{%
+ \cpt@sttrue\cpt@csvnormalize[;]\ltxkeys@tempa
+ \if@boolTF{ltxkeys@dec}{}{%
+ \cptexpandargonce{\ltxkeys@s@tdependants{#1}{#2}}\ltxkeys@tempa
+ }%
+ }%
+}
+\robust@def*\ltxkeys@s@tdependants#1#2#3{%
+ \begingroup
+ \toks0{}\toks1{}\toks2{}%
+ \def\csv@do##1{%
+ \ltxkeys@s@td@pendants{##1}%
+ \ltxkeys@s@td@p@ndants{#1}%
+ }%
+ \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#3}%
+ \let\ifblankTF\relax
+ \cptpassexpanded{%
+ \endgroup
+ \noexpand\ltxkeys@deptrue
+ \ifblankTF{\the\toks0}{}%
+ {\ltxkeys@setkeys[\expandcsonce\ltxkeys@ttpref]%
+ {\expandcsonce\ltxkeys@tfam}{\the\toks0}}%
+ \ifblankTF{\the\toks1}{}%
+ {\ltxkeys@declarekeys[\ltxkeys@ttpref]<\ltxkeys@tfam>[#2]{\the\toks1}}%
+ \ifblankTF{\the\toks2}{}{%
+ \ltxkeys@err{Undefined dependant keys:^^J||\the\toks2||}{%
+ I have come across undefined dependant keys. You can
+ \MsgBrk use the star (*) form of '\string\ltxkeys@stylekey'
+ \MsgBrk to define and set dependant keys on the fly.
+ }%
+ }%
+ }%
+ \ltxkeys@depfalse
+}
+\robust@def*\ltxkeys@s@td@pendants#1{%
+ \begingroup
+ \emptifycsset{\key@name,\key@default,\key@macro}%
+ \@temptokena{#1}%
+ \def\ltxkeys@splita##1/##2/{%
+ \ifblankTF{##1##2}{%
+ \gobble@to@ltxkeys@nil
+ }{%
+ \ltxkeys@trimspaces{##1}\key@type
+ \def\stripstar####1*\@empty####2\@nil{\edef\key@type{####1}}%
+ \expandafter\stripstar\key@type\@empty*\@empty\@nil
+ \xifstrcmpFT\key@type{sty}{}{%
+ \ltxkeys@err{A dependant key can't have dependants:
+ \MsgBrk ||\the\@temptokena||}\@ehc
+ }%
+ \xifinsetTF\key@type{,ord,cmd,bool,choice,}{}{%
+ \ltxkeys@err{Invalid key type '\key@type' in dependant key(s)
+ \MsgBrk ||\the\@temptokena||}\@ehc
+ }%
+ \ifblankTF{##2}{%
+ \ltxkeys@err{Empty key name in dependant key(s)\MsgBrk
+ ||\the\@temptokena||}\@ehc
+ }{%
+ \ltxkeys@findneedvalue{##2}%
+ \let\key@name\ltxkeys@tkey
+ }%
+ \ltxkeys@splitb.%
+ }%
+ }%
+ \def\ltxkeys@splitb##1/##2/##3\ltxkeys@nil{%
+ \edef\key@default{\expandcsonce{\@gobble##1}}%
+ \ltxkeys@trimspacesincs\key@default
+ \xifstrcmpTF{\cptoxdetok\key@default}{\detokenize{\parentval}}{%
+ \edef\key@default{\expandcstwice\key@default}%
+ }{}%
+ \edef\key@macro{\unexpanded{##2}}%
+ }%
+ \ltxkeys@splita#1////\ltxkeys@nil
+ \cptpassexpanded{%
+ \endgroup
+ \cpt@csexit\key@type\cpt@csexit\key@name
+ \cpt@csexit\key@default\cpt@csexit\key@macro
+ }%
+}
+\robust@def*\ltxkeys@s@td@p@ndants#1{%
+ \ifcsndefTF{\ltxkeys@hdr\key@name}{%
+ \cptpassexpanded{%
+ \toks0{\the\toks0\oifblankTF{\the\toks0}{}{,}%
+ \expandcsonce\key@name=\expandcsonce\key@default}%
+ }%
+ }{%
+ \cptpassexpanded{%
+ \ifnum\numexpr#1=\@ne
+ \toks1{%
+ \the\toks1\oifblankTF{\the\toks1}{}{;}%
+ \key@type/\key@name
+ \ifcsnullTF\key@default{}{/\expandcsonce\key@default}%
+ \ifcsnullTF\key@macro{}{/\expandcsonce\key@macro}%
+ }%
+ \else
+ \toks2{\the\toks2\oifblankTF{\the\toks2}{}{,}%
+ \expandcsonce\key@name}%
+ \fi
+ }%
+ }%
+}
+% \ltxkeys@choicekey
+% *+[<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<dft>]{<f1>}{<f2>}
+\robust@def*\ltxkeys@choicekey{%
+ \ltxkeys@svtrue\ltxkeys@swfalse
+ \ltxkeys@teststpl{%
+ \ltxkeys@testopt@a{\cpt@testopt\ltxkeys@choicekey@a{chc\ltxkeys@hdr}}%
+ }%
+}
+\robust@def*\ltxkeys@choicekey@a[#1]#2{%
+ \begingroup
+ \def\siso@do##1{\catcode`##1\string=12\relax}%
+ \siso@@loop{=,.}%
+ \cpt@testopt{\expandafter\endgroup\ltxkeys@choicekey@b{#1}{#2}}{}%
+}
+\robust@def*\ltxkeys@choicekey@b#1#2[#3]#4{%
+ \ltxkeys@makechclist{#4}{0}%
+ \cpt@ifbrack{%
+ \ltxkeys@sttrue\ltxkeys@bracedefault
+ {\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}}%
+ }{%
+ \ltxkeys@stfalse\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}[]%
+ }%
+}
+\robust@def*\ltxkeys@choicekey@c#1#2#3#4[#5]{%
+ \ltxkeys@findneedvalue{#1}%
+ \ifltxkeys@st\ltxkeys@definedefault\ltxkeys@tkey{#5}\fi
+ \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#5}%
+ \cptexpanded{%
+ \ifltxkeys@pl\ltxkeys@choicekey@e\else\ltxkeys@choicekey@d\fi
+ \cptmakecs{\ltxkeys@hdr\ltxkeys@tkey}%
+ }%
+ {#2}{#3}{#4}%
+}
+\robust@def*\ltxkeys@choicekey@d#1#2#3#4#5{%
+ \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}}%
+}
+\robust@def*\ltxkeys@choicekey@e#1#2#3#4#5#6{%
+ \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}{#6\relax}}%
+}
+\robust@def*\ltxkeys@choicekey@f#1#2#3#4#5{%
+ \ifinsetTF{/.code=}{#4}{%
+ \def\ltxkeys@tempa{\ltxkeys@executechclist}%
+ }{%
+ \def\ltxkeys@tempa{\@gobble}%
+ }%
+ \edef#1{%
+ \edef\cptmakecs{#2}{\noexpand\unexpanded{####1}}%
+ \cptmakecs{cpt@st\ifltxkeys@st true\else false\fi}%
+ \cptmakecs{cpt@pl\ifltxkeys@pl true\else false\fi}%
+ \unexpanded{\ltxkeys@cc@b,[#3]}{####1}{\expandcsonce\ltxkeys@chclist}%
+ \unexpanded{#5}\expandcsonce\ltxkeys@tempa{\unexpanded{#4}}%
+ }%
+ \def\ltxkeys@tempa{\def#1####1}%
+ \expandafter\ltxkeys@tempa\expandafter{#1}%
+}
+\robust@def*\ltxkeys@makechclist#1#2{%
+ \begingroup
+ \def\ltxkeys@chclist{}%
+ \def\ltxkeys@tempb##1/.code=##2\ltxkeys@nil{%
+ \ltxkeys@trimspaces{##1}\ltxkeys@tempa
+ \ifcase#2\relax
+ \cptaddtolist*[,]\ltxkeys@chclist\ltxkeys@tempa
+ \or
+ \cptpassexpanded{\lowercase{%
+ \def\noexpand\ltxkeys@tempa{\expandcsonce\ltxkeys@tempa}%
+ \def\noexpand\ltxkeys@tval{\expandcsonce\ltxkeys@tval}%
+ }}%
+ \oifstrcmpFT\ltxkeys@tempa\ltxkeys@tval{}{%
+ \edef\ltxkeys@chclist{\unexpanded{##2}}%
+ \cptbreakloop
+ }%
+ \else
+ \ltxkeys@err{Invalid number '#2' in \string\ltxkeys@makechclist}\@ehc
+ \fi
+ }%
+ \def\csv@do##1{%
+ \ifinsetTF{/.code=}{##1}{%
+ \ltxkeys@tempb##1\ltxkeys@nil
+ }{%
+ \ltxkeys@tempb##1/.code=\ltxkeys@nil
+ }%
+ }%
+ \ifinsetTF{/.code=}{#1}{%
+ \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#1}%
+ }{%
+ \csv@@parse[,]{#1}%
+ }%
+ \postgroupdef\ltxkeys@chclist\endgroup
+}
+\robust@def*\ltxkeys@executechclist#1{%
+ \begingroup
+ \ltxkeys@makechclist{#1}{1}%
+ \expandafter\endgroup\ltxkeys@chclist
+}
+\robust@def*\ltxkeys@definedefault#1#2{%
+ \xifstrcmpTF{\detokenize{#2}}{\detokenize{\parentval}}{%
+ \s@expandarg\ltxkeys@trimspaces{#2}\ltxkeys@tempa
+ }{%
+ \ltxkeys@trimspaces{#2}\ltxkeys@tempa
+ }%
+ \csn@edef{\ltxkeys@hdr#1@default}{%
+ \noexpandcsn{\ltxkeys@hdr#1}{\expandcsonce\ltxkeys@tempa}%
+ }%
+}
+\robust@def*\ltxkeys@getkeyname#1=#2\ltxkeys@nil#3{%
+ \ltxkeys@trimspaces{#1}#3%
+}
+\robust@def*\ltxkeys@getkeynames#1{%
+ \def\ltxkeys@keynames{}%
+ \def\ltxkeys@do##1{%
+ \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey
+ \edef\ltxkeys@keynames{%
+ \cptliststack,\ltxkeys@keynames\expandcsonce\ltxkeys@tkey
+ }%
+ }%
+ \ifblankTF{#1}{}{\ltxkeys@csvparse{#1}}%
+}
+\robust@def*\option@keys{%
+ \ltxkeys@inpkgcls\option@keys
+ \cpt@testst\ltxkeys@optionk@ys
+}
+\robust@def*\ltxkeys@optionk@ys{%
+ \if@boolTF{cpt@st}{%
+ \ltxkeys@testopt@g{optionkeys}{not}%
+ }{%
+ \ltxkeys@testopt@g{optionkeys}{}%
+ }%
+}
+\robust@def*\notoption@keys{%
+ \ltxkeys@inpkgcls\notoption@keys
+ \ltxkeys@testopt@g{optionkeys}{not}%
+}
+\robust@def*\ltxkeys@optionkeys#1#2{%
+ \def\ltxkeys@do##1{%
+ \ifcsndefTF{\ltxkeys@hdr##1}{%
+ \ifcsndefTF{\ltxkeys@hdr#1option@keys}{%
+ \xifinsetTF{,\detokenize{##1},}
+ {,\cptsxdetok{\@nameuse{\ltxkeys@hdr#1option@keys}},}{}{%
+ \csn@edef{\ltxkeys@hdr#1option@keys}{%
+ \expandcsnonce{\ltxkeys@hdr#1option@keys},%
+ \unexpanded{##1}%
+ }%
+ }%
+ }{%
+ \csn@def{\ltxkeys@hdr#1option@keys}{##1}%
+ }%
+ }{%
+ \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam'
+ \MsgBrk Only defined keys can be made '#1option' keys.}\@ehc
+ }%
+ }%
+ \ltxkeys@csvparse{#2}%
+}
+\robust@def*\makeoption@keys{\cpt@teststopt\ltxkeys@makeoptionkeys{KV}}
+\robust@def*\ltxkeys@makeoptionkeys[#1]#2{%
+ \let\ifmakeoptst\ifcpt@st
+ \ifcsndefTF{#1@#2@initial@keyvals}{%
+ \edef\ltxkeys@tempa{\expandcsnonce{#1@#2@initial@keyvals}}%
+ }{%
+ \ltxkeys@err{No initial key-values for family '#2'}\@ehc
+ }%
+ \s@expandarg\ltxkeys@getkeynames\ltxkeys@tempa
+ \ifcsnullTF\ltxkeys@keynames{}{%
+ \cptexpandarg{\usename{\ifmakeoptst not\fi option@keys}[#1]{#2}}{%
+ \expandcsonce\ltxkeys@keynames
+ }%
+ }%
+ \undefcs\ifmakeoptst
+}
+\robust@def*\makenotoption@keys{%
+ \cpt@sttrue\cpt@testopt\ltxkeys@makeoptionkeys{KV}%
+}
+\robust@def*\ltxkeys@testoptionkey#1{%
+ \ifcsndefFT{\ltxkeys@hdr#1option@keys}{}{%
+ \cpt@choicefdfalse
+ \def\ltxkeys@do##1{%
+ \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{%
+ \cpt@choicefdtrue\ltxkeys@break
+ }{}%
+ }%
+ \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr#1option@keys}%
+ \if@boolFT{cpt@choicefd}{}{%
+ \ltxkeys@err{The following key should
+ \ifnullTF{#1}\@gobblespace{#1} appear in
+ \MsgBrk\noexpand\usepackage or \string\RequirePackage:
+ ^^J||\ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey||%
+ }\@ehc
+ }%
+ }%
+}
+\robust@def*\ltxkeys@testneedvalkey{%
+ \begingroup
+ \cpt@choicefdfalse
+ \def\ltxkeys@do##1{%
+ \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{%
+ \cpt@choicefdtrue\ltxkeys@break
+ }{}%
+ }%
+ \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr needvalue@keys}%
+ \ifcpt@choicefd
+ \ltxkeys@err{You're required to supply a value for
+ \MsgBrk key '\ltxkeys@tkey' in family '\ltxkeys@tfam'}{%
+ Please supply a value for key '\ltxkeys@tkey' of families
+ \MsgBrk'\ltxkeys@fams' and rerun. The author of this key
+ \MsgBrk meant it to require a user value.
+ }%
+ \fi
+ \endgroup
+}
+\new@def*\ltxkeys@setbool#1{%
+ \xifstrcmpTF{#1}{on}{%
+ \def#1{true}%
+ }{%
+ \xifstrcmpTF{#1}{off}{%
+ \def#1{false}%
+ }{%
+ \edef#1{#1}%
+ }%
+ }%
+}
+\robust@def*\ltxkeys@accumkeyvals#1{%
+ \ltxkeys@ifinTF(1)%
+ {\ltxkeys@setmnkey,\setmnkey,\setaliaskey}{#1}%
+ \ltxkeys@twktrue\ltxkeys@twkfalse
+ \begingroup
+ \edef\key@vals{%
+ \cptliststack,\key@vals\expandcsonce\key@name=%
+ \ifltxkeys@dep
+ \expandcsonce\key@default
+ \else
+ \oifstrcmpTF\key@default{true}{false}{%
+ \expandcsonce\key@default
+ }%
+ \fi
+ }%
+ \ifltxkeys@ssk
+ \gletcs\key@vals\key@vals
+ \else
+ \ifltxkeys@twk\else
+ \gletcs\key@vals\key@vals
+ \fi
+ \fi
+ \endgroup
+}
+% \ltxkeys@definekeys[pref]<fam>[macropf]{<keyname>=<dft>/<callback>; ...}
+\robust@def*\ltxkeys@definekeys{%
+ \begingroup
+ \endlinechar\m@one
+ \cpt@teststopt\ltxkeys@definekeys@a{KV}%
+}
+\robust@def*\ltxkeys@definekeys@a[#1]{%
+ \gletcs\ifdefkeyst\ifcpt@st
+ \cpt@testfam{\ltxkeys@definekeys@b#1}%
+}
+\robust@def*\ltxkeys@definekeys@b#1<#2>{%
+ \cpt@testopt
+ {\expandafter\endgroup\ltxkeys@definekeys@c{#1}{#2}}{}%
+}
+\robust@def*\ltxkeys@definekeys@c#1#2[#3]#4{%
+ \begingroup
+ \ltxkeys@trimspaces{#1}\key@prefix
+ \ltxkeys@trimspaces{#2}\key@family
+ \ltxkeys@trimspaces{#3}\macro@prefix
+ \toks@{\undefcs\ifdefkeyst}%
+ \def\key@vals{}%
+ \def\ltxkeys@splita##1={%
+ \begingroup
+ \defpass\reserved@a####1\ltxkeys@nil{\endgroup
+ \ltxkeys@splitb##1/####1//\ltxkeys@nil
+ }.%
+ }%
+ \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
+ \ifblankTF{##1}{%
+ \ifblankTF{##2##3}{}{%
+ \ltxkeys@err{Empty key name while in
+ \string\ltxkeys@definekeys}\@ehc
+ }%
+ }{%
+ \ltxkeys@findneedvalue{##1}%
+ \let\key@name\ltxkeys@tkey
+ \ifdefkeyst
+ \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{%
+ \ltxkeys@err{Key '\key@name' already defined in family
+ \MsgBrk '#2' with prefix '#1'}\@ehc
+ }%
+ \fi
+ \ifblankTF{##2}{%
+ \def\key@default{}%
+ }{%
+ \s@expandarg\ltxkeys@trimspaces{\@gobble##2}\key@default
+ }%
+ \ltxkeys@accumkeyvals{##3}%
+ \def\defwith{\ltxkeys@boolkey}%
+ \oifstrcmpTF\key@default{true}{}{%
+ \oifstrcmpTF\key@default{false}{}{%
+ \def\defwith{\ltxkeys@cmdkey}%
+ }%
+ }%
+ \cptexpanded{%
+ \toks@{\the\toks@
+ \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}%
+ \defwith[\key@prefix]{\key@family}%
+ \ifx\macro@prefix\@empty\else[\macro@prefix]\fi
+ {\key@name}[\expandcsonce\key@default]{\unexpanded{##3}}%
+ }%
+ }%
+ }%
+ }%
+ \long\def\csv@do##1{%
+ \cpt@checkeq##1\cpt@nil{%
+ \ltxkeys@splita##1\ltxkeys@nil
+ }{%
+ \ltxkeys@splitb##1///\ltxkeys@nil
+ }%
+ }%
+ \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#4}%
+ \cptexpandsecond\endgroup{%
+ \the\toks@
+ \noexpand\ltxkeys@twkfalse
+ \ifcsnullTF\key@vals{}{\noexpand\ltxkeys@setkeys
+ [\key@prefix]{\key@family}{\expandcsonce\key@vals}%
+ }%
+ }%
+}
+\new@def*\ltxkeys@badkeytypes{}
+\robust@def*\ltxkeys@keytypeerr#1{%
+ \edef\ltxkeys@badkeytypes{\cptliststack,\ltxkeys@badkeytypes#1}%
+}
+% \ltxkeys@declarekeys[pref]<fam>[macropf]{<keytype>/<keyname>
+% /<dft>/<callback><parser> ...}
+\robust@def*\ltxkeys@declarekeys{%
+ \begingroup
+ \endlinechar\m@one
+ \cpt@teststopt\ltxkeys@declarekeys@a{KV}%
+}
+\robust@def*\ltxkeys@declarekeys@a[#1]{%
+ \gletcs\ifdefkeyst\ifcpt@st
+ \cpt@testfam{\ltxkeys@declarekeys@b{#1}}%
+}
+\robust@def*\ltxkeys@declarekeys@b#1<#2>{%
+ \cpt@testopt{\expandafter\endgroup\ltxkeys@declarekeys@c{#1}#2}{}%
+}
+\robust@def*\ltxkeys@declarekeys@c#1#2[#3]#4{%
+ \ltxkeys@dectrue
+ \begingroup
+ \ltxkeys@trimspaces{#1}\key@prefix
+ \ltxkeys@trimspaces{#2}\key@family
+ \ltxkeys@trimspaces{#3}\macro@prefix
+ \def\key@vals{}%
+ \toks@{\undefcs\ifdefkeyst}%
+ \def\ltxkeys@splita##1/##2/{%
+ \ifblankTF{##1##2}{%
+ \gobble@to@ltxkeys@nil
+ }{%
+ \ifblankTF{##2}{%
+ \ltxkeys@err{Empty key name in \string\ltxkeys@declarekeys}\@ehc
+ }{%
+ \ltxkeys@trimspaces{##1}\key@type
+ \ltxkeys@findneedvalue{##2}%
+ \let\key@name\ltxkeys@tkey
+ \ifdefkeyst
+ \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{%
+ \ltxkeys@err{Key '\key@name' already defined in family
+ \MsgBrk '#2' with prefix '#1'}\@ehc
+ }%
+ \fi
+ \oifstrcmpFT\key@type{choice}{}{%
+ \s@expandarg\ltxkeys@splitchoice\key@name
+ }%
+ \ltxkeys@splitb.%
+ }%
+ }%
+ }%
+ \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
+ \edef\key@default{\expandcsonce{\@gobble##1}}%
+ \ifcsnullTF\key@default{%
+ \oifstrcmpFT\key@type{bool}{}{\def\key@default{true}}%
+ }{%
+ \ltxkeys@trimspacesincs\key@default
+ }%
+ \oifinsetFT{sty}\key@type{}{\ltxkeys@declarekeys@d{##3}}%
+ \ltxkeys@accumkeyvals{##2}%
+ \def\ltxkeys@tempa{ord}%
+ \edef\ltxkeys@tempa{%
+ [\key@prefix]{\key@family}%
+ \ifx\key@type\ltxkeys@tempa\else\ifx\macro@prefix\@empty\else
+ [\macro@prefix]\fi\fi
+ {\key@name}%
+ }%
+ \cptpassexpanded{%
+ \toks@{\the\toks@
+ \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}%
+ \IfStrEqCase[\ltxkeys@keytypeerr{\expandcsonce\key@type}]%
+ {\key@type}{%
+ {sty}{%
+ \ltxkeys@stylekey\ltxkeys@tempa
+ [\expandcsonce\key@default](\expandcsonce\dependant)%
+ {\unexpanded{##2}}%
+ }%
+ {sty*}{%
+ \ltxkeys@stylekey*\ltxkeys@tempa
+ [\expandcsonce\key@default](\expandcsonce\dependant)%
+ {\unexpanded{##2}}%
+ }%
+ {cmd}{%
+ \ltxkeys@cmdkey\ltxkeys@tempa
+ [\expandcsonce\key@default]{\unexpanded{##2}}%
+ }%
+ {bool}{%
+ \ltxkeys@boolkey+\ltxkeys@tempa
+ [\expandcsonce\key@default]{\unexpanded{##2}}%
+ {\ltxkeys@keyvalerr}%
+ }%
+ {choice}{%
+ \ltxkeys@choicekey*+\ltxkeys@tempa
+ [\unexpanded{\val\nr}]{\expandcsonce\ltxkeys@alt}%
+ [\expandcsonce\key@default]{\unexpanded{##2}}%
+ {\ltxkeys@keyvalerr}%
+ }%
+ {ord}{%
+ \ltxkeys@ordkey\ltxkeys@tempa
+ [\expandcsonce\key@default]{\unexpanded{##2}}%
+ }%
+ }%
+ }%
+ }%
+ }%
+ \ifdefTF\ltxkeys@keyparser{%
+ \stripallouterbracesincs\ltxkeys@keyparser
+ }{%
+ \def\ltxkeys@keyparser{;}%
+ }%
+ \def\csv@do##1{%
+ \ltxkeys@splita##1/////\ltxkeys@nil
+ }%
+ \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#4}%
+ \cptexpandsecond\endgroup{%
+ \the\toks@
+ \noexpand\ltxkeys@twkfalse
+ \edef\noexpand\key@vals{\ox@unexpanded\key@vals}%
+ }%
+ \ifx\ltxkeys@badkeytypes\@empty\else
+ \cpt@err{Invalid key types '\ltxkeys@badkeytypes'}\@ehc
+ \fi
+ \ifcsnullTF\key@vals{}{%
+ \cptexpandargonce{\ltxkeys@setkeys[#1]{#2}}\key@vals
+ }%
+ \ltxkeys@decfalse
+}
+\robust@def\ltxkeys@declarekeys@d#1{%
+ \begingroup
+ \ifblankTF{#1}{%
+ \def\dependant{}%
+ }{%
+ \ifinsetFT{>}{#1}{%
+ \ltxkeys@err{Missing key type and name in dependant key
+ ^^J\detokenize{#1}'}{No '>' in dependant key.}%
+ \def\dependant{}%
+ }{%
+ \def\ltxkeys@tempa##1>##2>##3>##4>##5\ltxkeys@nil{%
+ \edef\dependant{\unexpanded{##1/##2/##3/##4}}%
+ }%
+ \ltxkeys@tempa#1>>>>\ltxkeys@nil
+ }%
+ }%
+ \postgroupdef\dependant\endgroup
+}
+\robust@def*\ltxkeys@setmnkey#1{%
+ \xifinsetTF{,}{\detokenize{#1}}{%
+ \ltxkeys@err{\noexpand\ltxkeys@setmnkey doesn't accept key list}\@ehc
+ }{%
+ \cpt@testopt{\ltxkeys@settmnkey@a#1}{}%
+ }%
+}
+\robust@def*\ltxkeys@settmnkey@a#1[#2]{%
+ \cptexpandsecond\ltxkeys@setkeys{%
+ [\ltxkeys@ttpref]{\ltxkeys@tfam}{%
+ #1=\ifnullTF{#2}{\expandcsonce\ltxkeys@tval}{\unexpanded{#2}}%
+ }%
+ }%
+}
+\newletcs\setmnkey\ltxkeys@setmnkey
+\newletcs\setaliaskey\ltxkeys@setmnkey
+\robust@def*\ltxkeys@splitchoice#1{%
+ \begingroup
+ \def\ltxkeys@tempa##1.##2##3\ltxkeys@nil{\endgroup
+ \ltxkeys@trimspaces{##1}\key@name
+ \ifstrcmpTF{##2}{.}{%
+ \ltxkeys@err{Invalid alternate value list for key '#1'}\@ehc
+ }{%
+ \cptifmacroTF{##2}{%
+ \edef\ltxkeys@alt{\expandcsonce{##2}}%
+ }{%
+ \edef\ltxkeys@alt{\unexpanded{##2}}%
+ }%
+ \despacecontent\ltxkeys@alt
+ }%
+ }%
+ \ltxkeys@tempa#1..\ltxkeys@nil
+}
+\robust@def*\ltxkeys@setinitialkeyvals#1#2{%
+ \ifcsndefFT{#1@#2@initial@keyvals}{}{%
+ \ifcsnnullTF{#1@#2@initial@keyvals}{}{%
+ \cptpassexpanded{%
+ \noexpand\ltxkeys@setkeys[#1]{#2}%
+ {\expandcsnonce{#1@#2@initial@keyvals}}%
+ }%
+ }%
+ }%
+}
+% \ltxkeys@initializekeys[<prefix>]{<fams>}[<na>]
+\robust@def*\ltxkeys@initializekeys{%
+ \cpt@testopt\ltxkeys@in@tializekeys{KV}%
+}
+\robust@def*\ltxkeys@in@tializekeys[#1]#2{%
+ \cpt@testopt{\ltxkeys@in@ti@lizekeys{#1}{#2}}{}%
+}
+\robust@def*\ltxkeys@in@ti@lizekeys#1#2[#3]{%
+ \begingroup
+ \def\ltxkeys@resa{}%
+ \def\ltxkeys@do##1{%
+ \edef\ltxkeys@resa{%
+ \cptliststack,\ltxkeys@resa
+ \ifcsndefFT{#1@##1@initial@keyvals}{}{%
+ \expandcsnonce{#1@##1@initial@keyvals}%
+ }%
+ }%
+ }%
+ \ltxkeys@csvparse{#2}%
+ \ltxkeys@getkeynames{#3}%
+ \cptexpandsecond{\endgroup\ltxkeys@setkeys*+[#1]{#2}}%
+ {[\ltxkeys@keynames]{\ltxkeys@resa}}%
+}
+
+% \ltxkeys@launchkeys[<prefix>]{<fams>}{<curr>}
+\robust@def*\ltxkeys@launchkeys{\cpt@testopt\ltxkeys@l@unchkeys{KV}}
+\robust@def*\ltxkeys@l@unchkeys[#1]#2#3{%
+ \ltxkeys@in@ti@lizekeys{#1}{#2}[#3]%
+ \ifblankTF{#3}{}{\ltxkeys@setkeys[#1]{#2}{#3}}%
+}
+
+% \ltxkeys@setkeys*+[<prfs>]{<fams>}[<na>]{<curr>}
+\robust@def*\ltxkeys@setkeys{%
+ \ltxkeys@rmfalse
+ \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setkeys@a}%
+}
+\robust@def*\ltxkeys@setrmkeys{%
+ \ltxkeys@rmtrue
+ \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setrmkeys@a}%
+}
+\robust@def*\ltxkeys@setrmkeys@a[#1]{%
+ \cptexpandarg{\ltxkeys@setkeys@a[#1]}
+ {\expandcsnonce{\ltxkeys@hdr rmkeys}}%
+}
+\robust@def*\ltxkeys@setkeys@a[#1]#2{%
+ \cpt@choicefdfalse
+ \def\siso@do##1{%
+ \ifstrcmpTF{#2}{##1}\cpt@choicefdtrue\relax
+ }%
+ \siso@@loop{.,;:+-=*^_/[()]}%
+ \ifcpt@choicefd
+ \ltxkeys@err{Invalid key list '#2'}\@ehc
+ \fi
+ \ifnum\ltxkeys@keydepth=\z@pt
+ \csn@def{\ltxkeys@hdr rmkeys}{}%
+ \def\ltxkeys@undefinedkeys{}%
+ \fi
+ \edef\ltxkeys@nakeys{\unexpanded{#1}}%
+ \ifcsemptyTF\ltxkeys@nakeys{}{%
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@nakeys
+ }%
+ \def\ltxkeys@do##1{%
+ \edef\CurrentKeyval{\unexpanded{##1}}%
+ \ltxkeys@setkeys@b##1=\ltxkeys@nil
+ }%
+ \ltxkeys@kvparse{#2}%
+ \emptifycsset{\CurrentPref,\CurrentFam,\CurrentKeyval,
+ \CurrentKey,\CurrentVal}%
+ \ltxkeys@exopfalse\ltxkeys@pxopfalse
+ \ifcsnullTF\ltxkeys@undefinedkeys{}\ltxkeys@logunknownkeys
+}
+\robust@def*\ltxkeys@setkeys@b#1=#2\ltxkeys@nil{%
+ \ifinsetTF{\needvalue}{#1}{%
+ \ltxkeys@err{\noexpand\needvalue pointer not allowed
+ \MsgBrk when setting keys}\@ehc
+ }{}%
+ \ltxkeys@findpointer\savevalue{#1}\ltxkeys@tkey
+ \ltxkeys@svtrue\ltxkeys@svfalse
+ \let\CurrentKey\ltxkeys@tkey
+ \ifinsetTF{=\ltxkeys@nil}{#2\ltxkeys@nil}{%
+ \ltxkeys@novalfalse
+ \begingroup
+ \defpass\reserved@a##1=##2\ltxkeys@nil{\endgroup
+ \edef\ltxkeys@tval{\expandcsonce{\@gobble##1}}%
+ \let\CurrentVal\ltxkeys@tval
+ }%
+ .#2\ltxkeys@nil
+ }{%
+ \ltxkeys@novaltrue
+ \def\ltxkeys@tval{}%
+ }%
+ \ifcsemptyTF\ltxkeys@tkey{%
+ \ifltxkeys@noval\else
+ \ltxkeys@err{No key specified for value
+ '\expandcsonce\ltxkeys@tval'
+ \MsgBrk in families '\ltxkeys@fams'}\@ehc
+ \fi
+ }{%
+ \xifinsetTF{,\ltxkeys@tkey,}{,\ltxkeys@nakeys,}{}{%
+ \ltxkeys@setkeys@c
+ }%
+ }%
+}
+\robust@def*\ltxkeys@setkeys@c{%
+ \ltxkeys@kffalse
+ \if@boolTF{ltxkeys@pl}{%
+ \def\ltxkeys@do##1{%
+ \def\CurrentPref{##1}%
+ \ltxkeys@makepf{##1}%
+ \def\ltxkeys@do####1{%
+ \def\ltxkeys@tfam{####1}%
+ \let\CurrentFam\ltxkeys@tfam
+ \ltxkeys@makehdr\ltxkeys@tfam
+ \ltxkeys@setkeys@d
+ }%
+ \ltxkeys@csvloop*\ltxkeys@fams
+ }%
+ \ltxkeys@csvloop*\ltxkeys@prefs
+ }{%
+ \def\ltxkeys@do##1{%
+ \if@boolTF{ltxkeys@kf}{%
+ \ltxkeys@break
+ }{%
+ \def\CurrentPref{##1}%
+ \ltxkeys@makepf{##1}%
+ \def\ltxkeys@do####1{%
+ \if@boolTF{ltxkeys@kf}{%
+ \ltxkeys@break
+ }{%
+ \def\ltxkeys@tfam{####1}%
+ \let\CurrentFam\ltxkeys@tfam
+ \ltxkeys@makehdr\ltxkeys@tfam
+ \ltxkeys@setkeys@d
+ }%
+ }%
+ \ltxkeys@csvloop*\ltxkeys@fams
+ }%
+ }%
+ \ltxkeys@csvloop*\ltxkeys@prefs
+ }%
+ \if@boolTF{ltxkeys@kf}{%
+ \if@boolFT{ltxkeys@pxop}{}{%
+ \ifx\ltxkeys@testname\cpt@documentclass
+ \cpt@removecurroption\CurrentKeyval
+ \fi
+ }%
+ }{%
+ \ifcsndefTF{\ltxkeys@hdr default@ds}{%
+ \begingroup
+ \let\xp\expandcsonce
+ \cptexpandsecond{%
+ \endgroup\usename{\ltxkeys@hdr default@ds}%
+ }{%
+ {\xp\ltxkeys@ttpref}{\xp\ltxkeys@tfam}%
+ {\xp\ltxkeys@tkey}{\xp\ltxkeys@tval}%
+ }%
+ }{%
+ \if@boolTF{ltxkeys@pxop}{%
+ \ifxTF\@currext\@clsextension{}\ltxkeys@unknownoptionerror
+ }{%
+ \if@boolTF{ltxkeys@st}{%
+ \cptexpandargonce{\aftercsname{\cptfiltermergekv[,]}
+ {\ltxkeys@hdr rmkeys}}\CurrentKeyval\nofilter
+ }{%
+ \ltxkeys@getinnoval
+ \cptexpandarg{\cptfiltermergecsv[;]\ltxkeys@undefinedkeys}{%
+ \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\InnocentVal
+ }\nofilter
+ }%
+ }%
+ }%
+ }%
+}
+\robust@def*\ltxkeys@setkeys@d{%
+ \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{}{%
+ \ltxkeys@kftrue
+ \if@boolTF{ltxkeys@pxop}{%
+ \ltxkeys@testoptionkey{not}%
+ }{%
+ \if@boolTF{ltxkeys@exop}{}{\ltxkeys@testoptionkey{}}%
+ }%
+ \if@boolTF{ltxkeys@sv}{%
+ \edef\ltxkeys@tempa{\ltxkeys@tkey{\expandcsonce\ltxkeys@tval}}%
+ \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tempa
+ }{}%
+ \if@boolTF{ltxkeys@noval}{%
+ \ifcsndefTF{\ltxkeys@hdr needvalue@keys}{\ltxkeys@testneedvalkey}{}%
+ \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey @default}{%
+ \cptsevenxp\ltxkeys@usedefault
+ \usename{\ltxkeys@hdr\ltxkeys@tkey @default}\ltxkeys@nil
+ }{%
+ \ltxkeys@err{No value specified for key '\ltxkeys@tkey'}\@ehc
+ }%
+ }{%
+ \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
+ \if@boolTF{ltxkeys@verbose}{%
+ \ltxkeys@getinnovalnopad
+ \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam,
+ \ltxkeys@tkey, \InnocentVal; on level '\the\ltxkeys@keydepth'.}%
+ }{}%
+ \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth
+ \csname\ltxkeys@hdr\ltxkeys@tkey\expandafter
+ \endcsname\expandafter{\ltxkeys@tval}\relax
+ \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth
+ }%
+ }%
+}
+\robust@def*\ltxkeys@usedefault#1#2\ltxkeys@nil{%
+ \begingroup
+ \csn@def{\ltxkeys@hdr\ltxkeys@tkey}##1{%
+ \toks@{\def\ltxkeys@tval{##1}}%
+ }%
+ \usename{\ltxkeys@hdr\ltxkeys@tkey @default}%
+ \expandafter\endgroup\the\toks@
+ \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
+ \if@boolTF{ltxkeys@verbose}{%
+ \ltxkeys@getinnovalnopad
+ \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam,
+ \ltxkeys@tkey, \InnocentVal\@space(default);
+ on level '\the\ltxkeys@keydepth'.}%
+ }{}%
+ \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth
+ \cptifmacroTF{#1}{%
+ \expandafter#1\expandafter{\ltxkeys@tval}\relax
+ }{%
+ \ltxkeys@err{Faulty key macro '\detokenize{#1}'}\@ehc
+ }%
+ \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth
+}
+
+\robust@def*\ltxkeys@getsavedval#1{%
+ \def\reserved@a##1#1##2##3\ltxkeys@nil{%
+ \ifblankTF{##3}\@firstoftwo{%
+ \def\reserved@a{##2}\@secondoftwo
+ }%
+ }%
+ \cptsevenxp\reserved@a\@nameuse
+ {\ltxkeys@hdr savevalue@keys}#1{\ltxkeys@nil}\ltxkeys@nil
+}
+\robust@def*\ltxkeys@replacepointers#1{%
+ \def\ltxkeys@resa{}%
+ \@tempswafalse
+ \ifbracedTF{#1}{%
+ \ltxkeys@r@placepointers{#1}\usevalue\ltxkeys@nil
+ }{%
+ \ltxkeys@r@placepointers#1\usevalue\ltxkeys@nil
+ }%
+ \let\ltxkeys@resa\relax
+}
+\robust@def*\ltxkeys@r@placepointers#1\usevalue#2{%
+ \def\reserved@a{#2}%
+ \ifxTF\reserved@a\ltxkeys@nnil{%
+ \edef\ltxkeys@tval{\unexpanded{#1}}%
+ \if@tempswa
+ \ifltxkeys@verbose
+ \ltxkeys@getinnovalnopad
+ \wlog{Value '\InnocentVal' of key '\ltxkeys@tkey'
+ inherited from key '\ltxkeys@tempb'.}%
+ \fi
+ \fi
+ }{%
+ \ltxkeys@getsavedval{#2}{%
+ \ltxkeys@err{No value recorded for key '#2'}\@ehc
+ \ltxkeys@r@placepointers
+ }{%
+ \@tempswatrue
+ \def\ltxkeys@tempb{#2}%
+ \oifinset@sp@TF,{#2}\ltxkeys@resa{%
+ \ltxkeys@err{Dangerous back linking of pointers}{%
+ Key pointer replacement terminated due
+ \MsgBrk to possible back linking.}%
+ \@gobble
+ }{%
+ \edef\ltxkeys@resa{\cptliststack,\ltxkeys@resa#2}%
+ \s@expandarg\ifbracedTF\reserved@a{%
+ \s@expandarg\ltxkeys@r@placepointers\reserved@a
+ }{%
+ \expandafter\ltxkeys@r@placepointers\reserved@a
+ }%
+ }%
+ }%
+ }%
+}
+\robust@def*\ltxkeys@storevalue{%
+ \ltxkeys@testpl{\ltxkeys@testopt@a\ltxkeys@st@revalue}%
+}
+\robust@def*\ltxkeys@st@revalue#1#2{%
+ \ifinsetFT{,}{#1}{}{%
+ \ltxkeys@err{Illegal multiple keys for \string\ltxkeys@storevalue}%
+ \@ehc
+ }%
+ \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
+ \ltxkeys@getsavedval{#1}{%
+ \ifltxkeys@pl
+ \expandafter\@firstofone
+ \else
+ \ltxkeys@err{%
+ No value recorded for key '#1' of
+ \MsgBrk family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref'
+ }{%
+ You have asked me to store the value of key '#1'
+ \MsgBrk (of family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref')
+ in the macro '\detokenize{#2}',
+ \MsgBrk but I can't find a value for key '#1'. Perhaps
+ \MsgBrk you haven't yet executed key '#1' or you didn't
+ \MsgBrk ask me to save its value.
+ }%
+ \fi
+ }{%
+ \let#2=\reserved@a
+ }%
+}
+\robust@def*\ltxkeys@getinnoval{\@tempswatrue\ltxkeys@g@tinnoval}
+\robust@def*\ltxkeys@getinnovalnopad{\@tempswafalse\ltxkeys@g@tinnoval}
+\robust@def*\ltxkeys@g@tinnoval{%
+ \ifxTF\ltxkeys@tval\@empty{%
+ \def\InnocentVal{???}%
+ }{%
+ \def\InnocentVal{}%
+ \def\ltxkeys@tempa{\\}%
+ \def\do##1##2##3##4##5##6##7##8##9\@@{%
+ \def\siso@do####1{%
+ \edef\InnocentVal{\InnocentVal\ifx\siso@arg\ltxkeys@tempa
+ \if@tempswa\@space\fi\else\if\siso@arg\cpt@leftbracechar[\else
+ \if\siso@arg\cpt@rightbracechar]\else####1\fi\fi\fi}%
+ }%
+ \siso@@loop{##1##2##3##4##5##6##7##8}%
+ }%
+ \expandafter\do\detokenize\expandafter
+ {\ltxkeys@tval}\\\\\\\\\\\\\\\\\\\@@
+
+ }%
+}
+\robust@def*\ltxkeys@keyvalerr{%
+ \ltxkeys@getinnovalnopad
+ \ltxkeys@err{Erroneous value '\InnocentVal' for key or option
+ \MsgBrk'\ltxkeys@tkey'}\@ehc
+}
+\robust@def*\ltxkeys@unknownkeyhandler{%
+ \cpt@testopt\ltxkeys@unkn@wnkeyhandler{KV}%
+}
+\robust@def*\ltxkeys@unkn@wnkeyhandler[#1]#2#3{%
+ \begingroup
+ \toks@{}%
+ \toks1{##1##2##3##4}%
+ \toks2{\ltxkeys@getinnovalnopad#3}%
+ \def\ltxkeys@do##1{%
+ \ltxkeys@makepf{##1}%
+ \def\ltxkeys@do####1{%
+ \ltxkeys@makehdr{####1}%
+ \toks@\expandafter{\the\expandafter\toks@\expandafter
+ \csn@def\expandafter{\ltxkeys@hdr default@ds}%
+ \the\toks1{\the\toks2}}%
+ }%
+ \ltxkeys@csvparse{#2}%
+ }%
+ \ltxkeys@csvparse{#1}%
+ \edef\reserved@a{\s@expandarg\@iden{\the\toks@}}%
+ \expandafter\endgroup\reserved@a
+}
+
+\robust@def*\ltxkeys@logunknownkeys{%
+ \ltxkeys@l@gunknownkeys
+ \ltxkeys@err{The above keys are undefined and %
+ couldn't be set}\@ehc
+}
+\robust@def*\ltxkeys@l@gunknownkeys{%
+ \gletcs\ltxkeys@l@gunknownkeys\relax
+ \begingroup
+ \cpt@cnta\z@pt
+ \edef\ltxkeys@skipa{}%
+ \cptwhilenum\cpt@cnta<20\do{%
+ \edef\ltxkeys@skipa{\expandcsonce\ltxkeys@skipa\@space}%
+ \advance\cpt@cnta\@ne
+ }%
+ \typeout{^^J\ltxkeys@skipa*** Unknown keys ***^^J}%
+ \def\ltxkeys@tempb{\\}%
+ \def\align@do##1##2##3##4##5##6##7##8##9\@@{%
+ \def\ltxkeys@tempc{##9}%
+ \def\siso@do####1{%
+ \ifx\siso@arg\ltxkeys@tempb
+ \edef\ltxkeys@skipb{\@space\ltxkeys@skipb}%
+ \fi
+ }%
+ \siso@@loop{##1##2##3##4##5##6##7##8}%
+ }%
+ \edef\ltxkeys@tempa{%
+ *Prefix,*Family,*Name,*Value;\expandcsonce\ltxkeys@undefinedkeys
+ }%
+ \def\ltxkeys@splita##1,##2,##3,##4\ltxkeys@nil{%
+ \def\ltxkeys@msg{}%
+ \def\ltxkeys@do####1{%
+ \let\ltxkeys@skipb\@empty
+ \align@do####1\\\\\\\\\\\\\\\\\\\@@
+ \expandafter\align@do\ltxkeys@tempc\\\\\\\\\\\\\\\\\\\@@
+ \edef\ltxkeys@msg{\expandcsonce\ltxkeys@msg####1\ltxkeys@skipb}%
+ }%
+ \ltxkeys@csvparse{##1,##2,##3,##4}%
+ \typeout{\ltxkeys@msg}%
+ }%
+ \def\csv@do##1{%
+ \ltxkeys@splita##1\ltxkeys@nil
+ }%
+ \csv@@loop*[;]\ltxkeys@tempa
+ \typeout{^^J\ltxkeys@skipa*******************^^J}%
+ \endgroup
+}
+\robust@def*\ltxkeys@disablekeys{\ltxkeys@testst\ltxkeys@dis@blekeys}
+\robust@def*\ltxkeys@dis@blekeys{%
+ \let\ifdisablest\ifltxkeys@st
+ \begingroup
+ \catcode`\,=12\relax
+ \cpt@testopt{\ltxkeys@dis@bl@keys}{KV}%
+}
+\robust@def*\ltxkeys@dis@bl@keys[#1]#2#3{%
+ \endgroup
+ \def\ltxkeys@prefs{#1}%
+ \def\ltxkeys@fams{#2}%
+ \def\ltxkeys@keys{#3}%
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys
+ \def\ltxkeys@do##1{%
+ \ltxkeys@makepf{##1}%
+ \def\ltxkeys@do####1{%
+ \def\ltxkeys@tfam{####1}%
+ \ltxkeys@makehdr{####1}%
+ \ltxkeys@dis@bl@k@ys
+ }%
+ \s@expandarg\ltxkeys@csvloop\ltxkeys@fams
+ }%
+ \s@expandarg\ltxkeys@csvloop\ltxkeys@prefs
+}
+\robust@def\ltxkeys@dis@bl@k@ys{%
+ \def\ltxkeys@do##1{%
+ \ifcsndefFT{\ltxkeys@hdr##1}{%
+ \ifltxkeys@verbose
+ \ltxkeys@warn{Key '##1' undefined in families '\ltxkeys@tfam':
+ \MsgBrk can't be disabled}%
+ \fi
+ }{%
+ \edef\ltxkeys@tempa{%
+ \noexpand\ltxkeys@err{%
+ Key '##1' of family '\ltxkeys@tfam' has been disabled
+ }{%
+ Key '##1' has been disabled.\MsgBrk
+ You can't set or reset it at this late stage.\MsgBrk
+ Perhaps you should have set it earlier in\MsgBrk
+ \noexpand\documentclass or \string\usepackage.
+ }%
+ }%
+ \cptpassexpanded{%
+ \ifdisablest\noexpand\AtBeginDocument{\fi
+ \ifcsndefTF{\ltxkeys@hdr##1@default}{%
+ \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]%
+ {\ltxkeys@tfam}{##1}[]{\expandcsonce\ltxkeys@tempa}%
+ }{%
+ \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]%
+ {\ltxkeys@tfam}{##1}{\expandcsonce\ltxkeys@tempa}%
+ }%
+ \ifdisablest}\fi
+ }%
+ }%
+ }%
+ \s@expandarg\ltxkeys@csvloop\ltxkeys@keys
+ \undefcs\ifdisablest
+}
+\robust@def*\ltxkeys@nostarform#1#2{%
+ \if\detokenize{#1*.}%
+ \ltxkeys@err{No star (*) form of command \string#2}\@ehc
+ \fi
+}
+\robust@def*\ltxkeys@declareoption{%
+ \let\ltxkeys@tempa\ltxkeys@ordkey
+ \let\@fileswith@pti@ns\@badrequireerror
+ \cpt@ifstar\ltxkeys@unknownoptionhandler\ltxkeys@d@cl@reoption
+}
+\robust@def\ltxkeys@unknownoptionhandler{%
+ \cpt@testopt\ltxkeys@unkn@wnoptionhandler{KV}%
+}
+\robust@def*\ltxkeys@unkn@wnoptionhandler[#1]{%
+ \cpt@testfam{\ltxkeys@unkn@wnopti@nhandler#1}%
+}
+\robust@def*\ltxkeys@unkn@wnopti@nhandler#1<#2>#3{%
+ \ltxkeys@unkn@wnkeyhandler[#1]{#2}{#3}%
+}
+\robust@def*\ltxkeys@declarecmdoption#1{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \ltxkeys@d@clareoption{#1}{cmd}%
+}
+\robust@def*\ltxkeys@declarebooloption#1{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \ltxkeys@d@clareoption{#1}{bool}%
+}
+\robust@def*\ltxkeys@declarechoiceoption#1{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \ltxkeys@d@clareoption{#1}{choice}%
+}
+\robust@def*\ltxkeys@d@clareoption#1#2{%
+ \aftercsname
+ {\ltxkeys@nostarform{#1}}{ltxkeys@declare#2option}%
+ \edef\ltxkeys@tempa{\noexpandcsn{ltxkeys@#2key}}%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \ltxkeys@d@cl@reoption#1%
+}
+\robust@def*\ltxkeys@d@cl@reoption{%
+ \cpt@testopt\ltxkeys@d@cl@r@option{KV}%
+}
+\robust@def*\ltxkeys@d@cl@r@option[#1]{%
+ \cpt@testfam{\ltxkeys@d@cl@r@opti@n#1}%
+}
+\robust@def*\ltxkeys@d@cl@r@opti@n#1<#2>{%
+ \ltxkeys@tempa[#1]{#2}%
+}
+\robust@def*\ltxkeys@executeoptions#1{%
+ \ltxkeys@nostarform{#1}\ltxkeys@executeoptions
+ \ltxkeys@exoptrue\ltxkeys@stfalse\ltxkeys@pltrue
+ \ltxkeys@rmfalse
+ \ltxkeys@testopt@@b\ltxkeys@setkeys@a#1%
+}
+\emptify\ltxkeys@processedoptions
+\robust@def*\ltxkeys@processoptions{%
+ \ltxkeys@pltrue\ltxkeys@rmfalse
+ \ltxkeys@testopt@@a\ltxkeys@pr@cessoptions
+}
+\robust@def*\ltxkeys@pr@cessoptions[#1]{%
+ \def\ltxkeys@poxlist{}%
+ \ltxkeys@pxoptrue
+ \let\@fileswith@pti@ns\@badrequireerror
+ \edef\ltxkeys@testname{\@currname.\@currext}%
+ \ifxTF\ltxkeys@testname\cpt@documentclass{%
+ \let\@unusedoptionlist\cpt@classoptionslist
+ }{%
+ \if@boolFT{ltxkeys@st}{}{%
+ \def\ltxkeys@do##1{%
+ \edef\CurrentKeyval{\unexpanded{##1}}%
+ \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey
+ \begingroup
+ \let\xp\expandcsonce
+ \edef\x{[\xp\ltxkeys@prefs]{\xp\ltxkeys@fams}{\xp\ltxkeys@tkey}}%
+ \expandafter\endgroup\expandafter\ltxkeys@ifkeydefFT\x{}{%
+ \ifcsnullTF\@unusedoptionlist{%
+ \cptgaddtolist\ltxkeys@processedoptions{##1}%
+ }{%
+ \cpt@removecurroption{##1}%
+ }%
+ \cptaddtolist\ltxkeys@poxlist{##1}%
+ }%
+ }%
+ \ifcsnullTF\cpt@classoptionslist{}%
+ {\ltxkeys@csvloop*\cpt@classoptionslist}%
+ }%
+ }%
+ \begingroup
+ \edef\ltxkeys@tempa{\cpt@optionlist{\@currname.\@currext}}%
+ \cptexpanded{\endgroup
+ \ifcsnullTF\ltxkeys@tempa{}{%
+ \cptaddtolist\noexpand\ltxkeys@poxlist{\expandcsonce\ltxkeys@tempa}%
+ }%
+ }%
+ \ifcsnullTF\ltxkeys@poxlist{}{%
+ \cptexpandargonce{\ltxkeys@setkeys@a[#1]}\ltxkeys@poxlist
+ }%
+ \gundefcs\ltxkeys@poxlist
+ \csn@def{\ltxkeys@hdr @rmkeys}{}%
+ \ltxkeys@pxopfalse
+ \let\@fileswith@pti@ns\@@fileswith@pti@ns
+ \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+}
+\robust@def*\ltxkeys@ifkeydefTF{\begingroup\ltxkeys@ifkeydef0}
+\robust@def*\ltxkeys@ifkeydefFT{\begingroup\ltxkeys@ifkeydef1}
+\robust@def*\ltxkeys@ifkeydef#1{\cpt@testopt{\ltxkeys@ifk@ydef#1}{KV}}
+\robust@def*\ltxkeys@ifk@ydef#1[#2]#3#4{%
+ \def\ltxkeys@prefs{#2}%
+ \def\ltxkeys@fams{#3}%
+ \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams
+ \ltxkeys@trimspaces{#4}\ltxkeys@tkey
+ \cpt@choicefdfalse
+ \def\ltxkeys@do##1{%
+ \if@boolTF{cpt@choicefd}{%
+ \ltxkeys@break
+ }{%
+ \ltxkeys@makepf{##1}%
+ \ltxkeys@ifk@yd@f
+ }%
+ }%
+ \ltxkeys@csvparse*\ltxkeys@prefs
+ \ltxkeys@oneoftwo#1\endgroup
+}
+\robust@def*\ltxkeys@ifk@yd@f{%
+ \def\ltxkeys@do##1{%
+ \ltxkeys@makehdr{##1}%
+ \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey}{%
+ \cpt@choicefdtrue\ltxkeys@break
+ }{}%
+ }%
+ \ltxkeys@csvloop*\ltxkeys@fams
+}
+\robust@def*\ltxkeys@emergencystop{%
+ \immediate\write\sixt@@n{OK, I'm exiting now.}%
+ \interactionmode\z@pt
+ \ifnumcmpTF\currentgrouptype>\z@pt{%
+ \endgroup\aftergroup\@@end
+ }{%
+ \aftergroup\@@end
+ }%
+}
+\robust@def*\ltxkeys@unknownoptionerror{%
+ \@tx@warn{Unknown option '\CurrentOption' for package '\@currname'}%
+ \typein[\answer]{%
+ ^^JUnknown option '\CurrentOption' for package '\@currname'.
+ ^^JThe option '\CurrentOption' was not declared in package
+ ^^J'\@currname'. Perhaps you misspelled its name.
+ ^^JEnter 'x' and <return> to stop or any character and
+ <return> to continue.
+ }%
+ \xifstrcmpTF\answer{x}\ltxkeys@emergencystop\relax
+}
+\cpt@cleanup\ltxkeys@processedoptions
+\cptonlypreamble{%
+ \ltxkeys@declareoption,\ltxkeys@declarecmdoption,
+ \ltxkeys@declarebooloption,\ltxkeys@declarechoiceoption,
+ \ltxkeys@processoptions,\ltxkeys@executeoptions,
+ \ltxkeys@unknownoptionhandler,\ltxkeys@unknownkeyhandler
+}
+\ltxkeys@declareoption*[KV]<ltxkeys>{%
+ \ltxkeys@warn{Unknown option '\CurrentKey' with
+ value '\InnocentVal' ignored.}%
+}
+\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{keyparser}[{;}]{%
+ \stripallouterbracesincs\ltxkeys@keyparser
+}
+\ltxkeys@declarebooloption[KV]<ltxkeys>[ltxkeys@]{verbose}[true]{}
+\ltxkeys@executeoptions[KV]<ltxkeys>{keyparser}\relax
+\ltxkeys@processoptions*[KV]<ltxkeys>\relax
+
+\endinput
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index de73c500fc5..44a50507592 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -218,7 +218,7 @@ my @TLP_working = qw(
lshort-polish lshort-portuguese lshort-russian lshort-slovak
lshort-slovenian lshort-spanish lshort-thai lshort-turkish lshort-ukr
lshort-vietnamese ltabptch
- ltxdockit ltxindex ltxmisc ltxnew
+ ltxdockit ltxindex ltxkeys ltxmisc ltxnew
lua-alt-getopt luacode
luainputenc lualatex-doc lualatex-math lualibs luamplib luaotfload
luasseq luatexbase luatextra
diff --git a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
index c067648fc7e..74c831db41a 100644
--- a/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
@@ -369,6 +369,7 @@ depend lsc
depend ltabptch
depend ltxdockit
depend ltxindex
+depend ltxkeys
depend ltxnew
depend magaz
depend mailing
diff --git a/Master/tlpkg/tlpsrc/ltxkeys.tlpsrc b/Master/tlpkg/tlpsrc/ltxkeys.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/ltxkeys.tlpsrc