1 """Support for Sphinx documentation
3 This is a wrapper for sphinx-build program. Please note that sphinx-build supports only
4 one output format at a time, but the tool can create multiple tasks to handle more.
5 The output formats can be passed via the sphinx_output_format, which is an array of
6 strings. For backwards compatibility if only one output is needed, it can be passed
8 The default output format is html.
10 Specific formats can be installed in different directories by specifying the
11 install_path_<FORMAT> attribute. If not defined, the standard install_path
22 sphinx_source='sources', # path to source directory
23 sphinx_options='-a -v', # sphinx-build program additional options
24 sphinx_output_format=['html', 'man'], # output format of sphinx documentation
25 install_path_man='${DOCDIR}/man' # put man pages in a specific directory
30 from waflib
.Node
import Node
31 from waflib
import Utils
32 from waflib
import Task
33 from waflib
.TaskGen
import feature
, after_method
37 """Check if sphinx-build program is available and loads gnu_dirs tool."""
38 cnf
.find_program('sphinx-build', var
='SPHINX_BUILD', mandatory
=False)
43 def build_sphinx(self
):
44 """Builds sphinx sources.
46 if not self
.env
.SPHINX_BUILD
:
47 self
.bld
.fatal('Program SPHINX_BUILD not defined.')
48 if not getattr(self
, 'sphinx_source', None):
49 self
.bld
.fatal('Attribute sphinx_source not defined.')
50 if not isinstance(self
.sphinx_source
, Node
):
51 self
.sphinx_source
= self
.path
.find_node(self
.sphinx_source
)
52 if not self
.sphinx_source
:
53 self
.bld
.fatal('Can\'t find sphinx_source: %r' % self
.sphinx_source
)
55 # In the taskgen we have the complete list of formats
56 Utils
.def_attrs(self
, sphinx_output_format
='html')
57 self
.sphinx_output_format
= Utils
.to_list(self
.sphinx_output_format
)
59 self
.env
.SPHINX_OPTIONS
= getattr(self
, 'sphinx_options', [])
61 for source_file
in self
.sphinx_source
.ant_glob('**/*'):
62 self
.bld
.add_manual_dependency(self
.sphinx_source
, source_file
)
64 for cfmt
in self
.sphinx_output_format
:
65 sphinx_build_task
= self
.create_task('SphinxBuildingTask')
66 sphinx_build_task
.set_inputs(self
.sphinx_source
)
67 # In task we keep the specific format this task is generating
68 sphinx_build_task
.env
.SPHINX_OUTPUT_FORMAT
= cfmt
70 # the sphinx-build results are in <build + output_format> directory
71 sphinx_build_task
.sphinx_output_directory
= self
.path
.get_bld().make_node(cfmt
)
72 sphinx_build_task
.set_outputs(sphinx_build_task
.sphinx_output_directory
)
73 sphinx_build_task
.sphinx_output_directory
.mkdir()
75 Utils
.def_attrs(sphinx_build_task
, install_path
=getattr(self
, 'install_path_' + cfmt
, getattr(self
, 'install_path', get_install_path(sphinx_build_task
))))
78 def get_install_path(object):
79 if object.env
.SPHINX_OUTPUT_FORMAT
== 'man':
80 return object.env
.MANDIR
81 elif object.env
.SPHINX_OUTPUT_FORMAT
== 'info':
82 return object.env
.INFODIR
84 return object.env
.DOCDIR
87 class SphinxBuildingTask(Task
.Task
):
89 run_str
= '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} -d ${TGT[0].bld_dir()}/doctrees-${SPHINX_OUTPUT_FORMAT} ${SPHINX_OPTIONS}'
92 return 'Compiling (%s)' % self
.env
.SPHINX_OUTPUT_FORMAT
94 def runnable_status(self
):
96 for x
in self
.run_after
:
101 ret
= Task
.Task
.runnable_status(self
)
102 if ret
== Task
.SKIP_ME
:
103 # in case the files were removed
110 return Task
.Task
.post_run(self
)
113 def add_install(self
):
114 nodes
= self
.sphinx_output_directory
.ant_glob('**/*', quiet
=True)
115 self
.outputs
+= nodes
116 self
.generator
.add_install_files(install_to
=self
.install_path
,
119 cwd
=self
.sphinx_output_directory
.make_node(self
.env
.SPHINX_OUTPUT_FORMAT
),