[Checkins] SVN: z3c.rmldocument/trunk/ Added block and field support for documents.

Christian Theune ct at gocept.com
Wed Mar 12 14:17:32 EDT 2008


Log message for revision 84621:
  Added block and field support for documents.
  

Changed:
  _U  z3c.rmldocument/trunk/
  D   z3c.rmldocument/trunk/.installed.cfg
  U   z3c.rmldocument/trunk/setup.py
  U   z3c.rmldocument/trunk/src/z3c/rmldocument/README.txt
  A   z3c.rmldocument/trunk/src/z3c/rmldocument/TODO.txt
  U   z3c.rmldocument/trunk/src/z3c/rmldocument/document.py
  A   z3c.rmldocument/trunk/src/z3c/rmldocument/examples/
  A   z3c.rmldocument/trunk/src/z3c/rmldocument/examples/example1.rml
  U   z3c.rmldocument/trunk/src/z3c/rmldocument/interfaces.py
  D   z3c.rmldocument/trunk/src/z3c/rmldocument/renderer.py
  U   z3c.rmldocument/trunk/src/z3c/rmldocument/tests.py

-=-

Property changes on: z3c.rmldocument/trunk
___________________________________________________________________
Name: svn:ignore
   + develop-eggs
parts
.installed.cfg
bin


Deleted: z3c.rmldocument/trunk/.installed.cfg
===================================================================
--- z3c.rmldocument/trunk/.installed.cfg	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/.installed.cfg	2008-03-12 18:17:31 UTC (rev 84621)
@@ -1,39 +0,0 @@
-[buildout]
-installed_develop_eggs = /home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rmldocument.egg-link
-parts = test
-
-[test]
-__buildout_installed__ = /home/ctheune/Development/z3c.rmldocument/parts/test
-	/home/ctheune/Development/z3c.rmldocument/bin/test
-__buildout_signature__ = zc.recipe.testrunner-1.0.0-py2.4.egg zc.recipe.egg-1.0.0-py2.4.egg setuptools-0.6c8-py2.4.egg zope.testing-3.5.1-py2.4.egg zc.buildout-1.0.0-py2.4.egg zc.buildout-1.0.0-py2.4.egg
-_b = /home/ctheune/Development/z3c.rmldocument/bin
-_d = /home/ctheune/Development/z3c.rmldocument/develop-eggs
-_e = /home/ctheune/.eggs
-bin-directory = /home/ctheune/Development/z3c.rmldocument/bin
-develop-eggs-directory = /home/ctheune/Development/z3c.rmldocument/develop-eggs
-eggs = z3c.rmldocument
-eggs-directory = /home/ctheune/.eggs
-executable = /home/ctheune/local/python2.4/bin/python
-location = /home/ctheune/Development/z3c.rmldocument/parts/test
-recipe = zc.recipe.testrunner
-script = /home/ctheune/Development/z3c.rmldocument/bin/test
-
-[buildout]
-installed_develop_eggs = /home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rmldocument.egg-link
-
-[buildout]
-parts = test
-
-[buildout]
-installed_develop_eggs = /home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rml.egg-link
-	/home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rmldocument.egg-link
-
-[buildout]
-parts = test
-
-[buildout]
-installed_develop_eggs = /home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rml.egg-link
-	/home/ctheune/Development/z3c.rmldocument/develop-eggs/z3c.rmldocument.egg-link
-
-[buildout]
-parts = test

Modified: z3c.rmldocument/trunk/setup.py
===================================================================
--- z3c.rmldocument/trunk/setup.py	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/setup.py	2008-03-12 18:17:31 UTC (rev 84621)
@@ -44,7 +44,9 @@
     namespace_packages = ['z3c'],
     install_requires = [
         'z3c.rml',
+        'zope.app.pagetemplate',
         'setuptools',
+        'lxml',
         ],
     include_package_data = True,
     zip_safe = False,

Modified: z3c.rmldocument/trunk/src/z3c/rmldocument/README.txt
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/README.txt	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/README.txt	2008-03-12 18:17:31 UTC (rev 84621)
@@ -15,32 +15,51 @@
 Additionally the developer provides a set of fields that can be used to
 customize the document on a per-document basis, e.g. with the client's name.
 
-
-  >>> import z3c.rmldocument.document
+  >>> from z3c.rmldocument.document import Document, DocumentPageTemplateFile
   >>> import zope.interface
-  >>> service_contract = z3c.rmldocument.document.Document(
-  ...     template="""<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
-  ...                <!DOCTYPE document SYSTEM "rml.dtd">
-  ...                <document
-  ...                  filename="tag-para.pdf">
-  ...                  <template>
-  ...                    <pageTemplate id="main">
-  ...                      <frame id="first" x1="1cm" y1="1cm" width="19cm" height="26cm"/>
-  ...                    </pageTemplate>
-  ...                  </template>
-  ...                  <story>
-  ...                    <para>Foo</para>
-  ...                  </story>
-  ...                </document>""")
+  >>> import zope.schema
 
+  >>> class IContractBlocks(zope.interface.Interface):
+  ...     introduction = zope.schema.Text(title=u"Introductory text")
 
-Rendering documents
-===================
+  >>> class IContractData(zope.interface.Interface):
+  ...     salutation = zope.schema.TextLine(title=u"Salutation")
+  ...     years = zope.schema.Int(title=u"Years to go")
 
-The document is a rather dull object. A rendering utility takes care of
-actually rendering the template:
 
-  >>> from z3c.rmldocument.renderer import Renderer
-  >>> renderer = Renderer()
-  >>> renderer.render(service_contract)
-  '%PDF...'
+  >>> class Contract(object):
+  ...     zope.interface.implements(IContractBlocks, IContractData)
+  ...     introduction = """<para>
+  ...         Everything will be fine in <doc:data field="years">Jahre seit Foo</doc:data> years.
+  ...         </para>"""
+  ...     salutation = u"Mr. Steve"
+  ...     years = 4
+
+  >>> class ServiceContract(Document):
+  ...
+  ...     template = DocumentPageTemplateFile(EXAMPLE % 1)
+  ...
+  ...     block_schema = IContractBlocks
+  ...     data_schema = IContractData
+
+Out of this document, we can produce RML that can be rendered into PDF later:
+
+  >>> theuni = Contract()
+  >>> contract_theuni = ServiceContract(theuni)
+  >>> print contract_theuni(raw=True)
+  <?xml version="1.0" encoding="utf-8" standalone="no"?>
+  <!DOCTYPE document SYSTEM "rml.dtd">
+  <document filename="service-contract.pdf">
+    <template>
+      <pageTemplate id="main">
+        <frame id="first" x1="1cm" y1="1cm" width="19cm" height="26cm"/>
+      </pageTemplate>
+    </template>
+    <story>
+      <heading>Mr. Steve</heading>
+      <para>
+        Everything will be fine in 4 years.
+      </para>
+      <para>Best regards,<br/>Peter</para>
+    </story>
+  </document>

Added: z3c.rmldocument/trunk/src/z3c/rmldocument/TODO.txt
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/TODO.txt	                        (rev 0)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/TODO.txt	2008-03-12 18:17:31 UTC (rev 84621)
@@ -0,0 +1,11 @@
+TODO
+====
+
+- Provide a display representation of field data that is suitable for
+  embedding in RML and customizable.
+
+- TinyRML-Integration and HTML-to-RML-Conversion
+
+    - subset of HTML to do markup
+    - XML-Element for inserting field data
+    - GUI picker for fields


Property changes on: z3c.rmldocument/trunk/src/z3c/rmldocument/TODO.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: z3c.rmldocument/trunk/src/z3c/rmldocument/document.py
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/document.py	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/document.py	2008-03-12 18:17:31 UTC (rev 84621)
@@ -9,24 +9,88 @@
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
-#
+#.
 ##############################################################################
 """RML document.
 
 $Id: interfaces.py 74195 2007-04-16 22:41:24Z srichter $
 """
 
+import lxml.etree
+import zope.pagetemplate.pagetemplatefile
 import z3c.rmldocument.interfaces
+import z3c.rml.rml2pdf
 import zope.interface
 
 
+class DocumentPageTemplateFile(
+    zope.pagetemplate.pagetemplatefile.PageTemplateFile):
+
+    def pt_getContext(self, args, kwargs):
+        document = args[0]
+        context = dict(
+            document=document,
+            data=document.data,
+            blocks=document.blocks)
+        return context
+
+
+def preprocess_block(block, data):
+    """Preprocess a given block of para-RML to RML.
+
+    """
+    root = lxml.etree.fromstring('<rmlblock xmlns:doc="http://xml.gocept.com/namespaces/rmldoc">'+block+'</rmlblock>')
+    # Process all value substitutions
+    for element in root.iter():
+        if element.tag != "{http://xml.gocept.com/namespaces/rmldoc}data":
+            continue
+
+        value = getattr(data, element.get('field'))
+        text = str(value) + element.tail
+
+        previous = element.getprevious()
+        parent = element.getparent()
+
+        if previous is not None:
+            previous.tail += text
+        else:
+            parent.text += text
+
+        parent.remove(element)
+    # Remove artificial <rmlblock> tags
+    xml = lxml.etree.tostring(root)
+    xml = xml[xml.find('>')+1:]
+    xml = xml[:xml.rfind('<')]
+    return xml
+
+
+class Bag(object):
+    """An attribute bag."""
+    pass
+
+
 class Document(object):
     """An RML document definition."""
 
     zope.interface.implements(z3c.rmldocument.interfaces.IDocument)
 
-    def __init__(self, template, fields=zope.interface.Interface,
-                 blocks=zope.interface.Interface):
-        self.template = template
-        self.fields = fields
-        self.blocks = blocks
+    encoding = 'utf-8'
+
+    def __init__(self, context):
+        self.context = context
+        self.data = self.data_schema(context)
+        self._setup_blocks()
+
+    def _setup_blocks(self):
+        raw_blocks = self.block_schema(self.context)
+        self.blocks = Bag()
+        for block_name in self.block_schema:
+            block_text = getattr(raw_blocks, block_name)
+            block_text = preprocess_block(block_text, self.data)
+            setattr(self.blocks, block_name, block_text)
+
+    def __call__(self, raw=False):
+        rml = self.template(self).encode(self.encoding)
+        if raw:
+            return rml
+        return z3c.rml.rml2pdf.parseString(rml).getvalue()

Added: z3c.rmldocument/trunk/src/z3c/rmldocument/examples/example1.rml
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/examples/example1.rml	                        (rev 0)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/examples/example1.rml	2008-03-12 18:17:31 UTC (rev 84621)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE document SYSTEM "rml.dtd">
+<document
+  xmlns:tal="http://xml.zope.org/namespaces/tal"
+  filename="service-contract.pdf">
+  <template>
+    <pageTemplate id="main">
+      <frame id="first" x1="1cm" y1="1cm" width="19cm" height="26cm"/>
+    </pageTemplate>
+  </template>
+  <story>
+    <heading tal:content="data/salutation"/>
+
+    <tal:block replace="structure blocks/introduction"/>
+
+    <para>Best regards,<br/>Peter</para>
+  </story>
+</document>

Modified: z3c.rmldocument/trunk/src/z3c/rmldocument/interfaces.py
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/interfaces.py	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/interfaces.py	2008-03-12 18:17:31 UTC (rev 84621)
@@ -43,16 +43,5 @@
         "A schema describing which blocks of RML are available")
 
 
-class IDocumentRenderer(zope.interface.Interface):
-
-    def render(document, fields=None, blocks=None):
-        """Render the document with the given fields and blocks and
-        return the PDF.
-
-        `document` is an IDocument object.
-
-        `fields` is a dict matching the `fields` schema on the class.
-
-        `blocks` is a dict matching the `blocks` schema on the class.
-
-        """
+    def renderRML(fields=None, blocks=None):
+        """Return RML ready to be rendered."""

Deleted: z3c.rmldocument/trunk/src/z3c/rmldocument/renderer.py
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/renderer.py	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/renderer.py	2008-03-12 18:17:31 UTC (rev 84621)
@@ -1,34 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""RML document.
-
-$Id: interfaces.py 74195 2007-04-16 22:41:24Z srichter $
-"""
-
-import z3c.rml.rml2pdf
-import z3c.rmldocument.interfaces
-import zope.interface
-
-
-class Renderer(object):
-    """Render RML documents."""
-
-    zope.interface.implements(z3c.rmldocument.interfaces.IDocumentRenderer)
-
-    def render(self, document, fields=None, blocks=None):
-        """Render the document with the given fields and blocks and
-        return the PDF.
-        """
-        rml = document.template
-        return z3c.rml.rml2pdf.parseString(rml).getvalue()

Modified: z3c.rmldocument/trunk/src/z3c/rmldocument/tests.py
===================================================================
--- z3c.rmldocument/trunk/src/z3c/rmldocument/tests.py	2008-03-12 16:19:44 UTC (rev 84620)
+++ z3c.rmldocument/trunk/src/z3c/rmldocument/tests.py	2008-03-12 18:17:31 UTC (rev 84621)
@@ -16,6 +16,7 @@
 $Id: interfaces.py 74195 2007-04-16 22:41:24Z srichter $
 """
 
+import os.path
 import unittest
 from zope.testing import doctest
 
@@ -23,5 +24,9 @@
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(doctest.DocFileSuite(
-        'README.txt', optionflags=doctest.ELLIPSIS))
+        'README.txt',
+        optionflags=doctest.ELLIPSIS|doctest.REPORT_NDIFF|doctest.NORMALIZE_WHITESPACE,
+        globs={'EXAMPLE': 
+               os.path.join(os.path.dirname(__file__), 'examples',
+                            'example%s.rml')}))
     return suite



More information about the Checkins mailing list