Sphinx extension for BibTeX style citations.
BibTeX file parsing, caching, and processing functionality built on pybtex. Handles reading, parsing, and managing bibliography data with efficient caching and dependency tracking.
Core data structures for managing bibliography file information and parsed data.
class BibData(NamedTuple):
"""
Information about a collection of bib files.
Attributes:
encoding: Encoding used for all bib files
bibfiles: Map from file paths to file information
data: Parsed bibliography data from pybtex
"""
encoding: str
bibfiles: Dict[Path, BibFile]
data: BibliographyData # From pybtex
class BibFile(NamedTuple):
"""
Information about a parsed bib file.
Attributes:
mtime: File modification time when last parsed
keys: Set of citation keys in this file (as ordered dict)
"""
mtime: float
keys: Dict[str, None]Functions for parsing, caching, and managing bibliography files with dependency tracking.
def parse_bibdata(bibfilenames: List[Path], encoding: str) -> BibData:
"""
Parse bibliography files with given encoding.
Parameters:
bibfilenames: List of bibliography file paths to parse
encoding: Text encoding to use when reading files
Returns:
Parsed bibliography data containing all entries
Raises:
BibliographyDataError: If bibliography files contain syntax errors
"""
def is_bibdata_outdated(
bibdata: BibData,
bibfilenames: List[Path],
encoding: str
) -> bool:
"""
Check if bibliography data needs to be reparsed.
Parameters:
bibdata: Current bibliography data
bibfilenames: List of current bibliography files
encoding: Current encoding setting
Returns:
True if data is outdated and needs reparsing
"""
def process_bibdata(
bibdata: BibData,
bibfilenames: List[Path],
encoding: str
) -> BibData:
"""
Parse bibliography files and store parsed data with caching.
Only reparses if files have changed, encoding changed, or file list changed.
Parameters:
bibdata: Previous bibliography data (for caching)
bibfilenames: List of bibliography file paths
encoding: Text encoding for files
Returns:
Updated bibliography data (may be cached if unchanged)
"""
def get_mtime(bibfilename: Path) -> float:
"""
Get file modification time, returning -inf if file doesn't exist.
Parameters:
bibfilename: Path to bibliography file
Returns:
Modification time as float, or -math.inf if file missing
"""Functions for parsing and processing citation targets from role content.
class CitationTarget(NamedTuple):
"""
Citation key with optional pre-text and post-text.
Attributes:
key: The bibliography key to cite
pre: Optional text to appear before citation
post: Optional text to appear after citation
"""
key: str
pre: str
post: str
def parse_citation_targets(targets: str, pos: int = 0) -> Iterable[CitationTarget]:
"""
Parse citation target string into citation keys with optional pre/post text.
Supports formats:
key - Simple key citation
{pre}key - Key with pre-text
key{post} - Key with post-text
{pre}key{post} - Key with both pre and post text
key1,key2,key3 - Multiple keys
Parameters:
targets: String containing citation targets
pos: Starting position for parsing (used internally for recursion)
Returns:
Iterable of CitationTarget objects
Raises:
ValueError: If citation target format is malformed
"""Utility functions for generating unique citation and bibliography IDs.
def _make_ids(docname: str, lineno: int, ids: Set[str], raw_id: str) -> List[str]:
"""
Generate unique IDs for citations and bibliographies.
Parameters:
docname: Document name for warning location
lineno: Line number for warning location
ids: Set of existing IDs to check for conflicts
raw_id: Raw ID template string
Returns:
List containing the generated ID, or empty list if duplicate detected
Side Effects:
- Adds generated ID to ids set if successful
- Logs warning if duplicate ID detected
"""from pathlib import Path
from sphinxcontrib.bibtex.bibfile import parse_bibdata, process_bibdata
# Parse bibliography files
bibfiles = [Path("refs.bib"), Path("additional.bib")]
bibdata = parse_bibdata(bibfiles, "utf-8")
# Access parsed data
for key, entry in bibdata.data.entries.items():
print(f"Key: {key}, Title: {entry.fields.get('title', 'No title')}")# First call - parses files
bibdata = process_bibdata(BibData("", {}, BibliographyData()), bibfiles, "utf-8")
# Second call - uses cache since files unchanged
bibdata = process_bibdata(bibdata, bibfiles, "utf-8") # Fast, uses cachefrom sphinxcontrib.bibtex.citation_target import parse_citation_targets
# Simple keys
targets = list(parse_citation_targets("smith2020,jones2019"))
# [CitationTarget(key='smith2020', pre='', post=''),
# CitationTarget(key='jones2019', pre='', post='')]
# With pre/post text
targets = list(parse_citation_targets("{see}smith2020{for details}"))
# [CitationTarget(key='smith2020', pre='see', post='for details')]from sphinxcontrib.bibtex.bibfile import get_mtime, is_bibdata_outdated
# Check if files need reparsing
if is_bibdata_outdated(current_bibdata, bibfiles, "utf-8"):
print("Bibliography files have changed, reparsing...")
bibdata = parse_bibdata(bibfiles, "utf-8")
else:
print("Bibliography files unchanged, using cache")ValueError raised with descriptive messageenv.note_dependency()bibtex_bibfiles and bibtex_encodingParser class for BibTeX parsingBibliographyData objectsInstall with Tessl CLI
npx tessl i tessl/pypi-sphinxcontrib-bibtex