Skip to content
Snippets Groups Projects
Commit 36e8f20a authored by Jay Rainey's avatar Jay Rainey Committed by Gigg, Martyn Anthony
Browse files

Add working set of Sphinx extensions.

Refs #9521
parent e19a7aa0
No related branches found
No related tags found
No related merge requests found
from base import BaseDirective
class AlgorithmDirective(BaseDirective):
"""
Adds a referenceable link for a given algorithm, a title,
and a screenshot of the algorithm to an rst file.
"""
required_arguments, optional_arguments = 1, 0
def run(self):
"""
Called by Sphinx when the ..algorithm:: directive is encountered
"""
algorithm_name = str(self.arguments[0])
# Seperate methods for each unique piece of functionality.
reference = self._make_reference_link(algorithm_name)
title = self._make_header(algorithm_name, True)
screenshot = self._get_algorithm_screenshot(algorithm_name)
return self._insert_rest(reference + title + screenshot)
def _make_reference_link(self, algorithm_name):
"""
Outputs a reference to the top of the algorithm's rst file.
Args:
algorithm_name (str): The name of the algorithm to reference.
Returns:
str: A ReST formatted reference.
"""
return ".. _" + algorithm_name.title() + ":" + "\n"
def _get_algorithm_screenshot(self, algorithm_name):
"""
Obtains the location of the screenshot for a given algorithm.
Args:
algorithm_name (str): The name of the algorithm.
Returns:
str: The location of the screenshot for the given algorithm.
"""
images_dir = self.state.document.settings.env.config["mantid_images"]
return ".. image:: " + images_dir + algorithm_name + ".png"
def setup(app):
app.add_config_value('mantid_images', 'mantid_images', 'env')
app.add_directive('algorithm', AlgorithmDirective)
from base import BaseDirective
class AliasesDirective(BaseDirective):
"""
Obtains the aliases for a given algorithm based on it's name.
"""
required_arguments, optional_arguments = 1, 0
def run(self):
"""
Called by Sphinx when the ..aliases:: directive is encountered.
"""
title = self._make_header(__name__.title())
alias = self._get_alias(str(self.arguments[0]))
return self._insert_rest(title + alias)
def _get_alias(self, algorithm_name):
"""
Return the alias for the named algorithm.
Args:
algorithm_name (str): The name of the algorithm to get the alias for.
"""
alg = self._create_mantid_algorithm(algorithm_name)
return "This algorithm is also known as: " + "**" + alg.alias() + "**"
def setup(app):
app.add_directive('aliases', AliasesDirective)
from docutils import statemachine
from docutils.parsers.rst import Directive
class BaseDirective(Directive):
"""
Contains shared functionality for Mantid custom directives.
"""
def _make_header(self, name, title=False):
"""
Makes a ReStructuredText title from the algorithm's name.
Args:
algorithm_name (str): The name of the algorithm to use for the title.
title (bool): If True, line is inserted above & below algorithm name.
Returns:
str: ReST formatted header with algorithm_name as content.
"""
line = "\n" + "-" * len(name) + "\n"
if title:
return line + name + line
else:
return name + line
def _insert_rest(self, text):
"""
Inserts ReStructuredText into the algorithm file.
Args:
text (str): Inserts ReStructuredText into the algorithm file.
Returns:
list: Empty list. This is required by the inherited run method.
"""
self.state_machine.insert_input(statemachine.string2lines(text), "")
return []
def _create_mantid_algorithm(self, algorithm_name):
"""
Create and initializes a Mantid algorithm.
Args:
algorithm_name (str): The name of the algorithm to use for the title.
Returns:
algorithm: An instance of a Mantid algorithm.
"""
from mantid.api import AlgorithmManager
alg = AlgorithmManager.createUnmanaged(algorithm_name)
alg.initialize()
return alg
from base import BaseDirective
class CategoriesDirective(BaseDirective):
"""
Obtains the categories for a given algorithm based on it's name.
"""
required_arguments, optional_arguments = 1, 0
def run(self):
"""
Called by Sphinx when the ..categories:: directive is encountered.
"""
title = self._make_header(__name__.title())
categories = self._get_categories(str(self.arguments[0]))
return self._insert_rest(title + categories)
def _get_categories(self, algorithm_name):
"""
Return the categories for the named algorithm.
Args:
algorithm_name (str): The name of the algorithm.
"""
alg = self._create_mantid_algorithm(algorithm_name)
# Create a list containing each category.
categories = alg.category().split("\\")
if len(categories) >= 2:
# Add a cross reference for each catagory.
links = (":ref:`%s` | " * len(categories)) % tuple(categories)
# Remove last three characters to remove last |
return ("`Categories: <categories.html>`_ " + links)[:-3]
else:
return "`Category: <categoies.html>`_ :ref:`%s`" % (categories)
def setup(app):
app.add_directive('categories', CategoriesDirective)
from base import BaseDirective
class PropertiesDirective(BaseDirective):
"""
Outputs the given algorithm's properties into a ReST formatted table.
"""
# Accept one required argument and no optional arguments.
required_arguments, optional_arguments = 1, 0
def run(self):
"""
Called by Sphinx when the ..properties:: directive is encountered.
"""
alg_name = str(self.arguments[0])
title = self._make_header(__name__.title())
properties_table = self._populate_properties_table(alg_name)
return self._insert_rest(title + properties_table)
def _populate_properties_table(self, algorithm_name):
"""
Populates the ReST table with algorithm properties.
Args:
algorithm_name (str): The name of the algorithm.
"""
alg = self._create_mantid_algorithm(algorithm_name)
alg_properties = alg.getProperties()
# Stores each property of the algorithm in a tuple.
properties = []
# Used to obtain the name for the direction property rather than an
# int.
direction_string = ["Input", "Output", "InOut", "None"]
for prop in alg_properties:
# Append a tuple of properties to the list.
properties.append((
str(prop.name),
str(direction_string[prop.direction]),
str(prop.type),
str(self._get_default_prop(prop)),
str(prop.documentation)
))
# Build and add the properties to the ReST table.
return self._build_table(properties)
def _build_table(self, table_content):
"""
Build the ReST format
Args:
table_content (list of tuples): Each tuple (row) container
property values for a unique property of that algorithm.
Returns:
str: ReST formatted table containing algorithm properties.
"""
# Default values for the table headers.
header_content = (
'Name', 'Direction', 'Type', 'Default', 'Description')
# The width of the columns. Multiply row length by 10 to ensure small
# properties format correctly.
col_sizes = [max(len(row[i] * 10) for row in table_content)
for i in range(len(header_content))]
# Use the column widths as a means to formatting columns.
formatter = ' '.join('{:<%d}' % col for col in col_sizes)
# Add whitespace to each column. This depends on the values returned by
# col_sizes.
table_content_formatted = [
formatter.format(*item) for item in table_content]
# Create a seperator for each column
seperator = formatter.format(*['=' * col for col in col_sizes])
# Build the table.
header = '\n' + seperator + '\n' + formatter.format(*header_content) + '\n'
content = seperator + '\n' + \
'\n'.join(table_content_formatted) + '\n' + seperator
# Join the header and footer.
return header + content
def _get_default_prop(self, prop):
"""
Converts the default value of the property to a more use-friendly one.
Args:
prop (str): The algorithm property to use.
Returns:
str: The default value of the property.
"""
from mantid.api import IWorkspaceProperty
# Used to obtain the name for the direction property rather than
# outputting an int.
direction_string = ["Input", "Output", "InOut", "None"]
# Nothing to show under the default section for an output properties
# that are not workspace properties.
if (direction_string[prop.direction] == "Output") and \
(not isinstance(prop, IWorkspaceProperty)):
default_prop = ""
elif (prop.isValid == ""):
default_prop = self._create_property_default_string(prop)
else:
default_prop = "Mandatory"
return default_prop
def _create_property_default_string(self, prop):
"""
Converts the default value of the property to a more use-friendly one.
Args:
prop. The property to find the default value of.
Returns:
str: The string to add to the property table default section.
"""
default = prop.getDefault
defaultstr = ""
# Convert to int, then float, then any string
try:
val = int(default)
if (val >= 2147483647):
defaultstr = "Optional"
else:
defaultstr = str(val)
except:
try:
val = float(default)
if (val >= 1e+307):
defaultstr = "Optional"
else:
defaultstr = str(val)
except:
# Fall-back default for anything
defaultstr = str(default)
# Replace the ugly default values with "Optional"
if (defaultstr == "8.9884656743115785e+307") or \
(defaultstr == "1.7976931348623157e+308") or \
(defaultstr == "2147483647"):
defaultstr = "Optional"
if str(prop.type) == "boolean":
if defaultstr == "1":
defaultstr = "True"
else:
defaultstr = "False"
return defaultstr
def setup(app):
app.add_directive('properties', PropertiesDirective)
from base import BaseDirective
class SummaryDirective(BaseDirective):
"""
Obtains the summary for a given algorithm based on it's name.
"""
required_arguments, optional_arguments = 1, 0
def run(self):
"""
Called by Sphinx when the ..summary:: directive is encountered.
"""
title = self._make_header(__name__.title())
summary = self._get_summary(str(self.arguments[0]))
return self._insert_rest(title + summary)
def _get_summary(self, algorithm_name):
"""
Return the summary for the named algorithm.
Args:
algorithm_name (str): The name of the algorithm.
"""
alg = self._create_mantid_algorithm(algorithm_name)
return alg.getWikiSummary()
def setup(app):
app.add_directive('summary', SummaryDirective)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment