diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3build/l3build.lua')
-rw-r--r-- | Master/texmf-dist/tex/latex/l3build/l3build.lua | 221 |
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 "") ) |