]> git.llucax.com Git - z.facultad/75.00/informe.git/blob - ext/aafig.py
7850613104e0906746fc8085db0c621c487856b8
[z.facultad/75.00/informe.git] / ext / aafig.py
1 # -*- coding: utf-8 -*-
2 """
3     sphinxcontrib.aafigure
4     ~~~~~~~~~~~~~~~~~~~~~~
5
6     Allow mscgen-formatted :abbr:`MSC (Message Sequence Chart)` graphs to be
7     included in Sphinx-generated documents inline.
8
9     See the README file for details.
10
11     :copyright: Copyright 2009 by Leandro Lucarella (based on \
12         sphinx.ext.graphviz).
13     :license: BSD, see LICENSE for details.
14 """
15
16 import posixpath
17 from os import path
18 try:
19     from hashlib import sha1 as sha
20 except ImportError:
21     from sha import sha
22
23 from docutils import nodes
24 from docutils.parsers.rst import directives
25
26 from sphinx.errors import SphinxError
27 from sphinx.util import ensuredir
28 from sphinx.util.compat import Directive
29
30 import aafigure
31
32 DEFAULT_PREFIX = 'aafig'
33
34 class AafigError(SphinxError):
35     category = 'aafig error'
36
37
38 class aafig(nodes.General, nodes.Element):
39     pass
40
41
42 class Aafig(Directive):
43     """
44     Directive to insert an ASCII art figure to be rendered by aafigure.
45     """
46     has_content = True
47     required_arguments = 0
48     optional_arguments = 0
49     final_argument_whitespace = False
50     option_spec = dict(
51         scale        = float,
52         line_width   = float,
53         background   = str,
54         foreground   = str,
55         fill         = str,
56         aspect       = float,
57         textual      = directives.flag,
58         proportional = directives.flag,
59     )
60
61     def run(self):
62         node = aafig()
63         node['text'] = '\n'.join(self.content)
64         if 'textual' in self.options: self.options['textual'] = True
65         if 'proportional' in self.options: self.options['proportional'] = True
66         node['options'] = self.options
67         return [node]
68
69
70 def render_aafigure(self, text, options, prefix):
71     """
72     Render an ASCII art figure into the requested format output file.
73     """
74     hashkey = text.encode('utf-8') + str(options)
75     id = sha(hashkey).hexdigest()
76     fname = '%s-%s.%s' % (prefix, id, options['format'])
77     if hasattr(self.builder, 'imgpath'):
78         # HTML
79         relfn = posixpath.join(self.builder.imgpath, fname)
80         outfn = path.join(self.builder.outdir, '_images', fname)
81     else:
82         # LaTeX
83         relfn = fname
84         outfn = path.join(self.builder.outdir, fname)
85
86     if path.isfile(outfn):
87         return relfn, outfn, id
88
89     ensuredir(path.dirname(outfn))
90
91     try:
92         aafigure.render(text, outfn, options)
93     except aafigure.UnsupportedFormatError, e:
94         raise MscgenError(str(e))
95
96     return relfn, outfn, id
97
98
99 def render_html(self, node, text, options, prefix=DEFAULT_PREFIX, imgcls=None):
100     try:
101         options['format'] = self.builder.config.aafig_format['html']
102         fname, outfn, id = render_aafigure(self, text, options, prefix)
103     except AafigError, exc:
104         self.builder.warn('aafigure error: ' + str(exc))
105         raise nodes.SkipNode
106
107     self.body.append(self.starttag(node, 'p', CLASS='aafigure'))
108     if fname is None:
109         self.body.append(self.encode(text))
110     else:
111         imgcss = imgcls and 'class="%s"' % imgcls or ''
112         # nothing in image map
113         self.body.append('<img src="%s" alt="%s" %s/>\n' %
114                          (fname, self.encode(text).strip(), imgcss))
115     self.body.append('</p>\n')
116     raise nodes.SkipNode
117
118
119 def html_visit(self, node):
120     render_html(self, node, node['text'], node['options'])
121
122
123 def render_latex(self, node, text, options, prefix=DEFAULT_PREFIX):
124     try:
125         options['format'] = self.builder.config.aafig_format['latex']
126         fname, outfn, id = render_aafigure(self, text, options, prefix)
127     except AafigError, exc:
128         self.builder.warn('aafigure error: ' + str(exc))
129         raise nodes.SkipNode
130
131     if fname is not None:
132         self.body.append('\\includegraphics[]{%s}' % fname)
133     raise nodes.SkipNode
134
135
136 def latex_visit(self, node):
137     render_latex(self, node, node['text'], node['options'])
138
139 def setup(app):
140     app.add_node(aafig, html=(html_visit, None), latex=(latex_visit, None))
141     app.add_directive('aafig', Aafig)
142     app.add_config_value('aafig_format', dict(html='svg', latex='pdf'), 'html')
143