Skip to content

Commit

Permalink
Merge pull request #15 from njzjz/sphinx-domain
Browse files Browse the repository at this point in the history
  • Loading branch information
y1xiaoc committed Jul 10, 2022
2 parents 809452c + 1875fd0 commit 9bad3f6
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
7 changes: 6 additions & 1 deletion dargs/dargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,10 @@ def gen_doc_head(self, path: Optional[List[str]] = None, **kwargs) -> str:
if self.alias:
typesig += f", alias{'es' if len(self.alias) > 1 else ''}: "
typesig += ', '.join(f"*{al}*" for al in self.alias)
head = f"{self.name}: \n{indent(typesig, INDENT)}"
head = f"{self.name}: "
if kwargs.get('use_sphinx_domain', False):
head = f".. dargs:argument:: {self.name}:\n :path: {'/'.join(path)}\n"
head += f"\n{indent(typesig, INDENT)}"
if kwargs.get("make_anchor"):
head = f"{make_rst_refid(path)}\n" + head
return head
Expand Down Expand Up @@ -711,6 +714,8 @@ def gen_doc_flag(self, path: Optional[List[str]] = None, **kwargs) -> str:
if path is None:
path = []
arg_path = [*path, self.flag_name]
if kwargs.get('use_sphinx_domain', False):
headdoc = f".. dargs:argument:: {self.flag_name}:\n :path: {'/'.join(arg_path)}\n"
pathdoc = indent(f"| argument path: ``{'/'.join(arg_path)}`` ", INDENT)
if kwargs.get("make_link"):
if not kwargs.get("make_anchor"):
Expand Down
74 changes: 73 additions & 1 deletion dargs/sphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@

from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives import unchanged
from sphinx import addnodes
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType
from sphinx.roles import XRefRole
from sphinx.util.nodes import make_refnode

from .dargs import Argument, Variant

Expand Down Expand Up @@ -59,14 +64,81 @@ def run(self):
for argument in arguments:
if not isinstance(argument, (Argument, Variant)):
raise RuntimeError("The function doesn't return Argument")
rst = argument.gen_doc(make_anchor=True, make_link=True)
rst = argument.gen_doc(make_anchor=True, make_link=True, use_sphinx_domain=True)
self.state_machine.insert_input(rst.split("\n"), "%s:%s" %(module_name, attr_name))
return []


class DargsObject(ObjectDescription):
"""dargs::argument directive.
This directive creates a signature node for an argument.
"""
option_spec = dict(
path=unchanged,
)

def handle_signature(self, sig, signode):
signode += addnodes.desc_name(sig, sig)
return sig

def add_target_and_index(self, name, sig, signode):
path = self.options['path']
targetid = "%s:%s" % (self.objtype, path)
if targetid not in self.state.document.ids:
signode['names'].append(targetid)
signode['ids'].append(targetid)
signode['first'] = (not self.names)
self.state.document.note_explicit_target(signode)
# for cross-references
inv = self.env.domaindata['dargs']['arguments']
if targetid in inv:
self.state.document.reporter.warning(
'Duplicated argument "%s" described in "%s".' %
(targetid, self.env.doc2path(inv[targetid][0])), line=self.lineno)
inv[targetid] = (self.env.docname, self.objtype)

self.indexnode['entries'].append(('pair', u'%s ; %s (%s) ' % (name, path, self.objtype.title()), targetid, 'main', None))


class DargsDomain(Domain):
"""Dargs domain.
Includes:
- dargs::argument directive
- dargs::argument role
"""
name = 'dargs'
label = 'dargs'
object_types = {
'argument': ObjType('argument', 'argument'),
}
directives = {
'argument': DargsObject,
}
roles = {
'argument': XRefRole(),
}

initial_data = {
'arguments': {}, # fullname -> docname, objtype
}

def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
"""Resolve cross-references."""
targetid = '%s:%s' % (typ, target)
obj = self.data['arguments'].get(targetid)
if obj is None:
return None
return make_refnode(builder, fromdocname, obj[0], targetid,
contnode, target)


def setup(app):
"""Setup sphinx app."""
app.add_directive('dargs', DargsDirective)
app.add_domain(DargsDomain)
return {'parallel_read_safe': True}


Expand Down
20 changes: 20 additions & 0 deletions docs/sphinx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,23 @@ where `_test_argument` returns an :class:`Argument <dargs.Argument>`. A :class:`
.. dargs::
:module: dargs.sphinx
:func: _test_argument


Cross-referencing Arguments
---------------------------

Both the following ways will create a cross-reference to the argument:

.. code-block:: rst
Both :dargs:argument:`this <test/test_argument>` and :ref:`this <test/test_argument>` will create a cross-reference to the argument!
It will be rendered as:

Both :dargs:argument:`this <test/test_argument>` and :ref:`this <test/test_argument>` will create a cross-reference to the argument!


Index page
----------

The arguments will be added into the :ref:`genindex` page. See :ref:`test_argument <test/test_argument>` in the :ref:`genindex` page.

0 comments on commit 9bad3f6

Please sign in to comment.