<!-- Generated by `cargo run --example docgen`. Do not edit by hand: edit each rule's `description()`/`examples()` in `src/bib/linter/rules/` and regenerate. -->

# BibTeX Linter Rules

`badness lint` runs a parallel set of built-in rules over each `.bib` file's
parse tree and reports a diagnostic for every finding. Each section describes
one rule, identified by its stable **rule id**. BibTeX rules share an id
namespace with the [LaTeX rules](linter-rules.md), so the same `[lint]` settings
and `--select` and `--ignore` flags select both sets.

Most rules are **on by default**. Each rule's section states whether it is
enabled by default. Use `select` to enable an opt-in rule, or use `select` and
`ignore` in the `[lint]` table to narrow the default set. See the
[Configuration reference](configuration.md#lint).

Some rules offer an **autofix** when a rewrite is unambiguous.
`badness lint --fix` applies *safe* fixes, shown below under "After applying the
fix".

Each example below is linted live to produce its diagnostic and fixed output, so
this page never drifts from the rules' actual behavior.

## `duplicate-key`

Flag a citation key defined by more than one entry in the same `.bib` file. Keys are compared case-insensitively, matching BibTeX, which silently keeps only one of the colliding entries. Every definition after the first is flagged. No autofix is offered because the author must choose whether to rename or delete an entry.

This rule is **enabled by default**.

The same cite key defined by two entries:

```bib
@misc{knuth84, title = {Draft}}
@book{knuth84, title = {Book}}
```

```text
warning: duplicate-key
 --> references.bib:2:7
  |
2 | @book{knuth84, title = {Book}}
  |       ^^^^^^^ cite key `knuth84` is defined more than once
```

## `deprecated-suppression-syntax`

Flag the retired `@comment{badness-ignore <rule>}` and `@comment{badness-ignore-file [<rule>]}` suppression spellings, which remain accepted for compatibility but are no longer documented. The Safe autofix rewrites only the family and verb to `badness-lint skip` or `badness-lint skip-file`; the selector, reason, delimiters, and remaining entry text stay byte-for-byte unchanged. This meta diagnostic is not silenced by the retired directive it reports; use `[lint].ignore` to disable the rule deliberately.

This rule is **enabled by default**.

A retired suppression directive in a structured comment:

```bib
@comment{badness-ignore unused-string: intentional}
@string{x = {X}}
```

```text
warning: deprecated-suppression-syntax
 --> references.bib:1:10
  |
1 | @comment{badness-ignore unused-string: intentional}
  |          ^^^^^^^^^^^^^^ retired suppression syntax; use `@comment{badness-lint skip …}` instead
```

After applying the fix:

```bib
@comment{badness-lint skip unused-string: intentional}
@string{x = {X}}
```

## `inert-suppression`

Flag a structured BibTeX suppression directive that cannot take effect: `skip` with no following entry, `on` with no matching `off`, or any `badness-format` directive, because the BibTeX formatter does not support format suppression. Also flag an `off` region left open at EOF; it currently suppresses through the end of the file, but the missing closer is usually accidental. Report-only: repairing the directive requires knowing the entry, boundary, or formatting policy the author intended. Inline suppressions cannot hide this meta diagnostic; use `[lint].ignore` to disable the rule deliberately.

This rule is **enabled by default**.

BibTeX recognizes the directive grammar, but its formatter has no suppression mechanism:

```bib
@comment{badness-format skip-file: preserve this file}
@book{key}
```

```text
warning: inert-suppression
 --> references.bib:1:1
  |
1 | @comment{badness-format skip-file: preserve this file}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the BibTeX formatter does not support format suppression, so this directive does nothing
```

## `missing-required-field`

Flag an entry lacking a field its type requires under the biblatex data model. An alternative such as `date` *or* `year` is satisfied by either field, and classic BibTeX aliases count (`journal` satisfies `journaltitle`). Entry types unknown to the built-in database have no signature and are not flagged. No autofix is offered because the rule cannot supply the missing content.

This rule is **enabled by default**.

An `@article` without its required `journaltitle`:

```bib
@article{doe2020,
  author = {Doe, Jane},
  title  = {A study},
  year   = 2020
}
```

```text
warning: missing-required-field
 --> references.bib:1:10
  |
1 | @article{doe2020,
  |          ^^^^^^^ entry `article` is missing required field `journaltitle`
```

## `unknown-field`

Flag a field that is neither required nor optional for its entry type and has no global field metadata. Such a field is usually a typo or data intended for another entry type. BibLaTeX silently ignores unknown fields, so the mistake can otherwise go unnoticed. The rule checks only entry types known to the built-in database. No autofix is offered because deleting the field would discard data.

This rule is **enabled by default**.

A misspelled field name (`pubisher` for `publisher`):

```bib
@book{turing50,
  author   = {Turing, Alan},
  title    = {A book},
  pubisher = {Elsevier},
  year     = 1950
}
```

```text
warning: unknown-field
 --> references.bib:4:3
  |
4 |   pubisher = {Elsevier},
  |   ^^^^^^^^ unknown field `pubisher` on `book` entry
```

## `empty-field`

Flag a field whose value is empty or whitespace-only (`title = {}`, `note = ""`). An empty field carries no data, and some styles still emit punctuation around it. The safe autofix deletes the field along with its separating comma.

This rule is **enabled by default**.

An empty `note` left behind by an edit:

```bib
@misc{knuth84,
  title = {Draft},
  note  = {}
}
```

```text
warning: empty-field
 --> references.bib:3:3
  |
3 |   note  = {}
  |   ^^^^^^^^^^ field `note` is empty
```

After applying the fix:

```bib
@misc{knuth84,
  title = {Draft}
}
```

## `duplicate-field`

Flag a field name appearing more than once in an entry, comparing names case-insensitively. BibTeX and Biber keep only one occurrence and silently discard the rest. A duplicate is therefore almost always a merge or copy-paste mistake, and every occurrence after the first is flagged.

When a repeated value is byte-identical to the retained value, a safe autofix deletes the redundant copy. When values differ, the retained value depends on the engine, so the rule reports the finding without a fix.

This rule is **enabled by default**.

Two `note` fields with identical values, so deleting the redundant copy is safe:

```bib
@misc{knuth84,
  note = {Draft},
  note = {Draft}
}
```

```text
warning: duplicate-field
 --> references.bib:3:3
  |
3 |   note = {Draft}
  |   ^^^^ duplicate field `note` on `misc` entry
```

After applying the fix:

```bib
@misc{knuth84,
  note = {Draft}
}
```

Differing values are report-only (which copy the engine keeps is style-dependent, so dropping either would change meaning):

```bib
@misc{knuth84,
  note = {First draft},
  note = {Second draft}
}
```

```text
warning: duplicate-field
 --> references.bib:3:3
  |
3 |   note = {Second draft}
  |   ^^^^ duplicate field `note` on `misc` entry
```

## `unused-string`

Flag an `@string` macro defined in the file but never referenced by a field value. In a self-contained `.bib` file, an unused macro serves no purpose. In a multi-file bibliography, another `.bib` file may reference it, and cross-file `@string` resolution is not yet modeled. No autofix is offered because deleting a definition is a choice for the author.

This rule is **enabled by default**.

A defined macro no field value references:

```bib
@string{cup = {Cambridge University Press}}
@book{turing50, title = {Draft}, publisher = {Springer}}
```

```text
warning: unused-string
 --> references.bib:1:9
  |
1 | @string{cup = {Cambridge University Press}}
  |         ^^^ `@string` macro `cup` is defined but never used
```

## `undefined-string`

Flag an `@string` macro used in a field value but defined nowhere in the file. The twelve month macros from `jan` through `dec` are predefined. An undefined macro usually means a misspelled name or a missing `@string` definition, and BibTeX reports an error at build time.

In a multi-file bibliography, another `.bib` file may supply the definition. Cross-file `@string` resolution is not yet modeled, so those uses produce false positives. No autofix is offered because the author must choose whether to define the macro or correct its name.

This rule is **enabled by default**.

A misspelled macro name (`cpu` for `cup`):

```bib
@string{cup = {Cambridge University Press}}
@book{turing50, title = {Draft}, publisher = cpu}
```

```text
warning: undefined-string
 --> references.bib:2:46
  |
2 | @book{turing50, title = {Draft}, publisher = cpu}
  |                                              ^^^ `@string` macro `cpu` is used but never defined
```

## `title-capitalization`

Flag an unprotected acronym or mid-word capital in a title-like field (`title`, `booktitle`, `journaltitle`, ...). Many bibliography styles lowercase unprotected title text, so `DNA` renders as `dna` unless written as `{DNA}`.

The rule flags runs of two or more capitals and camelCase brand names whose first capital occurs within a word that begins with a lowercase letter, such as `iPhone`. It leaves ordinary Title Case, name particles (`McDonald`), mixed-case tokens (`LaTeX`), and text already inside a `{...}` group alone. No autofix is offered because the author must choose what to protect.

This rule is **enabled by default**.

An unprotected acronym a title-lowercasing style would render as `dna`:

```bib
@article{watson53, title = {Molecular structure of DNA}}
```

```text
warning: title-capitalization
 --> references.bib:1:52
  |
1 | @article{watson53, title = {Molecular structure of DNA}}
  |                                                    ^^^ unprotected capitals `DNA` in `title`; wrap in braces (`{DNA}`) to keep case under title-lowercasing styles
```

## `encoding-hints`

Report non-ASCII text in field values as hints when checking compatibility with legacy BibTeX toolchains, which may mishandle UTF-8 during sorting, case conversion, or name abbreviation. Unicode-aware consumers, including Biber and website bibliography processors, can accept UTF-8 directly. pdfLaTeX has defaulted to UTF-8 input since April 2018, although supported characters still depend on LaTeX definitions and fonts. This rule does not infer the consumer or detect an actual encoding incompatibility. Enable it with `extend-select = ["encoding-hints"]` under `[lint]` for a compatibility audit. No autofix is offered because the right change depends on the project's toolchain.

This rule is **disabled by default**; enable it with `select`.

An accented name entered as raw UTF-8:

```bib
@article{erdos47, author = {Erdős, Paul}}
```

```text
help: encoding-hints
 --> references.bib:1:32
  |
1 | @article{erdos47, author = {Erdős, Paul}}
  |                                ^ non-ASCII text `ő`; legacy BibTeX toolchains may mishandle UTF-8; check compatibility or use a LaTeX escape
```

## Suppression

BibTeX has no line-comment token, so write suppression directives inside
structured `@comment` entries. A `skip` directive suppresses one rule on the
**next entry**:

```bib
@comment{badness-lint skip missing-required-field: publisher long gone}
@book{oldbook, title = {An Orphaned Book}}
```

The directive grammar is the same as in LaTeX. `off` and `on` delimit a
region of entries, and `skip-file` covers the whole file wherever the directive
appears:

```bib
@comment{badness-lint off missing-required-field: imported, incomplete by design}
@book{oldbook, title = {An Orphaned Book}}
@comment{badness-lint on missing-required-field}
```

The `<id>` is optional. Omitting it suppresses every rule over the same span.
Parse diagnostics (rule id `parse`) are never suppressed.
