[CMF-checkins] CVS: CMF - FSSTXMethod.py:1.1 __init__.py:1.8 utils.py:1.10

tseaver@digicool.com tseaver@digicool.com
Tue, 29 May 2001 22:53:48 -0400 (EDT)


Update of /cvs-repository/CMF/CMFCore
In directory korak.digicool.com:/tmp/cvs-serv9800/CMFCore

Modified Files:
	__init__.py utils.py 
Added Files:
	FSSTXMethod.py 
Log Message:


 - Moved STX handling ('_format_stx') out of CMFDefault.Document into
   CMFCore.utils & made it a free function (it was only a faux method
   anyway).

 - Created new document class in order to override search patterns
   for 'doc_href';  STXNG inexplicably doesn't include underscore in
   the reference portion (Tracker #281).

 - Added CMFCore.FSSTXMethod, to allow creation of "skin" methods from
   StructuredText files.  Note that these skin methods are not yet
   customizable.



--- Added File FSSTXMethod.py in package CMF ---
##############################################################################
# 
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
# 
# Copyright (c) Digital Creations.  All rights reserved.
# 
# This license has been certified as Open Source(tm).
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
# 1. Redistributions in source code must retain the above copyright
#    notice, this list of conditions, and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions, and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 
# 3. Digital Creations requests that attribution be given to Zope
#    in any manner possible. Zope includes a "Powered by Zope"
#    button that is installed by default. While it is not a license
#    violation to remove this button, it is requested that the
#    attribution remain. A significant investment has been put
#    into Zope, and this effort will continue if the Zope community
#    continues to grow. This is one way to assure that growth.
# 
# 4. All advertising materials and documentation mentioning
#    features derived from or use of this software must display
#    the following acknowledgement:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    In the event that the product being advertised includes an
#    intact Zope distribution (with copyright and license included)
#    then this clause is waived.
# 
# 5. Names associated with Zope or Digital Creations must not be used to
#    endorse or promote products derived from this software without
#    prior written permission from Digital Creations.
# 
# 6. Modified redistributions of any form whatsoever must retain
#    the following acknowledgment:
# 
#      "This product includes software developed by Digital Creations
#      for use in the Z Object Publishing Environment
#      (http://www.zope.org/)."
# 
#    Intact (re-)distributions of any official Zope release do not
#    require an external acknowledgement.
# 
# 7. Modifications are encouraged but must be packaged separately as
#    patches to official Zope releases.  Distributions that do not
#    clearly separate the patches from the original work must be clearly
#    labeled as unofficial distributions.  Modifications which do not
#    carry the name Zope may be packaged in any form, as long as they
#    conform to all of the clauses above.
# 
# 
# Disclaimer
# 
#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.
# 
# 
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations.  Specific
# attributions are listed in the accompanying credits file.
# 
##############################################################################
"""
    Export "methodish" STXDocument class, intended for use as
    an element in the skin of a CMFSite.
"""

from string import split
from os import path, stat
import re

import Globals
from AccessControl import ClassSecurityInfo, getSecurityManager, Permissions
from OFS.DTMLMethod import DTMLMethod, decapitate, guess_content_type

from utils import _dtmldir, _format_stx
import CMFCorePermissions
import StructuredText
from DirectoryView import registerFileExtension, registerMetaType, expandpath
from FSObject import FSObject

try:
    from AccessControl import full_read_guard
except ImportError:
    pass

class FSSTXMethod( FSObject ):
    """
        A chunk of StructuredText, rendered as a skin method of a
        CMFSite.
    """

    meta_type = 'Filesystem STX Method'

    manage_options=( { 'label'      : 'Customize'
                     , 'action'     : 'manage_main'
                     }
                   , { 'label'      : 'View'
                     , 'action'     : ''
                     , 'help'       : ('OFSP'
                                      ,'DTML-DocumentOrMethod_View.stx'
                                      )
                     }
                   )

    security = ClassSecurityInfo()
    security.declareObjectProtected( CMFCorePermissions.View )

    security.declareProtected( CMFCorePermissions.ViewManagementScreens
                             , 'manage_main')
    manage_main = Globals.DTMLFile( 'custstx', _dtmldir )

    #
    #   FSObject interface
    #
    def _createZODBClone(self):
        """
            Create a ZODB (editable) equivalent of this object.
        """
        # XXX:  do this soon
        raise NotImplemented, "See next week's model."

    def _readFile( self, reparse ):

        fp = expandpath( self._filepath )
        file = open( fp, 'r' )  # not binary, we want CRLF munging here.

        try:
            data = file.read()
        finally:
            file.close()

        self.raw = data

        if reparse:
            self.cook()

    #
    #   "Wesleyan" interface (we need to be "methodish").
    #
    class func_code:
        pass

    func_code=func_code()
    func_code.co_varnames= ()
    func_code.co_argcount=0
    func_code.__roles__=()
    
    func_defaults__roles__=()
    func_defaults=()

    index_html = None   # No accidental acquisition

    default_content_type = 'text/html'

    def cook( self ):
        if not hasattr( self, '_v_cooked' ):
            self._v_cooked = _format_stx( text=self.raw )
        return self._v_cooked

    _rendering_template = Globals.HTML( """\
<dtml-var standard_html_header>
<div class="Desktop">
<dtml-var cooked>
</div>
<dtml-var standard_html_footer>""" )

    def __call__( self, REQUEST={}, RESPONSE=None, **kw ):
        """
            Return our rendered StructuredText.
        """
        self._updateFromFS()

        if RESPONSE is not None:
            RESPONSE.setHeader( 'Content-Type', 'text/html' )
        return self._rendering_template( client=self
                                       , mapping=REQUEST
                                       , RESPONSE=RESPONSE
                                       , cooked=self.cook()
                                       )

    # Zope 2.3.x way:
    def validate( self, inst, parent, name, value, md ):
        return getSecurityManager().validate( inst, parent, name, value )

    # Zope 2.4.x way:
    def read_guard( self, ob ):
        return full_read_guard( ob )

    security.declareProtected( CMFCorePermissions.FTPAccess, 'manage_FTPget' )
    def manage_FTPget( self ):
        """
            Fetch our source for delivery via FTP.
        """
        return self.raw

    security.declareProtected( CMFCorePermissions.ViewManagementScreens
                             , 'PrincipiaSearchSource' )
    def PrincipiaSearchSource( self ):
        """
            Fetch our source for indexing in a catalog.
        """
        return self.raw

    security.declareProtected( CMFCorePermissions.ViewManagementScreens
                             , 'document_src' )
    def document_src( self ):
        """
            Fetch our source for indexing in a catalog.
        """
        return self.raw

Globals.InitializeClass( FSSTXMethod )

registerFileExtension( 'stx', FSSTXMethod )
registerMetaType( 'STX Method', FSSTXMethod )

--- Updated File __init__.py in package CMF --
--- __init__.py	2001/05/26 02:56:41	1.7
+++ __init__.py	2001/05/30 02:53:16	1.8
@@ -90,7 +90,8 @@
 import MembershipTool, WorkflowTool, CatalogTool, DiscussionTool
 import ActionsTool, UndoTool, RegistrationTool, SkinsTool
 import MemberDataTool, TypesTool
-import DirectoryView, FSDTMLMethod, FSImage, FSPropertiesObject, FSPythonScript
+import DirectoryView, FSImage, FSPropertiesObject
+import FSDTMLMethod, FSPythonScript, FSSTXMethod
 import CookieCrumbler
 import ContentTypeRegistry
 import utils

--- Updated File utils.py in package CMF --
--- utils.py	2001/04/24 14:12:13	1.9
+++ utils.py	2001/05/30 02:53:16	1.10
@@ -90,7 +90,7 @@
 import Globals
 from Acquisition import aq_get, aq_inner, aq_parent
 from string import split
-import os
+import os, re
 from Globals import package_home
 
 try: from OFS.ObjectManager import UNIQUE
@@ -470,6 +470,60 @@
         setattr(OFS.misc_.misc_, pid, OFS.misc_.Misc_(pid, {}))
     getattr(OFS.misc_.misc_, pid)[name]=icon
 
+#
+#   StructuredText handling.
+#
+import StructuredText
+from StructuredText.HTMLWithImages import HTMLWithImages
+
+_STXDWI = StructuredText.DocumentWithImages.__class__
+
+class CMFDocumentClass( StructuredText.DocumentWithImages.__class__ ):
+    """
+        Override DWI to get '_' into links.
+    """
+    _URL_AND_PUNC = r'([a-zA-Z0-9_\@\.\,\?\!\/\:\;\-\#\~]+)'
+    def doc_href( self
+                , s
+                , expr1 = re.compile( _STXDWI._DQUOTEDTEXT
+                                    + "(:)"
+                                    + _URL_AND_PUNC
+                                    + _STXDWI._SPACES
+                                    ).search
+                , expr2 = re.compile( _STXDWI._DQUOTEDTEXT
+                                    + r'(\,\s+)'
+                                    + _URL_AND_PUNC
+                                    + _STXDWI._SPACES
+                                    ).search
+                ):
+        return _STXDWI.doc_href( self, s, expr1, expr2 )
+
+CMFDocumentClass = CMFDocumentClass()
+
+class CMFHtmlWithImages( HTMLWithImages ):
+    """ Special subclass of HTMLWithImages, overriding document() """
+    def document(self, doc, level, output):
+        """\
+        HTMLWithImages.document renders full HTML (head, title, body).  For
+        CMF Purposes, we don't want that.  We just want those nice juicy
+        body parts perfectly rendered.
+        """
+        for c in doc.getChildNodes():
+           getattr(self, self.element_types[c.getNodeName()])(c, level, output)
+
+CMFHtmlWithImages = CMFHtmlWithImages()
+            
+def _format_stx( text, level=1 ):
+    """
+        Render STX to HTML.
+    """
+    st = StructuredText.Basic( text )   # Creates the basic DOM
+    if not st:                          # If it's an empty object
+        return ""                       # return now or have errors!
+
+    doc = CMFDocumentClass( st )
+    html = CMFHtmlWithImages( doc, level )
+    return html
 
 if 0:
     # Hopefully we can use this.