tableofcontents/paraparser: allow for format and offset parameters
authorrgbecker
Thu, 02 Jul 2009 13:53:21 +0000
changeset 3187 2d5a6655556e
parent 3186 baf61467fa9a
child 3188 be6793854075
tableofcontents/paraparser: allow for format and offset parameters
src/reportlab/platypus/paraparser.py
src/reportlab/platypus/tableofcontents.py
--- a/src/reportlab/platypus/paraparser.py	Thu Jul 02 08:12:53 2009 +0000
+++ b/src/reportlab/platypus/paraparser.py	Thu Jul 02 13:53:21 2009 +0000
@@ -9,6 +9,11 @@
 import sys
 import os
 import copy
+import base64
+try:
+    import cPickle as pickle
+except:
+    import pickle
 import unicodedata
 import reportlab.lib.sequencer
 from reportlab.lib.abag import ABag
@@ -176,6 +181,8 @@
 _indexAttrMap = {
                 'name': ('name',None),
                 'item': ('item',None),
+                'offset': ('offset',None),
+                'format': ('format',None),
                 }
 
 def _addAttributeNames(m):
@@ -896,13 +903,23 @@
         attr=self.getAttributes(attr,_indexAttrMap)
         defn = ABag()
         if attr.has_key('item'):
-            defn.label = attr['item']
+            label = attr['item']
         else:
             self._syntax_error('<index> needs at least an item attribute')
         if attr.has_key('name'):
             name = attr['name']
         else:
             name = DEFAULT_INDEX_NAME
+        format = attr.get('format',None)
+        if format is not None and format not in ('123','I','i','ABC','abc'):
+            raise ValueError('index tag format is %r not valid 123 I i ABC or abc' % offset)
+        offset = attr.get('offset',None)
+        if offset is not None:
+            try:
+                offset = int(offset)
+            except:
+                raise ValueError('index tag offset is %r not an int' % offset)
+        defn.label = base64.encodestring(cPickle.dumps((label,format,offset))).strip
         defn.name = name
         defn.kind='index'
         self._push(cbDefn=defn)
--- a/src/reportlab/platypus/tableofcontents.py	Thu Jul 02 08:12:53 2009 +0000
+++ b/src/reportlab/platypus/tableofcontents.py	Thu Jul 02 13:53:21 2009 +0000
@@ -55,7 +55,12 @@
 from reportlab.pdfbase.pdfmetrics import stringWidth
 from reportlab.pdfgen import canvas
 from base64 import encodestring, decodestring
-from marshal import dumps, loads
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+dumps = pickle.dumps
+loads = pickle.loads
 
 def unquote(txt):
     from xml.sax.saxutils import unescape
@@ -286,7 +291,14 @@
         self._flowable = None
         self.setup(**kwargs)
 
-    def setup(self, style=None, dot=None, tableStyle=None, headers=True, name=None):
+    def getFormatFunc(self,format):
+        try:
+            exec 'from reportlab.lib.sequencer import _format_%s as formatFunc' % format in locals()
+        except ImportError:
+            raise ValueError('Unknown format %r' % format)
+        return formatFunc
+
+    def setup(self, style=None, dot=None, tableStyle=None, headers=True, name=None, format='123', offset=0):
         """
         This method makes it possible to change styling and other parameters on an existing object.
         
@@ -302,6 +314,8 @@
             name of the index which it should appear in:
             
                 <index item="term" name="myindex" />
+
+        format can be 'I', 'i', '123',  'ABC', 'abc'
         """
         
         if style is None:
@@ -315,14 +329,29 @@
         if name is None:
             from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name
         self.name = name
+        self.formatFunc = self.getFormatFunc(format)
+        self.offset = offset
 
     def __call__(self,canv,kind,label):
-        terms = commasplit(label)
-        key = 'ix_%s_%s_p_%s' % (self.name, label, canv.getPageNumber())
+        try:
+            terms, format, offset = loads(decodestring(label))
+        except:
+            terms = label
+            format = offset = None
+        if format is None:
+            formatFunc = self.formatFunc
+        else:
+            formatFunc = self.getFormatFunc(format)
+        if offset is None:
+            offset = self.offset
+
+        terms = commasplit(terms)
+        pns = formatFunc(canv.getPageNumber()-offset)
+        key = 'ix_%s_%s_p_%s' % (self.name, label, pns)
 
         info = canv._curr_tx_info
         canv.bookmarkHorizontal(key, info['cur_x'], info['cur_y'] + info['leading'])
-        self.addEntry(terms, canv.getPageNumber(), key)
+        self.addEntry(terms, pns, key)
 
     def getCanvasMaker(self, canvasmaker=canvas.Canvas):
 
@@ -407,7 +436,7 @@
             if diff:
                 lastTexts = texts
                 texts = texts[i:]
-            label = encodestring(dumps(list(pageNumbers)))
+            label = encodestring(dumps(list(pageNumbers))).strip()
             texts[-1] = '%s<onDraw name="drawIndexEntryEnd" label="%s"/>' % (texts[-1], label)
             for text in texts:
                 style = self.getLevelStyle(i+leveloffset)