9. Fine tuning
latexindent.pl
operates by looking for the code blocks detailed in Table 2. The fine tuning of the details of such code blocks is controlled by the fineTuning
field, detailed in Listing 594.
This field is for those that would like to peek under the bonnet/hood and make some fine tuning to latexindent.pl
’s operating.
Warning
Making changes to the fine tuning may have significant consequences for your indentation scheme, proceed with caution!
630fineTuning:
631 environments:
632 name: [a-zA-Z@\*0-9_\\]+
633 ifElseFi:
634 name: (?!@?if[a-zA-Z@]*?\{)@?if[a-zA-Z@]*?
635 commands:
636 name: [+a-zA-Z@\*0-9_\:]+?
637 items:
638 canBeFollowedBy: (?:\[[^]]*?\])|(?:<[^>]*?>)
639 keyEqualsValuesBracesBrackets:
640 name: [a-zA-Z@\*0-9_\/.:\#-]+[a-zA-Z@\*0-9_\/.\h\{\}:\#-]*?
641 follow: (?:(?<!\\)\{)|,|(?:(?<!\\)\[)
642 namedGroupingBracesBrackets:
643 name: [0-9\.a-zA-Z@\*><]+?
644 follow: \h|\R|\{|\[|\$|\)|\(
645 UnNamedGroupingBracesBrackets:
646 follow: \{|\[|,|&|\)|\(|\$
647 arguments:
648 before: (?:#\d\h*;?,?\/?)+|\<.*?\>
649 between: _|\^|\*
650 trailingComments:
651 notPreceededBy: (?<!\\)
652 afterComment: .*?
653 modifyLineBreaks:
654 doubleBackSlash: \\\\(?:\h*\[\h*\d+\h*[a-zA-Z]+\h*\])?
655 comma: ','
656 betterFullStop: |-
657 (?x) # ignore spaces in the below
658 (?: #
659 \.\) # .)
660 (?!\h*[a-z]) # not *followed by* a-z
661 ) #
662 | # OR
663 (?: #
664 (?<! # not *preceded by*
665 (?: #
666 (?:[eE]\.[gG]) # e.g OR E.g OR e.G OR E.G
667 | #
668 (?:[iI]\.[eE]) # i.e OR I.e OR i.E OR I.E
669 | #
670 (?:etc) # etc
671 | #
672 (?:[wW]\.[rR]\.[tT]) # w.r.t OR W.r.t OR w.R.t OR w.r.T OR W.R.t OR W.r.T OR w.R.T OR W.R.T
673 ) #
674 ) #
675 ) #
676 \. # .
677 (?! # not *followed by*
678 (?: #
679 [a-zA-Z0-9-~,] #
680 | #
681 \), # ),
682 | #
683 \)\. # ).
684 ) #
685 ) #
The fields given in Listing 594 are all regular expressions. This manual is not intended to be a tutorial on regular expressions; you might like to read, for example, (Friedl, n.d.) for a detailed covering of the topic.
We make the following comments with reference to Listing 594:
the
environments:name
field details that the name of an environment can contain:a-z
lower case lettersA-Z
upper case letters@
the@
’letter’\*
stars0-9
numbers_
underscores\
backslashes
The
+
at the end means at least one of the above characters.the
ifElseFi:name
field:@?
means that it can possibly begin with@
followed by
if
followed by 0 or more characters from
a-z
,A-Z
and@
the
?
the end means non-greedy, which means ‘stop the match as soon as possible’
the
keyEqualsValuesBracesBrackets
contains some interesting syntax:|
means ‘or’(?:(?<!\\)\{)
the(?:...)
uses a non-capturing group – you don’t necessarily need to worry about what this means, but just know that for thefineTuning
feature you should only ever use non-capturing groups, and not capturing groups, which are simply(...)
(?<!\\)\{)
means a{
but it can not be immediately preceded by a\
in the
arguments:before
field\d\h*
means a digit (i.e. a number), followed by 0 or more horizontal spaces;?,?
means possibly a semi-colon, and possibly a comma\<.*?\>
is designed for ’beamer’-type commands; the.*?
means anything in between<...>
the
modifyLineBreaks
field refers to fine tuning settings detailed in Section 6. In particular:betterFullStop
is in relation to the one sentence per line routine, detailed in Section 6.2doubleBackSlash
is in relation to theDBSStartsOnOwnLine
andDBSFinishesWithLineBreak
polyswitches surrounding double backslashes, see Section 6.3.2comma
is in relation to theCommaStartsOnOwnLine
andCommaFinishesWithLineBreak
polyswitches surrounding commas in optional and mandatory arguments; see Table 3
It is not obvious from Listing 594, but each of the follow
, before
and between
fields allow trailing comments, line breaks, and horizontal spaces between each character.
Warning
For the fineTuning
feature you should only ever use non-capturing groups, such as (?:...)
and not capturing groups, which are (...)
As a demonstration, consider the file given in Listing 595, together with its default output using the command
latexindent.pl finetuning1.tex
is given in Listing 596.
\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}
}
It’s clear from Listing 596 that the indentation scheme has not worked as expected. We can fine tune the indentation scheme by employing the settings given in Listing 598 and running the command
latexindent.pl finetuning1.tex -l=fine-tuning1.yaml
and the associated (desired) output is given in Listing 597.
\mycommand{
\rule{G -> +H[-G]CL}
\rule{H -> -G[+H]CL}
\rule{g -> +h[-g]cL}
\rule{h -> -g[+h]cL}
}
fineTuning:
arguments:
between: '_|\^|\*|\->|\-|\+|h|H|g|G'
Let’s have another demonstration; consider the file given in Listing 599, together with its default output using the command
latexindent.pl finetuning2.tex
is given in Listing 600.
@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]"
}
It’s clear from Listing 600 that the indentation scheme has not worked as expected. We can fine tune the indentation scheme by employing the settings given in Listing 602 and running the command
latexindent.pl finetuning2.tex -l=fine-tuning2.yaml
and the associated (desired) output is given in Listing 601.
@misc{ wikilatex,
author = "{Wikipedia contributors}",
title = "LaTeX --- {Wikipedia}{,}",
note = "[Online; accessed 3-March-2020]"
}
fineTuning:
NamedGroupingBracesBrackets:
follow: '\h|\R|\{|\[|\$|\)|\(|"'
UnNamedGroupingBracesBrackets:
follow: '\{|\[|,|&|\)|\(|\$|"'
arguments:
between: '_|\^|\*|---'
In particular, note that the settings in Listing 602 specify that NamedGroupingBracesBrackets
and UnNamedGroupingBracesBrackets
can follow "
and that we allow ---
between arguments.
You can tweak the fineTuning
using the -y
switch, but to be sure to use quotes appropriately. For example, starting with the code in Listing 603 and running the following command
latexindent.pl -m -y='modifyLineBreaks:oneSentencePerLine:manipulateSentences: 1, modifyLineBreaks:oneSentencePerLine:sentencesBeginWith:a-z: 1, fineTuning:modifyLineBreaks:betterFullStop: "(?:\.|;|:(?![a-z]))|(?:(?<!(?:(?:e\.g)|(?:i\.e)|(?:etc))))\.(?!(?:[a-z]|[A-Z]|\-|~|\,|[0-9]))"' issue-243.tex -o=+-mod1
gives the output shown in Listing 604.
We go; you see: this sentence \cite{tex:stackexchange} finishes here.
We go;
you see:
this sentence \cite{tex:stackexchange} finishes here.
We can tweak the fineTuning
for how trailing comments are classified. For motivation, let’s consider the code given in Listing 605
some before text
\href{Handbook%20for%30Spoken%40document.pdf}{my document}
some after text
We will compare the settings given in Listing 606 and Listing 607.
modifyLineBreaks:
textWrapOptions:
columns: -1
blocksEndBefore:
verbatim: 0
blocksFollow:
verbatim: 0
removeTrailingWhitespace:
beforeProcessing: 1
fineTuning:
trailingComments:
notPreceededBy: '(?:(?<!Handbook)(?<!for)(?<!Spoken))'
modifyLineBreaks:
textWrapOptions:
columns: -1
blocksEndBefore:
verbatim: 0
blocksFollow:
verbatim: 0
removeTrailingWhitespace:
beforeProcessing: 1
Upon running the following commands
latexindent.pl -m finetuning4.tex -o=+-mod1 -l=href1
latexindent.pl -m finetuning4.tex -o=+-mod2 -l=href2
we receive the respective output in Listing 608 and Listing 609.
some before text \href{Handbooksome after text%20for%30Spoken%40document.pdf}{my document}
some before text \href{Handbook%20for%30Spoken%40document.pdf}{my document} some after text
We note that in:
Listing 608 the trailing comments are assumed to be everything following the first comment symbol, which has meant that everything following it has been moved to the end of the line; this is undesirable, clearly!
Listing 609 has fine-tuned the trailing comment matching, and says that % cannot be immediately preceded by the words ‘Handbook’, ‘for’ or ‘Spoken’, which means that none of the % symbols have been treated as trailing comments, and the output is desirable.
Another approach to this situation, which does not use fineTuning
, is to use noIndentBlock
which we discussed in Listing 60; using the settings in Listing 610 and running the command
latexindent.pl -m finetuning4.tex -o=+-mod3 -l=href3
then we receive the same output given in Listing 609.
modifyLineBreaks:
textWrapOptions:
columns: -1
blocksEndBefore:
verbatim: 0
blocksFollow:
verbatim: 0
noIndentBlock:
href:
begin: '\\href\{[^}]*?\}\{'
body: '[^}]*?'
end: '\}'
With reference to the body
field in Listing 610, we note that the body
field can be interpreted as: the fewest number of zero or more characters that are not right braces. This is an example of character class.
We can use the fineTuning
field to assist in the formatting of bibliography files.
Starting with the file in Listing 611 and running the command
latexindent.pl bib1.tex -o=+-mod1
gives the output in Listing 612.
@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 614 and running the command
latexindent.pl bib1.bib -l bibsettings1.yaml -o=+-mod2
gives the output in Listing 613.
@online{paulo,
title = "arararule,indent.yaml",
author = "PauloCereda",
date = {2013-05-23},
urldate = {2021-03-19},
keywords = {contributor},}
lookForAlignDelims:
online:
delimiterRegEx: '(=)'
fineTuning:
keyEqualsValuesBracesBrackets:
follow: '(?:(?<!\\)\{)|(?:(?<!\\)\[)'
UnNamedGroupingBracesBrackets:
follow: '\{|\[|,|&|\)|\(|\$|='
Some notes about Listing 614:
we have populated the
lookForAlignDelims
field with theonline
command, and have used thedelimiterRegEx
, discussed in Section 5.5.4;we have tweaked the
keyEqualsValuesBracesBrackets
code block so that it will not be found following a comma; this means that, in contrast to the default behaviour, the lines such asdate={2013-05-23},
will not be treated as key-equals-value braces;the adjustment to
keyEqualsValuesBracesBrackets
necessitates the associated change to theUnNamedGroupingBracesBrackets
field so that they will be searched for following=
symbols.
We can build upon Listing 614 for slightly more complicated bibliography files.
Starting with the file in Listing 615 and running the command
latexindent.pl bib2.bib -l bibsettings1.yaml -o=+-mod1
gives the output in Listing 616.
@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 616 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 617.
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 618.
@online{cmh:videodemo,
title = "Videodemonstrationofpl.latexindentonyoutube",
url = "https://www.youtube.com/watch?v=wo38aaH2F4E&spfreload=10",
urldate = {2017-02-21},
}
With reference to Listing 617 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
.
We can use the fineTuning
settings to tweak how latexindent.pl
finds trailing comments. We begin with the file in Listing 619
\chapter{chapter text} % 123
chapter text
\section{section text} % 456
section text
% end
% end
Using the settings in Listing 621 and running the command
latexindent.pl finetuning5.tex -l=fine-tuning3.yaml
gives the output in Listing 620.
\chapter{chapter text} % 123
chapter text
\section{section text} % 456
section text
% end
% end
fineTuning:
trailingComments:
notPreceededBy: (?<!\\)
afterComment: (?!(?:\hend)).*?
specialBeginEnd:
customSection:
begin: \\(?:section|chapter)
end: \%\h+end
specialBeforeCommand: 1
The settings in Listing 621 detail that trailing comments can not be followed by a single space, and then the text ‘end’. This means that the specialBeginEnd
routine will be able to find the pattern % end
as the end
part. The trailing comments 123
and 456
are still treated as trailing comments.
We can use the fineTuning
settings to tweak how latexindent.pl
finds environments.
We begin with the file in Listing 622.
\begin{myenv}\label{mylabel}The body of my environment...\end{myenv}
Using the settings in Listing 624 and running the command
latexindent.pl finetuning6.tex -m -l=fine-tuning4.yaml
gives the output in Listing 623.
\begin{myenv}\label{mylabel}
The body of my environment...
\end{myenv}
modifyLineBreaks:
environments:
BodyStartsOnOwnLine: 1
EndStartsOnOwnLine: 1
fineTuning:
environments:
begin: \\begin\{([a-zA-Z@\*0-9_\\]+)\}\s*\\label\{[^}]+?\}
end: \\end\{\2\}
By using the settings in Listing 624 it means that the default poly-switch location of BodyStartsOnOwnLine
for environments (denoted ♥ in Table 3) has been overwritten so that it is after the label
command.
Referencing Listing 624, unless both begin
and end
are specified, then the default value of name
will be used.
Friedl, Jeffrey E. F. n.d. Mastering Regular Expressions.