sphinx.py (4446B)
1 """Support for Sphinx documentation 2 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 7 as a single string. 8 The default output format is html. 9 10 Specific formats can be installed in different directories by specifying the 11 install_path_<FORMAT> attribute. If not defined, the standard install_path 12 will be used instead. 13 14 Example wscript: 15 16 def configure(cnf): 17 conf.load('sphinx') 18 19 def build(bld): 20 bld( 21 features='sphinx', 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 26 ) 27 28 """ 29 30 from waflib.Node import Node 31 from waflib import Utils 32 from waflib import Task 33 from waflib.TaskGen import feature, after_method 34 35 36 def configure(cnf): 37 """Check if sphinx-build program is available and loads gnu_dirs tool.""" 38 cnf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False) 39 cnf.load('gnu_dirs') 40 41 42 @feature('sphinx') 43 def build_sphinx(self): 44 """Builds sphinx sources. 45 """ 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) 54 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) 58 59 self.env.SPHINX_OPTIONS = getattr(self, 'sphinx_options', []) 60 61 for source_file in self.sphinx_source.ant_glob('**/*'): 62 self.bld.add_manual_dependency(self.sphinx_source, source_file) 63 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 69 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() 74 75 Utils.def_attrs(sphinx_build_task, install_path=getattr(self, 'install_path_' + cfmt, getattr(self, 'install_path', get_install_path(sphinx_build_task)))) 76 77 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 83 else: 84 return object.env.DOCDIR 85 86 87 class SphinxBuildingTask(Task.Task): 88 color = 'BOLD' 89 run_str = '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} ${SPHINX_OPTIONS}' 90 91 def keyword(self): 92 return 'Compiling (%s)' % self.env.SPHINX_OUTPUT_FORMAT 93 94 def runnable_status(self): 95 96 for x in self.run_after: 97 if not x.hasrun: 98 return Task.ASK_LATER 99 100 self.signature() 101 ret = Task.Task.runnable_status(self) 102 if ret == Task.SKIP_ME: 103 # in case the files were removed 104 self.add_install() 105 return ret 106 107 108 def post_run(self): 109 self.add_install() 110 return Task.Task.post_run(self) 111 112 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, 117 install_from=nodes, 118 postpone=False, 119 cwd=self.sphinx_output_directory.make_node(self.env.SPHINX_OUTPUT_FORMAT), 120 relative_trick=True)