| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |  # ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  # | 
					
						
							|  |  |  |  # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  # of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  # | 
					
						
							|  |  |  |  # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  # GNU General Public License for more details. | 
					
						
							|  |  |  |  # | 
					
						
							|  |  |  |  # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  # along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  |  # | 
					
						
							|  |  |  |  # Contributor(s): Campbell Barton | 
					
						
							|  |  |  |  # | 
					
						
							|  |  |  |  # #**** END GPL LICENSE BLOCK #**** | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | script_help_msg = '''
 | 
					
						
							|  |  |  | Usage, | 
					
						
							|  |  |  | run this script from blenders root path once you have compiled blender | 
					
						
							|  |  |  |     ./blender.bin -b -P /b/source/blender/python/sphinx_doc_gen.py | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-06 09:42:41 +00:00
										 |  |  | This will generate python files in "./source/blender/python/doc/sphinx-in" | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | Generate html docs  by running... | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2010-01-06 09:42:41 +00:00
										 |  |  |     sphinx-build source/blender/python/doc/sphinx-in source/blender/python/doc/sphinx-out | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | '''
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # if you dont have graphvis installed ommit the --graph arg. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # GLOBALS['BASEDIR'] = './source/blender/python/doc' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  | import inspect | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | import bpy | 
					
						
							|  |  |  | import rna_info | 
					
						
							|  |  |  | reload(rna_info) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def range_str(val): | 
					
						
							|  |  |  |     if val < -10000000:	return '-inf' | 
					
						
							|  |  |  |     if val >  10000000:	return 'inf' | 
					
						
							|  |  |  |     if type(val)==float: | 
					
						
							|  |  |  |         return '%g'  % val | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return str(val) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def write_indented_lines(ident, fn, text): | 
					
						
							|  |  |  |     if text is None: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     for l in text.split("\n"): | 
					
						
							|  |  |  |         fn(ident + l.strip() + "\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rna2sphinx(BASEPATH): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     structs, funcs, ops, props = rna_info.BuildRNAInfo() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         os.mkdir(BASEPATH) | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # conf.py - empty for now | 
					
						
							|  |  |  |     filepath = os.path.join(BASEPATH, "conf.py") | 
					
						
							|  |  |  |     file = open(filepath, "w") | 
					
						
							|  |  |  |     fw = file.write | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     fw("project = 'Blender 3D'\n") | 
					
						
							|  |  |  |     # fw("master_doc = 'index'\n") | 
					
						
							|  |  |  |     fw("copyright = u'Blender Foundation'\n") | 
					
						
							|  |  |  |     fw("version = '2.5'\n") | 
					
						
							|  |  |  |     fw("release = '2.5'\n") | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     filepath = os.path.join(BASEPATH, "contents.rst") | 
					
						
							|  |  |  |     file = open(filepath, "w") | 
					
						
							|  |  |  |     fw = file.write | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     fw("\n") | 
					
						
							|  |  |  |     fw(".. toctree::\n") | 
					
						
							|  |  |  |     fw("   :glob:\n\n") | 
					
						
							|  |  |  |     fw("   bpy.ops.*\n\n") | 
					
						
							|  |  |  |     fw("   bpy.types.*\n\n") | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if 0: | 
					
						
							|  |  |  |         filepath = os.path.join(BASEPATH, "bpy.rst") | 
					
						
							|  |  |  |         file = open(filepath, "w") | 
					
						
							|  |  |  |         fw = file.write | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         fw("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         title = ":mod:`bpy` --- Blender Python Module" | 
					
						
							|  |  |  |         fw("%s\n%s\n\n" % (title, "=" * len(title))) | 
					
						
							|  |  |  |         fw(".. module:: bpy.types\n\n") | 
					
						
							|  |  |  |         file.close() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |     def write_param(ident, fw, prop, is_return=False): | 
					
						
							|  |  |  |         if is_return: | 
					
						
							|  |  |  |             id_name = "return" | 
					
						
							|  |  |  |             id_type = "rtype" | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |             id_name = "arg" | 
					
						
							|  |  |  |             id_type = "type" | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |         type_descr = prop.get_type_description(as_arg=True, class_fmt=":class:`%s`") | 
					
						
							|  |  |  |         if prop.name or prop.description: | 
					
						
							|  |  |  |             fw(ident + "   :%s %s: %s\n" % (id_name, prop.identifier, ", ".join([val for val in (prop.name, prop.description) if val]))) | 
					
						
							|  |  |  |         fw(ident + "   :%s %s: %s\n" % (id_type, prop.identifier, type_descr)) | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def write_struct(struct): | 
					
						
							|  |  |  |         #if not struct.identifier.startswith("Sc") and not struct.identifier.startswith("I"): | 
					
						
							|  |  |  |         #    return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 19:01:19 +00:00
										 |  |  |         #if not struct.identifier == "Object": | 
					
						
							|  |  |  |         #    return | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % struct.identifier) | 
					
						
							|  |  |  |         file = open(filepath, "w") | 
					
						
							|  |  |  |         fw = file.write | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if struct.base:  | 
					
						
							|  |  |  |             title = "%s(%s)" % (struct.identifier, struct.base.identifier) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             title = struct.identifier | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fw("%s\n%s\n\n" % (title, "=" * len(title))) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         fw(".. module:: bpy.types\n\n") | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         bases = struct.get_bases() | 
					
						
							|  |  |  |         if bases: | 
					
						
							|  |  |  |             if len(bases) > 1: | 
					
						
							|  |  |  |                 fw("base classes --- ") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 fw("base class --- ") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             fw(", ".join([(":class:`%s`" % base.identifier) for base in reversed(bases)])) | 
					
						
							|  |  |  |             fw("\n\n") | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         subclasses = [s for s in structs.values() if s.base is struct] | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         if subclasses: | 
					
						
							|  |  |  |             fw("subclasses --- \n") | 
					
						
							|  |  |  |             fw(", ".join([(":class:`%s`" % s.identifier) for s in subclasses])) | 
					
						
							|  |  |  |             fw("\n\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if struct.base: | 
					
						
							|  |  |  |             fw(".. class:: %s(%s)\n\n" % (struct.identifier, struct.base.identifier)) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             fw(".. class:: %s\n\n" % struct.identifier) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fw("   %s\n\n" % struct.description) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for prop in struct.properties: | 
					
						
							|  |  |  |             fw("   .. attribute:: %s\n\n" % prop.identifier) | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |             if prop.description: | 
					
						
							|  |  |  |                 fw("      %s\n\n" % prop.description) | 
					
						
							|  |  |  |             type_descr = prop.get_type_description(as_arg=False, class_fmt=":class:`%s`") | 
					
						
							|  |  |  |             fw("      *type* %s\n\n" % type_descr) | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |          | 
					
						
							|  |  |  |         # python attributes | 
					
						
							|  |  |  |         py_properties = struct.get_py_properties() | 
					
						
							|  |  |  |         py_prop = None | 
					
						
							|  |  |  |         for identifier, py_prop in py_properties: | 
					
						
							|  |  |  |             fw("   .. attribute:: %s\n\n" % identifier) | 
					
						
							|  |  |  |             write_indented_lines("      ", fw, py_prop.__doc__) | 
					
						
							|  |  |  |             if py_prop.fset is None: | 
					
						
							|  |  |  |                 fw("      (readonly)\n\n") | 
					
						
							|  |  |  |         del py_properties, py_prop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for func in struct.functions: | 
					
						
							|  |  |  |             args_str = ", ".join([prop.get_arg_default(force=False) for prop in func.args]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             fw("   .. method:: %s(%s)\n\n" % (func.identifier, args_str)) | 
					
						
							|  |  |  |             fw("      %s\n\n" % func.description) | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             for prop in func.args: | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |                 write_param("      ", fw, prop) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-02 18:55:07 +00:00
										 |  |  |             if len(func.return_values) == 1: | 
					
						
							|  |  |  |                 write_param("      ", fw, func.return_values[0], is_return=True) | 
					
						
							|  |  |  |             else: # multiple return values | 
					
						
							|  |  |  |                 fw("         :return (%s):\n" % ", ".join([prop.identifier for prop in func.return_values])) | 
					
						
							|  |  |  |                 for prop in func.return_values: | 
					
						
							|  |  |  |                     type_descr = prop.get_type_description(as_arg=True, class_fmt=":class:`%s`") | 
					
						
							|  |  |  |                     descr = prop.description | 
					
						
							|  |  |  |                     if not descr: | 
					
						
							|  |  |  |                         descr = prop.name | 
					
						
							|  |  |  |                     fw("            `%s`, %s, %s\n\n" % (prop.identifier, descr, type_descr)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |             fw("\n") | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # python methods | 
					
						
							|  |  |  |         py_funcs = struct.get_py_functions() | 
					
						
							|  |  |  |         py_func = None | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         for identifier, py_func in py_funcs: | 
					
						
							| 
									
										
										
										
											2009-12-26 17:49:08 +00:00
										 |  |  |             arg_str = inspect.formatargspec(*inspect.getargspec(py_func)) | 
					
						
							|  |  |  |             if arg_str.startswith("(self, "): | 
					
						
							|  |  |  |                 arg_str = "(" + arg_str[7:] | 
					
						
							|  |  |  |                 func_type = "method" | 
					
						
							|  |  |  |             elif arg_str.startswith("(cls, "): | 
					
						
							|  |  |  |                 arg_str = "(" + arg_str[6:] | 
					
						
							|  |  |  |                 func_type = "classmethod" | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 func_type = "staticmethod" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             fw("   .. %s:: %s%s\n\n" % (func_type, identifier, arg_str)) | 
					
						
							|  |  |  |             if py_func.__doc__: | 
					
						
							|  |  |  |                 write_indented_lines("      ", fw, py_func.__doc__) | 
					
						
							|  |  |  |                 fw("\n") | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |         del py_funcs, py_func | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if struct.references: | 
					
						
							|  |  |  |             # use this otherwise it gets in the index for a normal heading. | 
					
						
							|  |  |  |             fw(".. rubric:: References\n\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for ref in struct.references: | 
					
						
							|  |  |  |                 ref_split = ref.split(".") | 
					
						
							|  |  |  |                 if len(ref_split) > 2: | 
					
						
							|  |  |  |                     ref = ref_split[-2] + "." + ref_split[-1] | 
					
						
							|  |  |  |                 fw("* :class:`%s`\n" % ref) | 
					
						
							|  |  |  |             fw("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for struct in structs.values(): | 
					
						
							|  |  |  |         write_struct(struct) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # oeprators | 
					
						
							|  |  |  |     def write_ops(): | 
					
						
							|  |  |  |         fw = None | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         last_mod = '' | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         for op_key in sorted(ops.keys()): | 
					
						
							|  |  |  |             op = ops[op_key] | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             if last_mod != op.module_name: | 
					
						
							|  |  |  |                 filepath = os.path.join(BASEPATH, "bpy.ops.%s.rst" % op.module_name) | 
					
						
							|  |  |  |                 file = open(filepath, "w") | 
					
						
							|  |  |  |                 fw = file.write | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 title = "%s Operators"  % (op.module_name[0].upper() + op.module_name[1:]) | 
					
						
							|  |  |  |                 fw("%s\n%s\n\n" % (title, "=" * len(title))) | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 fw(".. module:: bpy.ops.%s\n\n" % op.module_name) | 
					
						
							|  |  |  |                 last_mod = op.module_name | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             args_str = ", ".join([prop.get_arg_default(force=True) for prop in op.args]) | 
					
						
							|  |  |  |             fw(".. function:: %s(%s)\n\n" % (op.func_name, args_str)) | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |             if op.description: | 
					
						
							|  |  |  |                 fw("   %s\n\n" % op.description) | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |             for prop in op.args: | 
					
						
							| 
									
										
										
										
											2009-12-26 16:47:25 +00:00
										 |  |  |                 write_param("      ", fw, prop) | 
					
						
							|  |  |  |             if op.args: | 
					
						
							|  |  |  |                 fw("\n") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  |             location = op.get_location() | 
					
						
							|  |  |  |             if location != (None, None): | 
					
						
							|  |  |  |                 fw("   *python operator source --- `%s:%d`* \n\n" % location) | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     write_ops() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file.close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     if 'bpy' not in dir(): | 
					
						
							|  |  |  |         print("\nError, this script must run from inside blender2.5") | 
					
						
							|  |  |  |         print(script_help_msg) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2010-01-06 09:42:41 +00:00
										 |  |  |         # os.system("rm source/blender/python/doc/sphinx-in/*.rst") | 
					
						
							|  |  |  |         # os.system("rm -rf source/blender/python/doc/sphinx-out/*") | 
					
						
							|  |  |  |         rna2sphinx('source/blender/python/doc/sphinx-in') | 
					
						
							| 
									
										
										
										
											2009-12-25 15:50:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     import sys | 
					
						
							|  |  |  |     sys.exit() |