summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/luat-zip.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/luat-zip.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/luat-zip.lua220
1 files changed, 220 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/luat-zip.lua b/Master/texmf-dist/tex/context/base/luat-zip.lua
new file mode 100644
index 00000000000..91279cfe091
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/luat-zip.lua
@@ -0,0 +1,220 @@
+-- filename : luat-zip.lua
+-- comment : companion to luat-lib.tex
+-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+-- copyright: PRAGMA ADE / ConTeXt Development Team
+-- license : see context related readme files
+
+if not versions then versions = { } end versions['luat-zip'] = 1.001
+
+if zip and input then
+ zip.supported = true
+else
+ zip = { }
+ zip.supported = false
+end
+
+if not zip.supported then
+
+ if not input then input = { } end -- will go away
+
+ function zip.openarchive (...) return nil end -- needed ?
+ function zip.closenarchive (...) end -- needed ?
+ function input.usezipfile (...) end -- needed ?
+
+else
+
+ -- zip:///oeps.zip?name=bla/bla.tex
+ -- zip:///oeps.zip?tree=tex/texmf-local
+
+ local function validzip(str)
+ if not str:find("^zip://") then
+ return "zip:///" .. str
+ else
+ return str
+ end
+ end
+
+ zip.archives = { }
+ zip.registeredfiles = { }
+
+ function zip.openarchive(instance,name)
+ if not name or name == "" then
+ return nil
+ else
+ local arch = zip.archives[name]
+ if arch then
+ return arch
+ else
+ local full = input.find_file(instance,name) or ""
+ local arch = (full ~= "" and zip.open(full)) or false
+ zip.archives[name] = arch
+ return arch
+ end
+ end
+ end
+
+ function zip.closearchive(instance,name)
+ if not name or name == "" and zip.archives[name] then
+ zip.close(zip.archives[name])
+ zip.archives[name] = nil
+ end
+ end
+
+ -- zip:///texmf.zip?tree=/tex/texmf
+ -- zip:///texmf.zip?tree=/tex/texmf-local
+ -- zip:///texmf-mine.zip?tree=/tex/texmf-projects
+
+ function input.locators.zip(instance,specification) -- where is this used? startup zips (untested)
+ specification = input.splitmethod(specification)
+ local zipfile = specification.path
+ local zfile = zip.openarchive(instance,name) -- tricky, could be in to be initialized tree
+ if zfile then
+ input.logger('! zip locator', specification.original ..' found')
+ else
+ input.logger('? zip locator', specification.original ..' not found')
+ end
+ end
+
+ function input.hashers.zip(instance,tag,name)
+ input.report("loading zip file",name,"as",tag)
+ input.usezipfile(instance,tag .."?tree=" .. name)
+ end
+
+ function input.concatinators.zip(tag,path,name)
+ if not path or path == "" then
+ return tag .. '?name=' .. name
+ else
+ return tag .. '?name=' .. path .. "/" .. name
+ end
+ end
+
+ function input.is_readable.zip(name)
+ return true
+ end
+
+ function input.finders.zip(instance,specification,filetype)
+ specification = input.splitmethod(specification)
+ if specification.path then
+ local q = url.query(specification.query)
+ if q.name then
+ local zfile = zip.openarchive(instance,specification.path)
+ if zfile then
+ input.logger('! zip finder',specification.path)
+ local dfile = zfile:open(q.name)
+ if dfile then
+ dfile = zfile:close()
+ input.logger('+ zip finder',q.name)
+ return specification.original
+ end
+ else
+ input.logger('? zip finder',specification.path)
+ end
+ end
+ end
+ input.logger('- zip finder',filename)
+ return unpack(input.finders.notfound)
+ end
+
+ function input.openers.zip(instance,specification)
+ local zipspecification = input.splitmethod(specification)
+ if zipspecification.path then
+ local q = url.query(zipspecification.query)
+ if q.name then
+ local zfile = zip.openarchive(instance,zipspecification.path)
+ if zfile then
+ input.logger('+ zip starter',zipspecification.path)
+ local dfile = zfile:open(q.name)
+ if dfile then
+ input.show_open(specification)
+ return input.openers.text_opener(specification,dfile,'zip')
+ end
+ else
+ input.logger('- zip starter',zipspecification.path)
+ end
+ end
+ end
+ input.logger('- zip opener',filename)
+ return unpack(input.openers.notfound)
+ end
+
+ function input.loaders.zip(instance,specification)
+ specification = input.splitmethod(specification)
+ if specification.path then
+ local q = url.query(specification.query)
+ if q.name then
+ local zfile = zip.openarchive(instance,specification.path)
+ if zfile then
+ input.logger('+ zip starter',specification.path)
+ local dfile = zfile:open(q.name)
+ if dfile then
+ input.show_load(filename)
+ input.logger('+ zip loader',filename)
+ local s = dfile:read("*all")
+ dfile:close()
+ return true, s, #s
+ end
+ else
+ input.logger('- zip starter',specification.path)
+ end
+ end
+ end
+ input.logger('- zip loader',filename)
+ return unpack(input.openers.notfound)
+ end
+
+ -- zip:///somefile.zip
+ -- zip:///somefile.zip?tree=texmf-local -> mount
+
+ function input.usezipfile(instance,zipname)
+ zipname = validzip(zipname)
+ input.logger('! zip use','file '..zipname)
+ local specification = input.splitmethod(zipname)
+ local zipfile = specification.path
+ if zipfile and not zip.registeredfiles[zipname] then
+ local tree = url.query(specification.query).tree or ""
+ input.logger('! zip register','file '..zipname)
+ local z = zip.openarchive(instance,zipfile)
+ if z then
+ input.logger("= zipfile","registering "..zipname)
+ input.starttiming(instance)
+ input.aux.prepend_hash(instance,'zip',zipname,zipfile)
+ input.aux.extend_texmf_var(instance,zipname) -- resets hashes too
+ zip.registeredfiles[zipname] = z
+ instance.files[zipname] = input.aux.register_zip_file(z,tree or "")
+ input.stoptiming(instance)
+ else
+ input.logger("? zipfile","unknown "..zipname)
+ end
+ else
+ input.logger('! zip register','no file '..zipname)
+ end
+ end
+
+ function input.aux.register_zip_file(z,tree)
+ local files, filter = { }, ""
+ if tree == "" then
+ filter = "^(.+)/(.-)$"
+ else
+ filter = "^"..tree.."/(.+)/(.-)$"
+ end
+ input.logger('= zip filter',filter)
+ local register, n = input.aux.register_file, 0
+ for i in z:files() do
+ local path, name = i.filename:match(filter)
+ if path then
+ if name and name ~= '' then
+ register(files, name, path)
+ n = n + 1
+ else
+ -- directory
+ end
+ else
+ register(files, i.filename, '')
+ n = n + 1
+ end
+ end
+ input.report('= zip entries',n)
+ return files
+ end
+
+end