diff options
Diffstat (limited to 'numpy/doc/numpybook/runcode.py')
-rw-r--r-- | numpy/doc/numpybook/runcode.py | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/numpy/doc/numpybook/runcode.py b/numpy/doc/numpybook/runcode.py new file mode 100644 index 000000000..a0b82340b --- /dev/null +++ b/numpy/doc/numpybook/runcode.py @@ -0,0 +1,148 @@ +# This script takes a lyx file and runs the python code in it. +# Then rewrites the lyx file again. +# +# Each section of code portion is assumed to be in the same namespace +# where a from numpy import * has been applied +# +# If a PYNEW inside a Note is encountered, the name space is restarted +# +# The output (if any) is replaced in the file +# by the output produced during the code run. +# +# Options: +# -n name of code section (default MyCode) +# + +import sys +import optparse +import cStringIO +import re +import os + +newre = re.compile(r"\\begin_inset Note.*PYNEW\s+\\end_inset", re.DOTALL) + +def getoutput(tstr, dic): + print "\n\nRunning..." + print tstr, + tempstr = cStringIO.StringIO() + sys.stdout = tempstr + code = compile(tstr, '<input>', 'exec') + try: + res = eval(tstr, dic) + sys.stdout = sys.__stdout__ + except SyntaxError: + try: + res = None + exec code in dic + finally: + sys.stdout = sys.__stdout__ + if res is None: + res = tempstr.getvalue() + else: + res = tempstr.getvalue() + '\n' + repr(res) + if res != '': + print "\nOutput is" + print res, + return res + +# now find the code in the code segment +def getnewcodestr(substr, dic): + end = substr.find('\\layout ') + lines = substr[:end].split('\\newline') + outlines = [] + first = 1 + cmd = '' + lines.append('dummy') + for line in lines: + line = line.strip() + if (line[:3]=='>>>') or (line == 'dummy'): + # we have a new output + pyoutstr = getoutput(cmd, dic).strip() + if pyoutstr != '': + pyout = pyoutstr.split('\n') + outlines.extend(pyout) + cmd = line[4:] + elif (line[:3]=='...'): + # continuation output + cmd += "\n%s" % line[4:] + else: + # first line or output + if first: + first = 0 + cmd = line + else: + continue + if line != 'dummy': + outlines.append(line) + return "\n\\newline \n".join(outlines), end + + +def runpycode(lyxstr, name='MyCode'): + schobj = re.compile(r"\\layout %s\s+>>> " % name) + outstr = cStringIO.StringIO() + num = 0 + indx = [] + for it in schobj.finditer(lyxstr): + indx.extend([it.start(), it.end()]) + num += 1 + + if num == 0: + print "Nothing found for %s" % name + return lyxstr + + start = 0 + del indx[0] + indx.append(len(lyxstr)) + edic = {} + exec 'from numpy import *' in edic + exec 'set_printoptions(linewidth=65)' in edic + # indx now contains [st0,en0, ..., stN,enN] + # where stX is the start of code segment X + # and enX is the start of \layout MyCode for + # the X+1 code section (or string length if X=N) + for k in range(num): + # first write everything up to the start of the code segment + substr = lyxstr[start:indx[2*k]] + outstr.write(substr) + if start > 0: + mat = newre.search(substr) + # if PYNEW found, then start a new namespace + if mat: + edic = {} + exec 'from numpy import *' in edic + exec 'set_printoptions(linewidth=65)' in edic + # now find the code in the code segment + # endoutput will contain the index just past any output + # already present in the lyx string. + substr = lyxstr[indx[2*k]:indx[2*k+1]] + lyxcodestr, endcode = getnewcodestr(substr, edic) + # write the lyx for the input + new output + outstr.write(lyxcodestr) + outstr.write('\n') + start = endcode + indx[2*k] + + outstr.write(lyxstr[start:]) + return outstr.getvalue() + + +def main(args): + usage = "%prog {options} filename" + parser = optparse.OptionParser(usage) + parser.add_option('-n','--name', default='MyCode') + + options, args = parser.parse_args(args) + if len(args) < 1: + parser.error("incorrect number of arguments") + + os.system('cp -f %s %s.bak' % (args[0], args[0])) + fid = file(args[0]) + str = fid.read() + fid.close() + print "Processing %s" % options.name + newstr = runpycode(str, options.name) + fid = file(args[0],'w') + fid.write(newstr) + fid.close() + +if __name__ == "__main__": + main(sys.argv[1:]) |