s-system-syntax.lmt /size: 77 Kb    last modification: 2024-01-16 10:22
1local setmetatableindex, sortedhash, concat = table.setmetatableindex, table.sortedhash, table.concat
2local sub, gsub, count = string.sub, string.gsub, string.count
3local lpegmatch = lpeg.match
4
5local context = context
6
7local moduledata   = moduledata or { }
8moduledata.engine  = moduledata.engine or { }
9
10local primitives   = token.getprimitives()
11local commandnames = tokens.commands
12local origins      = tex.getprimitiveorigins()
13local commandhash  = { }
14local keywords     = setmetatableindex("number")
15
16for i=1,#primitives do
17    local p = primitives[i]
18    commandhash[p[3]] = p
19end
20
21local result = setmetatableindex(function(t,k)
22    local v = setmetatableindex(function(t,k)
23        local v = ""
24        t[k] = v
25        return v
26    end)
27    t[k]= v
28    return v
29end)
30
31local function TODO(t,k)
32    local v = "TODO"
33    t[k] = v
34    return v
35end
36
37local function newsyntax(t)
38    return setmetatableindex(t or { }, TODO)
39end
40
41local function newresult(t)
42    return t or { }
43end
44
45local category = setmetatableindex(function(t,k)
46    local v = "unset" -- might go
47    t[k]= v
48    return v
49end)
50
51local syntax = setmetatableindex(function(t,k)
52    local v = newsyntax()
53    t[k]= v
54    return v
55end)
56
57local function equals(...)
58    local t = { ... }
59    table.insert(t,#t,"[=]")
60    return concat(t," ")
61end
62
63local function sequence(...)
64    return concat({ ... }," ")
65end
66
67local function optional(s)
68    return "[" .. s .. "]"
69end
70
71local function choice(t,...)
72    return "( " .. concat(type(t) == "table" and t or { t, ... }," | ") .. ")"
73end
74
75local function repeated(...)
76    return "n * ( " .. concat({ ... }," ") .. ")"
77end
78
79local function keyword(s)
80    keywords[s] = keywords[s] + 1
81    return s
82end
83
84local s_dimension     = "dimension"
85local s_integer       = "integer"
86local s_cardinal      = "cardinal"
87local s_index         = "index"
88local s_float         = "float"
89local s_glue          = "glue"
90local s_muglue        = "muglue"
91local s_tokens        = "{tokens}"
92local s_token         = "token"
93local s_toks          = "toks"
94local s_mathstyle     = "mathstyle"
95local s_mathchar      = "mathchar"
96local s_quantity      = "quantity"
97local s_delimiter     = "delimiter"
98local s_nucleus       = "nucleus"
99local s_box           = "box"
100local s_cs            = "cs"
101local s_mathparameter = "mathparameter"
102local s_filler        = "fi[n*l]"
103local s_fontchar      = s_integer
104local s_character     = "character"
105local s_font          = choice("font",s_integer)
106local s_mathtokens    = choice("mathatom",s_tokens)
107local s_filename      = choice("{filename}","filename")
108local s_boxreference  = choice(s_index,s_box)
109local s_number        = choice(s_integer,s_float)
110local s_family        = "family"
111local s_rule          = "rule"
112local s_glyph         = "glyph"
113local s_todo          = "TODO"
114
115local s_expression    = [==[tokens\relax]==]
116local s_conditional   = [==[\if...]==]
117local s_tokens_or     = [==[tokens\or]==]
118local s_tokens_relax  = [==[tokens\relax]==]
119local s_tokens_endcs  = [==[tokens\endcsname]==]
120local s_tokens_endlc  = [==[tokens\endlocalcontrol]==]
121local s_parameter_or  = [==[parameter\or]==]
122
123local c_tokens        = "tokens"
124
125local r_dimension     = { "", s_dimension }
126local r_glue          = { "", s_glue }
127local r_integer       = { "", s_integer }
128local r_muglue        = { "", s_muglue }
129local r_toks          = { "", s_toks }
130local r_tokens        = { "", c_tokens }
131
132local function setdefaultresult(syntax, value)
133    local default = { }
134    for k in next, syntax do
135        default[k] = value
136    end
137    return default
138end
139
140local function setsyntaxfromresult(t)
141    local s = newsyntax()
142    for k, v in next, t do
143        s[k] = v and concat(v," [=] ") or false
144    end
145    return s
146end
147
148local compares = {
149    [0x003C] = "less",
150    [0x003D] = "equal",
151    [0x003E] = "greater",
152    [0x0021] = "negate next",
153    [0x2208] = "element",
154    [0x2209] = "not element",
155    [0x2260] = "not equal",
156    [0x2264] = "not greater",
157    [0x2265] = "not less",
158    [0x2270] = "not greater",
159    [0x2271] = "not less",
160}
161
162moduledata.engine.compares = compares
163
164local s_comparison = table.sortedkeys(compares) for i=1,#s_comparison do s_comparison[i] = utf.char(s_comparison[i]) end
165
166local o_equal      = optional("=")
167local s_comparison = choice(s_comparison)
168local o_preamble   = optional("preamble")
169
170-- start of syntax specification
171
172syntax.accent = newsyntax {
173    accent = sequence(
174        optional(sequence(keyword("xoffset"),s_dimension)),
175        optional(sequence(keyword("yoffset"),s_dimension)),
176        s_integer,
177        s_character
178    )
179}
180
181syntax.alignmenttab = newsyntax {
182    aligntab = false,
183}
184
185syntax.aftersomething = newsyntax {
186    afterassigned   = s_tokens,
187    afterassignment = s_token,
188    aftergroup      = s_token,
189    aftergrouped    = s_tokens,
190    atendofgroup    = s_token,
191    atendofgrouped  = s_tokens,
192    atendoffile     = s_token,
193    atendoffiled    = sequence(optional(keyword("reverse")),s_tokens),
194}
195
196result.association = newresult {
197    associateunit = { s_cs, s_integer }
198}
199
200syntax.association = setsyntaxfromresult(result.association)
201
202
203syntax.begingroup = newsyntax {
204    begingroup       = false,
205    beginmathgroup   = false,
206    beginsimplegroup = false,
207}
208
209syntax.arithmic = newsyntax {
210    advance    = sequence(s_quantity,optional(keyword("by")),s_quantity),
211    divide     = sequence(s_quantity,optional(keyword("by")),s_quantity),
212    multiply   = sequence(s_quantity,optional(keyword("by")),s_quantity),
213    advanceby  = sequence(s_quantity,s_quantity),
214    divideby   = sequence(s_quantity,s_quantity),
215    multiplyby = sequence(s_quantity,s_quantity),
216    edivide    = sequence(s_quantity,s_quantity),
217    edivideby  = sequence(s_quantity,s_quantity),
218    rdivide    = sequence(s_quantity,s_quantity),
219    rdivideby  = sequence(s_quantity,s_quantity),
220}
221
222syntax.beginlocal = newsyntax {
223    beginlocalcontrol      = false,
224    localcontrol           = s_tokens_endlc,
225    localcontrolled        = s_tokens,
226    localcontrolledloop    = sequence(s_integer,s_integer,s_integer,s_tokens),
227    expandedloop           = sequence(s_integer,s_integer,s_integer,s_tokens),
228    unexpandedloop         = sequence(s_integer,s_integer,s_integer,s_tokens),
229    localcontrolledrepeat  = sequence(s_integer,s_tokens),
230    expandedrepeat         = sequence(s_integer,s_tokens),
231    unexpandedrepeat       = sequence(s_integer,s_tokens),
232    localcontrolledendless = s_tokens,
233    expandedendless        = s_tokens,
234    unexpandedendless      = s_tokens,
235}
236
237syntax.beginparagraph = newsyntax {
238    indent       = false,
239    noindent     = false,
240    parattribute = sequence(s_integer,o_equal,s_integer),
241    quitvmode    = false,
242    snapshotpar  = s_cardinal,
243    undent       = false,
244    wrapuppar    = sequence(optional(keyword("reverse")),s_tokens),
245}
246
247result.beginparagraph = newresult {
248    indent       = false,
249    noindent     = false,
250    parattribute = false,
251    quitvmode    = false,
252    snapshotpar  = r_integer,
253    undent       = false,
254    wrapuppar    = false,
255}
256
257syntax.boundary = newsyntax {
258    boundary           = sequence(o_equal,s_integer),
259    noboundary         = false,
260    mathboundary       = sequence(o_equal,s_integer),
261    optionalboundary   = sequence(o_equal,s_integer), -- linebreak optionals
262    pageboundary       = sequence(o_equal,s_integer),
263    protrusionboundary = sequence(o_equal,s_integer),
264    wordboundary       = false,
265}
266
267syntax.caseshift = newsyntax {
268    lowercase = s_tokens,
269    uppercase = s_tokens,
270}
271
272syntax.catcodetable = newsyntax {
273    initcatcodetable = s_integer,
274    savecatcodetable = s_integer,
275}
276
277syntax.charnumber = newsyntax {
278    char  = s_integer,
279    glyph = sequence(
280        optional(sequence(keyword("xoffset"),s_dimension)),
281        optional(sequence(keyword("yoffset"),s_dimension)),
282        optional(sequence(keyword("scale"),s_integer)),
283        optional(sequence(keyword("xscale"),s_integer)),
284        optional(sequence(keyword("yscale"),s_integer)),
285        optional(sequence(keyword("left"),s_dimension)),
286        optional(sequence(keyword("right"),s_dimension)),
287        optional(sequence(keyword("raise"),s_dimension)),
288        optional(sequence(keyword("options"),s_integer)),
289        optional(sequence(keyword("font"),s_integer)),
290        optional(sequence(keyword("id"),s_integer)),
291        s_integer
292    ),
293}
294
295syntax.combinetoks = newsyntax {
296    etoks    = sequence(s_toks,s_tokens),
297    etoksapp = sequence(s_toks,s_tokens),
298    etokspre = sequence(s_toks,s_tokens),
299    gtoksapp = sequence(s_toks,s_tokens),
300    gtokspre = sequence(s_toks,s_tokens),
301    toksapp  = sequence(s_toks,s_tokens),
302    tokspre  = sequence(s_toks,s_tokens),
303    xtoks    = sequence(s_toks,s_tokens),
304    xtoksapp = sequence(s_toks,s_tokens),
305    xtokspre = sequence(s_toks,s_tokens),
306}
307
308result.convert = newresult {
309    tocharacter       = { s_integer, c_tokens },
310    csactive          = { s_token, c_tokens },
311    csstring          = { s_token, c_tokens },
312    detokened         = { choice(s_cs,s_tokens,s_toks,s_tok), c_tokens },
313    detokenized       = { s_tokens, c_tokens },
314    directlua         = { s_tokens, c_tokens },
315    expanded          = { s_tokens, c_tokens },
316    fontname          = { s_font, c_tokens },
317    fontspecifiedname = { s_font, c_tokens },
318    formatname        = { "", c_tokens },
319    jobname           = { "", c_tokens },
320    luabytecode       = { s_integer, c_tokens },
321    luaescapestring   = { s_tokens, c_tokens },
322    luafunction       = { s_integer, c_tokens },
323    luatexbanner      = { "", c_tokens },
324    meaning           = { s_token, c_tokens },
325    meaningasis       = { s_token, c_tokens },
326    meaningful        = { s_token, c_tokens },
327    meaningfull       = { s_token, c_tokens },
328    meaningles        = { s_token, c_tokens },
329    meaningless       = { s_token, c_tokens },
330    number            = { s_integer, c_tokens },
331    romannumeral      = { s_integer, c_tokens },
332    semiexpanded      = { s_tokens, c_tokens },
333    futureexpandis    = { s_todo },
334    futureexpandisap  = { s_todo },
335    string            = { s_token, c_tokens },
336    todimension       = { s_dimension, c_tokens },
337    tohexadecimal     = { s_integer, c_tokens },
338    tointeger         = { s_integer, c_tokens },
339    tomathstyle       = { s_mathstyle, c_tokens },
340    toscaled          = { s_dimension, c_tokens },
341    tosparsedimension = { s_dimension, c_tokens },
342    tosparsescaled    = { s_dimension, c_tokens },
343}
344
345syntax.convert = newsyntax { }  for k in next, result.convert do syntax.convert[k] = "" end
346
347syntax.csname = newsyntax {
348    begincsname  = s_tokens_endcs,
349    csname       = s_tokens_endcs,
350    futurecsname = s_tokens_endcs,
351    lastnamedcs  = false,
352}
353
354syntax.def = newsyntax {
355    cdef       = sequence(s_cs,o_preamble, s_tokens),
356    cdefcsname = sequence(s_tokens_endcs,o_preamble, s_tokens),
357    def        = sequence(s_cs,o_preamble, s_tokens),
358    defcsname  = sequence(s_tokens_endcs,o_preamble, s_tokens),
359    edef       = sequence(s_cs,o_preamble, s_tokens),
360    edefcsname = sequence(s_tokens_endcs,o_preamble, s_tokens),
361    gdef       = sequence(s_cs,o_preamble, s_tokens),
362    gdefcsname = sequence(s_tokens_endcs,o_preamble, s_tokens),
363    xdef       = sequence(s_cs,o_preamble, s_tokens),
364    xdefcsname = sequence(s_tokens_endcs,o_preamble, s_tokens),
365}
366
367result.definecharcode = newresult {
368    Udelcode  = { s_integer, s_integer }, -- todo
369    Umathcode = { s_integer, s_integer }, -- todo
370    amcode    = { s_integer, s_integer },
371    catcode   = { s_integer, s_integer },
372    delcode   = { s_integer, s_integer }, -- todo
373    hccode    = { s_integer, s_integer },
374    hmcode    = { s_integer, s_integer },
375    lccode    = { s_integer, s_integer },
376    mathcode  = { s_integer, s_integer }, -- todo
377    sfcode    = { s_integer, s_integer },
378    uccode    = { s_integer, s_integer },
379}
380
381syntax.definecharcode = setsyntaxfromresult(result.definecharcode)
382
383syntax.definefamily = newsyntax {
384    scriptfont       = sequence(s_family,s_font),
385    scriptscriptfont = sequence(s_family,s_font),
386    textfont         = sequence(s_family,s_font),
387}
388
389result.definefamily = setdefaultresult(syntax.definefamily, { s_family, s_integer })
390
391syntax.definefont = newsyntax {
392    font = sequence(s_cs,s_filename,optional(choice(sequence("at",s_dimension),sequence("scaled",s_integer)))),
393}
394
395result.definefont = newresult {
396    font = r_tokens
397}
398
399syntax.delimiternumber = newsyntax {
400    delimiter  = s_integer,
401    Udelimiter = sequence(s_integer,s_integer,s_integer),
402}
403
404syntax.discretionary = newsyntax {
405    ["-"]                   = false,
406    automaticdiscretionary  = false,
407    discretionary           = sequence(
408        optional(keyword("penalty"),s_integer),
409        optional(keyword("postword")),
410        optional(keyword("preword")),
411        optional(keyword("break")),
412        optional(keyword("nobreak")),
413        optional(keyword("options"),s_integer),
414        optional(keyword("class"),s_integer),
415        sequence(s_tokens,s_tokens,s_tokens)
416    ),
417    explicitdiscretionary   = false,
418}
419
420syntax.endcsname = newsyntax {
421    endcsname = false,
422}
423
424syntax.endgroup = newsyntax {
425    endgroup       = false,
426    endmathgroup   = false,
427    endsimplegroup = false,
428}
429
430syntax.endjob = newsyntax {
431    ["dump"] = false,
432    ["end"]  = false,
433}
434
435syntax.endlocal = newsyntax {
436    endlocalcontrol = false,
437}
438
439syntax.endparagraph = newsyntax {
440    par = false,
441}
442
443syntax.endtemplate = newsyntax {
444    aligncontent = false,
445    cr           = false,
446    crcr         = false,
447    noalign      = s_tokens,
448    omit         = false,
449    span         = false,
450}
451
452syntax.equationnumber = newsyntax {
453    eqno  = s_tokens,
454    leqno = s_tokens,
455}
456
457syntax.expandafter = newsyntax {
458    expand                  = s_token,
459    expandactive            = s_token,
460    expandafter             = sequence(s_token,s_token),
461    expandafterpars         = s_token,
462    expandafterspaces       = s_token,
463    expandcstoken           = s_token,
464    expandedafter           = sequence(s_token,s_tokens),
465    expandparameter         = s_integer,
466    expandtoken             = s_token,
467    expandtoks              = s_tokens,
468    futureexpand            = sequence(s_token,s_token,s_token),
469    futureexpandafterspaces = sequence(s_token,s_token,s_token),
470    futureexpandafterpars   = sequence(s_token,s_token,s_token),
471    semiexpand              = s_token,
472    unless                  = false,
473}
474
475syntax.explicitspace = newsyntax {
476    [" "] = false,
477}
478
479syntax.getmark = newsyntax {
480    botmark         = false,
481    botmarks        = s_integer,
482    currentmarks    = s_integer,
483    firstmark       = false,
484    firstmarks      = s_integer,
485    splitbotmark    = false,
486    splitbotmarks   = s_integer,
487    splitfirstmark  = false,
488    splitfirstmarks = s_integer,
489    topmark         = false,
490    topmarks        = s_integer,
491}
492
493syntax.halign = newsyntax {
494    halign = sequence(
495        optional(sequence(keyword("attr"),s_integer,s_integer)),
496        optional(sequence(keyword("callback"),s_integer)),
497        optional(keyword("discard")),
498        optional(keyword("noskips")),
499        optional(keyword("reverse")),
500        optional(sequence(keyword("to"),s_dimension)),
501        optional(sequence(keyword("spread"),s_dimension)),
502        s_tokens
503    ),
504}
505
506syntax.hmove = newsyntax {
507    moveleft  = sequence(s_dimension,s_box),
508    moveright = sequence(s_dimension,s_box),
509}
510
511syntax.hyphenation = newsyntax {
512    hjcode           = sequence(s_integer,o_equal,s_integer),
513    hyphenation      = s_tokens,
514    hyphenationmin   = sequence(o_equal,s_integer),
515    patterns         = s_tokens,
516    postexhyphenchar = sequence(o_equal,s_integer),
517    posthyphenchar   = sequence(o_equal,s_integer),
518    preexhyphenchar  = sequence(o_equal,s_integer),
519    prehyphenchar    = sequence(o_equal,s_integer),
520}
521
522result.hyphenation = newresult {
523    -- TODO
524}
525
526do
527
528    local vrule = sequence(
529        optional(sequence(keyword("attr"),s_integer,o_equal,s_integer)),
530        optional(sequence(keyword("width"),s_dimension)),
531        optional(sequence(keyword("height"),s_dimension)),
532        optional(sequence(keyword("depth"),s_dimension)),
533        optional(sequence(keyword("left"),s_dimension)),
534        optional(sequence(keyword("right"),s_dimension)),
535        optional(sequence(keyword("top"),s_dimension)),
536        optional(sequence(keyword("bottom"),s_dimension)),
537        optional(sequence(keyword("xoffset"),s_dimension)),
538        optional(sequence(keyword("yoffset"),s_dimension))
539    )
540
541    local rule = sequence(vrule,sequence(
542        optional(sequence(keyword("font"),s_integer)),
543        optional(sequence(keyword("fam"),s_integer)),
544        optional(sequence(keyword("char"),s_integer))
545    ))
546
547    syntax.hrule = newsyntax {
548        nohrule      = rule,
549        virtualhrule = vrule,
550        hrule        = rule,
551    }
552
553end
554
555syntax.hskip = newsyntax {
556    hfil    = false,
557    hfill   = false,
558    hfilneg = false,
559    hskip   = sequence(
560        s_dimension,
561        optional(sequence(keyword("plus"),choice(s_dimension,s_filler))),
562        optional(sequence(keyword("minus"),choice(s_dimension,s_filler)))
563    ),
564    hss     = false,
565}
566
567-- needs checking, first version
568
569syntax.iftest = newsyntax {
570    ["else"]        = false,
571    ["fi"]          = false,
572    ["if"]          = false,
573    ifabsdim        = sequence(s_dimension,s_comparison,s_dimension),
574    ifabsfloat      = sequence(s_float,s_comparison,s_float),
575    ifabsnum        = sequence(s_integer,s_comparison,s_integer),
576    ifarguments     = false,
577    ifboolean       = s_integer,
578    ifcase          = s_integer,
579    ifcat           = s_token,
580    ifchkdim        = s_tokens_or,
581    ifchkdimension  = s_tokens_or,
582    ifchknum        = s_tokens_or,
583    ifchknumber     = s_tokens_or,
584    ifcmpdim        = sequence(s_dimension,s_dimension),
585    ifcmpnum        = sequence(s_integer,s_integer),
586    ifcondition     = s_conditional,
587    ifcsname        = s_tokens_endcs,
588    ifcstok         = s_tokens_relax,
589    ifdefined       = s_token,
590    ifdim           = sequence(s_dimension,s_comparison,s_dimension),
591    ifdimexpression = s_tokens_relax,
592    ifdimval        = s_tokens_or,
593    ifempty         = choice(s_token,s_tokens),
594    iffalse         = false,
595    ifflags         = s_cs,
596    iffloat         = sequence(s_float,s_comparison,s_float),
597    iffontchar      = sequence(s_integer,s_integer),
598    ifhaschar       = sequence(s_token,s_tokens),
599    ifhastok        = sequence(s_token,s_tokens),
600    ifhastoks       = s_tokens_relax,
601    ifhasxtoks      = s_tokens_relax,
602    ifhbox          = s_boxreference,
603    ifhmode         = false,
604    ifinalignment   = false,
605    ifincsname      = s_tokens_endcs,
606    ifinner         = false,
607    ifinsert        = s_integer,
608    ifintervaldim   = sequence(s_dimension,s_dimension,s_dimension),
609    ifintervalfloat = sequence(s_integer,s_integer,s_integer),
610    ifintervalnum   = sequence(s_float,s_float,s_float),
611    iflastnamedcs   = false,
612    ifmathparameter = s_integer,
613    ifmathstyle     = s_mathstyle,
614    ifmmode         = false,
615    ifnum           = sequence(s_integer,s_comparison,s_integer),
616    ifnumexpression = s_tokens_relax,
617    ifnumval        = s_tokens_or,
618    ifodd           = s_integer,
619    ifparameter     = s_parameter_or,
620    ifparameters    = false,
621    ifrelax         = s_token,
622    iftok           = s_tokens_relax,
623    iftrue          = false,
624    ifvbox          = s_boxreference,
625    ifvmode         = false,
626    ifvoid          = s_boxreference,
627    ifx             = s_token,
628    ifzerodim       = s_dimension,
629    ifzerofloat     = s_float,
630    ifzeronum       = s_integer,
631    ["or"]          = false,
632    ["orelse"]      = false,
633    ["orunless"]    = false,
634}
635
636syntax.ignoresomething = newsyntax {
637    ignorearguments  = false,
638    ignorenestedupto = s_token,
639    ignorepars       = false,
640    ignorerest       = false,
641    ignorespaces     = false,
642    ignoreupto       = s_token,
643}
644
645-- result.ignoresomething = newresult {
646--     -- TODO
647-- }
648
649syntax.input = newsyntax {
650    endinput      = false,
651    input         = s_filename,
652    eofinput      = sequence(s_tokens, s_filename),
653    scantokens    = s_tokens,
654    scantextokens = s_tokens,
655    tokenized     = s_tokens,
656    quitloop      = false,
657    quitloopnow   = false,
658    retokenized   = sequence(optional(keyword("catcodetable")),s_tokens),
659}
660
661syntax.insert = newsyntax {
662    insert = s_integer
663}
664
665result.internaldimension = {
666    boxmaxdepth              = r_dimension,
667    delimitershortfall       = r_dimension,
668    displayindent            = r_dimension,
669    displaywidth             = r_dimension,
670    emergencyextrastretch    = r_dimension,
671    emergencystretch         = r_dimension,
672    glyphxoffset             = r_dimension,
673    glyphyoffset             = r_dimension,
674    hangindent               = r_dimension,
675    hfuzz                    = r_dimension,
676    hsize                    = r_dimension,
677    ignoredepthcriterion     = r_dimension,
678    lineskiplimit            = r_dimension,
679    mathsurround             = r_dimension,
680    maxdepth                 = r_dimension,
681    nulldelimiterspace       = r_dimension,
682    overfullrule             = r_dimension,
683    pageextragoal            = r_dimension,
684    parindent                = r_dimension,
685    predisplaysize           = r_dimension,
686    pxdimen                  = r_dimension,
687    scriptspace              = r_dimension,
688    shortinlinemaththreshold = r_dimension,
689    splitmaxdepth            = r_dimension,
690    tabsize                  = r_dimension,
691    vfuzz                    = r_dimension,
692    vsize                    = r_dimension,
693}
694
695syntax.internaldimension = setsyntaxfromresult(result.internaldimension)
696
697result.internalglue = {
698    abovedisplayshortskip = r_glue,
699    abovedisplayskip      = r_glue,
700    additionalpageskip    = r_glue,
701    baselineskip          = r_glue,
702    belowdisplayshortskip = r_glue,
703    belowdisplayskip      = r_glue,
704    emergencyleftskip     = r_glue,
705    emergencyrightskip    = r_glue,
706    initialpageskip       = r_glue,
707    initialtopskip        = r_glue,
708    leftskip              = r_glue,
709    lineskip              = r_glue,
710    mathsurroundskip      = r_glue,
711    maththreshold         = r_glue,
712    parfillleftskip       = r_glue,
713    parfillrightskip      = r_glue,
714    parfillskip           = r_glue,
715    parinitleftskip       = r_glue,
716    parinitrightskip      = r_glue,
717    parskip               = r_glue,
718    rightskip             = r_glue,
719    spaceskip             = r_glue,
720    splittopskip          = r_glue,
721    tabskip               = r_glue,
722    topskip               = r_glue,
723    xspaceskip            = r_glue,
724}
725
726syntax.internalglue = setsyntaxfromresult(result.internalglue)
727
728result.internalinteger = {
729    adjdemerits              = r_integer,
730    adjustspacing            = r_integer,
731    adjustspacingshrink      = r_integer,
732    adjustspacingstep        = r_integer,
733    adjustspacingstretch     = r_integer,
734    alignmentcellsource      = r_integer,
735    alignmentwrapsource      = r_integer,
736    automatichyphenpenalty   = r_integer,
737    automigrationmode        = r_integer,
738    autoparagraphmode        = r_integer,
739    binoppenalty             = r_integer,
740    brokenpenalty            = r_integer,
741    catcodetable             = r_integer,
742    clubpenalty              = r_integer,
743    day                      = r_integer,
744    defaulthyphenchar        = r_integer,
745    defaultskewchar          = r_integer,
746    delimiterfactor          = r_integer,
747    discretionaryoptions     = r_integer,
748    displaywidowpenalty      = r_integer,
749    doubleadjdemerits        = r_integer,
750    doublehyphendemerits     = r_integer,
751    endlinechar              = r_integer,
752    errorcontextlines        = r_integer,
753    escapechar               = r_integer,
754    eufactor                 = r_integer,
755    exceptionpenalty         = r_integer,
756    exhyphenchar             = r_integer,
757    exhyphenpenalty          = r_integer,
758    explicithyphenpenalty    = r_integer,
759    fam                      = r_integer,
760    finalhyphendemerits      = r_integer,
761    firstvalidlanguage       = r_integer,
762    floatingpenalty          = r_integer,
763    globaldefs               = r_integer,
764    glyphdatafield           = r_integer,
765    glyphoptions             = r_integer,
766    glyphscale               = r_integer,
767    glyphscriptfield         = r_integer,
768    glyphscriptscale         = r_integer,
769    glyphscriptscriptscale   = r_integer,
770    glyphslant               = r_integer,
771    glyphstatefield          = r_integer,
772    glyphtextscale           = r_integer,
773    glyphxscale              = r_integer,
774    glyphyscale              = r_integer,
775    glyphweight              = r_integer,
776    hangafter                = r_integer,
777    hbadness                 = r_integer,
778    holdinginserts           = r_integer,
779    holdingmigrations        = r_integer,
780    hyphenationmode          = r_integer,
781    hyphenpenalty            = r_integer,
782    interlinepenalty         = r_integer,
783    language                 = r_integer,
784    lastlinefit              = r_integer,
785    lefthyphenmin            = r_integer,
786    linebreakcriterion       = r_integer,
787    linebreakoptional        = r_integer,
788    linebreakpasses          = r_integer,
789    linedirection            = r_integer,
790    linepenalty              = r_integer,
791    localbrokenpenalty       = r_integer,
792    localinterlinepenalty    = r_integer,
793    localpretolerance        = r_integer,
794    localtolerance           = r_integer,
795    looseness                = r_integer,
796    luacopyinputnodes        = r_integer,
797    mathbeginclass           = r_integer,
798    mathcheckfencesmode      = r_integer,
799    mathdictgroup            = r_integer,
800    mathdictproperties       = r_integer,
801    mathdirection            = r_integer,
802    mathdisplaymode          = r_integer,
803    mathdisplaypenaltyfactor = r_integer,
804    mathdisplayskipmode      = r_integer,
805    mathdoublescriptmode     = r_integer,
806    mathendclass             = r_integer,
807    matheqnogapstep          = r_integer,
808    mathfontcontrol          = r_integer,
809    mathgluemode             = r_integer,
810    mathgroupingmode         = r_integer,
811    mathinlinepenaltyfactor  = r_integer,
812    mathleftclass            = r_integer,
813    mathlimitsmode           = r_integer,
814    mathnolimitsmode         = r_integer,
815    mathpenaltiesmode        = r_integer,
816    mathpretolerance         = r_integer,
817    mathrightclass           = r_integer,
818    mathrulesfam             = r_integer,
819    mathrulesmode            = r_integer,
820    mathscriptsmode          = r_integer,
821    mathslackmode            = r_integer,
822    mathspacingmode          = r_integer,
823    mathsurroundmode         = r_integer,
824    mathtolerance            = r_integer,
825    maxdeadcycles            = r_integer,
826    month                    = r_integer,
827    newlinechar              = r_integer,
828    normalizelinemode        = r_integer,
829    normalizeparmode         = r_integer,
830    nospaces                 = r_integer,
831    orphanpenalty            = r_integer,
832    outputbox                = r_integer,
833    outputpenalty            = r_integer,
834    overloadmode             = r_integer,
835    parametermode            = r_integer,
836    pardirection             = r_integer,
837    pausing                  = r_integer,
838    postdisplaypenalty       = r_integer,
839    postinlinepenalty        = r_integer,
840    postshortinlinepenalty   = r_integer,
841    prebinoppenalty          = r_integer,
842    predisplaydirection      = r_integer,
843    predisplaygapfactor      = r_integer,
844    predisplaypenalty        = r_integer,
845    preinlinepenalty         = r_integer,
846    prerelpenalty            = r_integer,
847    preshortinlinepenalty    = r_integer,
848    pretolerance             = r_integer,
849    protrudechars            = r_integer,
850    relpenalty               = r_integer,
851    righthyphenmin           = r_integer,
852    savinghyphcodes          = r_integer,
853    savingvdiscards          = r_integer,
854    setfontid                = r_integer,
855    setlanguage              = r_integer,
856    shapingpenaltiesmode     = r_integer,
857    shapingpenalty           = r_integer,
858    shortinlineorphanpenalty = r_integer,
859    showboxbreadth           = r_integer,
860    showboxdepth             = r_integer,
861    shownodedetails          = r_integer,
862    singlelinepenalty        = r_integer,
863    spacefactormode          = r_integer,
864    spacefactorshrinklimit   = r_integer,
865    spacefactorstretchlimit  = r_integer,
866    supmarkmode              = r_integer,
867    textdirection            = r_integer,
868    time                     = r_integer,
869    tolerance                = r_integer,
870    tracingadjusts           = r_integer,
871    tracingalignments        = r_integer,
872    tracingassigns           = r_integer,
873    tracingcommands          = r_integer,
874    tracingexpressions       = r_integer,
875    tracingfullboxes         = r_integer,
876    tracinggroups            = r_integer,
877    tracinghyphenation       = r_integer,
878    tracingifs               = r_integer,
879    tracinginserts           = r_integer,
880    tracinglevels            = r_integer,
881    tracinglists             = r_integer,
882    tracinglostchars         = r_integer,
883    tracingmacros            = r_integer,
884    tracingmarks             = r_integer,
885    tracingmath              = r_integer,
886    tracingnesting           = r_integer,
887    tracingnodes             = r_integer,
888    tracingonline            = r_integer,
889    tracingoutput            = r_integer,
890    tracingpages             = r_integer,
891    tracingparagraphs        = r_integer,
892    tracingpasses            = r_integer,
893    tracingpenalties         = r_integer,
894    tracingrestores          = r_integer,
895    tracingstats             = r_integer,
896    uchyph                   = r_integer,
897    variablefam              = r_integer,
898    vbadness                 = r_integer,
899    widowpenalty             = r_integer,
900    year                     = r_integer,
901}
902
903syntax.internalinteger = setsyntaxfromresult(result.internalinteger)
904
905result.internalmuglue = {
906    medmuskip   = r_muglue,
907    pettymuskip = r_muglue,
908    thickmuskip = r_muglue,
909    thinmuskip  = r_muglue,
910    tinymuskip  = r_muglue,
911}
912
913syntax.internalmuglue = setsyntaxfromresult(result.internalmuglue)
914
915result.internaltoks = {
916    errhelp        = r_toks,
917    everybeforepar = r_toks,
918    everycr        = r_toks,
919    everydisplay   = r_toks,
920    everyeof       = r_toks,
921    everyhbox      = r_toks,
922    everyjob       = r_toks,
923    everymath      = r_toks,
924    everymathatom  = r_toks,
925    everypar       = r_toks,
926    everytab       = r_toks,
927    everyvbox      = r_toks,
928    output         = r_toks,
929}
930
931syntax.internaltoks = setsyntaxfromresult(result.internaltoks)
932
933syntax.italiccorrection = newsyntax {
934    ["/"]            = false,
935    italiccorrection = false,
936    leftcorrection   = false,
937    rightcorrection  = false,
938}
939
940syntax.kern = newsyntax {
941    kern  = s_dimension,
942    hkern = s_dimension,
943    vkern = s_dimension,
944}
945
946syntax.leader = newsyntax {
947    cleaders = sequence(choice(s_box,s_rule,s_glyph),s_glue),
948    gleaders = sequence(choice(s_box,s_rule,s_glyph),s_glue),
949    leaders  = sequence(choice(s_box,s_rule,s_glyph),s_glue),
950    uleaders = sequence(optional(sequence(keyword("callback"), s_integer)),choice(s_box,s_rule,s_glyph),s_glue),
951    xleaders = sequence(choice(s_box,s_rule,s_glyph),s_glue),
952}
953
954syntax.legacy = newsyntax {
955    shipout = s_tokens
956}
957
958syntax.let = newsyntax {
959    futuredef        = sequence(s_cs,s_cs),
960    futurelet        = sequence(s_cs,o_equal,s_cs),
961    glet             = s_cs,
962    gletcsname       = s_tokens_endcs,
963    glettonothing    = s_cs,
964    let              = s_cs,
965    letcharcode      = s_cs,
966    letcsname        = s_tokens_endcs,
967    letfrozen        = s_cs,
968    letprotected     = s_cs,
969    lettolastnamedcs = s_cs,
970    lettonothing     = s_cs,
971    swapcsvalues     = sequence(s_cs,s_cs),
972    unletfrozen      = s_cs,
973    unletprotected   = s_cs,
974}
975
976syntax.localbox = newsyntax {
977    localleftbox   = s_box,
978    localmiddlebox = s_box,
979    localrightbox  = s_box,
980}
981
982syntax.luafunctioncall = newsyntax {
983    luabytecodecall = s_integer,
984    luafunctioncall = s_integer,
985}
986
987do
988
989    local split = sequence(
990        optional(keyword("attr"),s_integer,s_integer),
991        optional(keyword("to"),s_dimension),
992        optional(keyword("upto"),s_dimension),
993        s_tokens
994    )
995
996    local make   = sequence(
997        optional(sequence(keyword("target"),s_integer)),
998        optional(sequence(keyword("to"),s_dimension)),
999        optional(sequence(keyword("adapt"),s_scale)),
1000        optional(sequence(keyword("attr"),s_integer,s_integer)),
1001        optional(sequence(keyword("anchor"),s_integer)),
1002        optional(sequence(keyword("axis"),s_integer)),
1003        optional(sequence(keyword("shift"),s_dimension)),
1004        optional(sequence(keyword("spread"),s_dimension)),
1005        optional(sequence(keyword("source"),s_integer)),
1006        optional(sequence(keyword("direction"),s_integer)),
1007        optional(keyword("delay")),
1008        optional(sequence(keyword("orientation"),s_integer)),
1009        optional(sequence(keyword("xoffset"),s_dimension)),
1010        optional(sequence(keyword("xmove"),s_dimension)),
1011        optional(sequence(keyword("yoffset"),s_dimension)),
1012        optional(sequence(keyword("ymove"),s_dimension)),
1013        optional(keyword("reverse")),
1014        optional(keyword("retain")),
1015        optional(keyword("container")),
1016        optional(sequence(keyword("class"),s_integer)),
1017        s_tokens
1018    )
1019
1020    syntax.makebox = newsyntax {
1021        box               = s_boxreference,
1022        copy              = s_boxreference,
1023        dbox              = make,
1024        dpack             = make,
1025        dsplit            = split,
1026        hbox              = make,
1027        hpack             = make,
1028        insertbox         = s_integer,
1029        insertcopy        = s_integer,
1030        lastbox           = false,
1031        localleftboxbox   = false,
1032        localmiddleboxbox = false,
1033        localrightboxbox  = false,
1034        tpack             = make,
1035        tsplit            = split,
1036        vbox              = make,
1037        vpack             = make,
1038        vsplit            = split,
1039        vtop              = make,
1040    }
1041
1042end
1043
1044syntax.mathaccent = newsyntax {
1045    mathaccent  = s_tokens, -- overloaded in conetext
1046    Umathaccent = sequence(
1047        optional(sequence(keyword("attr"),s_integer,s_integer)),
1048        optional(keyword("center")),
1049        optional(sequence(keyword("class"),s_integer)),
1050        optional(keyword("exact")),
1051        optional(sequence(keyword("source"),s_integer)),
1052        optional(keyword("stretch")),
1053        optional(keyword("shrink")),
1054        optional(sequence(keyword("fraction"),s_integer)),
1055        optional(keyword("fixed")),
1056        optional(keyword("keepbase")),
1057        optional(keyword("nooverflow")),
1058        optional(keyword("base")),
1059        choice(
1060            sequence(keyword("both"),optional(keyword("fixed")),s_character,optional(keyword("fixed")),s_character),
1061            sequence(keyword("bottom"),optional(keyword("fixed")),s_character),
1062            sequence(keyword("top"),optional(keyword("fixed")),s_character),
1063            sequence(keyword("overlay"),s_character),
1064            s_character
1065        )
1066    ),
1067}
1068
1069syntax.mathcharnumber = newsyntax {
1070    Umathchar      = s_integer,
1071    mathclass      = s_integer,
1072    mathdictionary = sequence(s_integer,s_mathchar),
1073    mathchar       = s_integer,
1074}
1075
1076syntax.mathchoice = newsyntax {
1077    mathdiscretionary = sequence(optional(sequence(keyword("class"),s_integer)),s_tokens,s_tokens,s_tokens),
1078    mathstack         = s_tokens,
1079    mathchoice        = sequence(s_tokens,s_tokens,s_tokens,s_tokens),
1080}
1081
1082syntax.mathcomponent = newsyntax {
1083    mathatom  = sequence(
1084        optional(sequence(keyword("attr"),s_integer,s_integer)),
1085        optional(sequence(keyword("all"),s_integer)),
1086        optional(sequence(keyword("leftclass"),s_integer)),
1087        optional(keyword("limits")),
1088        optional(sequence(keyword("rightclass"),s_integer)),
1089        optional(sequence(keyword("class"),s_integer)),
1090        optional(keyword("unpack")),
1091        optional(keyword("unroll")),
1092        optional(keyword("single")),
1093        optional(sequence(keyword("source"),s_integer)),
1094        optional(keyword("textfont")),
1095        optional(keyword("mathfont")),
1096        optional(sequence(keyword("options"),s_integer)),
1097        optional(keyword("nolimits")),
1098        optional(keyword("nooverflow")),
1099        optional(keyword("void")),
1100        optional(keyword("phantom")),
1101        optional(s_integer)
1102    ),
1103    mathbin   = s_tokens,
1104    mathclose = s_tokens,
1105    mathinner = s_tokens,
1106    mathop    = s_tokens,
1107    mathopen  = s_tokens,
1108    mathord   = s_tokens,
1109    mathpunct = s_tokens,
1110    mathrel   = s_tokens,
1111    overline  = s_tokens,
1112    underline = s_tokens,
1113}
1114
1115do
1116
1117    local fence = sequence(
1118        optional(keyword("auto")),
1119        optional(sequence(keyword("attr"),s_integer,s_integer)),
1120        optional(keyword("axis")),
1121        optional(sequence(keyword("bottom"),s_dimension)),
1122        optional(sequence(keyword("depth"),s_dimension)),
1123        optional(sequence(keyword("factor"),s_integer)),
1124        optional(sequence(keyword("height"),s_dimension)),
1125        optional(keyword("noaxis")),
1126        optional(keyword("nocheck")),
1127        optional(keyword("nolimits")),
1128        optional(keyword("nooverflow")),
1129        optional(sequence(keyword("leftclass"),s_integer)),
1130        optional(keyword("limits")),
1131        optional(keyword("exact")),
1132        optional(keyword("void")),
1133        optional(keyword("phantom")),
1134        optional(sequence(keyword("class"),s_integer)),
1135        optional(sequence(keyword("rightclass"),s_integer)),
1136        optional(keyword("scale")),
1137        optional(sequence(keyword("source"),s_integer)),
1138        optional(keyword("top")),
1139        s_delimiter
1140    )
1141
1142    syntax.mathfence = newsyntax {
1143        Uleft        = fence,
1144        Umiddle      = fence,
1145        Uoperator    = fence,
1146        Uright       = fence,
1147        Uvextensible = fence,
1148        left         = fence,
1149        middle       = fence,
1150        right        = fence,
1151    }
1152
1153end
1154
1155do
1156
1157    local options = sequence(
1158        optional(sequence(keyword("attr"),s_integer,s_integer)),
1159        optional(sequence(keyword("class"),s_integer)),
1160        optional(keyword("center")),
1161        optional(keyword("exact")),
1162        optional(keyword("proportional")),
1163        optional(keyword("noaxis")),
1164        optional(keyword("nooverflow")),
1165        optional(sequence(keyword("style"),s_mathstyle)),
1166        optional(sequence(keyword("source"),s_integer)),
1167        optional(sequence(keyword("hfactor"),s_integer)),
1168        optional(sequence(keyword("vfactor"),s_integer)),
1169        optional(keyword("font")),
1170        optional(sequence(keyword("thickness"),s_dimension))
1171    )
1172
1173    -- needs checking
1174
1175    syntax.mathfraction = newsyntax {
1176        Uabove               = sequence(s_dimension,options),
1177        Uabovewithdelims     = sequence(s_delimiter,s_delimiter,s_dimension,options),
1178        Uatop                = sequence(s_dimension,options),
1179        Uatopwithdelims      = sequence(s_delimiter,s_delimiter,s_dimension,options),
1180        Uover                = sequence(options),
1181        Uoverwithdelims      = sequence(s_delimiter,s_delimiter,options),
1182        Uskewed              = sequence(s_delimiter,options),
1183        Uskewedwithdelims    = sequence(s_delimiter,s_delimiter,s_delimiter,options),
1184        Ustretched           = sequence(s_delimiter,options),
1185        Ustretchedwithdelims = sequence(s_delimiter,s_delimiter,s_delimiter,options),
1186        above                = s_dimension,
1187        abovewithdelims      = sequence(s_delimiter,s_delimiter,s_dimension),
1188        atop                 = s_dimension,
1189        atopwithdelims       = sequence(s_delimiter,s_delimiter,s_dimension),
1190        over                 = false,
1191        overwithdelims       = sequence(s_delimiter,s_delimiter),
1192    }
1193
1194end
1195
1196syntax.mathmodifier = newsyntax {
1197    Umathadapttoleft  = false,
1198    Umathadapttoright = false,
1199    Umathlimits       = false,
1200    Umathnoaxis       = false,
1201    Umathnolimits     = false,
1202    Umathopenupdepth  = s_dimension,
1203    Umathopenupheight = s_dimension,
1204    Umathphantom      = false,
1205    Umathsource       = sequence(optional(s_nucleus),s_integer),
1206    Umathuseaxis      = false,
1207    Umathvoid         = false,
1208    displaylimits     = false,
1209    limits            = false,
1210    nolimits          = false,
1211}
1212
1213do
1214
1215    local options = sequence(
1216        optional(sequence(keyword("attr"),s_integer,s_integer)),
1217        optional(keyword("bottom")),
1218        optional(keyword("exact")),
1219        optional(keyword("top")),
1220        optional(sequence(keyword("style"),s_mathstyle)),
1221        optional(sequence(keyword("source"),s_integer)),
1222        optional(keyword("stretch")),
1223        optional(keyword("shrink")),
1224        optional(sequence(keyword("width"),s_dimension)),
1225        optional(sequence(keyword("height"),s_dimension)),
1226        optional(sequence(keyword("depth"),s_dimension)),
1227        optional(keyword("left")),
1228        optional(keyword("middle")),
1229        optional(keyword("right")),
1230        optional(keyword("nooverflow"))
1231    )
1232
1233    syntax.mathradical = newsyntax {
1234        Udelimited      = sequence(options,s_delimiter,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1235        Udelimiterover  = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1236        Udelimiterunder = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1237        Uhextensible    = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1238        Uoverdelimiter  = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1239        Uradical        = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1240        Uroot           = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens,s_mathtokens),
1241        Urooted         = sequence(options,s_delimiter,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens,s_mathtokens),
1242        Uunderdelimiter = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens),
1243        radical         = sequence(options,s_delimiter,optional(s_delimiter),optional(s_delimiter),s_mathtokens,s_mathtokens),
1244    }
1245
1246end
1247
1248syntax.mathscript = newsyntax {
1249    nosubprescript        = false,
1250    nosubscript           = false,
1251    nosuperprescript      = false,
1252    nosuperscript         = false,
1253    primescript           = s_mathtokens,
1254    shiftedsubprescript   = s_mathtokens,
1255    shiftedsubscript      = s_mathtokens,
1256    shiftedsuperprescript = s_mathtokens,
1257    shiftedsuperscript    = s_mathtokens,
1258    subprescript          = s_mathtokens,
1259    subscript             = s_mathtokens,
1260    superprescript        = s_mathtokens,
1261    superscript           = s_mathtokens,
1262    noatomruling          = false,
1263    nonscript             = false,
1264}
1265
1266syntax.mathshiftcs = newsyntax {
1267    Ustartdisplaymath = false,
1268    Ustartmath        = false,
1269    Ustartmathmode    = false,
1270    Ustopdisplaymath  = false,
1271    Ustopmath         = false,
1272    Ustopmathmode     = false,
1273}
1274
1275syntax.mathstyle = newsyntax {
1276    givenmathstyle           = s_mathstyle,
1277    allcrampedstyles         = false,
1278    alldisplaystyles         = false,
1279    allmainstyles            = false,
1280    allmathstyles            = false,
1281    allscriptscriptstyles    = false,
1282    allscriptstyles          = false,
1283    allsplitstyles           = false,
1284    alltextstyles            = false,
1285    alluncrampedstyles       = false,
1286    allunsplitstyles         = false,
1287    crampeddisplaystyle      = false,
1288    crampedscriptscriptstyle = false,
1289    crampedscriptstyle       = false,
1290    crampedtextstyle         = false,
1291    displaystyle             = false,
1292    scaledmathstyle          = s_integer,
1293    scriptscriptstyle        = false,
1294    scriptstyle              = false,
1295    textstyle                = false,
1296}
1297
1298result.mathstyle = setdefaultresult(result.mathstyle, r_integer)
1299
1300result.mathstyle.Ustyle          = { s_mathstyle, s_integer }
1301result.mathstyle.scaledmathstyle = { s_mathstyle, s_integer }
1302
1303syntax.message = newsyntax {
1304    message    = s_tokens,
1305    errmessage = s_tokens,
1306}
1307
1308syntax.mkern = newsyntax {
1309    mkern = s_dimension
1310}
1311
1312syntax.mskip = newsyntax {
1313    mathatomskip = s_muglue,
1314    mskip        = s_muglue,
1315}
1316
1317syntax.noexpand = newsyntax {
1318    noexpand = s_token
1319}
1320
1321syntax.parameter = newsyntax {
1322    alignmark     = false,
1323    parametermark = false,
1324}
1325
1326syntax.penalty = newsyntax {
1327    hpenalty = s_integer,
1328    penalty  = s_integer,
1329    vpenalty = s_integer,
1330}
1331
1332syntax.prefix = newsyntax {
1333    aliased       = false,
1334    constant      = false,
1335    constrained   = false,
1336    deferred      = false,
1337    enforced      = false,
1338    frozen        = false,
1339    global        = false,
1340    immediate     = false,
1341    immutable     = false,
1342    inherited     = false,
1343    instance      = false,
1344    long          = false,
1345    mutable       = false,
1346    noaligned     = false,
1347    outer         = false,
1348    overloaded    = false,
1349    permanent     = false,
1350    protected     = false,
1351    retained      = false,
1352    semiprotected = false,
1353    tolerant      = false,
1354    untraced      = false,
1355}
1356
1357syntax.register = newsyntax {
1358    count     = sequence(s_boxreference,o_equal,s_integer),
1359    attribute = sequence(s_boxreference,o_equal,s_integer),
1360    dimen     = sequence(s_boxreference,o_equal,s_dimension),
1361    skip      = sequence(s_boxreference,o_equal,s_glue),
1362    muskip    = sequence(s_boxreference,o_equal,s_muglue),
1363    toks      = sequence(s_boxreference,o_equal,s_tokens),
1364    float     = sequence(s_boxreference,o_equal,s_float),
1365}
1366
1367result.register = newresult {
1368    count     =  { s_boxreference, s_integer },
1369    attribute =  { s_boxreference, s_integer },
1370    dimen     =  { s_boxreference, s_dimension },
1371    skip      =  { s_boxreference, s_glue },
1372    muskip    =  { s_boxreference, s_muglue },
1373    toks      =  { s_boxreference, s_tokens },
1374    float     =  { s_boxreference, s_float },
1375}
1376
1377syntax.relax = newsyntax {
1378    norelax = false,
1379    relax   = false,
1380}
1381
1382syntax.removeitem = newsyntax {
1383    unboundary = false,
1384    unkern     = false,
1385    unpenalty  = false,
1386    unskip     = false,
1387}
1388
1389syntax.auxiliary = newsyntax {
1390    insertmode      = s_integer,
1391    interactionmode = s_integer,
1392    prevdepth       = s_dimension,
1393    prevgraf        = s_integer,
1394    spacefactor     = s_integer,
1395}
1396
1397result.auxiliary = newresult {
1398    insertmode      = r_integer,
1399    interactionmode = r_integer,
1400    prevdepth       = r_dimension,
1401    prevgraf        = r_integer,
1402    spacefactor     = r_integer,
1403}
1404
1405syntax.setbox = newsyntax {
1406    setbox = sequence(s_boxreference,o_equal,o_box)
1407}
1408
1409syntax.boxproperty = newsyntax {
1410    boxadapt       = sequence(s_boxreference,o_equal,s_integer), -- scaled
1411    boxanchor      = sequence(s_boxreference,o_equal,s_integer),
1412    boxanchors     = sequence(s_boxreference,o_equal,s_integer,s_integer), -- check
1413    boxattribute   = sequence(s_boxreference,s_integer,o_equal,s_integer),
1414    boxdirection   = sequence(s_boxreference,o_equal,s_integer),
1415    boxfreeze      = sequence(s_boxreference,o_equal,s_integer),
1416    boxfinalize    = sequence(s_boxreference,o_equal,s_integer),
1417    boxgeometry    = sequence(s_boxreference,o_equal,s_integer),
1418    boxlimitate    = sequence(s_boxreference,o_equal,s_integer),
1419    boxorientation = sequence(s_boxreference,o_equal,s_integer),
1420    boxrepack      = s_boxreference,
1421    boxshift       = sequence(s_boxreference,o_equal,s_dimension),
1422    boxshrink      = s_boxreference,
1423    boxsource      = sequence(s_boxreference,o_equal,s_integer),
1424    boxstretch     = s_boxreference,
1425    boxtarget      = sequence(s_boxreference,o_equal,s_integer),
1426    boxtotal       = s_boxreference,
1427    boxvadjust     = sequence(s_boxreference,s_tokens), -- todo: pre/post etc
1428    boxxmove       = sequence(s_boxreference,o_equal,s_dimension),
1429    boxxoffset     = sequence(s_boxreference,o_equal,s_dimension),
1430    boxymove       = sequence(s_boxreference,o_equal,s_dimension),
1431    boxyoffset     = sequence(s_boxreference,o_equal,s_dimension),
1432    dp             = sequence(s_boxreference,o_equal,s_dimension),
1433    ht             = sequence(s_boxreference,o_equal,s_dimension),
1434    wd             = sequence(s_boxreference,o_equal,s_dimension),
1435}
1436
1437-- boxadapt   : zero
1438-- boxfreeze  : width or total
1439-- boxrepack  : width or total
1440-- boxvadjust : 0x1 = preadjust 0x2 = postadjust 0x4 = premigrate 0x8 = postmigrate
1441
1442result.boxproperty = newresult {
1443    boxadapt       = { s_boxreference, s_dimension },
1444    boxanchor      = { s_boxreference, s_integer },
1445    boxanchors     = { s_boxreference, s_integer },
1446    boxattribute   = { sequence(s_boxreference,s_integer), s_integer },
1447    boxdirection   = { s_boxreference, s_integer },
1448    boxfreeze      = { s_boxreference, s_integer },
1449    boxgeometry    = { s_boxreference, s_integer },
1450    boxlimitate    = { s_boxreference, s_integer },
1451    boxorientation = { s_boxreference, s_integer },
1452    boxrepack      = { s_boxreference, s_dimension },
1453    boxshift       = { s_boxreference, s_dimension },
1454    boxshrink      = { s_boxreference, s_dimension },
1455    boxsource      = { s_boxreference, s_integer },
1456    boxstretch     = { s_boxreference, s_dimension },
1457    boxtarget      = { s_boxreference, s_integer },
1458    boxtotal       = { s_boxreference, s_dimension },
1459    boxvadjust     = { s_boxreference, s_cardinal },
1460    boxxmove       = { s_boxreference, s_dimension },
1461    boxxoffset     = { s_boxreference, s_dimension },
1462    boxymove       = { s_boxreference, s_dimension },
1463    boxyoffset     = { s_boxreference, s_dimension },
1464    dp             = { s_boxreference, s_dimension },
1465    ht             = { s_boxreference, s_dimension },
1466    wd             = { s_boxreference, s_dimension },
1467}
1468
1469syntax.setfont = newsyntax {
1470    nullfont = false,
1471}
1472
1473result.setresult.setfont = newresult {
1474    nullfont = r_tokens,
1475}
1476
1477
1478syntax.fontproperty = newsyntax {
1479    cfcode          = sequence(s_font,s_integer,o_equal,s_integer),
1480    efcode          = sequence(s_font,s_integer,o_equal,s_integer),
1481    fontdimen       = sequence(s_font,s_integer,o_equal,s_dimension),
1482    hyphenchar      = sequence(s_font,o_equal,s_integer),
1483    lpcode          = sequence(s_font,s_integer,o_equal,s_dimension),
1484    rpcode          = sequence(s_font,s_integer,o_equal,s_dimension),
1485    scaledfontdimen = sequence(s_font,o_equal,s_integer),
1486    skewchar        = sequence(s_font,o_equal,s_integer),
1487}
1488
1489result.fontproperty = newresult {
1490    cfcode          = { sequence(s_font,s_integer), s_integer },
1491    efcode          = { sequence(s_font,s_integer), s_integer },
1492    fontdimen       = { sequence(s_font,s_integer), s_dimension },
1493    hyphenchar      = { s_font, s_integer },
1494    lpcode          = { sequence(s_font,s_integer), s_dimension },
1495    rpcode          = { sequence(s_font,s_integer), s_dimension },
1496    scaledfontdimen = { s_font, s_integer },
1497    skewchar        = { s_font, s_integer },
1498}
1499
1500syntax.interaction = newsyntax {
1501    batchmode     = false,
1502    errorstopmode = false,
1503    nonstopmode   = false,
1504    scrollmode    = false,
1505}
1506
1507syntax.mark = newsyntax {
1508    clearmarks = s_integer,
1509    flushmarks = false,
1510    mark       = s_tokens,
1511    marks      = sequence(s_integer,s_tokens),
1512    setmarks   = s_integer,
1513}
1514
1515
1516do
1517
1518    local dimension = { s_mathstyle, s_dimension }
1519    local integer   = { s_mathstyle, s_integer }
1520    local variant   = { "", s_mathstyle }
1521
1522
1523    result.mathparameter = newresult {
1524        Umathaccentbasedepth                = dimension,
1525        Umathaccentbaseheight               = dimension,
1526        Umathaccentbottomovershoot          = dimension,
1527        Umathaccentbottomshiftdown          = dimension,
1528        Umathaccentextendmargin             = dimension,
1529        Umathaccentsuperscriptdrop          = dimension,
1530        Umathaccentsuperscriptpercent       = integer,
1531        Umathaccenttopovershoot             = dimension,
1532        Umathaccenttopshiftup               = dimension,
1533        Umathaccentvariant                  = variant,
1534        Umathaxis                           = dimension,
1535        Umathbottomaccentvariant            = variant,
1536        Umathconnectoroverlapmin            = dimension,
1537        Umathdegreevariant                  = variant,
1538        Umathdelimiterextendmargin          = dimension,
1539        Umathdelimiterovervariant           = variant,
1540        Umathdelimiterpercent               = integer,
1541        Umathdelimitershortfall             = dimension,
1542        Umathdelimiterundervariant          = variant,
1543        Umathdenominatorvariant             = variant,
1544        Umathexheight                       = dimension,
1545        Umathextrasubpreshift               = dimension,
1546        Umathextrasubprespace               = dimension,
1547        Umathextrasubshift                  = dimension,
1548        Umathextrasubspace                  = dimension,
1549        Umathextrasuppreshift               = dimension,
1550        Umathextrasupprespace               = dimension,
1551        Umathextrasupshift                  = dimension,
1552        Umathextrasupspace                  = dimension,
1553        Umathflattenedaccentbasedepth       = dimension,
1554        Umathflattenedaccentbaseheight      = dimension,
1555        Umathflattenedaccentbottomshiftdown = dimension,
1556        Umathflattenedaccenttopshiftup      = dimension,
1557        Umathfractiondelsize                = dimension,
1558        Umathfractiondenomdown              = dimension,
1559        Umathfractiondenomvgap              = dimension,
1560        Umathfractionnumup                  = dimension,
1561        Umathfractionnumvgap                = dimension,
1562        Umathfractionrule                   = dimension,
1563        Umathfractionvariant                = variant,
1564        Umathhextensiblevariant             = variant,
1565        Umathlimitabovebgap                 = dimension,
1566        Umathlimitabovekern                 = dimension,
1567        Umathlimitabovevgap                 = dimension,
1568        Umathlimitbelowbgap                 = dimension,
1569        Umathlimitbelowkern                 = dimension,
1570        Umathlimitbelowvgap                 = dimension,
1571        Umathnolimitsubfactor               = integer,
1572        Umathnolimitsupfactor               = integer,
1573        Umathnumeratorvariant               = variant,
1574        Umathoperatorsize                   = dimension,
1575        Umathoverbarkern                    = dimension,
1576        Umathoverbarrule                    = dimension,
1577        Umathoverbarvgap                    = dimension,
1578        Umathoverdelimiterbgap              = dimension,
1579        Umathoverdelimitervariant           = variant,
1580        Umathoverdelimitervgap              = dimension,
1581        Umathoverlayaccentvariant           = variant,
1582        Umathoverlinevariant                = variant,
1583        Umathpresubshiftdistance            = dimension,
1584        Umathpresupshiftdistance            = dimension,
1585        Umathprimeraise                     = dimension,
1586        Umathprimeraisecomposed             = dimension,
1587        Umathprimeshiftdrop                 = dimension,
1588        Umathprimeshiftup                   = dimension,
1589        Umathprimespaceafter                = dimension,
1590        Umathprimevariant                   = variant,
1591        Umathprimewidth                     = dimension,
1592        Umathquad                           = dimension,
1593        Umathradicaldegreeafter             = dimension,
1594        Umathradicaldegreebefore            = dimension,
1595        Umathradicaldegreeraise             = dimension,
1596        Umathradicalextensibleafter         = dimension,
1597        Umathradicalextensiblebefore        = dimension,
1598        Umathradicalkern                    = dimension,
1599        Umathradicalrule                    = dimension,
1600        Umathradicalvariant                 = variant,
1601        Umathradicalvgap                    = dimension,
1602        Umathruledepth                      = dimension,
1603        Umathruleheight                     = dimension,
1604        Umathskeweddelimitertolerance       = dimension,
1605        Umathskewedfractionhgap             = dimension,
1606        Umathskewedfractionvgap             = dimension,
1607        Umathspaceafterscript               = dimension,
1608        Umathspacebeforescript              = dimension,
1609        Umathstackdenomdown                 = dimension,
1610        Umathstacknumup                     = dimension,
1611        Umathstackvariant                   = variant,
1612        Umathstackvgap                      = dimension,
1613        Umathsubscriptvariant               = variant,
1614        Umathsubshiftdistance               = dimension,
1615        Umathsubshiftdown                   = dimension,
1616        Umathsubshiftdrop                   = dimension,
1617        Umathsubsupshiftdown                = dimension,
1618        Umathsubsupvgap                     = dimension,
1619        Umathsubtopmax                      = dimension,
1620        Umathsupbottommin                   = dimension,
1621        Umathsuperscriptvariant             = dimension,
1622        Umathsupshiftdistance               = dimension,
1623        Umathsupshiftdrop                   = dimension,
1624        Umathsupshiftup                     = dimension,
1625        Umathsupsubbottommax                = dimension,
1626        Umathtopaccentvariant               = variant,
1627        Umathunderbarkern                   = dimension,
1628        Umathunderbarrule                   = dimension,
1629        Umathunderbarvgap                   = dimension,
1630        Umathunderdelimiterbgap             = dimension,
1631        Umathunderdelimitervariant          = variant,
1632        Umathunderdelimitervgap             = dimension,
1633        Umathunderlinevariant               = variant,
1634        Umathvextensiblevariant             = variant,
1635        Umathxscale                         = integer,
1636        Umathyscale                         = integer,
1637
1638        copymathatomrule                    = false, -- todo
1639        copymathparent                      = false, -- todo
1640        copymathspacing                     = false, -- todo
1641        letmathatomrule                     = false, -- todo
1642        letmathparent                       = false, -- todo
1643        letmathspacing                      = false, -- todo
1644        resetmathspacing                    = false,
1645        setdefaultmathcodes                 = false,
1646        setmathatomrule                     = false, -- todo
1647        setmathdisplaypostpenalty           = false, -- todo
1648        setmathdisplayprepenalty            = false, -- todo
1649        setmathignore                       = false, -- todo
1650        setmathoptions                      = false, -- todo
1651        setmathpostpenalty                  = false, -- todo
1652        setmathprepenalty                   = false, -- todo
1653        setmathspacing                      = false, -- todo
1654    }
1655
1656    local s = setsyntaxfromresult(result.mathparameter)
1657
1658    s.copymathatomrule          = sequence(s_integer,s_integer)
1659    s.copymathparent            = sequence(s_integer,s_integer)
1660    s.copymathspacing           = sequence(s_integer,s_integer)
1661    s.letmathatomrule           = sequence(s_integer,s_integer,s_integer,s_integer,s_integer)
1662    s.letmathparent             = sequence(s_integer,s_integer)
1663    s.letmathspacing            = sequence(s_integer,s_integer,s_integer,s_integer,s_integer)
1664    s.resetmathspacing          = false
1665    s.setdefaultmathcodes       = false
1666    s.setmathatomrule           = sequence(s_integer,s_integer,s_mathstyle,s_integer,s_integer)
1667    s.setmathdisplaypostpenalty = sequence(s_integer,o_equal,s_integer)
1668    s.setmathdisplayprepenalty  = sequence(s_integer,o_equal,s_integer)
1669    s.setmathignore             = sequence(s_mathparameter,s_integer)
1670    s.setmathoptions            = sequence(s_integer,o_equal,s_integer)
1671    s.setmathpostpenalty        = sequence(s_integer,o_equal,s_integer)
1672    s.setmathprepenalty         = sequence(s_integer,o_equal,s_integer)
1673    s.setmathspacing            = sequence(s_integer,s_integer,s_mathstyle,s_glue)
1674
1675    syntax.mathparameter = s
1676
1677end
1678
1679do
1680
1681    result.pageproperty = newresult {
1682        deadcycles           = r_integer,
1683        insertdepth          = { s_integer, s_dimension },
1684        insertdistance       = { s_integer, s_dimension },
1685        insertheight         = { s_integer, s_dimension },
1686        insertheights        = r_dimension,
1687        insertlimit          = { s_integer, s_dimension },
1688        insertmaxdepth       = { s_integer, s_dimension },
1689        insertmultiplier     = { s_integer, s_integer },
1690        insertpenalties      = r_integer,
1691        insertpenalty        = { s_integer, s_integer },
1692        insertstorage        = { s_integer, s_integer },
1693        insertstoring        = r_integer,
1694        insertwidth          = { s_integer, s_dimension },
1695        pagedepth            = r_dimension,
1696        pageexcess           = r_dimension,
1697        pagefilllstretch     = r_dimension,
1698        pagefillstretch      = r_dimension,
1699        pagefilstretch       = r_dimension,
1700        pagefistretch        = r_dimension,
1701        pagegoal             = r_dimension,
1702        pagelastdepth        = r_dimension,
1703        pagelastfilllstretch = r_dimension,
1704        pagelastfillstretch  = r_dimension,
1705        pagelastfilstretch   = r_dimension,
1706        pagelastheight       = r_dimension,
1707        pagelastshrink       = r_dimension,
1708        pagelaststretch      = r_dimension,
1709        pageshrink           = r_dimension,
1710        pagestretch          = r_dimension,
1711        pagetotal            = r_dimension,
1712        pagevsize            = r_dimension,
1713    }
1714
1715    syntax.pageproperty = setsyntaxfromresult(result.pageproperty)
1716
1717end
1718
1719syntax.specification = newsyntax {
1720    clubpenalties         = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1721    displaywidowpenalties = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1722    interlinepenalties    = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1723    mathbackwardpenalties = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1724    mathforwardpenalties  = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1725    orphanpenalties       = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1726    parpasses             = sequence(
1727                                optional(keyword("options"),s_integer),
1728                                repeated(
1729                                    optional(sequence(keyword("adjdemerits"),s_integer)),
1730                                    optional(sequence(keyword("adjustspacing"),s_integer)),
1731                                    optional(sequence(keyword("adjustspacingstep"),s_integer)),
1732                                    optional(sequence(keyword("adjustspacingshrink"),s_integer)),
1733                                    optional(sequence(keyword("adjustspacingstretch"),s_integer)),
1734                                    optional(sequence(keyword("badness"),s_integer)),
1735                                    optional(sequence(keyword("classes"),s_integer)),
1736                                    optional(sequence(keyword("callback"),s_integer)),
1737                                    optional(sequence(keyword("doubleadjdemerits"),s_integer)),
1738                                    optional(sequence(keyword("doublehyphendemerits"),s_integer)),
1739                                    optional(sequence(keyword("emergencystretch"),s_dimension)),
1740                                    optional(sequence(keyword("extrahyphenpenalty"),s_integer)),
1741                                    optional(sequence(keyword("finalhyphendemerits"),s_integer)),
1742                                    optional(sequence(keyword("identifier"),s_integer)),
1743                                    optional(sequence(keyword("ifadjustspacing"),s_integer)),
1744                                    optional(sequence(keyword("looseness"),s_integer)),
1745                                    optional(sequence(keyword("linebreakcriterium"),s_integer)),
1746                                    optional(sequence(keyword("linebreakoptional"),s_integer)),
1747                                    optional(sequence(keyword("linepenalty"),s_integer)),
1748                                    optional(keyword("next")),
1749                                    optional(sequence(keyword("orphanpenalty"),s_integer)),
1750                                    optional(keyword("quit")),
1751                                    optional(keyword("skip")),
1752                                    optional(sequence(keyword("threshold"),s_dimension)),
1753                                    optional(sequence(keyword("tolerance"),s_integer))
1754                                )
1755                            ),
1756    parshape              = sequence(optional(keyword("options"),s_integer),s_integer,repeated(sequence(s_dimension,s_dimension))),
1757    widowpenalties        = sequence(optional(keyword("options"),s_integer),s_integer,repeated(s_integer)),
1758}
1759
1760result.specification = setdefaultresult(syntax.specification, r_integer)
1761
1762syntax.shorthanddef = newsyntax {
1763    Umathchardef  = sequence(s_cs,s_integer),
1764    Umathdictdef  = sequence(s_cs,s_integer,s_integer),
1765    attributedef  = sequence(s_cs,s_integer),
1766    chardef       = sequence(s_cs,s_integer),
1767    countdef      = sequence(s_cs,s_integer),
1768    dimendef      = sequence(s_cs,s_integer),
1769    dimensiondef  = sequence(s_cs,s_integer),
1770    floatdef      = sequence(s_cs,s_integer),
1771    fontspecdef   = sequence(s_cs,s_font),
1772    gluespecdef   = sequence(s_cs,s_integer),
1773    integerdef    = sequence(s_cs,s_integer),
1774    luadef        = sequence(s_cs,s_integer),
1775    mathchardef   = sequence(s_cs,s_integer),
1776    mugluespecdef = sequence(s_cs,s_integer),
1777    muskipdef     = sequence(s_cs,s_integer),
1778    parameterdef  = sequence(s_cs,s_integer),
1779    positdef      = sequence(s_cs,s_integer),
1780    skipdef       = sequence(s_cs,s_integer),
1781    toksdef       = sequence(s_cs,s_integer),
1782}
1783
1784result.someitem = newresult {
1785    mathcharclass          = { s_integer, s_integer },
1786    mathcharfam            = { s_integer, s_integer },
1787    mathcharslot           = { s_integer, s_integer },
1788    badness                = { "", s_integer },
1789    currentgrouplevel      = { "", s_integer },
1790    currentgrouptype       = { "", s_integer },
1791    currentifbranch        = { "", s_integer },
1792    currentiflevel         = { "", s_integer },
1793    currentiftype          = { "", s_integer },
1794    currentloopiterator    = { "", s_integer },
1795    currentloopnesting     = { "", s_integer },
1796    currentstacksize       = { "", s_integer },
1797    dimexpr                = { s_expression, s_dimension },
1798    dimexpression          = { s_expression, s_dimension },
1799    floatexpr              = { s_expression, s_float },
1800    fontcharba             = { s_fontchar, s_dimension },
1801    fontchardp             = { s_fontchar, s_dimension },
1802    fontcharht             = { s_fontchar, s_dimension },
1803    fontcharic             = { s_fontchar, s_dimension },
1804    fontcharta             = { s_fontchar, s_dimension },
1805    fontcharwd             = { s_fontchar, s_dimension },
1806    fontid                 = { s_font, s_integer },
1807    fontmathcontrol        = { s_font, s_integer },
1808    fontspecid             = { s_font, s_integer },
1809    fontspecifiedsize      = { s_font, s_integer },
1810    fontspecscale          = { s_font, s_integer },
1811    fontspecslant          = { s_font, s_integer },
1812    fontspecxscale         = { s_font, s_integer },
1813    fontspecyscale         = { s_font, s_integer },
1814    fontspecweight         = { s_font, s_integer },
1815    fonttextcontrol        = { s_font, s_integer },
1816    glueexpr               = { s_expression, s_glue },
1817    glueshrink             = { s_glue, s_dimension },
1818    glueshrinkorder        = { s_glue, s_dimension },
1819    gluestretch            = { s_glue, s_integer},
1820    gluestretchorder       = { s_glue, s_integer},
1821    gluetomu               = { s_glue, s_glue },
1822    glyphxscaled           = { "", s_integer },
1823    glyphyscaled           = { "", s_integer },
1824    indexofcharacter       = { s_integer, s_integer },
1825    indexofregister        = { s_integer, s_integer },
1826    inputlineno            = { "",s_integer },
1827    insertprogress         = { s_integer, s_dimension },-- check
1828    lastarguments          = { "", s_integer },
1829    lastatomclass          = { "", s_integer },
1830    lastboundary           = { "", s_integer },
1831    lastchkdimension       = { "", s_dimension },
1832    lastchknumber          = { "", s_integer },
1833    lastkern               = { "", s_dimension },
1834    lastleftclass          = { "", s_integer },
1835    lastloopiterator       = { "", s_integer },
1836    lastnodesubtype        = { "", s_integer },
1837    lastnodetype           = { "", s_integer },
1838    lastpageextra          = { "", s_dimension },
1839    lastparcontext         = { "", s_integer },
1840    lastpenalty            = { "", s_integer },
1841    lastrightclass         = { "", s_integer },
1842    lastskip               = { "", s_glue },
1843    leftmarginkern         = { "", s_dimension }, -- check
1844    luatexrevision         = { "", s_tokens },
1845    luatexversion          = { "", s_tokens },
1846    mathatomglue           = { "", s_glue },
1847    mathmainstyle          = { "", s_integer },
1848    mathscale              = { "", s_integer },
1849    mathstackstyle         = { "", s_integer },
1850    mathstyle              = { "", s_integer },
1851    mathstylefontid        = { "", s_integer },
1852    muexpr                 = { s_expression, s_muglue },
1853    mutoglue               = { s_muglue, s_glue },
1854    nestedloopiterator     = { "", s_integer },
1855    numericscale           = { s_number, s_integer },
1856    numericscaled          = { s_number, s_integer },
1857    numexpr                = { s_expression, s_integer },
1858    numexpression          = { s_expression, s_integer },
1859    overshoot              = { "", s_dimension },
1860    parametercount         = { "", s_integer },
1861    parameterindex         = { "", s_integer },
1862    parshapedimen          = { s_integer, s_dimension },
1863    parshapeindent         = { s_integer, s_dimension },
1864    parshapelength         = { "", s_dimension },
1865    previousloopiterator   = { "", s_integer },
1866    rightmarginkern        = { "", s_dimension }, -- check
1867    scaledemwidth          = { s_font, s_dimension },
1868    scaledexheight         = { s_font, s_dimension },
1869    scaledextraspace       = { s_font, s_dimension },
1870    scaledfontcharba       = { s_fontchar, s_dimension },
1871    scaledfontchardp       = { s_fontchar, s_dimension },
1872    scaledfontcharht       = { s_fontchar, s_dimension },
1873    scaledfontcharic       = { s_fontchar, s_dimension },
1874    scaledfontcharta       = { s_fontchar, s_dimension },
1875    scaledfontcharwd       = { s_fontchar, s_dimension },
1876    scaledinterwordshrink  = { s_font, s_dimension },
1877    scaledinterwordspace   = { s_font, s_dimension },
1878    scaledinterwordstretch = { s_font, s_dimension },
1879    scaledmathaxis         = { s_mathstyle, s_dimension },
1880    scaledmathemwidth      = { s_mathstyle, s_dimension },
1881    scaledmathexheight     = { s_mathstyle, s_dimension },
1882    scaledslantperpoint    = { s_font, s_dimension },
1883}
1884
1885syntax.someitem = setsyntaxfromresult(result.someitem)
1886
1887syntax.the = newsyntax {
1888    detokenize                  = s_tokens,
1889    expandeddetokenize          = s_tokens,
1890    protecteddetokenize         = s_tokens,
1891    protectedexpandeddetokenize = s_tokens,
1892    the                         = s_dimension,
1893    thewithoutunit              = s_quantity,
1894    unexpanded                  = s_tokens,
1895}
1896
1897syntax.unhbox = newsyntax {
1898    unhbox  = s_integer,
1899    unhcopy = s_integer,
1900    unhpack = s_integer,
1901}
1902
1903syntax.unvbox = newsyntax {
1904    insertunbox   = s_integer,
1905    insertuncopy  = s_integer,
1906    pagediscards  = false,
1907    splitdiscards = false,
1908    unvbox        = s_integer,
1909    unvcopy       = s_integer,
1910    unvpack       = s_integer,
1911}
1912
1913syntax.vadjust = newsyntax {
1914    vadjust = sequence(
1915        optional(keyword("pre")),
1916        optional(keyword("post")),
1917        optional(keyword("baseline")),
1918        optional(keyword("before")),
1919        optional(sequence(keyword("index"),s_integer)),
1920        optional(keyword("after")),
1921        optional(sequence(keyword("attr"),s_integer,s_integer)),
1922        optional(sequence(keyword("depth"),choice(keyword("after"),keyword("before"),keyword("check"),keyword("last")))),
1923        s_tokens
1924    )
1925}
1926
1927syntax.valign = newsyntax {
1928    valign = syntax.halign.halign
1929}
1930
1931syntax.vcenter = newsyntax {
1932    vcenter = syntax.makebox.dbox
1933}
1934
1935syntax.vmove = newsyntax {
1936    raise = syntax.hmove.moveleft,
1937    lower = syntax.hmove.moveright,
1938}
1939
1940syntax.vrule = newsyntax {
1941    novrule      = syntax.hrule.hrule,
1942    srule        = syntax.hrule.hrule,
1943    virtualvrule = syntax.hrule.virtualhrule,
1944    vrule        = syntax.hrule.hrule,
1945}
1946
1947syntax.vskip = newsyntax {
1948   vfil    = false,
1949   vfill   = false,
1950   vfilneg = false,
1951   vskip   = syntax.hskip.hskip,
1952   vss     = false,
1953}
1954
1955syntax.xray = newsyntax {
1956    show       = s_token,
1957    showbox    = s_boxreference,
1958    showgroups = false,
1959    showifs    = false,
1960    showlists  = false,
1961    showstack  = false,
1962    showthe    = s_quantity,
1963    showtokens = s_tokens,
1964}
1965
1966-- so far
1967
1968local striplines = utilities.strings.striplines
1969
1970for cmd, chrs in next, syntax do
1971    for chr, str in next, chrs do
1972        if not str then
1973            chrs[chr] = ""
1974        elseif str ~= "" then
1975            chrs[chr] = striplines(str,"prune and to space")
1976        end
1977    end
1978end
1979
1980for cmd, chrs in next, result do
1981    for chr, str in next, chrs do
1982        if str then
1983            local s1 = str[1]
1984            local s2 = str[2]
1985            if not s1 then
1986                str[1] = ""
1987            elseif s1 ~= "" then
1988                str[1] = striplines(s1,"prune and to space")
1989            end
1990            if not s2 then
1991                str[2] = ""
1992            elseif s2 ~= "" then
1993                str[2] = striplines(s2,"prune and to space")
1994            end
1995        end
1996    end
1997end
1998
1999-- end of syntax specification
2000
2001do
2002
2003    local P   = lpeg.P
2004    local R   = lpeg.R
2005    local Cmt = lpeg.Cmt
2006
2007    local space   = lpeg.patterns.whitespace
2008    local unspace = lpeg.patterns.whitespace^0
2009    local word    = R("az","AZ")^1
2010    local utfchar = lpeg.patterns.utf8character
2011
2012    local p_enhance = (
2013                  P("[") * unspace / "" / context.SyntaxLeftBracket
2014      + unspace * P("]")           / "" / context.SyntaxRightBracket
2015      +           P("{") * unspace / "" / context.SyntaxLeftBrace
2016      + unspace * P("}")           / "" / context.SyntaxRightBrace
2017      +           P("(") * unspace / "" / context.SyntaxLeftParenthesis
2018      + unspace * P(")")           / "" / context.SyntaxRightParenthesis
2019      + unspace * P("|") * unspace / "" / context.SyntaxBar
2020      + P("character")   / context.SyntaxCharacter
2021      + P("token")       / context.SyntaxToken
2022      + P("tokens")      / context.SyntaxTokens
2023      + P("integer")     / context.SyntaxInteger
2024      + P("quantity")    / context.SyntaxQuantity
2025      + P("preamble")    / context.SyntaxPreamble
2026      + P("dimension")   / context.SyntaxDimension
2027      + P("glue")        / context.SyntaxGlue
2028      + P("muglue")      / context.SyntaxMuglue
2029      + P("float")       / context.SyntaxFloat
2030      + P("font")        / context.SyntaxFont
2031      + P("mathstyle")   / context.SyntaxMathstyle
2032      + P("tokenlist")   / context.SyntaxTokenlist
2033      + P("box")         / context.SyntaxBox
2034      + P("rule")        / context.SyntaxRule
2035      + P("toks")        / context.SyntaxToks
2036      + P("float")       / context.SyntaxFloat
2037      + P("cs")          / context.SyntaxCs
2038      + P("conditional") / context.SyntaxConditional
2039      + P("\\") * (word  / context.tex)
2040      + space^1          / context.space
2041      + utfchar          / context.type
2042
2043    )^1
2044
2045    local compact = false
2046    local compact = true
2047
2048    local cmd = setmetatableindex("table")
2049    local lst = { }
2050    local cat = { }
2051    local org = { }
2052
2053    for i=1,#primitives do
2054        local l = primitives[i]
2055        local n = gsub(commandnames[l[1]],"_","")
2056        local p = l[3]
2057        local t = {
2058            syntax[n][p] or false,
2059            result[n][p] or false,
2060        }
2061        cmd[n][p] = t
2062        lst[p]    = t
2063        cat[p]    = category[n]
2064        org[p]    = l[4]
2065    end
2066    local tag = { }
2067    for k, v in next, origins do
2068        tag[k] = sub(v,1,1)
2069    end
2070
2071    moduledata.engine.data = {
2072        cmd = cmd,
2073        lst = lst,
2074        org = org,
2075        cat = cat,
2076    }
2077
2078    local function specification(k,v,done)
2079        local s = v[1]
2080        local r = v[2]
2081        local d = done[s]
2082        context.formatted.startPrimitive("%s \\tex{%s}",tag[commandhash[k][4]],k)
2083        if s and s ~= "" then
2084            if d then
2085                context(" see \\tex{%s}",done[s])
2086                r = false
2087            else
2088                lpegmatch(p_enhance,s)
2089                if compact and count(s," ") > 2 then
2090                    done[s] = k
2091                end
2092            end
2093        else
2094            context.allowbreak(false)
2095        end
2096        if r and r ~= "" then
2097            if s and s ~= "" then
2098                context["break"](false)
2099            end
2100            context.strut()
2101            if r[1] and r[1] ~= "" then
2102                context.llap("> ")
2103                lpegmatch(p_enhance,r[1])
2104                context(" : ")
2105            else
2106                context.llap(": ")
2107            end
2108            lpegmatch(p_enhance,r[2])
2109        else
2110            context.allowbreak(false)
2111        end
2112        context.stopPrimitive()
2113    end
2114
2115    function moduledata.engine.specification(k)
2116        local v = lst[k]
2117        if v then
2118            context.startpacked()
2119            specification(k,v,{})
2120            context.stoppacked()
2121        else
2122            print("no command " .. k)
2123        end
2124    end
2125
2126    function moduledata.engine.allspecifications()
2127        for k, v in sortedhash(cmd) do
2128            local done = { }
2129            context.startSyntax { title = k }
2130                for k, v in sortedhash(v) do
2131                    specification(k,v,done)
2132                end
2133            context.stopSyntax()
2134
2135            table.save("s-system-syntax-check.lua",{
2136                syntax   = syntax,
2137                result   = result,
2138                keywords = keywords,
2139                compares = compares,
2140            })
2141
2142        end
2143    end
2144
2145end
2146
2147do
2148
2149    function moduledata.engine.codes(name)
2150        local t = type(name) == "table" and name or tex[name]
2151        if t then
2152            local l = { }
2153            for k, v in table.sortedhash(t) do
2154                if tonumber(k) then
2155                    l[#l+1] = k
2156                end
2157            end
2158            local m = l[#l]
2159            local f = (m > 0xFFFF and "0x%08X") or (m > 0x00FF and "0x%04X") or "0x%02X"
2160            context.starttabulate { "|lT|l|" }
2161            for i=1,#l do
2162                local li = l[i]
2163                context.NC()
2164                context(f,li)
2165                context.NC()
2166                context(t[li])
2167                context.NC()
2168                context.NR()
2169            end
2170            context.stoptabulate()
2171        end
2172    end
2173
2174end
2175