[CMF-checkins] SVN: CMF/trunk/C - CMFDefault.Document and
CMFDefault.NewsItem: It is now possible to
Jens Vagelpohl
jens at dataflake.org
Tue Jun 12 14:17:18 EDT 2007
Log message for revision 76644:
- CMFDefault.Document and CMFDefault.NewsItem: It is now possible to
register a utility (ILinebreakNormalizer) that can normalize line
breaks upon editing or rendering out to FTP.
(http://www.zope.org/Collectors/CMF/174)
Changed:
U CMF/trunk/CHANGES.txt
U CMF/trunk/CMFCore/interfaces/_tools.py
U CMF/trunk/CMFDefault/Document.py
U CMF/trunk/CMFDefault/tests/test_Document.py
-=-
Modified: CMF/trunk/CHANGES.txt
===================================================================
--- CMF/trunk/CHANGES.txt 2007-06-12 17:34:03 UTC (rev 76643)
+++ CMF/trunk/CHANGES.txt 2007-06-12 18:17:18 UTC (rev 76644)
@@ -2,6 +2,11 @@
New Features
+ - CMFDefault.Document and CMFDefault.NewsItem: It is now possible to
+ register a utility (ILinebreakNormalizer) that can normalize line
+ breaks upon editing or rendering out to FTP.
+ (http://www.zope.org/Collectors/CMF/174)
+
- CMFDefault.Document and CMFDefault.NewsItem: Added a format choice for
ReStructuredText.
(http://www.zope.org/Collectors/CMF/485)
Modified: CMF/trunk/CMFCore/interfaces/_tools.py
===================================================================
--- CMF/trunk/CMFCore/interfaces/_tools.py 2007-06-12 17:34:03 UTC (rev 76643)
+++ CMF/trunk/CMFCore/interfaces/_tools.py 2007-06-12 18:17:18 UTC (rev 76644)
@@ -1993,3 +1993,33 @@
o Permission: Private (Python only)
"""
+
+
+class ILinebreakNormalizer(Interface):
+
+ """ Interface for a utility to normalize line breaks in plain text
+
+ Implementations of this utility may adjust line breaks to conform to
+ any desired type, such as LF or CRLF.
+ """
+
+ def normalizeIncoming(ob, text):
+ """ Normalize line breaks in text pushed into the system
+
+ o ob is the content object receiving the text value
+
+ o text is the text value submitted by the user
+
+ o Permission: Private (Python only)
+ """
+
+ def normalizeOutgoing(ob, text):
+ """ Normalize line breaks in text emitted by the system
+
+ o ob is the content object rendering the text value
+
+ o text is the text value to be rendered
+
+ o Permission: Private (Python only)
+ """
+
Modified: CMF/trunk/CMFDefault/Document.py
===================================================================
--- CMF/trunk/CMFDefault/Document.py 2007-06-12 17:34:03 UTC (rev 76643)
+++ CMF/trunk/CMFDefault/Document.py 2007-06-12 18:17:18 UTC (rev 76644)
@@ -30,9 +30,11 @@
REST_AVAILABLE = False
from StructuredText.StructuredText import HTML
+from zope.component import queryUtility
from zope.component.factory import Factory
from zope.interface import implements
+from Products.CMFCore.interfaces import ILinebreakNormalizer
from Products.CMFCore.PortalContent import PortalContent
from Products.CMFCore.utils import contributorsplitter
from Products.CMFCore.utils import keywordsplitter
@@ -107,12 +109,22 @@
def _edit(self, text):
""" Edit the Document and cook the body.
"""
- self.text = text
self._size = len(text)
text_format = self.text_format
if not text_format:
text_format = self.text_format
+
+ if text_format != 'html':
+ normalizer = queryUtility(ILinebreakNormalizer)
+
+ if normalizer is not None:
+ self.text = normalizer.normalizeIncoming(self, text)
+ else:
+ self.text = text
+ else:
+ self.text = text
+
if text_format == 'html':
self.cooked_text = text
elif text_format == 'plain':
@@ -444,7 +456,14 @@
else:
hdrlist = self.getMetadataHeaders()
hdrtext = formatRFC822Headers( hdrlist )
- bodytext = '%s\r\n\r\n%s' % ( hdrtext, self.text )
+ normalizer = queryUtility(ILinebreakNormalizer)
+
+ if normalizer is not None:
+ text = normalizer.normalizeOutgoing(self, self.text)
+ else:
+ text = self.text
+
+ bodytext = '%s\r\n\r\n%s' % ( hdrtext, text )
return bodytext
Modified: CMF/trunk/CMFDefault/tests/test_Document.py
===================================================================
--- CMF/trunk/CMFDefault/tests/test_Document.py 2007-06-12 17:34:03 UTC (rev 76643)
+++ CMF/trunk/CMFDefault/tests/test_Document.py 2007-06-12 18:17:18 UTC (rev 76644)
@@ -26,8 +26,11 @@
from DocumentTemplate.DT_Util import html_quote
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
+from zope.component import getSiteManager
+from zope.interface import implements
from zope.interface.verify import verifyClass
+from Products.CMFCore.interfaces import ILinebreakNormalizer
from Products.CMFCore.testing import ConformsToContent
from Products.CMFCore.tests.base.content import BASIC_HTML
from Products.CMFCore.tests.base.content import BASIC_ReST
@@ -62,7 +65,21 @@
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
+class DummyLinebreakNormalizer(object):
+ implements(ILinebreakNormalizer)
+
+ def __init__(self, before, after):
+ self.before = before
+ self.after = after
+
+ def normalizeIncoming(self, obj, text):
+ return text.replace(self.before, self.after)
+
+ def normalizeOutgoing(self, ob, text):
+ return text.replace(self.before, self.after)
+
+
class DocumentTests(ConformsToContent, RequestTestBase):
def test_interfaces(self):
@@ -474,7 +491,68 @@
self.assertEqual( d.Format(), 'text/plain' )
self.assertEqual( d.text_format, 'structured-text' )
+ def test_normalize_linebreaks_incoming(self):
+ # New feature: Line breaks can be normalized on the way in
+ # and on the way out, *if* a specific utility exists.
+ # (http://www.zope.org/Collectors/CMF/174)
+ d = self._makeOne('foo', text='')
+ LF_TEXT = 'This\nis\nsome\ntext'
+ CRLF_TEXT = 'This\r\nis\r\nsome\r\ntext'
+ # First case, no normalizer installed. Text will stay the same.
+ d._edit(LF_TEXT)
+ self.assertEquals(d.text, LF_TEXT)
+
+ d._edit(CRLF_TEXT)
+ self.assertEquals(d.text, CRLF_TEXT)
+
+ # Now register a normalizer that always replaces CRLF with LF
+ # When I pass in CRLFs, the resulting text will only have LFs.
+ crlf_to_lf = DummyLinebreakNormalizer('\r\n', '\n')
+ sm = getSiteManager()
+ sm.registerUtility(crlf_to_lf, ILinebreakNormalizer)
+
+ d._edit(CRLF_TEXT)
+ self.assertEquals(d.text, LF_TEXT)
+
+ d._edit(LF_TEXT)
+ self.assertEquals(d.text, LF_TEXT)
+
+ # cleanup
+ sm.unregisterUtility(crlf_to_lf, ILinebreakNormalizer)
+
+ def test_normalize_linebreaks_outgoing(self):
+ # New feature: Line breaks can be normalized on the way in
+ # and on the way out, *if* a specific utility exists.
+ # (http://www.zope.org/Collectors/CMF/174)
+ d = self._makeOne('foo', text='')
+ LF_TEXT = 'This\nis\nsome\ntext'
+ CRLF_TEXT = 'This\r\nis\r\nsome\r\ntext'
+ HEADERS = """Title: \r\nSubject: \r\nPublisher: No publisher\r\nDescription: \r\nContributors: \r\nEffective_date: None\r\nExpiration_date: None\r\nType: Unknown\r\nFormat: text/plain\r\nLanguage: \r\nRights: \r\nSafetyBelt: \r\n\r\n"""
+
+ # First case, no normalizer installed. Text will stay the same.
+ d.text = LF_TEXT
+ self.assertEquals(d.manage_FTPget(), HEADERS + LF_TEXT)
+
+ d.text = CRLF_TEXT
+ self.assertEquals(d.manage_FTPget(), HEADERS + CRLF_TEXT)
+
+ # Now register a normalizer that always replaces CRLF with LF
+ # When I pass in CRLFs, the resulting text will only have LFs.
+ crlf_to_lf = DummyLinebreakNormalizer('\r\n', '\n')
+ sm = getSiteManager()
+ sm.registerUtility(crlf_to_lf, ILinebreakNormalizer)
+
+ d.text = (CRLF_TEXT)
+ self.assertEquals(d.manage_FTPget(), HEADERS + LF_TEXT)
+
+ d.text = LF_TEXT
+ self.assertEquals(d.manage_FTPget(), HEADERS + LF_TEXT)
+
+ # cleanup
+ sm.unregisterUtility(crlf_to_lf, ILinebreakNormalizer)
+
+
class DocumentFTPGetTests(RequestTestBase):
def setUp(self):
More information about the CMF-checkins
mailing list