summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/directives/__init__.py37
-rw-r--r--sphinx/directives/patches.py48
-rw-r--r--sphinx/testing/restructuredtext.py38
3 files changed, 111 insertions, 12 deletions
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index c639885f6..1f4520541 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -19,18 +19,6 @@ from sphinx.util import docutils
from sphinx.util.docfields import DocFieldTransformer
from sphinx.util.docutils import SphinxDirective
-# import all directives sphinx provides
-from sphinx.directives.code import ( # noqa
- Highlight, CodeBlock, LiteralInclude
-)
-from sphinx.directives.other import ( # noqa
- TocTree, Author, Index, VersionChange, SeeAlso,
- TabularColumns, Centered, Acks, HList, Only, Include, Class
-)
-from sphinx.directives.patches import ( # noqa
- Figure, Meta
-)
-
if False:
# For type annotation
from typing import Any, Dict # NOQA
@@ -44,6 +32,19 @@ nl_escape_re = re.compile(r'\\\n')
strip_backslash_re = re.compile(r'\\(.)')
+def optional_int(argument):
+ """
+ Check for an integer argument or None value; raise ``ValueError`` if not.
+ """
+ if argument is None:
+ return None
+ else:
+ value = int(argument)
+ if value < 0:
+ raise ValueError('negative value; must be positive or zero')
+ return value
+
+
class ObjectDescription(SphinxDirective):
"""
Directive to describe a class, function or similar object. Not used
@@ -241,6 +242,18 @@ class DefaultDomain(SphinxDirective):
self.env.temp_data['default_domain'] = self.env.domains.get(domain_name)
return []
+# import all directives sphinx provides (for compatibility)
+from sphinx.directives.code import ( # noqa
+ Highlight, CodeBlock, LiteralInclude
+)
+from sphinx.directives.other import ( # noqa
+ TocTree, Author, Index, VersionChange, SeeAlso,
+ TabularColumns, Centered, Acks, HList, Only, Include, Class
+)
+from sphinx.directives.patches import ( # noqa
+ Figure, Meta
+)
+
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py
index 40af03e80..ee8014aa6 100644
--- a/sphinx/directives/patches.py
+++ b/sphinx/directives/patches.py
@@ -14,6 +14,7 @@ from docutils.parsers.rst import directives
from docutils.parsers.rst.directives import images, html, tables
from sphinx import addnodes
+from sphinx.directives import optional_int
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
@@ -110,6 +111,52 @@ class ListTable(tables.ListTable):
return title, message
+class Code(SphinxDirective):
+ """Parse and mark up content of a code block.
+
+ This is compatible with docutils' :rst:dir:`code` directive.
+ """
+ optional_arguments = 1
+ option_spec = {
+ 'class': directives.class_option,
+ 'name': directives.unchanged,
+ 'number-lines': optional_int,
+ }
+ has_content = True
+
+ def run(self):
+ # type: () -> List[nodes.Node]
+ self.assert_has_content()
+
+ code = '\n'.join(self.content)
+ node = nodes.literal_block(code, code,
+ classes=self.options.get('classes', []),
+ highlight_args={})
+ self.add_name(node)
+ set_source_info(self, node)
+
+ if self.arguments:
+ # highlight language specified
+ node['language'] = self.arguments[0]
+ node['force_highlighting'] = True
+ else:
+ # no highlight language specified. Then this directive refers the current
+ # highlight setting via ``highlight`` directive or ``highlight_language``
+ # configuration.
+ node['language'] = self.env.temp_data.get('highlight_language',
+ self.config.highlight_language)
+ node['force_highlighting'] = False
+
+ if 'number-lines' in self.options:
+ node['linenos'] = True
+
+ # if number given, treat as lineno-start.
+ if self.options['number-lines']:
+ node['highlight_args']['linenostart'] = self.options['number-lines']
+
+ return [node]
+
+
class MathDirective(SphinxDirective):
has_content = True
required_arguments = 0
@@ -174,6 +221,7 @@ def setup(app):
directives.register_directive('table', RSTTable)
directives.register_directive('csv-table', CSVTable)
directives.register_directive('list-table', ListTable)
+ directives.register_directive('code', Code)
directives.register_directive('math', MathDirective)
return {
diff --git a/sphinx/testing/restructuredtext.py b/sphinx/testing/restructuredtext.py
new file mode 100644
index 000000000..8bf1c041e
--- /dev/null
+++ b/sphinx/testing/restructuredtext.py
@@ -0,0 +1,38 @@
+"""
+ sphinx.testing.restructuredtext
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+from os import path
+
+from docutils.core import publish_doctree
+
+from sphinx.io import SphinxStandaloneReader
+from sphinx.parsers import RSTParser
+from sphinx.util.docutils import sphinx_domains
+
+
+if False:
+ # For type annotation
+ from docutils import nodes # NOQA
+ from sphinx.application import Sphinx # NOQA
+
+
+def parse(app, text, docname='index'):
+ # type: (Sphinx, str, str) -> nodes.document
+ """Parse a string as reStructuredText with Sphinx application."""
+ try:
+ app.env.temp_data['docname'] = docname
+ parser = RSTParser()
+ parser.set_application(app)
+ with sphinx_domains(app.env):
+ return publish_doctree(text, path.join(app.srcdir, docname + '.rst'),
+ reader=SphinxStandaloneReader(app),
+ parser=parser,
+ settings_overrides={'env': app.env,
+ 'gettext_compact': True})
+ finally:
+ app.env.temp_data.pop('docname', None)