SourceForge logo
SourceForge logo
Menu

matplotlib-checkins

Revision: 8830
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8830&view=rev
Author: jdh2358
Date: 2010年12月13日 15:27:48 +0000 (2010年12月13日)
Log Message:
-----------
added ipython directive
Added Paths:
-----------
 branches/v1_0_maint/lib/matplotlib/sphinxext/ipython_directive.py
Added: branches/v1_0_maint/lib/matplotlib/sphinxext/ipython_directive.py
===================================================================
--- branches/v1_0_maint/lib/matplotlib/sphinxext/ipython_directive.py	 (rev 0)
+++ branches/v1_0_maint/lib/matplotlib/sphinxext/ipython_directive.py	2010年12月13日 15:27:48 UTC (rev 8830)
@@ -0,0 +1,567 @@
+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()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /