148
148
import traceback
149
149
import warnings
150
150
151
- from docutils .parsers .rst import directives
151
+ from docutils import nodes
152
+ from docutils .parsers .rst import directives , Directive
152
153
from docutils .parsers .rst .directives .images import Image
153
154
align = Image .align
154
155
import jinja2 # Sphinx dependency.
176
177
177
178
def plot_directive (name , arguments , options , content , lineno ,
178
179
content_offset , block_text , state , state_machine ):
179
- """Implementation of the ``.. plot::`` directive.
180
+ """Deprecated function-based implementation of the ``.. plot::`` directive.
180
181
181
- See the module docstring for details.
182
+ Use PlotDirective instead.
183
+ See the module docstring for details on configuration.
182
184
"""
183
185
return run (arguments , content , options , state_machine , state , lineno )
184
186
@@ -241,25 +243,45 @@ def mark_plot_labels(app, document):
241
243
break
242
244
243
245
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
+
244
277
def setup (app ):
245
278
setup .app = app
246
279
setup .config = app .config
247
280
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 )
263
285
app .add_config_value ('plot_pre_code' , None , True )
264
286
app .add_config_value ('plot_include_source' , False , True )
265
287
app .add_config_value ('plot_html_show_source_link' , True , True )
@@ -273,7 +295,8 @@ def setup(app):
273
295
274
296
app .connect ('doctree-read' , mark_plot_labels )
275
297
276
- metadata = {'parallel_read_safe' : True , 'parallel_write_safe' : True }
298
+ metadata = {'parallel_read_safe' : True , 'parallel_write_safe' : True ,
299
+ 'version' : 0.2 }
277
300
return metadata
278
301
279
302
@@ -630,7 +653,8 @@ def render_figures(code, code_path, output_dir, output_base, context,
630
653
return results
631
654
632
655
633
- def run (arguments , content , options , state_machine , state , lineno ):
656
+ def run (arguments , content , options , state_machine , state , lineno ,
657
+ function = True ):
634
658
document = state_machine .document
635
659
config = document .settings .env .config
636
660
nofigs = 'nofigs' in options
@@ -800,9 +824,6 @@ def run(arguments, content, options, state_machine, state, lineno):
800
824
total_lines .extend (result .split ("\n " ))
801
825
total_lines .extend ("\n " )
802
826
803
- if total_lines :
804
- state_machine .insert_input (total_lines , source = source_file_name )
805
-
806
827
# copy image files to builder's output directory, if necessary
807
828
Path (dest_dir ).mkdir (parents = True , exist_ok = True )
808
829
@@ -818,4 +839,14 @@ def run(arguments, content, options, state_machine, state, lineno):
818
839
unescape_doctest (code ) if source_file_name == rst_file else code ,
819
840
encoding = 'utf-8' )
820
841
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