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