What tex-fmt changes
PasteKit formats LaTeX with tex-fmt (WASM), a fast formatter written in Rust and compiled to WebAssembly. Unlike latexindent, it needs no Perl installation and no configuration file, and it is quick enough to run on every keystroke of a long thesis chapter.
The changes are deliberately limited to layout:
- the contents of each
\begin{...}/\end{...}pair are indented one level, so nesting becomes visible (thedocumentenvironment is the exception: its body stays at the margin) \itemlines initemize,enumerateanddescriptionsit one level in, with continuation lines indented further- groups opened with
{,[or(across several lines indent their contents - trailing spaces are removed and runs of blank lines are reduced
- long lines of prose are wrapped at the line width
Commands, math and text are never rewritten. Verbatim-like environments such as verbatim and lstlisting are left exactly as they are, because whitespace inside them is significant.
Settings and shortcuts
LaTeX has no options of its own here. The toolbar’s indent controls tex-fmt’s tabsize (two spaces by default, which is also tex-fmt’s default) and can switch to tabs. The line-width control sets the wrap length: lines of prose longer than that are broken at a space. If you prefer one sentence per line, or your editor soft-wraps, increase the width so that paragraphs are not reflowed; very small values are raised to a minimum of 20 columns.
Press Ctrl/Cmd+Enter to format, Ctrl/Cmd+Shift+C to copy the formatted source and Ctrl/Cmd+K to open the command palette. Ctrl/Cmd+Shift+M (minify) is not available for LaTeX.
Structure warnings and edge cases
tex-fmt does not compile your document, but it does track nesting. When the indentation would go negative — an \end{itemize} with no matching \begin — or does not return to zero at the end, PasteKit shows a warning with the line number. These are warnings rather than errors: the output is still produced, so you can see where the indentation drifts and fix the environment that is not closed.
A few constructs deserve care. Custom environments defined with \newenvironment are indented like built-in ones. Lines you need to keep as they are can be protected with a % tex-fmt: skip comment, and whole regions with % tex-fmt: off and % tex-fmt: on. Comments are preserved, including % at the end of a line that suppresses a space, so wrapping will not introduce stray spaces before it.
For tables written in LaTeX source, column alignment of & separators is not performed; if you are converting data into a table, generating it from CSV is usually quicker than aligning it by hand.
Examples
Table with booktabs
The tabular nests inside the table float, so its rows end up two levels deep.
\begin{table}[h]
\centering
\begin{tabular}{lrr}
\toprule
Format & Pages & Share \\
\midrule
JSON & 120 & 41\% \\
YAML & 64 & 22\% \\
\bottomrule
\end{tabular}
\caption{Traffic by format}
\end{table}\begin{table}[h]
\centering
\begin{tabular}{lrr}
\toprule
Format & Pages & Share \\
\midrule
JSON & 120 & 41\% \\
YAML & 64 & 22\% \\
\bottomrule
\end{tabular}
\caption{Traffic by format}
\end{table}
Proof with align and a list
Math lines are indented but otherwise untouched; the alignment markers stay where you put them.
\begin{proof}
\begin{align}
f(x) &= x^2 + 2x + 1 \\
&= (x+1)^2
\end{align}
\begin{itemize}
\item The square is non-negative.
\end{itemize}
\end{proof}\begin{proof}
\begin{align}
f(x) &= x^2 + 2x + 1 \\
&= (x+1)^2
\end{align}
\begin{itemize}
\item The square is non-negative.
\end{itemize}
\end{proof}
Beamer frame with 4-space indent
Four levels of nesting become obvious with a wider indent.
\begin{frame}{Results}
\begin{columns}
\begin{column}{0.5\textwidth}
\begin{itemize}
\item Faster builds
\item Fewer merge conflicts
\end{itemize}
\end{column}
\end{columns}
\end{frame}\begin{frame}{Results}
\begin{columns}
\begin{column}{0.5\textwidth}
\begin{itemize}
\item Faster builds
\item Fewer merge conflicts
\end{itemize}
\end{column}
\end{columns}
\end{frame}
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
Unmatched closing command \end{itemize} — there is no matching \begin | An \end{...} appears without an open environment of that name, often because the \begin was deleted or misspelled. | Restore the \begin{itemize} or remove the extra \end. The warning gives the line of the stray command. |
An environment or group is not closed — check for a missing \end{…} or } | Indentation did not return to zero at the end of the input: an environment or a brace group is still open. | Look at where the indentation of the output stops returning to the margin; the unclosed environment starts just above it. |
Paragraphs were rewrapped | Lines longer than the line width are wrapped. That is intended, but unwelcome if you keep one sentence per line. | Increase the line width, or protect the region with % tex-fmt: off and % tex-fmt: on. |
Frequently asked questions
Is this the same as latexindent?
No. It uses tex-fmt, a newer Rust formatter with similar goals and far fewer settings. The results are close for typical documents but not identical.
Will it break my document?
It only changes whitespace and line breaks outside verbatim environments. Comments that end a line with % are respected, so no spaces are introduced.
Can it format BibTeX files?
Yes, .bib files can be pasted too. Entries are indented consistently, although fields are not sorted or aligned.
Why do I see warnings but still get output?
Unbalanced environments are reported as warnings so you can use the indented output to locate them. Fix the reported line and format again.