From 823fdbdfe1e55a85430863680f95615601a4cb5b Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Sat, 25 Sep 2021 10:45:08 +0200 Subject: [PATCH] Initial implementation of 'hidden' option for domain directives Fixes sphinx-doc/sphinx#9662 --- sphinx/directives/__init__.py | 2 ++ sphinx/domains/c.py | 6 +++-- sphinx/domains/cpp.py | 6 +++-- sphinx/domains/javascript.py | 5 ++-- sphinx/domains/python.py | 6 ++--- sphinx/transforms/post_transforms/__init__.py | 27 +++++++++++++++++++ 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 8e8d65f0356..fc429bb0397 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -60,6 +60,7 @@ class ObjectDescription(SphinxDirective, Generic[T]): final_argument_whitespace = True option_spec: OptionSpec = { 'noindex': directives.flag, + 'hidden': directives.flag, } # types of doc fields that this directive handles, see sphinx.util.docfields @@ -170,6 +171,7 @@ def run(self) -> List[Node]: # 'desctype' is a backwards compatible attribute node['objtype'] = node['desctype'] = self.objtype node['noindex'] = noindex = ('noindex' in self.options) + node['hidden'] = 'hidden' in self.options if self.domain: node['classes'].append(self.domain) node['classes'].append(node['objtype']) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 58a0c70140d..a2a412c2781 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -3140,9 +3140,11 @@ class CObject(ObjectDescription[ASTDeclaration]): names=('rtype',)), ] - option_spec: OptionSpec = { + option_spec: OptionSpec = ObjectDescription.option_spec.copy() + option_spec.update({ 'noindexentry': directives.flag, - } + }) + del option_spec['noindex'] # is in ObjectDescription but doesn't make sense here def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: assert ast.objectType == 'enumerator' diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index d53997552cd..8d6e22a5c8b 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -6948,10 +6948,12 @@ class CPPObject(ObjectDescription[ASTDeclaration]): names=('returns', 'return')), ] - option_spec: OptionSpec = { + option_spec: OptionSpec = ObjectDescription.option_spec.copy() + option_spec.update({ 'noindexentry': directives.flag, 'tparam-line-spec': directives.flag, - } + }) + del option_spec['noindex'] # is in ObjectDescription but doesn't make sense here def _add_enumerator_to_parent(self, ast: ASTDeclaration) -> None: assert ast.objectType == 'enumerator' diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index 565d681dcf2..03bd356fa85 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -48,10 +48,11 @@ class JSObject(ObjectDescription[Tuple[str, str]]): #: based on directive nesting allow_nesting = False - option_spec: OptionSpec = { + option_spec: OptionSpec = ObjectDescription.option_spec.copy() + option_spec.update({ 'noindex': directives.flag, 'noindexentry': directives.flag, - } + }) def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]: """Breaks down construct signatures diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 2dc26a382e1..b19199b9116 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -389,13 +389,13 @@ class PyObject(ObjectDescription[Tuple[str, str]]): :cvar allow_nesting: Class is an object that allows for nested namespaces :vartype allow_nesting: bool """ - option_spec: OptionSpec = { - 'noindex': directives.flag, + option_spec: OptionSpec = ObjectDescription.option_spec.copy() + option_spec.update({ 'noindexentry': directives.flag, 'module': directives.unchanged, 'canonical': directives.unchanged, 'annotation': directives.unchanged, - } + }) doc_field_types = [ PyTypedField('parameter', label=_('Parameters'), diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py index e1da5438b3d..ff70ef12d8d 100644 --- a/sphinx/transforms/post_transforms/__init__.py +++ b/sphinx/transforms/post_transforms/__init__.py @@ -267,11 +267,38 @@ def run(self, **kwargs: Any) -> None: node['classes'].append(node.parent['domain']) +class HideHiddenDesc(SphinxPostTransform): + """Change all desc nodes to a node just with all ids in the subtree.""" + default_priority = 200 + + def run(self, **kwargs: Any) -> None: + for node in self.document.traverse(addnodes.desc): + if not node.get('hidden'): + continue + + def collectIds(node, ids): + if not isinstance(node, nodes.Element): + return + theseIds = node.get('ids') + if theseIds: + ids.extend(theseIds) + for c in node.children: + collectIds(c, ids) + + ids: List[str] = [] + collectIds(node, ids) + newNode = nodes.inline() + newNode['ids'] = ids + node.replace_self(newNode) + node['classes'] = [] # replace_self seems to copy attributes + + def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(ReferencesResolver) app.add_post_transform(OnlyNodeTransform) app.add_post_transform(SigElementFallbackTransform) app.add_post_transform(PropagateDescDomain) + app.add_post_transform(HideHiddenDesc) return { 'version': 'builtin',