Source code for capsul.sphinxext.layoutdocgen

# -*- coding: utf-8 -*-
##########################################################################
# CAPSUL - CAPS - Copyright (C) CEA, 2013
# Distributed under the terms of the CeCILL-B license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
# for details.
##########################################################################

# System import
from __future__ import absolute_import
import os
import sys
import six
from docutils.core import publish_parts
import logging
import traceback


[docs] class LayoutHelperWriter(object): """ A basic class to create sphinx layout and associated index. """ def __init__(self, module_names, root_module_name, rst_extension=".rst"): """ Initialize the LayoutHelperWriter class Parameters ---------- module_names: list of str (mandatory) list of modules defined in the project root_module_name: str (mandatory) the name of the python package rst_extension : string (optional) Extension for reST files, default '.rst' """ self.module_names = module_names self.rst_extension = rst_extension self.root_module_name = root_module_name self.rst_section_levels = ['*', '=', '-', '~', '^']
[docs] def generate_index_entry(self, module_name, indent=4): """ Make autodoc documentation of pilots Parameters ---------- module_name: string the name of the module we want to index ident: int the number of blank prefix Returns ------- ad : string the reST formatted index description. """ # Try to get the module description full_module_name = "{0}.{1}".format(self.root_module_name, module_name) try: __import__(full_module_name) except ImportError: exc_info = sys.exc_info() logging.error("".join(traceback.format_exception(*exc_info))) logging.error( "Can't load module {0}".format(full_module_name)) module = sys.modules[full_module_name] description = module.__doc__ # Then reST formatting spacer = " " * 4 ad = spacer + "<div class='span6 box'>\n" ad += spacer + "<h2><a href='{0}/index.html'>\n".format(module_name) ad += spacer + "{0} module\n".format(module_name) ad += spacer + "</a></h2>\n" ad += spacer + "<blockquote>\n" if description is not None: ad += spacer + "{0}\n".format(("\n" + spacer).join( self.rst2html(description).splitlines())) ad += spacer + "</blockquote>\n" ad += spacer + "</div>\n" return ad
[docs] def title_for(self, title): """ Create a title from a underscore-separated string. Parameters ---------- title: str (mandatory) the string to format. Returns ------- out: str the formatted string. """ return title.replace("_", " ").capitalize()
[docs] def rst2html(self, rst): """ Convert a rst formatted string to an html string. Parameters ---------- rst: str (mandatory) the rst formatted string. Returns ------- out: str the html formatted string. """ parts = publish_parts(rst, writer_name="html") return parts["body_pre_docinfo"] + parts["body"]
[docs] def write_layout(self, outdir): """Generate the sphinx layout. Parameters ---------- outdir : string Directory name in which to store files """ # Check if output dir exists if not os.path.exists(outdir): os.makedirs(outdir) # Get the layout template layout_file = os.path.join( os.path.dirname(__file__), "resources", "layout.html") # Top selection panel indices = [ """<li><a href="{{{{ pathto('generated/{0}/index') }}}}">""" """{1}</a></li>""".format(x, self.title_for(x)) for x in self.module_names] # Project description try: __import__(self.root_module_name) except ImportError: exc_info = sys.exc_info() logging.error("".join(traceback.format_exception(*exc_info))) logging.error( "Can't load module {0}".format(self.root_module_name)) module = sys.modules[self.root_module_name] release_info = {} exec(compile(open(os.path.join(module.__path__[0], "info.py"), "rb").read(), os.path.join(module.__path__[0], "info.py"), 'exec'), release_info) # Carousel items carousel_items_path = os.path.join( module.__path__[0], os.pardir, "doc", "source", "_static", "carousel") carousel_items = [item for item in os.listdir(carousel_items_path)] images = [] indicators = [] for cnt, item in enumerate(carousel_items): if cnt == 0: indicators.append( "<li data-target='#examples_carousel' data-slide-to='0' " "class='active'></li>") images.append( "<div class=\"active item\">" "<a href=\"{{pathto('index')}}\">" "<img src=\"{{ pathto('_static/carousel/%s', 1) }}\">" "</div></a>" % item) else: indicators.append( "<li data-target='#examples_carousel' data-slide-to='{0}' " "</li>".format(cnt)) images.append( "<div class=\"item\"><a href=\"{{pathto('index')}}\">" "<img src=\"{{ pathto('_static/carousel/%s', 1) }}\">" "</a></div>" % item) # Create correspondence mapping layout_info = { "NAME_LOWER": self.root_module_name, "NAME_UPPER": self.root_module_name.upper(), "INDEX": "\n".join(indices), "CAROUSEL_INDICATORS": "\n".join(indicators), "CAROUSEL_IMAGES": "\n".join(images), "DESCRIPTION": self.rst2html(release_info["LONG_DESCRIPTION"]), "LOGO": self.root_module_name, } # Get full output filename path path = os.path.join(outdir, "layout.html") # Start writing the index idx = open(path, "wt") w = idx.write # Edit the template with open(layout_file) as open_file: s = "".join(open_file.readlines()) for key, value in six.iteritems(layout_info): s = s.replace("%({0})s".format(key), value) w(s) # Close the open file idx.close()
[docs] def write_installation(self, outdir): """Generate the installation recommendations. Parameters ---------- outdir : string Directory name in which to store files """ # Check if output dir exists if not os.path.exists(outdir): os.makedirs(outdir) # Get the layout template layout_file = os.path.join( os.path.dirname(__file__), "resources", "installation.rst") # Generate title title = "Installing `{0}`".format(self.root_module_name.upper()) title = [self.rst_section_levels[1] * len(title), title, self.rst_section_levels[1] * len(title)] # Create correspondence mapping layout_info = { "NAME_LOWER": self.root_module_name, "NAME_UPPER": self.root_module_name.upper(), "TITLE": "\n".join(title), } # Get full output filename path path = os.path.join(outdir, "installation.rst") # Start writing the index idx = open(path, "wt") w = idx.write # Edit the template with open(layout_file) as open_file: s = "".join(open_file.readlines()) for key, value in six.iteritems(layout_info): s = s.replace("%({0})s".format(key), value) w(s) # Close the open file idx.close()
[docs] def write_index(self, outdir, froot="index", rst_extension=".rst"): """ Make a reST API index file from python modules Parameters ---------- outdir : string (mandatory) Directory to which to write generated index file froot : string (optional) root (filename without extension) of filename to write to Defaults to 'index'. We add ``rst_extension``. rst_extension : string (optional) Extension for reST files, default '.rst' """ # Check output directory if not os.path.exists(outdir): os.makedirs(outdir) # Get full output filename path path = os.path.join(outdir, froot + rst_extension) # Start writing the index idx = open(path, "wt") w = idx.write # Header w(".. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n") w(".. raw:: html\n\n") w(" <div class='container-index'>\n\n") title = "Documentation of the {0} Pipelines\n".format( self.root_module_name.upper()) w(title) w(self.rst_section_levels[1] * len(title) + "\n\n") # Modules w(".. raw:: html\n\n") w(" <!-- Block section -->\n\n") for cnt, module_name in enumerate(self.module_names): if cnt % 2 == 0: w(" <div class='row-fluid'>\n\n") w(self.generate_index_entry(module_name)) w("\n </div>\n") w("\n </div>") # Close the open file idx.close()