cmhughes / latexindent.pl

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

Custom `specialBeginEnd` bracket pair breaks indentation of commands #480

Closed arodomanov closed 11 months ago

arodomanov commented 11 months ago

Following my previous example, I was trying to make latexindent indent the text inside any square brackets. However, in doing so, I noticed some strange behavior which is probably a bug.

Specifically, I have a very simple command with one (optional) argument in the brackets and one (mandatory) argument in the braces (please see source.tex below). I'm then running latexindent with the latexindent.yaml settings file (see below). The expectation is that nothing should change in the output compared to the original file. However, for some reason, latexindent wants to unindent the "Do something" argument in the braces producing the output shown in the source-mod.tex file.

Original .tex code (source.tex)

\todo[inline]{
  Do something.
}

yaml settings (latexindent.yaml)

defaultIndent: "  "

specialBeginEnd:
  specialBeforeCommand: 1

  brackets:
    begin: (?<!\\)\[ # but not display math (\[)
    end: (?<!\\)\] # but not display math (\])
    lookForThis: 1

The command used to run latexindent

latexindent -l latexindent.yaml -o=+-mod.tex source.tex

Actual output (source-mod.tex)

\todo[inline]{
Do something.
}

Desired or expected output (same as source.tex)

\todo[inline]{
  Do something.
}

Version of latexindent

3.23.2, 2023-09-23

Additional remarks

I've experimented a bit and found out that everything works as expected if either

cmhughes commented 11 months ago

I don't understand why you need a y settings for your example, as latexindent will produce the desired output by default.

Do you have an actual use case?

arodomanov commented 11 months ago

Yes, of course, I don't need the special settings file to achieve the desired output for the example I presented.

What I actually want is to automatically indent the contents inside each pair of brackets in a mathematical expression. For example, consider the latex code from my previous issue (where I replaced parentheses with brackets):

$
  a
  +
  [
    b + c
  ]
  =
  d
$
and
$
  e + f = g
$

I'd like this code to stay exactly the same after formatting which is why I want to use the special latexindent.yaml settings file presented above. But, as I already wrote in the first message, this breaks the indentation of certain commands.

cmhughes commented 11 months ago

Thanks, that's helpful.

solution

defaultIndent: "  "

specialBeginEnd:
  specialBeforeCommand: 1
  brackets:
    begin: (?<![a-zA-Z\\])\[
    end: (?<!\\)\] 
    lookForThis: 1

gives the output

$
  a
  +
  [
    b + c
  ]
  =
  d
$
and
$
  e + f = g
$

\todo[inline]{
  Do something.
}

explanation

The expression

begin: (?<![a-zA-Z\\])\[

means [ but not immediately preceded by a to z, A to Z, or a backslash. This setting is means that commands, such as \todo in your example, are then found appropriately.

arodomanov commented 11 months ago

Good idea, thanks. This solution seems acceptable for my needs.

cmhughes commented 11 months ago

Great, glad it worked!