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