summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/data-vir.lmt
blob: 75a8c68c02e1fd244924a00f8d5fe1d258c317de (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
if not modules then modules = { } end modules ['data-vir'] = {
    version   = 1.001,
    comment   = "companion to luat-lib.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local type = type
local formatters = string.formatters

local trace_virtual  = false
local report_virtual = logs.reporter("resolvers","virtual")

trackers.register("resolvers.locating", function(v) trace_virtual = v end)
trackers.register("resolvers.virtual",  function(v) trace_virtual = v end)

local resolvers = resolvers
local savers    = resolvers.savers
local cleaners  = resolvers.cleaners

local data        = { }
local keep        = { }
local n           = 0 -- hm, number can be query
local f_virtual_n = formatters["virtual://%s.%s"]
local f_virtual_y = formatters["virtual://%s-%s.%s"]

local function virtualname(specification,suffix)
    n = n + 1 -- one number for all namespaces
    local path = type(specification) == "table" and specification.path or specification
    if type(path) ~= "string" or path == "" then
        path = "virtualfile"
    end
    return suffix and f_virtual_y(path,n,suffix) or f_virtual_n(path,n)
end

local function directvirtual(filename,content,persistent)
    if not content then
        content = ""
    end
    if trace_virtual then
        report_virtual("saver: file %a saved, size %i",filename,#content)
    end
    data[filename] = content or ""
    keep[filename] = persistent
    return filename
end

function savers.virtual(specification,content,suffix)
    return directvirtual(virtualname(specification,suffix),content)
end

savers.virtualname   = virtualname
savers.directvirtual = directvirtual

function cleaners.virtual(filename)
    data[filename] = nil
    keep[filename] = nil
end

local finders  = resolvers.finders
local notfound = finders.notfound

function finders.virtual(specification)
    local original = specification.original
    local d = data[original]
    if d then
        if trace_virtual then
            report_virtual("finder: file %a found",original)
        end
        return original
    else
        if trace_virtual then
            report_virtual("finder: unknown file %a",original)
        end
        return notfound()
    end
end

local openers    = resolvers.openers
local notfound   = openers.notfound
local textopener = openers.helpers.textopener

function openers.virtual(specification)
    local original = specification.original
    local d = data[original]
    if d then
        if trace_virtual then
            report_virtual("opener: file %a opened",original)
        end
        data[original] = nil -- when we comment this we can have error messages
        -- With utf-8 we signal that no regime is to be applied!
     -- characters.showstring(d)
        return textopener("virtual",original,d,"utf-8")
    else
        if trace_virtual then
            report_virtual("opener: file %a not found",original)
        end
        return notfound()
    end
end

local loaders  = resolvers.loaders
local notfound = loaders.notfound

function loaders.virtual(specification)
    local original = specification.original
    local d = data[original]
    if d then
        if trace_virtual then
            report_virtual("loader: file %a loaded",original)
        end
        if not keep[original] then
            data[original] = nil
            keep[original] = nil
        end
        return true, d, #d
    end
    if trace_virtual then
        report_virtual("loader: file %a not loaded",original)
    end
    return notfound()
end