This repository was archived by the owner on Jan 31, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathluakeyval.lua
More file actions
117 lines (109 loc) · 3.37 KB
/
luakeyval.lua
File metadata and controls
117 lines (109 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
-- luakeyval Version: 0.1, 2025-12-01
local put_next = token.unchecked_put_next
local get_next = token.get_next
local scan_toks = token.scan_toks
local scan_keyword = token.scan_keyword_cs
local texerror, utfchar = tex.error, utf8.char
local format = string.format
-- local relax = token.new(token.biggest_char() + 1)
local relax
do
-- initialization of the new primitives.
local prefix = '@lua^key&val_' -- unlikely prefix...
while token.is_defined(prefix .. 'relax') do
prefix = prefix .. '@lua^key&val_'
end
tex.enableprimitives(prefix,{'relax'})
-- Now we create new tokens with the meaning of
-- the primitives.
local tok = token.create(prefix .. 'relax')
relax = token.new(tok.mode, tok.command)
end
local function check_delimiter(error1, error2, key)
local tok = get_next()
if tok.tok ~= relax.tok then
local tok_name = tok.csname or utfchar(tok.mode)
texerror(format(error1, key, tok_name),{format(error2, key, tok_name)})
put_next({tok})
end
end
local unpack = table.unpack
local function process_keys(keys, messages, order)
assert(type(keys) == 'table')
local matched, vals, curr_key = true, { }
messages = messages or { }
local value_forbidden = messages.value_forbidden
or 'luakeyval: The key "%s" does not accept a value'
local value_required = messages.value_required
or 'luakeyval: The key "%s" requires a value'
local error1 = messages.error1
or 'luakeyval: Wrong syntax when processing keys'
local error2 = messages.error2
or 'luakeyval: The last scanned key was "%s".\nUnexpected token "%s" encountered.'
local key_list = { }
if order then
for _, k in ipairs(order) do
key_list[#key_list+1] = k
end
else
for k in pairs(keys) do
key_list[#key_list+1] = k
end
end
local toks = scan_toks()
toks[#toks+1] = relax
put_next(toks)
while matched do
matched = false
for _, key in ipairs(key_list) do
local param = keys[key]
if scan_keyword(key) then
matched = true
curr_key = key
local args = param.args or { }
local scanner = param.scanner
local val
if scan_keyword('=') then
if scanner then
val = scanner(unpack(args))
else
texerror(format(value_forbidden, key))
end
else
val = param.default
if val == nil then
texerror(format(value_required, key))
end
end
local func = param.func
if func then func(key,val) end
vals[key] = val
break
end
end
end
check_delimiter(error1, error2, curr_key or '<none>')
return vals
end
local function scan_choice(...)
local choices = {...}
for _, choice in ipairs(choices) do
if scan_keyword(choice) then
return choice
end
end
return nil
end
local function scan_bool()
if scan_keyword('true') then
return true
elseif scan_keyword('false') then
return false
end
return nil
end
return {
process = process_keys,
choices = scan_choice,
bool = scan_bool,
}