Sphinx extension for BibTeX style citations.
Pluggable style system for citation formatting and referencing, supporting multiple citation styles through a flexible plugin architecture built on top of pybtex styles.
Abstract base class for all citation reference styles that defines the interface for formatting citations.
class BaseReferenceStyle(ABC):
"""
Base class for citation reference styles.
All subclasses must be decorated as dataclass and provide default values
for all attributes to allow instantiation without arguments.
"""
def role_names(self) -> Iterable[str]:
"""
Get list of role names supported by this style.
Returns:
Iterable of role names (e.g., ['p', 't'] for parenthetical/textual)
"""
def outer(self, role_name: str, children: List[BaseText]) -> Node:
"""
Returns outer template for formatting multiple references.
Parameters:
role_name: The citation role name ('p', 't', etc.)
children: List of formatted individual references
Returns:
Template node for combining multiple references
"""
def inner(self, role_name: str) -> Node:
"""
Returns inner template for formatting individual references.
Parameters:
role_name: The citation role name ('p', 't', etc.)
Returns:
Template node for formatting single reference
"""Core function that formats lists of references according to a given style.
def format_references(
style: BaseReferenceStyle,
role_name: str,
references: Iterable[Tuple[Entry, FormattedEntry, ReferenceInfo]],
) -> BaseText:
"""
Format list of references according to the given role and style.
First formats each reference using the style's inner method,
then combines all formatted references using the style's outer method.
Parameters:
style: Reference style instance to use for formatting
role_name: Citation role name ('p' for parenthetical, 't' for textual)
references: Iterable of (entry, formatted_entry, reference_info) tuples
Returns:
Formatted text containing all references
"""Classes for composing and customizing reference styles with brackets, separators, and person formatting.
class BracketStyle:
"""
Provides brackets and separators for citation formatting.
Attributes:
left: Left bracket character or text (default: "[")
right: Right bracket character or text (default: "]")
sep: Separator between multiple citations (default: ", ")
sep2: Separator when exactly two citations (default: None)
last_sep: Separator before last citation when 3+ citations (default: None)
"""
left: Union[BaseText, str] = "["
right: Union[BaseText, str] = "]"
sep: Union[BaseText, str] = ", "
sep2: Optional[Union[BaseText, str]] = None
last_sep: Optional[Union[BaseText, str]] = None
def outer(
self,
children: List[BaseText],
brackets: bool = False,
capfirst: bool = False
) -> Node:
"""
Create outer template with separators, brackets, and capitalization.
Parameters:
children: List of formatted citation components
brackets: Whether to add brackets around the result
capfirst: Whether to capitalize the first word
Returns:
Template node with appropriate formatting
"""
class PersonStyle:
"""
Provides person name formatting for citations.
Attributes:
style: Plugin name for name formatting style (default: "last")
abbreviate: Whether to abbreviate first names (default: True)
sep: Separator between persons (default: ", ")
sep2: Separator for exactly two persons (default: " and ")
last_sep: Separator before last person when 3+ (default: ", and ")
other: Text for 3+ persons abbreviation (default: " et al.")
"""
style: str = "last"
abbreviate: bool = True
sep: Union[BaseText, str] = ", "
sep2: Optional[Union[BaseText, str]] = " and "
last_sep: Optional[Union[BaseText, str]] = ", and "
other: Optional[Union[BaseText, str]] = None # Defaults to " et al."
def names(self, role: str, full: bool) -> Node:
"""
Template for formatting person names with separators.
Parameters:
role: Person role ("author" or "editor")
full: Whether to show full person list or use abbreviation
Returns:
Template node for person name formatting
"""
def author_or_editor_or_title(self, full: bool) -> Node:
"""
Template for author names, falling back to editor or title.
Parameters:
full: Whether to show full person list
Returns:
Template node with fallback logic
"""
class GroupReferenceStyle(BaseReferenceStyle):
"""
Composes multiple reference styles into a single consistent style.
Allows different role names to use different formatting approaches
while maintaining a unified interface.
Attributes:
styles: List of component reference styles
"""
styles: List[BaseReferenceStyle] = field(default_factory=list)
def role_names(self) -> Iterable[str]:
"""Get all role names from all component styles."""
def outer(self, role_name: str, children: List[BaseText]) -> Node:
"""Get outer template from the appropriate component style."""
def inner(self, role_name: str) -> Node:
"""Get inner template from the appropriate component style."""Functions for loading and registering citation style plugins.
def find_plugin(group: str, name: str) -> Type[Any]:
"""
Load a sphinxcontrib-bibtex plugin from entry points or runtime store.
Parameters:
group: Plugin group name (e.g., "sphinxcontrib.bibtex.style.referencing")
name: Plugin name within the group
Returns:
Plugin class type
Raises:
ImportError: If plugin group or plugin name not found
"""
def register_plugin(
group: str,
name: str,
klass: Type[Any],
force: bool = False
) -> bool:
"""
Register a plugin in the runtime store.
Parameters:
group: Plugin group name
name: Plugin name within group
klass: Plugin class to register
force: Whether to override existing plugins
Returns:
True if plugin was registered, False if already exists and force=False
Raises:
ImportError: If plugin group is not recognized
"""The extension provides several built-in reference styles via entry points:
# Entry point: sphinxcontrib.bibtex.style.referencing.author_year:AuthorYearReferenceStyle
# Configuration: bibtex_reference_style = "author_year"
# Example output:
# :cite:t: -> Smith (2020)
# :cite:p: -> (Smith, 2020; Jones, 2019)# Entry point: sphinxcontrib.bibtex.style.referencing.label:LabelReferenceStyle
# Configuration: bibtex_reference_style = "label" (default)
# Example output:
# :cite:t: -> Smith [Smi20]
# :cite:p: -> [Smi20, Jon19]# Entry point: sphinxcontrib.bibtex.style.referencing.foot:FootReferenceStyle
# Configuration: bibtex_foot_reference_style = "foot" (default for footnotes)
# Used with :footcite: roles for footnote formatting# Entry point: sphinxcontrib.bibtex.style.referencing.super_:SuperReferenceStyle
# Configuration: bibtex_reference_style = "super"
# Example output:
# :cite:p: -> [1,2]
# :cite:t: -> Smith¹from dataclasses import dataclass
from sphinxcontrib.bibtex.style.referencing import BaseReferenceStyle
@dataclass
class CustomReferenceStyle(BaseReferenceStyle):
def role_names(self):
return ["p", "t"]
def outer(self, role_name, children):
if role_name == "p":
return join["(", sentence[children], ")"]
else: # textual
return sentence[children]
def inner(self, role_name):
return field("author") + " " + field("year")
# Register the style
from sphinxcontrib.bibtex.plugin import register_plugin
register_plugin(
"sphinxcontrib.bibtex.style.referencing",
"custom",
CustomReferenceStyle
)# conf.py
bibtex_reference_style = "author_year" # For regular citations
bibtex_foot_reference_style = "foot" # For footnote citations@dataclass
class AuthorYearStyle(BaseReferenceStyle):
bracket: BracketStyle = field(default_factory=BracketStyle)
person: PersonStyle = field(default_factory=PersonStyle)
def role_names(self):
return ["p", "t"]
def outer(self, role_name, children):
return self.bracket.outer(
children,
brackets=(role_name == "p"),
capfirst=(role_name == "t")
)
def inner(self, role_name):
return join[
self.person.author_or_editor_or_title(full=False),
" ",
field("year")
]The style system integrates with pybtex's rich text system for advanced formatting:
# Type definitions for rich text integration
ReferenceInfo = TypeVar("ReferenceInfo")
class BaseReferenceText(BaseMultipartText, Generic[ReferenceInfo], ABC):
"""
Generic rich text element for citation references.
Stores extra reference information for use during formatting.
Must be subclassed to override render method for specific output formats.
"""
def __init__(self, info: ReferenceInfo, *parts: BaseText):
"""Initialize with reference info and text parts."""ImportError with descriptive message about missing pluginImportError for unrecognized plugin groupsforce parameterInstall with Tessl CLI
npx tessl i tessl/pypi-sphinxcontrib-bibtex