- simplify doc output; use itemizedlists instead of tables to further
authorMark Huang <mlhuang@cs.princeton.edu>
Mon, 19 Feb 2007 18:02:39 +0000 (18:02 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Mon, 19 Feb 2007 18:02:39 +0000 (18:02 +0000)
  describe structs/array/mixed types. If an array is composed of just
  one subtype, abbreviate the list generation by one level.

doc/DocBook.py

index 84a5121..0185ab4 100755 (executable)
@@ -6,7 +6,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: DocBook.py,v 1.2 2006/10/25 14:32:01 mlhuang Exp $
+# $Id: DocBook.py,v 1.3 2006/10/25 19:35:36 mlhuang Exp $
 #
 
 import xml.dom.minidom
@@ -21,23 +21,26 @@ api = PLCAPI(None)
 # xml.dom.minidom.Text.writexml adds surrounding whitespace to textual
 # data when pretty-printing. Override this behavior.
 class TrimText(Text):
+    """text"""
+    def __init__(self, text = None):
+        self.data = unicode(text)
+
     def writexml(self, writer, indent="", addindent="", newl=""):
         Text.writexml(self, writer, "", "", "")
 
 class TrimTextElement(Element):
+    """<tagName>text</tagName>"""
+    def __init__(self, tagName, text = None):
+        Element.__init__(self, tagName)
+        if text is not None:
+            self.appendChild(TrimText(text))
+
     def writexml(self, writer, indent="", addindent="", newl=""):
         writer.write(indent)
         Element.writexml(self, writer, "", "", "")
         writer.write(newl)
 
-class simpleElement(TrimTextElement):
-    """<tagName>text</tagName>"""
-    def __init__(self, tagName, text = None):
-        TrimTextElement.__init__(self, tagName)
-        if text is not None:
-            t = TrimText()
-            t.data = unicode(text)
-            self.appendChild(t)
+class simpleElement(TrimTextElement): pass
 
 class paraElement(simpleElement):
     """<para>text</para>"""
@@ -57,130 +60,63 @@ class blockquoteElement(Element):
             for paragraph in paragraphs:
                 self.appendChild(paraElement(paragraph))
 
-class entryElement(simpleElement):
-    """<entry>text</entry>"""
-    def __init__(self, text = None):
-        simpleElement.__init__(self, 'entry', text)
-
-class rowElement(Element):
-    """
-    <row>
-      <entry>entries[0]</entry>
-      <entry>entries[1]</entry>
-      ...
-    </row>
-    """
-
-    def __init__(self, entries = None):
-        Element.__init__(self, 'row')
-        if entries:
-            for entry in entries:
-                if isinstance(entry, entryElement):
-                    self.appendChild(entry)
-                else:
-                    self.appendChild(entryElement(entry))
-
-class informaltableElement(Element):
-    """
-    <informaltable>
-      <tgroup>
-       <thead>
-         <row>
-           <entry>label1</entry>
-           <entry>label2</entry>
-           ...
-         </row>
-       </thead>
-       <tbody>
-         <row>
-           <entry>row1value1</entry>
-           <entry>row1value2</entry>
-           ...
-         </row>
-         ...
-       </tbody>
-      </tgroup>
-    </informaltable>
-    """
-
-    def __init__(self, head = None, rows = None):
-        Element.__init__(self, 'informaltable')
-        tgroup = Element('tgroup')
-        self.appendChild(tgroup)
-        if head:
-            thead = Element('thead')
-            tgroup.appendChild(thead)
-            if isinstance(head, rowElement):
-                thead.appendChild(head)
-            else:
-                thead.appendChild(rowElement(head))
-        if rows:
-            tbody = Element('tbody')
-            tgroup.appendChild(tbody)
-            for row in rows:
-                if isinstance(row, rowElement):
-                    tbody.appendChild(row)
-                else:
-                    tobdy.appendChild(rowElement(row))
-            cols = len(thead.childNodes[0].childNodes)
-            tgroup.setAttribute('cols', str(cols))
-
-def parameters(param, name, optional, doc, indent, step):
-    """Format a parameter into parameter row(s)."""
-
-    rows = []
-
-    row = rowElement()
-    rows.append(row)
-
-    # Parameter name
-    entry = entryElement()
-    entry.appendChild(simpleElement('literallayout', indent + name))
-    row.appendChild(entry)
-
-    # Parameter type
-    param_type = python_type(param)
-    row.appendChild(entryElement(xmlrpc_type(param_type)))
-
-    # Whether parameter is optional
-    if optional is not None:
-        row.appendChild(entryElement(str(bool(optional))))
+def param_type(param):
+    """Return the XML-RPC type of a parameter."""
+    if isinstance(param, Mixed) and len(param):
+        subtypes = [param_type(subparam) for subparam in param]
+        return " or ".join(subtypes)
+    elif isinstance(param, (list, tuple, set)) and len(param):
+        return "array of " + " or ".join([param_type(subparam) for subparam in param])
     else:
-        row.appendChild(entryElement(""))
+        return xmlrpc_type(python_type(param))
+
+class paramElement(Element):
+    """An optionally named parameter."""
+    def __init__(self, name, param):
+        # <listitem>
+        Element.__init__(self, 'listitem')
+
+        description = Element('para')
+
+        if name:
+            description.appendChild(simpleElement('parameter', name))
+            description.appendChild(TrimText(": "))
 
-    # Parameter documentation
-    row.appendChild(entryElement(doc))
+        description.appendChild(TrimText(param_type(param)))
 
-    # Indent the name of each sub-parameter
-    subparams = []
-    if isinstance(param, dict):
-        subparams = param.iteritems()
-    elif isinstance(param, Mixed):
-        subparams = [(name, subparam) for subparam in param]
-    elif isinstance(param, (list, tuple)):
-        subparams = [("", subparam) for subparam in param]
+        if isinstance(param, (list, tuple, set)) and len(param) == 1:
+            param = param[0]
 
-    for name, subparam in subparams:
-        if isinstance(subparam, Parameter):
-            (optional, doc) = (subparam.optional, subparam.doc)
-        else:
-            (optional, doc) = (None, "")
-        rows += parameters(subparam, name, optional, doc, indent + step, step)
+        if isinstance(param, Parameter):
+            description.appendChild(TrimText(", " + param.doc))
+            param = param.type
+
+        self.appendChild(description)
 
-    return rows
+        if isinstance(param, dict):
+            itemizedlist = Element('itemizedlist')
+            self.appendChild(itemizedlist)
+            for name, subparam in param.iteritems():
+                itemizedlist.appendChild(paramElement(name, subparam))
+
+        elif isinstance(param, (list, tuple, set)) and len(param):
+            itemizedlist = Element('itemizedlist')
+            self.appendChild(itemizedlist)
+            for subparam in param:
+                itemizedlist.appendChild(paramElement(None, subparam))
 
 for method in api.methods:
     func = api.callable(method)
+
+    if func.status == "deprecated":
+        continue
+
     (min_args, max_args, defaults) = func.args()
 
     section = Element('section')
     section.setAttribute('id', func.name)
     section.appendChild(simpleElement('title', func.name))
 
-    para = paraElement('Status:')
-    para.appendChild(blockquoteElement(func.status))
-    section.appendChild(para)
-
     prototype = "%s (%s)" % (method, ", ".join(max_args))
     para = paraElement('Prototype:')
     para.appendChild(blockquoteElement(prototype))
@@ -190,46 +126,24 @@ for method in api.methods:
     para.appendChild(blockquoteElement(func.__doc__))
     section.appendChild(para)
 
-    para = paraElement('Parameters:')
-    blockquote = blockquoteElement()
-    para.appendChild(blockquote)
-    section.appendChild(para)
-
-    head = rowElement(['Name', 'Type', 'Optional', 'Description'])
-    rows = []
-
-    indent = "  "
-    for name, param, default in zip(max_args, func.accepts, defaults):
-        optional = name not in min_args
-        if isinstance(param, Parameter):
-            doc = param.doc
-        else:
-            doc = ""
-        rows += parameters(param, name, optional, doc, "", indent)
-
-    if rows:
-        informaltable = informaltableElement(head, rows)
-        informaltable.setAttribute('frame', "none")
-        informaltable.setAttribute('rules', "rows")
-        blockquote.appendChild(informaltable)
-    else:
-        blockquote.appendChild(paraElement("None"))
-
-    para = paraElement('Returns:')
-    blockquote = blockquoteElement()
-    para.appendChild(blockquote)
+    para = paraElement('Allowed Roles:')
+    para.appendChild(blockquoteElement(", ".join(func.roles)))
     section.appendChild(para)
 
-    head = rowElement(['Name', 'Type', 'Optional', 'Description'])
-    if isinstance(func.returns, Parameter):
-        doc = func.returns.doc
+    section.appendChild(paraElement('Parameters:'))
+    params = Element('itemizedlist')
+    if func.accepts:
+        for name, param, default in zip(max_args, func.accepts, defaults):
+            params.appendChild(paramElement(name, param))
     else:
-        doc = ""
-    indent = "  "
-    rows = parameters(func.returns, "", None, doc, "", indent)
-    informaltable = informaltableElement(head, rows)
-    informaltable.setAttribute('frame', "none")
-    informaltable.setAttribute('rules', "rows")
-    blockquote.appendChild(informaltable)
+        listitem = Element('listitem')
+        listitem.appendChild(paraElement('None'))
+        params.appendChild(listitem)
+    section.appendChild(params)
+
+    section.appendChild(paraElement('Returns:'))
+    returns = Element('itemizedlist')
+    returns.appendChild(paramElement(None, func.returns))
+    section.appendChild(returns)
 
     print section.toprettyxml(encoding = "UTF-8")