1

I am trying to correct some long latex files > 10 000 lines. Something that bothers me and messes with the typopgraphy is the missuse of align and equation environments.

  • The equation environment should be used instead of align whenever the equation does not contain \\ or \newline

I know there exists some fringe cases with \begin{cases} and matrices, but the change above should do the bulk of the work, and I can do the rest manually.

Question

  • How can I write an regex expression that changes every align and align* environment into respectively equation and equation* environments, whenever the environment does not contain \\ or \newline?
  • I would also like to be able to remove & from the equation environments if possible.

Test cases

Input:

\begin{align}
  a &= b + c
\end{align}

\begin{align}
    a 
  &=b 
   + c
\end{align}

\begin{align*}
  a &= b + c
\end{align*}

\begin{align}
    a = b \newline c = d
\end{align}

\begin{align}
    a = b \\ c = d
\end{align}

Output

\begin{equation}
  a = b + c
\end{equation}

\begin{equation}
    a 
   =b 
   + c
\end{equation}

\begin{equation*}
  a = b + c
\end{equation*}

\begin{align}
    a = b \newline c = d
\end{align}

\begin{align}
    a = b \\ c = d
\end{align}
2

Try this:

%s/\\begin{align\*\=}\_.\{-}\\end{align\*\=}/\=submatch(0) !~# '\s\\\\\s\|\\newline' ? substitute(substitute(submatch(0), '\\\%(begin\|end\){\zsalign\(\*\=\)\ze}', 'equation\1', 'g'), '&=', '=', 'g') : submatch(0)/g

The pattern of the substitution command is:

\\begin{align\*\=}\_.\{-}\\end{align\*\=}

And the replacement is:

\=submatch(0) !~# '\s\\\\\s\|\\newline' ? substitute(substitute(submatch(0), '\\\%(begin\|end\){\zsalign\(\*\=\)\ze}', 'equation\1', 'g'), '&=', '=', 'g') : submatch(0)

It's an evaluated expression, because it begins with \=; and it relies on the conditional operator ?: which expects 3 operands.

The first operand – used as a test – is:

submatch(0) !~# '\s\\\\\s\|\\newline'

The second operand – used as the value if the test succeeds – is:

substitute(substitute(submatch(0), '\\\%(begin\|end\){\zsalign\(\*\=\)\ze}', 'equation\1', 'g'), '&=', '=', 'g')

The inner substitute() replaces align into equation, while the outer one removes &.

The third operand – used as the value if the test fails – is:

submatch(0)

For more information, see:

:h :s
:h /\_.
:h /\{-
:h /\=
:h :s\=
:h submatch()
:h !~#
:h /\s
:h /bar
:h expr1
:h substitute()
:h /\(
:h /\%(
:h /\zs
:h /\ze
:h /\1
  • Hmm, this seemed to replace all my aligns with equations. I am used the newest neovim configuration. I am not sure if that makes a difference? Regards – N3buchadnezzar Aug 26 '19 at 10:46
  • It converts the input file into the output file included in your question. It also works with Neovim (v0.4.0), with and without config. If the command fails on these files, try to reproduce without config ($ nvim -Nu NONE). If it fails on other files, you'll need to provide them. – user938271 Aug 26 '19 at 10:56
  • Hardcore answer.....I like it. +1! :) – B Layer Aug 26 '19 at 15:19
  • @user938271 I've tried with vim, neovim in standard configuration. I even tried a few online tools all of them replaces every align with equation regardless of wheter it contains `\` . I tried to copy paste the first line in your answer, am I doing something fundamentally wrong? – N3buchadnezzar Sep 3 '19 at 13:52
  • Here's a gif: i.imgur.com/xLDmLdw.gif On the left side and right sides are resp. the input and output files copied from the OP. Vim (8.1.1967) is started in diff mode (because it's invoked as $ vimdiff), and without any custom config (because of -Nu NONE). The substitution command which is run, has been copied from the posted answer. After the substitution, there's no difference between the input and output files, except for a missing space in front of =b in the second environment (but that seems irrelevant to the current issue). – user938271 Sep 3 '19 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.