Added Sphinx documentation framework
[hooke.git] / doc / SConstruct
1 """
2 This is a generic SCons script for running Sphinx (http://sphinx.pocoo.org).
3
4 Type 'scons -h' for help.  This prints the available build targets on your
5 system, and the configuration options you can set.
6
7 If you set the 'cache' option, the option settings are cached into a file
8 called '.sconsrc-sphinx' in the current directory.  When running
9 subsequently, this file is reread.  A file with this name is also read from
10 your home directory, if it exists, so you can put global settings there.
11
12 The script looks into your 'conf.py' file for information about the
13 project.  This is used in various places (e.g., to print the introductory
14 message, and create package files).
15
16 Here's some examples.  To build HTML docs:
17
18    scons html
19
20 To create a package containing HTML and PDF docs, remembering the 'install'
21 setting:
22
23    scons install=html,pdf cache=True package
24
25 To clean up everything:
26
27    scons -c all
28 """
29
30 # Script info.
31 __author__  = "Glenn Hutchings"
32 __email__   = "zondo42@googlemail.com"
33 __url__     = "http://bitbucket.org/zondo/sphinx-scons"
34 __license__ = "BSD"
35 __version__ = "0.4"
36
37 import sys, os
38
39 # Build targets.
40 targets = (
41     ("html",      "make standalone HTML files"),
42     ("dirhtml",   "make HTML files named index.html in directories"),
43     ("pickle",    "make pickle files"),
44     ("json",      "make JSON files"),
45     ("htmlhelp",  "make HTML files and a HTML help project"),
46     ("qthelp",    "make HTML files and a qthelp project"),
47     ("devhelp",   "make HTML files and a GNOME DevHelp project"),
48     ("epub",      "make HTML files and an EPUB file for bookreaders"),
49     ("latex",     "make LaTeX sources"),
50     ("text",      "make text file for each RST file"),
51     ("pdf",       "make PDF file from LaTeX sources"),
52     ("ps",        "make PostScript file from LaTeX sources"),
53     ("dvi",       "make DVI file from LaTeX sources"),
54     ("changes",   "make an overview over all changed/added/deprecated items"),
55     ("linkcheck", "check all external links for integrity"),
56     ("doctest",   "run all doctests embedded in the documentation if enabled"),
57     ("source",    "run a command to generate the reStructuredText source"),
58 )
59
60 # LaTeX builders.
61 latex_builders = {"pdf": "PDF", "ps": "PostScript", "dvi": "DVI"}
62
63 # List of target names.
64 targetnames = [name for name, desc in targets]
65
66 # Configuration cache filename.
67 cachefile = ".sconsrc-sphinx"
68
69 # User cache file.
70 homedir = os.path.expanduser('~')
71 usercache = os.path.join(homedir, cachefile)
72
73 # Configuration options.
74 config = Variables([usercache, cachefile], ARGUMENTS)
75
76 config.AddVariables(
77     EnumVariable("default", "default build target", "html", targetnames),
78     PathVariable("config", "sphinx configuration file", "conf.py"),
79     PathVariable("srcdir", "source directory", ".",
80                  PathVariable.PathIsDir),
81     PathVariable("builddir", "build directory", "build",
82                  PathVariable.PathIsDirCreate),
83     PathVariable("doctrees", "place to put doctrees", None,
84                  PathVariable.PathAccept),
85     EnumVariable("paper", "LaTeX paper size", None,
86                  ["a4", "letter"], ignorecase = False),
87     ("tags", "comma-separated list of 'only' tags", None),
88     ("builder", "program to run to build things", "sphinx-build"),
89     ("opts", "extra builder options to use", None),
90     ListVariable("install", "targets to install", ["html"], targetnames),
91     PathVariable("instdir", "installation directory", "/usr/local/doc",
92                  PathVariable.PathAccept),
93     EnumVariable("pkgtype", "package type to build with 'scons package'",
94                  "zip", ["zip", "targz", "tarbz2"], ignorecase = False),
95     BoolVariable("cache", "whether to cache settings in %s" % cachefile, False),
96     BoolVariable("debug", "debugging flag", False),
97     ("genrst", "Command to regenerate reStructuredText source", None),
98 )
99
100 # Create a new environment, inheriting PATH to find builder program.  Also
101 # force LaTeX instead of TeX, since the .tex file won't exist at the right
102 # time to check which one to use.
103 env = Environment(ENV = {"PATH" : os.environ["PATH"]},
104                   TEX = "latex", PDFTEX = "pdflatex",
105                   tools = ['default', 'packaging'],
106                   variables = config)
107
108 # Get configuration values from environment.
109 sphinxconf = env["config"]
110 builder = env["builder"]
111 default = env["default"]
112
113 srcdir = env["srcdir"]
114 builddir = env["builddir"]
115 doctrees = env.get("doctrees", os.path.join(builddir, "doctrees"))
116
117 cache = env["cache"]
118 debug = env["debug"]
119
120 options = env.get("opts", None)
121 paper = env.get("paper", None)
122 tags = env.get("tags", None)
123 genrst = env.get("genrst", None)
124
125 instdir = env["instdir"]
126 install = env["install"]
127 pkgtype = env["pkgtype"]
128
129 # Dump internals if debugging.
130 if debug:
131     print "Environment:"
132     print env.Dump()
133
134 # Get parameters from Sphinx config file.
135 sphinxparams = {}
136 execfile(sphinxconf, sphinxparams)
137
138 project = sphinxparams["project"]
139 release = sphinxparams["release"]
140 copyright = sphinxparams["copyright"]
141
142 try:
143     texfilename = sphinxparams["latex_documents"][0][1]
144 except KeyError:
145     texfilename = None
146
147 name2tag = lambda name: name.replace(" ", "-").strip("()")
148 project_tag = name2tag(project)
149 release_tag = name2tag(release)
150 package_tag = project_tag.lower() + "-" + release_tag.lower()
151
152 # Build project description string.
153 description = "%(project)s, release %(release)s, " \
154                "copyright %(copyright)s" % locals()
155
156 Help(description + "\n\n")
157 help_format = "   %-10s  %s\n"
158
159 # Print banner if required.
160 if not any(map(GetOption, ("silent", "clean", "help"))):
161     print
162     print "This is", description
163     print
164
165 # Build sphinx command-line options.
166 opts = []
167
168 if tags:
169     opts.extend(["-t %s" % tag for tag in tags.split(",")])
170
171 if paper:
172     opts.append("-D latex_paper_size=%s" % paper)
173
174 if options:
175     opts.append(options)
176
177 options = " ".join(opts)
178
179 # Build Sphinx command template.
180 sphinxcmd = """
181 %(builder)s -b %(name)s -d %(doctrees)s %(options)s %(srcdir)s %(targetdir)s
182 """.strip()
183
184 # Set up LaTeX input builder if required.
185 if texfilename:
186     latexdir = Dir("latex", builddir)
187     texinput = File(texfilename, latexdir)
188     env.SideEffect(texinput, "latex")
189     env.NoClean(texinput)
190
191 # Add build targets.
192 Help("Build targets:\n\n")
193
194 if genrst != None:
195     source = env.Command('source', [], genrst)
196     env.AlwaysBuild(source)
197     env.Depends(srcdir, source)
198 else:
199     Alias('source', srcdir)
200
201 for name, desc in targets:
202     target = Dir(name, builddir)
203     targetdir = str(target)
204
205     if name == 'source':
206         pass
207     elif name not in latex_builders:
208         # Standard Sphinx target.
209         env.Command(name, sphinxconf,
210                     sphinxcmd % locals(), chdir = True)
211         env.AlwaysBuild(name)
212         env.Alias(target, name)
213     elif texinput:
214         # Target built from LaTeX sources.
215         try:
216             buildfunc = getattr(env, latex_builders[name])
217         except AttributeError:
218             continue
219
220         filename = project_tag + "." + name
221         outfile = File(filename, latexdir)
222
223         buildfunc(outfile, texinput)
224
225         # Copy built file to separate directory.
226         target = File(filename, target)
227         env.Command(target, outfile, Move(target, outfile), chdir = True)
228
229         env.Alias(name, target)
230     else:
231         continue
232
233     env.Clean(name, [target])
234     env.Clean('all', target)
235
236     if name == default: desc += " (default)"
237     Help(help_format % (name, desc))
238
239 Clean('all', doctrees)
240 Default(default)
241
242 # Add installation targets and collect package sources.
243 Help("\nOther targets:\n\n")
244
245 Help(help_format % ("install", "install documentation"))
246 projectdir = os.path.join(instdir, project_tag)
247 sources = []
248
249 for name in install:
250     source = Dir(name, builddir)
251     sources.append(source)
252
253     inst = env.Install(projectdir, source)
254     env.Alias('install', inst)
255
256     for node in env.Glob(os.path.join(str(source), '*')):
257         filename = str(node).replace(builddir + os.path.sep, "")
258         dirname = os.path.dirname(filename)
259         dest = os.path.join(projectdir, dirname)
260         inst = env.Install(dest, node)
261         env.Alias('install', inst)
262
263 # Add uninstall target.
264 env.Command('uninstall', None, Delete(projectdir), chdir = True)
265 Help(help_format % ("uninstall", "uninstall documentation"))
266
267 ## Add package builder.
268 #packageroot = "-".join([project_tag, release_tag])
269 #archive, package = env.Package(NAME = project_tag, VERSION = release,
270 #                               PACKAGEROOT = packageroot,
271 #                               PACKAGETYPE = pkgtype,
272 #                               source = sources)
273 #
274 #env.AlwaysBuild(archive)
275 #env.AddPostAction(archive, Delete(packageroot))
276 #Help(help_format % ("package", "build documentation package"))
277 #
278 #env.Clean('all', archive)
279
280 # Add config settings to help.
281 Help("\nConfiguration variables:")
282 for line in config.GenerateHelpText(env).split("\n"):
283     Help("\n   " + line)
284
285 # Save local configuration if required.
286 if cache:
287     config.Update(env)
288     config.Save(cachefile, env)