Open jason-s opened 8 years ago
Agreed. PR is always welcome :-)
I would but I can't figure it out. Ignore the print statements below, this is the best I can get, but I can't seem to add index nodes programmatically via something in app.connect('doctree-read', handler)
or doctree-resolved
def create_index(document, entries, indexname='index', targetid = None):
env = document.settings.env
if targetid is None:
targetid = indexname + '-%s'
targetid = targetid % (env.new_serialno(indexname))
print "GOT TARGET", targetid
targetnode = docutils.nodes.target('', '', refid=targetid)
print targetnode
document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = [(ty, content, targetid, '', None) for ty, content in entries]
indexnode['inline'] = False
return [indexnode, targetnode]
ah -- I got it to work finally, I had to add a call to environment.note_indexentries_from
. Latest source code:
def create_index(document, entries, indexname='index', targetid = None):
"""
Programmatically create an index node in a doctree.
:param document: doctree of an entire document
:param entries: a list of tuples (type, entryname)
where type is ``single``, ``pair``, or ``triple`` and entryname
is the name of the index text
(see http://www.sphinx-doc.org/en/stable/markup/misc.html#directive-index)
:param indexname: name of the index container, useful only for custom indices
:param targetid: format string for the index target id (e.g. ``index-%s``),
``%s`` automatically gets replaced by a serial number counter
:return: a tuple (nodes, targetid) where nodes is the list of nodes generated
that can be added to the doctree, and targetid is the final
index target id used in these nodes.
:Example:
nodes, targetid = create_index(doctree,
[('single', u'abcdef'),
('single', u'ghijkl')]
)
nodes += [docutils.nodes.inline('','',ids=[targetid])]
# add nodes to doctree here #
doctree.settings.env.note_indexentries_from(doctree.settings.env.docname, doctree)
.. note:: The call to ``note_indexentries_from`` extracts all the index entries
from the doctree. If using this function from the doctree-read or
doctree-resolved event handlers, it appears as though the
``note_indexentries_from`` function has already been called automatically
and will need to be called manually, in order to pick up any new
index nodes.
"""
env = document.settings.env
if targetid is None:
targetid = indexname + '-%s'
targetid = targetid % (env.new_serialno(indexname))
targetnode = docutils.nodes.target('', '', refid=targetid)
document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = [(ty, content, targetid, '', None) for ty, content in entries]
indexnode['inline'] = False
return [indexnode, targetnode], targetid
This kind of thing is really hard to do via UTSL -- there are a whole bunch of interacting Python classes which appear to be working together in a really brittle way, so I can never be sure whether what I'm doing is actually the correct way to do it.
Agreed. It is very hard to understand. I don't understand how index works. So we need to refactor codes and improve docs. Please send us your code as a PR. I will take a look. (Sorry I really don't know about index. so I can't comment to your code immediately)
I am trying to write a simple extension to automatically add some index nodes. Unfortunately there doesn't seem to be any base function to do that. I found three places where the same essential stuff is being used to add index nodes to the toctree:
So it looks like I have to copy the appropriate implementation pieces of this (add a target node, add an index node, configure each of them).
It would be really useful to refactor the common functionality into a single, simple function that extensions could use.