17

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?

5
  • 3
    Useful link: A big list of every keyval package Mar 22, 2012 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, 2012 at 0:15
  • Sorry, not an expert on keyval packages --just thought it would be useful to have that linked here. Mar 22, 2012 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, 2012 at 1:08
  • 1
    See also tex.stackexchange.com/questions/37094/….
    – Ahmed Musa
    Mar 25, 2012 at 5:05

2 Answers 2

13

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.

3
  • 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, 2012 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, 2012 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, 2012 at 15:21
8

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 https://tex.stackexchange.com/a/45023/963. For global values see Is there a way to set a *global* key value using `pgfkeys`?.

5
  • 1
    I had the impression that all pgfkeys assignments were local: is that correct?
    – Joseph Wright
    Mar 22, 2012 at 8:28
  • @JosephWright You are correct although there are ways around this. (Did not notice that in the requirement). Mar 22, 2012 at 8:33
  • @YiannisLazarides: What would be those ways around this?
    – krlmlr
    Mar 22, 2012 at 8:48
  • @user946850 tex.stackexchange.com/questions/15204/… Mar 22, 2012 at 8:52
  • This was helpful to me as a syntax example.
    – twip
    Oct 27, 2016 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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