Anonymous avatar Anonymous committed eb4b881

Fixed footnote numbering

Comments (0)

Files changed (2)

sphinx/builders/pdf.py

 import logging
 from pprint import pprint
 
+
+class collected_footnote(nodes.footnote):
+    """Footnotes that are collected are assigned this class."""
+    
+class PDFTranslator(nodes.SparseNodeVisitor):
+    def __init__(self, document, builder):
+        nodes.NodeVisitor.__init__(self, document)
+        self.builder = builder
+        self.footnotestack = []
+	self.top_sectionlevel = 1
+
+    def visit_document(self, node):
+        self.footnotestack.append(self.collect_footnotes(node))
+	print 'VD:',self.footnotestack
+        #self.curfilestack.append(node.get('docname', ''))
+        #if self.first_document == 1:
+            ## the first document is all the regular content ...
+            #self.body.append(BEGIN_DOC % self.elements)
+            #self.first_document = 0
+        #elif self.first_document == 0:
+            ## ... and all others are the appendices
+            #self.body.append('\n\\appendix\n')
+            #self.first_document = -1
+        #if 'docname' in node:
+            #self.body.append('\\hypertarget{--doc-%s}{}' % node['docname'])
+        # "- 1" because the level is increased before the title is visited
+        self.sectionlevel = self.top_sectionlevel - 1
+    def visit_start_of_file(self, node):
+        # This marks the begin of a new file; therefore the current module and
+        # class must be reset
+        #self.body.append('\n\\resetcurrentobjects\n')
+        # and also, new footnotes
+        self.footnotestack.append(self.collect_footnotes(node))
+        # also add a document target
+        #self.body.append('\\hypertarget{--doc-%s}{}' % node['docname'])
+        #self.curfilestack.append(node['docname'])
+
+    def visit_footnote(self, node):
+        raise nodes.SkipNode
+
+    def visit_footnote_reference(self, node):
+        num = node.astext().strip()
+        try:
+            footnode, used = self.footnotestack[-1][num]
+        except (KeyError, IndexError):
+            raise nodes.SkipNode
+        # if a footnote has been inserted once, it shouldn't be repeated
+        # by the next reference
+        if used:
+	    pass
+            #self.body.append('\\footnotemark[%s]' % num)
+        else:
+            footnode.walkabout(self)
+            self.footnotestack[-1][num][1] = True
+        raise nodes.SkipChildren
+    
+    def depart_footnote_reference(self, node):
+        pass
+
+    def depart_start_of_file(self, node):
+        self.footnotestack.pop()
+
+    def visit_collected_footnote(self, node):
+        print 'CF:',node
+    def depart_collected_footnote(self, node):
+	pass
+	    
+    def collect_footnotes(self, node):
+        fnotes = {}
+        def footnotes_under(n):
+            if isinstance(n, nodes.footnote):
+                yield n
+            else:
+                for c in n.children:
+                    if isinstance(c, addnodes.start_of_file):
+                        continue
+                    for k in footnotes_under(c):
+                        yield k
+        for fn in footnotes_under(node):
+            num = fn.children[0].astext().strip()
+            fnotes[num] = [collected_footnote(*fn.children), False]
+        return fnotes
+
+
 class PDFBuilder(Builder):
     name = 'pdf'
     out_suffix = '.pdf'
                         self.warn('%s: toctree contains ref to nonexisting file %r'\
                                                      % (docname, includefile))
                     else:
-                        newnodes.extend(subtree.children)
+                        sof = addnodes.start_of_file(docname=includefile)
+                        sof.children = subtree.children
+                        newnodes.append(sof)
                 toctreenode.parent.replace(toctreenode, newnodes)
             return tree
 
             # This needs work, need to keep track of all targets
             # so I don't replace and create hanging refs, which
             # crash
-            print "REPLACING:",pendingnode
-            if pendingnode['reftype']=='ref':
+            if pendingnode['reftarget'] in ['genindex']:
                 pendingnode.replace_self(nodes.reference(text=pendingnode.astext(),
                     refuri=pendingnode['reftarget']))
-            else: 
+            else:
                 pass
         return tree
     

sphinx/writers/pdf.py

 
 from StringIO import StringIO
 from docutils import writers
+from docutils import nodes
 from rst2pdf import createpdf
+from sphinx import addnodes
 
 class PDFWriter(writers.Writer):
-   def __init__(self,
+    def __init__(self,
                 builder,
                 stylesheets,
                 language,
                 fitmode = 'shrink',
                 compressed = False,
                 inline_footnotes = False):
-      writers.Writer.__init__(self)
-      self.builder = builder
-      self.output = ''
-      self.stylesheets = stylesheets
-      self.language = language
-      self.breaklevel = int(breaklevel)
-      self.fontpath = fontpath
-      self.fitmode = fitmode
-      self.compressed = compressed
-      self.inline_footnotes = inline_footnotes
-      self.highlightlang = builder.config.highlight_language
+        writers.Writer.__init__(self)
+        self.builder = builder
+        self.output = ''
+        self.stylesheets = stylesheets
+        self.language = language
+        self.breaklevel = int(breaklevel)
+        self.fontpath = fontpath
+        self.fitmode = fitmode
+        self.compressed = compressed
+        self.inline_footnotes = inline_footnotes
+        self.highlightlang = builder.config.highlight_language
 
-   supported = ('pdf')
-   config_section = 'pdf writer'
-   config_section_dependencies = ('writers',)
+    supported = ('pdf')
+    config_section = 'pdf writer'
+    config_section_dependencies = ('writers',)
 
-   def translate(self):
-      sio=StringIO('')
-      createpdf.RstToPdf(sphinx=True,
-                         stylesheets=self.stylesheets,
-                         # FIXME
-                         language='en_US',
-                         breaklevel=self.breaklevel,
-                         fit_mode=self.fitmode,
-                         font_path=self.fontpath,
-                         inline_footnotes=self.inline_footnotes,
-			 highlightlang=self.highlightlang,
-                        ).createPdf(doctree=self.document,
-                                    output=sio,
-                                    compressed=self.compressed)
-      self.output=unicode(sio.getvalue(),'utf-8','ignore')
+    def translate(self):
+        visitor = PDFTranslator(self.document, self.builder)
+        self.document.walkabout(visitor)
+        sio=StringIO('')
+        createpdf.RstToPdf(sphinx=True,
+                 stylesheets=self.stylesheets,
+                 # FIXME
+                 language='en_US',
+                 breaklevel=self.breaklevel,
+                 fit_mode=self.fitmode,
+                 font_path=self.fontpath,
+                 inline_footnotes=self.inline_footnotes,
+                 highlightlang=self.highlightlang,
+                ).createPdf(doctree=self.document,
+                    output=sio,
+                    compressed=self.compressed)
+        self.output=unicode(sio.getvalue(),'utf-8','ignore')
 
-   def supports(self, format):
-      """This writer supports all format-specific elements."""
-      return 1
+    def supports(self, format):
+        """This writer supports all format-specific elements."""
+        return 1
 
+
+class PDFTranslator(nodes.SparseNodeVisitor):
+    def __init__(self, document, builder):
+        nodes.NodeVisitor.__init__(self, document)
+        self.builder = builder
+        self.footnotestack = []
+	self.top_sectionlevel = 1
+        self.footnotecounter=1
+        self.curfile=None
+        self.footnotedict={}
+
+    def visit_document(self,node):
+        self.footnotestack.append('')
+        
+    def visit_start_of_file(self,node):
+        self.footnotestack.append(node['docname'])
+
+    def depart_start_of_file(self,node):
+        self.footnotestack.pop()
+        
+    def visit_footnote(self, node):
+        node['backrefs']=[ '%s_%s'%(self.footnotestack[-1],x) for x in node['backrefs']]
+        node['ids']=[ '%s_%s'%(self.footnotestack[-1],x) for x in node['ids']]
+        node.children[0][0]=nodes.Text(str(self.footnotecounter))
+        for id in node['backrefs']:
+            fnr=self.footnotedict[id]
+            fnr.children[0]=nodes.Text(str(self.footnotecounter))        
+        self.footnotecounter+=1
+
+    def visit_footnote_reference(self, node):
+        node['ids']=[ '%s_%s'%(self.footnotestack[-1],x) for x in node['ids']]
+        node['refid']='%s_%s'%(self.footnotestack[-1],node['refid'])
+        self.footnotedict[node['ids'][0]]=node
+        
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.