[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ Backported

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Aug 12 16:11:48 EDT 2004


Log message for revision 27084:
  Backported
  
  r26614 | srichter | 2004-07-18 17:56:36 -0400 (Sun, 18 Jul 2004) | 4 lines
  r26615 | srichter | 2004-07-18 17:59:44 -0400 (Sun, 18 Jul 2004) | 5 lines
  r26622 | srichter | 2004-07-19 08:39:46 -0400 (Mon, 19 Jul 2004) | 2 lines
  r26623 | srichter | 2004-07-19 08:40:26 -0400 (Mon, 19 Jul 2004) | 2 lines
  
  


Changed:
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/apidoc.css
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/contents.pt
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/__init__.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/browser.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/configure.zcml
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/ftests.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/module_index.pt
  A   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/zcmlfile_index.pt
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/browser.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/index.pt
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/viewmodule/__init__.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/zcmlmodule/index.pt


-=-
Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/apidoc.css
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/apidoc.css	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/apidoc.css	2004-08-12 20:11:48 UTC (rev 27084)
@@ -6,7 +6,7 @@
     padding: 0pt;
 }
 
-code, pre {
+code, pre, span.pre {
   font-size: 120%;
 }
 
@@ -147,3 +147,23 @@
   padding: 0;
   margin: 0 0.5em 0 0;
 }
+
+/* Styles for ZCML markup */
+
+code.zcml a {
+  color: inherit;
+  font-style: italic;
+}
+
+code.zcml .attribute {
+  color: MediumVioletRed;
+}
+
+code.zcml .tagname {
+  color: blue;
+  font-weight: bold;
+}
+
+code.zcml .objectref {
+  color: DarkSalmon;
+}
\ No newline at end of file

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/contents.pt
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/contents.pt	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/browser/contents.pt	2004-08-12 20:11:48 UTC (rev 27084)
@@ -19,7 +19,11 @@
 
   <tal:omit-tag repeat="module view/getModuleList">
 
-    <h2 tal:content="module/title">Module Title</h2>
+    <h2>
+      <a target="menu" href=""
+         tal:attributes="href string:./${module/name}/menu.html"
+         tal:content="module/title">Module Title</a>
+    </h2>
 
     <p tal:replace="structure module/description">
       Module Description

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/__init__.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/__init__.py	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/__init__.py	2004-08-12 20:11:48 UTC (rev 27084)
@@ -28,7 +28,6 @@
 import zope
 from zope.security.checker import getCheckerForInstancesOf
 from zope.interface import Interface, Attribute, implements, implementedBy
-from zope.app import zapi
 from zope.app.container.interfaces import IReadContainer
 from zope.app.i18n import ZopeMessageIDFactory as _
 
@@ -126,6 +125,12 @@
         second is the attribute object itself.
         """
 
+class IZCMLFileDocumentation(Interface):
+    """Representation of a function for documentation."""
+
+    path = Attribute('Full path of the ZCML file.')
+
+
 class Module(ReadContainerBase):
     """This class represents a Python module.
 
@@ -219,6 +224,9 @@
                     if module is not None:
                         self.__children[name] = Module(self, name, module)
 
+                elif os.path.isfile(path) and file.endswith('.zcml'):
+                    self.__children[file] = ZCMLFile(self, file, path)
+
         # Setup classes in module, if any are available.
         for name in self.__module.__dict__.keys():
             attr = getattr(self.__module, name)
@@ -491,6 +499,30 @@
         return self.__func.__dict__.items()
 
 
+class ZCMLFile(object):
+    """Represent the documentation of any ZCML file.
+
+    This object in itself is rather simple, since it only stores the full path
+    of the ZCML file and its location in the documentation tree.
+
+    >>> zcml = ZCMLFile(None, 'foo.zcml', '/Zope3/src/zope/app/foo.zcml')
+    >>> zcml.__parent__ is None
+    True
+    >>> zcml.__name__
+    'foo.zcml'
+    >>> zcml.path
+    '/Zope3/src/zope/app/foo.zcml'
+    """
+    
+    implements(ILocation, IZCMLFileDocumentation)
+
+    def __init__(self, module, name, path):
+        """Initialize the object."""
+        self.__parent__ = module
+        self.__name__ = name
+        self.path = path
+
+
 class ClassModule(Module):
     """Represent the Documentation of any possible class.
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/browser.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/browser.py	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/browser.py	2004-08-12 20:11:48 UTC (rev 27084)
@@ -16,24 +16,35 @@
 $Id$
 """
 __docformat__ = 'restructuredtext'
-
+import inspect
 import os
-import inspect
+import re
+from types import TypeType, ClassType, FunctionType, ModuleType
+import xml.dom.minidom
+import xml.sax.saxutils
 
+from zope.configuration import docutils, xmlconfig
 from zope.configuration.config import ConfigurationContext
+from zope.configuration.fields import GlobalObject, Tokens
 from zope.exceptions import NotFoundError
 from zope.interface import implementedBy
+from zope.interface.interface import InterfaceClass
 from zope.proxy import removeAllProxies
+from zope.schema import getFieldsInOrder
 
+import zope.app
 from zope.app import zapi
 from zope.app.i18n import ZopeMessageIDFactory as _
+from zope.app.apidoc.classmodule import Module, Class, Function, ZCMLFile
+from zope.app.apidoc.classmodule import classRegistry
+from zope.app.apidoc.interfaces import IDocumentationModule
 from zope.app.apidoc.utilities import getPythonPath, renderText, columnize
 from zope.app.apidoc.utilities import getPermissionIds, getFunctionSignature
 from zope.app.apidoc.utilities import getPublicAttributes
 from zope.app.apidoc.utilities import getInterfaceForAttribute
-from zope.app.apidoc.classmodule import Module, Class, Function, classRegistry
-from zope.app.apidoc.interfaces import IDocumentationModule
+from zope.app.apidoc.zcmlmodule import quoteNS
 
+
 class Menu(object):
     """Menu for the Class Documentation Module.
 
@@ -111,6 +122,244 @@
         return results
 
 
+_obj_attr_re = r'(?P<start>&lt;%s.*?%s=".*?)(?P<value>%s)(?P<end>".*?&gt;)'
+_attrname_re = r'(?P<start>&lt;.*?%s.*?)(?P<attr>%s)(?P<end>=".*?".*?&gt;)'
+directives = {}
+
+class ZCMLFileDetails(ConfigurationContext):
+    """Represents the details of the ZCML file."""
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+        package = removeAllProxies(zapi.getParent(context))._Module__module
+        # Keep track of the package that is used for relative paths
+        self._package_stack = [package]
+        # Keep track of completed actions, so none is executed twice
+        self._done = []
+        # Kepp track of the parent node, so that we know whether we deal with
+        # a directive or sub-directive 
+        self._parent_node_info = None
+
+    # See zope.configuration.config.ConfigurationContext
+    # The package is used to resolve relative paths.
+    package = property(lambda self: self._package_stack[-1])
+
+    # All registered directives. The availability of directives depends on
+    # whether we a re looking for a directive or a sub-directive.
+    directives = property(lambda self: directives[self._parent_node_info])
+
+    def getBaseURL(self):
+        """Return the URL for the API Documentation Tool.
+
+        Example::
+
+          >>> from tests import getClassDetailsView
+          >>> view = getClassDetailsView()
+
+          Note that the following output is a bit different than usual, since
+          we have not setup all path elements.
+
+          >>> view.getBaseURL()
+          'http://127.0.0.1'
+        """
+        m = zapi.getUtility(IDocumentationModule, "Class")
+        return zapi.getView(zapi.getParent(m), 'absolute_url', self.request)()
+
+    def getHTMLContents(self):
+        """Return an HTML markup version of the ZCML file with links to other
+        documentation modules."""
+        if not directives:
+            self._makeDocStructure()
+        dom = xml.dom.minidom.parse(self.context.path)
+        self.text = file(self.context.path, 'r').read()
+        self.text = xml.sax.saxutils.escape(self.text)
+        self.text = self.text.replace(' ', '&nbsp;')
+        self.text = self.text.replace('\n', '<br />\n')
+
+        # Link interface and other object references
+        for node in dom.childNodes:
+            self._linkObjectReferences(node)
+
+        # Link ZCML directives
+        for node in dom.childNodes:
+            self._linkDirectives(node)
+
+        # Color directive attributes
+        for node in dom.childNodes:
+            self._colorAttributeNames(node)
+
+        # Color comments
+        self._colorComments()
+        
+        return self.text
+
+    def _colorComments(self):
+        self.text = self.text.replace('&lt;!--',
+                                      '<span style="color: red">&lt;!--')
+        self.text = self.text.replace('--&gt;',
+                                      '--&gt;</span>')
+
+    def _colorAttributeNames(self, node):
+        if node.nodeType in (node.TEXT_NODE, node.COMMENT_NODE):
+            return
+
+        for attrName in node.attributes.keys():
+            disc = ('color attribute name', node.tagName, attrName)
+            if disc in self._done:
+                continue
+
+            expr = re.compile(_attrname_re %(node.tagName, attrName),
+                              re.DOTALL)
+            self.text = re.sub(
+                expr,
+                r'\1<span class="attribute">\2</span>\3',
+            self.text)
+            
+            self._done.append(disc)
+
+        for child in node.childNodes:
+            self._colorAttributeNames(child)
+
+
+    def _linkDirectives(self, node):
+        if node.nodeType in (node.TEXT_NODE, node.COMMENT_NODE):
+            return
+
+        if (node.tagName,) in self._done:
+            return
+
+        if node.namespaceURI in self.directives.keys() and \
+               node.localName in self.directives[node.namespaceURI].keys():
+            namespace = quoteNS(node.namespaceURI)
+        else:
+            namespace = 'ALL'
+
+        self.text = self.text.replace(
+            '&lt;'+node.tagName,
+            '&lt;<a class="tagname" href="%s/ZCML/%s/%s/index.html">%s</a>' %(
+            self.getBaseURL(), namespace, node.localName, node.tagName))
+
+        self.text = self.text.replace(
+            '&lt;/'+node.tagName+'&gt;',
+            '&lt;/<a class="tagname" '
+            'href="%s/ZCML/%s/%s/index.html">%s</a>&gt;' %(
+            self.getBaseURL(), namespace, node.localName, node.tagName))
+
+        self._done.append((node.tagName,))
+        
+        for child in node.childNodes:
+            self._linkDirectives(child)
+
+
+    def _linkObjectReferences(self, node):
+        if node.nodeType in (node.TEXT_NODE, node.COMMENT_NODE):
+            return
+
+        if node.localName == 'configure' and node.hasAttribute('package'):
+            self._package_stack.push(
+                self.resolve(node.getAttribute('package')))
+
+        for child in node.childNodes:
+            self._linkObjectReferences(child)
+
+        namespace = self.directives.get(node.namespaceURI, self.directives[''])
+        directive = namespace.get(node.localName)
+        if directive is None:
+            # Try global namespace
+            directive = self.directives[''].get(node.localName)
+
+        for name, field in getFieldsInOrder(directive[0]):
+            if node.hasAttribute(name.strip('_')):
+                self._evalField(field, node)
+
+        if node.localName == 'configure' and node.hasAttribute('package'):
+            self._package_stack.pop()
+
+
+    def _evalField(self, field, node, attrName=None, dottedName=None):
+        bound = field.bind(self)
+        if attrName is None:
+            attrName = field.getName().strip('_')
+        if dottedName is None:
+            dottedName = node.getAttribute(attrName)
+
+        if isinstance(field, Tokens) and \
+               isinstance(field.value_type, GlobalObject):
+                       
+            tokens = [token.strip()
+                      for token in node.getAttribute(attrName).split(' \n\t')
+                      if token.strip() != '']
+
+            for token in tokens:
+                self._evalField(field.value_type, node, attrName, dottedName)
+
+        if isinstance(field, GlobalObject):
+            obj = bound.fromUnicode(dottedName)
+            disc = (node.tagName, attrName, dottedName)
+
+            if disc in self._done:
+                return
+
+            if isinstance(obj, InterfaceClass):
+                expr = re.compile(_obj_attr_re %(
+                    node.tagName, attrName, dottedName.replace('.', r'\.')),
+                                  re.DOTALL)                
+                path = obj.__module__ + '.' + obj.__name__
+                self.text = re.sub(
+                    expr,
+                    r'\1<a class="objectref" '
+                    r'href="%s/Interface/%s/apiindex.html">\2</a>\3' %(
+                    self.getBaseURL(), path),
+                    self.text)
+
+            elif isinstance(obj, (TypeType, ClassType, FunctionType)):
+                expr = re.compile(_obj_attr_re %(
+                    node.tagName, attrName, dottedName.replace('.', r'\.')),
+                                  re.DOTALL)
+                path = (obj.__module__ + '.' + obj.__name__).replace('.', '/')
+                self.text = re.sub(
+                    expr,
+                    r'\1<a class="objectref" '
+                    r'href="%s/Class/%s/index.html">\2</a>\3' %(
+                    self.getBaseURL(), path),
+                    self.text)
+
+            elif isinstance(obj, ModuleType):
+                expr = re.compile(_obj_attr_re %(
+                    node.tagName, attrName, dottedName.replace('.', r'\.')),
+                                  re.DOTALL)
+                path = obj.__name__.replace('.', '/')
+                self.text = re.sub(
+                    expr,
+                    r'\1<a class="objectref" '
+                    r'href="%s/Class/%s/index.html">\2</a>\3' %(
+                    self.getBaseURL(), path),
+                    self.text)
+
+            self._done.append(disc)
+                        
+    def _makeDocStructure(self):
+        # Some trivial caching
+        global directives
+        context = xmlconfig.file(
+            zope.app.appsetup.appsetup.getConfigSource(),
+            execute=False)
+        namespaces, subdirs = docutils.makeDocStructures(context)
+
+        for ns_name, dirs in namespaces.items():
+            for dir_name, dir in dirs.items():
+                parent = directives.setdefault(None, {})
+                namespace = parent.setdefault(ns_name, {})
+                namespace[dir_name] = dir
+
+        for parent_info, dirs in subdirs.items():
+            for dir in dirs:
+                parent = directives.setdefault(parent_info, {})
+                namespace = parent.setdefault(dir[0], {})
+                namespace[dir[1]] = dir[2:]
+
+
 class FunctionDetails(object):
     """Represents the details of the function."""
 
@@ -365,15 +614,17 @@
 
           >>> entries = view.getEntries(False)
           >>> entries.sort()
-          >>> pprint(entries[:2])
+          >>> pprint(entries[1:3])
           [[('isclass', False),
             ('isfunction', False),
             ('ismodule', True),
+            ('iszcmlfile', False),
             ('name', 'browser'),
             ('url', 'http://127.0.0.1/zope/app/apidoc/classmodule/browser')],
            [('isclass', False),
             ('isfunction', True),
             ('ismodule', False),
+            ('iszcmlfile', False),
             ('name', 'cleanUp'),
             ('url', 'http://127.0.0.1/zope/app/apidoc/classmodule/cleanUp')]]
         """
@@ -381,7 +632,8 @@
                     'url': zapi.getView(obj, 'absolute_url', self.request)(),
                     'ismodule': type(removeAllProxies(obj)) is Module,
                     'isclass': type(removeAllProxies(obj)) is Class,
-                    'isfunction': type(removeAllProxies(obj)) is Function,}
+                    'isfunction': type(removeAllProxies(obj)) is Function,
+                    'iszcmlfile': type(removeAllProxies(obj)) is ZCMLFile,}
                    for name, obj in self.context.items()]
         entries.sort(lambda x, y: cmp(x['name'], y['name']))
         if columns:

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/configure.zcml
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/configure.zcml	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/configure.zcml	2004-08-12 20:11:48 UTC (rev 27084)
@@ -14,6 +14,10 @@
     <allow interface=".IFunctionDocumentation" />
   </class>
 
+  <class class=".ZCMLFile">
+    <allow interface=".IZCMLFileDocumentation" />
+  </class>
+
   <class class=".ClassModule">
     <allow interface="zope.app.apidoc.interfaces.IDocumentationModule" />
     <allow interface=".IModuleDocumentation" />
@@ -53,4 +57,11 @@
     name="index.html"
     template="function_index.pt" />
 
+  <browser:page
+    for=".IZCMLFileDocumentation"
+    permission="zope.View"
+    class=".browser.ZCMLFileDetails"
+    name="index.html"
+    template="zcmlfile_index.pt" />
+
 </configure>

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/ftests.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/ftests.py	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/ftests.py	2004-08-12 20:11:48 UTC (rev 27084)
@@ -70,6 +70,16 @@
         self.checkForBrokenLinks(
             body, '/++apidoc++/Class/zope/app/apidoc/handleNamesapce',
             basic='mgr:mgrpw')
+
+    def testZCMLFileDetailsView(self):
+        response = self.publish(
+            '/++apidoc++/Class/zope/app/configure.zcml',
+            basic='mgr:mgrpw')
+        self.assertEqual(response.getStatus(), 200)
+        body = response.getBody()
+        self.checkForBrokenLinks(
+            body, '/++apidoc++/Class/zope/app/configure.zcml',
+            basic='mgr:mgrpw')
         
 
 def test_suite():

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/module_index.pt
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/module_index.pt	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/module_index.pt	2004-08-12 20:11:48 UTC (rev 27084)
@@ -36,6 +36,10 @@
          tal:condition="entry/isfunction"
          tal:attributes="href string:./${entry/name}/index.html"
          tal:content="structure string:<i>${entry/name}</i>" />
+      <a href=""
+         tal:condition="entry/iszcmlfile"
+         tal:attributes="href string:./${entry/name}/index.html"
+         tal:content="structure string:<i>${entry/name}</i>" />
     </li>
   </ul></td>
 

Copied: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/classmodule/zcmlfile_index.pt (from rev 26615, Zope3/trunk/src/zope/app/apidoc/classmodule/zcmlfile_index.pt)

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/browser.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/browser.py	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/browser.py	2004-08-12 20:11:48 UTC (rev 27084)
@@ -140,6 +140,45 @@
     return {'name': ifaces[0].getName(), 'id': getPythonPath(ifaces[0])}
 
 
+def _getFieldClass(field):
+    """Return PT-friendly dict about the field's class.
+
+    Examples::
+
+      >>> from zope.app.apidoc.tests import pprint
+      >>> from zope.interface import implements, Interface
+      
+      >>> class IField(Interface):
+      ...     pass
+      >>> class ISpecialField(IField):
+      ...     pass
+      >>> class Field(object):
+      ...     implements(IField)
+      >>> class SpecialField(object):
+      ...     implements(ISpecialField)
+      >>> class ExtraField(SpecialField):
+      ...     pass
+
+      >>> info = _getFieldClass(Field())
+      >>> pprint(info)
+      [('name', 'Field'),
+       ('path', 'zope/app/apidoc/ifacemodule/browser/Field')]
+
+      >>> info = _getFieldClass(SpecialField())
+      >>> pprint(info)
+      [('name', 'SpecialField'),
+       ('path', 'zope/app/apidoc/ifacemodule/browser/SpecialField')]
+
+      >>> info = _getFieldClass(ExtraField())
+      >>> pprint(info)
+      [('name', 'ExtraField'),
+       ('path', 'zope/app/apidoc/ifacemodule/browser/ExtraField')]
+    """
+    class_ = removeAllProxies(field).__class__
+    return {'name': class_.__name__,
+            'path': getPythonPath(class_).replace('.', '/')}
+
+
 def _getRequired(field):
     """Return a string representation of whether the field is required.
 
@@ -199,7 +238,10 @@
           >>> details.getDoc()[:34]
           '<h1>This is the Foo interface</h1>'
         """
-        return renderText(self.context.__doc__, self.context.__module__)
+        # We must remove all proxies here, so that we get the context's
+        # __module__ attribute and not the proxy's. 
+        return renderText(self.context.__doc__,
+                          removeAllProxies(self.context).__module__)
 
     def getBases(self):
         """Get all bases of this class
@@ -293,11 +335,11 @@
         return [{'name': method.getName(),
                  'signature': method.getSignatureString(),
                  'doc': renderText(method.getDoc() or '',
-                                   self.context.__module__)}
+                                   removeAllProxies(self.context).__module__)}
                 for method in _get(self.context, IMethod).values()]
             
     def getFields(self):
-        """Return a list of fields in the order they were specified.
+        r"""Return a list of fields in the order they were specified.
 
         Example::
 
@@ -307,15 +349,21 @@
 
           >>> fields = details.getFields()
           >>> pprint(fields)
-          [[('default', "u'Foo'"),
-            ('description', u'Title'),
+          [[('class',
+             [('name', 'TextLine'),
+              ('path', 'zope/schema/_bootstrapfields/TextLine')]),
+            ('default', "u'Foo'"),
+            ('description', '<p>Title</p>\n'),
             ('iface',
              [('id', 'zope.schema.interfaces.ITextLine'),
               ('name', 'ITextLine')]),
             ('name', 'title'),
             ('required', u'required')],
-           [('default', "u'Foo.'"),
-            ('description', u'Desc'),
+           [('class',
+             [('name', 'Text'),
+              ('path', 'zope/schema/_bootstrapfields/Text')]),
+            ('default', "u'Foo.'"),
+            ('description', '<p>Desc</p>\n'),
             ('iface',
              [('id', 'zope.schema.interfaces.IText'), ('name', 'IText')]),
             ('name', 'description'),
@@ -324,10 +372,12 @@
         fields = map(lambda x: x[1], _getInOrder(self.context, IField))
         return [{'name': field.getName(),
                  'iface': _getFieldInterface(field),
+                 'class': _getFieldClass(field),
                  'required': _getRequired(field),
                  'default': field.default.__repr__(),
-                 'description': field.description
-                 }
+                 'description': renderText(
+                     field.description or '',
+                     removeAllProxies(self.context).__module__)}
                 for field in fields]
 
     def getRequiredAdapters(self):
@@ -361,7 +411,8 @@
         adapters = []
         for reg in service.registrations():
             # Only grab the adapters for which this interface is required
-            if reg.required and reg.required[0] is not None and iface not in reg.required:
+            if reg.required and reg.required[0] is not None and \
+                   iface not in reg.required:
                 continue
             factory = _getRealFactory(reg.value)
             path = getPythonPath(factory)

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/index.pt
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/index.pt	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/ifacemodule/index.pt	2004-08-12 20:11:48 UTC (rev 27084)
@@ -63,12 +63,13 @@
     <li tal:repeat="field fields">
       <b><code tal:content="field/name">field</code></b>
       - <a href=""
-           tal:attributes="href string:../${field/iface/id}/apiindex.html">
-          <code tal:content="field/iface/name">IField</code></a>
+           tal:attributes="
+             href string:../../Class/${field/class/path}/index.html">
+          <code tal:content="field/class/name">Field</code></a>
       (<span tal:content="string:${field/required}, ">optional, </span>
         <span i18n:translate="">default</span> =
         <code tal:content="field/default" />)<br>
-      <span tal:content="field/description">field desc</span>      
+      <span tal:content="structure field/description">field desc</span>      
     </li>
 
   </ul>

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/viewmodule/__init__.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/viewmodule/__init__.py	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/viewmodule/__init__.py	2004-08-12 20:11:48 UTC (rev 27084)
@@ -15,6 +15,7 @@
 
 $Id$
 """
+__docformat__ = 'restructuredtext'
 from zope.app import zapi
 from zope.interface import implements, classImplements, Interface, Attribute
 from zope.component.presentation import SkinRegistration
@@ -71,8 +72,8 @@
     interface and a presentation type for which views should be found.
 
     By default, the resulting views exclude views that have no required
-    interface ('None') or are registered to require
-    'zope.interface.Interface'. To see these additional views, click on
+    interface (``None``) or are registered to require
+    ``zope.interface.Interface``. To see these additional views, click on
     "Show all views".
 
     Once you click on "Show" you will be presented with a list of all
@@ -120,7 +121,7 @@
 
     This is used as a wrapper to output end-user friendlier information. We
     also always want the documentation of a layer registration to be a string,
-    which the 'LayerRegistration.doc' attribute does not guarantee. 
+    which the `LayerRegistration.doc` attribute does not guarantee. 
 
     Examples::
 
@@ -217,7 +218,7 @@
 
     This is used as a wrapper to output end-user friendlier information. We
     also always want the documentation of a layer registration to be a string,
-    which the 'LayerRegistration.doc' attribute does not guarantee. 
+    which the `LayerRegistration.doc` attribute does not guarantee. 
 
     Examples::
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/zcmlmodule/index.pt
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/zcmlmodule/index.pt	2004-08-12 20:06:47 UTC (rev 27083)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/apidoc/zcmlmodule/index.pt	2004-08-12 20:11:48 UTC (rev 27084)
@@ -62,12 +62,12 @@
       <b><code tal:content="field/name">field</code></b>
       - <a href=""
            tal:attributes="href 
-               string:../../../Interface/${field/iface/id}/apiindex.html">
-          <code tal:content="field/iface/name">IField</code></a>
+               string:../../../Class/${field/class/path}/index.html">
+          <code tal:content="field/class/name">Field</code></a>
       (<span tal:content="string:${field/required}, ">optional, </span>
         <span i18n:translate="">default</span> =
             <code tal:content="field/default" />)<br>
-      <span tal:content="field/description">field desc</span>      
+      <span tal:content="structure field/description">field desc</span>      
     </li>
 
   </ul>



More information about the Zope3-Checkins mailing list