[latex3-commits] [git/l3build] master: Add "manifest" target (#34) (5d842d7)
GitHub
noreply at github.com
Tue Jan 2 02:20:39 CET 2018
Repository : https://github.com/latex3/l3build
On branch : master
Link : https://github.com/latex3/l3build/commit/5d842d7447a62e9107ee210df26411470a8f078b
>---------------------------------------------------------------
commit 5d842d7447a62e9107ee210df26411470a8f078b
Author: Will Robertson <will at wspr.io>
Date: Tue Jan 2 09:20:39 2018 +0800
Add "manifest" target (#34)
See <https://github.com/latex3/l3build/pull/34/> for the full evolution of this commit.
>---------------------------------------------------------------
5d842d7447a62e9107ee210df26411470a8f078b
build.lua | 6 +-
l3build-manifest-setup.lua | 364 ++++++++++++++++++++++++++++++++++++++++++++
l3build-manifest.lua | 280 ++++++++++++++++++++++++++++++++++
l3build.dtx | 194 +++++++++++++++++++++++
l3build.lua | 12 ++
5 files changed, 853 insertions(+), 3 deletions(-)
diff --git a/build.lua b/build.lua
index 844f24c..e55b461 100644
--- a/build.lua
+++ b/build.lua
@@ -11,12 +11,12 @@ checkconfigs = {"build", "plain"}
checkdeps = { }
checkengines = {"pdftex", "xetex", "luatex", "ptex", "uptex"}
cleanfiles = {"*.pdf", "*.tex", "*.zip"}
-installfiles = {"l3build.lua", "regression-test.tex"}
+installfiles = {"*.lua", "regression-test.tex"}
packtdszip = true
-sourcefiles = {"*.dtx", "l3build.lua", "*.ins"}
+sourcefiles = {"*.dtx", "*.lua", "*.ins"}
typesetcmds = "\\AtBeginDocument{\\DisableImplementation}"
unpackdeps = { }
-versionfiles = {"*.dtx", "*.md", "l3build.lua"}
+versionfiles = {"*.dtx", "*.md", "*.lua"}
-- Detail how to set the version automatically
function setversion_update_line(line, date, version)
diff --git a/l3build-manifest-setup.lua b/l3build-manifest-setup.lua
new file mode 100644
index 0000000..e35310d
--- /dev/null
+++ b/l3build-manifest-setup.lua
@@ -0,0 +1,364 @@
+--[[
+
+File l3build.lua Copyright (C) 2014-2017 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 development version of the bundle can be found at
+
+ https://github.com/latex3/l3build
+
+for those people who are interested.
+
+--]]
+
+
+--[[
+ L3BUILD MANIFEST SETUP
+ ======================
+ This file contains all of the code that is easily replaceable by the user.
+ Either create a copy of this file, rename, and include alongside your `build.lua`
+ script and load it with `dofile()`, or simply copy/paste the definitions below
+ into your `build.lua` script directly.
+--]]
+
+
+--[[
+ Setup of manifest "groups"
+ --------------------------
+
+ The grouping of manifest files is broken into three subheadings:
+
+ * The development repository
+ * The TDS structure from `ctan`
+ * The CTAN structure from `ctan`
+
+ The latter two will only be produced if the `manifest` target is run *after*
+ the `ctan` target. Contrarily, if you run `clean` before `manifest` then
+ only the first grouping will be printed.
+
+ If you want to omit the files in the development repository, essentially
+ producing a minimalist manifest with only the files included for distribution,
+ make a copy of the `manifest_setup` function and delete the groups under
+ the ‘Repository manifest’ subheading below.
+--]]
+
+
+manifest_setup = manifest_setup or function()
+ local groups = {
+ {
+ subheading = "Repository manifest",
+ description = [[
+The following groups list the files included in the development repository of the package.
+Files listed with a ‘†’ marker are included in the TDS but not CTAN files, and files listed
+with ‘‡’ are included in both.
+]],
+ },
+ {
+ name = "Source files",
+ description = [[
+These are source files for a number of purposes, including the `unpack` process which
+generates the installation files of the package. Additional files included here will also
+be installed for processing such as testing.
+]],
+ files = {sourcefiles},
+ dir = sourcefiledir or maindir, -- TODO: remove "or maindir" after rebasing onto master
+ },
+ {
+ name = "Typeset documentation source files",
+ description = [[
+These files are typeset using LaTeX to produce the PDF documentation for the package.
+]],
+ files = {typesetfiles,typesetsourcefiles,typesetdemofiles},
+ },
+ {
+ name = "Documentation files",
+ description = [[
+These files form part of the documentation but are not typeset. Generally they will be
+additional input files for the typeset documentation files listed above.
+]],
+ files = {docfiles},
+ dir = docfiledir or maindir, -- TODO: remove "or maindir" after rebasing onto master
+ },
+ {
+ name = "Text files",
+ description = [[
+Plain text files included as documentation or metadata.
+]],
+ files = {textfiles},
+ skipfiledescription = true,
+ },
+ {
+ name = "Demo files",
+ description = [[
+Files included to demonstrate package functionality. These files are *not*
+typeset or compiled in any way.
+]],
+ files = {demofiles},
+ },
+ {
+ name = "Bibliography and index files",
+ description = [[
+Supplementary files used for compiling package documentation.
+]],
+ files = {bibfiles,bstfiles,makeindexfiles},
+ },
+ {
+ name = "Derived files",
+ description = [[
+The files created by ‘unpacking’ the package sources. This typically includes
+`.sty` and `.cls` files created from DocStrip `.dtx` files.
+]],
+ files = {installfiles},
+ exclude = {excludefiles,sourcefiles},
+ dir = unpackdir,
+ skipfiledescription = true,
+ },
+ {
+ name = "Typeset documents",
+ description = [[
+The output files (PDF, essentially) from typesetting the various source, demo,
+etc., package files.
+]],
+ files = {typesetfiles,typesetsourcefiles,typesetdemofiles},
+ rename = {"%.%w+$", ".pdf"},
+ skipfiledescription = true,
+ },
+ {
+ name = "Support files",
+ description = [[
+These files are used for unpacking, typesetting, or checking purposes.
+]],
+ files = {unpacksuppfiles,typesetsuppfiles,checksuppfiles},
+ dir = supportdir,
+ },
+ {
+ name = "Checking-specific support files",
+ description = [[
+Support files for checking the test suite.
+]],
+ files = {"*.*"},
+ exclude = {{".",".."},excludefiles},
+ dir = testsuppdir,
+ },
+ {
+ name = "Test files",
+ description = [[
+These files form the test suite for the package. `.lvt` or `.lte` files are the individual
+unit tests, and `.tlg` are the stored output for ensuring changes to the package produce
+the same output. These output files are sometimes shared and sometime specific for
+different engines (pdfTeX, XeTeX, LuaTeX, etc.).
+]],
+ files = {"*"..lvtext,"*"..lveext,"*"..tlgext},
+ dir = testfiledir,
+ skipfiledescription = true,
+ },
+ {
+ subheading = "TDS manifest",
+ description = [[
+The following groups list the files included in the TeX Directory Structure used to install
+the package into a TeX distribution.
+]],
+ },
+ {
+ name = "Source files (TDS)",
+ description = "All files included in the `"..module.."/source` directory.\n",
+ dir = tdsdir.."/source/"..moduledir,
+ files = {"*.*"},
+ exclude = {".",".."},
+ flag = false,
+ skipfiledescription = true,
+ },
+ {
+ name = "TeX files (TDS)",
+ description = "All files included in the `"..module.."/tex` directory.\n",
+ dir = tdsdir.."/tex/"..moduledir,
+ files = {"*.*"},
+ exclude = {".",".."},
+ flag = false,
+ skipfiledescription = true,
+ },
+ {
+ name = "Doc files (TDS)",
+ description = "All files included in the `"..module.."/doc` directory.\n",
+ dir = tdsdir.."/doc/"..moduledir,
+ files = {"*.*"},
+ exclude = {".",".."},
+ flag = false,
+ skipfiledescription = true,
+ },
+ {
+ subheading = "CTAN manifest",
+ description = [[
+The following group lists the files included in the CTAN package.
+]],
+ },
+ {
+ name = "CTAN files",
+ dir = ctandir.."/"..module,
+ files = {"*.*"},
+ exclude = {".",".."},
+ flag = false,
+ skipfiledescription = true,
+ },
+ }
+ return groups
+end
+
+--[[
+ Sorting within groups
+ ---------------------
+--]]
+
+manifest_sort_within_match = manifest_sort_within_match or function(files)
+ local f = files
+ table.sort(f)
+ return f
+end
+
+manifest_sort_within_group = manifest_sort_within_group or function(files)
+ local f = files
+ --[[
+ -- no-op by default; make your own definition to customise. E.g.:
+ table.sort(f)
+ --]]
+ return f
+end
+
+--[[
+ Writing to file
+ ---------------
+--]]
+
+manifest_write_opening = manifest_write_opening or function(filehandle)
+
+ filehandle:write("# Manifest for " .. module .. "\n\n")
+ filehandle:write([[
+This file is a listing of all files considered to be part of this package.
+It is automatically generated with `texlua build.lua manifest`.
+]])
+
+end
+
+manifest_write_subheading = manifest_write_subheading or function(filehandle,heading,description)
+
+ filehandle:write("\n\n## " .. heading .. "\n\n")
+
+ if description then
+ filehandle:write(description)
+ end
+
+end
+
+manifest_write_group_heading = manifest_write_group_heading or function (filehandle,heading,description)
+
+ filehandle:write("\n### " .. heading .. "\n\n")
+
+ if description then
+ filehandle:write(description .. "\n")
+ end
+
+end
+
+manifest_write_group_file = manifest_write_group_file or function(filehandle,filename,param)
+ --[[
+ filehandle : write file object
+ filename : the count of the filename to be written
+
+ param.dir : the directory of the file
+ param.count : the name of the file to write
+ param.filemaxchar : the maximum number of chars of all filenames in this group
+ param.flag : false OR string for indicating CTAN/TDS location
+ param.ctanfile : (boolean) if file is in CTAN dir
+ param.tdsfile : (boolean) if file is in TDS dir
+ --]]
+
+ -- no file description: plain bullet list item:
+
+ flagstr = param.flag or ""
+ filehandle:write("* " .. filename .. " " .. flagstr .. "\n")
+
+ --[[
+ -- or if you prefer an enumerated list:
+ filehandle:write(param.count..". " .. filename .. "\n")
+ --]]
+
+
+end
+
+manifest_write_group_file_descr = manifest_write_group_file_descr or function(filehandle,filename,descr,param)
+ --[[
+ filehandle : write file object
+ filename : the name of the file to write
+ descr : description of the file to write
+
+ param.dir : the directory of the file
+ param.count : the count of the filename to be written
+ param.filemaxchar : the maximum number of chars of all filenames in this group
+ param.descmaxchar : the maximum number of chars of all descriptions in this group
+ param.flag : false OR string for indicating CTAN/TDS location
+ param.ctanfile : (boolean) if file is in CTAN dir
+ param.tdsfile : (boolean) if file is in TDS dir
+ --]]
+
+ -- filename+description: Github-flavoured Markdown table
+
+ filestr = string.format(" | %-"..param.filemaxchar.."s",filename)
+ flagstr = param.flag and string.format(" | %s",param.flag) or ""
+ descstr = string.format(" | %-"..param.descmaxchar.."s",descr)
+
+ filehandle:write(filestr..flagstr..descstr.." |\n")
+
+end
+
+--[[
+ Extracting ‘descriptions’ from source files
+ -------------------------------------------
+--]]
+
+manifest_extract_filedesc = manifest_extract_filedesc or function(filehandle)
+
+ -- no-op by default; two examples below
+
+end
+
+--[[
+
+-- From the first match of a pattern in a file:
+manifest_extract_filedesc = function(filehandle)
+
+ local all_file = filehandle:read("*all")
+ local matchstr = "\\section{(.-)}"
+
+ filedesc = string.match(all_file,matchstr)
+
+ return filedesc
+end
+
+-- From the match of the 2nd line (say) of a file:
+manifest_extract_filedesc = function(filehandle)
+
+ local end_read_loop = 2
+ local matchstr = "%%%S%s+(.*)"
+ local this_line = ""
+
+ for ii = 1, end_read_loop do
+ this_line = filehandle:read("*line")
+ end
+
+ filedesc = string.match(this_line,matchstr)
+
+ return filedesc
+end
+
+]]--
diff --git a/l3build-manifest.lua b/l3build-manifest.lua
new file mode 100644
index 0000000..ad0151f
--- /dev/null
+++ b/l3build-manifest.lua
@@ -0,0 +1,280 @@
+--[[
+
+File l3build.lua Copyright (C) 2014-2017 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 development version of the bundle can be found at
+
+ https://github.com/latex3/l3build
+
+for those people who are interested.
+
+--]]
+
+
+--[[
+ L3BUILD MANIFEST
+ ================
+ If desired this entire function can be replaced; if not, it uses a number of
+ auxiliary functions which are included in this file.
+
+ Additional setup can be performed by replacing the functions lists in the file
+ `l3build-manifest-setup.lua`.
+--]]
+
+manifest = manifest or function()
+
+ -- build list of ctan files
+ ctanfiles = {}
+ for _,f in ipairs(filelist(ctandir.."/"..ctanpkg,"*.*")) do
+ ctanfiles[f] = true
+ end
+ tdsfiles = {}
+ for _,subdir in ipairs({"/doc/","/source/","/tex/"}) do
+ for _,f in ipairs(filelist(tdsdir..subdir..moduledir,"*.*")) do
+ tdsfiles[f] = true
+ end
+ end
+
+ local manifest_entries = manifest_setup()
+
+ for ii,_ in ipairs(manifest_entries) do
+ manifest_entries[ii] = manifest_build_list(manifest_entries[ii])
+ end
+
+ manifest_write(manifest_entries)
+
+ printline = "Manifest written to " .. manifestfile
+ print((printline:gsub(".","*"))) print(printline) print((printline:gsub(".","*")))
+
+end
+
+--[[
+ Internal Manifest functions: build_list
+ ---------------------------------------
+--]]
+
+manifest_build_list = function(entry)
+
+ if not(entry.subheading) then
+
+ entry = manifest_build_init(entry)
+
+ -- build list of excluded files
+ for _,glob_list in ipairs(entry.exclude) do
+ for _,this_glob in ipairs(glob_list) do
+ for _,this_file in ipairs(filelist(maindir,this_glob)) do
+ entry.excludes[this_file] = true
+ end
+ end
+ end
+
+ -- build list of matched files
+ for _,glob_list in ipairs(entry.files) do
+ for _,this_glob in ipairs(glob_list) do
+
+ local these_files = filelist(entry.dir,this_glob)
+ these_files = manifest_sort_within_match(these_files)
+
+ for _,this_file in ipairs(these_files) do
+ entry = manifest_build_file(entry,this_file)
+ end
+
+ entry.files_ordered = manifest_sort_within_group(entry.files_ordered)
+
+ end
+ end
+
+ end
+
+ return entry
+
+end
+
+
+manifest_build_init = function(entry)
+
+ -- currently these aren't customisable; I guess they could be?
+ local manifest_group_defaults = {
+ skipfiledescription = false ,
+ rename = false ,
+ dir = maindir ,
+ exclude = {excludefiles} ,
+ flag = true ,
+ }
+
+ -- internal data added to each group in the table that needs to be initialised
+ local manifest_group_init = {
+ N = 0 , -- # matched files
+ ND = 0 , -- # descriptions
+ matches = {} ,
+ excludes = {} ,
+ files_ordered = {} ,
+ descr = {} ,
+ Nchar_file = 4 , -- TODO: generalise
+ Nchar_descr = 11 , -- TODO: generalise
+ }
+
+ -- copy default options to each group if necessary
+ for kk,ll in pairs(manifest_group_defaults) do
+ if entry[kk] == nil then
+ entry[kk] = ll
+ end
+ -- can't use "entry[kk] = entry[kk] or ll" because false/nil are indistinguishable!
+ end
+
+ -- initialisation for internal data
+ for kk,ll in pairs(manifest_group_init) do
+ entry[kk] = ll
+ end
+
+ -- allow nested tables by requiring two levels of nesting
+ if type(entry.files[1])=="string" then
+ entry.files = {entry.files}
+ end
+ if type(entry.exclude[1])=="string" then
+ entry.exclude = {entry.exclude}
+ end
+
+ return entry
+
+end
+
+
+manifest_build_file = function(entry,this_file)
+
+ if entry.rename then
+ this_file = this_file:gsub(entry.rename[1],entry.rename[2])
+ end
+
+ if not entry.excludes[this_file] then
+
+ entry.N = entry.N+1
+ if not(entry.matches[this_file]) then
+
+ entry.matches[this_file] = true -- store the file name
+ entry.files_ordered[entry.N] = this_file -- store the file order
+ entry.Nchar_file = math.max(entry.Nchar_file,this_file:len())
+
+ end
+
+ if not(entry.skipfiledescription) then
+
+ local ff = assert(io.open(entry.dir .. "/" .. this_file, "r"))
+ this_descr = manifest_extract_filedesc(ff,this_file)
+ ff:close()
+
+ if this_descr and this_descr ~= "" then
+ entry.descr[this_file] = this_descr
+ entry.ND = entry.ND+1
+ entry.Nchar_descr = math.max(entry.Nchar_descr,this_descr:len())
+ end
+
+ end
+ end
+
+ return entry
+
+end
+
+--[[
+ Internal Manifest functions: write
+ ----------------------------------
+--]]
+
+manifest_write = function(manifest_entries)
+
+ local f = assert(io.open(manifestfile, "w"))
+ manifest_write_opening(f)
+
+ for ii,vv in ipairs(manifest_entries) do
+ if manifest_entries[ii].subheading then
+ manifest_write_subheading(f,manifest_entries[ii].subheading,manifest_entries[ii].description)
+ elseif manifest_entries[ii].N > 0 then
+ manifest_write_group(f,manifest_entries[ii])
+ end
+ end
+
+ f:close()
+
+end
+
+
+manifest_write_group = function(f,entry)
+
+ manifest_write_group_heading(f,entry.name,entry.description)
+
+ if entry.ND > 0 then
+
+ for ii,file in ipairs(entry.files_ordered) do
+ local descr = entry.descr[file] or ""
+ local param = {
+ dir = entry.dir ,
+ count = ii ,
+ filemaxchar = entry.Nchar_file ,
+ descmaxchar = entry.Nchar_descr ,
+ ctanfile = ctanfiles[file] ,
+ tdsfile = tdsfiles[file] ,
+ flag = false ,
+ }
+
+ if entry.flag then
+ param.flag = " "
+ if tdsfiles[file] and not(ctanfiles[file]) then
+ param.flag = "† "
+ elseif ctanfiles[file] then
+ param.flag = "‡ "
+ end
+ end
+
+ if ii == 1 then
+ -- header of table
+ -- TODO: generalise
+ local p = {}
+ for k,v in pairs(param) do p[k] = v end
+ p.count = -1
+ p.flag = p.flag and "Flag"
+ manifest_write_group_file_descr(f,"File","Description",p)
+ p.flag = p.flag and "--- "
+ manifest_write_group_file_descr(f,"---","---",p)
+ end
+
+ manifest_write_group_file_descr(f,file,descr,param)
+ end
+
+ else
+
+ for ii,file in ipairs(entry.files_ordered) do
+ local param = {
+ dir = entry.dir ,
+ count = ii ,
+ filemaxchar = entry.Nchar_file ,
+ ctanfile = ctanfiles[file] ,
+ tdsfile = tdsfiles[file] ,
+ }
+ if entry.flag then
+ param.flag = ""
+ if tdsfiles[file] and not(ctanfiles[file]) then
+ param.flag = "†"
+ elseif ctanfiles[file] then
+ param.flag = "‡"
+ end
+ end
+ manifest_write_group_file(f,file,param)
+ end
+
+ end
+
+end
+
diff --git a/l3build.dtx b/l3build.dtx
index b9cb819..c783e54 100644
--- a/l3build.dtx
+++ b/l3build.dtx
@@ -154,8 +154,11 @@
\luavarset{typsetcycles}{3} {Number of cycles of typesetting to carry out.}
\luavarset{versionform} {""} {Nature of version strings for auto-replacement.}
\luavarset{recordstatus}{false} {Switch to include error level from test runs in \texttt{.tlg} files}
+\luavarset{manifestfile} {"MANIFEST.md"} {Filename to use for the manifest file.}
}
\allluavars
+
+
\newcommand\luavartypeset{%
\begingroup
\frenchspacing
@@ -496,6 +499,27 @@
% from the engines not available in earlier releases.
% \end{buildcmd}
%
+% \begin{buildcmd}{manifest}
+% Generates a `manifest' file which lists the files of the package as known to \pkg{l3build}.
+% The filename of this file (by default \luavar{manifestfile}) can be set with the variable \var{manifestfile}.
+%
+% The intended purpose of this manifest file is to include it within a package as metadata.
+% This would allow, say, for the copyright statement for the package to refer to the
+% manifest file rather than requiring the author to manually keep a file list up-to-date
+% in multiple locations. The manifest file can be structured and documented with a degree
+% of flexibility. Additional information is described in Section~\ref{sec:manifest}.
+%
+% In order for \texttt{manifest} to detect derived and typeset files, it should be run
+% \emph{after} running \texttt{unpack} and \texttt{doc}. If \texttt{manifest}
+% is run after also running \texttt{ctan} it will include the files included
+% in the CTAN and TDS directories as well.
+%
+% Presently, this means that if you wish to include an up-to-date manifest file
+% as part of a \texttt{ctan} release, you must run
+% \texttt{ctan} / \texttt{manifest} / \texttt{ctan}.
+% Improvements to this process are planned for the future.
+% \end{buildcmd}
+%
% \begin{buildcmd}{setversion}
% Modifies the content of files specified by |versionfiles| to allow
% automatic updating of the file date and version. The latter are
@@ -1197,6 +1221,7 @@
% \label{fig:PDF}
% \end{figure}
%
+%
% \section{Lua interfaces}
%
% Whilst for the majority of users the simple variable-based control methods
@@ -1418,6 +1443,175 @@
% |target| in this table is ignored.
% \end{function}
%
+% \subsection{Customising the manifest file}
+% \label{sec:manifest}
+%
+% The default setup for the manifest file creating with the \texttt{manifest}
+% target attempt to reflect the defaults for \pkg{l3build} itself.
+% The groups (and hence the files) displayed can be completely
+% customised by defining a new setup function which creates a Lua table with
+% the appropriate settings (\S\ref{sec:manifest-groups}).
+%
+% The formatting within the manifest file can be customised by redefining a number
+% of Lua functions. This includes
+% how the files are sorted within each group (\S\ref{sec:manifest-sorting}),
+% the inclusion of one-line descriptions for each file (\S\ref{sec:manifest-desc}),
+% and the details of the formatting of each entry (\S\ref{sec:manifest-formatting}).
+%
+% To perform such customisations, either include the re-definitions directly within your
+% package's |build.lua| file, or make a copy of |l3build-manifest-setup.lua|, rename it,
+% and load it within your |build.lua| using |dofile()|.
+%
+%
+% \subsubsection{Custom manifest groups}
+% \label{sec:manifest-groups}
+%
+% The setup code for defining each group of files within the manifest looks something like
+% the following:
+% \begin{verbatim}
+% manifest_setup = function()
+% local groups = {
+% {
+% subheading = "Repository files",
+% description = [[
+% Files located in the package development repository.
+% ]],
+% },
+% {
+% name = "Source files",
+% description = [[
+% These are source files generating the package files.
+% ]],
+% files = {sourcefiles},
+% },
+% {
+% name = "Typeset documentation source files",
+% description = [[
+% These files are typeset using LaTeX to produce the PDF documentation for the package.
+% ]],
+% files = {typesetfiles,typesetsourcefiles,typesetdemofiles},
+% },
+% ...
+% }
+% return groups
+% end
+% \end{verbatim}
+%
+% The |groups| variable is an ordered array of tables which contain the metadata about each
+% `group' in the manifest listing.
+% The keys supported in these tables are outlined in Table~\ref{tab:manifest-setup} and Table~\ref{tab:manifest-subheadings}
+% See the complete setup code in |l3build-manifest-setup.lua| for examples of these in use.
+%
+% \begin{table}
+% \caption{Table entries used in the manifest setup table for a group.}
+% \label{tab:manifest-setup}
+% \centering
+% \begin{tabular}{lp{8cm}}
+% \toprule
+% Entry & Description \\
+% \midrule
+% \var{name} & The heading of the group \\
+% \var{description} & The description printed below the heading \\
+% \var{files} & Files to include in this group \\
+% \var{exclude} & Files to exclude (default |{excludefiles}|) \\
+% \var{dir} & The directory to search (default |maindir|) \\
+% \var{rename} & An array with a |gsub| redefinition for the filename \\
+% \var{skipfiledescription} & Whether to extract file descriptions from these files (default |false|) \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+% \begin{table}
+% \caption{Table entries used in the manifest setup table for a subheading.}
+% \label{tab:manifest-subheadings}
+% \centering
+% \begin{tabular}{lp{8cm}}
+% \toprule
+% Entry & Description \\
+% \midrule
+% \var{subheading} & The subheading \\
+% \var{description} & The description printed below the subheading \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+%
+% \subsubsection{Sorting within each manifest group}
+% \label{sec:manifest-sorting}
+%
+% Within a single group in the manifest listing, files can be matched against multiple variables.
+% For example, for |sourcefiles={*.dtx,*.ins}| the following (unsorted) file listing might result:
+% \begin{itemize}
+% \item foo.dtx
+% \item bar.dtx
+% \item foo.ins
+% \item bar.ins
+% \end{itemize}
+% This listing can be sorted using two separate functions by the default manifest code.
+% The first, default, is to sort alphabetically within a single variable match.
+% This keeps all files of a single extension contiguous in the listing.
+% To edit how this sort is performed, redefine the |manifest_sort_within_match| function.
+%
+% The second approach to sorting is to apply a sorting function to the entire set of matched files.
+% (This happens \emph{after} any sorting is applied for each match.)
+% By default this is a no-op but can be edited by redefining the |manifest_sort_within_group|
+% function. For example:
+% \begin{verbatim}
+% manifest_sort_within_group = function(files)
+% local f = files
+% table.sort(f)
+% return f
+% end
+% \end{verbatim}
+% This will produce an alphabetical listing of files:
+% \begin{itemize}
+% \item bar.dtx
+% \item bar.ins
+% \item foo.dtx
+% \item foo.ins
+% \end{itemize}
+%
+%
+% \subsubsection{File descriptions}
+% \label{sec:manifest-desc}
+%
+% By default the manifest contains lists of files, and with a small addition these
+% lists can be augmented with a one-line summary of each file.
+% If the Lua function |manifest_extract_filedesc| is defined, it will be used to search
+% the contents of each file to extract a description for that file.
+% For example, perhaps you are using multiple |.dtx| files for a project and the argument
+% to the first |\section| in each can be used as a file description:
+% \begin{verbatim}
+% manifest_extract_filedesc = function(filehandle,filename)
+%
+% local all_file = filehandle:read("*all")
+% local matchstr = "\\section{(.-)}"
+%
+% filedesc = string.match(all_file,matchstr)
+%
+% return filedesc
+% end
+% \end{verbatim}
+% (Note the |matchstr| above is only an example and doesn't handle nested braces.)
+%
+%
+% \subsubsection{Custom formatting}
+% \label{sec:manifest-formatting}
+%
+% After the manifest code has built a complete listing of files to print, a series of
+% file writing operations are performed which create the manifest file.
+% The following functions can be re-defined to change the formatting of the manifest file:
+% \begin{itemize}
+% \item |manifest_write_opening|: Write the heading of the manifest file and its opening paragraph.
+% \item |manifest_write_subheading|: Write a subheading and description
+% \item |manifest_write_group_heading|: Write the section heading of the manifest group and the group description
+% \item |manifest_write_group_file|: Write the filename (when not writing file descriptions)
+% \item |manifest_write_group_file_descr|: Write the filename and the file description
+% \end{itemize}
+% Full descriptions of their usage and arguments can be found within the |l3build-manifest-setup.lua|
+% code itself.
+%
+%
% \end{documentation}
%
% \begin{implementation}
diff --git a/l3build.lua b/l3build.lua
index a3ef35a..aa5f6dd 100644
--- a/l3build.lua
+++ b/l3build.lua
@@ -196,6 +196,9 @@ pdfext = pdfext or ".pdf"
psext = psext or ".ps"
tlgext = tlgext or ".tlg"
+-- Manifest options
+manifestfile = "MANIFEST.md"
+
-- File operations are aided by the LuaFileSystem module
local lfs = require("lfs")
@@ -2406,6 +2409,13 @@ bundleunpack = bundleunpack or function(sourcedirs, sources)
return 0
end
+
+kpse.set_program_name("kpsewhich")
+build_kpse_path = dirname(kpse.lookup("l3build.lua"))
+require( kpse.lookup("l3build-manifest.lua", { path = build_kpse_path } ) )
+require( kpse.lookup("l3build-manifest-setup.lua", { path = build_kpse_path } ) )
+
+
function version()
print(
"\n" ..
@@ -2469,6 +2479,8 @@ function stdmain(target, files)
errorlevel = ctan()
elseif target == "install" then
errorlevel = install()
+ elseif target == "manifest" then
+ errorlevel = manifest()
elseif target == "save" then
if next(files) then
errorlevel = save(files)
More information about the latex3-commits
mailing list