# LaTeX code sniffer and/or beautifier?

I'm looking for a LaTeX code sniffer and/or code beautifier, because I'm creating a CI server for my LaTeX books and I wanted a few things. :D

-
When you say "CI server", do you mean continuous integration? Could you expand on that? I find the question confusing. – Matthew Leingang Aug 19 '11 at 15:46
latexindent is now a part of TeXLive 2013 – cmhughes Nov 26 '13 at 18:07
I created a website that reformats the latex code to make indents correct. c.albert-thompson.com/latex-pretty – Whitecat Oct 5 at 6:32

latexindent.pl is now available on ctan.

The script still performs the same tasks outlined below (and a lot more), but without nearly the same amount of manual input from the user. See the documentation for full details.

I've recently been working on a perl script that tidies up .tex files. It doesn't (or rather, shouldn't) remove any lines, and

• tidies up indentation
• tidies up environments that have alignment delimiters.

You can find (and follow) it on github at

https://github.com/cmhughes/latexindent.plx

# Old answer (left for historical purposes)

Please see the manual for instructions on how to use the script. The following instructions are out of date, and should be ignored- please see the manual.

The following is taken from the readme.txt

Usage

    perl indent.plx inputfile.tex


will output to the terminal and

    perl indent.plx inputfile.tex > outputfile.tex


will output to outputfile.tex

EXAMPLE 1: delimiter tabs

Populate %lookforaligndelims with a list of environments that have alignment tabs, the default is:

my %lookforaligndelims=("tabular"=>1,
"align"=>1,
"align*"=>1,
"alignat"=>1,
"alignat*"=>1,
"cases"=>1,
"dcases"=>1,
"aligned"=>1);


Include any environment name you like in here. If you change your mind, just change 1 to a 0 (or remove them completely).

Before:

\begin{align*}
F(-x) & =-(-x)^2 &   G(-x) & =-(-x)^4 & H(-x) & =-(-x)^6 \\
& =-x^2    & & =-x^4    &       & =-x^6\\
&  =F(x)  &      & =G(x)    &       & =H(x)
\end{align*}


After:

\begin{align*}
F(-x) & =-(-x)^2 & G(-x) & =-(-x)^4 & H(-x) & =-(-x)^6 \\
& =-x^2    &       & =-x^4    &       & =-x^6    \\
& =F(x)    &       & =G(x)    &       & =H(x)
\end{align*}


Example 2: nested environments

By default every time the script comes across \begin{something} it will increase the indentation- this can be customized as detailed in the next examples.

Before:

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


After:

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


Example 3: custom indentation

If you want to customize the indentation for an environment, then use %indentrules, for example

my %indentrules=("axis"=>"\t\t\t");


will indent the axis environment using 3 tabs.

Include any environment name you like in here with the special rule that you choose.

Before:

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


After:

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


Example 4: no additional indentation for an environment

If you want an environment to not have additional indentation, then populate %noindent, for example

my %noindent=("tikzpicture"=>1,
);


Include any environment name you like in here. If you change your mind, just change 1 to a 0, or remove it from %noindent completely.

Before:

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


After (notice that tikzpicture content is not indented):

\begin{figure}[!htb]
\centering
\begin{tikzpicture}
\begin{axis}[
framed,
width=\figurewidth,
xmin=-5,xmax=5,
ymin=-1,ymax=5,
xtick={-6},
ytick={-6},
]
\end{axis}
\end{tikzpicture}
\end{figure}


EXAMPLE 5: commands that split {} across lines

For example \parbox; populate %checkunmatched,

my %checkunmatched=("parbox"=>1,);


Include any command name you wish; you can put TikZ key names in here too- they don't have to begin with \, for example

my %checkunmatched=("parbox"=>1,
"vbox"=>1,
"marginpar"=>1,
"pgfplotstableset"=>1,
"typeset cell/.append code"=>1,
"create col/assign/.code"=>1,
"foreach"=>1);


You can specify particular indentation rules in %indentrules, as in Example 3.

Before:

\parbox{
some text
some text
some text
some text
some text
}


After:

\parbox{
some text
some text
some text
some text
some text
}


Note: you can nest these commands, e.g

Before:

\parbox{
some text
some text
some text
some text
some text
\parbox{
some text
some text
some text
some text
some text
}
}


After:

\parbox{
some text
some text
some text
some text
some text
\parbox{
some text
some text
some text
some text
some text
}
}


Example 6: else clause

Commands that have an else clause using {} and can split the {} across lines; populate %checkunmatchedELSE, for example

my %checkunmatchedELSE=("mycommand"=>1);


Include any command name you wish; you can put TikZ key names in here too- they don't have to begin with \ as in Example 5.

You can specify particular indentation rules in %indentrules, as in Example 3.

Before:

\mycommand{
if clause
}
{
else clause
}


After:

\mycommand{
if clause
}
{
else clause
}


Note that these can be nested as in Example 5.

Example 7: split [] across lines

For commands that split [] across lines; populate

%checkunmatchedbracket,


for example

my %checkunmatchedbracket=("mycommand"=>1);


Include any command name you wish that may split [] across lines; it doesn't have to begin with a \ as in Examples 5 and 6.

You can specify particular indentation rules in %indentrules, as in Example 3.

Before:

\mycommand[
some text
some text
some text
some text
some text
some text
]


After:

\mycommand[
some text
some text
some text
some text
some text
some text
]


Note that these can be nested as in Example 5.

Example 8: verbatim environments

If you don't want the script to modify a code block at all, then populate %verbatim, for example

my %verbatim=("verbatim"=>1);


Include any environment name you wish to behave like a verbatim environment.

Before:

\begin{verbatim}
this text won't change
at all
promise!
hopefully\ldots
\end{verbatim}


After:

\begin{verbatim}
this text won't change
at all
promise!
hopefully\ldots
\end{verbatim}


More examples

For more examples, see the sampleBEFORE.tex and sampleAFTER.tex which was obtained by running

perl indent.plx sampleBEFORE.tex > sampleAFTER.tex


Important

This script may not work for your style of formatting; I highly recommend comparing the outputfile.tex to make sure that nothing has been changed (or removed) in a way that will damage your file.

I recommend both using the following:

• a visual check, at the very least, make sure that each file has the same number of lines
• a check using latexdiff inputfile.tex outputfile.tex
-
Hi cmhughes, very interesting idea. But I get no difference in my source file and the resulting output. Indeed, when I run your script on sampleBEFORE.tex I still get no changes. (Perl ver. 5.12.4, running on OS X 10.8.1.) – NVaughan Sep 11 '12 at 1:41
@NVaughan I'm sorry to hear that :) Try and catch me in the chat room sometime and we can talk about debugging; running perl indent.plx sampleBEFORE.tex> sampleAFTER.tex should show you it in action. – cmhughes Sep 11 '12 at 2:58

The closest thing to a LaTeX code sniffer is the nag package which tries to detect and warn about usage of obsolete package and other things listed in l2tabu.

I'm not aware that a (La)TeX beautifier exists. LaTeX is a TeX format and TeX is a very dynamic language which allows to change its own parser rules during the compilation runs. This makes it very hard to process except by a full TeX compiler itself. I was thinking writing a limited tool using Perl a while ago, but never found the time to do so.

-
Thanks for pointing to nag and l2tabu. +1 – guillem Mar 14 '13 at 6:38

There are several (very) simple code tidiers available.

Some come with editors (e.g. Textmate has a LaTeX Tidy function) but I don't have an OS that can run this and it may just be the product below (see its edit history).

Some are written by users who needed one and wrote their own and have made it more widely available, e.g. Eric Tsu's LateX Tidy. I have used Eric Tsu's program a couple of times to reformat received LaTeX code as an aid to adapting it (to shorten lines, to remove redundant blank lines and to indent blocks (i.e. \begin environment) but, as with most products, I wouldn't use it to format code without subsequent detailed checking -- as it says on the website

This is a little Perl script to neaten up the format of LaTeX files.

This is simple and naive. This takes STDIN .tex files and prints to STDOUT.

Check your file! Backup! No guarantees!

This is released as Niceware, which is like the Perl Artistic License, except you have to be nice to me when you criticize the code.

If you are looking for something more than tools like this let us know if you find it -- or end up writing it yourself.

-

I created a website that reformats the latex code to make indents consistent. This if a very rudimentary system but will do all simple indentation of items inside parenthases so they are at the same level.

It does not do any code sniffing, it also cannot detect if you have missing end tags.

https://c.albert-thompson.com/latex-pretty/

-