Henning von Bargen's caseSensitive flag
authorrgbecker
Sun, 01 Jun 2003 09:38:16 +0000
changeset 1940 baa0abc136c4
parent 1939 1f6f0eda3214
child 1941 4126611958c0
Henning von Bargen's caseSensitive flag
reportlab/platypus/paragraph.py
reportlab/platypus/paraparser.py
reportlab/platypus/xpreformatted.py
reportlab/test/test_paragraphs.py
--- a/reportlab/platypus/paragraph.py	Fri May 30 09:58:45 2003 +0000
+++ b/reportlab/platypus/paragraph.py	Sun Jun 01 09:38:16 2003 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/paragraph.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/paragraph.py,v 1.65 2003/04/22 12:32:23 rgbecker Exp $
-__version__=''' $Id: paragraph.py,v 1.65 2003/04/22 12:32:23 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/platypus/paragraph.py,v 1.66 2003/06/01 09:38:16 rgbecker Exp $
+__version__=''' $Id: paragraph.py,v 1.66 2003/06/01 09:38:16 rgbecker Exp $ '''
 from string import split, strip, join, whitespace, find
 from operator import truth
 from types import StringType, ListType
@@ -351,10 +351,11 @@
     tx.XtraState.underline=0
 
 class Paragraph(Flowable):
-    """ Paragraph(text, style, bulletText=None)
+    """ Paragraph(text, style, bulletText=None, caseSensitive=1)
         text a string of stuff to go into the paragraph.
         style is a style definition as in reportlab.lib.styles.
         bulletText is an optional bullet defintion.
+        caseSensitive set this to 0 if you want the markup tags and their attributes to be case-insensitive.
 
         This class is a flowable that can format a block of text
         into a paragraph with a given style.
@@ -372,7 +373,8 @@
 
         It will also be able to handle any MathML specified Greek characters.
     """
-    def __init__(self, text, style, bulletText = None, frags=None):
+    def __init__(self, text, style, bulletText = None, frags=None, caseSensitive=1):
+        self.caseSensitive = caseSensitive 
         self._setup(text, style, bulletText, frags, cleanBlockQuotedText)
 
 
@@ -395,6 +397,7 @@
     def _setup(self, text, style, bulletText, frags, cleaner):
         if frags is None:
             text = cleaner(text)
+            _parser.caseSensitive = self.caseSensitive
             style, frags, bulletTextFrags = _parser.parse(text,style)
             if frags is None:
                 raise "xml parser error (%s) in paragraph beginning\n'%s'"\
@@ -913,3 +916,14 @@
         dumpParagraphFrags(P)
         w,h = P.wrap(6*72, 9.7*72)
         dumpParagraphLines(P)
+
+    if flagged(6):
+        for text in ['''Here comes <FONT FACE="Helvetica" SIZE="14pt">Helvetica 14</FONT> with <STRONG>strong</STRONG> <EM>emphasis</EM>.''',
+                     '''Here comes <font face="Helvetica" size="14pt">Helvetica 14</font> with <Strong>strong</Strong> <em>emphasis</em>.''',
+                     '''Here comes <font face="Courier" size="3cm">Courier 3cm</font> and normal again.''',
+                     ]:
+            P=Paragraph(text, styleSheet['Normal'], caseSensitive=0)
+            dumpParagraphFrags(P)
+            w,h = P.wrap(6*72, 9.7*72)
+            dumpParagraphLines(P)
+        
--- a/reportlab/platypus/paraparser.py	Fri May 30 09:58:45 2003 +0000
+++ b/reportlab/platypus/paraparser.py	Sun Jun 01 09:38:16 2003 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/paraparser.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/paraparser.py,v 1.50 2003/05/26 12:22:54 rgbecker Exp $
-__version__=''' $Id: paraparser.py,v 1.50 2003/05/26 12:22:54 rgbecker Exp $ '''
+#$Header: /tmp/reportlab/reportlab/platypus/paraparser.py,v 1.51 2003/06/01 09:38:16 rgbecker Exp $
+__version__=''' $Id: paraparser.py,v 1.51 2003/06/01 09:38:16 rgbecker Exp $ '''
 import string
 import re
 from types import TupleType
@@ -26,23 +26,46 @@
 from reportlab.lib.colors import toColor, white, black, red, Color
 from reportlab.lib.fonts import tt2ps, ps2tt
 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
+from reportlab.lib.units import inch,mm,cm,pica
 _re_para = re.compile('^\\s*<\\s*para(\\s+|>)')
 
 sizeDelta = 2       # amount to reduce font size by for super and sub script
 subFraction = 0.5   # fraction of font size that a sub script should be lowered
 superFraction = 0.5 # fraction of font size that a super script should be raised
 
-def _num(s):
+def _num(s, unit=1):
+    """Convert a string like '10cm' to an int or float (in points).
+       The default unit is point, but optionally you can use other
+       default units like mm.
+    """
+    if s[-2:]=='cm':
+        unit=cm
+        s = s[:-2]
+    if s[-2:]=='in':
+        unit=inch
+        s = s[:-2]
+    if s[-2:]=='pt':
+        unit=1
+        s = s[:-2]
+    if s[-1:]=='i':
+        unit=inch
+        s = s[:-1]
+    if s[-2:]=='mm':
+        unit=mm
+        s = s[:-2]
+    if s[-4:]=='pica':
+        unit=pica
+        s = s[:-4]
     if s[0] in ['+','-']:
         try:
-            return ('relative',int(s))
+            return ('relative',int(s)*unit)
         except ValueError:
-            return ('relative',float(s))
+            return ('relative',float(s)*unit)
     else:
         try:
-            return int(s)
+            return int(s)*unit
         except ValueError:
-            return float(s)
+            return float(s)*unit
 
 def _align(s):
     s = string.lower(s)
@@ -71,7 +94,8 @@
                 'backcolor':('backColor',toColor),
                 'bgcolor':('backColor',toColor),
                 'bg':('backColor',toColor),
-                'fg': ('textColor',toColor)}
+                'fg': ('textColor',toColor),
+                }
 
 _bulletAttrMap = {
                 'font': ('bulletFontName', None),
@@ -80,14 +104,16 @@
                 'fontsize': ('bulletFontSize',_num),
                 'indent': ('bulletIndent',_num),
                 'color': ('bulletColor',toColor),
-                'fg': ('bulletColor',toColor)}
+                'fg': ('bulletColor',toColor),
+                }
 
 #things which are valid font attributes
 _fontAttrMap = {'size': ('fontSize', _num),
                 'face': ('fontName', None),
                 'name': ('fontName', None),
                 'fg':   ('textColor', toColor),
-                'color':('textColor', toColor)}
+                'color':('textColor', toColor),
+                }
 
 def _addAttributeNames(m):
     K = m.keys()
@@ -112,7 +138,7 @@
         setattr(obj,k,v)
 
 #Named character entities intended to be supported from the special font
-#with additions suggested by Christoph Zwerschke who alos suggested the 
+#with additions suggested by Christoph Zwerschke who also suggested the 
 #numeric entity names that follow.
 greeks = {
     'Alpha': 'A',
@@ -416,6 +442,15 @@
     # for that data will be aparent by the current settings.
     #----------------------------------------------------------
 
+    def __getattr__( self, attrName ):
+        """This way we can handle <TAG> the same way as <tag> (ignoring case)."""
+        if attrName != attrName.lower() and attrName!="caseSensitive" and not self.caseSensitive:
+            if attrName[:6]=="start_":
+                return eval ("self."+attrName.lower())
+            if attrName[:4]=="end_":
+                return eval ("self."+attrName.lower())
+        raise AttributeError, attrName
+
     #### bold
     def start_b( self, attributes ):
         self._push(bold=1)
@@ -423,6 +458,12 @@
     def end_b( self ):
         self._pop(bold=1)
 
+    def start_strong( self, attributes ):
+        self._push(bold=1)
+
+    def end_strong( self ):
+        self._pop(bold=1)
+
     #### italics
     def start_i( self, attributes ):
         self._push(italic=1)
@@ -430,6 +471,12 @@
     def end_i( self ):
         self._pop(italic=1)
 
+    def start_em( self, attributes ):
+        self._push(italic=1)
+
+    def end_em( self ):
+        self._pop(italic=1)
+
     #### underline
     def start_u( self, attributes ):
         self._push(underline=1)
@@ -636,7 +683,8 @@
     def getAttributes(self,attr,attrMap):
         A = {}
         for k, v in attr.items():
-            k = string.lower(k)
+            if not self.caseSensitive:
+                k = string.lower(k)
             if k in attrMap.keys():
                 j = attrMap[k]
                 func = j[1]
@@ -651,20 +699,23 @@
     #----------------------------------------------------------------
 
     def __init__(self,verbose=0):
+        self.caseSensitive = 1
         if _xmllib_newStyle:
             xmllib.XMLParser.__init__(self,verbose=verbose)
         else:
             xmllib.XMLParser.__init__(self)
             # set up handlers for various tags
-            self.elements = {   'b': (self.start_b, self.end_b),
-                            'u': (self.start_u, self.end_u),
-                            'i': (self.start_i, self.end_i),
-                            'super': (self.start_super, self.end_super),
-                            'sup': (self.start_super, self.end_super),
-                            'sub': (self.start_sub, self.end_sub),
-                            'font': (self.start_font, self.end_font),
-                            'greek': (self.start_greek, self.end_greek),
-                            'para': (self.start_para, self.end_para)
+            self.elements = {'b': (self.start_b, self.end_b),
+                             'strong':  (self.start_b, self.end_b),
+                             'u': (self.start_u, self.end_u),
+                             'i': (self.start_i, self.end_i),
+                             'em': (self.start_i, self.end_i),
+                             'super': (self.start_super, self.end_super),
+                             'sup': (self.start_super, self.end_super),
+                             'sub': (self.start_sub, self.end_sub),
+                             'font': (self.start_font, self.end_font),
+                             'greek': (self.start_greek, self.end_greek),
+                             'para': (self.start_para, self.end_para),
                             }
 
 
@@ -883,3 +934,8 @@
 them when the man struck up with his tune.]''')
     check_text('''<onDraw name="myFunc" label="aaa   bbb">A paragraph''')
     check_text('''<para><onDraw name="myFunc" label="aaa   bbb">B paragraph</para>''')
+    # HVB, 30.05.2003: Test for new features
+    _parser.caseSensitive=0
+    check_text('''Here comes <FONT FACE="Helvetica" SIZE="14pt">Helvetica 14</FONT> with <STRONG>strong</STRONG> <EM>emphasis</EM>.''')
+    check_text('''Here comes <font face="Helvetica" size="14pt">Helvetica 14</font> with <Strong>strong</Strong> <em>emphasis</em>.''')
+    check_text('''Here comes <font face="Courier" size="3cm">Courier 3cm</font> and normal again.''')
--- a/reportlab/platypus/xpreformatted.py	Fri May 30 09:58:45 2003 +0000
+++ b/reportlab/platypus/xpreformatted.py	Sun Jun 01 09:38:16 2003 +0000
@@ -1,8 +1,8 @@
 #copyright ReportLab Inc. 2000
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/xpreformatted.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/platypus/xpreformatted.py,v 1.16 2002/07/24 19:56:38 andy_robinson Exp $
-__version__=''' $Id: xpreformatted.py,v 1.16 2002/07/24 19:56:38 andy_robinson Exp $ '''
+#$Header: /tmp/reportlab/reportlab/platypus/xpreformatted.py,v 1.17 2003/06/01 09:38:16 rgbecker Exp $
+__version__=''' $Id: xpreformatted.py,v 1.17 2003/06/01 09:38:16 rgbecker Exp $ '''
 
 import string
 from types import StringType, ListType
@@ -75,7 +75,8 @@
 
 
 class XPreformatted(Paragraph):
-    def __init__(self, text, style, bulletText = None, dedent=0, frags=None):
+    def __init__(self, text, style, bulletText = None, dedent=0, frags=None, caseSensitive=1):
+        self.caseSensitive = caseSensitive
         cleaner = lambda text, dedent=dedent: string.join(_dedenter(text,dedent),'\n')
         self._setup(text, style, bulletText, frags, cleaner)
 
@@ -313,4 +314,4 @@
             self.foo = 'bar'
 """,0, styleSheet['Code'], 456.0, 4.8, 1),
 ]:
-        if active: try_it(text,style,dedent,aW,aH)
\ No newline at end of file
+        if active: try_it(text,style,dedent,aW,aH)
--- a/reportlab/test/test_paragraphs.py	Fri May 30 09:58:45 2003 +0000
+++ b/reportlab/test/test_paragraphs.py	Sun Jun 01 09:38:16 2003 +0000
@@ -1,7 +1,7 @@
 #copyright ReportLab Inc. 2000-2001
 #see license.txt for license details
 #history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/test/test_paragraphs.py?cvsroot=reportlab
-#$Header: /tmp/reportlab/reportlab/test/test_paragraphs.py,v 1.15 2003/04/22 12:29:19 rgbecker Exp $
+#$Header: /tmp/reportlab/reportlab/test/test_paragraphs.py,v 1.16 2003/06/01 09:37:45 rgbecker Exp $
 # tests some paragraph styles
 
 from reportlab.test import unittest
@@ -120,6 +120,11 @@
         #story.append(Paragraph("""This has a font change to <font name=Helvetica-Oblique>Helvetica-Oblique</font>.""", styNormal))
         story.append(Paragraph("""This has a font change to <font name=Helvetica><i>Helvetica in italics</i></font>.""", styNormal))
 
+        story.append(Paragraph('''This one uses upper case tags and has set caseSensitive=0: Here comes <FONT FACE="Helvetica" SIZE="14pt">Helvetica 14</FONT> with <STRONG>strong</STRONG> <EM>emphasis</EM>.''', styNormal, caseSensitive=0))
+        story.append(Paragraph('''The same as before, but has set not set caseSensitive, thus the tags are ignored: Here comes <FONT FACE="Helvetica" SIZE="14pt">Helvetica 14</FONT> with <STRONG>strong</STRONG> <EM>emphasis</EM>.''', styNormal))
+        story.append(Paragraph('''This one uses fonts with size "14pt" and also uses the em and strong tags: Here comes <font face="Helvetica" size="14pt">Helvetica 14</font> with <Strong>strong</Strong> <em>emphasis</em>.''', styNormal, caseSensitive=0))
+        story.append(Paragraph('''This uses a font size of 3cm: Here comes <font face="Courier" size="3cm">Courier 3cm</font> and normal again.''', styNormal, caseSensitive=0))
+        story.append(Paragraph('''This is just a very long silly text to see if the <FONT face="Courier">caseSensitive</FONT> flag also works if the paragraph is <EM>very</EM> long. '''*20, styNormal, caseSensitive=0))
 
         template = SimpleDocTemplate('test_paragraphs.pdf',
                                      showBoundary=1)