Last active
March 14, 2016 09:59
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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