diff --git a/doc/conf.py b/doc/conf.py index 64023fa..e95951a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -39,7 +39,8 @@ # extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage','sphinx.ext.viewcode','sphinx.ext.inheritance_diagram'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx','plot_directive','only_directives', + 'sphinx.ext.intersphinx',#'plot_directive', + 'only_directives', 'sphinx.ext.inheritance_diagram', 'nbsphinx','edit_on_github'] nbsphinx_allow_errors = False diff --git a/doc/photos/Claw-Dev2016.jpg b/doc/photos/Claw-Dev2016.jpg new file mode 100644 index 0000000..1431a7e Binary files /dev/null and b/doc/photos/Claw-Dev2016.jpg differ diff --git a/doc/pyclaw/examples.rst b/doc/pyclaw/examples.rst index 80020a8..c532d4e 100644 --- a/doc/pyclaw/examples.rst +++ b/doc/pyclaw/examples.rst @@ -56,26 +56,10 @@ executing the Python script. For convenience, the scripts are set up to pass an command-line options as arguments to the setup function. -List of built-in examples +Built-in examples ========================= You can see results from many of the examples in the :ref:`galleries`. -.. toctree:: - :glob: - :maxdepth: 1 - - gallery/*adv* - gallery/*acoust* - gallery/*burg* - gallery/*shallow* - gallery/*blast* - gallery/*shock* - gallery/*psystem* - gallery/*Rossby* - gallery/*dam* - gallery/kpp - gallery/stegoton - Adding new examples ======================================== diff --git a/doc/pyclaw/ext/mathjax.py b/doc/pyclaw/ext/mathjax.py deleted file mode 100644 index 59beff3..0000000 --- a/doc/pyclaw/ext/mathjax.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -""" - sphinx.ext.mathjax - ~~~~~~~~~~~~~~~~~~ - - Allow `MathJax `_ to be used to display math - in Sphinx's HTML writer - requires the MathJax JavaScript library - on your webserver/computer. - - Kevin Dunn, kgdunn@gmail.com, 3-clause BSD license. - - - For background, installation details and support: - - https://bitbucket.org/kevindunn/sphinx-extension-mathjax - -""" -from docutils import nodes -from sphinx.application import ExtensionError -from sphinx.ext.mathbase import setup_math as mathbase_setup - -def html_visit_math(self, node): - self.body.append(self.starttag(node, 'span', '', CLASS='math')) - self.body.append(self.builder.config.mathjax_inline[0] + \ - self.encode(node['latex']) +\ - self.builder.config.mathjax_inline[1] + '') - raise nodes.SkipNode - -def html_visit_displaymath(self, node): - self.body.append(self.starttag(node, 'div', CLASS='math')) - if node['nowrap']: - self.body.append(self.builder.config.mathjax_display[0] + \ - node['latex'] +\ - self.builder.config.mathjax_display[1]) - self.body.append('') - raise nodes.SkipNode - - parts = [prt for prt in node['latex'].split('\n\n') if prt.strip() != ''] - for i, part in enumerate(parts): - part = self.encode(part) - if i == 0: - # necessary to e.g. set the id property correctly - if node['number']: - self.body.append('(%s)' % - node['number']) - if '&' in part or '\\\\' in part: - self.body.append(self.builder.config.mathjax_display[0] + \ - '\\begin{split}' + part + '\\end{split}' + \ - self.builder.config.mathjax_display[1]) - else: - self.body.append(self.builder.config.mathjax_display[0] + part + \ - self.builder.config.mathjax_display[1]) - self.body.append('\n') - raise nodes.SkipNode - -def builder_inited(app): - if not app.config.mathjax_path: - raise ExtensionError('mathjax_path config value must be set for the ' - 'mathjax extension to work') - app.add_javascript(app.config.mathjax_path) - -def setup(app): - mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None)) - app.add_config_value('mathjax_path', '', False) - app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html') - app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html') - app.connect('builder-inited', builder_inited) - diff --git a/doc/pyclaw/ext/only_directives.py b/doc/pyclaw/ext/only_directives.py deleted file mode 100644 index b93eb7f..0000000 --- a/doc/pyclaw/ext/only_directives.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# A pair of directives for inserting content that will only appear in -# either html or latex. -# - -from docutils.nodes import Body, Element -from docutils.writers.html4css1 import HTMLTranslator -from sphinx.writers.latex import LaTeXTranslator -#from sphinx.latexwriter import LaTeXTranslator -from docutils.parsers.rst import directives - -class html_only(Body, Element): - pass - -class latex_only(Body, Element): - pass - -def run(content, node_class, state, content_offset): - text = '\n'.join(content) - node = node_class(text) - state.nested_parse(content, content_offset, node) - return [node] - -try: - from docutils.parsers.rst import Directive -except ImportError: - from docutils.parsers.rst.directives import _directives - - def html_only_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - return run(content, html_only, state, content_offset) - - def latex_only_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - return run(content, latex_only, state, content_offset) - - for func in (html_only_directive, latex_only_directive): - func.content = 1 - func.options = {} - func.arguments = None - - _directives['htmlonly'] = html_only_directive - _directives['latexonly'] = latex_only_directive -else: - class OnlyDirective(Directive): - has_content = True - required_arguments = 0 - optional_arguments = 0 - final_argument_whitespace = True - option_spec = {} - - def run(self): - self.assert_has_content() - return run(self.content, self.node_class, - self.state, self.content_offset) - - class HtmlOnlyDirective(OnlyDirective): - node_class = html_only - - class LatexOnlyDirective(OnlyDirective): - node_class = latex_only - - directives.register_directive('htmlonly', HtmlOnlyDirective) - directives.register_directive('latexonly', LatexOnlyDirective) - -def setup(app): - app.add_node(html_only) - app.add_node(latex_only) - - # Add visit/depart methods to HTML-Translator: - def visit_perform(self, node): - pass - def depart_perform(self, node): - pass - def visit_ignore(self, node): - node.children = [] - def depart_ignore(self, node): - node.children = [] - - HTMLTranslator.visit_html_only = visit_perform - HTMLTranslator.depart_html_only = depart_perform - HTMLTranslator.visit_latex_only = visit_ignore - HTMLTranslator.depart_latex_only = depart_ignore - - LaTeXTranslator.visit_html_only = visit_ignore - LaTeXTranslator.depart_html_only = depart_ignore - LaTeXTranslator.visit_latex_only = visit_perform - LaTeXTranslator.depart_latex_only = depart_perform diff --git a/doc/pyclaw/ext/plot_directive.py b/doc/pyclaw/ext/plot_directive.py deleted file mode 100644 index af32eef..0000000 --- a/doc/pyclaw/ext/plot_directive.py +++ /dev/null @@ -1,473 +0,0 @@ -""" -A special directive for generating a matplotlib plot. - -.. warning:: - - This is a hacked version of plot_directive.py from Matplotlib. - It's very much subject to change! - -Usage ------ - -Can be used like this:: - - .. plot:: examples/example.py - - .. plot:: - - import matplotlib.pyplot as plt - plt.plot([1,2,3], [4,5,6]) - - .. plot:: - - A plotting example: - - .. doctest:: - - >>> import matplotlib.pyplot as plt - >>> plt.plot([1,2,3], [4,5,6]) - -The content is interpreted as doctest formatted if it has a line starting -with ``>>>``. - -The ``plot`` directive supports the options - - format : {'python', 'doctest'} - Specify the format of the input - include-source : bool - Whether to display the source code. Default can be changed in conf.py - -and the ``image`` directive options ``alt``, ``height``, ``width``, -``scale``, ``align``, ``class``. - -Configuration options ---------------------- - -The plot directive has the following configuration options: - - plot_output_dir - Directory (relative to config file) where to store plot output. - Should be inside the static directory. (Default: 'static') - - plot_pre_code - Code that should be executed before each plot. - - plot_rcparams - Dictionary of Matplotlib rc-parameter overrides. - Has 'sane' defaults. - - plot_include_source - Default value for the include-source option - - plot_formats - The set of files to generate. Default: ['png', 'pdf', 'hires.png'], - ie. everything. - -TODO ----- - -* Don't put temp files to _static directory, but do function in the way - the pngmath directive works, and plot figures only during output writing. - -* Refactor Latex output; now it's plain images, but it would be nice - to make them appear side-by-side, or in floats. - -""" - -import sys, os, glob, shutil, imp, warnings, cStringIO, re, textwrap - -def setup(app): - setup.app = app - setup.config = app.config - setup.confdir = app.confdir - - static_path = '_static' - if hasattr(app.config, 'html_static_path') and app.config.html_static_path: - static_path = app.config.html_static_path[0] - - app.add_config_value('plot_output_dir', static_path, True) - app.add_config_value('plot_pre_code', '', True) - app.add_config_value('plot_rcparams', sane_rcparameters, True) - app.add_config_value('plot_include_source', False, True) - app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True) - - app.add_directive('plot', plot_directive, True, (0, 1, False), - **plot_directive_options) - -sane_rcparameters = { - 'font.size': 9, - 'axes.titlesize': 9, - 'axes.labelsize': 9, - 'xtick.labelsize': 9, - 'ytick.labelsize': 9, - 'legend.fontsize': 9, - 'figure.figsize': (4, 3), -} - -#------------------------------------------------------------------------------ -# Run code and capture figures -#------------------------------------------------------------------------------ - -import matplotlib -import matplotlib.cbook as cbook -matplotlib.use('Agg') -import matplotlib.pyplot as plt -import matplotlib.image as image -from matplotlib import _pylab_helpers - -def contains_doctest(text): - r = re.compile(r'^\s*>>>', re.M) - m = r.match(text) - return bool(m) - -def unescape_doctest(text): - """ - Extract code from a piece of text, which contains either Python code - or doctests. - - """ - if not contains_doctest(text): - return text - - code = "" - for line in text.split("\n"): - m = re.match(r'^\s*(>>>|...) (.*)$', line) - if m: - code += m.group(2) + "\n" - elif line.strip(): - code += "# " + line.strip() + "\n" - else: - code += "\n" - return code - -def run_code(code, code_path): - # Change the working directory to the directory of the example, so - # it can get at its data files, if any. - pwd = os.getcwd() - old_sys_path = list(sys.path) - if code_path is not None: - dirname = os.path.abspath(os.path.dirname(code_path)) - os.chdir(dirname) - sys.path.insert(0, dirname) - - # Redirect stdout - stdout = sys.stdout - sys.stdout = cStringIO.StringIO() - - try: - code = unescape_doctest(code) - ns = {} - exec setup.config.plot_pre_code in ns - exec code in ns - finally: - os.chdir(pwd) - sys.path[:] = old_sys_path - sys.stdout = stdout - return ns - - -#------------------------------------------------------------------------------ -# Generating figures -#------------------------------------------------------------------------------ - -def out_of_date(original, derived): - """ - Returns True if derivative is out-of-date wrt original, - both of which are full file paths. - """ - return (not os.path.exists(derived) - or os.stat(derived).st_mtime < os.stat(original).st_mtime) - - -def makefig(code, code_path, output_dir, output_base, config): - """ - run a pyplot script and save the low and high res PNGs and a PDF in _static - - """ - - included_formats = config.plot_formats - if type(included_formats) is str: - included_formats = eval(included_formats) - - formats = [x for x in [('png', 80), ('hires.png', 200), ('pdf', 50)] - if x[0] in config.plot_formats] - - all_exists = True - - # Look for single-figure output files first - for format, dpi in formats: - output_path = os.path.join(output_dir, '%s.%s' % (output_base, format)) - if out_of_date(code_path, output_path): - all_exists = False - break - - if all_exists: - return [output_base] - - # Then look for multi-figure output files - image_names = [] - for i in xrange(1000): - image_names.append('%s_%02d' % (output_base, i)) - for format, dpi in formats: - output_path = os.path.join(output_dir, - '%s.%s' % (image_names[-1], format)) - if out_of_date(code_path, output_path): - all_exists = False - break - if not all_exists: - # assume that if we have one, we have them all - all_exists = (i > 0) - break - - if all_exists: - return image_names - - # We didn't find the files, so build them - print "-- Plotting figures %s" % output_base - - # Clear between runs - plt.close('all') - - # Reset figure parameters - matplotlib.rcdefaults() - matplotlib.rcParams.update(config.plot_rcparams) - - # Run code - run_code(code, code_path) - - # Collect images - image_names = [] - - fig_managers = _pylab_helpers.Gcf.get_all_fig_managers() - for i, figman in enumerate(fig_managers): - if len(fig_managers) == 1: - name = output_base - else: - name = "%s_%02d" % (output_base, i) - image_names.append(name) - for format, dpi in formats: - path = os.path.join(output_dir, '%s.%s' % (name, format)) - figman.canvas.figure.savefig(path, dpi=dpi) - - return image_names - -#------------------------------------------------------------------------------ -# Generating output -#------------------------------------------------------------------------------ - -from docutils import nodes, utils -import jinja2 - -TEMPLATE = """ -{{source_code}} - -.. htmlonly:: - - {% if source_code %} - (`Source code <{{source_link}}>`__) - {% endif %} - - .. admonition:: Output - :class: plot-output - - {% for name in image_names %} - .. figure:: {{link_dir}}/{{name}}.png - {%- for option in options %} - {{option}} - {% endfor %} - - ( - {%- if not source_code %}`Source code <{{source_link}}>`__, {% endif -%} - `PNG <{{link_dir}}/{{name}}.hires.png>`__, - `PDF <{{link_dir}}/{{name}}.pdf>`__) - {% endfor %} - -.. latexonly:: - - {% for name in image_names %} - .. image:: {{link_dir}}/{{name}}.pdf - {% endfor %} - -""" - -def run(arguments, content, options, state_machine, state, lineno): - if arguments and content: - raise RuntimeError("plot:: directive can't have both args and content") - - document = state_machine.document - config = document.settings.env.config - - options.setdefault('include-source', config.plot_include_source) - if options['include-source'] is None: - options['include-source'] = config.plot_include_source - - # determine input - rst_file = document.attributes['source'] - rst_dir = os.path.dirname(rst_file) - - if arguments: - file_name = os.path.join(rst_dir, directives.uri(arguments[0])) - code = open(file_name, 'r').read() - output_base = os.path.basename(file_name) - else: - file_name = rst_file - code = textwrap.dedent("\n".join(map(str, content))) - counter = document.attributes.get('_plot_counter', 0) + 1 - document.attributes['_plot_counter'] = counter - output_base = '%d-%s' % (counter, os.path.basename(file_name)) - - rel_name = relpath(file_name, setup.confdir) - - base, ext = os.path.splitext(output_base) - if ext in ('.py', '.rst', '.txt'): - output_base = base - - # is it in doctest format? - is_doctest = contains_doctest(code) - if options.has_key('format'): - if options['format'] == 'python': - is_doctest = False - else: - is_doctest = True - - # determine output - file_rel_dir = os.path.dirname(rel_name) - while file_rel_dir.startswith(os.path.sep): - file_rel_dir = file_rel_dir[1:] - - output_dir = os.path.join(setup.confdir, setup.config.plot_output_dir, - file_rel_dir) - - if not os.path.exists(output_dir): - cbook.mkdirs(output_dir) - - # copy script - target_name = os.path.join(output_dir, output_base) - f = open(target_name, 'w') - f.write(unescape_doctest(code)) - f.close() - - source_link = relpath(target_name, rst_dir) - - # determine relative reference - link_dir = relpath(output_dir, rst_dir) - - # make figures - try: - image_names = makefig(code, file_name, output_dir, output_base, config) - except RuntimeError, err: - reporter = state.memo.reporter - sm = reporter.system_message(3, "Exception occurred rendering plot", - line=lineno) - return [sm] - - # generate output - if options['include-source']: - if is_doctest: - lines = [''] - else: - lines = ['.. code-block:: python', ''] - lines += [' %s' % row.rstrip() for row in code.split('\n')] - source_code = "\n".join(lines) - else: - source_code = "" - - opts = [':%s: %s' % (key, val) for key, val in options.items() - if key in ('alt', 'height', 'width', 'scale', 'align', 'class')] - - #result = jinja.from_string(TEMPLATE).render( - result = jinja2.Template(TEMPLATE).render( - link_dir=link_dir.replace(os.path.sep, '/'), - source_link=source_link, - options=opts, - image_names=image_names, - source_code=source_code) - - lines = result.split("\n") - if len(lines): - state_machine.insert_input( - lines, state_machine.input_lines.source(0)) - - return [] - - -if hasattr(os.path, 'relpath'): - relpath = os.path.relpath -else: - def relpath(target, base=os.curdir): - """ - Return a relative path to the target from either the current - dir or an optional base dir. Base can be a directory - specified either as absolute or relative to current dir. - """ - - if not os.path.exists(target): - raise OSError, 'Target does not exist: '+target - - if not os.path.isdir(base): - raise OSError, 'Base is not a directory or does not exist: '+base - - base_list = (os.path.abspath(base)).split(os.sep) - target_list = (os.path.abspath(target)).split(os.sep) - - # On the windows platform the target may be on a completely - # different drive from the base. - if os.name in ['nt','dos','os2'] and base_list[0] <> target_list[0]: - raise OSError, 'Target is on a different drive to base. Target: '+target_list[0].upper()+', base: '+base_list[0].upper() - - # Starting from the filepath root, work out how much of the - # filepath is shared by base and target. - for i in range(min(len(base_list), len(target_list))): - if base_list[i] <> target_list[i]: break - else: - # If we broke out of the loop, i is pointing to the first - # differing path elements. If we didn't break out of the - # loop, i is pointing to identical path elements. - # Increment i so that in all cases it points to the first - # differing path elements. - i+=1 - - rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:] - return os.path.join(*rel_list) - -#------------------------------------------------------------------------------ -# plot:: directive registration etc. -#------------------------------------------------------------------------------ - -from docutils.parsers.rst import directives -try: - # docutils 0.4 - from docutils.parsers.rst.directives.images import align -except ImportError: - # docutils 0.5 - from docutils.parsers.rst.directives.images import Image - align = Image.align - -def plot_directive(name, arguments, options, content, lineno, - content_offset, block_text, state, state_machine): - return run(arguments, content, options, state_machine, state, lineno) - -plot_directive.__doc__ = __doc__ - -def _option_boolean(arg): - if not arg or not arg.strip(): - return None - elif arg.strip().lower() in ('no', '0', 'false'): - return False - elif arg.strip().lower() in ('yes', '1', 'true'): - return True - else: - raise ValueError('"%s" unknown boolean' % arg) - -def _option_format(arg): - return directives.choice(arg, ('python', 'lisp')) - -plot_directive_options = {'alt': directives.unchanged, - 'height': directives.length_or_unitless, - 'width': directives.length_or_percentage_or_unitless, - 'scale': directives.nonnegative_int, - 'align': align, - 'class': directives.class_option, - 'include-source': _option_boolean, - 'format': _option_format, - } diff --git a/doc/pyclaw/index.rst b/doc/pyclaw/index.rst index 74d1ffb..45da32b 100644 --- a/doc/pyclaw/index.rst +++ b/doc/pyclaw/index.rst @@ -46,7 +46,7 @@ PyClaw Documentation ../developers troubleshooting about - gallery/gallery_all + ../gallery/pyclaw/gallery/gallery_all .. _pyclaw_reference: diff --git a/gallery/conf.py b/gallery/conf.py index 6e7c118..f0d35d1 100644 --- a/gallery/conf.py +++ b/gallery/conf.py @@ -39,7 +39,8 @@ # extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage','sphinx.ext.viewcode','sphinx.ext.inheritance_diagram'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx','plot_directive','only_directives', + 'sphinx.ext.intersphinx',#'plot_directive', + 'only_directives', 'sphinx.ext.inheritance_diagram', 'nbsphinx','edit_on_github'] nbsphinx_allow_errors = False diff --git a/gallery/pyclaw/gallery/gallery.py b/gallery/pyclaw/gallery/gallery.py index b3f6057..f51f4bb 100644 --- a/gallery/pyclaw/gallery/gallery.py +++ b/gallery/pyclaw/gallery/gallery.py @@ -141,7 +141,7 @@ def create(self,fname,gallery_dir=None, copy_plots=True, write_file=True): rf.write(gsec.title+'\n') rf.write('-'*len(gsec.title)+'\n') rf.write('\n') - rf.write('.. automodule:: pyclaw.examples.'+gitem.appdir.split('/')[-1]+'.'+gitem.appname+'\n') + rf.write('.. automodule:: clawpack.pyclaw.examples.'+gitem.appdir.split('/')[-1]+'.'+gitem.appname+'\n') rf.write('\n') rf.write('Output:\n') diff --git a/gallery/pyclaw/gallery/make_plots.py b/gallery/pyclaw/gallery/make_plots.py index 8992080..93c84c2 100644 --- a/gallery/pyclaw/gallery/make_plots.py +++ b/gallery/pyclaw/gallery/make_plots.py @@ -20,7 +20,7 @@ def list_examples(examples_dir=None): if examples_dir is None: from clawpack import pyclaw - examples_dir = pyclaw.__path__[0]+'/examples' + examples_dir = list(pyclaw.__path__)[0]+'/examples' examples_dir = os.path.abspath(examples_dir) current_dir = os.getcwd() @@ -75,7 +75,7 @@ def run_examples(examples_dir=None): def make_plots(examples_dir=None): if examples_dir is None: from clawpack import pyclaw - examples_dir = pyclaw.__path__[0]+'/examples' + examples_dir = list(pyclaw.__path__)[0]+'/examples' examples_dir = os.path.abspath(examples_dir) current_dir = os.getcwd()