data-vir.lmt /size: 4253 b    last modification: 2025-02-21 11:03
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 data      = { }
20local keep      = { }
21
22do
23
24    local n = 0 -- hm, number can be query
25
26    local f_virtual_n = formatters["virtual://%s.%s"]
27    local f_virtual_y = formatters["virtual://%s-%s.%s"]
28
29    local function virtualname(specification,suffix)
30        n = n + 1 -- one number for all namespaces
31        local path = type(specification) == "table" and specification.path or specification
32        if type(path) ~= "string" or path == "" then
33            path = "virtualfile"
34        end
35        return suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,n)
36    end
37
38    local function directvirtual(filename,content,persistent)
39        if not content then
40            content = ""
41        end
42        if trace_virtual then
43            report_virtual("saver: file %a saved, size %i",filename,#content)
44        end
45        data[filename] = content or ""
46        keep[filename] = persistent
47        return filename
48    end
49
50    local savers = resolvers.savers
51
52    savers.virtualname   = virtualname
53    savers.directvirtual = directvirtual
54
55    function savers.virtual(specification,content,suffix)
56        return directvirtual(virtualname(specification,suffix),content)
57    end
58
59
60end
61
62do
63
64    local cleaners = resolvers.cleaners
65
66    function cleaners.virtual(filename)
67        if trace_virtual then
68            report_virtual("cleaner: file %a deleted",filename)
69        end
70        data[filename] = nil
71        keep[filename] = nil
72    end
73
74end
75
76do
77
78    local finders  = resolvers.finders
79    local notfound = finders.notfound
80
81    function finders.virtual(specification)
82        local original = specification.original
83        local d = data[original]
84        if d then
85            if trace_virtual then
86                report_virtual("finder: file %a found",original)
87            end
88            return original
89        else
90            if trace_virtual then
91                report_virtual("finder: unknown file %a",original)
92            end
93            return notfound()
94        end
95    end
96
97end
98
99do
100
101    local openers    = resolvers.openers
102    local notfound   = openers.notfound
103    local textopener = openers.helpers.textopener
104
105    function openers.virtual(specification)
106        local original = specification.original
107        local d = data[original]
108        if d then
109            if trace_virtual then
110                report_virtual("opener: file %a opened",original)
111            end
112            data[original] = nil -- when we comment this we can have error messages
113            -- With utf-8 we signal that no regime is to be applied!
114         -- characters.showstring(d)
115            return textopener("virtual",original,d,"utf-8")
116        else
117            if trace_virtual then
118                report_virtual("opener: file %a not found",original)
119            end
120            return notfound()
121        end
122    end
123
124end
125
126-- local closers = resolvers.closers
127
128-- function closers.virtual(specification)
129--     inspect(specification)
130-- end
131
132do
133
134    local loaders  = resolvers.loaders
135    local notfound = loaders.notfound
136
137    function loaders.virtual(specification)
138        local original = specification.original
139        local d = data[original]
140        if d then
141            if trace_virtual then
142                report_virtual("loader: file %a loaded",original)
143            end
144            if not keep[original] then
145                data[original] = nil
146                keep[original] = nil
147            end
148            return true, d, #d
149        end
150        if trace_virtual then
151            report_virtual("loader: file %a not loaded",original)
152        end
153        return notfound()
154    end
155
156end
157