Source code for sunpy.util.sphinx.generate
import os
import sys
from io import StringIO
from docutils import nodes
from docutils.parsers.rst import Directive, directives
__all__ = ['Generate']
[docs]
class Generate(Directive):
"""
Custom directive to include raw output generated using supplied Python code
This directive is similar to the ``raw`` directive, except that the raw content is generated
instead of statically provided. As with the ``raw`` directive, the required argument specifies
the format of the output (e.g., ``html`` or ``latex``).
The optional flag ``html_border`` surrounds HTML output with a black border for visual
separation.
"""
required_arguments = 1
optional_arguments = 0
option_spec = {'html_border': directives.flag}
has_content = True
[docs]
def run(self):
# Respect the same disabling options as the ``raw`` directive
if (not self.state.document.settings.raw_enabled
or not self.state.document.settings.file_insertion_enabled):
raise self.warning(f'"{self.name}" directive disabled.')
attributes = {'format': ' '.join(self.arguments[0].lower().split())}
source, lineno = self.state_machine.get_source_and_line(self.lineno)
old_stdout, sys.stdout = sys.stdout, StringIO()
try:
# Execute the Python code and capture its output
exec('\n'.join(self.content))
text = sys.stdout.getvalue()
# Wrap HTML output in a black border if requested
if attributes['format'] == 'html' and 'html_border' in self.options:
text = f"<div style='border:1px solid black; padding:3px'>{text}</div>"
# Append the output in the same fashion as the ``raw`` directive
raw_node = nodes.raw('', text, **attributes)
raw_node.source, raw_node.line = source, lineno
return [raw_node]
except Exception as e:
message = f"Unable to execute Python code at {os.path.basename(source)}:{lineno}"
return [nodes.error(None, nodes.paragraph(text=message)),
nodes.paragraph(text=str(e))]
finally:
sys.stdout = old_stdout
def setup(app):
app.add_directive('generate', Generate)
return {'parallel_read_safe': True, 'parallel_write_safe': True}