]> granicus.if.org Git - zziplib/blob - docs/makedocs.py
07718703254eff639c418abbb947961aebb2aa91
[zziplib] / docs / makedocs.py
1 import sys
2 from zzipdoc.match import *
3 from zzipdoc.options import *
4 from zzipdoc.textfile import *
5 from zzipdoc.textfileheader import *
6 from zzipdoc.functionheader import *
7 from zzipdoc.functionprototype import *
8 from zzipdoc.commentmarkup import *
9 from zzipdoc.functionlisthtmlpage import *
10 from zzipdoc.functionlistreference import *
11 from zzipdoc.dbk2htm import *
12
13 def _src_to_xml(text):
14     return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
15 def _email_to_xml(text):
16     return text & Match("<([^<>]*@[^<>]*)>") >> "&lt;\\1&gt;"
17
18 class PerFileEntry:
19     def __init__(self, header, comment):
20         self.textfileheader = header
21         self.filecomment = comment
22 class PerFile:
23     def __init__(self):
24         self.textfileheaders = []
25         self.filecomments = []
26         self.entries = []
27     def add(self, textfileheader, filecomment):
28         self.textfileheaders += [ textfileheader ]
29         self.filecomments += [ filecomment ]
30         self.entries += [ PerFileEntry(textfileheader, filecomment) ]
31     def where_filename(self, filename):
32         for entry in self.entries:
33             if entry.textfileheader.get_filename() == filename:
34                 return entry
35         return None
36     def print_list_mainheader(self):
37         for t_fileheader in self.headers:
38             print t_fileheader.get_filename(), t_fileheader.src_mainheader()
39         
40 class PerFunctionEntry:
41     def __init__(self, header, comment, prototype):
42         self.header = header
43         self.comment = comment
44         self.prototype = prototype
45     def get_name(self):
46         return self.prototype.get_name()
47     def get_titleline(self):
48         return self.header.get_titleline()
49     def get_head(self):
50         return self.prototype
51     def get_body(self):
52         return self.comment
53 class PerFunction:
54     def __init__(self):
55         self.headers = []
56         self.comments = []
57         self.prototypes = []
58         self.entries = []
59     def add(self, functionheader, functioncomment, functionprototype):
60         self.headers += [ functionheader ]
61         self.comments += [ functionprototype ]
62         self.prototypes += [ functionprototype ]
63         self.entries += [ PerFunctionEntry(functionheader, functioncomment,
64                                            functionprototype) ]
65     def print_list_titleline(self):
66         for funcheader in self.headers:
67             print funcheader.get_filename(), "[=>]", funcheader.get_titleline()
68     def print_list_name(self):
69         for funcheader in self.prototypes:
70             print funcheader.get_filename(), "[>>]", funcheader.get_name()
71
72 class PerFunctionFamilyEntry:
73     def __init__(self, leader):
74         self.leader = leader
75         self.functions = []
76     def contains(self, func):
77         for item in self.functions:
78             if item == func: return True
79         return False
80     def add(self, func):
81         if not self.contains(func):
82             self.functions += [ func ]
83     def get_name(self):
84         if self.leader is None: return None
85         return self.leader.get_name()
86 class PerFunctionFamily:
87     def __init__(self):
88         self.functions = []
89         self.families = []
90         self.retarget = {}
91         self.entries = []
92     def add_PerFunction(self, per_list):
93         for item in per_list.entries:
94             add_PerFunctionEntry(item)
95     def add_PerFunctionEntry(self, item):
96         self.functions += [ item ]
97     def get_function(self, name):
98         for item in self.functions:
99             if item.get_name() == name:
100                 return item
101         return None
102     def get_entry(self, name):
103         for item in self.entries:
104             if item.get_name() == name:
105                 return item
106         return None
107     def fill_families(self):
108         name_list = {}
109         for func in self.functions:
110             name = func.get_name()
111             name_list[name] = func
112         for func in self.functions:
113             name = func.get_name()
114             line = func.get_titleline()
115             is_retarget = Match("=>\s*(\w+)")
116             if line & is_retarget:
117                 into = is_retarget[1]
118                 self.retarget[name] = is_retarget[1]
119         lead_list = []
120         for name in self.retarget:
121             into = self.retarget[name]
122             if into not in name_list:
123                 print ("function '"+name+"' retarget into '"+into+
124                        "' does not exist - keep alone")
125             if into in self.retarget:
126                 other = self.retarget[into]
127                 print ("function '"+name+"' retarget into '"+into+
128                        "' which is itself a retarget into '"+other+"'")
129             if into not in lead_list:
130                 lead_list += [ into ]
131         for func in self.functions:
132             name = func.get_name()
133             if name not in lead_list and name not in self.retarget:
134                 lead_list += [ name ]
135         for name in lead_list:
136             func = self.get_function(name)
137             if func is not None:
138                 entry = PerFunctionFamilyEntry(func)
139                 entry.add(func) # the first
140                 self.entries += [ entry ]
141             else:
142                 print "head function '"+name+" has no entry"
143         for func in self.functions:
144             name = func.get_name()
145             if name in self.retarget:
146                 into = self.retarget[name]
147                 entry = self.get_entry(into)
148                 if entry is not None:
149                     entry.add(func) # will not add duplicates
150                 else:
151                     print "into function '"+name+" has no entry"
152     def print_list_name(self):
153         for family in self.entries:
154             name = family.get_name()
155             print name, ":",
156             for item in family.functions:
157                 print item.get_name(), ",",
158             print ""
159 class HtmlManualPageAdapter:
160     def __init__(self, entry):
161         """ usually takes a PerFunctionEntry """
162         self.entry = entry
163     def get_name(self):
164         return self.entry.get_name()
165     def _head(self):
166         return self.entry.get_head()
167     def _body(self):
168         return self.entry.get_body()
169     def head_xml_text(self):
170         return self._head().xml_text()
171     def body_xml_text(self, name):
172         return self._body().xml_text(name)
173     def head_get_prespec(self):
174         return self._head().get_prespec()
175     def head_get_namespec(self):
176         return self._head().get_namespec()
177     def head_get_callspec(self):
178         return self._head().get_callspec()
179     def get_title(self):
180         return self._body().header.get_title()
181     def get_filename(self):
182         return self._body().header.get_filename()
183     def src_mainheader(self):
184         return self._body().header.parent.textfile.src_mainheader()
185     def get_mainheader(self):
186         return _src_to_xml(self.src_mainheader())
187 class RefEntryManualPageAdapter:
188     def __init__(self, entry, per_file = None):
189         """ usually takes a PerFunctionEntry """
190         self.entry = entry
191         self.per_file = per_file
192     def get_name(self):
193         return self.entry.get_name()
194     def _head(self):
195         return self.entry.get_head()
196     def _body(self):
197         return self.entry.get_body()
198     def _textfile(self):
199         return self._body().header.parent.textfile
200     def head_xml_text(self):
201         return self._head().xml_text()
202     def body_xml_text(self, name):
203         return self._body().xml_text(name)
204     def get_title(self):
205         return self._body().header.get_title()
206     def get_filename(self):
207         return self._body().header.get_filename()
208     def src_mainheader(self):
209         return self._textfile().src_mainheader()
210     def get_mainheader(self):
211         return _src_to_xml(self.src_mainheader())
212     def get_includes(self):
213         return ""
214     def list_seealso(self):
215         return self._body().header.get_alsolist()
216     def get_authors(self):
217         comment = None
218         if self.per_file:
219             entry = self.per_file.where_filename(self.get_filename())
220             if entry:
221                 comment = entry.filecomment.xml_text()
222         if comment:
223             check = Match(r"(?s)<para>\s*[Aa]uthors*\b:*"
224                           r"((?:.(?!</para>))*.)</para>")
225             if comment & check: return _email_to_xml(check[1])
226         return None
227     def get_copyright(self):
228         comment = None
229         if self.per_file:
230             entry = self.per_file.where_filename(self.get_filename())
231             if entry:
232                 comment = entry.filecomment.xml_text()
233         if comment:
234             check = Match(r"(?s)<para>\s*[Cc]opyright\b"
235                           r"((?:.(?!</para>))*.)</para>")
236             if comment & check: return _email_to_xml(check[0])
237         return None
238
239 def makedocs(filenames, o):
240     textfiles = []
241     for filename in filenames:
242         textfile = TextFile(filename)
243         textfile.parse()
244         textfiles += [ textfile ]
245     per_file = PerFile()
246     for textfile in textfiles:
247         textfileheader = TextFileHeader(textfile)
248         textfileheader.parse()
249         filecomment = CommentMarkup(textfileheader)
250         filecomment.parse()
251         per_file.add(textfileheader, filecomment)
252     funcheaders = []
253     for textfile in per_file.textfileheaders:
254         funcheader = FunctionHeaderList(textfile)
255         funcheader.parse()
256         funcheaders += [ funcheader ]
257     per_function = PerFunction()
258     for funcheader in funcheaders:
259         for child in funcheader.get_children():
260             funcprototype = FunctionPrototype(child)
261             funcprototype.parse()
262             funccomment = CommentMarkup(child)
263             funccomment.parse()
264             per_function.add(child, funccomment, funcprototype)
265     per_family = PerFunctionFamily()
266     for item in per_function.entries:
267         per_family.add_PerFunctionEntry(item)
268     per_family.fill_families()
269     # debug output....
270     # per_file.print_list_mainheader()
271     # per_function.print_list_titleline()
272     # per_function.print_list_name()
273     per_family.print_list_name()
274     html = FunctionListHtmlPage(o)
275     for item in per_family.entries:
276         for func in item.functions:
277             func_adapter = HtmlManualPageAdapter(func)
278             if o.onlymainheader and not (Match("<"+o.onlymainheader+">")
279                                          & func_adapter.src_mainheader()):
280                     continue
281             html.add(func_adapter)
282         html.cut()
283     html.cut()
284     html_filename = "zziplib"+o.suffix+".html"
285     try:
286         print "writing "+html_filename
287         fd = open(html_filename, "w")
288         print >>fd, section2html(paramdef2html(html.xml_text()))
289         fd.close()
290     except IOError, e:
291         print "could not open '"+html_filename+"'file", e
292     man3 = FunctionListReference(o)
293     for item in per_family.entries:
294         for func in item.functions:
295             func_adapter = RefEntryManualPageAdapter(func, per_file)
296             if o.onlymainheader and not (Match("<"+o.onlymainheader+">")
297                                          & func_adapter.src_mainheader()):
298                     continue
299             man3.add(func_adapter)
300             man3.add_overview(func_adapter)
301         man3.cut()
302     man3.cut()
303     man3_filename = "zziplib"+o.suffix+".docbook"
304     try:
305         print "writing "+man3_filename
306         fd = open(man3_filename, "w")
307         print >>fd, man3.xml_text()
308         fd.close()
309     except IOError, e:
310         print "could not open '"+man3_filename+"'file", e
311     
312         
313 if __name__ == "__main__":
314     filenames = []
315     o = Options()
316     o.package = "ZZipLib"
317     o.program = sys.argv[0]
318     for item in sys.argv[1:]:
319         if o.scan(item): continue
320         filenames += [ item ]
321     makedocs(filenames, o)
322     
323