diff --git a/CHANGES b/CHANGES index 9488aedff..cb4499c4e 100644 --- a/CHANGES +++ b/CHANGES @@ -117,6 +117,7 @@ Deprecated * ``sphinx.registry.SphinxComponentRegistry.add_source_input()`` * ``sphinx.roles.abbr_role()`` * ``sphinx.roles.index_role()`` +* ``sphinx.roles.indexmarkup_role()`` * ``sphinx.testing.util.remove_unicode_literal()`` * ``sphinx.util.attrdict`` * ``sphinx.util.force_decode()`` diff --git a/doc/extdev/index.rst b/doc/extdev/index.rst index c3061852a..a7f84d2ea 100644 --- a/doc/extdev/index.rst +++ b/doc/extdev/index.rst @@ -385,6 +385,11 @@ The following is a list of deprecated interfaces. - 4.0 - ``sphinx.roles.Index`` + * - ``sphinx.roles.indexmarkup_role()`` + - 2.0 + - 4.0 + - ``sphinx.roles.PEP`` or ``sphinx.roles.RFC`` + * - ``sphinx.testing.util.remove_unicode_literal()`` - 2.0 - 4.0 diff --git a/sphinx/roles.py b/sphinx/roles.py index d2e64c40c..c36ed2613 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -182,6 +182,8 @@ class AnyXRefRole(XRefRole): def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA """Role for PEP/RFC references that generate an index entry.""" + warnings.warn('indexmarkup_role() is deprecated. Please use PEP or RFC class instead.', + RemovedInSphinx40Warning, stacklevel=2) env = inliner.document.settings.env if not typ: assert env.temp_data['default_role'] @@ -245,6 +247,80 @@ def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[] raise ValueError('unknown role type: %s' % typ) +class PEP(ReferenceRole): + def run(self): + # type: () -> Tuple[List[nodes.Node], List[nodes.system_message]] + target_id = 'index-%s' % self.env.new_serialno('index') + entries = [('single', _('Python Enhancement Proposals; PEP %s') % self.target, + target_id, '', None)] + + index = addnodes.index(entries=entries) + target = nodes.target('', '', ids=[target_id]) + self.inliner.document.note_explicit_target(target) + + try: + refuri = self.build_uri() + reference = nodes.reference('', '', internal=False, refuri=refuri, classes=['pep']) + if self.has_explicit_title: + reference += nodes.strong(self.title, self.title) + else: + title = "PEP " + self.title + reference += nodes.strong(title, title) + except ValueError: + msg = self.inliner.reporter.error('invalid PEP number %s' % self.target, + line=self.lineno) + prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) + return [prb], [msg] + + return [index, target, reference], [] + + def build_uri(self): + # type: () -> str + base_url = self.inliner.document.settings.pep_base_url + target, anchor = self.target.split('#', 1) + if anchor: + return base_url + 'pep-%04d#%s' % (int(target), anchor) + else: + return base_url + 'pep-%04d' % int(target) + + +class RFC(ReferenceRole): + def run(self): + # type: () -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA + target_id = 'index-%s' % self.env.new_serialno('index') + entries = [('single', 'RFC; RFC %s' % self.target, target_id, '', None)] + + index = addnodes.index(entries=entries) + target = nodes.target('', '', ids=[target_id]) + self.inliner.document.note_explicit_target(target) + + try: + refuri = self.build_uri() + reference = nodes.reference('', '', internal=False, refuri=refuri, classes=['rfc']) + if self.has_explicit_title: + reference += nodes.strong(self.title, self.title) + else: + title = "RFC " + self.title + reference += nodes.strong(title, title) + except ValueError: + msg = self.inliner.reporter.error('invalid RFC number %s' % self.target, + line=self.lineno) + prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) + return [prb], [msg] + + return [index, target, reference], [] + + def build_uri(self): + # type: () -> str + target, anchor = self.target.split('#', 1) + base_url = (self.inliner.document.settings.rfc_base_url + + self.inliner.rfc_url % int(target)) + if anchor: + return base_url + '#' + anchor + else: + return base_url + + _amp_re = re.compile(r'(? Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA - self.type = typ self.rawtext = rawtext self.text = unescape(text) self.lineno = lineno @@ -403,6 +402,16 @@ class SphinxRole: self.options = options self.content = content + # guess role type + if typ: + self.type = typ.lower() + else: + self.type = self.env.temp_data.get('default_role') + if not self.type: + self.type = self.env.config.default_role + if not self.type: + raise SphinxError('cannot determine default role!') + return self.run() def run(self):