Skip to content

Instantly share code, notes, and snippets.

@janernsting
Last active March 14, 2016 09:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janernsting/d6088dc4cbc72b04ef4b to your computer and use it in GitHub Desktop.
Save janernsting/d6088dc4cbc72b04ef4b to your computer and use it in GitHub Desktop.
Sorts a BibTex file according to its cited order (used in conjunction with biber and parallel alphabetic style)
#!/usr/bin/env python
from __future__ import print_function
import getopt, sys
bib_types = ("@misc", "@online")
def main(options):
aux_file = options[0]
bib_file = options[1]
citations = extract_citations(aux_file)
entries = extract_entries(bib_file)
number_of_digits = add_running_indices(citations, entries)
sortname_format = "%0" + str(number_of_digits) + "d"
new_bib_file = []
with open(bib_file) as f:
for line in f:
line = line.rstrip()
l = line.lower().lstrip()
if l.startswith("shorthand") or l.startswith("sortname"):
pass
else:
new_bib_file.append(line)
if l.startswith(bib_types):
shorthand = entries.get(extract_citation_key(line), 0)
if shorthand:
new_bib_file.append(" shorthand = {%s}," % shorthand)
new_bib_file.append((" sortname = {" + sortname_format + "},") % shorthand)
for line in new_bib_file:
print(line)
def extract_citations(aux_file):
with open(aux_file) as f:
for line in f.readlines():
if "abx@aux@cite" in line:
yield line.split("{")[1].split("}")[0]
def extract_entries(bib_file):
with open(bib_file) as f:
entries = {}
for line in f.readlines():
l = line.lower().lstrip()
if l.startswith(bib_types):
citation_key = extract_citation_key(line)
entries[citation_key] = 0
return entries
def extract_citation_key(s):
if s.lstrip().startswith("@"):
return s.split("{")[1].split(",")[0].strip()
else:
return ""
def add_running_indices(citations, entries):
running_index = 1
for cite in citations:
if cite in entries:
entries[cite] = running_index
running_index = running_index + 1
number_of_digits = len(str(running_index))
return number_of_digits
### Invocation
def help():
print("Usage: %s AUX_FILE BIB_FILE" % sys.argv[0])
print("""Sort BibTeX entries in BIB_FILE according to first cite in AUX_FILE
Outputs the annotated BibTeX entries to standard out.""")
def opterr(msg):
print("parse error:", msg, file=sys.stderr)
print("use `%s -h' to get help" % sys.argv[0], file=sys.stderr)
sys.exit(1)
def parse_options():
try:
opts,args=getopt.getopt(sys.argv[1:],"h",\
["help"])
except getopt.GetoptError, message:
opterr(message)
for opt,arg in opts:
if opt in ("-h","--help"):
help()
sys.exit(0)
return args
def check_filetypes(args):
if len(args) != 2:
opterr("provide AUX_FILE and BIB_FILE")
if not args[0].endswith(".aux"):
opterr("First argument has to be the AUX_FILE")
if not args[1].endswith(".bib"):
opterr("Second argument has to be the BIB_FILE")
if __name__=="__main__":
args=parse_options()
check_filetypes(args)
try:
main(args)
except KeyboardInterrupt:
print("error :(", file=sys.stderr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment