mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
#454: Add more index markup capabilities: marking see/seealso entries, and main entries for a given key.
This commit is contained in:
parent
98d884da6e
commit
bf767d5222
3
CHANGES
3
CHANGES
@ -46,6 +46,9 @@ Release 1.1 (in development)
|
||||
|
||||
* #521: Added :confval:`linkcheck_ignore` config value.
|
||||
|
||||
* #454: Add more index markup capabilities: marking see/seealso entries,
|
||||
and main entries for a given key.
|
||||
|
||||
* #516: Added new value of the :confval:`latex_show_urls` option to
|
||||
show the URLs in footnotes.
|
||||
|
||||
|
@ -113,11 +113,28 @@ mainly contained in information units, such as the language reference.
|
||||
Likewise, ``triple: module; search; path`` is a shortcut that creates
|
||||
three index entries, which are ``module; search path``, ``search; path,
|
||||
module`` and ``path; module search``.
|
||||
see
|
||||
``see: entry; other`` creates an index entry that refers from ``entry`` to
|
||||
``other``.
|
||||
seealso
|
||||
Like ``see``, but inserts "see also" instead of "see".
|
||||
module, keyword, operator, object, exception, statement, builtin
|
||||
These all create two index entries. For example, ``module: hashlib``
|
||||
creates the entries ``module; hashlib`` and ``hashlib; module``. (These
|
||||
are Python-specific and therefore deprecated.)
|
||||
|
||||
You can mark up "main" index entries by prefixing them with an exclamation
|
||||
mark. The references to "main" entries are emphasized in the generated
|
||||
index. For example, if two pages contain ::
|
||||
|
||||
.. index:: Python
|
||||
|
||||
and one page contains ::
|
||||
|
||||
.. index:: ! Python
|
||||
|
||||
then the backlink to the latter page is emphasized among the three backlinks.
|
||||
|
||||
For index directives containing only "single" entries, there is a shorthand
|
||||
notation::
|
||||
|
||||
@ -125,6 +142,9 @@ mainly contained in information units, such as the language reference.
|
||||
|
||||
This creates four index entries.
|
||||
|
||||
.. versionchanged:: 1.1
|
||||
Added ``see`` and ``seealso`` types, as well as marking main entries.
|
||||
|
||||
.. rst:role:: index
|
||||
|
||||
While the :rst:dir:`index` directive is a block-level markup and links to the
|
||||
|
@ -289,16 +289,17 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
# Logic modeled from themes/basic/genindex.html
|
||||
for key, columns in tree:
|
||||
for entryname, (links, subitems) in columns:
|
||||
for (i, link) in enumerate(links):
|
||||
for (i, (ismain, link)) in enumerate(links):
|
||||
m = _refuri_re.match(link)
|
||||
if m:
|
||||
links[i] = self.fix_fragment(m.group(1), m.group(2))
|
||||
links[i] = (ismain,
|
||||
self.fix_fragment(m.group(1), m.group(2)))
|
||||
for subentryname, subentrylinks in subitems:
|
||||
for (i, link) in enumerate(subentrylinks):
|
||||
for (i, (ismain, link)) in enumerate(subentrylinks):
|
||||
m = _refuri_re.match(link)
|
||||
if m:
|
||||
subentrylinks[i] = \
|
||||
self.fix_fragment(m.group(1), m.group(2))
|
||||
subentrylinks[i] = (ismain,
|
||||
self.fix_fragment(m.group(1), m.group(2)))
|
||||
|
||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
||||
outfilename=None, event_arg=None):
|
||||
|
@ -168,7 +168,7 @@ class CObject(ObjectDescription):
|
||||
|
||||
indextext = self.get_index_text(name)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext, name, name))
|
||||
self.indexnode['entries'].append(('single', indextext, name, ''))
|
||||
|
||||
def before_content(self):
|
||||
self.typename_set = False
|
||||
|
@ -852,7 +852,7 @@ class CPPObject(ObjectDescription):
|
||||
|
||||
indextext = self.get_index_text(name)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext, name, name))
|
||||
self.indexnode['entries'].append(('single', indextext, theid, ''))
|
||||
|
||||
def before_content(self):
|
||||
lastname = self.names and self.names[-1]
|
||||
|
@ -96,7 +96,7 @@ class JSObject(ObjectDescription):
|
||||
indextext = self.get_index_text(objectname, name_obj)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
fullname, fullname))
|
||||
fullname, ''))
|
||||
|
||||
def get_index_text(self, objectname, name_obj):
|
||||
name, obj = name_obj
|
||||
|
@ -221,7 +221,7 @@ class PyObject(ObjectDescription):
|
||||
indextext = self.get_index_text(modname, name_cls)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
fullname, fullname))
|
||||
fullname, ''))
|
||||
|
||||
def before_content(self):
|
||||
# needed for automatic qualification of members (reset in subclasses)
|
||||
@ -399,7 +399,7 @@ class PyModule(Directive):
|
||||
if not noindex:
|
||||
indextext = _('%s (module)') % modname
|
||||
inode = addnodes.index(entries=[('single', indextext,
|
||||
'module-' + modname, modname)])
|
||||
'module-' + modname, '')])
|
||||
ret.append(inode)
|
||||
return ret
|
||||
|
||||
|
@ -48,7 +48,7 @@ class ReSTMarkup(ObjectDescription):
|
||||
indextext = self.get_index_text(self.objtype, name)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
targetname, targetname))
|
||||
targetname, ''))
|
||||
|
||||
def get_index_text(self, objectname, name):
|
||||
if self.objtype == 'directive':
|
||||
|
@ -61,7 +61,7 @@ class GenericObject(ObjectDescription):
|
||||
indextype = 'single'
|
||||
indexentry = self.indextemplate % (name,)
|
||||
self.indexnode['entries'].append((indextype, indexentry,
|
||||
targetname, targetname))
|
||||
targetname, ''))
|
||||
self.env.domaindata['std']['objects'][self.objtype, name] = \
|
||||
self.env.docname, targetname
|
||||
|
||||
@ -82,8 +82,8 @@ class EnvVarXRefRole(XRefRole):
|
||||
tgtid = 'index-%s' % env.new_serialno('index')
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = [
|
||||
('single', varname, tgtid, varname),
|
||||
('single', _('environment variable; %s') % varname, tgtid, varname)
|
||||
('single', varname, tgtid, ''),
|
||||
('single', _('environment variable; %s') % varname, tgtid, '')
|
||||
]
|
||||
targetnode = nodes.target('', '', ids=[tgtid])
|
||||
document.note_explicit_target(targetnode)
|
||||
@ -118,7 +118,7 @@ class Target(Directive):
|
||||
indextype = indexentry[:colon].strip()
|
||||
indexentry = indexentry[colon+1:].strip()
|
||||
inode = addnodes.index(entries=[(indextype, indexentry,
|
||||
targetname, targetname)])
|
||||
targetname, '')])
|
||||
ret.insert(0, inode)
|
||||
name = self.name
|
||||
if ':' in self.name:
|
||||
@ -161,7 +161,7 @@ class Cmdoption(ObjectDescription):
|
||||
self.indexnode['entries'].append(
|
||||
('pair', _('%scommand line option; %s') %
|
||||
((currprogram and currprogram + ' ' or ''), sig),
|
||||
targetname, targetname))
|
||||
targetname, ''))
|
||||
self.env.domaindata['std']['progoptions'][currprogram, name] = \
|
||||
self.env.docname, targetname
|
||||
|
||||
@ -293,8 +293,8 @@ class Glossary(Directive):
|
||||
termtexts.append(termtext)
|
||||
# add an index entry too
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = [('single', termtext, new_id, termtext)]
|
||||
termnodes += indexnode
|
||||
indexnode['entries'] = [('single', termtext, new_id, 'main')]
|
||||
termnodes.append(indexnode)
|
||||
termnodes.extend(res[0])
|
||||
termnodes.append(addnodes.termsep())
|
||||
# make a single "term" node with all the terms, separated by termsep
|
||||
|
@ -37,7 +37,7 @@ from docutils.transforms import Transform
|
||||
from docutils.transforms.parts import ContentsFilter
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util import url_re, get_matching_docs, docname_join, \
|
||||
from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \
|
||||
FilenameUniqDict
|
||||
from sphinx.util.nodes import clean_astext, make_refnode, extract_messages
|
||||
from sphinx.util.osutil import movefile, SEP, ustrftime
|
||||
@ -1484,56 +1484,50 @@ class BuildEnvironment:
|
||||
"""Create the real index from the collected index entries."""
|
||||
new = {}
|
||||
|
||||
def add_entry(word, subword, dic=new):
|
||||
def add_entry(word, subword, link=True, dic=new):
|
||||
entry = dic.get(word)
|
||||
if not entry:
|
||||
dic[word] = entry = [[], {}]
|
||||
if subword:
|
||||
add_entry(subword, '', dic=entry[1])
|
||||
else:
|
||||
add_entry(subword, '', link=link, dic=entry[1])
|
||||
elif link:
|
||||
try:
|
||||
entry[0].append(builder.get_relative_uri('genindex', fn)
|
||||
+ '#' + tid)
|
||||
uri = builder.get_relative_uri('genindex', fn) + '#' + tid
|
||||
except NoUri:
|
||||
pass
|
||||
else:
|
||||
entry[0].append((main, uri))
|
||||
|
||||
for fn, entries in self.indexentries.iteritems():
|
||||
# new entry types must be listed in directives/other.py!
|
||||
for type, value, tid, alias in entries:
|
||||
if type == 'single':
|
||||
try:
|
||||
entry, subentry = value.split(';', 1)
|
||||
except ValueError:
|
||||
entry, subentry = value, ''
|
||||
if not entry:
|
||||
self.warn(fn, 'invalid index entry %r' % value)
|
||||
continue
|
||||
add_entry(entry.strip(), subentry.strip())
|
||||
elif type == 'pair':
|
||||
try:
|
||||
first, second = map(lambda x: x.strip(),
|
||||
value.split(';', 1))
|
||||
if not first or not second:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
self.warn(fn, 'invalid pair index entry %r' % value)
|
||||
continue
|
||||
add_entry(first, second)
|
||||
add_entry(second, first)
|
||||
elif type == 'triple':
|
||||
try:
|
||||
first, second, third = map(lambda x: x.strip(),
|
||||
value.split(';', 2))
|
||||
if not first or not second or not third:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
self.warn(fn, 'invalid triple index entry %r' % value)
|
||||
continue
|
||||
add_entry(first, second+' '+third)
|
||||
add_entry(second, third+', '+first)
|
||||
add_entry(third, first+' '+second)
|
||||
else:
|
||||
self.warn(fn, 'unknown index entry type %r' % type)
|
||||
for type, value, tid, main in entries:
|
||||
try:
|
||||
if type == 'single':
|
||||
try:
|
||||
entry, subentry = split_into(2, 'single', value)
|
||||
except ValueError:
|
||||
entry, = split_into(1, 'single', value)
|
||||
subentry = ''
|
||||
add_entry(entry, subentry)
|
||||
elif type == 'pair':
|
||||
first, second = split_into(2, 'pair', value)
|
||||
add_entry(first, second)
|
||||
add_entry(second, first)
|
||||
elif type == 'triple':
|
||||
first, second, third = split_into(3, 'triple', value)
|
||||
add_entry(first, second+' '+third)
|
||||
add_entry(second, third+', '+first)
|
||||
add_entry(third, first+' '+second)
|
||||
elif type == 'see':
|
||||
first, second = split_into(2, 'see', value)
|
||||
add_entry(first, _('see %s') % second, link=False)
|
||||
elif type == 'seealso':
|
||||
first, second = split_into(2, 'see', value)
|
||||
add_entry(first, _('see also %s') % second, link=False)
|
||||
else:
|
||||
self.warn(fn, 'unknown index entry type %r' % type)
|
||||
except ValueError, err:
|
||||
self.warn(fn, str(err))
|
||||
|
||||
# sort the index entries; put all symbols at the front, even those
|
||||
# following the letters in ASCII, this is where the chr(127) comes from
|
||||
|
@ -170,6 +170,7 @@ versionlabels = {
|
||||
'deprecated': l_('Deprecated since version %s'),
|
||||
}
|
||||
|
||||
# XXX Python specific
|
||||
pairindextypes = {
|
||||
'module': l_('module'),
|
||||
'keyword': l_('keyword'),
|
||||
|
@ -170,8 +170,8 @@ def indexmarkup_role(typ, rawtext, etext, lineno, inliner,
|
||||
inliner.document.note_explicit_target(targetnode)
|
||||
if typ == 'pep':
|
||||
indexnode['entries'] = [
|
||||
('single', _('Python Enhancement Proposals!PEP %s') % text,
|
||||
targetid, 'PEP %s' % text)]
|
||||
('single', _('Python Enhancement Proposals; PEP %s') % text,
|
||||
targetid, '')]
|
||||
anchor = ''
|
||||
anchorindex = text.find('#')
|
||||
if anchorindex > 0:
|
||||
@ -190,8 +190,7 @@ def indexmarkup_role(typ, rawtext, etext, lineno, inliner,
|
||||
rn += sn
|
||||
return [indexnode, targetnode, rn], []
|
||||
elif typ == 'rfc':
|
||||
indexnode['entries'] = [('single', 'RFC; RFC %s' % text,
|
||||
targetid, 'RFC %s' % text)]
|
||||
indexnode['entries'] = [('single', 'RFC; RFC %s' % text, targetid, '')]
|
||||
anchor = ''
|
||||
anchorindex = text.find('#')
|
||||
if anchorindex > 0:
|
||||
@ -282,7 +281,13 @@ def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
entries = process_index_entry(target, targetid)
|
||||
# otherwise we just create a "single" entry
|
||||
else:
|
||||
entries = [('single', target, targetid, target)]
|
||||
# but allow giving main entry
|
||||
main = ''
|
||||
if target.startswith('!'):
|
||||
target = target[1:]
|
||||
title = title[1:]
|
||||
main = 'main'
|
||||
entries = [('single', target, targetid, main)]
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = entries
|
||||
textnode = nodes.Text(title, title)
|
||||
|
@ -175,23 +175,6 @@
|
||||
}
|
||||
|
||||
|
||||
% Index-entry generation support.
|
||||
%
|
||||
|
||||
% Command to generate two index entries (using subentries)
|
||||
\newcommand{\indexii}[2]{\index{#1!#2}\index{#2!#1}}
|
||||
|
||||
% And three entries (using only one level of subentries)
|
||||
\newcommand{\indexiii}[3]{\index{#1!#2 #3}\index{#2!#3, #1}\index{#3!#1 #2}}
|
||||
|
||||
% And four (again, using only one level of subentries)
|
||||
\newcommand{\indexiv}[4]{
|
||||
\index{#1!#2 #3 #4}
|
||||
\index{#2!#3 #4, #1}
|
||||
\index{#3!#4, #1 #2}
|
||||
\index{#4!#1 #2 #3}
|
||||
}
|
||||
|
||||
% \moduleauthor{name}{email}
|
||||
\newcommand{\moduleauthor}[2]{}
|
||||
|
||||
|
@ -7,31 +7,48 @@
|
||||
:copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
#}
|
||||
{% macro indexentries(firstname, links) %}
|
||||
<dt>
|
||||
{%- if links -%}
|
||||
<a href="{{ links[0][1] }}">
|
||||
{%- if links[0][0] %}<strong>{% endif -%}
|
||||
{{ firstname|e }}
|
||||
{%- if links[0][0] %}</strong>{% endif -%}
|
||||
</a>
|
||||
|
||||
{%- for ismain, link in links[1:] -%}
|
||||
, <a href="{{ link }}">{% if ismain %}<strong>{% endif -%}
|
||||
[{{ loop.index }}]
|
||||
{%- if ismain %}</strong>{% endif -%}
|
||||
</a>
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
{{ firstname|e }}
|
||||
{%- endif %}
|
||||
</dt>
|
||||
{% endmacro %}
|
||||
|
||||
{% extends "layout.html" %}
|
||||
{% set title = _('Index') %}
|
||||
{% block body %}
|
||||
|
||||
<h1 id="index">{% trans key=key %}Index – {{ key }}{% endtrans %}</h1>
|
||||
<h1 id="index">{% trans key=key %}Index – {{ key }}{% endtrans %}</h1>
|
||||
|
||||
<table width="100%" class="indextable"><tr>
|
||||
{%- for column in entries|slice(2) if column %}
|
||||
<td width="33%" valign="top"><dl>
|
||||
{%- for entryname, (links, subitems) in column %}
|
||||
<dt>{% if links %}<a href="{{ links[0] }}">{{ entryname|e }}</a>
|
||||
{%- for link in links[1:] %}, <a href="{{ link }}">[{{ loop.index }}]</a>{% endfor %}
|
||||
{%- else %}{{ entryname|e }}{% endif %}</dt>
|
||||
{%- if subitems %}
|
||||
<dd><dl>
|
||||
{%- for subentryname, subentrylinks in subitems %}
|
||||
<dt><a href="{{ subentrylinks[0] }}">{{ subentryname|e }}</a>
|
||||
{%- for link in subentrylinks[1:] %}, <a href="{{ link }}">[{{ loop.index }}]</a>{% endfor -%}
|
||||
</dt>
|
||||
{%- for entryname, (links, subitems) in column %}
|
||||
{{ indexentries(entryname, links) }}
|
||||
{%- if subitems %}
|
||||
<dd><dl>
|
||||
{%- for subentryname, subentrylinks in subitems %}
|
||||
{{ indexentries(subentryname, subentrylinks) }}
|
||||
{%- endfor %}
|
||||
</dl></dd>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
</dl></dd>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
</dl></td>
|
||||
{%- endfor %}
|
||||
</dl></td>
|
||||
{%- endfor %}
|
||||
</tr></table>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -7,39 +7,57 @@
|
||||
:copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
#}
|
||||
{% macro indexentries(firstname, links) %}
|
||||
<dt>
|
||||
{%- if links -%}
|
||||
<a href="{{ links[0][1] }}">
|
||||
{%- if links[0][0] %}<strong>{% endif -%}
|
||||
{{ firstname|e }}
|
||||
{%- if links[0][0] %}</strong>{% endif -%}
|
||||
</a>
|
||||
|
||||
{%- for ismain, link in links[1:] -%}
|
||||
, <a href="{{ link }}">{% if ismain %}<strong>{% endif -%}
|
||||
[{{ loop.index }}]
|
||||
{%- if ismain %}</strong>{% endif -%}
|
||||
</a>
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
{{ firstname|e }}
|
||||
{%- endif %}
|
||||
</dt>
|
||||
{% endmacro %}
|
||||
|
||||
{% extends "layout.html" %}
|
||||
{% set title = _('Index') %}
|
||||
{% block body %}
|
||||
|
||||
<h1 id="index">{{ _('Index') }}</h1>
|
||||
<h1 id="index">{{ _('Index') }}</h1>
|
||||
|
||||
<div class="genindex-jumpbox">
|
||||
{% for key, dummy in genindexentries -%}
|
||||
<a href="#{{ key }}"><strong>{{ key }}</strong></a> {% if not loop.last %}| {% endif %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
<div class="genindex-jumpbox">
|
||||
{% for key, dummy in genindexentries -%}
|
||||
<a href="#{{ key }}"><strong>{{ key }}</strong></a>
|
||||
{% if not loop.last %}| {% endif %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
|
||||
{%- for key, entries in genindexentries %}
|
||||
{%- for key, entries in genindexentries %}
|
||||
<h2 id="{{ key }}">{{ key }}</h2>
|
||||
<table width="100%" class="indextable genindextable"><tr>
|
||||
{%- for column in entries|slice(2) if column %}
|
||||
<td width="33%" valign="top"><dl>
|
||||
{%- for entryname, (links, subitems) in column %}
|
||||
<dt>{% if links %}<a href="{{ links[0] }}">{{ entryname|e }}</a>
|
||||
{%- for link in links[1:] %}, <a href="{{ link }}">[{{ loop.index }}]</a>{% endfor %}
|
||||
{%- else %}{{ entryname|e }}{% endif %}</dt>
|
||||
{%- if subitems %}
|
||||
<dd><dl>
|
||||
{%- for subentryname, subentrylinks in subitems %}
|
||||
<dt><a href="{{ subentrylinks[0] }}">{{ subentryname|e }}</a>
|
||||
{%- for link in subentrylinks[1:] %}, <a href="{{ link }}">[{{ loop.index }}]</a>{% endfor -%}
|
||||
</dt>
|
||||
{%- for entryname, (links, subitems) in column %}
|
||||
{{ indexentries(entryname, links) }}
|
||||
{%- if subitems %}
|
||||
<dd><dl>
|
||||
{%- for subentryname, subentrylinks in subitems %}
|
||||
{{ indexentries(subentryname, subentrylinks) }}
|
||||
{%- endfor %}
|
||||
</dl></dd>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
</dl></dd>
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
</dl></td>
|
||||
{%- endfor %}
|
||||
</dl></td>
|
||||
{%- endfor %}
|
||||
</tr></table>
|
||||
{% endfor %}
|
||||
|
||||
|
@ -285,6 +285,14 @@ def rpartition(s, t):
|
||||
return '', s
|
||||
|
||||
|
||||
def split_into(n, type, value):
|
||||
"""Split an index entry into a given number of parts at semicolons."""
|
||||
parts = map(lambda x: x.strip(), value.split(';', n-1))
|
||||
if sum(1 for part in parts if part) < n:
|
||||
raise ValueError('invalid %s index entry %r' % (type, value))
|
||||
return parts
|
||||
|
||||
|
||||
def format_exception_cut_frames(x=1):
|
||||
"""Format an exception with traceback, but only the last x frames."""
|
||||
typ, val, tb = sys.exc_info()
|
||||
|
@ -74,17 +74,22 @@ def split_explicit_title(text):
|
||||
|
||||
|
||||
indextypes = [
|
||||
'single', 'pair', 'double', 'triple',
|
||||
'single', 'pair', 'double', 'triple', 'see', 'seealso',
|
||||
]
|
||||
|
||||
def process_index_entry(entry, targetid):
|
||||
indexentries = []
|
||||
entry = entry.strip()
|
||||
oentry = entry
|
||||
main = ''
|
||||
if entry.startswith('!'):
|
||||
main = 'main'
|
||||
entry = entry[1:].lstrip()
|
||||
for type in pairindextypes:
|
||||
if entry.startswith(type+':'):
|
||||
value = entry[len(type)+1:].strip()
|
||||
value = pairindextypes[type] + '; ' + value
|
||||
indexentries.append(('pair', value, targetid, value))
|
||||
indexentries.append(('pair', value, targetid, main))
|
||||
break
|
||||
else:
|
||||
for type in indextypes:
|
||||
@ -92,15 +97,19 @@ def process_index_entry(entry, targetid):
|
||||
value = entry[len(type)+1:].strip()
|
||||
if type == 'double':
|
||||
type = 'pair'
|
||||
indexentries.append((type, value, targetid, value))
|
||||
indexentries.append((type, value, targetid, main))
|
||||
break
|
||||
# shorthand notation for single entries
|
||||
else:
|
||||
for value in entry.split(','):
|
||||
for value in oentry.split(','):
|
||||
value = value.strip()
|
||||
main = ''
|
||||
if value.startswith('!'):
|
||||
main = 'main'
|
||||
value = value[1:].lstrip()
|
||||
if not value:
|
||||
continue
|
||||
indexentries.append(('single', value, targetid, value))
|
||||
indexentries.append(('single', value, targetid, main))
|
||||
return indexentries
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ from sphinx import addnodes
|
||||
from sphinx import highlighting
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import admonitionlabels, versionlabels, _
|
||||
from sphinx.util import split_into
|
||||
from sphinx.util.osutil import ustrftime
|
||||
from sphinx.util.pycompat import any
|
||||
from sphinx.util.texescape import tex_escape_map, tex_replace_map
|
||||
@ -1066,26 +1067,33 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
if not node.get('inline', True):
|
||||
self.body.append('\n')
|
||||
entries = node['entries']
|
||||
for type, string, tid, _ in entries:
|
||||
if type == 'single':
|
||||
self.body.append(r'\index{%s}' %
|
||||
scre.sub('!', self.encode(string)))
|
||||
elif type == 'pair':
|
||||
parts = tuple(self.encode(x.strip())
|
||||
for x in string.split(';', 1))
|
||||
try:
|
||||
self.body.append(r'\indexii{%s}{%s}' % parts)
|
||||
except TypeError:
|
||||
self.builder.warn('invalid pair index entry %r' % string)
|
||||
elif type == 'triple':
|
||||
parts = tuple(self.encode(x.strip())
|
||||
for x in string.split(';', 2))
|
||||
try:
|
||||
self.body.append(r'\indexiii{%s}{%s}{%s}' % parts)
|
||||
except TypeError:
|
||||
self.builder.warn('invalid triple index entry %r' % string)
|
||||
else:
|
||||
self.builder.warn('unknown index entry type %s found' % type)
|
||||
for type, string, tid, ismain in entries:
|
||||
m = ''
|
||||
if ismain:
|
||||
m = '|textbf'
|
||||
try:
|
||||
if type == 'single':
|
||||
p = scre.sub('!', self.encode(string))
|
||||
self.body.append(r'\index{%s%s}' % (p, m))
|
||||
elif type == 'pair':
|
||||
p1, p2 = map(self.encode, split_into(2, 'pair', string))
|
||||
self.body.append(r'\index{%s!%s%s}\index{%s!%s%s}' %
|
||||
(p1, p2, m, p2, p1, m))
|
||||
elif type == 'triple':
|
||||
p1, p2, p3 = map(self.encode, split_into(3, 'triple', string))
|
||||
self.body.append(
|
||||
r'\index{%s!%s %s%s}\index{%s!%s, %s%s}\index{%s!%s %s%s}' %
|
||||
(p1, p2, p3, m, p2, p3, p1, m, p3, p1, p2, m))
|
||||
elif type == 'see':
|
||||
p1, p2 = map(self.encode, split_into(2, 'see', string))
|
||||
self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
|
||||
elif type == 'seealso':
|
||||
p1, p2 = map(self.encode, split_into(2, 'seealso', string))
|
||||
self.body.append(r'\index{%s|see{%s}}' % (p1, p2))
|
||||
else:
|
||||
self.builder.warn('unknown index entry type %s found' % type)
|
||||
except ValueError, err:
|
||||
self.builder.warn(str(err))
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_raw(self, node):
|
||||
|
@ -277,6 +277,8 @@ Index markup
|
||||
double: entry; double
|
||||
triple: index; entry; triple
|
||||
keyword: with
|
||||
see: from; to
|
||||
seealso: fromalso; toalso
|
||||
|
||||
Invalid index markup...
|
||||
|
||||
@ -285,6 +287,11 @@ Invalid index markup...
|
||||
pair:
|
||||
keyword:
|
||||
|
||||
.. index::
|
||||
!Main, !Other
|
||||
!single: entry; pair
|
||||
|
||||
:index:`!Main`
|
||||
|
||||
.. _ölabel:
|
||||
|
||||
|
@ -49,7 +49,7 @@ http://sphinx.pocoo.org/domains.html
|
||||
|
||||
HTML_WARNINGS = ENV_WARNINGS + """\
|
||||
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/markup.txt:: WARNING: invalid index entry u''
|
||||
%(root)s/markup.txt:: WARNING: invalid single index entry u''
|
||||
%(root)s/markup.txt:: WARNING: invalid pair index entry u''
|
||||
%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
|
||||
"""
|
||||
@ -232,6 +232,14 @@ HTML_XPATH = {
|
||||
'_static/statictmpl.html': [
|
||||
(".//project", 'Sphinx <Tests>'),
|
||||
],
|
||||
'genindex.html': [
|
||||
# index entries
|
||||
(".//a/strong", "Main"),
|
||||
(".//a/strong", "[1]"),
|
||||
(".//a/strong", "Other"),
|
||||
(".//a", "entry"),
|
||||
(".//dt/a", "double"),
|
||||
]
|
||||
}
|
||||
|
||||
if pygments:
|
||||
|
@ -30,6 +30,7 @@ latex_warnfile = StringIO()
|
||||
LATEX_WARNINGS = ENV_WARNINGS + """\
|
||||
None:None: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
WARNING: invalid pair index entry u''
|
||||
WARNING: invalid pair index entry u'keyword; '
|
||||
"""
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
|
Loading…
Reference in New Issue
Block a user