file-lib.lua /size: 4550 b    last modification: 2020-07-01 14:35
1if not modules then modules = { } end modules ['file-lib'] = {
2    version   = 1.001,
3    comment   = "companion to file-lib.mkvi",
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-- todo: check all usage of truefilename at the tex end and remove
10-- files there (and replace definitions by full names)
11
12local format, gsub = string.format, string.gsub
13
14local trace_libraries = false  trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
15----- trace_files     = false  trackers.register("resolvers.readfile",  function(v) trace_files     = v end)
16
17local report_library  = logs.reporter("files","library")
18----- report_files    = logs.reporter("files","readfile")
19
20local removesuffix    = file.removesuffix
21
22local getreadfilename = resolvers.getreadfilename
23
24local loaded          = { }
25local defaultpatterns = { "%s" }
26
27local function defaultaction(name,foundname)
28    report_files("asked name %a, found name %a",name,foundname)
29end
30
31local function defaultfailure(name)
32    report_files("asked name %a, not found",name)
33end
34
35function resolvers.uselibrary(specification) -- todo: reporter
36    local name = specification.name
37    if name and name ~= "" then
38        local patterns = specification.patterns or defaultpatterns
39        local action   = specification.action   or defaultaction
40        local failure  = specification.failure  or defaultfailure
41        local onlyonce = specification.onlyonce
42        local files    = utilities.parsers.settings_to_array(name)
43        local truename = environment.truefilename
44        local function found(filename)
45            local somename  = truename and truename(filename) or filename
46            local foundname = getreadfilename("any",".",somename) -- maybe some day also an option not to backtrack .. and ../.. (or block global)
47            return foundname ~= "" and foundname
48        end
49        for i=1,#files do
50            local filename = files[i]
51            if not loaded[filename] then
52                local foundname = nil
53                local barename  = removesuffix(filename)
54                -- direct search (we have an explicit suffix)
55                if barename ~= filename then
56                    foundname = found(filename)
57                    if trace_libraries then
58                        report_library("checking %a: %s",filename,foundname or "not found")
59                    end
60                end
61                if not foundname then
62                    -- pattern based search
63                    for i=1,#patterns do
64                        local pattern = patterns[i]
65                        if pattern and pattern ~= "" then
66                            local wanted = format(pattern,barename)
67                            foundname = found(wanted)
68                            if trace_libraries then
69                                report_library("checking %a as %a: %s",filename,wanted,foundname or "not found")
70                            end
71                            if foundname then
72                                break
73                            end
74                        else
75                            -- can be a bogus path (coming from a test)
76                        end
77                    end
78                end
79                if not loaded[foundname] then
80                    if foundname then
81                        action(name,foundname)
82                        if onlyonce then
83                            loaded[foundname] = true -- todo: base this on return value
84                        end
85                    elseif failure then
86                        failure(name)
87                    end
88                    if onlyonce then
89                        loaded[filename]  = true -- todo: base this on return value
90                    end
91                end
92            end
93        end
94    end
95end
96
97-- We keep these in the commands namespace even if it's not that logical
98-- but this way we are compatible.
99
100function commands.loadlibrary(name,foundname,nointerference)
101    if not foundname then
102        foundname = name
103    end
104    if foundname and foundname ~= "" then
105        if nointerference then
106            context.startnointerference()
107        end
108        context.startreadingfile()
109        context.input(foundname)
110        context.stopreadingfile()
111        if nointerference then
112            context.stopnointerference()
113        end
114    end
115end
116
117commands.uselibrary = resolvers.uselibrary
118