From c1a1a9fe5029a1614972ffcb0b8b91b1381e25d8 Mon Sep 17 00:00:00 2001 From: Federico Pellegrin Date: Thu, 1 Sep 2022 19:42:54 +0000 Subject: [PATCH] sphinx: support multiple output formats --- playground/sphinx/wscript | 6 ++++- waflib/extras/sphinx.py | 55 +++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/playground/sphinx/wscript b/playground/sphinx/wscript index 79ff287e..0df455e5 100644 --- a/playground/sphinx/wscript +++ b/playground/sphinx/wscript @@ -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') diff --git a/waflib/extras/sphinx.py b/waflib/extras/sphinx.py index 71d10283..7d88f8ad 100644 --- a/waflib/extras/sphinx.py +++ b/waflib/extras/sphinx.py @@ -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_ 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,30 +52,36 @@ 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) + # 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 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 directory + sphinx_build_task.sphinx_output_directory = self.path.get_bld().make_node(cfmt) + sphinx_build_task.set_outputs(sphinx_build_task.sphinx_output_directory) + 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): @@ -96,10 +111,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.make_node(self.env.SPHINX_OUTPUT_FORMAT), relative_trick=True)