mtx-check.lua /size: 8266 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
mtx-check
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to mtxrun.lua
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
local
P
,
R
,
S
,
V
,
C
,
CP
,
CC
,
lpegmatch
=
lpeg
.
P
,
lpeg
.
R
,
lpeg
.
S
,
lpeg
.
V
,
lpeg
.
C
,
lpeg
.
Cp
,
lpeg
.
Cc
,
lpeg
.
match
10
local
gsub
,
sub
,
format
=
string
.
gsub
,
string
.
sub
,
string
.
format
11
local
insert
,
remove
=
table
.
insert
,
table
.
remove
12 13
local
helpinfo
=
[[
14<?xml version="1.0"?> 15<application> 16 <metadata> 17 <entry name="name">mtx-check</entry> 18 <entry name="detail">Basic ConTeXt Syntax Checking</entry> 19 <entry name="version">0.10</entry> 20 </metadata> 21 <flags> 22 <category name="basic"> 23 <subcategory> 24 <flag name="check"><short>check tex file for errors</short></flag> 25 </subcategory> 26 </category> 27 </flags> 28</application> 29
]]
30 31
local
application
=
logs
.
application
{
32
name
=
"
mtx-check
"
,
33
banner
=
"
Basic ConTeXt Syntax Checking 0.10
"
,
34
helpinfo
=
helpinfo
,
35
}
36 37
local
report
=
application
.
report
38 39
scripts
=
scripts
or
{
}
40
scripts
.
checker
=
scripts
.
checker
or
{
}
41 42
local
validator
=
{
}
43 44
validator
.
n
=
1
45
validator
.
errors
=
{
}
46
validator
.
trace
=
false
47
validator
.
direct
=
false
48 49
validator
.
printer
=
print
50
validator
.
tracer
=
print
51 52
local
message
=
function
(
position
,
kind
,
extra
)
53
local
ve
=
validator
.
errors
54
ve
[
#
ve
+
1
]
=
{
kind
,
position
,
validator
.
n
,
extra
}
55
if
validator
.
direct
then
56
position
=
position
or
"
eof
"
57
if
extra
then
58
validator
.
printer
(
format
(
"
%s error at position %s (line %s) (%s)
"
,
kind
,
position
,
validator
.
n
,
extra
)
)
59
else
60
validator
.
printer
(
format
(
"
%s error at position %s (line %s)
"
,
kind
,
position
,
validator
.
n
)
)
61
end
62
end
63
end
64 65
local
progress
=
function
(
position
,
data
,
kind
)
66
if
validator
.
trace
then
67
validator
.
tracer
(
format
(
"
%s at position %s: %s
"
,
kind
,
position
,
data
or
"
"
)
)
68
end
69
end
70 71
local
i_m
,
d_m
=
P
(
"
$
"
)
,
P
(
"
$$
"
)
72
local
l_s
,
r_s
=
P
(
"
[
"
)
,
P
(
"
]
"
)
73
local
l_g
,
r_g
=
P
(
"
{
"
)
,
P
(
"
}
"
)
74 75
local
okay
=
lpeg
.
P
(
"
{[}
"
)
+
lpeg
.
P
(
"
{]}
"
)
76 77
local
esc
=
P
(
"
\\
"
)
78
local
space
=
S
(
"
\t\f\v
"
)
79
local
newline
=
lpeg
.
patterns
.
newline
80 81
local
line
=
newline
/
function
(
)
validator
.
n
=
validator
.
n
+
1
end
82 83
local
startluacode
=
P
(
"
\\startluacode
"
)
84
local
stopluacode
=
P
(
"
\\stopluacode
"
)
85 86
local
somecode
=
startluacode
*
(
1
-
stopluacode
)
^
1
*
stopluacode
87 88
local
stack
=
{
}
89 90
local
function
push
(
p
,
s
)
91
-- print("start",p,s)
92
insert
(
stack
,
{
p
,
s
,
validator
.
n
}
)
93
end
94 95
local
function
pop
(
p
,
s
)
96
-- print("stop",p,s)
97
local
top
=
remove
(
stack
)
98
if
not
top
then
99
message
(
p
,
"
missing start
"
)
100
elseif
top
[
2
]
~
=
s
then
101
message
(
p
,
"
missing stop
"
,
format
(
"
see line %s
"
,
top
[
3
]
)
)
102
else
103
-- okay
104
end
105
end
106 107
local
cstoken
=
R
(
"
az
"
,
"
AZ
"
,
"
\127\255
"
)
108 109
local
start
=
CP
(
)
*
P
(
"
\\start
"
)
*
C
(
cstoken
^
0
)
/
push
110
local
stop
=
CP
(
)
*
P
(
"
\\stop
"
)
*
C
(
cstoken
^
0
)
/
pop
111 112
local
contextgrammar
=
P
{
"
tokens
"
,
113
[
"
tokens
"
]
=
(
V
(
"
ignore
"
)
+
V
(
"
start
"
)
+
V
(
"
stop
"
)
+
V
(
"
whatever
"
)
+
V
(
"
grouped
"
)
+
V
(
"
setup
"
)
+
V
(
"
display
"
)
+
V
(
"
inline
"
)
+
V
(
"
errors
"
)
+
1
)
^
0
,
114
[
"
start
"
]
=
start
,
115
[
"
stop
"
]
=
stop
,
116
[
"
whatever
"
]
=
line
+
esc
*
1
+
C
(
P
(
"
%
"
)
*
(
1
-
line
)
^
0
)
,
117
[
"
grouped
"
]
=
l_g
*
(
V
(
"
start
"
)
+
V
(
"
stop
"
)
+
V
(
"
whatever
"
)
+
V
(
"
grouped
"
)
+
V
(
"
setup
"
)
+
V
(
"
display
"
)
+
V
(
"
inline
"
)
+
line
+
(
1
-
l_g
-
r_g
)
)
^
0
*
r_g
,
118
[
"
setup
"
]
=
l_s
*
(
okay
+
V
(
"
whatever
"
)
+
V
(
"
grouped
"
)
+
V
(
"
setup
"
)
+
V
(
"
display
"
)
+
V
(
"
inline
"
)
+
(
1
-
l_s
-
r_s
)
)
^
0
*
r_s
,
119
[
"
display
"
]
=
d_m
*
(
V
(
"
whatever
"
)
+
V
(
"
grouped
"
)
+
(
1
-
d_m
)
)
^
0
*
d_m
,
120
[
"
inline
"
]
=
i_m
*
(
V
(
"
whatever
"
)
+
V
(
"
grouped
"
)
+
(
1
-
i_m
)
)
^
0
*
i_m
,
121
[
"
errors
"
]
=
V
(
"
gerror
"
)
+
V
(
"
serror
"
)
+
V
(
"
derror
"
)
+
V
(
"
ierror
"
)
,
122
[
"
gerror
"
]
=
CP
(
)
*
(
l_g
+
r_g
)
*
CC
(
"
grouping error
"
)
/
message
,
123
[
"
serror
"
]
=
CP
(
)
*
(
l_s
+
r_g
)
*
CC
(
"
setup error
"
)
/
message
,
124
[
"
derror
"
]
=
CP
(
)
*
d_m
*
CC
(
"
display math error
"
)
/
message
,
125
[
"
ierror
"
]
=
CP
(
)
*
i_m
*
CC
(
"
inline math error
"
)
/
message
,
126
[
"
ignore
"
]
=
somecode
,
127
}
128 129
-- metafun variant
130 131
local
function
push
(
p
,
s
)
132
insert
(
stack
,
{
p
,
s
,
validator
.
n
}
)
133
end
134 135
local
function
pop
(
p
,
s
)
136
local
top
=
remove
(
stack
)
137
if
not
top
then
138
message
(
p
,
"
missing <some>def
"
)
139
end
140
end
141 142
local
function
finish
(
p
)
143
local
bot
=
stack
[
1
]
144
if
bot
then
145
message
(
false
,
format
(
"
missing enddef for %s
"
,
bot
[
2
]
)
,
format
(
"
see line %s
"
,
bot
[
3
]
)
)
146
end
147
stack
=
{
}
148
end
149 150
local
l_b
,
r_b
=
P
(
"
[
"
)
,
P
(
"
]
"
)
151
local
l_g
,
r_g
=
P
(
"
{
"
)
,
P
(
"
}
"
)
152
local
l_p
,
r_p
=
P
(
"
(
"
)
,
P
(
"
)
"
)
153 154
local
start
=
CP
(
)
*
C
(
P
(
"
vardef
"
)
+
P
(
"
primarydef
"
)
+
P
(
"
secondarydef
"
)
+
P
(
"
tertiarydef
"
)
+
P
(
"
def
"
)
)
/
push
155
local
stop
=
CP
(
)
*
C
(
P
(
"
enddef
"
)
)
/
pop
156 157
local
dstring
=
P
(
'
"
'
)
*
(
1
-
P
(
'
"
'
)
)
^
0
*
P
(
'
"
'
)
158
local
semicolon
=
P
(
"
;
"
)
159 160
local
separator
=
line
+
space
+
semicolon
161 162
-- todo: start/stop also in ()
163 164
local
metafungrammar
=
P
{
"
tokens
"
,
165
[
"
tokens
"
]
=
(
V
(
"
start
"
)
+
V
(
"
stop
"
)
+
V
(
"
string
"
)
+
V
(
"
whatever
"
)
+
V
(
"
braces
"
)
+
V
(
"
brackets
"
)
+
V
(
"
parentheses
"
)
+
V
(
"
errors
"
)
+
1
)
^
0
166
*
(
CP
(
)
/
finish
)
,
167
[
"
start
"
]
=
separator
*
start
*
#
separator
,
168
[
"
stop
"
]
=
separator
*
stop
*
#
separator
,
169
[
"
string
"
]
=
dstring
,
170
[
"
whatever
"
]
=
line
+
C
(
P
(
"
%
"
)
*
(
1
-
line
)
^
0
)
,
171
[
"
braces
"
]
=
l_g
*
(
V
(
"
whatever
"
)
+
V
(
"
string
"
)
+
V
(
"
braces
"
)
+
V
(
"
brackets
"
)
+
V
(
"
parentheses
"
)
+
(
1
-
l_g
-
r_g
)
)
^
0
*
r_g
,
172
[
"
brackets
"
]
=
l_b
*
(
V
(
"
whatever
"
)
+
V
(
"
string
"
)
+
V
(
"
braces
"
)
+
V
(
"
brackets
"
)
+
V
(
"
parentheses
"
)
+
(
1
-
l_b
-
r_b
)
)
^
0
*
r_b
,
173
[
"
parentheses
"
]
=
l_p
*
(
V
(
"
whatever
"
)
+
V
(
"
string
"
)
+
V
(
"
braces
"
)
+
V
(
"
brackets
"
)
+
V
(
"
parentheses
"
)
+
(
1
-
l_p
-
r_p
)
)
^
0
*
r_p
,
174
[
"
errors
"
]
=
V
(
"
gerror
"
)
+
V
(
"
berror
"
)
+
V
(
"
perror
"
)
,
175
[
"
gerror
"
]
=
CP
(
)
*
(
l_g
+
r_g
)
*
CC
(
"
braces error
"
)
/
message
,
176
[
"
berror
"
]
=
CP
(
)
*
(
l_b
+
r_b
)
*
CC
(
"
brackets error
"
)
/
message
,
177
[
"
perror
"
]
=
CP
(
)
*
(
l_p
+
r_p
)
*
CC
(
"
parentheses error
"
)
/
message
,
178
}
179 180
local
grammars
=
{
181
mp
=
metafungrammar
,
182
mpii
=
metafungrammar
,
183
mpiv
=
metafungrammar
,
184
tex
=
contextgrammar
,
185
mkii
=
contextgrammar
,
186
mkiv
=
contextgrammar
,
187
mkvi
=
contextgrammar
,
188
mkil
=
contextgrammar
,
189
mkli
=
contextgrammar
,
190
}
191 192
function
validator
.
check
(
str
,
filetype
)
193
validator
.
n
=
1
194
validator
.
errors
=
{
}
195
local
grammar
=
grammars
[
filetype
]
or
grammars
.
tex
196
lpegmatch
(
grammar
,
str
)
197
end
198 199
--~ str = [[
200
--~ a{oeps {oe\{\}ps} }
201
--~ test { oeps \} \[\] oeps \setupxxx[oeps=bla]}
202
--~ test $$ \hbox{$ oeps \} \[\] oeps $} $$
203
--~ {$x\$xx$ $
204
--~ ]]
205
--~ str = string.rep(str,10)
206 207
local
remapper
=
{
208
[
"
\n
"
]
=
"
<lf>
"
,
209
[
"
\r
"
]
=
"
<cr>
"
,
210
[
"
\t
"
]
=
"
<tab>
"
,
211
}
212 213
function
scripts
.
checker
.
check
(
filename
)
214
local
str
=
io
.
loaddata
(
filename
)
215
if
str
then
216
validator
.
check
(
str
,
file
.
suffix
(
filename
)
)
217
local
errors
=
validator
.
errors
218
if
#
errors
>
0
then
219
for
k
=
1
,
#
errors
do
220
local
v
=
errors
[
k
]
221
local
kind
,
position
,
line
,
extra
=
v
[
1
]
,
v
[
2
]
,
v
[
3
]
,
v
[
4
]
222
if
not
position
then
223
position
=
#
str
224
end
225
local
data
=
sub
(
str
,
position
-30
,
position
+
30
)
226
data
=
gsub
(
data
,
"
.
"
,
remapper
)
227
data
=
gsub
(
data
,
"
^ *
"
,
"
"
)
228
if
extra
then
229
print
(
format
(
"
% 5i %-10s %s (%s)
"
,
line
,
kind
,
data
,
extra
)
)
230
else
231
print
(
format
(
"
% 5i %-10s %s
"
,
line
,
kind
,
data
)
)
232
end
233
end
234
else
235
print
(
"
no error
"
)
236
end
237
else
238
print
(
"
no file
"
)
239
end
240
end
241 242
if
environment
.
argument
(
"
check
"
)
then
243
scripts
.
checker
.
check
(
environment
.
files
[
1
]
)
244
elseif
environment
.
argument
(
"
help
"
)
then
245
application
.
help
(
)
246
elseif
environment
.
argument
(
"
exporthelp
"
)
then
247
application
.
export
(
environment
.
argument
(
"
exporthelp
"
)
,
environment
.
files
[
1
]
)
248
elseif
environment
.
files
[
1
]
then
249
scripts
.
checker
.
check
(
environment
.
files
[
1
]
)
250
else
251
application
.
help
(
)
252
end
253 254