Server : Apache System : Linux indy02.toastserver.com 3.10.0-962.3.2.lve1.5.85.el7.x86_64 #1 SMP Thu Apr 18 15:18:36 UTC 2024 x86_64 User : palandch ( 1163) PHP Version : 7.1.33 Disable Function : NONE Directory : /opt/alt/python27/lib64/python2.7/site-packages/matplotlib/sphinxext/ |
import sys, os, shutil, imp, warnings, cStringIO, re import IPython from IPython.Shell import MatplotlibShell try: from hashlib import md5 except ImportError: from md5 import md5 from docutils.parsers.rst import directives import sphinx sphinx_version = sphinx.__version__.split(".") # The split is necessary for sphinx beta versions where the string is # '6b1' sphinx_version = tuple([int(re.split('[a-z]', x)[0]) for x in sphinx_version[:2]]) COMMENT, INPUT, OUTPUT = range(3) rgxin = re.compile('In \[(\d+)\]:\s?(.*)\s*') rgxout = re.compile('Out\[(\d+)\]:\s?(.*)\s*') fmtin = 'In [%d]:' fmtout = 'Out[%d]:' def block_parser(part): """ part is a string of ipython text, comprised of at most one input, one ouput, comments, and blank lines. The block parser parses the text into a list of:: blocks = [ (TOKEN0, data0), (TOKEN1, data1), ...] where TOKEN is one of [COMMENT | INPUT | OUTPUT ] and data is, depending on the type of token:: COMMENT : the comment string INPUT: the (DECORATOR, INPUT_LINE, REST) where DECORATOR: the input decorator (or None) INPUT_LINE: the input as string (possibly multi-line) REST : any stdout generated by the input line (not OUTPUT) OUTPUT: the output string, possibly multi-line """ block = [] lines = part.split('\n') #print 'PARSE', lines N = len(lines) i = 0 decorator = None while 1: if i==N: # nothing left to parse -- the last line break line = lines[i] i += 1 line_stripped = line.strip() if line_stripped.startswith('#'): block.append((COMMENT, line)) continue if line_stripped.startswith('@'): # we're assuming at most one decorator -- may need to # rethink decorator = line_stripped continue # does this look like an input line? matchin = rgxin.match(line) if matchin: lineno, inputline = int(matchin.group(1)), matchin.group(2) # the ....: continuation string continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) Nc = len(continuation) # input lines can continue on for more than one line, if # we have a '\' line continuation char or a function call # echo line 'print'. The input line can only be # terminated by the end of the block or an output line, so # we parse out the rest of the input line if it is # multiline as well as any echo text rest = [] while i<N: # look ahead; if the next line is blank, or a comment, or # an output line, we're done nextline = lines[i] matchout = rgxout.match(nextline) #print "nextline=%s, continuation=%s, starts=%s"%(nextline, continuation, nextline.startswith(continuation)) if matchout or nextline.startswith('#'): break elif nextline.startswith(continuation): inputline += '\n' + nextline[Nc:] else: rest.append(nextline) i+= 1 block.append((INPUT, (decorator, inputline, '\n'.join(rest)))) continue # if it looks like an output line grab all the text to the end # of the block matchout = rgxout.match(line) if matchout: lineno, output = int(matchout.group(1)), matchout.group(2) if i<N-1: output = '\n'.join([output] + lines[i:]) #print 'OUTPUT', output block.append((OUTPUT, output)) break #print 'returning block', block return block import matplotlib matplotlib.use('Agg') class EmbeddedSphinxShell: def __init__(self): self.cout = cStringIO.StringIO() IPython.Shell.Term.cout = self.cout IPython.Shell.Term.cerr = self.cout argv = ['-autocall', '0'] self.user_ns = {} self.user_glocal_ns = {} self.IP = IPython.ipmaker.make_IPython( argv, self.user_ns, self.user_glocal_ns, embedded=True, #shell_class=IPython.Shell.InteractiveShell, shell_class=MatplotlibShell, rc_override=dict(colors = 'NoColor')) self.input = '' self.output = '' self.is_verbatim = False self.is_doctest = False self.is_suppress = False # on the first call to the savefig decorator, we'll import # pyplot as plt so we can make a call to the plt.gcf().savefig self._pyplot_imported = False # we need bookmark the current dir first so we can save # relative to it self.process_input('bookmark ipy_basedir') self.cout.seek(0) self.cout.truncate(0) def process_input(self, line): 'process the input, capturing stdout' #print "input='%s'"%self.input stdout = sys.stdout sys.stdout = self.cout #self.IP.resetbuffer() self.IP.push(self.IP.prefilter(line, 0)) #self.IP.runlines(line) sys.stdout = stdout def process_block(self, block): """ process block from the block_parser and return a list of processed lines """ #print 'BLOCK', block ret = [] output = None input_lines = None m = rgxin.match(str(self.IP.outputcache.prompt1).strip()) lineno = int(m.group(1)) input_prompt = fmtin%lineno output_prompt = fmtout%lineno image_file = None image_directive = None for token, data in block: if token==COMMENT: if not self.is_suppress: ret.append(data) elif token==INPUT: decorator, input, rest = data #print 'INPUT:', data is_verbatim = decorator=='@verbatim' or self.is_verbatim is_doctest = decorator=='@doctest' or self.is_doctest is_suppress = decorator=='@suppress' or self.is_suppress is_savefig = decorator is not None and decorator.startswith('@savefig') #print 'is_verbatim=%s, is_doctest=%s, is_suppress=%s, is_savefig=%s'%(is_verbatim, is_doctest, is_suppress, is_savefig) input_lines = input.split('\n') continuation = ' %s:'%''.join(['.']*(len(str(lineno))+2)) Nc = len(continuation) if is_savefig: saveargs = decorator.split(' ') filename = saveargs[1] outfile = os.path.join('_static/%s'%filename) # build out an image directive like # .. image:: somefile.png # :width 4in # # from an input like # savefig somefile.png width=4in imagerows = ['.. image:: %s'%outfile] for kwarg in saveargs[2:]: arg, val = kwarg.split('=') arg = arg.strip() val = val.strip() imagerows.append(' :%s: %s'%(arg, val)) image_file = outfile image_directive = '\n'.join(imagerows) # TODO: can we get "rest" from ipython #self.process_input('\n'.join(input_lines)) is_semicolon = False for i, line in enumerate(input_lines): if line.endswith(';'): is_semicolon = True if i==0: # process the first input line if is_verbatim: self.process_input('') else: # only submit the line in non-verbatim mode self.process_input(line) formatted_line = '%s %s'%(input_prompt, line) else: # process a continuation line if not is_verbatim: self.process_input(line) formatted_line = '%s %s'%(continuation, line) if not is_suppress: ret.append(formatted_line) if not is_suppress: if len(rest.strip()): if is_verbatim: # the "rest" is the standard output of the # input, which needs to be added in # verbatim mode ret.append("%s"%rest) ret.append('') self.cout.seek(0) output = self.cout.read() if not is_suppress and not is_semicolon and not is_verbatim: ret.append(output) self.cout.truncate(0) elif token==OUTPUT: #print 'token==OUTPUT is_verbatim=%s'%is_verbatim if is_verbatim: # construct a mock output prompt output = '%s %s\n'%(fmtout%lineno, data) ret.append(output) #print 'token==OUTPUT', output if is_doctest: submitted = data.strip() found = output if found is not None: ind = found.find(output_prompt) if ind<0: raise RuntimeError('output prompt="%s" does not match out line=%s'%(output_prompt, found)) found = found[len(output_prompt):].strip() if found!=submitted: raise RuntimeError('doctest failure for input_lines="%s" with found_output="%s" and submitted output="%s"'%(input_lines, found, submitted)) #print 'doctest PASSED for input_lines="%s" with found_output="%s" and submitted output="%s"'%(input_lines, found, submitted) if image_file is not None: self.insure_pyplot() command = 'plt.gcf().savefig("%s")'%image_file #print 'SAVEFIG', command self.process_input('bookmark ipy_thisdir') self.process_input('cd -b ipy_basedir') self.process_input(command) self.process_input('cd -b ipy_thisdir') self.cout.seek(0) self.cout.truncate(0) #print 'returning', ret, figure return ret, image_directive def insure_pyplot(self): if self._pyplot_imported: return self.process_input('import matplotlib.pyplot as plt') shell = EmbeddedSphinxShell() def ipython_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine, ): debug = ipython_directive.DEBUG shell.is_suppress = options.has_key('suppress') shell.is_doctest = options.has_key('doctest') shell.is_verbatim = options.has_key('verbatim') #print 'ipy', shell.is_suppress, options parts = '\n'.join(content).split('\n\n') lines = ['.. sourcecode:: ipython', ''] figures = [] for part in parts: block = block_parser(part) if len(block): rows, figure = shell.process_block(block) for row in rows: lines.extend([' %s'%line for line in row.split('\n')]) if figure is not None: figures.append(figure) for figure in figures: lines.append('') lines.extend(figure.split('\n')) lines.append('') #print lines if len(lines)>2: if debug: print '\n'.join(lines) else: #print 'INSERTING %d lines'%len(lines) state_machine.insert_input( lines, state_machine.input_lines.source(0)) return [] ipython_directive.DEBUG = False def setup(app): setup.app = app options = { 'suppress': directives.flag, 'doctest': directives.flag, 'verbatim': directives.flag, } app.add_directive('ipython', ipython_directive, True, (0, 2, 0), **options) def test(): examples = [ r""" In [9]: pwd Out[9]: '/home/jdhunter/py4science/book' In [10]: cd bookdata/ /home/jdhunter/py4science/book/bookdata In [2]: from pylab import * In [2]: ion() In [3]: im = imread('stinkbug.png') @savefig mystinkbug.png width=4in In [4]: imshow(im) Out[4]: <matplotlib.image.AxesImage object at 0x39ea850> """, r""" In [1]: x = 'hello world' # string methods can be # used to alter the string @doctest In [2]: x.upper() Out[2]: 'HELLO WORLD' @verbatim In [3]: x.st<TAB> x.startswith x.strip """, r""" In [130]: url = 'http://ichart.finance.yahoo.com/table.csv?s=CROX\ .....: &d=9&e=22&f=2009&g=d&a=1&br=8&c=2006&ignore=.csv' In [131]: print url.split('&') --------> print(url.split('&')) ['http://ichart.finance.yahoo.com/table.csv?s=CROX', 'd=9', 'e=22', 'f=2009', 'g=d', 'a=1', 'b=8', 'c=2006', 'ignore=.csv'] In [60]: import urllib """, r"""\ In [133]: import numpy.random @suppress In [134]: numpy.random.seed(2358) @doctest In [135]: np.random.rand(10,2) Out[135]: array([[ 0.64524308, 0.59943846], [ 0.47102322, 0.8715456 ], [ 0.29370834, 0.74776844], [ 0.99539577, 0.1313423 ], [ 0.16250302, 0.21103583], [ 0.81626524, 0.1312433 ], [ 0.67338089, 0.72302393], [ 0.7566368 , 0.07033696], [ 0.22591016, 0.77731835], [ 0.0072729 , 0.34273127]]) """, r""" In [106]: print x --------> print(x) jdh In [109]: for i in range(10): .....: print i .....: .....: 0 1 2 3 4 5 6 7 8 9 """, r""" In [144]: from pylab import * In [145]: ion() # use a semicolon to suppress the output @savefig test_hist.png width=4in In [151]: hist(np.random.randn(10000), 100); @savefig test_plot.png width=4in In [151]: plot(np.random.randn(10000), 'o'); """, r""" # use a semicolon to suppress the output In [151]: plt.clf() @savefig plot_simple.png width=4in In [151]: plot([1,2,3]) @savefig hist_simple.png width=4in In [151]: hist(np.random.randn(10000), 100); """, r""" # update the current fig In [151]: ylabel('number') In [152]: title('normal distribution') @savefig hist_with_text.png In [153]: grid(True) """, r""" In [239]: 1/2 @verbatim Out[239]: 0 In [240]: 1.0/2.0 Out[240]: 0.5 """, r""" @verbatim In [6]: pwd Out[6]: '/home/jdhunter/mypy' """, r""" @verbatim In [151]: myfile.upper? Type: builtin_function_or_method Base Class: <type 'builtin_function_or_method'> String Form: <built-in method upper of str object at 0x980e2f0> Namespace: Interactive Docstring: S.upper() -> string Return a copy of the string S converted to uppercase. """ ] ipython_directive.DEBUG = True #options = dict(suppress=True) options = dict() for example in examples: content = example.split('\n') ipython_directive('debug', arguments=None, options=options, content=content, lineno=0, content_offset=None, block_text=None, state=None, state_machine=None, ) if __name__=='__main__': test()