0

I'm trying to globally enclose in {}'s all instances of +,-,= that aren't already so enclosed. But I don't want to do this for lines that are latex commands. Since my latex commands are all on separate lines, and all begin with \, possibly preceded by tabs or spaces, my idea is to do the search and replace on any line except ones whose first non-whitespace character is \ Here's a simple example:

\parindent=0 pt
    \parskip=12 pt 
$=$
${=}$

My search and replace should operate only on the third line. From what I've read in this forum, the following should work at least for lines that begin with \, but it doesn't work even for this limited class, so I must be doing something wrong.

:g/^([^\\].*[^\{]=[^\}])/s/=/{=}/g

Could somebody please explain what I'm missing? And of course,

As a bonus, if you could explain how I would do the enclosures for +,-, and = all in the one command, as opposed to three separate commands that would be most helpful.

1 Answer 1

2

Your global regex is a bit too complex for this, I think. I would use

vglobal/^\s*\\\|{[-+=]}/ ...

to match all the lines not starting with optional whitespace followed by a \ and not containing one of the symbols already in braces. (The « backslash hell » is a necessary without \v, and even then you need \\ for the actual backslash.)

Then, you can use a backreference to do the rest of the substitution (replaces the ellipsis above):

substitute/[-+=]/{&}/ge

Some finer points:

  • - must come at the beginning or end of the character class because otherwise it builds a range.
  • I used the /e flag because we are no loner guaranteed to have a match in the line (this is the price of simplifying the global match).
8
  • OP also included a fourth line where the = is already wrapped {=} and mentioned "only third line"... So maybe add some extra matches there? (Yeah this is getting complicated again, especially if you consider matches at the end of the line.)
    – filbranden
    Jun 7, 2020 at 14:15
  • 1
    Rats yeah. I think I’ll handle in the vglobal @filbranden
    – D. Ben Knoble
    Jun 7, 2020 at 16:16
  • Also possible would be s/{\?\([-+=]\)}\?/{\1}/ge, which always substitutes but if one is already wrapped it will replace the curly braces too (effectively replacing it with itself.) This one also has a corner case that will replace {=something} with {=}something}, so yeah it's pretty hard to find a foolproof way to do this replacement.
    – filbranden
    Jun 7, 2020 at 18:02
  • 1
    Your current answer also uses \1 without an actual capture group... Might as well just use & directly (like you suggested later.)
    – filbranden
    Jun 7, 2020 at 18:03
  • That's very elegant indeed, thank you both very much. Two questions, one easy one hard: 1) what role does the \| play? 2) Of course, the command is going to skip lines that have, for example, {-} +. One very kludgy way around this would be to first replace all occurrences of {[-+=]} with their unbraced versions using something like :g/{\([-+=]\)}/s// \1 /g and then run something like vg/^\s*\\/s/[-+=]/{&}/g that will pick up all instances of unbraced +-=. Is there a better way to do this?
    – Leo Simon
    Jun 8, 2020 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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