1if 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
9local tostring , tonumber , type = tostring , tonumber , type
10local char , find = string . char , string . find
11
12local trace_locating = false trackers . register ( " resolvers.locating " , function ( v ) trace_locating = v end )
13
14local report_tex = logs . reporter ( " resolvers " , " tex " )
15
16
17local sequencers = utilities . sequencers
18local utffiletype = utf . filetype
19local setmetatableindex = table . setmetatableindex
20local loaddata = io . loaddata
21
22
23local resolvers = resolvers
24local methodhandler = resolvers . methodhandler
25local loadbinfile = resolvers . loadbinfile
26local pushinputname = resolvers . pushinputname
27local popinputname = resolvers . popinputname
28
29
30
31
32local textfileactions = sequencers . new {
33 arguments = " str,filename,coding " ,
34 returnvalues = " str " ,
35 results = " str " ,
36}
37
38local textlineactions = sequencers . new {
39 arguments = " str,filename,linenumber,noflines,coding " ,
40 returnvalues = " str " ,
41 results = " str " ,
42}
43
44local helpers = resolvers . openers . helpers
45local appendgroup = sequencers . appendgroup
46local appendaction = sequencers . appendaction
47
48helpers . textfileactions = textfileactions
49helpers . textlineactions = textlineactions
50
51appendgroup ( textfileactions , " before " )
52appendgroup ( textfileactions , " system " )
53appendgroup ( textfileactions , " after " )
54
55appendgroup ( textlineactions , " before " )
56appendgroup ( textlineactions , " system " )
57appendgroup ( textlineactions , " after " )
58
59local ctrl_d = char ( 4 )
60local ctrl_z = char ( 26 )
61
62
63
64local lpegmatch = lpeg . match
65local newline = lpeg . patterns . newline
66local tsplitat = lpeg . tsplitat
67
68local linesplitters = {
69 tsplitat ( newline ) ,
70 tsplitat ( lpeg . S ( " " ) ^ 0 * newline ) ,
71 tsplitat ( lpeg . S ( " \t " ) ^ 0 * newline ) ,
72 tsplitat ( lpeg . S ( " \f\t " ) ^ 0 * newline ) ,
73
74
75}
76
77local linesplitter = linesplitters [ 1 ]
78
79directives . register ( " system.linesplitmethod " , function ( v )
80 linesplitter = linesplitters [ tonumber ( v ) or 1 ] or linesplitters [ 1 ]
81end )
82
83local function splitlines ( str )
84 return lpegmatch ( linesplitter , str )
85end
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102local 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
109local 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 " )
120
121 filehandle : close ( )
122 end
123 if type ( lines ) = = " string " then
124 local coding = coding or utffiletype ( lines )
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
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
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
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 ( )
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
172 if currentline > = noflines then
173 return nil
174 else
175 currentline = currentline + 1
176
177 local content = lines [ currentline ]
178
179 if content = = " " then
180 return " "
181
182
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
201 end
202 end )
203 return handler
204end
205
206helpers . settextopener ( textopener )
207
208function resolvers . findtexfile ( filename , filetype )
209 return methodhandler ( ' finders ' , filename , filetype )
210end
211
212function resolvers . opentexfile ( filename )
213 return methodhandler ( ' openers ' , filename )
214end
215
216function resolvers . openfile ( filename )
217 local fullname = methodhandler ( ' finders ' , filename )
218 return fullname and fullname ~ = " " and methodhandler ( ' openers ' , fullname ) or nil
219end
220
221function resolvers . loadtexfile ( filename , filetype )
222
223 local ok , data , size = loadbinfile ( filename , filetype )
224 return data or " "
225end
226
227resolvers . texdatablob = resolvers . loadtexfile
228
229local 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
238end
239
240function resolvers . installinputlinehandler ( ... ) installhandler ( textlineactions , " line " , ... ) end
241function resolvers . installinputfilehandler ( ... ) installhandler ( textfileactions , " file " , ... ) end
242
243
244
245
246
247
248
249
250 |