summaryrefslogtreecommitdiff
path: root/scripts/context/lua/mtx-install-modules.lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/context/lua/mtx-install-modules.lua')
-rw-r--r--scripts/context/lua/mtx-install-modules.lua323
1 files changed, 323 insertions, 0 deletions
diff --git a/scripts/context/lua/mtx-install-modules.lua b/scripts/context/lua/mtx-install-modules.lua
new file mode 100644
index 000000000..590e321fe
--- /dev/null
+++ b/scripts/context/lua/mtx-install-modules.lua
@@ -0,0 +1,323 @@
+if not modules then modules = { } end modules ['mtx-install-modules'] = {
+ version = 1.234,
+ comment = "companion to mtxrun.lua",
+ author = "Hans Hagen",
+ copyright = "ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Installing tikz is a bit tricky because there are many packages involved and it's
+-- sort of impossible to derive from the names what to include in the installation.
+-- I tried to use the ctan scrips we ship but there is no way to reliably derive a
+-- set from the topics or packages using the web api (there are also some
+-- inconsistencies between the json and xml interfaces that will not be fixed). A
+-- wildcard pull of everything tikz/pgf is likely to fail or at least gives files we
+-- don't want and/or need, the solution is to be specific.
+--
+-- After that was implemented the script changed name and now also installs the
+-- third party modules.
+--
+-- We use curl and not the built in socket library because all kind of ssl and
+-- redirection can kick in and who know how it evolves.
+--
+-- We use the context unzipper because we cannot be sure if unzip is present on the
+-- system. In many cases windows, linux and osx installations lack it by default.
+--
+-- This script should be run in the tex root where there is also a texmf-context sub
+-- directory; it will quit otherwise. The modules path will be created when absent.
+--
+-- Maybe some day we can get the modules from ctan but then we need a consistent
+-- names and such.
+
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ <metadata>
+ <entry name="name">mtx-install</entry>
+ <entry name="detail">ConTeXt Installer</entry>
+ <entry name="version">2.01</entry>
+ </metadata>
+ <flags>
+ <category name="basic">
+ <subcategory>
+ <flag name="list"><short>list modules</short></flag>
+ <flag name="install"><short>install modules</short></flag>
+ <flag name="module"><short>install (zip) file(s)</short></flag>
+ </subcategory>
+ </category>
+ </flags>
+ <examples>
+ <category>
+ <title>Examples</title>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --list</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --install filter letter</command></example>
+ <example><command>mtxrun --script install-modules --install tikz</command></example>
+ <example><command>mtxrun --script install-modules --install --all</command></example>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script install-modules --install --module t-letter.zip</command></example>
+ </subcategory>
+ </category>
+ </examples>
+</application>
+]]
+
+
+local application = logs.application {
+ name = "mtx-install-modules",
+ banner = "ConTeXt Module Installer 1.00",
+ helpinfo = helpinfo,
+}
+
+local report = application.report
+
+scripts = scripts or { }
+scripts.modules = scripts.modules or { }
+
+local okay, curl = pcall(require,"libs-imp-curl")
+
+local fetched = curl and curl.fetch and function(str)
+ local data, message = curl.fetch {
+ url = str,
+ followlocation = true,
+ sslverifyhost = false,
+ sslverifypeer = false,
+ }
+ if not data then
+ report("some error: %s",message)
+ end
+ return data
+end or function(str)
+ -- So, no redirect to http, which means that we cannot use the built in socket
+ -- library. What if the client is happy with http?
+ local data = os.resultof("curl -sSL " .. str)
+ return data
+end
+
+local urls = {
+ ctan = "https://mirrors.ctan.org/install",
+ modules = "https://modules.contextgarden.net/dl"
+}
+
+local tmpzipfile = "temp.zip"
+local checkdir = "texmf-context"
+local targetdir = "texmf-modules"
+
+local function install(list)
+ if type(list) ~= "table"then
+ report("unknown specification")
+ end
+ local zips = list.zips
+ local wipes = list.wipes
+ if type(zips) ~= "table" then
+ report("incomplete specification")
+ else
+ report("installing into %a",targetdir)
+ for i=1,#zips do
+ local where = urls[list.url] .. "/" .. zips[i]
+ local data = fetched(where)
+ if string.find(data,"^PK") then
+ io.savedata(tmpzipfile,data)
+ report("from %a",where)
+ report("into %a",targetdir)
+ utilities.zipfiles.unzipdir {
+ zipname = tmpzipfile,
+ path = ".",
+ verbose = "steps",
+ }
+ os.remove(tmpzipfile)
+ else
+ report("unknown %a",where)
+ end
+ end
+
+ local function wiper(wipes)
+ for i=1,#wipes do
+ local s = wipes[i]
+ if type(s) == "table" then
+ wiper(s)
+ elseif type(s) == "string" then
+ local t = dir.glob(s)
+ report("wiping %i files in %a",#t,s)
+ for i=1,#t do
+ os.remove(t[i])
+ end
+ end
+ end
+ end
+
+ if type(wipes) == "table" then
+ wiper(wipes)
+ end
+ end
+end
+
+local function wipers(s)
+ return {
+ "tex/context/third/" ..s.. "/**",
+ "doc/context/third/" ..s.. "/**",
+ "source/context/third/" ..s.. "/**",
+
+ "tex/context/" ..s.. "/**",
+ "doc/context/" ..s.. "/**",
+ "source/context/" ..s.. "/**",
+
+ "scripts/" ..s.. "/**",
+ }
+end
+
+local defaults = {
+ "tex/latex/**",
+ "tex/plain/**",
+
+ "doc/latex/**",
+ "doc/plain/**",
+ "doc/generic/**",
+
+ "source/latex/**",
+ "source/plain/**",
+ "source/generic/**",
+}
+
+local lists = {
+ ["tikz"] = {
+ url = "ctan",
+ zips = {
+ "graphics/pgf/base/pgf.tds.zip",
+ "graphics/pgf/contrib/pgfplots.tds.zip",
+ "graphics/pgf/contrib/circuitikz.tds.zip",
+ },
+ wipes = {
+ wipers("pgf"),
+ wipers("pgfplots"),
+ wipers("circuitikz"),
+ defaults,
+ }
+ },
+ -- from the context garden
+ ["pocketdiary"] = { url = "modules", zips = { "Collection-of-calendars-based-on-PocketDiary-module.zip" } },
+ ["collating"] = { url = "modules", zips = { "Environment-for-collating-marks.zip" } },
+ ["account"] = { url = "modules", zips = { "t-account.zip" } },
+ ["algorithmic"] = { url = "modules", zips = { "t-algorithmic.zip" } },
+ ["animation"] = { url = "modules", zips = { "t-animation.zip" } },
+ ["annotation"] = { url = "modules", zips = { "t-annotation.zip" } },
+ ["aquamints"] = { url = "modules", zips = { "aquamints.zip" } },
+ ["bibmod-doc"] = { url = "modules", zips = { "bibmod-doc.zip" } },
+ -- ["bnf-0.3"] = { url = "modules", zips = { "t-bnf-0.3.zip" } },
+ ["bnf"] = { url = "modules", zips = { "t-bnf.zip" } },
+ ["chromato"] = { url = "modules", zips = { "t-chromato.zip" } },
+ ["cmscbf"] = { url = "modules", zips = { "t-cmscbf.zip" } },
+ ["cmttbf"] = { url = "modules", zips = { "t-cmttbf.zip" } },
+ ["crossref"] = { url = "modules", zips = { "t-crossref.zip" } },
+ ["cyrillicnumbers"] = { url = "modules", zips = { "t-cyrillicnumbers.zip" } },
+ ["degrade"] = { url = "modules", zips = { "t-degrade.zip" } },
+ ["enigma"] = { url = "modules", zips = { "enigma.zip" } },
+ ["fancybreak"] = { url = "modules", zips = { "t-fancybreak.zip" } },
+ ["filter"] = { url = "modules", zips = { "t-filter.zip" } },
+ ["french"] = { url = "modules", zips = { "t-french.zip" } },
+ ["fullpage"] = { url = "modules", zips = { "t-fullpage.zip" } },
+ ["gantt"] = { url = "modules", zips = { "t-gantt.zip" } },
+ ["gfsdidot"] = { url = "modules", zips = { "gfsdidot.zip" } },
+ ["gm"] = { url = "modules", zips = { "t-gm.zip" } },
+ ["gnuplot"] = { url = "modules", zips = { "t-gnuplot.zip" } },
+ ["greek"] = { url = "modules", zips = { "t-greek.zip" } },
+ ["grph-downsample"] = { url = "modules", zips = { "grph-downsample.lua.zip" } },
+ ["gs"] = { url = "modules", zips = { "t-gs.zip" } },
+ ["high"] = { url = "modules", zips = { "high.zip" } },
+ ["inifile"] = { url = "modules", zips = { "t-inifile.zip" } },
+ ["karnaugh"] = { url = "modules", zips = { "karnaugh.zip" } },
+ ["layout"] = { url = "modules", zips = { "t-layout.zip" } },
+ ["letter"] = { url = "modules", zips = { "t-letter.zip" } },
+ ["letterspace"] = { url = "modules", zips = { "t-letterspace.mkiv.zip" } },
+ ["lettrine"] = { url = "modules", zips = { "t-lettrine.zip" } },
+ ["lua-widow-control"] = { url = "modules", zips = { "lua-widow-control.zip" } },
+ ["mathsets"] = { url = "modules", zips = { "t-mathsets.zip" } },
+ ["metaducks"] = { url = "modules", zips = { "metaducks.zip" } },
+ ["pret-c.lua"] = { url = "modules", zips = { "pret-c.lua.zip" } },
+ ["rst"] = { url = "modules", zips = { "t-rst.zip" } },
+ ["rsteps"] = { url = "modules", zips = { "t-rsteps.zip" } },
+ ["simplebib"] = { url = "modules", zips = { "t-simplebib.zip" } },
+ ["simplefonts"] = { url = "modules", zips = { "t-simplefonts.zip" } },
+ ["simpleslides"] = { url = "modules", zips = { "t-simpleslides.zip" } },
+ ["stormfontsupport"] = { url = "modules", zips = { "stormfontsupport.zip" } },
+ ["sudoku"] = { url = "modules", zips = { "sudoku.zip" } },
+ ["taspresent"] = { url = "modules", zips = { "t-taspresent.zip" } },
+ ["texshow"] = { url = "modules", zips = { "u-texshow.zip" } },
+ ["title"] = { url = "modules", zips = { "t-title.zip" } },
+ ["transliterator"] = { url = "modules", zips = { "t-transliterator.zip" } },
+ ["typearea"] = { url = "modules", zips = { "t-typearea.zip" } },
+ ["typescripts"] = { url = "modules", zips = { "t-typescripts.zip" } },
+ ["urwgaramond"] = { url = "modules", zips = { "f-urwgaramond.zip" } },
+ ["urwgothic"] = { url = "modules", zips = { "f-urwgothic.zip" } },
+ ["vim"] = { url = "modules", zips = { "t-vim.zip" } },
+ ["visualcounter"] = { url = "modules", zips = { "t-visualcounter.zip" } },
+}
+
+
+function scripts.modules.list()
+ for k, v in table.sortedhash(lists) do
+ report("%-20s: %-36s : % t",k,urls[v.url],v.zips)
+ end
+end
+
+function scripts.modules.install()
+ local curdir = dir.current()
+ local done = false
+ if not lfs.isdir(checkdir) then
+ report("unknown subdirectory %a",checkdir)
+ elseif not dir.mkdirs(targetdir) then
+ report("unable to create %a",targetdir)
+ elseif not lfs.chdir(targetdir) then
+ report("unable to go into %a",targetdir)
+ elseif environment.argument("module") or environment.argument("modules") then
+ local files = environment.files
+ if #files == 0 then
+ report("no archive names provided")
+ else
+ for i=1,#files do
+ local name = files[i]
+ install { url = "modules", zips = { file.addsuffix(name,"zip") } }
+ end
+ done = files
+ end
+ else
+ local files = environment.argument("all") and table.sortedkeys(lists) or environment.files
+ if #files == 0 then
+ report("no module names provided")
+ else
+ for i=1,#files do
+ local list = lists[files[i]]
+ if list then
+ install(list)
+ end
+ end
+ done = files
+ end
+ end
+ if done then
+ report()
+ report("renewing file database")
+ report()
+ resolvers.renewcache()
+ resolvers.load()
+ report()
+ report("installed: % t",done)
+ report()
+ end
+ lfs.chdir(curdir)
+end
+
+if environment.argument("list") then
+ scripts.modules.list()
+elseif environment.argument("install") then
+ scripts.modules.install()
+elseif environment.argument("exporthelp") then
+ application.export(environment.argument("exporthelp"),environment.files[1])
+else
+ application.help()
+ report("")
+end
+