views:

446

answers:

3

Hello,

I am trying to replace characters inside a math environment with their boldface versions. Unfortunately, these characters occur inside the rest of the text, as well.

My text:

text text text text Gtext G G text ....
\begin{align}
f&=gG \\
G &= tG
\end{align}

text textG text $G$ text.


Every G inside \begin{align} \end{align} and between the dollar signs $G$ shall be replaced with

\mathbf{G}.

The others shall remain untouched.

I appreciate every idea :)

Thank you

BIG EDIT: So far, I have a working Program (Python), thanks to the advice and some other findings in stackoverflow.

But the program replaces f.e \quad to \q"replace"ad. if I want to replace all the "u" s with "replace".

from tempfile import mkstemp
from shutil import move
from os import remove, close
import shutil

def replace(file, outputfile, pattern, subst, boundary1, boundary2):
    #Create temp file
    fh, abs_path = mkstemp()
    newfile="tempfile.tmp"
    new_file = open(newfile,'w')
    old_file = open(file)
    inAlign=False
    for line in old_file:
     if boundary1 in line:
           inAlign = True

     if inAlign:
      print line
      print line.replace(pattern, subst)

      new_file.write(line.replace(pattern, subst))
     else:
      new_file.write(line)

     if boundary2 in line:
      inAlign = False;



    #close temp file

    new_file.close()
    close(fh)
    old_file.close()

    shutil.move(newfile,outputfile)

replace("texfile.tex","texfile_copy.tex","G", "\\mathbf{G}", "\\begin{align}", "\\end{align}")

Hopefully I got the formatting right...

+2  A: 

This will be hard-to-impossible with regexes alone. What language are you using? It it's perl, there's a module LaTeX::TOM that will help you out a great deal.

However, if you know that your \begin and \end tags are always on their own line, the following pseudocode would work:

foreach (line in file)
    if line.matches( /\\begin{align}/ )
        inAlign = true
    end

    if inAlign
        line.replace( /(G)/\\mathbf{$1}/ )
    else
        line.replace( /\$(G)\$/\$\\mathbf{$1}\$/ )
    end

    if line.matches( /\\end{align}/ )
        inAlign = false;
    end
end
JSBangs
Thank you for your reply.I have never used Perl and I hoped that there is a simpler method.I need to replace more characters with different commands. The above is just an example. "Trying" out Perl and diffing every change would be very cumbersome.
A: 

This will find the Gs within the align blocks:

s/(?<=\\begin\{align\})(((?!\\end\{align\}).)*?)G/{$1}\mathbf{G}/g
Jeremy Stein
A: 

To really solve this, you need to write a parser. Parsing general TeX is a task that might euphemistically be called nontrivial (try running this file through TeX), but for typical LaTeX math expressions you could start from matplotlib's parser and hack it to do the replacements you want. It still won't be trivial but shouldn't be insurmountable either.

Jouni K. Seppänen