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
864 stars 84 forks source link

`-r` switch does not respect `indentPreamble: 0` #517

Closed torik42 closed 6 months ago

torik42 commented 6 months ago

original .tex code

\documentclass{article}

\usepackage{mathtools}
\DeclarePairedDelimiter{\norm}{\lVert}{\rVert}

\begin{document}

$\lVert A \rVert$

\end{document}

yaml settings

indentPreamble: 0

replacements:
  -
    substitution: |-
      s/
        (?<!\\) \\l?Vert
        \s* (?P<content> .+? ) \s*
        (?<!\\) \\r?Vert
      /\\norm{$+{content}}/sgx

actual/given output

\documentclass{article}

\usepackage{mathtools}
\DeclarePairedDelimiter{\norm}{\norm{}{}}

\begin{document}

$\norm{A}$

\end{document}

desired or expected output

\documentclass{article}

\usepackage{mathtools}
\DeclarePairedDelimiter{\norm}{\lVert}{\rVert}

\begin{document}

$\norm{A}$

\end{document}

anything else

My expectation was that replacements would respect the indentPreamble key (also the modifylinebreaks switch respects it). One could have a separate setting to enable replacements in the preamble, if one wants them also there. Or a key to only use latexindent for the preamble. This would allow for different configurations for the preamble and the rest by running latexindent twice.

cmhughes commented 6 months ago

I have a few ideas on how to do this. Hoping to get to this over the weekend.

cmhughes commented 6 months ago

Here are a couple of options, both give your desired output.

option 1

Using the following

replacements:
  -
    substitution: |-
      s/
        (.*?)(\\begin\{document.*)/
        my $preamble = $1;                    # store preamble
        my $body = $2;                        # store body
        $body =~ s|(?<!\\) \\l?Vert           # 
                   \s* (?P<content> .+? ) \s* # make substitutions
                   (?<!\\) \\r?Vert           # on BODY
                  |\\norm{$+{content}}|sgx;   # 
        $preamble.$body;/esgx                 # reassemble

and calling

latexindent.pl -l -r myfile.tex

option 2

Using

specialBeginEnd:
  preamble:
    begin: \\documentclass
    end: \\begin\{document\}
    lookForThis: verbatim

replacements:
  -
    substitution: |-
      s/
        (?<!\\) \\l?Vert           
                   \s* (?P<content> .+? ) \s* 
                   (?<!\\) \\r?Vert           
       /\\norm{$+{content}}/sgx   

stores the preamble as a verbatim block and using the rv switch as in

latexindent.pl -rv -l myfile.tex
cmhughes commented 6 months ago

Let me know if you need anything else on this.

torik42 commented 4 months ago

Sorry for the (very) late reply. For my specific case I just use a negative lookbehind for the \DeclarePairedDelimiter now. The evaluate modifier still gave me some other ideas (I tried it quite some time ago and couldn’t make it work), now it worked. Thanks.