epy doc generator that runs inside blender2.5, in background mode.
[blender-staging.git] / source / blender / python / epy_doc_gen.py
1  # ***** BEGIN GPL LICENSE BLOCK *****
2  #
3  # This program is free software; you can redistribute it and/or
4  # modify it under the terms of the GNU General Public License
5  # as published by the Free Software Foundation; either version 2
6  # of the License, or (at your option) any later version.
7  #
8  # This program is distributed in the hope that it will be useful,
9  # but WITHOUT ANY WARRANTY; without even the implied warranty of
10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  # GNU General Public License for more details.
12  #
13  # You should have received a copy of the GNU General Public License
14  # along with this program; if not, write to the Free Software Foundation,
15  # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16  #
17  # Contributor(s): Campbell Barton
18  #
19  # #**** END GPL LICENSE BLOCK #****
20
21 # Usage,
22 # run this script from blenders root path once you have compiled blender
23 # ./blender.bin -b -P source/blender/python/epy_doc_gen.py
24
25 # This will generate rna.py, generate html docs  by running...
26 # epydoc source/blender/python/doc/rna.py -o source/blender/python/doc/html -v --no-sourcecode --name="RNA API" --url="http://brechtvanlommelfanclub.com" --graph=classtree
27
28 # if you dont have graphvis installed ommit the --graph arg.
29
30
31
32 def rna2epy(target_path):
33         
34         def range_str(val):
35                 if val < -10000000:     return '-inf'
36                 if val >  10000000:     return 'inf'
37                 if type(val)==float:
38                         return '%g'  % val
39                 else:
40                         return str(val) 
41         
42         def write_struct(rna_struct):
43                 identifier = rna_struct.identifier
44                 
45                 rna_base = rna_struct.base
46                 
47                 if rna_base:
48                         out.write('class %s(%s):\n' % (identifier, rna_base.identifier))
49                 else:
50                         out.write('class %s:\n' % identifier)
51                 
52                 out.write('\t"""\n')
53                 
54                 title = 'The %s Object' % rna_struct.name
55                 
56                 out.write('\t%s\n' %  title)
57                 out.write('\t%s\n' %  ('=' * len(title)))
58                 out.write('\t\t%s\n' %  rna_struct.description)
59                 
60                 for rna_prop_identifier, rna_prop in rna_struct.properties.items():
61                         
62                         if rna_prop_identifier=='RNA':
63                                 continue
64                         
65                         if rna_prop_identifier=='rna_type':
66                                 continue
67                         
68                         rna_desc = rna_prop.description
69                         if not rna_desc: rna_desc = rna_prop.name
70                         if not rna_desc: rna_desc = 'Note - No documentation for this property!'
71                         
72                         rna_prop_type = rna_prop.type.lower()
73                         
74                         if rna_prop_type=='collection': collection_str = 'Collection of '
75                         else:                                                   collection_str = ''
76                         
77                         try:            rna_prop_ptr = rna_prop.fixed_type
78                         except: rna_prop_ptr = None
79                         
80                         try:            length = rna_prop.array_length
81                         except: length = 0
82                         
83                         if length > 0:  array_str = ' array of %d items' % length
84                         else:           array_str = ''
85                         
86                         if rna_prop.readonly:   readonly_str = ' (readonly)'
87                         else:                           readonly_str = ''
88                         
89                         if rna_prop_ptr: # Use the pointer type
90                                 out.write('\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
91                                 out.write('\t@type %s: %sL{%s}%s%s\n' %  (rna_prop_identifier, collection_str, rna_prop_ptr.identifier, array_str, readonly_str))
92                         else:
93                                 if rna_prop_type == 'enum':
94                                         out.write('\t@ivar %s: %s in (%s)\n' %  (rna_prop_identifier, rna_desc, ', '.join(rna_prop.items.keys())))
95                                         out.write('\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type,  array_str, readonly_str))
96                                 elif rna_prop_type == 'int' or rna_prop_type == 'float':
97                                         out.write('\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
98                                         out.write('\t@type %s: %s%s%s in [%s, %s]\n' %  (rna_prop_identifier, rna_prop_type, array_str, range_str(rna_prop.hard_min), range_str(rna_prop.hard_max), readonly_str ))
99                                 elif rna_prop_type == 'string':
100                                         out.write('\t@ivar %s: %s (maximum length of %s)\n' %  (rna_prop_identifier, rna_desc, rna_prop.max_length))
101                                         out.write('\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type, array_str, readonly_str))
102                                 else:
103                                         out.write('\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
104                                         out.write('\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type, array_str, readonly_str))
105                                 
106                         
107                 out.write('\t"""\n\n')
108         
109         
110         out = open(target_path, 'w')
111
112         def base_id(rna_struct):
113                 try:            return rna_struct.base.identifier
114                 except: return None
115
116         structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
117         structs.sort() # not needed but speeds up sort below, setting items without an inheritance first
118         
119         # Arrange so classes are always defined in the correct order
120         deps_ok = False
121         while deps_ok == False:
122                 deps_ok = True
123                 rna_done = set()
124                 
125                 for i, (rna_base, identifier, rna_struct) in enumerate(structs):
126                         
127                         rna_done.add(identifier)
128                         
129                         if rna_base and rna_base not in rna_done:
130                                 deps_ok = False
131                                 data = structs.pop(i)
132                                 ok = False
133                                 while i < len(structs):
134                                         if structs[i][1]==rna_base:
135                                                 structs.insert(i+1, data) # insert after the item we depend on.
136                                                 ok = True
137                                                 break
138                                         i+=1
139                                         
140                                 if not ok:
141                                         print('Dependancy "%s"could not be found for "%s"' % (identifier, rna_base))
142                                 
143                                 break
144         
145         structs = [data[2] for data in structs]
146         # Done ordering structs
147         
148         
149         for rna_struct in structs:
150                 write_struct(rna_struct)
151                 
152         out.write('\n')
153         out.close()
154         
155         # # We could also just run....
156         # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v')
157
158 if __name__ == '__main__':
159         rna2epy('source/blender/python/doc/rna.py')
160