data-pre.lua /size: 5872 b    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['data-pre'] = {
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
9-- filename        : only the basename, including suffix (file:)
10-- pathname        : the pathpart (path:)
11-- locate          : lookup in database (full: kpse: loc:)
12-- home            : home path
13-- jobpath         : job path
14-- relative        : relative path ./ ../ ../.. (rel:)
15-- auto            : relatove or lookup
16-- toppath         : topmost path in input stack
17-- selfautodir     : rather tex specific
18-- selfautoloc     : rather tex specific
19-- selfautoparent  : rather tex specific
20-- environment     : expansion of variable (env:)
21--
22-- nodename        : computer name
23-- machine         : private, when set
24-- sysname         : operating system name
25-- version         : operating system version
26-- release         : operating system release
27
28
29local ipairs = ipairs
30local insert, remove = table.insert, table.remove
31
32local resolvers     = resolvers
33local prefixes      = resolvers.prefixes
34
35local cleanpath     = resolvers.cleanpath
36local findgivenfile = resolvers.findgivenfile
37local expansion     = resolvers.expansion
38local getenv        = resolvers.getenv -- we can probably also use resolvers.expansion
39
40local basename      = file.basename
41local dirname       = file.dirname
42local joinpath      = file.join
43
44local isfile        = lfs.isfile
45local isdir         = lfs.isdir
46
47prefixes.environment = function(str)
48    return cleanpath(expansion(str))
49end
50
51local function relative(str,n)
52    if not isfile(str) then
53        local pstr = "./" .. str
54        if isfile(pstr) then
55            str = pstr
56        else
57            local p = "../"
58            for i=1,n or 2 do
59                local pstr = p .. str
60                if isfile(pstr) then
61                    str = pstr
62                    break
63                else
64                    p = p .. "../"
65                end
66            end
67        end
68    end
69    return cleanpath(str)
70end
71
72local function locate(str)
73    local fullname = findgivenfile(str) or ""
74    return cleanpath(fullname ~= "" and fullname or str)
75end
76
77prefixes.relative = relative
78prefixes.locate   = locate
79
80prefixes.auto = function(str)
81    local fullname = relative(str)
82    if not isfile(fullname) then
83        fullname = locate(str)
84    end
85    return fullname
86end
87
88prefixes.filename = function(str)
89    local fullname = findgivenfile(str) or ""
90    return cleanpath(basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
91end
92
93prefixes.pathname = function(str)
94    local fullname = findgivenfile(str) or ""
95    return cleanpath(dirname((fullname ~= "" and fullname) or str))
96end
97
98-- we can actually freeze these
99
100prefixes.selfautoloc = function(str)
101    local pth = getenv('SELFAUTOLOC')
102    return cleanpath(str and joinpath(pth,str) or pth)
103end
104
105prefixes.selfautoparent = function(str)
106    local pth = getenv('SELFAUTOPARENT')
107    return cleanpath(str and joinpath(pth,str) or pth)
108end
109
110prefixes.selfautodir = function(str)
111    local pth = getenv('SELFAUTODIR')
112    return cleanpath(str and joinpath(pth,str) or pth)
113end
114
115prefixes.home = function(str)
116    local pth = getenv('HOME')
117    return cleanpath(str and joinpath(pth,str) or pth)
118end
119
120do
121    local tmppth
122
123    prefixes.temp = function(str)
124        if not tmppth then
125            for _, s in ipairs { "TMP", "TEMP", "TMPDIR", "TEMPDIR" } do
126                tmppth = getenv(s)
127                if tmppth ~= "" and isdir(tmppth) then
128                    break
129                end
130            end
131            if not tmppth or tmppth == "" then
132                tmppth = "."
133            end
134        end
135        return cleanpath(str and joinpath(tmppth,str) or tmppth)
136    end
137
138    prefixes.texruns = function(str)
139        local pth = getenv('TEXRUNS')
140        if pth == "" then
141            pth = tmppth
142        end
143        return cleanpath(str and joinpath(pth,str) or pth)
144    end
145
146end
147
148prefixes.env  = prefixes.environment
149prefixes.rel  = prefixes.relative
150prefixes.loc  = prefixes.locate
151prefixes.kpse = prefixes.locate
152prefixes.full = prefixes.locate
153prefixes.file = prefixes.filename
154prefixes.path = prefixes.pathname
155
156-- This one assumes that inputstack is set (used in the tex loader). It is a momentary resolve
157-- as the top of the input stack changes.
158
159local inputstack = { }
160local stackpath  = resolvers.stackpath
161
162local function toppath()
163    if not inputstack then                  -- more convenient to keep it here
164        return "."
165    end
166    local pathname = dirname(inputstack[#inputstack] or "")
167    if pathname == "" then
168        return "."
169    else
170        return pathname
171    end
172end
173
174-- The next variant is similar but bound to explicitly registered paths. Practice should
175-- show if that gives the same results as the previous one. It is meant for a project
176-- stucture.
177
178local function jobpath()
179    local path = stackpath()
180    if not path or path == "" then
181        return "."
182    else
183        return path
184    end
185end
186
187local function pushinputname(name)
188    insert(inputstack,name)
189end
190
191local function popinputname(name)
192    return remove(inputstack)
193end
194
195resolvers.toppath       = toppath
196resolvers.jobpath       = jobpath
197resolvers.pushinputname = pushinputname
198resolvers.popinputname  = popinputname
199
200-- This hook sit into the resolver:
201
202prefixes.toppath = function(str) return cleanpath(joinpath(toppath(),str)) end -- str can be nil or empty
203prefixes.jobpath = function(str) return cleanpath(joinpath(jobpath(),str)) end -- str can be nil or empty
204
205resolvers.setdynamic("toppath")
206resolvers.setdynamic("jobpath")
207
208-- for a while (obsolete):
209--
210-- prefixes.jobfile = prefixes.jobpath
211-- resolvers.setdynamic("jobfile")
212