Skip to main content

Colin's LaTeX Tidy — somewhere between a clang and a splat

Project description

clat — Opinionated LaTeX Tidy

PyPI Python versions Docs License: MIT

Colin's LaTeX Tidy — somewhere between a clang and a splat.
📖 Documentation

A configurable LaTeX source formatter with opinions. Every rule has a weight; you set a threshold. A weight of 0 disables a rule. What happens otherwise depends on the combination:

  • clang -- weight >= threshold and fixable: auto-fixed
  • clunk -- weight >= threshold and not fixable: needs your attention
  • splat -- 0 < weight < threshold: advisory, take it or leave it
  • off -- weight <= 0: disabled

Why "clat"?

Prosaically, clat is Colin's LaTeX Tool. But the name also has a bit of printer's noise in it.

In the "Aeolus" episode of Ulysses -- "How a great daily organ is turned out" -- Bloom moves through the newspaper office amid the machinery of print: clanking, rhythmic, three-four time; thump, thump, thump. My great-great-grandfather, a Dublin printer, is mentioned there too, though some editions mangle Caprani as Cuprani.

So clat is meant to sound a little like that composing-room racket: a small, opinionated machine for turning untidy copy into clean type.

How clat compares

The usual LaTeX formatting tools — latexindent, tex-fmt, prettier-plugin-latex — are excellent at indentation and line wrapping. They normalise whitespace, align tables, and keep columns tidy.

clat operates at a different layer. It doesn't touch indentation. Instead, it applies content-aware style rules that those tools don't cover:

What you need Tool
Indentation, line wrapping, alignment latexindent, tex-fmt
Style conventions and writing hygiene clat

For example, clat can:

  • Merge stray \labels onto their \section lines
  • Split prose to one sentence per line
  • Replace {\bf text} with \textbf{text}
  • Configure inline and display math delimiter preferences separately
  • Ensure ~ before \ref, \cite, and similar commands
  • Replace ... with \dots
  • Normalise number-unit spacing (100\,kN)
  • Detect hardcoded references (Figure 3 instead of \cref{...})
  • Add trailing punctuation to display equations
  • Convert superscript ordinals (1\textsuperscript{st}1st)
  • And more

None of these are available in latexindent, tex-fmt, or prettier-plugin-latex. clat is complementary — you can (and should) run both. A typical pipeline:

tex-fmt main.tex    # indentation, line wrapping
clat main.tex       # style rules

The weight/threshold system (clang/clunk/splat/off) also gives you granular control over which rules auto-fix, which flag for manual review, which are just advisory noise, and which are disabled — something the existing tools don't offer.

Install

pip install clat-tidy

The command is clat. (The distribution is published as clat-tidy because clat was already taken on PyPI; everything you type is still clat.)

For local development:

pip install -e .

Requires Python >= 3.8. On Python < 3.11, tomli is installed automatically.

Quick start

# Format files in place
clat main.tex appendix.tex

# Format a multi-file document by following LaTeX inputs/includes
clat -r main.tex

# Dry run (report without fixing)
clat --check main.tex

# Dry run a multi-file document
clat --check -r main.tex

# List all rules
clat list

# Override threshold for one run
clat --threshold 3 main.tex

# Limit formatting to a single pass instead of fixed-point sweeps
clat --max-iter 1 main.tex

Rules

Run clat list to see all rules with their numbers, weights, and current category.

# Rule Default Fixable Description
1 labels_inline 8 yes Merge \label onto the same line as \section
2 decorative_comments 6 yes Strip decorative comment separators (%%=== etc.)
3 heading_spacing 7 yes Two blank lines before headings, none after
4 equation_separators 7 yes Insert % lines around display-math environments
5 equation_punctuation 6 yes Add trailing comma or period to display equations
6 float_indentation 5 yes Tab-indent content inside figure/table/list environments
7 one_sentence_per_line 8 yes Split sentences onto individual lines
8 math_delimiters_inline 5 yes Replace \(...\) with $...$
9 math_delimiters_display 0 yes Replace \[...\] with $$...$$
10 math_delimiters_equation 0 yes Replace \[...\] or $$...$$ with equation
11 tilde_before_refs 7 yes Ensure ~ before \ref, \cite etc.
12 number_unit_spacing 6 yes Normalise number-unit spacing (100\,kN)
13 old_font_commands 5 yes Replace {\bf text} with \textbf{text} etc.
14 ellipsis 4 yes Replace ... with \dots
15 ordinal_suffixes 8 yes Convert superscript ordinals to plain text (1st, 2nd)
16 long_file 3 no Warn if file exceeds 2000 lines
17 hardcoded_refs 6 no Detect Figure 3 instead of \cref{...}
18 manual_sizing 3 no Detect \big, \Big etc.
19 float_after_heading 4 no Detect float placed directly after a heading

Configuration

Config is read from .clat.toml in the project directory, falling back to ~/.config/clat/config.toml.

Create a config file

clat set --init

This generates .clat.toml with all rules and their default weights:

threshold = 5

[weights]
labels_inline         =  8  # Merge \label onto the same line as \section (fixable)
decorative_comments   =  6  # Strip decorative comment separators (fixable)
heading_spacing       =  7  # Two blank lines before headings, none after (fixable)
# ... all 19 rules listed

Edit the file directly, or use the CLI:

Set threshold

clat set --threshold 8

Set a rule weight

# Prefer rule ids for scripts/configuration
clat set ellipsis 9                  # set ellipsis to weight 9
clat set hardcoded_refs 2            # demote hardcoded refs to a splat
clat set math_delimiters_display 5   # enable display math delimiter conversion
clat set math_delimiters_equation 5  # convert display delimiters to equation

# List numbers are also accepted for interactive use
clat set 14 9

Reset to defaults

clat set --reset

One-shot overrides

Override threshold for a single run without modifying the config:

clat --threshold 3 main.tex

CLI reference

clat <files...>              Format .tex files in place
clat -r <root.tex...>        Recursively format LaTeX inputs/includes
clat --recursive <root.tex>  Long form of -r
clat --check <files...>      Dry run: report issues without fixing
clat --check -r <root.tex>   Dry run a multi-file document
clat -o out.tex in.tex       Write to a different file
clat --threshold N <files>   Override threshold for this run
clat --max-iter N <files>    Maximum fixable-rule sweeps (default 5)

clat list                    List all rules with weights and categories
clat list --config path      Use a specific config file

clat set <rule-id|rule#> <weight>
                                Set a rule weight in .clat.toml (0 disables)
clat set --threshold N       Set the threshold in .clat.toml
clat set --init              Create .clat.toml with defaults
clat set --reset             Restore .clat.toml to defaults
clat set --config path       Target a specific config file

clat --version               Show version

Multi-file documents

Use -r or --recursive when a root .tex file assembles a document from other source files:

clat -r main.tex

Recursive mode follows \input, \include, \subfile, \import, \subimport, \includefrom, and \subincludefrom commands. Paths are resolved relative to the file containing the command, .tex is appended when no extension is given, duplicate files are skipped, and missing .tex inputs are reported through the normal formatter output.

How it works

Each rule is either fixable (clat can rewrite the source) or unfixable (clat can only detect the issue). clat applies enabled fixable rules repeatedly until a full sweep makes no text changes, up to --max-iter sweeps (default 5). Then detect-only rules run once on the final text. At runtime, each rule's weight is compared to the threshold:

weight >= threshold + fixable     =>  clang (auto-fixed)
weight >= threshold + NOT fixable =>  clunk (needs manual fix)
0 < weight < threshold            =>  splat (advisory)
weight <= 0                       =>  off (disabled)

Fixable rules below threshold are still applied (the text is still fixed), but reported as splats rather than clangs. Set a rule's weight to 0 to disable it entirely. Use --max-iter 1 for single-pass behaviour.

Development

pip install -e .
python -m pytest tests/ -v

License

MIT

Project details


Download files

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

Source Distribution

clat_tidy-0.5.0.tar.gz (30.8 kB view details)

Uploaded Source

Built Distribution

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

clat_tidy-0.5.0-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

Details for the file clat_tidy-0.5.0.tar.gz.

File metadata

  • Download URL: clat_tidy-0.5.0.tar.gz
  • Upload date:
  • Size: 30.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clat_tidy-0.5.0.tar.gz
Algorithm Hash digest
SHA256 f3860fef2ea10b068717b5e70ceab056dd7373db2e1a38bd1ab0bc9cf785a362
MD5 6f1b1c844f4bbf6fd3e5496c22b08073
BLAKE2b-256 67268418e657becefd7cabb1ea3675c613b6ddb49f66d4d0b770f14e5de7a0eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for clat_tidy-0.5.0.tar.gz:

Publisher: publish.yml on ccaprani/clat

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

File details

Details for the file clat_tidy-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: clat_tidy-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 22.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clat_tidy-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3122e129a0649f8a7b86dd566754d9a18a1067befb8906c29e66c3eb02adad25
MD5 34f6d3d16811bb1e14fbbc6638ff8e29
BLAKE2b-256 579744dcbe2e4773ec35691d6687525c35d5a373c15cdfc9ab21afb0a8efbb90

See more details on using hashes here.

Provenance

The following attestation bundles were made for clat_tidy-0.5.0-py3-none-any.whl:

Publisher: publish.yml on ccaprani/clat

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 Pingdom Monitoring Sentry Error logging StatusPage Status page