Self-hosted service
cmhughes/latexindent.pl avatar
cmhughes/latexindent.pl

latexindent.pl: a Perl formatter that indents LaTeX environments and can rewrite your line breaks

Perl script to add indentation (leading horizontal space) to LaTeX files. It can modify line breaks before, during and after code blocks; it can perform text wrapping and paragraph line break removal. It can also perform string-based and regex-based substitutions/replacements. The script is customisable through its YAML interface.

1,064 stars83 forksTeXGPL-3.0

At a glance

What is it?
latexindent.pl adds leading horizontal space inside LaTeX environments, commands, after headings and in special code blocks, and it goes further than indentation by wrapping text, applying one sentence per line, and running string and regex replacements over the file. Everything is driven by a YAML settings file, and the current version is 4.0.3.
Who is it for?
latexindent.pl suits a LaTeX author who wants consistent indentation across a multi file project and is prepared to have the tool rewrite line breaks and text, since wrapping and one sentence per line are part of what it does rather than options bolted on. It is the wrong tool for a document where paragraph line breaks are meaningful, for a shared repository where a reformat would produce a huge diff against other authors.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly TeX, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Indentation is the headline, but line rewriting is the real behaviour

latexindent.pl is a Perl script to beautify, tidy, format and indent LaTeX files, where indent means adding horizontal leading space to code within environments, commands, after headings and within special code blocks. That is the description on the tin, and the example in the README shows it well. A nested pair of environments goes from flush left to indented, with the inner environment and its body indented further than the outer one.

The example in the README is the cleanest way to see the shape of the output:

tex
\begin{one}
	latexindent.pl adds leading
	space to code blocks.
	\begin{two}
		It aims to beautify .tex, .sty
		and .cls files. It is customisable
		via its YAML interface.
	\end{two}
\end{one}

But the more consequential features are the ones that change what is in your file rather than where the whitespace sits. The script can align delimiters in environments and commands, and it can modify line breaks, including text wrapping and one sentence per line. It can also perform string based and regex based substitutions and replacements.

That combination is the source of both its value and its risk. A tool that only adds indentation is safe to run, because removing the added whitespace returns the original. A tool that also wraps paragraphs and applies substitutions has changed content, and a round trip is no longer guaranteed to be a no operation.

The project states its purpose as a beautifier and its own documentation says there are many more features available, detailed in full within the documentation. The audience is therefore a LaTeX author who wants a specific house style enforced across a document or a set of documents, not a user who wants to tidy a file once and forget about it.

Running it, and the version the tool reports

The invocation takes the file as an argument:

code
latexindent.pl myfile.tex

The script reports its own version in a header line, and the README shows the current one as:

code
latexindent.pl, version 4.0.3, 2026-10-04

The release tags in the repository match that numbering, with V4.0.3 as the most recent release on 2026-10-04, V4.0.2 on 2026-06-06 and V4.0.1 on 2026-05-04. The author is Chris Hughes.

The tool is distributed as more than a script. Perl users need three things in the same directory:

code
latexindent.pl
LatexIndent/*.pm
defaultSettings.yaml

The LatexIndent directory holds the Perl modules, and defaultSettings.yaml is the settings file that drives the behaviour. The README notes that a few readily available Perl modules are needed, with full details in the Appendix of the documentation, and points Strawberry Perl users at the .appveyor.yml file.

For anyone who cannot install Perl, there are standalone executables. Windows users who do not have a perl installation might prefer latexindent.exe, a standalone executable which does not require a perl installation, available from the releases page and from the CTAN tex archive at https://ctan.org/tex-archive/support/latexindent. Ubuntu Linux users without perl are pointed at latexindent-linux, which should be saved as simply latexindent, from the same two places. Mac users without perl get latexindent-macos, saved as simply latexindent, again from the releases page and CTAN.

The Perl script itself, LatexIndent/*.pm, defaultSettings.yaml and the Makefile.PL, plus the Dockerfile, the environment.yml, the .devcontainer directory, the path-helper-files and the test-cases directory, are what the repository listing contains. There is also a helper-scripts directory, which the Dockerfile uses.

Conda, Docker and pre-commit: three ways to run it in a pipeline

The project supports three installation and automation routes, and each is a single block of configuration.

Conda installs the executable and all of its dependencies, including perl, into the active environment, and defaultSettings.yaml comes with it:

code
conda install latexindent.pl -c conda-forge

There is a warning attached to this that trips people up: the executable name is latexindent.pl, not latexindent.

Docker pulls a published image and runs it against a mounted file:

code
docker pull ghcr.io/cmhughes/latexindent.pl
docker run -v /path/to/local/myfile.tex:/myfile.tex --rm -it ghcr.io/cmhughes/latexindent.pl -s -w myfile.tex

The Dockerfile behind that image is worth reading if you want to understand the runtime. It is based on perl:5.44.0-slim-threaded-bookworm, takes the latexindent version as a build argument defaulting to V4.0.3, installs the build toolchain including cmake, clones the repository at the requested tag, runs the module installer with the echo Y piped in, builds the path helper files with cmake and make install, and symlinks the result so that latexindent and latexindent.pl are both on the path. The entrypoint is latexindent.

The pre-commit route is the one most projects will want, and it needs a hook entry in .pre-commit-config.yaml:

yaml
  - repo: https://github.com/cmhughes/latexindent.pl.git
    rev: V4.0.3
    hooks:
      - id: latexindent

The repository ships a .pre-commit-hooks.yaml, which is what makes the hook id latexindent resolvable. The documentation also links a worked example demonstrating how to add a .latexindent.yaml to the repository so that the settings travel with the code rather than living in one developer's home directory.

That last point is the important one for team use. The tool is customised through its YAML interface, and if the configuration is not in the repository, every developer's output differs and the pre-commit hook becomes a source of conflict rather than a source of consistency.

What the YAML settings actually control

The script is customisable through its YAML interface, and defaultSettings.yaml is the shipped baseline. The documentation links specific settings pages for each area of behaviour, which is a reasonable way to see how far the configuration surface extends.

The linked pages cover aligning at delimiters in environments and commands, the m switch for modifying line breaks with sections on text wrapping and one sentence per line, and replacements for string based and regex based substitutions.

Reading that list tells you the settings are structured around three separate concerns that a user might otherwise expect to be one. Indentation is one. Line break policy is another, and it is the one that alters content, because wrapping a paragraph to a given width inserts newlines and one sentence per line puts a break after each sentence. The third is replacement rules, which are pattern driven edits to the text of the file.

The m switch is the option that does the work and the one to be careful with. The documentation has a dedicated section for it, which means it is a first class switch with sub-options rather than a single flag. The project targets.tex,.sty and.cls files, so it operates on class and style files too, not only on documents.

For the pre-commit route, the documentation also describes a worked example using the l and m switches together, and shows how a.latexindent.yaml file in the repository root configures the run. That is the pattern to copy: a settings file under version control, a hook pinned to a specific release tag such as V4.0.3, and a set of switches chosen once for the project.

The practical caution is the same one the tool's own scope implies. Indentation is reversible. Text wrapping and one sentence per line are not, in the sense that a second run over already wrapped text is idempotent only if the settings are stable, and if a colleague runs the tool with different settings over the same file you get a conflict that is about prose rather than about code.

Distribution, licence and who should not be running this

latexindent.pl has an unusually broad distribution for a single Perl script. It is on CTAN, the TeX archive, at https://ctan.org/tex-archive/support/latexindent, alongside the GitHub releases page. It is on conda-forge under the name latexindent.pl. It is published as a Docker image to ghcr.io under cmhughes/latexindent.pl. And the documentation notes it can be run in the browser through latexindent in zeroperl.

The documentation itself is published two ways, as a PDF at http://mirrors.ctan.org/support/latexindent/documentation/latexindent.pdf and online at readthedocs, and the README includes an instruction about which one to trust: if you find discrepancies between the pdf and readthedocs, defer to the pdf. That is a deliberate statement that the PDF is the canonical source, which is a sensible choice for a tool whose documentation is read in many small versions, and it is a hint that the two are not kept perfectly in step.

The licence is GPL-3.0, in a LICENSE.txt file at the top of the repository. The primary language listed for the repository is TeX, which reflects what the tool formats rather than what it is written in; the implementation is Perl with the modules in LatexIndent/.

The maintenance picture is a date rather than an adjective. The repository is not archived, and the last push was on 2026-10-04, the same day as the V4.0.3 release. The three most recent release tags are V4.0.3, V4.0.2 and V4.0.1, with gaps of about four and one month respectively, so the release cadence has picked up.

Who should not run this: anyone whose LaTeX paragraphs carry meaningful line breaks, such as a document where a line break inside a quotation is deliberate, or a verse environment where the break structure is the content. The script is told to modify line breaks and to wrap text, and it does not know about your intent in those cases. It is also the wrong tool for a shared repository where a whole file reformat produces a diff that hides the actual change in a review, unless the formatting is applied once and the project adopts it as the baseline.

Editorial conclusion

latexindent.pl suits a LaTeX author who wants consistent indentation across a multi file project and is prepared to have the tool rewrite line breaks and text, since wrapping and one sentence per line are part of what it does rather than options bolted on. It is the wrong tool for a document where paragraph line breaks are meaningful, for a shared repository where a reformat would produce a huge diff against other authors. Before adopting, run it on a copy of one file first, diff the result, and check the defaultSettings.yaml, because the defaults decide how aggressively your paragraphs get rewritten.

Frequently asked questions

How do I install latexindent.pl on Linux without Perl?

The README points Ubuntu Linux users without a perl installation to the standalone executable latexindent-linux, which should be saved as simply latexindent. It is available from the releases page of the repository and from https://ctan.org/tex-archive/support/latexindent. A Docker image is also published at ghcr.io/cmhughes/latexindent.pl.

What files does latexindent.pl need to run?

Perl users need latexindent.pl, the LatexIndent/*.pm modules and defaultSettings.yaml in the same directory, plus a few readily available Perl modules. The conda install includes the executable and all of its dependencies, including perl, and defaultSettings.yaml comes with it.

Can latexindent.pl be used with pre-commit?

Yes. Add the repository as a hook in your .pre-commit-config.yaml with a pinned rev such as V4.0.3 and the hook id latexindent. The documentation also shows a worked example adding a .latexindent.yaml to the repository so the settings travel with the code.

Does latexindent.pl only add indentation, or does it rewrite text?

It does both. The script can modify line breaks, including text wrapping and one sentence per line, and can perform string based and regex based substitutions and replacements, in addition to adding leading space inside environments, commands and after headings. Those line and text changes are the ones to review in a diff.

Official sources

  1. cmhughes/latexindent.pl on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cmhughes-latexindent-pl.svg)](https://hysenlabs.com/projects/cmhughes-latexindent-pl)