summaryrefslogtreecommitdiff
path: root/tex/generic/context/luatex/luatex-basics-gen.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/generic/context/luatex/luatex-basics-gen.lua')
-rw-r--r--tex/generic/context/luatex/luatex-basics-gen.lua259
1 files changed, 151 insertions, 108 deletions
diff --git a/tex/generic/context/luatex/luatex-basics-gen.lua b/tex/generic/context/luatex/luatex-basics-gen.lua
index 2be55ccea..3959ca022 100644
--- a/tex/generic/context/luatex/luatex-basics-gen.lua
+++ b/tex/generic/context/luatex/luatex-basics-gen.lua
@@ -7,10 +7,19 @@ if not modules then modules = { } end modules ['luat-basics-gen'] = {
}
if context then
- texio.write_nl("fatal error: this module is not for context")
os.exit()
end
+-- We could load a few more of the general context libraries but it would
+-- not make plain / latex users more happy I guess. So, we stick to some
+-- placeholders.
+
+local match, gmatch, gsub, lower = string.match, string.gmatch, string.gsub, string.lower
+local formatters, split, format, dump = string.formatters, string.split, string.format, string.dump
+local loadfile, type = loadfile, type
+local setmetatable, getmetatable, collectgarbage = setmetatable, getmetatable, collectgarbage
+local floor = math.floor
+
local dummyfunction = function()
end
@@ -18,13 +27,22 @@ local dummyreporter = function(c)
return function(f,...)
local r = texio.reporter or texio.write_nl
if f then
- r(c .. " : " .. string.formatters(f,...))
+ r(c .. " : " .. (formatters or format)(f,...))
else
r("")
end
end
end
+local dummyreport = function(c,f,...)
+ local r = texio.reporter or texio.write_nl
+ if f then
+ r(c .. " : " .. (formatters or format)(f,...))
+ else
+ r("")
+ end
+end
+
statistics = {
register = dummyfunction,
starttiming = dummyfunction,
@@ -59,17 +77,18 @@ logs = {
new = dummyreporter,
reporter = dummyreporter,
messenger = dummyreporter,
- report = dummyfunction,
+ report = dummyreport,
}
callbacks = {
register = function(n,f)
return callback.register(n,f)
end,
-
}
-utilities = utilities or { } utilities.storage = {
+utilities = utilities or { }
+
+utilities.storage = utilities.storage or {
allocate = function(t)
return t or { }
end,
@@ -78,6 +97,28 @@ utilities = utilities or { } utilities.storage = {
end,
}
+utilities.parsers = utilities.parsers or {
+ -- these are less flexible than in context but ok
+ -- for generic purpose
+ settings_to_array = function(s)
+ return split(s,",")
+ end,
+ settings_to_hash = function(s)
+ local t = { }
+ for k, v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do
+ t[k] = v
+ end
+ return t
+ end,
+ settings_to_hash_colon_too = function(s)
+ local t = { }
+ for k, v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do
+ t[k] = v
+ end
+ return t
+ end,
+}
+
characters = characters or {
data = { }
}
@@ -98,17 +139,18 @@ local remapper = {
pfb = "type1 fonts", -- needed for vector loading
afm = "afm",
enc = "enc files",
+ lua = "tex",
}
function resolvers.findfile(name,fileformat)
- name = string.gsub(name,"\\","/")
+ name = gsub(name,"\\","/")
if not fileformat or fileformat == "" then
fileformat = file.suffix(name)
if fileformat == "" then
fileformat = "tex"
end
end
- fileformat = string.lower(fileformat)
+ fileformat = lower(fileformat)
fileformat = remapper[fileformat] or fileformat
local found = kpse.find_file(name,fileformat)
if not found or found == "" then
@@ -117,13 +159,6 @@ function resolvers.findfile(name,fileformat)
return found
end
--- function resolvers.findbinfile(name,fileformat)
--- if not fileformat or fileformat == "" then
--- fileformat = file.suffix(name)
--- end
--- return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat)
--- end
-
resolvers.findbinfile = resolvers.findfile
function resolvers.loadbinfile(filename,filetype)
@@ -191,14 +226,14 @@ do
cachepaths = "."
end
- cachepaths = string.split(cachepaths,os.type == "windows" and ";" or ":")
+ cachepaths = split(cachepaths,os.type == "windows" and ";" or ":")
for i=1,#cachepaths do
local cachepath = cachepaths[i]
if not lfs.isdir(cachepath) then
lfs.mkdirs(cachepath) -- needed for texlive and latex
if lfs.isdir(cachepath) then
- texio.write(string.format("(created cache path: %s)",cachepath))
+ logs.report("system","creating cache path '%s'",cachepath)
end
end
if file.is_writable(cachepath) then
@@ -217,16 +252,16 @@ do
end
if not writable then
- texio.write_nl("quiting: fix your writable cache path")
+ logs.report("system","no writeable cache path, quiting")
os.exit()
elseif #readables == 0 then
- texio.write_nl("quiting: fix your readable cache path")
+ logs.report("system","no readable cache path, quiting")
os.exit()
elseif #readables == 1 and readables[1] == writable then
- texio.write(string.format("(using cache: %s)",writable))
+ logs.report("system","using cache '%s'",writable)
else
- texio.write(string.format("(using write cache: %s)",writable))
- texio.write(string.format("(using read cache: %s)",table.concat(readables, " ")))
+ logs.report("system","using write cache '%s'",writable)
+ logs.report("system","using read cache '%s'",table.concat(readables," "))
end
end
@@ -258,75 +293,34 @@ function caches.is_writable(path,name)
return fullname and file.is_writable(fullname)
end
--- function caches.loaddata(paths,name)
--- for i=1,#paths do
--- local data = false
--- local luaname, lucname = makefullname(paths[i],name)
--- if lucname and not lfs.isfile(lucname) and type(caches.compile) == "function" then
--- -- in case we used luatex and luajittex mixed ... lub or luc file
--- texio.write(string.format("(compiling luc: %s)",lucname))
--- data = loadfile(luaname)
--- if data then
--- data = data()
--- end
--- if data then
--- caches.compile(data,luaname,lucname)
--- return data
--- end
--- end
--- if lucname and lfs.isfile(lucname) then -- maybe also check for size
--- texio.write(string.format("(load luc: %s)",lucname))
--- data = loadfile(lucname)
--- if data then
--- data = data()
--- end
--- if data then
--- return data
--- else
--- texio.write(string.format("(loading failed: %s)",lucname))
--- end
--- end
--- if luaname and lfs.isfile(luaname) then
--- texio.write(string.format("(load lua: %s)",luaname))
--- data = loadfile(luaname)
--- if data then
--- data = data()
--- end
--- if data then
--- return data
--- end
--- end
--- end
--- end
-
function caches.loaddata(readables,name,writable)
for i=1,#readables do
local path = readables[i]
local loader = false
local luaname, lucname = makefullname(path,name)
if lfs.isfile(lucname) then
- texio.write(string.format("(load luc: %s)",lucname))
+ logs.report("system","loading luc file '%s'",lucname)
loader = loadfile(lucname)
end
if not loader and lfs.isfile(luaname) then
-- can be different paths when we read a file database from disk
local luacrap, lucname = makefullname(writable,name)
- texio.write(string.format("(compiling luc: %s)",lucname))
+ logs.report("system","compiling luc file '%s'",lucname)
if lfs.isfile(lucname) then
loader = loadfile(lucname)
end
caches.compile(data,luaname,lucname)
if lfs.isfile(lucname) then
- texio.write(string.format("(load luc: %s)",lucname))
+ logs.report("system","loading luc file '%s'",lucname)
loader = loadfile(lucname)
else
- texio.write(string.format("(loading failed: %s)",lucname))
+ logs.report("system","error in loading luc file '%s'",lucname)
end
if not loader then
- texio.write(string.format("(load lua: %s)",luaname))
+ logs.report("system","loading lua file '%s'",luaname)
loader = loadfile(luaname)
else
- texio.write(string.format("(loading failed: %s)",luaname))
+ logs.report("system","error in loading lua file '%s'",luaname)
end
end
if loader then
@@ -341,42 +335,19 @@ end
function caches.savedata(path,name,data)
local luaname, lucname = makefullname(path,name)
if luaname then
- texio.write(string.format("(save: %s)",luaname))
+ logs.report("system","saving lua file '%s'",luaname)
table.tofile(luaname,data,true)
if lucname and type(caches.compile) == "function" then
os.remove(lucname) -- better be safe
- texio.write(string.format("(save: %s)",lucname))
+ logs.report("system","saving luc file '%s'",lucname)
caches.compile(data,luaname,lucname)
end
end
end
--- According to KH os.execute is not permitted in plain/latex so there is
--- no reason to use the normal context way. So the method here is slightly
--- different from the one we have in context. We also use different suffixes
--- as we don't want any clashes (sharing cache files is not that handy as
--- context moves on faster.)
---
--- Beware: serialization might fail on large files (so maybe we should pcall
--- this) in which case one should limit the method to luac and enable support
--- for execution.
-
--- function caches.compile(data,luaname,lucname)
--- local d = io.loaddata(luaname)
--- if not d or d == "" then
--- d = table.serialize(data,true) -- slow
--- end
--- if d and d ~= "" then
--- local f = io.open(lucname,'w')
--- if f then
--- local s = loadstring(d)
--- if s then
--- f:write(string.dump(s,true))
--- end
--- f:close()
--- end
--- end
--- end
+-- The method here is slightly different from the one we have in context. We
+-- also use different suffixes as we don't want any clashes (sharing cache
+-- files is not that handy as context moves on faster.)
function caches.compile(data,luaname,lucname)
local d = io.loaddata(luaname)
@@ -388,23 +359,14 @@ function caches.compile(data,luaname,lucname)
if f then
local s = loadstring(d)
if s then
- f:write(string.dump(s,true))
+ f:write(dump(s,true))
end
f:close()
end
end
end
---
-
--- function table.setmetatableindex(t,f)
--- if type(t) ~= "table" then
--- f = f or t
--- t = { }
--- end
--- setmetatable(t,{ __index = f })
--- return t
--- end
+-- simplfied version:
function table.setmetatableindex(t,f)
if type(t) ~= "table" then
@@ -422,15 +384,96 @@ function table.setmetatableindex(t,f)
return t
end
+function table.makeweak(t)
+ local m = getmetatable(t)
+ if m then
+ m.__mode = "v"
+ else
+ setmetatable(t,{ __mode = "v" })
+ end
+ return t
+end
+
-- helper for plain:
arguments = { }
if arg then
for i=1,#arg do
- local k, v = string.match(arg[i],"^%-%-([^=]+)=?(.-)$")
+ local k, v = match(arg[i],"^%-%-([^=]+)=?(.-)$")
if k and v then
arguments[k] = v
end
end
end
+
+-- another one
+
+if not number.idiv then
+ function number.idiv(i,d)
+ return floor(i/d) -- i//d in 5.3
+ end
+end
+
+-- hook into unicode
+
+local u = unicode and unicode.utf8
+
+if u then
+
+ utf.lower = u.lower
+ utf.upper = u.upper
+ utf.char = u.char
+ utf.byte = u.byte
+ utf.len = u.len
+
+ -- needed on font-*
+
+ if lpeg.setutfcasers then
+ lpeg.setutfcasers(u.lower,u.upper)
+ end
+
+ -- needed on font-otr
+
+ local bytepairs = string.bytepairs
+ local utfchar = utf.char
+ local concat = table.concat
+
+ function utf.utf16_to_utf8_be(s)
+ if not s then
+ return nil
+ elseif s == "" then
+ return ""
+ end
+ local result, r, more = { }, 0, 0
+ for left, right in bytepairs(s) do
+ if right then
+ local now = 256*left + right
+ if more > 0 then
+ now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000
+ more = 0
+ r = r + 1
+ result[r] = utfchar(now)
+ elseif now >= 0xD800 and now <= 0xDBFF then
+ more = now
+ else
+ r = r + 1
+ result[r] = utfchar(now)
+ end
+ end
+ end
+ return concat(result)
+ end
+
+ local characters = string.utfcharacters
+
+ function utf.split(str)
+ local t, n = { }, 0
+ for s in characters(str) do
+ n = n + 1
+ t[n] = s
+ end
+ return t
+ end
+
+end