docs: Address review comments

helloworld:
- Return version metadata from extension
- Use 'reST' instead of 'rST'
- Don't use single backticks

todo:
- Return version metadata from extension
- Link to events section of API guide, rather than entire document
- Include name of phases in when describing build phases
- Use more method cross-references where possible
- Fix typo in usage example

recipe:
- Return version metadata from extension
- Rework code to simplify things
- Remove docstrings from 'generate' functions, which are simply
  duplicates of the original docstring
- Rename 'rcp' directive to 'recipe', the 'reref' role to 'ref', and a
  whole lot of variables to something more grokable
- Fix typos in both documentation and code

I've also fixed up the docstrings for some of the 'domain' functions to
make them render a little nicer (they took me a while to figure out).

Signed-off-by: Stephen Finucane <stephen@that.guru>
This commit is contained in:
Stephen Finucane
2019-02-11 10:44:49 +00:00
parent b1ebdcd3c6
commit 5c061ff266
8 changed files with 236 additions and 246 deletions

View File

@@ -0,0 +1,11 @@
:orphan:
Tutorial examples
=================
This directory contains a number of examples used in the tutorials. These are
intended to be increasingly complex to demonstrate the various features of
Sphinx, but should aim to be as complicated as necessary but no more.
Individual sections are referenced by line numbers, meaning if you make changes
to the source files, you should update the references in the documentation
accordingly.

View File

@@ -11,3 +11,9 @@ class HelloWorld(Directive):
def setup(app):
app.add_directive("helloworld", HelloWorld)
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@@ -1,3 +1,5 @@
from collections import defaultdict
import docutils
from docutils import nodes
from docutils.parsers import rst
@@ -18,33 +20,27 @@ class RecipeDirective(ObjectDescription):
has_content = True
required_arguments = 1
option_spec = {
'contains': directives.unchanged_required
'contains': directives.unchanged_required,
}
def handle_signature(self, sig, signode):
signode += addnodes.desc_name(text=sig)
signode += addnodes.desc_type(text='Recipe')
return sig
def add_target_and_index(self, name_cls, sig, signode):
signode['ids'].append('recipe' + '-' + sig)
if 'noindex' not in self.options:
name = '{}.{}.{}'.format('rcp', type(self).__name__, sig)
imap = self.env.domaindata['rcp']['obj2ingredient']
imap[name] = list(self.options.get('contains').split(' '))
objs = self.env.domaindata['rcp']['objects']
objs.append((name,
sig,
'Recipe',
self.env.docname,
'recipe' + '-' + sig,
0))
ingredients = [
x.strip() for x in self.options.get('contains').split(',')]
recipes = self.env.get_domain('recipe')
recipes.add_recipe(sig, ingredients)
class IngredientIndex(Index):
"""A custom directive that creates an ingredient matrix."""
"""A custom index that creates an ingredient matrix."""
name = 'ing'
name = 'ingredient'
localname = 'Ingredient Index'
shortname = 'Ingredient'
@@ -52,69 +48,39 @@ class IngredientIndex(Index):
super(IngredientIndex, self).__init__(*args, **kwargs)
def generate(self, docnames=None):
"""Return entries for the index given by *name*.
content = defaultdict(list)
If *docnames* is given, restrict to entries referring to these
docnames. The return value is a tuple of ``(content, collapse)``,
where:
recipes = {name: (dispname, typ, docname, anchor)
for name, dispname, typ, docname, anchor, _
in self.domain.get_objects()}
recipe_ingredients = self.domain.data['recipe_ingredients']
ingredient_recipes = defaultdict(list)
*collapse* is a boolean that determines if sub-entries should
start collapsed (for output formats that support collapsing
sub-entries).
# flip from recipe_ingredients to ingredient_recipes
for recipe_name, ingredients in recipe_ingredients.items():
for ingredient in ingredients:
ingredient_recipes[ingredient].append(recipe_name)
*content* is a sequence of ``(letter, entries)`` tuples, where *letter*
is the "heading" for the given *entries*, usually the starting letter.
# convert the mapping of ingredient to recipes to produce the expected
# output, shown below, using the ingredient name as a key to group
#
# name, subtype, docname, anchor, extra, qualifier, description
for ingredient, recipe_names in ingredient_recipes.items():
for recipe_name in recipe_names:
dispname, typ, docname, anchor = recipes[recipe_name]
content[ingredient].append(
(dispname, 0, docname, anchor, docname, '', typ))
*entries* is a sequence of single entries, where a single entry is a
sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``.
# convert the dict to the sorted list of tuples expected
content = sorted(content.items())
The items in this sequence have the following meaning:
- `name` -- the name of the index entry to be displayed
- `subtype` -- sub-entry related type:
- ``0`` -- normal entry
- ``1`` -- entry with sub-entries
- ``2`` -- sub-entry
- `docname` -- docname where the entry is located
- `anchor` -- anchor for the entry within `docname`
- `extra` -- extra info for the entry
- `qualifier` -- qualifier for the description
- `descr` -- description for the entry
Qualifier and description are not rendered by some builders, such as
the LaTeX builder.
"""
content = {}
objs = {name: (dispname, typ, docname, anchor)
for name, dispname, typ, docname, anchor, prio
in self.domain.get_objects()}
imap = {}
ingr = self.domain.data['obj2ingredient']
for name, ingr in ingr.items():
for ig in ingr:
imap.setdefault(ig,[])
imap[ig].append(name)
for ingredient in imap.keys():
lis = content.setdefault(ingredient, [])
objlis = imap[ingredient]
for objname in objlis:
dispname, typ, docname, anchor = objs[objname]
lis.append((
dispname, 0, docname,
anchor,
docname, '', typ
))
re = [(k, v) for k, v in sorted(content.items())]
return (re, True)
return content, True
class RecipeIndex(Index):
name = 'rcp'
"""A custom index that creates an recipe matrix."""
name = 'recipe'
localname = 'Recipe Index'
shortname = 'Recipe'
@@ -122,92 +88,54 @@ class RecipeIndex(Index):
super(RecipeIndex, self).__init__(*args, **kwargs)
def generate(self, docnames=None):
"""Return entries for the index given by *name*.
content = defaultdict(list)
If *docnames* is given, restrict to entries referring to these
docnames. The return value is a tuple of ``(content, collapse)``,
where:
# sort the list of recipes in alphabetical order
recipes = self.domain.get_objects()
recipes = sorted(recipes, key=lambda recipe: recipe[0])
*collapse* is a boolean that determines if sub-entries should
start collapsed (for output formats that support collapsing
sub-entries).
# generate the expected output, shown below, from the above using the
# first letter of the recipe as a key to group thing
#
# name, subtype, docname, anchor, extra, qualifier, description
for name, dispname, typ, docname, anchor, _ in recipes:
content[dispname[0].lower()].append(
(dispname, 0, docname, anchor, docname, '', typ))
*content* is a sequence of ``(letter, entries)`` tuples, where *letter*
is the "heading" for the given *entries*, usually the starting letter.
# convert the dict to the sorted list of tuples expected
content = sorted(content.items())
*entries* is a sequence of single entries, where a single entry is a
sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``.
The items in this sequence have the following meaning:
- `name` -- the name of the index entry to be displayed
- `subtype` -- sub-entry related type:
- ``0`` -- normal entry
- ``1`` -- entry with sub-entries
- ``2`` -- sub-entry
- `docname` -- docname where the entry is located
- `anchor` -- anchor for the entry within `docname`
- `extra` -- extra info for the entry
- `qualifier` -- qualifier for the description
- `descr` -- description for the entry
Qualifier and description are not rendered by some builders, such as
the LaTeX builder.
"""
content = {}
items = ((name, dispname, typ, docname, anchor)
for name, dispname, typ, docname, anchor, prio
in self.domain.get_objects())
items = sorted(items, key=lambda item: item[0])
for name, dispname, typ, docname, anchor in items:
lis = content.setdefault('Recipe', [])
lis.append((
dispname, 0, docname,
anchor,
docname, '', typ
))
re = [(k, v) for k, v in sorted(content.items())]
return (re, True)
return content, True
class RecipeDomain(Domain):
name = 'rcp'
name = 'recipe'
label = 'Recipe Sample'
roles = {
'reref': XRefRole()
'ref': XRefRole()
}
directives = {
'recipe': RecipeDirective,
}
indices = {
RecipeIndex,
IngredientIndex
}
initial_data = {
'objects': [], # object list
'obj2ingredient': {}, # name -> object
'recipes': [], # object list
'recipe_ingredients': {}, # name -> object
}
def get_full_qualified_name(self, node):
"""Return full qualified name for a given node"""
return "{}.{}.{}".format('rcp',
type(node).__name__,
node.arguments[0])
return '{}.{}'.format('recipe', node.arguments[0])
def get_objects(self):
for obj in self.data['objects']:
for obj in self.data['recipes']:
yield(obj)
def resolve_xref(self, env, fromdocname, builder, typ, target, node,
contnode):
match = [(docname, anchor)
for name, sig, typ, docname, anchor, prio
in self.get_objects() if sig == target]
@@ -219,21 +147,25 @@ class RecipeDomain(Domain):
return make_refnode(builder, fromdocname, todocname, targ,
contnode, targ)
else:
print("Awww, found nothing")
print('Awww, found nothing')
return None
def add_recipe(self, signature, ingredients):
"""Add a new recipe to the domain."""
name = '{}.{}'.format('recipe', signature)
anchor = 'recipe-{}'.format(signature)
self.data['recipe_ingredients'][name] = ingredients
# name, dispname, type, docname, anchor, priority
self.data['recipes'].append(
(name, signature, 'Recipe', self.env.docname, anchor, 0))
def setup(app):
app.add_domain(RecipeDomain)
StandardDomain.initial_data['labels']['recipeindex'] = (
'rcp-rcp', '', 'Recipe Index')
StandardDomain.initial_data['labels']['ingredientindex'] = (
'rcp-ing', '', 'Ingredient Index')
StandardDomain.initial_data['anonlabels']['recipeindex'] = (
'rcp-rcp', '')
StandardDomain.initial_data['anonlabels']['ingredientindex'] = (
'rcp-ing', '')
return {'version': '0.1'} # identifies the version of our extension
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@@ -117,4 +117,8 @@ def setup(app):
app.connect('doctree-resolved', process_todo_nodes)
app.connect('env-purge-doc', purge_todos)
return {'version': '0.1'} # identifies the version of our extension
return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@@ -2,12 +2,13 @@ Developing a "Hello world" extension
====================================
The objective of this tutorial is to create a very basic extension that adds a
new directive. This directive will output a paragraph containing `hello world`.
new directive. This directive will output a paragraph containing "hello world".
Only basic information is provided in this tutorial. For more information, refer
to the :doc:`other tutorials <index>` that go into more details.
.. warning::
For this extension, you will need some basic understanding of docutils_
and Python.
@@ -17,7 +18,7 @@ Overview
We want the extension to add the following to Sphinx:
* A ``helloworld`` directive, that will simply output the text `hello world`.
* A ``helloworld`` directive, that will simply output the text "hello world".
Prerequisites
@@ -104,10 +105,10 @@ Sphinx.
:linenos:
:lines: 12-
The simplest thing you can do it call the :meth:`~Sphinx.add_directive`
method, which is what we've done here. For this particular call, the first
argument is the name of the directive itself as used in an rST file. In this
case, we would use ``helloworld``. For example:
The simplest thing you can do it call the :meth:`~Sphinx.add_directive` method,
which is what we've done here. For this particular call, the first argument is
the name of the directive itself as used in a reST file. In this case, we would
use ``helloworld``. For example:
.. code-block:: rst
@@ -117,6 +118,10 @@ case, we would use ``helloworld``. For example:
Some more text here...
We also return the :ref:`extension metadata <ext-metadata>` that indicates the
version of our extension, along with the fact that it is safe to use the
extension for both parallel reading and writing.
Using the extension
-------------------

View File

@@ -19,14 +19,14 @@ Overview
We want the extension to add the following to Sphinx:
* A ``recipe`` :term:`directive`, containing some content describing the recipe
steps, along with a ``:contains:`` argument highlighting the main ingredients
steps, along with a ``:contains:`` option highlighting the main ingredients
of the recipe.
* A ``reref`` :term:`role`, which provides a cross-reference to the recipe
* A ``ref`` :term:`role`, which provides a cross-reference to the recipe
itself.
* A ``rcp`` :term:`domain`, which allows us to tie together the above role and
domain, along with things like indices.
* A ``recipe`` :term:`domain`, which allows us to tie together the above role
and domain, along with things like indices.
For that, we will need to add the following elements to Sphinx:
@@ -34,24 +34,15 @@ For that, we will need to add the following elements to Sphinx:
* New indexes to allow us to reference ingredient and recipes
* A new domain called ``rcp``, which will contain the ``recipe`` directive and
``reref`` role
* A new domain called ``recipe``, which will contain the ``recipe`` directive
and ``ref`` role
Prerequisites
-------------
As with :doc:`the previous extensions <todo>`, we will not be distributing this
plugin via PyPI so once again we need a Sphinx project to call this from. You
can use an existing project or create a new one using
:program:`sphinx-quickstart`.
We assume you are using separate source (:file:`source`) and build
(:file:`build`) folders. Your extension file could be in any folder of your
project. In our case, let's do the following:
#. Create an :file:`_ext` folder in :file:`source`
#. Create a new Python file in the :file:`_ext` folder called :file:`recipe.py`
We need the same setup as in :doc:`the previous extensions <todo>`. This time,
we will be putting out extension in a file called :file:`recipe.py`.
Here is an example of the folder structure you might obtain:
@@ -59,7 +50,7 @@ Here is an example of the folder structure you might obtain:
└── source
   ├── _ext
  └── todo.py
  └── recipe.py
   ├── conf.py
   └── index.rst
@@ -67,8 +58,8 @@ Here is an example of the folder structure you might obtain:
Writing the extension
---------------------
Open :file:`receipe.py` and paste the following code in it, all of which we
will explain in detail shortly:
Open :file:`recipe.py` and paste the following code in it, all of which we will
explain in detail shortly:
.. literalinclude:: examples/recipe.py
:language: python
@@ -79,12 +70,12 @@ on.
.. rubric:: The directive class
The first thing to examine is the ``RecipeNode`` directive:
The first thing to examine is the ``RecipeDirective`` directive:
.. literalinclude:: examples/recipe.py
:language: python
:linenos:
:lines: 15-40
:lines: 17-37
Unlike :doc:`helloworld` and :doc:`todo`, this directive doesn't derive from
:class:`docutils.parsers.rst.Directive` and doesn't define a ``run`` method.
@@ -100,7 +91,7 @@ for this node.
We also see that this directive defines ``has_content``, ``required_arguments``
and ``option_spec``. Unlike the ``TodoDirective`` directive added in the
:doc:`previous tutorial <todo>`, this directive takes a single argument, the
recipe name, and an optional argument, ``contains``, in addition to the nested
recipe name, and an option, ``contains``, in addition to the nested
reStructuredText in the body.
.. rubric:: The index classes
@@ -112,11 +103,11 @@ reStructuredText in the body.
.. literalinclude:: examples/recipe.py
:language: python
:linenos:
:lines: 44-172
:lines: 40-108
Both ``IngredientIndex`` and ``RecipeIndex`` are derived from :class:`Index`.
They implement custom logic to generate a tuple of values that define the
index. Note that ``RecipeIndex`` is a degenerate index that has only one entry.
index. Note that ``RecipeIndex`` is a simple index that has only one entry.
Extending it to cover more object types is not yet part of the code.
Both indices use the method :meth:`Index.generate` to do their work. This
@@ -135,9 +126,9 @@ creating here.
.. literalinclude:: examples/recipe.py
:language: python
:linenos:
:lines: 175-223
:lines: 111-161
There are some interesting things to note about this ``rcp`` domain and domains
There are some interesting things to note about this ``recipe`` domain and domains
in general. Firstly, we actually register our directives, roles and indices
here, via the ``directives``, ``roles`` and ``indices`` attributes, rather than
via calls later on in ``setup``. We can also note that we aren't actually
@@ -146,19 +137,21 @@ defining a custom role and are instead reusing the
:class:`sphinx.domains.Domain.resolve_xref` method. This method takes two
arguments, ``typ`` and ``target``, which refer to the cross-reference type and
its target name. We'll use ``target`` to resolve our destination from our
domain's ``objects`` because we currently have only one type of node.
domain's ``recipes`` because we currently have only one type of node.
Moving on, we can see that we've defined two items in ``intitial_data``:
``objects`` and ``obj2ingredient``. These contain a list of all objects defined
(i.e. all recipes) and a hash that maps a canonical ingredient name to the list
of objects. The way we name objects is common across our extension and is
defined in the ``get_full_qualified_name`` method. For each object created, the
canonical name is ``rcp.<typename>.<objectname>``, where ``<typename>`` is the
Python type of the object, and ``<objectname>`` is the name the documentation
writer gives the object. This enables the extension to use different object
types that share the same name. Having a canonical name and central place for
our objects is a huge advantage. Both our indices and our cross-referencing
code use this feature.
Moving on, we can see that we've defined ``initial_data``. The values defined in
``initial_data`` will be copied to ``env.domaindata[domain_name]`` as the
initial data of the domain, and domain instances can access it via
``self.data``. We see that we have defined two items in ``initial_data``:
``recipes`` and ``recipe2ingredient``. These contain a list of all objects
defined (i.e. all recipes) and a hash that maps a canonical ingredient name to
the list of objects. The way we name objects is common across our extension and
is defined in the ``get_full_qualified_name`` method. For each object created,
the canonical name is ``recipe.<recipename>``, where ``<recipename>`` is the
name the documentation writer gives the object (a recipe). This enables the
extension to use different object types that share the same name. Having a
canonical name and central place for our objects is a huge advantage. Both our
indices and our cross-referencing code use this feature.
.. rubric:: The ``setup`` function
@@ -171,7 +164,7 @@ hook the various parts of our extension into Sphinx. Let's look at the
.. literalinclude:: examples/recipe.py
:language: python
:linenos:
:lines: 226-
:lines: 164-
This looks a little different to what we're used to seeing. There are no calls
to :meth:`~Sphinx.add_directive` or even :meth:`~Sphinx.add_role`. Instead, we
@@ -192,8 +185,8 @@ You can now use the extension throughout your project. For example:
Joe's Recipes
=============
Below are a collection of my favourite receipes. I highly recommend the
:rcp:reref:`TomatoSoup` receipe in particular!
Below are a collection of my favourite recipes. I highly recommend the
:recipe:ref:`TomatoSoup` recipe in particular!
.. toctree::
@@ -204,15 +197,15 @@ You can now use the extension throughout your project. For example:
The recipe contains `tomato` and `cilantro`.
.. rcp:recipe:: TomatoSoup
.. recipe:recipe:: TomatoSoup
:contains: tomato cilantro salt pepper
This recipe is a tasty tomato soup, combine all ingredients
and cook.
The important things to note are the use of the ``:rcp:recipe:`` role to
The important things to note are the use of the ``:recipe:ref:`` role to
cross-reference the recipe actually defined elsewhere (using the
``:rcp:recipe:`` directive.
``:recipe:recipe:`` directive.
Further reading

View File

@@ -174,10 +174,10 @@ The node structure that the directive returns looks like this::
.. rubric:: The event handlers
Event handlers are one of Sphinx's most powerful features, providing a way to do
hook into any part of the documentation process. There are many hooks available,
as detailed in :doc:`/extdev/appapi`, and we're going to use a subset of them
here.
Event handlers are one of Sphinx's most powerful features, providing a way to
do hook into any part of the documentation process. There are many events
provided by Sphinx itself, as detailed in :ref:`the API guide <events>`, and
we're going to use a subset of them here.
Let's look at the event handlers used in the above example. First, the one for
the :event:`env-purge-doc` event:
@@ -203,18 +203,19 @@ The other handler belongs to the :event:`doctree-resolved` event:
:lines: 64-103
The :event:`doctree-resolved` event is emitted at the end of :ref:`phase 3
<build-phases>` and allows custom resolving to be done. The handler we have
written for this event is a bit more involved. If the ``todo_include_todos``
config value (which we'll describe shortly) is false, all ``todo`` and
``todolist`` nodes are removed from the documents. If not, ``todo`` nodes just
stay where and how they are. ``todolist`` nodes are replaced by a list of todo
entries, complete with backlinks to the location where they come from. The list
items are composed of the nodes from the ``todo`` entry and docutils nodes
created on the fly: a paragraph for each entry, containing text that gives the
location, and a link (reference node containing an italic node) with the
backreference. The reference URI is built by ``app.builder.get_relative_uri``
which creates a suitable URI depending on the used builder, and appending the
todo node's (the target's) ID as the anchor name.
(resolving) <build-phases>` and allows custom resolving to be done. The handler
we have written for this event is a bit more involved. If the
``todo_include_todos`` config value (which we'll describe shortly) is false,
all ``todo`` and ``todolist`` nodes are removed from the documents. If not,
``todo`` nodes just stay where and how they are. ``todolist`` nodes are
replaced by a list of todo entries, complete with backlinks to the location
where they come from. The list items are composed of the nodes from the
``todo`` entry and docutils nodes created on the fly: a paragraph for each
entry, containing text that gives the location, and a link (reference node
containing an italic node) with the backreference. The reference URI is built
by :meth:`sphinx.builders.Builder.get_relative_uri`` which creates a suitable
URI depending on the used builder, and appending the todo node's (the target's)
ID as the anchor name.
.. rubric:: The ``setup`` function
@@ -238,13 +239,13 @@ What the individual calls do is the following:
If the third argument was ``'html'``, HTML documents would be full rebuild if the
config value changed its value. This is needed for config values that
influence reading (build :ref:`phase 1 <build-phases>`).
influence reading (build :ref:`phase 1 (reading) <build-phases>`).
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
can specify visitor functions for each supported output format. These visitor
functions are needed when the new nodes stay until :ref:`phase 4 <build-phases>`
-- since the ``todolist`` node is always replaced in :ref:`phase 3 <build-phases>`,
it doesn't need any.
functions are needed when the new nodes stay until :ref:`phase 4 (writing)
<build-phases>`. Since the ``todolist`` node is always replaced in
:ref:`phase 3 (resolving) <build-phases>`, it doesn't need any.
* :meth:`~Sphinx.add_directive` adds a new *directive*, given by name and class.
@@ -279,7 +280,7 @@ For example:
sys.path.append(os.path.abspath("./_ext"))
extensions = ['helloworld']
extensions = ['todo']
todo_include_todos = False

View File

@@ -91,32 +91,54 @@ class Index:
def generate(self, docnames=None):
# type: (Iterable[str]) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]
"""Return entries for the index given by *name*. If *docnames* is
given, restrict to entries referring to these docnames.
"""Get entries for the index.
The return value is a tuple of ``(content, collapse)``, where *collapse*
is a boolean that determines if sub-entries should start collapsed (for
output formats that support collapsing sub-entries).
If ``docnames`` is given, restrict to entries referring to these
docnames.
*content* is a sequence of ``(letter, entries)`` tuples, where *letter*
is the "heading" for the given *entries*, usually the starting letter.
The return value is a tuple of ``(content, collapse)``:
*entries* is a sequence of single entries, where a single entry is a
sequence ``[name, subtype, docname, anchor, extra, qualifier, descr]``.
The items in this sequence have the following meaning:
``collapse``
A boolean that determines if sub-entries should start collapsed (for
output formats that support collapsing sub-entries).
- `name` -- the name of the index entry to be displayed
- `subtype` -- sub-entry related type:
0 -- normal entry
1 -- entry with sub-entries
2 -- sub-entry
- `docname` -- docname where the entry is located
- `anchor` -- anchor for the entry within `docname`
- `extra` -- extra info for the entry
- `qualifier` -- qualifier for the description
- `descr` -- description for the entry
``content``:
A sequence of ``(letter, entries)`` tuples, where ``letter`` is the
"heading" for the given ``entries``, usually the starting letter, and
``entries`` is a sequence of single entries. Each entry is a sequence
``[name, subtype, docname, anchor, extra, qualifier, descr]``. The
items in this sequence have the following meaning:
Qualifier and description are not rendered e.g. in LaTeX output.
``name``
The name of the index entry to be displayed.
``subtype``
The sub-entry related type. One of:
``0``
A normal entry.
``1``
An entry with sub-entries.
``2``
A sub-entry.
``docname``
*docname* where the entry is located.
``anchor``
Anchor for the entry within ``docname``
``extra``
Extra info for the entry.
``qualifier``
Qualifier for the description.
``descr``
Description for the entry.
Qualifier and description are not rendered for some output formats such
as LaTeX.
"""
raise NotImplementedError
@@ -318,21 +340,37 @@ class Domain:
def get_objects(self):
# type: () -> Iterable[Tuple[str, str, str, str, str, int]]
"""Return an iterable of "object descriptions", which are tuples with
five items:
"""Return an iterable of "object descriptions".
* `name` -- fully qualified name
* `dispname` -- name to display when searching/linking
* `type` -- object type, a key in ``self.object_types``
* `docname` -- the document where it is to be found
* `anchor` -- the anchor name for the object
* `priority` -- how "important" the object is (determines placement
in search results)
Object descriptions are tuples with six items:
- 1: default priority (placed before full-text matches)
- 0: object is important (placed before default-priority objects)
- 2: object is unimportant (placed after full-text matches)
- -1: object should not show up in search at all
``name``
Fully qualified name.
``dispname``
Name to display when searching/linking.
``type``
Object type, a key in ``self.object_types``.
``docname``
The document where it is to be found.
``anchor``
The anchor name for the object.
``priority``
How "important" the object is (determines placement in search
results). One of:
``1``
Default priority (placed before full-text matches).
``0``
Object is important (placed before default-priority objects).
``2``
Object is unimportant (placed after full-text matches).
``-1``
Object should not show up in search at all.
"""
return []