Anexo I

Anexo I

Tengo una lista de key=valuecadenas separadas por comas. Quiero extraer el valor según la clave. Algo un poco como

\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

La intención es que esto dé como resultado la cadena baz.

¿Cómo puedo hacer esto?

Respuesta1

Podría definir un analizador clave-valor personalizado (suponiendo que el conjunto de claves debe ser variable):

\documentclass{article}

\makeatletter
\def\LookUpValue#1#2#3{%
  \@tempswafalse
  \gdef\LookUpValue@false{#3}%
  \xdef\@tempa{#1}%
  \LookUpValue@#2,\@end,}
\def\LookUpValue@#1,{%
  \ifx#1\@end
    \if@tempswa\@tempc\else\LookUpValue@false\fi
  \else
    \LookUpValue@@#1\@nil\expandafter\LookUpValue@\fi}
\def\LookUpValue@@#1=#2\@nil{%
  \edef\@tempb{#1}%
  \ifx\@tempa\@tempb\gdef\@tempc{#2}\@tempswatrue\fi
}
\makeatother

\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\textit{\LookUpValue{d}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}}

\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}

producción

Anexo I

Si echas un vistazo a la respuesta de @egreg, existe una característica muy interesante que te permite almacenar el resultado \LookUpValueen una macro sin imprimirlo. Aquí hay una manera de lograr esto en LaTeX2e (dada mi solución principal):

\documentclass{article}

\makeatletter
\def\LookUpValue{\kernel@ifnextchar[\@LookUpValue{\@LookUpValue[\@tempa]}}
\def\@LookUpValue[#1]#2#3{%
  \@tempswafalse
  \begingroup
    \escapechar\m@ne
    \xdef\luv@namespace{\string#1}%
  \endgroup
  \xdef\reserved@a{#2}%
  \expandafter\LookUpValue@#3,\@end,}
\def\LookUpValue@#1,{%
  \ifx#1\@end
    \if@tempswa\@nameuse{@tempa}\let\@tempa\relax
      \expandafter\expandafter\expandafter\@gobble\fi%
  \else
    \LookUpValue@@#1\@nil\expandafter\LookUpValue@\fi}
\def\LookUpValue@@#1=#2\@nil{%
  \edef\reserved@b{#1}%
  \ifx\reserved@a\reserved@b\@namedef{\luv@namespace}{#2}\@tempswatrue\fi
}
\makeatother

\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\def\mypreset{a=foo,b=bar,c=baz,d=zyyzx}
\LookUpValue[\myval]{d}{\mypreset}{}

\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\textsc{\myval}
\end{document}

Anexo II

Sin embargo, si el conjunto de claves cuyos valores intenta extraer está fijo en todo el documento, existe esta forma más sencilla:

\documentclass{article}
\usepackage{keyval}

\makeatletter
\newcommand\newspraffkey[1]{\define@key{spraffkeys}{#1}{\@namedef{value_of_#1}{##1}}}
\newcommand\LookUpValue[2]{%
  \begingroup
  \setkeys{spraffkeys}{#2}%
  \@nameuse{value_of_#1}%
  \expandafter\ifx\csname value_of_#1\endcsname\relax\else\expandafter\@gobbleaftergroup\fi
  \endgroup
}
\def\@gobbleaftergroup{\aftergroup\@gobble}
\makeatother

\newspraffkey{a}
\newspraffkey{b}
\newspraffkey{c}
\newspraffkey{d}

\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\LookUpValue{d}{a=foo,b=bar,c=baz}{error:notfound}

\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}

Respuesta2

Una versión que permite completar una propertylista usando expl3sintaxis y buscando el par clave-valor relevante. Quizás no sea la forma más rápida, pero sí bastante fácil de usar.

\documentclass{article}

\usepackage{xparse}


\ExplSyntaxOn
\cs_generate_variant:Nn \prop_put:Nnn {Nxn,Nxx}
\NewDocumentCommand{\LookUpValue}{mmm}{%
  \seq_set_from_clist:Nn \l_tmpa_seq {#2}
  \seq_map_inline:Nn \l_tmpa_seq {% Mapping through the sequence
    \seq_set_split:Nnn \l_tmpb_seq {=} {##1} 
    % Filling the property list
    \prop_put:Nxx \l_tmpa_prop {\seq_item:Nn \l_tmpb_seq {1}} {\seq_item:Nn \l_tmpb_seq {2}}
  }
  % Look if #1 is in the property list and display the value, otherwise #3
  \prop_if_in:NnTF \l_tmpa_prop {#1} {\prop_item:Nn \l_tmpa_prop {#1}} {#3}
}
\ExplSyntaxOff


\begin{document}

\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\LookUpValue{foobar}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

El siguiente código utiliza las funciones clave-valor en expl3; aquí exploto las “claves desconocidas”, se puede hacer algo mejor si las claves se conocen de antemano.

Si se proporciona un argumento opcional, debe ser una secuencia de control que se (re)definirá en el resultado.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\LookUpValue}{ommm}
 {
  \str_set:Nn \l_spraff_given_key_str { #2 }
  \tl_clear:N \l_spraff_output_tl
  \keys_set:nn { spraff/random } { #3 }
  \tl_if_empty:NT \l_spraff_output_tl
   {
    \tl_set:Nn \l_spraff_output_tl { #4 }
   }
  \IfNoValueTF{#1}
   { \tl_use:N \l_spraff_output_tl }
   { \tl_set_eq:NN #1 \l_spraff_output_tl }
 }

\keys_define:nn { spraff/random }
 {
  unknown .code:n =
   \str_if_eq:NNT \l_spraff_given_key_str \l_keys_key_tl
    {
     \tl_set:Nn \l_spraff_output_tl { #1 }
    }
 }
\ExplSyntaxOff

\begin{document}

\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\LookUpValue[\temp]{a}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}

\texttt{\meaning\temp}

\end{document}

ingrese la descripción de la imagen aquí

información relacionada