summaryrefslogtreecommitdiff
path: root/sphinx
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-02-20 01:13:23 +0100
committerGeorg Brandl <georg@python.org>2010-02-20 01:13:23 +0100
commit69af046cfcbadba827d8301a7bfaa2c4f1e5d3a8 (patch)
tree4cb0f9cd3897bf61524e76eb51f3d313f0157f0e /sphinx
parent71a29487ac88b6b48ae62cbad1c97de561cabe06 (diff)
downloadsphinx-69af046cfcbadba827d8301a7bfaa2c4f1e5d3a8.tar.gz
Make the concept of "module index" generalized to domains. As a side-effect, the latex modindex is no longer generated by LaTeX.
Diffstat (limited to 'sphinx')
-rw-r--r--sphinx/builders/html.py129
-rw-r--r--sphinx/builders/htmlhelp.py6
-rw-r--r--sphinx/builders/qthelp.py6
-rw-r--r--sphinx/config.py6
-rw-r--r--sphinx/domains/__init__.py18
-rw-r--r--sphinx/domains/python.py80
-rw-r--r--sphinx/environment.py12
-rw-r--r--sphinx/quickstart.py4
-rw-r--r--sphinx/texinputs/Makefile2
-rw-r--r--sphinx/texinputs/sphinx.sty83
-rw-r--r--sphinx/themes/basic/domainindex.html54
-rw-r--r--sphinx/themes/basic/layout.html2
-rw-r--r--sphinx/themes/basic/modindex.html52
-rw-r--r--sphinx/themes/basic/static/doctools.js8
-rw-r--r--sphinx/util/texescape.py2
-rw-r--r--sphinx/writers/latex.py120
16 files changed, 287 insertions, 297 deletions
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 7f4e4c66..c722a195 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -230,6 +230,20 @@ class StandaloneHTMLBuilder(Builder):
defaults=self.env.settings,
components=(self.docwriter,)).get_default_values()
+ # determine the additional indices to include
+ self.domain_indices = []
+ # html_domain_indices can be False/True or a list of index names
+ indices_config = self.config.html_domain_indices
+ if indices_config:
+ for domain in self.env.domains.itervalues():
+ for indexinfo in domain.indices:
+ indexname = '%s-%s' % (domain.name, indexinfo[0])
+ if isinstance(indices_config, list):
+ if indexname not in indices_config:
+ continue
+ if domain.has_index_entries(indexinfo[0]):
+ self.domain_indices.append((domain.name,) + indexinfo)
+
# format the "last updated on" string, only once is enough since it
# typically doesn't include the time of day
lufmt = self.config.html_last_updated_fmt
@@ -254,11 +268,8 @@ class StandaloneHTMLBuilder(Builder):
rellinks = []
if self.config.html_use_index:
rellinks.append(('genindex', _('General Index'), 'I', _('index')))
- # XXX generalization of modindex?
- if self.config.html_use_modindex and \
- self.env.domaindata['py']['modules']:
- rellinks.append(('modindex', _('Global Module Index'),
- 'M', _('modules')))
+ for index in self.domain_indices:
+ rellinks.append(('%s-%s' % index[0:2], index[2], '', index[3]))
if self.config.html_style is not None:
stylename = self.config.html_style
@@ -396,9 +407,8 @@ class StandaloneHTMLBuilder(Builder):
if self.config.html_use_index:
self.write_genindex()
- # the global module index
- if self.config.html_use_modindex:
- self.write_modindex()
+ # the global domain-specific indices
+ self.write_domain_indices()
# the search page
if self.name != 'htmlhelp':
@@ -454,98 +464,17 @@ class StandaloneHTMLBuilder(Builder):
else:
self.handle_page('genindex', genindexcontext, 'genindex.html')
- def write_modindex(self):
- moduleindex = self.env.domaindata['py']['modules']
- if not moduleindex:
- return
- # the sorted list of all modules, for the global module index
- modules = sorted(((mn, (self.get_relative_uri('modindex', fn) +
- '#module-' + mn, sy, pl, dep))
- for (mn, (fn, sy, pl, dep)) in
- moduleindex.iteritems()),
- key=lambda x: x[0].lower())
- # collect all platforms
- platforms = set()
- # sort out collapsable modules
- modindexentries = []
- letters = []
- pmn = ''
- num_toplevels = 0
- num_collapsables = 0
- cg = 0 # collapse group
- fl = '' # first letter
- for mn, (fn, sy, pl, dep) in modules:
- pl = pl and pl.split(', ') or []
- platforms.update(pl)
-
- ignore = self.env.config['modindex_common_prefix']
- ignore = sorted(ignore, key=len, reverse=True)
- for i in ignore:
- if mn.startswith(i):
- mn = mn[len(i):]
- stripped = i
- break
- else:
- stripped = ''
-
- # we stripped the whole module name
- if not mn:
- continue
-
- if fl != mn[0].lower() and mn[0] != '_':
- # heading
- letter = mn[0].upper()
- if letter not in letters:
- modindexentries.append(['', False, 0, False,
- letter, '', [], False, ''])
- letters.append(letter)
- tn = mn.split('.')[0]
- if tn != mn:
- # submodule
- if pmn == tn:
- # first submodule - make parent collapsable
- modindexentries[-1][1] = True
- num_collapsables += 1
- elif not pmn.startswith(tn):
- # submodule without parent in list, add dummy entry
- cg += 1
- modindexentries.append([tn, True, cg, False, '', '',
- [], False, stripped])
- else:
- num_toplevels += 1
- cg += 1
- modindexentries.append([mn, False, cg, (tn != mn), fn, sy, pl,
- dep, stripped])
- pmn = mn
- fl = mn[0].lower()
- platforms = sorted(platforms)
-
- # apply heuristics when to collapse modindex at page load:
- # only collapse if number of toplevel modules is larger than
- # number of submodules
- collapse = len(modules) - num_toplevels < num_toplevels
-
- # As some parts of the module names may have been stripped, those
- # names have changed, thus it is necessary to sort the entries.
- if ignore:
- def sorthelper(entry):
- name = entry[0]
- if name == '':
- # heading
- name = entry[4]
- return name.lower()
-
- modindexentries.sort(key=sorthelper)
- letters.sort()
-
- modindexcontext = dict(
- modindexentries = modindexentries,
- platforms = platforms,
- letters = letters,
- collapse_modindex = collapse,
- )
- self.info(' modindex', nonl=1)
- self.handle_page('modindex', modindexcontext, 'modindex.html')
+ def write_domain_indices(self):
+ for index in self.domain_indices:
+ content, collapse = self.env.domains[index[0]].get_index(index[1])
+ indexcontext = dict(
+ indextitle = index[2],
+ content = content,
+ collapse_index = collapse,
+ )
+ indexname = '%s-%s' % index[0:2]
+ self.info(' ' + indexname, nonl=1)
+ self.handle_page(indexname, indexcontext, 'domainindex.html')
def copy_image_files(self):
# copy image files
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
index b7adc638..9bbe0a5d 100644
--- a/sphinx/builders/htmlhelp.py
+++ b/sphinx/builders/htmlhelp.py
@@ -217,9 +217,9 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
# special books
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
'index.html'))
- if self.config.html_use_modindex:
- f.write('<LI> ' + object_sitemap % (_('Global Module Index'),
- 'modindex.html'))
+ for index in self.domain_indices:
+ f.write('<LI> ' + object_sitemap % (index[2],
+ '%s-%s.html' % index[0:2]))
# the TOC
tocdoc = self.env.get_and_resolve_doctree(
self.config.master_doc, self, prune_toctrees=False)
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
index 623a5c95..72708803 100644
--- a/sphinx/builders/qthelp.py
+++ b/sphinx/builders/qthelp.py
@@ -130,9 +130,9 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
for node in tocdoc.traverse(istoctree):
sections.extend(self.write_toc(node))
- if self.config.html_use_modindex:
- item = section_template % {'title': _('Global Module Index'),
- 'ref': 'modindex.html'}
+ for index in self.domain_indices:
+ item = section_template % {'title': index[2],
+ 'ref': '%s-%s.html' % index[0:2]}
sections.append(' '*4*4 + item)
sections = '\n'.join(sections)
diff --git a/sphinx/config.py b/sphinx/config.py
index f6f506bc..1c262eb1 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -81,7 +81,8 @@ class Config(object):
html_translator_class = (None, 'html'),
html_sidebars = ({}, 'html'),
html_additional_pages = ({}, 'html'),
- html_use_modindex = (True, 'html'),
+ html_use_modindex = (True, 'html'), # deprecated
+ html_domain_indices = (True, 'html'),
html_add_permalinks = (True, 'html'),
html_use_index = (True, 'html'),
html_split_index = (False, 'html'),
@@ -125,7 +126,8 @@ class Config(object):
latex_logo = (None, None),
latex_appendices = ([], None),
latex_use_parts = (False, None),
- latex_use_modindex = (True, None),
+ latex_use_modindex = (True, None), # deprecated
+ latex_domain_indices = (True, None),
# paper_size and font_size are still separate values
# so that you can give them easily on the command line
latex_paper_size = ('letter', None),
diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py
index 3f1257ba..e5d3b06f 100644
--- a/sphinx/domains/__init__.py
+++ b/sphinx/domains/__init__.py
@@ -70,6 +70,8 @@ class Domain(object):
directives = {}
#: role name -> role callable
roles = {}
+ #: (index identifier, localized index name, localized short name) tuples
+ indices = []
#: data value for a fresh environment
initial_data = {}
@@ -175,6 +177,22 @@ class Domain(object):
"""
return []
+ def has_index_entries(self, name, docnames=None):
+ """
+ Return True if there are entries for the index given by *name*. If
+ *docnames* is given, restrict to entries referring to these docnames.
+ """
+ return False
+
+ def get_index(self, name, docnames=None):
+ """
+ Return entries for the index given by *name*. If *docnames* is given,
+ restrict to entries referring to these docnames.
+
+ XXX document return format
+ """
+ return [], False
+
from sphinx.domains.c import CDomain
from sphinx.domains.std import StandardDomain
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index c1619200..995914c1 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -462,6 +462,9 @@ class PythonDomain(Domain):
'objects': {}, # fullname -> docname, objtype
'modules': {}, # modname -> docname, synopsis, platform, deprecated
}
+ indices = [
+ ('modindex', l_('Global Module Index'), l_('modules')),
+ ]
def clear_doc(self, docname):
for fullname, (fn, _) in self.data['objects'].items():
@@ -545,3 +548,80 @@ class PythonDomain(Domain):
yield (modname, 'module', info[0], 'module-' + modname, 0)
for refname, (docname, type) in self.data['objects'].iteritems():
yield (refname, type, docname, refname, 1)
+
+ def has_index_entries(self, name, docnames=None):
+ if name != 'modindex':
+ return False
+ if not docnames:
+ return bool(self.data['modules'])
+ else:
+ for modname, info in self.data['modules'].iteritems():
+ if info[0] in docnames:
+ return True
+ return False
+
+ def get_index(self, name, docnames=None):
+ if name != 'modindex':
+ return None, None
+
+ content = {}
+ # list of prefixes to ignore
+ ignores = self.env.config['modindex_common_prefix']
+ ignores = sorted(ignores, key=len, reverse=True)
+ # list of all modules, sorted by module name
+ modules = sorted(self.data['modules'].iteritems(),
+ key=lambda x: x[0].lower())
+ # sort out collapsable modules
+ prev_modname = ''
+ num_toplevels = 0
+ current_group = 0 # collapse group
+ for modname, (docname, synopsis, platforms, deprecated) in modules:
+ if docnames and docname not in docnames:
+ continue
+
+ for ignore in ignores:
+ if modname.startswith(ignore):
+ modname = modname[len(ignore):]
+ stripped = ignore
+ break
+ else:
+ stripped = ''
+
+ # we stripped the whole module name?
+ if not modname:
+ modname, stripped = stripped, ''
+
+ entries = content.setdefault(modname[0].lower(), [])
+
+ package = modname.split('.')[0]
+ if package != modname:
+ # it's a submodule
+ if prev_modname == package:
+ # first submodule - make parent a group head
+ entries[-1][1] = 1
+ elif not prev_modname.startswith(package):
+ # submodule without parent in list, add dummy entry
+ current_group += 1
+ entries.append([stripped + package, 1, current_group,
+ '', '', '', '', ''])
+ grouptype = 2
+ else:
+ num_toplevels += 1
+ current_group += 1
+ grouptype = 0
+
+ qualifier = deprecated and _('Deprecated') or ''
+ entries.append([stripped + modname, grouptype, current_group,
+ docname, 'module-' + stripped + modname,
+ platforms, qualifier, synopsis])
+ prev_modname = modname
+
+ # apply heuristics when to collapse modindex at page load:
+ # only collapse if number of toplevel modules is larger than
+ # number of submodules
+ collapse = len(modules) - num_toplevels < num_toplevels
+
+ # sort by first letter
+ content = sorted(content.iteritems())
+
+ return content, collapse
diff --git a/sphinx/environment.py b/sphinx/environment.py
index d8f1f9fd..c35d0e59 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -110,6 +110,8 @@ class DefaultSubstitutions(Transform):
class MoveModuleTargets(Transform):
"""
Move module targets to their nearest enclosing section title.
+
+ XXX Python specific
"""
default_priority = 210
@@ -318,11 +320,13 @@ class BuildEnvironment:
self.temp_data = {}
# Some magically present labels
- def add_magic_label(name, description):
- self.labels[name] = (name, '', description)
- self.anonlabels[name] = (name, '')
+ def add_magic_label(name, description, target=None):
+ self.labels[name] = (target or name, '', description)
+ self.anonlabels[name] = (target or name, '')
add_magic_label('genindex', _('Index'))
- add_magic_label('modindex', _('Module Index'))
+ # XXX add per domain?
+ # compatibility alias
+ add_magic_label('modindex', _('Module Index'), 'py-modindex')
add_magic_label('search', _('Search Page'))
def set_warnfunc(self, func):
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 73fb968d..daa88c36 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -164,7 +164,7 @@ html_static_path = ['%(dot)sstatic']
#html_additional_pages = {}
# If false, no module index is generated.
-#html_use_modindex = True
+#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
@@ -223,7 +223,7 @@ latex_documents = [
#latex_appendices = []
# If false, no module index is generated.
-#latex_use_modindex = True
+#latex_domain_indices = True
# -- Options for Epub output ---------------------------------------------------
diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile
index 5c0d5018..d5a73f5b 100644
--- a/sphinx/texinputs/Makefile
+++ b/sphinx/texinputs/Makefile
@@ -37,7 +37,6 @@ bz2: tar
latex $(LATEXOPTS) '$<'
latex $(LATEXOPTS) '$<'
-makeindex -s python.ist '$(basename $<).idx'
- -makeindex -s python.ist '$(basename mod$<).idx'
latex $(LATEXOPTS) '$<'
latex $(LATEXOPTS) '$<'
@@ -46,7 +45,6 @@ bz2: tar
pdflatex $(LATEXOPTS) '$<'
pdflatex $(LATEXOPTS) '$<'
-makeindex -s python.ist '$(basename $<).idx'
- -makeindex -s python.ist '$(basename mod$<).idx'
pdflatex $(LATEXOPTS) '$<'
pdflatex $(LATEXOPTS) '$<'
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index dab48b96..a0c14cb4 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -130,8 +130,6 @@
\newcommand{\samp}[1]{`\code{#1}'}
\newcommand{\email}[1]{\textsf{#1}}
-\newcommand{\py@modulebadkey}{{--just-some-junk--}}
-
% Redefine the Verbatim environment to allow border and background colors.
% The original environment is still used for verbatims within tables.
\let\OriginalVerbatim=\Verbatim
@@ -193,89 +191,12 @@
\index{#4!#1 #2 #3}
}
-
-% Support for the module index.
-%
-\newif\ifpy@UseModuleIndex
-\py@UseModuleIndexfalse
-
-\newcommand{\makemodindex}{
- \newwrite\modindexfile
- \openout\modindexfile=mod\jobname.idx
- \py@UseModuleIndextrue
-}
-
-\newcommand{\printmodindex}{
- \@input@{mod\jobname.ind}
-}
-
-% Add the defining entry for a module.
-\newcommand{\py@modindex}[2]{%
- \renewcommand{\py@thismodule}{#1}
- \ifpy@UseModuleIndex%
- \@ifundefined{py@modplat@\py@thismodulekey}{
- \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}|hyperpage}{\thepage}}%
- }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1 }%
- \emph{(\platformof{\py@thismodulekey})}}|hyperpage}{\thepage}}%
- }
- \fi%
-}
-
-% "Current" keys
-\newcommand{\py@thismodule}{}
-\newcommand{\py@thismodulekey}{}
-\newcommand{\py@thismoduletype}{}
-\newcommand{\py@emptymodule}{}
-
-% \declaremodule[key]{type}{name}
-\newcommand{\declaremodule}[3][\py@modulebadkey]{
- \renewcommand{\py@thismoduletype}{#2}
- \ifx\py@modulebadkey#1
- \renewcommand{\py@thismodulekey}{#3}
- \else
- \renewcommand{\py@thismodulekey}{#1}
- \fi
- \py@modindex{#3}{}
- %\label{module-\py@thismodulekey}
-}
-
-% Record module platforms for the Module Index.
-\newif\ifpy@ModPlatformFileIsOpen \py@ModPlatformFileIsOpenfalse
-\long\def\py@writeModPlatformFile#1{%
- \protected@write\py@ModPlatformFile%
- {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
- {\string#1}%
-}
-\newcommand{\py@ModPlatformFilename}{\jobname.pla}
-\newcommand{\platform}[1]{
- \ifpy@ModPlatformFileIsOpen\else
- \newwrite\py@ModPlatformFile
- \openout\py@ModPlatformFile=\py@ModPlatformFilename
- \py@ModPlatformFileIsOpentrue
- \fi
- \py@writeModPlatformFile{\py@defplatform{\py@thismodulekey}{#1}}
-}
-\newcommand{\py@defplatform}[2]{\expandafter\def\csname py@modplat@#1\endcsname{#2}}
-\newcommand{\platformof}[1]{\csname py@modplat@#1\endcsname}
-
-\InputIfFileExists{\jobname.pla}{}{}
-
% \moduleauthor{name}{email}
\newcommand{\moduleauthor}[2]{}
% \sectionauthor{name}{email}
\newcommand{\sectionauthor}[2]{}
-% Ignore module synopsis.
-\newcommand{\modulesynopsis}[1]{}
-
-% Reset "current" objects.
-\newcommand{\resetcurrentobjects}{
- \renewcommand{\py@thismodule}{}
- \renewcommand{\py@thismodulekey}{}
- \renewcommand{\py@thismoduletype}{}
-}
-
% Augment the sectioning commands used to get our own font family in place,
% and reset some internal data items:
\titleformat{\section}{\Large\py@HeaderFamily}%
@@ -301,8 +222,6 @@
\let\makelabel=\py@itemnewline}
}{\end{list}}
-\let\py@badkey=\@undefined
-
% \optional is used for ``[, arg]``, i.e. desc_optional nodes.
\newcommand{\optional}[1]{%
{\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
@@ -325,7 +244,7 @@
% the example completely.
%
\newcommand{\grammartoken}[1]{\texttt{#1}}
-\newenvironment{productionlist}[1][\py@badkey]{
+\newenvironment{productionlist}[1][\@undefined]{
\def\optional##1{{\Large[}##1{\Large]}}
\def\production##1##2{\hypertarget{grammar-token-##1}{}%
\code{##1}&::=&\code{##2}\\}
diff --git a/sphinx/themes/basic/domainindex.html b/sphinx/themes/basic/domainindex.html
new file mode 100644
index 00000000..9f4d4637
--- /dev/null
+++ b/sphinx/themes/basic/domainindex.html
@@ -0,0 +1,54 @@
+{#
+ basic/domainindex.html
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Template for domain indices (module index, ...).
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{% extends "layout.html" %}
+{% set title = indextitle %}
+{% block extrahead %}
+{{ super() }}
+{% if not embedded and collapse_index %}
+ <script type="text/javascript">
+ DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
+ </script>
+{% endif %}
+{% endblock %}
+{% block body %}
+
+ <h1>{{ indextitle }}</h1>
+
+ <div class="modindex-jumpbox">
+ {%- for (letter, entries) in content %}
+ <a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a>
+ {%- if not loop.last %} | {% endif %}
+ {%- endfor %}
+ </div>
+
+ <table class="indextable modindextable" cellspacing="0" cellpadding="2">
+ {%- for letter, entries in content %}
+ <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+ <tr class="cap"><td></td><td><a name="cap-{{ letter }}">
+ <strong>{{ letter }}</strong></a></td><td></td></tr>
+ {%- for (name, grouptype, group, page, anchor, extra, qualifier, description)
+ in entries %}
+ <tr{% if grouptype == 2 %} class="cg-{{ cgroup }}"{% endif %}>
+ <td>{% if grouptype == 1 -%}
+ <img src="{{ pathto('_static/minus.png', 1) }}" id="toggle-{{ group }}"
+ class="toggler" style="display: none" alt="-" />
+ {%- endif %}</td>
+ <td>{% if grouptype == 2 %}&nbsp;&nbsp;&nbsp;{% endif %}
+ {% if page %}<a href="{{ pathto(page) }}#{{ anchor }}">{% endif -%}
+ <tt class="xref">{{ name|e }}</tt>
+ {%- if page %}</a>{% endif %}
+ {%- if extra %} <em>({{ extra|e }})</em>{% endif -%}
+ </td><td>{% if qualifier %}<strong>{{ qualifier|e }}:</strong>{% endif %}
+ <em>{{ description|e }}</em></td></tr>
+ {%- endfor %}
+ {%- endfor %}
+ </table>
+
+{% endblock %}
diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html
index d3ef88ab..c844dabc 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -98,7 +98,7 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}',
VERSION: '{{ release|e }}',
- COLLAPSE_MODINDEX: false,
+ COLLAPSE_INDEX: false,
FILE_SUFFIX: '{{ file_suffix }}',
HAS_SOURCE: {{ has_source|lower }}
};
diff --git a/sphinx/themes/basic/modindex.html b/sphinx/themes/basic/modindex.html
deleted file mode 100644
index 96f8ac43..00000000
--- a/sphinx/themes/basic/modindex.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{#
- basic/modindex.html
- ~~~~~~~~~~~~~~~~~~~
-
- Template for the module index.
-
- :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-#}
-{% extends "layout.html" %}
-{% set title = _('Global Module Index') %}
-{% block extrahead %}
-{{ super() }}
-{% if not embedded and collapse_modindex %}
- <script type="text/javascript">
- DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX = true;
- </script>
-{% endif %}
-{% endblock %}
-{% block body %}
-
- <h1 id="global-module-index">{{ _('Global Module Index') }}</h1>
-
- <div class="modindex-jumpbox">
- {%- for letter in letters %}
- <a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a> {% if not loop.last %}| {% endif %}
- {%- endfor %}
- </div>
-
- <table class="indextable modindextable" cellspacing="0" cellpadding="2">
- {%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %}
- {%- if not modname -%}
- <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
- <tr class="cap"><td></td><td><a name="cap-{{ fname }}"><strong>{{ fname }}</strong></a></td><td></td></tr>
- {%- else -%}
- <tr{% if indent %} class="cg-{{ cgroup }}"{% endif %}>
- <td>{% if collapse -%}
- <img src="{{ pathto('_static/minus.png', 1) }}" id="toggle-{{ cgroup }}"
- class="toggler" style="display: none" alt="-" />
- {%- endif %}</td>
- <td>{% if indent %}&nbsp;&nbsp;&nbsp;{% endif %}
- {% if fname %}<a href="{{ fname }}">{% endif -%}
- <tt class="xref">{{ stripped|e }}{{ modname|e }}</tt>
- {%- if fname %}</a>{% endif %}
- {%- if pform and pform[0] %} <em>({{ pform|join(', ') }})</em>{% endif -%}
- </td><td>{% if dep %}<strong>{{ _('Deprecated')}}:</strong>{% endif %}
- <em>{{ synops|e }}</em></td></tr>
- {%- endif -%}
- {% endfor %}
- </table>
-
-{% endblock %}
diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js
index e91c4f3e..28c7a6da 100644
--- a/sphinx/themes/basic/static/doctools.js
+++ b/sphinx/themes/basic/static/doctools.js
@@ -111,7 +111,7 @@ var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
- this.initModIndex();
+ this.initIndexTable();
},
/**
@@ -192,9 +192,9 @@ var Documentation = {
},
/**
- * init the modindex toggle buttons
+ * init the domain index toggle buttons
*/
- initModIndex : function() {
+ initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
@@ -204,7 +204,7 @@ var Documentation = {
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
- if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) {
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py
index 73790829..4cabd9b2 100644
--- a/sphinx/util/texescape.py
+++ b/sphinx/util/texescape.py
@@ -99,6 +99,7 @@ tex_replacements = [
]
tex_escape_map = {}
+tex_replace_map = {}
tex_hl_escape_map_old = {} # replacement map for Pygments <= 1.1
tex_hl_escape_map_new = {} # replacement map for Pygments >= 1.2
_old_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'}
@@ -106,6 +107,7 @@ _old_cmd_chars = {ord(u'\\'): u'@', ord(u'{'): u'[', ord(u'}'): u']'}
def init():
for a, b in tex_replacements:
tex_escape_map[ord(a)] = b
+ tex_replace_map[ord(a)] = u'_'
for a, b in tex_replacements:
if a in u'[]{}\\': continue
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 74d2c8d2..c75424b2 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -24,7 +24,7 @@ from sphinx import highlighting
from sphinx.errors import SphinxError
from sphinx.locale import admonitionlabels, versionlabels, _
from sphinx.util.osutil import ustrftime
-from sphinx.util.texescape import tex_escape_map
+from sphinx.util.texescape import tex_escape_map, tex_replace_map
from sphinx.util.smartypants import educateQuotesLatex
HEADER = r'''%% Generated by Sphinx.
@@ -47,7 +47,6 @@ HEADER = r'''%% Generated by Sphinx.
\newcommand{\sphinxlogo}{%(logo)s}
\renewcommand{\releasename}{%(releasename)s}
%(makeindex)s
-%(makemodindex)s
'''
BEGIN_DOC = r'''
@@ -58,9 +57,6 @@ BEGIN_DOC = r'''
'''
FOOTER = r'''
-%(footer)s
-\renewcommand{\indexname}{%(modindexname)s}
-%(printmodindex)s
\renewcommand{\indexname}{%(indexname)s}
%(printindex)s
\end{document}
@@ -146,12 +142,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
'logo': '',
'releasename': 'Release',
'makeindex': '\\makeindex',
- 'makemodindex': '\\makemodindex',
'shorthandoff': '',
'maketitle': '\\maketitle',
'tableofcontents': '\\tableofcontents',
'footer': '',
- 'printmodindex': '\\printmodindex',
'printindex': '\\printindex',
}
@@ -176,7 +170,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
'author': document.settings.author,
'releasename': _('Release'),
'preamble': builder.config.latex_preamble,
- 'modindexname': _('Module Index'),
'indexname': _('Index'),
})
if document.settings.docclass == 'howto':
@@ -204,9 +197,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.elements['fncychap'] = '\\usepackage[Sonny]{fncychap}'
else:
self.elements['classoptions'] += ',english'
- if not builder.config.latex_use_modindex:
- self.elements['makemodindex'] = ''
- self.elements['printmodindex'] = ''
# allow the user to override them all
self.elements.update(builder.config.latex_elements)
@@ -243,11 +233,60 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.first_param = 0
def astext(self):
- return (HEADER % self.elements + self.highlighter.get_stylesheet() +
- u''.join(self.body) + FOOTER % self.elements)
+ return (HEADER % self.elements +
+ self.highlighter.get_stylesheet() +
+ u''.join(self.body) +
+ '\n' + self.elements['footer'] + '\n' +
+ self.generate_indices() +
+ FOOTER % self.elements)
+
+ def hypertarget(self, target, text='', anchor=True):
+ #return '\\hypertarget{%s}{%s}' % (self.idescape(target), text)
+ return (anchor and '\\phantomsection' or '') + \
+ '\\label{%s}%s' % (self.idescape(target), text)
+
+ def hyperlink(self, target):
+ #return '\\hyperlink{%s}{' % (self.idescape(target))
+ return '\\hyperref[%s]{' % (self.idescape(target))
def idescape(self, id):
- return str(unicode(id).translate(tex_escape_map))
+ return str(unicode(id).translate(tex_replace_map))
+
+ def generate_indices(self):
+ def generate(content, collapsed):
+ ret.append('\\begin{theindex}\n')
+ ret.append('\\def\\bigletter#1{{\\Large\\sffamily#1}'
+ '\\nopagebreak\\vspace{1mm}}\n')
+ for i, (letter, entries) in enumerate(content):
+ if i > 0:
+ ret.append('\\indexspace\n')
+ ret.append('\\bigletter{%s}\n' % letter)
+ for entry in entries:
+ if not entry[4]:
+ continue
+ ret.append('\\item {\\texttt{%s}}, \\pageref{%s}' %
+ (self.encode(entry[0]), entry[4]))
+ ret.append('\\end{theindex}\n')
+
+ ret = []
+ # latex_domain_indices can be False/True or a list of index names
+ indices_config = self.builder.config.latex_domain_indices
+ if indices_config:
+ for domain in self.builder.env.domains.itervalues():
+ for indexinfo in domain.indices:
+ indexname = '%s-%s' % (domain.name, indexinfo[0])
+ if isinstance(indices_config, list):
+ if indexname not in indices_config:
+ continue
+ if not domain.has_index_entries(indexinfo[0],
+ self.builder.docnames):
+ continue
+ ret.append('\\renewcommand{\\indexname}{%s}\n' %
+ indexinfo[1])
+ generate(*domain.get_index(indexinfo[0],
+ self.builder.docnames))
+
+ return ''.join(ret)
def visit_document(self, node):
self.footnotestack.append(self.collect_footnotes(node))
@@ -261,8 +300,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append('\n\\appendix\n')
self.first_document = -1
if node.has_key('docname'):
- self.body.append('\\hypertarget{--doc-%s}{}' %
- self.idescape(node['docname']))
+ self.body.append(self.hypertarget('--doc-' + node['docname']))
# "- 1" because the level is increased before the title is visited
self.sectionlevel = self.top_sectionlevel - 1
def depart_document(self, node):
@@ -275,21 +313,17 @@ class LaTeXTranslator(nodes.NodeVisitor):
for bi in self.bibitems:
# cite_key: underscores must not be escaped
cite_key = bi[0].replace(r"\_", "_")
- self.body.append('\\bibitem[%s]{%s}{\hypertarget{%s}{} %s}\n' %
+ self.body.append('\\bibitem[%s]{%s}{%s %s}\n' %
(bi[0], cite_key,
- self.idescape(cite_key.lower()), bi[1]))
+ self.hypertarget(cite_key.lower()), bi[1]))
self.body.append('\\end{thebibliography}\n')
self.bibitems = []
def visit_start_of_file(self, node):
- # This marks the begin of a new file; therefore the current module and
- # class must be reset
- self.body.append('\n\\resetcurrentobjects\n')
- # and also, new footnotes
+ # collect new footnotes
self.footnotestack.append(self.collect_footnotes(node))
# also add a document target
- self.body.append('\\hypertarget{--doc-%s}{}' %
- self.idescape(node['docname']))
+ self.body.append(self.hypertarget('--doc-' + node['docname']))
self.curfilestack.append(node['docname'])
def collect_footnotes(self, node):
@@ -321,14 +355,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
if not self.this_is_the_title:
self.sectionlevel += 1
self.body.append('\n\n')
- if self.next_section_target:
- self.body.append(r'\hypertarget{%s}{}' %
- self.idescape(self.next_section_target))
- self.next_section_target = None
#if node.get('ids'):
# for id in node['ids']:
# if id not in self.written_ids:
- # self.body.append(r'\hypertarget{%s}{}' % id)
+ # self.body.append(self.hypertarget(id))
# self.written_ids.add(id)
def depart_section(self, node):
self.sectionlevel = max(self.sectionlevel - 1,
@@ -400,6 +430,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
# just use "subparagraph", it's not numbered anyway
self.body.append(r'\%s{' % self.sectionnames[-1])
self.context.append('}\n')
+
+ if self.next_section_target:
+ self.context[-1] += self.hypertarget(self.next_section_target,
+ anchor=False)
+ self.next_section_target = None
+
elif isinstance(parent, (nodes.topic, nodes.sidebar)):
self.body.append(r'\textbf{')
self.context.append('}\n\n\medskip\n\n')
@@ -438,7 +474,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_signature(self, node):
if node.parent['objtype'] != 'describe' and node['ids']:
- hyper = '\\hypertarget{%s}{}' % self.idescape(node['ids'][0])
+ hyper = self.hypertarget(node['ids'][0])
else:
hyper = ''
self.body.append(hyper)
@@ -700,7 +736,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_term(self, node):
ctx = '] \\leavevmode'
if node.has_key('ids') and node['ids']:
- ctx += '\\hypertarget{%s}{}' % self.idescape(node['ids'][0])
+ ctx += self.hypertarget(node['ids'][0])
self.body.append('\\item[')
self.context.append(ctx)
def depart_term(self, node):
@@ -759,14 +795,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_module(self, node):
modname = node['modname']
- self.body.append('\n\\hypertarget{module-%s}{}' %
- self.idescape(modname.replace(' ','')))
- self.body.append('\n\\declaremodule[%s]{}{%s}' % (
- modname.replace('_', ''), self.encode(modname)))
- self.body.append('\n\\modulesynopsis{%s}' %
- self.encode(node['synopsis']))
- if node.has_key('platform'):
- self.body.append('\\platform{%s}' % self.encode(node['platform']))
+ self.body.append('\n' +
+ self.hypertarget('module-' + modname.replace(' ','')))
+ #self.body.append('\n\\declaremodule[%s]{}{%s}' % (
+ # modname.replace('_', ''), self.encode(modname)))
+ #self.body.append('\n\\modulesynopsis{%s}' %
+ # self.encode(node['synopsis']))
+ #if node.has_key('platform'):
+ # self.body.append('\\platform{%s}' % self.encode(node['platform']))
def depart_module(self, node):
pass
@@ -925,7 +961,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
# indexing uses standard LaTeX index markup, so the targets
# will be generated differently
if not id.startswith('index-'):
- self.body.append(r'\hypertarget{%s}{}' % self.idescape(id))
+ self.body.append(self.hypertarget(id))
if node.has_key('refid') and node['refid'] not in self.written_ids:
parindex = node.parent.index(node)
@@ -986,14 +1022,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.context.append('}')
elif uri.startswith('#'):
# references to labels
- self.body.append('\\hyperlink{%s}{' % self.idescape(uri[1:]))
+ self.body.append(self.hyperlink(uri[1:]))
self.context.append('}')
elif uri.startswith('%'):
# references to documents or labels inside documents
hashindex = uri.find('#')
targetname = (hashindex == -1) and '--doc-' + uri[1:] \
or uri[hashindex+1:]
- self.body.append('\\hyperlink{%s}{' % self.idescape(targetname))
+ self.body.append(self.hyperlink(targetname))
self.context.append('}')
elif uri.startswith('@token'):
if self.in_production_list: