risch: recognize Derivatives as components (#1012)
[sympy.git] / doc / generate_reference.py
blob1fcbf3c2916b7e4770c36a936cbd310c340e2073
1 #! /usr/bin/python2.5
3 # You need to run python2.5 with this, because python2.4 has some weird
4 # Exception hierarchy classes that causes Exceptions to be ignored by this
5 # script
7 import types
8 import os
9 import sys
11 def isclass(x):
12 from inspect import isclass as _isclass
13 return _isclass(x)
15 def ismethod(x):
16 from inspect import ismethod as _ismethod
17 if _ismethod(x) or isinstance(x, (types.MethodType, types.FunctionType,
18 types.UnboundMethodType)) or str(type(x)) in [
19 "<type 'classmethod'>", "<type 'staticmethod'>"]:
20 return True
21 else:
22 return False
24 def get_method_name(x):
25 if hasattr(x, "__name__"):
26 return x.__name__
27 # This is a static method, don't know how to read the name.
28 return None
30 def get_method_args(x):
31 from inspect import getsource
32 try:
33 s = getsource(x)
34 except TypeError:
35 return ""
36 s = s[s.find("("):s.find(":")]
37 assert s is not None
38 return s
40 def getdoc(x):
41 from inspect import getdoc as _getdoc
42 s = _getdoc(x)
43 return s
45 class Parser(object):
47 def __init__(self):
48 self.modules = {}
50 def generate_doc(self, module, outdir="/tmp/", importpath = ""):
51 """
52 Takes the "module" string and generates a rst for this module.
54 modules is just the name, like "sympy", i.e. without a path.
55 """
57 print "Generating API documentation ... (this may take a while)"
58 sys.path.insert(0, importpath)
59 m = __import__(module)
60 self.main_module = module
61 self.handle_module(m)
62 print " saving..."
63 for x in self.modules:
64 if x.startswith(module):
65 f = open(outdir+x+".txt", "w")
66 f.write(self.modules[x])
67 print "API generated in %s." % (outdir)
70 def handle_module(self, mod):
71 mname = mod.__name__
72 if mname in self.modules:
73 # we already handled this module
74 return
75 self.modules[mname] = ""
77 # if you want to get the top level modules without "sympy.", uncomment
78 # this:
79 #if mname.startswith(self.main_module):
80 # #strip the "sympy.":
81 # s = ".. module:: %s\n\n" % mname[len(self.main_module)+1:]
82 #else:
83 # s = ".. module:: %s\n\n" % mname
85 s = "=" * len(mname) + "\n"
86 s += mname + "\n"
87 s += "=" * len(mname) + "\n" + "\n"
89 s += ".. module:: %s\n\n" % mname
90 if hasattr(mod, __file__):
91 s += "filename: %s\n" % mod.__file__
92 for x in mod.__dict__.values():
93 if isinstance(x, types.ModuleType):
94 self.handle_module(x)
95 elif x is None:
96 pass
97 elif isinstance(x, (int, float, str, list, dict)):
98 # skip these
99 pass
100 elif str(type(x)) == "<type 'classobj'>":
101 # old style classes
102 pass
103 elif hasattr(x, "__class__"):
104 s += self.handle_class(x)
105 else:
106 print " Ignored:", type(x), x
107 self.modules[mod.__name__] = s
109 def handle_class(self, cls):
110 if hasattr(cls, "__name__"):
111 s = "\n.. class:: %s\n" % cls.__name__
112 else:
113 return ""
115 # Uncomment this to generate class docstrings too:
116 # unfortunately, sphinx fails to read them, so we need to fix sympy
117 # first.
118 #doc = getdoc(cls)
119 #if doc is not None:
120 # s += doc
121 # s += "\n"
123 if hasattr(cls, "__dict__"):
124 for x in cls.__dict__.values():
125 if isinstance(x, types.ModuleType):
126 self.handle_module(x)
127 elif str(type(x)) == "<type 'classobj'>":
128 # old style classes
129 pass
130 elif x is None:
131 pass
132 elif ismethod(x):
133 s += self.handle_method(x)
134 elif str(type(x)) == "<type 'property'>":
135 pass
136 elif isinstance(x, (int, float, str, list, tuple, dict)):
137 # skip these
138 pass
139 elif hasattr(x, "__class__"):
140 # ignore nested classes
141 pass
142 else:
143 print " Ignored in class:", type(x), x
145 return s
147 def handle_method(self, m):
148 mname = get_method_name(m)
149 if mname is None:
150 s = ""
151 else:
152 s = "\n.. method:: %s%s\n\n" % (mname, get_method_args(m))
153 doc = getdoc(m)
154 if doc is not None:
155 s += doc
156 s += "\n"
157 return s
159 Parser().generate_doc("sympy", importpath = "..", outdir="api/modules/")