summaryrefslogtreecommitdiff
path: root/sphinx/domains
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2011-09-22 10:42:09 +0200
committerGeorg Brandl <georg@python.org>2011-09-22 10:42:09 +0200
commitc5599ea28eeac416ab4646a9ef1b9eb3d783f8b7 (patch)
tree76a1db0ec536f130b4394c48be68fee820d8024b /sphinx/domains
parentccef6db7cb04db18258c41a4fd5af6384525737a (diff)
parent7cabc9f2a989a78753f9ddcbfd941dd3fc45e106 (diff)
downloadsphinx-c5599ea28eeac416ab4646a9ef1b9eb3d783f8b7.tar.gz
Merge with 1.0
Diffstat (limited to 'sphinx/domains')
-rw-r--r--sphinx/domains/__init__.py29
-rw-r--r--sphinx/domains/c.py2
-rw-r--r--sphinx/domains/cpp.py91
-rw-r--r--sphinx/domains/javascript.py6
-rw-r--r--sphinx/domains/python.py107
-rw-r--r--sphinx/domains/rst.py9
-rw-r--r--sphinx/domains/std.py122
7 files changed, 257 insertions, 109 deletions
diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py
index 1d04a593..c48568eb 100644
--- a/sphinx/domains/__init__.py
+++ b/sphinx/domains/__init__.py
@@ -66,9 +66,8 @@ class Index(object):
self.domain = domain
def generate(self, docnames=None):
- """
- Return entries for the index given by *name*. If *docnames* is given,
- restrict to entries referring to these docnames.
+ """Return entries for the index given by *name*. If *docnames* is
+ given, restrict to entries referring to these docnames.
The return value is a tuple of ``(content, collapse)``, where *collapse*
is a boolean that determines if sub-entries should start collapsed (for
@@ -160,8 +159,7 @@ class Domain(object):
self.objtypes_for_role = self._role2type.get
def role(self, name):
- """
- Return a role adapter function that always gives the registered
+ """Return a role adapter function that always gives the registered
role its full name ('domain:name') as the first argument.
"""
if name in self._role_cache:
@@ -177,8 +175,7 @@ class Domain(object):
return role_adapter
def directive(self, name):
- """
- Return a directive adapter class that always gives the registered
+ """Return a directive adapter class that always gives the registered
directive its full name ('domain:name') as ``self.name``.
"""
if name in self._directive_cache:
@@ -197,21 +194,16 @@ class Domain(object):
# methods that should be overwritten
def clear_doc(self, docname):
- """
- Remove traces of a document in the domain-specific inventories.
- """
+ """Remove traces of a document in the domain-specific inventories."""
pass
def process_doc(self, env, docname, document):
- """
- Process a document after it is read by the environment.
- """
+ """Process a document after it is read by the environment."""
pass
def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
- """
- Resolve the ``pending_xref`` *node* with the given *typ* and *target*.
+ """Resolve the pending_xref *node* with the given *typ* and *target*.
This method should return a new node, to replace the xref node,
containing the *contnode* which is the markup content of the
@@ -227,8 +219,7 @@ class Domain(object):
pass
def get_objects(self):
- """
- Return an iterable of "object descriptions", which are tuples with
+ """Return an iterable of "object descriptions", which are tuples with
five items:
* `name` -- fully qualified name
@@ -247,9 +238,7 @@ class Domain(object):
return []
def get_type_name(self, type, primary=False):
- """
- Return full name for given ObjType.
- """
+ """Return full name for given ObjType."""
if primary:
return type.lname
return _('%s %s') % (self.label, type.lname)
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index 48fbb36f..b0dd332b 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -168,7 +168,7 @@ class CObject(ObjectDescription):
indextext = self.get_index_text(name)
if indextext:
- self.indexnode['entries'].append(('single', indextext, name, name))
+ self.indexnode['entries'].append(('single', indextext, name, ''))
def before_content(self):
self.typename_set = False
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index dac0106b..0d33f59d 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -21,6 +21,7 @@ from sphinx.domains import Domain, ObjType
from sphinx.directives import ObjectDescription
from sphinx.util.nodes import make_refnode
from sphinx.util.compat import Directive
+from sphinx.util.docfields import Field, GroupedField
_identifier_re = re.compile(r'(~?\b[a-zA-Z_][a-zA-Z0-9_]*)\b')
@@ -28,6 +29,8 @@ _whitespace_re = re.compile(r'\s+(?u)')
_string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"
r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
_visibility_re = re.compile(r'\b(public|private|protected)\b')
+_array_def_re = re.compile(r'\[\s*(.+?)?\s*\]')
+_template_arg_re = re.compile(r'[^,>]+')
_operator_re = re.compile(r'''(?x)
\[\s*\]
| \(\s*\)
@@ -109,7 +112,7 @@ class DefinitionError(Exception):
return self.description
def __str__(self):
- return unicode(self.encode('utf-8'))
+ return unicode(self).encode('utf-8')
class DefExpr(object):
@@ -131,17 +134,21 @@ class DefExpr(object):
def __ne__(self, other):
return not self.__eq__(other)
+ __hash__ = None
+
def clone(self):
- """Close a definition expression node"""
+ """Clone a definition expression node."""
return deepcopy(self)
def get_id(self):
- """Returns the id for the node"""
+ """Return the id for the node."""
return u''
def get_name(self):
- """Returns the name. Returns either `None` or a node with
- a name you might call :meth:`split_owner` on.
+ """Return the name.
+
+ Returns either `None` or a node with a name you might call
+ :meth:`split_owner` on.
"""
return None
@@ -154,7 +161,7 @@ class DefExpr(object):
return None, self
def prefix(self, prefix):
- """Prefixes a name node (a node returned by :meth:`get_name`)."""
+ """Prefix a name node (a node returned by :meth:`get_name`)."""
raise NotImplementedError()
def __str__(self):
@@ -235,6 +242,18 @@ class TemplateDefExpr(PrimaryDefExpr):
return u'%s<%s>' % (self.typename, u', '.join(map(unicode, self.args)))
+class ConstantTemplateArgExpr(PrimaryDefExpr):
+
+ def __init__(self, arg):
+ self.arg = arg
+
+ def get_id(self):
+ return self.arg.replace(u' ', u'-')
+
+ def __unicode__(self):
+ return unicode(self.arg)
+
+
class WrappingDefExpr(DefExpr):
def __init__(self, typename):
@@ -269,6 +288,22 @@ class PtrDefExpr(WrappingDefExpr):
return u'%s*' % self.typename
+class ArrayDefExpr(WrappingDefExpr):
+
+ def __init__(self, typename, size_hint=None):
+ WrappingDefExpr.__init__(self, typename)
+ self.size_hint = size_hint
+
+ def get_id(self):
+ return self.typename.get_id() + u'A'
+
+ def __unicode__(self):
+ return u'%s[%s]' % (
+ self.typename,
+ self.size_hint is not None and unicode(self.size_hint) or u''
+ )
+
+
class RefDefExpr(WrappingDefExpr):
def get_id(self):
@@ -523,8 +558,15 @@ class DefinitionParser(object):
return CastOpDefExpr(type)
def _parse_name(self):
+ return self._parse_name_or_template_arg(False)
+
+ def _parse_name_or_template_arg(self, in_template):
if not self.match(_identifier_re):
- self.fail('expected name')
+ if not in_template:
+ self.fail('expected name')
+ if not self.match(_template_arg_re):
+ self.fail('expected name or constant template argument')
+ return ConstantTemplateArgExpr(self.matched_text.strip())
identifier = self.matched_text
# strictly speaking, operators are not regular identifiers
@@ -558,6 +600,8 @@ class DefinitionParser(object):
expr = ConstDefExpr(expr)
elif self.skip_string('*'):
expr = PtrDefExpr(expr)
+ elif self.match(_array_def_re):
+ expr = ArrayDefExpr(expr, self.last_match.group(1))
elif self.skip_string('&'):
expr = RefDefExpr(expr)
else:
@@ -591,8 +635,8 @@ class DefinitionParser(object):
rv = ModifierDefExpr(NameDefExpr(typename), modifiers)
return self._attach_crefptr(rv, is_const)
- def _parse_type_expr(self):
- typename = self._parse_name()
+ def _parse_type_expr(self, in_template=False):
+ typename = self._parse_name_or_template_arg(in_template)
self.skip_ws()
if not self.skip_string('<'):
return typename
@@ -641,7 +685,7 @@ class DefinitionParser(object):
(result and not self.skip_string('::')) or \
self.eof:
break
- result.append(self._parse_type_expr())
+ result.append(self._parse_type_expr(in_template))
if not result:
self.fail('expected type')
@@ -689,6 +733,13 @@ class DefinitionParser(object):
self.fail('expected comma between arguments')
self.skip_ws()
+ if self.skip_string('...'):
+ args.append(ArgumentDefExpr(None, '...', None))
+ if self.skip_string(')'):
+ break
+ else:
+ self.fail('expected closing parenthesis after ellipses')
+
argtype = self._parse_type()
argname = default = None
self.skip_ws()
@@ -788,6 +839,17 @@ class DefinitionParser(object):
class CPPObject(ObjectDescription):
"""Description of a C++ language object."""
+ doc_field_types = [
+ GroupedField('parameter', label=l_('Parameters'),
+ names=('param', 'parameter', 'arg', 'argument'),
+ can_collapse=True),
+ GroupedField('exceptions', label=l_('Throws'), rolename='cpp:class',
+ names=('throws', 'throw', 'exception'),
+ can_collapse=True),
+ Field('returnvalue', label=l_('Returns'), has_arg=False,
+ names=('returns', 'return')),
+ ]
+
def attach_name(self, node, name):
owner, name = name.split_owner()
varname = unicode(name)
@@ -829,7 +891,7 @@ class CPPObject(ObjectDescription):
indextext = self.get_index_text(name)
if indextext:
- self.indexnode['entries'].append(('single', indextext, theid, name))
+ self.indexnode['entries'].append(('single', indextext, theid, ''))
def before_content(self):
lastname = self.names and self.names[-1]
@@ -977,8 +1039,9 @@ class CPPFunctionObject(CPPObject):
class CPPCurrentNamespace(Directive):
- """This directive is just to tell Sphinx that we're documenting
- stuff in namespace foo.
+ """
+ This directive is just to tell Sphinx that we're documenting stuff in
+ namespace foo.
"""
has_content = False
@@ -1077,7 +1140,7 @@ class CPPDomain(Domain):
node.line)
return None
- parent = node['cpp:parent']
+ parent = node.get('cpp:parent', None)
rv = _create_refnode(expr)
if rv is not None or parent is None:
diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py
index e53eb5fd..09d555ad 100644
--- a/sphinx/domains/javascript.py
+++ b/sphinx/domains/javascript.py
@@ -98,7 +98,7 @@ class JSObject(ObjectDescription):
if indextext:
self.indexnode['entries'].append(('single', indextext,
fullname.replace('$', '_S_'),
- fullname))
+ ''))
def get_index_text(self, objectname, name_obj):
name, obj = name_obj
@@ -128,11 +128,13 @@ class JSCallable(JSObject):
can_collapse=True),
Field('returnvalue', label=l_('Returns'), has_arg=False,
names=('returns', 'return')),
+ Field('returntype', label=l_('Return type'), has_arg=False,
+ names=('rtype',)),
]
class JSConstructor(JSCallable):
- """Like a callable but with a different prefix"""
+ """Like a callable but with a different prefix."""
display_prefix = 'class '
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index 0220afd0..4004599c 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -88,6 +88,7 @@ class PyObject(ObjectDescription):
option_spec = {
'noindex': directives.flag,
'module': directives.unchanged,
+ 'annotation': directives.unchanged,
}
doc_field_types = [
@@ -110,22 +111,21 @@ class PyObject(ObjectDescription):
]
def get_signature_prefix(self, sig):
- """
- May return a prefix to put before the object name in the signature.
+ """May return a prefix to put before the object name in the
+ signature.
"""
return ''
def needs_arglist(self):
- """
- May return true if an empty argument list is to be generated even if
+ """May return true if an empty argument list is to be generated even if
the document contains none.
"""
return False
def handle_signature(self, sig, signode):
- """
- Transform a Python signature into RST nodes.
- Returns (fully qualified name of the thing, classname if any).
+ """Transform a Python signature into RST nodes.
+
+ Return (fully qualified name of the thing, classname if any).
If inside a class, the current class name is handled intelligently:
* it is stripped from the displayed name if present
@@ -181,6 +181,8 @@ class PyObject(ObjectDescription):
nodetext = modname + '.'
signode += addnodes.desc_addname(nodetext, nodetext)
+ anno = self.options.get('annotation')
+
signode += addnodes.desc_name(name, name)
if not arglist:
if self.needs_arglist():
@@ -188,16 +190,19 @@ class PyObject(ObjectDescription):
signode += addnodes.desc_parameterlist()
if retann:
signode += addnodes.desc_returns(retann, retann)
+ if anno:
+ signode += addnodes.desc_annotation(' ' + anno, ' ' + anno)
return fullname, name_prefix
+
_pseudo_parse_arglist(signode, arglist)
if retann:
signode += addnodes.desc_returns(retann, retann)
+ if anno:
+ signode += addnodes.desc_annotation(' ' + anno, ' ' + anno)
return fullname, name_prefix
def get_index_text(self, modname, name):
- """
- Return the text for the index entry of the object.
- """
+ """Return the text for the index entry of the object."""
raise NotImplementedError('must be implemented in subclasses')
def add_target_and_index(self, name_cls, sig, signode):
@@ -224,7 +229,7 @@ class PyObject(ObjectDescription):
indextext = self.get_index_text(modname, name_cls)
if indextext:
self.indexnode['entries'].append(('single', indextext,
- fullname, fullname))
+ fullname, ''))
def before_content(self):
# needed for automatic qualification of members (reset in subclasses)
@@ -360,6 +365,38 @@ class PyClassmember(PyObject):
self.clsname_set = True
+class PyDecoratorMixin(object):
+ """
+ Mixin for decorator directives.
+ """
+ def handle_signature(self, sig, signode):
+ ret = super(PyDecoratorMixin, self).handle_signature(sig, signode)
+ signode.insert(0, addnodes.desc_addname('@', '@'))
+ return ret
+
+ def needs_arglist(self):
+ return False
+
+
+class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel):
+ """
+ Directive to mark functions meant to be used as decorators.
+ """
+ def run(self):
+ # a decorator function is a function after all
+ self.name = 'py:function'
+ return PyModulelevel.run(self)
+
+
+class PyDecoratorMethod(PyDecoratorMixin, PyClassmember):
+ """
+ Directive to mark methods meant to be used as decorators.
+ """
+ def run(self):
+ self.name = 'py:method'
+ return PyClassmember.run(self)
+
+
class PyModule(Directive):
"""
Directive to mark description of a new module.
@@ -386,26 +423,17 @@ class PyModule(Directive):
env.domaindata['py']['modules'][modname] = \
(env.docname, self.options.get('synopsis', ''),
self.options.get('platform', ''), 'deprecated' in self.options)
- # make a duplicate entry in 'objects' to facilitate searching for
- # the module in PythonDomain.find_obj()
+ # make a duplicate entry in 'objects' to facilitate searching for the
+ # module in PythonDomain.find_obj()
env.domaindata['py']['objects'][modname] = (env.docname, 'module')
- targetnode = nodes.target('', '', ids=['module-' + modname],
- ismod=True)
+ targetnode = nodes.target('', '', ids=['module-' + modname], ismod=True)
self.state.document.note_explicit_target(targetnode)
+ # the platform and synopsis aren't printed; in fact, they are only used
+ # in the modindex currently
ret.append(targetnode)
- # XXX this behavior of the module directive is a mess...
- if 'platform' in self.options:
- platform = self.options['platform']
- node = nodes.paragraph()
- node += nodes.emphasis('', _('Platforms: '))
- node += nodes.Text(platform, platform)
- ret.append(node)
- # the synopsis isn't printed; in fact, it is only used in the
- # modindex currently
- if not noindex:
indextext = _('%s (module)') % modname
inode = addnodes.index(entries=[('single', indextext,
- 'module-' + modname, modname)])
+ 'module-' + modname, '')])
ret.append(inode)
return ret
@@ -540,16 +568,18 @@ class PythonDomain(Domain):
}
directives = {
- 'function': PyModulelevel,
- 'data': PyModulelevel,
- 'class': PyClasslike,
- 'exception': PyClasslike,
- 'method': PyClassmember,
- 'classmethod': PyClassmember,
- 'staticmethod': PyClassmember,
- 'attribute': PyClassmember,
- 'module': PyModule,
- 'currentmodule': PyCurrentModule,
+ 'function': PyModulelevel,
+ 'data': PyModulelevel,
+ 'class': PyClasslike,
+ 'exception': PyClasslike,
+ 'method': PyClassmember,
+ 'classmethod': PyClassmember,
+ 'staticmethod': PyClassmember,
+ 'attribute': PyClassmember,
+ 'module': PyModule,
+ 'currentmodule': PyCurrentModule,
+ 'decorator': PyDecoratorFunction,
+ 'decoratormethod': PyDecoratorMethod,
}
roles = {
'data': PyXRefRole(),
@@ -579,9 +609,8 @@ class PythonDomain(Domain):
del self.data['modules'][modname]
def find_obj(self, env, modname, classname, name, type, searchmode=0):
- """
- Find a Python object for "name", perhaps using the given module and/or
- classname. Returns a list of (name, object entry) tuples.
+ """Find a Python object for "name", perhaps using the given module
+ and/or classname. Returns a list of (name, object entry) tuples.
"""
# skip parens
if name[-2:] == '()':
diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py
index 6b3e05ee..e67f827e 100644
--- a/sphinx/domains/rst.py
+++ b/sphinx/domains/rst.py
@@ -48,7 +48,7 @@ class ReSTMarkup(ObjectDescription):
indextext = self.get_index_text(self.objtype, name)
if indextext:
self.indexnode['entries'].append(('single', indextext,
- targetname, targetname))
+ targetname, ''))
def get_index_text(self, objectname, name):
if self.objtype == 'directive':
@@ -59,9 +59,10 @@ class ReSTMarkup(ObjectDescription):
def parse_directive(d):
- """
- Parses a directive signature. Returns (directive, arguments) string tuple.
- if no arguments are given, returns (directive, '').
+ """Parse a directive signature.
+
+ Returns (directive, arguments) string tuple. If no arguments are given,
+ returns (directive, '').
"""
dir = d.strip()
if not dir.startswith('.'):
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index 1fd015ac..9d5b0b0f 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -14,6 +14,7 @@ import unicodedata
from docutils import nodes
from docutils.parsers.rst import directives
+from docutils.statemachine import ViewList
from sphinx import addnodes
from sphinx.roles import XRefRole
@@ -60,7 +61,7 @@ class GenericObject(ObjectDescription):
indextype = 'single'
indexentry = self.indextemplate % (name,)
self.indexnode['entries'].append((indextype, indexentry,
- targetname, targetname))
+ targetname, ''))
self.env.domaindata['std']['objects'][self.objtype, name] = \
self.env.docname, targetname
@@ -81,8 +82,8 @@ class EnvVarXRefRole(XRefRole):
tgtid = 'index-%s' % env.new_serialno('index')
indexnode = addnodes.index()
indexnode['entries'] = [
- ('single', varname, tgtid, varname),
- ('single', _('environment variable; %s') % varname, tgtid, varname)
+ ('single', varname, tgtid, ''),
+ ('single', _('environment variable; %s') % varname, tgtid, '')
]
targetnode = nodes.target('', '', ids=[tgtid])
document.note_explicit_target(targetnode)
@@ -117,7 +118,7 @@ class Target(Directive):
indextype = indexentry[:colon].strip()
indexentry = indexentry[colon+1:].strip()
inode = addnodes.index(entries=[(indextype, indexentry,
- targetname, targetname)])
+ targetname, '')])
ret.insert(0, inode)
name = self.name
if ':' in self.name:
@@ -160,7 +161,7 @@ class Cmdoption(ObjectDescription):
self.indexnode['entries'].append(
('pair', _('%scommand line option; %s') %
((currprogram and currprogram + ' ' or ''), sig),
- targetname, targetname))
+ targetname, ''))
self.env.domaindata['std']['progoptions'][currprogram, name] = \
self.env.docname, targetname
@@ -206,8 +207,8 @@ class OptionXRefRole(XRefRole):
class Glossary(Directive):
"""
- Directive to create a glossary with cross-reference targets
- for :term: roles.
+ Directive to create a glossary with cross-reference targets for :term:
+ roles.
"""
has_content = True
@@ -224,37 +225,100 @@ class Glossary(Directive):
gloss_entries = env.temp_data.setdefault('gloss_entries', set())
node = addnodes.glossary()
node.document = self.state.document
- self.state.nested_parse(self.content, self.content_offset, node)
-
- # the content should be definition lists
- dls = [child for child in node
- if isinstance(child, nodes.definition_list)]
- # now, extract definition terms to enable cross-reference creation
- new_dl = nodes.definition_list()
- new_dl['classes'].append('glossary')
+
+ # This directive implements a custom format of the reST definition list
+ # that allows multiple lines of terms before the definition. This is
+ # easy to parse since we know that the contents of the glossary *must
+ # be* a definition list.
+
+ # first, collect single entries
+ entries = []
+ in_definition = True
+ was_empty = True
+ messages = []
+ for line, (source, lineno) in zip(self.content, self.content.items):
+ # empty line -> add to last definition
+ if not line:
+ if in_definition and entries:
+ entries[-1][1].append('', source, lineno)
+ was_empty = True
+ continue
+ # unindented line -> a term
+ if line and not line[0].isspace():
+ # first term of definition
+ if in_definition:
+ if not was_empty:
+ messages.append(self.state.reporter.system_message(
+ 2, 'glossary term must be preceded by empty line',
+ source=source, line=lineno))
+ entries.append(([(line, source, lineno)], ViewList()))
+ in_definition = False
+ # second term and following
+ else:
+ if was_empty:
+ messages.append(self.state.reporter.system_message(
+ 2, 'glossary terms must not be separated by empty '
+ 'lines', source=source, line=lineno))
+ entries[-1][0].append((line, source, lineno))
+ else:
+ if not in_definition:
+ # first line of definition, determines indentation
+ in_definition = True
+ indent_len = len(line) - len(line.lstrip())
+ entries[-1][1].append(line[indent_len:], source, lineno)
+ was_empty = False
+
+ # now, parse all the entries into a big definition list
items = []
- for dl in dls:
- for li in dl.children:
- if not li.children or not isinstance(li[0], nodes.term):
- continue
- termtext = li.children[0].astext()
+ for terms, definition in entries:
+ termtexts = []
+ termnodes = []
+ system_messages = []
+ ids = []
+ for line, source, lineno in terms:
+ # parse the term with inline markup
+ res = self.state.inline_text(line, lineno)
+ system_messages.extend(res[1])
+
+ # get a text-only representation of the term and register it
+ # as a cross-reference target
+ tmp = nodes.paragraph('', '', *res[0])
+ termtext = tmp.astext()
new_id = 'term-' + nodes.make_id(termtext)
if new_id in gloss_entries:
new_id = 'term-' + str(len(gloss_entries))
gloss_entries.add(new_id)
- li[0]['names'].append(new_id)
- li[0]['ids'].append(new_id)
+ ids.append(new_id)
objects['term', termtext.lower()] = env.docname, new_id
+ termtexts.append(termtext)
# add an index entry too
indexnode = addnodes.index()
- indexnode['entries'] = [('single', termtext, new_id, termtext)]
- li.insert(0, indexnode)
- items.append((termtext, li))
+ indexnode['entries'] = [('single', termtext, new_id, 'main')]
+ termnodes.append(indexnode)
+ termnodes.extend(res[0])
+ termnodes.append(addnodes.termsep())
+ # make a single "term" node with all the terms, separated by termsep
+ # nodes (remove the dangling trailing separator)
+ term = nodes.term('', '', *termnodes[:-1])
+ term['ids'].extend(ids)
+ term['names'].extend(ids)
+ term += system_messages
+
+ defnode = nodes.definition()
+ self.state.nested_parse(definition, definition.items[0][1], defnode)
+
+ items.append((termtexts,
+ nodes.definition_list_item('', term, defnode)))
+
if 'sorted' in self.options:
- items.sort(key=lambda x: unicodedata.normalize('NFD', x[0].lower()))
- new_dl.extend(item[1] for item in items)
- node.children = [new_dl]
- return [node]
+ items.sort(key=lambda x:
+ unicodedata.normalize('NFD', x[0][0].lower()))
+
+ dlist = nodes.definition_list()
+ dlist['classes'].append('glossary')
+ dlist.extend(item[1] for item in items)
+ node += dlist
+ return messages + [node]
token_re = re.compile('`([a-z_][a-z0-9_]*)`')