Skip to main content

Badness

Build and Test Documentation Open VSX VS Code

Badness is a language server, formatter, and linter for LaTeX, built on a lossless concrete syntax tree.

It parses LaTeX once and serves three tools from that tree:

  • Formatter (badness format): deterministic, rule-based layout.
  • Linter (badness lint): diagnostics with source snippets.
  • Language server (badness lsp): both, live in your editor.

The architecture follows rust-analyzer: a generic, error-tolerant, hand-written parser produces a lossless tree, semantics are layered on top as a separate concern, and recomputation is incremental. badness never requires resolving macros or catcodes to succeed—anything it cannot statically recognize degrades to generic nodes rather than a crash. Two properties hold by construction and are enforced as tests: losslessness (the tree reconstructs the input byte-for-byte) and idempotence (formatting an already formatted file changes nothing).

Installation

Badness is available from several sources:

  • crates.io: cargo install badness
  • npm: npm install -g badness (bundles a prebuilt binary)
  • PyPI: uv tool install badness/pipx install badness
  • Prebuilt binaries: from the releases page
  • VS Code/Open VSX: the Badness extension (also works in Positron and Cursor)
  • From source: cargo install --path . in a checkout

The VS Code/Open VSX extension bundles the badness binary and starts the language server automatically when you open a .tex file.

Usage

# Format a file in place (or stdin → stdout with no path)
badness format paper.tex

# Verify formatting without writing—exits non-zero if anything would change
badness format --check paper.tex

# Lint, reporting parse diagnostics
badness lint paper.tex

# Run the language server over stdio
badness lsp

Formatting is configurable via a TOML file named badness.toml. See the documentation for the full reference.

The language server runs over stdio (badness lsp); see the editor setup guide for Neovim and VS Code wiring.

Pre-commit hook

badness-pre-commit provides pre-commit hooks for linting and formatting. It installs a prebuilt binary wheel from PyPI, so no Rust toolchain or LaTeX distribution is required:

repos:
  - repo: https://github.com/jolars/badness-pre-commit
    # badness version
    rev: v0.11.0
    hooks:
      # Lint .tex, .sty, .cls, .dtx, .ins, and .bib files
      - id: badness-lint
      # Format the same files in place
      - id: badness-format

GitHub Actions

badness-action installs badness and runs format and lint checks in CI:

jobs:
  badness:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: jolars/badness-action@v1

Documentation

Full documentation lives at https://badness.dev/ (built with mdBook from docs/).

Contributing

See CONTRIBUTING.md.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

badness-0.13.0.tar.gz (1.7 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

badness-0.13.0-py3-none-win_arm64.whl (3.1 MB view details)

Uploaded Python 3Windows ARM64

badness-0.13.0-py3-none-win_amd64.whl (3.2 MB view details)

Uploaded Python 3Windows x86-64

badness-0.13.0-py3-none-musllinux_1_2_x86_64.whl (3.5 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

badness-0.13.0-py3-none-musllinux_1_2_aarch64.whl (3.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

badness-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

badness-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

badness-0.13.0-py3-none-macosx_11_0_arm64.whl (3.1 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

badness-0.13.0-py3-none-macosx_10_12_x86_64.whl (3.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file badness-0.13.0.tar.gz.

File metadata

  • Download URL: badness-0.13.0.tar.gz
  • Upload date:
  • Size: 1.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for badness-0.13.0.tar.gz
Algorithm Hash digest
SHA256 194d0e77baa85384862102c5d661ac38688b193602c82542d62fe57a42ef25ae
MD5 0795904928407f2cb2478f774ea94d7d
BLAKE2b-256 fe7071f3cf18be3fd5c176d0cf7ebbde34427b40c0dec8712a3035c2e3657eb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0.tar.gz:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: badness-0.13.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for badness-0.13.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 c774e4316deca6b494896ac9303b2506cdabc57f2b2fdc7763fd7bfc7609b87b
MD5 aaf3dc770289df93c19eedb230153e9c
BLAKE2b-256 5e519b712fc161f8606f0fd791bdc5051c09eee7f09663cc7a97f82c6e0a121d

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-win_arm64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: badness-0.13.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for badness-0.13.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 795730c6501d64e1a31ee8437a6b238f5738fc9bf83ebff1bfe92a46dad7797c
MD5 996b610dbe626230ccfe78c616a1e0a6
BLAKE2b-256 444b6fb9c9ffa1c659f54185f6f07b29451d16a7b6a43ab9808a13cacee03581

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-win_amd64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b9eb979b03af737b42669bd141947cda25219cf0c31e50bb997825ac6ace5dec
MD5 e04f971e4e4f9c8eb4c364bc919d272b
BLAKE2b-256 2f038e9422a4b81a5f22b50cc51d3ffda71f03862423306dec7cc69b2e9926bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 79cf4d577af47bc6a2d0ca6d88207087c77591862013a57cbdde412f6375fc10
MD5 8484c69593310623e8d7b72fbd58e54a
BLAKE2b-256 44bab697b63e464383f2b3ad83d496a200c9b1afce27394b72c7128cae235d21

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1ce712360a582d04eeffbacb52a42f3298fc962c70dea08687e11ecd2f6467f1
MD5 6e9b5769a0c3a151f482cf422762d6aa
BLAKE2b-256 2c8dbab8a06ebd1b8e5dd1a243d1aae5af94c9a81f5d25f2749e4c48a0fa9229

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 08d32eb6cd060075950ea61d1926174b78ad3a5eb4fc044f621326e360cf8360
MD5 4abca0f9098c9b82ab658fb10f0fc6dc
BLAKE2b-256 03f83a08c91a306e6f26020dc02a3e7591e1f97347b91959b736345612b16834

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d8b4245c8abd6179de31a821ed1193d0e9c0dd88bf45e2f33239e78a4289d446
MD5 e86b1142486ceb200bd02916ae68c303
BLAKE2b-256 883909f9ffd797b3b33c4c852c9d2971bcaee9b2767db7cca7c5d79149683601

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file badness-0.13.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for badness-0.13.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bf98358900367c86432434228cd466c1410f595fd226e3b869d15422f80056b2
MD5 227abc61fcac177d012ac4af95cb5b7c
BLAKE2b-256 829929caa43d42cbd5af3cc4e758191874f9268c2c1ebc4aad292330f1ad8546

See more details on using hashes here.

Provenance

The following attestation bundles were made for badness-0.13.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: publish-pypi.yml on jolars/badness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page