From 85b7bc695629926641c7cb752fd478adfdf374f3 Mon Sep 17 00:00:00 2001 From: Marius Date: Sun, 4 Jul 2010 15:32:09 +0300 Subject: stable 2010-05-24 13:10 --- tex/context/base/supp-fil.lua | 279 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 tex/context/base/supp-fil.lua (limited to 'tex/context/base/supp-fil.lua') diff --git a/tex/context/base/supp-fil.lua b/tex/context/base/supp-fil.lua new file mode 100644 index 000000000..8d69f64a7 --- /dev/null +++ b/tex/context/base/supp-fil.lua @@ -0,0 +1,279 @@ +if not modules then modules = { } end modules ['supp-fil'] = { + version = 1.001, + comment = "companion to supp-fil.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +

It's more convenient to manipulate filenames (paths) in + than in . These methods have counterparts +at the side.

+--ldx]]-- + +local find, gsub, match, format, concat = string.find, string.gsub, string.match, string.format, table.concat +local texsprint, texwrite, ctxcatcodes = tex.sprint, tex.write, tex.ctxcatcodes + +local trace_modules = false trackers.register("modules.loading", function(v) trace_modules = v end) + +support = support or { } +environment = environment or { } + +environment.outputfilename = environment.outputfilename or environment.jobname + +function support.checkfilename(str) -- "/whatever..." "c:..." "http://..." + commands.chardef("kindoffile",boolean.tonumber(find(str,"^/") or find(str,"[%a]:"))) +end + +function support.thesanitizedfilename(str) + texwrite((gsub(str,"\\","/"))) +end + +function support.splitfilename(fullname) + local path, name, base, suffix, kind = '', fullname, fullname, '', 0 + local p, n = match(fullname,"^(.+)/(.-)$") + if p and n then + path, name, base = p, n, n + end + local b, s = match(base,"^(.+)%.(.-)$") + if b and s then + name, suffix = b, s + end + if path == "" then + kind = 0 + elseif path == '.' then + kind = 1 + else + kind = 2 + end + commands.def("splitofffull", fullname) + commands.def("splitoffpath", path) + commands.def("splitoffbase", base) + commands.def("splitoffname", name) + commands.def("splitofftype", suffix) + commands.chardef("splitoffkind", kind) +end + +function support.splitfiletype(fullname) + local name, suffix = fullname, '' + local n, s = match(fullname,"^(.+)%.(.-)$") + if n and s then + name, suffix = n, s + end + commands.def("splitofffull", fullname) + commands.def("splitoffpath", "") + commands.def("splitoffname", name) + commands.def("splitofftype", suffix) +end + +function support.doifparentfileelse(n) + commands.testcase(n==environment.jobname or n==environment.jobname..'.tex' or n==environment.outputfilename) +end + +-- saves some .15 sec on 12 sec format generation + +local lastexistingfile = "" + +function support.doiffileexistelse(name) + if not name or name == "" then + lastexistingfile = "" + else + lastexistingfile = resolvers.findtexfile(name) or "" + end + return commands.testcase(lastexistingfile ~= "") +end + +function support.lastexistingfile() + texsprint(ctxcatcodes,lastexistingfile) +end + +-- more, we can cache matches + +local finders, loaders, openers = resolvers.finders, resolvers.loaders, resolvers.openers + +local found = { } -- can best be done in the resolver itself + +-- todo: tracing + +local function readfilename(specification,backtrack,treetoo) + local fnd = found[specification] + if not fnd then + local splitspec = resolvers.splitmethod(specification) + local filename = splitspec.path or "" + if lfs.isfile(filename) then + fnd = filename + end + if not fnd and backtrack then + local fname = filename + for i=1,backtrack,1 do + fname = "../" .. fname + if lfs.isfile(fname) then + fnd = fname + break + end + end + end + if not fnd and treetoo then +--~ fnd = resolvers.find_file(filename) + fnd = resolvers.findtexfile(filename) + end + found[specification] = fnd + end + return fnd or "" +end + +support.readfilename = readfilename + +function finders.job(filename) return readfilename(filename,nil,false) end -- current path, no backtracking +function finders.loc(filename) return readfilename(filename,2, false) end -- current path, backtracking +function finders.sys(filename) return readfilename(filename,nil,true ) end -- current path, obeys tex search +function finders.fix(filename) return readfilename(filename,2, false) end -- specified path, backtracking +function finders.set(filename) return readfilename(filename,nil,false) end -- specified path, no backtracking +function finders.any(filename) return readfilename(filename,2, true ) end -- loc job sys + +openers.job = openers.generic loaders.job = loaders.generic +openers.loc = openers.generic loaders.loc = loaders.generic +openers.sys = openers.generic loaders.sys = loaders.generic +openers.fix = openers.generic loaders.fix = loaders.generic +openers.set = openers.generic loaders.set = loaders.generic +openers.any = openers.generic loaders.any = loaders.generic + +function support.doreadfile(protocol,path,name) -- better do a split and then pass table + local specification + if url.hasscheme(name) then + specification = name + else + specification = ((path == "") and format("%s:///%s",protocol,name)) or format("%s:///%s/%s",protocol,path,name) + end + texsprint(ctxcatcodes,resolvers.findtexfile(specification)) +end + +-- modules can only have a tex or mkiv suffix or can have a specified one + +local prefixes = { "m", "p", "s", "x", "t" } +local suffixes = { "tex", "mkiv" } +local modstatus = { } + +local function usemodule(name,hassheme) + local foundname + if hasscheme then + -- no auto suffix as http will return a home page or error page + -- so we only add one if missing + local fullname = file.addsuffix(name,"tex") + if trace_modules then + logs.report("modules","checking scheme driven file '%s'",fullname) + end + foundname = resolvers.findtexfile(fullname) or "" + elseif file.extname(name) ~= "" then + if trace_modules then + logs.report("modules","checking suffix driven file '%s'",name) + end + foundname = support.readfilename(name,false,true) or "" + else + for i=1,#suffixes do + local fullname = file.addsuffix(name,suffixes[i]) + if trace_modules then + logs.report("modules","checking suffix driven file '%s'",fullname) + end + foundname = support.readfilename(fullname,false,true) or "" + if foundname ~= "" then + break + end + end + end + if foundname ~= "" then + if trace_modules then + logs.report("modules","loading '%s'",foundname) + end + context.startreadingfile() + context.input(foundname) + context.stopreadingfile() + return true + else + return false + end +end + +function support.usemodules(prefix,askedname,truename) + local hasprefix = prefix and prefix ~= "" + local hashname = ((hasprefix and prefix) or "*") .. "-" .. truename + local status = modstatus[hashname] + if status == 0 then + -- not found + elseif status == 1 then + status = status + 1 + else + if trace_modules then + logs.report("modules","locating '%s'",truename) + end + local hasscheme = url.hasscheme(truename) + if hasscheme then + -- no prefix and suffix done + if usemodule(truename,true) then + status = 1 + else + status = 0 + end + elseif hasprefix then + if usemodule(prefix .. "-" .. truename) then + status = 1 + else + status = 0 + end + else + for i=1,#prefixes do + -- todo: reconstruct name i.e. basename + local thename = prefixes[i] .. "-" .. truename + if usemodule(thename) then + status = 1 + break + end + end + if status then + -- ok, don't change + elseif usemodule(truename) then + status = 1 + else + status = 0 + end + end + end + if status == 0 then + if trace_modules then + logs.report("modules","skipping '%s' (not found)",truename) + else + interfaces.showmessage("systems",6,askedname) + end + elseif status == 1 then + if not trace_modules then + interfaces.showmessage("systems",5,askedname) + end + else + if trace_modules then + logs.report("modules","skipping '%s' (already loaded)",truename) + else + interfaces.showmessage("systems",7,askedname) + end + end + modstatus[hashname] = status +end + +statistics.register("loaded tex modules", function() + if next(modstatus) then + local t, f = { }, { } + for k, v in table.sortedhash(modstatus) do + k = file.basename(k) + if v == 0 then + f[#f+1] = k + else + t[#t+1] = k + end + end + local ts = (#t>0 and format(" (%s)",concat(t," "))) or "" + local fs = (#f>0 and format(" (%s)",concat(f," "))) or "" + return format("%s requested, %s found%s, %s missing%s",#t+#f,#t,ts,#f,fs) + else + return nil + end +end) -- cgit v1.2.3