SPB Git

spb/wp44_uqo

Public
2.1 KB · 34 lines python
1#!/usr/bin/env python32"""Merge manuscript/references.bib (main, Agent B-lit) with the writers' references_part*.bib into references_all.bib.3First occurrence wins (main bib first); duplicate keys are reported in references_merge_report.txt with a flag when the4DOI differs (a real conflict to resolve by hand). main.tex uses \\bibliography{references_all}."""5import glob, re, os6H = os.path.dirname(os.path.abspath(__file__))7files = [os.path.join(H, "references.bib")] + sorted(glob.glob(os.path.join(H, "references_part*.bib")) + sorted(glob.glob(os.path.join(H, "references_app*.bib"))))8seen = {}; out = []; dups = []9for f in files:10    txt = open(f, encoding="utf-8").read()11    for m in re.finditer(r"@(\w+)\s*\{\s*([^,\s]+)\s*,", txt):12        start = m.start(); depth = 0; i = m.end() - 113        # find matching closing brace of the entry14        j = txt.find("{", start); depth = 0; k = j15        while k < len(txt):16            if txt[k] == "{": depth += 117            elif txt[k] == "}":18                depth -= 119                if depth == 0: break20            k += 121        entry = txt[start:k + 1]; key = m.group(2)22        doi = re.search(r"doi\s*=\s*[{\"]([^}\"]+)", entry, re.I)23        doi = doi.group(1).strip().lower() if doi else None24        if key in seen:25            dups.append((key, os.path.basename(f), "DOI_CONFLICT" if (doi and seen[key] and doi != seen[key]) else "same"))26            continue27        # verification notes live in the CSVs; strip them from the printed bibliography (aer.bst prints `note`)28        entry = re.sub(r",\s*note\s*=\s*[{\"]verified[^}\"]*[}\"]", "", entry)29        seen[key] = doi; out.append(entry)30open(os.path.join(H, "references_all.bib"), "w", encoding="utf-8").write("% merged by merge_bibs.py — do not edit; edit the source bib files\n\n" + "\n\n".join(out) + "\n")31with open(os.path.join(H, "references_merge_report.txt"), "w") as fh:32    fh.write(f"entries: {len(out)} from {len(files)} files\n"); [fh.write(f"DUP {k} in {f}: {st}\n") for k, f, st in dups]33print(len(out), "entries;", len(dups), "duplicates;", sum(1 for d in dups if d[2] == "DOI_CONFLICT"), "DOI conflicts")34
Files · main
Menu

Theme