synth-net / src /utils /bibliography.py
github-actions
Sync from GitHub (CI)
6ca4b94
import logging
from pathlib import Path
from functools import lru_cache
from typing import Optional
from pybtex.database import parse_file, BibliographyData
from pybtex.plugin import find_plugin
logger = logging.getLogger(__name__)
BIB_DIR = Path("public/bib")
STYLE_NAME = "apa7"
OUTPUT_FORMAT = "html"
@lru_cache(maxsize=1)
def load_bibliography() -> BibliographyData:
bib_files = list(BIB_DIR.glob("*.bib"))
if not bib_files:
logger.warning(f"No .bib files found in {BIB_DIR}")
return BibliographyData()
merged_bib = parse_file(str(bib_files[0]))
logger.info(f"Loaded bibliography from {bib_files[0].name}")
for bib_file in bib_files[1:]:
try:
bib_data = parse_file(str(bib_file))
merged_bib.entries.update(bib_data.entries)
logger.info(f"Merged bibliography from {bib_file.name}")
except Exception as e:
logger.error(f"Error parsing {bib_file}: {e}")
logger.info(f"Total entries loaded: {len(merged_bib.entries)}")
return merged_bib
def format_citation(
cite_key: str,
style: str = STYLE_NAME,
output_format: str = OUTPUT_FORMAT
) -> str:
try:
bibliography = load_bibliography()
if cite_key not in bibliography.entries:
logger.warning(f"Citation key '{cite_key}' not found in bibliography")
return f"<p class='citation-error'>[Citation not found: {cite_key}]</span>"
filtered_bib = BibliographyData({cite_key: bibliography.entries[cite_key]})
style_plugin = find_plugin('pybtex.style.formatting', style)()
backend = find_plugin('pybtex.backends', output_format)()
formatted = style_plugin.format_bibliography(filtered_bib)
for entry in formatted:
return entry.text.render(backend)
return f"<p class='citation-error'>[Error formatting: {cite_key}]</span>"
except Exception as e:
logger.error(f"Error formatting citation {cite_key}: {e}")
return f"<p class='citation-error'>[Error: {cite_key}]</span>"
def format_bibliography(
cite_keys: Optional[list[str]] = None,
style: str = STYLE_NAME,
output_format: str = OUTPUT_FORMAT
) -> str:
try:
bibliography = load_bibliography()
# Filter to requested keys if provided
if cite_keys:
filtered_entries = {
key: bibliography.entries[key]
for key in cite_keys
if key in bibliography.entries
}
if not filtered_entries:
return "<p class='bibliography-error'>No valid citation keys provided.</p>"
filtered_bib = BibliographyData(filtered_entries)
else:
filtered_bib = bibliography
style_plugin = find_plugin('pybtex.style.formatting', style)()
backend = find_plugin('pybtex.backends', output_format)()
formatted = style_plugin.format_bibliography(filtered_bib)
entries_html = []
for entry in formatted:
entries_html.append(entry.text.render(backend))
return "\n".join(entries_html)
except Exception as e:
logger.error(f"Error formatting bibliography: {e}")
return f"<p class='bibliography-error'>[Error formatting bibliography]</p>"
def get_bibtex_entry(cite_key: str) -> Optional[str]:
try:
bibliography = load_bibliography()
if cite_key not in bibliography.entries:
logger.warning(f"Citation key '{cite_key}' not found")
return None
single_entry = BibliographyData({cite_key: bibliography.entries[cite_key]})
return single_entry.to_string('bibtex')
except Exception as e:
logger.error(f"Error getting BibTeX for {cite_key}: {e}")
return None