Skip to main content

python-bibtex-linter

A Python tool to parse BibTeX entries and run (custom) checks on them.

> bibtex_linter refs.bib

Entry 'SomeBook' of type 'BOOK' failed verification:
  ❌ Misses the following required fields: [publisher]
  ❌ Has fields present that would be omitted in the compiled document: [url]. This could lead to a loss of information.
    
Found 2 invariant violations in 17 entries.

Motivation

I've always assumed that I just needed to take care that my references.bib file was in order, that as many of the fields of the entries in there were filled, and then I could easily use them to create standard-conforming citations in my LaTeX documents. As it turns out, a lot of different citation styles omit various fields, and it's an overall mess. Therefore, I created this tool (in Python, since that's what I know best), that can parse the entries and then performs arbitrary (self-defined) invariant checks on them.

In my field the most used citation style is ieeetr so this is how I've defined the default rules of the script. I've written down the observations on which the rules are based here. These should not be confused with the LaTeX built-in IEEEtran citation style, for which I also developed rules.

It is however relatively easy to define your own custom ruleset, should the need arise.

How to use:

First we need to install the tool, I recommend to use pipx for that:

pipx install bibtex_linter

You can find the package on PyPI here.

Basic Usage

Then you can call the script the following way:

bibtex_linter path/to/refs.bib

The script will parse the file, perform the checks and print out the results.

Defined Rulesets

Currently, the following rulesets are shipped with the bibtex_linter:

  • bibtex_linter path/to/refs.bib ieeetr (default): Citation style of some IEEE conferences (needs IEEEtran.cls).
  • bibtex_linter path/to/refs.bib IEEEtran: LaTeX built-in IEEE citation style (via \bibliographystyle{IEEEtran}). Check out this cheatsheet for documentation of the rules.

If you want to define your own rules, see the next section on how to do this:

Advanced: Custom Rulesets

It is also possible to define your own rules inside a Python file.

Let's call our custom rule file my_own_rules.py. Creating your own rule is as simple as:

from typing import List

from bibtex_linter.parser import BibTeXEntry
from bibtex_linter.verification import linter_rule


@linter_rule(entry_type="article")
def check_article(entry: BibTeXEntry) -> List[str]:
    """
    Check that a `BibTeXEntry` has a nonempty `author` field.

    :param entry: The BibTeXEntry
    :return: A list of string descriptions of rule violations for this entry.
    """
    if not entry.fields.get("author"):
        return ["Misses the required field [author]."]
    return []

As you can see, we created a method and designated that it is a linter rule by using the @linter_rule decorator. The method needs to have a specific interface: It needs to take the BibTeXEntry to be checked as input argument, and it needs to return a List of strings explaining the rule violations for that BibTeXEntry. If there are no rule violations, it should return an empty list.

This rule only gets executed for entries of the article type, as specified by the decorator argument. If we left the entry_type argument empty, this check would be executed on all entries. Read section Entry Type for some notes on how the entry_type is parsed to string.

For more inspiration on what you could define as your custom rules, have a look into bibtex_linter/default_rules.py. After defining the rules in my_own_rules.py, we can execute them on a BibTeX file like this:

bibtex_linter path/to/refs.bib path/to/my_own_rules.py

Let's reiterate the warning from beforehand:

Definition of used Terms

If you're unfamiliar with BibTex, here's a short list of terms, so that you can better understand the output of the bibtex_linter.

Entry

An entry to the BibTeX file:

@article{basic_case,
  author = {Test author},
  title = {Standard field format},
  year = {2020}
}

Field

A field inside an entry, consists of a key and a value:

author = {Test author},

In this case, "author" would be the key and "Test author" the value.

Entry Type

The entry type specifies the available fields and is written behind the @ and in front of the first { of an entry:

@article{...}
@conference{...}
@online{...}

Metadata

Release files for bibtex-linter 2.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bibtex-linter 2.3.1
File Size Uploaded
bibtex_linter-2.3.1.tar.gz 28.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bibtex-linter 2.3.1
File Interpreter ABI Platform
bibtex_linter-2.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 42.4 kB

Release files / bibtex_linter-2.3.1.tar.gz

Download URL bibtex_linter-2.3.1.tar.gz
Size 28.0 kB
Tags Source
SHA-256 checksum
How to use checksums
2c2fc899b9a1f6f2777e58686ea914b33fb4a9fb0ad00e62d2b198916fa4175a
BLAKE2b-256 checksum
How to use checksums
929f359f844b40e876d8168cfb42d2510bdeb5dfd60ef69751d74267a4abdb64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / bibtex_linter-2.3.1-py3-none-any.whl

Download URL bibtex_linter-2.3.1-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
860f9900a5da092db37ef17ae8a1cdc8f2d94887630a2b9e2bf12dc60c5c671e
BLAKE2b-256 checksum
How to use checksums
8f5d29c5a0b028d29f4720733aa51082b23336a267e5fef6031ed20f6627d38c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.3.1 This release

2 release files

2.3.0

2 release files

2.2.1

2 release files

2.1

2 release files

2.0

2 release files

1.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page