Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for xrefitem based page generation #596

Merged
merged 7 commits into from
Nov 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion breathe/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def run(self) -> List[Node]:
if not matches:
warning = create_warning(project_info, self.state, self.lineno, name=name,
kind=self.kind)
return warning.warn('doxygen{kind}: Cannot find namespace "{name}" {tail}')
return warning.warn('doxygen{kind}: Cannot find {kind} "{name}" {tail}')

if 'content-only' in self.options:
# Unpack the single entry in the matches list
Expand Down Expand Up @@ -412,6 +412,14 @@ class DoxygenGroupDirective(_DoxygenContentBlockDirective):
}


class DoxygenPageDirective(_DoxygenContentBlockDirective):
kind = "page"
option_spec = {
"path": unchanged_required,
"project": unchanged_required,
}


# TODO: is this comment still relevant?
# This class was the same as the DoxygenBaseDirective above, except that it
# wraps the output in a definition_list before passing it back. This should be
Expand Down Expand Up @@ -557,6 +565,7 @@ def setup(app: Sphinx) -> None:
"doxygengroup": DoxygenGroupDirective,
"doxygenfile": DoxygenFileDirective,
"autodoxygenfile": AutoDoxygenFileDirective,
"doxygenpage": DoxygenPageDirective,
}

# note: the parser factory contains a cache of the parsed XML
Expand Down
50 changes: 50 additions & 0 deletions breathe/parser/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,12 @@ class docVarListEntryTypeSub(supermod.docVarListEntryType):
def __init__(self, term=None):
supermod.docVarListEntryType.__init__(self, term)

def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and nodeName_ == 'term':
obj_ = supermod.docTitleType.factory()
obj_.build(child_)
self.set_term(obj_)


supermod.docVarListEntryType.subclass = docVarListEntryTypeSub
# end class docVarListEntryTypeSub
Expand Down Expand Up @@ -858,6 +864,33 @@ def __init__(self, id=None, xreftitle=None, xrefdescription=None):
# end class docXRefSectTypeSub


class docVariableListTypeSub(supermod.docVariableListType):

node_type = "docvariablelist"

def __init__(self, valueOf_=''):
supermod.docVariableListType.__init__(self, valueOf_)

self.varlistentries = []
self.listitems = []

def buildChildren(self, child_, nodeName_):
supermod.docVariableListType.buildChildren(self, child_, nodeName_)

if child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "varlistentry":
obj_ = supermod.docVarListEntryType.factory()
obj_.build(child_)
self.varlistentries.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "listitem":
obj_ = supermod.docListItemType.factory()
obj_.build(child_)
self.listitems.append(obj_)


supermod.docVariableListType.subclass = docVariableListTypeSub
# end class docVariableListTypeSub


class docCopyTypeSub(supermod.docCopyType):

node_type = "doccopy"
Expand Down Expand Up @@ -1009,6 +1042,10 @@ def buildChildren(self, child_, nodeName_):
obj_ = supermod.docXRefSectType.factory()
obj_.build(child_)
self.content.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "variablelist":
obj_ = supermod.docVariableListType.factory()
obj_.build(child_)
self.content.append(obj_)


supermod.docParaType.subclass = docParaTypeSub
Expand Down Expand Up @@ -1052,6 +1089,19 @@ def __init__(self, valueOf_='', mixedclass_=None, content_=None):
supermod.docTitleType.__init__(self, valueOf_, mixedclass_, content_)
self.type_ = None

def buildChildren(self, child_, nodeName_):
supermod.docTitleType.buildChildren(self, child_, nodeName_)

if child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "ref":
obj_ = supermod.docRefTextType.factory()
obj_.build(child_)
self.content_.append(obj_)
self.valueOf_ += obj_.valueOf_
elif child_.nodeType == Node.ELEMENT_NODE and nodeName_ == "anchor":
obj_ = supermod.docAnchorType.factory()
obj_.build(child_)
self.content_.append(obj_)


supermod.docTitleType.subclass = docTitleTypeSub
# end class docTitleTypeSub
Expand Down
10 changes: 8 additions & 2 deletions breathe/renderer/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ def __init__(self, app: Sphinx) -> None:
def create_render_filter(self, kind: str, options: Dict[str, Any]) -> Filter:
"""Render filter for group & namespace blocks"""

if kind not in ['group', 'namespace']:
if kind not in ['group', 'page', 'namespace']:
raise UnrecognisedKindError(kind)

# Generate new dictionary from defaults
Expand Down Expand Up @@ -933,7 +933,7 @@ def create_content_filter(self, kind: str, options: Dict[str, Any]) -> Filter:
As a finder/content filter we only need to match exactly what we're interested in.
"""

if kind not in ['group', 'namespace']:
if kind not in ['group', 'page', 'namespace']:
raise UnrecognisedKindError(kind)

node = Node()
Expand Down Expand Up @@ -1063,6 +1063,12 @@ def create_finder_filter(self, kind: str, name: str) -> Filter:
InFilter(KindAccessor(Node()), ["group"]),
InFilter(NameAccessor(Node()), [name])
)
elif kind == 'page':
filter_ = AndFilter(
InFilter(NodeTypeAccessor(Node()), ["compound"]),
InFilter(KindAccessor(Node()), ["page"]),
InFilter(NameAccessor(Node()), [name])
)
else:
# Assume kind == 'namespace'
filter_ = AndFilter(
Expand Down
34 changes: 33 additions & 1 deletion breathe/renderer/sphinxrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1543,7 +1543,15 @@ def visit_docxrefsect(self, node) -> List[Node]:
signode = addnodes.desc_signature()
title = node.xreftitle[0] + ':'
titlenode = nodes.emphasis(text=title)
signode += titlenode
ref = addnodes.pending_xref(
"",
reftype="ref",
refdomain="std",
refexplicit=True,
reftarget=node.id,
refdoc=self.app.env.docname,
*[titlenode])
signode += ref

nodelist = self.render(node.xrefdescription)
contentnode = addnodes.desc_content()
Expand All @@ -1556,6 +1564,27 @@ def visit_docxrefsect(self, node) -> List[Node]:

return [descnode]

def visit_docvariablelist(self, node) -> List[Node]:
output = []
for varlistentry, listitem in zip(node.varlistentries, node.listitems):
descnode = addnodes.desc()
descnode['objtype'] = 'varentry'
signode = addnodes.desc_signature()
signode += self.render_optional(varlistentry)
descnode += signode
contentnode = addnodes.desc_content()
contentnode += self.render_iterable(listitem.para)
descnode += contentnode
output.append(descnode)
return output

def visit_docvarlistentry(self, node) -> List[Node]:
content = node.term.content_
return self.render_iterable(content)

def visit_docanchor(self, node) -> List[None]:
return self.create_doxygen_target(node)

def visit_mixedcontainer(self, node) -> List[Node]:
return self.render_optional(node.getValue())

Expand Down Expand Up @@ -1932,6 +1961,9 @@ def dispatch_memberdef(self, node) -> List[Node]:
"docparamname": visit_docparamname,
"templateparamlist": visit_templateparamlist,
"docxrefsect": visit_docxrefsect,
"docvariablelist": visit_docvariablelist,
"docvarlistentry": visit_docvarlistentry,
"docanchor": visit_docanchor,
}

def render(self, node, context: Optional[RenderContext] = None) -> List[Node]:
Expand Down
27 changes: 25 additions & 2 deletions documentation/source/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Directives & Config Variables
file
group
autofile
page

.. contents:: Table of Contents

Expand Down Expand Up @@ -193,7 +194,7 @@ doxygengroup

This directive generates the appropriate output for the contents of a doxygen
group. A doxygen group can be declared with specific doxygen markup in the
source comments as covered in the `doxygen documentation`_.
source comments as covered in the `doxygen grouping documentation`_.

It takes the standard ``project``, ``path``, ``outline`` and ``no-link`` options
and additionally the ``content-only``, ``members``, ``protected-members``,
Expand All @@ -216,7 +217,7 @@ and additionally the ``content-only``, ``members``, ``protected-members``,
Checkout the :ref:`doxygengroup documentation <group-example>` for more details
and to see it in action.

.. _doxygen documentation: http://www.stack.nl/~dimitri/doxygen/manual/grouping.html
.. _doxygen grouping documentation: https://www.doxygen.nl/manual/grouping.html


.. _doxygenindex:
Expand Down Expand Up @@ -387,6 +388,28 @@ It behaves the same as the doxygenstruct directive.
Checkout the :ref:`example <variable-example>` to see it in action.


doxygenpage
~~~~~~~~~~~

This directive generates the appropriate output for the contents of a doxygen
page. A doxygen page is created for each "key" of every \\xrefitem command used
for markup in the source comments. For more information check the
`doxygen xrefitem documentation`_.

It takes the standard ``project`` and ``path`` options.

::

.. doxygenpage:: <page name>
:project: ...
:path: ...

Checkout the :ref:`doxygenpage documentation <page-example>` for more details
and to see it in action.
vermeeren marked this conversation as resolved.
Show resolved Hide resolved

.. _doxygen xrefitem documentation: https://www.doxygen.nl/manual/commands.html#cmdxrefitem



Config Values
-------------
Expand Down
4 changes: 2 additions & 2 deletions documentation/source/group.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ doxygengroup Directive

This directive generates the appropriate output for the contents of a doxygen
group. A doxygen group can be declared with specific doxygen markup in the
source comments as cover in the `doxygen documentation`_.
source comments as cover in the `doxygen grouping documentation`_.

It takes the standard ``project``, ``path``, ``outline`` and ``no-link`` options
and additionally the ``content-only``, ``members``, ``protected-members``,
Expand Down Expand Up @@ -47,7 +47,7 @@ variable to set it in the ``conf.py``.
defining them inside the scope of another group, or by using the Doxygen
\ingroup command, are also parsed and loaded.

.. _doxygen documentation: http://www.stack.nl/~dimitri/doxygen/manual/grouping.html
.. _doxygen grouping documentation: https://www.doxygen.nl/manual/grouping.html

.. contents::

Expand Down
60 changes: 60 additions & 0 deletions documentation/source/page.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

.. _page-example:

doxygenpage Directive
=====================

This directive generates the appropriate output for the contents of a doxygen
page. A doxygen page is created for each "key" of every \\xrefitem command used
for markup in the source comments. For more information check the
`doxygen documentation`_.

It takes the standard ``project`` and ``path`` options.

::

.. doxygenpage:: <page name>
:project: ...
:path: ...

.. _doxygen documentation: https://www.doxygen.nl/manual/commands.html#cmdxrefitem

.. contents::


Basic Example
-------------

.. cpp:namespace:: @ex_page_basic

The plain ``doxygenpage`` directive will output the page name and description
and any variable entries which were defined to be part of this page (with an
\xrefitem usage).

.. code-block:: rst

.. doxygenpage:: xrefsample
:project: xrefsect

It produces this output:

.. doxygenpage:: xrefsample
:project: xrefsect


Failing Example
---------------

.. cpp:namespace:: @ex_page_failing

This intentionally fails:

.. code-block:: rst

.. doxygengroup:: madeuppage
:project: xrefsect

It produces the following warning message:

.. warning:: Cannot find file "madeuppage" in doxygen xml output for project
"xrefsect" from directory: ../../examples/specific/xrefsect/xml/