3 # Generates a DocBook section documenting all PLCAPI methods on
6 # Mark Huang <mlhuang@cs.princeton.edu>
7 # Copyright (C) 2006 The Trustees of Princeton University
9 # $Id: DocBook.py,v 1.1 2006/09/06 15:34:41 mlhuang Exp $
12 import xml.dom.minidom
13 from xml.dom.minidom import Element, Text
16 from PLC.API import PLCAPI
17 from PLC.Method import *
21 # xml.dom.minidom.Text.writexml adds surrounding whitespace to textual
22 # data when pretty-printing. Override this behavior.
24 def writexml(self, writer, indent="", addindent="", newl=""):
25 Text.writexml(self, writer, "", "", "")
27 class TrimTextElement(Element):
28 def writexml(self, writer, indent="", addindent="", newl=""):
30 Element.writexml(self, writer, "", "", "")
33 class simpleElement(TrimTextElement):
34 """<tagName>text</tagName>"""
35 def __init__(self, tagName, text = None):
36 TrimTextElement.__init__(self, tagName)
39 t.data = unicode(text)
42 class paraElement(simpleElement):
43 """<para>text</para>"""
44 def __init__(self, text = None):
45 simpleElement.__init__(self, 'para', text)
47 class blockquoteElement(Element):
48 """<blockquote><para>text...</para><para>...text</para></blockquote>"""
49 def __init__(self, text = None):
50 Element.__init__(self, 'blockquote')
52 # Split on blank lines
53 lines = [line.strip() for line in text.strip().split("\n")]
54 lines = "\n".join(lines)
55 paragraphs = lines.split("\n\n")
57 for paragraph in paragraphs:
58 self.appendChild(paraElement(paragraph))
60 class entryElement(simpleElement):
61 """<entry>text</entry>"""
62 def __init__(self, text = None):
63 simpleElement.__init__(self, 'entry', text)
65 class rowElement(Element):
68 <entry>entries[0]</entry>
69 <entry>entries[1]</entry>
74 def __init__(self, entries = None):
75 Element.__init__(self, 'row')
78 if isinstance(entry, entryElement):
79 self.appendChild(entry)
81 self.appendChild(entryElement(entry))
83 class informaltableElement(Element):
96 <entry>row1value1</entry>
97 <entry>row1value2</entry>
106 def __init__(self, head = None, rows = None):
107 Element.__init__(self, 'informaltable')
108 tgroup = Element('tgroup')
109 self.appendChild(tgroup)
111 thead = Element('thead')
112 tgroup.appendChild(thead)
113 if isinstance(head, rowElement):
114 thead.appendChild(head)
116 thead.appendChild(rowElement(head))
118 tbody = Element('tbody')
119 tgroup.appendChild(tbody)
121 if isinstance(row, rowElement):
122 tbody.appendChild(row)
124 tobdy.appendChild(rowElement(row))
125 cols = len(thead.childNodes[0].childNodes)
126 tgroup.setAttribute('cols', str(cols))
128 def parameters(param, name, optional, doc, indent, step):
129 """Format a parameter into parameter row(s)."""
137 entry = entryElement()
138 entry.appendChild(simpleElement('literallayout', indent + name))
139 row.appendChild(entry)
142 param_type = python_type(param)
143 row.appendChild(entryElement(xmlrpc_type(param_type)))
145 # Whether parameter is optional
146 if optional is not None:
147 row.appendChild(entryElement(str(bool(optional))))
149 row.appendChild(entryElement(""))
151 # Parameter documentation
152 row.appendChild(entryElement(doc))
154 # Indent the name of each sub-parameter
156 if isinstance(param, dict):
157 subparams = param.iteritems()
158 elif isinstance(param, Mixed):
159 subparams = [(name, subparam) for subparam in param]
160 elif isinstance(param, (list, tuple)):
161 subparams = [("", subparam) for subparam in param]
163 for name, subparam in subparams:
164 if isinstance(subparam, Parameter):
165 (optional, doc) = (subparam.optional, subparam.doc)
167 (optional, doc) = (None, "")
168 rows += parameters(subparam, name, optional, doc, indent + step, step)
172 for method in api.methods:
173 func = api.callable(method)
174 (min_args, max_args, defaults) = func.args()
176 section = Element('section')
177 section.setAttribute('id', func.name)
178 section.appendChild(simpleElement('title', func.name))
180 para = paraElement('Status:')
181 para.appendChild(blockquoteElement(func.status))
182 section.appendChild(para)
184 prototype = "%s (%s)" % (method, ", ".join(max_args))
185 para = paraElement('Prototype:')
186 para.appendChild(blockquoteElement(prototype))
187 section.appendChild(para)
189 para = paraElement('Description:')
190 para.appendChild(blockquoteElement(func.__doc__))
191 section.appendChild(para)
193 para = paraElement('Parameters:')
194 blockquote = blockquoteElement()
195 para.appendChild(blockquote)
196 section.appendChild(para)
198 head = rowElement(['Name', 'Type', 'Optional', 'Description'])
202 for name, param, default in zip(max_args, func.accepts, defaults):
203 optional = name not in min_args
204 if isinstance(param, Parameter):
208 rows += parameters(param, name, optional, doc, "", indent)
211 informaltable = informaltableElement(head, rows)
212 informaltable.setAttribute('frame', "none")
213 informaltable.setAttribute('rules', "rows")
214 blockquote.appendChild(informaltable)
216 blockquote.appendChild(paraElement("None"))
218 print section.toprettyxml(encoding = "UTF-8")