rsc05
rsc05

Reputation: 3820

Sublime and Python: How to use Python Plugin to create neat equations from Scientific Workplace in Latex

I am using a program that helps in writing latex. However, there is a problem that everytime I write an argument it display it as eqnarray*

For example

\begin{eqnarray*}
r_{t}^{p} &=&\frac{P_{t}-P_{t-1}}{P_{t-1}} \\
&=&\frac{\left( \left( 1-\alpha \right) r_{t}^{\ast }-\alpha \right)
P_{t-1}+\alpha A_{t}}{P_{t-1}} \\
&=&\left( 1-\alpha \right) r_{t}^{\ast }-\alpha +\alpha \frac{A_{t}}{P_{t-1}}
\\
&=&\left( 1-\alpha \right) r_{t}^{\ast }+\alpha \left( \frac{A_{t}}{P_{t-1}}%
-1\right) 
\end{eqnarray*}

I want it to look more organized as so

\begin{equation*}
    \begin{split} 
        r_{t}^{p} &=\frac{P_{t}-P_{t-1}}{P_{t-1}} \\ 
        &=\frac{((1-\alpha) r_{t}^{\ast}-\alpha) P_{t-1}+\alpha A_{t}}{P_{t-1}} \\ 
        &=(1-\alpha) r_{t}^{\ast}-\alpha +\alpha \frac{A_{t}}{P_{t-1}} \\ 
        &=(1-\alpha) r_{t}^{\ast}+\alpha (\frac{A_{t}}{P_{t-1}} -1) 
    \end{split}
\end{equation*}

I am using Sublime text 3 editor, therefore, I find myself doing the same thing again and again which is the following steps

  1. replace all the \ with /
  2. make it one line

    s= '/begin{eqnarray*} r_{t}^{p} &=&/frac{P_{t}-P_{t-1}}{P_{t-1}} // &=&/frac{/left( /left( 1-/alpha /right) r_{t}^{/ast }-/alpha /right) P_{t-1}+/alpha A_{t}}{P_{t-1}} // &=&/left( 1-/alpha /right) r_{t}^{/ast }-/alpha +/alpha /frac{A_{t}}{P_{t-1}} // &=&/left( 1-/alpha /right) r_{t}^{/ast }+/alpha /left( /frac{A_{t}}{P_{t-1}}% -1/right) /end{eqnarray*}'

  3. remove %

    s=s.replace("%", "") s

  4. replace eqnarray* by equation*

    s1=s.replace("eqnarray*", "equation*")

  5. if the text include // then include a \begin{split} directly after \begin{equation*} and \end{split} before \end{equation}

    if '//' in s1: f1 = "equation*}" f2='/end{equation*}' s3=s1[:s1.index(f1) + len(f1)] + '/begin{split}' + s1[s1.index(f1) + len(f1):] s4= s3[:s3.index(f2)] + '/end{split}' + s3[s3.index(f2):s3.index(f2) + len(f2)]

etc...

I have written a plugin code as so

import sublime, sublime_plugin, re, string   #import the required modules

class RonvertCommand(sublime_plugin.TextCommand): #create Text Command
    def run(self, edit):   #implement run method
        for region in self.view.sel():  #get user selection
            if not region.empty():  #if selection not empty then
                s = self.view.substr(region)  #assign s variable the selected region
                s4=s.replace("%", "")
                # s1=s.replace("eqnarray*", "equation*")
                if '\\begin{eqnarray*}' in s4:
                    s4=s4.replace("eqnarray*", "equation*")
                    f1 = "equation*}"
                    s4=s4[:s4.index(f1) + len(f1)] + '\\begin{split}' + s4[s4.index(f1) + len(f1):]
                    f2='\\end{equation*}'
                    s4= s4[:s4.index(f2)] + '\end{split}' + s4[s4.index(f2):s4.index(f2) + len(f2)]
                if '\\end{eqnarray*}' in s4:
                    s4=s4.replace("eqnarray*", "equation*")
                    f2='\\end{equation*}'
                    s4= s4[:s4.index(f2)] + '\end{split}' + s4[s4.index(f2):s4.index(f2) + len(f2)]
                s4=s4.replace("&=&", "&=")
                s4=s4.replace("\\left", "")
                s4=s4.replace("\\right", "")
                s4=s4.replace("( ", "(")
                s4=s4.replace(" )", ")")
                s4=s4.replace(" }", "}")
                s4=s4.replace(" _{", "_{")
                s4=s4.replace("[ ", "[")
                s4=s4.replace(" ]", "]")
                s4=s4.replace("& =", "&=")
                s4=s4.replace("+(", "+ (")
                # s1 = '\n'.join([' '.join(para.splitlines()) for para in s.split('\n\n')])
                self.view.replace(edit, region, s4) #replace content in view

However, I still need to do some steps before I use the plugin and after I use it. This is because I can not simply write \ in python I need to write it as / can anybody help me reach this desirable thing without these mess?

Thank you

Upvotes: 0

Views: 218

Answers (1)

rsc05
rsc05

Reputation: 3820

I have solved my problem with noticing some nice issues. First realized that before coding it into sublime text 3 plug-in we have to do some tests on python Jupyter notebook. As I mentioned in my question the problem with taking strings in \ is a problematic therefore in sublime text 3 it automaticall transform it to \\ therefore, to do some testing on python it is always better to replace all \ with a \\ and then paste it as a string in python. This what I have done and I was able to fix my problem.

The code goes as follow

import sublime, sublime_plugin, re, string   #import the required modules

class RonvertCommand(sublime_plugin.TextCommand): #create Text Command
    def run(self, edit):   #implement run method
        for region in self.view.sel():  #get user selection
            if not region.empty():  #if selection not empty then
                s = self.view.substr(region)  #assign s variable the selected region
                s4=s.replace("%", "")
                if '\\begin{eqnarray*}' in s4:
                    s4=s4.replace("eqnarray*", "equation*")
                    f1 = "equation*}"
                    s4=s4[:s4.index(f1) + len(f1)] + '\n\t\\begin{split}' + s4[s4.index(f1) + len(f1):]
                    f2='\\end{equation*}'
                    s4= s4[:s4.index(f2)] + '\t\\end{split}\n' + s4[s4.index(f2):s4.index(f2) + len(f2)]
                    ss=s4.split('\n')
                    while '\\\\' in ss:
                            a=ss.index('\\\\')
                            ss[a-1]= ss[a-1] + '\\\\'
                            del ss[a]
                    a=ss.index('\t\\end{split}')
                    ss[a-1]=ss[a-1]+ '\\\\'
                    for x in range(ss.index('\t\\begin{split}')+1,ss.index('\t\\end{split}')-1):
                        if x<ss.index('\t\\end{split}')-1:
                            if '&=&' and '\\\\' not in ss[x]:
                                ss[x]=ss[x]+ss[x+1]
                                del ss[x+1]
                    for x in range(ss.index('\t\\begin{split}')+1,ss.index('\t\\end{split}')):
                        ss[x]='\t\t'+ ss[x]
                    s4="\n".join(ss)  

                elif ('\\[' in s4) or ('\\begin{equation*}' in s4):
                    s4=s4.replace("\\[","\\begin{equation*}")
                    s4=s4.replace("\\]","\\end{equation*}")
                    ss=s4.split('\n')
                    for x in range(2,len(ss)-1):
                        ss[1]=ss[1]+ss[x]
                    ss=[ss[0],ss[1], ss[-1]]
                    s4="\n".join(ss)
                    s4=s4[0:s4.index('\n')+1]+'\t'+s4[1+s4.index('\n')::]
                # For all the sentences beteween I want to insert two tabs 
                s4=s4.replace("&=&", "&=")
                s4=s4.replace("&&", "&")
                s4=s4.replace("\\left", "")
                s4=s4.replace("\\right", "")
                s4=s4.replace("( ", "(")
                s4=s4.replace(" )", ")")
                s4=s4.replace(" }", "}")
                s4=s4.replace(" _{", "_{")
                s4=s4.replace("[ ", "[")
                s4=s4.replace(" ]", "]")
                s4=s4.replace("& =", "&=")
                s4=s4.replace("+(", "+ (")
                s4=s4.replace("+\\", "+ \\")
                s4=s4.replace("}+", "} +")
                s4=s4.replace(") -(", ")-(")
                s4=s4.replace(") -(", ")-(")
                s4=s4.replace(") (", ")(")
                s4=s4.replace(") -", ")-")
                s4=s4.replace(") ^", ")^")
                s4=s4.replace(") $", ")$")
                s4=s4.replace("} +", "}+")
                s4=s4.replace("\\text{ and}", "\\qquad\\text{and}\\qquad ")
                s4=s4.replace("\\text{ or}", "\\qquad\\text{or}\\qquad ")
                s4=s4.replace("\\text{ where}", "\\text{,}\\qquad\\text{where}\\qquad")

                if '\\vert' in s4:
                    Vert = re.findall('vert', s4)
                    for i in range(0,int(len(Vert)/2)):
                        A=re.search(r'(\\vert.*?\\vert)', s4).group(1)
                        s3=re.sub(r"{array}{([a-z])\1+}", "{vmatrix}", A)
                        s3=re.sub(r"{array}", "{vmatrix}", s3)
                        s3=s3.replace("\\vert", "")
                        s4=s4[0:s4.index(A)]+s3+s4[s4.index(A)+len(A):]
                s4=s4.replace("\\text{if}", "\\text{if}\\qquad ")

                if '(' in s4:
                    start = '('
                    end = ')'
                    A=s4[s4.find(start)+len(start):s4.rfind(end)-1]
                    if '(' in A:
                        s4=s4[:s4.find(start)]+'\\Big('+s4[s4.find(start)+len(start):s4.rfind(end)]+'\\Big)'+s4[1+s4.rfind(end)::]


                self.view.replace(edit, region, s4) 

                #replace content in view
                # self.view.replace(edit, region, s.count('\n')) #replace content in view
                # self.view.insert(edit, 0, s.count('\n'))

Additional steps for Keybindings

1- go to Keybinding (Preference-Key bindings)

2- paste the following:

{"keys": ["alt+x"], "command": "ronvert"},

3- save it and close

now you can select all the text and just apply press alt x on windows enter image description here

Upvotes: 1

Related Questions