Latexのコードを入力として、参考文献の出てくる順番通りにbibitemを並べかえたものを出力します。
以下のリンクのDaveWさんの回答を基にしました。
sctex.py
import argparse
#https://tex.stackexchange.com/questions/17354/sort-thebibliography-by-citation-order
#DaveW Mar 27, 2017 at 7:43
parser = argparse.ArgumentParser(description='latex citation sorter')
parser.add_argument('filein')
args = parser.parse_args()
with open(args.filein) as f:
string = f.read()
start = '\\begin{document}'
end = '\\begin{thebibliography}'
si = string.find(start) + len(start)
ei = string.rfind(end)
body = string[si:ei]
start = '\\begin{thebibliography}'
end = '\\end{thebibliography}'
si = string.find(start) + len(start)
ei = string.rfind(end)
bib = string[si:ei]
authors = []
for c in range(0,len(body)-10):
if body[c:c+6] == '\\cite{':
author = ''
c+=6
while(body[c]!='}'):
if(body[c]==' '):
c+=1
elif(body[c]==','):
c+=1
if author in authors:
author = ''
else:
authors.append(author)
author=''
else:
author += (body[c])
c+=1
if author in authors:
pass
else:
authors.append(author)
labels = []
refs = []
for c in range(0,len(bib)-7):
ref=''
if bib[c:c+9] == '\\bibitem{':
c+=9
label=''
while(bib[c]!='}'):
label += bib[c]
c+=1
labels.append(label)
c+=1
while(bib[c:c+9] != '\\bibitem{'):
if c == len(bib)-1:
break
elif (bib[c]) == '\n':
c+=1
else:
ref += (bib[c])
c+=1
refs.append(ref)
labref = dict(zip(labels,refs))
for author in authors:
print('\\bibitem{' + author + '}\t' + labref[author])
print('orphans:')
if len(authors) < len(labels):
orphans = list(set(labels)-set(authors))
for orphan in orphans:
print('\033[91m' + '\\bibitem{' + orphan + '}\t' + labref[orphan] + '\033[0m')