From 8f923948816b24e3c3f2449439dcce1c94888607 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 1 Feb 2015 21:52:07 +0000 Subject: l3build (1feb15) git-svn-id: svn://tug.org/texlive/trunk@36183 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/l3build/l3build.pdf | Bin 512080 -> 512804 bytes Master/texmf-dist/source/latex/l3build/l3build.dtx | 10 +- Master/texmf-dist/source/latex/l3build/l3build.lua | 1132 -------------------- Master/texmf-dist/tex/latex/l3build/l3build.lua | 156 ++- .../tex/latex/l3build/regression-test.tex | 2 +- 5 files changed, 117 insertions(+), 1183 deletions(-) delete mode 100644 Master/texmf-dist/source/latex/l3build/l3build.lua (limited to 'Master') diff --git a/Master/texmf-dist/doc/latex/l3build/l3build.pdf b/Master/texmf-dist/doc/latex/l3build/l3build.pdf index 9f6391217c1..480919d6adf 100644 Binary files a/Master/texmf-dist/doc/latex/l3build/l3build.pdf and b/Master/texmf-dist/doc/latex/l3build/l3build.pdf differ diff --git a/Master/texmf-dist/source/latex/l3build/l3build.dtx b/Master/texmf-dist/source/latex/l3build/l3build.dtx index 990788d6dbc..b75bd060034 100644 --- a/Master/texmf-dist/source/latex/l3build/l3build.dtx +++ b/Master/texmf-dist/source/latex/l3build/l3build.dtx @@ -1,6 +1,6 @@ % \iffalse %% -%% File l3build.dtx (C) Copyright 2014 The LaTeX3 Project +%% File l3build.dtx (C) Copyright 2014-2015 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -39,8 +39,8 @@ \RequirePackage{expl3} \def\ExplFileName{l3build} \def\ExplFileDescription{L3 Regression test suite} -\def\ExplFileDate{2014/11/25} -\def\ExplFileVersion{5471} +\def\ExplFileDate{2015/02/01} +\def\ExplFileVersion{5504} \documentclass[full]{l3doc} \renewcommand\partname{Part} \usepackage{multicol,needspace} @@ -100,8 +100,8 @@ \luavarset{cleanfiles} {\{"*.pdf", "*.zip"\}}{Files to delete when cleaning.} \luavarset{excludefiles} {\{"*\string~"\}} {Files to ignore entirely (default for Emacs backup files).} \luavarset{installfiles} {\{"*.sty"\}} {Files to install to the \TeX{} tree and similar tasks.} -\luavarset{makeindexfiles} { }{MakeIndex files to be included in a TDS-style zip} -\luavarset{readmefiles} {\{"*.md", "*.markdown", "*.txt"\}} {Files which should have the extension removed when sent to CTAN.} +\luavarset{makeindexfiles} {\{"*.ist"\}}{MakeIndex files to be included in a TDS-style zip} +\luavarset{readmefiles} {\{"README.md", "README.markdown", "README.txt"\}} {Files which should have the extension removed when sent to CTAN.} \luavarset{sourcefiles} {\{"*.dtx", "*.ins"\}}{Files to copy for unpacking.} \luavarset{textfiles} {\{ \}}{Plain text files to send to CTAN as-is.} \luavarset{typesetfiles} {\{"*.dtx"\}} {Files to typeset for documentation.} diff --git a/Master/texmf-dist/source/latex/l3build/l3build.lua b/Master/texmf-dist/source/latex/l3build/l3build.lua deleted file mode 100644 index e965353d2ea..00000000000 --- a/Master/texmf-dist/source/latex/l3build/l3build.lua +++ /dev/null @@ -1,1132 +0,0 @@ ---[[ - - File l3build.lua (C) Copyright 2014 The LaTeX3 Project - - It may be distributed and/or modified under the conditions of the - LaTeX Project Public License (LPPL), either version 1.3c of this - license or (at your option) any later version. The latest version - of this license is in the file - - http://www.latex-project.org/lppl.txt - - This file is part of the "l3build bundle" (The Work in LPPL) - and all files in that bundle must be distributed together. - - The released version of this bundle is available from CTAN. - ---]] - --- Version information: should be identical to that in l3build.dtx -release_date = "2014/11/25" -release_ver = "5471" - --- "module" is a deprecated function in Lua 5.2: as we want the name --- for other purposes, and it should eventually be 'free', simply --- remove the built-in -if type (module) == "function" then - module = nil -end - --- Ensure the module and bundle exist -module = module or "" -bundle = bundle or "" - --- Sanity check -if module == "" and bundle == "" then - if string.match (arg[0], ".*l3build%.lua$") then - print ( - "\n" .. - "Error: Call l3build using a configuration file, not directly.\n" - ) - else - print ( - "\n" .. - "Error: Specify either bundle or module in configuration script.\n" - ) - end - os.exit (1) -end - --- Directory structure for the build system --- Use Unix-style path separators -maindir = maindir or "." - --- Substructure for tests and support files -testfiledir = testfiledir or "testfiles" -- Set to "" to cancel any tests -testsuppdir = testsuppdir or testfiledir .. "/support" -supportdir = supportdir or maindir .. "/support" - --- Structure within a development area -distribdir = distribdir or maindir .. "/build/distrib" -localdir = localdir or maindir .. "/build/local" -testdir = testdir or maindir .. "/build/test" -typesetdir = typesetdir or maindir .. "/build/doc" -unpackdir = unpackdir or maindir .. "/build/unpacked" - --- Substructure for CTAN release material -ctandir = ctandir or distribdir .. "/ctan" -tdsdir = tdsdir or distribdir .. "/tds" -tdsroot = tdsroot or "latex" - --- Location for installation on CTAN or in TEXMFHOME -if bundle == "" then - moduledir = tdsroot .. "/" .. module -else - moduledir = tdsroot .. "/" .. bundle .. "/" .. module -end - --- File types for various operations --- Use Unix-style globs --- All of these may be set earlier, so a initialised conditionally -binaryfiles = binaryfiles or {"*.pdf", "*.zip"} -checkfiles = checkfiles or { } -- Extra files unpacked purely for tests -checksuppfiles = checksuppfiles or { } -cmdchkfiles = cmdchkfiles or { } -demofiles = demofiles or { } -cleanfiles = cleanfiles or {"*.pdf", "*.zip"} -excludefiles = excludefiles or {"*~"} -- Any Emacs stuff -installfiles = installfiles or {"*.sty"} -makeindexfiles = makeindexfiles or { } -readmefiles = readmefiles or {"*.md", "*.markdown", "*.txt"} -sourcefiles = sourcefiles or {"*.dtx", "*.ins"} -- Files to copy for unpacking -textfiles = textfiles or { } -typesetfiles = typesetfiles or {"*.dtx"} -typesetsuppfiles = typesetsuppfiles or { } -unpackfiles = unpackfiles or {"*.ins"} -- Files to actually unpack -unpacksuppfiles = unpacksuppfiles or { } - --- Roots which should be unpacked to support unpacking/testing/typesetting -checkdeps = checkdeps or { } -typesetdeps = typesetdeps or { } -unpackdeps = unpackdeps or { } - --- Executable names plus following options -typesetexe = typesetexe or "pdflatex" -unpackexe = unpackexe or "tex" -zipexe = "zip" - -checkopts = checkopts or "-interaction=batchmode" -cmdchkopts = cmdchkopts or "-interaction=batchmode" -typesetopts = typesetopts or "-interaction=nonstopmode" -unpackopts = unpackopts or "" -zipopts = zipopts or "-v -r -X" - --- Engines for testing -checkengines = checkengines or {"pdftex", "xetex", "luatex"} -checkformat = checkformat or "latex" -stdengine = stdengine or "pdftex" - --- Enable access to trees outside of the repo --- As these may be set false, a more elaborate test than normal is needed --- here -if checksearch == nil then - checksearch = true -end -if typesetsearch == nil then - typesetsearch = true -end -if unpacksearch == nil then - unpacksearch = true -end - --- Additional settings to fine-tune typesetting -glossarystyle = glossarystyle or "gglo.ist" -indexstyle = indexstyle or "gind.ist" - --- Other required settings -checkruns = checkruns or 1 -packtdszip = packtdszip or false -- Not actually needed but clearer -scriptname = scriptname or "build.lua" -- Script used in each directory -typesetcmds = typesetcmds or "" - --- Extensions for various file types: used to abstract out stuff a bit -logext = logext or ".log" -lvtext = lvtext or ".lvt" -tlgext = tlgext or ".tlg" - --- Convert a file glob into a pattern for use by e.g. string.gub --- Based on https://github.com/davidm/lua-glob-pattern --- Simplified substantially: "[...]" syntax not supported as is not --- required by the file patterns used by the team. Also note style --- changes to match coding approach in rest of this file. --- --- License for original globtopattern ---[[ - - (c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT). - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - (end license) - ---]] -function glob_to_pattern (glob) - - local pattern = "^" -- pattern being built - local i = 0 -- index in glob - local char -- char at index i in glob - - -- escape pattern char - local function escape (char) - return string.match (char, "^%w$") and char or "%" .. char - end - - -- Convert tokens. - while true do - i = i + 1 - char = string.sub (glob, i, i) - if char == "" then - pattern = pattern .. "$" - break - elseif char == "?" then - pattern = pattern .. "." - elseif char == "*" then - pattern = pattern .. ".*" - elseif char == "[" then - -- Ignored - print ("[...] syntax not supported in globs!") - elseif char == "\\" then - i = i + 1 - char = string.sub(glob, i, i) - if char == "" then - pattern = pattern .. "\\$" - break - end - pattern = pattern .. escape (char) - else - pattern = pattern .. escape (char) - end - end - return pattern -end - --- File operation support --- Much of this is OS-dependent as Lua offers a very limited range of file --- operations 'natively'. - --- Detect the operating system in use --- See http://www.lua.org/manual/5.2/manual.html#pdf-package.config for details --- of the string used here to pick up the operating system (Windows or --- 'not-Windows' --- Support items are defined here for cases where a single string can cover --- both Windows and Unix cases: more complex situations are handled inside --- the support functions -if string.sub (package.config, 1, 1) == "\\" then - os_concat = "&" - os_diffext = ".fc" - os_diffexe = "fc /n" - os_null = "nul" - os_pathsep = ";" - os_setenv = "set" - os_windows = true - os_yes = "for /l %I in (1,1,200) do @echo y" -else - os_concat = ";" - os_diffext = ".diff" - os_diffexe = "diff -c --strip-trailing-cr" - os_null = "/dev/null" - os_pathsep = ":" - os_setenv = "export" - os_windows = false - os_yes = "printf 'y\\n%.0s' {1..200}" -end - --- File operations are aided by the LuaFileSystem module, which is available --- within texlua -lfs = require ("lfs") - --- For cleaning out a directory, which also ensures that it exists -function cleandir (dir) - mkdir (dir) - rm (dir, "*") -end - --- Copy files 'quietly' -function cp (glob, source, dest) - for _,i in ipairs (filelist (source, glob)) do - local source = source .. "/" .. i - if os_windows then - os.execute ( - "copy /y " .. unix_to_win (source) .. " " - .. unix_to_win (dest) .. " > nul" - ) - else - os.execute ("cp -f " .. source .. " " .. dest) - end - end -end - --- OS-dependent test for a directory -function direxists (dir) - local errorlevel - if os_windows then - errorlevel = - os.execute ("if not exist \"" .. unix_to_win (dir) .. "\" exit 1") - else - errorlevel = os.execute ("[ -d " .. dir .. " ]") - end - if errorlevel ~= 0 then - return (false) - end - return (true) -end - -function fileexists (file) - local f = io.open (file, "r") - if f ~= nil then - io.close(f) - return true - else - return false - end -end - --- Generate a table containing all file names of the given glob or all files --- if absent --- Not actually OS-dependent but in the same area -function filelist (path, glob) - local files = { } - local pattern - if glob then - pattern = glob_to_pattern (glob) - end - if direxists (path) then - for entry in lfs.dir (path) do - if pattern then - if string.match (entry, pattern) then - table.insert (files, entry) - end - else - if entry ~= "." and entry ~= ".." then - table.insert (files, entry) - end - end - end - end - return files -end - -function mkdir (dir) - if os_windows then - -- Windows (with the extensions) will automatically make directory trees - -- but issues a warning if the dir already exists: avoid by including a test - local dir = unix_to_win (dir) - os.execute ("if not exist " .. dir .. "\\nul " .. "mkdir " .. dir) - else - os.execute ("mkdir -p " .. dir) - end -end - --- Rename -function ren (dir, source, dest) - local dir = dir .. "/" - if os_windows then - os.execute ("ren " .. unix_to_win (dir) .. source .. " " .. dest) - else - os.execute ("mv " .. dir .. source .. " " .. dir .. dest) - end -end - --- Remove file(s) based on a glob -function rm (source, glob) - for _,i in ipairs (filelist (source, glob)) do - os.remove (source .. "/" .. i) - end -end - --- Remove a directory tree -function rmdir (dir) - -- First, make sure it exists to avoid any errors - mkdir (dir) - if os_windows then - os.execute ("rmdir /s /q " .. unix_to_win (dir) ) - else - os.execute ("rm -r " .. dir) - end -end - --- Run a command in a given directory -function run (dir, cmd) - local errorlevel = os.execute ("cd " .. dir .. os_concat .. cmd) - return (errorlevel) -end - --- Deal with the fact that Windows and Unix use different path separators -function unix_to_win (path) - local path = string.gsub (path, "/", "\\") - return path -end - --- --- Auxiliary functions which are used by more than one main function --- - --- Do some subtarget for all modules in a bundle -function allmodules (target) - local errorlevel = 0 - for _,i in ipairs (modules) do - print ( - "Running script " .. scriptname .. " with target \"" .. target .. "\" for module " - .. i - ) - errorlevel = run (i, "texlua " .. scriptname .. " " .. target) - if errorlevel > 0 then - return (errorlevel) - end - end - return (errorlevel) -end - --- Set up the check system files: needed for checking one or more tests and --- for saving the test files -function checkinit () - cleandir (testdir) - depinstall (checkdeps) - -- Copy dependencies to the test directory itself: this makes the paths - -- a lot easier to manage, and is important for dealing with the log and - -- with file input/output tests - for _,i in ipairs (filelist (localdir)) do - cp (i, localdir, testdir) - end - bundleunpack () - for _,i in ipairs (installfiles) do - cp (i, unpackdir, testdir) - end - for _,i in ipairs (checkfiles) do - cp (i, unpackdir, testdir) - end - if direxists (testsuppdir) then - for _,i in ipairs (filelist (testsuppdir)) do - cp (i, testsuppdir, testdir) - end - end - for _,i in ipairs (checksuppfiles) do - cp (i, supportdir, testdir) - end -end - --- Unpack files needed to support testing/typesetting/unpacking -function depinstall (deps) - for _,i in ipairs (deps) do - print ("Installing dependency: " .. i) - run (i, "texlua " .. scriptname .. " unpack") - end -end - --- Convert the raw log file into one for comparison/storage: keeps only --- the 'business' part from the tests and removes system-dependent stuff -function formatlog (logfile, newfile) - local function killcheck (line, kill) - local killnext = false - local line = line - -- Skip lines containing file dates - if string.match (line, "[^<]%d%d%d%d/%d%d/%d%d") then - line = "" - elseif - -- Skip \openin/\openout lines in web2c 7.x - -- As Lua doesn't allow "(in|out)", a slightly complex approach: - -- do a substitution to check the line is exactly what is required! - string.match ( - string.gsub (line, "^\\openin", "\\openout"), "^\\openout%d = " - ) - then - line = "" - elseif - -- Various things that only LuaTeX adds to boxes: - -- Remove the 'no-op' versions - string.match (line, "^%.*\\whatsit$") or - string.match (line, "^%.*\\localinterlinepenalty=0$") or - string.match (line, "^%.*\\localbrokenpenalty=0$") or - string.match (line, "^%.*\\localleftbox=null$") or - string.match (line, "^%.*\\localrightbox=null$") then - line = "" - -- Pick up LuaTeX's \discretionary line and remove it and the next - -- line - elseif - string.match (line, "%.+\\discretionary") then - line = "" - killnext = true - elseif kill then - line = "" - end - return line, killnext - end - -- Substitutions to remove some non-useful changes - local function normalize (line) - local line = line - -- Remove test file name from lines - -- This needs ato 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 = string.gsub ( - line, - string.gsub ( - string.match ("/" .. logfile, ".*/(.*)%" .. logext .. "$"), - "-", - "%%-" - ), - "" - ) - -- Zap ./ at begin of filename - line = string.gsub (line, "%(%.%/", "(") - -- Zap paths if places other than 'here' are accessible - if checksearch then - line = string.gsub (line, "%(.*/([%w-]+%.[%w-]+)%s*$", "(../%1") - end - -- Zap map loading on first page output - line = string.gsub (line, "%[1{[%w/%-]*/pdftex%.map}%]", "[1]") - -- XeTeX knows only the smaller set of dimension units - line = string.gsub ( - line, "cm, mm, dd, cc, bp, or sp", "cm, mm, dd, cc, nd, nc, bp, or sp" - ) - -- Normalise a case where a LuaTeX bug misprints \csname\endcsname - -- This comes before the normalisation of the appearance of - -- \csname\endcsname in case we alter that! - line = string.gsub (line, "\\ycsnam\\rendcsnam", "\\csname\\endcsname") - -- Normalise a case where fixing a TeX bug changes the message text - line = string.gsub (line, "\\csname\\endcsname ", "\\csname\\endcsname") - -- Zap "on line " and replace with "on line ..." - line = string.gsub (line, "on line %d*", "on line ...") - -- Remove spaces at the start of lines: deals with the fact that LuaTeX - -- uses a different number to the other engines - line = string.gsub (line, "^%s+", "") - -- LuaTeX can give slightly different glue setting to pdfTeX: - -- handle this by restricting to four decimal places - line = string.gsub ( - line, "glue set (%d+.%d%d%d%d)%dfil", "glue set %1fil" - ) - -- Remove 'display' at end of display math boxes: LuaTeX omits this - line = string.gsub (line, "(\\hbox%(.*), display$", "%1") - -- Remove 'normal' direction information on boxes in LuaTeX: - -- any bidi/vertical stuff will still show - line = string.gsub (line, ", direction TLT", "") - -- LuaTeX displays low chars differently: tidy up to ^^ notation - for i = 1, 31, 1 do - line = string.gsub (line, string.char (i), "^^" .. string.char (64 + i)) - end - -- Minor LuaTeX difference: it does not include parentheses in one message - line = string.gsub ( - line, - "%(If you're confused by all this, try typing `I}' now%.%)", - "If you're confused by all this, try typing `I}' now." - ) - -- Minor LuaTeX bug: it prints an extra "'" in one message: add enough - -- context to hopefully hit only the bug - line = string.gsub ( - line, "I''m going to assume", "I'm going to assume" - ) - return line - end - local newlog = "" - local prestart = true - local skipping = false - local killnext = false - for line in io.lines (logfile) do - if line == "START-TEST-LOG" then - prestart = false - elseif line == "END-TEST-LOG" then - break - elseif line == "OMIT" then - skipping = true - elseif line == "TIMO" then - skipping = false - elseif not prestart and not skipping then - line = normalize (line) - line, killnext = killcheck (line, killnext) - if not string.match (line, "^ *$") then - newlog = newlog .. line .. "\n" - end - end - end - local newfile = io.open (newfile, "w") - io.output (newfile) - io.write (newlog) - io.close (newfile) -end - --- List all modules -function listmodules () - local modules = { } - local exclmodules = exclmodules or { } - for entry in lfs.dir (".") do - if entry ~= "." and entry ~= ".." then - local attr = lfs.attributes (entry) - assert (type (attr) == "table") - if attr.mode == "directory" then - if not exclmodules[entry] then - table.insert (modules, entry) - end - end - end - end - return (modules) -end - --- Runs a single test: needs the name of the test rather than the .lvt file --- One 'test' here may apply to multiple engines -function runcheck (name, engine, hide) - local checkengines = checkengines - if engine then - checkengines = {engine} - end - local errorlevel = 0 - for _,i in ipairs (checkengines) do - cp (name .. tlgext, testfiledir, testdir) - runtest (name, i, hide) - local testname = name .. "." .. i - local difffile = testdir .. "/" .. testname .. os_diffext - local newfile = testdir .. "/" .. testname .. logext - -- Use engine-specific file if available - local tlgfile = testfiledir .. "/" .. name .. "." .. i .. tlgext - if not fileexists (tlgfile) then - tlgfile = testfiledir .. "/" .. name .. tlgext - end - if os_windows then - tlgfile = unix_to_win (tlgfile) - end - local errlevel = os.execute ( - os_diffexe .. " " .. tlgfile .. " " .. newfile .. " > " .. difffile - ) - if errlevel == 0 then - os.remove (difffile) - else - errorlevel = errlevel - end - end - return (errorlevel) -end - --- Run one of the test files: doesn't check the result so suitable for --- both creating and verifying .tlg files -function runtest (name, engine, hide) - cp (name .. lvtext, testfiledir, testdir) - local engine = engine or stdengine - -- Engine name doesn't include the "la" for LaTeX! - local cmd = engine - if checkformat == "latex" then - cmd = string.gsub (engine, "tex$", "latex") - end - local logfile = testdir .. "/" .. name .. logext - local lvtfile = name .. lvtext - local newfile = testdir .. "/" .. name .. "." .. engine .. logext - for i = 1, checkruns, 1 do - run ( - testdir, - os_setenv .. " TEXINPUTS=." .. (checksearch and os_pathsep or "") - .. os_concat .. - cmd .. " " .. checkopts .. " " .. lvtfile - .. (hide and (" > " .. os_null) or "") - ) - end - formatlog (logfile, newfile) -end - --- Strip the extension from a file name -function stripext (file) - local name = string.match (file, "^(.*)%.") - return name -end - -function testexists (test) - if fileexists (testfiledir .. "/" .. test .. lvtext) then - return true - else - return false - end -end - --- Standard versions of the main targets for building modules - --- Simply print out how to use the build system -help = help or function () - print "" - if testfiledir ~= "" then - print " build check - run all automated tests for all engines" - end - if module ~= "" and testfiledir ~= "" then - print " build check - check one test file for all engines" - print " build check - check one test file for " - end - print " build clean - clean out directory tree " - if next (cmdchkfiles) ~= nil then - print " build cmdcheck - check commands documented are defined " - end - if module == "" or bundle == "" then - print " build ctan - create CTAN-ready archive " - end - print " build doc - runs all documentation files " - print " build install - install files in local texmf tree " - if module ~= "" and testfiledir ~= "" then - print " build save - save test log for for all engines " - print " build save - save test log for for " - end - print "" -end - -function check (name, engine) - local errorlevel = 0 - if name then - errorlevel = checklvt (name, engine) - else - errorlevel = checkall () - end - return (errorlevel) -end - -function checkall () - local errorlevel = 0 - if testfiledir ~= "" and direxists (testfiledir) then - checkinit () - print ("Running checks on") - for _,i in ipairs (filelist (testfiledir, "*" .. lvtext)) do - local name = stripext (i) - print (" " .. name) - local errlevel = runcheck (name, nil, true) - if errlevel ~= 0 then - errorlevel = 1 - end - end - if errorlevel ~= 0 then - checkdiff () - else - print ("\n All checks passed\n") - end - end - return (errorlevel) -end - -function checklvt (name, engine) - if testexists (name) then - checkinit () - print ("Running checks on " .. name) - local errorlevel = runcheck (name, engine) - if errorlevel ~= 0 then - checkdiff () - else - if engine then - print (" Check passes") - else - print ("\n All checks passed\n") - end - end - else - print ("Test \"" .. name .. "\" not set up!") - end -end - --- A short auxiliary to print the list of differences for check -function checkdiff () - print ("\n Check failed with difference files") - for _,i in ipairs (filelist (testdir, "*" .. os_diffext)) do - print (" - " .. testdir .. "/" .. i) - end - print ("") -end - --- Remove all generated files -function clean () - -- To make sure that distribdir never contains any stray subdirs, - -- it is entirely removed then recreated rather than simply deleting - -- all of the files - rmdir (distribdir) - mkdir (distribdir) - cleandir (localdir) - cleandir (testdir) - cleandir (typesetdir) - cleandir (unpackdir) - for _,i in ipairs (cleanfiles) do - rm (".", i) - end -end - -function bundleclean () - allmodules ("clean") - for _,i in ipairs (cleanfiles) do - rm (".", i) - end - rmdir (ctandir) - rmdir (tdsdir) -end - --- Check commands are defined -function cmdcheck () - mkdir (localdir) - cleandir (testdir) - depinstall (checkdeps) - local engine = string.gsub (stdengine, "tex$", "latex") - print ("Checking source files") - for _,i in ipairs (cmdchkfiles) do - for _,j in ipairs (filelist (".", i)) do - print (" " .. stripext (j)) - os.execute ( - os_setenv .. " TEXINPUTS=." .. os_pathsep .. localdir .. - (checksearch and os_pathsep or "") .. os_concat .. - engine .. " " .. cmdchkopts .. " -output-directory=" .. testdir .. - " \"\\PassOptionsToClass{check}{l3doc} \\input " .. j .. "\"" - .. " > " .. os_null - ) - for line in io.lines (testdir .. "/" .. stripext (j) .. ".cmds") do - if string.match (line, "^%!") then - print (" - " .. string.match (line, "^%! (.*)")) - end - end - end - end -end - -function ctan (standalone) - local function dirzip (dir, name) - local zipname = name .. ".zip" - local function tab_to_str (table) - local string = "" - for _,i in ipairs (table) do - string = string .. " " .. "\"" .. i .. "\"" - end - return string - end - -- Convert the tables of files to quoted strings - local binfiles = tab_to_str (binaryfiles) - local exclude = tab_to_str (excludefiles) - -- First, zip up all of the text files - run ( - dir, - zipexe .. " " .. zipopts .. " -ll ".. zipname .. " " .. "." .. " -x" - .. binfiles .. " " .. exclude - ) - -- Then add the binary ones - run ( - dir, - zipexe .. " " .. zipopts .. " -g ".. zipname .. " " .. ". -i" .. - binfiles .. " -x" .. exclude - ) - end - local errorlevel - if standalone then - errorlevel = check () - bundle = module - else - errorlevel = allmodules ("bundlecheck") - end - if errorlevel == 0 then - rmdir (ctandir) - mkdir (ctandir .. "/" .. bundle) - rmdir (tdsdir) - mkdir (tdsdir) - if standalone then - errorlevel = bundlectan () - else - errorlevel = allmodules ("bundlectan") - end - end - if errorlevel == 0 then - for _,i in ipairs (readmefiles) do - for _,j in ipairs (filelist (".", i)) do - local function installtxt (name, dir) - cp (name, ".", dir) - ren (dir, name, stripext (name)) - end - installtxt (j, ctandir .. "/" .. bundle) - installtxt (j, tdsdir .. "/doc/" .. tdsroot .. "/" .. bundle) - end - end - dirzip (tdsdir, bundle .. ".tds") - if packtdszip then - cp (bundle .. ".tds.zip", tdsdir, ctandir) - end - dirzip (ctandir, bundle) - cp (bundle .. ".zip", ctandir, ".") - else - print ("\n====================") - print ("Tests failed, zip stage skipped!") - print ("====================\n") - end - return (errorlevel) -end - -function bundlectan () - local function install (source, dest, files, ctan, tool) - local installdir - local moduledir = moduledir - -- For material associated with secondary tools (BibTeX, MakeIndex) - -- the structure needed is slightly different from those items going - -- into the tex/doc/source trees - if tool then - -- "base" is reserved for the tools themselves: make the assumption - -- in this case that the tdsroot name is the right place for stuff to - -- go (really just for the team) - if module == "base" then - moduledir = tdsroot - else - moduledir = module - end - end - installdir = tdsdir .. "/" .. dest .. "/" .. moduledir - mkdir (installdir) - for _,i in ipairs (files) do - if ctan then - cp (i, source, ctandir .. "/" .. bundle) - end - cp (i, source, installdir) - end - end - unpack () - if next (makeindexfiles) ~= nil then - install (unpackdir, "makeindex", makeindexfiles, false, true) - end - install (unpackdir, "tex", installfiles, false) - local errorlevel = doc () - if errorlevel == 0 then - -- Convert input names for typesetting into names of PDF files - local pdffiles = { } - for _,i in ipairs (typesetfiles) do - table.insert (pdffiles, (string.gsub (i, "%.%w+$", ".pdf"))) - end - install (".", "doc", pdffiles, true) - install (".", "doc", demofiles, true) - install (".", "doc", textfiles, true) - install (".", "source", typesetfiles, true) - install (".", "source", sourcefiles, true) - end - return (errorlevel) -end - --- Typeset all required documents --- This function has several sub-parts, but as most are not needed anywhere --- else everything is done locally within the main function -function doc () - local function typeset (file) - local name = stripext (file) - -- A couple of short functions to deal with the repeated steps in a - -- clear way - local function makeindex (name, inext, outext, logext, style) - if fileexists (typesetdir .. "/" .. name .. inext) then - run ( - typesetdir , - "makeindex -s " .. style .. " -o " .. name .. outext - .. " -t " .. name .. logext .. " " .. name .. inext - ) - end - end - local function typeset (file) - local errorlevel = - os.execute ( - os_setenv .. " TEXINPUTS=" .. typesetdir .. - os_pathsep .. localdir .. (typesetsearch and os_pathsep or "") .. - os_concat .. - typesetexe .. " " .. typesetopts .. - " -output-directory=" .. typesetdir .. - " \"" .. typesetcmds .. - "\\input " .. typesetdir .. "/" .. file .. "\"" - ) - return errorlevel - end - os.remove (name .. ".pdf") - print ("Typesetting " .. name) - local errorlevel = typeset (file) - if errorlevel ~= 0 then - print (" ! Compilation failed") - return (errorlevel) - else - makeindex (name, ".glo", ".gls", ".glg", glossarystyle) - makeindex (name, ".idx", ".ind", ".ilg", indexstyle) - typeset (file) - typeset (file) - cp (name .. ".pdf", typesetdir, ".") - end - return (errorlevel) - end - -- Set up - cleandir (typesetdir) - for _,i in ipairs (sourcefiles) do - cp (i, ".", typesetdir) - end - for _,i in ipairs (typesetfiles) do - cp (i, ".", typesetdir) - end - for _,i in ipairs (typesetsuppfiles) do - cp (i, supportdir, typesetdir) - end - depinstall (typesetdeps) - unpack () - -- Main loop for doc creation - for _,i in ipairs (typesetfiles) do - for _,j in ipairs (filelist (".", i)) do - local errorlevel = typeset (j) - if errorlevel ~= 0 then - return (errorlevel) - end - end - end - return 0 -end - --- Locally install files: only deals with those extracted, not docs etc. -function install () - unpack () - kpse.set_program_name ("latex") - local texmfhome = kpse.var_value ("TEXMFHOME") - local installdir = texmfhome .. "/tex/" .. moduledir - cleandir (installdir) - for _,i in ipairs (installfiles) do - cp (i, unpackdir, installdir) - end -end - -function save (name, engine) - local tlgfile = name .. (engine and ("." .. engine) or "") .. tlgext - local newfile = name .. "." .. (engine or stdengine) .. logext - if fileexists (testfiledir .. "/" .. name .. lvtext) then - checkinit () - print ("Creating and copying " .. tlgfile) - runtest (name, engine, false) - ren (testdir, newfile, tlgfile) - cp (tlgfile, testdir, testfiledir) - else - print ( - "Test input \"" .. testfiledir .. "/" .. name .. lvtext .. - "\" not found" - ) - end -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 () - depinstall (unpackdeps) - bundleunpack () - for _,i in ipairs (installfiles) do - cp (i, unpackdir, localdir) - end -end - --- Split off from the main unpack so it can be used on a bundle and not --- leave only one modules files -function bundleunpack () - mkdir (localdir) - cleandir (unpackdir) - for _,i in ipairs (sourcefiles) do - cp (i, ".", unpackdir) - end - for _,i in ipairs (unpacksuppfiles) do - cp (i, supportdir, localdir) - end - for _,i in ipairs (unpackfiles) do - for _,j in ipairs (filelist (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 os.execute (it never - -- stops, which confuses Lua) - os.execute (os_yes .. ">>" .. localdir .. "/yes") - os.execute ( - -- Notice that os.execute is used from 'here' as this ensures that - -- localdir points to the correct place: running 'inside' - -- unpackdir would avoid the need for setting -output-directory - -- but at the cost of needing to correct the relative position - -- of localdir w.r.t. unpackdir - os_setenv .. " TEXINPUTS=" .. unpackdir .. os_pathsep .. localdir .. - (unpacksearch and os_pathsep or "") .. os_concat .. - unpackexe .. " " .. unpackopts .. " -output-directory=" .. unpackdir - .. " " .. unpackdir .. "/" .. j .. " < " .. localdir .. "/yes" - ) - end - end -end - -function version () - print ( - "\nl3build Release " .. string.gsub (release_date, "/", "-") .. - " (SVN r" .. release_ver .. ")\n" - ) -end - --- --- The overall main function --- - -function stdmain (target, file, engine) - local errorlevel - -- If the module name is empty, the script is running in a bundle: - -- apart from ctan all of the targets are then just mappings - if module == "" then - -- Detect all of the modules - modules = modules or listmodules () - if target == "doc" then - errorlevel = allmodules ("doc") - elseif target == "check" then - errorlevel = allmodules ("bundlecheck") - if errorlevel ~=0 then - print ("There were errors: checks halted!\n") - end - elseif target == "clean" then - errorlevel = bundleclean () - elseif target == "cmdcheck" and next (cmdchkfiles) ~= nil then - errorlevel = allmodules ("cmdcheck") - elseif target == "ctan" then - errorlevel = ctan () - elseif target == "install" then - errorlevel = allmodules ("install") - elseif target == "unpack" then - errorlevel = allmodules ("bundleunpack") - elseif target == "version" then - version () - else - help () - end - else - if target == "bundleunpack" then -- 'Hidden' as only needed 'higher up' - depinstall (unpackdeps) - errorlevel = bundleunpack () - elseif target == "bundlecheck" then - errorlevel = check () - elseif target == "bundlectan" then - errorlevel = bundlectan () - elseif target == "doc" then - errorlevel = doc () - elseif target == "check" and testfiledir ~= "" then - errorlevel = check (file, engine) - elseif target == "clean" then - errorlevel = clean () - elseif target == "cmdcheck" and next (cmdchkfiles) ~= nil then - errorlevel = cmdcheck () - elseif target == "ctan" and bundle == "" then -- Stand-alone module - errorlevel = ctan (true) - elseif target == "install" then - errorlevel = install () - elseif target == "save" and testfiledir ~= "" then - if file then - errorlevel = save (file, engine) - else - help () - end - elseif target == "unpack" then - unpack () - elseif target == "version" then - version () - else - help () - end - end - os.exit (errorlevel) -end - --- Allow main function to be disabled 'higher up' -main = main or stdmain - --- Call the main function -main (arg[1], arg[2], arg[3]) diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua index e965353d2ea..5250161fb2c 100644 --- a/Master/texmf-dist/tex/latex/l3build/l3build.lua +++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua @@ -1,6 +1,6 @@ --[[ - File l3build.lua (C) Copyright 2014 The LaTeX3 Project + File l3build.lua (C) Copyright 2014-2015 The LaTeX3 Project It may be distributed and/or modified under the conditions of the LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,8 +17,8 @@ --]] -- Version information: should be identical to that in l3build.dtx -release_date = "2014/11/25" -release_ver = "5471" +release_date = "2015/02/01" +release_ver = "5504" -- "module" is a deprecated function in Lua 5.2: as we want the name -- for other purposes, and it should eventually be 'free', simply @@ -86,8 +86,8 @@ demofiles = demofiles or { } cleanfiles = cleanfiles or {"*.pdf", "*.zip"} excludefiles = excludefiles or {"*~"} -- Any Emacs stuff installfiles = installfiles or {"*.sty"} -makeindexfiles = makeindexfiles or { } -readmefiles = readmefiles or {"*.md", "*.markdown", "*.txt"} +makeindexfiles = makeindexfiles or {"*.ist"} +readmefiles = readmefiles or {"README.md", "README.markdown", "README.txt"} sourcefiles = sourcefiles or {"*.dtx", "*.ins"} -- Files to copy for unpacking textfiles = textfiles or { } typesetfiles = typesetfiles or {"*.dtx"} @@ -420,6 +420,57 @@ function checkinit () end end +-- Copy files to the main CTAN release directory +function copyctan () + -- Do all of the copying in one go + for _,i in ipairs ({demofiles, pdffiles, sourcefiles, textfiles, typesetlist}) do + for _,j in ipairs (i) do + cp (j, ".", ctandir .. "/" .. bundle) + end + end +end + +-- Copy files to the correct places in the TDS tree +function copytds () + local function install (source, dest, files, tool) + local moduledir = moduledir + -- For material associated with secondary tools (BibTeX, MakeIndex) + -- the structure needed is slightly different from those items going + -- into the tex/doc/source trees + if tool then + -- "base" is reserved for the tools themselves: make the assumption + -- in this case that the tdsroot name is the right place for stuff to + -- go (really just for the team) + if module == "base" then + moduledir = tdsroot + else + moduledir = module + end + end + local installdir = tdsdir .. "/" .. dest .. "/" .. moduledir + -- Convert the file table(s) to a list of individual files + local filenames = { } + for _,i in ipairs (files) do + for _,j in ipairs (i) do + for _,k in ipairs (filelist (source, j)) do + table.insert (filenames, k) + end + end + end + -- The target is only created if there are actual files to install + if next (filenames) ~= nil then + mkdir (installdir) + for _,i in ipairs (filenames) do + cp (i, source, installdir) + end + end + end + install (".", "doc", {demofiles, pdffiles, textfiles, typesetlist}) + install (unpackdir, "makeindex", {makeindexfiles}, true) + install (".", "source", {sourcelist}) + install (unpackdir, "tex", {installfiles}) +end + -- Unpack files needed to support testing/typesetting/unpacking function depinstall (deps) for _,i in ipairs (deps) do @@ -519,6 +570,13 @@ function formatlog (logfile, newfile) for i = 1, 31, 1 do line = string.gsub (line, string.char (i), "^^" .. string.char (64 + i)) end + -- For normalising UTF-8 to ASCII + local utf8 = unicode.utf8 + -- Unicode engines display chars in the upper half of the 8-bit range: + -- tidy up to match pdfTeX. + for i = 128, 255, 1 do + line = string.gsub (line, utf8.char (i), "^^" .. string.format ("%02x", i)) + end -- Minor LuaTeX difference: it does not include parentheses in one message line = string.gsub ( line, @@ -616,10 +674,12 @@ end function runtest (name, engine, hide) cp (name .. lvtext, testfiledir, testdir) local engine = engine or stdengine - -- Engine name doesn't include the "la" for LaTeX! - local cmd = engine - if checkformat == "latex" then - cmd = string.gsub (engine, "tex$", "latex") + -- Set up the format file name if it's one ending "...tex" + local format + if string.match (checkformat, "tex$") then + format = " -fmt=" .. string.gsub (engine, "(.*)tex$", "%1") .. checkformat + else + format = "" end local logfile = testdir .. "/" .. name .. logext local lvtfile = name .. lvtext @@ -629,17 +689,26 @@ function runtest (name, engine, hide) testdir, os_setenv .. " TEXINPUTS=." .. (checksearch and os_pathsep or "") .. os_concat .. - cmd .. " " .. checkopts .. " " .. lvtfile + engine .. format .. " " .. checkopts .. " " .. lvtfile .. (hide and (" > " .. os_null) or "") ) end formatlog (logfile, newfile) + -- Store secondary files for this engine + for _,i in ipairs (filelist (testdir, name .. ".???")) do + local ext = string.match (i, "%....") + if ext ~= lvtext and ext ~= tlgext and ext ~= logext then + if not fileexists (testsuppdir .. "/" .. i) then + ren (testdir, i, string.gsub (i, name, name .. "." .. engine )) + end + end + end end --- Strip the extension from a file name +-- Strip the extension from a file name (if present) function stripext (file) local name = string.match (file, "^(.*)%.") - return name + return name or file end function testexists (test) @@ -832,6 +901,11 @@ function ctan (standalone) else errorlevel = allmodules ("bundlectan") end + else + print ("\n====================") + print ("Tests failed, zip stage skipped!") + print ("====================\n") + return (errorlevel) end if errorlevel == 0 then for _,i in ipairs (readmefiles) do @@ -852,55 +926,47 @@ function ctan (standalone) cp (bundle .. ".zip", ctandir, ".") else print ("\n====================") - print ("Tests failed, zip stage skipped!") + print ("Typesetting failed, zip stage skipped!") print ("====================\n") end return (errorlevel) end function bundlectan () - local function install (source, dest, files, ctan, tool) - local installdir - local moduledir = moduledir - -- For material associated with secondary tools (BibTeX, MakeIndex) - -- the structure needed is slightly different from those items going - -- into the tex/doc/source trees - if tool then - -- "base" is reserved for the tools themselves: make the assumption - -- in this case that the tdsroot name is the right place for stuff to - -- go (really just for the team) - if module == "base" then - moduledir = tdsroot - else - moduledir = module + -- Generate a list of individual file names excluding those in the second + -- argument: the latter is a table + local function excludelist (include, exclude) + local includelist = { } + local excludelist = { } + for _,i in ipairs (exclude) do + for _,j in ipairs (i) do + for _,k in ipairs (filelist (".", j)) do + excludelist[k] = true + end end end - installdir = tdsdir .. "/" .. dest .. "/" .. moduledir - mkdir (installdir) - for _,i in ipairs (files) do - if ctan then - cp (i, source, ctandir .. "/" .. bundle) + for _,i in ipairs (include) do + for _,j in ipairs (filelist (".", i)) do + if excludelist[j] then + else + table.insert (includelist, j) + end end - cp (i, source, installdir) end + return (includelist) end - unpack () - if next (makeindexfiles) ~= nil then - install (unpackdir, "makeindex", makeindexfiles, false, true) - end - install (unpackdir, "tex", installfiles, false) + unpack() local errorlevel = doc () if errorlevel == 0 then - -- Convert input names for typesetting into names of PDF files - local pdffiles = { } + -- Work out what PDF files are available + pdffiles = { } for _,i in ipairs (typesetfiles) do table.insert (pdffiles, (string.gsub (i, "%.%w+$", ".pdf"))) end - install (".", "doc", pdffiles, true) - install (".", "doc", demofiles, true) - install (".", "doc", textfiles, true) - install (".", "source", typesetfiles, true) - install (".", "source", sourcefiles, true) + typesetlist = excludelist (typesetfiles, {sourcefiles}) + sourcelist = excludelist (sourcefiles, {installfiles, makeindexfiles}) + copyctan () + copytds () end return (errorlevel) end diff --git a/Master/texmf-dist/tex/latex/l3build/regression-test.tex b/Master/texmf-dist/tex/latex/l3build/regression-test.tex index 660c8ff4a2a..792eac0f1e3 100644 --- a/Master/texmf-dist/tex/latex/l3build/regression-test.tex +++ b/Master/texmf-dist/tex/latex/l3build/regression-test.tex @@ -14,7 +14,7 @@ %% Do not distribute a modified version of this file. %% %% -%% File l3build.dtx (C) Copyright 2014 The LaTeX3 Project +%% File l3build.dtx (C) Copyright 2014-2015 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this -- cgit v1.2.3