summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/data-tex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/data-tex.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/data-tex.lua306
1 files changed, 123 insertions, 183 deletions
diff --git a/Master/texmf-dist/tex/context/base/data-tex.lua b/Master/texmf-dist/tex/context/base/data-tex.lua
index c9fa3625a66..14148b20ea8 100644
--- a/Master/texmf-dist/tex/context/base/data-tex.lua
+++ b/Master/texmf-dist/tex/context/base/data-tex.lua
@@ -6,221 +6,161 @@ if not modules then modules = { } end modules ['data-tex'] = {
license = "see context related readme files"
}
--- special functions that deal with io
-
-local format, lower = string.format, string.lower
-local unpack = unpack or table.unpack
-
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
-local texiowrite_nl = (texio and texio.write_nl) or print
-local texiowrite = (texio and texio.write) or print
+local report_tex = logs.reporter("resolvers","tex")
-local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
+local resolvers = resolvers
-function finders.generic(tag,filename,filetype)
- local foundname = resolvers.find_file(filename,filetype)
- if foundname and foundname ~= "" then
- if trace_locating then
- logs.report("fileio","%s finder: file '%s' found",tag,filename)
- end
- return foundname
- else
- if trace_locating then
- logs.report("fileio","%s finder: unknown file '%s'",tag,filename)
- end
- return unpack(finders.notfound)
- end
-end
+local sequencers = utilities.sequencers
+local methodhandler = resolvers.methodhandler
+local splitlines = string.splitlines
+local utffiletype = unicode.filetype
---~ local lpegmatch = lpeg.match
---~ local getlines = lpeg.Ct(lpeg.patterns.textline)
+local fileprocessor = nil
+local lineprocessor = nil
-local input_translator, utf_translator, user_translator = nil, nil, nil
+local textfileactions = sequencers.reset {
+ arguments = "str,filename",
+ returnvalues = "str",
+ results = "str",
+}
-function resolvers.install_text_filter(name,func)
- if name == "input" then input_translator = func
- elseif name == "utf" then utf_translator = func
- elseif name == "user" then user_translator = func end
-end
+local textlineactions = sequencers.reset {
+ arguments = "str,filename,linenumber,noflines",
+ returnvalues = "str",
+ results = "str",
+}
-function openers.text_opener(filename,file_handle,tag)
- local u = unicode.utftype(file_handle)
- local t = { }
- if u > 0 then
- if trace_locating then
- logs.report("fileio","%s opener, file '%s' opened using method '%s'",tag,filename,unicode.utfname[u])
- end
- local l
- if u > 2 then
- l = unicode.utf32_to_utf8(file_handle:read("*a"),u==4)
- else
- l = unicode.utf16_to_utf8(file_handle:read("*a"),u==2)
- end
- file_handle:close()
- t = {
- utftype = u, -- may go away
- lines = l,
- current = 0, -- line number, not really needed
- handle = nil,
- noflines = #l,
- close = function()
- if trace_locating then
- logs.report("fileio","%s closer, file '%s' closed",tag,filename)
- end
- logs.show_close(filename)
- t = nil
- end,
- reader = function(self)
- self = self or t
- local current, lines = self.current, self.lines
- if current >= #lines then
- return nil
- else
- current = current + 1
- self.current = current
- local line = lines[current]
- if not line then
- return nil
- elseif line == "" then
- return ""
- else
- if input_translator then
- line = input_translator(line)
- end
- if utf_translator then
- line = utf_translator(line)
- end
- if user_translator then
- line = user_translator(line)
- end
- return line
- end
- end
- end
- }
+local helpers = resolvers.openers.helpers
+local appendgroup = sequencers.appendgroup
+
+helpers.textfileactions = textfileactions
+helpers.textlineactions = textlineactions
+
+appendgroup(textfileactions,"before") -- user
+appendgroup(textfileactions,"system") -- private
+appendgroup(textfileactions,"after" ) -- user
+
+appendgroup(textlineactions,"before") -- user
+appendgroup(textlineactions,"system") -- private
+appendgroup(textlineactions,"after" ) -- user
+
+function helpers.textopener(tag,filename,filehandle)
+ local lines
+ local t_filehandle = type(filehandle)
+ if not filehandle then
+ lines = io.loaddata(filename)
+ elseif t_filehandle == "string" then
+ lines = filehandle
+ elseif t_filehandle == "table" then
+ lines = filehandle
else
+ lines = filehandle:read("*a")
+ filehandle:close()
+ end
+ if type(lines) == "string" then
+ local coding = utffiletype(lines)
if trace_locating then
- logs.report("fileio","%s opener, file '%s' opened",tag,filename)
+ report_tex("%s opener, '%s' opened using method '%s'",tag,filename,coding)
end
- -- todo: file;name -> freeze / eerste regel scannen -> freeze
- --~ local data = lpegmatch(getlines,file_handle:read("*a"))
- --~ local n = 0
- t = {
- reader = function() -- self
- local line = file_handle:read()
- --~ n = n + 1
- --~ local line = data[n]
- --~ print(line)
- if not line then
- return nil
- elseif line == "" then
- return ""
- else
- if input_translator then
- line = input_translator(line)
- end
- if utf_translator then
- line = utf_translator(line)
- end
- if user_translator then
- line = user_translator(line)
- end
- return line
- end
- end,
- close = function()
- if trace_locating then
- logs.report("fileio","%s closer, file '%s' closed",tag,filename)
- end
- logs.show_close(filename)
- file_handle:close()
- t = nil
- collectgarbage("step") -- saves some memory
- end,
- handle = function()
- return file_handle
- end,
- noflines = function()
- t.noflines = io.noflines(file_handle)
- return t.noflines
- end
- }
- end
- return t
-end
-
-function openers.generic(tag,filename)
- if filename and filename ~= "" then
- local f = io.open(filename,"r")
- if f then
- logs.show_open(filename) -- todo
- if trace_locating then
- logs.report("fileio","%s opener, file '%s' opened",tag,filename)
+ if coding == "utf-16-be" then
+ lines = unicode.utf16_to_utf8_be(lines)
+ elseif coding == "utf-16-le" then
+ lines = unicode.utf16_to_utf8_le(lines)
+ elseif coding == "utf-32-be" then
+ lines = unicode.utf32_to_utf8_be(lines)
+ elseif coding == "utf-32-le" then
+ lines = unicode.utf32_to_utf8_le(lines)
+ else -- utf8 or unknown
+ if textfileactions.dirty then -- maybe use autocompile
+ fileprocessor = sequencers.compile(textfileactions)
end
- return openers.text_opener(filename,f,tag)
+ lines = fileprocessor(lines,filename) or lines
+ lines = splitlines(lines)
end
+ elseif trace_locating then
+ report_tex("%s opener, '%s' opened",tag,filename)
end
- if trace_locating then
- logs.report("fileio","%s opener, file '%s' not found",tag,filename)
+ local noflines = #lines
+ if lines[noflines] == "" then -- maybe some special check is needed
+ lines[noflines] = nil
end
- return unpack(openers.notfound)
-end
-
-function loaders.generic(tag,filename)
- if filename and filename ~= "" then
- local f = io.open(filename,"rb")
- if f then
- logs.show_load(filename)
+ logs.show_open(filename)
+ return {
+ filename = filename,
+ noflines = noflines,
+ currentline = 0,
+ close = function()
if trace_locating then
- logs.report("fileio","%s loader, file '%s' loaded",tag,filename)
+ report_tex("%s closer, '%s' closed",tag,filename)
end
- local s = f:read("*a")
- if garbagecollector and garbagecollector.check then garbagecollector.check(#s) end
- f:close()
- if s then
- return true, s, #s
+ logs.show_close(filename)
+ t = nil
+ end,
+ reader = function(self)
+ self = self or t
+ local currentline, noflines = self.currentline, self.noflines
+ if currentline >= noflines then
+ return nil
+ else
+ currentline = currentline + 1
+ self.currentline = currentline
+ local content = lines[currentline]
+ if not content then
+ return nil
+ elseif content == "" then
+ return ""
+ else
+ if textlineactions.dirty then
+ lineprocessor = sequencers.compile(textlineactions) -- maybe use autocompile
+ end
+ return lineprocessor(content,filename,currentline,noflines) or content
+ end
end
end
- end
- if trace_locating then
- logs.report("fileio","%s loader, file '%s' not found",tag,filename)
- end
- return unpack(loaders.notfound)
+ }
end
-function finders.tex(filename,filetype)
- return finders.generic('tex',filename,filetype)
+function resolvers.findtexfile(filename,filetype)
+ return methodhandler('finders',filename,filetype)
end
-function openers.tex(filename)
- return openers.generic('tex',filename)
+function resolvers.opentexfile(filename)
+ return methodhandler('openers',filename)
end
-function loaders.tex(filename)
- return loaders.generic('tex',filename)
+function resolvers.openfile(filename)
+ local fullname = methodhandler('finders',filename)
+ return fullname and fullname ~= "" and methodhandler('openers',fullname) or nil
end
-function resolvers.findtexfile(filename, filetype)
- return resolvers.methodhandler('finders',filename, filetype)
+function resolvers.loadtexfile(filename,filetype)
+ -- todo: optionally apply filters
+ local ok, data, size = resolvers.loadbinfile(filename, filetype)
+ return data or ""
end
-function resolvers.opentexfile(filename)
- return resolvers.methodhandler('openers',filename)
-end
+resolvers.texdatablob = resolvers.loadtexfile
-function resolvers.openfile(filename)
- local fullname = resolvers.findtexfile(filename)
- if fullname and (fullname ~= "") then
- return resolvers.opentexfile(fullname)
+local function installhandler(namespace,what,where,func)
+ if not func then
+ where, func = "after", where
+ end
+ if where == "before" or where == "after" then
+ sequencers.appendaction(namespace,where,func)
else
- return nil
+ report_tex("installing input %s handlers in %s is not possible",what,tostring(where))
end
end
-function resolvers.texdatablob(filename, filetype)
- local ok, data, size = resolvers.loadbinfile(filename, filetype)
- return data or ""
-end
+function resolvers.installinputlinehandler(...) installhandler(helpers.textlineactions,"line",...) end
+function resolvers.installinputfilehandler(...) installhandler(helpers.textfileactions,"file",...) end
-resolvers.loadtexfile = resolvers.texdatablob
+-- local basename = file.basename
+-- resolvers.installinputlinehandler(function(str,filename,linenumber,noflines)
+-- report_tex("[lc] file: %s, line: %s of %s, length: %s",basename(filename),linenumber,noflines,#str)
+-- end)
+-- resolvers.installinputfilehandler(function(str,filename)
+-- report_tex("[fc] file: %s, length: %s",basename(filename),#str)
+-- end)