summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorPauli Virtanen <pav@iki.fi>2010-08-08 18:52:01 +0000
committerPauli Virtanen <pav@iki.fi>2010-08-08 18:52:01 +0000
commit9c3297c78a0f8e680869ad3856fd6d2d9b7625f0 (patch)
tree0b31748abc78d67963f4f6a7fd87fa721bb6af30 /doc
parent0c058e7db288f05e3e4af56ed345f350046d01f4 (diff)
downloadnumpy-9c3297c78a0f8e680869ad3856fd6d2d9b7625f0.tar.gz
sphinxext: plot_directive: insert figures at points where plt.show() is called in the text
Diffstat (limited to 'doc')
-rw-r--r--doc/sphinxext/plot_directive.py275
1 files changed, 163 insertions, 112 deletions
diff --git a/doc/sphinxext/plot_directive.py b/doc/sphinxext/plot_directive.py
index fc836d811..419a9548d 100644
--- a/doc/sphinxext/plot_directive.py
+++ b/doc/sphinxext/plot_directive.py
@@ -164,39 +164,37 @@ TEMPLATE = """
{{ only_html }}
- {% if source_code %}
- (`Source code <{{ source_link }}>`__)
-
- .. admonition:: Output
- :class: plot-output
-
+ {% if source_link or (html_show_formats and not multi_image) %}
+ (
+ {%- if source_link -%}
+ `Source code <{{ source_link }}>`__
+ {%- endif -%}
+ {%- if html_show_formats and not multi_image -%}
+ {%- for img in images -%}
+ {%- for fmt in img.formats -%}
+ {%- if source_link or not loop.first -%}, {% endif -%}
+ `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
+ {%- endfor -%}
+ {%- endfor -%}
+ {%- endif -%}
+ )
{% endif %}
- {% for img in images %}
- .. figure:: {{ build_dir }}/{{ img.basename }}.png
- {%- for option in options %}
- {{ option }}
- {% endfor %}
-
- {%- if not source_code -%}
- (`Source code <{{source_link}}>`__
- {%- if html_show_formats -%}
- {%- for fmt in img.formats -%}
- , `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
- {%- endfor -%}
- {%- endif -%}
- )
- {%- else -%}
- {%- if html_show_formats -%}
- (
- {%- for fmt in img.formats -%}
- {%- if not loop.first -%}, {% endif -%}
- `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
- {%- endfor -%}
- )
- {%- endif -%}
- {%- endif -%}
- {% endfor %}
+ {% for img in images %}
+ .. figure:: {{ build_dir }}/{{ img.basename }}.png
+ {%- for option in options %}
+ {{ option }}
+ {% endfor %}
+
+ {% if html_show_formats and multi_image -%}
+ (
+ {%- for fmt in img.formats -%}
+ {%- if not loop.first -%}, {% endif -%}
+ `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
+ {%- endfor -%}
+ )
+ {%- endif -%}
+ {% endfor %}
{{ only_latex }}
@@ -290,60 +288,75 @@ def run(arguments, content, options, state_machine, state, lineno):
# make figures
try:
- images = makefig(code, source_file_name, build_dir, output_base,
- config)
+ results = makefig(code, source_file_name, build_dir, output_base,
+ config)
+ errors = []
except PlotError, err:
reporter = state.memo.reporter
sm = reporter.system_message(
- 3, "Exception occurred in plotting %s: %s" % (output_base, err),
+ 2, "Exception occurred in plotting %s: %s" % (output_base, err),
line=lineno)
- return [sm]
+ results = [(code, [])]
+ errors = [sm]
# generate output restructuredtext
- if options['include-source']:
- if is_doctest:
- lines = ['']
- lines += [row.rstrip() for row in code.split('\n')]
+ total_lines = []
+ for j, (code_piece, images) in enumerate(results):
+ if options['include-source']:
+ if is_doctest:
+ lines = ['']
+ lines += [row.rstrip() for row in code_piece.split('\n')]
+ else:
+ lines = ['.. code-block:: python', '']
+ lines += [' %s' % row.rstrip()
+ for row in code_piece.split('\n')]
+ source_code = "\n".join(lines)
else:
- lines = ['.. code-block:: python', '']
- lines += [' %s' % row.rstrip() for row in code.split('\n')]
- source_code = "\n".join(lines)
- else:
- source_code = ""
+ source_code = ""
- opts = [':%s: %s' % (key, val) for key, val in options.items()
- if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
+ opts = [':%s: %s' % (key, val) for key, val in options.items()
+ if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
- if sphinx.__version__ >= "0.6":
- only_html = ".. only:: html"
- only_latex = ".. only:: latex"
- else:
- only_html = ".. htmlonly::"
- only_latex = ".. latexonly::"
-
- result = format_template(
- TEMPLATE,
- dest_dir=dest_dir_link,
- build_dir=build_dir_link,
- source_link=source_link,
- only_html=only_html,
- only_latex=only_latex,
- options=opts,
- images=images,
- source_code=source_code,
- html_show_formats=config.plot_html_show_formats)
-
- lines = result.split("\n")
- if len(lines):
- state_machine.insert_input(lines, source=source_file_name)
+ if sphinx.__version__ >= "0.6":
+ only_html = ".. only:: html"
+ only_latex = ".. only:: latex"
+ else:
+ only_html = ".. htmlonly::"
+ only_latex = ".. latexonly::"
+
+ if j == 0:
+ src_link = source_link
+ else:
+ src_link = None
+
+ result = format_template(
+ TEMPLATE,
+ dest_dir=dest_dir_link,
+ build_dir=build_dir_link,
+ source_link=src_link,
+ multi_image=len(images) > 1,
+ only_html=only_html,
+ only_latex=only_latex,
+ options=opts,
+ images=images,
+ source_code=source_code,
+ html_show_formats=config.plot_html_show_formats)
+
+ total_lines.extend(result.split("\n"))
+ total_lines.extend("\n")
+
+ if total_lines:
+ state_machine.insert_input(total_lines, source=source_file_name)
# copy image files to builder's output directory
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
- for img in images:
- for fn in img.filenames():
- shutil.copyfile(fn, os.path.join(dest_dir, os.path.basename(fn)))
+ for code_piece, images in results:
+ for img in images:
+ for fn in img.filenames():
+ shutil.copyfile(fn, os.path.join(dest_dir,
+ os.path.basename(fn)))
# copy script (if necessary)
if source_file_name == rst_file:
@@ -352,7 +365,7 @@ def run(arguments, content, options, state_machine, state, lineno):
f.write(unescape_doctest(code))
f.close()
- return []
+ return errors
#------------------------------------------------------------------------------
@@ -398,10 +411,32 @@ def unescape_doctest(text):
code += "\n"
return code
+def split_code_at_show(text):
+ """
+ Split code at plt.show()
+
+ """
+
+ parts = []
+ is_doctest = contains_doctest(text)
+
+ part = []
+ for line in text.split("\n"):
+ if (not is_doctest and line.strip() == 'plt.show()') or \
+ (is_doctest and line.strip() == '>>> plt.show()'):
+ part.append(line)
+ parts.append("\n".join(part))
+ part = []
+ else:
+ part.append(line)
+ if "\n".join(part).strip():
+ parts.append("\n".join(part))
+ return parts
+
class PlotError(RuntimeError):
pass
-def run_code(code, code_path):
+def run_code(code, code_path, ns=None):
# Change the working directory to the directory of the example, so
# it can get at its data files, if any.
pwd = os.getcwd()
@@ -422,8 +457,10 @@ def run_code(code, code_path):
try:
try:
code = unescape_doctest(code)
- ns = {}
- exec setup.config.plot_pre_code in ns
+ if ns is None:
+ ns = {}
+ if not ns:
+ exec setup.config.plot_pre_code in ns
exec code in ns
except (Exception, SystemExit), err:
raise PlotError(traceback.format_exc())
@@ -468,6 +505,8 @@ def makefig(code, code_path, output_dir, output_base, config):
# -- Try to determine if all images already exist
+ code_pieces = split_code_at_show(code)
+
# Look for single-figure output files first
all_exists = True
img = ImageFile(output_base, output_dir)
@@ -478,54 +517,66 @@ def makefig(code, code_path, output_dir, output_base, config):
img.formats.append(format)
if all_exists:
- return [img]
+ return [(code, [img])]
# Then look for multi-figure output files
- images = []
+ results = []
all_exists = True
- for i in xrange(1000):
- img = ImageFile('%s_%02d' % (output_base, i), output_dir)
- for format, dpi in formats:
- if out_of_date(code_path, img.filename(format)):
- all_exists = False
+ for i, code_piece in enumerate(code_pieces):
+ images = []
+ for j in xrange(1000):
+ img = ImageFile('%s_%02d_%02d' % (output_base, i, j), output_dir)
+ for format, dpi in formats:
+ if out_of_date(code_path, img.filename(format)):
+ all_exists = False
+ break
+ img.formats.append(format)
+
+ # assume that if we have one, we have them all
+ if not all_exists:
+ all_exists = (j > 0)
break
- img.formats.append(format)
-
- # assume that if we have one, we have them all
+ images.append(img)
if not all_exists:
- all_exists = (i > 0)
break
- images.append(img)
+ results.append((code_piece, images))
if all_exists:
- return images
+ return results
# -- We didn't find the files, so build them
- # Clear between runs
- plt.close('all')
-
- # Run code
- run_code(code, code_path)
-
- # Collect images
- images = []
-
- fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
- for i, figman in enumerate(fig_managers):
- if len(fig_managers) == 1:
- img = ImageFile(output_base, output_dir)
- else:
- img = ImageFile("%s_%02d" % (output_base, i), output_dir)
- images.append(img)
- for format, dpi in formats:
- try:
- figman.canvas.figure.savefig(img.filename(format), dpi=dpi)
- except exceptions.BaseException, err:
- raise PlotError(traceback.format_exc())
- img.formats.append(format)
-
- return images
+ results = []
+ ns = {}
+
+ for i, code_piece in enumerate(code_pieces):
+ # Clear between runs
+ plt.close('all')
+
+ # Run code
+ run_code(code_piece, code_path, ns)
+
+ # Collect images
+ images = []
+ fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
+ for j, figman in enumerate(fig_managers):
+ if len(fig_managers) == 1 and len(code_pieces) == 1:
+ img = ImageFile(output_base, output_dir)
+ else:
+ img = ImageFile("%s_%02d_%02d" % (output_base, i, j),
+ output_dir)
+ images.append(img)
+ for format, dpi in formats:
+ try:
+ figman.canvas.figure.savefig(img.filename(format), dpi=dpi)
+ except exceptions.BaseException, err:
+ raise PlotError(traceback.format_exc())
+ img.formats.append(format)
+
+ # Results
+ results.append((code_piece, images))
+
+ return results
#------------------------------------------------------------------------------