Skip to content

bib.bibtexparser.library

Classes

Library

Library(blocks=None)

A collection of parsed bibtex blocks.

Source code in pybibtexer/bib/bibtexparser/library.py
def __init__(self, blocks: list[Block] | None = None):
    self._blocks = []
    self._entries_by_key = {}
    self._strings_by_key = {}
    if blocks is not None:
        self.add(blocks)

Attributes

blocks property
blocks

All blocks in the library, preserving order of insertion.

comments property
comments

All comment blocks in the library, preserving order of insertion.

entries property
entries

All entry (@article, ...) blocks in the library, preserving order of insertion.

entries_dict property
entries_dict

Dict representation of all entry blocks in the library.

failed_blocks property
failed_blocks

All blocks that could not be parsed, preserving order of insertion.

preambles property
preambles

All @preamble blocks in the library, preserving order of insertion.

strings property
strings

All @string blocks in the library, preserving order of insertion.

strings_dict property
strings_dict

Dict representation of all @string blocks in the library.

Functions

add
add(blocks, fail_on_duplicate_key=False)

Add blocks to library.

The adding is key-safe, i.e., it is made sure that no duplicate keys are added. for the same type (i.e., String or Entry). Duplicates are silently replaced with a DuplicateKeyBlock.

:param blocks: Block or list of blocks to add. :param fail_on_duplicate_key: If True, raises ValueError if a block was replaced with a DuplicateKeyBlock.

Source code in pybibtexer/bib/bibtexparser/library.py
def add(self, blocks: list[Block] | Block, fail_on_duplicate_key: bool = False):
    """Add blocks to library.

    The adding is key-safe, i.e., it is made sure that no duplicate keys are added.
    for the same type (i.e., String or Entry). Duplicates are silently replaced with
    a DuplicateKeyBlock.

    :param blocks: Block or list of blocks to add.
    :param fail_on_duplicate_key:
        If True, raises ValueError if a block was replaced with a DuplicateKeyBlock.
    """
    if isinstance(blocks, Block):
        blocks = [blocks]

    _added_blocks = []
    for block in blocks:
        # This may replace block with a DuplicateEntryKeyBlock
        block = self._add_to_dicts(block)
        self._blocks.append(block)
        _added_blocks.append(block)

    if fail_on_duplicate_key:
        duplicate_keys = []
        for original, added in zip(blocks, _added_blocks, strict=True):
            if original is not added and isinstance(added, DuplicateBlockKeyBlock):
                duplicate_keys.append(added.key)

        if len(duplicate_keys) > 0:
            raise ValueError(
                f"Duplicate keys found: {duplicate_keys}. "
                f"Duplicate entries have been added to the library as DuplicateBlockKeyBlock."
                f"Use `library.failed_blocks` to access them. "
            )
convert
convert(name)

Convert the library to special library.

Convert the library to special library only contain block whose name is name, such as entry, 'string', ...

Source code in pybibtexer/bib/bibtexparser/library.py
def convert(self, name: str):
    """Convert the library to special library.

    Convert the library to special library only contain block
    whose name is `name`, such as `entry`, 'string', ...
    """
    for block in self._blocks:
        if block.__class__.__name__.lower() != name.lower():
            self.remove(block)
remove
remove(blocks)

Remove blocks from library.

:param blocks: Block or list of blocks to remove. :raises ValueError: If block is not in library.

Source code in pybibtexer/bib/bibtexparser/library.py
def remove(self, blocks: list[Block] | Block):
    """Remove blocks from library.

    :param blocks: Block or list of blocks to remove.
    :raises ValueError: If block is not in library.
    """
    if isinstance(blocks, Block):
        blocks = [blocks]

    for block in blocks:
        self._blocks.remove(block)
        if isinstance(block, Entry):
            del self._entries_by_key[block.key]
        elif isinstance(block, String):
            del self._strings_by_key[block.key]
replace
replace(old_block, new_block, fail_on_duplicate_key=True)

Replace a block with another block, at the same position.

:param old_block: Block to replace. :param new_block: Block to replace with. :param fail_on_duplicate_key: If False, adds a DuplicateKeyBlock if a block with new_block.key (other than old_block) already exists. :raises ValueError: If old_block is not in library or if fail_on_duplicate_key is True and a block with new_block.key (other than old_block) already exists.

Source code in pybibtexer/bib/bibtexparser/library.py
def replace(self, old_block: Block, new_block: Block, fail_on_duplicate_key: bool = True):
    """Replace a block with another block, at the same position.

    :param old_block: Block to replace.
    :param new_block: Block to replace with.
    :param fail_on_duplicate_key: If False, adds a DuplicateKeyBlock if
            a block with new_block.key (other than old_block) already exists.
    :raises ValueError: If old_block is not in library or if fail_on_duplicate_key is True
            and a block with new_block.key (other than old_block) already exists.
    """
    try:
        index = self._blocks.index(old_block)
        self.remove(old_block)
    except ValueError:
        raise ValueError("Block to replace is not in library.")

    block_after_add = self._add_to_dicts(new_block)
    self._blocks.insert(index, block_after_add)

    if (
        new_block is not block_after_add
        and isinstance(block_after_add, DuplicateBlockKeyBlock)
        and fail_on_duplicate_key
    ):
        # Revert changes to old_block
        #   Don't fail on duplicate key, as this would lead to an infinite recursion
        #   (should never happen for a clean library, but could happen if the user
        #   tampered with the internals of the library).
        self.replace(block_after_add, old_block, fail_on_duplicate_key=False)
        raise ValueError("Duplicate key found.")