diff --git a/AUTHORS b/AUTHORS index 09be75330..6e215c8c1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,6 +5,8 @@ Substantial parts of the templates were written by Armin Ronacher Other contributors, listed alphabetically, are: +* Andi Albrecht -- agogo theme +* Henrique Bastos -- SVG support for graphviz extension * Daniel Bültmann -- todo extension * Michael Droettboom -- inheritance_diagram extension * Charles Duffy -- original graphviz extension @@ -14,7 +16,9 @@ Other contributors, listed alphabetically, are: * Dave Kuhlman -- original LaTeX writer * Thomas Lamb -- linkcheck builder * Dan MacKinlay -- metadata fixes +* Martin Mahner -- nature theme * Will Maier -- directory HTML builder +* Roland Meister -- epub builder * Christopher Perkins -- autosummary integration * Benjamin Peterson -- unittests * Stefan Seefeld -- toctree improvements diff --git a/CHANGES b/CHANGES index 54fe76bbd..aaac057c3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,12 +1,44 @@ Release 1.0 (in development) ============================ +* Added ``tab-width`` option to ``literalinclude`` directive. + +* The ``html_sidebars`` config value can now contain patterns as + keys, and the values can be lists that explicitly select which + sidebar templates should be rendered. That means that the builtin + sidebar contents can be included only selectively. + +* ``html_static_path`` can now contain single file entries. + +* The new universal config value ``exclude_patterns`` makes the + old ``unused_docs``, ``exclude_trees`` and ``exclude_dirnames`` + obsolete. + +* Remove the deprecated ``exclude_dirs`` config value. + +* #129: Wrap toctrees in a div tag with class ``toctree-wrapper`` + in HTML output. + +* #280: Autodoc can now document instance attributes assigned in + ``__init__`` methods. + +* Added ``alt`` option to ``graphviz`` extension directives. + +* Added Epub builder. + +* #309: The ``graphviz`` extension can now output SVG instead of PNG + images, controlled by the ``graphviz_output_format`` config value. + * #284: All docinfo metadata is now put into the document metadata, not just the author. +* Added new HTML theme ``haiku``, inspired by the Haiku OS user guide. + +* Added new HTML theme ``nature``. + * Added new HTML theme ``agogo``, created by Andi Albrecht. -* Added new minimal theme called scrolls, created by Armin Ronacher. +* Added new HTML theme ``scrolls``, created by Armin Ronacher. * Added ``html_output_encoding`` config value. @@ -47,6 +79,42 @@ Release 1.0 (in development) Release 0.6.4 (in development) ============================== +* Restore compatibility with Pygments >= 1.2. + +* #295: Fix escaping of hyperref targets in LaTeX output. + +* #302: Fix links generated by the ``:doc:`` role for LaTeX output. + +* #286: collect todo nodes after the whole document has been read; + this allows placing substitution references in todo items. + +* #294: do not ignore an explicit ``today`` config value in a + LaTeX build. + +* The ``alt`` text of inheritance diagrams is now much cleaner. + +* Ignore images in section titles when generating link captions. + +* #310: support exception messages in the ``testoutput`` blocks of + the ``doctest`` extension. + +* #293: line blocks are styled properly in HTML output. + +* #285: make the ``locale_dirs`` config value work again. + +* #303: ``html_context`` values given on the command line via ``-A`` + should not override other values given in conf.py. + +* Fix a bug preventing incremental rebuilds for the ``dirhtml`` + builder. + +* #299: Fix the mangling of quotes in some literal blocks. + +* #292: Fix path to the search index for the ``dirhtml`` builder. + +* Fix a Jython compatibility issue: make the dependence on the + ``parser`` module optional. + * #238: In autodoc, catch all errors that occur on module import, not just ``ImportError``. diff --git a/EXAMPLES b/EXAMPLES index 9d97c8156..8f89a0687 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -1,93 +1,136 @@ Projects using Sphinx ===================== -This is an (incomplete) alphabetic list of projects that use Sphinx or are -experimenting with using it for their documentation. If you like to be -included, please mail to `the Google group +This is an (incomplete) alphabetic list of projects that use Sphinx or +are experimenting with using it for their documentation. If you like to +be included, please mail to `the Google group `_. -* Applied Mathematics at the Stellenbosch University: http://dip.sun.ac.za/ +I've grouped the list into sections to make it easier to find +interesting examples. + +Documentation using the default theme +------------------------------------- + * APSW: http://apsw.googlecode.com/svn/publish/index.html * ASE: https://wiki.fysik.dtu.dk/ase/ +* Blender: http://www.blender.org/documentation/250PythonDoc/ * boostmpi: http://documen.tician.de/boostmpi/ * Calibre: http://calibre.kovidgoyal.net/user_manual/ -* Chaco: http://code.enthought.com/projects/chaco/docs/html/ * CodePy: http://documen.tician.de/codepy/ * Cython: http://docs.cython.org/ * C\\C++ Python language binding project: http://language-binding.net/index.html * Director: http://packages.python.org/director/ -* Djagios: http://djagios.org/ -* Django: http://docs.djangoproject.com/ * F2py: http://www.f2py.org/html/ -* Fityk: http://www.unipress.waw.pl/fityk/ * GeoDjango: http://geodjango.org/docs/ -* GeoServer: http://docs.geoserver.org/ -* Glashammer: http://glashammer.org/ -* GPAW: https://wiki.fysik.dtu.dk/gpaw/ -* Grok: http://grok.zope.org/doc/current/ * GSL Shell: http://www.nongnu.org/gsl-shell/ * Hedge: http://documen.tician.de/hedge/ -* IFM: http://fluffybunny.memebot.com/ifm-docs/index.html -* Jinja: http://jinja.pocoo.org/2/documentation/ * Kaa: http://doc.freevo.org/api/kaa/ -* LEPL: http://www.acooke.org/lepl/ -* MapServer: http://mapserver.org/ -* Matplotlib: http://matplotlib.sourceforge.net/ -* Mayavi: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi * MeshPy: http://documen.tician.de/meshpy/ -* MirrorBrain: http://mirrorbrain.org/docs/ -* Mixin.com: http://dev.mixin.com/ * mpmath: http://mpmath.googlecode.com/svn/trunk/doc/build/index.html -* MyHDL: http://www.myhdl.org/doc/0.6/ -* NetworkX: http://networkx.lanl.gov/ -* NOC: http://trac.nocproject.org/trac/wiki/NocGuide -* nose: http://somethingaboutorange.com/mrl/projects/nose/ -* NumPy: http://docs.scipy.org/doc/numpy/reference/ -* ObjectListView: http://objectlistview.sourceforge.net/python -* Open ERP: http://doc.openerp.com/ * OpenEXR: http://excamera.com/articles/26/doc/index.html -* OpenLayers: http://docs.openlayers.org/ +* OpenGDA: http://www.opengda.org/gdadoc/html/ * openWNS: http://docs.openwns.org/ * Paste: http://pythonpaste.org/script/ * Paver: http://www.blueskyonmars.com/projects/paver/ -* Py on Windows: http://timgolden.me.uk/python-on-windows/ * Pyccuracy: http://www.pyccuracy.org/ * PyCuda: http://documen.tician.de/pycuda/ -* PyEphem: http://rhodesmill.org/pyephem/ * Pyevolve: http://pyevolve.sourceforge.net/ -* PyLit: http://pylit.berlios.de/ * Pylo: http://documen.tician.de/pylo/ -* Pylons: http://docs.pylonshq.com/ -* PyMOTW: http://www.doughellmann.com/PyMOTW/ * PyPubSub: http://pubsub.sourceforge.net/ * pyrticle: http://documen.tician.de/pyrticle/ -* Pysparse: http://pysparse.sourceforge.net/ * Python: http://docs.python.org/ -* python-apt: http://people.debian.org/~jak/python-apt-doc/ +* python-apt: http://apt.alioth.debian.org/python-apt-doc/ * PyUblas: http://documen.tician.de/pyublas/ -* Quex: http://quex.sourceforge.net/ -* Reteisi: http://docs.argolinux.org/reteisi/ -* Roundup: http://www.roundup-tracker.org/ -* Sage: http://sagemath.org/doc/ -* Satchmo: http://www.satchmoproject.com/docs/svn/ +* Quex: http://quex.sourceforge.net/doc/html/main.html * Scapy: http://www.secdev.org/projects/scapy/doc/ +* SimPy: http://simpy.sourceforge.net/SimPyDocs/index.html +* SymPy: http://docs.sympy.org/ +* WTForms: http://wtforms.simplecodes.com/docs/ +* z3c: http://docs.carduner.net/z3c-tutorial/ + + +Documentation using a customized version of the default theme +------------------------------------------------------------- + +* Advanced Generic Widgets: http://xoomer.virgilio.it/infinity77/AGW_Docs/index.html +* Bazaar: http://doc.bazaar.canonical.com/en/ +* Chaco: http://code.enthought.com/projects/chaco/docs/html/ +* Djagios: http://djagios.org/ +* GPAW: https://wiki.fysik.dtu.dk/gpaw/ +* Grok: http://grok.zope.org/doc/current/ +* IFM: http://fluffybunny.memebot.com/ifm-docs/index.html +* LEPL: http://www.acooke.org/lepl/ +* Mayavi: http://code.enthought.com/projects/mayavi/docs/development/html/mayavi +* NOC: http://trac.nocproject.org/trac/wiki/NocGuide +* NumPy: http://docs.scipy.org/doc/numpy/reference/ +* Peach^3: http://peach3.nl/doc/latest/userdoc/ +* Py on Windows: http://timgolden.me.uk/python-on-windows/ +* PyLit: http://pylit.berlios.de/ +* Sage: http://sagemath.org/doc/ * SciPy: http://docs.scipy.org/doc/scipy/reference/ +* Sprox: http://sprox.org/ +* TurboGears: http://turbogears.org/2.0/docs/ +* Zope: http://docs.zope.org/zope2/index.html +* zc.async: http://packages.python.org/zc.async/1.5.0/ + + +Documentation using the sphinxdoc theme +--------------------------------------- + +* Fityk: http://www.unipress.waw.pl/fityk/ +* MapServer: http://mapserver.org/ +* Matplotlib: http://matplotlib.sourceforge.net/ +* MyHDL: http://www.myhdl.org/doc/0.6/ +* NetworkX: http://networkx.lanl.gov/ +* Pysparse: http://pysparse.sourceforge.net/ +* PyTango: http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html +* Reteisi: http://docs.argolinux.org/reteisi/ +* Satchmo: http://www.satchmoproject.com/docs/svn/ +* Sphinx: http://sphinx.pocoo.org/ +* Sqlkit: http://sqlkit.argolinux.org/ +* Total Open Station: http://tops.berlios.de/ +* WebFaction: http://docs.webfaction.com/ + + +Documentation using another builtin theme +----------------------------------------- + +* Distribute: http://packages.python.org/distribute/ (nature) +* Jinja: http://jinja.pocoo.org/2/documentation/ (scrolls) +* pip: http://pip.openplans.org/ (nature) +* sqlparse: http://python-sqlparse.googlecode.com/svn/docs/api/index.html (agogo) + + +Documentation using a custom theme/integrated in a site +------------------------------------------------------- + +* Django: http://docs.djangoproject.com/ +* GeoServer: http://docs.geoserver.org/ +* Glashammer: http://glashammer.org/ +* MirrorBrain: http://mirrorbrain.org/docs/ +* nose: http://somethingaboutorange.com/mrl/projects/nose/ +* ObjectListView: http://objectlistview.sourceforge.net/python +* Open ERP: http://doc.openerp.com/ +* OpenLayers: http://docs.openlayers.org/ +* PyEphem: http://rhodesmill.org/pyephem/ +* Pylons: http://pylonshq.com/docs/en/0.9.7/ +* PyMOTW: http://www.doughellmann.com/PyMOTW/ +* Roundup: http://www.roundup-tracker.org/ * Selenium: http://seleniumhq.org/docs/ * Self: http://selflanguage.org/ -* SimPy: http://simpy.sourceforge.net/ -* Sphinx: http://sphinx.pocoo.org/ -* Sprox: http://sprox.org/ * SQLAlchemy: http://www.sqlalchemy.org/docs/ -* Sqlkit: http://sqlkit.argolinux.org/ -* sqlparse: http://python-sqlparse.googlecode.com/svn/docs/api/index.html -* SymPy: http://docs.sympy.org/ * tinyTiM: http://tinytim.sourceforge.net/docs/2.0/ -* The Wine Cellar Book: http://www.thewinecellarbook.com/doc/en/ -* TurboGears: http://turbogears.org/2.0/docs/ -* VOR: http://www.vor-cycling.be/ -* WebFaction: http://docs.webfaction.com/ * Werkzeug: http://werkzeug.pocoo.org/documentation/dev/ * WFront: http://discorporate.us/projects/WFront/ -* WTForms: http://wtforms.simplecodes.com/docs/ -* Zope 3: e.g. http://docs.carduner.net/z3c-tutorial/ -* zc.async: http://packages.python.org/zc.async/1.5.0/ + + +Homepages and other non-documentation sites +------------------------------------------- + +* Applied Mathematics at the Stellenbosch University: http://dip.sun.ac.za/ +* A personal page: http://www.dehlia.in/ +* Benoit Boissinot: http://perso.ens-lyon.fr/benoit.boissinot/ +* lunarsite: http://lunaryorn.de/ +* The Wine Cellar Book: http://www.thewinecellarbook.com/doc/en/ +* VOR: http://www.vor-cycling.be/ diff --git a/LICENSE b/LICENSE index fb2049a8a..468914934 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ License for Sphinx ================== -Copyright (c) 2007-2009 by the Sphinx team (see AUTHORS file). +Copyright (c) 2007-2010 by the Sphinx team (see AUTHORS file). All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Makefile b/Makefile index 64fef3346..b7716b592 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ all: clean-pyc check test check: @$(PYTHON) utils/check_sources.py -i build -i dist -i sphinx/style/jquery.js \ - -i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \ + -i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py -i .ropeproject \ -i doc/_build -i ez_setup.py -i tests/path.py -i tests/coverage.py . clean: clean-pyc clean-patchfiles diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html index c738aeec2..a268ec6ef 100644 --- a/doc/_templates/indexsidebar.html +++ b/doc/_templates/indexsidebar.html @@ -11,6 +11,8 @@

Get Sphinx from the Python Package Index, or install it with:

easy_install -U Sphinx
+

Latest development version docs +are also available.

{% endif %}

Questions? Suggestions?

diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html index e41b68b17..60d217df5 100644 --- a/doc/_templates/layout.html +++ b/doc/_templates/layout.html @@ -1,12 +1,13 @@ {% extends "!layout.html" %} {% block extrahead %} +{{ super() }} {%- if not embedded %} -{% endif %} +{%- endif %} {% endblock %} {% block rootrellink %} diff --git a/doc/builders.rst b/doc/builders.rst index 3ce8f56a7..e8dccc430 100644 --- a/doc/builders.rst +++ b/doc/builders.rst @@ -67,11 +67,9 @@ The builder's "name" must be given to the **-b** command-line option of .. class:: EpubBuilder This builder produces the same output as the standalone HTML builder, but - also generates an *epub* file for ebook readers. - This builder is meant to be used together with the - :confval:`html_theme` ``'epub'``. - See ``_ or - ``_ for the definition of epubs. + also generates an *epub* file for ebook readers. See :ref:`epub-faq` for + details about it. For definition of the epub format, have a look at + ``_ or ``_. Its name is ``epub``. diff --git a/doc/concepts.rst b/doc/concepts.rst index 277672111..5aabdd3b8 100644 --- a/doc/concepts.rst +++ b/doc/concepts.rst @@ -133,8 +133,8 @@ tables of contents. The ``toctree`` directive is the central element. In the end, all documents in the :term:`source directory` (or subdirectories) must occur in some ``toctree`` directive; Sphinx will emit a warning if it finds a file that is not included, because that means that this file will not - be reachable through standard navigation. Use :confval:`unused_documents` to - explicitly exclude documents from building, and :confval:`exclude_dirs` to + be reachable through standard navigation. Use :confval:`unused_docs` to + explicitly exclude documents from building, and :confval:`exclude_trees` to exclude whole directories. The "master document" (selected by :confval:`master_doc`) is the "root" of diff --git a/doc/conf.py b/doc/conf.py index 7393643a1..836ad52eb 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -9,8 +9,6 @@ import sys, os, re extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.autosummary'] -extlinks = {'issue': ('http://bugs.python.org/issue', 'issue ')} - # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -20,9 +18,11 @@ source_suffix = '.rst' # The master toctree document. master_doc = 'contents' +exclude_patterns = ['_build'] + # General substitutions. project = 'Sphinx' -copyright = '2007-2009, Georg Brandl' +copyright = '2007-2010, Georg Brandl' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. @@ -34,7 +34,7 @@ release = version show_authors = True # The HTML template theme. -html_theme = 'epub' +html_theme = 'sphinxdoc' # A list of ignored prefixes names for module index sorting. modindex_common_prefix = ['sphinx.'] @@ -52,7 +52,7 @@ html_last_updated_fmt = '%b %d, %Y' html_index = 'index.html' # Custom sidebar templates, maps page names to templates. -html_sidebars = {'index': 'indexsidebar.html'} +html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']} # Additional templates that should be rendered to pages, maps page names to # templates. @@ -65,12 +65,13 @@ html_use_opensearch = 'http://sphinx.pocoo.org' htmlhelp_basename = 'Sphinxdoc' # Epub fields +epub_theme = 'epub' epub_basename = 'sphinx' -epub_author = 'Georg Brandl' +epub_author = 'Georg Brandl' epub_publisher = 'http://sphinx.pocoo.org/' epub_scheme = 'url' epub_identifier = epub_publisher -epub_pre_files = [ ('index', 'Welcome')] +epub_pre_files = [('index', 'Welcome')] epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js', '_static/jquery.js', '_static/searchtools.js', '_static/basic.css', 'search.html'] diff --git a/doc/config.rst b/doc/config.rst index 99b484c85..e4693d848 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -87,12 +87,37 @@ General configuration The document name of the "master" document, that is, the document that contains the root :dir:`toctree` directive. Default is ``'contents'``. +.. confval:: exclude_patterns + + A list of glob-style patterns that should be excluded when looking for source + files. [1]_ They are matched against the source file names relative to the + source directory, using slashes as directory separators on all platforms. + + Example patterns: + + - ``'library/xml.rst'`` -- ignores the ``library/xml.rst`` file (replaces + entry in :confval:`unused_docs` + - ``'library/xml'`` -- ignores the ``library/xml`` directory (replaces entry + in :confval:`exclude_trees`) + - ``'library/xml*'`` -- ignores all files and directories starting with + ``library/xml`` + - ``'**/.svn'`` -- ignores all ``.svn`` directories (replaces entry in + :confval:`exclude_dirnames`) + + :confval:`exclude_patterns` is also consulted when looking for static files + in :confval:`html_static_path`. + + .. versionadded:: 1.0 + .. confval:: unused_docs A list of document names that are present, but not currently included in the toctree. Use this setting to suppress the warning that is normally emitted in that case. + .. deprecated:: 1.0 + Use :confval:`exclude_patterns` instead. + .. confval:: exclude_trees A list of directory paths, relative to the source directory, that are to be @@ -101,6 +126,9 @@ General configuration .. versionadded:: 0.4 + .. deprecated:: 1.0 + Use :confval:`exclude_patterns` instead. + .. confval:: exclude_dirnames A list of directory names that are to be excluded from any recursive @@ -110,15 +138,8 @@ General configuration .. versionadded:: 0.5 -.. confval:: exclude_dirs - - A list of directory names, relative to the source directory, that are to be - excluded from the search for source files. - - .. deprecated:: 0.5 - This does not take subdirs of the excluded directories into account. Use - :confval:`exclude_trees` or :confval:`exclude_dirnames`, which match the - expectations. + .. deprecated:: 1.0 + Use :confval:`exclude_patterns` instead. .. confval:: locale_dirs @@ -398,6 +419,9 @@ that use Sphinx' HTMLWriter class. .. versionchanged:: 0.4 The paths in :confval:`html_static_path` can now contain subdirectories. + .. versionchanged:: 1.0 + The entries in :confval:`html_static_path` can now be single files. + .. confval:: html_last_updated_fmt If this is not the empty string, a 'Last updated on:' timestamp is inserted @@ -421,14 +445,53 @@ that use Sphinx' HTMLWriter class. .. confval:: html_sidebars Custom sidebar templates, must be a dictionary that maps document names to - template names. Example:: + template names. + + The keys can contain glob-style patterns [1]_, in which case all matching + documents will get the specified sidebars. (A warning is emitted when a + more than one glob-style pattern matches for any document.) + + The values can be either lists or single strings. + + * If a value is a list, it specifies the complete list of sidebar templates + to include. If all or some of the default sidebars are to be included, + they must be put into this list as well. + + The default sidebars (for documents that don't match any pattern) are: + ``['localtoc.html', 'relations.html', 'sourcelink.html', + 'searchbox.html']``. + + * If a value is a single string, it specifies a custom sidebar to be added + between the ``'sourcelink.html'`` and ``'searchbox.html'`` entries. This + is for compatibility with Sphinx versions before 1.0. + + Builtin sidebar templates that can be rendered are: + + * **localtoc.html** -- a fine-grained table of contents of the current document + * **globaltoc.html** -- a coarse-grained table of contents for the whole + documentation set, collapsed + * **relations.html** -- two links to the previous and next documents + * **sourcelink.html** -- a link to the source of the current document, if + enabled in :confval:`html_show_sourcelink` + * **searchbox.html** -- the "quick search" box + + Example:: html_sidebars = { - 'using/windows': 'windowssidebar.html' + '**': ['globaltoc.html', 'sourcelink.html', 'searchbox.html'], + 'using/windows': ['windowssidebar.html', 'searchbox.html'], } - This will render the template ``windowssidebar.html`` within the sidebar of - the given document. + This will render the custom template ``windowssidebar.html`` and the quick + search box within the sidebar of the given document, and render the default + sidebars for all other pages (except that the local TOC is replaced by the + global TOC). + + .. versionadded:: 1.0 + The ability to use globbing keys and to specify multiple sidebars. + + Note that this value only has no effect if the chosen theme does not possess + a sidebar, like the builtin **scrolls** and **haiku** themes. .. confval:: html_additional_pages @@ -554,92 +617,89 @@ that use Sphinx' HTMLWriter class. Options for epub output ----------------------- -These options influence the epub output. As this writer derives from the -HTMLWriter the HTML options also apply where appropriate. -The actual values for some of the options is not really important, -they just have to be entered into +These options influence the epub output. As this builder derives from the HTML +builder, the HTML options also apply where appropriate. The actual values for +some of the options is not really important, they just have to be entered into the `Dublin Core metadata `_. .. confval:: epub_basename - The basename for the epub file. It defaults to the :confval:`project` name. + The basename for the epub file. It defaults to the :confval:`project` name. + +.. confval:: epub_theme + + The HTML theme for the epub output. Since the default themes are not + optimized for small screen space, using the same theme for HTML and epub + output is usually not wise. This defaults to ``'epub'``, a theme designed to + save visual space. .. confval:: epub_title - The title of the document. - It defaults to the :confval:`html_title` option - but can be set independently for epub creation. + The title of the document. It defaults to the :confval:`html_title` option + but can be set independently for epub creation. .. confval:: epub_author - The author of the document. - This is put in the Dublin Core metadata. - The default value is ``'unknown'``. + The author of the document. This is put in the Dublin Core metadata. The + default value is ``'unknown'``. .. confval:: epub_language - The language of the document. - This is put in the Dublin Core metadata. - The default is the :confval:`language` option or ``'en'`` if unset. + The language of the document. This is put in the Dublin Core metadata. The + default is the :confval:`language` option or ``'en'`` if unset. .. confval:: epub_publisher - The publisher of the document. - This is put in the Dublin Core metadata. - You may use any sensible string, e.g. the project homepage. - The default value is ``'unknown'``. + The publisher of the document. This is put in the Dublin Core metadata. You + may use any sensible string, e.g. the project homepage. The default value is + ``'unknown'``. .. confval:: epub_copyright - The copyright of the document. - It defaults to the :confval:`copyright` option - but can be set independently for epub creation. + The copyright of the document. It defaults to the :confval:`copyright` + option but can be set independently for epub creation. .. confval:: epub_identifier - An identifier for the document. - This is put in the Dublin Core metadata. - For published documents this is the ISBN number, but you can - also use an alternative scheme, e.g. the project homepage. - The default value is ``'unknown'``. + An identifier for the document. This is put in the Dublin Core metadata. + For published documents this is the ISBN number, but you can also use an + alternative scheme, e.g. the project homepage. The default value is + ``'unknown'``. .. confval:: epub_scheme - The publication scheme for the :confval:`epub_identifier`. - This is put in the Dublin Core metadata. - For published books the scheme is ``'ISBN'``. - If you use the project homepage, ``'URL'`` seems reasonable. + The publication scheme for the :confval:`epub_identifier`. This is put in + the Dublin Core metadata. For published books the scheme is ``'ISBN'``. If + you use the project homepage, ``'URL'`` seems reasonable. The default value + is ``'unknown'``. .. confval:: epub_uid - A unique identifier for the document. - This is put in the Dublin Core metadata. - You may use a random string. - The default value is ``'unknown'``. + A unique identifier for the document. This is put in the Dublin Core + metadata. You may use a random string. The default value is ``'unknown'``. .. confval:: epub_pre_files - Additional files that should be inserted before the text generated by - Sphinx. It is a list of tuples containing the file name and the title. - Example:: + Additional files that should be inserted before the text generated by + Sphinx. It is a list of tuples containing the file name and the title. + Example:: epub_pre_files = [ - ('index.html', 'Welcome'), + ('index.html', 'Welcome'), ] - The default value is ``[]``. + The default value is ``[]``. .. confval:: epub_post_files - Additional files that should be inserted after the text generated by - Sphinx. It is a list of tuples containing the file name and the title. - The default value is ``[]``. + Additional files that should be inserted after the text generated by Sphinx. + It is a list of tuples containing the file name and the title. The default + value is ``[]``. .. confval:: epub_exclude_files - A list of files that are generated/copied in the build directory - but should not be included in the epub file. - The default value is ``[]``. + A list of files that are generated/copied in the build directory but should + not be included in the epub file. The default value is ``[]``. .. _latex-options: @@ -810,3 +870,11 @@ These options influence LaTeX output. .. deprecated:: 0.5 Use the ``'pointsize'`` key in the :confval:`latex_elements` value. + + +.. rubric:: Footnotes + +.. [1] A note on available globbing syntax: you can use the standard shell + constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that + these all don't match slashes. A double star ``**`` can be used to match + any sequence of characters *including* slashes. diff --git a/doc/ext/appapi.rst b/doc/ext/appapi.rst index 0a3dae8fb..88bbe4853 100644 --- a/doc/ext/appapi.rst +++ b/doc/ext/appapi.rst @@ -56,9 +56,11 @@ the following public API: given as keyword arguments: the keyword must be one or more of ``'html'``, ``'latex'``, ``'text'``, the value a 2-tuple of ``(visit, depart)`` methods. ``depart`` can be ``None`` if the ``visit`` function raises - :exc:`docutils.nodes.SkipNode`. Example:: + :exc:`docutils.nodes.SkipNode`. Example: - class math(docutils.nodes.Element) + .. code-block:: python + + class math(docutils.nodes.Element): pass def visit_math_html(self, node): self.body.append(self.starttag(node, 'math')) @@ -98,7 +100,9 @@ the following public API: support directive classes otherwise). For example, the (already existing) :dir:`literalinclude` directive would be - added like this:: + added like this: + + .. code-block:: python from docutils.parsers.rst import directives add_directive('literalinclude', literalinclude_directive, diff --git a/doc/ext/autosummary.rst b/doc/ext/autosummary.rst index f270a67b6..20b688c1f 100644 --- a/doc/ext/autosummary.rst +++ b/doc/ext/autosummary.rst @@ -163,6 +163,8 @@ Autosummary uses the following template files: The following variables available in the templates: +.. currentmodule:: None + .. data:: name Name of the documented object, excluding the module and class parts. @@ -214,7 +216,7 @@ The following variables available in the templates: List containing names of "public" methods in the class. Only available for classes. -.. data:: methods +.. data:: attributes List containing names of "public" attributes in the class. Only available for classes. diff --git a/doc/ext/doctest.rst b/doc/ext/doctest.rst index 1ef2e8077..03d35e02a 100644 --- a/doc/ext/doctest.rst +++ b/doc/ext/doctest.rst @@ -87,10 +87,30 @@ names. * ``hide``, a flag option, hides the code block in other builders. By default it is shown as a highlighted code block. + .. note:: + + Code in a ``testcode`` block is always executed all at once, no matter how + many statements it contains. Therefore, output will *not* be generated + for bare expressions -- use ``print``. Example:: + + .. testcode:: + + 1+1 # this will give no output! + print 2+2 # this will give output + + .. testoutput:: + + 4 + + Also, please be aware that since the doctest module does not support + mixing regular output and an exception message in the same snippet, this + applies to testcode/testoutput as well. + .. directive:: .. testoutput:: [group] - The corresponding output for the last :dir:`testcode` block. + The corresponding output, or the exception message, for the last + :dir:`testcode` block. This directive supports two options: @@ -102,6 +122,10 @@ names. Example:: + .. testcode:: + + print 'Output text.' + .. testoutput:: :hide: :options: -ELLIPSIS, +NORMALIZE_WHITESPACE @@ -111,7 +135,7 @@ names. The following is an example for the usage of the directives. The test via :dir:`doctest` and the test via :dir:`testcode` and :dir:`testoutput` are -completely equivalent. :: +equivalent. :: The parrot module ================= diff --git a/doc/ext/extlinks.rst b/doc/ext/extlinks.rst index fb101ff3f..d4478c5b3 100644 --- a/doc/ext/extlinks.rst +++ b/doc/ext/extlinks.rst @@ -27,11 +27,13 @@ The extension adds one new config value: short alias names to a base URL and a *prefix*. For example, to create an alias for the above mentioned issues, you would add :: - extlinks = {'issue': ('http://bitbucket.org/birkenfeld/sphinx/issue/', + extlinks = {'issue': ('http://bitbucket.org/birkenfeld/sphinx/issue/%s', 'issue ')} Now, you can use the alias name as a new role, e.g. ``:issue:`123```. This then inserts a link to http://bitbucket.org/birkenfeld/sphinx/issue/123. + As you can see, the target given in the role is substituted in the base URL + in the place of ``%s``. The link *caption* depends on the second item in the tuple, the *prefix*: @@ -45,3 +47,8 @@ The extension adds one new config value: You can also use the usual "explicit title" syntax supported by other roles that generate links, i.e. ``:issue:`this issue <123>```. In this case, the *prefix* is not relevant. + +.. note:: + + Since links are generated from the role in the reading stage, they appear as + ordinary links to e.g. the ``linkcheck`` builder. diff --git a/doc/ext/graphviz.rst b/doc/ext/graphviz.rst index d007bf258..77eae7d8c 100644 --- a/doc/ext/graphviz.rst +++ b/doc/ext/graphviz.rst @@ -25,8 +25,9 @@ It adds these directives: "bar" -> "baz"; } - In HTML output, the code will be rendered to a PNG image. In LaTeX output, - the code will be rendered to an embeddable PDF file. + In HTML output, the code will be rendered to a PNG or SVG image (see + :confval:`graphviz_output_format`). In LaTeX output, the code will be + rendered to an embeddable PDF file. .. directive:: graph @@ -55,6 +56,12 @@ It adds these directives: "bar" -> "baz" -> "quux"; +.. versionadded:: 1.0 + All three directives support an ``alt`` option that determines the image's + alternate text for HTML output. If not given, the alternate text defaults to + the graphviz code. + + There are also these new config values: .. confval:: graphviz_dot @@ -75,3 +82,11 @@ There are also these new config values: Additional command-line arguments to give to dot, as a list. The default is an empty list. This is the right place to set global graph, node or edge attributes via dot's ``-G``, ``-N`` and ``-E`` options. + +.. confval:: graphviz_output_format + + The output format for Graphviz when building HTML files. This must be either + ``'png'`` or ``'svg'``; the default is ``'png'``. + + .. versionadded:: 1.0 + Previously, output always was PNG. diff --git a/doc/ext/math.rst b/doc/ext/math.rst index a214b41e3..c16025583 100644 --- a/doc/ext/math.rst +++ b/doc/ext/math.rst @@ -191,10 +191,10 @@ value: JSMath. There is no default. The path can be absolute or relative; if it is relative, it is relative to - the root of the built docs. + the ``_static`` directory of the built docs. For example, if you put JSMath into the static path of the Sphinx docs, this - value would be ``_static/jsMath/easy/load.js``. If you host more than one + value would be ``jsMath/easy/load.js``. If you host more than one Sphinx documentation set on one server, it is advisable to install jsMath in a shared location. diff --git a/doc/extensions.rst b/doc/extensions.rst index 0bc9b5b75..29c40ccdb 100644 --- a/doc/extensions.rst +++ b/doc/extensions.rst @@ -61,8 +61,8 @@ There are several extensions that are not (yet) maintained in the Sphinx distribution. The `Wiki at BitBucket`_ maintains a list of those. If you write an extension that you think others will find useful, please write -to the project mailing list (sphinx-dev@googlegroups.com) and we'll find the -proper way of including or hosting it for the public. +to the project mailing list (`join here `_) +and we'll find the proper way of including or hosting it for the public. .. _Wiki at BitBucket: http://www.bitbucket.org/birkenfeld/sphinx/wiki/Home diff --git a/doc/faq.rst b/doc/faq.rst index 46a714dd0..401e1c751 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -54,46 +54,42 @@ github pages Sphinx HTML output. -Epub ----- +.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py +.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py -The EpubBuilder is currently in an experimental stage. -It has only been tested with the Sphinx documentation itself. -If you want to create epubs, here are some notes: -* Split the text into several files. The longer the individual HTML files - are, the longer it takes the ebook reader to render them. - In extreme cases, the rendering can take up to one minute. +.. _epub-faq: -* Try to minimize the markup. This also pays in rendering time. +Epub info +--------- -* For some readers you can use embedded or external fonts - using the CSS ``@font-face`` directive. - This is *extremely* useful for code listings which are often cut - at the right margin. The default Courier font (or variant) is quite - wide and you can only display up to 60 characters on a line. - If you replace it with a narrower font, you can get more characters - on a line. You may even use - `fontforge `_ - and create narrow variants - of some free font. In my case I get up to 70 characters on a line. +The epub builder is currently in an experimental stage. It has only been tested +with the Sphinx documentation itself. If you want to create epubs, here are +some notes: + +* Split the text into several files. The longer the individual HTML files are, + the longer it takes the ebook reader to render them. In extreme cases, the + rendering can take up to one minute. + +* Try to minimize the markup. This also pays in rendering time. + +* For some readers you can use embedded or external fonts using the CSS + ``@font-face`` directive. This is *extremely* useful for code listings which + are often cut at the right margin. The default Courier font (or variant) is + quite wide and you can only display up to 60 characters on a line. If you + replace it with a narrower font, you can get more characters on a line. You + may even use `FontForge `_ and create + narrow variants of some free font. In my case I get up to 70 characters on a + line. You may have to experiment a little until you get reasonable results. -* Test the created epubs. You can use several alternatives. - The ones I am aware of are - Epubcheck - (`http://code.google.com/p/epubcheck/ - `_), - Calibre - (`http://calibre-ebook.com/ `_), - FBreader (`http://www.fbreader.org/ `_, - although it does not render the CSS), and - Bookworm (`http://bookworm.oreilly.com/ `_). - For bookworm you can download the source from - `http://code.google.com/p/threepress/ `_ - and run you own local server. +* Test the created epubs. You can use several alternatives. The ones I am aware + of are Epubcheck_, Calibre_, FBreader_ (although it does not render the CSS), + and Bookworm_. For bookworm you can download the source from + http://code.google.com/p/threepress/ and run your own local server. - -.. _api role: http://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py -.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py +.. _Epubcheck: http://code.google.com/p/epubcheck/ +.. _Calibre: http://calibre-ebook.com/ +.. _FBreader: http://www.fbreader.org/ +.. _Bookworm: http://bookworm.oreilly.com/ diff --git a/doc/markup/code.rst b/doc/markup/code.rst index 8c223297e..968711158 100644 --- a/doc/markup/code.rst +++ b/doc/markup/code.rst @@ -103,6 +103,9 @@ Includes is absolute (starting with ``/``), it is relative to the top source directory. + Tabs in the input are expanded if you give a ``tab-width`` option with the + desired tab width. + The directive also supports the ``linenos`` flag option to switch on line numbers, and a ``language`` option to select a language different from the current file's standard language. Example with options:: @@ -153,7 +156,7 @@ Includes The ``pyobject``, ``lines``, ``start-after`` and ``end-before`` options, as well as support for absolute filenames. .. versionadded:: 1.0 - The ``prepend`` and ``append`` options. + The ``prepend`` and ``append`` options, as well as ``tab-width``. .. rubric:: Footnotes diff --git a/doc/templating.rst b/doc/templating.rst index 61657547d..abcc478a0 100644 --- a/doc/templating.rst +++ b/doc/templating.rst @@ -74,8 +74,8 @@ render the block's content in the extended template -- unless you don't want that content to show up. -Working the the builtin templates ---------------------------------- +Working with the builtin templates +---------------------------------- The builtin **basic** theme supplies the templates that all builtin Sphinx themes are based on. It has the following elements you can override or use: @@ -139,23 +139,36 @@ The following blocks exist in the ``layout.html`` template: The logo location within the sidebar. Override this if you want to place some content at the top of the sidebar. +`footer` + The block for the footer div. If you want a custom footer or markup before + or after it, override this one. + +The following four blocks are *only* used for pages that do not have assigned a +list of custom sidebars in the :confval:`html_sidebars` config value. Their use +is deprecated in favor of separate sidebar templates, which can be included via +:confval:`html_sidebars`. + `sidebartoc` The table of contents within the sidebar. + .. deprecated:: 1.0 + `sidebarrel` The relation links (previous, next document) within the sidebar. + .. deprecated:: 1.0 + `sidebarsourcelink` The "Show source" link within the sidebar (normally only shown if this is enabled by :confval:`html_show_sourcelink`). + .. deprecated:: 1.0 + `sidebarsearch` The search box within the sidebar. Override this if you want to place some content at the bottom of the sidebar. -`footer` - The block for the footer div. If you want a custom footer or markup before - or after it, override this one. + .. deprecated:: 1.0 Configuration Variables diff --git a/doc/themes/agogo.png b/doc/themes/agogo.png index 7afc4a136..d29aa45cc 100644 Binary files a/doc/themes/agogo.png and b/doc/themes/agogo.png differ diff --git a/doc/themes/default.png b/doc/themes/default.png index be821b676..93d8526c8 100644 Binary files a/doc/themes/default.png and b/doc/themes/default.png differ diff --git a/doc/themes/fullsize/haiku.png b/doc/themes/fullsize/haiku.png new file mode 100644 index 000000000..1590da5d4 Binary files /dev/null and b/doc/themes/fullsize/haiku.png differ diff --git a/doc/themes/fullsize/nature.png b/doc/themes/fullsize/nature.png new file mode 100644 index 000000000..d42957e3b Binary files /dev/null and b/doc/themes/fullsize/nature.png differ diff --git a/doc/themes/haiku.png b/doc/themes/haiku.png new file mode 100644 index 000000000..a8ae85579 Binary files /dev/null and b/doc/themes/haiku.png differ diff --git a/doc/themes/nature.png b/doc/themes/nature.png new file mode 100644 index 000000000..3d4f587f7 Binary files /dev/null and b/doc/themes/nature.png differ diff --git a/doc/themes/scrolls.png b/doc/themes/scrolls.png index e4cb9aa9c..8073c10e0 100644 Binary files a/doc/themes/scrolls.png and b/doc/themes/scrolls.png differ diff --git a/doc/themes/sphinxdoc.png b/doc/themes/sphinxdoc.png index 2d2723a8c..f4b59ecdb 100644 Binary files a/doc/themes/sphinxdoc.png and b/doc/themes/sphinxdoc.png differ diff --git a/doc/themes/traditional.png b/doc/themes/traditional.png index 535213fe2..4ad2b5ce1 100644 Binary files a/doc/themes/traditional.png and b/doc/themes/traditional.png differ diff --git a/doc/theming.rst b/doc/theming.rst index 4f7cadd1d..6c650e4a6 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -65,9 +65,13 @@ Builtin themes | | | | *scrolls* | *agogo* | +--------------------+--------------------+ -| |traditional| | | +| |traditional| | |nature| | | | | -| *traditional* | | +| *traditional* | *nature* | ++--------------------+--------------------+ +| |haiku| | | +| | | +| *haiku* | | +--------------------+--------------------+ .. |default| image:: themes/default.png @@ -75,15 +79,17 @@ Builtin themes .. |scrolls| image:: themes/scrolls.png .. |agogo| image:: themes/agogo.png .. |traditional| image:: themes/traditional.png +.. |nature| image:: themes/nature.png +.. |haiku| image:: themes/haiku.png Sphinx comes with a selection of themes to choose from. These themes are: * **basic** -- This is a basically unstyled layout used as the base for the - *default* and *sphinxdoc* themes, and usable as the base for custom themes as - well. The HTML contains all important elements like sidebar and relation bar. - There is one option (which is inherited by *default* and *sphinxdoc*): + other themes, and usable as the base for custom themes as well. The HTML + contains all important elements like sidebar and relation bar. There is one + option (which is inherited by the other themes): - **nosidebar** (true or false): Don't include the sidebar. Defaults to false. @@ -128,7 +134,7 @@ These themes are: on the right side. There are currently no options beyond *nosidebar*. * **scrolls** -- A more lightweight theme, based on `the Jinja documentation - `_. The following color options are + `_. The following color options are available: - **headerbordercolor** @@ -157,12 +163,26 @@ These themes are: - **headerlinkcolor** (CSS color): Color for the backreference link in headings. +* **nature** -- A greenish theme. There are currently no options beyond + *nosidebar*. + +* **haiku** -- A theme without sidebar inspired by the `Haiku OS user guide + `_. The following + options are supported: + + - **full_logo** (true or false, default false): If this is true, the header + will only show the :confval:`html_logo`. Use this for large logos. If this + is false, the logo (if present) will be shown floating right, and the + documentation title will be put in the header. + - **textcolor**, **headingcolor**, **linkcolor**, **visitedlinkcolor**, + **hoverlinkcolor** (CSS colors): Colors for various body elements. + * **traditional** -- A theme resembling the old Python documentation. There are currently no options beyond *nosidebar*. -* **epub** -- A theme for the epub formatter. There are currently no - options. This theme tries to reduce visual space which is a sparse - resource on ebook readers. +* **epub** -- A theme for the epub builder. There are currently no options. + This theme tries to save visual space which is a sparse resource on ebook + readers. Creating themes diff --git a/sphinx-autogen.py b/sphinx-autogen.py index 494f4d85a..621784196 100755 --- a/sphinx-autogen.py +++ b/sphinx-autogen.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: 2007-2009 by Georg Brandl. + :copyright: 2007-2010 by Georg Brandl. :license: BSD. """ diff --git a/sphinx-build.py b/sphinx-build.py index c1998911d..30f3f6e6b 100755 --- a/sphinx-build.py +++ b/sphinx-build.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx-quickstart.py b/sphinx-quickstart.py index ea55f8341..99c0f0b37 100755 --- a/sphinx-quickstart.py +++ b/sphinx-quickstart.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/__init__.py b/sphinx/__init__.py index e6fb54b4d..31726e4b5 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -5,7 +5,7 @@ The Sphinx documentation toolchain. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index b8c9a3544..83ba8a004 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -5,7 +5,7 @@ Additional docutils nodes. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/application.py b/sphinx/application.py index 0c26b131d..ad3a08330 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -7,7 +7,7 @@ Gracefully adapted from the TextPress system by Armin. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index b35d0fd16..159d1f035 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -5,7 +5,7 @@ Builder superclass for all builders. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -16,7 +16,7 @@ from os import path from docutils import nodes from sphinx import package_dir, locale -from sphinx.util import SEP, relative_uri +from sphinx.util import SEP, ENOENT, relative_uri from sphinx.environment import BuildEnvironment from sphinx.util.console import bold, purple, darkgreen, term_width_line @@ -186,7 +186,7 @@ class Builder(object): if self.translator is None: self.translator = trans else: - self.translator._catalog.update(trans.catalog) + self.translator._catalog.update(trans._catalog) except Exception: # Language couldn't be found in the specified path pass @@ -210,7 +210,7 @@ class Builder(object): path.join(self.doctreedir, ENV_PICKLE_FILENAME)) self.info('done') except Exception, err: - if type(err) is IOError and err.errno == 2: + if type(err) is IOError and err.errno == ENOENT: self.info('not found') else: self.info('failed: %s' % err) diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index c1ea14a88..3bc51d43d 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -5,7 +5,7 @@ Changelog builder. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -139,11 +139,10 @@ class ChangesBuilder(Builder): self.theme.get_options({}).iteritems()) copy_static_entry(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'), - path.join(self.outdir, 'default.css_t'), - self, themectx) + self.outdir, self, themectx) copy_static_entry(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'), - path.join(self.outdir, 'basic.css'), self) + self.outdir, self) def hl(self, text, version): text = escape(text) diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py index ba117e622..d7acf764e 100644 --- a/sphinx/builders/devhelp.py +++ b/sphinx/builders/devhelp.py @@ -7,7 +7,7 @@ .. _Devhelp: http://live.gnome.org/devhelp - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index 07f13ffeb..e5157d2dd 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -6,25 +6,22 @@ Build epub files. Originally derived from qthelp.py. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os -import re import codecs from os import path import zipfile from docutils import nodes -from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder -# (Fragment) templates from which the metainfo files -# content.opf, toc.ncx, mimetype, and META-INF/container.xml -# are created. +# (Fragment) templates from which the metainfo files content.opf, toc.ncx, +# mimetype, and META-INF/container.xml are created. _mimetype_template = 'application/epub+zip' # no EOL! @@ -118,9 +115,10 @@ _media_types = { class EpubBuilder(StandaloneHTMLBuilder): """Builder that outputs epub files. - It creates the metainfo files - container.opf, toc.ncx, mimetype, and META-INF/container.xml. - Afterwards, all necessary files are zipped to an epub file. + + It creates the metainfo files container.opf, toc.ncx, mimetype, and + META-INF/container.xml. Afterwards, all necessary files are zipped to an + epub file. """ name = 'epub' @@ -136,18 +134,20 @@ class EpubBuilder(StandaloneHTMLBuilder): def init(self): StandaloneHTMLBuilder.init(self) - # the output files for HTML help must be .html only + # the output files for epub must be .html only self.out_suffix = '.html' self.playorder = 0 + def get_theme_config(self): + return self.config.epub_theme, {} # generic support functions def make_id(self, name): - """Replace all characters not allowed for (X)HTML ids""" + """Replace all characters not allowed for (X)HTML ids.""" return name.replace('/', '_') def esc(self, name): - """Replace all characters not allowed in text an attribute values""" + """Replace all characters not allowed in text an attribute values.""" # Like cgi.escape, but also replace apostrophe name = name.replace('&', '&') name = name.replace('<', '<') @@ -157,17 +157,22 @@ class EpubBuilder(StandaloneHTMLBuilder): return name def collapse_text(self, doctree, result): - """Remove all HTML markup and return only the text nodes""" + """Remove all HTML markup and return only the text nodes.""" for c in doctree.children: if isinstance(c, nodes.Text): - result.append(c.data) + try: + # docutils 0.4 and 0.5: Text is a UserString subclass + result.append(c.data) + except AttributeError: + # docutils 0.6: Text is a unicode subclass + result.append(c) else: result = self.collapse_text(c, result) return result def get_refnodes(self, doctree, result): - """Collect section titles, their depth in the toc and the refuri""" - # XXX: is there a betterr way than checking the attribute + """Collect section titles, their depth in the toc and the refuri.""" + # XXX: is there a better way than checking the attribute # toctree-l[1-6] on the parent node? if isinstance(doctree, nodes.reference): classes = doctree.parent.attributes['classes'] @@ -187,7 +192,8 @@ class EpubBuilder(StandaloneHTMLBuilder): def get_toc(self): """Get the total table of contents, containg the master_doc - and pre and post files not managed by sphinx""" + and pre and post files not managed by sphinx. + """ doctree = self.env.get_and_resolve_doctree(self.config.master_doc, self, prune_toctrees=False) self.refnodes = self.get_refnodes(doctree, []) @@ -215,7 +221,7 @@ class EpubBuilder(StandaloneHTMLBuilder): # Finish by building the epub file def handle_finish(self): - """Create the metainfo files and finally the epub""" + """Create the metainfo files and finally the epub.""" self.get_toc() self.build_mimetype(self.outdir, 'mimetype') self.build_container(self.outdir, 'META-INF/container.xml') @@ -224,7 +230,7 @@ class EpubBuilder(StandaloneHTMLBuilder): self.build_epub(self.outdir, self.config.epub_basename + '.epub') def build_mimetype(self, outdir, outname): - """Write the metainfo file mimetype""" + """Write the metainfo file mimetype.""" self.info('writing %s file...' % outname) f = codecs.open(path.join(outdir, outname), 'w', 'utf-8') try: @@ -233,7 +239,7 @@ class EpubBuilder(StandaloneHTMLBuilder): f.close() def build_container(self, outdir, outname): - """Write the metainfo file META-INF/cointainer.xml""" + """Write the metainfo file META-INF/cointainer.xml.""" self.info('writing %s file...' % outname) fn = path.join(outdir, outname) try: @@ -249,7 +255,8 @@ class EpubBuilder(StandaloneHTMLBuilder): def content_metadata(self, files, spine): """Create a dictionary with all metadata for the content.opf - file properly escaped""" + file properly escaped. + """ metadata = {} metadata['title'] = self.esc(self.config.epub_title) metadata['author'] = self.esc(self.config.epub_author) @@ -264,9 +271,9 @@ class EpubBuilder(StandaloneHTMLBuilder): return metadata def build_content(self, outdir, outname): - """Write the metainfo file content.opf - It contains bibliographic data, a file list and - the spine (the reading order).""" + """Write the metainfo file content.opf It contains bibliographic data, + a file list and the spine (the reading order). + """ self.info('writing %s file...' % outname) # files @@ -318,7 +325,7 @@ class EpubBuilder(StandaloneHTMLBuilder): f.close() def new_navpoint(self, node, level, incr=True): - """Create a new entry in the toc from the node at given level""" + """Create a new entry in the toc from the node at given level.""" # XXX Modifies the node if incr: self.playorder += 1 @@ -328,16 +335,19 @@ class EpubBuilder(StandaloneHTMLBuilder): return _navpoint_template % node def insert_subnav(self, node, subnav): - """Insert nested navpoints for given node - The node and subnav are already rendered to text""" + """Insert nested navpoints for given node. + The node and subnav are already rendered to text. + """ nlist = node.split('\n') nlist.insert(-1, subnav) return '\n'.join(nlist) def build_navpoints(self, nodes): - """Create the toc navigation structure + """Create the toc navigation structure. + Subelements of a node are nested inside the navpoint. - For nested nodes the parent node is reinserted in the subnav.""" + For nested nodes the parent node is reinserted in the subnav. + """ navstack = [] navlist = [] level = 1 @@ -373,7 +383,8 @@ class EpubBuilder(StandaloneHTMLBuilder): def toc_metadata(self, level, navpoints): """Create a dictionary with all metadata for the toc.ncx - file properly escaped""" + file properly escaped. + """ metadata = {} metadata['uid'] = self.config.epub_uid metadata['title'] = self.config.epub_title @@ -382,7 +393,7 @@ class EpubBuilder(StandaloneHTMLBuilder): return metadata def build_toc(self, outdir, outname): - """Write the metainfo file toc.ncx""" + """Write the metainfo file toc.ncx.""" self.info('writing %s file...' % outname) navpoints = self.build_navpoints(self.refnodes) @@ -394,9 +405,11 @@ class EpubBuilder(StandaloneHTMLBuilder): f.close() def build_epub(self, outdir, outname): - """Write the epub file + """Write the epub file. + It is a zip file with the mimetype file stored uncompressed - as the first entry.""" + as the first entry. + """ self.info('writing %s file...' % outname) projectfiles = ['META-INF/container.xml', 'content.opf', 'toc.ncx'] \ + self.files @@ -407,4 +420,3 @@ class EpubBuilder(StandaloneHTMLBuilder): for file in projectfiles: epub.write(path.join(outdir, file), file, zipfile.ZIP_DEFLATED) epub.close() - diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 54327fa1e..cdabcd65c 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -5,7 +5,7 @@ Several HTML builders. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -22,14 +22,14 @@ except ImportError: from docutils import nodes from docutils.io import DocTreeInput, StringOutput -from docutils.core import Publisher, publish_parts +from docutils.core import Publisher from docutils.utils import new_document from docutils.frontend import OptionParser from docutils.readers.doctree import Reader as DoctreeReader from sphinx import package_dir, __version__ -from sphinx.util import SEP, os_path, relative_uri, ensuredir, \ - movefile, ustrftime, copy_static_entry, copyfile +from sphinx.util import SEP, os_path, relative_uri, ensuredir, patmatch, \ + movefile, ustrftime, copy_static_entry, copyfile, compile_matchers, any from sphinx.errors import SphinxError from sphinx.search import js_index from sphinx.theming import Theme @@ -74,6 +74,9 @@ class StandaloneHTMLBuilder(Builder): # Dito for this one. css_files = [] + default_sidebars = ['localtoc.html', 'relations.html', + 'sourcelink.html', 'searchbox.html'] + # cached publisher object for snippets _publisher = None @@ -101,9 +104,14 @@ class StandaloneHTMLBuilder(Builder): if path.isfile(jsfile): self.script_files.append('_static/translations.js') + def get_theme_config(self): + return self.config.html_theme, self.config.html_theme_options + def init_templates(self): Theme.init_themes(self) - self.theme = Theme(self.config.html_theme) + themename, themeoptions = self.get_theme_config() + self.theme = Theme(themename) + self.theme_options = themeoptions.copy() self.create_template_bridge() self.templates.init(self, self.theme) @@ -167,8 +175,7 @@ class StandaloneHTMLBuilder(Builder): if docname not in self.env.all_docs: yield docname continue - targetname = self.env.doc2path(docname, self.outdir, - self.out_suffix) + targetname = self.get_outfilename(docname) try: targetmtime = path.getmtime(targetname) except Exception: @@ -279,8 +286,7 @@ class StandaloneHTMLBuilder(Builder): if self.theme: self.globalcontext.update( ('theme_' + key, val) for (key, val) in - self.theme.get_options( - self.config.html_theme_options).iteritems()) + self.theme.get_options(self.theme_options).iteritems()) self.globalcontext.update(self.config.html_context) def get_doc_context(self, docname, body, metatags): @@ -435,6 +441,10 @@ class StandaloneHTMLBuilder(Builder): else: stripped = '' + # we stripped the whole module name + if not mn: + continue + if fl != mn[0].lower() and mn[0] != '_': # heading letter = mn[0].upper() @@ -549,30 +559,39 @@ class StandaloneHTMLBuilder(Builder): if path.isfile(jsfile): copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js')) - # then, copy over all user-supplied static files + # then, copy over theme-supplied static files if self.theme: - staticdirnames = [path.join(themepath, 'static') - for themepath in self.theme.get_dirchain()[::-1]] - else: - staticdirnames = [] - staticdirnames += [path.join(self.confdir, spath) - for spath in self.config.html_static_path] - for staticdirname in staticdirnames: - if not path.isdir(staticdirname): - self.warn('static directory %r does not exist' % staticdirname) + themeentries = [path.join(themepath, 'static') + for themepath in self.theme.get_dirchain()[::-1]] + for entry in themeentries: + copy_static_entry(entry, path.join(self.outdir, '_static'), + self, self.globalcontext) + # then, copy over all user-supplied static files + staticentries = [path.join(self.confdir, spath) + for spath in self.config.html_static_path] + matchers = compile_matchers( + self.config.exclude_patterns + + ['**/' + d for d in self.config.exclude_dirnames] + ) + for entry in staticentries: + if not path.exists(entry): + self.warn('html_static_path entry %r does not exist' % entry) continue - for filename in os.listdir(staticdirname): - if filename.startswith('.'): - continue - fullname = path.join(staticdirname, filename) - targetname = path.join(self.outdir, '_static', filename) - copy_static_entry(fullname, targetname, self, - self.globalcontext) - # last, copy logo file (handled differently) + copy_static_entry(entry, path.join(self.outdir, '_static'), self, + self.globalcontext, exclude_matchers=matchers) + # copy logo and favicon files if not already in static path if self.config.html_logo: logobase = path.basename(self.config.html_logo) - copyfile(path.join(self.confdir, self.config.html_logo), - path.join(self.outdir, '_static', logobase)) + logotarget = path.join(self.outdir, '_static', logobase) + if not path.isfile(logotarget): + copyfile(path.join(self.confdir, self.config.html_logo), + logotarget) + if self.config.html_favicon: + iconbase = path.basename(self.config.html_favicon) + icontarget = path.join(self.outdir, '_static', iconbase) + if not path.isfile(icontarget): + copyfile(path.join(self.confdir, self.config.html_favicon), + icontarget) # write build info file fp = open(path.join(self.outdir, '.buildinfo'), 'w') @@ -646,6 +665,36 @@ class StandaloneHTMLBuilder(Builder): def get_outfilename(self, pagename): return path.join(self.outdir, os_path(pagename) + self.out_suffix) + def add_sidebars(self, pagename, ctx): + def has_wildcard(pattern): + return any(char in pattern for char in '*?[') + sidebars = None + matched = None + customsidebar = None + for pattern, patsidebars in self.config.html_sidebars.iteritems(): + if patmatch(pagename, pattern): + if matched: + if has_wildcard(pattern): + # warn if both patterns contain wildcards + if has_wildcard(matched): + self.warn('page %s matches two patterns in ' + 'html_sidebars: %r and %r' % + (pagename, matched, pattern)) + # else the already matched pattern is more specific + # than the present one, because it contains no wildcard + continue + matched = pattern + sidebars = patsidebars + if sidebars is None: + # keep defaults + pass + elif isinstance(sidebars, basestring): + # 0.x compatible mode: insert custom sidebar before searchbox + customsidebar = sidebars + sidebars = None + ctx['sidebars'] = sidebars + ctx['customsidebar'] = customsidebar + # --------- these are overwritten by the serialization builder def get_target_uri(self, docname, typ=None): @@ -661,12 +710,13 @@ class StandaloneHTMLBuilder(Builder): baseuri=self.get_target_uri(pagename)): if not resource: otheruri = self.get_target_uri(otheruri) - return relative_uri(baseuri, otheruri) + uri = relative_uri(baseuri, otheruri) or '#' + return uri ctx['pathto'] = pathto ctx['hasdoc'] = lambda name: name in self.env.all_docs - ctx['customsidebar'] = self.config.html_sidebars.get(pagename) ctx['encoding'] = encoding = self.config.html_output_encoding ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw) + self.add_sidebars(pagename, ctx) ctx.update(addctx) self.app.emit('html-page-context', pagename, templatename, @@ -781,9 +831,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder): def handle_page(self, pagename, ctx, templatename='page.html', outfilename=None, event_arg=None): ctx['current_page_name'] = pagename - sidebarfile = self.config.html_sidebars.get(pagename) - if sidebarfile: - ctx['customsidebar'] = sidebarfile + self.add_sidebars(pagename, ctx) if not outfilename: outfilename = path.join(self.outdir, diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py index 58eaeca96..3ef98f346 100644 --- a/sphinx/builders/htmlhelp.py +++ b/sphinx/builders/htmlhelp.py @@ -6,7 +6,7 @@ Build HTML help support files. Parts adapted from Python's Doc/tools/prechm.py. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py index 95b343a4c..0db30d553 100644 --- a/sphinx/builders/latex.py +++ b/sphinx/builders/latex.py @@ -5,7 +5,7 @@ LaTeX builder. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index f3962965c..3f9f16d96 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -5,7 +5,7 @@ The CheckExternalLinksBuilder class. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -70,6 +70,8 @@ class CheckExternalLinksBuilder(Builder): lineno = node.line if uri[0:5] == 'http:' or uri[0:6] == 'https:': + if lineno: + self.info('(line %3d) ' % lineno, nonl=1) self.info(uri, nonl=1) if uri in self.broken: diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py index df01aaa54..547bf2fdd 100644 --- a/sphinx/builders/qthelp.py +++ b/sphinx/builders/qthelp.py @@ -5,7 +5,7 @@ Build input files for the Qt collection generator. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py index 8651778cb..d8451371d 100644 --- a/sphinx/builders/text.py +++ b/sphinx/builders/text.py @@ -5,7 +5,7 @@ Plain-text Sphinx builder. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index 898678b72..8a069b325 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -5,7 +5,7 @@ sphinx-build command-line handling. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -96,7 +96,6 @@ def main(argv): error = sys.stderr warnfile = None confoverrides = {} - htmlcontext = {} tags = [] doctreedir = path.join(outdir, '.doctrees') for opt, val in opts: @@ -142,7 +141,7 @@ def main(argv): val = int(val) except ValueError: pass - htmlcontext[key] = val + confoverrides['html_context.%s' % key] = val elif opt == '-N': nocolor() elif opt == '-E': @@ -158,7 +157,6 @@ def main(argv): warnfile = val elif opt == '-P': use_pdb = True - confoverrides['html_context'] = htmlcontext if warning and warnfile: warnfp = open(warnfile, 'w') diff --git a/sphinx/config.py b/sphinx/config.py index 5050a7796..5fe3f63f4 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -5,7 +5,7 @@ Build configuration file handling. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -38,8 +38,9 @@ class Config(object): master_doc = ('contents', 'env'), source_suffix = ('.rst', 'env'), source_encoding = ('utf-8-sig', 'env'), + exclude_patterns = ([], 'env'), + # the next three are all deprecated now unused_docs = ([], 'env'), - exclude_dirs = ([], 'env'), exclude_trees = ([], 'env'), exclude_dirnames = ([], 'env'), default_role = (None, 'env'), @@ -97,6 +98,21 @@ class Config(object): # Devhelp only options devhelp_basename = (lambda self: make_filename(self.project), None), + # Epub options + epub_basename = (lambda self: make_filename(self.project), None), + epub_theme = ('epub', 'html'), + epub_title = (lambda self: self.html_title, 'html'), + epub_author = ('unknown', 'html'), + epub_language = (lambda self: self.language or 'en', 'html'), + epub_publisher = ('unknown', 'html'), + epub_copyright = (lambda self: self.copyright, 'html'), + epub_identifier = ('unknown', 'html'), + epub_scheme = ('unknown', 'html'), + epub_uid = ('unknown', 'env'), + epub_pre_files = ([], 'env'), + epub_post_files = ([], 'env'), + epub_exclude_files = ([], 'env'), + # LaTeX options latex_documents = ([], None), latex_logo = (None, None), @@ -112,20 +128,6 @@ class Config(object): latex_docclass = ({}, None), # now deprecated - use latex_elements latex_preamble = ('', None), - - # Epub options - epub_basename = (lambda self: make_filename(self.project), None), - epub_title = (lambda self: self.html_title, 'html'), - epub_author = ('unknown', 'html'), - epub_language = (lambda self: self.language or 'en', 'html'), - epub_publisher = ('unknown', 'html'), - epub_copyright = (lambda self: self.copyright, 'html'), - epub_identifier = ('unknown', 'html'), - epub_scheme = ('unknown', 'html'), - epub_uid = ('unknown', 'env'), - epub_pre_files = ([], 'env'), - epub_post_files = ([], 'env'), - epub_exclude_files = ([], 'env'), ) def __init__(self, dirname, filename, overrides, tags): diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 2de29010c..00bb55ecc 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -5,7 +5,7 @@ Handlers for additional ReST directives. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index 4f44c3335..6535bdf56 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -3,7 +3,7 @@ sphinx.directives.code ~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -81,6 +81,7 @@ class LiteralInclude(Directive): final_argument_whitespace = False option_spec = { 'linenos': directives.flag, + 'tab-width': int, 'language': directives.unchanged_required, 'encoding': directives.encoding, 'pyobject': directives.unchanged_required, @@ -174,6 +175,8 @@ class LiteralInclude(Directive): lines.append(append + '\n') text = ''.join(lines) + if self.options.get('tab-width'): + text = text.expandtabs(self.options['tab-width']) retnode = nodes.literal_block(text, text, source=fn) retnode.line = 1 if self.options.get('language', ''): diff --git a/sphinx/directives/desc.py b/sphinx/directives/desc.py index db261a878..5a8ed7914 100644 --- a/sphinx/directives/desc.py +++ b/sphinx/directives/desc.py @@ -3,7 +3,7 @@ sphinx.directives.desc ~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 50db49ced..d746ea625 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -3,7 +3,7 @@ sphinx.directives.other ~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -100,7 +100,9 @@ class TocTree(Directive): subnode['hidden'] = 'hidden' in self.options subnode['numbered'] = 'numbered' in self.options subnode['titlesonly'] = 'titlesonly' in self.options - ret.append(subnode) + wrappernode = nodes.compound(classes=['toctree-wrapper']) + wrappernode.append(subnode) + ret.append(wrappernode) return ret @@ -238,7 +240,7 @@ class Index(Directive): option_spec = {} indextypes = [ - 'single', 'pair', 'triple', + 'single', 'pair', 'double', 'triple', ] def run(self): @@ -262,6 +264,8 @@ class Index(Directive): for type in self.indextypes: if entry.startswith(type+':'): value = entry[len(type)+1:].strip() + if type == 'double': + type = 'pair' ne.append((type, value, targetid, value)) break # shorthand notation for single entries diff --git a/sphinx/environment.py b/sphinx/environment.py index 426d78c25..1b89b8c06 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -5,7 +5,7 @@ Global creation environment. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -35,7 +35,7 @@ from docutils.transforms.parts import ContentsFilter from sphinx import addnodes from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \ - docname_join, FilenameUniqDict, url_re + docname_join, FilenameUniqDict, url_re, clean_astext, compile_matchers from sphinx.errors import SphinxError from sphinx.directives import additional_xref_types @@ -51,7 +51,7 @@ default_settings = { # This is increased every time an environment attribute is added # or changed to properly invalidate pickle files. -ENV_VERSION = 30 +ENV_VERSION = 31 default_substitutions = set([ @@ -393,14 +393,15 @@ class BuildEnvironment: """ Find all source files in the source dir and put them in self.found_docs. """ - exclude_dirs = [d.replace(SEP, path.sep) for d in config.exclude_dirs] - exclude_trees = [d.replace(SEP, path.sep) for d in config.exclude_trees] + matchers = compile_matchers( + config.exclude_patterns[:] + + config.exclude_trees + + [d + config.source_suffix for d in config.unused_docs] + + ['**/' + d for d in config.exclude_dirnames] + + ['**/_sources'] + ) self.found_docs = set(get_matching_docs( - self.srcdir, config.source_suffix, - exclude_docs=set(config.unused_docs), - exclude_dirs=exclude_dirs, - exclude_trees=exclude_trees, - exclude_dirnames=['_sources'] + config.exclude_dirnames)) + self.srcdir, config.source_suffix, exclude_matchers=matchers)) def get_outdated_files(self, config_changed): """ @@ -821,11 +822,11 @@ class BuildEnvironment: node.line) self.anonlabels[name] = docname, labelid if node.tagname == 'section': - sectname = node[0].astext() # node[0] == title node + sectname = clean_astext(node[0]) # node[0] == title node elif node.tagname == 'figure': for n in node: if n.tagname == 'caption': - sectname = n.astext() + sectname = clean_astext(n) break else: continue @@ -931,7 +932,7 @@ class BuildEnvironment: """Return a TOC nodetree -- for use on the same page only!""" toc = self.tocs[docname].deepcopy() for node in toc.traverse(nodes.reference): - node['refuri'] = node['anchorname'] + node['refuri'] = node['anchorname'] or '#' return toc def get_toctree_for(self, docname, builder, collapse): @@ -1075,7 +1076,7 @@ class BuildEnvironment: # toctree originates ref = toctreenode['parent'] if not title: - title = self.titles[ref].astext() + title = clean_astext(self.titles[ref]) reference = nodes.reference('', '', refuri=ref, anchorname='', @@ -1180,7 +1181,7 @@ class BuildEnvironment: docname, labelid = self.anonlabels.get(target, ('','')) sectname = node.astext() if not docname: - self.warn(fromdocname, 'undefined label: %s' % + self.warn(node['refdoc'], 'undefined label: %s' % target, node.line) else: # reference to the named label; the final node will @@ -1189,7 +1190,7 @@ class BuildEnvironment: ('','','')) if not docname: self.warn( - fromdocname, + node['refdoc'], 'undefined label: %s' % target + ' -- if you ' 'don\'t give a link caption the label must ' 'precede a section header.', node.line) @@ -1215,17 +1216,17 @@ class BuildEnvironment: elif typ == 'doc': # directly reference to document by source name; # can be absolute or relative - docname = docname_join(fromdocname, target) + docname = docname_join(node['refdoc'], target) if docname not in self.all_docs: - self.warn(fromdocname, 'unknown document: %s' % docname, - node.line) + self.warn(node['refdoc'], + 'unknown document: %s' % docname, node.line) newnode = contnode else: if node['refcaption']: # reference with explicit title caption = node.astext() else: - caption = self.titles[docname].astext() + caption = clean_astext(self.titles[docname]) innernode = nodes.emphasis(caption, caption) newnode = nodes.reference('', '') newnode['refuri'] = builder.get_relative_uri( @@ -1235,7 +1236,8 @@ class BuildEnvironment: # keywords are referenced by named labels docname, labelid, _ = self.labels.get(target, ('','','')) if not docname: - #self.warn(fromdocname, 'unknown keyword: %s' % target) + #self.warn(node['refdoc'], + # 'unknown keyword: %s' % target) newnode = contnode else: newnode = nodes.reference('', '') @@ -1264,11 +1266,11 @@ class BuildEnvironment: ('', '')) if not docname: if typ == 'term': - self.warn(fromdocname, + self.warn(node['refdoc'], 'term not in glossary: %s' % target, node.line) elif typ == 'citation': - self.warn(fromdocname, + self.warn(node['refdoc'], 'citation not found: %s' % target, node.line) newnode = contnode diff --git a/sphinx/errors.py b/sphinx/errors.py index f39ee5823..684101c68 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -6,7 +6,7 @@ Contains SphinxError and a few subclasses (in an extra module to avoid circular import problems). - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/__init__.py b/sphinx/ext/__init__.py index c6e239518..31b6f2aef 100644 --- a/sphinx/ext/__init__.py +++ b/sphinx/ext/__init__.py @@ -5,6 +5,6 @@ Contains Sphinx features not activated by default. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index b5c59ec53..cf38dbb8a 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -7,7 +7,7 @@ the doctree, thus avoiding duplication between docstrings and documentation for those who like elaborate docstrings. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -72,6 +72,7 @@ class Options(dict): ALL = object() +INSTANCEATTR = object() def members_option(arg): """Used to convert the :members: option to auto directives.""" @@ -474,19 +475,30 @@ class Documenter(object): self.directive.warn('missing attribute %s in object %s' % (mname, self.fullname)) return False, ret - elif self.options.inherited_members: + + if self.options.inherited_members: # safe_getmembers() uses dir() which pulls in members from all # base classes - return False, safe_getmembers(self.object) + members = safe_getmembers(self.object) else: # __dict__ contains only the members directly defined in # the class (but get them via getattr anyway, to e.g. get # unbound method objects instead of function objects); # using keys() because apparently there are objects for which # __dict__ changes while getting attributes - return False, sorted([ - (mname, self.get_attr(self.object, mname, None)) - for mname in self.get_attr(self.object, '__dict__').keys()]) + obj_dict = self.get_attr(self.object, '__dict__') + members = [(mname, self.get_attr(self.object, mname, None)) + for mname in obj_dict.keys()] + membernames = set(m[0] for m in members) + # add instance attributes from the analyzer + if self.analyzer: + attr_docs = self.analyzer.find_attr_docs() + namespace = '.'.join(self.objpath) + for item in attr_docs.iteritems(): + if item[0][0] == namespace: + if item[0][1] not in membernames: + members.append((item[0][1], INSTANCEATTR)) + return False, sorted(members) def filter_members(self, members, want_all): """ @@ -1036,6 +1048,34 @@ class AttributeDocumenter(ClassLevelDocumenter): pass +class InstanceAttributeDocumenter(AttributeDocumenter): + """ + Specialized Documenter subclass for attributes that cannot be imported + because they are instance attributes (e.g. assigned in __init__). + """ + objtype = 'instanceattribute' + directivetype = 'attribute' + member_order = 60 + + # must be higher than AttributeDocumenter + priority = 11 + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + """This documents only INSTANCEATTR members.""" + return isattr and (member is INSTANCEATTR) + + def import_object(self): + """Never import anything.""" + # disguise as an attribute + self.objtype = 'attribute' + return True + + def add_content(self, more_content, no_docstring=False): + """Never try to get a docstring from the object.""" + AttributeDocumenter.add_content(self, more_content, no_docstring=True) + + class AutoDirective(Directive): """ The AutoDirective class is used for all autodoc directives. It dispatches @@ -1132,6 +1172,7 @@ def setup(app): app.add_autodocumenter(FunctionDocumenter) app.add_autodocumenter(MethodDocumenter) app.add_autodocumenter(AttributeDocumenter) + app.add_autodocumenter(InstanceAttributeDocumenter) app.add_config_value('autoclass_content', 'class', True) app.add_config_value('autodoc_member_order', 'alphabetic', True) diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 3c9ff466b..da41acb2e 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -49,7 +49,7 @@ resolved to a Python object, and otherwise it becomes simple emphasis. This can be used as the default role to make links 'smart'. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 8c0e10111..83c61b8b3 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -14,7 +14,7 @@ generate: sphinx-autogen source/*.rst source/generated - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 964e58eec..0d2487f08 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -6,7 +6,7 @@ Check Python modules and C API for coverage. Mostly written by Josip Dzolonga for the Google Highly Open Participation contest. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 9bf086f74..a424bdfec 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -6,7 +6,7 @@ Mimic doctest by automatically executing code snippets and checking their results. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -355,7 +355,14 @@ Doctest summary options = code[1] and code[1].options or {} # disable processing as it is not needed options[doctest.DONT_ACCEPT_BLANKLINE] = True + # find out if we're testing an exception + m = parser._EXCEPTION_RE.match(output) + if m: + exc_msg = m.group('msg') + else: + exc_msg = None example = doctest.Example(code[0].code, output, + exc_msg=exc_msg, lineno=code[0].lineno, options=options) test = doctest.DocTest([example], {}, group.name, diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py index 8e68681bc..423b6447e 100644 --- a/sphinx/ext/extlinks.py +++ b/sphinx/ext/extlinks.py @@ -8,10 +8,10 @@ This adds a new config value called ``extlinks`` that is created like this:: - extlinks = {'exmpl': ('http://example.com/', prefix), ...} + extlinks = {'exmpl': ('http://example.com/%s.html', prefix), ...} Now you can use e.g. :exmpl:`foo` in your documents. This will create a - link to ``http://example.com/foo``. The link caption depends on the + link to ``http://example.com/foo.html``. The link caption depends on the *prefix* value given: - If it is ``None``, the caption will be the full URL. @@ -20,7 +20,7 @@ You can also give an explicit caption, e.g. :exmpl:`Foo `. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -32,15 +32,20 @@ from sphinx.util import split_explicit_title def make_link_role(base_url, prefix): def role(typ, rawtext, text, lineno, inliner, options={}, content=[]): text = utils.unescape(text) - has_explicit_title, title, url = split_explicit_title(text) - # NOTE: not using urlparse.urljoin() here, to allow something like - # base_url = 'bugs.python.org/issue' and url = '1024' - full_url = base_url + url + has_explicit_title, title, part = split_explicit_title(text) + try: + full_url = base_url % part + except (TypeError, ValueError): + env = inliner.document.settings.env + env.warn(env.docname, 'unable to expand %s extlink with base ' + 'URL %r, please make sure the base contains \'%%s\' ' + 'exactly once' % (typ, base_url)) + full_url = base_url + part if not has_explicit_title: if prefix is None: title = full_url else: - title = prefix + url + title = prefix + part pnode = nodes.reference(title, title, refuri=full_url) return [pnode], [] return role diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 449d9524a..2f78d0887 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -6,13 +6,14 @@ Allow graphviz-formatted graphs to be included in Sphinx-generated documents inline. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re import posixpath from os import path +from math import ceil from subprocess import Popen, PIPE try: from hashlib import sha1 as sha @@ -20,13 +21,15 @@ except ImportError: from sha import sha from docutils import nodes +from docutils.parsers.rst import directives from sphinx.errors import SphinxError -from sphinx.util import ensuredir +from sphinx.util import ensuredir, ENOENT from sphinx.util.compat import Directive mapname_re = re.compile(r'\n' % \ + (svgref, imgcss, style) + + +def render_dot_html(self, node, code, options, prefix='graphviz', + imgcls=None, alt=None): + format = self.builder.config.graphviz_output_format + try: + if format not in ('png', 'svg'): + raise GraphvizError("graphviz_output_format must be one of 'png', " + "'svg', but is %r" % format) + fname, outfn = render_dot(self, code, options, format, prefix) except GraphvizError, exc: self.builder.warn('dot code %r: ' % code + str(exc)) raise nodes.SkipNode @@ -139,23 +186,29 @@ def render_dot_html(self, node, code, options, prefix='graphviz', imgcls=None): if fname is None: self.body.append(self.encode(code)) else: - mapfile = open(outfn + '.map', 'rb') - try: - imgmap = mapfile.readlines() - finally: - mapfile.close() - imgcss = imgcls and 'class="%s"' % imgcls or '' - if len(imgmap) == 2: - # nothing in image map (the lines are and ) - self.body.append('%s\n' % - (fname, self.encode(code).strip(), imgcss)) + if alt is None: + alt = node.get('alt', self.encode(code).strip()) + if format == 'svg': + svgtag = get_svg_tag(fname, outfn, imgcls) + self.body.append(svgtag) else: - # has a map: get the name of the map and connect the parts - mapname = mapname_re.match(imgmap[0]).group(1) - self.body.append('%s\n' % - (fname, self.encode(code).strip(), - mapname, imgcss)) - self.body.extend(imgmap) + mapfile = open(outfn + '.map', 'rb') + try: + imgmap = mapfile.readlines() + finally: + mapfile.close() + imgcss = imgcls and 'class="%s"' % imgcls or '' + if len(imgmap) == 2: + # nothing in image map (the lines are and ) + self.body.append('%s\n' % + (fname, alt, imgcss)) + else: + # has a map: get the name of the map and connect the parts + mapname = mapname_re.match(imgmap[0]).group(1) + self.body.append('%s\n' % + (fname, alt, mapname, imgcss)) + self.body.extend(imgmap) + self.body.append('

\n') raise nodes.SkipNode @@ -188,3 +241,4 @@ def setup(app): app.add_directive('digraph', GraphvizSimple) app.add_config_value('graphviz_dot', 'dot', 'html') app.add_config_value('graphviz_dot_args', [], 'html') + app.add_config_value('graphviz_output_format', 'png', 'html') diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py index 1bc66af82..cdb6e2c3c 100644 --- a/sphinx/ext/ifconfig.py +++ b/sphinx/ext/ifconfig.py @@ -16,7 +16,7 @@ namespace of the project configuration (that is, all variables from ``conf.py`` are available.) - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 357907310..a271e1014 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -32,7 +32,7 @@ The graph is inserted as a PNG+image map into HTML and a PDF in LaTeX. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -301,7 +301,7 @@ class InheritanceDiagram(Directive): node['graph'] = graph # Store the original content for use as a hash node['parts'] = self.options.get('parts', 0) - node['content'] = ' '.join(class_names) + node['content'] = ', '.join(class_names) return [node] @@ -329,7 +329,8 @@ def html_visit_inheritance_diagram(self, node): urls[child['reftitle']] = '#' + child.get('refid') dotcode = graph.generate_dot(name, parts, urls, env=self.builder.env) - render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance') + render_dot_html(self, node, dotcode, [], 'inheritance', 'inheritance', + alt='Inheritance diagram of ' + node['content']) raise nodes.SkipNode diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 3c97a7342..e20cc266d 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -20,7 +20,7 @@ also be specified individually, e.g. if the docs should be buildable without Internet access. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py index 79e2565a7..8277caa57 100644 --- a/sphinx/ext/jsmath.py +++ b/sphinx/ext/jsmath.py @@ -6,7 +6,7 @@ Set up everything for use of JSMath to display math in HTML via JavaScript. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index b2baa6287..774f5608f 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -5,7 +5,7 @@ Set up math support in source files and LaTeX/text output. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py index 02f46e3d3..c64379e6f 100644 --- a/sphinx/ext/pngmath.py +++ b/sphinx/ext/pngmath.py @@ -5,7 +5,7 @@ Render math in HTML via dvipng. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -23,7 +23,7 @@ except ImportError: from docutils import nodes from sphinx.errors import SphinxError -from sphinx.util import ensuredir +from sphinx.util import ensuredir, ENOENT from sphinx.util.png import read_png_depth, write_png_depth from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath @@ -119,7 +119,7 @@ def render_math(self, math): try: p = Popen(ltx_args, stdout=PIPE, stderr=PIPE) except OSError, err: - if err.errno != 2: # No such file or directory + if err.errno != ENOENT: # No such file or directory raise self.builder.warn('LaTeX command %r cannot be run (needed for math ' 'display), check the pngmath_latex setting' % @@ -147,7 +147,7 @@ def render_math(self, math): try: p = Popen(dvipng_args, stdout=PIPE, stderr=PIPE) except OSError, err: - if err.errno != 2: # No such file or directory + if err.errno != ENOENT: # No such file or directory raise self.builder.warn('dvipng command %r cannot be run (needed for math ' 'display), check the pngmath_dvipng setting' % diff --git a/sphinx/ext/refcounting.py b/sphinx/ext/refcounting.py index cad9d7f1a..398520b8c 100644 --- a/sphinx/ext/refcounting.py +++ b/sphinx/ext/refcounting.py @@ -9,7 +9,7 @@ Usage: Set the `refcount_file` config value to the path to the reference count data file. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index 249fb3611..43e8eaa72 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -8,7 +8,7 @@ all todos of your project and lists them along with a backlink to the original location. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -42,20 +42,31 @@ class Todo(Directive): ad = make_admonition(todo_node, self.name, [_('Todo')], self.options, self.content, self.lineno, self.content_offset, self.block_text, self.state, self.state_machine) + ad[0].line = self.lineno + return [targetnode] + ad - # Attach a list of all todos to the environment, - # the todolist works with the collected todo nodes - if not hasattr(env, 'todo_all_todos'): - env.todo_all_todos = [] + +def process_todos(app, doctree): + # collect all todos in the environment + # this is not done in the directive itself because it some transformations + # must have already been run, e.g. substitutions + env = app.builder.env + if not hasattr(env, 'todo_all_todos'): + env.todo_all_todos = [] + for node in doctree.traverse(todo_node): + try: + targetnode = node.parent[node.parent.index(node) - 1] + if not isinstance(targetnode, nodes.target): + raise IndexError + except IndexError: + targetnode = None env.todo_all_todos.append({ 'docname': env.docname, - 'lineno': self.lineno, - 'todo': ad[0].deepcopy(), + 'lineno': node.line, + 'todo': node.deepcopy(), 'target': targetnode, }) - return [targetnode] + ad - class TodoList(Directive): """ @@ -152,6 +163,7 @@ def setup(app): app.add_directive('todo', Todo) app.add_directive('todolist', TodoList) + app.connect('doctree-read', process_todos) app.connect('doctree-resolved', process_todo_nodes) app.connect('env-purge-doc', purge_todos) diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index 98ee4ab9c..8300bd326 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -5,7 +5,7 @@ Highlight code blocks using Pygments. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -20,7 +20,7 @@ except ImportError: # parser is not available on Jython parser = None -from sphinx.util.texescape import tex_hl_escape_map +from sphinx.util.texescape import tex_hl_escape_map_old, tex_hl_escape_map_new try: import pygments @@ -130,7 +130,7 @@ class PygmentsBridge(object): # first, escape highlighting characters like Pygments does source = source.translate(escape_hl_chars) # then, escape all characters nonrepresentable in LaTeX - source = source.translate(tex_hl_escape_map) + source = source.translate(tex_hl_escape_map_old) return '\\begin{Verbatim}[commandchars=@\\[\\]]\n' + \ source + '\\end{Verbatim}\n' @@ -215,7 +215,10 @@ class PygmentsBridge(object): return highlight(source, lexer, self.fmter[bool(linenos)]) else: hlsource = highlight(source, lexer, self.fmter[bool(linenos)]) - return hlsource.translate(tex_hl_escape_map) + if hlsource.startswith(r'\begin{Verbatim}[commandchars=\\\{\}'): + # Pygments >= 1.2 + return hlsource.translate(tex_hl_escape_map_new) + return hlsource.translate(tex_hl_escape_map_old) except ErrorToken: # this is most probably not the selected language, # so let it pass unhighlighted diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py index 91f7c101f..baeb7c330 100644 --- a/sphinx/jinja2glue.py +++ b/sphinx/jinja2glue.py @@ -5,7 +5,7 @@ Glue code for the jinja2 templating engine. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 36fabc615..4ad3f4c6b 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -5,7 +5,7 @@ Locale utilities. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index fa8d0e948..19fd09e13 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -5,7 +5,7 @@ Utilities parsing and analyzing Python code. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -45,22 +45,33 @@ _eq = nodes.Leaf(token.EQUAL, '=') class AttrDocVisitor(nodes.NodeVisitor): """ Visitor that collects docstrings for attribute assignments on toplevel and - in classes. + in classes (class attributes and attributes set in __init__). The docstrings can either be in special '#:' comments before the assignment or in a docstring after it. """ def init(self, scope, encoding): self.scope = scope + self.in_init = 0 self.encoding = encoding self.namespace = [] self.collected = {} def visit_classdef(self, node): + """Visit a class.""" self.namespace.append(node[1].value) self.generic_visit(node) self.namespace.pop() + def visit_funcdef(self, node): + """Visit a function (or method).""" + # usually, don't descend into functions -- nothing interesting there + if node[1].value == '__init__': + # however, collect attributes set in __init__ methods + self.in_init += 1 + self.generic_visit(node) + self.in_init -= 1 + def visit_expr_stmt(self, node): """Visit an assignment which may have a special comment before it.""" if _eq not in node.children: @@ -97,20 +108,32 @@ class AttrDocVisitor(nodes.NodeVisitor): docstring = prepare_docstring(docstring) self.add_docstring(prev[0], docstring) - def visit_funcdef(self, node): - # don't descend into functions -- nothing interesting there - return - def add_docstring(self, node, docstring): # add an item for each assignment target for i in range(0, len(node) - 1, 2): target = node[i] - if target.type != token.NAME: - # don't care about complex targets + if self.in_init and self.number2name[target.type] == 'power': + # maybe an attribute assignment -- check necessary conditions + if (# node must have two children + len(target) != 2 or + # first child must be "self" + target[0].type != token.NAME or target[0].value != 'self' or + # second child must be a "trailer" with two children + self.number2name[target[1].type] != 'trailer' or + len(target[1]) != 2 or + # first child must be a dot, second child a name + target[1][0].type != token.DOT or + target[1][1].type != token.NAME): + continue + name = target[1][1].value + elif target.type != token.NAME: + # don't care about other complex targets continue + else: + name = target.value namespace = '.'.join(self.namespace) if namespace.startswith(self.scope): - self.collected[namespace, target.value] = docstring + self.collected[namespace, name] = docstring class PycodeError(Exception): diff --git a/sphinx/pycode/nodes.py b/sphinx/pycode/nodes.py index f8f57740e..e71846779 100644 --- a/sphinx/pycode/nodes.py +++ b/sphinx/pycode/nodes.py @@ -5,7 +5,7 @@ Parse tree node implementations. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index eaf9f55a0..faea2c2ed 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -5,7 +5,7 @@ Quickly setup documentation source to work with Sphinx. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -84,12 +84,9 @@ release = '%(release_str)s' # 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 = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = [%(exclude_trees)s] +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [%(exclude_patterns)s] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None @@ -227,39 +224,23 @@ latex_documents = [ # -- Options for Epub output --------------------------------------------------- -# Please also set the html_theme to 'epub' or any other approriate theme. -# The display size is quite small for ebook readers. -# The default themes may take too much space. - -# bibliographic Dublin Core description of the content.opf and -# in the toc.ncx file. It defaults to the html_title option. +# Bibliographic Dublin Core info. #epub_title = '' - -# The author of the text. The author is inserted into the -# bibliographic Dublin Core description of the content.opf file. #epub_author = '' +#epub_publisher = '' +#epub_copyright = '' # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' -# The publisher of the text. The publisher is inserted into the -# bibliographic Dublin Core description of the content.opf file. -# You may use the project homepage. -#epub_publisher = '' - -# The copyright of the text. The copyright is inserted into the -# bibliographci Dublin Core description of the content.opf file. -# It defaults to the copyright option. -#epub_copyright = '' +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' -# The scheme of the identifier. Typical schemes are ISBN or URL. -#epub_scheme = '' - # A unique identification for the text. #epub_uid = '' @@ -759,10 +740,10 @@ directly.''' mkdir_p(srcdir) if d['sep']: builddir = path.join(d['path'], 'build') - d['exclude_trees'] = '' + d['exclude_patterns'] = '' else: builddir = path.join(srcdir, d['dot'] + 'build') - d['exclude_trees'] = repr(d['dot'] + 'build') + d['exclude_patterns'] = repr(d['dot'] + 'build') mkdir_p(builddir) mkdir_p(path.join(srcdir, d['dot'] + 'templates')) mkdir_p(path.join(srcdir, d['dot'] + 'static')) diff --git a/sphinx/roles.py b/sphinx/roles.py index af574b98c..0a1393b5e 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -5,7 +5,7 @@ Handlers for additional ReST roles. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -190,6 +190,7 @@ def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): else: # remove all whitespace to avoid referencing problems target = ws_re.sub('', target) + pnode['refdoc'] = env.docname pnode['reftarget'] = target pnode += innernodetypes.get(typ, nodes.literal)(rawtext, title, classes=['xref']) diff --git a/sphinx/search.py b/sphinx/search.py index 9bfa9d92c..7161bc4ca 100644 --- a/sphinx/search.py +++ b/sphinx/search.py @@ -5,7 +5,7 @@ Create a search index for offline search. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import re diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index a33b4ee65..1b434fa23 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -8,7 +8,7 @@ :author: Sebastian Wiesner :contact: basti.wiesner@gmx.net - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/themes/agogo/layout.html b/sphinx/themes/agogo/layout.html index d8b9d57ed..736363762 100644 --- a/sphinx/themes/agogo/layout.html +++ b/sphinx/themes/agogo/layout.html @@ -1,3 +1,13 @@ +{# + agogo/layout.html + ~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the agogo theme, originally written + by Andi Albrecht. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "basic/layout.html" %} {% block header %} diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t index 24e7dba58..4dd03d922 100644 --- a/sphinx/themes/agogo/static/agogo.css_t +++ b/sphinx/themes/agogo/static/agogo.css_t @@ -1,3 +1,14 @@ +/* + * agogo.css_t + * ~~~~~~~~~~~ + * + * Sphinx stylesheet -- agogo theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + * { margin: 0px; padding: 0px; @@ -44,6 +55,18 @@ a { float: right; } +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + h1, h2, h3, h4 { font-family: {{ theme_headerfont }}; font-weight: normal; @@ -257,7 +280,7 @@ div.footer .left { } -/* Styles copied form basic theme */ +/* Styles copied from basic theme */ /* -- search page ----------------------------------------------------------- */ diff --git a/sphinx/themes/basic/defindex.html b/sphinx/themes/basic/defindex.html index 40f4f4c90..f337faece 100644 --- a/sphinx/themes/basic/defindex.html +++ b/sphinx/themes/basic/defindex.html @@ -1,3 +1,12 @@ +{# + basic/defindex.html + ~~~~~~~~~~~~~~~~~~~ + + Default template for the "index" page. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Overview') %} {% block body %} diff --git a/sphinx/themes/basic/genindex-single.html b/sphinx/themes/basic/genindex-single.html index 9aaaeb0ca..1e98ba9c9 100644 --- a/sphinx/themes/basic/genindex-single.html +++ b/sphinx/themes/basic/genindex-single.html @@ -1,36 +1,38 @@ +{# + basic/genindex-single.html + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Template for a "single" page of a split index. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Index') %} {% block body %}

{% trans key=key %}Index – {{ key }}{% endtrans %}

- +{%- endfor %} +
-
-{%- set breakat = count // 2 %} -{%- set numcols = 1 %} -{%- set numitems = 0 %} -{% for entryname, (links, subitems) in entries %} -
{%- if links -%}{{ entryname|e }} - {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} - {%- else -%} -{{ entryname|e }} - {%- endif -%}
- {%- if subitems %} -
+ + {%- for column in entries|slice(2) if column %} +
+ {%- for entryname, (links, subitems) in column %} +
{% if links %}{{ entryname|e }} + {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor %} + {%- else %}{{ entryname|e }}{% endif %}
+ {%- if subitems %} +
{%- for subentryname, subentrylinks in subitems %} -
{{ subentryname|e }} - {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} -
+
{{ subentryname|e }} + {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} +
{%- endfor %}
{%- endif -%} -{%- set numitems = numitems + 1 + (subitems|length) -%} -{%- if numcols < 2 and numitems > breakat -%} -{%- set numcols = numcols+1 -%} -
-{%- endif -%} {%- endfor %} -
+
{% endblock %} diff --git a/sphinx/themes/basic/genindex-split.html b/sphinx/themes/basic/genindex-split.html index ab099e5bd..d068a96a6 100644 --- a/sphinx/themes/basic/genindex-split.html +++ b/sphinx/themes/basic/genindex-split.html @@ -1,3 +1,12 @@ +{# + basic/genindex-split.html + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Template for a "split" index overview page. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Index') %} {% block body %} @@ -6,6 +15,7 @@

{{ _('Index pages by letter') }}:

+

{% for key, dummy in genindexentries -%} {{ key }} {% if not loop.last %}| {% endif %} @@ -13,6 +23,7 @@

{{ _('Full index on one page') }} ({{ _('can be huge') }})

+
{% endblock %} diff --git a/sphinx/themes/basic/genindex.html b/sphinx/themes/basic/genindex.html index a19aa80f4..4d46380f1 100644 --- a/sphinx/themes/basic/genindex.html +++ b/sphinx/themes/basic/genindex.html @@ -1,44 +1,46 @@ +{# + basic/genindex.html + ~~~~~~~~~~~~~~~~~~~ + + Template for an "all-in-one" index. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Index') %} {% block body %}

{{ _('Index') }}

+
{% for key, dummy in genindexentries -%} {{ key }} {% if not loop.last %}| {% endif %} {%- endfor %} +
-
- - {% for key, entries in genindexentries %} + {%- for key, entries in genindexentries %}

{{ key }}

- +{%- endfor %} +
-
-{%- set breakat = genindexcounts[loop.index0] // 2 %} -{%- set numcols = 1 %} -{%- set numitems = 0 %} -{% for entryname, (links, subitems) in entries %} -
{%- if links -%}{{ entryname|e }} - {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} - {%- else -%} -{{ entryname|e }} - {%- endif -%}
- {%- if subitems %} -
+ + {%- for column in entries|slice(2) if column %} +
+ {%- for entryname, (links, subitems) in column %} +
{% if links %}{{ entryname|e }} + {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor %} + {%- else %}{{ entryname|e }}{% endif %}
+ {%- if subitems %} +
{%- for subentryname, subentrylinks in subitems %} -
{{ subentryname|e }} - {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} -
+
{{ subentryname|e }} + {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} +
{%- endfor %}
{%- endif -%} -{%- set numitems = numitems + 1 + (subitems|length) -%} -{%- if numcols < 2 and numitems > breakat -%} -{%- set numcols = numcols+1 -%} -
-{%- endif -%} {%- endfor %} -
+
{% endfor %} {% endblock %} diff --git a/sphinx/themes/basic/globaltoc.html b/sphinx/themes/basic/globaltoc.html new file mode 100644 index 000000000..c53324714 --- /dev/null +++ b/sphinx/themes/basic/globaltoc.html @@ -0,0 +1,13 @@ +{# + basic/globaltoc.html + ~~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: global table of contents. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if display_toc %} +

{{ _('Table Of Contents') }}

+ {{ toctree() }} +{%- endif %} diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index c012116cd..429cc9bb4 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -1,3 +1,12 @@ +{# + basic/layout.html + ~~~~~~~~~~~~~~~~~ + + Master layout template for Sphinx themes. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {%- block doctype -%} @@ -37,53 +46,29 @@

{%- endif %} {%- endblock %} - {%- block sidebartoc %} - {%- if display_toc %} -

{{ _('Table Of Contents') }}

- {{ toc }} + {%- if sidebars %} + {#- new style sidebar: explicitly include/exclude templates #} + {%- for sidebartemplate in sidebars %} + {%- include sidebartemplate %} + {%- endfor %} + {%- else %} + {#- old style sidebars: using blocks -- should be deprecated #} + {%- block sidebartoc %} + {%- include "localtoc.html" %} + {%- endblock %} + {%- block sidebarrel %} + {%- include "relations.html" %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- include "sourcelink.html" %} + {%- endblock %} + {%- if customsidebar %} + {%- include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- include "searchbox.html" %} + {%- endblock %} {%- endif %} - {%- endblock %} - {%- block sidebarrel %} - {%- if prev %} -

{{ _('Previous topic') }}

-

{{ prev.title }}

- {%- endif %} - {%- if next %} -

{{ _('Next topic') }}

-

{{ next.title }}

- {%- endif %} - {%- endblock %} - {%- block sidebarsourcelink %} - {%- if show_source and has_source and sourcename %} -

{{ _('This Page') }}

- - {%- endif %} - {%- endblock %} - {%- if customsidebar %} - {% include customsidebar %} - {%- endif %} - {%- block sidebarsearch %} - {%- if pagename != "search" %} - - - {%- endif %} - {%- endblock %} {%- endif %}{% endif %} diff --git a/sphinx/themes/basic/localtoc.html b/sphinx/themes/basic/localtoc.html new file mode 100644 index 000000000..896eda9ce --- /dev/null +++ b/sphinx/themes/basic/localtoc.html @@ -0,0 +1,13 @@ +{# + basic/localtoc.html + ~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: local table of contents. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if display_toc %} +

{{ _('Table Of Contents') }}

+ {{ toc }} +{%- endif %} diff --git a/sphinx/themes/basic/modindex.html b/sphinx/themes/basic/modindex.html index 0392edc80..96f8ac433 100644 --- a/sphinx/themes/basic/modindex.html +++ b/sphinx/themes/basic/modindex.html @@ -1,3 +1,12 @@ +{# + basic/modindex.html + ~~~~~~~~~~~~~~~~~~~ + + Template for the module index. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Global Module Index') %} {% block extrahead %} @@ -12,12 +21,13 @@

{{ _('Global Module Index') }}

+
{%- for letter in letters %} {{ letter }} {% if not loop.last %}| {% endif %} {%- endfor %} -
+
- +
{%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} {%- if not modname -%} diff --git a/sphinx/themes/basic/page.html b/sphinx/themes/basic/page.html index 17a930165..c7188fa52 100644 --- a/sphinx/themes/basic/page.html +++ b/sphinx/themes/basic/page.html @@ -1,3 +1,12 @@ +{# + basic/page.html + ~~~~~~~~~~~~~~~ + + Master template for simple pages. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% block body %} {{ body }} diff --git a/sphinx/themes/basic/relations.html b/sphinx/themes/basic/relations.html new file mode 100644 index 000000000..b693daf88 --- /dev/null +++ b/sphinx/themes/basic/relations.html @@ -0,0 +1,19 @@ +{# + basic/relations.html + ~~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: relation links. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if prev %} +

{{ _('Previous topic') }}

+

{{ prev.title }}

+{%- endif %} +{%- if next %} +

{{ _('Next topic') }}

+

{{ next.title }}

+{%- endif %} diff --git a/sphinx/themes/basic/search.html b/sphinx/themes/basic/search.html index 224d87b86..eac326055 100644 --- a/sphinx/themes/basic/search.html +++ b/sphinx/themes/basic/search.html @@ -1,3 +1,12 @@ +{# + basic/search.html + ~~~~~~~~~~~~~~~~~ + + Template for the search page. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "layout.html" %} {% set title = _('Search') %} {% set script_files = script_files + ['_static/searchtools.js'] %} @@ -41,5 +50,5 @@ {% endblock %} {% block footer %} {{ super() }} - + {% endblock %} diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html new file mode 100644 index 000000000..56d6617c9 --- /dev/null +++ b/sphinx/themes/basic/searchbox.html @@ -0,0 +1,24 @@ +{# + basic/searchbox.html + ~~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: quick search box. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if pagename != "search" %} + + +{%- endif %} diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html new file mode 100644 index 000000000..8fa7563b4 --- /dev/null +++ b/sphinx/themes/basic/sourcelink.html @@ -0,0 +1,16 @@ +{# + basic/sourcelink.html + ~~~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: "show source" link. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if show_source and has_source and sourcename %} +

{{ _('This Page') }}

+ +{%- endif %} diff --git a/sphinx/themes/basic/static/basic.css b/sphinx/themes/basic/static/basic.css index a440964e7..bd0a85446 100644 --- a/sphinx/themes/basic/static/basic.css +++ b/sphinx/themes/basic/static/basic.css @@ -1,6 +1,12 @@ -/** - * Sphinx stylesheet -- basic theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ /* -- main layout ----------------------------------------------------------- */ @@ -127,6 +133,10 @@ span.linkdescr { /* -- general index --------------------------------------------------------- */ +table.indextable { + width: 100%; +} + table.indextable td { text-align: left; vertical-align: top; @@ -152,6 +162,20 @@ img.toggler { cursor: pointer; } +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + /* -- general body styles --------------------------------------------------- */ a.headerlink { @@ -332,6 +356,18 @@ dl.glossary dt { background-color: #ffa } +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + /* -- code displays --------------------------------------------------------- */ pre { diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index 9447678cd..cb6f30e56 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -1,4 +1,13 @@ -/// XXX: make it cross browser +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for all documentation. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ /** * make the code below compatible with browsers without diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index 36acb12ee..2e9b5bee6 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -1,3 +1,14 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilties for the full-text search. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + /** * helper function to return a node containing the * search summary for a given text. keywords is a list diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t index fbfd64a85..04562d961 100644 --- a/sphinx/themes/default/static/default.css_t +++ b/sphinx/themes/default/static/default.css_t @@ -1,6 +1,12 @@ -/** - * Sphinx stylesheet -- default theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ @import url("basic.css"); @@ -250,3 +256,11 @@ tt { th { background-color: #ede; } + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} diff --git a/sphinx/themes/epub/layout.html b/sphinx/themes/epub/layout.html index 64b1a4cb2..8a348beda 100644 --- a/sphinx/themes/epub/layout.html +++ b/sphinx/themes/epub/layout.html @@ -1,3 +1,12 @@ +{# + epub/layout.html + ~~~~~~~~~~~~~~~~ + + Sphinx layout template for the epub theme. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "basic/layout.html" %} {# add only basic navigation links #} diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css index 72b771905..f941b79a6 100644 --- a/sphinx/themes/epub/static/epub.css +++ b/sphinx/themes/epub/static/epub.css @@ -1,6 +1,12 @@ -/** - * Sphinx stylesheet -- epub theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* + * epub.css_t + * ~~~~~~~~~~ + * + * Sphinx stylesheet -- epub theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ /* -- main layout ----------------------------------------------------------- */ diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html new file mode 100644 index 000000000..91c768521 --- /dev/null +++ b/sphinx/themes/haiku/layout.html @@ -0,0 +1,68 @@ +{# + haiku/layout.html + ~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the haiku theme. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{% extends "basic/layout.html" %} +{% set script_files = script_files + ['_static/theme_extras.js'] %} +{% set css_files = css_files + ['_static/print.css'] %} + +{# do not display relbars #} +{% block relbar1 %}{% endblock %} +{% block relbar2 %}{% endblock %} + +{% macro nav() %} +

+ {%- block haikurel1 %} + {%- endblock %} + {%- if prev %} + «  {{ prev.title }} +   ::   + {%- endif %} + {{ _('Contents') }} + {%- if next %} +   ::   + {{ next.title }}  » + {%- endif %} + {%- block haikurel2 %} + {%- endblock %} +

+{% endmacro %} + +{% block content %} +
+ {%- block haikuheader %} + {%- if theme_full_logo != "false" %} + + + + {%- else %} + {%- if logo -%} + + {%- endif -%} +

+ {{ shorttitle|e }}

+

{{ title|striptags }}

+ {%- endif %} + {%- endblock %} +
+
+ {{ nav() }} +
+
+ {#{%- if display_toc %} +
+

Table Of Contents

+ {{ toc }} +
+ {%- endif %}#} + {% block body %}{% endblock %} +
+
+ {{ nav() }} +
+{% endblock %} \ No newline at end of file diff --git a/sphinx/themes/haiku/static/alert_info_32.png b/sphinx/themes/haiku/static/alert_info_32.png new file mode 100644 index 000000000..05b4fe898 Binary files /dev/null and b/sphinx/themes/haiku/static/alert_info_32.png differ diff --git a/sphinx/themes/haiku/static/alert_warning_32.png b/sphinx/themes/haiku/static/alert_warning_32.png new file mode 100644 index 000000000..f13611cde Binary files /dev/null and b/sphinx/themes/haiku/static/alert_warning_32.png differ diff --git a/sphinx/themes/haiku/static/bg-page.png b/sphinx/themes/haiku/static/bg-page.png new file mode 100644 index 000000000..c6f3bc477 Binary files /dev/null and b/sphinx/themes/haiku/static/bg-page.png differ diff --git a/sphinx/themes/haiku/static/bullet_orange.png b/sphinx/themes/haiku/static/bullet_orange.png new file mode 100644 index 000000000..ad5d02f34 Binary files /dev/null and b/sphinx/themes/haiku/static/bullet_orange.png differ diff --git a/sphinx/themes/haiku/static/haiku.css_t b/sphinx/themes/haiku/static/haiku.css_t new file mode 100644 index 000000000..7adfb0f3b --- /dev/null +++ b/sphinx/themes/haiku/static/haiku.css_t @@ -0,0 +1,359 @@ +/* + * haiku.css_t + * ~~~~~~~~~~~ + * + * Sphinx stylesheet -- haiku theme. + * + * Adapted from http://haiku-os.org/docs/Haiku-doc.css. + * Original copyright message: + * + * Copyright 2008-2009, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Francois Revol + * Stephan Assmus + * Braden Ewing + * Humdinger + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +html { + margin: 0px; + padding: 0px; + background: #FFF url(bg-page.png) top left repeat-x; +} + +body { + line-height: 1.5; + margin: auto; + padding: 0px; + font-family: "DejaVu Sans", Arial, Helvetica, sans-serif; + min-width: 59em; + max-width: 70em; + color: {{ theme_textcolor }}; +} + +div.footer { + padding: 8px; + font-size: 11px; + text-align: center; + letter-spacing: 0.5px; +} + +/* link colors and text decoration */ + +a:link { + font-weight: bold; + text-decoration: none; + color: {{ theme_linkcolor }}; +} + +a:visited { + font-weight: bold; + text-decoration: none; + color: {{ theme_visitedlinkcolor }}; +} + +a:hover, a:active { + text-decoration: underline; + color: {{ theme_hoverlinkcolor }}; +} + +/* Some headers act as anchors, don't give them a hover effect */ + +h1 a:hover, a:active { + text-decoration: none; + color: {{ theme_headingcolor }}; +} + +h2 a:hover, a:active { + text-decoration: none; + color: {{ theme_headingcolor }}; +} + +h3 a:hover, a:active { + text-decoration: none; + color: {{ theme_headingcolor }}; +} + +h4 a:hover, a:active { + text-decoration: none; + color: {{ theme_headingcolor }}; +} + +a.headerlink { + color: #a7ce38; + padding-left: 5px; +} + +a.headerlink:hover { + color: #a7ce38; +} + +/* basic text elements */ + +div.content { + margin-top: 20px; + margin-left: 40px; + margin-right: 40px; + margin-bottom: 50px; + font-size: 0.9em; +} + +/* heading and navigation */ + +div.header { + position: relative; + left: 0px; + top: 0px; + height: 85px; + /* background: #eeeeee; */ + padding: 0 40px; +} +div.header h1 { + font-size: 1.6em; + font-weight: normal; + letter-spacing: 1px; + color: {{ theme_headingcolor }}; + border: 0; + margin: 0; + padding-top: 15px; +} +div.header h1 a { + font-weight: normal; + color: {{ theme_headingcolor }}; +} +div.header h2 { + font-size: 1.3em; + font-weight: normal; + letter-spacing: 1px; + text-transform: uppercase; + color: #aaa; + border: 0; + margin-top: -3px; + padding: 0; +} + +div.header img.rightlogo { + float: right; +} + + +div.title { + font-size: 1.3em; + font-weight: bold; + color: {{ theme_headingcolor }}; + border-bottom: dotted thin #e0e0e0; + margin-bottom: 25px; +} +div.topnav { + /* background: #e0e0e0; */ +} +div.topnav p { + margin-top: 0; + margin-left: 40px; + margin-right: 40px; + margin-bottom: 0px; + text-align: right; + font-size: 0.8em; +} +div.bottomnav { + background: #eeeeee; +} +div.bottomnav p { + margin-right: 40px; + text-align: right; + font-size: 0.8em; +} + +a.uplink { + font-weight: normal; +} + + +/* contents box */ + +table.index { + margin: 0px 0px 30px 30px; + padding: 1px; + border-width: 1px; + border-style: dotted; + border-color: #e0e0e0; +} +table.index tr.heading { + background-color: #e0e0e0; + text-align: center; + font-weight: bold; + font-size: 1.1em; +} +table.index tr.index { + background-color: #eeeeee; +} +table.index td { + padding: 5px 20px; +} + +table.index a:link, table.index a:visited { + font-weight: normal; + text-decoration: none; + color: {{ theme_linkcolor }}; +} +table.index a:hover, table.index a:active { + text-decoration: underline; + color: {{ theme_hoverlinkcolor }}; +} + + +/* Haiku User Guide styles and layout */ + +/* Rounded corner boxes */ +/* Common declarations */ +div.admonition { + -webkit-border-radius: 10px; + -khtml-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + border-style: dotted; + border-width: thin; + border-color: #dcdcdc; + padding: 10px 15px 10px 15px; + margin-bottom: 15px; + margin-top: 15px; +} +div.note { + padding: 10px 15px 10px 80px; + background: #e4ffde url(alert_info_32.png) 15px 15px no-repeat; + min-height: 42px; +} +div.warning { + padding: 10px 15px 10px 80px; + background: #fffbc6 url(alert_warning_32.png) 15px 15px no-repeat; + min-height: 42px; +} +div.seealso { + background: #e4ffde; +} + +/* More layout and styles */ +h1 { + font-size: 1.3em; + font-weight: bold; + color: {{ theme_headingcolor }}; + border-bottom: dotted thin #e0e0e0; + margin-top: 30px; +} + +h2 { + font-size: 1.2em; + font-weight: normal; + color: {{ theme_headingcolor }}; + border-bottom: dotted thin #e0e0e0; + margin-top: 30px; +} + +h3 { + font-size: 1.1em; + font-weight: normal; + color: {{ theme_headingcolor }}; + margin-top: 30px; +} + +h4 { + font-size: 1.0em; + font-weight: normal; + color: {{ theme_headingcolor }}; + margin-top: 30px; +} + +p { + text-align: justify; +} + +p.last { + margin-bottom: 0; +} + +ol { + padding-left: 20px; +} + +ul { + padding-left: 5px; + margin-top: 3px; +} + +li { + line-height: 1.3; +} + +div.content li { + -moz-background-clip:border; + -moz-background-inline-policy:continuous; + -moz-background-origin:padding; + background: transparent url(bullet_orange.png) no-repeat scroll left 0.45em; + list-style-image: none; + list-style-type: none; + padding: 0 0 0 1.666em; + margin-bottom: 3px; +} + +td { + vertical-align: top; +} + +tt { + background-color: #e2e2e2; + font-size: 1.0em; + font-family: monospace; +} + +pre { + border-color: #0c3762; + border-style: dotted; + border-width: thin; + margin: 0 0 12px 0; + padding: 0.8em; + background-color: #f0f0f0; +} + +hr { + border-top: 1px solid #ccc; + border-bottom: 0; + border-right: 0; + border-left: 0; + margin-bottom: 10px; + margin-top: 20px; +} + +/* printer only pretty stuff */ +@media print { + .noprint { + display: none; + } + /* for acronyms we want their definitions inlined at print time */ + acronym[title]:after { + font-size: small; + content: " (" attr(title) ")"; + font-style: italic; + } + /* and not have mozilla dotted underline */ + acronym { + border: none; + } + div.topnav, div.bottomnav, div.header, table.index { + display: none; + } + div.content { + margin: 0px; + padding: 0px; + } + html { + background: #FFF; + } +} diff --git a/sphinx/themes/haiku/theme.conf b/sphinx/themes/haiku/theme.conf new file mode 100644 index 000000000..3537da1d3 --- /dev/null +++ b/sphinx/themes/haiku/theme.conf @@ -0,0 +1,12 @@ +[theme] +inherit = basic +stylesheet = haiku.css +pygments_style = autumn + +[options] +full_logo = false +textcolor = #333333 +headingcolor = #0c3762 +linkcolor = #dc3c01 +visitedlinkcolor = #892601 +hoverlinkcolor = #ff4500 diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t new file mode 100644 index 000000000..5991e349e --- /dev/null +++ b/sphinx/themes/nature/static/nature.css_t @@ -0,0 +1,235 @@ +/* + * nature.css_t + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- nature theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Arial, sans-serif; + font-size: 100%; + background-color: #111; + color: #555; + margin: 0; + padding: 0; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.document { + background-color: #eee; +} + +div.body { + background-color: #ffffff; + color: #3E4349; + padding: 0 30px 30px 30px; + font-size: 0.9em; +} + +div.footer { + color: #555; + width: 100%; + padding: 13px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #444; + text-decoration: underline; +} + +div.related { + background-color: #6BA81E; + line-height: 32px; + color: #fff; + text-shadow: 0px 1px 0 #444; + font-size: 0.9em; +} + +div.related a { + color: #E2F3CC; +} + +div.sphinxsidebar { + font-size: 0.75em; + line-height: 1.5em; +} + +div.sphinxsidebarwrapper{ + padding: 20px 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Arial, sans-serif; + color: #222; + font-size: 1.2em; + font-weight: normal; + margin: 0; + padding: 5px 10px; + background-color: #ddd; + text-shadow: 1px 1px 0 white +} + +div.sphinxsidebar h4{ + font-size: 1.1em; +} + +div.sphinxsidebar h3 a { + color: #444; +} + + +div.sphinxsidebar p { + color: #888; + padding: 5px 20px; +} + +div.sphinxsidebar p.topless { +} + +div.sphinxsidebar ul { + margin: 10px 20px; + padding: 0; + color: #000; +} + +div.sphinxsidebar a { + color: #444; +} + +div.sphinxsidebar input { + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar input[type=text]{ + margin-left: 20px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #005B81; + text-decoration: none; +} + +a:hover { + color: #E32E00; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Arial, sans-serif; + background-color: #BED4EB; + font-weight: normal; + color: #212224; + margin: 30px 0px 10px 0px; + padding: 5px 0 5px 10px; + text-shadow: 0px 1px 0 white +} + +div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 150%; background-color: #C8D5E3; } +div.body h3 { font-size: 120%; background-color: #D8DEE3; } +div.body h4 { font-size: 110%; background-color: #D8DEE3; } +div.body h5 { font-size: 100%; background-color: #D8DEE3; } +div.body h6 { font-size: 100%; background-color: #D8DEE3; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + line-height: 1.5em; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.highlight{ + background-color: white; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 10px; + background-color: White; + color: #222; + line-height: 1.2em; + border: 1px solid #C6C9CB; + font-size: 1.1em; + margin: 1.5em 0 1.5em 0; + -webkit-box-shadow: 1px 1px 1px #d8d8d8; + -moz-box-shadow: 1px 1px 1px #d8d8d8; +} + +tt { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ + font-size: 1.1em; + font-family: monospace; +} diff --git a/sphinx/themes/nature/theme.conf b/sphinx/themes/nature/theme.conf new file mode 100644 index 000000000..1cc400446 --- /dev/null +++ b/sphinx/themes/nature/theme.conf @@ -0,0 +1,4 @@ +[theme] +inherit = basic +stylesheet = nature.css +pygments_style = tango diff --git a/sphinx/themes/scrolls/genindex.html b/sphinx/themes/scrolls/genindex.html deleted file mode 100644 index 9add6e952..000000000 --- a/sphinx/themes/scrolls/genindex.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "layout.html" %} -{% set title = 'Index' %} -{% block body %} - -

Index

- - {% for key, dummy in genindexentries -%} - {{ key }} {% if not loop.last %}| {% endif %} - {%- endfor %} -
- - {% for key, entries in genindexentries %} -

{{ key }}

-
 
- {%- for column in entries|slice(2) if column %} - - {%- endfor %} -
- {%- for entryname, (links, subitems) in column %} -
{% if links %}{{ entryname|e }} - {% for link in links[1:] %}, [Link]{% endfor %} - {%- else %}{{ entryname|e }}{% endif %}
- {%- if subitems %} -
- {%- for subentryname, subentrylinks in subitems %} -
{{ subentryname|e }} - {%- for link in subentrylinks[1:] %}, [Link]{% endfor -%} -
- {%- endfor %} -
- {%- endif -%} - {%- endfor %} -
- {% endfor %} - -{% endblock %} diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html index d1c66ae2f..9c139b880 100644 --- a/sphinx/themes/scrolls/layout.html +++ b/sphinx/themes/scrolls/layout.html @@ -1,58 +1,20 @@ - - - - {%- if not embedded %} - {%- set titlesuffix = " — "|safe + docstitle|e %} - {%- else %} - {%- set titlesuffix = "" %} - {%- endif %} - {{ title|striptags }}{{ titlesuffix }} - - - - - {%- if builder != 'htmlhelp' %} - - - - - - {%- endif %} - {%- if use_opensearch and builder != 'htmlhelp' %} - - {%- endif %} - {%- if hasdoc('about') %} - - {%- endif %} - - - - {%- if hasdoc('copyright') %} - - {%- endif %} - - {%- if parents %} - - {%- endif %} - {%- if next %} - - {%- endif %} - {%- if prev %} - - {%- endif %} - {% block extrahead %}{% endblock %} - - +{# + scrolls/layout.html + ~~~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the scrolls theme, originally written + by Armin Ronacher. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{% extends "basic/layout.html" %} +{% set script_files = script_files + ['_static/theme_extras.js'] %} +{% set css_files = css_files + ['_static/print.css'] %} +{# do not display relbars #} +{% block relbar1 %}{% endblock %} +{% block relbar2 %}{% endblock %} +{% block content %}
- - - +{% endblock %} \ No newline at end of file diff --git a/sphinx/themes/scrolls/modindex.html b/sphinx/themes/scrolls/modindex.html deleted file mode 100644 index 314ebdd91..000000000 --- a/sphinx/themes/scrolls/modindex.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "layout.html" %} -{% set title = _('Global Module Index') %} -{% block extrahead %} -{{ super() }} -{% if not embedded and collapse_modindex %} - -{% endif %} -{% endblock %} -{% block body %} - -

{{ _('Global Module Index') }}

- -
- {%- for letter in letters %} - {{ letter }} {% if not loop.last %}| {% endif %} - {%- endfor %} -
- - - {%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} - {%- if not modname -%} - - - {%- else -%} - - - - {%- endif -%} - {% endfor %} -
 
{{ fname }}
{% if collapse -%} - - {%- endif %}{% if indent %}   {% endif %} - {% if fname %}{% endif -%} - {{ stripped|e }}{{ modname|e }} - {%- if fname %}{% endif %} - {%- if pform and pform[0] %} ({{ pform|join(', ') }}){% endif -%} - {% if dep %}{{ _('Deprecated')}}:{% endif %} - {{ synops|e }}
- -{% endblock %} diff --git a/sphinx/themes/scrolls/opensearch.xml b/sphinx/themes/scrolls/opensearch.xml deleted file mode 100644 index 9f2fa4274..000000000 --- a/sphinx/themes/scrolls/opensearch.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - {{ project }} - Search {{ docstitle }} - utf-8 - - {{ docstitle }} - diff --git a/sphinx/themes/scrolls/page.html b/sphinx/themes/scrolls/page.html deleted file mode 100644 index ee6cad3dc..000000000 --- a/sphinx/themes/scrolls/page.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends 'layout.html' %} -{% block body %} - {{ body }} -{% endblock %} diff --git a/sphinx/themes/scrolls/search.html b/sphinx/themes/scrolls/search.html deleted file mode 100644 index 0c942b70f..000000000 --- a/sphinx/themes/scrolls/search.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "layout.html" %} -{% set title = 'Search' %} -{% block extrahead %} - -{% endblock %} -{% block body %} -

Search

-

- From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing less words won't appear in the result list. -

-

- - -

- {% if search_performed %} -

Search Results

- {% if not search_results %} -

Your search did not match any results.

- {% endif %} - {% endif %} -
- {% if search_results %} -
    - {% for href, caption, context in search_results %} -
  • {{ caption }} -
    {{ context|e }}
    -
  • - {% endfor %} -
- {% endif %} -
-{% endblock %} diff --git a/sphinx/themes/scrolls/static/style.css_t b/sphinx/themes/scrolls/static/scrolls.css_t similarity index 93% rename from sphinx/themes/scrolls/static/style.css_t rename to sphinx/themes/scrolls/static/scrolls.css_t index 0c346d04a..41a725a6d 100644 --- a/sphinx/themes/scrolls/static/style.css_t +++ b/sphinx/themes/scrolls/static/scrolls.css_t @@ -1,3 +1,14 @@ +/* + * scrolls.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- scrolls theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + body { background-color: #222; margin: 0; @@ -86,13 +97,6 @@ h1.heading span { display: none; } -#jinjalogo { - background-image: url(jinjalogo.png); - background-repeat: no-repeat; - width: 400px; - height: 160px; -} - #contentwrapper { max-width: 680px; padding: 0 18px 20px 18px; @@ -259,7 +263,7 @@ table.indextable { width: 100%; } -table.indextable td { +table.genindextable td { vertical-align: top; width: 50%; } @@ -396,3 +400,15 @@ span.highlight { #toc ul li { margin: 2px 0 0 0; } + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} diff --git a/sphinx/themes/scrolls/theme.conf b/sphinx/themes/scrolls/theme.conf index b42050460..4e7800f90 100644 --- a/sphinx/themes/scrolls/theme.conf +++ b/sphinx/themes/scrolls/theme.conf @@ -1,5 +1,5 @@ [theme] -inherit = default +inherit = basic stylesheet = scrolls.css pygments_style = tango diff --git a/sphinx/themes/sphinxdoc/layout.html b/sphinx/themes/sphinxdoc/layout.html index 48d2118e8..2d653f9fc 100644 --- a/sphinx/themes/sphinxdoc/layout.html +++ b/sphinx/themes/sphinxdoc/layout.html @@ -1,3 +1,12 @@ +{# + sphinxdoc/layout.html + ~~~~~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the sphinxdoc theme. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} {% extends "basic/layout.html" %} {# put the sidebar before the body #} diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css b/sphinx/themes/sphinxdoc/static/sphinxdoc.css index 75b2ae0f9..3f1e84e5d 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css @@ -1,8 +1,13 @@ -/** - * Sphinx stylesheet -- sphinxdoc theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/* + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. * - * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl. */ @import url("basic.css"); diff --git a/sphinx/themes/traditional/static/traditional.css b/sphinx/themes/traditional/static/traditional.css index 8c224c073..022e55ae9 100644 --- a/sphinx/themes/traditional/static/traditional.css +++ b/sphinx/themes/traditional/static/traditional.css @@ -1,5 +1,12 @@ -/** - * Sphinx Doc Design -- traditional python.org style +/* + * traditional.css + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- traditional docs.python.org theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ body { @@ -636,6 +643,18 @@ tt.xref, a tt { .footnote:target { background-color: #ffa } +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } diff --git a/sphinx/theming.py b/sphinx/theming.py index 217dd81c9..0d0f28634 100644 --- a/sphinx/theming.py +++ b/sphinx/theming.py @@ -5,7 +5,7 @@ Theming support for HTML builders. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 46408d48a..f5ca564df 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -5,14 +5,13 @@ Utility functions for Sphinx. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os import re import sys -import stat import time import errno import types @@ -24,8 +23,15 @@ import traceback from os import path import docutils +from docutils.utils import relative_path + +import jinja2 + import sphinx +# Errnos that we need. +EEXIST = getattr(errno, 'EEXIST', 0) +ENOENT = getattr(errno, 'ENOENT', 0) # Generally useful regular expressions. ws_re = re.compile(r'\s+') @@ -70,7 +76,7 @@ def ensuredir(path): os.makedirs(path) except OSError, err: # 0 for Jython/Win32 - if err.errno not in [0, getattr(errno, 'EEXIST', 0)]: + if err.errno not in [0, EEXIST]: raise @@ -98,38 +104,45 @@ def walk(top, topdown=True, followlinks=False): yield top, dirs, nondirs -def get_matching_docs(dirname, suffix, exclude_docs=(), exclude_dirs=(), - exclude_trees=(), exclude_dirnames=()): +def get_matching_files(dirname, exclude_matchers=()): + """ + Get all file names in a directory, recursively. + + Exclude files and dirs matching some matcher in *exclude_matchers*. + """ + # dirname is a normalized absolute path. + dirname = path.normpath(path.abspath(dirname)) + dirlen = len(dirname) + 1 # exclude final os.path.sep + + for root, dirs, files in walk(dirname, followlinks=True): + relativeroot = root[dirlen:] + + qdirs = enumerate(path.join(relativeroot, dn).replace(os.path.sep, SEP) + for dn in dirs) + qfiles = enumerate(path.join(relativeroot, fn).replace(os.path.sep, SEP) + for fn in files) + for matcher in exclude_matchers: + qdirs = [entry for entry in qdirs if not matcher(entry[1])] + qfiles = [entry for entry in qfiles if not matcher(entry[1])] + + dirs[:] = sorted(dirs[i] for (i, _) in qdirs) + + for i, filename in sorted(qfiles): + yield filename + + +def get_matching_docs(dirname, suffix, exclude_matchers=()): """ Get all file names (without suffix) matching a suffix in a directory, recursively. - Exclude docs in *exclude_docs*, exclude dirs in *exclude_dirs*, - prune dirs in *exclude_trees*, prune dirnames in *exclude_dirnames*. + Exclude files and dirs matching a pattern in *exclude_patterns*. """ - pattern = '*' + suffix - # dirname is a normalized absolute path. - dirname = path.normpath(path.abspath(dirname)) - dirlen = len(dirname) + 1 # exclude slash - for root, dirs, files in walk(dirname, followlinks=True): - if root[dirlen:] in exclude_dirs: + suffixpattern = '*' + suffix + for filename in get_matching_files(dirname, exclude_matchers): + if not fnmatch.fnmatch(filename, suffixpattern): continue - if root[dirlen:] in exclude_trees: - del dirs[:] - continue - dirs.sort() - files.sort() - for prunedir in exclude_dirnames: - if prunedir in dirs: - dirs.remove(prunedir) - for sfile in files: - if not fnmatch.fnmatch(sfile, pattern): - continue - qualified_name = path.join(root[dirlen:], sfile[:-len(suffix)]) - qualified_name = qualified_name.replace(os.path.sep, SEP) - if qualified_name in exclude_docs: - continue - yield qualified_name + yield filename[:-len(suffix)] def mtimes_of_files(dirnames, suffix): @@ -216,6 +229,7 @@ def save_traceback(): os.write(fd, '# Sphinx version: %s\n' % sphinx.__version__) os.write(fd, '# Docutils version: %s %s\n' % (docutils.__version__, docutils.__version_details__)) + os.write(fd, '# Jinja2 version: %s\n' % jinja2.__version__) os.write(fd, exc) os.close(fd) return path @@ -267,15 +281,25 @@ def _translate_pattern(pat): res += re.escape(c) return res + '$' +def compile_matchers(patterns): + return [re.compile(_translate_pattern(pat)).match for pat in patterns] + _pat_cache = {} +def patmatch(name, pat): + """ + Return if name matches pat. Adapted from fnmatch module. + """ + if pat not in _pat_cache: + _pat_cache[pat] = re.compile(_translate_pattern(pat)) + return _pat_cache[pat].match(name) + def patfilter(names, pat): """ Return the subset of the list NAMES that match PAT. Adapted from fnmatch module. """ - result = [] if pat not in _pat_cache: _pat_cache[pat] = re.compile(_translate_pattern(pat)) match = _pat_cache[pat].match @@ -406,7 +430,6 @@ def movefile(source, dest): def copytimes(source, dest): """Copy a file's modification times.""" st = os.stat(source) - mode = stat.S_IMODE(st.st_mode) if hasattr(os, 'utime'): os.utime(dest, (st.st_atime, st.st_mtime)) @@ -421,9 +444,16 @@ def copyfile(source, dest): pass -def copy_static_entry(source, target, builder, context={}): +def copy_static_entry(source, targetdir, builder, context={}, + exclude_matchers=(), level=0): + if exclude_matchers: + relpath = relative_path(builder.srcdir, source) + for matcher in exclude_matchers: + if matcher(relpath): + return if path.isfile(source): - if source.lower().endswith('_t'): + target = path.join(targetdir, path.basename(source)) + if source.lower().endswith('_t') and builder.templates: # templated! fsrc = open(source, 'rb') fdst = open(target[:-2], 'wb') @@ -433,13 +463,27 @@ def copy_static_entry(source, target, builder, context={}): else: copyfile(source, target) elif path.isdir(source): - if source in builder.config.exclude_dirnames: - return - if path.exists(target): - shutil.rmtree(target) - shutil.copytree(source, target) + if level == 0: + for entry in os.listdir(source): + if entry.startswith('.'): + continue + copy_static_entry(path.join(source, entry), targetdir, + builder, context, level=1, + exclude_matchers=exclude_matchers) + else: + target = path.join(targetdir, path.basename(source)) + if path.exists(target): + shutil.rmtree(target) + shutil.copytree(source, target) +def clean_astext(node): + """Like node.astext(), but ignore images.""" + node = node.deepcopy() + for img in node.traverse(docutils.nodes.image): + img['alt'] = '' + return node.astext() + def split_explicit_title(text): """Split role content into title and target, if given.""" @@ -448,6 +492,16 @@ def split_explicit_title(text): return True, match.group(1), match.group(2) return False, text, text + +try: + any = any +except NameError: + def any(gen): + for i in gen: + if i: + return True + return False + # monkey-patch Node.traverse to get more speed # traverse() is called so many times during a build that it saves # on average 20-25% overall build time! diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py index c00f9d4ec..885a458e3 100644 --- a/sphinx/util/compat.py +++ b/sphinx/util/compat.py @@ -5,7 +5,7 @@ Stuff for docutils compatibility. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/console.py b/sphinx/util/console.py index 4dcdd1c8d..bd2851fa4 100644 --- a/sphinx/util/console.py +++ b/sphinx/util/console.py @@ -5,7 +5,7 @@ Format colored console output. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/docstrings.py b/sphinx/util/docstrings.py index ea03340a0..538af653e 100644 --- a/sphinx/util/docstrings.py +++ b/sphinx/util/docstrings.py @@ -5,7 +5,7 @@ Utilities for docstring processing. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 9cec5deca..4f1cf9228 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -5,7 +5,7 @@ Helpers for inspecting Python modules. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py index 8c760b68c..e357128c2 100644 --- a/sphinx/util/jsdump.py +++ b/sphinx/util/jsdump.py @@ -6,7 +6,7 @@ This module implements a simple JavaScript serializer. Uses the basestring encode function from simplejson by Bob Ippolito. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/png.py b/sphinx/util/png.py index 805a6bdc3..2cb2aa9d8 100644 --- a/sphinx/util/png.py +++ b/sphinx/util/png.py @@ -5,7 +5,7 @@ PNG image manipulation helpers. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py index 49af46829..021943072 100644 --- a/sphinx/util/pycompat.py +++ b/sphinx/util/pycompat.py @@ -5,7 +5,7 @@ Stuff for Python version compatibility. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/tags.py b/sphinx/util/tags.py index c08e5e5a0..3f98e0ac1 100644 --- a/sphinx/util/tags.py +++ b/sphinx/util/tags.py @@ -3,7 +3,7 @@ sphinx.util.tags ~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py index f495243cb..737908295 100644 --- a/sphinx/util/texescape.py +++ b/sphinx/util/texescape.py @@ -5,7 +5,7 @@ TeX escaping helper. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -99,8 +99,9 @@ tex_replacements = [ ] tex_escape_map = {} -tex_hl_escape_map = {} -_new_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'} +tex_hl_escape_map_old = {} # replacement map for Pygments <= 1.1 +tex_hl_escape_map_new = {} # replacement map for Pygments >= 1.2 +_old_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'} def init(): for a, b in tex_replacements: @@ -108,4 +109,5 @@ def init(): for a, b in tex_replacements: if a in u'[]{}\\': continue - tex_hl_escape_map[ord(a)] = b.translate(_new_cmd_chars) + tex_hl_escape_map_new[ord(a)] = b + tex_hl_escape_map_old[ord(a)] = b.translate(_old_cmd_chars) diff --git a/sphinx/writers/__init__.py b/sphinx/writers/__init__.py index 7bb8cad91..da3b9abf5 100644 --- a/sphinx/writers/__init__.py +++ b/sphinx/writers/__init__.py @@ -5,6 +5,6 @@ Custom docutils writers. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 851aa909c..c99fc28e5 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -5,7 +5,7 @@ docutils writers handling Sphinx' custom nodes. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -501,6 +501,13 @@ class SmartyPantsHTMLTranslator(HTMLTranslator): finally: self.no_smarty -= 1 + def visit_literal_block(self, node): + self.no_smarty += 1 + try: + HTMLTranslator.visit_literal_block(self, node) + finally: + self.no_smarty -= 1 + def visit_literal_emphasis(self, node): self.no_smarty += 1 self.visit_emphasis(node) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 700867796..35e393c54 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -8,7 +8,7 @@ Much of this code is adapted from Dave Kuhlman's "docpy" writer from his docutils sandbox. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -180,8 +180,6 @@ class LaTeXTranslator(nodes.NodeVisitor): 'pointsize': builder.config.latex_font_size, # if empty, the title is set to the first section title 'title': document.settings.title, - 'date': ustrftime(builder.config.today_fmt - or _('%B %d, %Y')), 'release': builder.config.release, 'author': document.settings.author, 'releasename': _('Release'), @@ -194,6 +192,11 @@ class LaTeXTranslator(nodes.NodeVisitor): else: docclass = builder.config.latex_docclass.get('manual', 'report') self.elements['docclass'] = docclass + if builder.config.today: + self.elements['date'] = builder.config.today + else: + self.elements['date'] = ustrftime(builder.config.today_fmt + or _('%B %d, %Y')) if builder.config.latex_logo: self.elements['logo'] = '\\includegraphics{%s}\\par' % \ path.basename(builder.config.latex_logo) @@ -250,6 +253,9 @@ class LaTeXTranslator(nodes.NodeVisitor): return (HEADER % self.elements + self.highlighter.get_stylesheet() + u''.join(self.body) + FOOTER % self.elements) + def idescape(self, id): + return str(unicode(id).translate(tex_escape_map)) + def visit_document(self, node): self.footnotestack.append(self.collect_footnotes(node)) self.curfilestack.append(node.get('docname', '')) @@ -463,7 +469,7 @@ class LaTeXTranslator(nodes.NodeVisitor): d = self.descstack[-1] d.cls = d.cls.rstrip('.') if node.parent['desctype'] != 'describe' and node['ids']: - hyper = '\\hypertarget{%s}{}' % node['ids'][0] + hyper = '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) else: hyper = '' if d.count == 0: @@ -754,7 +760,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_term(self, node): ctx = '] \\leavevmode' if node.has_key('ids') and node['ids']: - ctx += '\\hypertarget{%s}{}' % node['ids'][0] + ctx += '\\hypertarget{%s}{}' % self.idescape(node['ids'][0]) self.body.append('\\item[') self.context.append(ctx) def depart_term(self, node): diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index 9e7bb63d2..84dc4b38a 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -5,7 +5,7 @@ Custom docutils writer for plain text. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/root/_static/README b/tests/root/_static/README index d517219be..9e1ec3569 100644 --- a/tests/root/_static/README +++ b/tests/root/_static/README @@ -1 +1 @@ -This placeholder file is there because Mercurial ignores empty directories. +This whole directory is there to test html_static_path. diff --git a/tests/root/_static/excluded.css b/tests/root/_static/excluded.css new file mode 100644 index 000000000..03c941a44 --- /dev/null +++ b/tests/root/_static/excluded.css @@ -0,0 +1 @@ +/* This file should be excluded from being copied over */ diff --git a/tests/root/_static/subdir/foo.css b/tests/root/_static/subdir/foo.css new file mode 100644 index 000000000..9427981d6 --- /dev/null +++ b/tests/root/_static/subdir/foo.css @@ -0,0 +1 @@ +/* Stub file */ diff --git a/tests/root/_templates/contentssb.html b/tests/root/_templates/contentssb.html new file mode 100644 index 000000000..9951d3c35 --- /dev/null +++ b/tests/root/_templates/contentssb.html @@ -0,0 +1,2 @@ +{# sidebar only for contents document #} +

Contents sidebar

\ No newline at end of file diff --git a/tests/root/_templates/customsb.html b/tests/root/_templates/customsb.html new file mode 100644 index 000000000..cc88b8cfb --- /dev/null +++ b/tests/root/_templates/customsb.html @@ -0,0 +1,2 @@ +{# custom sidebar template #} +

Custom sidebar

diff --git a/tests/root/_templates/layout.html b/tests/root/_templates/layout.html index e8920025d..7f290fc1e 100644 --- a/tests/root/_templates/layout.html +++ b/tests/root/_templates/layout.html @@ -1,5 +1,8 @@ {% extends "!layout.html" %} {% block extrahead %} +{# html_context variable from conf.py #} +{# html_context variable from confoverrides (as if given on cmdline) #} + {{ super() }} {% endblock %} diff --git a/tests/root/conf.py b/tests/root/conf.py index fd82be7d7..a3783511b 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -4,9 +4,9 @@ import sys, os sys.path.append(os.path.abspath('.')) -extensions = ['ext', 'sphinx.ext.autodoc', 'sphinx.ext.jsmath', - 'sphinx.ext.coverage', 'sphinx.ext.todo', - 'sphinx.ext.autosummary'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.todo', + 'sphinx.ext.coverage', 'sphinx.ext.autosummary', + 'sphinx.ext.doctest', 'sphinx.ext.extlinks', 'ext'] jsmath_path = 'dummy.js' @@ -16,13 +16,13 @@ master_doc = 'contents' source_suffix = '.txt' project = 'Sphinx ' -copyright = '2008, Georg Brandl & Team' +copyright = '2010, Georg Brandl & Team' # If this is changed, remember to update the versionchanges! version = '0.6' release = '0.6alpha1' today_fmt = '%B %d, %Y' #unused_docs = [] -exclude_trees = ['_build'] +exclude_patterns = ['_build', '**/excluded.*'] keep_warnings = True pygments_style = 'sphinx' @@ -31,11 +31,11 @@ rst_epilog = '.. |subst| replace:: global substitution' html_theme = 'testtheme' html_theme_path = ['.'] html_theme_options = {'testopt': 'testoverride'} - +html_sidebars = {'**': 'customsb.html', 'contents': 'contentssb.html'} html_style = 'default.css' -html_static_path = ['_static'] +html_static_path = ['_static', 'templated.css_t'] html_last_updated_fmt = '%b %d, %Y' -html_context = {'hckey': 'hcval'} +html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'} htmlhelp_basename = 'SphinxTestsdoc' @@ -53,6 +53,9 @@ coverage_c_regexes = {'cfunction': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)'} autosummary_generate = ['autosummary'] +extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '), + 'pyurl': ('http://python.org/%s', None)} + # modify tags from conf.py tags.add('confpytag') diff --git a/tests/root/contents.txt b/tests/root/contents.txt index 6133f8873..c9005d575 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -22,6 +22,9 @@ Contents: autodoc autosummary metadata + extensions + doctest + extensions Python diff --git a/tests/root/doctest.txt b/tests/root/doctest.txt new file mode 100644 index 000000000..35cdd589c --- /dev/null +++ b/tests/root/doctest.txt @@ -0,0 +1,120 @@ +Testing the doctest extension +============================= + +Simple doctest blocks +--------------------- + +>>> 1+1 +2 +>>> 1/0 +Traceback (most recent call last): + ... +ZeroDivisionError: integer division or modulo by zero + + +Special directives +------------------ + +* doctest + + .. doctest:: + + >>> 1+1 + 2 + >>> 1/0 + Traceback (most recent call last): + ... + ZeroDivisionError: integer division or modulo by zero + +* testcode/testoutput + + .. testcode:: + + print 1+1 + + .. testoutput:: + + 2 + + .. testcode:: + + 1/0 + + .. testoutput:: + + Traceback (most recent call last): + ... + ZeroDivisionError: integer division or modulo by zero + +* testsetup + + .. testsetup:: * + + from math import floor + + .. doctest:: + + >>> floor(1.2) + 1.0 + + .. testcode:: + + print floor(1.2) + + .. testoutput:: + + 1.0 + + >>> floor(1.2) + 1.0 + +* options for testcode/testoutput blocks + + .. testcode:: + :hide: + + print 'Output text.' + + .. testoutput:: + :hide: + :options: +NORMALIZE_WHITESPACE + + Output text. + +* grouping + + .. testsetup:: group1 + + from math import ceil + + ``ceil`` is now known in "group1", but not in others. + + .. doctest:: group1 + + >>> ceil(0.8) + 1.0 + + .. doctest:: group2 + + >>> ceil(0.8) + Traceback (most recent call last): + ... + NameError: name 'ceil' is not defined + + Interleaving testcode/testoutput: + + .. testcode:: group1 + + print ceil(0.8) + + .. testcode:: group2 + + print floor(0.8) + + .. testoutput:: group1 + + 1.0 + + .. testoutput:: group2 + + 0.0 diff --git a/tests/root/extensions.txt b/tests/root/extensions.txt new file mode 100644 index 000000000..96b1f8ef3 --- /dev/null +++ b/tests/root/extensions.txt @@ -0,0 +1,28 @@ +Test for diverse extensions +=========================== + +extlinks +-------- + +Test diverse links: :issue:`1000` and :pyurl:`dev/`, also with +:issue:`explicit caption <1042>`. + + +todo +---- + +.. todo:: + + Test the todo extension. + +.. todo:: + + Test with |sub| (see #286). + +.. |sub| replace:: substitution references + + +list of all todos +^^^^^^^^^^^^^^^^^ + +.. todolist:: diff --git a/tests/root/includes.txt b/tests/root/includes.txt index da36503b3..cb1708403 100644 --- a/tests/root/includes.txt +++ b/tests/root/includes.txt @@ -49,6 +49,16 @@ Literalinclude options :prepend: START CODE :append: END CODE +.. cssclass:: inc-tab3 +.. literalinclude:: tabs.inc + :tab-width: 3 + :language: text + +.. cssclass:: inc-tab8 +.. literalinclude:: tabs.inc + :tab-width: 8 + :language: python + Test if dedenting before parsing works. .. highlight:: python @@ -56,3 +66,11 @@ Test if dedenting before parsing works. .. cssclass:: inc-pyobj-dedent .. literalinclude:: literal.inc :pyobject: Bar.baz + +Docutils include with "literal" +=============================== + +While not recommended, it should work (and leave quotes alone). + +.. include:: quotes.inc + :literal: diff --git a/tests/root/markup.txt b/tests/root/markup.txt index 32b037ee1..cdb8c5fcd 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -162,6 +162,7 @@ Index markup .. index:: single: entry pair: entry; pair + double: entry; double triple: index; entry; triple keyword: with diff --git a/tests/root/quotes.inc b/tests/root/quotes.inc new file mode 100644 index 000000000..276cc56ba --- /dev/null +++ b/tests/root/quotes.inc @@ -0,0 +1 @@ +Testing "quotes" in literal 'included' text. diff --git a/tests/root/subdir/excluded.txt b/tests/root/subdir/excluded.txt new file mode 100644 index 000000000..5df3139b4 --- /dev/null +++ b/tests/root/subdir/excluded.txt @@ -0,0 +1,2 @@ +Excluded file -- should *not* be read as source +----------------------------------------------- diff --git a/tests/root/tabs.inc b/tests/root/tabs.inc new file mode 100644 index 000000000..20b51820d --- /dev/null +++ b/tests/root/tabs.inc @@ -0,0 +1,5 @@ +Tabs include file test +---------------------- + +The next line has a tab: +-| |- diff --git a/tests/root/templated.css_t b/tests/root/templated.css_t new file mode 100644 index 000000000..72ddb807c --- /dev/null +++ b/tests/root/templated.css_t @@ -0,0 +1,2 @@ +/* Stub file, templated */ +{{ sphinx_version }} diff --git a/tests/run.py b/tests/run.py index 4cc23442a..0cb41442c 100755 --- a/tests/run.py +++ b/tests/run.py @@ -6,7 +6,7 @@ This script runs the Sphinx unit test suite. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_application.py b/tests/test_application.py index a113c2359..3d287a57c 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -5,7 +5,7 @@ Test the Sphinx class. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 687fbd0d7..b505b06ae 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -6,7 +6,7 @@ Test the autodoc extension. This tests mainly the Documenters; the auto directives are tested in a test source file translated by test_build. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -382,7 +382,10 @@ def test_generate(): ('attribute', 'test_autodoc.Class.descr'), ('attribute', 'test_autodoc.Class.attr'), ('attribute', 'test_autodoc.Class.docattr'), - ('attribute', 'test_autodoc.Class.udocattr')]) + ('attribute', 'test_autodoc.Class.udocattr'), + ('attribute', 'test_autodoc.Class.inst_attr_comment'), + ('attribute', 'test_autodoc.Class.inst_attr_string') + ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True @@ -403,7 +406,7 @@ def test_generate(): assert_result_contains(' :platform: Platform', 'module', 'test_autodoc') # test if __all__ is respected for modules options.members = ALL - assert_result_contains('.. class:: Class', 'module', 'test_autodoc') + assert_result_contains('.. class:: Class(arg)', 'module', 'test_autodoc') try: assert_result_contains('.. exception:: CustomEx', 'module', 'test_autodoc') @@ -499,6 +502,13 @@ class Class(Base): udocattr = 'quux' u"""should be documented as well - süß""" + def __init__(self, arg): + #: a documented instance attribute + self.inst_attr_comment = None + self.inst_attr_string = None + """a documented instance attribute""" + + class CustomDict(dict): """Docstring.""" diff --git a/tests/test_autosummary.py b/tests/test_autosummary.py index 276b93557..7e3093676 100644 --- a/tests/test_autosummary.py +++ b/tests/test_autosummary.py @@ -5,7 +5,7 @@ Test the autosummary extension. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_build.py b/tests/test_build.py index 6d0cb9334..b282b6291 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -5,7 +5,7 @@ Test the entire build process with the test root. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -13,28 +13,19 @@ import os import re import sys import difflib -import htmlentitydefs from StringIO import StringIO from subprocess import Popen, PIPE -from util import * -from etree13 import ElementTree as ET - -try: - import pygments -except ImportError: - pygments = None - -from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.builders.latex import LaTeXBuilder from sphinx.writers.latex import LaTeXTranslator +from util import * + def teardown_module(): (test_root / '_build').rmtree(True) -html_warnfile = StringIO() latex_warnfile = StringIO() ENV_WARNINGS = """\ @@ -46,155 +37,11 @@ included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option %(root)s/includes.txt:4: WARNING: download file not readable: nonexisting.png """ -HTML_WARNINGS = ENV_WARNINGS + """\ -%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.*' -%(root)s/markup.txt:: WARNING: invalid index entry u'' -%(root)s/markup.txt:: WARNING: invalid pair index entry u'' -%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; ' -""" - LATEX_WARNINGS = ENV_WARNINGS + """\ None:None: WARNING: no matching candidate for image URI u'foo.*' WARNING: invalid pair index entry u'' """ -HTML_XPATH = { - 'images.html': { - ".//img[@src='_images/img.png']": '', - ".//img[@src='_images/img1.png']": '', - ".//img[@src='_images/simg.png']": '', - ".//object[@data='_images/svgimg.svg']": '', - ".//embed[@src='_images/svgimg.svg']": '', - }, - 'subdir/images.html': { - ".//img[@src='../_images/img1.png']": '', - ".//img[@src='../_images/rimg.png']": '', - }, - 'subdir/includes.html': { - ".//a[@href='../_downloads/img.png']": '', - }, - 'includes.html': { - ".//pre": u'Max Strauß', - ".//a[@href='_downloads/img.png']": '', - ".//a[@href='_downloads/img1.png']": '', - }, - 'autodoc.html': { - ".//dt[@id='test_autodoc.Class']": '', - ".//dt[@id='test_autodoc.function']/em": r'\*\*kwds', - ".//dd": r'Return spam\.', - }, - 'markup.html': { - ".//meta[@name='author'][@content='Me']": '', - ".//meta[@name='keywords'][@content='docs, sphinx']": '', - ".//a[@href='contents.html#ref1']": '', - ".//div[@id='label']": '', - ".//span[@class='option']": '--help', - ".//p": 'A global substitution.', - ".//p": 'In HTML.', - ".//p": 'In both.', - ".//p": 'Always present', - ".//title": 'set by title directive', - ".//span[@class='pre']": 'CFunction()', - }, - 'desc.html': { - ".//dt[@id='mod.Cls.meth1']": '', - ".//dt[@id='errmod.Error']": '', - ".//a[@href='#mod.Cls']": '', - ".//dl[@class='userdesc']": '', - ".//dt[@id='userdescrole-myobj']": '', - ".//a[@href='#userdescrole-myobj']": '', - }, - 'contents.html': { - ".//meta[@name='hc'][@content='hcval']": '', - ".//meta[@name='testopt'][@content='testoverride']": '', - #".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only - ".//td[@class='label']": '', - ".//li[@class='toctree-l1']/a": 'Testing various markup', - ".//li[@class='toctree-l2']/a": 'Admonitions', - ".//title": 'Sphinx ', - ".//div[@class='footer']": 'Georg Brandl & Team', - ".//a[@href='http://python.org/']": '', - }, - 'bom.html': { - ".//title": " File with UTF-8 BOM", - }, - '_static/statictmpl.html': { - ".//project": 'Sphinx ', - }, -} - -if pygments: - HTML_XPATH['includes.html'].update({ - ".//pre/span[@class='s']": u'üöä', - ".//div[@class='inc-pyobj1 highlight-text']/div/pre": - r'^class Foo:\n pass\n\s*$', - ".//div[@class='inc-pyobj2 highlight-text']/div/pre": - r'^ def baz\(\):\n pass\n\s*$', - ".//div[@class='inc-lines highlight-text']/div/pre": - r'^class Foo:\n pass\nclass Bar:\n$', - ".//div[@class='inc-startend highlight-text']/div/pre": - ur'^foo = u"Including Unicode characters: üöä"\n$', - ".//div[@class='inc-preappend highlight-text']/div/pre": - r'(?m)^START CODE$', - ".//div[@class='inc-pyobj-dedent highlight-python']/div/pre/span": - r'def', - }) - HTML_XPATH['subdir/includes.html'].update({ - ".//pre/span": 'line 1', - ".//pre/span": 'line 2', - }) - -class NslessParser(ET.XMLParser): - """XMLParser that throws away namespaces in tag names.""" - - def _fixname(self, key): - try: - return self._names[key] - except KeyError: - name = key - br = name.find('}') - if br > 0: - name = name[br+1:] - self._names[key] = name = self._fixtext(name) - return name - - -def check_xpath(etree, fname, path, check): - nodes = list(etree.findall(path)) - assert nodes != [], ('did not find any node matching xpath ' - '%r in file %s' % (path, fname)) - if hasattr(check, '__call__'): - check(nodes) - elif not check: - # only check for node presence - pass - else: - rex = re.compile(check) - for node in nodes: - if node.text and rex.search(node.text): - break - else: - assert False, ('%r not found in any node matching ' - 'path %s in %s: %r' % (check, path, fname, - [node.text for node in nodes])) - -@gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True, - tags=['testtag']) -def test_html(app): - app.builder.build_all() - html_warnings = html_warnfile.getvalue().replace(os.sep, '/') - html_warnings_exp = HTML_WARNINGS % {'root': app.srcdir} - assert html_warnings == html_warnings_exp, 'Warnings don\'t match:\n' + \ - '\n'.join(difflib.ndiff(html_warnings_exp.splitlines(), - html_warnings.splitlines())) - - for fname, paths in HTML_XPATH.iteritems(): - parser = NslessParser() - parser.entity.update(htmlentitydefs.entitydefs) - etree = ET.parse(os.path.join(app.outdir, fname), parser) - for path, check in paths.iteritems(): - yield check_xpath, etree, fname, path, check - @with_app(buildername='latex', warning=latex_warnfile, cleanenv=True) def test_latex(app): diff --git a/tests/test_build_html.py b/tests/test_build_html.py new file mode 100644 index 000000000..25f733a48 --- /dev/null +++ b/tests/test_build_html.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +""" + test_build_html + ~~~~~~~~~~~~~~~ + + Test the HTML builder and check output against XPath. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +import re +import difflib +import htmlentitydefs +from StringIO import StringIO + +try: + import pygments +except ImportError: + pygments = None + +from sphinx import __version__ +from util import * +from test_build import ENV_WARNINGS +from etree13 import ElementTree as ET + + +def teardown_module(): + (test_root / '_build').rmtree(True) + + +html_warnfile = StringIO() + +HTML_WARNINGS = ENV_WARNINGS + """\ +%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.*' +%(root)s/markup.txt:: WARNING: invalid index entry u'' +%(root)s/markup.txt:: WARNING: invalid pair index entry u'' +%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; ' +""" + +HTML_XPATH = { + 'images.html': { + ".//img[@src='_images/img.png']": '', + ".//img[@src='_images/img1.png']": '', + ".//img[@src='_images/simg.png']": '', + ".//object[@data='_images/svgimg.svg']": '', + ".//embed[@src='_images/svgimg.svg']": '', + }, + 'subdir/images.html': { + ".//img[@src='../_images/img1.png']": '', + ".//img[@src='../_images/rimg.png']": '', + }, + 'subdir/includes.html': { + ".//a[@href='../_downloads/img.png']": '', + }, + 'includes.html': { + ".//pre": u'Max Strauß', + ".//a[@href='_downloads/img.png']": '', + ".//a[@href='_downloads/img1.png']": '', + ".//pre": u'"quotes"', + ".//pre": u"'included'", + }, + 'autodoc.html': { + ".//dt[@id='test_autodoc.Class']": '', + ".//dt[@id='test_autodoc.function']/em": r'\*\*kwds', + ".//dd": r'Return spam\.', + }, + 'markup.html': { + ".//meta[@name='author'][@content='Me']": '', + ".//meta[@name='keywords'][@content='docs, sphinx']": '', + ".//a[@href='contents.html#ref1']": '', + ".//div[@id='label']": '', + ".//span[@class='option']": '--help', + ".//p": 'A global substitution.', + ".//p": 'In HTML.', + ".//p": 'In both.', + ".//p": 'Always present', + ".//title": 'set by title directive', + ".//span[@class='pre']": 'CFunction()', + }, + 'desc.html': { + ".//dt[@id='mod.Cls.meth1']": '', + ".//dt[@id='errmod.Error']": '', + ".//a[@href='#mod.Cls']": '', + ".//dl[@class='userdesc']": '', + ".//dt[@id='userdescrole-myobj']": '', + ".//a[@href='#userdescrole-myobj']": '', + # custom sidebar + ".//h4": 'Custom sidebar', + }, + 'contents.html': { + ".//meta[@name='hc'][@content='hcval']": '', + ".//meta[@name='hc_co'][@content='hcval_co']": '', + ".//meta[@name='testopt'][@content='testoverride']": '', + #".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only + ".//td[@class='label']": '', + ".//li[@class='toctree-l1']/a": 'Testing various markup', + ".//li[@class='toctree-l2']/a": 'Admonitions', + ".//title": 'Sphinx ', + ".//div[@class='footer']": 'Georg Brandl & Team', + ".//a[@href='http://python.org/']": '', + # custom sidebar only for contents + ".//h4": 'Contents sidebar', + }, + 'bom.html': { + ".//title": " File with UTF-8 BOM", + }, + 'extensions.html': { + ".//a[@href='http://python.org/dev/']": "http://python.org/dev/", + ".//a[@href='http://bugs.python.org/issue1000']": "issue 1000", + ".//a[@href='http://bugs.python.org/issue1042']": "explicit caption", + }, + '_static/statictmpl.html': { + ".//project": 'Sphinx ', + }, +} + +if pygments: + HTML_XPATH['includes.html'].update({ + ".//pre/span[@class='s']": u'üöä', + ".//div[@class='inc-pyobj1 highlight-text']//pre": + r'^class Foo:\n pass\n\s*$', + ".//div[@class='inc-pyobj2 highlight-text']//pre": + r'^ def baz\(\):\n pass\n\s*$', + ".//div[@class='inc-lines highlight-text']//pre": + r'^class Foo:\n pass\nclass Bar:\n$', + ".//div[@class='inc-startend highlight-text']//pre": + ur'^foo = u"Including Unicode characters: üöä"\n$', + ".//div[@class='inc-preappend highlight-text']//pre": + r'(?m)^START CODE$', + ".//div[@class='inc-pyobj-dedent highlight-python']//span": + r'def', + ".//div[@class='inc-tab3 highlight-text']//pre": + r'-| |-', + ".//div[@class='inc-tab8 highlight-python']//pre": + r'-| |-', + }) + HTML_XPATH['subdir/includes.html'].update({ + ".//pre/span": 'line 1', + ".//pre/span": 'line 2', + }) + +class NslessParser(ET.XMLParser): + """XMLParser that throws away namespaces in tag names.""" + + def _fixname(self, key): + try: + return self._names[key] + except KeyError: + name = key + br = name.find('}') + if br > 0: + name = name[br+1:] + self._names[key] = name = self._fixtext(name) + return name + + +def check_xpath(etree, fname, path, check): + nodes = list(etree.findall(path)) + assert nodes != [], ('did not find any node matching xpath ' + '%r in file %s' % (path, fname)) + if hasattr(check, '__call__'): + check(nodes) + elif not check: + # only check for node presence + pass + else: + rex = re.compile(check) + for node in nodes: + if node.text and rex.search(node.text): + break + else: + assert False, ('%r not found in any node matching ' + 'path %s in %s: %r' % (check, path, fname, + [node.text for node in nodes])) + +def check_static_entries(outdir): + staticdir = outdir / '_static' + assert staticdir.isdir() + # a file from a directory entry in html_static_path + assert (staticdir / 'README').isfile() + # a directory from a directory entry in html_static_path + assert (staticdir / 'subdir' / 'foo.css').isfile() + # a file from a file entry in html_static_path + assert (staticdir / 'templated.css').isfile() + assert (staticdir / 'templated.css').text().splitlines()[1] == __version__ + # a file from _static, but matches exclude_patterns + assert not (staticdir / 'excluded.css').exists() + +@gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True, + confoverrides={'html_context.hckey_co': 'hcval_co'}, + tags=['testtag']) +def test_html(app): + app.builder.build_all() + html_warnings = html_warnfile.getvalue().replace(os.sep, '/') + html_warnings_exp = HTML_WARNINGS % {'root': app.srcdir} + assert html_warnings == html_warnings_exp, 'Warnings don\'t match:\n' + \ + '\n'.join(difflib.ndiff(html_warnings_exp.splitlines(), + html_warnings.splitlines())) + + for fname, paths in HTML_XPATH.iteritems(): + parser = NslessParser() + parser.entity.update(htmlentitydefs.entitydefs) + etree = ET.parse(os.path.join(app.outdir, fname), parser) + for path, check in paths.iteritems(): + yield check_xpath, etree, fname, path, check + + check_static_entries(app.builder.outdir) diff --git a/tests/test_config.py b/tests/test_config.py index b3aa4eeaa..b1c50f704 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,7 +6,7 @@ Test the sphinx.config.Config class and its handling in the Application class. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -30,8 +30,8 @@ def test_core_config(app): assert cfg.latex_elements['docclass'] == 'scrartcl' # simple default values - assert 'exclude_dirs' not in cfg.__dict__ - assert cfg.exclude_dirs == [] + assert 'locale_dirs' not in cfg.__dict__ + assert cfg.locale_dirs == [] assert cfg.show_authors == False # complex default values diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 369788a19..282db6776 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -5,7 +5,7 @@ Test the coverage builder. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_doctest.py b/tests/test_doctest.py new file mode 100644 index 000000000..b4b6bbe21 --- /dev/null +++ b/tests/test_doctest.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +""" + test_doctest + ~~~~~~~~~~~~ + + Test the doctest extension. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import sys +import StringIO + +from util import * + +status = StringIO.StringIO() + +@with_app(buildername='doctest', status=status) +def test_build(app): + app.builder.build_all() + if app.statuscode != 0: + print >>sys.stderr, status.getvalue() + assert False, 'failures in doctests' diff --git a/tests/test_env.py b/tests/test_env.py index a06656d69..0090d6b6f 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -5,7 +5,7 @@ Test the BuildEnvironment class. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -43,6 +43,8 @@ def test_first_update(): for docname in it: # the generator does all the work docnames.add(docname) assert docnames == env.found_docs == set(env.all_docs) + # test if exclude_patterns works ok + assert 'subdir/excluded' not in env.found_docs def test_images(): assert warning_emitted('images.txt', 'image file not readable: foo.png') diff --git a/tests/test_highlighting.py b/tests/test_highlighting.py index 7c303283b..7496690be 100644 --- a/tests/test_highlighting.py +++ b/tests/test_highlighting.py @@ -5,7 +5,7 @@ Test the Pygments highlighting bridge. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_i18n.py b/tests/test_i18n.py index 94648727e..135cc3e11 100644 --- a/tests/test_i18n.py +++ b/tests/test_i18n.py @@ -5,7 +5,7 @@ Test locale features. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_markup.py b/tests/test_markup.py index 03c421a13..fcd5c307e 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -5,7 +5,7 @@ Test various Sphinx-specific markup extensions. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 9675947ac..a6b0e7f5a 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -5,7 +5,7 @@ Test our handling of metadata in files with bibliographic metadata. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index 1a76fbd26..11782fb66 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -5,7 +5,7 @@ Test the sphinx.quickstart module. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_search.py b/tests/test_search.py index 3dd043bc7..15257aebd 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -5,7 +5,7 @@ Test the search index builder. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_theming.py b/tests/test_theming.py index cdaf2baff..0cad0f8d1 100644 --- a/tests/test_theming.py +++ b/tests/test_theming.py @@ -5,7 +5,7 @@ Test the Theme class. - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -24,8 +24,8 @@ def test_theme_api(app): # test Theme class API assert set(Theme.themes.keys()) == \ - set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', - 'traditional', 'testtheme', 'ziptheme', 'epub']) + set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', 'haiku', + 'traditional', 'testtheme', 'ziptheme', 'epub', 'nature']) assert Theme.themes['testtheme'][1] is None assert isinstance(Theme.themes['ziptheme'][1], zipfile.ZipFile) diff --git a/tests/util.py b/tests/util.py index 4bb6a6538..2b3807224 100644 --- a/tests/util.py +++ b/tests/util.py @@ -3,7 +3,7 @@ Sphinx test suite utilities ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/utils/check_sources.py b/utils/check_sources.py index 7fe0cbb7d..ec7695d57 100755 --- a/utils/check_sources.py +++ b/utils/check_sources.py @@ -7,7 +7,7 @@ Make sure each Python file has a correct file header including copyright and license information. - :copyright: Copyright 2006-2009 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -30,7 +30,7 @@ def checker(*suffixes, **kwds): name_mail_re = r'[\w ]+(<.*?>)?' -copyright_re = re.compile(r'^ :copyright: Copyright 200\d(-200\d)? ' +copyright_re = re.compile(r'^ :copyright: Copyright 200\d(-20\d\d)? ' r'by %s(, %s)*[,.]$' % (name_mail_re, name_mail_re)) license_re = re.compile(r" :license: (.*?).\n")