Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Sagetex from the notebook - feedback on how I automate things

This isn't really a question, so please accept my apologies if non-questions are unwelcome here.

I am using sage with latex, but I am the kind of person who doesn't like leaving the notebook, so I tried to automate the process. You can see my code below. Any comments and suggestions are appreciated.

Also, if you think you will find this or a similar setup useful, please say so, because people who like staying within the notebook are probably underrepresented among the developers.

def load_cache(f): # so that we don't recompute for every latex change
    try:f.cache=load(DATA+"/cache/"+f.f.func_name)
    except IOError:pass

def export_code (list_of_functions, folder): # copy code to our latex folder
    for func in list_of_functions:
        try:
            save(func.cache,DATA+"/cache/"+func.f.func_name)
            func=func.f
        except AttributeError:pass # in case the function isn't cached
        sh.eval("cp " + func.func_code.co_filename + " " + folder + "/" + func.func_name + ".py")

def runsagelatex(latexfile):
    def evalindir(cmd,path): # otherwise the output appears in the current directory
        sh.eval("( cd "+os.path.dirname(path)+" ; "+cmd+" )")
    evalindir("pdflatex --file-line-error "+latexfile,latexfile)
    evalindir("sage "+os.path.splitext(latexfile)[0]+".sagetex.sage",latexfile)
    evalindir("pdflatex --file-line-error "+latexfile,latexfile)

def sagelatex(name="project",export=[],cmd=""):
    html(r'<div class="notruncate">') # for the output of pdflatex
    try:os.mkdir(DATA+"/cache/")
    except OSError:pass
    try:os.mkdir(DATA+"/sagelatex/")
    except OSError:pass
    try:os.mkdir(DATA+"/sagelatex/sagenb-export/")
    except OSError:pass
    export_code(export,DATA+"/sagelatex/sagenb-export/")
    f=open(DATA+"/sagelatex/"+name+".tex","wb")
    f.write(cmd)
    f.close()
    runsagelatex(DATA+"/sagelatex/"+name+".tex")
    html(r'</div>')

Example usage:

def f1(a,b):
    return a+b

@cached_function
def f2(a):
    return a^2
load_cache(f2)

And in a new cell (and change DATA below):

sagelatex(name="myproject",export=[f1,f2,load_cache],cmd=\
r"""
\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
DATA="/.../.sage/sage_notebook.sagenb/home/user/123/data/" # make it match the worksheet's DATA constant
execfile("sagenb-export/load_cache.py")
execfile("sagenb-export/f1.py")
execfile("sagenb-export/f2.py")
\end{sagesilent}
$\sage{f1(1,2)+f2(10)}$
\end{document}
""")

This should produce a pdf file in your DATA/sagelatex folder.

Sagetex from the notebook - feedback on how I automate things

This isn't really a question, so please accept my apologies if non-questions are unwelcome here.

I am using sage with latex, but I am the kind of person who doesn't like leaving the notebook, so I tried to automate the process. You can see my code below. Any comments and suggestions are appreciated.

Also, if you think you will find this or a similar setup useful, please say so, because people who like staying within the notebook are probably underrepresented among the developers.

def load_cache(f): # so that we don't recompute for every latex change
    try:f.cache=load(DATA+"/cache/"+f.f.func_name)
    except IOError:pass

def export_code (list_of_functions, folder): # copy code to our latex folder
    for func in list_of_functions:
        try:
            save(func.cache,DATA+"/cache/"+func.f.func_name)
            func=func.f
        except AttributeError:pass # in case the function isn't cached
        sh.eval("cp " + func.func_code.co_filename + " " + folder + "/" + func.func_name + ".py")

def runsagelatex(latexfile):
    def evalindir(cmd,path): # otherwise the output appears in the current directory
        sh.eval("( cd "+os.path.dirname(path)+" ; "+cmd+" )")
    evalindir("pdflatex --file-line-error "+latexfile,latexfile)
    evalindir("sage "+os.path.splitext(latexfile)[0]+".sagetex.sage",latexfile)
    evalindir("pdflatex --file-line-error "+latexfile,latexfile)

def sagelatex(name="project",export=[],cmd=""):
    html(r'<div class="notruncate">') # for the output of pdflatex
    try:os.mkdir(DATA+"/cache/")
    except OSError:pass
    try:os.mkdir(DATA+"/sagelatex/")
    except OSError:pass
    try:os.mkdir(DATA+"/sagelatex/sagenb-export/")
    except OSError:pass
    export_code(export,DATA+"/sagelatex/sagenb-export/")
    f=open(DATA+"/sagelatex/"+name+".tex","wb")
    f.write(cmd)
    f.close()
    runsagelatex(DATA+"/sagelatex/"+name+".tex")
    html(r'</div>')

Example usage:

def f1(a,b):
    return a+b

@cached_function
def f2(a):
    return a^2
load_cache(f2)

And in a new cell (and change DATA below):

sagelatex(name="myproject",export=[f1,f2,load_cache],cmd=\
r"""
\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
DATA="/.../.sage/sage_notebook.sagenb/home/user/123/data/" # make it match the worksheet's DATA constant
execfile("sagenb-export/load_cache.py")
execfile("sagenb-export/f1.py")
execfile("sagenb-export/f2.py")
\end{sagesilent}
$\sage{f1(1,2)+f2(10)}$
\end{document}
""")

This should produce a pdf file in your DATA/sagelatex folder.folder. That folder is accessible through your web browser.