[Checkins] SVN: z3c.rml/trunk/src/z3c/rml/ * Implemented new "link" directive that can put a link around any set of

Stephan Richter srichter at cosmos.phy.tufts.edu
Sun Apr 15 18:04:25 EDT 2007


Log message for revision 74160:
  * Implemented new "link" directive that can put a link around any set of 
    flowables. The link can either be to an internal bookmark/destination or 
    valid URL. This is a feature that is not even available in plain 
    ReportLab.
  
  * Vastly improve usefulness of error reporting. All errors relating to 
    directives and attribute validation now include the filename and line 
    number.
  
  * Do not throw warnings into the logger, when a comment is encountered.
  
  * Make sure that examples that have lines longer than 80 cols are line 
    wrapped. The line-wrapped code formats nicely within the example.
  
  * Provide custom format for the combination attribute type.
  
  * Recursively remove all doc: prefixed attributes from example code.
  
  * Make all sub-directives a link to the declaration.
  
  * Added tests for a bunch of tags.
  
  * Linked many tests as examples into the reference documentation.
  
  * Added documentation to several underdocumented directives.
  
  * Fix blockTableStyle sub-directives to have correct stop attribute:
    end -> stop
  
  * Fixed attribute name in imageAndFlowables.
  
  * Fixed fitType to work when used.
  
  

Changed:
  U   z3c.rml/trunk/src/z3c/rml/attr.py
  U   z3c.rml/trunk/src/z3c/rml/canvas.py
  U   z3c.rml/trunk/src/z3c/rml/chart.py
  U   z3c.rml/trunk/src/z3c/rml/directive.py
  U   z3c.rml/trunk/src/z3c/rml/document.py
  U   z3c.rml/trunk/src/z3c/rml/flowable.py
  U   z3c.rml/trunk/src/z3c/rml/form.py
  U   z3c.rml/trunk/src/z3c/rml/pagetemplate.py
  U   z3c.rml/trunk/src/z3c/rml/platypus.py
  U   z3c.rml/trunk/src/z3c/rml/rml-reference.pt
  U   z3c.rml/trunk/src/z3c/rml/rml-reference.py
  U   z3c.rml/trunk/src/z3c/rml/rml2pdf.py
  U   z3c.rml/trunk/src/z3c/rml/stylesheet.py
  A   z3c.rml/trunk/src/z3c/rml/tests/input/tag-alias.rml
  U   z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart.rml
  U   z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart3d.rml
  U   z3c.rml/trunk/src/z3c/rml/tests/input/tag-barCodeFlowable.rml
  U   z3c.rml/trunk/src/z3c/rml/tests/input/tag-barcode.rml
  U   z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-1.rml
  A   z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-bulkData.rml
  A   z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTableStyle.rml
  A   z3c.rml/trunk/src/z3c/rml/tests/input/tag-bookmark.rml

-=-
Modified: z3c.rml/trunk/src/z3c/rml/attr.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/attr.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/attr.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -32,6 +32,14 @@
 
 MISSING = object()
 
+def getFileInfo(attr):
+    root = attr.context
+    while root.parent:
+        root = root.parent
+    return '(file %s, line %i)' % (
+        root.filename, attr.context.element.sourceline)
+
+
 def getManager(context, interface=None):
     if interface is None:
         # Avoid circular imports
@@ -76,7 +84,8 @@
         if value in self.choices:
             return self.choices[value]
         raise ValueError(
-            '%r not a valid value for attribute "%s"' % (value, self.__name__))
+            '%r not a valid value for attribute "%s". %s' % (
+            value, self.__name__, getFileInfo(self)))
 
 
 class Combination(RMLAttribute):
@@ -93,7 +102,8 @@
                 return bound.fromUnicode(value)
             except ValueError:
                 pass
-        raise ValueError(value)
+        raise ValueError(
+            '"%s" is not a valid value. %s' %(value, getFileInfo(self)))
 
 
 class String(RMLAttribute, zope.schema.Bytes):
@@ -150,8 +160,8 @@
         if ((self.min_length is not None and len(result) < self.min_length) and
             (self.max_length is not None and len(result) > self.max_length)):
             raise ValueError(
-                'Length of sequence must be at least %s and at most %i' % (
-                self.min_length, self.max_length))
+                'Length of sequence must be at least %s and at most %i. %s' % (
+                self.min_length, self.max_length, getFileInfo(self)))
         return result
 
 
@@ -215,7 +225,9 @@
             res = unit[0].search(value, 0)
             if res:
                 return unit[1]*float(res.group(1))
-        raise ValueError('The value %r is not a valid measurement.' %value)
+        raise ValueError(
+            'The value %r is not a valid measurement. %s' % (
+            value, getFileInfo(self)))
 
 
 class File(Text):
@@ -240,7 +252,8 @@
             result = self.packageExtract.match(value)
             if result is None:
                 raise ValueError(
-                    'The package-path-pair you specified was incorrect')
+                    'The package-path-pair you specified was incorrect. %s' %(
+                    getFileInfo(self)))
             modulepath, path = result.groups()
             module = __import__(modulepath, {}, {}, (modulepath))
             value = os.path.join(os.path.dirname(module.__file__), path)
@@ -288,9 +301,14 @@
         manager = getManager(self.context)
         if value in manager.colors:
             return manager.colors[value]
-        return reportlab.lib.colors.toColor(value)
+        try:
+            return reportlab.lib.colors.toColor(value)
+        # Bare except, since code raises string exception: Invalid color value
+        except:
+            raise ValueError(
+                'The color specification "%s" is not valid. %s' % (
+                value, getFileInfo(self)))
 
-
 class Style(String):
     """Requires a valid style to be entered.
 
@@ -309,7 +327,8 @@
                 return styles['style.' + value]
             elif value.startswith('style.') and value[6:] in styles:
                 return styles[value[6:]]
-        raise ValueError('Style %r could not be found.' %value)
+        raise ValueError('Style %r could not be found. %s' % (
+            value, getFileInfo(self)))
 
 
 class Symbol(Text):
@@ -394,7 +413,8 @@
         result = super(TextNodeGrid, self).fromUnicode(ustr)
         if len(result) % self.columns != 0:
             raise ValueError(
-                'Number of elements must be divisible by %i.' %self.columns)
+                'Number of elements must be divisible by %i. %s' %(
+                self.columns, getFileInfo(self)))
         return [result[i*self.columns:(i+1)*self.columns]
                 for i in range(len(result)/self.columns)]
 

Modified: z3c.rml/trunk/src/z3c/rml/canvas.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/canvas.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/canvas.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -573,7 +573,7 @@
 
 
 class IScale(interfaces.IRMLDirectiveSignature):
-    """Scale the drawing using x and y sclaing factors."""
+    """Scale the drawing using x and y scaling factors."""
 
     sx = attr.Float(
         title=u'X-Scaling-Factor',

Modified: z3c.rml/trunk/src/z3c/rml/chart.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/chart.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/chart.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -998,44 +998,70 @@
     # Drawing Options
 
     dx = attr.Measurement(
+        title=u'Drawing X-Position',
+        description=u'The x-position of the entire drawing on the canvas.',
         required=False)
 
     dy = attr.Measurement(
+        title=u'Drawing Y-Position',
+        description=u'The y-position of the entire drawing on the canvas.',
         required=False)
 
     dwidth = attr.Measurement(
+        title=u'Drawing Width',
+        description=u'The width of the entire drawing',
         required=False)
 
     dheight = attr.Measurement(
+        title=u'Drawing Height',
+        description=u'The height of the entire drawing',
         required=False)
 
     angle = attr.Float(
+        title=u'Angle',
+        description=u'The orientation of the drawing as an angle in degrees.',
         required=False)
 
     # Plot Area Options
 
     x = attr.Measurement(
+        title=u'Chart X-Position',
+        description=u'The x-position of the chart within the drawing.',
         required=False)
 
     y = attr.Measurement(
+        title=u'Chart Y-Position',
+        description=u'The y-position of the chart within the drawing.',
         required=False)
 
     width = attr.Measurement(
+        title=u'Chart Width',
+        description=u'The width of the chart.',
         required=False)
 
     height = attr.Measurement(
+        title=u'Chart Height',
+        description=u'The height of the chart.',
         required=False)
 
     strokeColor = attr.Color(
+        title=u'Stroke Color',
+        description=u'Color of the chart border.',
         required=False)
 
     strokeWidth = attr.Measurement(
+        title=u'Stroke Width',
+        description=u'Width of the chart border.',
         required=False)
 
     fillColor = attr.Color(
+        title=u'Fill Color',
+        description=u'Color of the chart interior.',
         required=False)
 
     debug = attr.Boolean(
+        title=u'Debugging',
+        description=u'A flag that when set to True turns on debug messages.',
         required=False)
 
 class Chart(directive.RMLDirective):
@@ -1043,12 +1069,13 @@
     factories = {
         'texts': Texts
         }
+    attrMapping = {}
 
     def createChart(self, attributes):
         raise NotImplementedError
 
     def process(self):
-        attrs = dict(self.getAttributeValues())
+        attrs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
         angle = attrs.pop('angle', 0)
         x, y = attrs.pop('dx'), attrs.pop('dy')
         self.drawing = shapes.Drawing(attrs.pop('dwidth'), attrs.pop('dheight'))
@@ -1063,30 +1090,43 @@
 
 
 class IBarChart(IChart):
+    """Creates a two-dimensional bar chart."""
     occurence.containing(
         occurence.One('data', IData1D),
         occurence.ZeroOrOne('bars', IBars),
+        occurence.ZeroOrOne('categoryAxis', ICategoryAxis),
+        occurence.ZeroOrOne('valueAxis', IValueAxis),
         *IChart.queryTaggedValue('directives', ())
         )
 
     direction = attr.Choice(
+        title=u'Direction',
+        description=u'The direction of the bars within the chart.',
         choices=('horizontal', 'vertical'),
         default='horizontal',
         required=False)
 
     useAbsolute = attr.Boolean(
+        title=u'Use Absolute Spacing',
+        description=u'Flag to use absolute spacing values.',
         default=False,
         required=False)
 
     barWidth = attr.Measurement(
+        title=u'Bar Width',
+        description=u'The width of an individual bar.',
         default=10,
         required=False)
 
     groupSpacing = attr.Measurement(
+        title=u'Group Spacing',
+        description=u'Width between groups of bars.',
         default=5,
         required=False)
 
     barSpacing = attr.Measurement(
+        title=u'Bar Spacing',
+        description=u'Width between individual bars.',
         default=0,
         required=False)
 
@@ -1117,22 +1157,35 @@
 
 
 class IBarChart3D(IBarChart):
+    """Creates a three-dimensional bar chart."""
+    occurence.containing(
+        *IBarChart.queryTaggedValue('directives', ())
+        )
 
-    theta_x = attr.Float(
+    thetaX = attr.Float(
+        title=u'Theta-X',
+        description=u'Fraction of dx/dz.',
         required=False)
 
-    theta_y = attr.Float(
+    thetaY = attr.Float(
+        title=u'Theta-Y',
+        description=u'Fraction of dy/dz.',
         required=False)
 
     zDepth = attr.Measurement(
+        title=u'Z-Depth',
+        description=u'Depth of an individual series/bar.',
         required=False)
 
     zSpace = attr.Measurement(
+        title=u'Z-Space',
+        description=u'Z-Gap around a series/bar.',
         required=False)
 
 class BarChart3D(BarChart):
     signature = IBarChart3D
     nameBase = 'BarChart3D'
+    attrMapping = {'thetaX': 'theta_x', 'thetaY': 'theta_y'}
 
 
 class ILinePlot(IChart):

Modified: z3c.rml/trunk/src/z3c/rml/directive.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/directive.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/directive.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -20,11 +20,18 @@
 import zope.interface
 import zope.schema
 
+from lxml import etree
 from z3c.rml import interfaces
 
 logger = logging.getLogger("z3c.rml")
 
 
+def getFileInfo(directive):
+    root = directive
+    while root.parent:
+        root = root.parent
+    return '(file %s, line %i)' %(root.filename, directive.element.sourceline)
+
 class RMLDirective(object):
     zope.interface.implements(interfaces.IRMLDirective)
     signature = None
@@ -48,7 +55,9 @@
                 # error
                 if attr.required and value is attr.missing_value:
                     raise ValueError(
-                        'No value for required attribute %s' %name)
+                        'No value for required attribute "%s" '
+                        'in directive "%s" %s.' % (
+                        name, self.element.tag, getFileInfo(self)))
                 # Only add the entry if the value is not the missing value or
                 # missing values are requested to be included.
                 if value is not attr.missing_value or includeMissing:
@@ -74,6 +83,9 @@
     def processSubDirectives(self, select=None, ignore=None):
         # Go through all children of the directive and try to process them.
         for element in self.element.getchildren():
+            # Ignore all comments
+            if isinstance(element, etree._Comment):
+                continue
             if select is not None and element.tag not in select:
                 continue
             if ignore is not None and element.tag in ignore:
@@ -85,7 +97,7 @@
             else:
                 # Record any tags/elements that could not be processed.
                 logger.warn("Directive %r could not be processed and was "
-                            "ignored." %element.tag)
+                            "ignored. %s" %(element.tag, getFileInfo(self)))
 
     def process(self):
         self.processSubDirectives()

Modified: z3c.rml/trunk/src/z3c/rml/document.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/document.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/document.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -216,6 +216,7 @@
         self.styles = {}
         self.colors = {}
         self.postProcessors = []
+        self.filename = '<unknwon>'
 
     def process(self, outputFile=None):
         """Process document"""

Modified: z3c.rml/trunk/src/z3c/rml/flowable.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/flowable.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/flowable.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -534,7 +534,7 @@
 
 
 class ITableBulkData(interfaces.IRMLDirectiveSignature):
-    """Bulk Data allows one to wuickly create a table."""
+    """Bulk Data allows one to quickly create a table."""
 
     content = attr.TextNodeSequence(
         title=u'Content',
@@ -784,7 +784,7 @@
         description=u'The padding on the bottom of the image.',
         required=False)
 
-    iamgeSide = attr.Choice(
+    imageSide = attr.Choice(
         title=u'Image Side',
         description=u'The side at which the image will be placed.',
         choices=('left', 'right'),
@@ -950,9 +950,53 @@
 class Bookmark(Flowable):
     signature = IBookmark
     klass = platypus.BookmarkPage
-    attrMapping = {'name': 'key'}
+    attrMapping = {'name': 'key', 'fitType': 'fit'}
 
 
+class ILink(interfaces.IRMLDirectiveSignature):
+    """Place an internal link around a set of flowables."""
+
+    destination = attr.Text(
+        title=u'Destination',
+        description=u'The name of the destination to link to.',
+        required=False)
+
+    url = attr.Text(
+        title=u'URL',
+        description=u'The URL to link to.',
+        required=False)
+
+    boxStrokeWidth = attr.Measurement(
+        title=u'Box Stroke Width',
+        description=u'The width of the box border line.',
+        required=False)
+
+    boxStrokeDashArray = attr.Sequence(
+        title=u'Box Stroke Dash Array',
+        description=u'The dash array of the box border line.',
+        value_type=attr.Float(),
+        required=False)
+
+    boxStrokeColor = attr.Color(
+        title=u'Box Stroke Color',
+        description=(u'The color in which the box border is drawn.'),
+        required=False)
+
+
+class Link(Flowable):
+    signature = ILink
+    attrMapping = {'destination': 'destinationname',
+                   'boxStrokeWidth': 'thickness',
+                   'boxStrokeDashArray': 'dashArray',
+                   'boxStrokeColor': 'color'}
+
+    def process(self):
+        flow = Flow(self.element, self.parent)
+        flow.process()
+        args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
+        self.parent.flow.append(platypus.Link(flow.flow, **args))
+
+
 class IHorizontalRow(interfaces.IRMLDirectiveSignature):
     """Create a horizontal line on the page."""
 
@@ -1070,6 +1114,7 @@
         occurence.ZeroOrMore('indent', IIndent),
         occurence.ZeroOrMore('fixedSize', IFixedSize),
         occurence.ZeroOrMore('bookmark', IBookmark),
+        occurence.ZeroOrMore('link', ILink),
         occurence.ZeroOrMore('hr', IHorizontalRow),
         occurence.ZeroOrMore('name', special.IName),
         )
@@ -1105,6 +1150,7 @@
         'indent': Indent,
         'fixedSize': FixedSize,
         'bookmark': Bookmark,
+        'link': Link,
         'hr': HorizontalRow,
         # Special Elements
         'name': special.Name,

Modified: z3c.rml/trunk/src/z3c/rml/form.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/form.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/form.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -152,13 +152,13 @@
         required=False)
 
     # I2of5, Code128, Standard93, FIM, POSTNET, Ean13
-    frontName = attr.String(
+    fontName = attr.String(
         title=u'Font Name',
         description=(u'The font used to print the value.'),
         required=False)
 
     # I2of5, Code128, Standard93, FIM, POSTNET, Ean13
-    frontSize = attr.Measurement(
+    fontSize = attr.Measurement(
         title=u'Font Size',
         description=(u'The size of the value text.'),
         required=False)

Modified: z3c.rml/trunk/src/z3c/rml/pagetemplate.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/pagetemplate.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/pagetemplate.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -43,10 +43,5 @@
     def __call__(self, *args, **kwargs):
         rml = super(RMLPageTemplateFile, self).__call__(*args, **kwargs)
 
-        # RML is a unicode string, but oftentimes documents declare their
-        # encoding using <?xml ...>. Unfortuantely, I cannot tell lxml to
-        # ignore that directive. Thus we remove it.
-        if rml.startswith('<?xml'):
-            rml = rml.split('\n', 1)[-1]
-
-        return rml2pdf.parseString(rml).getvalue()
+        return rml2pdf.parseString(
+            rml, filename=self.pt_source_file()).getvalue()

Modified: z3c.rml/trunk/src/z3c/rml/platypus.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/platypus.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/platypus.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -17,6 +17,7 @@
 """
 __docformat__ = "reStructuredText"
 import reportlab.platypus.flowables
+import reportlab.rl_config
 import zope.interface
 
 from z3c.rml import interfaces
@@ -83,3 +84,49 @@
             self.kw['key'] = str(hash(self))
         self.canv.bookmarkPage(self.kw['key'])
         self.canv.addOutlineEntry(**self.kw)
+
+
+class Link(reportlab.platypus.flowables._Container,
+           reportlab.platypus.flowables.Flowable):
+
+    def __init__(self, content, **args):
+        self._content = content
+        self.args = args
+
+    def wrap(self, availWidth, availHeight):
+        self.width, self.height = reportlab.platypus.flowables._listWrapOn(
+            self._content, availWidth, self.canv)
+        return self.width, self.height
+
+    def drawOn(self, canv, x, y, _sW=0, scale=1.0, content=None, aW=None):
+        '''we simulate being added to a frame'''
+        pS = 0
+        if aW is None: aW = self.width
+        aW = scale*(aW+_sW)
+        if content is None:
+            content = self._content
+        y += self.height*scale
+
+        startX = x
+        startY = y
+        totalWidth = 0
+        totalHeight = 0
+
+        for c in content:
+            w, h = c.wrapOn(canv,aW,0xfffffff)
+            if w < reportlab.rl_config._FUZZ or h < reportlab.rl_config._FUZZ:
+                continue
+            if c is not content[0]: h += max(c.getSpaceBefore()-pS,0)
+            y -= h
+            c.drawOn(canv,x,y,_sW=aW-w)
+            if c is not content[-1]:
+                pS = c.getSpaceAfter()
+                y -= pS
+            totalWidth += w
+            totalHeight += h
+        rectangle = [startX, startY-totalHeight,
+                startX+totalWidth, startY]
+        if 'url' in self.args:
+            canv.linkURL(rect=rectangle, **self.args)
+        else:
+            canv.linkAbsolute('', Rect=rectangle, **self.args)

Modified: z3c.rml/trunk/src/z3c/rml/rml-reference.pt
===================================================================
--- z3c.rml/trunk/src/z3c/rml/rml-reference.pt	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/rml-reference.pt	2007-04-15 22:04:24 UTC (rev 74160)
@@ -72,6 +72,7 @@
         fontName="Times-Roman"
         fontSize="10"
         leftIndent="0.5cm"
+        spaceAfter="5"
         />
     <paraStyle
         name="code"
@@ -164,6 +165,7 @@
       <outlineAdd level="1" tal:content="directive/name">
         Element Name
       </outlineAdd>
+      <bookmark tal:attributes="name directive/id"/>
       <para style="content" tal:content="directive/description">
         What is this element doing?
       </para>
@@ -211,13 +213,18 @@
         <para style="element-subtitle">
           <i>Sub-Directives</i>
         </para>
-        <para style="sub-directive"
-              tal:repeat="directive directive/sub-directives">
-          <b tal:content="directive/name">para</b>
-          <i>
-            (<tal:block replace="directive/occurence">ZeroOrMore</tal:block>)
-          </i>
-        </para>
+        <link destination=""
+              tal:repeat="directive directive/sub-directives"
+              tal:attributes="destination directive/id">
+          <para style="sub-directive">
+            <font color="blue">
+              <b tal:content="directive/name">para</b>
+            </font>
+            <i>
+              (<tal:block replace="directive/occurence">ZeroOrMore</tal:block>)
+            </i>
+          </para>
+        </link>
       </tal:block>
 
       <tal:block condition="directive/examples">

Modified: z3c.rml/trunk/src/z3c/rml/rml-reference.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/rml-reference.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/rml-reference.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -41,6 +41,8 @@
      6 : ('<font textColor="blue">', '</font>'),
     11 : ('<font textColor="red">', '</font>'),
     }
+EXAMPLE_NS = 'http://namespaces.zope.org/rml/doc'
+EXAMPLE_ATTR_NAME = '{%s}example' %EXAMPLE_NS
 
 
 def dedent(rml):
@@ -51,6 +53,26 @@
     return rml.replace('\n'+' '*least, '\n')
 
 
+def enforceColumns(rml, columns=80):
+    result = []
+    for line in rml.split('\n'):
+        if len(line) <= columns:
+            result.append(line)
+            continue
+        # Determine the indentation for all other lines
+        lineStart = re.findall('^( *<[a-zA-Z0-9]+ )', line)
+        lineIndent = 0
+        if lineStart:
+            lineIndent = len(lineStart[0])
+        # Create lines having at most the specified number of columns
+        while len(line) > columns:
+            end = line[:columns].rfind(' ')
+            result.append(line[:end])
+            line = ' '*lineIndent + line[end+1:]
+        result.append(line)
+
+    return '\n'.join(result)
+
 def highlightRML(rml):
     if SilverCity is None:
         return rml
@@ -62,6 +84,14 @@
     return styledRml
 
 
+def removeDocAttributes(elem):
+    for name in elem.attrib.keys():
+        if name.startswith('{'+EXAMPLE_NS+'}'):
+            del elem.attrib[name]
+    for child in elem.getchildren():
+        removeDocAttributes(child)
+
+
 def getAttributeTypes():
     types = []
     candidates = sorted(attr.__dict__.items(), key=lambda e: e[0])
@@ -93,9 +123,15 @@
     return '%s with %i cols of %s' %(
         field.__class__.__name__, field.columns, vtFormatter(field.value_type))
 
+def formatCombination(field):
+    vts = [typeFormatters.get(vt.__class__, formatField)(vt)
+           for vt in field.value_types]
+    return '%s of %s' %(field.__class__.__name__, ', '.join(vts))
+
 typeFormatters = {
     attr.Choice: formatChoice,
     attr.Sequence: formatSequence,
+    attr.Combination: formatCombination,
     attr.TextNodeSequence: formatSequence,
     attr.TextNodeGrid: formatGrid}
 
@@ -104,7 +140,8 @@
         directives = {}
     # Process this directive
     if signature not in directives:
-        info = {'name': name, 'description': signature.getDoc()}
+        info = {'name': name, 'description': signature.getDoc(),
+                'id': str(hash(signature))}
         attrs = []
         content = None
         for fname, field in zope.schema.getFieldsInOrder(signature):
@@ -130,6 +167,7 @@
             subs.append({
                 'name': occurence.tag,
                 'occurence': occurence.__class__.__name__,
+                'id': str(hash(occurence.signature))
                 })
         info['sub-directives'] = subs
         directives[signature] = info
@@ -140,8 +178,6 @@
 
 
 def extractExamples(directory):
-    EXAMPLE_NS = 'http://namespaces.zope.org/rml/doc'
-    EXAMPLE_ATTR_NAME = '{%s}example' %EXAMPLE_NS
     examples = {}
     for filename in os.listdir(directory):
         if not filename.endswith('.rml'):
@@ -152,8 +188,11 @@
                               {'doc': EXAMPLE_NS})
         for elem in elements:
             demoTag = elem.get(EXAMPLE_ATTR_NAME) or elem.tag
-            del elem.attrib[EXAMPLE_ATTR_NAME]
-            xml = highlightRML(dedent(etree.tounicode(elem).strip()))
+            removeDocAttributes(elem)
+            xml = etree.tounicode(elem).strip()
+            xml = dedent(xml)
+            xml = enforceColumns(xml, 80)
+            xml = highlightRML(xml)
             elemExamples = examples.setdefault(demoTag, [])
             elemExamples.append(
                 {'filename': filename, 'line': elem.sourceline, 'code': xml})

Modified: z3c.rml/trunk/src/z3c/rml/rml2pdf.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/rml2pdf.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/rml2pdf.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -26,7 +26,7 @@
 zope.interface.moduleProvides(interfaces.IRML2PDF)
 
 
-def parseString(xml, removeEncodingLine=True):
+def parseString(xml, removeEncodingLine=True, filename=None):
     if isinstance(xml, unicode) and removeEncodingLine:
         # RML is a unicode string, but oftentimes documents declare their
         # encoding using <?xml ...>. Unfortuantely, I cannot tell lxml to
@@ -35,6 +35,8 @@
             xml = xml.split('\n', 1)[-1]
     root = etree.fromstring(xml)
     doc = document.Document(root)
+    if filename:
+        doc.filename = filename
     output = cStringIO.StringIO()
     doc.process(output)
     output.seek(0)
@@ -48,6 +50,7 @@
     xmlFile = open(xmlInputName, 'r')
     root = etree.parse(xmlFile).getroot()
     doc = document.Document(root)
+    doc.filename = xmlInputName
 
     outputFile = None
 

Modified: z3c.rml/trunk/src/z3c/rml/stylesheet.py
===================================================================
--- z3c.rml/trunk/src/z3c/rml/stylesheet.py	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/stylesheet.py	2007-04-15 22:04:24 UTC (rev 74160)
@@ -169,7 +169,7 @@
         max_length=2,
         required=True)
 
-    end = attr.Sequence(
+    stop = attr.Sequence(
         title=u'End Coordinates',
         description=u'The end table coordinates for the style instruction',
         value_type=attr.Combination(

Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-alias.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-alias.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-alias.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -0,0 +1,25 @@
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document
+    filename="tag-alias.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
+
+  <template>
+    <pageTemplate id="main">
+      <frame id="first" x1="72" y1="72" width="451" height="698"/>
+    </pageTemplate>
+  </template>
+
+  <stylesheet>
+    <initialize>
+      <alias id="h1" value="style.Heading1"
+             doc:example="" />
+    </initialize>
+  </stylesheet>
+
+  <story>
+
+    <title><font face="Courier">&lt;alias&gt;</font> Tag Demo</title>
+    <para style="h1">Header 1 via Alias</para>
+
+  </story>
+</document>

Modified: z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE document SYSTEM "rml.dtd">
 
-<document filename="tag-barChart.pdf">
+<document
+    filename="tag-barChart.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
 
   <stylesheet>
   </stylesheet>
@@ -16,10 +18,11 @@
     <barChart
         dx="2in" dy="7in" dwidth="6in" dheight="4in"
          x="0"    y="0"    width="5in"  height="3in"
-        barSpacing="7"
-        groupSpacing="15">
+        barSpacing="7" groupSpacing="15"
+        doc:example="">
       <bars>
-        <bar fillColor="blue" strokeColor="red" strokeWidth="0.5" />
+        <bar fillColor="blue" strokeColor="red" strokeWidth="0.5"
+             doc:example="" />
         <bar fillColor="yellow" strokeColor="green" strokeWidth="1" />
       </bars>
       <categoryAxis strokeColor="black" strokeWidth="1">

Modified: z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart3d.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart3d.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-barChart3d.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -1,11 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE document SYSTEM "rml.dtd">
 
-<document filename="tag-barChart3d.pdf">
+<document
+    filename="tag-barChart3d.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
 
-  <stylesheet>
-  </stylesheet>
-
   <pageDrawing>
 
     <setFont name="Helvetica-Bold" size="16" />
@@ -44,8 +43,9 @@
     <barChart3D
         dx="2in" dy="4in" dwidth="6in" dheight="4in"
          x="0"    y="0"    width="5in"  height="2in"
-         theta_x="0.3" theta_y="0.3" zDepth="5" zSpace="10"
-        direction="vertical">
+        thetaX="0.3" thetaY="0.3" zDepth="5" zSpace="10"
+        direction="vertical"
+        doc:example="">
       <categoryAxis strokeColor="black" strokeWidth="1"
                     visibleGrid="true">
         <labels fontName="Helvetica" />

Modified: z3c.rml/trunk/src/z3c/rml/tests/input/tag-barCodeFlowable.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-barCodeFlowable.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-barCodeFlowable.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -1,5 +1,7 @@
 <!DOCTYPE document SYSTEM "rml.dtd">
-<document filename="tag-spacer.pdf">
+<document
+    filename="tag-spacer.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
   <template>
     <pageTemplate id="main">
       <frame id="header" x1="2cm" y1="26cm" width="17cm" height="2cm"/>
@@ -21,7 +23,7 @@
     <nextFrame />
     <para>Code 128</para>
     <spacer length="5mm" />
-    <barCodeFlowable code="Code128" value="PFWZF" />
+    <barCodeFlowable code="Code128" value="PFWZF" doc:example="" />
     <spacer length="10mm" />
 
     <para>Code 128 with several options</para>
@@ -29,7 +31,8 @@
     <barCodeFlowable code="Code128" value="PFWZF" humanReadable="true"
                      fontName="Helvetica" fontSize="10"
                      barFillColor="red" barStrokeColor="red"
-                     quiet="false" barHeight="0.4in" barWidth="0.009in" />
+                     quiet="false" barHeight="0.4in" barWidth="0.009in"
+                     doc:example="" />
     <spacer length="10mm" />
 
     <para>Standard 93</para>

Modified: z3c.rml/trunk/src/z3c/rml/tests/input/tag-barcode.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-barcode.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-barcode.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -1,14 +1,17 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE document SYSTEM "rml.dtd">
 
-<document filename="tag-place.pdf">
+<document
+    filename="tag-place.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
 
-  <stylesheet>
-  </stylesheet>
-
   <pageDrawing>
 
-    <barCode x="5cm" y="25cm" code="MSI">
+    <drawCenteredString x="10.5cm" y="26cm">
+      barCode Tag Demo
+    </drawCenteredString>
+
+    <barCode x="5cm" y="24cm" code="MSI" doc:example="">
       23465092892
     </barCode>
 
@@ -16,5 +19,15 @@
       217829804
     </barCode>
 
+    <barCode
+        x="5cm" y="17cm" height="2cm" width="5cm"
+        code="Ean13"
+        humanReadable="true" fontName="Helvetica" fontSize="7"
+        barStrokeColor="blue" barFillColor="blue" textColor="blue"
+        quiet="false" barHeight="0.4in" barWidth="0.009in"
+        doc:example="">
+      123456789012
+    </barCode>
+
   </pageDrawing>
 </document>

Modified: z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-1.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-1.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-1.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -1,5 +1,7 @@
 <!DOCTYPE document SYSTEM "rml.dtd">
-<document filename="tag-pre.pdf">
+<document
+    filename="tag-pre.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
 
   <template>
     <pageTemplate id="main">
@@ -7,13 +9,12 @@
     </pageTemplate>
   </template>
 
-  <stylesheet>
-  </stylesheet>
-
   <story>
 
     <title><font face="Courier">&lt;blockTable&gt;</font> Tag Demo</title>
-    <blockTable>
+    <blockTable
+        colWidths="50% 50%" rowHeights="1cm 1cm"
+        doc:example="">
       <tr>
        <td>This</td>
        <td>is</td>

Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-bulkData.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-bulkData.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTable-bulkData.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -0,0 +1,27 @@
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document
+    filename="tag-pre.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
+
+  <template>
+    <pageTemplate id="main">
+      <frame id="first" x1="72" y1="72" width="451" height="698"/>
+    </pageTemplate>
+  </template>
+
+  <story>
+
+    <title><font face="Courier">&lt;bulkData&gt;</font> Tag Demo</title>
+    <blockTable >
+      <bulkData doc:example=""><![CDATA[
+Product,Profit
+Sprockets,26
+Widgets,34
+Thingummies,217
+Bits & Bobs,23
+Total,277
+        ]]></bulkData>
+    </blockTable>
+
+  </story>
+</document>

Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTableStyle.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTableStyle.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-blockTableStyle.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -0,0 +1,197 @@
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document
+    filename="tag-blockTableStyle.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
+
+  <template>
+    <pageTemplate id="main">
+      <frame id="first" x1="72" y1="72" width="451" height="698"/>
+    </pageTemplate>
+  </template>
+
+  <stylesheet>
+    <blockTableStyle id="table">
+      <blockAlignment
+          start="0,0" stop="-1,1" value="center"
+          doc:example="" />
+      <blockBackground start="1,1" stop="-2,-2" colorName="green"
+          doc:example="" />
+      <blockTopPadding start="0,0" stop="-1,1" length="5mm"
+          doc:example="" />
+      <blockRightPadding start="0,0" stop="-1,1" length="5mm"
+          doc:example="" />
+      <blockBottomPadding start="0,0" stop="-1,1" length="5mm"
+          doc:example="" />
+      <blockLeftPadding start="0,0" stop="-1,1" length="5mm"
+          doc:example="" />
+      <blockFont
+          start="0,0" stop="1,-1" name="Courier" size="14" leading="18"
+          doc:example="" />
+      <blockTextColor start="0,0" stop="1,-1" colorName="red"
+          doc:example="" />
+    </blockTableStyle>
+
+    <blockTableStyle id="table2">
+      <blockColBackground
+          start="0,0" stop="2,-1" colorNames="red green"
+          doc:example="" />
+      <blockRowBackground
+          start="3,0" stop="-1,-1" colorNames="blue yellow"
+          doc:example="" />
+      <blockLeading
+          start="0,0" stop="-1,1" length="18"
+          doc:example="" />
+    </blockTableStyle>
+
+    <blockTableStyle id="table3">
+      <blockSpan
+          start="0,0" stop="2,2" doc:example="" />
+      <blockAlignment
+          start="0,0" stop="2,2" value="center" />
+      <blockValign
+          start="0,0" stop="2,2" value="middle"
+          doc:example="" />
+    </blockTableStyle>
+
+    <blockTableStyle id="custom-table" doc:example="">
+      <blockFont
+          start="0,0" stop="-1,-1" name="Courier-Bold" size="10" />
+    </blockTableStyle>
+
+  </stylesheet>
+
+  <story>
+    <title><font face="Courier">&lt;blockTableStyle&gt;</font> Tag Demo</title>
+
+    <blockTable style="table">
+      <tr>
+        <td>00</td>
+        <td>01</td>
+        <td>02</td>
+        <td>03</td>
+        <td>04</td>
+      </tr>
+      <tr>
+        <td>10</td>
+        <td>11</td>
+        <td>12</td>
+        <td>13</td>
+        <td>14</td>
+      </tr>
+      <tr>
+        <td>20</td>
+        <td>21</td>
+        <td>22</td>
+        <td>23</td>
+        <td>24</td>
+      </tr>
+      <tr>
+        <td>30</td>
+        <td>31</td>
+        <td>32</td>
+        <td>33</td>
+        <td>34</td>
+      </tr>
+    </blockTable>
+
+    <spacer length="1cm" />
+
+    <blockTable style="table2">
+      <tr>
+        <td>00</td>
+        <td>01</td>
+        <td>02</td>
+        <td>03</td>
+        <td>04</td>
+      </tr>
+      <tr>
+        <td>10</td>
+        <td>11</td>
+        <td>12</td>
+        <td>13</td>
+        <td>14</td>
+      </tr>
+      <tr>
+        <td>20</td>
+        <td>21</td>
+        <td>22</td>
+        <td>23</td>
+        <td>24</td>
+      </tr>
+      <tr>
+        <td>30</td>
+        <td>31</td>
+        <td>32</td>
+        <td>33</td>
+        <td>34</td>
+      </tr>
+    </blockTable>
+
+    <spacer length="1cm" />
+
+    <blockTable style="table3">
+      <tr>
+        <td>00</td>
+        <td>01</td>
+        <td>02</td>
+        <td>03</td>
+        <td>04</td>
+      </tr>
+      <tr>
+        <td>10</td>
+        <td>11</td>
+        <td>12</td>
+        <td>13</td>
+        <td>14</td>
+      </tr>
+      <tr>
+        <td>20</td>
+        <td>21</td>
+        <td>22</td>
+        <td>23</td>
+        <td>24</td>
+      </tr>
+      <tr>
+        <td>30</td>
+        <td>31</td>
+        <td>32</td>
+        <td>33</td>
+        <td>34</td>
+      </tr>
+    </blockTable>
+
+    <spacer length="1cm" />
+
+    <blockTable style="custom-table">
+      <tr>
+        <td>00</td>
+        <td>01</td>
+        <td>02</td>
+        <td>03</td>
+        <td>04</td>
+      </tr>
+      <tr>
+        <td>10</td>
+        <td>11</td>
+        <td>12</td>
+        <td>13</td>
+        <td>14</td>
+      </tr>
+      <tr>
+        <td>20</td>
+        <td>21</td>
+        <td>22</td>
+        <td>23</td>
+        <td>24</td>
+      </tr>
+      <tr>
+        <td>30</td>
+        <td>31</td>
+        <td>32</td>
+        <td>33</td>
+        <td>34</td>
+      </tr>
+    </blockTable>
+  </story>
+
+</document>

Added: z3c.rml/trunk/src/z3c/rml/tests/input/tag-bookmark.rml
===================================================================
--- z3c.rml/trunk/src/z3c/rml/tests/input/tag-bookmark.rml	2007-04-15 20:14:02 UTC (rev 74159)
+++ z3c.rml/trunk/src/z3c/rml/tests/input/tag-bookmark.rml	2007-04-15 22:04:24 UTC (rev 74160)
@@ -0,0 +1,51 @@
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document
+    filename="tag-bookmark.pdf"
+    xmlns:doc="http://namespaces.zope.org/rml/doc">
+
+  <template>
+    <pageTemplate id="main">
+      <frame id="first" x1="72" y1="72" width="451" height="698"/>
+    </pageTemplate>
+  </template>
+
+  <story>
+
+    <title>
+      <font face="Courier">&lt;bookmark&gt;</font>
+      and
+      <font face="Courier">&lt;link&gt;</font>
+      Tag Demo
+    </title>
+    <bookmark name="TITLE" doc:example="" />
+    <link destination="PAGE_1"
+          boxStrokeColor="red" boxStrokeWidth="1" boxStrokeDashArray="1 2"
+          doc:example="">
+      <para>Go to page 1 now!</para>
+    </link>
+    <nextPage/>
+    <bookmark
+        name="PAGE_1" fitType="fitv" zoom="2"
+        left="2cm" right="10cm" top="20cm"
+        doc:example=""
+        />
+    <h1>This is page 1.</h1>
+    <link destination="TITLE"
+          doc:example="">
+      <imageAndFlowables
+          imageName="images/replogo.gif"
+          imageSide="left">
+        <para>Go to title.</para>
+      </imageAndFlowables>
+    </link>
+    <link destination="PAGE_1">
+      <para>Go to page 1.</para>
+    </link>
+
+    <link url="http://www.reportlab.org"
+          doc:example="">
+      <para>Link to ReporLab Web Site.</para>
+    </link>
+
+  </story>
+</document>



More information about the Checkins mailing list