sphinx: support multiple output formats

formats (builders) can be passed as an array of strings.
keeps backwards compatibility if format is passed as string.
additionally support possibility to install the output of
the different builders to different directories
This commit is contained in:
Federico Pellegrin 2022-08-29 10:56:37 +02:00
parent bccfb03e76
commit 10c3ee7755
2 changed files with 41 additions and 21 deletions

View File

@ -7,4 +7,8 @@ def configure(cnf):
def build(bld):
bld(features='sphinx', sphinx_source='src', sphinx_output_format='html')
# When multiple output format are given, the install_path_FMT can specify where to place a specific format, fallback is always on install_path
bld(features='sphinx', sphinx_source='src', sphinx_output_format=['html', 'info', 'man'], install_path_man='${DOCDIR}/man', install_path='${DOCDIR}')
# Old style syntax, with single format
# bld(features='sphinx', sphinx_source='src', sphinx_output_format='man')

View File

@ -1,7 +1,15 @@
"""Support for Sphinx documentation
This is a wrapper for sphinx-build program. Please note that sphinx-build supports only one output format which can
passed to build via sphinx_output_format attribute. The default output format is html.
This is a wrapper for sphinx-build program. Please note that sphinx-build supports only
one output format at a time, but the tool can create multiple tasks to handle more.
The output formats can be passed via the sphinx_output_format, which is an array of
strings. For backwards compatibility if only one output is needed, it can be passed
as a single string.
The default output format is html.
Specific formats can be installed in different directories by specifying the
install_path_<FORMAT> attribute. If not defined, the standard install_path
will be used instead.
Example wscript:
@ -13,7 +21,8 @@ def build(bld):
features='sphinx',
sphinx_source='sources', # path to source directory
sphinx_options='-a -v', # sphinx-build program additional options
sphinx_output_format='man' # output format of sphinx documentation
sphinx_output_format=['html', 'man'], # output format of sphinx documentation
install_path_man='${DOCDIR}/man' # put man pages in a specific directory
)
"""
@ -43,35 +52,42 @@ def build_sphinx(self):
if not self.sphinx_source:
self.bld.fatal('Can\'t find sphinx_source: %r' % self.sphinx_source)
# In the taskgen we have the complete list of formats
Utils.def_attrs(self, sphinx_output_format='html')
self.env.SPHINX_OUTPUT_FORMAT = self.sphinx_output_format
self.sphinx_output_format = Utils.to_list(self.sphinx_output_format)
self.env.SPHINX_OPTIONS = getattr(self, 'sphinx_options', [])
for source_file in self.sphinx_source.ant_glob('**/*'):
self.bld.add_manual_dependency(self.sphinx_source, source_file)
sphinx_build_task = self.create_task('SphinxBuildingTask')
sphinx_build_task.set_inputs(self.sphinx_source)
sphinx_build_task.set_outputs(self.path.get_bld())
for cfmt in self.sphinx_output_format:
sphinx_build_task = self.create_task('SphinxBuildingTask')
sphinx_build_task.set_inputs(self.sphinx_source)
sphinx_build_task.set_outputs(self.path.get_bld())
# In task we keep the specific format this task is generating
sphinx_build_task.env.SPHINX_OUTPUT_FORMAT = cfmt
# the sphinx-build results are in <build + output_format> directory
self.sphinx_output_directory = self.path.get_bld().make_node(self.env.SPHINX_OUTPUT_FORMAT)
self.sphinx_output_directory.mkdir()
Utils.def_attrs(self, install_path=get_install_path(self))
# the sphinx-build results are in <build + output_format> directory
sphinx_build_task.sphinx_output_directory = self.path.get_bld().make_node(cfmt)
sphinx_build_task.sphinx_output_directory.mkdir()
Utils.def_attrs(sphinx_build_task, install_path=getattr(self, 'install_path_' + cfmt, getattr(self, 'install_path', get_install_path(sphinx_build_task))))
def get_install_path(tg):
if tg.env.SPHINX_OUTPUT_FORMAT == 'man':
return tg.env.MANDIR
elif tg.env.SPHINX_OUTPUT_FORMAT == 'info':
return tg.env.INFODIR
def get_install_path(object):
if object.env.SPHINX_OUTPUT_FORMAT == 'man':
return object.env.MANDIR
elif object.env.SPHINX_OUTPUT_FORMAT == 'info':
return object.env.INFODIR
else:
return tg.env.DOCDIR
return object.env.DOCDIR
class SphinxBuildingTask(Task.Task):
color = 'BOLD'
run_str = '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} ${SPHINX_OPTIONS}'
no_errcheck_out = 'yes' # Needed for multiple formats uses same root out dir
def keyword(self):
return 'Compiling (%s)' % self.env.SPHINX_OUTPUT_FORMAT
@ -96,10 +112,10 @@ class SphinxBuildingTask(Task.Task):
def add_install(self):
nodes = self.generator.sphinx_output_directory.ant_glob('**/*', quiet=True)
nodes = self.sphinx_output_directory.ant_glob('**/*', quiet=True)
self.outputs += nodes
self.generator.add_install_files(install_to=self.generator.install_path,
self.generator.add_install_files(install_to=self.install_path,
install_from=nodes,
postpone=False,
cwd=self.generator.sphinx_output_directory,
cwd=self.sphinx_output_directory,
relative_trick=True)