diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 309e3e3f258..2e5afebb5ff 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -35,4 +35,4 @@ GENERATE_DOXYGEN_HTML(Doxyfile_en.in pages html insert_examples.py) GENERATE_DOXYGEN_HTML(Doxyfile_cn.in pages_cn html_cn insert_examples_cn.py) add_subdirectory(sphinx) -add_custom_target(doc DEPENDS examples documented_example shogun_sphinx_doc ${DOC_DEPENDENCIES}) +add_custom_target(doc DEPENDS examples documented_examples shogun_sphinx_doc ${DOC_DEPENDENCIES}) diff --git a/doc/sphinx/extensions/sgexample.py b/doc/sphinx/extensions/sgexample.py new file mode 100644 index 00000000000..7b78c375535 --- /dev/null +++ b/doc/sphinx/extensions/sgexample.py @@ -0,0 +1,136 @@ +from sphinx.directives.code import LiteralInclude +from docutils import nodes +import os +import uuid +import sys + +def setup(app): + app.add_config_value('target_languages', None, True) + app.add_config_value('generated_examples_path', None, True) + + # register functions called upon node-visiting + app.add_node(sgexample, + html=(visit_sgexample_node, depart_sgexample_node)) + app.add_node(tabpanel, + html=(visit_tabpanel_node, depart_tabpanel_node)) + app.add_node(navtabs, + html=(visit_navtabs_node, depart_navtabs_node)) + app.add_node(navtab, + html=(visit_navtab_node, depart_navtab_node)) + app.add_node(fluid_tab_content, + html=(visit_fluid_tab_content, depart_fluid_tab_content)) + + app.add_directive('sgexample', ShogunExample) + app.connect('builder-inited', setup_parameters) + + return {'version': '0.1'} + +class LocalContext(object): + pass + +context = LocalContext() + +def setup_parameters(app): + context.target_languages = app.config.target_languages + context.generated_examples_path = app.config.generated_examples_path + +class sgexample(nodes.Element): + pass +class fluid_tab_content(nodes.Element): + pass +class tabpanel(nodes.Element): + pass +class navtabs(nodes.Element): + pass +class navtab(nodes.Element): + pass + +def visit_tabpanel_node(self, node): + self.body.append('
') +def depart_tabpanel_node(self, node): + self.body.append('
') + +def visit_navtabs_node(self, node): + self.body.append('') + +def visit_navtab_node(self, node): + cls = "" + if node.index is 0: + cls = 'class="active"' + self.body.append('') + +def visit_fluid_tab_content(self, node): + self.body.append('
') +def depart_fluid_tab_content(self, node): + self.body.append('
') + +def visit_sgexample_node(self, node): + cls = "" + if node.index is 0: + cls = 'active' + self.body.append('
' % (cls, node.language)) +def depart_sgexample_node(self, node): + self.body.append('
') + +class ShogunExample(LiteralInclude): + def element_id(self, target, uid): + return '%s-code-%s' % (target, uid) + def resolve_path(self, name): + return self.state.document.settings.env.relfn2path(name) + + def run(self): + + section = self.arguments[0].split(':')[1] + if section == 'begin': + self.options['end-before'] = section + elif section == 'end': + self.options['start-after'] = section + else: + self.options['start-after'] = section + self.options['end-before'] = section + uid = str(uuid.uuid1())[:6] + result = tabpanel() + nvtbs = navtabs() + nvtbs.uid = uid + for i, (target, _) in enumerate(context.target_languages): + nvtb = navtab() + nvtb.language = self.element_id(target, uid) + nvtb.index = i + nvtbs += nvtb + + result += nvtbs + + # save original node + fname = self.arguments[0].split(':')[0].strip() + fname = [context.generated_examples_path] + self.resolve_path(fname)[0].split(os.sep)[1:] + + tbcntnt = fluid_tab_content() + + # create nodes with parsed listings + for i, (target, extension) in enumerate(context.target_languages): + target_fname = list(fname) + target_fname.insert(1, target) + target_fname[-1] = os.path.splitext(target_fname[-1])[0]+'.'+extension + target_fname = os.path.join(*target_fname) + if not os.path.exists(target_fname): + raise IOError('Generated listing %s not found, it is expected to be created from the corresponding meta-example' % (os.path.abspath(target_fname))) + + relative_target_fname = os.path.relpath(target_fname, self.state.document.settings.env.srcdir) + self.arguments[0] = '/' + relative_target_fname + self.options['language'] = target + # call base class, returns list + include_container = sgexample() + include_container.language = self.element_id(target, uid) + include_container.index = i + include_container += LiteralInclude.run(self) + tbcntnt += include_container + result += tbcntnt + + return [result] + +def meta_convert(fname): + pass diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py index e9b7ab8d980..8253c55b764 100644 --- a/doc/sphinx/source/conf.py +++ b/doc/sphinx/source/conf.py @@ -187,6 +187,8 @@ ('java', 'java') ) +generated_examples_path = None + html_context = { 'target_languages': [x[0] for x in target_languages]