summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/cld/cld-variables.tex
blob: c9afbd44c0b6453f3641fb639c0cedd05637a69e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
% language=uk

\startcomponent cld-variables

\environment cld-environment

\startchapter[title={Variables}]

\startsection[title={Introduction}]

\index {variables}

Sometimes a bit of experimenting and exploring the boundaries of the \TEX|-|\LUA\
interfaces results in new mechanisms. To what extent they are really useful is
hard to say but we just keep them around. Some are described here. This is, at
least for the moment, a \LMTX\ specific chapter.

\stopsection

\startsection[title={Simple tables}]

\index {variables+grouped tables}

The basic \TEX\ data types are counters (integers), dimensions (kind of floating
point variables with typographic dimensions), token lists, node lists (boxes),
fonts, and so on, but no data organized in tables. The first mechanism that we
discuss is one that obeys grouping. In that respect is behaves like regular
registers.

\startbuffer
\newhashedtable\somehashtable

\somehashtable{ foo = 123, bar = "foo" }
[123 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]

\bgroup
\somehashtable{ foo = 456, bar = "oof" }
[456 = \the\somehashtable{foo}]
[oof = \the\somehashtable{bar}]
\egroup

[123 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]

\bgroup
\global\somehashtable{ foo = 456 }
       \somehashtable{ bar = "oof" }
[456 = \the\somehashtable{foo}]
[oof = \the\somehashtable{bar}]
\egroup

[456 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]
\stopbuffer

\typebuffer

We define a hashed table, one with keys and values. The definition is global.
We can then assign values to this table where the assignments themselves are
hash tables. The above code generates:

\getbuffer

As you can see, the \type {\global} prefix makes the value persistent outside the
group. You can mix local and global assignments.

Instead of a hashed table, you can have an indexed table. This time the keys are
numbers.

\startbuffer
\newindexedtable\someindextable

\someindextable{ 123, "foo" }
[123 = \the\someindextable 1]
[foo = \the\someindextable 2]

\bgroup
\someindextable{ 456, "oof" }
[456 = \the\someindextable 1]
[oof = \the\someindextable 2]
\egroup

[123 = \the\someindextable 1]
[foo = \the\someindextable 2]

\bgroup
\global\someindextable{ [1] = 456 }
       \someindextable{ [2] = "oof" }
[456 = \the\someindextable 1]
[oof = \the\someindextable 2]
\egroup

[456 = \the\someindextable 1]
[foo = \the\someindextable 2]
\stopbuffer

\typebuffer

The outcome is the same as before:

\getbuffer

At the \LUA\ end you can access these tables too:

\startbuffer
\startluacode
context("[hashed : bar = %s]",context.hashedtables.somehashtable.bar)
context("[indexed : 2 = %s]", context.indexedtables.someindextable[2])
\stopluacode
\stopbuffer

\typebuffer

Indeed we get:

\getbuffer

\stopsection

\startsection[title={Data tables}]

\index {variables+data tables}

In \LUA, tables can be more complex than in the previous section. When you need
more complex tables, it is likely that your grouping needs are also different,
which is why we have another mechanism. This mechanism is build on top of another
model: data values. There are 64K integer registers in any modern \TEX\ engine
and normally that is more than enough. However, in addition in \LUAMETATEX\ we
have a variant integer storage unit, one that is lightweight and where the amount
is limited by the size of the hash table. It was added as part of the low level
cleanup up of the \LUA\ token interface (a bit more abstraction). Here is an
example of its usage:

\startbuffer
\dorecurse {100} {
    \setdatavalue{#1}{#1}
}

\start \tttf \darkred \raggedright \dorecurse {100} {
    #1=\scratchcounter\getdatavalue{#1}\the\scratchcounter
} \par \stop \blank

\start \tttf \darkgreen \raggedright \dorecurse {100} {
    #1=\thedatavalue{#1}%
} \par \stop \blank
\stopbuffer

\typebuffer

\getbuffer

We define hundred values which are a simple numeric macros. Here we use two
auxiliary macros because we prefer to use a dedicated namespace for these
variables. However, there are also primitives that deal with these data values:

\startbuffer[usage]
\setdatavalue{my-data}{12345}%
\letdatacode  \MyData  67890
\thedatavalue{my-data} \the\MyData
\stopbuffer

\typebuffer[usage]

gives: \inlinebuffer[usage]

But, when more is needed than simple integers, tables come into view. This interface
is different from the simple one and involves more commands. The next examples show
about all:

\startbuffer
\newluatable\testtable
\setluatable\testtable{ foo = 123, bar = "456", oof = "rab" }
% \inspectluatable\testtable
\darkcyan
foo = \getfromluatable\testtable{foo}\par
bar = \getfromluatable\testtable{bar}\par
oof = \getfromluatable\testtable{oof}\par
\bgroup
    \useluatable\testtable
    \setluatable\testtable{ foo = 123123, bar = "456456" }
  % \inspectluatable\testtable
    \darkmagenta
    foo = \getfromluatable\testtable{foo}\par
    bar = \getfromluatable\testtable{bar}\par
    oof = \getfromluatable\testtable{oof}\par
    \startluacode
        local t = context.luatables.get("testtable")
        context("<%s %s %s>",t.foo,t.bar,t.oof)
    \stopluacode \par
\egroup
\darkyellow
foo = \getfromluatable\testtable{foo}\par
bar = \getfromluatable\testtable{bar}\par
oof = \getfromluatable\testtable{oof}\par
\startluacode
    local t = context.luatables.get("testtable")
    context("<%s %s %s>",t.foo,t.bar,t.oof)
\stopluacode \par
% \inspectluatable\testtable
\stopbuffer

\typebuffer

The tables are semi|-|local: \type {\newluatable} creates a table and \type
{\useluatable} will create a local copy that is discarded when the group ends.

\startpacked
\tttf \getbuffer
\stoppacked

Hashed and indexed tables can be used mixed, but there are additional accessors
for indexed tables because there we expect numbers.

\startbuffer
\newluatable\moretable
\setluatable\moretable{ 1, "foo" }
\darkcyan
[1] = \getfromluatable\moretable{1}\par
[2] = \idxfromluatable\moretable 2 \par
\bgroup
    \useluatable\moretable
    \setluatable\moretable{ foo = 123123, bar = "456456" }
    \darkmagenta
    [1] = \getfromluatable\moretable{1}\par
    [2] = \idxfromluatable\moretable 2 \par
    \startluacode
        local t = context.luatables.get("moretable")
        context("<%s %s>",t[1],t[2])
    \stopluacode \par
\egroup
\darkyellow
[1] = \getfromluatable\moretable{1}\par
[2] = \idxfromluatable\moretable 2 \par
\startluacode
    local t = context.luatables.get("moretable")
    context("<%s %s>",t[1],t[2])
\stopluacode \par
\stopbuffer

\typebuffer

\startpacked
\tttf \getbuffer
\stoppacked

You can create more complex (nested) tables that you can handle at the \LUA\
end in the usual way. Basically any \LUA\ that makes a table can go between
the curly braces.

\stopsection

\startsection[title=Named variables]

\index {variables+named}
\index {variables+integers}
\index {variables+cardinals}
\index {variables+floats}
\index {integers}
\index {cardinals}
\index {floats}

Just because it can be done, and maybe it even has it use, we offer additional
numbers, stored and accessible by name. The different types all live in their
own namespace:

\startbuffer[definition]
\luainteger bar 123456
\luafloat   bar 123.456e12
\luainteger gnu = 0xFFFF
\stopbuffer

\startbuffer[usage]
{\darkcyan   \the\luainteger bar}
{\darkmagenta\the\luafloat   bar}
{\darkyellow \the\luainteger gnu}
\stopbuffer

\typebuffer[definition,usage] \getbuffer[definition]

These serialize like: \getbuffer[usage]\removeunwantedspaces , and when not set they
default to zero. There is an extra type, cardinal:

\startbuffer
\luainteger  a  0x7FFFFFFFFFFFFFFF
\luainteger  b -0x7FFFFFFFFFFFFFFF
\luacardinal c  0xFFFFFFFFFFFFFFFF
\stopbuffer

\typebuffer \getbuffer

We cheat a bit behind the screens because it is actually a double but we scan
it as positive integer and serialize it as such.

\startbuffer
[\the \luainteger  a\relax]\par
[\the \luainteger  b\relax]\par
[\the \luacardinal c\relax]\par
\stopbuffer

\typebuffer \getbuffer

You have access to the numbers at the \LUA\ end, as in:

\startbuffer
\luainteger one 123 \luafloat two 456.678
\luaexpr{interfaces.numbers.one/1000 + interfaces.numbers.two/10000}
\stopbuffer

\typebuffer

There are \type {integers}, \type {cardinals} and \type {floats} but the \type
{numbers} one is the most generic as it tries to resolve it from one of these
namespaces, so we get: [\inlinebuffer\space\space]. There is also a related
expression command:

\startbuffer
(?: \luaexpression          {n.one/1000 + n.two/10000})
(f: \luaexpression float    {n.one/1000 + n.two/10000})
(i: \luaexpression integer  {n.one/1000 + n.two/10000})
(c: \luaexpression cardinal {n.one/1000 + n.two/10000})
(l: \luaexpression lua      {n.one/1000 + n.two/10000})
\stopbuffer

\typebuffer

It typesets this (watch the \type {lua} variant, which is a precise
roundtrip serialization method):

\startlines
\tttf \getbuffer
\stoplines

The \type {n} table is just a shortcut to \type {interfaces.numbers}.

\stopsection

\stopchapter

\stopcomponent