[Python-checkins] r64465 - in doctools/trunk: CHANGES sphinx/htmlwriter.py sphinx/latexwriter.py sphinx/texinputs/sphinx.sty

georg.brandl python-checkins at python.org
Sun Jun 22 21:02:49 CEST 2008


Author: georg.brandl
Date: Sun Jun 22 21:02:49 2008
New Revision: 64465

Log:
Add support for subscript/superscript nodes in latex.


Modified:
   doctools/trunk/CHANGES
   doctools/trunk/sphinx/htmlwriter.py
   doctools/trunk/sphinx/latexwriter.py
   doctools/trunk/sphinx/texinputs/sphinx.sty

Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES	(original)
+++ doctools/trunk/CHANGES	Sun Jun 22 21:02:49 2008
@@ -101,7 +101,7 @@
 
 * Fix behavior of references to functions/methods with an explicit title.
 
-* Support citation nodes in LaTeX writer.
+* Support citation, subscript and superscript nodes in LaTeX writer.
 
 * Provide the standard "class" directive as "cssclass"; else it is
   shadowed by the Sphinx-defined directive.

Modified: doctools/trunk/sphinx/htmlwriter.py
==============================================================================
--- doctools/trunk/sphinx/htmlwriter.py	(original)
+++ doctools/trunk/sphinx/htmlwriter.py	Sun Jun 22 21:02:49 2008
@@ -310,6 +310,9 @@
                              u'title="Permalink to this headline">\u00B6</a>')
         BaseTranslator.depart_title(self, node)
 
+    def unknown_visit(self, node):
+        raise NotImplementedError("Unknown node: " + node.__class__.__name__)
+
 
 class SmartyPantsHTMLTranslator(HTMLTranslator):
     """

Modified: doctools/trunk/sphinx/latexwriter.py
==============================================================================
--- doctools/trunk/sphinx/latexwriter.py	(original)
+++ doctools/trunk/sphinx/latexwriter.py	Sun Jun 22 21:02:49 2008
@@ -595,12 +595,26 @@
     def depart_module(self, node):
         pass
 
+    def latex_image_length(self, width_str):
+        match = re.match('(\d*\.?\d*)\s*(\S*)', width_str)
+        if not match:
+            # fallback
+            return width_str
+        res = width_str
+        amount, unit = match.groups()[:2]
+        if unit == "px":
+            # LaTeX does not know pixels but points
+            res = "%spt" % amount
+        elif unit == "%":
+            res = "%.3f\\linewidth" % (float(amount) / 100.0)
+        return res
+
     def visit_image(self, node):
         self.need_graphicx = 1
         attrs = node.attributes
         pre = []                        # in reverse order
         post = []
-        include_graphics_options = ""
+        include_graphics_options = []
         inline = isinstance(node.parent, nodes.TextElement)
         if attrs.has_key('scale'):
             # Could also be done with ``scale`` option to
@@ -608,7 +622,11 @@
             pre.append('\\scalebox{%f}{' % (attrs['scale'] / 100.0,))
             post.append('}')
         if attrs.has_key('width'):
-            include_graphics_options = '[width=%s]' % attrs['width']
+            include_graphics_options.append('width=%s' % (
+                            self.latex_image_length(attrs['width']), ))
+        if attrs.has_key('height'):
+            include_graphics_options.append('height=%s' % (
+                            self.latex_image_length(attrs['height']), ))
         if attrs.has_key('align'):
             align_prepost = {
                 # By default latex aligns the top of an image.
@@ -625,7 +643,7 @@
                 pre.append(align_prepost[inline, attrs['align']][0])
                 post.append(align_prepost[inline, attrs['align']][1])
             except KeyError:
-                pass
+                pass                    # XXX complain here?
         if not inline:
             pre.append('\n')
             post.append('\n')
@@ -638,22 +656,39 @@
             # ignore remote images
             return
         self.body.extend(pre)
-        # XXX: for now, don't fiddle around with graphics formats
-        self.body.append('\\includegraphics%s{%s}' % (include_graphics_options, uri))
+        options = ''
+        if include_graphics_options:
+            options = '[%s]' % ','.join(include_graphics_options)
+        self.body.append('\\includegraphics%s{%s}' % (options, uri))
         self.body.extend(post)
     def depart_image(self, node):
         pass
 
     def visit_figure(self, node):
-        self.body.append('\\begin{figure}\n')
+        if (not node.attributes.has_key('align') or
+            node.attributes['align'] == 'center'):
+            # centering does not add vertical space like center.
+            align = '\n\\centering'
+            align_end = ''
+        else:
+            # TODO non vertical space for other alignments.
+            align = '\\begin{flush%s}' % node.attributes['align']
+            align_end = '\\end{flush%s}' % node.attributes['align']
+        self.body.append('\\begin{figure}[htbp]%s\n' % align)
+        self.context.append('%s\\end{figure}\n' % align_end)
     def depart_figure(self, node):
-        self.body.append('\\end{figure}\n')
+        self.body.append(self.context.pop())
 
     def visit_caption(self, node):
         self.body.append('\\caption{')
     def depart_caption(self, node):
         self.body.append('}')
 
+    def visit_legend(self, node):
+        self.body.append('{\\small ')
+    def depart_legend(self, node):
+        self.body.append('}')
+
     def visit_admonition(self, node):
         self.body.append('\n\\begin{quote}')
     def depart_admonition(self, node):
@@ -721,6 +756,12 @@
     def depart_target(self, node):
         pass
 
+    def visit_attribution(self, node):
+        self.body.append('\n\\begin{flushright}\n')
+        self.body.append('---')
+    def depart_attribution(self, node):
+        self.body.append('\n\\end{flushright}\n')
+
     indextype_map = {
         'module': 'refmodindex',
         'keyword': 'kwindex',
@@ -751,7 +792,7 @@
 
     def visit_raw(self, node):
         if 'latex' in node.get('format', '').split():
-            self.body.append(r'%s' % node.astext())
+            self.body.append(node.astext())
         raise nodes.SkipNode
 
     def visit_reference(self, node):
@@ -948,9 +989,42 @@
     def depart_description(self, node):
         pass
 
+    def visit_superscript(self, node):
+        self.body.append('$^{\\text{')
+    def depart_superscript(self, node):
+        self.body.append('}}$')
+
+    def visit_subscript(self, node):
+        self.body.append('$_{\\text{')
+    def depart_subscript(self, node):
+        self.body.append('}}$')
+
     def visit_substitution_definition(self, node):
         raise nodes.SkipNode
 
+    def visit_substitution_reference(self, node):
+        raise nodes.SkipNode
+
+    def visit_generated(self, node):
+        pass
+    def depart_generated(self, node):
+        pass
+
+    def visit_compound(self, node):
+        pass
+    def depart_compound(self, node):
+        pass
+
+    def visit_container(self, node):
+        pass
+    def depart_container(self, node):
+        pass
+
+    def visit_decoration(self, node):
+        pass
+    def depart_decoration(self, node):
+        pass
+
     # text handling
 
     replacements = [

Modified: doctools/trunk/sphinx/texinputs/sphinx.sty
==============================================================================
--- doctools/trunk/sphinx/texinputs/sphinx.sty	(original)
+++ doctools/trunk/sphinx/texinputs/sphinx.sty	Sun Jun 22 21:02:49 2008
@@ -13,6 +13,7 @@
 \RequirePackage{fancyvrb}
 \RequirePackage{titlesec}
 \RequirePackage{tabulary}
+\RequirePackage{amsmath} % for \text
 
 \RequirePackage{color}
 % Redefine these colors to your liking in the preamble.


More information about the Python-checkins mailing list