diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
commit | fc4466b32ed330a956ac603b00fd145524cff49a (patch) | |
tree | 2c50e2b8de13aa9233b2c76dffe201558f169e86 /Master/texmf-dist/tex/context/base/mkiv/util-env.lua | |
parent | 50e2368597d5f6fe2057195d0ae6a9f2044923e4 (diff) |
context (22apr16)
git-svn-id: svn://tug.org/texlive/trunk@40691 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/util-env.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/util-env.lua | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/util-env.lua b/Master/texmf-dist/tex/context/base/mkiv/util-env.lua new file mode 100644 index 00000000000..b72226900a9 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/util-env.lua @@ -0,0 +1,262 @@ +if not modules then modules = { } end modules ['util-env'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local allocate, mark = utilities.storage.allocate, utilities.storage.mark + +local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find +local unquoted, quoted, optionalquoted = string.unquoted, string.quoted, string.optionalquoted +local concat, insert, remove = table.concat, table.insert, table.remove + +environment = environment or { } +local environment = environment + +-- precautions + +os.setlocale(nil,nil) -- useless feature and even dangerous in luatex + +function os.setlocale() + -- no way you can mess with it +end + +-- dirty tricks (we will replace the texlua call by luatex --luaonly) + +local validengines = allocate { + ["luatex"] = true, + ["luajittex"] = true, + -- ["luatex.exe"] = true, + -- ["luajittex.exe"] = true, +} + +local basicengines = allocate { + ["luatex"] = "luatex", + ["texlua"] = "luatex", + ["texluac"] = "luatex", + ["luajittex"] = "luajittex", + ["texluajit"] = "luajittex", + -- ["texlua.exe"] = "luatex", + -- ["texluajit.exe"] = "luajittex", +} + +local luaengines = allocate { + ["lua"] = true, + ["luajit"] = true, +} + +environment.validengines = validengines +environment.basicengines = basicengines + +-- [-1] = binary +-- [ 0] = self +-- [ 1] = argument 1 ... + +-- instead we could set ranges + +if not arg then + environment.used_as_library = true + -- used as library +elseif luaengines[file.removesuffix(arg[-1])] then +-- arg[-1] = arg[0] +-- arg[ 0] = arg[1] +-- for k=2,#arg do +-- arg[k-1] = arg[k] +-- end +-- remove(arg) -- last +-- +-- environment.used_as_library = true +elseif validengines[file.removesuffix(arg[0])] then + if arg[1] == "--luaonly" then + arg[-1] = arg[0] + arg[ 0] = arg[2] + for k=3,#arg do + arg[k-2] = arg[k] + end + remove(arg) -- last + remove(arg) -- pre-last + else + -- tex run + end + + -- This is an ugly hack but it permits symlinking a script (say 'context') to 'mtxrun' as in: + -- + -- ln -s /opt/minimals/tex/texmf-linux-64/bin/mtxrun context + -- + -- The special mapping hack is needed because 'luatools' boils down to 'mtxrun --script base' + -- but it's unlikely that there will be more of this + + local originalzero = file.basename(arg[0]) + local specialmapping = { luatools == "base" } + + if originalzero ~= "mtxrun" and originalzero ~= "mtxrun.lua" then + arg[0] = specialmapping[originalzero] or originalzero + insert(arg,0,"--script") + insert(arg,0,"mtxrun") + end + +end + +-- environment + +environment.arguments = allocate() +environment.files = allocate() +environment.sortedflags = nil + +-- context specific arguments (in order not to confuse the engine) + +function environment.initializearguments(arg) + local arguments, files = { }, { } + environment.arguments, environment.files, environment.sortedflags = arguments, files, nil + for index=1,#arg do + local argument = arg[index] + if index > 0 then + local flag, value = match(argument,"^%-+(.-)=(.-)$") + if flag then + flag = gsub(flag,"^c:","") + arguments[flag] = unquoted(value or "") + else + flag = match(argument,"^%-+(.+)") + if flag then + flag = gsub(flag,"^c:","") + arguments[flag] = true + else + files[#files+1] = argument + end + end + end + end + environment.ownname = file.reslash(environment.ownname or arg[0] or 'unknown.lua') +end + +function environment.setargument(name,value) + environment.arguments[name] = value +end + +-- todo: defaults, better checks e.g on type (boolean versus string) +-- +-- tricky: too many hits when we support partials unless we add +-- a registration of arguments so from now on we have 'partial' + +function environment.getargument(name,partial) + local arguments, sortedflags = environment.arguments, environment.sortedflags + if arguments[name] then + return arguments[name] + elseif partial then + if not sortedflags then + sortedflags = allocate(table.sortedkeys(arguments)) + for k=1,#sortedflags do + sortedflags[k] = "^" .. sortedflags[k] + end + environment.sortedflags = sortedflags + end + -- example of potential clash: ^mode ^modefile + for k=1,#sortedflags do + local v = sortedflags[k] + if find(name,v) then + return arguments[sub(v,2,#v)] + end + end + end + return nil +end + +environment.argument = environment.getargument + +function environment.splitarguments(separator) -- rather special, cut-off before separator + local done, before, after = false, { }, { } + local originalarguments = environment.originalarguments + for k=1,#originalarguments do + local v = originalarguments[k] + if not done and v == separator then + done = true + elseif done then + after[#after+1] = v + else + before[#before+1] = v + end + end + return before, after +end + +function environment.reconstructcommandline(arg,noquote) + local resolveprefix = resolvers.resolve -- something rather special + arg = arg or environment.originalarguments + if noquote and #arg == 1 then + return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1]) + elseif #arg > 0 then + local result = { } + for i=1,#arg do + result[i] = optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix) + end + return concat(result," ") + else + return "" + end +end + +-- handy in e.g. package.addluapath(environment.relativepath("scripts")) + +function environment.relativepath(path,root) + if not path then + path = "" + end + if not file.is_rootbased_path(path) then + if not root then + root = file.pathpart(environment.ownscript or environment.ownname or ".") + end + if root == "" then + root = "." + end + path = root .. "/" .. path + end + return file.collapsepath(path,true) +end + +-- -- when script lives on e:/tmp we get this: +-- +-- print(environment.relativepath("x/y/z","c:/w")) -- c:/w/x/y/z +-- print(environment.relativepath("x")) -- e:/tmp/x +-- print(environment.relativepath("../x")) -- e:/x +-- print(environment.relativepath("./x")) -- e:/tmp/x +-- print(environment.relativepath("/x")) -- /x +-- print(environment.relativepath("c:/x")) -- c:/x +-- print(environment.relativepath("//x")) -- //x +-- print(environment.relativepath()) -- e:/tmp + +if arg then + + -- new, reconstruct quoted snippets (maybe better just remove the " then and add them later) + + local newarg, instring = { }, false + + for index=1,#arg do + local argument = arg[index] + if find(argument,"^\"") then + newarg[#newarg+1] = gsub(argument,"^\"","") + if not find(argument,"\"$") then + instring = true + end + elseif find(argument,"\"$") then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") + instring = false + elseif instring then + newarg[#newarg] = newarg[#newarg] .. " " .. argument + else + newarg[#newarg+1] = argument + end + end + for i=1,-5,-1 do + newarg[i] = arg[i] + end + + environment.initializearguments(newarg) + + environment.originalarguments = mark(newarg) + environment.rawarguments = mark(arg) + + arg = { } -- prevent duplicate handling + +end |