reportlab: fix up links in paragraphs
authorrgbecker
Wed, 10 May 2006 12:56:39 +0000
changeset 2594 746800f5caf9
parent 2593 3adaab508968
child 2595 ffb020e8ab50
reportlab: fix up links in paragraphs
reportlab/platypus/paragraph.py
reportlab/platypus/paraparser.py
reportlab/test/test_platypus_paragraphs.py
--- a/reportlab/platypus/paragraph.py	Mon May 08 15:04:15 2006 +0000
+++ b/reportlab/platypus/paragraph.py	Wed May 10 12:56:39 2006 +0000
@@ -14,7 +14,7 @@
 from reportlab.lib.textsplit import wordSplit
 from copy import deepcopy
 from reportlab.lib.abag import ABag
-
+import re
 
 #on UTF8 branch, split and strip must be unicode-safe!
 def split(text, delim=' '):
@@ -385,13 +385,26 @@
     xtraState.underline=0
     xtraState.underlineColor=None
 
+_scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$')
+def _doLink(tx,link,rect):
+    if type(link) is unicode:
+        link = unicode.encode('utf8')
+    parts = link.split(':',1)
+    scheme = len(parts)==2 and parts[0].lower() or ''
+    if _scheme_re.match(scheme) and scheme!='document':
+        kind=scheme.lower()=='pdf' and 'GoToR' or 'URI'
+        if kind=='GoToR': link = parts[1]
+        tx._canvas.linkURL(link, rect, relative=1, kind=kind)
+    else:
+        tx._canvas.linkRect("", scheme!='document' and link or parts[1], rect, relative=1)
+
 def _do_link_line(i, t_off, tx):
     xs = tx.XtraState
     leading = xs.style.leading
     y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py
     text = join(xs.lines[i][1])
     textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
-    tx._canvas.linkRect("", xs.link, (t_off, y, t_off+textlen, y+leading), relative=1)
+    _doLink(tx, xs.link, (t_off, y, t_off+textlen, y+leading))
 
 def _do_link(i, t_off, tx):
     xs = tx.XtraState
@@ -399,7 +412,7 @@
     y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py
     for x1,x2,link in xs.links:
         tx._canvas.line(t_off+x1, y, t_off+x2, y)
-        tx._canvas.linkRect("", link, (t_off+x1, y, t_off+x2, y+leading), relative=1)
+        _doLink(tx, link, (t_off+x1, y, t_off+x2, y+leading))
     xs.links = []
     xs.link=None
 
--- a/reportlab/platypus/paraparser.py	Mon May 08 15:04:15 2006 +0000
+++ b/reportlab/platypus/paraparser.py	Wed May 10 12:56:39 2006 +0000
@@ -118,6 +118,7 @@
                 'dest': ('link', None),
                 'destination': ('link', None),
                 'target': ('link', None),
+                'href': ('link', None),
                 }
 
 def _addAttributeNames(m):
@@ -422,9 +423,7 @@
 
     def handle_entityref(self,name):
         if greeks.has_key(name):
-            self._push(greek=1)
             self.handle_data(greeks[name])
-            self._pop(greek=1)
         else:
             xmllib.XMLParser.handle_entityref(self,name)
 
--- a/reportlab/test/test_platypus_paragraphs.py	Mon May 08 15:04:15 2006 +0000
+++ b/reportlab/test/test_platypus_paragraphs.py	Wed May 10 12:56:39 2006 +0000
@@ -131,8 +131,10 @@
 see how the AdSu one might be done generically, but the O'Reilly, unsure...
 I guess I'm hoping that I've missed something, and that
 it's actually easy to do using platypus.We can do greek letters <greek>mDngG</greek>. This should be a
-u with a dieresis on top "<unichar code=0xfc/>" and this "&#xfc;". On the other hand this
-should be a pound sign "&pound;" &alpha;.
+u with a dieresis on top &lt;unichar code=0xfc/&gt;="<unichar code=0xfc/>" and this &amp;#xfc;="&#xfc;" and this \\xc3\\xbc="\xc3\xbc". On the other hand this
+should be a pound sign &amp;pound;="&pound;" and this an alpha &amp;alpha;="&alpha;". You can have links in the page <link href=http://www.reportlab.com color=blue>ReportLab</link>.
+Use scheme "pdf:" to indicate an external PDF link, "http:", "https:" to indicate an external link eg something to open in
+your browser. If an internal link begins with something that looks like a scheme, precede with "document:".
 '''
         from reportlab.platypus.flowables import ImageAndFlowables, Image
         from reportlab.lib.utils import _RL_DIR