mtxlibs.lua / last modification: 2020-01-30 14:16
if not modules then modules = { } end modules ['mtxlibs'] = {
    version   = 1.001,
    comment   = "a reasonable subset of mtxrun preloaded libraries",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"

-- This file can be used to load a the (relevant) helper libraries that are also used
-- in ConTeXt. You can use it as:
--   -- if needed (outside texlua):
--   -- require("lpeg")      -- mandate
--   -- require("md5")       -- handy
--   -- require("lfs")       -- recommended
--   -- require("slunicode") -- sort of obsolete
--   -- the library:
--   require("mtxlibs")
-- An alternative is to merge all libraries into this one so that you don't have to
-- distribute them.
--   mtxlibs --selfmerge
-- If you need additional libraries, you can do something like this:
--   lua mtxlibs.lua  --selfmerge  my-web-project.lua  trac-lmx util-jsn
--   lua mtxlibs.lua  --selfmerge  my-sql-project.lua  util-sql util-sql-imp-library util-sql-imp-client
-- That way you only need to update one file in a project and are not dependent on changes
-- in the core ConTeXT libraries. The libraries are maintained as part of ConTeXt and used
-- in projects so relative stable. The code works in Lua 5.1 as well as in 5.2. Not all
-- functionality makes sense for users who are not familiar with ConTeXt but for instance
-- trackers and loggers are included because that way we have can provide users with a
-- consistent ecosystem.
-- Much of the provided functionality is described in cld-mkiv.pdf and related manuals, on
-- as well in articles. The XML subsystem is described in its own manual.
-- Templates and SQL (not preloaded) is also has its own manual.
-- The next section contains the merged code, with each block ending uop in its own
-- closure. The code gets somewhat compacted to save space and speed up loading.
-- There are some dependencies between the several modules. Also, quite some functions are added
-- to the regular Lua namespaces. In due time I'll isolate them in their own namespaces but with
-- the for context handy option to expose them in the normal ones. I might make the dependencies
-- less but it probably makes no sense to waste time on them.

xpcall(function() local _, t = require("lpeg")      if t then lpeg     = t end return  end,function() end)
xpcall(function() local _, t = require("md5")       if t then md5      = t end return  end,function() end)
xpcall(function() local _, t = require("lfs")       if t then lfs      = t end return  end,function() end)
xpcall(function() local _, t = require("slunicode") if t then unicode  = t end return  end,function() end)

-- begin library merge

-- end library merge

local gsub, gmatch, match, find = string.gsub, string.gmatch, string.match, string.find
local concat = table.concat

local ownname = arg and arg[0] or 'mtxlibs.lua'
local ownpath = gsub(match(ownname,"^(.+)[\\/].-$") or ".","\\","/")
local owntree = ownpath

local ownlibs = {

    "l-file.lua",     -- limited functionality when no lfs
 -- "l-gzip.lua",
    "l-md5.lua",      -- not loaded when no md5 library
    "l-sha.lua",      -- not loaded when no sha2 library
    "l-dir.lua",      -- limited functionality when no lfs
    "l-unicode.lua",  -- nowadays independent of slunicode

 -- "util-lua.lua", -- no need for compiling
 -- "util-fmt.lua", -- no need for table formatters
 -- "util-deb.lua", -- no need for debugging (and tracing)

 -- "util-soc-imp-mbox",

 -- "trac-pro.lua",  -- not relevant outside context


 -- "luat-env.lua",  -- not relevant outside context


    "trac-xml.lua",  -- handy for helpinfo

package.path = "t:/sources/?.lua;t:/sources/?;" .. package.path

local ownlist = {
    ownpath ,
    ownpath .. "/../sources", -- HH's development path
    owntree .. "/../../texmf-local/tex/context/base/mkiv",
    owntree .. "/../../texmf-context/tex/context/base/mkiv",
    owntree .. "/../../texmf/tex/context/base/mkiv",
    owntree .. "/../../../texmf-local/tex/context/base/mkiv",
    owntree .. "/../../../texmf-context/tex/context/base/mkiv",
    owntree .. "/../../../texmf/tex/context/base/mkiv",
    owntree .. "/../../texmf-local/tex/context/base",
    owntree .. "/../../texmf-context/tex/context/base",
    owntree .. "/../../texmf/tex/context/base",
    owntree .. "/../../../texmf-local/tex/context/base",
    owntree .. "/../../../texmf-context/tex/context/base",
    owntree .. "/../../../texmf/tex/context/base",

if ownpath == "." then table.remove(ownlist,1) end

own = {
    name = ownname,
    path = ownpath,
    tree = owntree,
    list = ownlist,
    libs = ownlibs,

local function locate_libs()
    local name = ownlibs[1]
    local done = false
    for i=1,#ownlist do
        local path = ownlist[i]
        local filename = path .. "/" .. name
        local f =
        if f then
            package.path = package.path .. ";" .. path .. "/?.lua" -- in case l-* does a require
            done = path
    locate_libs = function() return done end
    return done

local function load_libs()
    local found = locate_libs()
    if found then
        for i=1,#ownlibs do
            local basename = ownlibs[i]
            local filename = found .. "/" .. basename
            local codeblob = loadfile(filename)
            if codeblob then
                package.preload[basename] = codeblob() or true

if not unicode then

local merger = utilities and utilities.merger

if not merger then

local arguments = environment.arguments
local files     = environment.files

local ownname   = file.basename(environment.ownname)

local helpinfo = [[
usage: mtxlibs [options]

--selfmerge targetfile extralibs

and in a lua file:


local application = logs.application {
    name     = "mtxlibs",
    banner   = "ConTeXt Basic Lua Libraries 1.00",
    helpinfo = helpinfo,

local report =

if ownname == "mtxrun" or ownname == "mtxrun.lua" then
    -- we're using mtxrun
    ownname = "mtxlibs.lua"
elseif ownname == "mtxlibs" or ownname == "mtxlibs.lua" then
    -- we're using lua
    ownname = "mtxlibs.lua"
    report("usage : lua mtxlibs.lua ...")
    report("      : mtxrun --script mtxlibs.lua ...")

if arguments.selfmerge then

    report("merging libraries")
    local found = locate_libs()
    if found then
        local target = files[1]
        if target == ownname then
            report("target cannot be this file")
        elseif target then
            report("target: %s",target)
            for i=1,#files do
                ownlibs[#ownlibs+1] = file.addsuffix(files[i],"lua")
        merger.selfmerge(ownname,ownlibs,{ found },target)
        report("no libraries found")

elseif arguments.selfclean then

    report("cleaning libraries")

else -- if or files[1] == "help" then