summaryrefslogtreecommitdiff
path: root/tex/context/base/data-tex.lua
blob: d6c375b52977cc8479bd8f2ca6af1daa0bff6b69 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
if not modules then modules = { } end modules ['data-tex'] = {
    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 trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)

local report_tex = logs.reporter("resolvers","tex")

local resolvers = resolvers

local sequencers    = utilities.sequencers
local methodhandler = resolvers.methodhandler
local splitlines    = string.splitlines
local utffiletype   = unicode.filetype

local fileprocessor = nil
local lineprocessor = nil

local textfileactions = sequencers.reset {
    arguments    = "str,filename",
    returnvalues = "str",
    results      = "str",
}

local textlineactions = sequencers.reset {
    arguments    = "str,filename,linenumber,noflines",
    returnvalues = "str",
    results      = "str",
}

local helpers     = resolvers.openers.helpers
local appendgroup = sequencers.appendgroup

helpers.textfileactions = textfileactions
helpers.textlineactions = textlineactions

appendgroup(textfileactions,"before") -- user
appendgroup(textfileactions,"system") -- private
appendgroup(textfileactions,"after" ) -- user

appendgroup(textlineactions,"before") -- user
appendgroup(textlineactions,"system") -- private
appendgroup(textlineactions,"after" ) -- user

function helpers.textopener(tag,filename,filehandle)
    local lines
    local t_filehandle = type(filehandle)
    if not filehandle then
        lines = io.loaddata(filename)
    elseif t_filehandle == "string" then
        lines = filehandle
    elseif t_filehandle == "table" then
        lines = filehandle
    else
        lines = filehandle:read("*a")
        filehandle:close()
    end
    if type(lines) == "string" then
        local kind = utffiletype(lines)
        if trace_locating then
            report_tex("%s opener, '%s' opened using method '%s'",tag,filename,kind)
        end
        if kind == "utf-16-be" then
            lines = unicode.utf16_to_utf8_be(lines)
        elseif kind == "utf-16-le" then
            lines = unicode.utf16_to_utf8_le(lines)
        elseif kind == "utf-32-be" then
            lines = unicode.utf32_to_utf8_be(lines)
        elseif kind == "utf-32-le" then
            lines = unicode.utf32_to_utf8_le(lines)
        else -- utf8 or unknown
            if textfileactions.dirty then -- maybe use autocompile
                fileprocessor = sequencers.compile(textfileactions)
            end
            lines = fileprocessor(lines,filename) or lines
            lines = splitlines(lines)
        end
    elseif trace_locating then
        report_tex("%s opener, '%s' opened",tag,filename)
    end
    logs.show_open(filename)
    return {
        filename    = filename,
        noflines    = #lines,
        currentline = 0,
        close       = function()
            if trace_locating then
                report_tex("%s closer, '%s' closed",tag,filename)
            end
            logs.show_close(filename)
            t = nil
        end,
        reader      = function(self)
            self = self or t
            local currentline, noflines = self.currentline, self.noflines
            if currentline >= noflines then
                return nil
            else
                currentline = currentline + 1
                self.currentline = currentline
                local content = lines[currentline]
                if not content then
                    return nil
                elseif content == "" then
                    return ""
                else
                    if textlineactions.dirty then
                        lineprocessor = sequencers.compile(textlineactions) -- maybe use autocompile
                    end
                    return lineprocessor(content,filename,currentline,noflines) or content
                end
            end
        end
    }
end

function resolvers.findtexfile(filename,filetype)
    return methodhandler('finders',filename,filetype)
end

function resolvers.opentexfile(filename)
    return methodhandler('openers',filename)
end

function resolvers.openfile(filename)
    local fullname = methodhandler('finders',filename)
    return fullname and fullname ~= "" and methodhandler('openers',fullname) or nil
end

function resolvers.loadtexfile(filename,filetype)
    -- todo: optionally apply filters
    local ok, data, size = resolvers.loadbinfile(filename, filetype)
    return data or ""
end

resolvers.texdatablob = resolvers.loadtexfile

local function installhandler(namespace,what,where,func)
    if not func then
        where, func = "after", where
    end
    if where == "before" or where == "after" then
        sequencers.appendaction(namespace,where,func)
    else
        report_tex("installing input %s handlers in %s is not possible",what,tostring(where))
    end
end

function resolvers.installinputlinehandler(...) installhandler(helpers.textlineactions,"line",...) end
function resolvers.installinputfilehandler(...) installhandler(helpers.textfileactions,"file",...) end

-- local basename = file.basename
-- resolvers.installinputlinehandler(function(str,filename,linenumber,noflines)
--     report_tex("[lc] file: %s, line: %s of %s, length: %s",basename(filename),linenumber,noflines,#str)
-- end)
-- resolvers.installinputfilehandler(function(str,filename)
--     report_tex("[fc] file: %s, length: %s",basename(filename),#str)
-- end)