5. defaultSettings.yaml
latexindent.pl
loads its 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.
If you look in defaultSettings.yaml
you’ll find the switches 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.
47fileExtensionPreference:
48 .tex: 1
49 .sty: 2
50 .cls: 3
51 .bib: 4
Calling latexindent.pl myfile
with the (default) settings specified in Listing 52 means that the script will first look for myfile.tex
, then myfile.sty
, myfile.cls
, and finally myfile.bib
in order 1.
5.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
.
- logFilePreferences:fields
latexindent.pl
writes information to indent.log
, some of which can be customized by changing logFilePreferences
; see Listing 53. If you load your own user settings (see Section 4) then latexindent.pl
will detail them in indent.log
; you can choose not to have the details logged by switching showEveryYamlRead
to 0
. Once all of your settings have been loaded, you can see the amalgamated settings in the log file by switching
showAmalgamatedSettings
to 1
, if you wish.
91logFilePreferences:
92 showEveryYamlRead: 1
93 showAmalgamatedSettings: 0
94 showDecorationStartCodeBlockTrace: 0
95 showDecorationFinishCodeBlockTrace: 0
96 endLogFileWith: '--------------'
97 showGitHubInfoFooter: 1
98 Dumper:
99 Terse: 1
100 Indent: 1
101 Useqq: 1
102 Deparse: 1
103 Quotekeys: 0
104 Sortkeys: 1
105 Pair: " => "
When either of the trace
modes (see page page:traceswitch) are active, you will receive detailed information in indent.log
. You can specify character strings to appear before and after the notification of a found code block using, respectively, showDecorationStartCodeBlockTrace
and showDecorationFinishCodeBlockTrace
. A demonstration is given in Section 12.9.
The log file will end with the characters given in endLogFileWith
, and will report the GitHub
address of latexindent.pl
to the log file if showGitHubInfoFooter
is set to 1
.
Note: latexindent.pl
no longer uses the log4perl
module to handle the creation of the logfile.
Some of the options for Perl’s Dumper
module can be specified in Listing 53; see (“Data::Dumper Module” n.d.) and (“Data Dumper Demonstration” n.d.) for more information. These options will mostly be helpful for those calling latexindent.pl
with the -tt
option described in Section 3.2.
5.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 54.
109verbatimEnvironments:
110 verbatim: 1
111 lstlisting: 1
112 minted: 1
115verbatimCommands:
116 verb: 1
117 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 56 and Listing 57 are equivalent.
verbatimEnvironments:
latexcode: 1
latexcode*: 1
pythoncode: 1
pythoncode*: 1
verbatimEnvironments:
nameAsRegex:
name: '\w+code\*?'
lookForThis: 1
With reference to Listing 57:
the
name
field as specified here means any word followed by the word code, optionally followed by *;we have used
nameAsRegex
to identify this field, but you can use any description you like;the
lookForThis
field 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 6).
With reference to Listing 55, 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 58 and Listing 59 are equivalent.
verbatimCommands:
verbinline: 1
myinline: 1
verbatimCommands:
nameAsRegex:
name: '\w+inline'
lookForThis: 1
With reference to Listing 59:
the
name
field as specified here means any word followed by the word inline;we have used
nameAsRegex
to identify this field, but you can use any description you like;the
lookForThis
field 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 60.
122noIndentBlock:
123 noindent: 1
124 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 61 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 62 to demonstrate this feature.
some before text
this code
won't
be touched
by
latexindent.pl!
some after text
The settings given in Listing 63 and Listing 64 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 66.
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 63. 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 65 demonstrates setting lookForThis
to 0 (off); running the command
latexindent.pl -l noindent3.yaml noindent1
gives the output in Listing 67.
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 590.
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 68 and Listing 69 are equivalent.
noIndentBlock:
mytest:
begin: '\\begin\{testnoindent\*?\}'
end: '\\end\{testnoindent\*?\}'
noIndentBlock:
nameAsRegex:
name: '\w+noindent\*?'
lookForThis: 1
With reference to Listing 69:
the
name
field as specified here means any word followed by the word noindent, optionally followed by *;we have used
nameAsRegex
to identify this field, but you can use any description you like;the
lookForThis
field is optional, and can take the values 0 (off) or 1 (on); by default, it is assumed to be 1 (on).
5.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 70. The behaviour of latexindent.pl
on these environments is determined by their location (preamble or not), and the value indentPreamble
, discussed next.
128fileContentsEnvironments:
129 filecontents: 1
130 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 71, 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.
136lookForPreamble:
137 .tex: 1
138 .sty: 0
139 .cls: 0
140 .bib: 0
- preambleCommandsBeforeEnvironments:0|1
Assuming that latexindent.pl
is asked to operate upon the preamble of a document, when this switch is set to 0
then environment code blocks will be sought first, and then command code blocks. When this switch is set to 1
, commands will be sought first. The example that first motivated this switch contained the code given in Listing 72.
...
preheadhook={\begin{mdframed}[style=myframedstyle]},
postfoothook=\end{mdframed},
...
5.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 5.8.
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 73; each of the fields can take the values 0
or 1
. See Listing 476 and Listing 477 and Listing 478 for before and after results. Thanks to (Voßkuhle 2013) for providing this feature.
153removeTrailingWhitespace:
154 beforeProcessing: 0
155 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 74.
5.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 75). In fact, the fields in lookForAlignDelims
can actually take two different forms: the basic version is shown in Listing 75 and the advanced version in Listing 78; we will discuss each in turn.
lookForAlignDelims:
tabular: 1
tabularx: 1
longtable: 1
array: 1
matrix: 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 10), but in many cases it will produce results such as those in Listing 76 and Listing 77; running the command
latexindent.pl tabular1.tex
gives the output given in Listing 77.
\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 60).
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 78 is for you.
158lookForAlignDelims:
159 tabular:
160 delims: 1
161 alignDoubleBackSlash: 1
162 spacesBeforeDoubleBackSlash: 1
163 multiColumnGrouping: 0
164 alignRowsWithoutMaxDelims: 1
165 spacesBeforeAmpersand: 1
166 spacesAfterAmpersand: 1
167 justification: left
168 alignFinalDoubleBackSlash: 0
169 dontMeasure: 0
170 delimiterRegEx: (?<!\\)(&)
171 delimiterJustification: left
172 lookForChildCodeBlocks: 1
173 tabularx:
174 delims: 1
Note that you can use a mixture of the basic and advanced form: in Listing 78 tabular
and tabularx
are advanced and longtable
is basic. 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: 1
in the basic version shown in Listing 75. Ifdelims
is set to0
then 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.pl
should group columns above and below a\multicolumn
command (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 5.5.4;
lookForChildCodeBlocks optionally instructs
latexindent.pl
to search for child code blocks or not (default: 1), discussed in Section 5.5.5.
We will explore most of these features using the file tabular2.tex
in Listing 79 (which contains a \multicolumn
command), and the YAML files in Listing 80 – Listing 86; we will explore alignFinalDoubleBackSlash
in Listing 107; the dontMeasure
feature will be described in Section 5.5.3, and delimiterRegEx
in Section 5.5.4.
\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 87 – Listing 94.
\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 87 and Listing 88 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 87 the columns have been aligned at the ampersand;
in Listing 88 the
\multicolumn
command has grouped the \(2\) columns beneath and above it, becausemultiColumnGrouping
is set to \(1\) in Listing 80;in Listing 89 rows 3 and 6 have not been aligned at the ampersand, because
alignRowsWithoutMaxDelims
has been to set to \(0\) in Listing 81; however, the\\
have still been aligned;in Listing 90 the columns beneath and above the
\multicolumn
commands have been grouped (becausemultiColumnGrouping
is set to \(1\)), and there are at least \(4\) spaces before each aligned ampersand becausespacesBeforeAmpersand
is set to \(4\);in Listing 91 the columns beneath and above the
\multicolumn
commands have been grouped (becausemultiColumnGrouping
is set to \(1\)), and there are at least \(4\) spaces after each aligned ampersand becausespacesAfterAmpersand
is set to \(4\);in Listing 92 the
\\
have not been aligned, becausealignDoubleBackSlash
is set to0
, otherwise the output is the same as Listing 88;in Listing 93 the
\\
have been aligned, and becausespacesBeforeDoubleBackSlash
is set to0
, there are no spaces ahead of them; the output is otherwise the same as Listing 88;in Listing 94 the cells have been right-justified; note that cells above and below the
\multicol
statements have still been group correctly, because of the settings in Listing 80.
5.5.1. lookForAlignDelims: spacesBeforeAmpersand
The spacesBeforeAmpersand
can be specified in a few different ways. The basic form is demonstrated in Listing 82, 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 95; upon running the following command
latexindent.pl aligned1.tex -o=+-default
then we receive the default output given in Listing 96.
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
The settings in Listing 97 – Listing 100 are all equivlanent; we have used the not-yet discussed noAdditionalIndent
field (see Section 5.8) 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 101; we note that there is one space before each ampersand.
\begin{aligned}
& a & b, \\
& c & d.
\end{aligned}
We note in particular:
Listing 97 demonstrates the basic form for
lookForAlignDelims
; in this case, the default values are specified as in Listing 78;Listing 98 demonstrates the advanced form for
lookForAlignDelims
and specifiedspacesBeforeAmpersand
. The default value is1
;Listing 99 demonstrates the new advanced way to specify
spacesBeforeAmpersand
, and for us to set thedefault
value that sets the number of spaces before ampersands which are not in leading blank columns. The default value is1
.We note that
leadingBlankColumn
has not been specified in Listing 99, and it will inherit the value fromdefault
;Listing 100 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
1
by default.
We can customise the space before the ampersand in the leading blank column of Listing 101 by using either of Listing 102 and Listing 103, 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 104. We note that the space before the ampersand in the leading blank column has been set to 0
by Listing 103.
We can demonstrated this feature further using the settings in Listing 106 which give the output in Listing 105.
\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
5.5.2. lookForAlignDelims: alignFinalDoubleBackSlash
There may be times when a line of a code block contains more than \\
, and in which case, you may want the final double backslash to be aligned.
We explore the alignFinalDoubleBackSlash
feature by using the file in Listing 107. Upon running the following commands
latexindent.pl tabular4.tex -o=+-default
latexindent.pl tabular4.tex -o=+-FDBS -y="lookForAlignDelims:tabular:alignFinalDoubleBackSlash:1"
then we receive the respective outputs given in Listing 108 and Listing 109.
\begin{tabular}{lc}
Name & \shortstack{Hi \\ Lo} \\
Foo & Bar \\
\end{tabular}
\begin{tabular}{lc}
Name & \shortstack{Hi \\ Lo} \\
Foo & Bar \\
\end{tabular}
\begin{tabular}{lc}
Name & \shortstack{Hi \\ Lo} \\
Foo & Bar \\
\end{tabular}
We note that in:
Listing 108, by default, the first set of double back slashes in the first row of the
tabular
environment have been used for alignment;Listing 109, the final set of double backslashes in the first row have been used, because we specified
alignFinalDoubleBackSlash
as 1.
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 110 and Listing 111 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 112; the default output is shown in Listing 113. 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 5.8), these comment-marked blocks are considered environments
.
5.5.3. 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 114; the default output is shown in Listing 115.
\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 117, we can run the command
latexindent.pl tabular-DM.tex -l=dontMeasure1.yaml
and receive the output given in Listing 116.
\begin{tabular}{cccc}
aaaaaa & bbbbb & ccc & dd \\
11 & 2 & 33 & 4 \\
5 & 66 & 7 & 8
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure: largest
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 119. On running the following commands,
latexindent.pl tabular-DM.tex -l=dontMeasure2.yaml
we receive the output in Listing 118.
\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 119 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 121 and Listing 122. 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 120
\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 121 we have specified entries not to be measured, each one has a string in the
this
field, together with an optional specification ofapplyTo
ascell
;Listing 122 we have specified entries not to be measured as a regular expression using the
regex
field, together with an optional specification ofapplyTo
ascell
field, together with an optional specification ofapplyTo
ascell
.
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 124; upon running
latexindent.pl tabular-DM.tex -l=dontMeasure5.yaml
we receive the output in Listing 123.
\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 126, upon running
latexindent.pl tabular-DM.tex -l=dontMeasure6.yaml
we receive the output in Listing 125.
\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
5.5.4. 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 127; the default output from latexindent.pl
is given in Listing 128.
\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 130 and run the command
latexindent.pl tabbing.tex -l=delimiterRegEx1.yaml
to receive the output given in Listing 129.
\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 129 the code has been aligned, as intended, at both the
\=
and\>
;in Listing 130 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 132 and run the command
latexindent.pl tabbing.tex -l=delimiterRegEx2.yaml
to receive the output given in Listing 131.
\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 78 remain the same; for example, using the settings in Listing 134, and running
latexindent.pl tabbing.tex -l=delimiterRegEx3.yaml
to receive the output given in Listing 133.
\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 135, and associated YAML in Listing 137. Note that the Listing 137 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 136.
\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 139 and running the command
latexindent.pl tabbing1.tex -l=delimiterRegEx5.yaml -o=+-mod5
gives the output in Listing 138.
\begin{tabbing}
1 # 22 \> 333 \\
xxx # aaa # yyyyy \\
. # # & \\
\end{tabbing}
lookForAlignDelims:
tabbing:
delimiterRegEx: '(#|\\>)'
delimiterJustification: right
Note that in Listing 138 the second set of delimiters have been right aligned – it is quite subtle!
5.5.5. 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 117 on the file in Listing 140 and running the command
latexindent.pl tabular-DM-1.tex -l=dontMeasure1.yaml -o=+-mod1
gives the output in Listing 141.
\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 141 by employing the settings in Listing 143
latexindent.pl tabular-DM-1.tex -l=dontMeasure1a.yaml -o=+-mod1a
which gives the output in Listing 143.
\begin{tabular}{cc}
1 & 2\only<2->{ \\
3 & 4}
\end{tabular}
lookForAlignDelims:
tabular:
dontMeasure: largest
lookForChildCodeBlocks: 0
5.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 145 and Listing 146
237indentAfterItems:
238 itemize: 1
239 itemize*: 1
240 enumerate: 1
241 enumerate*: 1
242 description: 1
243 description*: 1
244 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}
- itemNames:fields
item
commands (perhaps you prefer to use myitem
, for example) then you can put populate them in itemNames
. For example, users of the exam
document class might like to add parts
to indentAfterItems
and part
to itemNames
to their user settings (see Section 4 for details of how to configure user settings, and Listing 45.)
250itemNames:
251 item: 1
252 myitem: 1
- 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 148 shows the default settings of specialBeginEnd
.
256specialBeginEnd:
257 displayMath:
258 begin: (?<!\\)\\\[ # \[ but *not* \\[
259 end: \\\] # \]
260 lookForThis: 1
261 inlineMath:
262 begin: (?<!\$)(?<!\\)\$(?!\$) # $ but *not* \$ or $$
263 end: (?<!\\)\$(?!\$) # $ but *not* \$ or $$
264 lookForThis: 1
265 displayMathTeX:
266 begin: \$\$ # $$
267 end: \$\$ # $$
268 lookForThis: 1
269 specialBeforeCommand: 0
The field displayMath
represents \[...\]
, inlineMath
represents $...$
and displayMathTex
represents $$...$$
. You can, of course, rename these in your own YAML files (see Section 4.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 149 and Listing 150; explicitly, running the command
latexindent.pl special1.tex -o=+-default
gives the output given in Listing 150.
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
.
There are examples in which it is advantageous to search for specialBeginEnd
fields before searching for commands, and the specialBeforeCommand
switch controls this behaviour.
For example, consider the file shown in Listing 151.
\begin{equation}
\left[
\sqrt{
a+b
}
\right]
\end{equation}
Now consider the YAML files shown in Listing 152 and Listing 153
specialBeginEnd:
leftRightSquare:
begin: '\\left\['
end: '\\right\]'
lookForThis: 1
specialBeginEnd:
specialBeforeCommand: 1
Upon running the following commands
latexindent.pl specialLR.tex -l=specialsLeftRight.yaml
latexindent.pl specialLR.tex -l=specialsLeftRight.yaml,specialBeforeCommand.yaml
we receive the respective outputs in Listing 154 and Listing 155.
\begin{equation}
\left[
\sqrt{
a+b
}
\right]
\end{equation}
\begin{equation}
\left[
\sqrt{
a+b
}
\right]
\end{equation}
Notice that in:
Listing 154 the
\left
has been treated as a command, with one optional argument;Listing 155 the
specialBeginEnd
pattern in Listing 152 has been obeyed because Listing 153 specifies that thespecialBeginEnd
should be sought before commands.
You can,optionally, specify the middle
field for anything that you specify in specialBeginEnd
.
For example, let’s consider the .tex
file in Listing 156.
\If
something 0
\ElsIf
something 1
\ElsIf
something 2
\ElsIf
something 3
\Else
something 4
\EndIf
Upon saving the YAML settings in Listing 158 and Listing 160 and running the commands
latexindent.pl special2.tex -l=middle
latexindent.pl special2.tex -l=middle1
then we obtain the output given in Listing 157 and Listing 159.
\If
something 0
\ElsIf
something 1
\ElsIf
something 2
\ElsIf
something 3
\Else
something 4
\EndIf
specialBeginEnd:
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:
If:
begin: '\\If'
middle:
- '\\ElsIf'
- '\\Else'
end: '\\EndIf'
lookForThis: 1
We note that:
in Listing 157 the bodies of each of the
Elsif
statements have been indented appropriately;the
Else
statement has not been indented appropriately in Listing 157 – read on!we have specified multiple settings for the
middle
field using the syntax demonstrated in Listing 160 so that the body of theElse
statement has been indented appropriately in Listing 159.
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 161 and the YAML in Listing 162, and running
latexindent.pl special3.tex -l=special-verb1
then the output in Listing 161 is unchanged.
\[
special code
blocks
can be
treated
as verbatim\]
specialBeginEnd:
displayMath:
lookForThis: verbatim
We can combine the specialBeginEnd
with the lookForAlignDelims
feature.
We begin with the code in Listing 163.
\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 165 and run the command
latexindent.pl special-align.tex -l edge-node1.yaml -o=+-mod1
to receive the output in Listing 164.
\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:
path:
begin: '\\path'
end: ';'
lookForThis: 1
specialBeforeCommand: 1
lookForAlignDelims:
path:
delimiterRegEx: '(edge|node)'
The output in Listing 164 is not quite ideal. We can tweak the settings within Listing 165 in order to improve the output; in particular, we employ the code in Listing 167 and run the command
latexindent.pl special-align.tex -l edge-node2.yaml -o=+-mod2
to receive the output in Listing 166.
\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:
path:
begin: '\\path'
end: ';'
specialBeforeCommand: 1
lookForAlignDelims:
path:
delimiterRegEx: '(edge|node\h*\{[0-9,A-Z]+\})'
The lookForThis
field can be considered optional; by default, it is assumed to be 1, which is demonstrated in Listing 167.
- 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. 2
279indentAfterHeadings:
280 part:
281 indentAfterThisHeading: 0
282 level: 1
283 chapter:
284 indentAfterThisHeading: 0
285 level: 2
286 section:
287 indentAfterThisHeading: 0
288 level: 3
The default settings do not place indentation after a heading, but you can easily switch them on by changing indentAfterThisHeading
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 5.8); 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 170 saved into headings1.yaml
, and that you have the text from Listing 169 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:
indentAfterThisHeading: 1
level: 1
paragraph:
indentAfterThisHeading: 1
level: 2
If you run the command
latexindent.pl headings1.tex -l=headings1.yaml
then you should receive the output given in Listing 171.
\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 170 so that the paragraph
level
is 1
; after running
latexindent.pl headings1.tex -l=headings1.yaml
you should receive the code given in Listing 172; 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 173 together with the default output shown in Listing 174.
\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 176 and that you run the following command:
latexindent.pl mult-nested.tex -l=max-indentation1
You should receive the output shown in Listing 175.
\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 174 and Listing 175 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 54) or noIndentBlock
(see Listing 60).
5.7. The code blocks known 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 144 and Listing 147 |
|
specialBeginEnd |
User specified, see Listing 148 |
|
afterHeading |
User specified, see Listing 168 |
|
filecontents |
User specified, see Listing 70 |
|
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 9.
5.8. noAdditionalIndent and indentRules
latexindent.pl
operates on files by looking for code blocks, as detailed in Section 5.7; 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:
noAdditionalIndent
for the name of the current <thing>;indentRules
for the name of the current <thing>;noAdditionalIndentGlobal
for the type of the current <thing>;indentRulesGlobal
for 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.
5.8.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 177.
\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 178 and Listing 179.
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 180; 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 181 and Listing 182, 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 183.
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 184.
\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 185; 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 178), 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 186 and Listing 187.
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 188 and Listing 189. Note that in Listing 188 the text for the optional argument has not received any additional indentation, and that in Listing 189 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 190 and Listing 191.
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 192; note in particular that the environment myenv
has received one tab (from the outer
environment) plus three spaces from Listing 190 or Listing 191.
\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 184 that contains optional and mandatory arguments. Upon using Listing 190 as in
latexindent.pl myenv-args.tex -l=myenv-rules1.yaml
we obtain the output in Listing 193; 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 194 and Listing 195
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 196 and 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}
Note that in Listing 196, 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 197, 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 198).
337noAdditionalIndentGlobal:
338 environments: 0 # 0/1
Let’s say that you change the value of environments
to 1
in Listing 198, 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 199 and Listing 200; in Listing 199 notice that both environments receive no additional indentation but that the arguments of myenv
still do receive indentation. In Listing 200 notice that the outer environment does not receive additional indentation, but because of the settings from myenv-rules1.yaml
(in Listing 190), 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 201 and Listing 202
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 203 and Listing 204. Notice that in Listing 203 the optional argument has not received any additional indentation, and in Listing 204 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 205.
353indentRulesGlobal:
354 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 206 and Listing 207. Note that in Listing 206, both the environment blocks have received a single-space indentation, whereas in Listing 207 the outer
environment has received single-space indentation (specified by indentRulesGlobal
), but myenv
has received " "
, as specified by the
particular indentRules
for myenv
Listing 190.
\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 208 and Listing 209
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 210 and Listing 211. Note that the optional argument in Listing 210 has received two tabs worth of indentation, while the mandatory argument has done so in Listing 211.
\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}
5.8.2. Environments with items
With reference to Listing 144 and Listing 147, some commands may contain item
commands; for the purposes of this discussion, we will use the code from Listing 145.
Assuming that you’ve populated itemNames
with the name of your item
, you can put the item name into noAdditionalIndent
as in Listing 212, 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 213
noAdditionalIndent:
item: 1
# itemNames:
# item: 0
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 214 and Listing 215; note that in Listing 214 that the text after each item
has not received any additional indentation, and in Listing 215, the text after each item
has received a single space of indentation, specified by Listing 213.
\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 216 and Listing 217. 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 214 and Listing 215 are obtained; note, however, that all such item
commands without their own individual noAdditionalIndent
or indentRules
settings would behave as in these listings.
5.8.3. Commands with arguments
Let’s begin with the simple example in Listing 218; when latexindent.pl
operates on this file, the default output is shown in Listing 219. 3
\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 178 and Listing 179) we may specify noAdditionalIndent
either in ‘scalar’ form, or in ‘field’ form, as shown in Listing 220 and Listing 221
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 222 and Listing 223
\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 222 that the ‘body’, optional argument and mandatory argument have all received no additional indentation, while in Listing 223, 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 186 and Listing 187; explicit examples are given in Listing 224 and Listing 225.
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 226 and Listing 227.
\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 226 and Listing 227 has received no additional indent, even though body
is explicitly set to 0
in both Listing 224 and Listing 225. This is because, by default, noAdditionalIndentGlobal
for commands
is set to 1
by default; this can be easily fixed as in Listing 228 and
Listing 229.
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 230 and Listing 231.
\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 194 and Listing 195 and Listing 205 and Listing 208 and Listing 209.
5.8.4. ifelsefi code blocks
Let’s use the simple example shown in Listing 232; when latexindent.pl
operates on this file, the output as in Listing 233; 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 234 and Listing 235.
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 236 and Listing 237; note that in Listing 236, the ifnum
code block has not received any additional indentation, while in Listing 237, 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 238 and Listing 239.
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 240 and Listing 241; notice that in Listing 240 neither of the ifelsefi
code blocks have received indentation, while in Listing 241 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 242, and the associated default output given in Listing 243; 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
5.8.5. specialBeginEnd code blocks
Let’s use the example from Listing 149 which has default output shown in Listing 150.
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 244 and Listing 245.
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 246 and Listing 247; note that in Listing 246, the displayMath
code block has not received any additional indentation, while in Listing 247, 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 248 and Listing 249.
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 250 and Listing 251; notice that in Listing 250 neither of the special
code blocks have received indentation, while in Listing 251 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)
$
5.8.6. afterHeading code blocks
Let’s use the example Listing 252 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 254 by running the command
latexindent.pl headings2.tex -l headings3.yaml
we obtain the output in Listing 253. 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:
indentAfterThisHeading: 1
level: 1
If we specify noAdditionalIndent
as in Listing 256 and run the command
latexindent.pl headings2.tex -l headings4.yaml
then we receive the output in Listing 255. 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:
indentAfterThisHeading: 1
level: 1
noAdditionalIndent:
paragraph: 1
Similarly, if we specify indentRules
as in Listing 258 and run analogous commands to those above, we receive the output in Listing 257; 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:
indentAfterThisHeading: 1
level: 1
indentRules:
paragraph: "\t\t\t"
We may, instead, specify noAdditionalIndent
in ‘field’ form, as in Listing 260 which gives the output in Listing 259.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
indentAfterThisHeading: 1
level: 1
noAdditionalIndent:
paragraph:
body: 0
mandatoryArguments: 0
afterHeading: 1
Analogously, we may specify indentRules
as in Listing 262 which gives the output in Listing 261; 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:
indentAfterThisHeading: 1
level: 1
indentRules:
paragraph:
mandatoryArguments: " "
afterHeading: "\t\t\t"
Finally, let’s consider noAdditionalIndentGlobal
and indentRulesGlobal
shown in Listing 264 and Listing 266 respectively, with respective output in Listing 263 and Listing 265. Note that in Listing 264 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 265, the argument has received both a (default) tab plus two spaces of indentation (from the global rule specified in Listing 266), and the remaining body after paragraph
has received just two spaces of indentation.
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
indentAfterThisHeading: 1
level: 1
noAdditionalIndentGlobal:
afterHeading: 1
\paragraph{paragraph
title}
paragraph text
paragraph text
indentAfterHeadings:
paragraph:
indentAfterThisHeading: 1
level: 1
indentRulesGlobal:
afterHeading: " "
5.8.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 5.8.3, but a small discussion defining these remaining code blocks is necessary.
5.8.7.1. keyEqualsValuesBracesBrackets
latexindent.pl
defines this type of code block by the following criteria:
it must immediately follow either
\{
OR[
OR,
with comments and blank lines allowed.then 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: follow
and keyEqualsValuesBracesBrackets: name
fields of the fine tuning section in Listing 574
An example is shown in Listing 267, with the default output given in Listing 268.
\pgfkeys{/tikz/.cd,
start coordinate/.initial={0,
\vertfactor},
}
\pgfkeys{/tikz/.cd,
start coordinate/.initial={0,
\vertfactor},
}
In Listing 268, note that the maximum indentation is three tabs, and these come from:
the
\pgfkeys
command’s mandatory argument;the
start coordinate/.initial
key’s mandatory argument;the
start coordinate/.initial
key’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 fornoAdditionalIndent
and friends from page sec:noadd-indent-rules.
5.8.7.2. namedGroupingBracesBrackets
This type of code block is mostly motivated by tikz-based code; we define this code block as follows:
it must immediately follow either horizontal space OR one or more line breaks OR
\{
OR[
OR$
OR)
OR(
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: follow
and NamedGroupingBracesBrackets: name
fields of the fine tuning section in Listing 574
A simple example is given in Listing 269, with default output in Listing 270.
\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
, parent
and node
all to be namedGroupingBracesBrackets
4. Referencing Listing 270, note that the maximum indentation is two tabs, and these come from:
the
child
’s mandatory argument;the
child
’s body, which is defined as any lines following the name of thenamedGroupingBracesBrackets
that include its arguments. This is the part controlled by the body field fornoAdditionalIndent
and friends from page sec:noadd-indent-rules.
5.8.7.3. UnNamedGroupingBracesBrackets
occur in a variety of situations; specifically, we define this type of code block as satisfying the following criteria:
it must immediately follow either
\{
OR[
OR,
OR&
OR)
OR(
OR$
;then at least one set of curly braces or square brackets (comments and line breaks allowed throughout).
See the UnNamedGroupingBracesBrackets: follow
field of the fine tuning section in Listing 574
An example is shown in Listing 271 with default output give in Listing 272.
\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 272, there are three sets of unnamed braces. Note also that the maximum value of indentation is three tabs, and these come from:
the
\psforeach
command’s mandatory argument;the first un-named braces mandatory argument;
the first un-named braces body, which we define as any lines following the first opening
\{
or[
that defined the code block. This is the part controlled by the body field fornoAdditionalIndent
and friends from page sec:noadd-indent-rules.
Users wishing to customise the mandatory and/or optional arguments on a per-name basis for the UnNamedGroupingBracesBrackets
should use always-un-named
.
5.8.7.4. filecontents
code blocks behave just as environments
, except that neither arguments nor items are sought.
5.8.8. Summary
Having considered all of the different types of code blocks, the functions of the fields given in Listing 273 and Listing 274 should now make sense.
337noAdditionalIndentGlobal:
338 environments: 0 # 0/1
339 commands: 1 # 0/1
340 optionalArguments: 0 # 0/1
341 mandatoryArguments: 0 # 0/1
342 ifElseFi: 0 # 0/1
343 items: 0 # 0/1
344 keyEqualsValuesBracesBrackets: 0 # 0/1
345 namedGroupingBracesBrackets: 0 # 0/1
346 UnNamedGroupingBracesBrackets: 0 # 0/1
347 specialBeginEnd: 0 # 0/1
348 afterHeading: 0 # 0/1
349 filecontents: 0 # 0/1
353indentRulesGlobal:
354 environments: 0 # 0/h-space
355 commands: 0 # 0/h-space
356 optionalArguments: 0 # 0/h-space
357 mandatoryArguments: 0 # 0/h-space
358 ifElseFi: 0 # 0/h-space
359 items: 0 # 0/h-space
360 keyEqualsValuesBracesBrackets: 0 # 0/h-space
361 namedGroupingBracesBrackets: 0 # 0/h-space
362 UnNamedGroupingBracesBrackets: 0 # 0/h-space
363 specialBeginEnd: 0 # 0/h-space
364 afterHeading: 0 # 0/h-space
365 filecontents: 0 # 0/h-space
5.9. Commands and the strings between their arguments
The command
code blocks will always look for optional (square bracketed) and mandatory (curly braced) arguments which can contain comments, line breaks and ‘beamer’ commands <.*?>
between them. There are switches that can allow them to contain other strings, which we discuss next.
- commandCodeBlocks:fields
The commandCodeBlocks
field contains a few switches detailed in Listing 275.
368commandCodeBlocks:
369 roundParenthesesAllowed: 1
370 stringsAllowedBetweenArguments:
371 -
372 amalgamate: 1
373 - node
374 - at
375 - to
376 - decoration
377 - \+\+
378 - \-\-
379 - \#\#\d
380 commandNameSpecial:
381 -
382 amalgamate: 1
383 - '@ifnextchar\['
- roundParenthesesAllowed:0|1
The need for this field was mostly motivated by commands found in code used to generate images in PSTricks
and tikz
; for example, let’s consider the code given in Listing 276.
\defFunction[algebraic]{torus}(u,v)
{(2+cos(u))*cos(v+\Pi)}
{(2+cos(u))*sin(v+\Pi)}
{sin(u)}
\defFunction[algebraic]{torus}(u,v)
{(2+cos(u))*cos(v+\Pi)}
{(2+cos(u))*sin(v+\Pi)}
{sin(u)}
Notice that the \defFunction
command has an optional argument, followed by a mandatory argument, followed by a round-parenthesis argument, \((u,v)\).
By default, because roundParenthesesAllowed
is set to \(1\) in Listing 275, then latexindent.pl
will allow round parenthesis between optional and mandatory arguments. In the case of the code in Listing 276, latexindent.pl
finds all the arguments of defFunction
, both before and after (u,v)
.
The default output from running latexindent.pl
on Listing 276 actually leaves it unchanged (see Listing 277); note in particular, this is because of noAdditionalIndentGlobal
as discussed on page page:command:noAddGlobal.
Upon using the YAML settings in Listing 279, and running the command
latexindent.pl pstricks1.tex -l noRoundParentheses.yaml
we obtain the output given in Listing 278.
\defFunction[algebraic]{torus}(u,v)
{(2+cos(u))*cos(v+\Pi)}
{(2+cos(u))*sin(v+\Pi)}
{sin(u)}
commandCodeBlocks:
roundParenthesesAllowed: 0
Notice the difference between Listing 277 and Listing 278; in particular, in Listing 278, because round parentheses are not allowed, latexindent.pl
finds that the \defFunction
command finishes at the first opening round parenthesis. As such, the remaining braced, mandatory, arguments are found to be UnNamedGroupingBracesBrackets
(see Table 2) which, by default, assume indentation for their body, and hence
the tabbed indentation in Listing 278.
Let’s explore this using the YAML given in Listing 281 and run the command
latexindent.pl pstricks1.tex -l defFunction.yaml
then the output is as in Listing 280.
\defFunction[algebraic]{torus}(u,v)
{(2+cos(u))*cos(v+\Pi)}
{(2+cos(u))*sin(v+\Pi)}
{sin(u)}
indentRules:
defFunction:
body: " "
Notice in Listing 280 that the body of the defFunction
command i.e, the subsequent lines containing arguments after the command name, have received the single space of indentation specified by Listing 281.
- stringsAllowedBetweenArguments:fields
tikz
users may well specify code such as that given in Listing 282; processing this code using latexindent.pl
gives the default output in Listing 283.
\draw[thin]
(c) to[in=110,out=-90]
++(0,-0.5cm)
node[below,align=left,scale=0.5]
\draw[thin]
(c) to[in=110,out=-90]
++(0,-0.5cm)
node[below,align=left,scale=0.5]
With reference to Listing 275, we see that the strings
to, node, ++
are all allowed to appear between arguments; importantly, you are encouraged to add further names to this field as necessary. This means that when latexindent.pl
processes Listing 282, it consumes:
the optional argument
[thin]
the round-bracketed argument
(c)
becauseroundParenthesesAllowed
is \(1\) by defaultthe string
to
(specified instringsAllowedBetweenArguments
)the optional argument
[in=110,out=-90]
the string
++
(specified instringsAllowedBetweenArguments
)the round-bracketed argument
(0,-0.5cm)
becauseroundParenthesesAllowed
is \(1\) by defaultthe string
node
(specified instringsAllowedBetweenArguments
)the optional argument
[below,align=left,scale=0.5]
We can explore this further, for example using Listing 285 and running the command
latexindent.pl tikz-node1.tex -l draw.yaml
we receive the output given in Listing 284.
\draw[thin]
(c) to[in=110,out=-90]
++(0,-0.5cm)
node[below,align=left,scale=0.5]
indentRules:
draw:
body: " "
Notice that each line after the \draw
command (its ‘body’) in Listing 284 has been given the appropriate two-spaces worth of indentation specified in Listing 285.
Let’s compare this with the output from using the YAML settings in Listing 287, and running the command
latexindent.pl tikz-node1.tex -l no-strings.yaml
given in Listing 286.
\draw[thin]
(c) to[in=110,out=-90]
++(0,-0.5cm)
node[below,align=left,scale=0.5]
commandCodeBlocks:
stringsAllowedBetweenArguments: 0
In this case, latexindent.pl
sees that:
the
\draw
command finishes after the(c)
, asstringsAllowedBetweenArguments
has been set to \(0\) so there are no strings allowed between arguments;it finds a
namedGroupingBracesBrackets
calledto
(see Table 2) with argument[in=110,out=-90]
it finds another
namedGroupingBracesBrackets
but this time callednode
with argument[below,align=left,scale=0.5]
Referencing Listing 275, , we see that the first field in the stringsAllowedBetweenArguments
is amalgamate
and is set to 1
by default. This is for users who wish to specify their settings in multiple YAML files. For example, by using the settings in either Listing 288 or:numref:lst:amalgamate-demo1
is equivalent to using the settings in Listing 290.
commandCodeBlocks:
stringsAllowedBetweenArguments:
- 'more'
- 'strings'
- 'here'
commandCodeBlocks:
stringsAllowedBetweenArguments:
-
amalgamate: 1
- 'more'
- 'strings'
- 'here'
commandCodeBlocks:
stringsAllowedBetweenArguments:
-
amalgamate: 1
- 'node'
- 'at'
- 'to'
- 'decoration'
- '\+\+'
- '\-\-'
- 'more'
- 'strings'
- 'here'
We specify amalgamate
to be set to 0
and in which case any settings loaded prior to those specified, including the default, will be overwritten. For example, using the settings in Listing 291 means that only the strings specified in that field will be used.
commandCodeBlocks:
stringsAllowedBetweenArguments:
-
amalgamate: 0
- 'further'
- 'settings'
It is important to note that the amalgamate
field, if used, must be in the first field, and specified using the syntax given in Listing 289 and Listing 290 and Listing 291.
We may explore this feature further with the code in Listing 292, whose default output is given in Listing 293.
\foreach \x/\y in {0/1,1/2}{
body of foreach
}
\foreach \x/\y in {0/1,1/2}{
body of foreach
}
Let’s compare this with the output from using the YAML settings in Listing 295, and running the command
latexindent.pl for-each.tex -l foreach.yaml
given in Listing 294.
\foreach \x/\y in {0/1,1/2}{
body of foreach
}
commandCodeBlocks:
stringsAllowedBetweenArguments:
-
amalgamate: 0
- '\\x\/\\y'
- 'in'
You might like to compare the output given in Listing 293 and Listing 294. Note,in particular, in Listing 293 that the foreach
command has not included any of the subsequent strings, and that the braces have been treated as a namedGroupingBracesBrackets
. In Listing 294 the foreach
command has been allowed to have \x/\y
and in
between arguments because of the settings given in
Listing 295.
- commandNameSpecial:fields
There are some special command names that do not fit within the names recognised by latexindent.pl
, the first one of which is \@ifnextchar[
. From the perspective of latexindent.pl
, the whole of the text \@ifnextchar[
is a command, because it is immediately followed by sets of mandatory arguments. However, without the commandNameSpecial
field, latexindent.pl
would not be able to label it as such, because the [
is, necessarily, not matched by a closing ]
.
For example, consider the sample file in Listing 296, which has default output in Listing 297.
\parbox{
\@ifnextchar[{arg 1}{arg 2}
}
\parbox{
\@ifnextchar[{arg 1}{arg 2}
}
Notice that in Listing 297 the parbox
command has been able to indent its body, because latexindent.pl
has successfully found the command \@ifnextchar
first; the pattern-matching of latexindent.pl
starts from the inner most <thing> and works outwards, discussed in more detail on page page:phases.
For demonstration, we can compare this output with that given in Listing 298 in which the settings from Listing 299 have dictated that no special command names, including the \@ifnextchar[
command, should not be searched for specially; as such, the parbox
command has been unable to indent its body successfully, because the \@ifnextchar[
command has not been found.
\parbox{
\@ifnextchar[{arg 1}{arg 2}
}
commandCodeBlocks:
commandNameSpecial: 0
The amalgamate
field can be used for commandNameSpecial
, just as for stringsAllowedBetweenArguments
. The same condition holds as stated previously, which we state again here:
Warning
It is important to note that the amalgamate
field, if used, in either commandNameSpecial
or stringsAllowedBetweenArguments
must be in the first field, and specified using the syntax given in Listing 289 and Listing 290 and Listing 291.
“Data Dumper Demonstration.” n.d. Accessed June 18, 2021. https://stackoverflow.com/questions/7466825/how-do-you-sort-the-output-of-datadumper.
“Data::Dumper Module.” n.d. Accessed June 18, 2021. https://perldoc.perl.org/Data::Dumper.
“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.
- 1
Throughout this manual, listings shown with line numbers represent code taken directly from
defaultSettings.yaml
.- 2
There is a slight difference in interface for this field when comparing Version 2.2 to Version 3.0; see Section 12.12 for details.
- 3
The command code blocks have quite a few subtleties, described in Section 5.9.
- 4
You may like to verify this by using the
-tt
option and checkingindent.log
!