Spaces:
Sleeping
Sleeping
| """ | |
| Usage checker for bibliography entries in TeX files. | |
| """ | |
| from dataclasses import dataclass | |
| from typing import Optional | |
| from ..parsers.bib_parser import BibEntry | |
| from ..parsers.tex_parser import TexParser, CitationContext | |
| class UsageResult: | |
| """Result of checking if a bib entry is used.""" | |
| entry_key: str | |
| is_used: bool | |
| usage_count: int | |
| contexts: list[CitationContext] | |
| line_numbers: list[int] | |
| def first_usage_line(self) -> Optional[int]: | |
| return self.line_numbers[0] if self.line_numbers else None | |
| class UsageChecker: | |
| """Checks if bibliography entries are used in TeX files.""" | |
| def __init__(self, tex_parser: TexParser): | |
| self.tex_parser = tex_parser | |
| self._cited_keys = tex_parser.get_all_cited_keys() | |
| def check_usage(self, entry: BibEntry) -> UsageResult: | |
| """Check if a bib entry is used in the TeX document.""" | |
| key = entry.key | |
| is_used = key in self._cited_keys | |
| contexts = self.tex_parser.get_citation_contexts(key) | |
| return UsageResult( | |
| entry_key=key, | |
| is_used=is_used, | |
| usage_count=len(contexts), | |
| contexts=contexts, | |
| line_numbers=[ctx.line_number for ctx in contexts] | |
| ) | |
| def get_unused_entries(self, entries: list[BibEntry]) -> list[BibEntry]: | |
| """Get list of entries that are not cited in the document.""" | |
| unused = [] | |
| for entry in entries: | |
| if entry.key not in self._cited_keys: | |
| unused.append(entry) | |
| return unused | |
| def get_missing_entries(self, entries: list[BibEntry]) -> list[str]: | |
| """Get list of citation keys that don't have corresponding bib entries.""" | |
| entry_keys = {e.key for e in entries} | |
| missing = [] | |
| for key in self._cited_keys: | |
| if key not in entry_keys: | |
| missing.append(key) | |
| return missing | |
| def get_combined_context(self, key: str, max_chars: int = 1000) -> str: | |
| """Get combined context for all usages of a key.""" | |
| contexts = self.tex_parser.get_citation_contexts(key) | |
| if not contexts: | |
| return "" | |
| combined = [] | |
| total_chars = 0 | |
| for ctx in contexts: | |
| if total_chars + len(ctx.full_context) > max_chars: | |
| # Add truncated context | |
| remaining = max_chars - total_chars | |
| if remaining > 100: | |
| combined.append(ctx.full_context[:remaining] + "...") | |
| break | |
| combined.append(ctx.full_context) | |
| total_chars += len(ctx.full_context) | |
| return "\n---\n".join(combined) | |