3 # Process a list of Python and/or XML files containing SCons documentation.
5 # This script creates formatted lists of the Builders, Tools or
6 # construction variables documented in the specified XML files.
8 # Dependening on the options, the lists are output in either
9 # DocBook-formatted generated SGML files containing the summary text
10 # and/or .mod files contining the ENTITY definitions for each item,
11 # or in man-page-formatted output.
23 base_sys_path = [os.getcwd() + '/build/test-tar-gz/lib/scons'] + sys.path
26 Usage: scons-proc.py [--man|--sgml] \
27 [-b file(s)] [-t file(s)] [-v file(s)] [infile ...]
29 -b file(s) dump builder information to the specified file(s)
30 -t file(s) dump tool information to the specified file(s)
31 -v file(s) dump variable information to the specified file(s)
32 --man print info in man page format, each -[btv] argument
34 --sgml (default) print info in SGML format, each -[btv] argument
35 is a pair of comma-separated .gen,.mod file names
38 opts, args = getopt.getopt(sys.argv[1:],
40 ['builders=', 'man', 'sgml', 'tools=', 'variables='])
43 output_type = '--sgml'
48 if o in ['-b', '--builders']:
50 elif o in ['--man', '--sgml']:
52 elif o in ['-t', '--tools']:
54 elif o in ['-v', '--variables']:
57 h = SConsDoc.SConsDocHandler()
58 saxparser = xml.sax.make_parser()
59 saxparser.setContentHandler(h)
60 saxparser.setErrorHandler(h)
72 _, ext = os.path.splitext(f)
74 dir, _ = os.path.split(f)
76 sys.path = [dir] + base_sys_path
77 module = SConsDoc.importfile(f)
78 h.set_file_info(f, len(xml_preamble.split('\n')))
80 content = module.__scons_doc__
81 except AttributeError:
84 del module.__scons_doc__
86 h.set_file_info(f, len(xml_preamble.split('\n')))
87 content = open(f).read()
89 content = content.replace('&', '&')
90 input = xml_preamble + content + xml_postamble
92 saxparser.parse(StringIO.StringIO(input))
94 sys.stderr.write("error in %s\n" % f)
99 THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
103 Regular_Entities_Header = """\
111 Link_Entities_Header = """\
114 Entities that are links to the %s entries in the appendix.
120 def __init__(self, entries, **kw):
121 values = entries.values()
124 for k, v in kw.items():
126 def fopen(self, name):
129 return open(name, 'w')
131 class SCons_XML_to_SGML(SCons_XML):
132 def write(self, files):
133 gen, mod = string.split(files, ',')
136 def write_gen(self, filename):
139 f = self.fopen(filename)
140 for v in self.values:
141 f.write('\n<varlistentry id="%s%s">\n' %
142 (self.prefix, self.idfunc(v.name)))
143 for term in self.termfunc(v.name):
144 f.write('<term><%s>%s</%s></term>\n' %
145 (self.tag, term, self.tag))
146 f.write('<listitem>\n')
147 for chunk in v.summary.body:
150 # u = map(lambda x, s: '&%slink-%s;' % (s.prefix, x), v.uses)
151 # f.write('<para>\n')
152 # f.write('Uses: ' + ', '.join(u) + '.\n')
153 # f.write('</para>\n')
154 f.write('</listitem>\n')
155 f.write('</varlistentry>\n')
156 def write_mod(self, filename):
159 f = self.fopen(filename)
162 f.write(Regular_Entities_Header % self.description)
164 for v in self.values:
165 f.write('<!ENTITY %s%s "<%s>%s</%s>">\n' %
166 (self.prefix, self.idfunc(v.name),
167 self.tag, self.entityfunc(v.name), self.tag))
171 f.write(Link_Entities_Header % self.description)
173 for v in self.values:
174 f.write('<!ENTITY %slink-%s \'<link linkend="%s%s"><%s>%s</%s></link>\'>\n' %
175 (self.prefix, self.idfunc(v.name),
176 self.prefix, self.idfunc(v.name),
177 self.tag, self.entityfunc(v.name), self.tag))
181 class SCons_XML_to_man(SCons_XML):
184 def initial_chunks(self, name):
186 def write(self, filename):
189 f = self.fopen(filename)
191 for v in self.values:
192 chunks.extend(self.mansep())
193 for n in self.initial_chunks(v.name):
194 chunks.append('.IP %s\n' % n)
195 chunks.extend(map(str, v.summary.body))
197 body = ''.join(chunks)
198 body = string.replace(body, '<programlisting>', '.ES')
199 body = string.replace(body, '</programlisting>', '.EE')
200 body = string.replace(body, '\n</para>\n<para>\n', '\n\n')
201 body = string.replace(body, '<para>\n', '')
202 body = string.replace(body, '<para>', '\n')
203 body = string.replace(body, '</para>\n', '')
204 body = re.sub('\.EE\n\n+(?!\.IP)', '.EE\n.IP\n', body)
205 body = re.sub('&(scons|SConstruct|SConscript|jar);', r'\\fB\1\\fP', body)
206 body = string.replace(body, '&Dir;', r'\fBDir\fP')
207 body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
208 body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
209 body = re.sub(r'<(command|envar|filename|literal|option)>([^<]*)</\1>',
211 body = re.sub(r'<(classname|emphasis|varname)>([^<]*)</\1>',
213 body = re.compile(r'^\\f([BI])(.*)\\fP\s*$', re.M).sub(r'.\1 \2', body)
214 body = re.compile(r'^\\f([BI])(.*)\\fP(\S+)', re.M).sub(r'.\1R \2 \3', body)
215 body = string.replace(body, '<', '<')
216 body = string.replace(body, '>', '>')
217 body = re.sub(r'\\([^f])', r'\\\\\1', body)
218 body = re.compile("^'\\\\\\\\", re.M).sub("'\\\\", body)
219 body = re.compile(r'^\.([BI]R?) -', re.M).sub(r'.\1 \-', body)
220 body = re.compile(r'^\.([BI]R?) (\S+)\\\\(\S+)', re.M).sub(r'.\1 "\2\\\\\\\\\2"', body)
221 body = re.compile(r'\\f([BI])-', re.M).sub(r'\\f\1\-', body)
224 if output_type == '--man':
225 processor_class = SCons_XML_to_man
226 elif output_type == '--sgml':
227 processor_class = SCons_XML_to_SGML
229 sys.stderr.write("Unknown output type '%s'\n" % output_type)
233 g = processor_class(h.builders,
234 description = 'builder',
237 idfunc = lambda x: x,
238 termfunc = lambda x: [x+'()', 'env.'+x+'()'],
239 entityfunc = lambda x: x)
241 g.mansep = lambda: ['\n', "'\\" + '"'*69 + '\n']
242 g.initial_chunks = lambda n: [n+'()', 'env.'+n+'()']
244 g.write(buildersfiles)
247 g = processor_class(h.tools,
248 description = 'tool',
251 idfunc = lambda x: string.replace(x, '+', 'X'),
252 termfunc = lambda x: [x],
253 entityfunc = lambda x: x)
258 g = processor_class(h.cvars,
259 description = 'construction variable',
262 idfunc = lambda x: x,
263 termfunc = lambda x: [x],
264 entityfunc = lambda x: '$'+x)
266 g.write(variablesfiles)