ok anoter compile fix
[blender.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 def range_str(val):
31         if val < -10000000:     return '-inf'
32         if val >  10000000:     return 'inf'
33         if type(val)==float:
34                 return '%g'  % val
35         else:
36                 return str(val) 
37
38 def get_array_str(length):
39         if length > 0:  return ' array of %d items' % length
40         else:           return ''
41
42 def rna2epy(target_path):
43         
44
45         
46         def write_struct(rna_struct, structs, ident):
47                 identifier = rna_struct.identifier
48                 
49                 rna_base = rna_struct.base
50                 
51                 if rna_base:
52                         out.write(ident+ 'class %s(%s):\n' % (identifier, rna_base.identifier))
53                 else:
54                         out.write(ident+ 'class %s:\n' % identifier)
55                 
56                 out.write(ident+ '\t"""\n')
57                 
58                 title = 'The %s Object' % rna_struct.name
59                 
60                 out.write(ident+ '\t%s\n' %  title)
61                 out.write(ident+ '\t%s\n' %  ('=' * len(title)))
62                 out.write(ident+ '\t\t%s\n' %  rna_struct.description)
63                 
64                 for rna_prop_identifier, rna_prop in rna_struct.properties.items():
65                         
66                         if rna_prop_identifier=='RNA':
67                                 continue
68                         
69                         if rna_prop_identifier=='rna_type':
70                                 continue
71                         
72                         rna_desc = rna_prop.description
73                         if not rna_desc: rna_desc = rna_prop.name
74                         if not rna_desc: rna_desc = 'Note - No documentation for this property!'
75                         
76                         rna_prop_type = rna_prop.type.lower()
77                         
78                         if rna_prop_type=='collection': collection_str = 'Collection of '
79                         else:                                                   collection_str = ''
80                         
81                         try:            rna_prop_ptr = rna_prop.fixed_type
82                         except: rna_prop_ptr = None
83                         
84                         try:            length = rna_prop.array_length
85                         except: length = 0
86                         
87                         array_str = get_array_str(length)
88                         
89                         if rna_prop.editable:   readonly_str = ''
90                         else:                           readonly_str = ' (readonly)'
91                         
92                         if rna_prop_ptr: # Use the pointer type
93                                 out.write(ident+ '\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
94                                 out.write(ident+ '\t@type %s: %sL{%s}%s%s\n' %  (rna_prop_identifier, collection_str, rna_prop_ptr.identifier, array_str, readonly_str))
95                         else:
96                                 if rna_prop_type == 'enum':
97                                         out.write(ident+ '\t@ivar %s: %s in (%s)\n' %  (rna_prop_identifier, rna_desc, ', '.join(rna_prop.items.keys())))
98                                         out.write(ident+ '\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type,  array_str, readonly_str))
99                                 elif rna_prop_type == 'int' or rna_prop_type == 'float':
100                                         out.write(ident+ '\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
101                                         out.write(ident+ '\t@type %s: %s%s%s in [%s, %s]\n' %  (rna_prop_identifier, rna_prop_type, array_str, readonly_str, range_str(rna_prop.hard_min), range_str(rna_prop.hard_max) ))
102                                 elif rna_prop_type == 'string':
103                                         out.write(ident+ '\t@ivar %s: %s (maximum length of %s)\n' %  (rna_prop_identifier, rna_desc, rna_prop.max_length))
104                                         out.write(ident+ '\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type, array_str, readonly_str))
105                                 else:
106                                         out.write(ident+ '\t@ivar %s: %s\n' %  (rna_prop_identifier, rna_desc))
107                                         out.write(ident+ '\t@type %s: %s%s%s\n' %  (rna_prop_identifier, rna_prop_type, array_str, readonly_str))
108                                 
109                         
110                 out.write(ident+ '\t"""\n\n')
111                 
112                 # Now write children recursively
113                 for child in structs:
114                         if rna_struct == child.nested:
115                                 write_struct(child, structs, ident + '\t')
116                 
117         
118         out = open(target_path, 'w')
119
120         def base_id(rna_struct):
121                 try:            return rna_struct.base.identifier
122                 except: return '' # invalid id
123
124         #structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
125         
126         structs = []
127         for rna_struct in bpydoc.structs.values():
128                 structs.append( (base_id(rna_struct), rna_struct.identifier, rna_struct) )
129                 
130         
131         
132         structs.sort() # not needed but speeds up sort below, setting items without an inheritance first
133         
134         # Arrange so classes are always defined in the correct order
135         deps_ok = False
136         while deps_ok == False:
137                 deps_ok = True
138                 rna_done = set()
139                 
140                 for i, (rna_base, identifier, rna_struct) in enumerate(structs):
141                         
142                         rna_done.add(identifier)
143                         
144                         if rna_base and rna_base not in rna_done:
145                                 deps_ok = False
146                                 data = structs.pop(i)
147                                 ok = False
148                                 while i < len(structs):
149                                         if structs[i][1]==rna_base:
150                                                 structs.insert(i+1, data) # insert after the item we depend on.
151                                                 ok = True
152                                                 break
153                                         i+=1
154                                         
155                                 if not ok:
156                                         print('Dependancy "%s"could not be found for "%s"' % (identifier, rna_base))
157                                 
158                                 break
159         
160         structs = [data[2] for data in structs]
161         # Done ordering structs
162         
163         
164         for rna_struct in structs:
165                 if rna_struct.nested:
166                         continue
167                 
168                 write_struct(rna_struct, structs, '')
169                 
170                 
171         out.write('\n')
172         out.close()
173         
174         # # We could also just run....
175         # os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v')
176
177 def op2epy(target_path):
178         out = open(target_path, 'w')
179         
180         operators = dir(bpyoperator)
181         operators.remove('add')
182         operators.remove('remove')
183         operators.sort()
184         
185         
186         for op in operators:
187                 
188                 if op.startswith('__'):
189                         continue
190                 
191                 # Keyword attributes
192                 kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'"
193                 kw_arg_attrs = [] # "@type mode: int"
194                 
195                 rna = getattr(bpyoperator, op).rna
196                 rna_struct = rna.rna_type
197                 # print (dir(rna))
198                 # print (dir(rna_struct))
199                 for rna_prop_identifier, rna_prop in rna_struct.properties.items():
200                         if rna_prop_identifier=='rna_type':
201                                 continue
202                         # ['rna_type', 'name', 'array_length', 'description', 'hard_max', 'hard_min', 'identifier', 'precision', 'readonly', 'soft_max', 'soft_min', 'step', 'subtype', 'type']
203                         #rna_prop=  op_rna.rna_type.properties[attr]
204                         rna_prop_type = rna_prop.type.lower() # enum, float, int, boolean
205                         
206                         try:            length = rna_prop.array_length
207                         except: length = 0
208                         
209                         array_str = get_array_str(length)
210                         
211                         try:
212                                 val = getattr(rna, rna_prop_identifier)
213                         except:
214                                 val = '<UNDEFINED>'
215                         
216                         kw_type_str= "@type %s: %s%s" % (rna_prop_identifier, rna_prop_type, array_str)
217                         kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description)
218                         kw_param_set = False
219                         
220                         if rna_prop_type=='float':
221                                 if length==0:
222                                         val_str= '%g' % val
223                                         if '.' not in val_str:
224                                                 val_str += '.0'
225                                 else:
226                                         # array
227                                         val_str = str(tuple(val))
228                                 
229                                 kw_param_str += (' in (%s, %s)' % (range_str(rna_prop.hard_min), range_str(rna_prop.hard_max)))
230                                 kw_param_set= True
231                                 
232                         elif rna_prop_type=='int':
233                                 if length==0:
234                                         val_str='%d' % val
235                                 else:
236                                         val_str = str(tuple(val))
237                                 
238                                 # print(dir(rna_prop))
239                                 kw_param_str += (' in (%s, %s)' % (range_str(rna_prop.hard_min), range_str(rna_prop.hard_max)))
240                                 # These strings dont have a max length???
241                                 #kw_param_str += ' (maximum length of %s)' %  (rna_prop.max_length)
242                                 kw_param_set= True
243                                 
244                         elif rna_prop_type=='boolean':
245                                 if length==0:
246                                         if val: val_str='True'
247                                         else:   val_str='False'
248                                 else:
249                                         val_str = str(tuple(val))
250                         
251                         elif rna_prop_type=='enum':
252                                 # no array here?
253                                 val_str="'%s'" % val
254                                 kw_param_str += (' in (%s)' % ', '.join(rna_prop.items.keys()))
255                                 kw_param_set= True
256                                 
257                         elif rna_prop_type=='string':
258                                 # no array here?
259                                 val_str='"%s"' % val
260                         
261                         # todo - collection - array
262                         # print (rna_prop.type)
263                         
264                         kw_args.append('%s = %s' % (rna_prop_identifier, val_str))
265                         
266                         # stora 
267                         
268                         kw_arg_attrs.append(kw_type_str)
269                         if kw_param_set:
270                                 kw_arg_attrs.append(kw_param_str)
271                         
272                 
273                 
274                 out.write('def %s(%s):\n' % (op, ', '.join(kw_args)))
275                 out.write('\t"""\n')
276                 out.write('\t%s\n' % rna_struct.description)
277                 for desc in kw_arg_attrs:
278                         out.write('\t%s\n' % desc)
279                 out.write('\t@rtype: None\n')
280                 out.write('\t"""\n')
281         
282         
283         out.write('\n')
284         out.close()
285
286 if __name__ == '__main__':
287         rna2epy('source/blender/python/doc/rna.py')
288         op2epy('source/blender/python/doc/bpyoperator.py')
289