%%%============================================================================== % WinEdt pragmas % !Mode:: "TeX:EN" % Default Compile engines: % !TEX program = pdflatex % !PDFTeXify ext = --enable-etex --restrict-write18 % !PDFLaTeX ext = --enable-etex --restrict-write18 % !BIB program = none %%%============================================================================== %% Copyright 2023 by Alceu Frigeri %% %% This work may be distributed and/or modified under the conditions of %% %% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt), %% version 1.3c (or later), and/or %% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html), %% version 3 (or later) %% %% This work has the LPPL maintenance status *maintained*. %% %% The Current Maintainer of this work is Alceu Frigeri %% %% This is version {1.4} {2025/05/28} %% %% The list of files that compose this work can be found in the README.md file at %% https://ctan.org/pkg/pgfkeysearch %% %%%============================================================================== \documentclass[10pt]{article} \RequirePackage[verbose,a4paper,marginparwidth=27.5mm,top=2.5cm,bottom=1.5cm,hmargin={40mm,20mm},marginparsep=2.5mm,columnsep=10mm,asymmetric]{geometry} \usepackage{codedescribe} \usepackage[root search]{pgfkeysearch} \RequirePackage[inline]{enumitem} \SetEnumitemKey{miditemsep}{parsep=0ex,itemsep=0.4ex} \RequirePackage{pgfkeys} \RequirePackage[hidelinks,hypertexnames=false]{hyperref} \begin{document} \tstitle{ author={Alceu Frigeri\footnote{\tsverb{https://github.com/alceu-frigeri/pgfkeysearch}}}, date={\tsdate}, title={The pgfkeysearch Package\break A Search Extension for pgfkeys\break Version \PkgInfo{pgfkeysearch}{version}} } \begin{typesetabstract} The command \tsobj{\pgfkeysvalueof}, unlike \tsobj{\pgfkeys} command, doesn't use the \tsobj[keys]{.unknown} handler, and it raises an error if the key isn't defined in the given path. It doesn't offers the option to search for a key in other paths. The following commands will recursively search for the key in a collection of paths. \end{typesetabstract} \tableofcontents \section{Package Options}\label{Pack-Options} The default search behaviour assumes that all keys defined by a package or document are under a uniquely defined path, meaning, no root keys. For instance, given the path /A/B/C/D, the following commands will look, first, at /A/B/C/D/\tsobj[marg]{key}, then /A/B/C/\tsobj[marg]{key}, and so on, until /A/\tsobj[marg]{key}, stopping at the first hit. This can be changed with the following package option: \begin{describelist*}{keys} \describe{root search}{If set, the \emph{path root} will also be included in the search, meaning it will look if /\tsobj[marg]{key}, as last resort, is defined.} \end{describelist*} \begin{tsremark} If set, the root key (/\tsobj[marg]{key}) will be look at for every path in the path list. For instance \tsobj[verb]{\pgfkeysearch{/A/B/C,/X/Y,/Z/T}{key}}, /\tsobj[marg]{key} will be tried up to three times. \end{tsremark} \begin{codedescribe}[code,new=2025/05/27]{\pgfkeysearchsettings} \begin{codesyntax}% \tsmacro{\pgfkeysearchsettings}{options} \end{codesyntax} To change the search behaviour, middle document, including or not the path root. \tsobj[marg]{options} are any valid package option (for now just \tsobj[key]{root search}). \end{codedescribe} \section{User Document Commands}\label{Doc-level} Those commands are meant to be used at Document level. For packages, one is advised to use the ones defined at \ref{expl-ones}. \begin{codedescribe}[code,update=2024/01/11]{\pgfkeysearchvalueof,\pgfkeysearch} \begin{codesyntax}% \tsmacro{\pgfkeysearchvalueof}{path-list,key,macro} \tsmacro{\pgfkeysearch}{path-list,key,macro} \end{codesyntax} \tsobj[marg]{path-list} is a comma separated list (clist) of paths (can be a single one). \tsobj[marg]{key} is the desired key, and \tsobj[marg]{macro} is the macro/command that will receive (store) the key value (if one is found). \tsobj[marg]{key} will be searched for in the many paths from \tsobj[marg]{path-list} as described in \ref{Pack-Options}. \tsobj[marg]{macro} will be set with the found (if any) value. \end{codedescribe} \begin{tsremark} \tsobj{\pgfkeysearch,\pgfkeysearchvalueof} are aliases to each other. \end{tsremark} \begin{tsremark} These commands aren't expandable, that's the reason to store the key value in a macro and not just place the found value in the input stream. \end{tsremark} \begin{tsremark} If \tsobj[marg]{key} isn't found, \tsobj[marg]{macro} will be empty, no warning or error will be raised. \end{tsremark} \begin{codedescribe}[code,update=2024/01/11]{\pgfkeysearchvalueofTF,\pgfkeysearchTF} \begin{codesyntax}% \tsmacro{\pgfkeysearchvalueofTF}{path-list,key,macro,if-found,if-not} \tsmacro{\pgfkeysearchTF}{path-list,key,macro,if-found,if-not} \end{codesyntax} \tsobj[marg]{path-list} is a comma separated list (clist) of paths (can be a single one). \tsobj[marg]{key} is the desired key and \tsobj[marg]{macro} is the macro/command that will receive (store) the key value (if one was found). These branch versions will also execute either \tsobj[marg,sep={or}]{if-found,if-not}. \end{codedescribe} \begin{tsremark} \tsobj{\pgfkeysearchvalueofTF,\pgfkeysearchTF} are aliases to each other. \end{tsremark} \begin{tsremark} These commands aren't expandable, that's the reason to store the key value in a macro and not just place the found value in the input stream. \end{tsremark} \begin{tsremark} If \tsobj[marg]{key} isn't found, \tsobj[marg]{macro} will be empty, no warning or error will be raised. \end{tsremark} \begin{codestore}[keyval.demo] \pgfkeys{% /tikz/A/.cd, keyA/.initial={keyA at /tikz/A}, keyB/.initial={keyB at /tikz/A}, % B/.cd, keyA/.initial={keyA at /tikz/A/B}, keyC/.initial={keyC at /tikz/A/B}, % C/.cd, keyX/.initial={keyX at /tikz/A/B/C} } \end{codestore} \begin{codestore}[keyval.demo] \pgfkeysearch{/tikz/A/B/C}{keyA}{\VALkeyA} \pgfkeysearch{/tikz/A/B/C}{keyB}{\VALkeyB} \pgfkeysearch{/tikz/A/B/C}{keyC}{\VALkeyC} \pgfkeysearch{/tikz/A/B/C}{keyX}{\VALkeyX} \end{codestore} \begin{codestore}[keyval.demo] I got for keyA: \textbf{\VALkeyA} \par I got for keyB: \textbf{\VALkeyB} \par I got for keyC: \textbf{\VALkeyC} \par I got for keyX: \textbf{\VALkeyX} \par \end{codestore} \setnewcodekey{keydemo}{codeprefix={},resultprefix={},texcs2={pgfkeysearchvalueof,pgfkeysearch},keywd3={keyA,keyB,keyC,keyX},emph2={VALkeyA,VALkeyB,VALkeyC,VALkeyX}} \subsection{Example} Given the following pgfkeys: \tscode*[keydemo]{keyval.demo}[1] \tsexec{keyval.demo}[1] Key values can be retrieved as: \tscode*[keydemo]{keyval.demo}[2] \tsexec{keyval.demo}[2] and finally used as: \tsdemo[keydemo]{keyval.demo}[3] \section{Expl3 Commands}\label{expl-ones} \begin{codedescribe}[code,new=2025/05/27]{\pgfkeysearch_settings:n} \begin{codesyntax}% \tsmacro{\pgfkeysearch_settings:n}{options} \end{codesyntax} To change the search behaviour, middle document, including or not the path root. \tsobj[marg]{options} are any valid package option (for now just \tsobj[key]{root search}, see \ref{Pack-Options}, notice the space\ldots). \end{codedescribe} \begin{codedescribe}[code,update=2025/05/26]{\pgfkeysearch_keysearch:nnNTF} \begin{codesyntax}% \tsmacro{\pgfkeysearch_keysearch:nnNTF}{single-path,key,tl-var,if-found,if-not} \end{codesyntax} \tsobj[marg]{key} is the desired key, and \tsobj[marg]{tl-var} is a token list variable that will receive the key value, if one is found. \tsobj[marg]{key} will be searched for in \tsobj[marg]{single-path} as described in \ref{Pack-Options}. \tsobj{\pgfkeysearch_keysearch:nnNTF} is slightly faster than the more generic multi-path version. \end{codedescribe} \begin{tsremark} If \tsobj[marg]{key} isn't found, no assignment will be made (to \tsobj[marg]{tl-var}), unlike the user's document one (defined at \ref{Doc-level}). No warning or error will be raised. \end{tsremark} \begin{tsremark} The old signature \tsobj{\pgfkeysearch_keysearch:nnnTF} is deprecated, and will raise a warning if used. \end{tsremark} \begin{codedescribe}[code,update=2025/05/26]{\pgfkeysearch_multipath_keysearch:nnNTF} \begin{codesyntax}% \tsmacro{\pgfkeysearch_multipath_keysearch:nnNTF}{path-list,key,tl-var,if-found,if-not} \end{codesyntax} Given a comma separated \tsobj[marg]{path-list}, this will call \tsobj{\pgfkeysearch_keysearch:nnNTF} for each path in \tsobj[marg]{path-list}, until \tsobj[marg]{key} is found. \end{codedescribe} \begin{tsremark} If \tsobj[marg]{key} isn't found, no assignment will be made (to \tsobj[marg]{tl-var}), unlike the user's document one (defined at \ref{Doc-level}). No warning or error will be raised. \end{tsremark} \begin{tsremark} \tsobj[code]{\pgfkeysearchvalueof,\pgfkeysearch,\pgfkeysearchvalueofTF,\pgfkeysearchTF} are just wrappers to \tsobj{\pgfkeysearch_multipath_keysearch:nnNTF}. \end{tsremark} \begin{tsremark} The old signature \tsobj{\pgfkeysearch_multipath_keysearch:nnnTF} is deprecated, and will raise a warning if used. \end{tsremark} \end{document}