data-tex.lua /size: 8193 b    last modification: 2021-10-28 13:50
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
data-tex
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to luat-lib.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
local
tostring
,
tonumber
,
type
=
tostring
,
tonumber
,
type
10
local
char
,
find
=
string
.
char
,
string
.
find
11 12
local
trace_locating
=
false
trackers
.
register
(
"
resolvers.locating
"
,
function
(
v
)
trace_locating
=
v
end
)
13 14
local
report_tex
=
logs
.
reporter
(
"
resolvers
"
,
"
tex
"
)
15 16 17
local
sequencers
=
utilities
.
sequencers
18
local
utffiletype
=
utf
.
filetype
19
local
setmetatableindex
=
table
.
setmetatableindex
20
local
loaddata
=
io
.
loaddata
21
----- readall = io.readall
22 23
local
resolvers
=
resolvers
24
local
methodhandler
=
resolvers
.
methodhandler
25
local
loadbinfile
=
resolvers
.
loadbinfile
26
local
pushinputname
=
resolvers
.
pushinputname
27
local
popinputname
=
resolvers
.
popinputname
28 29
-- local fileprocessor = nil
30
-- local lineprocessor = nil
31 32
local
textfileactions
=
sequencers
.
new
{
33
arguments
=
"
str,filename,coding
"
,
34
returnvalues
=
"
str
"
,
35
results
=
"
str
"
,
36
}
37 38
local
textlineactions
=
sequencers
.
new
{
39
arguments
=
"
str,filename,linenumber,noflines,coding
"
,
40
returnvalues
=
"
str
"
,
41
results
=
"
str
"
,
42
}
43 44
local
helpers
=
resolvers
.
openers
.
helpers
45
local
appendgroup
=
sequencers
.
appendgroup
46
local
appendaction
=
sequencers
.
appendaction
47 48
helpers
.
textfileactions
=
textfileactions
49
helpers
.
textlineactions
=
textlineactions
50 51
appendgroup
(
textfileactions
,
"
before
"
)
-- user
52
appendgroup
(
textfileactions
,
"
system
"
)
-- private
53
appendgroup
(
textfileactions
,
"
after
"
)
-- user
54 55
appendgroup
(
textlineactions
,
"
before
"
)
-- user
56
appendgroup
(
textlineactions
,
"
system
"
)
-- private
57
appendgroup
(
textlineactions
,
"
after
"
)
-- user
58 59
local
ctrl_d
=
char
(
4
)
-- unix
60
local
ctrl_z
=
char
(
26
)
-- windows
61 62
----------------------------------------
63 64
local
lpegmatch
=
lpeg
.
match
65
local
newline
=
lpeg
.
patterns
.
newline
66
local
tsplitat
=
lpeg
.
tsplitat
67 68
local
linesplitters
=
{
69
tsplitat
(
newline
)
,
-- default since we started
70
tsplitat
(
lpeg
.
S
(
"
"
)
^
0
*
newline
)
,
71
tsplitat
(
lpeg
.
S
(
"
\t
"
)
^
0
*
newline
)
,
72
tsplitat
(
lpeg
.
S
(
"
\f\t
"
)
^
0
*
newline
)
,
-- saves a bit of space at the cost of runtime
73
-- tsplitat(lpeg.S(" \v\f\t")^0 * newline),
74
-- tsplitat(lpeg.R("\0\31")^0 * newline),
75
}
76 77
local
linesplitter
=
linesplitters
[
1
]
78 79
directives
.
register
(
"
system.linesplitmethod
"
,
function
(
v
)
80
linesplitter
=
linesplitters
[
tonumber
(
v
)
or
1
]
or
linesplitters
[
1
]
81
end
)
82 83
local
function
splitlines
(
str
)
84
return
lpegmatch
(
linesplitter
,
str
)
85
end
86 87
-- not really a bottleneck, but it might become:
88
--
89
-- local splitlines = string.splitlines or function(str)
90
-- return lpegmatch(linesplitter,str)
91
-- end
92
--
93
-- directives.register("system.linesplitmethod",function(v)
94
-- linesplitter = linesplitters[tonumber(v) or 1] or linesplitters[1]
95
-- splitlines = function(str)
96
-- return lpegmatch(linesplitter,str)
97
-- end
98
-- end)
99 100
-----------------------------------------
101 102
local
wideutfcoding
=
{
103
[
"
utf-16-be
"
]
=
utf
.
utf16_to_utf8_be_t
,
104
[
"
utf-16-le
"
]
=
utf
.
utf16_to_utf8_le_t
,
105
[
"
utf-32-be
"
]
=
utf
.
utf32_to_utf8_be_t
,
106
[
"
utf-32-le
"
]
=
utf
.
utf32_to_utf8_le_t
,
107
}
108 109
local
function
textopener
(
tag
,
filename
,
filehandle
,
coding
)
110
local
lines
111
local
t_filehandle
=
type
(
filehandle
)
112
if
not
filehandle
then
113
lines
=
loaddata
(
filename
)
114
elseif
t_filehandle
=
=
"
string
"
then
115
lines
=
filehandle
116
elseif
t_filehandle
=
=
"
table
"
then
117
lines
=
filehandle
118
else
119
lines
=
filehandle
:
read
(
"
*a
"
)
-- readall(filehandle) ... but never that large files anyway
120
-- lines = readall(filehandle)
121
filehandle
:
close
(
)
122
end
123
if
type
(
lines
)
=
=
"
string
"
then
124
local
coding
=
coding
or
utffiletype
(
lines
)
-- so we can signal no regime
125
if
trace_locating
then
126
report_tex
(
"
%a opener: %a opened using method %a
"
,
tag
,
filename
,
coding
)
127
end
128
local
wideutf
=
wideutfcoding
[
coding
]
129
if
wideutf
then
130
lines
=
wideutf
(
lines
)
131
else
-- utf8 or unknown (could be a mkvi file)
132
local
runner
=
textfileactions
.
runner
133
if
runner
then
134
lines
=
runner
(
lines
,
filename
,
coding
)
or
lines
135
end
136
lines
=
splitlines
(
lines
)
137
end
138
elseif
trace_locating
then
139
report_tex
(
"
%a opener: %a opened
"
,
tag
,
filename
)
140
end
141
local
noflines
=
#
lines
142
if
lines
[
noflines
]
=
=
"
"
then
-- maybe some special check is needed
143
lines
[
noflines
]
=
nil
144
end
145
pushinputname
(
filename
)
146
local
currentline
=
0
147
local
noflines
=
noflines
148
local
handler
=
{
149
filename
=
filename
,
150
noflines
=
noflines
,
151
-- currentline = 0,
152
gotoline
=
function
(
self
,
n
)
153
currentline
=
n
-
1
154
if
currentline
<
=
0
then
155
currentline
=
0
156
end
157
end
,
158
endoffile
=
function
(
)
159
return
not
lines
or
currentline
>
=
noflines
160
end
,
161
close
=
function
(
)
162
local
usedname
=
popinputname
(
)
-- should match filename
163
if
trace_locating
then
164
report_tex
(
"
%a closer: %a closed
"
,
tag
,
filename
)
165
end
166
handler
=
nil
167
lines
=
nil
168
end
,
169
reader
=
function
(
self
)
170
self
=
self
or
handler
171
-- local currentline, noflines = self.currentline, self.noflines
172
if
currentline
>
=
noflines
then
173
return
nil
174
else
175
currentline
=
currentline
+
1
176
-- self.currentline = currentline
177
local
content
=
lines
[
currentline
]
178
-- lines[currentline] = nil
179
if
content
=
=
"
"
then
180
return
"
"
181
-- elseif content == ctrl_d or ctrl_z then
182
-- return nil -- we need this as \endinput does not work in prints
183
elseif
content
then
184
local
runner
=
textlineactions
.
runner
185
if
runner
then
186
return
runner
(
content
,
filename
,
currentline
,
noflines
,
coding
)
or
content
187
else
188
return
content
189
end
190
else
191
return
nil
192
end
193
end
194
end
195
}
196
setmetatableindex
(
handler
,
function
(
t
,
k
)
197
if
k
=
=
"
currentline
"
then
198
return
currentline
199
else
200
-- no such key
201
end
202
end
)
203
return
handler
204
end
205 206
helpers
.
settextopener
(
textopener
)
-- can only be done once
207 208
function
resolvers
.
findtexfile
(
filename
,
filetype
)
209
return
methodhandler
(
'
finders
'
,
filename
,
filetype
)
210
end
211 212
function
resolvers
.
opentexfile
(
filename
)
213
return
methodhandler
(
'
openers
'
,
filename
)
214
end
215 216
function
resolvers
.
openfile
(
filename
)
217
local
fullname
=
methodhandler
(
'
finders
'
,
filename
)
218
return
fullname
and
fullname
~
=
"
"
and
methodhandler
(
'
openers
'
,
fullname
)
or
nil
219
end
220 221
function
resolvers
.
loadtexfile
(
filename
,
filetype
)
222
-- todo: optionally apply filters
223
local
ok
,
data
,
size
=
loadbinfile
(
filename
,
filetype
)
224
return
data
or
"
"
225
end
226 227
resolvers
.
texdatablob
=
resolvers
.
loadtexfile
228 229
local
function
installhandler
(
namespace
,
what
,
where
,
func
)
230
if
not
func
then
231
where
,
func
=
"
after
"
,
where
232
end
233
if
where
=
=
"
before
"
or
where
=
=
"
after
"
then
234
appendaction
(
namespace
,
where
,
func
)
235
else
236
report_tex
(
"
installing input %a handlers in %a is not possible
"
,
what
,
tostring
(
where
)
)
237
end
238
end
239 240
function
resolvers
.
installinputlinehandler
(
...
)
installhandler
(
textlineactions
,
"
line
"
,
...
)
end
241
function
resolvers
.
installinputfilehandler
(
...
)
installhandler
(
textfileactions
,
"
file
"
,
...
)
end
242 243
-- local basename = file.basename
244
-- resolvers.installinputlinehandler(function(str,filename,linenumber,noflines)
245
-- report_tex("[lc] file %a, line %a of %a, length %a",basename(filename),linenumber,noflines,#str)
246
-- end)
247
-- resolvers.installinputfilehandler(function(str,filename)
248
-- report_tex("[fc] file %a, length %a",basename(filename),#str)
249
-- end)
250