Source code for bibtexparser.middlewares.interpolate

import warnings
from copy import deepcopy
from typing import Any

from bibtexparser.library import Library
from bibtexparser.model import Entry
from bibtexparser.model import Field

from .enclosing import REMOVED_ENCLOSING_KEY
from .middleware import LibraryMiddleware


def _value_is_nonstring_or_enclosed(value: Any) -> bool:
    """Check if value is an int or enclosed in curly braces."""
    if not isinstance(value, str):
        return True
    if value.startswith('"') and value.endswith('"'):
        return True
    if value.startswith("{") and value.endswith("}"):
        return True
    return False


[docs] class ResolveStringReferencesMiddleware(LibraryMiddleware): """Replace strings references with their values.""" # docstr-coverage: inherited def __init__(self, allow_inplace_modification: bool = True): super().__init__(allow_inplace_modification) # docstr-coverage: inherited @classmethod def metadata_key(cls) -> str: return "ResolveStringReferences" # docstr-coverage: inherited
[docs] def transform(self, library: Library) -> Library: if not self.allow_inplace_modification: library = deepcopy(library) # BibTeX string keys are case-insensitive; later definitions win. string_values = {key.lower(): s.value for key, s in library.strings_dict.items()} entry: Entry raised_enclosing_warning = False for entry in library.entries: resolved_fields = list() if not raised_enclosing_warning and REMOVED_ENCLOSING_KEY in entry.parser_metadata: raised_enclosing_warning = True warnings.warn( ( "The RemoveEnclosingMiddleware must not run before " "the ResolveStringReferencesMiddleware. " "We continue, but string interpolation is likely to fail, " "or to be too aggressive (i.e., replace too many strings)." ), UserWarning, ) field: Field for field in entry.fields: if _value_is_nonstring_or_enclosed(field.value): continue try: field.value = string_values[field.value.lower()] except KeyError: continue resolved_fields.append(field.key) if resolved_fields: entry.parser_metadata[self.metadata_key()] = resolved_fields return library
# TODO Middleware to replace field values with string references, if found # TODO Middleware to resolve Crossref