summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-03-28 18:54:10 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-03-28 18:54:10 +0900
commit8da576cce029dd0b8ecde60b2549e8dcbc71d88b (patch)
tree0fd43d70997f7c3d94638418e86bf0c5375b6ae8
parent6a90c166008a46de95120ecc974fb16225f7a144 (diff)
downloadsphinx-git-8da576cce029dd0b8ecde60b2549e8dcbc71d88b.tar.gz
Fix #6477: Escape first "!" in a cross reference linking no longer possible
-rw-r--r--CHANGES1
-rw-r--r--sphinx/roles.py3
-rw-r--r--sphinx/util/docutils.py4
-rw-r--r--tests/test_domain_std.py12
4 files changed, 17 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index f0c19c854..c246d8a2f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -23,6 +23,7 @@ Bugs fixed
* #7368: C++, comma operator in expressions, pack expansion in template
argument lists, and more comprehensive error messages in some cases.
* C, C++, fix crash and wrong duplicate warnings related to anon symbols.
+* #6477: Escape first "!" in a cross reference linking no longer possible
Testing
--------
diff --git a/sphinx/roles.py b/sphinx/roles.py
index a42a5610d..862191831 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -126,8 +126,7 @@ class XRefRole(ReferenceRole):
self.refdomain, self.reftype = self.name.split(':', 1)
self.classes = ['xref', self.refdomain, '%s-%s' % (self.refdomain, self.reftype)]
- if self.text.startswith('!'):
- # if the first character is a bang, don't cross-reference at all
+ if self.disabled:
return self.create_non_xref_node()
else:
return self.create_xref_node()
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index 7069189e3..972db3520 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -409,6 +409,7 @@ class ReferenceRole(SphinxRole):
``self.title`` and ``self.target``.
"""
has_explicit_title = None #: A boolean indicates the role has explicit title or not.
+ disabled = False #: A boolean indicates the reference is disabled.
title = None #: The link title for the interpreted text.
target = None #: The link target for the interpreted text.
@@ -418,6 +419,9 @@ class ReferenceRole(SphinxRole):
def __call__(self, name: str, rawtext: str, text: str, lineno: int,
inliner: Inliner, options: Dict = {}, content: List[str] = []
) -> Tuple[List[Node], List[system_message]]:
+ # if the first character is a bang, don't cross-reference at all
+ self.disabled = text.startswith('!')
+
matched = self.explicit_title_re.match(text)
if matched:
self.has_explicit_title = True
diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py
index 1f0024efc..6f213e565 100644
--- a/tests/test_domain_std.py
+++ b/tests/test_domain_std.py
@@ -19,7 +19,8 @@ from html5lib import HTMLParser
from sphinx import addnodes
from sphinx.addnodes import (
- desc, desc_addname, desc_content, desc_name, desc_signature, glossary, index
+ desc, desc_addname, desc_content, desc_name, desc_signature, glossary, index,
+ pending_xref
)
from sphinx.domains.std import StandardDomain
from sphinx.testing import restructuredtext
@@ -373,3 +374,12 @@ def test_productionlist(app, status, warning):
text = (app.outdir / 'LineContinuation.html').read_text()
assert "A</strong> ::= B C D E F G" in text
+
+
+def test_disabled_docref(app):
+ text = (":doc:`index`\n"
+ ":doc:`!index`\n")
+ doctree = restructuredtext.parse(app, text)
+ assert_node(doctree, ([nodes.paragraph, ([pending_xref, nodes.inline, "index"],
+ "\n",
+ [nodes.inline, "index"])],))