Skip to content

An extremely fast LaTeX formatter written in Rust

License

Notifications You must be signed in to change notification settings

WGUNDERWOOD/tex-fmt

Repository files navigation

tex-fmt tex-fmt

CI crates.io Packaging status license: MIT

An extremely fast LaTeX formatter written in Rust.

Input Output
\documentclass{article}

\begin{document}

\begin{itemize}
\item Lists with items
over multiple lines
\end{itemize}

\begin{equation}
E = m c^2
\end{equation}

\end{document}
\documentclass{article}

\begin{document}

\begin{itemize}
  \item Lists with items
    over multiple lines
\end{itemize}

\begin{equation}
  E = m c^2
\end{equation}

\end{document}
  • ⚡  Extremely fast run-time performance
  • 🔧  Minimal configuration required
  • 📟  Command-line interface
  • 📜  Handles LaTeX file types .tex, .bib, .cls, and .sty
  • 🦀  Written entirely in safe Rust

Installation

Cargo

Install the stable release with

cargo install tex-fmt

Install from GitHub with

cargo install --git "https://github.com/wgunderwood/tex-fmt"

Nix

Install from nixpkgs into a temporary shell with

nix-shell -p tex-fmt

Build from source using flakes with

nix build "github:wgunderwood/tex-fmt"

Add to your NixOS installation with

environment.systemPackages = [
  pkgs.tex-fmt
];

Arch Linux

Install from the Arch User Repository. For example, using the yay AUR helper:

yay -S tex-fmt

Homebrew

Install using Homebrew with

brew install tex-fmt

Binary download

Binaries for various platforms are available on the GitHub releases page.

Visual Studio Code

Integration with VS Code is provided by the LaTeX Workshop extension. You will need to first install tex-fmt through one of the above methods.

Usage

The most commonly used options are given below. For a full list, see the options section below.

tex-fmt file.tex             # format file.tex and overwrite
tex-fmt --check file.tex     # check if file.tex is correctly formatted
tex-fmt --print file.tex     # format file.tex and print to stdout
tex-fmt --nowrap file.tex    # do not wrap long lines
tex-fmt --stdin              # read from stdin and print to stdout
tex-fmt --help               # view help information

Configuration

Options can also be read from a configuration file, which will be read from the following locations, in order of decreasing priority.

  • A named config file passed as tex-fmt --config <config>
  • A file named tex-fmt.toml in the current working directory
  • A file named tex-fmt.toml in the root directory of the current git repository
  • A file named tex-fmt.toml in a subdirectory titled tex-fmt/ in the user's configuration directory
    • Linux: ~/.config/tex-fmt/tex-fmt.toml
    • macOS: /Users/<user>/Library/Application Support/tex-fmt/tex-fmt.toml
    • Windows: C:\Users\<user>\AppData\Roaming\tex-fmt\tex-fmt.toml

Arguments passed on the command line will always override those specified in configuration files. An example configuration file is available at tex-fmt.toml. To ignore all config files, use the --noconfig flag.

Note for contributors: this repository's configuration file will be automatically applied if tex-fmt is run from within the repository. Use --noconfig or --config <config> to avoid this.

Disabling the formatter

Ending a source line with % tex-fmt: skip disables formatting for that line. To disable the formatter for a block, use % tex-fmt: off and % tex-fmt: on.

\documentclass{article}

\begin{document}

    This line is skipped % tex-fmt: skip

% tex-fmt: off
  These lines are also
    not formatted or wrapped
% tex-fmt: on

\end{document}

Verbatim environments including verbatim, Verbatim, lstlisting and minted are automatically skipped.

Shell completion

Shell completion scripts can be generated at run-time using the --completion <shell> flag. See the completion directory for more details.

Man page

A man page can be generated at run-time using the --man flag. See the man directory for more details.

Performance

When formatting all of the test cases, tex-fmt is over a thousand times faster than latexindent.

Files Lines Size tex-fmt latexindent latexindent -m
51 94k 3.5M 0.055s 106s [x1927] 127s [x2309]

Contribution

Please feel free to open an issue or submit a pull request, including as much information as you can. Documentation of internals can be accessed by cloning this repository and running cargo doc.

Alternatively, you can Buy Me a Coffee!

Limitations

  • Semantic parsing of LaTeX code not conducted
  • No linting or correction of syntax errors
  • Compliance with existing formatting guidelines not guaranteed
  • No spelling or grammar checking

Existing tools

  • latexindent. Perl script, many configuration options, slow on large files

  • LaTeXTidy. Perl script, download links seem to be broken

  • latex-pretty. Browser-based, uses latexindent as the backend

  • latexformat.com. Browser-based

  • texpretty. C program which works sometimes and appears to be fast

  • latex-editor. Browser-based

  • LaTeXFmt. Vim plugin, does not apply indentation

  • latex-formatter. Visual Studio plugin, uses latexindent as the backend

  • LLF. Lua script, many configuration options

Options

The following command-line options are offered by tex-fmt.

Option Alias Default Description
--check -c Check formatting, do not modify files
--print -p Print to stdout, do not modify files
--nowrap -n Do not wrap long lines
--wraplen -l 80 Line length for wrapping
--tabsize -t 2 Number of characters to use as tab size
--usetabs Use tabs instead of spaces for indentation
--stdin -s Process stdin as a single file, output to stdout
--config Path to config file
--noconfig Do not read any config file
--verbose -v Show info messages
--quiet -q Hide warning messages
--trace Show trace messages
--completion Generate a shell completion script
--man Generate a man page
--args View arguments passed to tex-fmt
--help -h Print help
--version -V Print version