# Using property list from expl3

I'm trying to use a property list from expl3 however, I have a very simple example that fails. Can anyone help me understand my error?

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
% define a propery list
\prop_new:N \my_tooltip_prop
%
\NewDocumentCommand{\CSetA}{mm}{
\prop_gput:Nnn \my_tooltip_prop {#1} {#2}
}
%
\NewDocumentCommand{\CGetA}{m}{
\prop_get:NnN \my_tooltip_prop {#1}
}
%
%
% Altenative
%
\cs_new_protected:Npn \CSetB #1#2 {
\prop_gput:Nnn \my_tooltip_prop {#1} {#2}
}
%
\cs_new:Npn \CGetB #1 {
\prop_get:NnN \my_tooltip_prop {#1}
}
\ExplSyntaxOff

\begin{document}
\pagestyle{empty}

Hello

%\CSetA{key1}{value1}
%\CGetA{key1} % same error as with \CGetB{key2}

\CSetB{key2}{value2}
\CGetB{key2}

\end{document}


The error message is

! TeX capacity exceeded, sorry [main memory size=5000000].
\par ->valu
e2
l.40 \end{document}


My system is running Kubuntu 16.10.

• \prop_get:NnN needs three arguments – you only have two! – clemens Dec 14 '16 at 10:12
• Use \prop_item:Nn instead of \prop_get:NnN. – Henri Menke Dec 14 '16 at 10:41
• Thank you, you are right! \prop_item:Nn is not defined anymore :( I had to change \CGetA and \CGetB to: \prop_get:NnN \my_tooltip_prop {#1} \tempVar \tempVar – João Leal Dec 14 '16 at 11:10

The correct way is with \prop_item:Nn:

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
% define a propery list
\prop_new:N \g_leal_tooltip_prop
%
\NewDocumentCommand{\CSet}{mm}
{
\prop_gput:Nnn \g_leal_tooltip_prop {#1} {#2}
}
%
\NewDocumentCommand{\CGet}{m}
{
\prop_item:Nn \g_leal_tooltip_prop {#1}
}
\ExplSyntaxOff

\begin{document}
\pagestyle{empty}

Hello

\CSet{key1}{value1}
\CGet{key1}

\CSet{key2}{value2}
\CGet{key2}

\end{document}


The \prop_item:Nn function has been introduced on 2014-07-17; if you get it is undefined, your TeX distribution is lagging behind.

An almost equivalent version would be with the help of a token list variable:

\tl_new:N \l_leal_tooltip_temp_tl
\NewDocumentCommand{\CGet}{m}
{
\prop_get:NnN \g_leal_tooltip_prop {#1} \l_leal_tooltip_temp_tl
\tl_use:N \l_leal_tooltip_temp_tl
}

• This »almost equivalent« version of \prop_item:Nn is not fully expandable. It should be fairly easy to backport \prop_item:Nn. It’s only a few lines. – Henri Menke Dec 14 '16 at 12:37
• @HenriMenke Yes, I used “almost” on purpose. I'd prefer to update the TeX distribution rather than hacking. – egreg Dec 14 '16 at 12:39
• Thank you! My version of expl3 is from 2016/05/18 (v6512). I had previously used \prop_item:Nn but then it stopped working after an upgrade (Undefined control sequence). – João Leal Dec 15 '16 at 13:15
• @egreg : Can you replace \tl_new:Nn for \tl_new:N?, just with the idea of keeping the answer updated, Saludos – Pablo González L Jun 25 at 3:46

In ConTeXt you get property lists with a high-level interface.

\starttext

\setvariables
[tooltip]
[
key1=value1,
key2=value2,
]

\getvariable{tooltip}{key1}
\getvariable{tooltip}{key2}

\stoptext

• Interestingly, we're currently discussing the link between property lists and keyval methods on the LaTeX team list :) – Joseph Wright Dec 14 '16 at 12:56

You can achieve something similar to my ConTeXt answer with LuaLaTeX. To parse the key-value list, I still use utilities.parsers.settings_to_hash from ConTeXt. To do so, I have to import the necessary ConTeXt core files, namely

dofile(kpse.find_file("l-lpeg.lua"))
dofile(kpse.find_file("util-sto.lua"))
dofile(kpse.find_file("util-prs.lua"))


The following code is very generic and has an interface similar to the ConTeXt version. It should be easy to repurpose it.

\documentclass{article}

\directlua{
dofile(kpse.find_file("l-lpeg.lua"))
dofile(kpse.find_file("util-sto.lua"))
dofile(kpse.find_file("util-prs.lua"))

uservariables         = uservariables or {}
uservariables.content = uservariables.content or {}

function uservariables.put(namespace,keyvals)
local input = utilities.parsers.settings_to_hash(keyvals)

uservariables.content[namespace] = uservariables.content[namespace] or {}

for k,v in pairs(input) do
uservariables.content[namespace][k] = v
end
end

function uservariables.get(namespace,k)
tex.sprint(uservariables.content[namespace][k] or "")
end
}

\newcommand\setvariables[2]{%
\directlua{uservariables.put(\unexpanded{[==[#1]==], [==[#2]==]})}}

\newcommand\getvariable[2]{%
\directlua{uservariables.get(\unexpanded{[==[#1]==], [==[#2]==]})}}

\begin{document}

\setvariables
{tooltip}
{
key1=value1,
key2=value2,
}

\getvariable{tooltip}{key1}
\getvariable{tooltip}{key2}

\end{document}