]> git.llucax.com Git - z.facultad/75.00/informe.git/commitdiff
Agregar extensiones de Sphinx para mejor manejo de figuras
authorLeandro Lucarella <llucax@gmail.com>
Sun, 24 May 2009 04:26:59 +0000 (01:26 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Sun, 31 May 2009 00:30:12 +0000 (21:30 -0300)
El soporte de Sphinx (y reST en general) para generar figuras es
bastante incompleto. Este parche agrega un par de extensiones para
simplificarlo.

ext/fig.py [new file with mode: 0644]
ext/vref.py [new file with mode: 0644]

diff --git a/ext/fig.py b/ext/fig.py
new file mode 100644 (file)
index 0000000..d258dea
--- /dev/null
@@ -0,0 +1,148 @@
+
+from docutils import nodes, utils
+from docutils.parsers.rst import directives
+from sphinx.util.compat import Directive
+
+
+DEFAULT_PLACES  = 'hbtp'
+DEFAULT_PADDING = '0.1'
+
+
+# subfig
+############################################################################
+
+class subcap(nodes.Part, nodes.TextElement):
+    pass
+
+def latex_visit_subcap(self, node):
+    self.body.append('[')
+
+def latex_depart_subcap(self, node):
+    self.body.append(']{')
+
+
+class subfig(nodes.General, nodes.Element):
+    pass
+
+def latex_visit_subfig(self, node):
+    space = '\\hspace{%sin}\n' % node['space'] if node['space'] else ''
+    self.body.append(space)
+    self.body.append('\\subfigure')
+
+def latex_depart_subfig(self, node):
+    self.body.append('}\n')
+
+
+class SubfigDirective(Directive):
+
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 1
+    final_argument_whitespace = True
+    option_spec = dict(
+        label   = directives.unchanged,
+        space   = float,
+    )
+
+    def run(self):
+        self.assert_has_content()
+        subfig_node = subfig('\n'.join(self.content))
+        subfig_node['label'] = self.options.get('label', None)
+        subfig_node['space'] = self.options.get('space', None)
+        if self.arguments and self.arguments[0]:
+            subfig_node['label'] = self.arguments[0]
+        node = nodes.Element() # anonymous container for parsing
+        self.state.nested_parse(self.content, self.content_offset, node)
+        first_node = node[0]
+        if isinstance(first_node, nodes.paragraph):
+            cap = subcap(first_node.rawsource, '', *first_node.children)
+            subfig_node += cap
+            subfig_node += node[1:]
+        else:
+            subfig_node += subcap('', '', nodes.Text(''))
+            subfig_node += node[:]
+        return [subfig_node]
+
+
+# fig
+############################################################################
+
+class pad(nodes.Part, nodes.TextElement):
+    pass
+
+def latex_visit_pad(self, node):
+    self.body.append('\\hspace{%sin}\n' % node['inches'])
+
+def latex_depart_pad(self, node):
+    pass
+    #self.body.append('\\hspace{%sin}\n' % DEFAULT_PADDING) #node['inches'])
+
+
+class fig(nodes.General, nodes.Element):
+    pass
+
+def latex_visit_fig(self, node):
+    self.body.append('\\begin{figure}[%s]\n' % node['placement'])
+    self.body.append('' if node['nocenter'] else '\\centering\n')
+
+def latex_depart_fig(self, node):
+    label = '\\label{%s}\n' % node['label'] if node['label'] else ''
+    self.body.append(label)
+    self.body.append('\\end{figure}\n\n')
+
+class FigDirective(Directive):
+
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 1
+    final_argument_whitespace = True
+    option_spec = dict(
+        label     = directives.unchanged,
+        placement = directives.unchanged,
+        padding   = float,
+        nocenter  = directives.flag,
+    )
+
+    def run(self):
+        self.assert_has_content()
+        fig_node = fig('\n'.join(self.content))
+        fig_node['label'] = self.options.get('label', None)
+        fig_node['placement'] = self.options.get('placement', DEFAULT_PLACES)
+        fig_node['padding'] = self.options.get('padding', DEFAULT_PADDING)
+        fig_node['nocenter'] = 'nocenter' in self.options
+        if self.arguments and self.arguments[0]:
+            fig_node['label'] = self.arguments[0]
+        node = nodes.Element() # anonymous container for parsing
+        self.state.nested_parse(self.content, self.content_offset, node)
+        first_node = node[0]
+        cap = None
+        if isinstance(first_node, nodes.paragraph):
+            cap = nodes.caption(first_node.rawsource, '', *first_node.children)
+            node = node[1:]
+        first = True
+        children = []
+        for n in node:
+            if isinstance(n, subfig):
+                if first:
+                    first = False
+                else:
+                    children.append(pad('', '', nodes.Text(''),
+                            inches=fig_node['padding']))
+            children.append(n)
+        fig_node += children
+        if cap:
+            fig_node += cap
+        return [fig_node]
+
+
+
+def setup(app):
+    app.add_node(subcap, latex=(latex_visit_subcap, latex_depart_subcap))
+    app.add_node(subfig, latex=(latex_visit_subfig, latex_depart_subfig))
+    app.add_node(pad, latex=(latex_visit_pad, latex_depart_pad))
+    app.add_node(fig, latex=(latex_visit_fig, latex_depart_fig))
+    app.add_directive('fig', FigDirective)
+    app.add_directive('subfig', SubfigDirective)
+
+
+# vim: set et sw=4 sts=4 :
diff --git a/ext/vref.py b/ext/vref.py
new file mode 100644 (file)
index 0000000..564e000
--- /dev/null
@@ -0,0 +1,19 @@
+
+
+from docutils import nodes, utils
+
+class vref(nodes.Inline, nodes.TextElement):
+    pass
+
+def vref_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
+    latex = utils.unescape(text, restore_backslashes=True)
+    return [vref(latex=latex)], []
+
+def latex_visit_vref(self, node):
+    self.body.append(r'\vref{' + node['latex'] + '}')
+    raise nodes.SkipNode
+
+def setup(app):
+    app.add_node(vref, latex=(latex_visit_vref, None))
+    app.add_role('vref', vref_role)
+