File size: 3,980 Bytes
6ca4b94 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
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 |