Repository: DataBiosphere/toil

Issue:
Sidebar TOC in docs sucks
The sidebar in the current documentation is not useful. It contains only two entries while the full TOC is further down on the page. While the full TOC can't probably be included in the sidebar it should at least contain the top-level entries.


Discussion:

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,7 +15,6 @@
 import os
 import inspect
 import re
-import subprocess
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -24,6 +23,10 @@
 
 import toil.version
 
+# This makes the modules located in docs/vendor available to import
+sys.path.insert(0, os.path.abspath('./vendor'))
+import sphinxcontrib.fulltoc
+
 
 def real_dir_name(p, n=1):
     p = os.path.realpath(p)
@@ -53,6 +56,7 @@ def real_dir_name(p, n=1):
     'sphinx.ext.todo',
     'sphinx.ext.coverage',
     'sphinx.ext.viewcode',
+    'sphinxcontrib.fulltoc',
 ]
 
 
diff --git a/docs/vendor/sphinxcontrib/__init__.py b/docs/vendor/sphinxcontrib/__init__.py
new file mode 100644
--- /dev/null
+++ b/docs/vendor/sphinxcontrib/__init__.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+"""
+    sphinxcontrib
+    ~~~~~~~~~~~~~
+    This package is a namespace package that contains all extensions
+    distributed in the ``sphinx-contrib`` distribution.
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/docs/vendor/sphinxcontrib/fulltoc.py b/docs/vendor/sphinxcontrib/fulltoc.py
new file mode 100644
--- /dev/null
+++ b/docs/vendor/sphinxcontrib/fulltoc.py
@@ -0,0 +1,90 @@
+# -*- encoding: utf-8 -*-
+#
+# Copyright © 2012 New Dream Network, LLC (DreamHost)
+#
+# Author: Doug Hellmann <doug.hellmann@dreamhost.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from sphinx import addnodes
+
+
+def html_page_context(app, pagename, templatename, context, doctree):
+    """Event handler for the html-page-context signal.
+    Modifies the context directly.
+     - Replaces the 'toc' value created by the HTML builder with one
+       that shows all document titles and the local table of contents.
+     - Sets display_toc to True so the table of contents is always
+       displayed, even on empty pages.
+     - Replaces the 'toctree' function with one that uses the entire
+       document structure, ignores the maxdepth argument, and uses
+       only prune and collapse.
+    """
+    rendered_toc = get_rendered_toctree(app.builder, pagename)
+    context['toc'] = rendered_toc
+    context['display_toc'] = True  # force toctree to display
+
+    if "toctree" not in context:
+        # json builder doesn't use toctree func, so nothing to replace
+        return
+
+    def make_toctree(collapse=True):
+        return get_rendered_toctree(app.builder,
+                                    pagename,
+                                    prune=False,
+                                    collapse=collapse,
+                                    )
+
+    context['toctree'] = make_toctree
+
+
+def get_rendered_toctree(builder, docname, prune=False, collapse=True):
+    """Build the toctree relative to the named document,
+    with the given parameters, and then return the rendered
+    HTML fragment.
+    """
+    fulltoc = build_full_toctree(builder,
+                                 docname,
+                                 prune=prune,
+                                 collapse=collapse,
+                                 )
+    rendered_toc = builder.render_partial(fulltoc)['fragment']
+    return rendered_toc
+
+
+def build_full_toctree(builder, docname, prune, collapse):
+    """Return a single toctree starting from docname containing all
+    sub-document doctrees.
+    """
+    env = builder.env
+    doctree = env.get_doctree(env.config.master_doc)
+    toctrees = []
+    for toctreenode in doctree.traverse(addnodes.toctree):
+        toctree = env.resolve_toctree(docname, builder, toctreenode,
+                                      collapse=collapse,
+                                      prune=prune,
+                                      )
+        toctrees.append(toctree)
+    if not toctrees:
+        return None
+    result = toctrees[0]
+    for toctree in toctrees[1:]:
+        if toctree:
+            result.extend(toctree.children)
+    env.resolve_references(result, docname, builder)
+    return result
+
+
+def setup(app):
+    app.connect('html-page-context', html_page_context)


Test patch: