From b9469b9013eca8ba4df2df527a9a9fdf3666c458 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 19 Sep 2014 12:21:38 +0200 Subject: [PATCH] Changing the default role document-locally with the docutils ".. default-role::" directive is now supported. --- CHANGES | 2 ++ sphinx/directives/__init__.py | 32 +++++++++++++++++++++++++++++++- sphinx/environment.py | 1 + sphinx/roles.py | 7 ++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 6279c4467..114e27706 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,8 @@ Features added can be shown in the traceback log files). Version requirements for extensions can be specified in projects using the new :confval:`needs_extensions` config value. +* Changing the default role within a document with the :rst:dir:`default-role` + directive is now supported. * PR#214: Added stemming support for 14 languages, so that the built-in document search can now handle these. Thanks to Shibukawa Yoshiki. * PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 52b638fe0..969426bc1 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -11,7 +11,8 @@ import re -from docutils.parsers.rst import Directive, directives +from docutils import nodes +from docutils.parsers.rst import Directive, directives, roles from sphinx import addnodes from sphinx.util.docfields import DocFieldTransformer @@ -162,6 +163,34 @@ class ObjectDescription(Directive): DescDirective = ObjectDescription +class DefaultRole(Directive): + """ + Set the default interpreted text role. Overridden from docutils. + """ + + optional_arguments = 1 + final_argument_whitespace = False + + def run(self): + if not self.arguments: + if '' in roles._roles: + # restore the "default" default role + del roles._roles[''] + return [] + role_name = self.arguments[0] + role, messages = roles.role(role_name, self.state_machine.language, + self.lineno, self.state.reporter) + if role is None: + error = self.state.reporter.error( + 'Unknown interpreted text role "%s".' % role_name, + nodes.literal_block(self.block_text, self.block_text), + line=self.lineno) + return messages + [error] + roles._roles[''] = role + self.state.document.settings.env.temp_data['default_role'] = role_name + return messages + + class DefaultDomain(Directive): """ Directive to (re-)set the default domain for this source file. @@ -186,6 +215,7 @@ class DefaultDomain(Directive): return [] +directives.register_directive('default-role', DefaultRole) directives.register_directive('default-domain', DefaultDomain) directives.register_directive('describe', ObjectDescription) # new, more consistent, name diff --git a/sphinx/environment.py b/sphinx/environment.py index 42f4da0ef..7838a5d1c 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -681,6 +681,7 @@ class BuildEnvironment: # cleanup self.temp_data.clear() + roles._roles.pop('', None) # if a document has set a local default role if save_parsed: # save the parsed doctree diff --git a/sphinx/roles.py b/sphinx/roles.py index aaf6272bd..b99b22795 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -17,6 +17,7 @@ from docutils.parsers.rst import roles from sphinx import addnodes from sphinx.locale import _ +from sphinx.errors import SphinxError from sphinx.util import ws_re from sphinx.util.nodes import split_explicit_title, process_index_entry, \ set_role_source_info @@ -96,7 +97,11 @@ class XRefRole(object): options={}, content=[]): env = inliner.document.settings.env if not typ: - typ = env.config.default_role + typ = env.temp_data.get('default_role') + if not typ: + typ = env.config.default_role + if not typ: + raise SphinxError('cannot determine default role!') else: typ = typ.lower() if ':' not in typ: