summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/l3build/l3build.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3build/l3build.lua')
-rw-r--r--Master/texmf-dist/tex/latex/l3build/l3build.lua221
1 files changed, 146 insertions, 75 deletions
diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua
index 44a4783727d..958c30e0d6c 100644
--- a/Master/texmf-dist/tex/latex/l3build/l3build.lua
+++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua
@@ -23,7 +23,7 @@ for those people who are interested.
--]]
-- Version information
-release_date = "2017/05/29"
+release_date = "2017/06/25"
-- "module" is a deprecated function in Lua 5.2: as we want the name
-- for other purposes, and it should eventually be 'free', simply
@@ -85,26 +85,27 @@ end
-- File types for various operations
-- Use Unix-style globs
-- All of these may be set earlier, so a initialised conditionally
-bibfiles = bibfiles or {"*.bib"}
-binaryfiles = binaryfiles or {"*.pdf", "*.zip"}
-bstfiles = bstfiles or {"*.bst"}
-checkfiles = checkfiles or { }
-checksuppfiles = checksuppfiles or { }
-cmdchkfiles = cmdchkfiles or { }
-cleanfiles = cleanfiles or {"*.log", "*.pdf", "*.zip"}
-demofiles = demofiles or { }
-docfiles = docfiles or { }
-excludefiles = excludefiles or {"*~"}
-installfiles = installfiles or {"*.sty"}
-makeindexfiles = makeindexfiles or {"*.ist"}
-sourcefiles = sourcefiles or {"*.dtx", "*.ins"}
-textfiles = textfiles or {"*.md", "*.txt"}
-typesetdemofiles = typesetdemofiles or { }
-typesetfiles = typesetfiles or {"*.dtx"}
-typesetsuppfiles = typesetsuppfiles or { }
-unpackfiles = unpackfiles or {"*.ins"}
-unpacksuppfiles = unpacksuppfiles or { }
-versionfiles = versionfiles or {"*.dtx"}
+bibfiles = bibfiles or {"*.bib"}
+binaryfiles = binaryfiles or {"*.pdf", "*.zip"}
+bstfiles = bstfiles or {"*.bst"}
+checkfiles = checkfiles or { }
+checksuppfiles = checksuppfiles or { }
+cmdchkfiles = cmdchkfiles or { }
+cleanfiles = cleanfiles or {"*.log", "*.pdf", "*.zip"}
+demofiles = demofiles or { }
+docfiles = docfiles or { }
+excludefiles = excludefiles or {"*~"}
+installfiles = installfiles or {"*.sty"}
+makeindexfiles = makeindexfiles or {"*.ist"}
+sourcefiles = sourcefiles or {"*.dtx", "*.ins"}
+textfiles = textfiles or {"*.md", "*.txt"}
+typesetdemofiles = typesetdemofiles or { }
+typesetfiles = typesetfiles or {"*.dtx"}
+typesetsuppfiles = typesetsuppfiles or { }
+typesetsourcefiles = typesetsourcefiles or { }
+unpackfiles = unpackfiles or {"*.ins"}
+unpacksuppfiles = unpacksuppfiles or { }
+versionfiles = versionfiles or {"*.dtx"}
-- Roots which should be unpacked to support unpacking/testing/typesetting
checkdeps = checkdeps or { }
@@ -489,7 +490,7 @@ end
-- Copy files 'quietly'
function cp(glob, source, dest)
local errorlevel
- for _,i in ipairs(filelist(source, glob)) do
+ for i,_ in pairs(tree(source, glob)) do
local source = source .. "/" .. i
if os_type == "windows" then
if lfs_attributes(source)["mode"] == "directory" then
@@ -562,6 +563,58 @@ function filelist(path, glob)
return files
end
+-- Does what filelist does, but can also glob subdirectories. In the returned
+-- table, the keys are paths relative to the given starting path, the values
+-- are their counterparts relative to the current working directory.
+function tree(path, glob)
+ function cropdots(path)
+ return gsub(gsub(path, "^%./", ""), "/%./", "/")
+ end
+ function always_true()
+ return true
+ end
+ function is_dir(file)
+ return lfs.attributes(file)["mode"] == "directory"
+ end
+ local dirs = {["."]=cropdots(path)}
+ for pattern, critereon in gmatch(cropdots(glob), "([^/]+)(/?)") do
+ local critereon = critereon == "/" and is_dir or always_true
+ function fill(path, dir, table)
+ for _, file in ipairs(filelist(dir, pattern)) do
+ local fullpath = path .. "/" .. file
+ if file ~= "." and file ~= ".." and
+ fullpath ~= maindir .. "/build" and
+ (string.sub(pattern, 1, 1) == "."
+ or string.sub(file, 1, 1) ~= ".")
+ then
+ local fulldir = dir .. "/" .. file
+ if critereon(fulldir) then
+ table[fullpath] = fulldir
+ end
+ end
+ end
+ end
+ local newdirs = {}
+ if pattern == "**" then
+ while true do
+ path, dir = next(dirs)
+ if not path then
+ break
+ end
+ dirs[path] = nil
+ newdirs[path] = dir
+ fill(path, dir, dirs)
+ end
+ else
+ for path, dir in pairs(dirs) do
+ fill(path, dir, newdirs)
+ end
+ end
+ dirs = newdirs
+ end
+ return dirs
+end
+
function mkdir(dir)
if os_type == "windows" then
-- Windows (with the extensions) will automatically make directory trees
@@ -658,7 +711,7 @@ end
-- Set up the check system files: needed for checking one or more tests and
-- for saving the test files
-local function checkinit()
+function checkinit()
cleandir(testdir)
depinstall(checkdeps)
-- Copy dependencies to the test directory itself: this makes the paths
@@ -801,26 +854,17 @@ local function formatlog(logfile, newfile, engine)
end
local line = (lastline or "") .. line
lastline = ""
- -- Remove test file name from lines
- -- This needs to extract the base name from the log name,
- -- and one to allow for the case that there might be "-" chars
- -- in the name (other cases are ignored)
- line = gsub(
- line,
- gsub(
- match("/" .. logfile, ".*/(.*)%" .. logext .. "$"),
- "-",
- "%%-"
- ),
- ""
- )
-- Zap ./ at begin of filename
line = gsub(line, "%(%.%/", "(")
-- Zap paths if places other than 'here' are accessible
if checksearch then
- local pattern = "%w?:?/[^ ]*/([^/%(%)]*%.%w*)"
+ -- The pattern excludes < and > as the image part can have
+ -- several entries on one line
+ local pattern = "%w?:?/[^ %<%>]*/([^/%(%)]*%.%w*)"
-- Files loaded from TeX: all start ( -- )
line = gsub(line, "%(" .. pattern, "(../%1")
+ -- Images
+ line = gsub(line, "<" .. pattern .. ">", "<../%1>")
-- luaotfload files start with keywords
line = gsub(line, "from " .. pattern .. "%(", "from. ./%1(")
line = gsub(line, ": " .. pattern .. "%)", ": ../%1)")
@@ -849,6 +893,7 @@ local function formatlog(logfile, newfile, engine)
end
-- Remove 'normal' direction information on boxes with (u)pTeX
line = gsub(line, ",? yoko direction,?", "")
+ line = gsub(line, ",? yoko%(math%) direction,?", "")
-- Remove the \special line that in DVI mode keeps PDFs comparable
if match(line, "^%.*\\special%{pdf: docinfo << /Creator") then
return ""
@@ -1402,15 +1447,28 @@ function dvitopdf(name, dir, engine, hide)
end
end
--- Strip the path from a file name (if present)
+-- Split a path into file and directory component
+function splitpath(file)
+ local path, name = match(file, "^(.*)/([^/]*)$")
+ if path then
+ return path, name
+ else
+ return ".", file
+ end
+end
+
+-- Arguably clearer names
function basename(file)
- local name = match(file, "^.*/([^/]*)$")
- return name or file
+ return(select(2, splitpath(file)))
+end
+
+function dirname(file)
+ return(select(1, splitpath(file)))
end
-- Strip the extension from a file name (if present)
function jobname(file)
- local name = match(basename(file), "^(.*)%.")
+ local name = match(select(2, splitpath(file)), "^(.*)%.")
return name or file
end
@@ -1424,12 +1482,14 @@ end
--
-- An auxiliary used to set up the environmental variables
-function runtool(envvar, command)
+function runtool(subdir, dir, envvar, command)
+ dir = dir or "."
return(
run(
- typesetdir,
+ typesetdir .. "/" .. subdir,
os_setenv .. " " .. envvar .. "=." .. os_pathsep
- .. abspath(localdir)
+ .. abspath(localdir) .. os_pathsep
+ .. abspath(dir .. "/" .. subdir)
.. (typesetsearch and os_pathsep or "") ..
os_concat ..
command
@@ -1437,16 +1497,17 @@ function runtool(envvar, command)
)
end
-function biber(name)
+function biber(name, dir)
if fileexists(typesetdir .. "/" .. name .. ".bcf") then
+ local path, name = splitpath(name)
return(
- runtool("BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name)
+ runtool(path, dir, "BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name)
)
end
return 0
end
-function bibtex(name)
+function bibtex(name, dir)
if fileexists(typesetdir .. "/" .. name .. ".aux") then
-- LaTeX always generates an .aux file, so there is a need to
-- look inside it for a \citation line
@@ -1456,6 +1517,7 @@ function bibtex(name)
else
grep = "\\\\\\\\"
end
+ local path, name = splitpath(name)
if run(
typesetdir,
os_grepexe .. " \"^" .. grep .. "citation{\" " .. name .. ".aux > "
@@ -1468,6 +1530,7 @@ function bibtex(name)
return(
-- Cheat slightly as we need to set two variables
runtool(
+ path, dir,
"BIBINPUTS",
os_setenv .. " BSTINPUTS=." .. os_pathsep
.. abspath(localdir)
@@ -1481,34 +1544,38 @@ function bibtex(name)
return 0
end
-function makeindex(name, inext, outext, logext, style)
+function makeindex(name, dir, inext, outext, logext, style)
if fileexists(typesetdir .. "/" .. name .. inext) then
+ local path, name = splitpath(name)
return(
runtool(
+ path, dir,
"INDEXSTYLE",
makeindexexe .. " " .. makeindexopts .. " "
.. " -s " .. style .. " -o " .. name .. outext
- .. " -t " .. name .. logext .. " " .. name .. inext
+ .. " -t " .. name .. " " .. name .. inext
)
)
end
return 0
end
-function tex(file)
+function tex(file, dir)
+ local path, name = splitpath(file)
return(
runtool(
+ path, dir,
"TEXINPUTS",
typesetexe .. " " .. typesetopts .. " \"" .. typesetcmds
- .. "\\input " .. file .. "\""
+ .. "\\input " .. name .. "\""
)
)
end
-function typesetpdf(file)
+function typesetpdf(file, dir)
local name = jobname(file)
print("Typesetting " .. name)
- local errorlevel = typeset(file)
+ local errorlevel = typeset(file, dir)
if errorlevel == 0 then
os_remove(name .. ".pdf")
cp(name .. ".pdf", typesetdir, ".")
@@ -1518,24 +1585,25 @@ function typesetpdf(file)
return errorlevel
end
-typeset = typeset or function(file)
- local errorlevel = tex(file)
+typeset = typeset or function(file, dir)
+ dir = dir or "."
+ local errorlevel = tex(file, dir)
if errorlevel ~= 0 then
return errorlevel
else
local name = jobname(file)
- errorlevel = biber(name) + bibtex(name)
+ errorlevel = biber(name, dir) + bibtex(name, dir)
if errorlevel == 0 then
- local function cycle(name)
+ local function cycle(name, dir)
return(
- makeindex(name, ".glo", ".gls", ".glg", glossarystyle) +
- makeindex(name, ".idx", ".ind", ".ilg", indexstyle) +
- tex(file)
+ makeindex(name, dir, ".glo", ".gls", ".glg", glossarystyle) +
+ makeindex(name, dir, ".idx", ".ind", ".ilg", indexstyle) +
+ tex(file, dir)
)
end
- errorlevel = cycle(name)
+ errorlevel = cycle(name, dir)
if errorlevel == 0 then
- errorlevel = cycle(name)
+ errorlevel = cycle(name, dir)
end
end
return errorlevel
@@ -1859,12 +1927,12 @@ function doc(files)
cp(i, supportdir, typesetdir)
end
depinstall(typesetdeps)
- unpack()
+ unpack({sourcefiles, typesetsourcefiles})
-- Main loop for doc creation
for _, typesetfiles in ipairs({typesetdemofiles, typesetfiles}) do
for _,i in ipairs(typesetfiles) do
for _, dir in ipairs({unpackdir, typesetdir}) do
- for _,j in ipairs(filelist(dir, i)) do
+ for j,_ in pairs(tree(dir, i)) do
-- Allow for command line selection of files
local typeset = true
if files and next(files) then
@@ -1877,7 +1945,7 @@ function doc(files)
end
end
if typeset then
- local errorlevel = typesetpdf(abspath(dir) .. "/" .. j)
+ local errorlevel = typesetpdf(j, dir)
if errorlevel ~= 0 then
return errorlevel
end
@@ -2068,12 +2136,12 @@ end
-- Unpack the package files using an 'isolated' system: this requires
-- a copy of the 'basic' DocStrip program, which is used then removed
-function unpack()
+function unpack(sources)
local errorlevel = depinstall(unpackdeps)
if errorlevel ~= 0 then
return errorlevel
end
- errorlevel = bundleunpack()
+ errorlevel = bundleunpack({"."}, sources)
if errorlevel ~= 0 then
return errorlevel
end
@@ -2088,7 +2156,7 @@ end
-- Split off from the main unpack so it can be used on a bundle and not
-- leave only one modules files
-bundleunpack = bundleunpack or function(sourcedir)
+bundleunpack = bundleunpack or function(sourcedir, sources)
local errorlevel = mkdir(localdir)
if errorlevel ~=0 then
return errorlevel
@@ -2098,10 +2166,12 @@ bundleunpack = bundleunpack or function(sourcedir)
return errorlevel
end
for _,i in ipairs(sourcedir or {"."}) do
- for _,j in ipairs(sourcefiles) do
- errorlevel = cp(j, i, unpackdir)
- if errorlevel ~=0 then
- return errorlevel
+ for _,j in ipairs(sources or {sourcefiles}) do
+ for _,k in ipairs(j) do
+ errorlevel = cp(k, i, unpackdir)
+ if errorlevel ~=0 then
+ return errorlevel
+ end
end
end
end
@@ -2112,20 +2182,21 @@ bundleunpack = bundleunpack or function(sourcedir)
end
end
for _,i in ipairs(unpackfiles) do
- for _,j in ipairs(filelist(unpackdir, i)) do
+ for j,_ in pairs(tree(unpackdir, i)) do
-- This 'yes' business is needed to pass a series of "y\n" to
-- TeX if \askforoverwrite is true
-- That is all done using a file as it's the only way on Windows and
-- on Unix the "yes" command can't be used inside execute (it never
-- stops, which confuses Lua)
execute(os_yes .. ">>" .. localdir .. "/yes")
+ local path, name = splitpath(j)
local localdir = abspath(localdir)
errorlevel = run(
- unpackdir,
+ unpackdir .. "/" .. path,
os_setenv .. " TEXINPUTS=." .. os_pathsep
.. localdir .. (unpacksearch and os_pathsep or "") ..
os_concat ..
- unpackexe .. " " .. unpackopts .. " " .. j .. " < "
+ unpackexe .. " " .. unpackopts .. " " .. name .. " < "
.. localdir .. "/yes"
.. (optquiet and (" > " .. os_null) or "")
)