3. Config
latexindent.pl loads its default settings from defaultSettings.yaml. The idea is to separate the behaviour of the script from the internal working – this is very similar to the way that we separate content from form when writing our documents in LaTeX. All of these settings can be changed by you, the user; demonstrations are given throughout this documentation using the -l switch.
If you look in defaultSettings.yaml you’ll find the settings that govern the behaviour of latexindent.pl. If you’re not sure where defaultSettings.yaml resides on your computer, don’t worry as indent.log will tell you where to find it. defaultSettings.yaml is commented, but here is a description of what each switch is designed to do. The default value is given in each case; whenever you see integer in this section, assume that it must be greater than or equal to 0
unless otherwise stated.
For most of the settings in defaultSettings.yaml that are specified as integers, then we understand 0 to represent ‘off’ and 1 to represent ‘on’. For fields that allow values other than 0 or 1, it is hoped that the specific context and associated commentary should make it clear which values are allowed.
- fileExtensionPreference:fields
latexindent.pl can be called to act on a file without specifying the file extension. For example we can call
latexindent.pl myfile
in which case the script will look for myfile with the extensions specified in fileExtensionPreference in their numeric order. If no match is found, the script will exit. As with all of the fields, you should change and/or add to this as necessary.
31fileExtensionPreference:
32 .tex: 1
33 .sty: 2
34 .cls: 3
35 .bib: 4
Calling latexindent.pl myfile with the (default) settings specified in Listing 34 means that the script will first look for myfile.tex, then myfile.sty, myfile.cls, and finally myfile.bib in order 1.
3.1. Backup and log file preferences
- backupExtension:extension name
If you call latexindent.pl with the -w switch (to overwrite myfile.tex) then it will create a backup file before doing any indentation; the default extension is .bak, so, for example, myfile.bak0 would be created when calling latexindent.pl myfile.tex for the first time.
By default, every time you subsequently call latexindent.pl with the -w to act upon myfile.tex, it will create successive back up files: myfile.bak1, myfile.bak2, etc.
- onlyOneBackUp:integer
If you don’t want a backup for every time that you call latexindent.pl (so you don’t want myfile.bak1, myfile.bak2, etc) and you simply want myfile.bak (or whatever you chose backupExtension to be) then change onlyOneBackUp to 1; the default value of onlyOneBackUp is 0.
- maxNumberOfBackUps:integer
Some users may only want a finite number of backup files, say at most \(3\), in which case, they can change this switch. The smallest value of maxNumberOfBackUps is \(0\) which will not prevent backup files being made; in this case, the behaviour will be dictated entirely by onlyOneBackUp. The default value of maxNumberOfBackUps is 0.
- cycleThroughBackUps:integer
Some users may wish to cycle through backup files, by deleting the oldest backup file and keeping only the most recent; for example, with maxNumberOfBackUps: 4, and cycleThroughBackUps set to 1 then the copy procedure given below would be obeyed.
copy myfile.bak1 to myfile.bak0
copy myfile.bak2 to myfile.bak1
copy myfile.bak3 to myfile.bak2
copy myfile.bak4 to myfile.bak3
The default value of cycleThroughBackUps is 0.
3.2. Verbatim code blocks
- verbatimEnvironments:fields
A field that contains a list of environments that you would like left completely alone – no indentation will be performed on environments that you have specified in this field, see Listing 35.
68verbatimEnvironments:
69 verbatim: 1
70 lstlisting: 1
71 minted: 1
74verbatimCommands:
75 verb: 1
76 lstinline: 1
Note that if you put an environment in verbatimEnvironments and in other fields such as lookForAlignDelims or noAdditionalIndent then latexindent.pl will always prioritize verbatimEnvironments.
You can, optionally, specify the verbatim field using the name field which takes a regular expression as its argument; thank you to (XuehaiPan 2021) for contributing this feature.
For demonstration, then assuming that your file contains the environments latexcode, latexcode*, pythoncode and pythoncode*, then the listings given in Listing 37 and Listing 38 are equivalent.
verbatimEnvironments:
latexcode: 1
latexcode*: 1
pythoncode: 1
pythoncode*: 1
verbatimEnvironments:
nameAsRegex:
name: '\w+code\*?'
lookForThis: 1
With reference to Listing 38:
the
namefield as specified here means any word followed by the word code, optionally followed by *;we have used
nameAsRegexto identify this field, but you can use any description you like;the
lookForThisfield is optional, and can take the values 0 (off) or 1 (on); by default, it is assumed to be 1 (on).
- verbatimCommands:fields
A field that contains a list of commands that are verbatim commands, for example \verb; any commands populated in this field are protected from line breaking routines (only relevant if the -m is active, see Section 4).
With reference to Listing 36, by default latexindent.pl looks for \verb immediately followed by another character, and then it takes the body as anything up to the next occurrence of the character; this means that, for example, \verb!x+3! is treated as a verbatimCommands.
You can, optionally, specify the verbatimCommands field using the name field which takes a regular expression as its argument; thank you to (XuehaiPan 2021) for contributing this feature.
For demonstration, then assuming that your file contains the commands verbinline, myinline then the listings given in Listing 39 and Listing 40 are equivalent.
verbatimCommands:
verbinline: 1
myinline: 1
verbatimCommands:
nameAsRegex:
name: '\w+inline'
lookForThis: 1
With reference to Listing 40:
the
namefield as specified here means any word followed by the word inline;we have used
nameAsRegexto identify this field, but you can use any description you like;the
lookForThisfield is optional, and can take the values 0 (off) or 1 (on); by default, it is assumed to be 1 (on).
- noIndentBlock:fields
If you have a block of code that you don’t want latexindent.pl to touch (even if
it is not a verbatim-like environment) then you can wrap it in an environment from noIndentBlock; you can use any name you like for this, provided you populate it as demonstrate in Listing 41.
81noIndentBlock:
82 noindent: 1
83 cmhtest: 1
Of course, you don’t want to have to specify these as null environments in your code, so you use them with a comment symbol, %, followed by as many spaces (possibly none) as you like; see Listing 42 for example.
% \begin{noindent}
some before text
this code
won't
be touched
by
latexindent.pl!
some after text
% \end{noindent}
Important note: it is assumed that the noindent block statements specified in this way appear on their own line.
The noIndentBlock fields can also be specified in terms of begin and end fields. We use the code in Listing 43 to demonstrate this feature.
some before text
this code
won't
be touched
by
latexindent.pl!
some after text
The settings given in Listing 44 and Listing 45 are equivalent:
noIndentBlock:
demo:
begin: 'some\hbefore'
body: '.*?'
end: 'some\hafter\htext'
lookForThis: 1
noIndentBlock:
demo:
begin: 'some\hbefore'
end: 'some\hafter\htext'
noIndentBlock:
demo:
begin: 'some\hbefore'
body: '.*?'
end: 'some\hafter\htext'
lookForThis: 0
Upon running the commands
latexindent.pl -l noindent1.yaml noindent1
latexindent.pl -l noindent2.yaml noindent1
then we receive the output given in Listing 47.
some before text
this code
won't
be touched
by
latexindent.pl!
some after text
The begin, body and end fields for noIndentBlock are all regular expressions. If the body field is not specified, then it takes a default value of .*? which is written explicitly in Listing 44. In this context, we interpret .*? in words as the fewest number of characters (possibly none) until the ‘end’ field is reached.
The lookForThis field is optional, and can take the values 0 (off) or 1 (on); by default, it is assumed to be 1 (on).
Using Listing 46 demonstrates setting lookForThis to 0 (off); running the command
latexindent.pl -l noindent3.yaml noindent1
gives the output in Listing 48.
some before text
this code
won't
be touched
by
latexindent.pl!
some after text
We will demonstrate this feature later in the documentation in Listing 565.
You can, optionally, specify the noIndentBlock field using the name field which takes a regular expression as its argument; thank you to (XuehaiPan 2021) for contributing this feature.
For demonstration, then assuming that your file contains the environments testnoindent, testnoindent* then the listings given in Listing 49 and Listing 50 are equivalent.
noIndentBlock:
mytest:
begin: '\\begin\{testnoindent\*?\}'
end: '\\end\{testnoindent\*?\}'
noIndentBlock:
nameAsRegex:
name: '\w+noindent\*?'
lookForThis: 1
With reference to Listing 50:
the
namefield as specified here means any word followed by the word noindent, optionally followed by *;we have used
nameAsRegexto identify this field, but you can use any description you like;the
lookForThisfield is optional, and can take the values 0 (off) or 1 (on); by default, it is assumed to be 1 (on).
3.3. filecontents and preamble
- fileContentsEnvironments:field
Before latexindent.pl determines the difference between preamble (if any) and the main document, it first searches for any of the environments specified in fileContentsEnvironments, see Listing 51. The behaviour of latexindent.pl on these environments is determined by their location (preamble or not), and the value indentPreamble, discussed next.
87fileContentsEnvironments:
88 filecontents: 1
89 filecontents*: 1
- indentPreamble:0|1
The preamble of a document can sometimes contain some trickier code for latexindent.pl to operate upon. By default, latexindent.pl won’t try to operate on the preamble (as indentPreamble is set to 0, by default), but if you’d like latexindent.pl to try then change indentPreamble to 1.
- lookForPreamble:fields
Not all files contain preamble; for example, sty, cls and bib files typically do not. Referencing Listing 52, if you set, for example, .tex to 0, then regardless of the setting of the value of indentPreamble, preamble will not be assumed when operating upon .tex files.
95lookForPreamble:
96 .tex: 1
97 .sty: 0
98 .cls: 0
99 .bib: 0
100 STDIN: 1
3.4. Indentation and horizontal space
- defaultIndent:horizontal space
This is the default indentation used in the absence of other details for the code block with which we are working. The default value is \t which means a tab; we will explore customisation beyond defaultIndent in Section 3.9.
If you’re interested in experimenting with latexindent.pl then you can remove all indentation by setting defaultIndent: "".
- removeTrailingWhitespace:fields
Trailing white space can be removed both before and after processing the document, as detailed in Listing 53; each of the fields can take the values 0 or 1. See Listing 455 and Listing 456 and Listing 457 for before and after results. Thanks to (Voßkuhle 2013) for providing this feature.
106removeTrailingWhitespace:
107 beforeProcessing: 0
108 afterProcessing: 1
removeTrailingWhitespace: 1
You can specify removeTrailingWhitespace simply as 0 or 1, if you wish; in this case, latexindent.pl will set both beforeProcessing and afterProcessing to the value you specify; see Listing 54.
3.5. Aligning at delimiters
- lookForAlignDelims:fields
This contains a list of code blocks that are operated upon in a special way by latexindent.pl (see Listing 55). In fact, the fields in lookForAlignDelims can actually take two different forms: the basic version is shown in Listing 55 and the advanced version in Listing 58; we will discuss each in turn.
111lookForAlignDelims:
112 tabular: 1
113 tabularx: 1
114 longtable: 1
Specifying code blocks in this field instructs latexindent.pl to try and align each column by its alignment delimiters. It does have some limitations (discussed further in Section 8), but in many cases it will produce results such as those in Listing 56 and Listing 57; running the command
latexindent.pl tabular1.tex
gives the output given in Listing 57.
\begin{tabular}{cccc}
1& 2 &3 &4\\
5& &6 &\\
\end{tabular}
\begin{tabular}{cccc}
1 & 2 & 3 & 4 \\
5 & & 6 & \\
\end{tabular}
If you find that latexindent.pl does not perform satisfactorily on such environments then you can set the relevant key to 0, for example tabular: 0; alternatively, if you just want to ignore specific instances of the environment, you could wrap them in something from noIndentBlock (see Listing 41).
If, for example, you wish to remove the alignment of the \\ within a delimiter-aligned block, then the advanced form of lookForAlignDelims shown in Listing 58 is for you.
tabular:
delims: 1
alignDoubleBackSlash: 1
spacesBeforeDoubleBackSlash: 1
multiColumnGrouping: 0
alignRowsWithoutMaxDelims: 1
spacesBeforeAmpersand: 1
spacesAfterAmpersand: 1
justification: left
alignFinalDoubleBackSlash: 0
dontMeasure: 0
delimiterRegEx: (?<!\\)(&)
delimiterJustification: left
lookForChildCodeBlocks: 1
alignContentAfterDoubleBackSlash: 0
spacesAfterDoubleBackSlash: 1
doubleBackSlash: \\\\(?:\h*\[\h*[0-9.]+\h*[a-zA-Z]+\h*\])?
Note that you can use a mixture of the basic and advanced form: in Listing 55 the entries are basic; in Listing 58 the entry for tabular is advanced. The default values for the advanced form are controlled in fineTuning, see Section 7.6. When using the advanced form, each field should receive at least 1 sub-field, and can (but does not have to) receive any of the following fields:
delims: binary switch (0 or 1) equivalent to simply specifying, for example,tabular: 1in the basic version shown in Listing 55. Ifdelimsis set to0then the align at ampersand routine will not be called for this code block (default: 1);alignDoubleBackSlash: binary switch (0 or 1) to determine if\\should be aligned (default: 1);spacesBeforeDoubleBackSlash: optionally, specifies the number (integer \(\geq\) 0) of spaces to be inserted before\\(default: 1);multiColumnGrouping: binary switch (0 or 1) that details iflatexindent.plshould group columns above and below a\multicolumncommand (default: 0);alignRowsWithoutMaxDelims: binary switch (0 or 1) that details if rows that do not contain the maximum number of delimiters should be formatted so as to have the ampersands aligned (default: 1);spacesBeforeAmpersand: optionally specifies the number (integer \(\geq\) 0) of spaces to be placed before ampersands (default: 1);spacesAfterAmpersand: optionally specifies the number (integer \(\geq\) 0) of spaces to be placed After ampersands (default: 1);justification: optionally specifies the justification of each cell as either left or right (default: left);alignFinalDoubleBackSlash optionally specifies if the final double backslash should be used for alignment (default: 0);
dontMeasure optionally specifies if user-specified cells, rows or the largest entries should not be measured (default: 0);
delimiterRegEx optionally specifies the pattern matching to be used for the alignment delimiter (default:
(?<!\\)(&)*);delimiterJustification optionally specifies the justification for the alignment delimiters (default: left); note that this feature is only useful if you have delimiters of different lengths in the same column, discussed in Section 3.5.3;
lookForChildCodeBlocks optionally instructs
latexindent.plto search for child code blocks or not (default: 1), discussed in Section 3.5.4;alignContentAfterDoubleBackSlash optionally instructs
latexindent.plto align content after double back slash (default: 0), discussed in Section 3.5.5;spacesAfterDoubleBackSlash optionally specifies the number (integer \(\geq\) 0) of spaces to be placed after the double back slash when alignContentAfterDoubleBackSlash is active; demonstrated in Section 3.5.5.
We will explore most of these features using the file tabular2.tex in Listing 59 (which contains a \multicolumn command), and the YAML files in Listing 60 – Listing 66; the dontMeasure feature will be described in Section 3.5.2, and delimiterRegEx in Section 3.5.3.
\begin{tabular}{cccc}
A& B & C &D\\
AAA& BBB & CCC &DDD\\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading}\\
one& two & three &four\\
five& &six &\\
seven & \\
\end{tabular}
lookForAlignDelims:
tabular:
multiColumnGrouping: 1
lookForAlignDelims:
tabular:
alignRowsWithoutMaxDelims: 0
lookForAlignDelims:
tabular:
spacesBeforeAmpersand: 4
lookForAlignDelims:
tabular:
spacesAfterAmpersand: 4
lookForAlignDelims:
tabular:
alignDoubleBackSlash: 0
lookForAlignDelims:
tabular:
spacesBeforeDoubleBackSlash: 0
lookForAlignDelims:
tabular:
justification: "right"
On running the commands
latexindent.pl tabular2.tex
latexindent.pl tabular2.tex -l tabular2.yaml
latexindent.pl tabular2.tex -l tabular3.yaml
latexindent.pl tabular2.tex -l tabular2.yaml,tabular4.yaml
latexindent.pl tabular2.tex -l tabular2.yaml,tabular5.yaml
latexindent.pl tabular2.tex -l tabular2.yaml,tabular6.yaml
latexindent.pl tabular2.tex -l tabular2.yaml,tabular7.yaml
latexindent.pl tabular2.tex -l tabular2.yaml,tabular8.yaml
we obtain the respective outputs given in Listing 67 – Listing 74.
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading}\\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
\begin{tabular}{cccc}
A & B & C & D \\
AAA & BBB & CCC & DDD \\
\multicolumn{2}{c}{first heading} & \multicolumn{2}{c}{second heading} \\
one & two & three & four \\
five & & six & \\
seven & \\
\end{tabular}
Notice in particular:
in both Listing 67 and Listing 68 all rows have been aligned at the ampersand, even those that do not contain the maximum number of ampersands (3 ampersands, in this case);
in Listing 67 the columns have been aligned at the ampersand;
in Listing 68 the
\multicolumncommand has grouped the \(2\) columns beneath and above it, becausemultiColumnGroupingis set to \(1\) in Listing 60;in Listing 69 rows 3 and 6 have not been aligned at the ampersand, because
alignRowsWithoutMaxDelimshas been to set to \(0\) in Listing 61; however, the\\have still been aligned;in Listing 70 the columns beneath and above the
\multicolumncommands have been grouped (becausemultiColumnGroupingis set to \(1\)), and there are at least \(4\) spaces before each aligned ampersand becausespacesBeforeAmpersandis set to \(4\);in Listing 71 the columns beneath and above the
\multicolumncommands have been grouped (becausemultiColumnGroupingis set to \(1\)), and there are at least \(4\) spaces after each aligned ampersand becausespacesAfterAmpersandis set to \(4\);in Listing 72 the
\\have not been aligned, becausealignDoubleBackSlashis set to0, otherwise the output is the same as Listing 68;in Listing 73 the
\\have been aligned, and becausespacesBeforeDoubleBackSlashis set to0, there are no spaces ahead of them; the output is otherwise the same as Listing 68;in Listing 74 the cells have been right-justified; note that cells above and below the
\multicolstatements have still been group correctly, because of the settings in Listing 60.
3.5.1. lookForAlignDelims: spacesBeforeAmpersand
The spacesBeforeAmpersand can be specified in a few different ways. The basic form is demonstrated in Listing 62, but we can customise the behaviour further by specifying if we would like this value to change if it encounters a leading blank column; that is, when the first column contains only zero-width entries. We refer to this as the advanced form.
We demonstrate this feature in relation to Listing 75; upon running the following command
latexindent.pl aligned1.tex -o=+-default
then we receive the default output given in Listing 76.
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
The settings in Listing 77 – Listing 80 are all equivlanent; we have used the not-yet discussed noAdditionalIndent field (see Section 3.9) which will assist in the demonstration in what follows.
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned: 1
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand: 1
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand:
default: 1
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand:
leadingBlankColumn: 1
Upon running the following commands
latexindent.pl aligned1.tex -l sba1.yaml
latexindent.pl aligned1.tex -l sba2.yaml
latexindent.pl aligned1.tex -l sba3.yaml
latexindent.pl aligned1.tex -l sba4.yaml
then we receive the (same) output given in Listing 81; we note that there is one space before each ampersand.
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
We note in particular:
Listing 77 demonstrates the basic form for
lookForAlignDelims; in this case, the default values are specified as in Listing 58;Listing 78 demonstrates the advanced form for
lookForAlignDelimsand specifiedspacesBeforeAmpersand. The default value is1;Listing 79 demonstrates the new advanced way to specify
spacesBeforeAmpersand, and for us to set thedefaultvalue that sets the number of spaces before ampersands which are not in leading blank columns. The default value is1.We note that
leadingBlankColumnhas not been specified in Listing 79, and it will inherit the value fromdefault;Listing 80 demonstrates spaces to be used before amperands for leading blank columns. We note that default has not been specified, and it will be set to
1by default.
We can customise the space before the ampersand in the leading blank column of Listing 81 by using either of Listing 82 and Listing 83, which are equivalent.
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand:
leadingBlankColumn: 0
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand:
leadingBlankColumn: 0
default: 1
Upon running
latexindent.pl aligned1.tex -l sba5.yaml
latexindent.pl aligned1.tex -l sba6.yaml
then we receive the (same) output given in Listing 84. We note that the space before the ampersand in the leading blank column has been set to 0 by Listing 83.
We can demonstrated this feature further using the settings in Listing 86 which give the output in Listing 85.
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
\begin{aligned}
& a& b, \\
& c& d.
\end{aligned}
noAdditionalIndent:
aligned: 1
lookForAlignDelims:
aligned:
spacesBeforeAmpersand:
leadingBlankColumn: 3
default: 0
3.5.2. lookForAlignDelims: the dontMeasure feature
The lookForAlignDelims field can, optionally, receive the dontMeasure option which can be specified in a few different ways.
We will explore this feature in relation to the code given in Listing 87; the default output is shown in Listing 88.
\begin{tabular}{cccc}
aaaaaa&bbbbb&ccc&dd\\
11&2&33&4\\
5&66&7&8
\end{tabular}
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
The dontMeasure field can be specified as largest, and in which case, the largest element will not be measured; with reference to the YAML file given in Listing 90, we can run the command
latexindent.pl tabular-DM.tex -l=dontMeasure1.yaml
and receive the output given in Listing 89.
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure: largest
lookForChildCodeBlocks: 0
We note that the largest column entries have not contributed to the measuring routine.
The dontMeasure field can also be specified in the form demonstrated in Listing 92. On running the following commands,
latexindent.pl tabular-DM.tex -l=dontMeasure2.yaml
we receive the output in Listing 91.
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure:
- aaaaaa
- bbbbb
- ccc
- dd
We note that in Listing 92 we have specified entries not to be measured, one entry per line.
The dontMeasure field can also be specified in the forms demonstrated in Listing 94 and Listing 95. Upon running the commands
latexindent.pl tabular-DM.tex -l=dontMeasure3.yaml
latexindent.pl tabular-DM.tex -l=dontMeasure4.yaml
we receive the output given in Listing 93
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure:
-
this: aaaaaa
applyTo: cell
-
this: bbbbb
- ccc
- dd
lookForAlignDelims:
tabular:
dontMeasure:
-
regex: [a-z]
applyTo: cell
We note that in:
Listing 94 we have specified entries not to be measured, each one has a string in the
thisfield, together with an optional specification ofapplyToascell;Listing 95 we have specified entries not to be measured as a regular expression using the
regexfield, together with an optional specification ofapplyToascellfield, together with an optional specification ofapplyToascell.
In both cases, the default value of applyTo is cell, and does not need to be specified.
We may also specify the applyTo field as row, a demonstration of which is given in Listing 97; upon running
latexindent.pl tabular-DM.tex -l=dontMeasure5.yaml
we receive the output in Listing 96.
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure:
-
this: aaaaaa&bbbbb&ccc&dd\\
applyTo: row
Finally, the applyTo field can be specified as row, together with a regex expression. For example, for the settings given in Listing 99, upon running
latexindent.pl tabular-DM.tex -l=dontMeasure6.yaml
we receive the output in Listing 98.
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure:
-
regex: [a-z]
applyTo: row
3.5.3. lookForAlignDelims: the delimiterRegEx and delimiterJustification feature
The delimiter alignment will, by default, align code blocks at the ampersand character. The behaviour is controlled by the delimiterRegEx field within lookForAlignDelims; the default value is (?<!\\)(&)*, which can be read as: an ampersand, as long as it is not immediately preceded by a backslash.
Warning
Important: note the ‘capturing’ parenthesis in the (&) which are necessary; if you intend to customise this field, then be sure to include them appropriately.
We demonstrate how to customise this with respect to the code given in Listing 100; the default output from latexindent.pl is given in Listing 101.
\begin{tabbing}
aa \= bb \= cc \= dd \= ee \\
\>2\> 1 \> 7 \> 3 \\
\>3 \> 2\>8\> 3 \\
\>4 \>2 \\
\end{tabbing}
\begin{tabbing}
aa \= bb \= cc \= dd \= ee \\
\>2\> 1 \> 7 \> 3 \\
\>3 \> 2\>8\> 3 \\
\>4 \>2 \\
\end{tabbing}
Let’s say that we wish to align the code at either the \= or \>. We employ the settings given in Listing 103 and run the command
latexindent.pl tabbing.tex -l=delimiterRegEx1.yaml
to receive the output given in Listing 102.
\begin{tabbing}
aa \= bb \= cc \= dd \= ee \\
\> 2 \> 1 \> 7 \> 3 \\
\> 3 \> 2 \> 8 \> 3 \\
\> 4 \> 2 \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(\\(?:=|>))'
We note that:
in Listing 102 the code has been aligned, as intended, at both the
\=and\>;in Listing 103 we have heeded the warning and captured the expression using grouping parenthesis, specified a backslash using
\\and said that it must be followed by either=or>.
We can explore delimiterRegEx a little further using the settings in Listing 105 and run the command
latexindent.pl tabbing.tex -l=delimiterRegEx2.yaml
to receive the output given in Listing 104.
\begin{tabbing}
aa \= bb \= cc \= dd \= ee \\
\> 2 \> 1 \> 7 \> 3 \\
\> 3 \> 2 \> 8 \> 3 \\
\> 4 \> 2 \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(\\>)'
We note that only the \> have been aligned.
Of course, the other lookForAlignDelims options can be used alongside the delimiterRegEx; regardless of the type of delimiter being used (ampersand or anything else), the fields from Listing 58 remain the same; for example, using the settings in Listing 107, and running
latexindent.pl tabbing.tex -l=delimiterRegEx3.yaml
to receive the output given in Listing 106.
\begin{tabbing}
aa\=bb\=cc\=dd\=ee \\
\>2 \>1 \>7 \>3 \\
\>3 \>2 \>8 \>3 \\
\>4 \>2 \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(\\(?:=|>))'
spacesBeforeAmpersand: 0
spacesAfterAmpersand: 0
It is possible that delimiters specified within delimiterRegEx can be of different lengths. Consider the file in Listing 108, and associated YAML in Listing 110. Note that the Listing 110 specifies the option for the delimiter to be either # or \>, which are different lengths. Upon running the command
latexindent.pl tabbing1.tex -l=delimiterRegEx4.yaml -o=+-mod4
we receive the output in Listing 109.
\begin{tabbing}
1#22\>333\\
xxx#aaa#yyyyy\\
.##&\\
\end{tabbing}
\begin{tabbing}
1 # 22 \> 333 \\
xxx # aaa # yyyyy \\
. # # & \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(#|\\>)'
You can set the delimiter justification as either left (default) or right, which will only have effect when delimiters in the same column have different lengths. Using the settings in Listing 112 and running the command
latexindent.pl tabbing1.tex -l=delimiterRegEx5.yaml -o=+-mod5
gives the output in Listing 111.
\begin{tabbing}
1 # 22 \> 333 \\
xxx # aaa # yyyyy \\
. # # & \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(#|\\>)'
delimiterJustification: right
Note that in Listing 111 the second set of delimiters have been right aligned – it is quite subtle!
3.5.4. lookForAlignDelims: lookForChildCodeBlocks
There may be scenarios in which you would prefer to instruct latexindent.pl not to search for child blocks; in which case setting lookForChildCodeBlocks to 0 may be a good way to proceed.
Using the settings from Listing 90 on the file in Listing 113 and running the command
latexindent.pl tabular-DM-1.tex -l=dontMeasure1.yaml -o=+-mod1
gives the output in Listing 114.
\begin{tabular}{cc}
1&2\only<2->{\\
3&4}
\end{tabular}
\begin{tabular}{cc}
1 & 2\only<2->{ \\
3 & 4}
\end{tabular}
We can improve the output from Listing 114 by employing the settings in Listing 116
latexindent.pl tabular-DM-1.tex -l=dontMeasure1a.yaml -o=+-mod1a
which gives the output in Listing 116.
\begin{tabular}{cc}
1 & 2\only<2->{ \\
3 & 4}
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure: largest
lookForChildCodeBlocks: 0
3.5.5. lookForAlignDelims: alignContentAfterDoubleBackSlash
You can instruct latexindent to align content after the double back slash. See also Section 4.3.2.
We consider the file in Listing 117, and the default output given in Listing 118.
\begin{tabular}{cc}
1 & 2
\\ aa & bbb
\\ ccc&ddd
\end{tabular}
\begin{tabular}{cc}
1 & 2
\\ aa & bbb
\\ ccc&ddd
\end{tabular}
Using the settings given in Listing 120 and running
latexindent.pl -s tabular5.tex -l alignContentAfterDBS1 -o=+-mod1
gives the output in Listing 119.
\begin{tabular}{cc}
1 & 2
\\ aa & bbb
\\ ccc & ddd
\end{tabular}
lookForAlignDelims:
tabular:
alignContentAfterDoubleBackSlash: 1
When using the alignContentAfterDoubleBackSlash feature, then you can also specify how many spaces to insert after the double backslash; the default is 1. Starting from Listing 117 and using the the settings given in Listing 122
latexindent.pl -s tabular5.tex -l alignContentAfterDBS2 -o=+-mod2
gives the output in Listing 121.
\begin{tabular}{cc}
1 & 2
\\ aa & bbb
\\ ccc & ddd
\end{tabular}
lookForAlignDelims:
tabular:
alignContentAfterDoubleBackSlash: 1
spacesAfterDoubleBackSlash: 3
3.5.6. lookForAlignDelims: other
As of Version 3.0, the alignment routine works on mandatory and optional arguments within commands, and also within ‘special’ code blocks (see specialBeginEnd on page yaml:specialBeginEnd).
Assuming that you have a command called \matrix and that it is populated within lookForAlignDelims (which it is, by default), and that you run the command
latexindent.pl matrix1.tex
then the before-and-after results shown in Listing 123 and Listing 124 are achievable by default.
\matrix [
1&2 &3\\
4&5&6]{
7&8 &9\\
10&11&12
}
\matrix [
1 & 2 & 3 \\
4 & 5 & 6]{
7 & 8 & 9 \\
10 & 11 & 12
}
If you have blocks of code that you wish to align at the & character that are not wrapped in, for example, \begin{tabular} … \end{tabular}, then you can use the mark up illustrated in Listing 125; the default output is shown in Listing 126. Note that the %* must be next to each other, but that there can be any number of spaces (possibly none) between the * and \begin{tabular}; note also that you may use any environment name
that you have specified in lookForAlignDelims.
%* \begin{tabular}
1 & 2 & 3 & 4 \\
5 & & 6 & \\
%* \end{tabular}
%* \begin{tabular}
1 & 2 & 3 & 4 \\
5 & & 6 & \\
%* \end{tabular}
With reference to Table 2 and the, yet undiscussed, fields of noAdditionalIndent and indentRules (see Section 3.9), these comment-marked blocks are considered environments.
3.6. Indent after items, specials and headings
- indentAfterItems:fields
The environment names specified in indentAfterItems tell latexindent.pl to look for \item commands; if these switches are set to 1 then indentation will be performed so as indent the code after each item. A demonstration is given in Listing 128 and Listing 129
179indentAfterItems:
180 itemize: 1
181 itemize*: 1
182 enumerate: 1
183 enumerate*: 1
184 description: 1
185 description*: 1
186 list: 1
\begin{itemize}
\item some text here
some more text here
some more text here
\item another item
some more text here
\end{itemize}
\begin{itemize}
\item some text here
some more text here
some more text here
\item another item
some more text here
\end{itemize}
If you have your own item commands (perhaps you prefer to use myitem, for example) then you can put adjust itemRegEx in the fineTuning field, discussed in Section 7.3… describe:: specialBeginEnd:fields
The fields specified
in specialBeginEnd are, in their default state, focused on math mode begin and end statements, but there is no requirement for this to be the case; Listing 130 shows the default settings of specialBeginEnd.
189specialBeginEnd:
190 - amalgamate: 1
191 - name: displayMath
192 begin: (?<!\\)\\\[ # \[ but *not* \\[
193 end: \\\] # \]
194 - name: inlineMath
195 begin: (?<!\$)(?<!\\)\$(?!\$) # $ but *not* \$ or $$
196 end: (?<!\\)\$(?!\$) # $ but *not* \$ or $$
197 - name: displayMathTeX
198 begin: \$\$ # $$
199 end: \$\$ # $$
200 lookForThis: 1 # 0/1, default 1
201 nested: 0 # 0/1, default 0
The field displayMath represents \[...\], inlineMath represents $...$ and displayMathTex represents $$...$$. You can, of course, rename these in your own YAML files (see Section 10.8.2); indeed, you might like to set up your own special begin and end statements.
A demonstration of the before-and-after results are shown in Listing 131 and Listing 132; explicitly, running the command
latexindent.pl special1.tex -o=+-default
gives the output given in Listing 132.
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
For each field, lookForThis is set to 1 by default, which means that latexindent.pl will look for this pattern; you can tell latexindent.pl not to look for the pattern, by setting lookForThis to 0.
For example, consider the file shown in Listing 133.
\begin{equation}
\left[
\sqrt{
a+b
}
\right]
\end{equation}
Now consider the YAML file shown in Listing 134
specialBeginEnd:
- name: leftRightSquare
begin: \\left\[
end: \\right\]
fineTuning:
commands:
name: |-
(?x)
(?! # NOT
(?: #
begin #
| #
end #
| #
left #
| #
right #
) #
)[+a-zA-Z@*0-9_:]+
Upon running the following commands
latexindent.pl specialLR.tex -l=specialsLeftRight.yaml
we receive the output in Listing 135.
\begin{equation}
\left[
\sqrt{
a+b
}
\right]
\end{equation}
You can, optionally, specify the middle field for anything that you specify in specialBeginEnd.
For example, let’s consider the .tex file in Listing 136.
\If
something 0
\ElsIf
something 1
\ElsIf
something 2
\ElsIf
something 3
\Else
something 4
\EndIf
Upon saving the YAML settings in Listing 138 and Listing 140 and running the commands
latexindent.pl special2.tex -l=middle
latexindent.pl special2.tex -l=middle1
then we obtain the output given in Listing 137 and Listing 139.
\If
something 0
\ElsIf
something 1
\ElsIf
something 2
\ElsIf
something 3
\Else
something 4
\EndIf
specialBeginEnd:
- name: If
begin: '\\If'
middle: '\\ElsIf'
end: '\\EndIf'
lookForThis: 1
\If
something 0
\ElsIf
something 1
\ElsIf
something 2
\ElsIf
something 3
\Else
something 4
\EndIf
specialBeginEnd:
- name: If
begin: '\\If'
middle:
- '\\ElsIf'
- '\\Else'
end: '\\EndIf'
lookForThis: 1
We note that:
in Listing 137 the bodies of each of the
Elsifstatements have been indented appropriately;the
Elsestatement has not been indented appropriately in Listing 137 – read on!we have specified multiple settings for the
middlefield using the syntax demonstrated in Listing 140 so that the body of theElsestatement has been indented appropriately in Listing 139.
You may need these fields in your own YAML files (see Section 10.8.2), if you use popular algorithm packages such as algorithms, algorithm2e or algpseudocode, etc.
For example, let’s consider the .tex file in Listing 141.
\For{$n = 1, \dots, 10$}
\State body
\EndFor
\FOR{for 1}
\FOR{for 2}
\FOR{for 3}
\STATE{some statement.}
\ENDFOR
\ENDFOR
\ENDFOR
\If{$quality\ge 9$}
\State $a\gets perfect$
\ElsIf{$quality\ge 7$}
\State $a\gets good$
\Else
\While{$i\le n$}
\State $i\gets i+1$
\EndWhile
\EndIf
\ForAll{$n \in \{1, \dots, 10\}$}
\State body
\Loop
\State body
\EndLoop
\State $i\gets 1$
\Repeat
\State $i\gets i+1$
\Until{$i>n$}
\EndFor
\Function{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
\While{$r\not=0$}\Comment{We have the answer if r is 0}
\State $r\gets a\bmod b$
\EndWhile
\State \textbf{return} $b$\Comment{The gcd is b}
\EndFunction
Upon saving the YAML settings in Listing 143 and running the command
latexindent.pl -l=algo.yaml specialAlgo.tex
then we obtain the output given in Listing 142.
\For{$n = 1, \dots, 10$}
\State body
\EndFor
\FOR{for 1}
\FOR{for 2}
\FOR{for 3}
\STATE{some statement.}
\ENDFOR
\ENDFOR
\ENDFOR
\If{$quality\ge 9$}
\State $a\gets perfect$
\ElsIf{$quality\ge 7$}
\State $a\gets good$
\Else
\While{$i\le n$}
\State $i\gets i+1$
\EndWhile
\EndIf
\ForAll{$n \in \{1, \dots, 10\}$}
\State body
\Loop
\State body
\EndLoop
\State $i\gets 1$
\Repeat
\State $i\gets i+1$
\Until{$i>n$}
\EndFor
\Function{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
\While{$r\not=0$}\Comment{We have the answer if r is 0}
\State $r\gets a\bmod b$
\EndWhile
\State \textbf{return} $b$\Comment{The gcd is b}
\EndFunction
specialBeginEnd:
- name: ForStatement
begin: \\For\{[^}]+?\}
end: \\EndFor
- name: FORStatement
begin: \\FOR\{[^}]+?\}
end: \\ENDFOR
nested: 1
- name: WhileStatement
begin: \\While\{[^}]+?\}
end: \\EndWhile
nested: 1
- name: WHILEStatement
begin: \\WHILE\{[^}]+?\}
end: \\ENDWHILE
- name: ForAllStatement
begin: \\ForAll\{[^}]+?\}
end: \\EndFor
nested: 1
- name: LoopStatement
begin: \\Loop
end: \\EndLoop
- name: RepeatStatement
begin: \\Repeat
end: \\Until\{[^}]+?\}
- name: ProcedureStatement
begin: \\Procedure\{[^}]+?\}\{[^}]+?\}
end: \\EndProcedure
- name: FunctionStatement
begin: \\Function\{[^}]+?\}\{[^}]+?\}
end: \\EndFunction
- name: IfStatement
begin: \\If\{[^}]+?\}
middle:
- \\Else
- \\ElsIf\{[^}]+?\}
end: \\EndIf
- name: IFStatement
begin: \\IF\{[^}]+?\}
middle:
- \\ELSE
- \\ELSIF\{[^}]+?\}
end: \\ENDIF
- name: inlineMath
lookForThis: 0
fineTuning:
commands:
name: |-
(?x)
(?!
(?:
begin
|
end
|
ElsIf
|
EndFor
|
ENDFOR
|
EndWhile
|
ENDWHILE
|
Function
|
For
|
FOR
|
If
|
IF
|
Loop
|
Procedure
|
Repeat
|
While
)
)[+a-zA-Z@*0-9_:]+
You may specify fields in specialBeginEnd to be treated as verbatim code blocks by changing lookForThis to be verbatim.
For example, beginning with the code in Listing 144 and the YAML in Listing 145, and running
latexindent.pl special3.tex -l=special-verb1
then the output in Listing 144 is unchanged.
\[
special code
blocks
can be
treated
as verbatim\]
specialBeginEnd:
- name: displayMath
lookForThis: verbatim
We can combine the specialBeginEnd with the lookForAlignDelims feature.
We begin with the code in Listing 146.
\begin{tikzpicture}
\path (A) edge node {0,1,L}(B)
edge node {1,1,R} (C)
(B) edge [loop above]node {1,1,L}(B)
edge node {0,1,L}(C)
(C) edge node {0,1,L}(D)
edge [bend left]node {1,0,R}(E)
(D) edge[loop below] node {1,1,R}(D)
edge node {0,1,R}(A)
(E) edge[bend left] node {1,0,R} (A);
\end{tikzpicture}
Let’s assume that our goal is to align the code at the edge and node text; we employ the code given in Listing 148 and run the command
latexindent.pl special-align.tex -l edge-node1.yaml -o=+-mod1
to receive the output in Listing 147.
\begin{tikzpicture}
\path (A) edge node {0,1,L}(B)
edge node {1,1,R} (C)
(B) edge [loop above] node {1,1,L}(B)
edge node {0,1,L}(C)
(C) edge node {0,1,L}(D)
edge [bend left] node {1,0,R}(E)
(D) edge [loop below] node {1,1,R}(D)
edge node {0,1,R}(A)
(E) edge [bend left] node {1,0,R} (A);
\end{tikzpicture}
specialBeginEnd:
- name: path
begin: '\\path'
end: ';'
lookForAlignDelims:
path:
delimiterRegEx: '(edge|node)'
lookForChildCodeBlocks: 0
The output in Listing 147 is not quite ideal. We can tweak the settings within Listing 148 in order to improve the output; in particular, we employ the code in Listing 150 and run the command
latexindent.pl special-align.tex -l edge-node2.yaml -o=+-mod2
to receive the output in Listing 149.
\begin{tikzpicture}
\path (A) edge node {0,1,L} (B)
edge node {1,1,R} (C)
(B) edge [loop above] node {1,1,L} (B)
edge node {0,1,L} (C)
(C) edge node {0,1,L} (D)
edge [bend left] node {1,0,R} (E)
(D) edge [loop below] node {1,1,R} (D)
edge node {0,1,R} (A)
(E) edge [bend left] node {1,0,R} (A);
\end{tikzpicture}
specialBeginEnd:
-
name: path
begin: '\\path'
end: ';'
lookForAlignDelims:
path:
delimiterRegEx: '(edge|node\h*\{[0-9,A-Z]+\})'
lookForChildCodeBlocks: 0
The lookForThis field can be considered optional; by default, it is assumed to be 1, which is demonstrated in Listing 150.
Referencing Listing 130 we see that each of the specialBeginEnd fields can optionally accept the body field. If the body field is omitted, then latexindent.pl uses a value that means
anything except one of the begin statements from
specialBeginEnd.
In general, it is usually not necessary to specify the body field, but let’s detail an example just for reference.
We begin with the example in Listing 151
$
a
+
(
b + c
-
(
d
)
)
=
e
$
and
$
f + g = h
$
Using the settings in Listing 153 and running the command
latexindent.pl special-body.tex -l=special-nested1.yaml
gives the output in Listing 152.
$
a
+
(
b + c
-
(
d
)
)
=
e
$
and
$
f + g = h
$
defaultIndent: " "
specialBeginEnd:
- name: parentheses
begin: \(
end: \)
nested: 1
We note that the output in Listing 152 is as we would expect, as the nested field has been specified in Listing 153.
- indentAfterHeadings:fields
This field enables the user to specify indentation rules that take effect after heading commands such as \part, \chapter, \section, \subsection*, or indeed any user-specified command written in this field.
211indentAfterHeadings:
212 part:
213 lookForThis: 0
214 level: 1
215 chapter:
216 lookForThis: 0
217 level: 2
218 section:
219 lookForThis: 0
220 level: 3
The default settings do not place indentation after a heading, but you can easily switch them on by changing lookForThis from 0 to 1. The level field tells latexindent.pl the hierarchy of the heading structure in your document. You might, for example, like to have both section and subsection set with level: 3 because you do not want the indentation to go too deep.
You can add any of your own custom heading commands to this field, specifying the level as appropriate. You can also specify your own indentation in indentRules (see Section 3.9); you will find the default indentRules contains chapter: " " which tells latexindent.pl simply to use a space character after chapter headings (once indent is set to 1 for chapter).
For example, assuming that you have the code in Listing 156 saved into headings1.yaml, and that you have the text from Listing 155 saved into headings1.tex.
\subsection{subsection title}
subsection text
subsection text
\paragraph{paragraph title}
paragraph text
paragraph text
\paragraph{paragraph title}
paragraph text
paragraph text
indentAfterHeadings:
subsection:
lookForThis: 1
level: 1
paragraph:
lookForThis: 1
level: 2
If you run the command
latexindent.pl headings1.tex -l=headings1.yaml
then you should receive the output given in Listing 157.
\subsection{subsection title}
subsection text
subsection text
\paragraph{paragraph title}
paragraph text
paragraph text
\paragraph{paragraph title}
paragraph text
paragraph text
\subsection{subsection title}
subsection text
subsection text
\paragraph{paragraph title}
paragraph text
paragraph text
\paragraph{paragraph title}
paragraph text
paragraph text
Now say that you modify the YAML from Listing 156 so that the paragraph level is 1; after running
latexindent.pl headings1.tex -l=headings1.yaml
you should receive the code given in Listing 158; notice that the paragraph and subsection are at the same indentation level.
- maximumIndentation:horizontal space
You can control the maximum indentation given to your file by specifying the maximumIndentation field as horizontal space (but not including tabs). This feature uses the Text::Tabs module (“Text::Tabs Perl Module” n.d.), and is off by default.
For example, consider the example shown in Listing 159 together with the default output shown in Listing 160.
\begin{one}
one
\begin{two}
two
\begin{three}
three
\begin{four}
four
\end{four}
\end{three}
\end{two}
\end{one}
\begin{one}
one
\begin{two}
two
\begin{three}
three
\begin{four}
four
\end{four}
\end{three}
\end{two}
\end{one}
Now say that, for example, you have the max-indentation1.yaml from Listing 162 and that you run the following command:
latexindent.pl mult-nested.tex -l=max-indentation1
You should receive the output shown in Listing 161.
\begin{one}
one
\begin{two}
two
\begin{three}
three
\begin{four}
four
\end{four}
\end{three}
\end{two}
\end{one}
maximumIndentation: " "
Comparing the output in Listing 160 and Listing 161 we notice that the (default) tabs of indentation have been replaced by a single space.
In general, when using the maximumIndentation feature, any leading tabs will be replaced by equivalent spaces except, of course, those found in verbatimEnvironments (see Listing 35) or noIndentBlock (see Listing 41).
3.7. Arguments and the strings allowed between them
The strings allowed between arguments for commands, namedGroupingBracesBrackets, keyEqualsValuesBracesBrackets and UnNamedGroupingBracesBrackets are controlled by fineTuning; specific demonstrations are given in Section 7.4.
3.8. The code blocks known to latexindent.pl
As of Version 3.0, latexindent.pl processes documents using code blocks; each of these are shown in Table 2.
Code block |
characters allowed in name |
example |
|---|---|---|
environments |
|
|
optionalArguments |
inherits name from parent (e.g environment name) |
|
mandatoryArguments |
inherits name from parent (e.g environment name) |
|
commands |
|
|
keyEqualsValuesBracesBrackets |
|
|
namedGroupingBracesBrackets |
|
|
UnNamedGroupingBracesBrackets |
No name! |
|
ifElseFi |
|
|
items |
User specified, see Listing 127 |
|
specialBeginEnd |
User specified, see Listing 130 |
|
afterHeading |
User specified, see Listing 154 |
|
filecontents |
User specified, see Listing 51 |
|
We will refer to these code blocks in what follows. Note that the fine tuning of the definition of the code blocks detailed in Table 2 is discussed in Section 7.
3.9. noAdditionalIndent and indentRules
latexindent.pl operates on files by looking for code blocks, as detailed in Section 3.8; for each type of code block in Table 2 (which we will call a <thing> in what follows) it searches YAML fields for information in the following order:
noAdditionalIndentfor the name of the current <thing>;indentRulesfor the name of the current <thing>;noAdditionalIndentGlobalfor the type of the current <thing>;indentRulesGlobalfor the type of the current <thing>.
Using the above list, the first piece of information to be found will be used; failing that, the value of defaultIndent is used. If information is found in multiple fields, the first one according to the list above will be used; for example, if information is present in both indentRules and in noAdditionalIndentGlobal, then the information from indentRules takes priority.
We now present details for the different type of code blocks known to latexindent.pl, as detailed in Table 2; for reference, there follows a list of the code blocks covered.
3.9.1. Environments and their arguments
There are a few different YAML switches governing the indentation of environments; let’s start with the code shown in Listing 163.
\begin{outer}
\begin{myenv}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
- noAdditionalIndent:fields
If we do not wish myenv to receive any additional indentation, we have a few choices available to us, as demonstrated in Listing 164 and Listing 165.
noAdditionalIndent:
myenv: 1
noAdditionalIndent:
myenv:
body: 1
On applying either of the following commands,
latexindent.pl myenv.tex -l myenv-noAdd1.yaml
latexindent.pl myenv.tex -l myenv-noAdd2.yaml
we obtain the output given in Listing 166; note in particular that the environment myenv has not received any additional indentation, but that the outer environment has still received indentation.
\begin{outer}
\begin{myenv}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
Upon changing the YAML files to those shown in Listing 167 and Listing 168, and running either
latexindent.pl myenv.tex -l myenv-noAdd3.yaml
latexindent.pl myenv.tex -l myenv-noAdd4.yaml
we obtain the output given in Listing 169.
noAdditionalIndent:
myenv: 0
noAdditionalIndent:
myenv:
body: 0
\begin{outer}
\begin{myenv}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
Let’s now allow myenv to have some optional and mandatory arguments, as in Listing 170.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
Upon running
latexindent.pl -l=myenv-noAdd1.yaml myenv-args.tex
we obtain the output shown in Listing 171; note that the optional argument, mandatory argument and body all have received no additional indent. This is because, when noAdditionalIndent is specified in ‘scalar’ form (as in Listing 164), then all parts of the environment (body, optional and mandatory arguments) are assumed to want no additional indent.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
We may customise noAdditionalIndent for optional and mandatory arguments of the myenv environment, as shown in, for example, Listing 172 and Listing 173.
noAdditionalIndent:
myenv:
body: 0
optionalArguments: 1
mandatoryArguments: 0
noAdditionalIndent:
myenv:
body: 0
optionalArguments: 0
mandatoryArguments: 1
Upon running
latexindent.pl myenv.tex -l myenv-noAdd5.yaml
latexindent.pl myenv.tex -l myenv-noAdd6.yaml
we obtain the respective outputs given in Listing 174 and Listing 175. Note that in Listing 174 the text for the optional argument has not received any additional indentation, and that in Listing 175 the mandatory argument has not received any additional indentation; in both cases, the body has not received any additional indentation.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
- indentRules:fields
We may also specify indentation rules for environment code blocks using the indentRules field; see, for example, Listing 176 and Listing 177.
indentRules:
myenv: " "
indentRules:
myenv:
body: " "
On applying either of the following commands,
latexindent.pl myenv.tex -l myenv-rules1.yaml
latexindent.pl myenv.tex -l myenv-rules2.yaml
we obtain the output given in Listing 178; note in particular that the environment myenv has received one tab (from the outer environment) plus three spaces from Listing 176 or Listing 177.
\begin{outer}
\begin{myenv}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
If you specify a field in indentRules using anything other than horizontal space, it will be ignored.
Returning to the example in Listing 170 that contains optional and mandatory arguments. Upon using Listing 176 as in
latexindent.pl myenv-args.tex -l=myenv-rules1.yaml
we obtain the output in Listing 179; note that the body, optional argument and mandatory argument of myenv have all received the same customised indentation.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
You can specify different indentation rules for the different features using, for example, Listing 180 and Listing 181
indentRules:
myenv:
body: " "
optionalArguments: " "
indentRules:
myenv:
body: " "
mandatoryArguments: "\t\t"
After running
latexindent.pl myenv-args.tex -l myenv-rules3.yaml
latexindent.pl myenv-args.tex -l myenv-rules4.yaml
then we obtain the respective outputs given in Listing 182 and Listing 183.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
Note that in Listing 182, the optional argument has only received a single space of indentation, while the mandatory argument has received the default (tab) indentation; the environment body has received three spaces of indentation.
In Listing 183, the optional argument has received the default (tab) indentation, the mandatory argument has received two tabs of indentation, and the body has received three spaces of indentation.
- noAdditionalIndentGlobal:fields
Assuming that your environment name is not found within neither noAdditionalIndent nor indentRules, the next place that latexindent.pl will look is noAdditionalIndentGlobal, and in particular for the environments key (see Listing 184).
260noAdditionalIndentGlobal:
261 environments: 0 # 0/1
Let’s say that you change the value of environments to 1 in Listing 184, and that you run
latexindent.pl myenv-args.tex -l env-noAdditionalGlobal.yaml
latexindent.pl myenv-args.tex -l myenv-rules1.yaml,env-noAdditionalGlobal.yaml
The respective output from these two commands are in Listing 185 and Listing 186; in Listing 185 notice that both environments receive no additional indentation but that the arguments of myenv still do receive indentation. In Listing 186 notice that the outer environment does not receive additional indentation, but because of the settings from myenv-rules1.yaml
(in Listing 176), the myenv environment still does receive indentation.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
In fact, noAdditionalIndentGlobal also contains keys that control the indentation of optional and mandatory arguments; on referencing Listing 187 and Listing 188
noAdditionalIndentGlobal:
optionalArguments: 1
noAdditionalIndentGlobal:
mandatoryArguments: 1
we may run the commands
latexindent.pl myenv-args.tex -local opt-args-no-add-glob.yaml
latexindent.pl myenv-args.tex -local mand-args-no-add-glob.yaml
which produces the respective outputs given in Listing 189 and Listing 190. Notice that in Listing 189 the optional argument has not received any additional indentation, and in Listing 190 the mandatory argument has not received any additional indentation.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
- indentRulesGlobal:fields
The final check that latexindent.pl will make is to look for indentRulesGlobal as detailed in Listing 191.
275indentRulesGlobal:
276 environments: 0 # 0/h-space
If you change the environments field to anything involving horizontal space, say " ", and then run the following commands
latexindent.pl myenv-args.tex -l env-indentRules.yaml
latexindent.pl myenv-args.tex -l myenv-rules1.yaml,env-indentRules.yaml
then the respective output is shown in Listing 192 and Listing 193. Note that in Listing 192, both the environment blocks have received a single-space indentation, whereas in Listing 193 the outer environment has received single-space indentation (specified by indentRulesGlobal), but myenv has received " ", as specified by the
particular indentRules for myenv Listing 176.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
You can specify indentRulesGlobal for both optional and mandatory arguments, as detailed in Listing 194 and Listing 195
indentRulesGlobal:
optionalArguments: "\t\t"
indentRulesGlobal:
mandatoryArguments: "\t\t"
Upon running the following commands
latexindent.pl myenv-args.tex -local opt-args-indent-rules-glob.yaml
latexindent.pl myenv-args.tex -local mand-args-indent-rules-glob.yaml
we obtain the respective outputs in Listing 196 and Listing 197. Note that the optional argument in Listing 196 has received two tabs worth of indentation, while the mandatory argument has done so in Listing 197.
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
\begin{outer}
\begin{myenv}[%
optional argument text
optional argument text]%
{ mandatory argument text
mandatory argument text}
body of environment
body of environment
body of environment
\end{myenv}
\end{outer}
3.9.2. Environments with items
With reference to Listing 127, some commands may contain item commands; for the purposes of this discussion, we will use the code from Listing 128.
Assuming that you’ve populated itemNames with the name of your item, you can put the item name into noAdditionalIndent as in Listing 198, although a more efficient approach may be to change the relevant field in itemNames to 0.
Similarly, you can customise the indentation that your item receives using indentRules, as in Listing 199
noAdditionalIndent:
item: 1
indentRules:
item: " "
Upon running the following commands
latexindent.pl items1.tex -local item-noAdd1.yaml
latexindent.pl items1.tex -local item-rules1.yaml
the respective outputs are given in Listing 200 and Listing 201; note that in Listing 200 that the text after each item has not received any additional indentation, and in Listing 201, the text after each item has received a single space of indentation, specified by Listing 199.
\begin{itemize}
\item some text here
some more text here
some more text here
\item another item
some more text here
\end{itemize}
\begin{itemize}
\item some text here
some more text here
some more text here
\item another item
some more text here
\end{itemize}
Alternatively, you might like to populate noAdditionalIndentGlobal or indentRulesGlobal using the items key, as demonstrated in Listing 202 and Listing 203. Note that there is a need to ‘reset/remove’ the item field from indentRules in both cases (see the hierarchy description given on page sec:noadd-indent-rules) as the item command is a member of indentRules by default.
indentRules:
item: 0
noAdditionalIndentGlobal:
items: 1
indentRules:
item: 0
indentRulesGlobal:
items: " "
Upon running the following commands,
latexindent.pl items1.tex -local items-noAdditionalGlobal.yaml
latexindent.pl items1.tex -local items-indentRulesGlobal.yaml
the respective outputs from Listing 200 and Listing 201 are obtained; note, however, that all such item commands without their own individual noAdditionalIndent or indentRules settings would behave as in these listings.
3.9.3. Commands with arguments
Let’s begin with the simple example in Listing 204; when latexindent.pl operates on this file, the default output is shown in Listing 205.
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
As in the environment-based case (see Listing 164 and Listing 165) we may specify noAdditionalIndent either in ‘scalar’ form, or in ‘field’ form, as shown in Listing 206 and Listing 207
noAdditionalIndent:
mycommand: 1
noAdditionalIndent:
mycommand:
body: 1
After running the following commands,
latexindent.pl mycommand.tex -l mycommand-noAdd1.yaml
latexindent.pl mycommand.tex -l mycommand-noAdd2.yaml
we receive the respective output given in Listing 208 and Listing 209
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
Note that in Listing 208 that the ‘body’, optional argument and mandatory argument have all received no additional indentation, while in Listing 209, only the ‘body’ has not received any additional indentation. We define the ‘body’ of a command as any lines following the command name that include its optional or mandatory arguments.
We may further customise noAdditionalIndent for mycommand as we did in Listing 172 and Listing 173; explicit examples are given in Listing 210 and Listing 211.
noAdditionalIndent:
mycommand:
body: 0
optionalArguments: 1
mandatoryArguments: 0
noAdditionalIndent:
mycommand:
body: 0
optionalArguments: 0
mandatoryArguments: 1
After running the following commands,
latexindent.pl mycommand.tex -l mycommand-noAdd3.yaml
latexindent.pl mycommand.tex -l mycommand-noAdd4.yaml
we receive the respective output given in Listing 212 and Listing 213.
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
Attentive readers will note that the body of mycommand in both Listing 212 and Listing 213 has received no additional indent, even though body is explicitly set to 0 in both Listing 210 and Listing 211. This is because, by default, noAdditionalIndentGlobal for commands is set to 1 by default; this can be easily fixed as in Listing 214 and
Listing 215.
noAdditionalIndent:
mycommand:
body: 0
optionalArguments: 1
mandatoryArguments: 0
noAdditionalIndentGlobal:
commands: 0
noAdditionalIndent:
mycommand:
body: 0
optionalArguments: 0
mandatoryArguments: 1
noAdditionalIndentGlobal:
commands: 0
After running the following commands,
latexindent.pl mycommand.tex -l mycommand-noAdd5.yaml
latexindent.pl mycommand.tex -l mycommand-noAdd6.yaml
we receive the respective output given in Listing 216 and Listing 217.
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
\mycommand
{
mand arg text
mand arg text}
[
opt arg text
opt arg text
]
Both indentRules and indentRulesGlobal can be adjusted as they were for environment code blocks, as in Listing 180 and Listing 181 and Listing 191 and Listing 194 and Listing 195.
3.9.4. ifelsefi code blocks
Let’s use the simple example shown in Listing 218; when latexindent.pl operates on this file, the output as in Listing 219; note that the body of each of the \if statements have been indented, and that the \else statement has been accounted for correctly.
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
It is recommended to specify noAdditionalIndent and indentRules in the ‘scalar’ form only for these type of code blocks, although the ‘field’ form would work, assuming that body was specified. Examples are shown in Listing 220 and Listing 221.
noAdditionalIndent:
ifnum: 1
indentRules:
ifnum: " "
After running the following commands,
latexindent.pl ifelsefi1.tex -local ifnum-noAdd.yaml
latexindent.pl ifelsefi1.tex -l ifnum-indent-rules.yaml
we receive the respective output given in Listing 222 and Listing 223; note that in Listing 222, the ifnum code block has not received any additional indentation, while in Listing 223, the ifnum code block has received one tab and two spaces of indentation.
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
We may specify noAdditionalIndentGlobal and indentRulesGlobal as in Listing 224 and Listing 225.
noAdditionalIndentGlobal:
ifElseFi: 1
indentRulesGlobal:
ifElseFi: " "
Upon running the following commands
latexindent.pl ifelsefi1.tex -local ifelsefi-noAdd-glob.yaml
latexindent.pl ifelsefi1.tex -l ifelsefi-indent-rules-global.yaml
we receive the outputs in Listing 226 and Listing 227; notice that in Listing 226 neither of the ifelsefi code blocks have received indentation, while in Listing 227 both code blocks have received a single space of indentation.
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
\ifodd\radius
\ifnum\radius<14
\pgfmathparse{100-(\radius)*4};
\else
\pgfmathparse{200-(\radius)*3};
\fi\fi
We can further explore the treatment of ifElseFi code blocks in Listing 228, and the associated default output given in Listing 229; note, in particular, that the bodies of each of the ‘or statements’ have been indented.
\ifcase#1
zero%
\or
one%
\or
two%
\or
three%
\else
default
\fi
\ifcase#1
zero%
\or
one%
\or
two%
\or
three%
\else
default
\fi
Fine tuning of ifElseFi is demonstrated in Section 7.5.
3.9.5. specialBeginEnd code blocks
Let’s use the example from Listing 131 which has default output shown in Listing 132.
It is recommended to specify noAdditionalIndent and indentRules in the ‘scalar’ form for these type of code blocks, although the ‘field’ form would work, assuming that body was specified. Examples are shown in Listing 230 and Listing 231.
noAdditionalIndent:
displayMath: 1
indentRules:
displayMath: "\t\t\t"
After running the following commands,
latexindent.pl special1.tex -local displayMath-noAdd.yaml
latexindent.pl special1.tex -l displayMath-indent-rules.yaml
we receive the respective output given in Listing 232 and Listing 233; note that in Listing 232, the displayMath code block has not received any additional indentation, while in Listing 233, the displayMath code block has received three tabs worth of indentation.
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
We may specify noAdditionalIndentGlobal and indentRulesGlobal as in Listing 234 and Listing 235.
noAdditionalIndentGlobal:
specialBeginEnd: 1
indentRulesGlobal:
specialBeginEnd: " "
Upon running the following commands
latexindent.pl special1.tex -local special-noAdd-glob.yaml
latexindent.pl special1.tex -l special-indent-rules-global.yaml
we receive the outputs in Listing 236 and Listing 237; notice that in Listing 236 neither of the special code blocks have received indentation, while in Listing 237 both code blocks have received a single space of indentation.
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
The function $f$ has formula
\[
f(x)=x^2.
\]
If you like splitting dollars,
$
g(x)=f(2x)
$
3.9.6. afterHeading code blocks
Let’s use the example Listing 238 for demonstration throughout this . As discussed on page lst:headings1, by default latexindent.pl will not add indentation after headings.
\paragraph{paragraph
title}
paragraph text
paragraph text
On using the YAML file in Listing 240 by running the command
latexindent.pl headings2.tex -l headings3.yaml
we obtain the output in Listing 239. Note that the argument of paragraph has received (default) indentation, and that the body after the heading statement has received (default) indentation.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
If we specify noAdditionalIndent as in Listing 242 and run the command
latexindent.pl headings2.tex -l headings4.yaml
then we receive the output in Listing 241. Note that the arguments and the body after the heading of paragraph has received no additional indentation, because we have specified noAdditionalIndent in scalar form.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
noAdditionalIndent:
paragraph: 1
Similarly, if we specify indentRules as in Listing 244 and run analogous commands to those above, we receive the output in Listing 243; note that the body, mandatory argument and content after the heading of paragraph have all received three tabs worth of indentation.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
indentRules:
paragraph: "\t\t\t"
We may, instead, specify noAdditionalIndent in ‘field’ form, as in Listing 246 which gives the output in Listing 245.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
noAdditionalIndent:
paragraph:
body: 0
mandatoryArguments: 0
afterHeading: 1
Analogously, we may specify indentRules as in Listing 248 which gives the output in Listing 247; note that mandatory argument text has only received a single space of indentation, while the body after the heading has received three tabs worth of indentation.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
indentRules:
paragraph:
mandatoryArguments: " "
afterHeading: "\t\t\t"
Finally, let’s consider noAdditionalIndentGlobal and indentRulesGlobal shown in Listing 250 and Listing 252 respectively, with respective output in Listing 249 and Listing 251. Note that in Listing 250 the mandatory argument of paragraph has received a (default) tab’s worth of indentation, while the body after the heading has received no additional indentation. Similarly, in
Listing 251, the argument has received both a (default) tab plus two spaces of indentation (from the global rule specified in Listing 252), and the remaining body after paragraph has received just two spaces of indentation.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
noAdditionalIndentGlobal:
afterHeading: 1
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
lookForThis: 1
level: 1
indentRulesGlobal:
afterHeading: " "
3.9.7. The remaining code blocks
Referencing the different types of code blocks in Table 2, we have a few code blocks yet to cover; these are very similar to the commands code block type covered comprehensively in Section 3.9.3, but a small discussion defining these remaining code blocks is necessary.
3.9.7.1. keyEqualsValuesBracesBrackets
latexindent.pl defines this type of code block by the following criteria:
it has a name made up of the characters detailed in Table 2;
then an \(=\) symbol;
then at least one set of curly braces or square brackets (comments and line breaks allowed throughout).
See the keyEqualsValuesBracesBrackets: name field of the fine tuning section in Listing 559
An example is shown in Listing 253, with the default output given in Listing 254.
\pgfkeys{/tikz/.cd,
start coordinate/.initial={0,
\vertfactor},
}
\pgfkeys{/tikz/.cd,
start coordinate/.initial={0,
\vertfactor},
}
In Listing 254, note that the maximum indentation is three tabs, and these come from:
the
\pgfkeyscommand’s mandatory argument;the
start coordinate/.initialkey’s mandatory argument;the
start coordinate/.initialkey’s body, which is defined as any lines following the name of the key that include its arguments. This is the part controlled by the body field fornoAdditionalIndentand friends from page sec:noadd-indent-rules.
3.9.7.2. namedGroupingBracesBrackets
This type of code block is mostly motivated by tikz-based code; we define this code block as follows:
the name may contain the characters detailed in Table 2;
then at least one set of curly braces or square brackets (comments and line breaks allowed throughout).
See the NamedGroupingBracesBrackets: name field of the fine tuning section in Listing 559
A simple example is given in Listing 255, with default output in Listing 256.
\coordinate
child[grow=down]{
edge from parent [antiparticle]
node [above=3pt] {$C$}
}
\coordinate
child[grow=down]{
edge from parent [antiparticle]
node [above=3pt] {$C$}
}
In particular, latexindent.pl considers child and parent to be namedGroupingBracesBrackets 2. Referencing Listing 256, note that the maximum indentation is three tabs, and these come from:
the
child’s mandatory argument;the
child’s body, which is defined as any lines following the name of thenamedGroupingBracesBracketsthat include its arguments. This is the part controlled by the body field fornoAdditionalIndentand friends from page sec:noadd-indent-rules;the
parent’s body, which is defined as any lines following the name that include its arguments.
Consider the file given in Listing 257, together with its default output using the command
latexindent.pl named1.tex
is given in Listing 258.
\mycommand{
\rule{G -> +H[-G]CL}
\rule{H -> -G[+H]CL}
\rule{g -> +h[-g]cL}
\rule{h -> -g[+h]cL}
}
\mycommand{
\rule{G -> +H[-G]CL}
\rule{H -> -G[+H]CL}
\rule{g -> +h[-g]cL}
\rule{h -> -g[+h]cL}
}
Consider the file given in Listing 259, together with its default output using the command
latexindent.pl finetuning2.tex
is given in Listing 260.
@misc{ wikilatex,
author = "{Wikipedia contributors}",
title = "LaTeX --- {Wikipedia}{,}",
note = "[Online; accessed 3-March-2020]"
}
@misc{ wikilatex,
author = "{Wikipedia contributors}",
title = "LaTeX --- {Wikipedia}{,}",
note = "[Online; accessed 3-March-2020]"
}
Starting with the file in Listing 261 and running the command
latexindent.pl bib1.tex -o=+-mod1
gives the output in Listing 262.
@online{paulo,
title="arararule,indent.yaml",
author="PauloCereda",
date={2013-05-23},
urldate={2021-03-19},
keywords={contributor},}
@online{paulo,
title="arararule,indent.yaml",
author="PauloCereda",
date={2013-05-23},
urldate={2021-03-19},
keywords={contributor},}
Let’s assume that we would like to format the output so as to align the = symbols. Using the settings in Listing 264 and running the command
latexindent.pl bib1.bib -l bibsettings1.yaml -o=+-mod2
gives the output in Listing 263.
@online{paulo,
title = "arararule,indent.yaml",
author = "PauloCereda",
date = {2013-05-23},
urldate = {2021-03-19},
keywords = {contributor},}
lookForAlignDelims:
@online:
delimiterRegEx: '(=)'
lookForChildCodeBlocks: 0
noAdditionalIndentGlobal:
namedGroupingBracesBrackets: 1
we have populated the lookForAlignDelims field with the online command, and have used the delimiterRegEx, discussed in Section 3.5.3.
We can build upon Listing 264 for slightly more complicated bibliography files.
Starting with the file in Listing 265 and running the command
latexindent.pl bib2.bib -l bibsettings1.yaml -o=+-mod1
gives the output in Listing 266.
@online{cmh:videodemo,
title="Videodemonstrationofpl.latexindentonyoutube",
url="https://www.youtube.com/watch?v=wo38aaH2F4E&spfreload=10",
urldate={2017-02-21},
}
@online{cmh:videodemo,
title = "Videodemonstrationofpl.latexindentonyoutube",
url = "https://www.youtube.com/watch?v = wo38aaH2F4E&spfreload = 10",
urldate = {2017-02-21},
}
The output in Listing 266 is not ideal, as the = symbol within the url field has been incorrectly used as an alignment delimiter.
We address this by tweaking the delimiterRegEx field in Listing 267.
lookForAlignDelims:
@online:
delimiterRegEx: '(?<!v)(?<!spfreload)(=)'
Upon running the command
latexindent.pl bib2.bib -l bibsettings1.yaml,bibsettings2.yaml -o=+-mod2
we receive the desired output in Listing 268.
@online{cmh:videodemo,
title = "Videodemonstrationofpl.latexindentonyoutube",
url = "https://www.youtube.com/watch?v=wo38aaH2F4E&spfreload=10",
urldate = {2017-02-21},
}
With reference to Listing 267 we note that the delimiterRegEx has been adjusted so that = symbols are used as the delimiter, but only when they are not preceded by either v or spfreload.
3.9.7.3. UnNamedGroupingBracesBrackets
occur in a variety of situations; specifically, we define this type of code block as satisfying the following criteria:
it isn’t a
command,keyEqualsValuesBracesBracketsornamedGroupingBracesBracketsand it has at least one set of curly braces or square brackets (comments and line breaks allowed throughout).
An example is shown in Listing 269 with default output give in Listing 270.
\psforeach{\row}{%
{
{3,2.8,2.7,3,3.1}},%
{2.8,1,1.2,2,3},%
}
\psforeach{\row}{%
{
{3,2.8,2.7,3,3.1}},%
{2.8,1,1.2,2,3},%
}
Referencing Listing 270, there are two sets of unnamed braces. Note also that the maximum value of indentation is two tabs, and these come from:
the
\psforeachcommand’s mandatory argument;the first un-named braces mandatory argument.
Users wishing to customise the mandatory and/or optional arguments on a per-name basis for the UnNamedGroupingBracesBrackets should use always-un-named.
Starting with the file in Listing 271 we receive the default output in Listing 272.
{%
{1,2,3,4}
}[%
{1,2,3,4}
]
{%
{1,2,3,4}
}[%
{1,2,3,4}
]
We can customise the output using, for example, Listing 273 and running
latexindent.pl unnamed1 -l unnamed1.yaml unnamed1
gives the output in Listing 272
indentRules:
always-un-named:
body: ""
mandatoryArguments: " "
optionalArguments: " "
{%
{1,2,3,4}
}[%
{1,2,3,4}
]
3.9.8. Summary
Having considered all of the different types of code blocks, the functions of the fields given in Listing 275 and Listing 276 should now make sense.
260noAdditionalIndentGlobal:
261 environments: 0 # 0/1
262 commands: 1 # 0/1
263 optionalArguments: 0 # 0/1
264 mandatoryArguments: 0 # 0/1
265 ifElseFi: 0 # 0/1
266 items: 0 # 0/1
267 keyEqualsValuesBracesBrackets: 0 # 0/1
268 namedGroupingBracesBrackets: 0 # 0/1
269 UnNamedGroupingBracesBrackets: 1 # 0/1
270 specialBeginEnd: 0 # 0/1
271 afterHeading: 0 # 0/1
272
275indentRulesGlobal:
276 environments: 0 # 0/h-space
277 commands: 0 # 0/h-space
278 optionalArguments: 0 # 0/h-space
279 mandatoryArguments: 0 # 0/h-space
280 ifElseFi: 0 # 0/h-space
281 items: 0 # 0/h-space
282 keyEqualsValuesBracesBrackets: 0 # 0/h-space
283 namedGroupingBracesBrackets: 0 # 0/h-space
284 UnNamedGroupingBracesBrackets: 0 # 0/h-space
285 specialBeginEnd: 0 # 0/h-space
286 afterHeading: 0 # 0/h-space
287
“Text::Tabs Perl Module.” n.d. Accessed July 6, 2017. http://search.cpan.org/~muir/Text-Tabs+Wrap-2013.0523/lib.old/Text/Tabs.pm.
Voßkuhle, Michel. 2013. “Remove Trailing White Space.” November 10, 2013. https://github.com/cmhughes/latexindent.pl/pull/12.
XuehaiPan. 2021. “Verbatim Block Upgrade.” October 3, 2021. https://github.com/cmhughes/latexindent.pl/pull/290.