# Global key-value dictionary

Is there any package that implements a data structure that provides a key-value mapping (akin to Python's dict)? The keys will be user input and may contain spaces and non-ASCII characters. I would like to have such a thing at global level so that I can add items inside macros.

If not, I appreciate any hints or code snippets.

I have peeked into the docs of keyval, but couldn't see how to use this for my purpose. Also, I am aware that etoolbox has list processing, perhaps this can be turned into a dictionary with some work?

-
Useful link: A big list of every keyval package –  Peter Grill Mar 22 '12 at 0:06
@PeterGrill: Thanks. This is for sure related, but will any of the packages be able to have arbitrary keys containing spaces and non-ASCII characters? –  krlmlr Mar 22 '12 at 0:15
Sorry, not an expert on keyval packages --just thought it would be useful to have that linked here. –  Peter Grill Mar 22 '12 at 0:16
The key-value system doesn't use a hash; it uses only a 'key' and the corresponding author or user-supplied 'value'. See blip.tv/pycon-us-videos-2009-2010-2011/… for the implementation of Python dict. All you need is to read the documentation of a key-value package. etoolbox's list processing scheme has nothing to do with key-value syntax or semantics, unless you define a \do macro that can process a key-value list. –  Ahmed Musa Mar 22 '12 at 1:08
–  Ahmed Musa Mar 25 '12 at 5:05

The 'classical' way to store values with a key is to use a csname-based approach

\def\addvalue#1#2{\expandafter\gdef\csname my@data@#1\endcsname{#2}}
\def\usevalue#1{\csname my@data@#1\endcsname}


To allow arbitrary material in the key, you can use e-TeX's \detokenize, and also add a test for undefined values if you wish

\def\addvalue#1#2{\expandafter\gdef\csname my@data@\detokenize{#1}\endcsname{#2}}
\def\usevalue#1{%
\ifcsname my@data@\detokenize{#1}\endcsname
\csname my@data@\detokenize{#1}\expandafter\endcsname
\else
\expandafter\ERROR
\fi
}


This approach needs one csname per key, which can get awkward for very large data sets. It also means you end up doing all of the work yourself every time you want to use such an approach. As has been pointed out, the etoolbox package offers some support for data storage. I would also point to the LaTeX3 prop data structure

\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_my_data_prop
\cs_new_protected:Npn \addvalue #1#2 { \prop_gput:Nnn \g_my_data_prop {#1} {#2} }
\cs_new:Npn \usevalue #1 { \prop_get:Nn \g_my_data_prop {#1} }
\ExplSyntaxOff


This approach offers a full range of support functions, for example tests for the presence of a key, counting the total number of keys, and so on.

-
Note that I'm focussing on data storage: the various keyval packages are used to parse user input in the key = value, ... format, which may or may not be relevant here. –  Joseph Wright Mar 22 '12 at 7:18
No, it's really the storage that matters, input is not really important. I should have a look at LaTeX3, these codes seem to compile on my system although I fail to understand why :-) –  krlmlr Mar 22 '12 at 8:48
@user946850 On why LaTeX3 stuff works with LaTeX2e, perhaps look at tex.stackexchange.com/questions/13541/…. The current LaTeX3 code is 'LaTeX3 in 2e': a way of developing new ideas while still being able to do something useful. The programming layer of LaTeX3 does not make any changes to existing documents, so can be loaded in this way safely. More user-level stuff is different (see for example xgalley). –  Joseph Wright Mar 22 '12 at 15:21

You can also use the pgfkeys library for a slightly different approach, using a key value system, which is designed as a tree structure.

First you define a family,

 \pgfkeys{/combo/.is family}


and then the keys,

 \pgfkeys{/combo
left/.store in=\left@c,
left/.default=0,
right/.store in=\right@c
...}


You can set default values:

\def\setdefaults{
\pgfkeys{/combo
left=100,
right=25,
top=30,
bottom=60,
}
}
\setdefaults


and you incorporate the keys in a newcommand:

\newcommand{\putgraphic}[5][\setdefaults]{%
\pgfkeys{/combo #1}
...
}


You can find a full implementation based on this method at Using an overpic grid to crop a resized image in Beamer and http://tex.stackexchange.com/a/45023/963. For global values see Is there a way to set a *global* key value using pgfkeys?.

-
I had the impression that all pgfkeys assignments were local: is that correct? –  Joseph Wright Mar 22 '12 at 8:28
@JosephWright You are correct although there are ways around this. (Did not notice that in the requirement). –  Yiannis Lazarides Mar 22 '12 at 8:33
@YiannisLazarides: What would be those ways around this? –  krlmlr Mar 22 '12 at 8:48
@user946850 tex.stackexchange.com/questions/15204/… –  Yiannis Lazarides Mar 22 '12 at 8:52