summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-01-07 17:56:09 +0100
committerGeorg Brandl <georg@python.org>2010-01-07 17:56:09 +0100
commitcbfa4e8acfa7ec1b81dbac4afca8b498ef96569a (patch)
tree1e9354e3f8e01164bddf751f2a02858e1c2d2c77 /sphinx
parent6aaac900333341f58ca319ee0850e20af4214093 (diff)
downloadsphinx-cbfa4e8acfa7ec1b81dbac4afca8b498ef96569a.tar.gz
The ``html_sidebars`` config value can now contain patterns as keys, and the values can be lists that explicitly select which sidebar templates should be rendered.
That means that the builtin sidebar contents can be included only selectively.
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/builders/html.py40
-rw-r--r--sphinx/themes/basic/globaltoc.html15
-rw-r--r--sphinx/themes/basic/layout.html50
-rw-r--r--sphinx/themes/basic/localtoc.html15
-rw-r--r--sphinx/themes/basic/relations.html21
-rw-r--r--sphinx/themes/basic/searchbox.html26
-rw-r--r--sphinx/themes/basic/sourcelink.html18
-rw-r--r--sphinx/util/__init__.py18
8 files changed, 149 insertions, 54 deletions
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 31af5903..09be64f2 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -28,8 +28,8 @@ from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import package_dir, __version__
-from sphinx.util import SEP, os_path, relative_uri, ensuredir, \
- movefile, ustrftime, copy_static_entry, copyfile, compile_matchers
+from sphinx.util import SEP, os_path, relative_uri, ensuredir, patmatch, \
+ movefile, ustrftime, copy_static_entry, copyfile, compile_matchers, any
from sphinx.errors import SphinxError
from sphinx.search import js_index
from sphinx.theming import Theme
@@ -74,6 +74,9 @@ class StandaloneHTMLBuilder(Builder):
# Dito for this one.
css_files = []
+ default_sidebars = ['localtoc.html', 'relations.html',
+ 'sourcelink.html', 'searchbox.html']
+
# cached publisher object for snippets
_publisher = None
@@ -654,6 +657,33 @@ class StandaloneHTMLBuilder(Builder):
def get_outfilename(self, pagename):
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
+ def get_sidebars(self, pagename):
+ def has_wildcard(pattern):
+ return any(char in pattern for char in '*?[')
+ sidebars = None
+ matched = None
+ for pattern, patsidebars in self.config.html_sidebars.iteritems():
+ if patmatch(pagename, pattern):
+ if matched:
+ if has_wildcard(pattern):
+ # warn if both patterns contain wildcards
+ if has_wildcard(matched):
+ self.warn('page %s matches two patterns in '
+ 'html_sidebars: %r and %r' %
+ (pagename, matched, pattern))
+ # else the already matched pattern is more specific
+ # than the present one, because it contains no wildcard
+ continue
+ matched = pattern
+ sidebars = patsidebars
+ if sidebars is None:
+ sidebars = self.default_sidebars
+ elif isinstance(sidebars, basestring):
+ # 0.x compatible mode: insert custom sidebar before searchbox
+ sidebars = self.default_sidebars[:-1] + [sidebars] + \
+ self.default_sidebars[-1:]
+ return sidebars
+
# --------- these are overwritten by the serialization builder
def get_target_uri(self, docname, typ=None):
@@ -673,9 +703,9 @@ class StandaloneHTMLBuilder(Builder):
return uri
ctx['pathto'] = pathto
ctx['hasdoc'] = lambda name: name in self.env.all_docs
- ctx['customsidebar'] = self.config.html_sidebars.get(pagename)
ctx['encoding'] = encoding = self.config.html_output_encoding
ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
+ ctx['sidebars'] = self.get_sidebars(pagename)
ctx.update(addctx)
self.app.emit('html-page-context', pagename, templatename,
@@ -790,9 +820,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
def handle_page(self, pagename, ctx, templatename='page.html',
outfilename=None, event_arg=None):
ctx['current_page_name'] = pagename
- sidebarfile = self.config.html_sidebars.get(pagename)
- if sidebarfile:
- ctx['customsidebar'] = sidebarfile
+ ctx['sidebars'] = self.get_sidebars(pagename)
if not outfilename:
outfilename = path.join(self.outdir,
diff --git a/sphinx/themes/basic/globaltoc.html b/sphinx/themes/basic/globaltoc.html
new file mode 100644
index 00000000..472af34f
--- /dev/null
+++ b/sphinx/themes/basic/globaltoc.html
@@ -0,0 +1,15 @@
+{#
+ basic/globaltoc.html
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Sphinx sidebar template: global table of contents.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- block sidebartoc %}
+{%- if display_toc %}
+ <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
+ {{ toctree() }}
+{%- endif %}
+{%- endblock %}
diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html
index d86da2cb..97b68f8a 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -46,53 +46,9 @@
</a></p>
{%- endif %}
{%- endblock %}
- {%- block sidebartoc %}
- {%- if display_toc %}
- <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
- {{ toc }}
- {%- endif %}
- {%- endblock %}
- {%- block sidebarrel %}
- {%- if prev %}
- <h4>{{ _('Previous topic') }}</h4>
- <p class="topless"><a href="{{ prev.link|e }}"
- title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
- {%- endif %}
- {%- if next %}
- <h4>{{ _('Next topic') }}</h4>
- <p class="topless"><a href="{{ next.link|e }}"
- title="{{ _('next chapter') }}">{{ next.title }}</a></p>
- {%- endif %}
- {%- endblock %}
- {%- block sidebarsourcelink %}
- {%- if show_source and has_source and sourcename %}
- <h3>{{ _('This Page') }}</h3>
- <ul class="this-page-menu">
- <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
- rel="nofollow">{{ _('Show Source') }}</a></li>
- </ul>
- {%- endif %}
- {%- endblock %}
- {%- if customsidebar %}
- {% include customsidebar %}
- {%- endif %}
- {%- block sidebarsearch %}
- {%- if pagename != "search" %}
- <div id="searchbox" style="display: none">
- <h3>{{ _('Quick search') }}</h3>
- <form class="search" action="{{ pathto('search') }}" method="get">
- <input type="text" name="q" size="18" />
- <input type="submit" value="{{ _('Go') }}" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- <p class="searchtip" style="font-size: 90%">
- {{ _('Enter search terms or a module, class or function name.') }}
- </p>
- </div>
- <script type="text/javascript">$('#searchbox').show(0);</script>
- {%- endif %}
- {%- endblock %}
+ {%- for sidebar in sidebars %}
+ {%- include sidebar %}
+ {%- endfor %}
</div>
</div>
{%- endif %}{% endif %}
diff --git a/sphinx/themes/basic/localtoc.html b/sphinx/themes/basic/localtoc.html
new file mode 100644
index 00000000..dab70cd8
--- /dev/null
+++ b/sphinx/themes/basic/localtoc.html
@@ -0,0 +1,15 @@
+{#
+ basic/localtoc.html
+ ~~~~~~~~~~~~~~~~~~~
+
+ Sphinx sidebar template: local table of contents.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- block sidebartoc %}
+{%- if display_toc %}
+ <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
+ {{ toc }}
+{%- endif %}
+{%- endblock %}
diff --git a/sphinx/themes/basic/relations.html b/sphinx/themes/basic/relations.html
new file mode 100644
index 00000000..18e7cc4c
--- /dev/null
+++ b/sphinx/themes/basic/relations.html
@@ -0,0 +1,21 @@
+{#
+ basic/relations.html
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Sphinx sidebar template: relation links.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- block sidebarrel %}
+{%- if prev %}
+ <h4>{{ _('Previous topic') }}</h4>
+ <p class="topless"><a href="{{ prev.link|e }}"
+ title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
+{%- endif %}
+{%- if next %}
+ <h4>{{ _('Next topic') }}</h4>
+ <p class="topless"><a href="{{ next.link|e }}"
+ title="{{ _('next chapter') }}">{{ next.title }}</a></p>
+{%- endif %}
+{%- endblock %}
diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html
new file mode 100644
index 00000000..fb5e0889
--- /dev/null
+++ b/sphinx/themes/basic/searchbox.html
@@ -0,0 +1,26 @@
+{#
+ basic/searchbox.html
+ ~~~~~~~~~~~~~~~~~~~~
+
+ Sphinx sidebar template: quick search box.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- block sidebarsearch %}
+{%- if pagename != "search" %}
+<div id="searchbox" style="display: none">
+ <h3>{{ _('Quick search') }}</h3>
+ <form class="search" action="{{ pathto('search') }}" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="{{ _('Go') }}" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ {{ _('Enter search terms or a module, class or function name.') }}
+ </p>
+</div>
+<script type="text/javascript">$('#searchbox').show(0);</script>
+{%- endif %}
+{%- endblock %}
diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html
new file mode 100644
index 00000000..665e1272
--- /dev/null
+++ b/sphinx/themes/basic/sourcelink.html
@@ -0,0 +1,18 @@
+{#
+ basic/sourcelink.html
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ Sphinx sidebar template: "show source" link.
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{%- block sidebarsourcelink %}
+{%- if show_source and has_source and sourcename %}
+ <h3>{{ _('This Page') }}</h3>
+ <ul class="this-page-menu">
+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
+ rel="nofollow">{{ _('Show Source') }}</a></li>
+ </ul>
+{%- endif %}
+{%- endblock %}
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index ab277f4a..a7d9b67f 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -12,7 +12,6 @@
import os
import re
import sys
-import stat
import time
import errno
import types
@@ -285,6 +284,14 @@ def compile_matchers(patterns):
_pat_cache = {}
+def patmatch(name, pat):
+ """
+ Return if name matches pat. Adapted from fnmatch module.
+ """
+ if pat not in _pat_cache:
+ _pat_cache[pat] = re.compile(_translate_pattern(pat))
+ return _pat_cache[pat].match(name)
+
def patfilter(names, pat):
"""
Return the subset of the list NAMES that match PAT.
@@ -483,6 +490,15 @@ def split_explicit_title(text):
return False, text, text
+try:
+ any = any
+except NameError:
+ def any(gen):
+ for i in gen:
+ if i:
+ return True
+ return False
+
# monkey-patch Node.traverse to get more speed
# traverse() is called so many times during a build that it saves
# on average 20-25% overall build time!