-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathluamml-tex-annotate.lua
140 lines (133 loc) · 4 KB
/
luamml-tex-annotate.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
local nest = tex.nest
local properties = node.get_properties_table()
local mark_environment = {
data = {
},
}
do
local _ENV = mark_environment
function consume_label(label, fn)
local mathml = data.mathml[label]
data.mathml[label] = nil
if fn then fn(mathml) end
return mathml
end
end
local function annotate()
local annotation, err = load( 'return {'
.. token.scan_argument()
.. '}', nil, 't', mark_environment)
if not annotation then
tex.error('Error while parsing LuaMML annotation', {err})
return 0
end
annotation = annotation()
local nesting = nest.top
local props = properties[nesting.head]
local current = props and props.luamml__annotate_context
if current then
current, props.luamml__annotate_context = current.head, current.prev
else
tex.error('Mismatched LuaMML annotation',
{'Something odd happened. Maybe you forgot braces around an annotated symbol in a subscript or superscript?'})
return 0
end
local after = nesting.tail
local count, offset = 0, annotation.offset
local marked
if current == after then
tex.error'Empty LuaMML annotation'
else
repeat
current = current.next
count = count + 1
if count == offset then
marked = current
elseif offset or current ~= after then
local props = properties[current]
if not props then
props = {}
properties[current] = props
end
props.mathml_table, props.mathml_core = nil, false
end
until current == after
if offset and not marked then
tex.error'Invalid offset in LuaMML annotation'
end
marked = marked or current
if annotation.nucleus then
marked = marked.nucleus
end
if marked then
local props = properties[marked]
if not props then
props = {}
properties[marked] = props
end
if annotation.core ~= nil then
props.mathml_core = annotation.core
end
if annotation.struct ~= nil then
local saved = props.mathml_filter
local struct = annotation.struct
function props.mathml_filter(mml, core)
mml[':struct'] = struct
if saved then
return saved(mml, core)
else
return mml, core
end
end
end
if annotation.structnum ~= nil then
local saved = props.mathml_filter
local structnum = annotation.structnum
function props.mathml_filter(mml, core)
mml[':structnum'] = structnum
if saved then
return saved(mml, core)
else
return mml, core
end
end
end
else
tex.error'Unable to annotate nucleus of node without nucleus'
end
end
return count
end
local funcid = luatexbase.new_luafunction'__luamml_annotate_begin:'
token.set_lua('__luamml_annotate_begin:', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
local top = nest.top
local temp = top.head
local props = properties[temp]
if not props then
props = {}
properties[temp] = props
end
props.luamml__annotate_context = {
prev = props.luamml__annotate_context,
head = top.tail,
}
end
funcid = luatexbase.new_luafunction'__luamml_annotate_end:we'
token.set_lua('__luamml_annotate_end:we', funcid, 'protected')
lua.get_functions_table()[funcid] = function()
local count = token.scan_int()
local real_count = annotate()
if count ~= real_count then
tex.error('Incorrect count in LuaMML annotation', {
'A LuaMML annotation was discovered with an explicit count \z
which was not the same as the number of top-level nodes annotated.',
string.format('This can be fixed by changing the supplied count from %i to %i \z
or by omitting the count value entirely.', count, real_count)
})
end
end
funcid = luatexbase.new_luafunction'__luamml_annotate_end:e'
token.set_lua('__luamml_annotate_end:e', funcid, 'protected')
lua.get_functions_table()[funcid] = annotate
return mark_environment