From bf767d5222b6259e11306594e3d64602f4bd93ca Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 7 Jan 2011 19:00:29 +0100 Subject: [PATCH] #454: Add more index markup capabilities: marking see/seealso entries, and main entries for a given key. --- CHANGES | 3 + doc/markup/misc.rst | 20 +++++++ sphinx/builders/epub.py | 11 ++-- sphinx/domains/c.py | 2 +- sphinx/domains/cpp.py | 2 +- sphinx/domains/javascript.py | 2 +- sphinx/domains/python.py | 4 +- sphinx/domains/rst.py | 2 +- sphinx/domains/std.py | 14 ++--- sphinx/environment.py | 76 +++++++++++------------- sphinx/locale/__init__.py | 1 + sphinx/roles.py | 15 +++-- sphinx/texinputs/sphinx.sty | 17 ------ sphinx/themes/basic/genindex-single.html | 49 ++++++++++----- sphinx/themes/basic/genindex.html | 62 ++++++++++++------- sphinx/util/__init__.py | 8 +++ sphinx/util/nodes.py | 19 ++++-- sphinx/writers/latex.py | 48 ++++++++------- tests/root/markup.txt | 7 +++ tests/test_build_html.py | 10 +++- tests/test_build_latex.py | 1 + 21 files changed, 228 insertions(+), 145 deletions(-) diff --git a/CHANGES b/CHANGES index 151edd6c0..459000f89 100644 --- a/CHANGES +++ b/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. diff --git a/doc/markup/misc.rst b/doc/markup/misc.rst index 55370de7e..95899ef32 100644 --- a/doc/markup/misc.rst +++ b/doc/markup/misc.rst @@ -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 diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index 128965033..ddc6fb5c6 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -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): diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 48fbb36f2..b0dd332b5 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -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 diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 4688691df..4e40dde7d 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -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] diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index 07a54e4dd..57cee8f9c 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -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 diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index f9aef0500..aa3375df9 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -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 diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index fa3b4f1a0..e67f827e0 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -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': diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 606c88cd6..7dcec6168 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -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 diff --git a/sphinx/environment.py b/sphinx/environment.py index e11a981a9..583234cce 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -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 diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 5174f4952..3aca780cf 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -170,6 +170,7 @@ versionlabels = { 'deprecated': l_('Deprecated since version %s'), } +# XXX Python specific pairindextypes = { 'module': l_('module'), 'keyword': l_('keyword'), diff --git a/sphinx/roles.py b/sphinx/roles.py index 6b22d20ac..1d791f6d2 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -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) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 7d2820822..bac435cc7 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -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]{} diff --git a/sphinx/themes/basic/genindex-single.html b/sphinx/themes/basic/genindex-single.html index 225abfa8f..b6fa6a855 100644 --- a/sphinx/themes/basic/genindex-single.html +++ b/sphinx/themes/basic/genindex-single.html @@ -7,31 +7,48 @@ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} +{% macro indexentries(firstname, links) %} +
+ {%- if links -%} + + {%- if links[0][0] %}{% endif -%} + {{ firstname|e }} + {%- if links[0][0] %}{% endif -%} + + + {%- for ismain, link in links[1:] -%} + , {% if ismain %}{% endif -%} + [{{ loop.index }}] + {%- if ismain %}{% endif -%} + + {%- endfor %} + {%- else %} + {{ firstname|e }} + {%- endif %} +
+{% endmacro %} + {% extends "layout.html" %} {% set title = _('Index') %} {% block body %} -

{% trans key=key %}Index – {{ key }}{% endtrans %}

+

{% trans key=key %}Index – {{ key }}{% endtrans %}

{%- for column in entries|slice(2) if column %} -{%- endfor %} + + {%- endfor %}
- {%- for entryname, (links, subitems) in column %} -
{% if links %}{{ entryname|e }} - {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor %} - {%- else %}{{ entryname|e }}{% endif %}
- {%- if subitems %} -
- {%- for subentryname, subentrylinks in subitems %} -
{{ subentryname|e }} - {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} -
+ {%- for entryname, (links, subitems) in column %} + {{ indexentries(entryname, links) }} + {%- if subitems %} +
+ {%- for subentryname, subentrylinks in subitems %} + {{ indexentries(subentryname, subentrylinks) }} + {%- endfor %} +
+ {%- endif -%} {%- endfor %} -
- {%- endif -%} -{%- endfor %} -
{% endblock %} diff --git a/sphinx/themes/basic/genindex.html b/sphinx/themes/basic/genindex.html index 4af472528..536f09639 100644 --- a/sphinx/themes/basic/genindex.html +++ b/sphinx/themes/basic/genindex.html @@ -7,39 +7,57 @@ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} +{% macro indexentries(firstname, links) %} +
+ {%- if links -%} + + {%- if links[0][0] %}{% endif -%} + {{ firstname|e }} + {%- if links[0][0] %}{% endif -%} + + + {%- for ismain, link in links[1:] -%} + , {% if ismain %}{% endif -%} + [{{ loop.index }}] + {%- if ismain %}{% endif -%} + + {%- endfor %} + {%- else %} + {{ firstname|e }} + {%- endif %} +
+{% endmacro %} + {% extends "layout.html" %} {% set title = _('Index') %} {% block body %} -

{{ _('Index') }}

+

{{ _('Index') }}

-
- {% for key, dummy in genindexentries -%} - {{ key }} {% if not loop.last %}| {% endif %} - {%- endfor %} -
+
+ {% for key, dummy in genindexentries -%} + {{ key }} + {% if not loop.last %}| {% endif %} + {%- endfor %} +
- {%- for key, entries in genindexentries %} +{%- for key, entries in genindexentries %}

{{ key }}

{%- for column in entries|slice(2) if column %} -{%- endfor %} + + {%- endfor %}
- {%- for entryname, (links, subitems) in column %} -
{% if links %}{{ entryname|e }} - {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor %} - {%- else %}{{ entryname|e }}{% endif %}
- {%- if subitems %} -
- {%- for subentryname, subentrylinks in subitems %} -
{{ subentryname|e }} - {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} -
+ {%- for entryname, (links, subitems) in column %} + {{ indexentries(entryname, links) }} + {%- if subitems %} +
+ {%- for subentryname, subentrylinks in subitems %} + {{ indexentries(subentryname, subentrylinks) }} + {%- endfor %} +
+ {%- endif -%} {%- endfor %} -
- {%- endif -%} -{%- endfor %} -
{% endfor %} diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index d51f02083..becaff0bd 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -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() diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 09ab8b880..a241f5742 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -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 diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index a6dce7cb3..c557101be 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -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): diff --git a/tests/root/markup.txt b/tests/root/markup.txt index 601485341..4c6b10862 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -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: diff --git a/tests/test_build_html.py b/tests/test_build_html.py index f89df08c4..7e68f8dbb 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -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 '), ], + 'genindex.html': [ + # index entries + (".//a/strong", "Main"), + (".//a/strong", "[1]"), + (".//a/strong", "Other"), + (".//a", "entry"), + (".//dt/a", "double"), + ] } if pygments: diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 5fc6e0afc..68a8c07c6 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -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):