|
From: <jd...@us...> - 2008-05-24 20:49:35
|
Revision: 5253
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5253&view=rev
Author: jdh2358
Date: 2008-05-24 13:49:31 -0700 (Sat, 24 May 2008)
Log Message:
-----------
added new docs dir
Added Paths:
-----------
trunk/matplotlib/docs/
trunk/matplotlib/docs/_static/
trunk/matplotlib/docs/_templates/
trunk/matplotlib/docs/api/
trunk/matplotlib/docs/api/artist_api.rst
trunk/matplotlib/docs/api/index.rst
trunk/matplotlib/docs/conf.py
trunk/matplotlib/docs/devel/
trunk/matplotlib/docs/devel/add_new_projection.rst
trunk/matplotlib/docs/devel/coding_guide.rst
trunk/matplotlib/docs/devel/documenting_mpl.rst
trunk/matplotlib/docs/devel/index.rst
trunk/matplotlib/docs/index.rst
trunk/matplotlib/docs/make.py
trunk/matplotlib/docs/mpl_data
trunk/matplotlib/docs/mpl_examples
trunk/matplotlib/docs/sphinxext/
trunk/matplotlib/docs/sphinxext/ipython_console_highlighting.py
trunk/matplotlib/docs/sphinxext/mathml.py
trunk/matplotlib/docs/sphinxext/mathpng.py
trunk/matplotlib/docs/users/
trunk/matplotlib/docs/users/artists.rst
trunk/matplotlib/docs/users/customizing.rst
trunk/matplotlib/docs/users/event_handling.rst
trunk/matplotlib/docs/users/figures/
trunk/matplotlib/docs/users/figures/dollar_ticks.py
trunk/matplotlib/docs/users/figures/fig_axes_customize_simple.py
trunk/matplotlib/docs/users/figures/fig_axes_labels_simple.py
trunk/matplotlib/docs/users/figures/fig_x.py
trunk/matplotlib/docs/users/figures/make.py
trunk/matplotlib/docs/users/figures/pyplot_formatstr.py
trunk/matplotlib/docs/users/figures/pyplot_mathtext.py
trunk/matplotlib/docs/users/figures/pyplot_simple.py
trunk/matplotlib/docs/users/figures/pyplot_text.py
trunk/matplotlib/docs/users/figures/pyplot_three.py
trunk/matplotlib/docs/users/figures/pyplot_two_subplots.py
trunk/matplotlib/docs/users/index.rst
trunk/matplotlib/docs/users/navigation_toolbar.rst
trunk/matplotlib/docs/users/pyplot_tutorial.rst
Added: trunk/matplotlib/docs/api/artist_api.rst
===================================================================
--- trunk/matplotlib/docs/api/artist_api.rst (rev 0)
+++ trunk/matplotlib/docs/api/artist_api.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,31 @@
+******************
+matplotlib artists
+******************
+
+:mod:`matplotlib.artist`
+=============================
+
+.. automodule:: matplotlib.artist
+ :members:
+ :undoc-members:
+
+:mod:`matplotlib.lines`
+=============================
+
+.. automodule:: matplotlib.lines
+ :members:
+ :undoc-members:
+
+:mod:`matplotlib.patches`
+=============================
+
+.. automodule:: matplotlib.patches
+ :members:
+ :undoc-members:
+
+:mod:`matplotlib.text`
+=============================
+
+.. automodule:: matplotlib.text
+ :members:
+ :undoc-members:
Added: trunk/matplotlib/docs/api/index.rst
===================================================================
--- trunk/matplotlib/docs/api/index.rst (rev 0)
+++ trunk/matplotlib/docs/api/index.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,15 @@
+.. _api-index:
+
+####################
+ The Matplotlib API
+####################
+
+:Release: |version|
+:Date: |today|
+
+Introduction to developer's guide here **TODO**.
+
+.. toctree::
+
+ artist_api.rst
+
Added: trunk/matplotlib/docs/conf.py
===================================================================
--- trunk/matplotlib/docs/conf.py (rev 0)
+++ trunk/matplotlib/docs/conf.py 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+#
+# Matplotlib documentation build configuration file, created by
+# sphinx-quickstart on Fri May 2 12:33:25 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+sys.path.append(os.path.abspath('sphinxext'))
+
+# Import support for ipython console session syntax highlighting (lives
+# in the sphinxext directory defined above)
+import ipython_console_highlighting
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['mathpng', 'sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'Matplotlib'
+copyright = '2008, John Hunter, Darren Dale, Michael Droettboom'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.98'
+# The full version, including alpha/beta/rc tags.
+release = '0.98pre'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+unused_docs = []
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# The name of an image file (within the static path) to place at the top of
+# the sidebar.
+#html_logo = 'logo.png'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If nonempty, this is the file name suffix for generated HTML files. The
+# default is ``".html"``.
+#html_file_suffix = '.xhtml'
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.
+html_use_opensearch = 'False'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Matplotlibdoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+latex_font_size = '11pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+ ('index', 'Matplotlib.tex', 'Matplotlib', 'John Hunter, Darren Dale', 'Michael Droettboom', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+latex_logo = None
+
+# Additional stuff for the LaTeX preamble.
+latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+latex_appendices = []
+
+# If false, no module index is generated.
+latex_use_modindex = True
+
+latex_use_parts = True
Added: trunk/matplotlib/docs/devel/add_new_projection.rst
===================================================================
--- trunk/matplotlib/docs/devel/add_new_projection.rst (rev 0)
+++ trunk/matplotlib/docs/devel/add_new_projection.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,105 @@
+***********************************************
+Adding new scales and projections to matplotlib
+***********************************************
+
+.. ::author Michael Droettboom
+
+Matplotlib supports the addition of custom procedures that transform
+the data before it is displayed.
+
+There is an important distinction between two kinds of
+transformations. Separable transformations, working on a single
+dimension, are called "scales", and non-separable transformations,
+that handle data in two or more dimensions at a time, are called
+"projections".
+
+From the user's perspective, the scale of a plot can be set with
+:meth:`~matplotlib.axes.Axes.set_xscale` and
+:meth:`~matplotlib.axes.Axes.set_xscale`. Projections can be chosen
+using the ``projection`` keyword argument to the
+:func:`~matplotlib.pylab.plot` or :func:`~matplotlib.pylab.subplot`
+functions, e.g.::
+
+ plot(x, y, projection="custom")
+
+This document is intended for developers and advanced users who need
+to create new scales and projections for matplotlib. The necessary
+code for scales and projections can be included anywhere: directly
+within a plot script, in third-party code, or in the matplotlib source
+tree itself.
+
+
+Creating a new scale
+====================
+
+Adding a new scale consists of defining a subclass of
+:class:`matplotlib.scale.ScaleBase`, that includes the following
+elements:
+
+ - A transformation from data coordinates into display coordinates.
+
+ - An inverse of that transformation. This is used, for example, to
+ convert mouse positions from screen space back into data space.
+
+ - A function to limit the range of the axis to acceptable values
+ (``limit_range_for_scale()``). A log scale, for instance, would
+ prevent the range from including values less than or equal to
+ zero.
+
+ - Locators (major and minor) that determine where to place ticks in
+ the plot, and optionally, how to adjust the limits of the plot to
+ some "good" values. Unlike ``limit_range_for_scale()``, which is
+ always enforced, the range setting here is only used when
+ automatically setting the range of the plot.
+
+ - Formatters (major and minor) that specify how the tick labels
+ should be drawn.
+
+Once the class is defined, it must be registered with matplotlib so
+that the user can select it.
+
+A full-fledged and heavily annotated example is in
+:file:`examples/api/custom_scale_example.py`. There are also some classes
+in :mod:`matplotlib.scale` that may be used as starting points.
+
+
+Creating a new projection
+=========================
+
+Adding a new projection consists of defining a subclass of
+:class:`matplotlib.axes.Axes`, that includes the following elements:
+
+ - A transformation from data coordinates into display coordinates.
+
+ - An inverse of that transformation. This is used, for example, to
+ convert mouse positions from screen space back into data space.
+
+ - Transformations for the gridlines, ticks and ticklabels. Custom
+ projections will often need to place these elements in special
+ locations, and matplotlib has a facility to help with doing so.
+
+ - Setting up default values (overriding
+ :meth:`~matplotlib.axes.Axes.cla`), since the defaults for a
+ rectilinear axes may not be appropriate.
+
+ - Defining the shape of the axes, for example, an elliptical axes,
+ that will be used to draw the background of the plot and for
+ clipping any data elements.
+
+ - Defining custom locators and formatters for the projection. For
+ example, in a geographic projection, it may be more convenient to
+ display the grid in degrees, even if the data is in radians.
+
+ - Set up interactive panning and zooming. This is left as an
+ "advanced" feature left to the reader, but there is an example of
+ this for polar plots in :mod:`matplotlib.projections.polar`.
+
+ - Any additional methods for additional convenience or features.
+
+Once the class is defined, it must be registered with matplotlib
+so that the user can select it.
+
+A full-fledged and heavily annotated example is in
+:file:`examples/api/custom_projection_example.py`. The polar plot
+functionality in :mod:`matplotlib.projections.polar` may also be of
+interest.
Added: trunk/matplotlib/docs/devel/coding_guide.rst
===================================================================
--- trunk/matplotlib/docs/devel/coding_guide.rst (rev 0)
+++ trunk/matplotlib/docs/devel/coding_guide.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,317 @@
+***************
+Version Control
+***************
+
+svn checkouts
+=============
+
+Checking out everything in the trunk (matplotlib and toolkits)::
+
+ svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk \
+ matplotlib --username=youruser --password=yourpass
+
+Checking out the main source::
+
+ svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/\
+ matplotlib matplotlib --username=youruser --password=yourpass
+
+Branch checkouts, eg the maintenance branch::
+
+ svn co https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/\
+ v0_91_maint mplv0_91_maint
+
+Committing changes
+==================
+
+When committing changes to matplotlib, there are a few things to bear
+in mind.
+
+* if your changes are non-trivial, please make an entry in the
+ CHANGELOG
+* if you change the API, please document it in API_CHANGES, and
+ consider posting to mpl-devel
+* Are your changes python2.3 compatible? We are still trying to
+ support 2.3, so avoid 2.4 only features like decorators until we
+ remove 2.3 support
+* Can you pass examples/backend_driver.py? This is our poor man's
+ unit test.
+* If you have altered extension code, do you pass
+ unit/memleak_hawaii.py?
+* if you have added new files or directories, or reorganized
+ existing ones, are the new files included in the match patterns in
+ MANIFEST.in. This file determines what goes into the src
+ distribution of the mpl build.
+* Keep the maintenance branch and trunk in sync where it makes sense.
+ If there is a bug on both that needs fixing, use svnmerge.py to
+ keep them in sync. http://www.orcaware.com/svn/wiki/Svnmerge.py. The
+ basic procedure is:
+
+ * install svnmerge.py in your PATH::
+
+ wget http://svn.collab.net/repos/svn/trunk/contrib/client-side/\
+ svnmerge/svnmerge.py
+
+ * get a svn copy of the maintenance branch and the trunk (see above)
+ * Michael advises making the change on the branch and committing
+ it. Make sure you svn upped on the trunk and have no local
+ modifications, and then from the svn trunk do::
+
+ > svnmerge.py merge -rNNN1,NNN2
+
+ where the NNN* are the revision numbers. Ranges arealso acceptable.
+ svnmergy.py automatically creates a file containing the commit messages,
+ so you are ready to make the commit::
+
+ > svn commit -F svnmerge-commit-message.txt
+
+***********
+Style Guide
+***********
+
+Importing and name spaces
+=========================
+
+For numpy, use::
+
+ import numpy as np
+ a = np.array([1,2,3])
+
+For masked arrays, use::
+
+ from numpy import ma
+
+(The earlier recommendation, 'import matplotlib.numerix.npyma as ma',
+was needed temporarily during the development of the maskedarray
+implementation as a separate package. As of numpy 1.1, it replaces the
+old implementation. Note: "from numpy import ma" works with numpy < 1.1
+*and* with numpy >= 1.1. "import numpy.ma as ma" works *only* with
+numpy >= 1.1, so for now we must not use it.)
+
+For matplotlib main module, use::
+
+ import matplotlib as mpl
+ mpl.rcParams['xtick.major.pad'] = 6
+
+For matplotlib modules (or any other modules), use::
+
+ import matplotlib.cbook as cbook
+
+ if cbook.iterable(z):
+ pass
+
+We prefer this over the equivalent 'from matplotlib import cbook'
+because the latter is ambiguous whether cbook is a module or a
+function to the new developer. The former makes it explcit that
+you are importing a module or package.
+
+Naming, spacing, and formatting conventions
+===========================================
+
+In general, we want to hew as closely as possible to the standard
+coding guidelines for python written by Guido in
+http://www.python.org/dev/peps/pep-0008, though we do not do this
+throughout.
+
+* functions and class methods: lower or lower_underscore_separated
+
+* attributes and variables: lower or lowerUpper
+
+* classes: Upper or MixedCase
+
+Personally, I prefer the shortest names that are still readable.
+
+Also, use an editor that does not put tabs in files. Four spaces
+should be used for indentation everywhere and if there is a file with
+tabs or more or less spaces it is a bug -- please fix it.
+
+Please avoid spurious invisible spaces at the ends of lines.
+(Tell your editor to strip whitespace from line ends when saving
+a file.)
+
+Keep docstrings uniformly indented as in the example below, with
+nothing to the left of the triple quotes. The dedent() function
+is needed to remove excess indentation only if something will be
+interpolated into the docstring, again as in the example above.
+
+Limit line length to 80 characters. If a logical line needs to be
+longer, use parentheses to break it; do not use an escaped
+newline. It may be preferable to use a temporary variable
+to replace a single long line with two shorter and more
+readable lines.
+
+Please do not commit lines with trailing white space, as it causes
+noise in svn diffs. If you are an emacs user, the following in your
+.emacs will cause emacs to strip trailing white space on save for
+python, C and C++::
+
+ ; and similarly for c++-mode-hook and c-mode-hook
+ (add-hook 'python-mode-hook
+ (lambda ()
+ (add-hook 'write-file-functions 'delete-trailing-whitespace)))
+
+for older versions of emacs (emacs<22) you need to do::
+
+ (add-hook 'python-mode-hook
+ (lambda ()
+ (add-hook 'local-write-file-hooks 'delete-trailing-whitespace)))
+
+Keyword argument processing
+===========================
+
+Matplotlib makes extensive use of ``**kwargs`` for pass through
+customizations from one function to another. A typical example is in
+pylab.text, The definition of the pylab text function is a simple
+pass-through to axes.Axes.text::
+
+ # in pylab.py
+ def text(*args, **kwargs):
+ ret = gca().text(*args, **kwargs)
+ draw_if_interactive()
+ return ret
+
+axes.Axes.text in simplified form looks like this, ie it just passes
+them on to text.Text.__init__::
+
+ # in axes.py
+ def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
+ t = Text(x=x, y=y, text=s, **kwargs)
+
+and Text.__init__ (again with liberties for illustration) just passes
+them on to the artist.Artist.update method::
+
+ # in text.py
+ def __init__(self, x=0, y=0, text='', **kwargs):
+ Artist.__init__(self)
+ self.update(kwargs)
+
+'update' does the work looking for methods named like 'set_property'
+if 'property' is a keyword argument. Ie, noone looks at the keywords,
+they just get passed through the API to the artist constructor which
+looks for suitably named methods and calls them with the value.
+
+As a general rule, the use of ``**kwargs`` should be reserved for
+pass-through keyword arguments, as in the examaple above. If I intend
+for all the keyword args to be used in some function and not passed
+on, I just use the key/value keyword args in the function definition
+rather than the ``**kwargs`` idiom.
+
+In some cases I want to consume some keys and pass through the others,
+in which case I pop the ones I want to use locally and pass on the
+rest, eg I pop scalex and scaley in Axes.plot and assume the rest are
+Line2D keyword arguments. As an example of a pop, passthrough
+usage, see Axes.plot::
+
+ # in axes.py
+ def plot(self, *args, **kwargs):
+ scalex = kwargs.pop('scalex', True)
+ scaley = kwargs.pop('scaley', True)
+ if not self._hold: self.cla()
+ lines = []
+ for line in self._get_lines(*args, **kwargs):
+ self.add_line(line)
+ lines.append(line)
+
+The matplotlib.cbook function popd() is rendered
+obsolete by the pop() dictionary method introduced in Python 2.3,
+so it should not be used for new code.
+
+Note there is a use case when kwargs are meant to be used locally in
+the function (not passed on), but you still need the ``**kwargs`` idiom.
+That is when you want to use ``*args`` to allow variable numbers of
+non-keyword args. In this case, python will not allow you to use
+named keyword args after the ``*args`` usage, so you will be forced to use
+``**kwargs``. An example is matplotlib.contour.ContourLabeler.clabel::
+
+ # in contour.py
+ def clabel(self, *args, **kwargs):
+ fontsize = kwargs.get('fontsize', None)
+ inline = kwargs.get('inline', 1)
+ self.fmt = kwargs.get('fmt', '%1.3f')
+ colors = kwargs.get('colors', None)
+ if len(args) == 0:
+ levels = self.levels
+ indices = range(len(self.levels))
+ elif len(args) == 1:
+ ...etc...
+
+Documentation and Docstrings
+============================
+
+matplotlib uses artist instrospection of docstrings to support
+properties. All properties that you want to support through setp and
+getp should have a set_property and get_property method in the Artist
+class. Yes, this is not ideal given python properties or enthought
+traits, but it is a historical legacy for now. The setter methods use
+the docstring with the ACCEPTS token to indicate the type of argument
+the method accepts. Eg in matplotlib.lines.Line2D::
+
+ # in lines.py
+ def set_linestyle(self, linestyle):
+ """
+ Set the linestyle of the line
+
+ ACCEPTS: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' | ' ' | '' ]
+ """
+
+Since matplotlib uses a lot of pass through kwargs, eg in every
+function that creates a line (plot, semilogx, semilogy, etc...), it
+can be difficult for the new user to know which kwargs are supported.
+I have developed a docstring interpolation scheme to support
+documentation of every function that takes a ``**kwargs``. The
+requirements are:
+
+1. single point of configuration so changes to the properties don't
+ require multiple docstring edits
+
+2. as automated as possible so that as properties change the docs
+ are updated automagically.
+
+I have added a matplotlib.artist.kwdocd and kwdoc() to faciliate this.
+They combines python string interpolation in the docstring with the
+matplotlib artist introspection facility that underlies setp and getp.
+The kwdocd is a single dictionary that maps class name to a docstring
+of kwargs. Here is an example from matplotlib.lines::
+
+ # in lines.py
+ artist.kwdocd['Line2D'] = artist.kwdoc(Line2D)
+
+Then in any function accepting Line2D passthrough kwargs, eg
+matplotlib.axes.Axes.plot::
+
+ # in axes.py
+ def plot(self, *args, **kwargs):
+ """
+ Some stuff omitted
+
+ The kwargs are Line2D properties:
+ %(Line2D)s
+
+ kwargs scalex and scaley, if defined, are passed on
+ to autoscale_view to determine whether the x and y axes are
+ autoscaled; default True. See Axes.autoscale_view for more
+ information
+ """
+ pass
+ plot.__doc__ = cbook.dedent(plot.__doc__) % artist.kwdocd
+
+Note there is a problem for Artist __init__ methods, eg Patch.__init__
+which supports Patch kwargs, since the artist inspector cannot work
+until the class is fully defined and we can't modify the
+Patch.__init__.__doc__ docstring outside the class definition. I have
+made some manual hacks in this case which violates the "single entry
+point" requirement above; hopefully we'll find a more elegant solution
+before too long
+
+********
+Licenses
+********
+
+Matplotlib only uses BSD compatible code. If you bring in code from
+another project make sure it has a PSF, BSD, MIT or compatible
+license. If not, you may consider contacting the author and asking
+them to relicense it. GPL and LGPL code are not acceptible in the
+main code base, though we are considering an alternative way of
+distributing L/GPL code through an separate channel, possibly a
+toolkit. If you include code, make sure you include a copy of that
+code's license in the license directory if the code's license requires
+you to distribute the license with it.
\ No newline at end of file
Added: trunk/matplotlib/docs/devel/documenting_mpl.rst
===================================================================
--- trunk/matplotlib/docs/devel/documenting_mpl.rst (rev 0)
+++ trunk/matplotlib/docs/devel/documenting_mpl.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,76 @@
+**********************
+Documenting Matplotlib
+**********************
+
+The documentation for matplotlib is generated from ReStructured Text
+using the Sphinx_ documentation generation tool. Sphinx-0.4 or later
+is required. Currently this means we need to install from the svn
+repository by doing::
+
+ svn co http://svn.python.org/projects/doctools/trunk sphinx
+ cd sphinx
+ python setup.py install
+
+.. _Sphinx: http://sphinx.pocoo.org/
+
+The documentation sources are found in the doc/ directory in the trunk.
+To build the users guid in html format, cd into doc/users_guide and do::
+
+ python make.py html
+
+you can also pass a ``latex`` flag to make.py to build a pdf, or pass no
+arguments to build everything. The same procedure can be followed for
+the sources in doc/api_reference.
+
+The actual ReStructured Text files are kept in doc/users_guide/source
+and doc/api_reference/source. The main entry point is index.rst.
+Additional files can be added by including their base file name
+(dropping the .rst extension) in the table of contents. It is also
+possible to include other documents through the use of an include
+statement. For example, in the Developers Guide, index.rst lists
+coding_guide, which automatically inserts coding_guide.rst.
+
+Mathematical expressions can be rendered as png images in html, and in
+the usual way by latex. For example:
+
+``math:`sin(x_n^2)`` yields: :math:`sin(x_n^2)`, and::
+
+ .. math::
+
+ \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}}``
+
+yields:
+
+.. math::
+
+ \int_{-\infty}^{\infty}\frac{e^{i\phi}}{1+x^2\frac{e^{i\phi}}{1+x^2}}
+
+The output produced by Sphinx can be configured by editing the conf.py
+files located in the documentation source directories.
+
+The Sphinx website contains plenty of documentation_ concerning ReST
+markup and working with Sphinx in general.
+
+.. _documentation: http://sphinx.pocoo.org/contents.html
+
+Referring to mpl documents
+==========================
+
+In the documentation, you may want to include to a document in the
+matplotlib src, eg a license file, an image file from ``mpl-data``, or an
+example. When you include these files, include them using a symbolic
+link from the documentation parent directory. This way, if we
+relocate the mpl documentation directory, all of the internal pointers
+to files will not have to change, just the top level symlinks. For
+example, In the top level doc directory we have symlinks pointing to
+the mpl ``examples`` and ``mpl-data``::
+
+ home:~/mpl/doc2> ls -l mpl_*
+ mpl_data -> ../lib/matplotlib/mpl-data
+ mpl_examples -> ../examples
+
+
+In the ``users`` subdirectory, if I want to refer to a file in the mpl-data directory, I use the symlink direcotry. For example, from ``customizing.rst``::
+
+ .. literalinclude:: ../mpl_data/matplotlibrc
+
Added: trunk/matplotlib/docs/devel/index.rst
===================================================================
--- trunk/matplotlib/docs/devel/index.rst (rev 0)
+++ trunk/matplotlib/docs/devel/index.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,16 @@
+.. _developers_guide-index:
+
+###################################
+ The Matplotlib Developers's Guide
+###################################
+
+:Release: |version|
+:Date: |today|
+
+Introduction to developer's guide here **TODO**.
+
+.. toctree::
+
+ coding_guide.rst
+ documenting_mpl.rst
+ add_new_projection.rst
Added: trunk/matplotlib/docs/index.rst
===================================================================
--- trunk/matplotlib/docs/index.rst (rev 0)
+++ trunk/matplotlib/docs/index.rst 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,23 @@
+.. matplotlib documentation master file, created by sphinx-quickstart on Sat May 24 15:37:00 2008.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to matplotlib's documentation!
+======================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ users/index.rst
+ devel/index.rst
+ api/index.rst
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
Added: trunk/matplotlib/docs/make.py
===================================================================
--- trunk/matplotlib/docs/make.py (rev 0)
+++ trunk/matplotlib/docs/make.py 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+import fileinput
+import glob
+import os
+import shutil
+import sys
+
+def check_build():
+ build_dirs = ['build', 'build/doctrees', 'build/html', 'build/latex',
+ '_static', '_templates']
+ for d in build_dirs:
+ try:
+ os.mkdir(d)
+ except OSError:
+ pass
+
+def figs():
+ os.system('cd users/figures/ && python make.py')
+
+def html():
+ check_build()
+ os.system('sphinx-build -b html -d build/doctrees . build/html')
+
+def latex():
+ if sys.platform != 'win32':
+ # LaTeX format.
+ os.system('sphinx-build -b latex -d build/doctrees . build/latex')
+
+ # Produce pdf.
+ os.chdir('build/latex')
+
+ # Copying the makefile produced by sphinx...
+ os.system('pdflatex Matplotlib_Users_Guide.tex')
+ os.system('pdflatex Matplotlib_Users_Guide.tex')
+ os.system('makeindex -s python.ist Matplotlib_Users_Guide.idx')
+ os.system('makeindex -s python.ist modMatplotlib_Users_Guide.idx')
+ os.system('pdflatex Matplotlib_Users_Guide.tex')
+
+ os.chdir('../..')
+ else:
+ print 'latex build has not been tested on windows'
+
+def clean():
+ shutil.rmtree('build')
+
+def all():
+ figs()
+ html()
+ latex()
+
+
+funcd = {'figs':figs,
+ 'html':html,
+ 'latex':latex,
+ 'clean':clean,
+ 'all':all,
+ }
+
+
+if len(sys.argv)>1:
+ for arg in sys.argv[1:]:
+ func = funcd.get(arg)
+ if func is None:
+ raise SystemExit('Do not know how to handle %s; valid args are'%(
+ arg, funcd.keys()))
+ func()
+else:
+ all()
Property changes on: trunk/matplotlib/docs/make.py
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/matplotlib/docs/mpl_data
===================================================================
--- trunk/matplotlib/docs/mpl_data (rev 0)
+++ trunk/matplotlib/docs/mpl_data 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1 @@
+link ../lib/matplotlib/mpl-data/
\ No newline at end of file
Property changes on: trunk/matplotlib/docs/mpl_data
___________________________________________________________________
Name: svn:special
+ *
Added: trunk/matplotlib/docs/mpl_examples
===================================================================
--- trunk/matplotlib/docs/mpl_examples (rev 0)
+++ trunk/matplotlib/docs/mpl_examples 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1 @@
+link ../examples/
\ No newline at end of file
Property changes on: trunk/matplotlib/docs/mpl_examples
___________________________________________________________________
Name: svn:special
+ *
Added: trunk/matplotlib/docs/sphinxext/ipython_console_highlighting.py
===================================================================
--- trunk/matplotlib/docs/sphinxext/ipython_console_highlighting.py (rev 0)
+++ trunk/matplotlib/docs/sphinxext/ipython_console_highlighting.py 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,75 @@
+from pygments.lexer import Lexer, do_insertions
+from pygments.lexers.agile import PythonConsoleLexer, PythonLexer, \
+ PythonTracebackLexer
+from pygments.token import Comment, Generic
+from sphinx import highlighting
+import re
+
+line_re = re.compile('.*?\n')
+
+class IPythonConsoleLexer(Lexer):
+ """
+ For IPython console output or doctests, such as:
+
+ Tracebacks are not currently supported.
+
+ .. sourcecode:: pycon
+
+ In [1]: a = 'foo'
+
+ In [2]: a
+ Out[2]: 'foo'
+
+ In [3]: print a
+ foo
+
+ In [4]: 1 / 0
+ """
+ name = 'IPython console session'
+ aliases = ['ipython']
+ mimetypes = ['text/x-ipython-console']
+ input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)")
+ output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)")
+ continue_prompt = re.compile(" \.\.\.+:")
+ tb_start = re.compile("\-+")
+
+ def get_tokens_unprocessed(self, text):
+ pylexer = PythonLexer(**self.options)
+ tblexer = PythonTracebackLexer(**self.options)
+
+ curcode = ''
+ insertions = []
+ for match in line_re.finditer(text):
+ line = match.group()
+ input_prompt = self.input_prompt.match(line)
+ continue_prompt = self.continue_prompt.match(line.rstrip())
+ output_prompt = self.output_prompt.match(line)
+ if line.startswith("#"):
+ insertions.append((len(curcode),
+ [(0, Comment, line)]))
+ elif input_prompt is not None:
+ insertions.append((len(curcode),
+ [(0, Generic.Prompt, input_prompt.group())]))
+ curcode += line[input_prompt.end():]
+ elif continue_prompt is not None:
+ insertions.append((len(curcode),
+ [(0, Generic.Prompt, continue_prompt.group())]))
+ curcode += line[continue_prompt.end():]
+ elif output_prompt is not None:
+ insertions.append((len(curcode),
+ [(0, Generic.Output, output_prompt.group())]))
+ curcode += line[output_prompt.end():]
+ else:
+ if curcode:
+ for item in do_insertions(insertions,
+ pylexer.get_tokens_unprocessed(curcode)):
+ yield item
+ curcode = ''
+ insertions = []
+ yield match.start(), Generic.Output, line
+ if curcode:
+ for item in do_insertions(insertions,
+ pylexer.get_tokens_unprocessed(curcode)):
+ yield item
+
+highlighting.lexers['ipython'] = IPythonConsoleLexer()
Added: trunk/matplotlib/docs/sphinxext/mathml.py
===================================================================
--- trunk/matplotlib/docs/sphinxext/mathml.py (rev 0)
+++ trunk/matplotlib/docs/sphinxext/mathml.py 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,552 @@
+from docutils import nodes
+from docutils.writers.html4css1 import HTMLTranslator
+from sphinx.latexwriter import LaTeXTranslator
+
+# Define LaTeX math node:
+class latex_math(nodes.General, nodes.Element):
+ pass
+
+def math_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ i = rawtext.find('`')
+ latex = rawtext[i+1:-1]
+ try:
+ mathml_tree = parse_latex_math(latex, inline=True)
+ except SyntaxError, msg:
+ msg = inliner.reporter.error(msg, line=lineno)
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+ node = latex_math(rawtext)
+ node['latex'] = latex
+ node['mathml_tree'] = mathml_tree
+ return [node], []
+
+
+try:
+ from docutils.parsers.rst import Directive
+except ImportError:
+ # Register directive the old way:
+ from docutils.parsers.rst.directives import _directives
+ def math_directive(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ latex = ''.join(content)
+ try:
+ mathml_tree = parse_latex_math(latex, inline=False)
+ except SyntaxError, msg:
+ error = state_machine.reporter.error(
+ msg, nodes.literal_block(block_text, block_text), line=lineno)
+ return [error]
+ node = latex_math(block_text)
+ node['latex'] = latex
+ node['mathml_tree'] = mathml_tree
+ return [node]
+ math_directive.arguments = None
+ math_directive.options = {}
+ math_directive.content = 1
+ _directives['math'] = math_directive
+else:
+ class math_directive(Directive):
+ has_content = True
+ def run(self):
+ latex = ' '.join(self.content)
+ try:
+ mathml_tree = parse_latex_math(latex, inline=False)
+ except SyntaxError, msg:
+ error = self.state_machine.reporter.error(
+ msg, nodes.literal_block(self.block_text, self.block_text),
+ line=self.lineno)
+ return [error]
+ node = latex_math(self.block_text)
+ node['latex'] = latex
+ node['mathml_tree'] = mathml_tree
+ return [node]
+ from docutils.parsers.rst import directives
+ directives.register_directive('math', math_directive)
+
+def setup(app):
+ app.add_node(latex_math)
+ app.add_role('math', math_role)
+
+ # Add visit/depart methods to HTML-Translator:
+ def visit_latex_math_html(self, node):
+ mathml = ''.join(node['mathml_tree'].xml())
+ self.body.append(mathml)
+ def depart_latex_math_html(self, node):
+ pass
+ HTMLTranslator.visit_latex_math = visit_latex_math_html
+ HTMLTranslator.depart_latex_math = depart_latex_math_html
+
+ # Add visit/depart methods to LaTeX-Translator:
+ def visit_latex_math_latex(self, node):
+ inline = isinstance(node.parent, nodes.TextElement)
+ if inline:
+ self.body.append('$%s$' % node['latex'])
+ else:
+ self.body.extend(['\\begin{equation}',
+ node['latex'],
+ '\\end{equation}'])
+ def depart_latex_math_latex(self, node):
+ pass
+ LaTeXTranslator.visit_latex_math = visit_latex_math_latex
+ LaTeXTranslator.depart_latex_math = depart_latex_math_latex
+
+
+# LaTeX to MathML translation stuff:
+class math:
+ """Base class for MathML elements."""
+
+ nchildren = 1000000
+ """Required number of children"""
+
+ def __init__(self, children=None, inline=None):
+ """math([children]) -> MathML element
+
+ children can be one child or a list of children."""
+
+ self.children = []
+ if children is not None:
+ if type(children) is list:
+ for child in children:
+ self.append(child)
+ else:
+ # Only one child:
+ self.append(children)
+
+ if inline is not None:
+ self.inline = inline
+
+ def __repr__(self):
+ if hasattr(self, 'children'):
+ return self.__class__.__name__ + '(%s)' % \
+ ','.join([repr(child) for child in self.children])
+ else:
+ return self.__class__.__name__
+
+ def full(self):
+ """Room for more children?"""
+
+ return len(self.children) >= self.nchildren
+
+ def append(self, child):
+ """append(child) -> element
+
+ Appends child and returns self if self is not full or first
+ non-full parent."""
+
+ assert not self.full()
+ self.children.append(child)
+ child.parent = self
+ node = self
+ while node.full():
+ node = node.parent
+ return node
+
+ def delete_child(self):
+ """delete_child() -> child
+
+ Delete last child and return it."""
+
+ child = self.children[-1]
+ del self.children[-1]
+ return child
+
+ def close(self):
+ """close() -> parent
+
+ Close element and return first non-full element."""
+
+ parent = self.parent
+ while parent.full():
+ parent = parent.parent
+ return parent
+
+ def xml(self):
+ """xml() -> xml-string"""
+
+ return self.xml_start() + self.xml_body() + self.xml_end()
+
+ def xml_start(self):
+ if not hasattr(self, 'inline'):
+ return ['<%s>' % self.__class__.__name__]
+ xmlns = 'http://www.w3.org/1998/Math/MathML'
+ if self.inline:
+ return ['<math xmlns="%s">' % xmlns]
+ else:
+ return ['<math xmlns="%s" mode="display">' % xmlns]
+
+ def xml_end(self):
+ return ['</%s>' % self.__class__.__name__]
+
+ def xml_body(self):
+ xml = []
+ for child in self.children:
+ xml.extend(child.xml())
+ return xml
+
+class mrow(math): pass
+class mtable(math): pass
+class mtr(mrow): pass
+class mtd(mrow): pass
+
+class mx(math):
+ """Base class for mo, mi, and mn"""
+
+ nchildren = 0
+ def __init__(self, data):
+ self.data = data
+
+ def xml_body(self):
+ return [self.data]
+
+class mo(mx):
+ translation = {'<': '<', '>': '>'}
+ def xml_body(self):
+ return [self.translation.get(self.data, self.data)]
+
+class mi(mx): pass
+class mn(mx): pass
+
+class msub(math):
+ nchildren = 2
+
+class msup(math):
+ nchildren = 2
+
+class msqrt(math):
+ nchildren = 1
+
+class mroot(math):
+ nchildren = 2
+
+class mfrac(math):
+ nchildren = 2
+
+class msubsup(math):
+ nchildren = 3
+ def __init__(self, children=None, reversed=False):
+ self.reversed = reversed
+ math.__init__(self, children)
+
+ def xml(self):
+ if self.reversed:
+## self.children[1:3] = self.children[2:0:-1]
+ self.children[1:3] = [self.children[2], self.children[1]]
+ self.reversed = False
+ return math.xml(self)
+
+class mfenced(math):
+ translation = {'\\{': '{', '\\langle': u'\u2329',
+ '\\}': '}', '\\rangle': u'\u232A',
+ '.': ''}
+ def __init__(self, par):
+ self.openpar = par
+ math.__init__(self)
+
+ def xml_start(self):
+ open = self.translation.get(self.openpar, self.openpar)
+ close = self.translation.get(self.closepar, self.closepar)
+ return ['<mfenced open="%s" close="%s">' % (open, close)]
+
+class mspace(math):
+ nchildren = 0
+
+class mstyle(math):
+ def __init__(self, children=None, nchildren=None, **kwargs):
+ if nchildren is not None:
+ self.nchildren = nchildren
+ math.__init__(self, children)
+ self.attrs = kwargs
+
+ def xml_start(self):
+ return ['<mstyle '] + ['%s="%s"' % item
+ for item in self.attrs.items()] + ['>']
+
+class mover(math):
+ nchildren = 2
+ def __init__(self, children=None, reversed=False):
+ self.reversed = reversed
+ math.__init__(self, children)
+
+ def xml(self):
+ if self.reversed:
+ self.children.reverse()
+ self.reversed = False
+ return math.xml(self)
+
+class munder(math):
+ nchildren = 2
+
+class munderover(math):
+ nchildren = 3
+ def __init__(self, children=None):
+ math.__init__(self, children)
+
+class mtext(math):
+ nchildren = 0
+ def __init__(self, text):
+ self.text = text
+
+ def xml_body(self):
+ return [self.text]
+
+
+over = {'tilde': '~',
+ 'hat': '^',
+ 'bar': '_',
+ 'vec': u'\u2192'}
+
+Greek = {
+ # Upper case greek letters:
+ 'Phi': u'\u03a6', 'Xi': u'\u039e', 'Sigma': u'\u03a3', 'Psi': u'\u03a8', 'Delta': u'\u0394', 'Theta': u'\u0398', 'Upsilon': u'\u03d2', 'Pi': u'\u03a0', 'Omega': u'\u03a9', 'Gamma': u'\u0393', 'Lambda': u'\u039b'}
+greek = {
+ # Lower case greek letters:
+ 'tau': u'\u03c4', 'phi': u'\u03d5', 'xi': u'\u03be', 'iota': u'\u03b9', 'epsilon': u'\u03f5', 'varrho': u'\u03f1', 'varsigma': u'\u03c2', 'beta': u'\u03b2', 'psi': u'\u03c8', 'rho': u'\u03c1', 'delta': u'\u03b4', 'alpha': u'\u03b1', 'zeta': u'\u03b6', 'omega': u'\u03c9', 'varepsilon': u'\u03b5', 'kappa': u'\u03ba', 'vartheta': u'\u03d1', 'chi': u'\u03c7', 'upsilon': u'\u03c5', 'sigma': u'\u03c3', 'varphi': u'\u03c6', 'varpi': u'\u03d6', 'mu': u'\u03bc', 'eta': u'\u03b7', 'theta': u'\u03b8', 'pi': u'\u03c0', 'varkappa': u'\u03f0', 'nu': u'\u03bd', 'gamma': u'\u03b3', 'lambda': u'\u03bb'}
+
+special = {
+ # Binary operation symbols:
+ 'wedge': u'\u2227', 'diamond': u'\u22c4', 'star': u'\u22c6', 'amalg': u'\u2a3f', 'ast': u'\u2217', 'odot': u'\u2299', 'triangleleft': u'\u25c1', 'bigtriangleup': u'\u25b3', 'ominus': u'\u2296', 'ddagger': u'\u2021', 'wr': u'\u2240', 'otimes': u'\u2297', 'sqcup': u'\u2294', 'oplus': u'\u2295', 'bigcirc': u'\u25cb', 'oslash': u'\u2298', 'sqcap': u'\u2293', 'bullet': u'\u2219', 'cup': u'\u222a', 'cdot': u'\u22c5', 'cap': u'\u2229', 'bigtriangledown': u'\u25bd', 'times': u'\xd7', 'setminus': u'\u2216', 'circ': u'\u2218', 'vee': u'\u2228', 'uplus': u'\u228e', 'mp': u'\u2213', 'dagger': u'\u2020', 'triangleright': u'\u25b7', 'div': u'\xf7', 'pm': u'\xb1',
+ # Relation symbols:
+ 'subset': u'\u2282', 'propto': u'\u221d', 'geq': u'\u2265', 'ge': u'\u2265', 'sqsubset': u'\u228f', 'Join': u'\u2a1d', 'frown': u'\u2322', 'models': u'\u22a7', 'supset': u'\u2283', 'in': u'\u2208', 'doteq': u'\u2250', 'dashv': u'\u22a3', 'gg': u'\u226b', 'leq': u'\u2264', 'succ': u'\u227b', 'vdash': u'\u22a2', 'cong': u'\u2245', 'simeq': u'\u2243', 'subseteq': u'\u2286', 'parallel': u'\u2225', 'equiv': u'\u2261', 'ni': u'\u220b', 'le': u'\u2264', 'approx': u'\u2248', 'precsim': u'\u227e', 'sqsupset': u'\u2290', 'll': u'\u226a', 'sqsupseteq': u'\u2292', 'mid': u'\u2223', 'prec': u'\u227a', 'succsim': u'\u227f', 'bowtie': u'\u22c8', 'perp': u'\u27c2', 'sqsubseteq': u'\u2291', 'asymp': u'\u224d', 'smile': u'\u2323', 'supseteq': u'\u2287', 'sim': u'\u223c', 'neq': u'\u2260',
+ # Arrow symbols:
+ 'searrow': u'\u2198', 'updownarrow': u'\u2195', 'Uparrow': u'\u21d1', 'longleftrightarrow': u'\u27f7', 'Leftarrow': u'\u21d0', 'longmapsto': u'\u27fc', 'Longleftarrow': u'\u27f8', 'nearrow': u'\u2197', 'hookleftarrow': u'\u21a9', 'downarrow': u'\u2193', 'Leftrightarrow': u'\u21d4', 'longrightarrow': u'\u27f6', 'rightharpoondown': u'\u21c1', 'longleftarrow': u'\u27f5', 'rightarrow': u'\u2192', 'Updownarrow': u'\u21d5', 'rightharpoonup': u'\u21c0', 'Longleftrightarrow': u'\u27fa', 'leftarrow': u'\u2190', 'mapsto': u'\u21a6', 'nwarrow': u'\u2196', 'uparrow': u'\u2191', 'leftharpoonup': u'\u21bc', 'leftharpoondown': u'\u21bd', 'Downarrow': u'\u21d3', 'leftrightarrow': u'\u2194', 'Longrightarrow': u'\u27f9', 'swarrow': u'\u2199', 'hookrightarrow': u'\u21aa', 'Rightarrow': u'\u21d2',
+ # Miscellaneous symbols:
+ 'infty': u'\u221e', 'surd': u'\u221a', 'partial': u'\u2202', 'ddots': u'\u22f1', 'exists': u'\u2203', 'flat': u'\u266d', 'diamondsuit': u'\u2662', 'wp': u'\u2118', 'spadesuit': u'\u2660', 'Re': u'\u211c', 'vdots': u'\u22ee', 'aleph': u'\u2135', 'clubsuit': u'\u2663', 'sharp': u'\u266f', 'angle': u'\u2220', 'prime': u'\u2032', 'natural': u'\u266e', 'ell': u'\u2113', 'neg': u'\xac', 'top': u'\u22a4', 'nabla': u'\u2207', 'bot': u'\u22a5', 'heartsuit': u'\u2661', 'cdots': u'\u22ef', 'Im': u'\u2111', 'forall': u'\u2200', 'imath': u'\u0131', 'hbar': u'\u210f', 'emptyset': u'\u2205',
+ # Variable-sized symbols:
+ 'bigotimes': u'\u2a02', 'coprod': u'\u2210', 'int': u'\u222b', 'sum': u'\u2211', 'bigodot': u'\u2a00', 'bigcup': u'\u22c3', 'biguplus': u'\u2a04', 'bigcap': u'\u22c2', 'bigoplus': u'\u2a01', 'oint': u'\u222e', 'bigvee': u'\u22c1', 'bigwedge': u'\u22c0', 'prod': u'\u220f',
+ # Braces:
+ 'langle': u'\u2329', 'rangle': u'\u232A'}
+
+sumintprod = ''.join([special[symbol] for symbol in
+ ['sum', 'int', 'oint', 'prod']])
+
+functions = ['arccos', 'arcsin', 'arctan', 'arg', 'cos', 'cosh',
+ 'cot', 'coth', 'csc', 'deg', 'det', 'dim',
+ 'exp', 'gcd', 'hom', 'inf', 'ker', 'lg',
+ 'lim', 'liminf', 'limsup', 'ln', 'log', 'max',
+ 'min', 'Pr', 'sec', 'sin', 'sinh', 'sup',
+ 'tan', 'tanh',
+ 'injlim', 'varinjlim', 'varlimsup',
+ 'projlim', 'varliminf', 'varprojlim']
+
+
+def parse_latex_math(string, inline=True):
+ """parse_latex_math(string [,inline]) -> MathML-tree
+
+ Returns a MathML-tree parsed from string. inline=True is for
+ inline math and inline=False is for displayed math.
+
+ tree is the whole tree and node is the current element."""
+
+ # Normalize white-space:
+ string = ' '.join(string.split())
+
+ if inline:
+ node = mrow()
+ tree = math(node, inline=True)
+ else:
+ node = mtd()
+ tree = math(mtable(mtr(node)), inline=False)
+
+ while len(string) > 0:
+ n = len(string)
+ c = string[0]
+ skip = 1 # number of characters consumed
+ if n > 1:
+ c2 = string[1]
+ else:
+ c2 = ''
+## print n, string, c, c2, node.__class__.__name__
+ if c == ' ':
+ pass
+ elif c == '\\':
+ if c2 in '{}':
+ node = node.append(mo(c2))
+ skip = 2
+ elif c2 == ' ':
+ node = node.append(mspace())
+ skip = 2
+ elif c2.isalpha():
+ # We have a LaTeX-name:
+ i = 2
+ while i < n and string[i].isalpha():
+ i += 1
+ name = string[1:i]
+ node, skip = handle_keyword(name, node, string[i:])
+ skip += i
+ elif c2 == '\\':
+ # End of a row:
+ entry = mtd()
+ row = mtr(entry)
+ node.close().close().append(row)
+ node = entry
+ skip = 2
+ else:
+ raise SyntaxError('Syntax error: "%s%s"' % (c, c2))
+ elif c.isalpha():
+ node = node.append(mi(c))
+ elif c.isdigit():
+ node = node.append(mn(c))
+ elif c in "+-/()[]|=<>,.!'":
+ node = node.append(mo(c))
+ elif c == '_':
+ child = node.delete_child()
+ if isinstance(child, msup):
+ sub = msubsup(child.children, reversed=True)
+ elif isinstance(child, mo) and child.data in sumintprod:
+ sub = munder(child)
+ else:
+ sub = msub(child)
+ node.append(sub)
+ node = sub
+ elif c == '^':
+ child = node.delete_child()
+ if isinstance(child, msub):
+ sup = msubsup(child.children)
+ elif isinstance(child, mo) and child.data in sumintprod:
+ sup = mover(child)
+ elif (isinstance(child, munder) and
+ child.children[0].data in sumintprod):
+ sup = munderover(child.children)
+ else:
+ sup = msup(child)
+ node.append(sup)
+ node = sup
+ elif c == '{':
+ row = mrow()
+ node.append(row)
+ node = row
+ elif c == '}':
+ node = node.close()
+ elif c == '&':
+ entry = mtd()
+ node.close().append(entry)
+ node = entry
+ else:
+ raise SyntaxError('Illegal character: "%s"' % c)
+ string = string[skip:]
+ return tree
+
+
+mathbb = {'A': u'\U0001D538',
+ 'B': u'\U0001D539',
+ 'C': u'\u2102',
+ 'D': u'\U0001D53B',
+ 'E': u'\U0001D53C',
+ 'F': u'\U0001D53D',
+ 'G': u'\U0001D53E',
+ 'H': u'\u210D',
+ 'I': u'\U0001D540',
+ 'J': u'\U0001D541',
+ 'K': u'\U0001D542',
+ 'L': u'\U0001D543',
+ 'M': u'\U0001D544',
+ 'N': u'\u2115',
+ 'O': u'\U0001D546',
+ 'P': u'\u2119',
+ 'Q': u'\u211A',
+ 'R': u'\u211D',
+ 'S': u'\U0001D54A',
+ 'T': u'\U0001D54B',
+ 'U': u'\U0001D54C',
+ 'V': u'\U0001D54D',
+ 'W': u'\U0001D54E',
+ 'X': u'\U0001D54F',
+ 'Y': u'\U0001D550',
+ 'Z': u'\u2124'}
+
+negatables = {'=': u'\u2260',
+ '\in': u'\u2209',
+ '\equiv': u'\u2262'}
+
+
+def handle_keyword(name, node, string):
+ skip = 0
+ if len(string) > 0 and string[0] == ' ':
+ string = string[1:]
+ skip = 1
+ if name == 'begin':
+ if not string.startswith('{matrix}'):
+ raise SyntaxError('Expected "\begin{matrix}"!')
+ skip += 8
+ entry = mtd()
+ table = mtable(mtr(entry))
+ node.append(table)
+ node = entry
+ elif name == 'end':
+ if not string.startswith('{matrix}'):
+ raise SyntaxError('Expected "\end{matrix}"!')
+ skip += 8
+ node = node.close().close().close()
+ elif name == 'text':
+ if string[0] != '{':
+ raise SyntaxError('Expected "\text{...}"!')
+ i = string.find('}')
+ if i == -1:
+ raise SyntaxError('Expected "\text{...}"!')
+ node = node.append(mtext(string[1:i]))
+ skip += i + 1
+ elif name == 'sqrt':
+ sqrt = msqrt()
+ node.append(sqrt)
+ node = sqrt
+ elif name == 'frac':
+ frac = mfrac()
+ node.append(frac)
+ node = frac
+ elif name == 'left':
+ for par in ['(', '[', '|', '\\{', '\\langle', '.']:
+ if string.startswith(par):
+ break
+ else:
+ raise SyntaxError('Missing left-brace!')
+ fenced = mfenced(par)
+ node.append(fenced)
+ row = mrow()
+ fenced.append(row)
+ node = row
+ skip += len(par)
+ elif name == 'right':
+ for par in [')', ']', '|', '\\}', '\\rangle', '.']:
+ if string.startswith(par):
+ break
+ else:
+ raise SyntaxError('Missing right-brace!')
+ node = node.close()
+ node.closepar = par
+ node = node.close()
+ skip += len(par)
+ elif name == 'not':
+ for operator in negatables:
+ if string.startswith(operator):
+ break
+ else:
+ raise SyntaxError('Expected something to negate: "\\not ..."!')
+ node = node.append(mo(negatables[operator]))
+ skip += len(operator)
+ elif name == 'mathbf':
+ style = mstyle(nchildren=1, fontweight='bold')
+ node.append(style)
+ node = style
+ elif name == 'mathbb':
+ if string[0] != '{' or not string[1].isupper() or string[2] != '}':
+ raise SyntaxError('Expected something like "\mathbb{A}"!')
+ node = node.append(mi(mathbb[string[1]]))
+ skip += 3
+ elif name in greek:
+ node = node.append(mi(greek[name]))
+ elif name in Greek:
+ node = node.append(mo(Greek[name]))
+ elif name in special:
+ node = node.append(mo(special[name]))
+ elif name in functions:
+ node = node.append(mo(name))
+ else:
+ chr = over.get(name)
+ if chr is not None:
+ ovr = mover(mo(chr), reversed=True)
+ node.append(ovr)
+ node = ovr
+ else:
+ raise SyntaxError('Unknown LaTeX command: ' + name)
+
+ return node, skip
Added: trunk/matplotlib/docs/sphinxext/mathpng.py
===================================================================
--- trunk/matplotlib/docs/sphinxext/mathpng.py (rev 0)
+++ trunk/matplotlib/docs/sphinxext/mathpng.py 2008-05-24 20:49:31 UTC (rev 5253)
@@ -0,0 +1,111 @@
+import os
+try:
+ from hashlib import md5
+except ImportError:
+ from md5 import md5
+
+from docutils import nodes
+from docutils.writers.html4css1 import HTMLTranslator
+from sphinx.latexwriter import LaTeXTranslator
+
+# Define LaTeX math node:
+class latex_math(nodes.General, nodes.Element):
+ pass
+
+def math_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ i = rawtext.find('`')
+ latex = rawtext[i+1:-1]
+ node = latex_math(rawtext)
+ node['latex'] = latex
+ return [node], []
+
+
+try:
+ from docutils.parsers.rst import Directive
+except ImportError:
+ # Register directive the old way:
+ from docutils.parsers.rst.directives import _directives
+ def math_directive(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ latex = ''.join(content)
+ node = latex_math(block_text)
+ node['latex'] = latex
+ return [node]
+ math_directive.arguments = None
+ math_directive.options = {}
+ math_directive.content = 1
+ _directives['math'] = math_directive
+else:
+ class math_directive(Directive):
+ has_content = True
+ def run(self):
+ latex = ' '.join(self.content)
+ node = latex_math(self.block_text)
+ node['latex'] = latex
+ return [node]
+ from docutils.parsers.rst import directives
+ directives.register_directive('math', math_directive)
+
+def setup(app):
+ app.add_node(latex_math)
+ app.add_role('math', math_role)
+
+ # Add visit/depart methods to HTML-Translator:
+ def visit_latex_math_html(self, node):
+ source = self.document.attributes['source']
+ self.body.append(latex2html(node, source))
+ def depart_latex_math_html(self, node):
+ pass
+ HTMLTranslator.visit_latex_math = visit_latex_math_html
+ HTMLTranslator.depart_latex_math = depart_latex_math_html
+
+ # Add visit/depart methods to LaTeX-Translator:
+ def visit_latex_math_latex(self, node):
+ inline = isinstance(node.parent, nodes.TextElement)
+ if inline:
+ self.body.append('$%s$' % node['latex'])
+ else:
+ self.body.extend(['\\begin{equation}',
+ node['latex'],
+ '\\end{equation}'])
+ def depart_latex_math_latex(self, node):
+ pass
+ LaTeXTranslator.visit_latex_math = visit_latex_math_latex
+ LaTeXTranslator.depart_latex_math = depart_latex_math_latex
+
+from os.path import isfile
+# LaTeX to HTML translation stuff:
+def latex2html(node, source):
+ inline = isinstance(node.parent, nodes.TextElement)
+ latex = node['latex']
+ print latex
+ name = 'math-' + md5(latex).hexdigest()[-10:]
+ if not isfile('_static/%s.png' % name):
+ f = open('math.tex', 'w')
+ f.write(r...
[truncated message content] |