[Zope3-checkins] CVS: Zope3/utilities - makezcmldocs.py:1.1.2.1

R. David Murray bitz@bitdance.com
Mon, 14 Oct 2002 19:09:53 -0400


Update of /cvs-repository/Zope3/utilities
In directory cvs.zope.org:/tmp/cvs-serv8946

Added Files:
      Tag: rdmurray-metameta-branch
	makezcmldocs.py 
Log Message:
This utility program loads the Zope package using makezcmldocs.zcml
and then walks the resulting augmented _directives data structure
and creates a 'namespaces.zope.org' directory tree of documentation.

This is not a finished product, but a proof of concept.  It must
be run from the utilities directory and creates the namespaces.zope.org
directory in that subdirectory.  If the concept is approved, I'll
work this up into a more finished product that (1) creates the
directory in the 'doc' subdirectory, (2) is careful about the validity
of the structured text it generates (the current text is not really
valid structured text) and (3) issues warning messages if a
directive does not have documentation attributes.

Note that if you run this with python2.3 the descriptions will be
paragraph wrapped using the textwrap module.  Under 2.2, it just
outputs them as one long line.


=== Added File Zope3/utilities/makezcmldocs.py ===
#! /usr/bin/env python2.2
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""

$Id: makezcmldocs.py,v 1.1.2.1 2002/10/14 23:09:53 rdmurray Exp $
"""

from types import UnicodeType, FunctionType, TypeType, ClassType
import os, sys
try: from textwrap import TextWrapper
except:
    class TextWrapper:
        def __init__(initial_indent='',**kw): pass
        def __fill__(txt):
            return initial_indent+txt
#Get Zope3 stuff in the pythonpath.  Note that we use 'here' later as well.
basepath = filter(None, sys.path)
here = os.path.join(os.getcwd(), os.path.split(sys.argv[0])[0])
#We live in the utilities subdirectory...
libpython = os.path.join(here, '..', 'lib', 'python')
sys.path=[libpython] + basepath
#Now for the z3 imports.
from Zope.Configuration.meta import _directives
from Zope.Configuration.metametaConfigureForDocgen import _metadataKey

wrapper = TextWrapper(width=75, replace_whitespace=False)
paragraph = wrapper.fill

def printdirective(outfile, name, handler, registry, level=0):
    if level>10: return
    wrapper.initial_indent = wrapper.subsequent_indent = ' '*level
    ns, name = name
    if type(handler)==FunctionType: handler = "function '%s'" % handler.__name__
    elif type(handler)==TypeType:
        handler = "type '%s.%s'" % (handler.__module__, handler.__name__)
    elif type(handler)==ClassType:
        handler = "class '%s.%s'" % (handler.__module__, handler.__name__)
    elif type(handler)==UnicodeType: handler = "method '%s'" % handler
    if outfile.name.startswith(ns[7:]): prefix = ''
    else: prefix = ns + '/'
    outfile.write("%s%s%s (%s)\n\n" % (' '*level, prefix, name, handler))
    md = registry[_metadataKey]
    wrapper.initial_indent = wrapper.subsequent_indent = ' '*(level+2)
    outfile.write(paragraph(md['description'])+'\n\n')
    wrapper.subsequent_indent = ' '*(level+4)
    for attr in md['attributes']:
        amd = md['attributes'][attr]
        outfile.write(paragraph("%s -- %s%s" % (attr,
            amd.get('required') and '(%s) ' % amd.get('required') or '',
            amd['description']))+'\n\n')
    if (level<9 and len(registry)>1 or len(registry)==1 and not 
            registry.keys()==[_metadataKey]):
        outfile.write(' '*level+'Subdirectives\n\n')
    for subdir in registry:
        if subdir==_metadataKey: continue
        subs, handler = registry[subdir]
        printdirective(outfile, subdir, handler, subs, level+2)


def run(argv=sys.argv):

    from Zope.Configuration.xmlconfig import XMLConfig

    # Set user to system_user, so we can do anything we want
    from Zope.Security.SecurityManagement import system_user
    from Zope.Security.SecurityManagement import newSecurityManager
    newSecurityManager(system_user)

    # Load the zcml for the Zope package in docgen mode.
    XMLConfig(os.path.join(here, 'makezcmldocs.zcml'))()
    
    # Build the meta docs from the contents of the directive registry.
    #XXX: replace /dev/null redirection with if test
    os.system('mkdir namespaces.zope.org 2>/dev/null')
    for directive in _directives:
        ns, name = directive
        ns = ns[27:]
        #XXX same as above
        os.system('mkdir namespaces.zope.org/%s 2>/dev/null' % ns)
        dirfile = open('namespaces.zope.org/%s/%s.stx' % (ns, name),'w')
        callable, subs = _directives[directive]
        printdirective(dirfile, directive, callable, subs)


if __name__ == '__main__':
    run()