Add a CMakeLists.txt which provides the 'manual' target for building the Sphinx documentation. This may require you to set the SPHINXBUILD_EXECUTABLE CMake variable to the sphinx-build executable
Change the file extension to 'rst' rather than 'txt' to avoid clashes with CMakeLists.txt and to help syntax highlighting. Add the doxylink Sphinx extension from sphinx-contrib to provide Doxygen links.
This commit is contained in:
148
documentation/_extensions/sphinxcontrib/doxylink.py
Normal file
148
documentation/_extensions/sphinxcontrib/doxylink.py
Normal file
@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
doxylink
|
||||
~~~~~~~~
|
||||
|
||||
Sphinx extension to link to external Doxygen API documentation.
|
||||
|
||||
It works much like the extlinks extension but it does some more processing to link C++ symbols against their Doxygen HTML documentation.
|
||||
|
||||
.. confval:: doxylink
|
||||
|
||||
The environment is set up with a dictionary mapping the interpereted text role
|
||||
to a tuple of tag file and prefix:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
doxylink = {
|
||||
'polyvox' : ('/home/matt/PolyVox.tag', '/home/matt/PolyVox/html/'),
|
||||
'qtogre' : ('/home/matt/QtOgre.tag', '/home/matt/QtOgre/html/'),
|
||||
}
|
||||
|
||||
This allows one to do:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
:polyvox:`Array <PolyVox::Array>`.
|
||||
:polyvox:`PolyVox::Volume`
|
||||
:qtogre:`QtOgre::Log`
|
||||
:polyvox:`tidyUpMemeory(int) <tidyUpMemory>`
|
||||
:polyvox:`PolyVox::Array::operator[]`
|
||||
|
||||
:requires: Python 2.5
|
||||
|
||||
.. todo::
|
||||
|
||||
Make the extension atuomatically re-run if the tag file is altered on disc
|
||||
|
||||
Find a way to parse the tag file to a DOM tree *once* and then just reference it from then on.
|
||||
|
||||
:copyright: Copyright 2010 by Matt Williams
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from docutils import nodes, utils
|
||||
|
||||
from sphinx.util.nodes import split_explicit_title
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
def find_url(doc, symbol):
|
||||
"""
|
||||
Return the URL for a given symbol.
|
||||
|
||||
This is where the magic happens.
|
||||
This function could be a lot more clever. At present it required the passed symbol to be almost exactly the same as the entries in the Doxygen tag file.
|
||||
|
||||
.. todo::
|
||||
|
||||
Maybe print a list of all possible matches as a warning (but still only return the first)
|
||||
|
||||
:Parameters:
|
||||
doc : xml.etree.ElementTree
|
||||
The XML DOM object
|
||||
symbol : string
|
||||
The symbol to lookup in the file. E.g. something like 'PolyVox::Array' or 'tidyUpMemory'
|
||||
|
||||
:return: String representing the filename part of the URL
|
||||
"""
|
||||
|
||||
#First check for an exact match with a top-level object (namespaces, objects etc.)
|
||||
|
||||
#env = inliner.document.settings.env
|
||||
|
||||
matches = []
|
||||
for compound in doc.findall('.//compound'):
|
||||
if compound.find('name').text == symbol:
|
||||
matches += [compound.find('filename').text]
|
||||
|
||||
if len(matches) > 1:
|
||||
pass
|
||||
#env.warn(env.docname, 'There were multiple matches for `%s`: %s' % (symbol, matches))
|
||||
if len(matches) == 1:
|
||||
return matches[0]
|
||||
|
||||
|
||||
#Strip off first namespace bit of the compound name so that 'ArraySizes' can match 'PolyVox::ArraySizes'
|
||||
for compound in doc.findall('.//compound'):
|
||||
symbol_list = compound.find('name').text.split('::', 1)
|
||||
if len(symbol_list) == 2:
|
||||
reducedsymbol = symbol_list[1]
|
||||
if reducedsymbol == symbol:
|
||||
return compound.find('filename').text
|
||||
|
||||
#Now split the symbol by '::'. Find an exact match for the first part and then a member match for the second
|
||||
#So PolyVox::Array::operator[] becomes like {namespace: "PolyVox::Array", endsymbol: "operator[]"}
|
||||
symbol_list = symbol.rsplit('::', 1)
|
||||
if len(symbol_list) == 2:
|
||||
namespace = symbol_list[0]
|
||||
endsymbol = symbol_list[1]
|
||||
for compound in doc.findall('.//compound'):
|
||||
if compound.find('name').text == namespace:
|
||||
for member in compound.findall('member'):
|
||||
# #If this compound object contains the matching member then return it
|
||||
if member.find('name').text == endsymbol:
|
||||
return member.find('anchorfile').text + '#' + member.find('anchor').text
|
||||
|
||||
#Then we'll look at unqualified members
|
||||
for member in doc.findall('.//member'):
|
||||
if member.find('name').text == symbol:
|
||||
return member.find('anchorfile').text + '#' + member.find('anchor').text
|
||||
|
||||
return None
|
||||
|
||||
def create_role(app, tag_filename, rootdir):
|
||||
def find_doxygen_link(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
text = utils.unescape(text)
|
||||
# from :name:`title <part>`
|
||||
has_explicit_title, title, part = split_explicit_title(text)
|
||||
|
||||
try:
|
||||
tag_file = ET.parse(tag_filename)
|
||||
except (IOError):
|
||||
env = inliner.document.settings.env
|
||||
env.warn(env.docname, 'Could not open %s' % tag_filename)
|
||||
else:
|
||||
url = find_url(tag_file, part)
|
||||
if url:
|
||||
full_url = rootdir + url
|
||||
pnode = nodes.reference(title, title, internal=False, refuri=full_url)
|
||||
return [pnode], []
|
||||
#By here, no match was found
|
||||
env = app.env
|
||||
env.warn(env.docname, 'Could not find match for `%s` in `%s` tag file' % (part, tag_filename), lineno)
|
||||
|
||||
full_url="#"
|
||||
#TODO find which command to use to just output it as plain text (no link) in this case
|
||||
pnode = nodes.reference(title, title, internal=False, refuri=full_url)
|
||||
return [pnode], []
|
||||
|
||||
return find_doxygen_link
|
||||
|
||||
def setup_doxylink_roles(app):
|
||||
for name, [tag_filename, rootdir] in app.config.doxylink.iteritems():
|
||||
app.add_role(name, create_role(app, tag_filename, rootdir))
|
||||
|
||||
def setup(app):
|
||||
app.add_config_value('doxylink', {}, 'env')
|
||||
app.connect('builder-inited', setup_doxylink_roles)
|
Reference in New Issue
Block a user