node-ini.lmt /size: 8005 b    last modification: 2025-02-21 11:03
1if not modules then modules = { } end modules ['node-ini'] = {
2    version   = 1.001,
3    comment   = "companion to node-ini.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local next, type, tostring = next, type, tostring
10local gsub = string.gsub
11local concat, remove = table.concat, table.remove
12local sortedhash, sortedkeys, swapped = table.sortedhash, table.sortedkeys, table.swapped
13
14-- Access to nodes is what gives LuaTeX its power. Here we implement a few helper
15-- functions. These functions are rather optimized.
16
17nodes                = nodes or { }
18local nodes          = nodes
19nodes.handlers       = nodes.handlers or { }
20
21local mark           = utilities.storage.mark
22local allocate       = utilities.storage.allocate
23local formatcolumns  = utilities.formatters.formatcolumns
24
25local getsubtypes    = node.subtypes
26----- getvalues      = node.values
27
28local listcodes      = mark(getsubtypes("list"))
29local rulecodes      = mark(getsubtypes("rule"))
30local dircodes       = mark(getsubtypes("dir"))
31local markcodes      = mark(getsubtypes("mark"))
32local glyphcodes     = mark(getsubtypes("glyph"))
33local disccodes      = mark(getsubtypes("disc"))
34local gluecodes      = mark(getsubtypes("glue"))
35local boundarycodes  = mark(getsubtypes("boundary"))
36local penaltycodes   = mark(getsubtypes("penalty"))
37local kerncodes      = mark(getsubtypes("kern"))
38local mathcodes      = mark(getsubtypes("math"))
39local noadcodes      = mark(getsubtypes("noad"))
40local radicalcodes   = mark(getsubtypes("radical"))
41local accentcodes    = mark(getsubtypes("accent"))
42local fencecodes     = mark(getsubtypes("fence"))
43local choicecodes    = mark(getsubtypes("choice"))
44local fractioncodes  = mark(getsubtypes("fraction"))
45local parcodes       = mark(getsubtypes("par"))
46local attributecodes = mark(getsubtypes("attribute"))
47
48local function simplified(t)
49    local r = { }
50    for k, v in next, t do
51        r[k] = gsub(v,"_","")
52    end
53    return r
54end
55
56local nodecodes = simplified(node.types())
57
58gluecodes      = allocate(swapped(gluecodes,gluecodes))
59dircodes       = allocate(swapped(dircodes,dircodes))
60markcodes      = allocate(swapped(markcodes,markcodes))
61boundarycodes  = allocate(swapped(boundarycodes,boundarycodes))
62noadcodes      = allocate(swapped(noadcodes,noadcodes))
63radicalcodes   = allocate(swapped(radicalcodes,radicalcodes))
64nodecodes      = allocate(swapped(nodecodes,nodecodes))
65listcodes      = allocate(swapped(listcodes,listcodes))
66glyphcodes     = allocate(swapped(glyphcodes,glyphcodes))
67kerncodes      = allocate(swapped(kerncodes,kerncodes))
68penaltycodes   = allocate(swapped(penaltycodes,penaltycodes))
69mathcodes      = allocate(swapped(mathcodes,mathcodes))
70disccodes      = allocate(swapped(disccodes,disccodes))
71accentcodes    = allocate(swapped(accentcodes,accentcodes))
72fencecodes     = allocate(swapped(fencecodes,fencecodes))
73choicecodes    = allocate(swapped(choicecodes,choicecodes))
74fractioncodes  = allocate(swapped(fractioncodes,fractioncodes))
75parcodes       = allocate(swapped(parcodes,parcodes))
76attributecodes = allocate(swapped(attributecodes,attributecodes))
77rulecodes      = allocate(swapped(rulecodes,rulecodes))
78
79nodes.gluecodes      = gluecodes
80nodes.dircodes       = dircodes
81nodes.markcodes      = markcodes
82nodes.boundarycodes  = boundarycodes
83nodes.noadcodes      = noadcodes
84nodes.listcodes      = listcodes
85nodes.glyphcodes     = glyphcodes
86nodes.kerncodes      = kerncodes
87nodes.penaltycodes   = penaltycodes
88nodes.mathcodes      = mathcodes
89nodes.disccodes      = disccodes
90nodes.accentcodes    = accentcodes
91nodes.radicalcodes   = radicalcodes
92nodes.fencecodes     = fencecodes
93nodes.choicecodes    = choicecodes
94nodes.fractioncodes  = fractioncodes
95nodes.parcodes       = parcodes
96nodes.attributecodes = attributecodes
97nodes.rulecodes      = rulecodes
98
99nodes.nodecodes      = nodecodes
100
101-- these are now in tex namespace but we keep them for old times sake
102
103nodes.fillvalues      = tex.fillcodes
104nodes.fillcodes       = tex.fillcodes
105nodes.dirvalues       = tex.directioncodes
106nodes.directionvalues = tex.directioncodes
107nodes.mathvalues      = tex.mathparametercodes
108
109-- we will transition to more verbose subtypes (after other math is done)
110
111noadcodes.ord      = noadcodes.ord   or noadcodes.ordinary
112noadcodes.operator = noadcodes.op    or noadcodes.operator
113noadcodes.bin      = noadcodes.bin   or noadcodes.binary
114noadcodes.rel      = noadcodes.rel   or noadcodes.relation
115noadcodes.punct    = noadcodes.punct or noadcodes.punctuation
116noadcodes.rad      = noadcodes.rad   or noadcodes.radical
117noadcodes.frac     = noadcodes.frac  or noadcodes.fraction
118noadcodes.acc      = noadcodes.acc   or noadcodes.accent
119
120-- so for now:
121
122noadcodes.ordinary    = noadcodes.ordinary    or noadcodes.ord
123noadcodes.operator    = noadcodes.operator    or noadcodes.op
124noadcodes.binary      = noadcodes.binary      or noadcodes.bin
125noadcodes.relation    = noadcodes.relation    or noadcodes.rel
126noadcodes.punctuation = noadcodes.punctuation or noadcodes.punct
127noadcodes.radical     = noadcodes.radical     or noadcodes.rad
128noadcodes.fraction    = noadcodes.fraction    or noadcodes.frac
129noadcodes.accent      = noadcodes.accent      or noadcodes.acc
130
131local subtypes = allocate {
132    glue      = gluecodes,
133    dir       = dircodes,
134    mark      = markcodes,
135    boundary  = boundarycodes,
136    noad      = noadcodes,
137    glyph     = glyphcodes,
138    kern      = kerncodes,
139    penalty   = penaltycodes,
140    math      = mathcodes,
141    disc      = disccodes,
142    accent    = accentcodes,
143    radical   = radicalcodes,
144    fence     = fencecodes,
145    choice    = choicecodes,
146    par       = parcodes,
147    attribute = attributecodes,
148    rule      = rulecodes,
149
150    vlist     = listcodes,
151    hlist     = listcodes,
152
153 -- list      = listcodes,
154
155 -- parameter = parametercodes,
156 -- user      = usercodes,
157}
158
159for k, v in table.sortedhash(subtypes) do
160    local i = nodecodes[k]
161    if i and not subtypes[i] then
162        subtypes[i] = v
163    end
164end
165
166nodes.subtypes = subtypes
167
168-- a few more friendly aliases:
169
170nodes.skipcodes            = gluecodes
171nodes.directioncodes       = dircodes
172nodes.discretionarycodes   = disccodes
173
174glyphcodes.glyph           = glyphcodes.character
175
176gluecodes.parfillrightskip = gluecodes.parfillrightskip or gluecodes.parfillskip
177gluecodes.parfillskip      = gluecodes.parfillskip      or gluecodes.parfillrightskip
178
179listcodes.row              = listcodes.alignment
180listcodes.column           = listcodes.alignment
181
182kerncodes.italiccorrection = kerncodes.italiccorrection
183kerncodes.italickern       = kerncodes.italiccorrection -- compatibility
184
185-- We use the real node code numbers.
186
187local texsetintegervalue = tex.setintegervalue
188
189for i=0,nodecodes.glyph do
190    texsetintegervalue(nodecodes[i] .. "nodecode",i,"immutable")
191end
192texsetintegervalue("tempnodecode",nodecodes.temp,"immutable") -- can happen in tables
193
194for i=0,#gluecodes do
195    texsetintegervalue(gluecodes[i] .. "subtypecode",i,"immutable")
196end
197
198nodes.specialskipcodes = {
199    [gluecodes.leftskip]                             = true,
200    [gluecodes.rightskip]                            = true,
201    [gluecodes.lefthangskip]                         = true,
202    [gluecodes.righthangskip]                        = true,
203    [gluecodes.parfillleftskip  or parfillskip_code] = true,
204    [gluecodes.parfillrightskip or parfillskip_code] = true,
205    [gluecodes.indentskip]                           = true,
206    [gluecodes.correctionskip]                       = true,
207}
208
209table.setmetatableindex(listcodes,function(t,k)
210    local v
211 -- if mathematics then
212        if type(k) == "string" then
213            v = mathematics.classes[k] + 0x100
214        else
215            local i = k - 0x100
216            v = mathematics.classes[i] or mathematics.classnames[i]
217        end
218 -- end
219    if not v then
220        v = listcodes.unknown
221    end
222    t[k] = v
223    return v
224end)
225