Skip to content

Instantly share code, notes, and snippets.

@nik-ko
Created February 20, 2024 07:52
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 nik-ko/c6dec6301cc977555652f95924f6a244 to your computer and use it in GitHub Desktop.
Save nik-ko/c6dec6301cc977555652f95924f6a244 to your computer and use it in GitHub Desktop.
Replace lowercase in title, journal and booktitle in BibTeX entries with titlecase e.g., 'The greatest title of the all time' to 'The Greatest Title of All Time'. Extends https://www.dlgreenwald.com/miscellanea/capitalizing-titles-in-bibtex to process all *.bib files in a directory recursively.
"""
Replace lowercase in title, journal and booktitle in BibTeX entries with titlecase
e.g., 'The greatest title of the all time' to 'The Greatest Title of All Time'.
Extends https://www.dlgreenwald.com/miscellanea/capitalizing-titles-in-bibtex
to process all *.bib files in a directory recursively.
"""
import shutil
import regex as re
from titlecase import titlecase
import os
from glob import glob
# Custom replacements
replace_dict = {
"Int. ": "International ",
"Symp. ": "Symposium ",
"Proc. ": "Proceedings ",
"Conf. ": "Conference ",
"Conf ": "Conference ",
}
backup = True
# Set path where to search for *.bib files
root_dir = "../"
# Match title or journal segment allowing for whitespace
pattern = re.compile(r'(\W*)(title|journal|booktitle|Title|Journal|Booktitle)\s*=\s*{(.*)},')
for path in glob(os.path.join(root_dir, "**", "*.bib"), recursive=True):
# Backup
shutil.copyfile(path, path + ".backup")
# Read bib file
with open(path, 'r') as f:
lines = f.readlines()
# Search for title strings and replace with titlecase
newlines = []
for line in lines:
# Custom replacements
for k, v in replace_dict.items():
line = line.replace(k, v)
# Check if line contains title
match_obj = pattern.match(line)
if match_obj is not None:
# Need to escape any special chars to avoid misinterpreting them in the regular expression
oldtitle = re.escape(match_obj.group(3))
# Apply titlecase to get the correct title
newtitle = titlecase(match_obj.group(3))
# Replace and add to list
p_title = re.compile(oldtitle)
newline = p_title.sub(newtitle, line)
newlines.append(newline)
else:
# If not title, add as is
newlines.append(line)
# Update file
with open(path, 'w') as f:
f.writelines(newlines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment