2 # SConscript file for building SCons documentation.
8 # Permission is hereby granted, free of charge, to any person obtaining
9 # a copy of this software and associated documentation files (the
10 # "Software"), to deal in the Software without restriction, including
11 # without limitation the rights to use, copy, modify, merge, publish,
12 # distribute, sublicense, and/or sell copies of the Software, and to
13 # permit persons to whom the Software is furnished to do so, subject to
14 # the following conditions:
16 # The above copyright notice and this permission notice shall be included
17 # in all copies or substantial portions of the Software.
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
20 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
21 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 Import('env', 'whereis')
34 build = os.path.join('#build', 'doc')
39 doc_tar_gz = os.path.join('#build',
41 'scons-doc-%s.tar.gz' % env.Dictionary('VERSION'))
44 # We'll only try to build text files (for some documents)
45 # if lynx is available to do the dump.
47 fig2dev = whereis('fig2dev')
48 groff = whereis('groff')
49 lynx = whereis('lynx')
50 man2html = whereis('man2html')
51 jade = whereis('jade')
52 jadetex = whereis('jadetex')
53 pdfjadetex = whereis('pdfjadetex')
55 tidy = whereis('tidy')
60 entity_re = re.compile(r'<!entity\s+(?:%\s+)?(?:\S+)\s+SYSTEM\s+"([^"]*)">', re.I)
61 format_re = re.compile(r'<(?:graphic|imagedata)\s+fileref="([^"]*)"(?:\s+format="([^"]*)")?')
64 # Find internal dependencies in .sgml files:
66 # <!entity bground SYSTEM "bground.sgml">
67 # <graphic fileref="file.jpg">
68 # <imagedata fileref="file.jpg">
70 # This only finds one per line, and assumes that anything
71 # defined as a SYSTEM entity is, in fact, a file included
72 # somewhere in the document.
74 def scansgml(node, env, target):
77 contents = node.get_contents()
79 includes.extend(entity_re.findall(contents))
81 matches = format_re.findall(contents)
84 if format and file[-len(format):] != format:
85 file = file + '.' + format
86 if not os.path.isabs(file):
90 f, tail = os.path.split(f)
94 file = apply(os.path.join, a, {})
99 s = Scanner(name = 'sgml', function = scansgml, skeys = ['.sgml', '.mod'])
101 env = orig_env.Copy(SCANNERS = [s])
105 # Always create a version.sgml file containing the version information
106 # for this run. Ignore it for dependency purposes so we don't
107 # rebuild all the docs every time just because the date changes.
109 date, ver, rev = env.Dictionary('DATE', 'VERSION', 'REVISION')
110 version_sgml = File(os.path.join(build, "version.sgml"))
111 #version_sgml = File("version.sgml")
112 verfile = str(version_sgml)
116 pass # okay if the file didn't exist
117 dir, f = os.path.split(verfile)
121 pass # okay if the directory already exists
122 open(verfile, "w").write("""<!--
123 THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
125 <!ENTITY builddate "%s">
126 <!ENTITY buildversion "%s">
127 <!ENTITY buildrevision "%s">
128 """ % (date, ver, rev))
131 # Each document will live in its own subdirectory. List them here
132 # as hash keys, with a hash of the info to control its build.
136 'htmlindex' : 'book1.html',
142 'htmlindex' : 't1.html',
147 'graphics' : [ 'arch', 'builder', 'job-task', 'node', 'scanner', 'sig' ],
150 'htmlindex' : 'book1.html',
157 'htmlindex' : 'book1.html',
166 # We have to tell SCons to scan the top-level SGML files which
167 # get included by the document SGML files in the subdirectories.
169 manifest = File('MANIFEST').rstr()
170 src_files = map(lambda x: x[:-1], open(manifest).readlines())
172 base, ext = os.path.splitext(s)
173 if ext in ['.fig', '.jpg']:
174 orig_env.Install(build, s)
176 orig_env.SCons_revision(os.path.join(build, s), s)
177 Local(os.path.join(build, s))
180 # For each document, build the document itself in HTML, Postscript,
183 for doc in docs.keys():
184 manifest = File(os.path.join(doc, 'MANIFEST')).rstr()
185 src_files = map(lambda x: x[:-1],
186 open(manifest).readlines())
188 base, ext = os.path.splitext(s)
189 if ext in ['.fig', '.jpg']:
190 orig_env.Install(os.path.join(build, doc), os.path.join(doc, s))
192 orig_env.SCons_revision(os.path.join(build, doc, s),
193 os.path.join(doc, s))
194 Local(os.path.join(build, doc, s))
196 main = os.path.join(build, doc, 'main.sgml')
199 # Hard-coding the scons-src path is a bit of a hack. This can
200 # be reworked when a better solution presents itself.
201 scons_src_main = os.path.join('#build', 'scons-src', 'doc', main)
202 env.Ignore(scons_src_main, version_sgml)
204 htmldir = os.path.join(build, 'HTML', 'scons-%s' % doc)
205 htmlindex = os.path.join(htmldir, docs[doc]['htmlindex'])
206 html = os.path.join(build, 'HTML', 'scons-%s.html' % doc)
207 ps = os.path.join(build, 'PS', 'scons-%s.ps' % doc)
208 pdf = os.path.join(build, 'PDF', 'scons-%s.pdf' % doc)
209 text = os.path.join(build, 'TEXT', 'scons-%s.txt' % doc)
211 if docs[doc].get('html') and jade:
213 "rm -f ${TARGET.dir}/*.html",
214 "jw -b html -o ${TARGET.dir} $SOURCES",
215 "mv -v ${TARGET.dir}/index.html $TARGET || true",
218 cmds.append("tidy -m -q $TARGET || true")
219 env.Command(htmlindex, main, cmds)
223 "rm -f ${TARGET.dir}/main.html",
224 "jw -u -b html -o ${TARGET.dir} $SOURCES",
225 "mv -v ${TARGET.dir}/main.html $TARGET || true",
228 cmds.append("tidy -m -q $TARGET || true")
229 env.Command(html, main, cmds)
232 env.Ignore([html, htmlindex], version_sgml)
234 tar_deps.extend([html, htmlindex])
235 tar_list.extend([html, htmldir])
238 for g in docs[doc].get('graphics', []):
239 fig = os.path.join(build, doc, '%s.fig' % g)
240 jpg = os.path.join(htmldir, '%s.jpg' % g)
241 env.Command(jpg, fig,
242 "%s -L jpeg -q 100 $SOURCES $TARGET" % fig2dev)
243 env.Depends(html, jpg)
246 if docs[doc].get('ps') and jadetex:
247 env.Command(ps, main, [
248 "rm -f ${TARGET.dir}/%s" % out,
249 "jw -b ps -o ${TARGET.dir} $SOURCES",
250 "mv ${TARGET.dir}/main.ps $TARGET",
251 "rm -f ${TARGET.dir}/%s" % out,
255 env.Ignore(ps, version_sgml)
261 for g in docs[doc].get('graphics', []):
262 fig = os.path.join(build, doc, '%s.fig' % g)
263 eps = os.path.join(build, 'PS', '%s.eps' % g)
264 env.Command(eps, fig, "%s -L eps $SOURCES $TARGET" % fig2dev)
268 if docs[doc].get('pdf') and pdfjadetex:
269 env.Command(pdf, main, [
270 "rm -f ${TARGET.dir}/%s" % out,
271 "jw -b pdf -o ${TARGET.dir} $SOURCES",
272 "mv ${TARGET.dir}/main.pdf $TARGET",
273 "rm -f ${TARGET.dir}/out",
277 env.Ignore(pdf, version_sgml)
282 if docs[doc].get('text') and jade and lynx:
283 env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
286 env.Ignore(text, version_sgml)
288 tar_deps.append(text)
289 tar_list.append(text)
292 # Man page(s), in good ol' troff format.
294 man_page_list = ['scons', 'sconsign']
296 for man in man_page_list:
297 man_1 = os.path.join('man', '%s.1' % man)
300 ps = os.path.join(build, 'PS', '%s-man.ps' % man)
301 text = os.path.join(build, 'TEXT', '%s-man.txt' % man)
303 env.Command(ps, man_1, "groff -man -Tps $SOURCES > $TARGET")
306 env.Command(text, man_1, "groff -man -Tascii $SOURCES > $TARGET")
309 tar_deps.extend([ps, text])
310 tar_list.extend([ps, text])
313 html = os.path.join(build, 'HTML' , '%s-man.html' % man)
315 cmds = [ "man2html $SOURCES > $TARGET" ]
317 cmds.append("tidy -m -q $TARGET || true")
318 env.Command(html, man_1, cmds)
321 tar_deps.append(html)
322 tar_list.append(html)
325 # Now actually create the tar file of the documentation,
326 # for easy distribution to the web site.
329 tar_list = string.join(map(lambda x: x[11:], tar_list))
330 env.Command(doc_tar_gz, tar_deps,
331 "tar cf${TAR_HFLAG} - -C build/doc %s | gzip > $TARGET" % tar_list)