summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/file-lib.lua
blob: 62cf938ba4d637bcc27573b578f6a9e4c4e0e472 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
if not modules then modules = { } end modules ['file-lib'] = {
    version   = 1.001,
    comment   = "companion to file-lib.mkvi",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- todo: check all usage of truefilename at the tex end and remove
-- files there (and replace definitions by full names)

local format, gsub = string.format, string.gsub

local trace_libraries = false  trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
----- trace_files     = false  trackers.register("resolvers.readfile",  function(v) trace_files     = v end)

local report_library  = logs.reporter("files","library")
----- report_files    = logs.reporter("files","readfile")

local removesuffix    = file.removesuffix

local getreadfilename = resolvers.getreadfilename

local loaded          = { }
local defaultpatterns = { "%s" }

local function defaultaction(name,foundname)
    report_files("asked name %a, found name %a",name,foundname)
end

local function defaultfailure(name)
    report_files("asked name %a, not found",name)
end

function resolvers.uselibrary(specification) -- todo: reporter
    local name = specification.name
    if name and name ~= "" then
        local patterns = specification.patterns or defaultpatterns
        local action   = specification.action   or defaultaction
        local failure  = specification.failure  or defaultfailure
        local onlyonce = specification.onlyonce
        local files    = utilities.parsers.settings_to_array(name)
        local truename = environment.truefilename
        local function found(filename)
            local somename  = truename and truename(filename) or filename
            local foundname = getreadfilename("any",".",somename) -- maybe some day also an option not to backtrack .. and ../.. (or block global)
            return foundname ~= "" and foundname
        end
        for i=1,#files do
            local filename = files[i]
            if not loaded[filename] then
                local foundname = nil
                local barename  = removesuffix(filename)
                -- direct search (we have an explicit suffix)
                if barename ~= filename then
                    foundname = found(filename)
                    if trace_libraries then
                        report_library("checking %a: %s",filename,foundname or "not found")
                    end
                end
                if not foundname then
                    -- pattern based search
                    for i=1,#patterns do
                        local wanted = format(patterns[i],barename)
                        foundname = found(wanted)
                        if trace_libraries then
                            report_library("checking %a as %a: %s",filename,wanted,foundname or "not found")
                        end
                        if foundname then
                            break
                        end
                    end
                end
                if not loaded[foundname] then
                    if foundname then
                        action(name,foundname)
                        if onlyonce then
                            loaded[foundname] = true -- todo: base this on return value
                        end
                    elseif failure then
                        failure(name)
                    end
                    if onlyonce then
                        loaded[filename]  = true -- todo: base this on return value
                    end
                end
            end
        end
    end
end

commands.uselibrary = resolvers.uselibrary -- for the moment