data-vir.lmt /size: 3633 b    last modification: 2024-01-16 10:22
1if not modules then modules = { } end modules ['data-vir'] = {
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
9local type = type
10local formatters = string.formatters
11
12local trace_virtual  = false
13local report_virtual = logs.reporter("resolvers","virtual")
14
15trackers.register("resolvers.locating", function(v) trace_virtual = v end)
16trackers.register("resolvers.virtual",  function(v) trace_virtual = v end)
17
18local resolvers = resolvers
19local savers    = resolvers.savers
20local cleaners  = resolvers.cleaners
21
22local data        = { }
23local keep        = { }
24local n           = 0 -- hm, number can be query
25local f_virtual_n = formatters["virtual://%s.%s"]
26local f_virtual_y = formatters["virtual://%s-%s.%s"]
27
28local function virtualname(specification,suffix)
29    n = n + 1 -- one number for all namespaces
30    local path = type(specification) == "table" and specification.path or specification
31    if type(path) ~= "string" or path == "" then
32        path = "virtualfile"
33    end
34    return suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,n)
35end
36
37local function directvirtual(filename,content,persistent)
38    if not content then
39        content = ""
40    end
41    if trace_virtual then
42        report_virtual("saver: file %a saved, size %i",filename,#content)
43    end
44    data[filename] = content or ""
45    keep[filename] = persistent
46    return filename
47end
48
49function savers.virtual(specification,content,suffix)
50    return directvirtual(virtualname(specification,suffix),content)
51end
52
53savers.virtualname   = virtualname
54savers.directvirtual = directvirtual
55
56function cleaners.virtual(filename)
57    data[filename] = nil
58    keep[filename] = nil
59end
60
61local finders  = resolvers.finders
62local notfound = finders.notfound
63
64function finders.virtual(specification)
65    local original = specification.original
66    local d = data[original]
67    if d then
68        if trace_virtual then
69            report_virtual("finder: file %a found",original)
70        end
71        return original
72    else
73        if trace_virtual then
74            report_virtual("finder: unknown file %a",original)
75        end
76        return notfound()
77    end
78end
79
80local openers    = resolvers.openers
81local notfound   = openers.notfound
82local textopener = openers.helpers.textopener
83
84function openers.virtual(specification)
85    local original = specification.original
86    local d = data[original]
87    if d then
88        if trace_virtual then
89            report_virtual("opener: file %a opened",original)
90        end
91        data[original] = nil -- when we comment this we can have error messages
92        -- With utf-8 we signal that no regime is to be applied!
93     -- characters.showstring(d)
94        return textopener("virtual",original,d,"utf-8")
95    else
96        if trace_virtual then
97            report_virtual("opener: file %a not found",original)
98        end
99        return notfound()
100    end
101end
102
103local loaders  = resolvers.loaders
104local notfound = loaders.notfound
105
106function loaders.virtual(specification)
107    local original = specification.original
108    local d = data[original]
109    if d then
110        if trace_virtual then
111            report_virtual("loader: file %a loaded",original)
112        end
113        if not keep[original] then
114            data[original] = nil
115            keep[original] = nil
116        end
117        return true, d, #d
118    end
119    if trace_virtual then
120        report_virtual("loader: file %a not loaded",original)
121    end
122    return notfound()
123end
124