From 6e2dd2398016b344c6ef9030936eeeac17313413 Mon Sep 17 00:00:00 2001 From: Joel Nothman Date: Wed, 6 Jun 2018 23:42:19 +1000 Subject: [PATCH 1/3] Use DEDUPLICATION_TAG to determine whether a citation node is in a numpydoc docstring Fixes #177 --- numpydoc/numpydoc.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/numpydoc/numpydoc.py b/numpydoc/numpydoc.py index 763c022d..50355a82 100644 --- a/numpydoc/numpydoc.py +++ b/numpydoc/numpydoc.py @@ -24,10 +24,11 @@ import inspect import collections import hashlib +import itertools -from docutils.nodes import citation, Text +from docutils.nodes import citation, Text, section, comment import sphinx -from sphinx.addnodes import pending_xref, desc_content +from sphinx.addnodes import pending_xref if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") @@ -70,18 +71,35 @@ def rename_references(app, what, name, obj, options, lines): sixu('.. [%s]') % new_r) -def _ascend(node, cls): - while node and not isinstance(node, cls): - node = node.parent - return node +def _is_cite_in_numpydoc_docstring(citation_node): + # Find DEDUPLICATION_TAG in comment as last node of sibling section + + # XXX: I failed to use citation_node.traverse to do this: + section_node = citation_node.parent + while not isinstance(section_node, section): + section_node = section_node.parent + if section_node is None: + return False + + sibling_sections = itertools.chain(section_node.traverse(section, + include_self=True, + descend=False, + siblings=True)) + for sibling_section in sibling_sections: + if not sibling_section.children: + continue + last_child = sibling_section.children[-1] + if not isinstance(last_child, comment): + continue + if last_child.rawsource.strip() == DEDUPLICATION_TAG.strip(): + return True + return False def relabel_references(app, doc): # Change 'hash-ref' to 'ref' in label text for citation_node in doc.traverse(citation): - if _ascend(citation_node, desc_content) is None: - # no desc node in ancestry -> not in a docstring - # XXX: should we also somehow check it's in a References section? + if not _is_cite_in_numpydoc_docstring(citation_node): continue label_node = citation_node[0] prefix, _, new_label = label_node[0].astext().partition('-') From 7eca9a73281e2824f3b9d0c2660b9dce43f76212 Mon Sep 17 00:00:00 2001 From: Joel Nothman Date: Wed, 6 Jun 2018 23:46:43 +1000 Subject: [PATCH 2/3] Fix regression for citations in class/function docstrings --- numpydoc/numpydoc.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/numpydoc/numpydoc.py b/numpydoc/numpydoc.py index 50355a82..6ab8025b 100644 --- a/numpydoc/numpydoc.py +++ b/numpydoc/numpydoc.py @@ -28,7 +28,7 @@ from docutils.nodes import citation, Text, section, comment import sphinx -from sphinx.addnodes import pending_xref +from sphinx.addnodes import pending_xref, desc_content if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") @@ -76,12 +76,17 @@ def _is_cite_in_numpydoc_docstring(citation_node): # XXX: I failed to use citation_node.traverse to do this: section_node = citation_node.parent - while not isinstance(section_node, section): + + def is_docstring_section(node): + return isinstance(node, (section, desc_content)) + + while not is_docstring_section(section_node): + print(section_node) section_node = section_node.parent if section_node is None: return False - sibling_sections = itertools.chain(section_node.traverse(section, + sibling_sections = itertools.chain(section_node.traverse(is_docstring_section, include_self=True, descend=False, siblings=True)) From f595006a350f8fcaf300de1a9ae31b16458e9d9c Mon Sep 17 00:00:00 2001 From: Joel Nothman Date: Wed, 6 Jun 2018 23:49:29 +1000 Subject: [PATCH 3/3] Remove debug print --- numpydoc/numpydoc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/numpydoc/numpydoc.py b/numpydoc/numpydoc.py index 6ab8025b..e7606dfb 100644 --- a/numpydoc/numpydoc.py +++ b/numpydoc/numpydoc.py @@ -81,7 +81,6 @@ def is_docstring_section(node): return isinstance(node, (section, desc_content)) while not is_docstring_section(section_node): - print(section_node) section_node = section_node.parent if section_node is None: return False