From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 .../doc/text-en/pgfmanual-en-pgfkeysfiltered.tex   | 576 +++++++++++++++++++++
 1 file changed, 576 insertions(+)
 create mode 100644 graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex

(limited to 'graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex')

diff --git a/graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex b/graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex
new file mode 100644
index 0000000000..d93c8b8c0e
--- /dev/null
+++ b/graphics/pgf/base/doc/text-en/pgfmanual-en-pgfkeysfiltered.tex
@@ -0,0 +1,576 @@
+
+\subsection{Key Filtering}
+\begingroup
+
+{\small \emph{An extension by Christian Feuersänger}}
+\vspace{0.4cm}%
+
+\noindent Normally, a call to |\pgfkeys| sets all keys provided in its argument
+list. This is usually what users expect it to do. However, implementations of
+different packages or \pgfname-libraries may need more control over the key
+setting procedure: library~A may want to set its options directly and
+communicate all remaining ones to library~B.
+
+This section describes key filtering methods of \pgfname, including options for
+family groupings. If you merely want to use \pgfname\ (or its libraries), you
+can skip this section. It is addressed to package (or library) authors.
+
+
+\subsubsection{Starting With An Example}
+\label{section-key-filter-example}
+
+Users of |xkeyval| are familiar with the concept of key families: keys belong
+to groups and those keys can be `filtered' out of other options. \pgfname\
+supports family groupings and more abstract key selection mechanism with
+|\pgfkeysfiltered|, a variant of |\pgfkeys|. Suppose we have the example key
+grouping
+
+\pgfkeys{
+    /my group/A1/.code=(A1:#1),
+    /my group/A2/.code=(A2:#1),
+    /my group/A3/.code=(A3:#1),
+    /my group/B/.code=(B:#1),
+    /my group/C/.code=(B:#1),
+    /my group/A/.is family,
+    /my group/A1/.belongs to family=/my group/A,
+    /my group/A2/.belongs to family=/my group/A,
+    /my group/A3/.belongs to family=/my group/A,
+    /pgf/key filters/active families/.install key filter,
+    /my group/A/.activate family,
+}%
+\begin{codeexample}[code only]
+\pgfkeys{
+    /my group/A1/.code=(A1:#1),
+    /my group/A2/.code=(A2:#1),
+    /my group/A3/.code=(A3:#1),
+    /my group/B/.code=(B:#1),
+    /my group/C/.code=(B:#1),
+}
+\end{codeexample}
+
+\noindent and we want to set options |A1|, |A2| and |A3| only. A call to
+|\pgfkeys| yields
+%
+\begin{codeexample}[]
+\pgfkeys{/my group/A1=a1, /my group/A2=a2, /my group/B=b,  /my group/C=c}
+\end{codeexample}
+%
+\noindent because all those command option are processed consecutively.
+
+Now, let's define a family named |A| which contains |A1|, |A2| and |A3| and set
+only family members of |A|. We prepare our key settings with
+%
+\begin{codeexample}[code only]
+\pgfkeys{
+    /my group/A/.is family,
+    /my group/A1/.belongs to family=/my group/A,
+    /my group/A2/.belongs to family=/my group/A,
+    /my group/A3/.belongs to family=/my group/A,
+}
+\end{codeexample}
+%
+\noindent and
+%
+\begin{codeexample}[code only]
+\pgfkeys{/pgf/key filters/active families/.install key filter}
+\end{codeexample}
+%
+\noindent After this preparation, we can use |\pgfkeysfiltered| with
+%
+\begin{codeexample}[]
+\pgfkeys{/my group/A/.activate family}
+\pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2,
+ /my group/B=b,  /my group/C=c}
+\end{codeexample}
+%
+\noindent or
+%
+\begin{codeexample}[]
+\pgfkeys{/my group/A/.activate family}
+\pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2,
+ /my group/B=b,  /my group/C=c, /tikz/color=blue, /my group/A3=a3}
+\end{codeexample}
+%
+\noindent to set only keys which belong to an `active' family -- in our case,
+only family~|A| was active, so the remaining options have not been processed.
+The family processing is quite fast and allows an arbitrary number of active
+key families.
+
+Unprocessed options can be collected into a macro (similar to |xkeyval|'s
+|\xkv@rm|), discarded or handled manually. The details of key selection and
+family declaration are described in the following sections.
+
+
+\subsubsection{Setting Filters}
+
+The command |\pgfkeysfiltered| is the main tool to process only selected
+options. It works as follows.
+%
+\begin{command}{\pgfkeysfiltered\marg{key--value-list}}
+    Processes all options in exactly the same way as
+    |\pgfkeys|\marg{key--value-list}, but a key filter is considered as soon as
+    key identification is complete.
+
+    The key filter tells |\pgfkeysfiltered| whether it should continue to apply
+    the current option (return value is `true') or whether something different
+    shall be done (filter returns `false').
+
+    There is exactly one key filter in effect, and it is installed by the
+    |.install key filter| handler or by |\pgfkeysinstallkeyfilter|.
+
+    If the key filter returns `false', a unique key filter handler gets
+    control. This handler is installed by the |.install key filter handler|
+    method and has access to the key's full name, value and (possibly) path.
+
+    Key filtering applies to any (possibly nested) call to |\pgfkeys|,
+    |\pgfkeysalso|, |\pgfqkeys| and |\pgfqkeysalso| during the evaluation of
+    \marg{key--value-list}. It does \emph{not} apply to routines like
+    |\pgfkeyssetvalue| or |\pgfkeysgetvalue|. Furthermore, keys belonging to
+    |/errors| are always processed. Key filtering routines can't be nested: you
+    can't combine different key filters automatically.
+\end{command}
+
+\begin{command}{\pgfqkeysfiltered\marg{default-path}\marg{key--value-list}}
+    A variant of |\pgfkeysfiltered| which uses the `quick' search path setting.
+    It is the |\pgfqkeys| variant of |\pgfkeysfiltered|, see the documentation
+    for |\pgfqkeys| for more details.
+\end{command}
+
+\begin{command}{\pgfkeysalsofrom\marg{macro}}
+    A variant of |\pgfkeysalso| which loads its key list from \marg{macro}.
+
+    It is useful in conjunction with the
+    |/pgf/key filter handlers/append filtered to=|\meta{macro} handler.
+
+    The following example uses the same settings as in the intro
+    section~\ref{section-key-filter-example}.
+    %
+\begin{codeexample}[]
+\pgfkeys{/pgf/key filter handlers/append filtered to/.install key filter handler=\remainingoptions}
+\def\remainingoptions{}
+\pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2,
+ /my group/B=b,  /my group/C=c, /tikz/color=blue, /my group/A3=a3}
+
+Remaining: `\remainingoptions'.
+\pgfkeysalsofrom{\remainingoptions}
+\end{codeexample}
+    %
+\end{command}
+
+\begin{command}{\pgfkeysalsofiltered\marg{key--value-list}}
+    This command works as |\pgfkeysfiltered|, but it does not change the
+    current default path. See the documentation of |\pgfkeysalso| for more
+    details.
+\end{command}
+
+\begin{command}{\pgfkeysalsofilteredfrom\marg{macro}}
+    A variant of |\pgfkeysalsofiltered| which loads its key list from
+    \marg{macro}.
+\end{command}
+
+\begin{handler}{{.install key filter}|=|\meta{optional arguments}}
+    This handler installs a key filter. A key filter is a command key which
+    sets the \TeX-boolean |\ifpgfkeysfiltercontinue|, that means a key with
+    existing `|/.@cmd|' suffix. A simple example is a key filter which returns
+    always true:
+    %
+\begin{codeexample}[code only]
+\pgfkeys{/foo/bar/true key filter/.code={\pgfkeysfiltercontinuetrue}}
+\pgfkeys{/foo/bar/true key filter/.install key filter}
+\end{codeexample}
+    %
+    If key filters require arguments, they are installed by
+    |.install key filter| as well. An example is the |/pgf/key filters/equals|
+    handler:
+    %
+\begin{codeexample}[]
+\pgfkeys{/pgf/key filters/equals/.install key filter={/my group/A1}}
+\pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2,
+/my group/B=b,  /my group/C=c, /tikz/color=blue, /my group/A3=a3}
+\end{codeexample}
+    %
+    If a key filter requires more than one argument, you need to provide the
+    complete argument list in braces like |{{first}{second}}|.
+
+    You can also use |\pgfkeysinstallkeyfilter|\meta{full key}\meta{optional
+    arguments}, it has the same effect.
+
+    See section~\ref{section-key-writing-filters} for how to write key filters.
+\end{handler}
+
+\begin{handler}{{.install key filter handler}|=|\meta{optional arguments}}
+    This handler installs the routine which will be invoked for every
+    \emph{unprocessed} option, that means any option for which the key filter
+    returned `false'.
+
+    The |.install key filter handler| is used in the same way as
+    |.install key filter|. There exists a macro version,
+    |\pgfkeysinstallkeyfilterhandler|\meta{full key}\meta{optional arguments},
+    which has the same effect.
+
+    See section~\ref{section-key-writing-filters} for how to write key filter
+    handlers.
+\end{handler}
+
+
+\subsubsection{Handlers For Unprocessed Keys}
+
+Each option for which key filters decided to skip them is handed over to a `key
+filter handler'. There are several predefined key filter handlers.
+
+\begin{key}{/pgf/key filter handlers/append filtered to=\marg{macro}}
+    Install this filter handler to append any unprocessed options to macro
+    \marg{macro}.
+    %
+\begin{codeexample}[]
+\pgfkeys{/pgf/key filter handlers/append filtered to/.install key filter handler=\remainingoptions}
+\def\remainingoptions{}
+\pgfkeysfiltered{/my group/A1=a1, /my group/A2=a2,
+ /my group/B=b,  /my group/C=c, /tikz/color=blue}
+
+Remaining options: `\remainingoptions'.
+\end{codeexample}
+    %
+    This example uses the same keys as defined in the intro
+    section~\ref{section-key-filter-example}.
+\end{key}
+
+\begin{key}{/pgf/key filter handlers/ignore}
+    Install this filter handler if you simply want to ignore any unprocessed
+    option. This is the default.
+\end{key}
+
+\begin{key}{/pgf/key filter handlers/log}
+    This key filter handler writes messages for any unprocessed option to your
+    logfile (and terminal).
+\end{key}
+
+
+\subsubsection{Family Support}
+
+\pgfname{} supports a family concept: every option can be associated with (at
+most) one family. Families form loose key groups which are independent of the
+key hierarchy. For example, |/my tree/key1| can belong to family |/tikz|.
+
+It is possible to `activate' or `deactivate' single families. Furthermore, it
+is possible to set only keys which belong to active families using appropriate
+key filter handlers.
+
+The family support is fast: if there are $N$ options in a key--value-list and
+there are $K$ active families, the runtime for |\pgfkeysfiltered| is $O(N+K)$
+(activate every family $O(K)$, check every option $O(N)$, deactivate every
+family $O(K)$).
+
+\begin{handler}{{.is family}}
+    Defines a new family. This option has already been described in
+    section~\ref{section-is family-handler} on page~\pageref{section-is
+    family-handler}.
+\end{handler}
+
+\begin{handler}{{.activate family}}
+    Activates a family. The family needs to be defined, otherwise
+    |/errors/family unknown| will be raised.
+
+    Activation means a \TeX-boolean will be set to |true|, indicating that a
+    family should be processed.
+
+    You can also use |\pgfkeysactivatefamily|\meta{full path} to get the same
+    effect. Furthermore, you can use |\pgfkeysactivatefamilies|\meta{list of
+    families}\meta{macro name for de-activation} to activate a list of families
+    (see section~\ref{section-key-filter-api}).
+\end{handler}
+
+\begin{handler}{{.deactivate family}}
+    Deactivates a family. The family needs to be defined, otherwise
+    |/errors/family unknown| will be raised.
+
+    You can also use |\pgfkeysdeactivatefamily|\meta{full path} to get the same
+    effect.
+\end{handler}
+
+\begin{handler}{{.belongs to family}|=|\marg{family name}}
+    Associates the current option with \marg{family name}, which is expected to
+    be a full path of a family.
+    %
+\begin{codeexample}[code only]
+\pgfkeys{/foo/bar/.is family}
+\pgfkeys{
+    /foo/a/.belongs to family=/foo/bar,
+    /foo/b/.belongs to family=/foo/bar
+}
+\end{codeexample}
+    %
+    Each option can have up to one family, |.belongs to family| overwrites any
+    old setting.
+\end{handler}
+
+\begin{key}{/pgf/key filters/active families}
+    Install this key filter if |\pgfkeysfiltered| should only process activated
+    families. If a key does not belong to any family, it is not processed. If a
+    key is completely unknown within the default path, the normal `unknown'
+    handlers of |\pgfkeys| are invoked.
+\end{key}
+
+\begin{key}{/pgf/key filters/active families or no family=\marg{key filter 1}\marg{key filter 2}}
+    This key filter configures |\pgfkeysfiltered| to work as follows.
+    %
+    \begin{enumerate}
+        \item If the current key belongs to a family, set
+            |\ifpgfkeysfiltercontinue| to true if and only if its family is
+            active.
+        \item If the current key does \emph{not} belong to a family, assign
+            |\ifpgfkeysfiltercontinue| as result of \marg{key filter 1}.
+        \item If the current key is unknown within the default path, assign
+            |\ifpgfkeysfiltercontinue| as result of \marg{key filter 2}.
+    \end{enumerate}
+    %
+    The arguments \marg{key filter 1} and \marg{key filter 2} are other key
+    filters (possibly with options) and allow fine-grained control over the
+    filtering process.
+    %
+\begin{codeexample}[code only]
+    \pgfkeysinstallkeyfilter
+        {/pgf/key filters/active families or no family}
+        {{/pgf/key filters/is descendant of=/tikz}% for keys without family
+         {/pgf/key filters/false}% for unknown keys
+        }%
+\end{codeexample}
+    %
+    This key filter will return true for any option with active family. If an
+    option has no family, the return value is true if and only if it belongs to
+    |/tikz|. If the option is unknown, the return value is |false| and unknown
+    handlers won't be called.
+\end{key}
+
+\begin{key}{/pgf/key filters/active families or no family DEBUG=\marg{key filter 1}\marg{key filter 2}}
+    A variant of |active families or no family| which protocols each action on
+    your terminal (log-file).
+\end{key}
+
+\begin{key}{/pgf/key filters/active families and known}
+    A fast alias for
+
+    |/pgf/key filters/active families or no family=|\par
+    \noindent\hskip10pt|{/pgf/keys filters/false}|\par
+    \noindent\hskip10pt|{/pgf/keys filters/false}|.
+\end{key}
+%
+\begin{key}{/pgf/key filters/active families or descendants of=\marg{path prefix}}
+    A fast alias for
+
+    |/pgf/key filters/active families or no family=|\par
+    \noindent\hskip10pt|{/pgf/keys filters/is descendant of=|\marg{path prefix}|}|\par
+    \noindent\hskip10pt|{/pgf/keys filters/false}|.
+\end{key}
+
+\begin{command}{\pgfkeysactivatefamiliesandfilteroptions\marg{family list}\marg{key--value-list}}
+    A simple shortcut macro which activates any family in the comma separated
+    \marg{family list}, invokes |\pgfkeysfiltered|\meta{key--value-list} and
+    deactivates the families afterwards.
+
+    Please note that you will need to install a family key filter, otherwise
+    family activation has no effect.
+\end{command}
+%
+\begin{command}{\pgfqkeysactivatefamiliesandfilteroptions\marg{family list}\marg{default path}\marg{key--value-list}}
+    The `quick' default path variant of |\pgfkeysactivatefamiliesandfilteroptions|.
+\end{command}
+
+\begin{command}{\pgfkeysactivatesinglefamilyandfilteroptions\marg{family name}\marg{key--value-list}}
+    A shortcut macro which activates a single family and invokes |\pgfkeysfiltered|.
+
+    Please note that you will need to install a family key filter, otherwise
+    family activation has no effect.
+\end{command}
+%
+\begin{command}{\pgfqkeysactivatesinglefamilyandfilteroptions\marg{family name}\marg{default path}\marg{key--value-list}}%
+    The `quick' default path variant of |\pgfkeysactivatesinglefamilyandfilteroptions|.
+\end{command}
+
+
+\subsubsection{Other Key Filters}
+
+There are some more key filters which have nothing to do with family handling.
+%
+\begin{key}{/pgf/key filters/is descendant of=\marg{path}}
+    Install this key filter to process only options belonging to the key tree
+    \meta{path}. It returns true for every key whose key path is equal to
+    \meta{path}. It also returns true for any unknown key, that means unknown
+    keys are processed using the standard unknown handlers of \pgfname.
+    %
+\begin{codeexample}[]
+\pgfkeys{
+/group 1/A/.code={(A:#1)},
+/group 1/foo/bar/B/.code={(B:#1)},
+/group 2/C/.code={(C:#1)},
+/pgf/key filters/is descendant of/.install key filter=/group 1}
+\pgfkeysfiltered{/group 1/A=a,/group 1/foo/bar/B=b,/group 2/C=c}
+\end{codeexample}
+    %
+\end{key}
+
+\begin{key}{/pgf/key filters/equals=\marg{full key}}
+    Install this key filter to process only the fully qualified option
+    \marg{full key}. The filter returns true for any unknown key or if the key
+    equals \marg{full key}.
+    %
+\begin{codeexample}[]
+\pgfkeys{
+/group 1/A/.code={(A:#1)},
+/group 1/B/.code={(B:#1)},
+/pgf/key filters/equals/.install key filter=/group 1/A}
+\pgfqkeysfiltered{/group 1}{A=a,B=b}
+\end{codeexample}
+    %
+\end{key}
+
+\begin{key}{/pgf/key filters/not=\marg{key filter}}
+    This key filter logically inverts the result of \marg{key filter}.
+    %
+\begin{codeexample}[]
+\pgfkeys{
+/group 1/A/.code={(A:#1)},
+/group 1/foo/bar/B/.code={(B:#1)},
+/group 2/C/.code={(C:#1)},
+/pgf/key filters/not/.install key filter=
+    {/pgf/key filters/is descendant of=/group 1}}
+\pgfkeysfiltered{/group 1/A=a,/group 1/foo/bar/B=b,/group 2/C=c}
+\end{codeexample}
+    %
+    Please note that unknown keys will be handed to the usual unknown handlers.
+\end{key}
+
+\begin{key}{/pgf/key filters/and=\marg{key filter 1}\marg{key filter 2}}
+    This key filter returns true if and only if both, \marg{key filter 1} and
+    \marg{key filter 2} return true.
+\end{key}
+
+\begin{key}{/pgf/key filters/or=\marg{key filter 1}\marg{key filter 2}}
+    This key filter returns true if one of \marg{key filter 1} and \marg{key
+    filter 2} returns true.
+\end{key}
+
+\begin{key}{/pgf/key filters/true}
+    This key filter returns always true.
+\end{key}
+
+\begin{key}{/pgf/key filters/false}
+    This key filter returns always false (including unknown keys).
+\end{key}
+
+\begin{key}{/pgf/key filters/defined}
+    This key filter returns false if the current key is unknown, which avoids
+    calling the unknown handlers.
+\end{key}
+
+
+\subsubsection{Programmer Interface}
+\label{section-key-filter-api}
+
+\begin{plainenvironment}{{pgfkeysinterruptkeyfilter}}
+    Temporarily disables key filtering inside the environment. If key filtering
+    is not active, this has no effect at all.
+
+    Please note that no \TeX-group is introduced.
+\end{plainenvironment}
+
+\begin{command}{\pgfkeyssavekeyfilterstateto\marg{macro}}
+    Creates \marg{macro} which contains commands to re-activate the current key
+    filter and key filter handler. It can be used to temporarily switch the key
+    filter.
+\end{command}
+
+\begin{command}{\pgfkeysinstallkeyfilter\marg{full key}\marg{optional arguments}}
+    The command
+    |\pgfkeysinstallkeyfilter{|\meta{full key}|}{|\meta{optional arguments}|}|
+    has the same effect as
+    |\pgfkeys{|\meta{full key}|/.install key filter={|\meta{optional arguments}|}}|.
+\end{command}
+
+\begin{command}{\pgfkeysinstallkeyfilterhandler\marg{full key}\marg{optional arguments}}
+    The command
+    |\pgfkeysinstallkeyfilterhandler{|\meta{full key}|}{|\meta{optional arguments}|}|
+    has the same effect as
+    |\pgfkeys{|\meta{full key}|/.install key filter handler={|\meta{optional arguments}|}}|.
+\end{command}
+
+\begin{command}{\pgfkeysactivatefamily\marg{family name}}
+    Equivalent to |\pgfkeys{|\meta{family name}|/.activate family}|.
+\end{command}
+
+\begin{command}{\pgfkeysdeactivatefamily\marg{family name}}
+    Equivalent to |\pgfkeys{|\meta{family name}|/.deactivate family}|.
+\end{command}
+
+\begin{command}{\pgfkeysactivatefamilies\marg{family list}\marg{deactivate macro name}}
+    Activates each family in \meta{family list} and creates a macro
+    \meta{deactivate macro name} which deactivates each family in \meta{family
+    list}.
+    %
+\begin{codeexample}[code only]
+\pgfkeysactivatefamilies{/family 1,/family 2,/family 3}{\deactivatename}
+\pgfkeysfiltered{foo,bar}
+\deactivatename
+\end{codeexample}
+    %
+\end{command}
+
+\begin{command}{\pgfkeysiffamilydefined\marg{family}\marg{true case}\marg{false case}}%
+    Checks whether the full key \meta{family} is a family and executes either
+    \meta{true case} or \meta{false case}.
+\end{command}
+
+\begin{command}{\pgfkeysisfamilyactive\marg{family}}
+    Sets the \TeX-boolean |\ifpgfkeysfiltercontinue| to whether \meta{family}
+    is active or not.
+\end{command}
+
+\begin{command}{\pgfkeysgetfamily\marg{key}\marg{resultmacro}}
+    Returns the family associated to a full key \meta{key} into macro
+    \meta{resultmacro}.
+\end{command}
+
+\begin{command}{\pgfkeyssetfamily\marg{key}\marg{family}}
+    The command |\pgfkeyssetfamily|\marg{full key}\marg{family} has the same
+    effect as |\pgfkeys{|\meta{full key}|/.belongs to family=|\marg{family}|}|.
+\end{command}
+
+
+\subsubsection{Defining Own Filters Or Filter Handlers}
+\label{section-key-writing-filters}
+
+During |\pgfkeysfiltered|, the key filter code will be invoked. At this time,
+the full key path including key name is available as |\pgfkeyscurrentkey|, the
+key name before default paths have been considered as |\pgfkeyscurrentkeyRAW|
+and the values as |\pgfkeyscurrentvalue|.
+
+Furthermore, the macro |\pgfkeyscasenumber| contains the current key's type as
+an integer:
+%
+\begin{itemize}
+    \item[\meta{1}] The key is a command key (i.e. |.../.@cmd| exists).
+    \item[\meta{2}] The key contains its value directly.
+    \item[\meta{3}] The key is handled (for example it is |.code| or |.cd|).
+
+        In this case, the macros |\pgfkeyscurrentname| and
+        |\pgfkeyscurrentpath| are set to the handlers name and path,
+        respectively. Invoke |\pgfkeyssplitpath{}| to extract these values for
+        non-handled keys.
+    \item[\meta{0}] The key is unknown.
+\end{itemize}
+%
+Any key filter or key filter handler can access these variables. Key filters
+are expected to set the \TeX-boolean |\ifpgfkeysfiltercontinue| to whether the
+current key shall be processed or not.
+
+\begin{command}{\pgfkeysevalkeyfilterwith\marg{full key}=\marg{filter arguments}}
+    Evaluates a fully qualified key filter \meta{full key} with argument(s)
+    \meta{filter arguments}.
+    %
+\begin{codeexample}[code only]
+\pgfkeysevalkeyfilterwith{/pgf/key filters/equals=/tikz}
+\end{codeexample}
+    %
+\end{command}
+
+\endgroup
-- 
cgit v1.2.3

