summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile6
-rw-r--r--doc/builders.rst12
-rw-r--r--doc/config.rst1
-rw-r--r--doc/contents.rst2
-rw-r--r--doc/ext/graphviz.rst11
-rw-r--r--doc/intl.rst13
-rw-r--r--doc/intro.rst12
-rw-r--r--doc/markup/inline.rst1
-rw-r--r--doc/markup/misc.rst79
-rw-r--r--doc/markup/para.rst62
-rw-r--r--doc/markup/toctree.rst14
-rw-r--r--doc/web/api.rst65
-rw-r--r--doc/web/quickstart.rst261
-rw-r--r--doc/web/searchadapters.rst45
-rw-r--r--doc/web/storagebackends.rst46
-rw-r--r--doc/websupport.rst16
16 files changed, 579 insertions, 67 deletions
diff --git a/doc/Makefile b/doc/Makefile
index 90fb5af2..aa3ecb61 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -29,6 +29,7 @@ help:
@echo " epub to make an epub file"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run pdflatex"
+ @echo " gettext to make PO message catalogs"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@@ -112,6 +113,11 @@ latexpdf:
make -C _build/latex all-pdf
@echo "pdflatex finished; the PDF files are in _build/latex."
+gettext:
+ $(SPHINXBUILD) -b gettext $(ALLSPHINXOPTS) _build/locale
+ @echo
+ @echo "Build finished. The message catalogs are in _build/locale."
+
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
diff --git a/doc/builders.rst b/doc/builders.rst
index 80203e75..7d182d06 100644
--- a/doc/builders.rst
+++ b/doc/builders.rst
@@ -220,6 +220,18 @@ Note that a direct PDF builder using ReportLab is available in `rst2pdf
.. versionadded:: 0.5
+.. module:: sphinx.builders.intl
+.. class:: MessageCatalogBuilder
+
+ This builder produces a message catalog file for each reST file or
+ subdirectory.
+
+ See the documentation on :ref:`internationalization <intl>` for further reference.
+
+ Its name is ``gettext``.
+
+ .. versionadded:: 1.1
+
.. module:: sphinx.builders.changes
.. class:: ChangesBuilder
diff --git a/doc/config.rst b/doc/config.rst
index e0fbeb46..3115c401 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -300,6 +300,7 @@ Project information
* ``pt_BR`` -- Brazilian Portuguese
* ``ru`` -- Russian
* ``sl`` -- Slovenian
+ * ``sv`` -- Swedish
* ``tr`` -- Turkish
* ``uk_UA`` -- Ukrainian
* ``zh_CN`` -- Simplified Chinese
diff --git a/doc/contents.rst b/doc/contents.rst
index 079f93f2..3bbc2835 100644
--- a/doc/contents.rst
+++ b/doc/contents.rst
@@ -14,9 +14,11 @@ Sphinx documentation contents
domains
builders
config
+ intl
theming
templating
extensions
+ websupport
faq
glossary
diff --git a/doc/ext/graphviz.rst b/doc/ext/graphviz.rst
index 3741cec6..de6e03e2 100644
--- a/doc/ext/graphviz.rst
+++ b/doc/ext/graphviz.rst
@@ -29,6 +29,17 @@ It adds these directives:
:confval:`graphviz_output_format`). In LaTeX output, the code will be
rendered to an embeddable PDF file.
+ You can also embed external dot files, by giving the file name as an
+ argument to :rst:dir:`graphviz` and no additional content::
+
+ .. graphviz:: external.dot
+
+ As for all file references in Sphinx, if the filename is absolute, it is
+ taken as relative to the source directory.
+
+ .. versionchanged:: 1.1
+ Added support for external files.
+
.. rst:directive:: graph
diff --git a/doc/intl.rst b/doc/intl.rst
new file mode 100644
index 00000000..b6036767
--- /dev/null
+++ b/doc/intl.rst
@@ -0,0 +1,13 @@
+.. _intl:
+
+Internationalization
+====================
+
+.. versionadded:: 1.1
+
+Complementary to translations provided for Sphinx-generated messages such as
+navigation bars, Sphinx provides mechanisms facilitating *document* translations
+in itself. It relies on the existing configuration values :confval:`language`
+and :confval:`locale_dirs`.
+
+.. XXX write more!
diff --git a/doc/intro.rst b/doc/intro.rst
index 1a39e266..caff141d 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -45,15 +45,19 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
Prerequisites
-------------
-Sphinx needs at least **Python 2.4** to run, as well as the docutils_ and
-Jinja2_ libraries. Sphinx should work with docutils version 0.5 or some
-(not broken) SVN trunk snapshot. If you like to have source code highlighting
-support, you must also install the Pygments_ library.
+Sphinx needs at least **Python 2.4** or **Python 3.1** to run, as well as the
+docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.5
+or some (not broken) SVN trunk snapshot. If you like to have source code
+highlighting support, you must also install the Pygments_ library.
+
+If you use **Python 2.4** you also need uuid_.
.. _reStructuredText: http://docutils.sf.net/rst.html
.. _docutils: http://docutils.sf.net/
.. _Jinja2: http://jinja.pocoo.org/2/
.. _Pygments: http://pygments.org/
+.. The given homepage is only a directory listing so I'm using the pypi site.
+.. _uuid: http://pypi.python.org/pypi/uuid/
Usage
diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst
index 35981edc..78aaea69 100644
--- a/doc/markup/inline.rst
+++ b/doc/markup/inline.rst
@@ -309,6 +309,7 @@ in a different style:
If you don't need the "variable part" indication, use the standard
````code```` instead.
+There is also an :rst:role:`index` role to generate index entries.
The following roles generate external links:
diff --git a/doc/markup/misc.rst b/doc/markup/misc.rst
index 6173589b..44da3aac 100644
--- a/doc/markup/misc.rst
+++ b/doc/markup/misc.rst
@@ -62,6 +62,85 @@ Meta-information markup
:confval:`show_authors` configuration value is True.
+Index-generating markup
+-----------------------
+
+Sphinx automatically creates index entries from all object descriptions (like
+functions, classes or attributes) like discussed in :ref:`domains`.
+
+However, there is also explicit markup available, to make the index more
+comprehensive and enable index entries in documents where information is not
+mainly contained in information units, such as the language reference.
+
+.. rst:directive:: .. index:: <entries>
+
+ This directive contains one or more index entries. Each entry consists of a
+ type and a value, separated by a colon.
+
+ For example::
+
+ .. index::
+ single: execution; context
+ module: __main__
+ module: sys
+ triple: module; search; path
+
+ The execution context
+ ---------------------
+
+ ...
+
+ This directive contains five entries, which will be converted to entries in
+ the generated index which link to the exact location of the index statement
+ (or, in case of offline media, the corresponding page number).
+
+ Since index directives generate cross-reference targets at their location in
+ the source, it makes sense to put them *before* the thing they refer to --
+ e.g. a heading, as in the example above.
+
+ The possible entry types are:
+
+ single
+ Creates a single index entry. Can be made a subentry by separating the
+ subentry text with a semicolon (this notation is also used below to
+ describe what entries are created).
+ pair
+ ``pair: loop; statement`` is a shortcut that creates two index entries,
+ namely ``loop; statement`` and ``statement; loop``.
+ triple
+ Likewise, ``triple: module; search; path`` is a shortcut that creates
+ three index entries, which are ``module; search path``, ``search; path,
+ module`` and ``path; module search``.
+ module, keyword, operator, object, exception, statement, builtin
+ These all create two index entries. For example, ``module: hashlib``
+ creates the entries ``module; hashlib`` and ``hashlib; module``. (These
+ are Python-specific and therefore deprecated.)
+
+ For index directives containing only "single" entries, there is a shorthand
+ notation::
+
+ .. index:: BNF, grammar, syntax, notation
+
+ This creates four index entries.
+
+.. rst:role:: index
+
+ While the :rst:dir:`index` directive is a block-level markup and links to the
+ beginning of the next paragraph, there is also a corresponding role that sets
+ the link target directly where it is used.
+
+ The content of the role can be a simple phrase, which is then kept in the
+ text and used as an index entry. It can also be a combination of text and
+ index entry, styled like with explicit targets of cross-references. In that
+ case, the "target" part can be a full entry as described for the directive
+ above. For example::
+
+ This is a normal reST :index:`paragraph` that contains several
+ :index:`index entries <pair: index; entry>`.
+
+ .. versionadded:: 1.1
+
+
.. _tags:
Including content based on tags
diff --git a/doc/markup/para.rst b/doc/markup/para.rst
index ecc6b4a6..52a5019b 100644
--- a/doc/markup/para.rst
+++ b/doc/markup/para.rst
@@ -144,68 +144,6 @@ For local tables of contents, use the standard reST :dudir:`contents directive
<contents>`.
-Index-generating markup
------------------------
-
-Sphinx automatically creates index entries from all object descriptions (like
-functions, classes or attributes) like discussed in :ref:`domains`.
-
-However, there is also an explicit directive available, to make the index more
-comprehensive and enable index entries in documents where information is not
-mainly contained in information units, such as the language reference.
-
-.. rst:directive:: .. index:: <entries>
-
- This directive contains one or more index entries. Each entry consists of a
- type and a value, separated by a colon.
-
- For example::
-
- .. index::
- single: execution; context
- module: __main__
- module: sys
- triple: module; search; path
-
- The execution context
- ---------------------
-
- ...
-
- This directive contains five entries, which will be converted to entries in
- the generated index which link to the exact location of the index statement
- (or, in case of offline media, the corresponding page number).
-
- Since index directives generate cross-reference targets at their location in
- the source, it makes sense to put them *before* the thing they refer to --
- e.g. a heading, as in the example above.
-
- The possible entry types are:
-
- single
- Creates a single index entry. Can be made a subentry by separating the
- subentry text with a semicolon (this notation is also used below to
- describe what entries are created).
- pair
- ``pair: loop; statement`` is a shortcut that creates two index entries,
- namely ``loop; statement`` and ``statement; loop``.
- triple
- Likewise, ``triple: module; search; path`` is a shortcut that creates
- three index entries, which are ``module; search path``, ``search; path,
- module`` and ``path; module search``.
- module, keyword, operator, object, exception, statement, builtin
- These all create two index entries. For example, ``module: hashlib``
- creates the entries ``module; hashlib`` and ``hashlib; module``. (These
- are Python-specific and therefore deprecated.)
-
- For index directives containing only "single" entries, there is a shorthand
- notation::
-
- .. index:: BNF, grammar, syntax, notation
-
- This creates four index entries.
-
-
Glossary
--------
diff --git a/doc/markup/toctree.rst b/doc/markup/toctree.rst
index 2c0a418a..0b6a46c1 100644
--- a/doc/markup/toctree.rst
+++ b/doc/markup/toctree.rst
@@ -41,6 +41,8 @@ tables of contents. The ``toctree`` directive is the central element.
document, the library index. From this information it generates "next
chapter", "previous chapter" and "parent chapter" links.
+ **Entries**
+
Document titles in the :rst:dir:`toctree` will be automatically read from the
title of the referenced document. If that isn't what you want, you can
specify an explicit title and target using a similar syntax to reST
@@ -59,8 +61,10 @@ tables of contents. The ``toctree`` directive is the central element.
You can also add external links, by giving an HTTP URL instead of a document
name.
+ **Section numbering**
+
If you want to have section numbers even in HTML output, give the toctree a
- ``numbered`` flag option. For example::
+ ``numbered`` option. For example::
.. toctree::
:numbered:
@@ -71,6 +75,11 @@ tables of contents. The ``toctree`` directive is the central element.
Numbering then starts at the heading of ``foo``. Sub-toctrees are
automatically numbered (don't give the ``numbered`` flag to those).
+ Numbering up to a specific depth is also possible, by giving the depth as a
+ numeric argument to ``numbered``.
+
+ **Additional options**
+
If you want only the titles of documents in the tree to show up, not other
headings of the same level, you can use the ``titlesonly`` option::
@@ -133,6 +142,9 @@ tables of contents. The ``toctree`` directive is the central element.
.. versionchanged:: 1.0
Added "titlesonly" option.
+ .. versionchanged:: 1.1
+ Added numeric argument to "numbered".
+
Special names
-------------
diff --git a/doc/web/api.rst b/doc/web/api.rst
new file mode 100644
index 00000000..070cd3a2
--- /dev/null
+++ b/doc/web/api.rst
@@ -0,0 +1,65 @@
+.. _websupportapi:
+
+.. currentmodule:: sphinx.websupport
+
+The WebSupport Class
+====================
+
+.. class:: WebSupport
+
+ The main API class for the web support package. All interactions with the
+ web support package should occur through this class.
+
+ The class takes the following keyword arguments:
+
+ srcdir
+ The directory containing reStructuredText source files.
+
+ builddir
+ The directory that build data and static files should be placed in. This
+ should be used when creating a :class:`WebSupport` object that will be
+ used to build data.
+
+ datadir
+ The directory that the web support data is in. This should be used when
+ creating a :class:`WebSupport` object that will be used to retrieve data.
+
+ search
+ This may contain either a string (e.g. 'xapian') referencing a built-in
+ search adapter to use, or an instance of a subclass of
+ :class:`~.search.BaseSearch`.
+
+ storage
+ This may contain either a string representing a database uri, or an
+ instance of a subclass of :class:`~.storage.StorageBackend`. If this is
+ not provided, a new sqlite database will be created.
+
+ moderation_callback
+ A callable to be called when a new comment is added that is not
+ displayed. It must accept one argument: a dictionary representing the
+ comment that was added.
+
+ staticdir
+ If static files are served from a location besides ``'/static'``, this
+ should be a string with the name of that location
+ (e.g. ``'/static_files'``).
+
+ docroot
+ If the documentation is not served from the base path of a URL, this
+ should be a string specifying that path (e.g. ``'docs'``).
+
+
+Methods
+~~~~~~~
+
+.. automethod:: sphinx.websupport.WebSupport.build
+
+.. automethod:: sphinx.websupport.WebSupport.get_document
+
+.. automethod:: sphinx.websupport.WebSupport.get_data
+
+.. automethod:: sphinx.websupport.WebSupport.add_comment
+
+.. automethod:: sphinx.websupport.WebSupport.process_vote
+
+.. automethod:: sphinx.websupport.WebSupport.get_search_results
diff --git a/doc/web/quickstart.rst b/doc/web/quickstart.rst
new file mode 100644
index 00000000..0627c9c3
--- /dev/null
+++ b/doc/web/quickstart.rst
@@ -0,0 +1,261 @@
+.. _websupportquickstart:
+
+Web Support Quick Start
+=======================
+
+Building Documentation Data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To make use of the web support package in your application you'll need to build
+the data it uses. This data includes pickle files representing documents,
+search indices, and node data that is used to track where comments and other
+things are in a document. To do this you will need to create an instance of the
+:class:`~.WebSupport` class and call its :meth:`~.WebSupport.build` method::
+
+ from sphinx.websupport import WebSupport
+
+ support = WebSupport(srcdir='/path/to/rst/sources/',
+ builddir='/path/to/build/outdir',
+ search='xapian')
+
+ support.build()
+
+This will read reStructuredText sources from `srcdir` and place the necessary
+data in `builddir`. The `builddir` will contain two sub-directories: one named
+"data" that contains all the data needed to display documents, search through
+documents, and add comments to documents. The other directory will be called
+"static" and contains static files that should be served from "/static".
+
+.. note::
+
+ If you wish to serve static files from a path other than "/static", you can
+ do so by providing the *staticdir* keyword argument when creating the
+ :class:`~.WebSupport` object.
+
+
+Integrating Sphinx Documents Into Your Webapp
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that the data is built, it's time to do something useful with it. Start off
+by creating a :class:`~.WebSupport` object for your application::
+
+ from sphinx.websupport import WebSupport
+
+ support = WebSupport(datadir='/path/to/the/data',
+ search='xapian')
+
+You'll only need one of these for each set of documentation you will be working
+with. You can then call it's :meth:`~.WebSupport.get_document` method to access
+individual documents::
+
+ contents = support.get_document('contents')
+
+This will return a dictionary containing the following items:
+
+* **body**: The main body of the document as HTML
+* **sidebar**: The sidebar of the document as HTML
+* **relbar**: A div containing links to related documents
+* **title**: The title of the document
+* **css**: Links to css files used by Sphinx
+* **js**: Javascript containing comment options
+
+This dict can then be used as context for templates. The goal is to be easy to
+integrate with your existing templating system. An example using `Jinja2
+<http://jinja.pocoo.org/2/>`_ is:
+
+.. sourcecode:: html+jinja
+
+ {%- extends "layout.html" %}
+
+ {%- block title %}
+ {{ document.title }}
+ {%- endblock %}
+
+ {% block css %}
+ {{ super() }}
+ {{ document.css|safe }}
+ <link rel="stylesheet" href="/static/websupport-custom.css" type="text/css">
+ {% endblock %}
+
+ {%- block js %}
+ {{ super() }}
+ {{ document.js|safe }}
+ {%- endblock %}
+
+ {%- block relbar %}
+ {{ document.relbar|safe }}
+ {%- endblock %}
+
+ {%- block body %}
+ {{ document.body|safe }}
+ {%- endblock %}
+
+ {%- block sidebar %}
+ {{ document.sidebar|safe }}
+ {%- endblock %}
+
+
+Authentication
+--------------
+
+To use certain features such as voting, it must be possible to authenticate
+users. The details of the authentication are left to your application. Once a
+user has been authenticated you can pass the user's details to certain
+:class:`~.WebSupport` methods using the *username* and *moderator* keyword
+arguments. The web support package will store the username with comments and
+votes. The only caveat is that if you allow users to change their username you
+must update the websupport package's data::
+
+ support.update_username(old_username, new_username)
+
+*username* should be a unique string which identifies a user, and *moderator*
+should be a boolean representing whether the user has moderation privilieges.
+The default value for *moderator* is *False*.
+
+An example `Flask <http://flask.pocoo.org/>`_ function that checks whether a
+user is logged in and then retrieves a document is::
+
+ from sphinx.websupport.errors import *
+
+ @app.route('/<path:docname>')
+ def doc(docname):
+ username = g.user.name if g.user else ''
+ moderator = g.user.moderator if g.user else False
+ try:
+ document = support.get_document(docname, username, moderator)
+ except DocumentNotFoundError:
+ abort(404)
+ return render_template('doc.html', document=document)
+
+The first thing to notice is that the *docname* is just the request path. This
+makes accessing the correct document easy from a single view. If the user is
+authenticated, then the username and moderation status are passed along with the
+docname to :meth:`~.WebSupport.get_document`. The web support package will then
+add this data to the ``COMMENT_OPTIONS`` that are used in the template.
+
+.. note::
+
+ This only works works if your documentation is served from your
+ document root. If it is served from another directory, you will
+ need to prefix the url route with that directory, and give the `docroot`
+ keyword argument when creating the web support object::
+
+ support = WebSupport(..., docroot='docs')
+
+ @app.route('/docs/<path:docname>')
+
+
+Performing Searches
+~~~~~~~~~~~~~~~~~~~
+
+To use the search form built-in to the Sphinx sidebar, create a function to
+handle requests to the url 'search' relative to the documentation root. The
+user's search query will be in the GET parameters, with the key `q`. Then use
+the :meth:`~sphinx.websupport.WebSupport.get_search_results` method to retrieve
+search results. In `Flask <http://flask.pocoo.org/>`_ that would be like this::
+
+ @app.route('/search')
+ def search():
+ q = request.args.get('q')
+ document = support.get_search_results(q)
+ return render_template('doc.html', document=document)
+
+Note that we used the same template to render our search results as we did to
+render our documents. That's because :meth:`~.WebSupport.get_search_results`
+returns a context dict in the same format that :meth:`~.WebSupport.get_document`
+does.
+
+
+Comments & Proposals
+~~~~~~~~~~~~~~~~~~~~
+
+Now that this is done it's time to define the functions that handle the AJAX
+calls from the script. You will need three functions. The first function is
+used to add a new comment, and will call the web support method
+:meth:`~.WebSupport.add_comment`::
+
+ @app.route('/docs/add_comment', methods=['POST'])
+ def add_comment():
+ parent_id = request.form.get('parent', '')
+ node_id = request.form.get('node', '')
+ text = request.form.get('text', '')
+ proposal = request.form.get('proposal', '')
+ username = g.user.name if g.user is not None else 'Anonymous'
+ comment = support.add_comment(text, node_id='node_id',
+ parent_id='parent_id',
+ username=username, proposal=proposal)
+ return jsonify(comment=comment)
+
+You'll notice that both a `parent_id` and `node_id` are sent with the
+request. If the comment is being attached directly to a node, `parent_id`
+will be empty. If the comment is a child of another comment, then `node_id`
+will be empty. Then next function handles the retrieval of comments for a
+specific node, and is aptly named
+:meth:`~sphinx.websupport.WebSupport.get_data`::
+
+ @app.route('/docs/get_comments')
+ def get_comments():
+ username = g.user.name if g.user else None
+ moderator = g.user.moderator if g.user else False
+ node_id = request.args.get('node', '')
+ data = support.get_data(parent_id, user_id)
+ return jsonify(**data)
+
+The final function that is needed will call :meth:`~.WebSupport.process_vote`,
+and will handle user votes on comments::
+
+ @app.route('/docs/process_vote', methods=['POST'])
+ def process_vote():
+ if g.user is None:
+ abort(401)
+ comment_id = request.form.get('comment_id')
+ value = request.form.get('value')
+ if value is None or comment_id is None:
+ abort(400)
+ support.process_vote(comment_id, g.user.id, value)
+ return "success"
+
+
+Comment Moderation
+~~~~~~~~~~~~~~~~~~
+
+By default, all comments added through :meth:`~.WebSupport.add_comment` are
+automatically displayed. If you wish to have some form of moderation, you can
+pass the `displayed` keyword argument::
+
+ comment = support.add_comment(text, node_id='node_id',
+ parent_id='parent_id',
+ username=username, proposal=proposal,
+ displayed=False)
+
+You can then create two new views to handle the moderation of comments. The
+first will be called when a moderator decides a comment should be accepted and
+displayed::
+
+ @app.route('/docs/accept_comment', methods=['POST'])
+ def accept_comment():
+ moderator = g.user.moderator if g.user else False
+ comment_id = request.form.get('id')
+ support.accept_comment(comment_id, moderator=moderator)
+ return 'OK'
+
+The next is very similar, but used when rejecting a comment::
+
+ @app.route('/docs/reject_comment', methods=['POST'])
+ def reject_comment():
+ moderator = g.user.moderator if g.user else False
+ comment_id = request.form.get('id')
+ support.reject_comment(comment_id, moderator=moderator)
+ return 'OK'
+
+To perform a custom action (such as emailing a moderator) when a new comment is
+added but not displayed, you can pass callable to the :class:`~.WebSupport`
+class when instantiating your support object::
+
+ def moderation_callback(comment):
+ """Do something..."""
+
+ support = WebSupport(..., moderation_callback=moderation_callback)
+
+The moderation callback must take one argument, which will be the same comment
+dict that is returned by :meth:`add_comment`.
diff --git a/doc/web/searchadapters.rst b/doc/web/searchadapters.rst
new file mode 100644
index 00000000..7d8634f7
--- /dev/null
+++ b/doc/web/searchadapters.rst
@@ -0,0 +1,45 @@
+.. _searchadapters:
+
+.. currentmodule:: sphinx.websupport.search
+
+Search Adapters
+===============
+
+To create a custom search adapter you will need to subclass the
+:class:`BaseSearch` class. Then create an instance of the new class and pass
+that as the `search` keyword argument when you create the :class:`~.WebSupport`
+object::
+
+ support = WebSupport(srcdir=srcdir,
+ builddir=builddir,
+ search=MySearch())
+
+For more information about creating a custom search adapter, please see the
+documentation of the :class:`BaseSearch` class below.
+
+.. class:: BaseSearch
+
+ Defines an interface for search adapters.
+
+
+BaseSearch Methods
+~~~~~~~~~~~~~~~~~~
+
+ The following methods are defined in the BaseSearch class. Some methods do
+ not need to be overridden, but some (:meth:`~BaseSearch.add_document` and
+ :meth:`~BaseSearch.handle_query`) must be overridden in your subclass. For a
+ working example, look at the built-in adapter for whoosh.
+
+.. automethod:: BaseSearch.init_indexing
+
+.. automethod:: BaseSearch.finish_indexing
+
+.. automethod:: BaseSearch.feed
+
+.. automethod:: BaseSearch.add_document
+
+.. automethod:: BaseSearch.query
+
+.. automethod:: BaseSearch.handle_query
+
+.. automethod:: BaseSearch.extract_context
diff --git a/doc/web/storagebackends.rst b/doc/web/storagebackends.rst
new file mode 100644
index 00000000..a46ea9e5
--- /dev/null
+++ b/doc/web/storagebackends.rst
@@ -0,0 +1,46 @@
+.. _storagebackends:
+
+.. currentmodule:: sphinx.websupport.storage
+
+Storage Backends
+================
+
+To create a custom storage backend you will need to subclass the
+:class:`StorageBackend` class. Then create an instance of the new class and
+pass that as the `storage` keyword argument when you create the
+:class:`~.WebSupport` object::
+
+ support = WebSupport(srcdir=srcdir,
+ builddir=builddir,
+ storage=MyStorage())
+
+For more information about creating a custom storage backend, please see the
+documentation of the :class:`StorageBackend` class below.
+
+.. class:: StorageBackend
+
+ Defines an interface for storage backends.
+
+
+StorageBackend Methods
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. automethod:: StorageBackend.pre_build
+
+.. automethod:: StorageBackend.add_node
+
+.. automethod:: StorageBackend.post_build
+
+.. automethod:: StorageBackend.add_comment
+
+.. automethod:: StorageBackend.delete_comment
+
+.. automethod:: StorageBackend.get_data
+
+.. automethod:: StorageBackend.process_vote
+
+.. automethod:: StorageBackend.update_username
+
+.. automethod:: StorageBackend.accept_comment
+
+.. automethod:: StorageBackend.reject_comment
diff --git a/doc/websupport.rst b/doc/websupport.rst
new file mode 100644
index 00000000..3ccae246
--- /dev/null
+++ b/doc/websupport.rst
@@ -0,0 +1,16 @@
+.. _websupport:
+
+Sphinx Web Support
+==================
+
+.. versionadded:: 1.1
+
+Sphinx provides a Python API to easily integrate Sphinx documentation into your
+web application. To learn more read the :ref:`websupportquickstart`.
+
+.. toctree::
+
+ web/quickstart
+ web/api
+ web/searchadapters
+ web/storagebackends