17

Is there a command/macro in latex to generate python-like dictionaries, i.e.

var = {a:1, b:2, c:3}

which then return for \var{b} 2?

1
  • If you use numeric keys you can use the TeX primitive \ifcase ... \or: \def\var#1{\ifcase 1 a\or b\or c} Mar 20, 2016 at 13:58

2 Answers 2

18

You can emulate it with a property list:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefineDictionary}{mm}
 {
  \arclupus_dict_def:nn { #1 } { #2 }
 }

\seq_new:N \l__arclupus_dict_temp_seq

\cs_new_protected:Nn \arclupus_dict_def:nn
 {
  \prop_gclear_new:c { g_arclupus_#1_dict_prop }
  \clist_map_inline:nn { #2 }
   {
    \__arclupus_dict_add:nn { #1 } { ##1 }
   }
  \cs_new:cpn { #1 } ##1 { \prop_item:cn { g_arclupus_#1_dict_prop } { ##1 } }
 }

\cs_new_protected:Nn \__arclupus_dict_add:nn
 {
  \seq_set_split:Nnn \l__arclupus_dict_temp_seq { / } { #2 }
  \prop_gput:cxx { g_arclupus_#1_dict_prop }
   {
    \seq_item:Nn \l__arclupus_dict_temp_seq { 1 }
   }
   {
    \seq_item:Nn \l__arclupus_dict_temp_seq { 2 }
   }
 }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }
\ExplSyntaxOff

\DefineDictionary{var}{a/1, b/2, c/3}

\begin{document}

\var{a}

\var{c}

\var{b}

\end{document}

The \DefineDictionary takes as argument the dictionary name and the data. A new property list is created (or an existing one is cleared); then each item in the second argument is split at / to become an item in the property list. Finally, a macro with the name of the dictionary is created to retrieve the data.

The version with the colon is slightly trickier, because we can't use a literal : for the split operation.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefineDictionary}{mm}
 {
  \arclupus_dict_def:nn { #1 } { #2 }
 }

\seq_new:N \l__arclupus_dict_temp_seq

\cs_new_protected:Nn \arclupus_dict_def:nn
 {
  \prop_gclear_new:c { g_arclupus_#1_dict_prop }
  \clist_map_inline:nn { #2 }
   {
    \__arclupus_dict_add:nn { #1 } { ##1 }
   }
  \cs_new:cpn { #1 } ##1 { \prop_item:cn { g_arclupus_#1_dict_prop } { ##1 } }
 }

\cs_new_protected:Nn \__arclupus_dict_add:nn
 {
  \seq_set_split:NVn \l__arclupus_dict_temp_seq \c_colon_str { #2 }
  \prop_gput:cxx { g_arclupus_#1_dict_prop }
   {
    \seq_item:Nn \l__arclupus_dict_temp_seq { 1 }
   }
   {
    \seq_item:Nn \l__arclupus_dict_temp_seq { 2 }
   }
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }
\ExplSyntaxOff

\DefineDictionary{var}{a:1, b:2, c:3}

\begin{document}

\var{a}

\var{c}

\var{b}

\end{document}

If you also need to pass macros to \var, then change the line

  \cs_new:cpn { #1 } ##1 { \prop_item:cn { g_arclupus_#1_dict_prop } { ##1 } }

into

  \cs_new:cpn { #1 } ##1 { \prop_item:cf { g_arclupus_#1_dict_prop } { ##1 } }

and add, just before \ExplSyntaxOff, the magic line

\cs_generate_variant:Nn \prop_item:Nn { cf }

that defines the required variant.

Macros that expand to strings are then welcome in the argument of the newly created macro (\var in the example). Note that \var is still fully expandable.

9
  • You could add the {a:1, b:2} version. With the recent (or not so recent) \char_generate:nn and a \seq_set_split:Nfn it's relatively simple.
    – Manuel
    Mar 20, 2016 at 0:12
  • @Manuel Done; no \char_generate:nn, though. ;-)
    – egreg
    Mar 20, 2016 at 0:17
  • I see it already exists :)
    – Manuel
    Mar 20, 2016 at 0:17
  • Going to test that, will report back, thanks!
    – arc_lupus
    Mar 20, 2016 at 0:18
  • 1
    Is it possible to get \var{\mysinglelettermacro} working? Right now it just prints nothing. (Assuming the \var from the above MWE).
    – PTNobel
    Mar 20, 2016 at 5:24
4

FWIW, ConTeXt has built-in data-structure that is equivalent to a dictionary. In particular,

\setvariables
    [var]
    [
      a=1,
      b=2,
      c=3,
    ]

Then you can access the variables using \getvariable{var}{a}, etc.

Using \def\abc{a} \getvariable{var}{\abc} also works.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .