Skip to content

Instantly share code, notes, and snippets.

@ToxicFrog
Created July 3, 2012 23:11
Show Gist options
  • Save ToxicFrog/3044080 to your computer and use it in GitHub Desktop.
Save ToxicFrog/3044080 to your computer and use it in GitHub Desktop.
Bibgen
-- invoke as: lua bibgen.lua master.bib paper1.tex paper2.mybib paper3.cites ...
-- a ".tex" or ".latex" file will be parsed for \cite{name} entries
-- anything else will be treated as a newline-separated list of paper names
-- the output file will be the name of the input file, with the extension replaced with ".bib"
-- note: will overwrite files without prompting. Handle with care.
-- parse a BibTeX file into a table of entries indexed by name
local function parsebib(buf)
local bib = {}
-- each entry is of the form @<type>{name, key=value, key=value, ...}
for entry in buf:gmatch('@%w+%b{}') do
local name = entry:match('{%s*([^,]+)')
bib[name] = entry
end
return bib
end
-- scan a TeX or LaTeX file for \cites
local function parseTeX(buf)
local iter = buf:gmatch([[\cite(%b{})]])
return function() for cite in iter do return cite:sub(2,-2) end end
end
local function genbib(bib, file)
local cites
local ofname = file:gsub("%.[^%.]*$", ".bib")
local fout = assert(io.open(ofname, "w"))
print("Generating " .. ofname .. " from " .. file)
if file:match("%.tex$") or file:match("%.latex$") then
local buf = assert(io.open(file, "r")):read("*a")
cites = parseTeX(buf)
else
cites = io.lines(file)
end
for cite in cites do
if bib[cite] then
fout:write(bib[cite] .. "\n\n")
else
print("", "WARNING: cite '" .. cite .. "' not found in master file.")
end
end
fout:close()
end
print("Loading " .. arg[1] .. "...")
local bib = parsebib(assert(io.open(arg[1], "r")):read("*a"))
for name in pairs(bib) do print("", name) end
for i=2,#arg do
genbib(bib, arg[i])
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment