FIX: Used wrong asciidoc conf in doxyToX.py.in
[freefoam.git] / data / utilities / doxyToX.py.in
blob6bf81fd69f43977bf580fc207327263fd364a24b
1 #!@PYTHON_EXECUTABLE@
2 #-------------------------------------------------------------------------------
3 # ______ _ ____ __ __
4 # | ____| _| |_ / __ \ /\ | \/ |
5 # | |__ _ __ ___ ___ / \| | | | / \ | \ / |
6 # | __| '__/ _ \/ _ ( (| |) ) | | |/ /\ \ | |\/| |
7 # | | | | | __/ __/\_ _/| |__| / ____ \| | | |
8 # |_| |_| \___|\___| |_| \____/_/ \_\_| |_|
10 # FreeFOAM: The Cross-Platform CFD Toolkit
12 # Copyright (C) 2008-2010 Michael Wild <themiwi@users.sf.net>
13 # Gerber van der Graaf <gerber_graaf@users.sf.net>
14 #-------------------------------------------------------------------------------
15 # License
16 # This file is part of FreeFOAM.
18 # FreeFOAM is free software; you can redistribute it and/or modify it
19 # under the terms of the GNU General Public License as published by the
20 # Free Software Foundation; either version 2 of the License, or (at your
21 # option) any later version.
23 # FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
24 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 # for more details.
28 # You should have received a copy of the GNU General Public License
29 # along with FreeFOAM; if not, write to the Free Software Foundation,
30 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 # Script
33 # doxyToX
35 # Description
36 # Converts the documentation comments in the file headers into
37 # various formats (currently manpage and xhtml).
39 #------------------------------------------------------------------------------
41 """Usage: doxyToX@PY_SCRIPT_SUFFIX@ [options] <name> <file>
43 Converts the documentation comments in the file headers into various formats
44 (such as asciidoc, man, pdf, html or xml). If <file> ends on [0-9]+.txt, it
45 is assumed that it is an AsciiDoc source file.
47 Options
48 -------
50 -help Display this help message
51 -f <format> Output format (default to 'manpage'). Possible values
52 are: manpage, xhtml and asciidoc (invalid for AsciiDoc
53 input files)
54 -o <outDir> Put the output in <outDir> instead of the same directory as
55 the source is in.
56 -a <confFile> Specify additional AsciiDoc configuration file to use. The
57 files @FOAM_DATA_DIR@/asciidoc/manpage.conf and
58 @FOAM_DATA_DIR@/asciidoc/html.conf for manpage and xhtml
59 formats, respectively are always used. Can be specified
60 multiple times.
61 -v <version> Use <version> as the version number. Defaults
62 to '@FOAM_VERSION_FULL@'.
63 <name> Name of the man-page to create.
64 <file> The source file to to process.
66 """
68 import imp
69 import sys
70 import os
71 import os.path
72 import re
73 import tempfile
74 sys.path.insert(0, '@FOAM_PYTHON_DIR@')
75 from FreeFOAM.compat import *
77 # cleanup utility function
78 def _cleanup_generated(files, dirs):
79 for f in files:
80 if os.path.isfile(f):
81 os.remove(f)
82 for d in dirs:
83 if os.path.isdir(d):
84 os.rmdir(d)
86 def _prepare_asciidoc(format, source):
87 if format == 'asciidoc':
88 echo("Error: Input and output cannot be both in AsciiDoc format", file=sys.stderr)
89 sys.exit(1)
90 section = None
91 outName = None
92 # parse the section and the name from the source
93 lines = open(source, 'rt').readlines()
94 for l in lines:
95 m = re.match(r'^=.*\((?P<section>\d+)\)\s*=$', l)
96 if m:
97 section = m.group('section')
98 break
99 i = 0
100 while i < len(lines):
101 l = lines[i]
102 if re.match(r'^NAME$', l):
103 outName = lines[i+2].split()[0]
104 break
105 i += 1
106 if not section:
107 echo("ERROR: '%s' is malformed (no man section number in title)"%source,
108 file=sys.stderr)
109 sys.exit(1)
110 elif not outName:
111 echo("ERROR: '%s' is malformed (does not contain NAME section)"%source,
112 file=sys.stderr)
113 sys.exit(1)
114 if format == 'manpage':
115 # only manpage format creates name from file contents,
116 # all others just strip .txt from the end
117 outName = os.path.join(outDir, outName+'.'+section+outExt)
118 else:
119 outName = os.path.join(outDir, os.path.basename(os.path.splitext(source)[0]))+outExt
120 return section, outName
122 def _prepare_header_comments(format, source):
123 import FreeFOAM.doxyToAsciidoc
124 # parse the header comments
125 doc = FreeFOAM.doxyToAsciidoc.Parser(source).parse()
126 # set up substitutions
127 substitutions = {
128 'arguments': ' '.join(map(lambda x: "'%s'"%x, doc['arguments'])),
129 'author': '\n'.join(doc['author']),
130 'bar': 57*'/',
131 'brief': '\n'.join(doc['brief']),
132 'detailed': '\n'.join(doc['detailed']),
133 'name': name,
134 'name_upper': name.upper(),
135 'optional_text': '',
136 'project': '@PROJECT_NAME@',
137 'project_lower': '@PROJECT_NAME@'.lower(),
138 'project_upper': '@PROJECT_NAME@'.upper(),
139 'section': section,
140 'seealso': '\n'.join(doc['seealso']),
141 'source': source,
142 'usage': '\n'.join(doc['usage']),
143 'version': '@FOAM_VERSION_FULL@',
145 options = []
146 for o, a in doc['options'].iteritems():
147 if a:
148 options.append("[%s '%s']"%(o,a))
149 else:
150 options.append("[%s]"%o)
151 substitutions['options'] = ' '.join(options)
152 if len('@FOAM_EXE_PREFIX@'):
153 substitutions['base_name'] = name.replace('@FOAM_EXE_PREFIX@', '', 1)
154 for s, t in doc['sections'].iteritems():
155 substitutions['optional_text'] += (
156 '\n'.join((s.upper(), len(s)*'-', '')) +
157 '\n'.join(t))
158 # construct output name
159 outName = os.path.join(outDir,
160 '%(name)s.%(section)s'%substitutions)+outExt
162 # set up temporary asciidoc source
163 tmpdir = ''
164 asciidocSource = '%(name)s.%(section)s.txt'%substitutions
165 if format == 'asciidoc':
166 asciidocSource = os.path.join(outDir, asciidocSource)
167 else:
168 tmpdir = tempfile.mkdtemp()
169 asciidocSource = os.path.join(tmpdir, asciidocSource)
170 # write it
171 try:
172 outFile = open(asciidocSource, 'wt')
173 outFile.write("""%(bar)s
174 THIS FILE WAS AUTOMATICALLY GENERATED FROM:
175 %(source)s
176 CHANGES TO THIS FILE WILL BE LOST! EDIT THE
177 ABOVE MENTIONED SOURCE FILE INSTEAD.
178 %(bar)s
179 = %(name_upper)s(%(section)s) =
180 :mansource: %(project)s
181 :manversion: %(version)s
182 :manmanual: %(project)s Manual
184 NAME
185 ----
186 %(name)s - %(brief)s
188 SYNOPSIS
189 --------
190 *%(project_lower)s %(base_name)s* %(arguments)s %(options)s
192 DESCRIPTION
193 -----------
194 %(detailed)s
196 OPTIONS
197 -------
198 %(usage)s
200 %(optional_text)s
202 SEE ALSO
203 --------
204 %(seealso)sAn overview of %(project)s is given in linkff:%(project_lower)s[1].
206 AUTHOR
207 ------
208 %(author)s
209 == %(project_upper)s ==
210 Part of the linkff:%(project_lower)s[1] suite.
212 COPYRIGHT
213 ---------
214 * Copyright (C) 2008-2010 Michael Wild.
215 * Copyright (C) 1991-2010 OpenCFD Ltd.
216 """%substitutions)
217 except:
218 _cleanup_generated([asciidocSource], [tmpdir])
219 raise
220 return asciidocSource, outName
222 # option parsing
223 outDir = '.'
224 version = '@FOAM_VERSION_FULL@'
225 format = 'manpage'
226 outExt = ''
227 customConfigs = []
228 attributes = []
230 args = sys.argv[1:]
231 while len(args) > 0:
232 a = args[0]
233 if a == '-h' or a == '-help':
234 echo(__doc__)
235 sys.exit(0)
236 elif a == '-f':
237 if len(args) < 2:
238 echo('Error: The -f option requires an argument', file=sys.stderr)
239 sys.exit(1)
240 format = args[1]
241 del args[0:2]
242 validformats = ('manpage', 'xhtml', 'asciidoc')
243 if format not in validformats:
244 echo('Error: Invalid format "%s". Must be one of\n %s'%
245 (format, ' '.join(validformats)), file=sys.stderr)
246 sys.exit(1)
247 if format == 'xhtml':
248 outExt = '.html'
249 elif format == 'asciidoc':
250 outExt = '.txt'
251 elif a == '-o':
252 if len(args) < 2:
253 echo('Error: The -o option requires an argument', file=sys.stderr)
254 sys.exit(1)
255 outDir = args[1]
256 del args[0:2]
257 elif a == '-a':
258 if len(args) < 2:
259 echo('Error: The -a option requires an argument', file=sys.stderr)
260 sys.exit(1)
261 customConfigs.append('"%"'%args[1])
262 del args[0:2]
263 elif a == '-v':
264 if len(args) < 2:
265 echo('Error: The -v option requires an argument', file=sys.stderr)
266 sys.exit(1)
267 version = args[1]
268 del args[0:2]
269 else:
270 break
272 if len(args) != 2:
273 echo('Error: the name and input file required arguments', file=sys.stderr)
274 sys.exit(1)
276 name = args[0]
277 source = args[1]
279 if not os.path.isfile(source):
280 echo('Error: "%s" does not exist or is not a file'%source, file=sys.stderr)
281 sys.exit(1)
283 if not os.path.isdir(outDir):
284 echo('Error: "%s" does not exist or is not a directory'%outDir, file=sys.stderr)
285 sys.exit(1)
287 # assemble list of configuration files
288 asciidocConfigs = [
289 '', # empty for formatting
291 if format == 'manpage':
292 asciidocConfigs.append('"@FOAM_DATA_DIR@/asciidoc/manpage.conf"')
293 elif format == 'xhtml':
294 asciidocConfigs.append('"@FOAM_DATA_DIR@/asciidoc/docbook.conf"')
295 asciidocConfigs.extend(customConfigs)
297 # check whether it is already asciidoc source
298 m = re.search(r'\.txt$', source)
299 if m:
300 is_generated = False
301 asciidocSource = source
302 section, outName = _prepare_asciidoc(format, source)
303 else:
304 is_generated = True
305 section = 1
306 asciidocSource, outName = _prepare_header_comments(format, source)
308 # process the AsciiDoc source
309 if format != 'asciidoc':
310 # load the a2x executble as a module
311 a2xfile = open('@A2X_EXECUTABLE@', 'rt')
312 try:
313 a2xmodule = imp.load_module('a2xmodule', a2xfile, a2xfile.name,
314 (os.path.splitext(a2xfile.name)[1], 'r', imp.PY_SOURCE))
315 finally:
316 a2xfile.close()
317 # set up options for a2x
318 opts = {
319 'doctype': 'manpage',
320 'destination_dir': os.path.abspath(outDir),
321 'format': format,
322 'asciidoc_opts': ' -f '.join(asciidocConfigs),
323 'xsltproc_opts': '--param man.th.title.max.length 100',
324 'asciidoc_file': asciidocSource,
325 'conf_file': None,
326 'verbose': False,
327 'resource_dirs': [],
328 'resources': [],
329 'resource_manifest': None,
330 'attributes': attributes,
331 'epubcheck': False,
332 'icons': False,
333 'icons_dir': None,
334 'keep_artifacts': False,
335 'lynx': False,
336 'no_xmllint': False,
337 'dry_run': False,
338 'stylesheet': '../@PROJECT_NAME@ManPage.css',
339 'dblatex_opts': '',
340 'fop': False,
341 'fop_opts': '',
342 'xsl_file': None,
344 # instantiate A2X class and execute the thing
345 a2x = a2xmodule.A2X(opts)
346 a2xmodule.OPTIONS = a2x
347 a2x.load_conf()
348 a2x.execute()
350 # tidy up
351 if is_generated:
352 _cleanup_generated([asciidocSource], [os.path.dirname(asciidocSource)])
353 # compute the final destination name the output SHOULD have
354 destName = os.path.join(outDir,
355 '%s.%s%s'%(name, section, outExt))
356 # if that doesn't match the output file name, rename it
357 if outName != destName:
358 os.rename(outName, destName)
360 # ------------------------- vim: set sw=3 sts=3 et: --------------- end-of-file