# Storing and retrieving data in tuc file

I want to store some data in the .tuc file, which is being picked up in the next run. I suceeded in storing some values but I failed in retrieving them afterwards.

Here is my attempt:

\starttext
\startluacode
local collected = utilities.storage.allocate()
local tobesaved = utilities.storage.allocate()

job.register("job.userdata", tobesaved)

tobesaved["foo"] = "value_foo"
tobesaved["bar"] = "value_bar"
\stopluacode
\stoptext


This leads to the following entry in the .tuc file:

utilitydata.job.userdata={
["bar"]="value_bar",
["foo"]="value_foo",
}


The two values are stored as desired.

Side question: I randomly picked the table utilitydata.job.userdata to store my values. Is there a default table which should be used for this to avoid clashes with the ones used by the system?

I expected to be able to retrieve the data with e.g. collected["foo"], but the collected table is empty.

The sources tell me that job.register has four arguments: collected, tobesaved, initializer and finalizer. Maybe that is where my mistake is. I don't know what they are doing.

What is the interface to retrieve the values from the .tuc file?

(I don't know if the question is ConTeXt centric or generally applies to LuaTeX. If the mechanism is ConTeXt related, feel free to add the tag.)

• There was a recent message on dev-context mailing list by Hans giving a complete example of how to use job.register and a new feature that allows you to add two pass data from the tex side. Unfortunately, the dev-context archives are only accessible to members. So, you'll need to join the list to view the message. Apr 17 '12 at 4:18
• @Aditya I am subscribed to dev-context, but frankly, I often don't read it thoroughly. However, I fail to find Hans' mail. Grepping the archive for job.register returns nothing. Could you give a pointer? gmane hosts the list archive also for non-members. Apr 17 '12 at 8:11
• Sorry, I just realized that that discussion was off-list. I'll post the gist of it as an answer. Apr 17 '12 at 14:44
• The code needs to be loaded at the time you are generating the format to work. Please wait until the next beta for an alternative implementation of two-pass data Apr 17 '12 at 17:51

# Defining a data set

To store values to the .tuc file you can use \definedataset [myset] to define a container for the data.

# Storing data

To store key-value pairs use the command \setdataset.

    \setdataset [myset] [foo=foo-first,  bar=bar-first]
\setdataset [myset] [foo=foo-second, bar=bar-second]
\setdataset [myset] [foo=foo-third,  bar=bar-third]


Subsequent calls with the same keys to different data like in the example above does not overwrite the former values. All values are stored and enumerated. The calls above lead to the following entries in the .tuc file.

utilitydata.job.datasets.collected={
["myset"]={
{
["bar"]="bar-first",
["foo"]="foo-first",
},
{
["bar"]="bar-second",
["foo"]="foo-second",
},
{
["bar"]="bar-third",
["foo"]="foo-third",
},
},
}


The system takes care of the name of the table not to interfere with core tables.

One can also add another parameter to address the individual values (with the same keys) from subsequent calls.

\setdataset [myset] [first]  [foo=foo-first,  bar=bar-first]
\setdataset [myset] [second] [foo=foo-second, bar=bar-second]
\setdataset [myset] [third]  [foo=foo-third,  bar=bar-third]


These calls with the additional parameter lead to the following entries in the .tuc file.

utilitydata.job.datasets.collected={
["myset"]={
["first"]={
["bar"]="bar-first",
["foo"]="foo-first",
},
["second"]={
["bar"]="bar-second",
["foo"]="foo-second",
},
["third"]={
["bar"]="bar-third",
["foo"]="foo-third",
},
},
}


# Retrieving the values

The values can be retrieved with the \datasetvariable command. The first argument is the data set defined with \definedataset.

The second argument is a number if the first variant with two parameters of \setdataset was used. It's the number of the \setdataset call. If the second variant with three parameters was used, then it is the identifier given in the second argument.

And the third argument is the key which value should be retrieved.

Note: In contrast to the other mentioned commands, the arguments of \datasetvariable are delimited by braces, instead of brackets, because the actually typeset data. That's ConTeXts convention.

# Complete example

\starttext

\definedataset [myset-1]

% two arguments ⇒ the data is accessed by number
\setdataset    [myset-1] [foo=foo-first,  bar=bar-first]
\setdataset    [myset-1] [foo=foo-second, bar=bar-second]

% Outputs foo-first
\datasetvariable{myset-1}{1}{foo}\par

% Outputs foo-second
\datasetvariable{myset-1}{2}{foo}\par

% Outputs bar-first
\datasetvariable{myset-1}{1}{bar}\par

% Outputs bar-second
\datasetvariable{myset-1}{2}{bar}\blank

\definedataset [myset-2]

% three arguments ⇒ the data is accessed by identifier
\setdataset    [myset-2] [first]  [alpha=alpha-first,  beta=beta-first]
\setdataset    [myset-2] [second] [alpha=alpha-second, beta=beta-second]

% Outputs alpha-first
\datasetvariable{myset-2}{first} {alpha}\par

% Outputs alpha-second
\datasetvariable{myset-2}{second}{alpha}\par

% Outputs beta-first
\datasetvariable{myset-2}{first} {beta}\par

% Outputs beta-second
\datasetvariable{myset-2}{second}{beta}\par

\stoptext


Result: