~ubuntu-branches/ubuntu/gutsy/pygame/gutsy

« back to all changes in this revision

Viewing changes to docs/util/makedocs.py

  • Committer: Bazaar Package Importer
  • Author(s): Ed Boraas
  • Date: 2002-02-20 06:39:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020220063924-amlzj7tqkeods4eq
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""take all the PyGame source and create html documentation"""
 
2
 
 
3
import fnmatch, glob, os, types
 
4
 
 
5
 
 
6
DOCPATTERN = '*static char*doc_*=*'
 
7
 
 
8
SOURCES = ['../../src/*.c']
 
9
IGNORE_SOURCES = ['rwobject.c']
 
10
PYTHONSRC =['cursors', 'version', 'sprite']
 
11
 
 
12
OUTPUTDIR = '../ref/'
 
13
PAGETEMPLATE = open('pagelate.html').readlines()
 
14
DOCTEMPLATE = open('doclate.html').readlines()
 
15
LISTTEMPLATE = open('listlate.html').readlines()
 
16
INDEXTEMPLATE = ['<a href=ref/{category}.html#{name}>{mod}.{name}</a> - {quick}<br>']
 
17
 
 
18
INDEXSTART = "\n<br><hr><br><font size=+1><b>Full Index</b></font><ul>\n<!--FULLINDEX-->\n"
 
19
INDEXEND = "<!--ENDINDEX-->\n</ul>\n"
 
20
 
 
21
MODULETOC = ""
 
22
 
 
23
 
 
24
mainindex_desc = """
 
25
The <b>pygame documentation</b> is mainly generated automatically from the
 
26
documentation. Each module and object in the package is broken into its
 
27
own page in the reference documentation. The names of the objects are
 
28
capitalized, while the regular module names are lower case.
 
29
<br>&nbsp;<br>
 
30
The <b>pygame documentation</b> also comes with a full set of tutorials.
 
31
You can find links to these tutorials and other documentation files below.
 
32
 
 
33
"""
 
34
 
 
35
 
 
36
 
 
37
def filltemplate(template, info):
 
38
    output = []
 
39
    for line in template:
 
40
        line = line.rstrip()
 
41
        pos = 0
 
42
        while 1:
 
43
            pos = line.find('{', pos)
 
44
            if pos == -1: break
 
45
            end = line.find('}', pos)
 
46
            if end == -1:
 
47
                pos += 1
 
48
                continue
 
49
            lookname = line[pos+1:end]
 
50
            match = info.get(lookname, '')
 
51
            if not match:
 
52
                pos = end
 
53
                continue
 
54
            try:line = line[:pos] + match + line[end+1:]
 
55
            except:
 
56
                print lookname, type(match), match
 
57
                raise
 
58
            pos += len(match) - (end-pos)
 
59
        output.append(line)
 
60
    return '\n'.join(output) + '\n'
 
61
 
 
62
 
 
63
 
 
64
def readsource(filename):
 
65
    documents = []
 
66
    file = open(filename)
 
67
    #read source
 
68
    while 1:
 
69
        line = file.readline()
 
70
        if not line: break
 
71
        if fnmatch.fnmatch(line, DOCPATTERN) and line.find(';') == -1:
 
72
            lines = [line]
 
73
            while 1:
 
74
                line = file.readline()
 
75
                if not line or line.find('"') == -1: break
 
76
                line = line[line.find('"')+1:line.rfind('"')]
 
77
                line = line.rstrip()
 
78
                if line == '\\n':
 
79
                    line = '<br>&nbsp;<br>'
 
80
                elif line.endswith('\\n'):
 
81
                    line = line[:-2]
 
82
                lines.append(line)
 
83
            documents.append(lines)
 
84
    return documents
 
85
 
 
86
 
 
87
def getpydoclines(doc):
 
88
    if doc is None: return
 
89
    lines = []
 
90
    for line in doc.split('\n'):
 
91
        if line == '':
 
92
            line = '<br>&nbsp;<br>'
 
93
        lines.append(line)
 
94
    return lines
 
95
 
 
96
 
 
97
def readpysource(name):
 
98
    modulename = 'pygame.' + name
 
99
    documents = []
 
100
    module = getattr(__import__(modulename), name)
 
101
    title = '    /*DOC*/ static char doc_pygame_' + name + '_MODULE[] =\n'
 
102
    documents.append([title] + getpydoclines(module.__doc__))
 
103
    modname = name
 
104
    for name, obj in module.__dict__.items():
 
105
        if type(obj) is types.ClassType:
 
106
            title = '    /*DOC*/ static char doc_%s[] =\n'%(name)
 
107
            initdocs = []
 
108
            if hasattr(obj, '__init__'):
 
109
                    init = getattr(obj, '__init__')
 
110
                    if hasattr(init, '__doc__'):
 
111
                            initdocs = getpydoclines(init.__doc__)
 
112
                            if not initdocs: initdocs = []
 
113
            try:
 
114
                docs = getpydoclines(obj.__doc__)
 
115
                if docs:
 
116
                    quick = '<b>(class)</b> - ' + docs[0]
 
117
                    usage = 'pygame.%s.%s()'%(modname,name)
 
118
                    if initdocs:
 
119
                        usage = 'pygame.%s.%s'%(modname,name) + initdocs[0][initdocs[0].find('('):]
 
120
                    docs = [usage,  quick,  '']+docs+['<br>&nbsp;<br>']+initdocs[2:]
 
121
                    documents.append([title] + docs)
 
122
 
 
123
            except AttributeError:
 
124
                documents.append([title] + ['%s.%s'&(modname,name),'noclassdocs'])
 
125
            for methname, meth in obj.__dict__.items():
 
126
                if methname is '__init__': continue
 
127
                title = '    /*DOC*/ static char doc_%s_%s[] =\n'%(name,methname)
 
128
                try:
 
129
                    docs = getpydoclines(meth.__doc__)
 
130
                    if docs:
 
131
                        docs[0] = ('pygame.%s.%s?'%(modname,name))+docs[0]
 
132
                        documents.append([title] + docs)
 
133
                except AttributeError: pass
 
134
 
 
135
        elif hasattr(obj, '__doc__'):
 
136
            title = '    /*DOC*/ static char doc_' + name + '[] =\n'
 
137
            documents.append([title] + getpydoclines(obj.__doc__))
 
138
    return documents
 
139
 
 
140
 
 
141
def parsedocs(docs):
 
142
    modules = {}
 
143
    extras = {}
 
144
    funcs = []
 
145
 
 
146
    for d in docs:
 
147
        modpos = d[0].find('_MODULE')
 
148
        extpos = d[0].find('_EXTRA')
 
149
 
 
150
        if modpos != -1:
 
151
            start = d[0].rfind(' ', 0, modpos)
 
152
            name = d[0][start+5:modpos]
 
153
            modules[name] = '\n'.join(d[1:])
 
154
        elif extpos != -1:
 
155
            start = d[0].rfind(' ', 0, extpos)
 
156
            name = d[0][start+5:extpos]
 
157
            extras[name] = '\n'.join(d[1:])
 
158
        else:
 
159
            obj = {'docs':['no documentation']}
 
160
            name = d[1][:d[1].find('(')]
 
161
            dot = name.rfind('.')
 
162
            name = name.replace('?', '.')
 
163
            if dot == -1:
 
164
                obj['category'] = 'misc'
 
165
                obj['name'] = name
 
166
                obj['fullname'] = name
 
167
            else:
 
168
                obj['category'] = name[:dot].replace('.', '_')
 
169
                obj['name'] = name[dot+1:]
 
170
                obj['fullname'] = name
 
171
            try:
 
172
                obj['usage'] = d[1].replace('?',  '.')
 
173
                obj['quick'] = d[2]
 
174
                obj['docs'] = d[4:]
 
175
            except IndexError: pass
 
176
            funcs.append(obj)
 
177
 
 
178
    return [modules, extras, funcs]
 
179
 
 
180
 
 
181
def getdocinfo(file, prefix=''):
 
182
    path = os.path.join(prefix, file[3:])
 
183
    prettyname = (os.path.splitext(os.path.split(file)[-1])[0])
 
184
    prettyname = prettyname[0].capitalize() + prettyname[1:]
 
185
    if file.find('html') >= 0:
 
186
        info = open(file).readlines(2)[1]
 
187
    else:
 
188
        info = open(file).readline().strip().capitalize()
 
189
    return path, prettyname, info
 
190
 
 
191
 
 
192
def findtutorials():
 
193
    fileline = '<li><a href=%s>%s</a> - %s</li>'
 
194
    texthead = '<font size=+1><b>Basic Documentation</b></font><br>'
 
195
    tuthead = '<font size=+1><b>Tutorials / Introductions</b></font><br>'
 
196
    texts1 =  ['../../readme.html', '../../install.html', '../LGPL', '../logos.html']
 
197
    texts = [fileline%x for x in [getdocinfo(x) for x in texts1]]
 
198
    finaltext = texthead + '\n'.join(texts)
 
199
    tuts1 =  glob.glob('../tut/*.html') 
 
200
    tuts1.sort()
 
201
    tuts = [fileline%(x[0],x[1],x[2][9:]) for x in [getdocinfo(x) for x in tuts1] if x[2].startswith('TUTORIAL:')]
 
202
    finaltut = tuthead + '\n'.join(tuts)
 
203
    return finaltext + '<br>&nbsp;<br>' + finaltut
 
204
 
 
205
 
 
206
def lookupdoc(docs, name, category):
 
207
    for d in docs:
 
208
        if d['fullname'] == category + '.' + name:
 
209
            return d
 
210
        if d['fullname'] == name or d['name'] == name:
 
211
            return d
 
212
 
 
213
 
 
214
def htmlize(doc, obj, func):
 
215
    for i in range(len(doc)):
 
216
        line = doc[i]
 
217
        line = line.replace('<<', '&lt;&lt;').replace('>>', '&gt;&gt;')
 
218
        pos = 0
 
219
        while 1:
 
220
            pos = line.find('(', pos+1)
 
221
            if pos == -1: break
 
222
            if line[pos-1].isspace(): continue
 
223
            start = line.rfind(' ', 0, pos)
 
224
            start2 = line.rfind('\n', 0, pos)
 
225
            start = max(max(start, start2), 0)
 
226
            lookname = line[start+1:pos]
 
227
            if lookname.startswith('ygame'):
 
228
                lookname = 'p' + lookname
 
229
                start -= 1
 
230
            elif lookname[1:].startswith('pygame'):
 
231
                lookname = lookname[1:]
 
232
                start += 1
 
233
            match = lookupdoc(func, lookname, obj['category'])
 
234
            if not match:
 
235
                #print 'NOMATCH: "'+ obj['category'] +'" "' + lookname + '"'
 
236
                continue
 
237
            end = line.find(')', pos)+1
 
238
            if match['fullname'] == obj['fullname']:
 
239
                link = '<u>%s</u>' % line[start+1:end]
 
240
            else:
 
241
                if match['category'] == obj['category']:
 
242
                    dest = '#%s' % (match['name'])
 
243
                else:
 
244
                    dest = '%s.html#%s' % (match['category'], match['name'])
 
245
                link = '<a href=%s>%s</a>' % (dest, line[start+1:end])
 
246
            line = line[:start+1] + link + line[end:]
 
247
            pos += len(link) - (pos-start)
 
248
        doc[i] = line
 
249
 
 
250
 
 
251
def buildlinks(alldocs):
 
252
    mod, ext, func = alldocs
 
253
    for obj in func:
 
254
        doc = obj['docs']
 
255
        htmlize(doc, obj, func)
 
256
    for k,i in mod.items():
 
257
        doc = [i]
 
258
        obj = {'category': k, 'fullname':''}
 
259
        htmlize(doc, obj, func)
 
260
        mod[k] = doc[0]
 
261
    for k,i in ext.items():
 
262
        doc = [i]
 
263
        obj = {'category': k, 'fullname':''}
 
264
        htmlize(doc, obj, func)
 
265
        ext[k] = doc[0]
 
266
 
 
267
 
 
268
def categorize(allfuncs):
 
269
    cats = {}
 
270
    for f in allfuncs:
 
271
        cat = f['category']
 
272
        if not cats.has_key(cat):
 
273
            cats[cat] = []
 
274
        cats[cat].append(f)
 
275
    return cats
 
276
 
 
277
 
 
278
 
 
279
def create_toc(allfuncs, prefix=''):
 
280
    mods = {}
 
281
    for f in allfuncs:
 
282
        cat = f['category']
 
283
        mods[cat] = ''
 
284
 
 
285
    l_mod = []
 
286
    l_py = []
 
287
    l_type = []
 
288
    for m in mods.keys():
 
289
        if m[7:] in PYTHONSRC:
 
290
            l = l_py
 
291
        elif m[0].lower() == m[0]:
 
292
            l = l_mod
 
293
        else:
 
294
            l = l_type
 
295
 
 
296
        file = m.replace('.', '_') + '.html'
 
297
        if m[:7] == 'pygame_':
 
298
            m = m[7:]
 
299
        str = '<a href=%s%s>%s</a>' % (prefix, file, m)
 
300
        l.append(str)
 
301
 
 
302
    l_py.sort()
 
303
    l_mod.sort()
 
304
    l_type.sort()
 
305
 
 
306
    str = ''
 
307
    items_per_line = 6
 
308
    for x in range(0, len(l_mod), items_per_line):
 
309
        row = l_mod[x:x+items_per_line]
 
310
        str += '|| ' + ' || \n'.join(row) + ' ||<br>\n'
 
311
    str += '&nbsp;<br>'
 
312
    for x in range(0, len(l_type), items_per_line):
 
313
        row = l_type[x:x+items_per_line]
 
314
        str += '|| ' + ' || \n'.join(row) + ' ||<br>\n'
 
315
    str += '&nbsp;<br>'
 
316
    for x in range(0, len(l_py), items_per_line):
 
317
        row = l_py[x:x+items_per_line]
 
318
        str += '|| ' + ' || \n'.join(row) + ' ||<br>\n'
 
319
 
 
320
    return str
 
321
 
 
322
 
 
323
def namesort(a,b): return cmp(a['name'], b['name'])
 
324
 
 
325
 
 
326
def writefuncdoc(alldocs):
 
327
    modules, extras, funcs = alldocs
 
328
    for cat, docs in funcs.items():
 
329
        htmldocs = []
 
330
        htmllist = []
 
331
        docs.sort(namesort)
 
332
        for d in docs:
 
333
            d['docs'] = '\n'.join(d['docs'])
 
334
            htmldocs.append(filltemplate(DOCTEMPLATE, d))
 
335
            htmllist.append(filltemplate(LISTTEMPLATE, d))
 
336
        modinfo = modules.get(cat, '')
 
337
        extrainfo = extras.get(cat, None)
 
338
        if extrainfo:
 
339
            modinfo += '<p>&nbsp;</p>' + extrainfo
 
340
 
 
341
        finalinfo = {'title': cat.replace('_', '.'),
 
342
                     'docs': '\n'.join(htmldocs),
 
343
                     'index': '\n'.join(htmllist),
 
344
                     'toc': MODULETOC,
 
345
                     'module': modinfo,
 
346
                     'mainpage': '../index.html',
 
347
                     'logo': '../pygame_tiny.gif'}
 
348
        page = filltemplate(PAGETEMPLATE, finalinfo)
 
349
        file = open(OUTPUTDIR + cat + '.html', 'w')
 
350
        file.write(page)
 
351
        file.close()
 
352
 
 
353
 
 
354
 
 
355
def makefullindex(alldocs):
 
356
    modules, extras, funcs = alldocs
 
357
    fullindex = []
 
358
    for cat, docs in funcs.items():
 
359
        htmldocs = []
 
360
        htmllist = []
 
361
        docs.sort(namesort)
 
362
        for d in docs:
 
363
            d['mod'] = d['category'].replace('_', '.')
 
364
            s = filltemplate(INDEXTEMPLATE, d)
 
365
            fullindex.append(s)
 
366
    fullindex.sort()
 
367
    return INDEXSTART + ''.join(fullindex) + INDEXEND
 
368
 
 
369
 
 
370
 
 
371
def main():
 
372
    #find all sources
 
373
    files = []
 
374
    for s in SOURCES:
 
375
        files += glob.glob(s)
 
376
    for f in files[:]:
 
377
        if os.path.split(f)[1] in IGNORE_SOURCES:
 
378
            files.remove(f)
 
379
 
 
380
    #load all sources
 
381
    print 'read c sources...'
 
382
    rawdocs = []
 
383
    for f in files:
 
384
        rawdocs += readsource(f)
 
385
 
 
386
    print 'read python sources...'
 
387
    for f in PYTHONSRC:
 
388
        rawdocs += readpysource(f)
 
389
 
 
390
 
 
391
    #parse sources
 
392
    alldocs = parsedocs(rawdocs)
 
393
 
 
394
    #find and create hyperlinks
 
395
    buildlinks(alldocs)
 
396
 
 
397
    #create table of contents
 
398
    global MODULETOC
 
399
    pathed_toc = create_toc(alldocs[2], 'ref/')
 
400
    MODULETOC = create_toc(alldocs[2])
 
401
 
 
402
    #categorize
 
403
    alldocs[2] = categorize(alldocs[2])
 
404
    #write html
 
405
    print 'writing...'
 
406
    writefuncdoc(alldocs)
 
407
 
 
408
    fulldocs = findtutorials() + makefullindex(alldocs)
 
409
    fulldocs = fulldocs
 
410
 
 
411
 
 
412
 
 
413
    #create index
 
414
    finalinfo = {'title': 'Pygame Documentation',
 
415
                 'docs': fulldocs,
 
416
                 'index': mainindex_desc,
 
417
                 'toc': pathed_toc,
 
418
                 'module': ' ',
 
419
                 'mainpage': 'index.html',
 
420
                 'logo': 'pygame_tiny.gif',
 
421
                }
 
422
    page = filltemplate(PAGETEMPLATE, finalinfo)
 
423
    file = open('../index.html', 'w')
 
424
    file.write(page)
 
425
    file.close()
 
426
 
 
427
 
 
428
if __name__ == '__main__':
 
429
    main()