2 # -*- Mode: Python; py-indent-offset: 4 -*-
3 import sys, os, string, re, getopt
11 def __init__(self, name, interfaces=[]):
13 self.interfaces = interfaces
15 def add_child(self, node):
16 self.subclasses.append(node)
18 def build_object_tree(parser):
19 # reorder objects so that parent classes come first ...
20 objects = parser.objects[:]
22 while pos < len(objects):
23 parent = objects[pos].parent
24 for i in range(pos+1, len(objects)):
25 if objects[i].c_name == parent:
26 objects.insert(i+1, objects[pos])
33 nodes = { None: root }
34 for obj_def in objects:
36 parent_node = nodes[obj_def.parent]
37 node = Node(obj_def.c_name, obj_def.implements)
38 parent_node.add_child(node)
39 nodes[node.name] = node
42 interfaces = Node('gobject.GInterface')
43 root.add_child(interfaces)
44 nodes[interfaces.name] = interfaces
45 for obj_def in parser.interfaces:
46 node = Node(obj_def.c_name)
47 interfaces.add_child(node)
48 nodes[node.name] = node
51 boxed = Node('gobject.GBoxed')
53 nodes[boxed.name] = boxed
54 for obj_def in parser.boxes:
55 node = Node(obj_def.c_name)
57 nodes[node.name] = node
60 pointers = Node('gobject.GPointer')
61 root.add_child(pointers)
62 nodes[pointers.name] = pointers
63 for obj_def in parser.pointers:
64 node = Node(obj_def.c_name)
65 pointers.add_child(node)
66 nodes[node.name] = node
73 self.parser = defsparser.DefsParser(())
74 self.overrides = override.Overrides()
78 def add_sourcedirs(self, source_dirs):
79 self.docs = docextract.extract(source_dirs, self.docs)
80 def add_tmpldirs(self, tmpl_dirs):
81 self.docs = docextract.extract_tmpl(tmpl_dirs, self.docs)
83 def add_docs(self, defs_file, overrides_file, module_name):
84 '''parse information about a given defs file'''
85 self.parser.filename = defs_file
86 self.parser.startParsing(defs_file)
88 self.overrides.handle_file(overrides_file)
90 for obj in self.parser.objects:
91 if not self.classmap.has_key(obj.c_name):
92 self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
93 for obj in self.parser.interfaces:
94 if not self.classmap.has_key(obj.c_name):
95 self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
96 for obj in self.parser.boxes:
97 if not self.classmap.has_key(obj.c_name):
98 self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
99 for obj in self.parser.pointers:
100 if not self.classmap.has_key(obj.c_name):
101 self.classmap[obj.c_name] = '%s.%s' % (module_name, obj.name)
103 def pyname(self, name):
104 return self.classmap.get(name, name)
106 def __compare(self, obja, objb):
107 return cmp(self.pyname(obja.c_name), self.pyname(objb.c_name))
108 def output_docs(self, output_prefix):
112 hierarchy = build_object_tree(self.parser)
113 filename = self.create_filename('hierarchy', output_prefix)
114 fp = open(filename, 'w')
115 self.write_full_hierarchy(hierarchy, fp)
118 obj_defs = self.parser.objects + self.parser.interfaces + \
119 self.parser.boxes + self.parser.pointers
120 obj_defs.sort(self.__compare)
121 for obj_def in obj_defs:
122 filename = self.create_filename(obj_def.c_name, output_prefix)
123 fp = open(filename, 'w')
124 if isinstance(obj_def, definitions.ObjectDef):
125 self.output_object_docs(obj_def, fp)
126 elif isinstance(obj_def, definitions.InterfaceDef):
127 self.output_interface_docs(obj_def, fp)
128 elif isinstance(obj_def, definitions.BoxedDef):
129 self.output_boxed_docs(obj_def, fp)
130 elif isinstance(obj_def, definitions.PointerDef):
131 self.output_boxed_docs(obj_def, fp)
133 files.append((os.path.basename(filename), obj_def))
136 filename = self.create_toc_filename(output_prefix)
137 fp = open(filename, 'w')
138 self.output_toc(files, fp)
141 def output_object_docs(self, obj_def, fp=sys.stdout):
142 self.write_class_header(obj_def.c_name, fp)
144 self.write_heading('Synopsis', fp)
145 self.write_synopsis(obj_def, fp)
146 self.close_section(fp)
148 # construct the inheritence hierarchy ...
149 ancestry = [ (obj_def.c_name, obj_def.implements) ]
151 parent = obj_def.parent
152 while parent != None:
153 if parent == 'GObject':
154 ancestry.append(('GObject', []))
157 parent_def = self.parser.find_object(parent)
158 ancestry.append((parent_def.c_name, parent_def.implements))
159 parent = parent_def.parent
163 self.write_heading('Ancestry', fp)
164 self.write_hierarchy(obj_def.c_name, ancestry, fp)
165 self.close_section(fp)
167 constructor = self.parser.find_constructor(obj_def, self.overrides)
169 self.write_heading('Constructor', fp)
170 self.write_constructor(constructor,
171 self.docs.get(constructor.c_name, None),
173 self.close_section(fp)
175 methods = self.parser.find_methods(obj_def)
176 methods = filter(lambda meth, self=self:
177 not self.overrides.is_ignored(meth.c_name), methods)
179 self.write_heading('Methods', fp)
180 for method in methods:
181 self.write_method(method, self.docs.get(method.c_name, None), fp)
182 self.close_section(fp)
184 self.write_class_footer(obj_def.c_name, fp)
186 def output_interface_docs(self, int_def, fp=sys.stdout):
187 self.write_class_header(int_def.c_name, fp)
189 self.write_heading('Synopsis', fp)
190 self.write_synopsis(int_def, fp)
191 self.close_section(fp)
193 methods = self.parser.find_methods(int_def)
194 methods = filter(lambda meth, self=self:
195 not self.overrides.is_ignored(meth.c_name), methods)
197 self.write_heading('Methods', fp)
198 for method in methods:
199 self.write_method(method, self.docs.get(method.c_name, None), fp)
200 self.close_section(fp)
202 self.write_class_footer(int_def.c_name, fp)
204 def output_boxed_docs(self, box_def, fp=sys.stdout):
205 self.write_class_header(box_def.c_name, fp)
207 self.write_heading('Synopsis', fp)
208 self.write_synopsis(box_def, fp)
209 self.close_section(fp)
211 constructor = self.parser.find_constructor(box_def, self.overrides)
213 self.write_heading('Constructor', fp)
214 self.write_constructor(constructor,
215 self.docs.get(constructor.c_name, None),
217 self.close_section(fp)
219 methods = self.parser.find_methods(box_def)
220 methods = filter(lambda meth, self=self:
221 not self.overrides.is_ignored(meth.c_name), methods)
223 self.write_heading('Methods', fp)
224 for method in methods:
225 self.write_method(method, self.docs.get(method.c_name, None), fp)
226 self.close_section(fp)
228 self.write_class_footer(box_def.c_name, fp)
230 def output_toc(self, files, fp=sys.stdout):
232 for filename, obj_def in files:
233 fp.write(obj_def.c_name + ' - ' + filename + '\n')
235 # override the following to create a more complex output format
236 def create_filename(self, obj_name, output_prefix):
237 '''Create output filename for this particular object'''
238 return output_prefix + '-' + string.lower(obj_name) + '.txt'
239 def create_toc_filename(self, output_prefix):
240 return self.create_filename(self, 'docs', output_prefix)
242 def write_full_hierarchy(self, hierarchy, fp):
243 def handle_node(node, fp, indent=''):
244 for child in node.subclasses:
245 fp.write(indent + node.name)
247 fp.write(' (implements ')
248 fp.write(string.join(node.interfaces, ', '))
252 handle_node(child, fp, indent + ' ')
253 handle_node(hierarchy, fp)
255 # these need to handle default args ...
256 def create_constructor_prototype(self, func_def):
257 return func_def.is_constructor_of + '(' + \
258 string.join(map(lambda x: x[1], func_def.params), ', ') + \
260 def create_function_prototype(self, func_def):
261 return func_def.name + '(' + \
262 string.join(map(lambda x: x[1], func_def.params), ', ') + \
264 def create_method_prototype(self, meth_def):
265 return meth_def.of_object + '.' + \
266 meth_def.name + '(' + \
267 string.join(map(lambda x: x[1], meth_def.params), ', ') + \
270 def write_class_header(self, obj_name, fp):
271 fp.write('Class %s\n' % obj_name)
272 fp.write('======%s\n\n' % ('=' * len(obj_name)))
273 def write_class_footer(self, obj_name, fp):
275 def write_heading(self, text, fp):
276 fp.write('\n' + text + '\n' + ('-' * len(text)) + '\n')
277 def close_section(self, fp):
279 def write_synopsis(self, obj_def, fp):
280 fp.write('class %s' % obj_def.c_name)
281 if isinstance(obj_def, definitions.ObjectDef):
283 if obj_def.parent: bases.append(obj_def.parent)
284 bases = bases = obj_def.implements
286 fp.write('(%s)' % string.join(bases, ', '))
289 constructor = self.parser.find_constructor(obj_def, self.overrides)
291 prototype = self.create_constructor_prototype(constructor)
292 fp.write(' def %s\n' % prototype)
293 methods = self.parser.find_methods(obj_def)
294 methods = filter(lambda meth, self=self:
295 not self.overrides.is_ignored(meth.c_name), methods)
297 prototype = self.create_method_prototype(meth)
298 fp.write(' def %s\n' % prototype)
300 def write_hierarchy(self, obj_name, ancestry, fp):
302 for name, interfaces in ancestry:
303 fp.write(indent + '+-- ' + name)
305 fp.write(' (implements ')
306 fp.write(string.join(interfaces, ', '))
310 indent = indent + ' '
312 def write_constructor(self, func_def, func_doc, fp):
313 prototype = self.create_constructor_prototype(func_def)
314 fp.write(prototype + '\n\n')
315 for type, name, dflt, null in func_def.params:
317 descr = func_doc.get_param_description(name)
320 fp.write(' ' + name + ': ' + descr + '\n')
321 if func_def.ret and func_def.ret != 'none':
322 if func_doc and func_doc.ret:
325 descr = 'a ' + func_def.ret
326 fp.write(' Returns: ' + descr + '\n')
327 if func_doc and func_doc.description:
328 fp.write(func_doc.description)
330 def write_method(self, meth_def, func_doc, fp):
331 prototype = self.create_method_prototype(meth_def)
332 fp.write(prototype + '\n\n')
333 for type, name, dflt, null in meth_def.params:
335 descr = func_doc.get_param_description(name)
338 fp.write(' ' + name + ': ' + descr + '\n')
339 if meth_def.ret and meth_def.ret != 'none':
340 if func_doc and func_doc.ret:
343 descr = 'a ' + meth_def.ret
344 fp.write(' Returns: ' + descr + '\n')
345 if func_doc and func_doc.description:
347 fp.write(func_doc.description)
350 class DocbookDocWriter(DocWriter):
351 def __init__(self, use_xml=0):
352 DocWriter.__init__(self)
353 self.use_xml = use_xml
355 def create_filename(self, obj_name, output_prefix):
356 '''Create output filename for this particular object'''
357 stem = output_prefix + '-' + string.lower(obj_name)
361 return stem + '.sgml'
362 def create_toc_filename(self, output_prefix):
364 return self.create_filename('classes', output_prefix)
366 return self.create_filename('docs', output_prefix)
368 # make string -> reference translation func
369 __transtable = [ '-' ] * 256
370 for digit in '0123456789':
371 __transtable[ord(digit)] = digit
372 for letter in 'abcdefghijklmnopqrstuvwxyz':
373 __transtable[ord(letter)] = letter
374 __transtable[ord(string.upper(letter))] = letter
375 __transtable = string.join(__transtable, '')
377 def make_class_ref(self, obj_name):
378 return 'class-' + string.translate(obj_name, self.__transtable)
379 def make_method_ref(self, meth_def):
380 return 'method-' + string.translate(meth_def.of_object,
381 self.__transtable) + \
382 '--' + string.translate(meth_def.name, self.__transtable)
384 __function_pat = re.compile(r'(\w+)\s*\(\)')
385 def __format_function(self, match):
386 info = self.parser.c_name.get(match.group(1), None)
388 if isinstance(info, defsparser.FunctionDef):
389 if info.is_constructor_of is not None:
390 # should have a link here
391 return '<function>%s()</function>' % \
392 self.pyname(info.is_constructor_of)
394 return '<function>' + info.name + '()</function>'
395 if isinstance(info, defsparser.MethodDef):
396 return '<link linkend="' + self.make_method_ref(info) + \
397 '"><function>' + self.pyname(info.of_object) + '.' + \
398 info.name + '()</function></link>'
399 # fall through through
400 return '<function>' + match.group(1) + '()</function>'
401 __parameter_pat = re.compile(r'\@(\w+)')
402 def __format_param(self, match):
403 return '<parameter>' + match.group(1) + '</parameter>'
404 __constant_pat = re.compile(r'\%(-?\w+)')
405 def __format_const(self, match):
406 return '<literal>' + match.group(1) + '</literal>'
407 __symbol_pat = re.compile(r'#([\w-]+)')
408 def __format_symbol(self, match):
409 info = self.parser.c_name.get(match.group(1), None)
411 if isinstance(info, defsparser.FunctionDef):
412 if info.is_constructor_of is not None:
413 # should have a link here
414 return '<methodname>' + self.pyname(info.is_constructor_of) + \
417 return '<function>' + info.name + '</function>'
418 if isinstance(info, defsparser.MethodDef):
419 return '<link linkend="' + self.make_method_ref(info) + \
420 '"><methodname>' + self.pyname(info.of_object) + '.' + \
421 info.name + '</methodname></link>'
422 if isinstance(info, defsparser.ObjectDef) or \
423 isinstance(info, defsparser.InterfaceDef) or \
424 isinstance(info, defsparser.BoxedDef) or \
425 isinstance(info, defsparser.PointerDef):
426 return '<link linkend="' + self.make_class_ref(info.c_name) + \
427 '"><classname>' + self.pyname(info.c_name) + \
428 '</classname></link>'
429 # fall through through
430 return '<literal>' + match.group(1) + '</literal>'
432 def reformat_text(self, text, singleline=0):
433 # replace special strings ...
434 text = self.__function_pat.sub(self.__format_function, text)
435 text = self.__parameter_pat.sub(self.__format_param, text)
436 text = self.__constant_pat.sub(self.__format_const, text)
437 text = self.__symbol_pat.sub(self.__format_symbol, text)
439 # don't bother with <para> expansion for single line text.
440 if singleline: return text
442 lines = string.split(string.strip(text), '\n')
443 for index in range(len(lines)):
444 if string.strip(lines[index]) == '':
445 lines[index] = '</para>\n<para>'
447 lines.insert(0, '<para>')
448 lines.append('</para>')
449 return string.join(lines, '\n')
451 # write out hierarchy
452 def write_full_hierarchy(self, hierarchy, fp):
453 def handle_node(node, fp, indent=''):
455 fp.write('%s<link linkend="%s">%s</link>' %
456 (indent, self.make_class_ref(node.name),
457 self.pyname(node.name)))
459 fp.write(' (implements ')
460 for i in range(len(node.interfaces)):
461 fp.write('<link linkend="%s">%s</link>' %
462 (self.make_class_ref(node.interfaces[i]),
463 self.pyname(node.interfaces[i])))
464 if i != len(node.interfaces) - 1:
470 indent = indent + ' '
471 node.subclasses.sort(lambda a,b:
472 cmp(self.pyname(a.name), self.pyname(b.name)))
473 for child in node.subclasses:
474 handle_node(child, fp, indent)
476 fp.write('<?xml version="1.0" standalone="no"?>\n')
477 fp.write('<!DOCTYPE synopsis PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
478 fp.write(' "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
479 fp.write('<synopsis>')
480 handle_node(hierarchy, fp)
481 fp.write('</synopsis>\n')
483 # these need to handle default args ...
484 def create_constructor_prototype(self, func_def):
485 sgml = [ '<constructorsynopsis language="python">\n']
486 sgml.append(' <methodname>__init__</methodname>\n')
487 for type, name, dflt, null in func_def.params:
488 sgml.append(' <methodparam><parameter>')
490 sgml.append('</parameter>')
492 sgml.append('<initializer>')
494 sgml.append('</initializer>')
495 sgml.append('</methodparam>\n')
496 if not func_def.params:
497 sgml.append(' <methodparam></methodparam>')
498 sgml.append(' </constructorsynopsis>')
499 return string.join(sgml, '')
500 def create_function_prototype(self, func_def):
501 sgml = [ '<funcsynopsis language="python">\n <funcprototype>\n']
502 sgml.append(' <funcdef><function>')
503 sgml.append(func_def.name)
504 sgml.append('</function></funcdef>\n')
505 for type, name, dflt, null in func_def.params:
506 sgml.append(' <paramdef><parameter>')
508 sgml.append('</parameter>')
510 sgml.append('<initializer>')
512 sgml.append('</initializer>')
513 sgml.append('</paramdef>\n')
514 if not func_def.params:
515 sgml.append(' <paramdef></paramdef')
516 sgml.append(' </funcprototype>\n </funcsynopsis>')
517 return string.join(sgml, '')
518 def create_method_prototype(self, meth_def, addlink=0):
519 sgml = [ '<methodsynopsis language="python">\n']
520 sgml.append(' <methodname>')
522 sgml.append('<link linkend="%s">' % self.make_method_ref(meth_def))
523 sgml.append(self.pyname(meth_def.name))
525 sgml.append('</link>')
526 sgml.append('</methodname>\n')
527 for type, name, dflt, null in meth_def.params:
528 sgml.append(' <methodparam><parameter>')
530 sgml.append('</parameter>')
532 sgml.append('<initializer>')
534 sgml.append('</initializer>')
535 sgml.append('</methodparam>\n')
536 if not meth_def.params:
537 sgml.append(' <methodparam></methodparam>')
538 sgml.append(' </methodsynopsis>')
539 return string.join(sgml, '')
541 def write_class_header(self, obj_name, fp):
543 fp.write('<?xml version="1.0" standalone="no"?>\n')
544 fp.write('<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
545 fp.write(' "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
546 fp.write('<refentry id="' + self.make_class_ref(obj_name) + '">\n')
547 fp.write(' <refmeta>\n')
548 fp.write(' <refentrytitle>%s</refentrytitle>\n'
549 % self.pyname(obj_name))
550 fp.write(' <manvolnum>3</manvolnum>\n')
551 fp.write(' <refmiscinfo>PyGTK Docs</refmiscinfo>\n')
552 fp.write(' </refmeta>\n\n')
553 fp.write(' <refnamediv>\n')
554 fp.write(' <refname>%s</refname><refpurpose></refpurpose>\n'
555 % self.pyname(obj_name))
556 fp.write(' </refnamediv>\n\n')
557 def write_class_footer(self, obj_name, fp):
558 fp.write('</refentry>\n')
559 def write_heading(self, text, fp):
560 fp.write(' <refsect1>\n')
561 fp.write(' <title>' + text + '</title>\n\n')
562 def close_section(self, fp):
563 fp.write(' </refsect1>\n')
565 def write_synopsis(self, obj_def, fp):
566 fp.write('<classsynopsis language="python">\n')
567 fp.write(' <ooclass><classname>%s</classname></ooclass>\n'
568 % self.pyname(obj_def.c_name))
569 if isinstance(obj_def, definitions.ObjectDef):
571 fp.write(' <ooclass><classname><link linkend="%s">%s'
572 '</link></classname></ooclass>\n'
573 % (self.make_class_ref(obj_def.parent),
574 self.pyname(obj_def.parent)))
575 for base in obj_def.implements:
576 fp.write(' <ooclass><classname><link linkend="%s">%s'
577 '</link></classname></ooclass>\n'
578 % (self.make_class_ref(base), self.pyname(base)))
579 elif isinstance(obj_def, definitions.InterfaceDef):
580 fp.write(' <ooclass><classname>gobject.GInterface'
581 '</classname></ooclass>\n')
582 elif isinstance(obj_def, definitions.BoxedDef):
583 fp.write(' <ooclass><classname>gobject.GBoxed'
584 '</classname></ooclass>\n')
585 elif isinstance(obj_def, definitions.PointerDef):
586 fp.write(' <ooclass><classname>gobject.GPointer'
587 '</classname></ooclass>\n')
589 constructor = self.parser.find_constructor(obj_def, self.overrides)
591 fp.write('%s\n' % self.create_constructor_prototype(constructor))
592 methods = self.parser.find_methods(obj_def)
593 methods = filter(lambda meth, self=self:
594 not self.overrides.is_ignored(meth.c_name), methods)
596 fp.write('%s\n' % self.create_method_prototype(meth, addlink=1))
597 fp.write('</classsynopsis>\n\n')
599 def write_hierarchy(self, obj_name, ancestry, fp):
600 fp.write('<synopsis>')
602 for name, interfaces in ancestry:
603 fp.write(indent + '+-- <link linkend="' +
604 self.make_class_ref(name) + '">'+ self.pyname(name) + '</link>')
606 fp.write(' (implements ')
607 for i in range(len(interfaces)):
608 fp.write('<link linkend="%s">%s</link>' %
609 (self.make_class_ref(interfaces[i]),
610 self.pyname(interfaces[i])))
611 if i != len(interfaces) - 1:
616 indent = indent + ' '
617 fp.write('</synopsis>\n\n')
619 def write_params(self, params, ret, func_doc, fp):
620 if not params and (not ret or ret == 'none'):
622 fp.write(' <variablelist>\n')
623 for type, name, dflt, null in params:
625 descr = string.strip(func_doc.get_param_description(name))
628 fp.write(' <varlistentry>\n')
629 fp.write(' <term><parameter>%s</parameter> :</term>\n' % name)
630 fp.write(' <listitem><simpara>%s</simpara></listitem>\n' %
631 self.reformat_text(descr, singleline=1))
632 fp.write(' </varlistentry>\n')
633 if ret and ret != 'none':
634 if func_doc and func_doc.ret:
635 descr = string.strip(func_doc.ret)
638 fp.write(' <varlistentry>\n')
639 fp.write(' <term><emphasis>Returns</emphasis> :</term>\n')
640 fp.write(' <listitem><simpara>%s</simpara></listitem>\n' %
641 self.reformat_text(descr, singleline=1))
642 fp.write(' </varlistentry>\n')
643 fp.write(' </variablelist>\n')
645 def write_constructor(self, func_def, func_doc, fp):
646 prototype = self.create_constructor_prototype(func_def)
647 fp.write('<programlisting>%s</programlisting>\n' % prototype)
648 self.write_params(func_def.params, func_def.ret, func_doc, fp)
650 if func_doc and func_doc.description:
651 fp.write(self.reformat_text(func_doc.description))
654 def write_method(self, meth_def, func_doc, fp):
655 fp.write(' <refsect2 id="' + self.make_method_ref(meth_def) + '">\n')
656 fp.write(' <title>' + self.pyname(meth_def.of_object) + '.' +
657 meth_def.name + '</title>\n\n')
658 prototype = self.create_method_prototype(meth_def)
659 fp.write('<programlisting>%s</programlisting>\n' % prototype)
660 self.write_params(meth_def.params, meth_def.ret, func_doc, fp)
661 if func_doc and func_doc.description:
662 fp.write(self.reformat_text(func_doc.description))
663 fp.write(' </refsect2>\n\n\n')
665 def output_toc(self, files, fp=sys.stdout):
667 fp.write('<?xml version="1.0" standalone="no"?>\n')
668 fp.write('<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"\n')
669 fp.write(' "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">\n')
670 #for filename, obj_def in files:
671 # fp.write(' <!ENTITY ' + string.translate(obj_def.c_name,
672 # self.__transtable) +
673 # ' SYSTEM "' + filename + '" >\n')
676 #fp.write('<reference id="class-reference">\n')
677 #fp.write(' <title>Class Documentation</title>\n')
678 #for filename, obj_def in files:
679 # fp.write('&' + string.translate(obj_def.c_name,
680 # self.__transtable) + ';\n')
681 #fp.write('</reference>\n')
683 fp.write('<reference id="class-reference" xmlns:xi="http://www.w3.org/2001/XInclude">\n')
684 fp.write(' <title>Class Reference</title>\n')
685 for filename, obj_def in files:
686 fp.write(' <xi:include href="%s"/>\n' % filename)
687 fp.write('</reference>\n')
689 fp.write('<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1.2//EN" [\n')
690 for filename, obj_def in files:
691 fp.write(' <!ENTITY ' + string.translate(obj_def.c_name,
693 ' SYSTEM "' + filename + '" >\n')
696 fp.write('<book id="index">\n\n')
697 fp.write(' <bookinfo>\n')
698 fp.write(' <title>PyGTK Docs</title>\n')
699 fp.write(' <authorgroup>\n')
700 fp.write(' <author>\n')
701 fp.write(' <firstname>James</firstname>\n')
702 fp.write(' <surname>Henstridge</surname>\n')
703 fp.write(' </author>\n')
704 fp.write(' </authorgroup>\n')
705 fp.write(' </bookinfo>\n\n')
707 fp.write(' <chapter id="class-hierarchy">\n')
708 fp.write(' <title>Class Hierarchy</title>\n')
709 fp.write(' <para>Not done yet</para>\n')
710 fp.write(' </chapter>\n\n')
712 fp.write(' <reference id="class-reference">\n')
713 fp.write(' <title>Class Documentation</title>\n')
714 for filename, obj_def in files:
715 fp.write('&' + string.translate(obj_def.c_name,
716 self.__transtable) + ';\n')
718 fp.write(' </reference>\n')
719 fp.write('</book>\n')
721 if __name__ == '__main__':
723 opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
724 ["defs-file=", "override=", "source-dir=",
726 except getopt.error, e:
727 sys.stderr.write('docgen.py: %s\n' % e)
729 'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
732 overrides_file = None
734 output_prefix = 'docs'
735 for opt, arg in opts:
736 if opt in ('-d', '--defs-file'):
738 if opt in ('--override',):
740 elif opt in ('-s', '--source-dir'):
741 source_dirs.append(arg)
742 elif opt in ('-o', '--output-prefix'):
744 if len(args) != 0 or not defs_file:
746 'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
749 d = DocbookDocWriter()
750 d.add_sourcedirs(source_dirs)
751 d.add_docs(defs_file, overrides_file, 'gtk')
752 d.output_docs(output_prefix)