Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
#!/usr/bin/env lua5.1
-- flsfile.lua: extract the important files from a ".fls" file.
-- This file: http://angg.twu.net/LUA/flsfiles.lua
--            http://angg.twu.net/LUA/flsfiles.lua.html
--             (find-angg        "LUA/flsfiles.lua")
-- By: Eduardo Ochs <[email protected]>
-- Version: 2016feb17 / 2021jul24
-- Public domain.
--
-- Here's how I use this script.
-- To recompile one of my .tex files from scratch I usually do
-- something like this:
--
--   cd ~/LATEX/
--   # See: (find-LATEX "2019.mk")
--   make -f 2019.mk STEM=2021lindenhovius-j-to-X veryclean
--   make -f 2019.mk STEM=2021lindenhovius-j-to-X pdf
--
-- which corresponds, modulo small details, to:
--
--   cd ~/LATEX/
--   # "rm" lots of files starting with "2021lindenhovius-j-to-X.", then:
--   lualatex -record 2021lindenhovius-j-to-X.tex
--   biber            2021lindenhovius-j-to-X
--   lualatex         2021lindenhovius-j-to-X.tex
--
-- the step that starts with "lualatex -record" generates a file
-- called "2021lindenhovius-j-to-X.fls", that lists all the files that
-- lualatex used to build the .pdf, but that is in a format that needs
-- some cleanups to be usable... this script does these clean-ups. The
-- "-record" option in mentioned briefly in the manpage of
-- tex/latex/pdflatex/lualatex/etc, here:
--
--   (find-man "1 tex" "-recorder" ".fls")
--
-- In my ~/.zshrc I have these definitions for the shell functions
-- "flsfiles", "flsfiles-tgz", and "flsfiles-zip":
--
--   # From: (find-angg ".zshrc" "flsfiles")
--   function flsfiles     () { ~/LUA/flsfiles.lua $1 | grep -v "^/" }
--   function flsfiles-tgz () { tar -chvzf "$2" $(flsfiles $1) }
--   function flsfiles-zip () { rm -fv "$2"; zip "$2" $(flsfiles $1) }
--
-- If I run these commands
--
--   cd ~/LATEX/
--   flsfiles-tgz 2021lindenhovius-j-to-X.fls 2021lindenhovius-j-to-X.tgz
--   flsfiles-zip 2021lindenhovius-j-to-X.fls 2021lindenhovius-j-to-X.zip
--
-- the calls to "flsfiles-tgz" and "flsfiles-zip" produce files
-- "2021lindenhovius-j-to-X.tgz" and "2021lindenhovius-j-to-X.zip"
-- with all the source files needed to recompile my .tex. This
-- includes all the lua files; it was a bit tricky to make this work
-- correctly for dednat6... the gory details are here:
--
--   http://angg.twu.net/LATEX/dednat6/lualoader.lua.html#dednatlualoader
--                (find-LATEX "dednat6/lualoader.lua"    "dednatlualoader")
--
-- Actually I have a couple of 5-minute(-ish) hacks, as complex as
-- these ones here,
--
--   (find-angg ".emacs.videos" "eevtempl")
--   (find-eevtemplvideo "19:23" "5. `find-youtubedl-links'")
--
-- that generate all the shell commands above for a given .tex file
-- and that let me execute them with very keystrokes. I haven't
-- documented them yet; if you think that you would like to adapt that
-- to your workflow, please get in touch:
--
--   http://angg.twu.net/contact.html


-- NOTE (2022oct23): this file needs my init file. See:
--   http://angg.twu.net/LUA/lua50init.lua.html
--           (find-angg "LUA/lua50init.lua")
-- TODO: fix that! Use this as a reference:
--   http://angg.twu.net/luatree/luatree.lua.html
--           (find-angg "luatree/luatree.lua")

dofile "/home/edrx/LUA/lua50init.lua"

-- «.FlsFiles»		(to "FlsFiles")
-- «.FlsFiles-tests»	(to "FlsFiles-tests")
-- «.main»		(to "main")



--                                 _     _
--  _ __  _ __ ___  __ _ _ __ ___ | |__ | | ___
-- | '_ \| '__/ _ \/ _` | '_ ` _ \| '_ \| |/ _ \
-- | |_) | | |  __/ (_| | | | | | | |_) | |  __/
-- | .__/|_|  \___|\__,_|_| |_| |_|_.__/|_|\___|
-- |_|
--
-- See: (find-es "lua5" "getdefs")

readfile = function (fname)
    local f = assert(io.open(fname, "r"))
    local bigstr = f:read("*a")
    f:close()
    return bigstr
  end
ee_readfile  = function (fname) return readfile(ee_expand(fname)) end
split = function (str, pat)
    local arr = {}
    string.gsub(str, pat or "([^%s]+)", function (word)
        table.insert(arr, word)
      end)
    return arr
  end
ee_expand = function (path)
    path = string.gsub(path, "^~$", "$HOME/", 1)
    path = string.gsub(path, "^~/", "$HOME/", 1)
    path = string.gsub(path, "^%$(%w+)", os.getenv, 1)
    return path
  end
Set = Class {
  type    = "Set",
  new = function () return Set {_={}} end,
  from = function (L) return Set.fromarray(L) end,
  fromarray = function (L)
      local C = Set.new()
      for i,v in ipairs(L) do C._[v]=v end
      return C
    end,
  __add = function (A, B)   -- union
      local C = Set.new()
      for k,v in pairs(A._) do C._[v]=v end
      for k,v in pairs(B._) do C._[v]=v end
      return C
    end,
  __sub = function (A, B)   -- difference
      local C = Set.new()
      for k,v in pairs(A._) do C._[v]=v end
      for k,v in pairs(B._) do C._[v]=nil end
      return C
    end,
  __mul = function (A, B)     -- intersection
      local C = Set.new()
      for k,v in pairs(A._) do if B._[v] then C._[v]=v end end
      return C
    end,
  __len = function (A) print"!" return #(keys(A._)) end,  -- number of elements
  __tostring = function (A)
      return "(Set with "..A:n().." elements)"
    end,
  --
  -- Methods
  __index = {
    has = function (A, k) return A._[k] end,
    n   = function (A) return #keys(A._) end,
    k   = function (A) return  keys(A._) end,
    ks  = function (A) return sorted(keys(A._)) end,
    ksc = function (A, sep) return table.concat(A:ks(), sep or "\n") end,
    gen = function (A)
        return cow(function ()
            for i,v in ipairs(A:ks()) do coy(v) end
          end)
      end,
    add = function (A, key, val)
        A._[key] = val or key
        return A
      end,
    del = function (A, key)
        A._[key] = nil
        return A
      end,
  },
}
coy = coroutine.yield
cow = coroutine.wrap


--  _               _
-- | |__   ___   __| |_   _
-- | '_ \ / _ \ / _` | | | |
-- | |_) | (_) | (_| | |_| |
-- |_.__/ \___/ \__,_|\__, |
--                    |___/

flsfiles_nontrivial0 = function (bigstr)
    return cow(function ()
        for li in bigstr:gmatch "[^\n]+" do
          local fn = li:match("^INPUT (.*)")
          if fn and
             not fn:match "/usr/share/" and
             not fn:match "/%.texmf%-var/" and
             not fn:match "%.aux$" and
             not fn:match "%.out$" and
             true
          then
            if fn:match "^%./" then fn = fn:sub(3) end
            coy(fn)
          end
        end
      end)
  end
flsfiles_nontrivial = function (fname)
    return flsfiles_nontrivial0(ee_readfile(fname))
  end
flsfiles_nontrivialset = function (fname)
    local s = Set:new()
    for fn in flsfiles_nontrivial(fname) do s:add(fn) end
    return s
  end

-- local fname = ...
-- if fname then
--   local s = flsfiles_nontrivialset(fname)
--   print(s:ksc())
-- end


--  _____ _     _____ _ _           
-- |  ___| |___|  ___(_) | ___  ___ 
-- | |_  | / __| |_  | | |/ _ \/ __|
-- |  _| | \__ \  _| | | |  __/\__ \
-- |_|   |_|___/_|   |_|_|\___||___/
--                                  
-- «FlsFiles»  (to ".FlsFiles")
FlsFiles = Class {
  type = "FlsFiles",
  from = function (fname)
      return FlsFiles {fname=fname, bigstr=ee_readfile(fname)}
    end,
  filesfrom = function (fname)
      return FlsFiles.from(fname):files()  -- returns a Set
    end,
  __index = {
    istrivial = function (fl, fname)
        return fname:match "/usr/share/"
            or fname:match "/usr/local/"
            or fname:match "/%.texmf%-var/"
            or fname:match "/%.texlive"
            or fname:match "%.aux$"
            or fname:match "%.out$"
      end,
    gen_inputs = function (fl)
        return cow(function ()
            for li in fl.bigstr:gmatch "[^\n]+" do
              local fname = li:match "^INPUT (.*)"
              if fname then coy(fname) end
            end
          end)
      end,
    gen_nontrivialinputs = function (fl)
        return cow(function ()
            for fname in fl:gen_inputs() do
	      if not fl:istrivial(fname) then
                fname = fname:gsub("^%./", "")
                coy(fname)
              end
            end
          end)
      end,
    allfiles = function (fl)
        local s = Set:new()
        for fname in fl:gen_inputs() do s:add(fname) end
        return s
      end,
    files = function (fl)
        local s = Set:new()
        for fname in fl:gen_nontrivialinputs() do s:add(fname) end
        return s
      end,
  },
}

-- «FlsFiles-tests»  (to ".FlsFiles-tests")
-- (find-fline "~/LATEX/2022tikzwd-2.fls")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "flsfiles.lua"
fl = FlsFiles.from "~/LATEX/2022tikzwd-2.fls"
for fname in fl:gen_inputs()           do print(fname) end
for fname in fl:gen_nontrivialinputs() do print(fname) end
= fl:files()
= fl:files():ksc("\n")
= FlsFiles.filesfrom("~/LATEX/2022tikzwd-2.fls")
= FlsFiles.filesfrom("~/LATEX/2022tikzwd-2.fls"):ksc("\n")

--]]

-- «main»  (to ".main")
local fname = ...
if fname then
  local s = FlsFiles.filesfrom(fname)
  print(s:ksc())
end





--[[
-- Tests etc (very old)
-- (find-LATEX "2015-2-GA-P1-gab.tex")
-- (find-LATEX "2015-2-GA-P1-gab.fls")
-- (find-LATEX "2015-2-GA-P1-gab.files")

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "flsfiles.lua"
s = flsfiles_nontrivialset "~/LATEX/2015-2-GA-P1-gab.fls"
= s:ksc()
= s:del("/home/edrx/dednat6/dednat6.lua"):ksc()

* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
~/LUA/flsfiles.lua ~/LATEX/2015-2-GA-P1-gab.fls |
  grep -v "^/" |
  tee ~/LATEX/2015-2-GA-P1-gab.files

cd ~/LATEX/
zip 2015-2-GA-P1-gab.zip $(~/LUA/flsfiles.lua 2015-2-GA-P1-gab.fls | grep -v "^/")
tar -cvzf 2015-2-GA-P1-gab.tgz $(~/LUA/flsfiles.lua 2015-2-GA-P1-gab.fls | grep -v "^/")
tar -cvzf 2015-2-GA-P1-gab.tgz $(flsfiles 2015-2-GA-P1-gab.fls | grep -v "^/")

# (find-angg ".zshrc" "flsfiles")
cd ~/LATEX/
flsfiles     2015-2-GA-P1-gab.fls
flsfiles-tgz 2015-2-GA-P1-gab.fls 2015-2-GA-P1-gab.tgz
flsfiles-zip 2015-2-GA-P1-gab.fls 2015-2-GA-P1-gab.zip

~/LUA/flsfiles.lua ~/LATEX/2015-2-GA-P1-gab.fls |
  grep -v "^/" |
  tee ~/LATEX/2015-2-GA-P1-gab.files

rm -v   /tmp/z.zip
rm -Rfv /tmp/z/
mkdir   /tmp/z/
cd ~/LATEX/
zip     /tmp/z.zip $(cat 2015-2-GA-P1-gab.files)
cd      /tmp/z/
unzip -d /tmp/z/ /tmp/z.zip
lualatex 2015-2-GA-P1-gab.tex

# (find-fline "/tmp/")
# (find-fline "/tmp/z/")
# (find-fline "/tmp/z.zip")
# (find-man "unzip")
# (find-sh "cd /tmp/z/ && grep diagxy $(find * -type f)")
# (find-sh "cd /tmp/z/ && grep edrxdnt $(find * -type f)")


--]]


-- Local Variables:
-- coding: raw-text-unix
-- End: