summaryrefslogtreecommitdiff
path: root/support/texfindpkg/tfpbuild.lua
diff options
context:
space:
mode:
Diffstat (limited to 'support/texfindpkg/tfpbuild.lua')
-rw-r--r--support/texfindpkg/tfpbuild.lua312
1 files changed, 312 insertions, 0 deletions
diff --git a/support/texfindpkg/tfpbuild.lua b/support/texfindpkg/tfpbuild.lua
new file mode 100644
index 0000000000..c0ccac47aa
--- /dev/null
+++ b/support/texfindpkg/tfpbuild.lua
@@ -0,0 +1,312 @@
+#!/usr/bin/env texlua
+
+-- Description: Install TeX packages and their dependencies
+-- Copyright: 2023 (c) Jianrui Lyu <tolvjr@163.com>
+-- Repository: https://github.com/lvjr/texfindpkg
+-- License: GNU General Public License v3.0
+
+tfp = { building = true }
+
+kpse.set_program_name("kpsewhich")
+local tfp = require(kpse.lookup("texfindpkg.lua"))
+
+------------------------------------------------------------
+--> \section{Some variables and functions}
+------------------------------------------------------------
+
+local tfpMain = tfp.tfpMain
+local showdbg = tfp.showdbg
+local dbgPrint = tfp.dbgPrint
+local fileRead = tfp.fileRead
+local fileWrite = tfp.fileWrite
+local getFiles = tfp.getFiles
+local valueExists = tfp.valueExists
+local json = tfp.json
+local gzip = tfp.gzip
+local tlParsePackageDB = tfp.tlParsePackageDB
+local mtParsePackageDB = tfp.mtParsePackageDB
+
+local insert = table.insert
+local remove = table.remove
+local concat = table.concat
+local gmatch = string.gmatch
+local match = string.match
+
+------------------------------------------------------------
+--> \section{Compare TeX Live and MiKTeX packages}
+------------------------------------------------------------
+
+local tlpkgname = "download/texlive.tlpdb"
+local mtpkgname = "download/package-manifests.ini"
+
+local function compareDistributions()
+ tlpkgtext = fileRead(tlpkgname)
+ if tlpkgtext then
+ tlpkgdata = tlParsePackageDB(tlpkgtext)
+ else
+ print("error in reading texlive package database!")
+ end
+ mtpkgtext = fileRead(mtpkgname)
+ if mtpkgtext then
+ mtpkgdata = mtParsePackageDB(mtpkgtext)
+ else
+ print("error in reading miktex package database!")
+ end
+ local tlmissing, mkmissing = {}, {}
+ for k, vt in pairs(tlpkgdata) do
+ local vm = mtpkgdata[k] -- or "[none]"
+ if vm then
+ mtpkgdata[k] = nil -- remove it
+ if vm ~= vt then
+ print("texlive->" .. vt, "miktex->" .. vm, k)
+ end
+ else
+ insert(mkmissing, {vt, k})
+ end
+ end
+ for k, v in pairs(mtpkgdata) do
+ print("texlive doesn't include " .. v .. " -> " .. k)
+ end
+ for _, v in ipairs(mkmissing) do
+ print("miktex doesn't include " .. v[1] .. " -> " .. v[2])
+ end
+end
+
+------------------------------------------------------------
+--> \section{Generate json file from cwl files}
+------------------------------------------------------------
+
+local function insertNewValue(tbl, val)
+ if not valueExists(tbl, val) then
+ insert(tbl, val)
+ end
+end
+
+local latexcwls = {"tex", "xetex", "luatex", "plaintex", "latex-document", "latex-dev"}
+local islatexcwl = false
+
+local function cwlToRealName(base)
+ if valueExists(latexcwls, base) then return end
+ local n = match(base, "^tikzlibrary(.+)$")
+ if n then return base .. ".code.tex" end
+ local n = match(base, "^tcolorboxlibrary(.+)$")
+ if n then
+ if n == "many" or n == "most" or n == "all" then
+ return nil
+ else
+ return "tcb" .. n .. ".code.tex"
+ end
+ end
+ n = match(base, "^class%-(.+)$")
+ if n then return n .. ".cls" end
+ return base .. ".sty"
+end
+
+local cwldata = {}
+
+local function extractFileData(cwl)
+ -- the cwl files have different eol characters
+ local deps = {}
+ for base in gmatch(cwl, "\n#include:(.-)[\r\n]") do
+ --dbgPrint(base)
+ local n = cwlToRealName(base)
+ if n then insertNewValue(deps, n) end
+ end
+ local envs = {}
+ if islatexcwl and cwldata["latex.ltx"] then
+ envs = cwldata["latex.ltx"].envs or {}
+ end
+ for e in gmatch(cwl, "\n\\begin{(.-)}") do
+ --dbgPrint("{" .. e .. "}")
+ insertNewValue(envs, e)
+ end
+ local cmds = {}
+ if islatexcwl and cwldata["latex.ltx"] then
+ cmds = cwldata["latex.ltx"].cmds or {}
+ end
+ for c in gmatch(cwl, "\n\\(%a+)") do
+ if c ~= "begin" and c ~= "end" then
+ --dbgPrint("\\" .. c)
+ if not valueExists(cmds, c) then
+ insert(cmds, c)
+ end
+ end
+ end
+ --return {deps, envs, cmds}
+ if #deps == 0 then deps = nil end
+ if #cmds == 0 then cmds = nil end
+ if #envs == 0 then envs = nil end
+ return {deps = deps, envs = envs, cmds = cmds}
+end
+
+local function writeJson()
+ print("writing json database to file...")
+ local tbl1 = {}
+ for k, v in pairs(cwldata) do
+ insert(tbl1, {k, v})
+ end
+ table.sort(tbl1, function(a, b)
+ -- make latex.ltx the first item in the json file
+ local aa, bb
+ if a[1] == "latex.ltx" then aa = "001" else aa = a[1] end
+ if b[1] == "latex.ltx" then bb = "001" else bb = b[1] end
+ return aa < bb
+ end)
+ local tbl2 = {}
+ for _, v in ipairs(tbl1) do
+ local item = '"' .. v[1] .. '":' .. json.tostring(v[2])
+ insert(tbl2, item)
+ end
+ local text = "{\n" .. concat(tbl2, "\n,\n") .. "\n}"
+ fileWrite(text, "texfindpkg.json")
+ fileWrite(gzip.compress(text), "texfindpkg.json.gz")
+end
+
+local cwlpath = "completion"
+
+local ignoredcwls = {"optex"}
+
+local function generateJsonData()
+ local list = getFiles(cwlpath, "%.cwl$")
+ local fname
+ for _, v in ipairs(list) do
+ local base = match(v, "^(.+)%.cwl")
+ if not valueExists(ignoredcwls, base) then
+ if valueExists(latexcwls, base) then
+ islatexcwl = true
+ fname = "latex.ltx"
+ else
+ islatexcwl = false
+ fname = cwlToRealName(base)
+ end
+ if fname then
+ --print(fname)
+ local cwl = fileRead(cwlpath .. "/" .. v)
+ --print(cwl)
+ if cwl then
+ local item = extractFileData(cwl)
+ dbgPrint(item)
+ cwldata[fname] = item
+ else
+ print("error in reading " .. v)
+ end
+ end
+ end
+ end
+ writeJson()
+end
+
+------------------------------------------------------------
+--> \section{Print help or version text}
+------------------------------------------------------------
+
+local helptext = [[
+usage: texfindpkg <action> [<options>] [<name>]
+
+valid actions are:
+ generate Generate texfindpkg.json and texfindpkg.json.gz
+ compare Compare packages in TeXLive and MiKTeX
+ check Check test files and report the results
+ save Check test files and save the results
+ help Print this message and exit
+ version Print version information and exit
+
+please report bug at https://github.com/lvjr/texfindpkg
+]]
+
+local function help()
+ print(helptext)
+end
+
+local function version()
+ print("TeXFindPkg Version " .. tfp.version .. " (" .. tfp.date .. ")\n")
+end
+
+------------------------------------------------------------
+--> \section{Check or save test files}
+------------------------------------------------------------
+
+local function cmdLineToArgList(cmdline)
+ local tfparg = {}
+ for v in gmatch(cmdline, "([^ ]+)") do
+ insert(tfparg, v)
+ end
+ remove(tfparg, 1)
+ return tfparg
+end
+
+local testpath = "test"
+
+local function readTestFiles(v)
+ local tests = {}
+ local text = fileRead(testpath .. "/" .. v)
+ for i, o in gmatch(text, "<<<<+\n(.-)\n%-%-%-%-+\n(.-)\n>>>>+") do
+ --print(i, o)
+ insert(tests, {i, o})
+ end
+ return tests
+end
+
+local function checkTestFiles()
+ local files = getFiles(testpath, "%.tfp$")
+ for _, v in ipairs(files) do
+ print("checking test file " .. v)
+ local tests = readTestFiles(v)
+ for _, v in ipairs(tests) do
+ local i, o = v[1], v[2] .. "\n"
+ local result = tfpMain(cmdLineToArgList(i))
+ if o == result then
+ dbgPrint("test passed for '" .. i .. "'")
+ else
+ print("test failed for '" .. i .. "'")
+ end
+ end
+ end
+end
+
+local function saveTestFiles()
+ local files = getFiles(testpath, "%.tfp$")
+ for _, v in ipairs(files) do
+ print("reading test file " .. v)
+ local tests = readTestFiles(v)
+ local text = ""
+ for _, v in ipairs(tests) do
+ local i = v[1]
+ dbgPrint("running test '" .. i .. "'")
+ local o = tfpMain(cmdLineToArgList(i))
+ local sect = "<<<<<<<<\n" .. i .. "\n--------\n" .. o .. ">>>>>>>>\n"
+ text = text .. sect
+ end
+ print("saving test file " .. v)
+ fileWrite(text, testpath .. "/" .. v)
+ end
+end
+
+------------------------------------------------------------
+--> \section{Respond to user input}
+------------------------------------------------------------
+
+local function main()
+ if arg[1] == nil then return help() end
+ local action = remove(arg, 1)
+ action = match(action, "^%-*(.*)$") -- remove leading dashes
+ --print(action)
+ if action == "help" then
+ help()
+ elseif action == "version" then
+ version()
+ elseif action == "generate" then
+ generateJsonData()
+ elseif action == "compare" then
+ compareDistributions()
+ elseif action == "check" then
+ checkTestFiles()
+ elseif action == "save" then
+ saveTestFiles()
+ else
+ print("unknown action '" .. action .. "'")
+ help()
+ end
+end
+
+main()