Full API

bibtexparser — High-Level Entrypoints

bibtexparser.parse_file(path: str, parse_stack: Iterable[Middleware] | None = None, append_middleware: Iterable[Middleware] | None = None, encoding: str = 'UTF-8') → Library[source]

Parse a BibTeX file

Parameters:
  • path – Path to BibTeX file

  • parse_stack – List of middleware to apply to the database after splitting. If None (default), a default stack will be used providing simple standard functionality.

  • append_middleware – List of middleware to append to the default stack (ignored if a not-None parse_stack is passed).

  • encoding – Encoding of the .bib file. Default encoding is "UTF-8".

Returns:

Library: Parsed BibTeX library

Raises:

LookupError – If the specified encoding is not recognized.

bibtexparser.parse_string(bibtex_str: str, parse_stack: Iterable[Middleware] | None = None, append_middleware: Iterable[Middleware] | None = None, library: Library | None = None) → Library[source]

Parse a BibTeX string.

Parameters:
  • bibtex_str – BibTeX string to parse

  • parse_stack – List of middleware to apply to the database after splitting. If None (default), a default stack will be used providing simple standard functionality.

  • append_middleware – List of middleware to append to the default stack (ignored if a not-None parse_stack is passed).

  • library –

    Library to add the newly parsed blocks to. If None (default), a new library is created and returned. If a library is passed, it is returned (mutated) and:

    • the parse stack is applied only to the newly parsed blocks; blocks already contained in the passed library are left untouched (they were already transformed when they were parsed);

    • @string blocks already contained in the passed library are visible to the parse stack, i.e. string references in bibtex_str resolve against them (unless bibtex_str redefines the same key);

    • keys defined both in the passed library and in bibtex_str do not raise, but yield DuplicateBlockKeyBlock instances (see library.failed_blocks), just like duplicates within a single string.

Returns:

Library: Parsed BibTeX database

bibtexparser.write_file(file: str | TextIO, library: Library, unparse_stack: Iterable[Middleware] | None = None, prepend_middleware: Iterable[Middleware] | None = None, bibtex_format: BibtexFormat | None = None, encoding: str = 'UTF-8', **kwargs) → None[source]

Write a BibTeX database to a file.

The passed library is never modified, unless every middleware in the unparse stack allows in-place modification (e.g. unparse_stack=default_unparse_stack(allow_inplace_modification=True)).

Parameters:
  • file – File to write to. Can be a file name or a file object.

  • library – BibTeX database to serialize.

  • unparse_stack – List of middleware to apply to the database before writing. If None, a default stack will be used.

  • prepend_middleware – List of middleware to prepend to the default stack. Only applicable if unparse_stack is None.

  • bibtex_format – Customized BibTeX format to use (optional).

  • encoding – Encoding of the .bib file. Default encoding is "UTF-8".

Writing a library with at least LARGE_LIBRARY_WARNING_THRESHOLD blocks logs a warning if the unparse stack deep-copies blocks (middlewares with allow_inplace_modification=False), as that is slow; pass an all-in-place stack to avoid it.

Deprecated since version (next: version) Parameters ‘parse_stack’ and ‘append_middleware’ are deprecated, will be deleted soon. Use ‘unparse_stack’ and ‘prepend_middleware’ instead.

bibtexparser.write_string(library: Library, unparse_stack: Iterable[Middleware] | None = None, prepend_middleware: Iterable[Middleware] | None = None, bibtex_format: BibtexFormat | None = None, **kwargs) → str[source]

Serialize a BibTeX database to a string.

The passed library is never modified, unless every middleware in the unparse stack allows in-place modification (e.g. unparse_stack=default_unparse_stack(allow_inplace_modification=True)).

Parameters:
  • library – BibTeX database to serialize.

  • unparse_stack – List of middleware to apply to the database before writing. If None, a default stack will be used.

  • prepend_middleware – List of middleware to prepend to the default stack. Only applicable if unparse_stack is None.

  • bibtex_format – Customized BibTeX format to use (optional).

Writing a library with at least LARGE_LIBRARY_WARNING_THRESHOLD blocks logs a warning if the unparse stack deep-copies blocks (middlewares with allow_inplace_modification=False), as that is slow; pass an all-in-place stack to avoid it.

Deprecated since version (next: version) Parameters ‘parse_stack’ and ‘append_middleware’ are deprecated. Use ‘unparse_stack’ and ‘prepend_middleware’ instead.

bibtexparser.Library — The class containing the parsed library

class bibtexparser.Library(blocks: list[Block] | None = None, fail_on_duplicate_key: bool = True)[source]

A collection of parsed bibtex blocks.

property blocks: list[Block]

All blocks in the library, preserving order of insertion.

property comments: list[ExplicitComment | ImplicitComment]

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

property entries: list[Entry]

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

property entries_dict: dict[str, Entry]

Dict representation of all entry blocks in the library.

property failed_blocks: list[ParsingFailedBlock]

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

property preambles: list[Preamble]

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

property strings: list[String]

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

bibtexparser.model — The classes used in the library

class bibtexparser.model.Block(start_line: int | None = None, raw: str | None = None, parser_metadata: dict[str, Any] | None = None)[source]

An abstract superclass of all top-level building blocks of a bibtex file.

E.g. a @string block, a @preamble block, an @entry block, a comment, etc.

get_parser_metadata(key: str) → Any | None[source]

EXPERIMENTAL: get auxiliary information stored in parser_metadata.

See attribute parser_metadata for more information.

property parser_metadata: dict[str, Any]

EXPERIMENTAL: field for middleware to store auxiliary information.

As an end-user, as long as you are not writing middleware, you probably do not need to use this field.

** Warning (experimental) ** The content of this field is undefined and may change at any time.

This field is intended for middleware to store auxiliary information. It is a key-value store, where the key is a string and the value is any python object. This allows for example to pass information between different middleware.

property raw: str | None

The raw, unmodified string (bibtex) representation of this block.

Note: Middleware does not update this field, hence, after applying middleware to a library, this field may be outdated.

set_parser_metadata(key: str, value: Any)[source]

EXPERIMENTAL: set auxiliary information stored in parser_metadata.

See attribute parser_metadata for more information.

property start_line: int | None

The line number of the first line of this block in the parsed string.

class bibtexparser.model.DuplicateBlockKeyBlock(key: str, previous_block: Block, duplicate_block: Block, start_line: int | None = None, raw: str | None = None)[source]

An error-indicating block created for blocks with keys present in the library already.

To get the block that caused this error, call block.ignore_error_block.

property key: str

The key of the entry, e.g. Cesar2013 in @article{Cesar2013, ...}.

property previous_block: Block

A reference to a previous block with the same key.

class bibtexparser.model.DuplicateFieldKeyBlock(duplicate_keys: set[str], entry: Entry)[source]

An error-indicating block indicating a duplicate field key in an entry.

The entry containing the duplicate field keys is available as block.ignore_error_block, the duplicate keys as block.duplicate_keys.

property duplicate_keys: set[str]

The field-keys that occurred more than once in the entry.

class bibtexparser.model.Entry(entry_type: str, key: str, fields: list[Field], start_line: int | None = None, raw: str | None = None)[source]

Bibtex Blocks of the @entry type, e.g. @article{Cesar2013, ...}.

property entry_type: str

The type of the entry, e.g. article in @article{Cesar2013, ...}.

property fields: list[Field]

The key-value attributes of an entry, as Field instances.

property fields_dict: dict[str, Field]

A dict of fields, with field keys as keys.

Note that with duplicate field keys, the behavior is undefined.

get(key: str, default=None) → Field | None[source]

Returns the field with the given key, or the default value if it does not exist.

Parameters:
  • key – The key of the field.

  • default – The value to return if the field does not exist.

items() → list[tuple[str, Any]][source]

Dict-mimicking, for partial v1.x backwards compatibility.

For newly written code, it’s recommended to use entry.entry_type, entry.key and entry.fields instead.

property key: str

The key of the entry, e.g. Cesar2013 in @article{Cesar2013, ...}.

keys() → list[str][source]

Dict-mimicking, for partial v1.x backwards compatibility.

Same keys and order as in items(), e.g. allowing dict(entry).

pop(key: str, default=None) → Field | None[source]

Removes and returns the field with the given key.

Parameters:
  • key – The key of the field to remove.

  • default – The value to return if the field does not exist.

set_field(field: Field)[source]

Adds a new field, or replaces existing with same key.

class bibtexparser.model.ExplicitComment(comment: str, start_line: int | None = None, raw: str | None = None)[source]

Bibtex Blocks of the @comment type, e.g. @comment{This is a comment}.

property comment: str

The value of the comment, e.g. blabla in @comment{blabla}.

class bibtexparser.model.Field(key: str, value: Any, start_line: int | None = None, enclosing: str | None = None)[source]

A field of a Bibtex entry, e.g. author = {John Doe}.

property enclosing: str | None

The enclosing demanded when writing this field, e.g. '{'.

Allowed values are '{', '"' and 'no-enclosing'. None (the default) leaves the choice to the writing middleware (see AddEnclosingMiddleware), which is the right choice for most use-cases.

A demand of 'no-enclosing' is used for values that must be written verbatim, such as bibtex string references (month = jan) or concatenation expressions (pages = intro # outro), where adding an enclosing would change the semantics of the value.

Note: Assigning a new value to the field resets this attribute to None.

property key: str

The key of the field, e.g. author in author = {John Doe}.

property start_line: int

The line number of the first line of this field in the originally parsed string.

property value: Any

The value of the field, e.g. {John Doe} in author = {John Doe}.

class bibtexparser.model.ImplicitComment(comment: str, start_line: int | None = None, raw: str | None = None)[source]

Bibtex outside of an @{...} block, which is treated as a comment.

property comment: str

The (possibly multi-line) comment.

class bibtexparser.model.MiddlewareErrorBlock(block: Block, error: Exception)[source]

A block that could not be parsed due to a middleware error.

To get the block that caused this error, call block.ignore_error_block (which is the block with the middleware not or only partially applied).

class bibtexparser.model.ParsingFailedBlock(error: Exception, start_line: int | None = None, raw: str | None = None, ignore_error_block: Block | None = None)[source]

A block that could not be parsed due to some raised exception.

property error: Exception

The exception that was raised during parsing.

property ignore_error_block: Block | None

The possibly faulty block when ignoring the error.

This may be None, as it may not always be possible to ignore the error. For errors caused by middleware, this is typically the block without the middleware applied.

class bibtexparser.model.Preamble(value: str, start_line: int | None = None, raw: str | None = None)[source]

Bibtex Blocks of the @preamble type, e.g. @preamble{This is a preamble}.

property value: str

The value of the preamble, e.g. blabla in @preamble{blabla}.

class bibtexparser.model.String(key: str, value: str, start_line: int | None = None, raw: str | None = None, enclosing: str | None = None)[source]

Bibtex Blocks of the @string type, e.g. @string{me = "My Name"}.

property enclosing: str | None

The enclosing demanded when writing this string, e.g. '{'.

Allowed values are '{', '"' and 'no-enclosing'. None (the default) leaves the choice to the writing middleware (see AddEnclosingMiddleware), which is the right choice for most use-cases.

Note: Assigning a new value to the string resets this attribute to None.

property key: str

The key of the string, e.g. me in @string{me = "My Name"}.

property value: str

The value of the string, e.g. "My Name" in @string{me = "My Name"}.

bibtexparser.middlewares — Customizers to transform parsed library

class bibtexparser.middlewares.AddEnclosingMiddleware(reuse_previous_enclosing: bool, enclose_integers: bool, default_enclosing: str, allow_inplace_modification: bool = True)[source]

Add enclosing characters to values such as field and strings.

This middleware adds enclosing characters to a field value. It is useful when the field value is enclosed in braces or quotes.

The enclosing to add is determined with the following precedence:

  1. An enclosing demanded on the field or string itself (i.e., a non-None field.enclosing, e.g. set by a month middleware) is always honored.

  2. If reuse_previous_enclosing is True, the enclosing removed by the RemoveEnclosingMiddleware (if any) is used.

  3. If the value is an integer in a common int field and enclose_integers is False, no enclosing is added.

  4. Otherwise, the default_enclosing is used.

A no-enclosing resulting from 1. or 2. is overruled by the default_enclosing if the value cannot be written verbatim, i.e. if writing it as-is would not parse back to the same value. This happens when a middleware changed the value after the demand was set.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

transform_entry(entry: Entry, library: Library) → Entry[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_string(string: String, library: Library) → String[source]

Transform a string. Called by transform_block if the block is a string.

Note: This method modifies the passed string. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.BlockMiddleware(allow_parallel_execution: bool = True, allow_inplace_modification: bool = True)[source]

Transforms a library on a per-block basis.

The BlockMiddleware replaces a block with zero, one or more new (transformed) blocks.

Changes may rely on the state of the overall library, but must not change the state of the library directly, except if allow_inplace_modification is true.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

transform(library: Library) → Library[source]

Main entrypoint of the middleware. Applies transformation to a library.

transform_block(block: Block, library: Library) → Block | Collection[Block] | None[source]

Transform a block.

Parameters:
  • block – Block to transform.

  • library – Library containing the block. Should typically not be modified during the transformation, but be considered as read-only. If the library is modified, make sure to set the allow_multithreading constructor argument to false

Returns:

Transformed block. If the block should be removed, return None. If the block should be replaced by multiple blocks, return a collection of blocks. If the block should be replaced by a single block, return the single block. If the block should not be modified, return a copy of the original block. The returned block has to be a new instance, except if self.allow_inplace_modification is True (in which case the block may also return the original block).

transform_entry(entry: Entry, library: Library) → Block | Collection[Block] | None[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_explicit_comment(explicit_comment: ExplicitComment, library: Library) → Block | Collection[Block] | None[source]

Transform an explicit comment. Called by transform_block if the block is an explicit comment.

Note: This method modifies the passed explicit comment. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_failed_block(failed_block: ParsingFailedBlock, library: Library) → Block | Collection[Block] | None[source]

Transform a block whose parsing failed (e.g. a DuplicateFieldKeyBlock). Called by transform_block if the block is a ParsingFailedBlock.

By default, failed blocks are kept in the library unchanged, i.e., the middleware is not applied to them.

transform_implicit_comment(implicit_comment: ImplicitComment, library: Library) → Block | Collection[Block] | None[source]

Transform an implicit comment. Called by transform_block if the block is an implicit comment.

Note: This method modifies the passed implicit comment. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_preamble(preamble: Preamble, library: Library) → Block | Collection[Block] | None[source]

Transform a preamble. Called by transform_block if the block is a preamble.

Note: This method modifies the passed preamble. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_string(string: String, library: Library) → Block | Collection[Block] | None[source]

Transform a string. Called by transform_block if the block is a string.

Note: This method modifies the passed string. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.LatexDecodingMiddleware(allow_inplace_modification: bool = True, keep_braced_groups: bool | None = None, keep_math_mode: bool | None = None, decoder: LatexNodes2Text | None = None)[source]

Latex-Decodes all strings in the library

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

class bibtexparser.middlewares.LatexEncodingMiddleware(keep_math: bool | None = None, enclose_urls: bool | None = None, encoder: UnicodeToLatexEncoder | None = None, allow_inplace_modification: bool = True)[source]

Latex-Encodes all strings in the library

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

class bibtexparser.middlewares.LibraryMiddleware(allow_inplace_modification: bool = True)[source]

Changes an overall library at once (not just on a per-block basis).

Examples of library-wide changes are: - Re-Sorting the blocks in the library. - Transforming the library instance to a custom subclass of Library.

Whatever can be done in a BlockMiddleware, should be done in a BlockMiddleware (and not in a LibraryMiddleware), for performance reasons (e.g. deleting blocks, …).

transform(library: Library) → Library[source]

Transform a library.

Parameters:

library – Library to transform.

Returns:

Transformed library. If the library should not be modified, return a copy of the original library. The returned library has to be a new instance, except if self.allow_inplace_modification is True (in which case the library may also return the original library).

class bibtexparser.middlewares.MergeCoAuthors(allow_inplace_modification: bool = True, name_fields: tuple[str, ...] = ('author', 'editor', 'translator'))[source]

Middleware to merge multi-person-list fields (e.g. co-authors, co-editors).

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

class bibtexparser.middlewares.MergeNameParts(style: Literal['last', 'first'] = 'last', allow_inplace_modification: bool = True, name_fields: tuple[str, ...] = ('author', 'editor', 'translator'))[source]

Middleware to merge a persons name parts (first, von, last, jr) into a single string.

Name fields (e.g. author, editor, translator) are expected to be lists of NameParts.

The merging style indicates whether: - the merging is done without commas in first-name-first order (“first”), or - the merging is done with commas in last-name-first order (“last”).

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

class bibtexparser.middlewares.MonthAbbreviationMiddleware(allow_inplace_modification: bool = True)[source]

Replace month values with month abbreviations.

Note that this may be used before or after removing the enclosing, but the semantics are different: Enclosed values (e.g. ‘{jan}’, ‘“jan”’ or ‘“1”’) will not be transformed. If you want to transform these values, you should use this middleware after the RemoveEnclosingMiddleware.

The created abbreviations are always lowercase and unenclosed. As the abbreviations are bibtex string references (macros, e.g. jan), a no-enclosing demand is set on the month field (see Field.enclosing), making sure the AddEnclosingMiddleware keeps them unenclosed when writing.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

resolve_month_field_val(month_field: Field)[source]

Transform the month field.

Args:

month_field: The month field to transform.

Returns:

A tuple of the transformed value and the metadata.

class bibtexparser.middlewares.MonthIntMiddleware(allow_inplace_modification: bool = True)[source]

Replace month values with month numbers.

Note that this may be used before or after removing the enclosing, but the semantics are different: Enclosed values (e.g. ‘{jan}’, ‘“jan”’ or ‘“1”’) will not be transformed. If you want to transform these values, you should use this middleware after the RemoveEnclosingMiddleware.

The created int-months are always integers and unenclosed. A no-enclosing demand is set on the month field (see Field.enclosing), making sure the AddEnclosingMiddleware keeps them unenclosed when writing.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

resolve_month_field_val(month_field: Field)[source]

Transform the month field.

Args:

month_field: The month field to transform.

Returns:

A tuple of the transformed value and the metadata.

class bibtexparser.middlewares.MonthLongStringMiddleware(allow_inplace_modification: bool = True)[source]

Replace month numbers with full month names.

Note that this may be used before or after removing the enclosing, but the semantics are different: Enclosed values (e.g. ‘{jan}’, ‘“jan”’ or ‘“1”’) will not be transformed. If you want to transform these values, you should use this middleware after the RemoveEnclosingMiddleware.

Full names returned by this middleware are always capitalized and unenclosed.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

resolve_month_field_val(month_field: Field)[source]

Transform the month field.

Args:

month_field: The month field to transform.

Returns:

A tuple of the transformed value and the metadata.

class bibtexparser.middlewares.NameParts(first: list[str] = <factory>, von: list[str] = <factory>, last: list[str] = <factory>, jr: list[str] = <factory>)[source]

A dataclass representing the parts of a person name.

The different parts are defined according to BibTex’s implementation of name parts (first, von, last, jr).

property merge_first_name_first: str

Merging the name parts into a single string, first-name-first (no comma) format.

property merge_last_name_first: str

Merging the name parts into a single string, last-name-first (with commas) format.

The structure of the output is: von Last, Jr, First

class bibtexparser.middlewares.NormalizeFieldKeys(allow_inplace_modification: bool = True)[source]

Normalize field keys to lowercase.

In case of conflicts (e.g. both ‘author’ and ‘Author’ exist in the same entry), a warning is emitted, and the last value wins.

Some other middlewares, such as SeparateCoAuthors, assume lowercase key names.

transform_entry(entry: Entry, library: Library) → Entry[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.RemoveEnclosingMiddleware(allow_inplace_modification: bool = True)[source]

Remove enclosing characters from values such as field and strings.

This middleware removes enclosing characters from a field value. It is useful when the field value is enclosed in braces or quotes (which is the case for the vast majority of values).

Only a delimiter pair enclosing the whole value is removed: pages = {intro} # {outro} merely starts and ends in braces, but these do not belong to the same pair and are thus kept.

Values that were not enclosed and are not plain integers (i.e., unresolved bibtex string references such as month = jan and concatenation expressions such as pages = intro # outro or pages = {intro} # {outro}) get a no-enclosing demand (see Field.enclosing), as enclosing them when writing would change their semantics.

Note: If you want to interpolate strings, you should do so before removing any enclosing.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

transform_entry(entry: Entry, library: Library) → Entry[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

transform_string(string: String, library: Library) → String[source]

Transform a string. Called by transform_block if the block is a string.

Note: This method modifies the passed string. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.ResolveStringReferencesMiddleware(allow_inplace_modification: bool = True)[source]

Replace strings references with their values.

transform(library: Library) → Library[source]

Transform a library.

Parameters:

library – Library to transform.

Returns:

Transformed library. If the library should not be modified, return a copy of the original library. The returned library has to be a new instance, except if self.allow_inplace_modification is True (in which case the library may also return the original library).

class bibtexparser.middlewares.SeparateCoAuthors(allow_inplace_modification: bool = True, name_fields: tuple[str, ...] = ('author', 'editor', 'translator'))[source]

Middleware to separate multi-person fields (e.g. co-authors, co-editors).

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

class bibtexparser.middlewares.SortBlocksByTypeAndKeyMiddleware(block_type_order: tuple[type[~bibtexparser.model.Block], ...] = (<class 'bibtexparser.model.String'>, <class 'bibtexparser.model.Preamble'>, <class 'bibtexparser.model.Entry'>, <class 'bibtexparser.model.ImplicitComment'>, <class 'bibtexparser.model.ExplicitComment'>), preserve_comments_on_top: bool = True)[source]

Sorts the blocks of a library by type and key. Optionally, comments remain above same block.

class bibtexparser.middlewares.SortBlocksMiddleware(key: Callable[[Block], Any], reverse: bool = False, preserve_comments_on_top: bool = True)[source]

Sorts the blocks of a library by a user-provided sort key.

This middleware works like Pythons built-in sorting (the key and reverse arguments behave as in sorted()): The key callable is applied to each block and the blocks are sorted by the returned values.

Example: To sort entries by their year field, with all non-entry blocks (strings, preambles, …) and year-less entries on top:

from bibtexparser.middlewares import SortBlocksMiddleware
from bibtexparser.model import Entry

def by_year(block):
    if isinstance(block, Entry) and "year" in block:
        return (1, int(block["year"]))
    return (0, 0)

middleware = SortBlocksMiddleware(key=by_year)

Hints regarding the key callable:

  • It must accept every block it may be called with (see below) and the returned values must be mutually comparable. Returning tuples - as in the example above - is a simple way to achieve this for libraries with mixed block types, and also allows hierarchical sorting criteria.

  • The sort is stable: blocks for which the key returns equal values remain in their original relative order.

  • The key should be pure (deterministic and without side-effects).

  • If you have a comparator function (compare(block_1, block_2) -> int) instead of a key function, wrap it with functools.cmp_to_key().

Comment handling: if preserve_comments_on_top is True (default), comments remain directly above the consecutive non-comment block and the key is only called with said non-comment block. (Exception: for comments at the very end of the library - not followed by any non-comment block - the key is called with the last comment.) If preserve_comments_on_top is False, comments are sorted like all other blocks, and the key must thus handle comment blocks, too.

transform(library: Library) → Library[source]

Transform a library.

Parameters:

library – Library to transform.

Returns:

Transformed library. If the library should not be modified, return a copy of the original library. The returned library has to be a new instance, except if self.allow_inplace_modification is True (in which case the library may also return the original library).

class bibtexparser.middlewares.SortFieldsAlphabeticallyMiddleware(allow_inplace_modification: bool = True)[source]

Sorts the fields of an entry alphabetically by key.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

transform_entry(entry: Entry, library: Library) → Block[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.SortFieldsCustomMiddleware(order: tuple[str, ...], case_sensitive: bool = False, allow_inplace_modification: bool = True)[source]

Sorts the fields of an entry according to a custom order provided by user.

The order is a list of field keys. Fields not in the list are put at the end.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

transform_entry(entry: Entry, library: Library) → Block[source]

Transform an entry. Called by transform_block if the block is an entry.

Note: This method modifies the passed entry. For a method respecting the allow_inplace_modification property, you should use transform or transform_block instead.

class bibtexparser.middlewares.SplitNameParts(allow_inplace_modification: bool = True, name_fields: tuple[str, ...] = ('author', 'editor', 'translator'))[source]

Middleware to split a persons name into its parts (first, von, last, jr).

Name fields (e.g. author, editor, translator) are expected to be lists of strings, which can be achieved by using the SeparateCoAuthors middleware before this one.

classmethod metadata_key() → str[source]

Identifier of the middleware. This key is used to identify the middleware in a blocks metadata.

bibtexparser.middlewares.default_parse_stack(allow_inplace_modification: bool = True) → list[Middleware][source]

The default parse stack to be applied after splitting, if not specified otherwise.

bibtexparser.middlewares.default_unparse_stack(allow_inplace_modification: bool = False) → list[Middleware][source]

The default unparse stack to be applied before writing, if not specified otherwise.

bibtexparser.BibtexFormat — Formatting options for writer

class bibtexparser.BibtexFormat[source]

Definition of formatting (alignment, …) when writing a BibTeX file.

Hint: For more manual, GUI-based formatting, see the bibtex-tidy tool:

https://flamingtempura.github.io/bibtex-tidy/

property block_separator: str

Character(s) for separating BibTeX entries.

Default: Two lines breaks, i.e., two blank lines.

property indent: str

Character(s) for indenting BibTeX field-value pairs. Default: single tab.

property parsing_failed_comment: str

Comment to use for blocks that could not be parsed.

property trailing_comma: bool

Use the trailing comma syntax for BibTeX entries. Default: False

BibTeX syntax allows an optional comma at the end of the last field in an entry.

property value_column: int | str

Controls the alignment of field- and string-values. Default: no alignment.

This impacts String and Entry blocks.

An integer value x specifies that spaces should be added before the “ = “, such that, if possible, the value starts x characters after the line prefix (the indent for entry fields, @string{ for string values). Entry and string values are thus each aligned among themselves. Note that for long keys, the value may be written at a later column.

Thus, a value of 0 means that the value is written directly after the “ = “.

The special value “auto” specifies that values should be aligned based on the longest key in the library (considering both entry field keys and string keys).