sql_schema.py 4.45 KB
Newer Older
1

2
# Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
nwillhoft's avatar
nwillhoft committed
3
# Copyright [2016-2021] EMBL-European Bioinformatics Institute
4 5 6 7 8 9 10 11 12 13 14 15 16
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#      http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

17 18 19
##############################################################
## Sphinx extension to colour the HTML schema documentation ##
##############################################################
20

21
from docutils import nodes
22

23 24 25 26
import sphinx.ext.graphviz


class SchemaDiagramDirective(sphinx.ext.graphviz.Graphviz):
27 28 29
    has_content = True
    required_arguments = 0
    optional_arguments = 1
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
    final_argument_whitespace = False
    option_spec = {}

    def run(self):
        nodes = super(SchemaDiagramDirective, self).run()
        for _ in nodes:
            _.__class__ = versatile_graphviz
        return nodes

class versatile_graphviz(sphinx.ext.graphviz.graphviz):
    pass


def html_visit_graphviz(self, node):
    code = node['code']
    # svg files are smaller than png
    format = 'svg'
    try:
        fname, outfn = sphinx.ext.graphviz.render_dot(self, code, node['options'], format, 'graphviz')
    except sphinx.ext.graphviz.GraphvizError as exc:
        self.builder.warn('dot code %r: ' % code + str(exc))
        raise nodes.SkipNode

    if fname is None:
        self.body.append(self.encode(code))
    # this svg handler does not make the images clickable
    #elif format == 'svg':
        #self.body.append('<a class="reference internal image-reference" href="{0}"><object data="{0}" type="image/svg+xml" class="align-center" style="max-width: 500px; max-height: 500px"><p class="warning">{0}</p></object>'.format(fname))
    else:
        self.body.append('<a class="reference internal image-reference" href="{0}"><img alt="{0}" class="align-center" src="{0}" style="max-width: 500px; max-height: 500px"></a>'.format(fname))
    raise nodes.SkipNode

def latex_visit_graphviz(self, node):
    code = node['code'].replace("{", "{\nsize=\"8,5\";", 1)
    sphinx.ext.graphviz.render_dot_latex(self, node, code, node['options'])
65

66
## A node to record in the doctree
67 68 69
class schema_table_header(nodes.Element):
    pass

70 71 72 73

## The role, which will create an instance of the above node class
## Use like this
##   :schema_table_header:`<#C70C09,square>Pipeline structure`
74 75
def schema_table_header_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    (params,_,text) = text.partition('>')
76
    # "square" is the default shape
77 78 79 80
    if "," not in params:
        params = params + ",square"
    (colour_spec, shape) = params[1:].split(",")
    schema_table_header_node = schema_table_header()
81
    schema_table_header_node.append(nodes.Text(text))
82 83 84 85 86
    schema_table_header_node['colour_spec'] = colour_spec
    schema_table_header_node['shape'] = shape

    return [schema_table_header_node], []

87 88 89 90 91 92

## HTML writer
#
# <div> and <span> element with the right CSS class
#

93 94 95 96 97 98
def visit_schema_table_header_html(self, node):
    self.body.append('<div class="sql_schema_table_%s_bullet" style="border-color:%s;"><span style="background-color:%s;"></span>' % (node['shape'], node['colour_spec'], node['colour_spec']))

def depart_schema_table_header_html(self, node):
    self.body.append('</div>')

99 100 101 102 103 104

## Latex writer
#
# Don't do anything, i.e. no colour
#

105
def visit_schema_table_header_latex(self, node):
106
    pass
107 108

def depart_schema_table_header_latex(self, node):
109
    pass
110 111


112 113 114 115
## Register the extension
def setup(app):
    # Add the CSS
    app.add_stylesheet("schema_doc.css")
116 117 118 119 120
    app.add_directive('schema_diagram', SchemaDiagramDirective)
    app.add_node(versatile_graphviz,
            html=(html_visit_graphviz, None),
            latex=(latex_visit_graphviz, None),
            )
121 122 123 124 125 126 127
    # Register the role and the node, and their handlers
    app.add_role('schema_table_header', schema_table_header_role)
    app.add_node(schema_table_header,
        html = (visit_schema_table_header_html, depart_schema_table_header_html),
        latex = (visit_schema_table_header_latex, depart_schema_table_header_latex),
    )