Skip to content

Commit c153cfb

Browse files
committed
API: Use class-based directive in sphinxext
1 parent 6c0bc66 commit c153cfb

File tree

1 file changed

+55
-24
lines changed

1 file changed

+55
-24
lines changed

lib/matplotlib/sphinxext/plot_directive.py

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@
148148
import traceback
149149
import warnings
150150

151-
from docutils.parsers.rst import directives
151+
from docutils import nodes
152+
from docutils.parsers.rst import directives, Directive
152153
from docutils.parsers.rst.directives.images import Image
153154
align = Image.align
154155
import jinja2 # Sphinx dependency.
@@ -176,9 +177,10 @@
176177

177178
def plot_directive(name, arguments, options, content, lineno,
178179
content_offset, block_text, state, state_machine):
179-
"""Implementation of the ``.. plot::`` directive.
180+
"""Deprecated function-based implementation of the ``.. plot::`` directive.
180181
181-
See the module docstring for details.
182+
Use PlotDirective instead.
183+
See the module docstring for details on configuration.
182184
"""
183185
return run(arguments, content, options, state_machine, state, lineno)
184186

@@ -241,25 +243,45 @@ def mark_plot_labels(app, document):
241243
break
242244

243245

246+
class PlotDirective(Directive):
247+
"""Implementation of the ``.. plot::`` directive.
248+
249+
See the module docstring for details.
250+
"""
251+
252+
has_content = True
253+
required_arguments = 0
254+
optional_arguments = 2
255+
final_argument_whitespace = False
256+
option_spec = {
257+
'alt': directives.unchanged,
258+
'height': directives.length_or_unitless,
259+
'width': directives.length_or_percentage_or_unitless,
260+
'scale': directives.nonnegative_int,
261+
'align': _option_align,
262+
'class': directives.class_option,
263+
'include-source': _option_boolean,
264+
'format': _option_format,
265+
'context': _option_context,
266+
'nofigs': directives.flag,
267+
'encoding': directives.encoding,
268+
}
269+
270+
def run(self):
271+
"""Run the plot directive."""
272+
return run(self.arguments, self.content, self.options,
273+
self.state_machine, self.state, self.lineno,
274+
function=False)
275+
276+
244277
def setup(app):
245278
setup.app = app
246279
setup.config = app.config
247280
setup.confdir = app.confdir
248-
249-
options = {'alt': directives.unchanged,
250-
'height': directives.length_or_unitless,
251-
'width': directives.length_or_percentage_or_unitless,
252-
'scale': directives.nonnegative_int,
253-
'align': _option_align,
254-
'class': directives.class_option,
255-
'include-source': _option_boolean,
256-
'format': _option_format,
257-
'context': _option_context,
258-
'nofigs': directives.flag,
259-
'encoding': directives.encoding
260-
}
261-
262-
app.add_directive('plot', plot_directive, True, (0, 2, False), **options)
281+
# Old, function-based method was equivalent to:
282+
# app.add_directive('plot', plot_directive, True, (0, 2, False),
283+
# **PlotDirective.option_spec)
284+
app.add_directive('plot', PlotDirective)
263285
app.add_config_value('plot_pre_code', None, True)
264286
app.add_config_value('plot_include_source', False, True)
265287
app.add_config_value('plot_html_show_source_link', True, True)
@@ -273,7 +295,8 @@ def setup(app):
273295

274296
app.connect('doctree-read', mark_plot_labels)
275297

276-
metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
298+
metadata = {'parallel_read_safe': True, 'parallel_write_safe': True,
299+
'version': 0.2}
277300
return metadata
278301

279302

@@ -630,7 +653,8 @@ def render_figures(code, code_path, output_dir, output_base, context,
630653
return results
631654

632655

633-
def run(arguments, content, options, state_machine, state, lineno):
656+
def run(arguments, content, options, state_machine, state, lineno,
657+
function=True):
634658
document = state_machine.document
635659
config = document.settings.env.config
636660
nofigs = 'nofigs' in options
@@ -800,9 +824,6 @@ def run(arguments, content, options, state_machine, state, lineno):
800824
total_lines.extend(result.split("\n"))
801825
total_lines.extend("\n")
802826

803-
if total_lines:
804-
state_machine.insert_input(total_lines, source=source_file_name)
805-
806827
# copy image files to builder's output directory, if necessary
807828
Path(dest_dir).mkdir(parents=True, exist_ok=True)
808829

@@ -818,4 +839,14 @@ def run(arguments, content, options, state_machine, state, lineno):
818839
unescape_doctest(code) if source_file_name == rst_file else code,
819840
encoding='utf-8')
820841

821-
return errors
842+
if function:
843+
if total_lines:
844+
state_machine.insert_input(total_lines, source=source_file_name)
845+
out = errors
846+
else:
847+
if len(errors):
848+
out = errors
849+
else:
850+
out = [nodes.raw('\n'.join(total_lines))] if total_lines else []
851+
852+
return out

0 commit comments

Comments
 (0)