Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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?

share|improve this question
2  
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
1  
See also tex.stackexchange.com/questions/37094/…. –  Ahmed Musa Mar 25 '12 at 5:05

2 Answers 2

up vote 10 down vote accepted

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.

share|improve this answer
    
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`?.

share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.