Repository: sphinx-doc/sphinx

Issue:
All sources are re-built, even if nothing has changed (using nbsphinx extension)
This problem was introduced in PR #4966. Before that, everything was working fine.

This only happens when the `nbsphinx` extension is used (but maybe other extensions are affected, too?).

#### Procedure to reproduce the problem

This can be reproduced by building the docs for the `nbsphinx` module.
Installation instructions: https://github.com/spatialaudio/nbsphinx/blob/master/CONTRIBUTING.rst

In short:

```
git clone https://github.com/spatialaudio/nbsphinx.git
cd nbsphinx
python3 -m pip install -e . --user
python3 setup.py build_sphinx
```

All source files (including Jupyter notebooks) are built at this point.

If I re-build immediately after that (without touching any files) ...

```
python3 setup.py build_sphinx
```

... all source files are built again.

#### Expected results

The second time the source files should not be processed again.
Instead, there should be this message:

```
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
no targets are out of date.
```

### Reproducible project / your project
- https://github.com/spatialaudio/nbsphinx

### Environment info
- OS: Linux
- Python version: Python 3.6.6rc1+
- Sphinx version: `master` branch, every commit after PR #4966 (commit 3ffde92c54c6e9d594b2a41a365a90dc0dcbac6c)

Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 4db799ef4..ca7bef359 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,11 +4,6 @@ Release 1.8.0 (in development)
 Dependencies
 ------------
 
-* LaTeX: :confval:`latex_use_xindy`, if ``True`` (default for
-  ``xelatex/lualatex``), instructs ``make latexpdf`` to use :program:`xindy`
-  for general index.  Make sure your LaTeX distribution includes it.
-  (refs: #5134)
-
 Incompatible changes
 --------------------
 
@@ -44,10 +39,6 @@ Incompatible changes
   Please use ``app.add_js_file()`` instead.
 * #5072: Save environment object also with only new documents
 * #5035: qthelp builder allows dashes in :confval:`qthelp_namespace`
-* LaTeX: with lualatex or xelatex use by default :program:`xindy` as
-  UTF-8 able replacement of :program:`makeindex` (refs: #5134).  After
-  upgrading Sphinx, please clean latex build repertory of existing project
-  before new build.
 
 Deprecated
 ----------
@@ -152,8 +143,6 @@ Features added
   for mathjax
 * #4362: latex: Don't overwrite .tex file if document not changed
 * #1431: latex: Add alphanumeric enumerated list support
-* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
-  if :confval:`latex_engine` is ``'xelatex'`` or ``'lualatex'``.
 
 Bugs fixed
 ----------
@@ -163,8 +152,6 @@ Bugs fixed
 * #4945: i18n: fix lang_COUNTRY not fallback correctly for IndexBuilder. Thanks
   to Shengjing Zhu.
 * #4983: productionlist directive generates invalid IDs for the tokens
-* #5132: (lualatex) PDF build fails if indexed word starts with Unicode character
-* #5133: latex: index headings "Symbols" and "Numbers" not internationalized
 
 Testing
 --------
diff --git a/doc/conf.py b/doc/conf.py
index 724d355d0..732c4d4a0 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -72,7 +72,6 @@
 ''',
 }
 latex_show_urls = 'footnote'
-latex_use_xindy = True
 
 autodoc_member_order = 'groupwise'
 todo_include_todos = True
diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst
index 8db606515..a0fbe641a 100644
--- a/doc/usage/configuration.rst
+++ b/doc/usage/configuration.rst
@@ -1872,40 +1872,6 @@ information.
 
    .. versionadded:: 1.6
 
-.. confval:: latex_use_xindy
-
-   If ``True``, the PDF build from the LaTeX files created by Sphinx
-   will use :program:`xindy` (doc__) rather than :program:`makeindex`
-   for preparing the index of general terms (from :rst:dir:`index`
-   usage).  This means that words with UTF-8 characters will get
-   ordered correctly for the :confval:`language`.
-
-   __ http://xindy.sourceforge.net/
-
-   - This option is ignored if :confval:`latex_engine` is ``'platex'``
-     (Japanese documents) as :program:`mendex` is used in that case.
-
-   - The default is ``True`` for ``'xelatex'`` or ``'lualatex'`` as
-     :program:`makeindex`, if any indexed term starts with a non-ascii
-     character, creates ``.ind`` file containing invalid bytes for
-     UTF-8 encoding. With ``'lualatex'`` this then breaks the PDF
-     build.  Notice that :program:`xindy` supports most but not
-     all European languages.
-
-   - The default is ``False`` for ``'pdflatex'`` but ``True`` is
-     recommended for non-English documents as soon as some indexed
-     terms use non-ascii characters from the language script.
-     Cyrillic scripts are (transparently) supported with
-     ``'pdflatex'`` thanks to a specific Sphinx-contributed ``xindy``
-     style file :file:`cyrLICRutf8.xdy`.
-
-     As :program:`xindy` does not support the same range of languages
-     as ``LaTeX/babel`` does, the default :program:`makeindex` for
-     ``'pdflatex'`` may be preferred in some circumstances, although
-     the index will be ill-formed probably.
-
-   .. versionadded:: 1.8
-
 .. confval:: latex_elements
 
    .. versionadded:: 0.5
diff --git a/doc/usage/quickstart.rst b/doc/usage/quickstart.rst
index 0f9452f05..fabbf9905 100644
--- a/doc/usage/quickstart.rst
+++ b/doc/usage/quickstart.rst
@@ -127,7 +127,7 @@ directory in which you want to place the built documentation.
 The :option:`-b <sphinx-build -b>` option selects a builder; in this example
 Sphinx will build HTML files.
 
-|more| Refer to the :doc:`sphinx-build man page </man/sphinx-build>` for all
+|more| Refer to the :program:`sphinx-build man page <sphinx-build>` for all
 options that :program:`sphinx-build` supports.
 
 However, :program:`sphinx-quickstart` script creates a :file:`Makefile` and a
@@ -331,7 +331,7 @@ More topics to be covered
 
 .. [#] This is the usual layout.  However, :file:`conf.py` can also live in
        another directory, the :term:`configuration directory`.  Refer to the
-       :doc:`sphinx-build man page </man/sphinx-build>` for more information.
+       :program:`sphinx-build man page <sphinx-build>` for more information.
 
 .. |more| image:: /_static/more.png
           :align: middle
diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py
index c17ead5c2..382914731 100644
--- a/sphinx/builders/latex/__init__.py
+++ b/sphinx/builders/latex/__init__.py
@@ -44,67 +44,6 @@
     from sphinx.config import Config  # NOQA
 
 
-XINDY_LANG_OPTIONS = {
-    # language codes from docutils.writers.latex2e.Babel
-    # ! xindy language names may differ from those in use by LaTeX/babel
-    # ! xindy does not support all Latin scripts as recognized by LaTeX/babel
-    # ! not all xindy-supported languages appear in Babel.language_codes
-    # cd /usr/local/texlive/2018/texmf-dist/xindy/modules/lang
-    # find . -name '*utf8.xdy'
-    # LATIN
-    'sq': '-L albanian -C utf8 ',
-    'hr': '-L croatian -C utf8 ',
-    'cs': '-L czech -C utf8 ',
-    'da': '-L danish -C utf8 ',
-    'nl': '-L dutch -C ij-as-ij-utf8 ',
-    'en': '-L english -C utf8 ',
-    'eo': '-L esperanto -C utf8 ',
-    'et': '-L estonian -C utf8 ',
-    'fi': '-L finnish -C utf8 ',
-    'fr': '-L french -C utf8 ',
-    'de': '-L german -C din5007-utf8 ',
-    'is': '-L icelandic -C utf8 ',
-    'it': '-L italian -C utf8 ',
-    'la': '-L latin -C utf8 ',
-    'lv': '-L latvian -C utf8 ',
-    'lt': '-L lithuanian -C utf8 ',
-    'dsb': '-L lower-sorbian -C utf8 ',
-    'ds': '-L lower-sorbian -C utf8 ',   # trick, no conflict
-    'nb': '-L norwegian -C utf8 ',
-    'no': '-L norwegian -C utf8 ',       # and what about nynorsk?
-    'pl': '-L polish -C utf8 ',
-    'pt': '-L portuguese -C utf8 ',
-    'ro': '-L romanian -C utf8 ',
-    'sk': '-L slovak -C small-utf8 ',    # there is also slovak-large
-    'sl': '-L slovenian -C utf8 ',
-    'es': '-L spanish -C modern-utf8 ',  # there is also spanish-traditional
-    'sv': '-L swedish -C utf8 ',
-    'tr': '-L turkish -C utf8 ',
-    'hsb': '-L upper-sorbian -C utf8 ',
-    'hs': '-L upper-sorbian -C utf8 ',   # trick, no conflict
-    'vi': '-L vietnamese -C utf8 ',
-    # CYRILLIC
-    # for usage with pdflatex, needs also cyrLICRutf8.xdy module
-    'be': '-L belarusian -C utf8 ',
-    'bg': '-L bulgarian -C utf8 ',
-    'mk': '-L macedonian -C utf8 ',
-    'mn': '-L mongolian -C cyrillic-utf8 ',
-    'ru': '-L russian -C utf8 ',
-    'sr': '-L serbian -C utf8 ',
-    'sh-cyrl': '-L serbian -C utf8 ',
-    'sh': '-L serbian -C utf8 ',         # trick, no conflict
-    'uk': '-L ukrainian -C utf8 ',
-    # GREEK
-    # can work only with xelatex/lualatex, not supported by texindy+pdflatex
-    'el': '-L greek -C utf8 ',
-    # FIXME, not compatible with [:2] slice but does Sphinx support Greek ?
-    'el-polyton': '-L greek -C polytonic-utf8 ',
-}  # type: Dict[unicode, unicode]
-
-XINDY_CYRILLIC_SCRIPTS = [
-    'be', 'bg', 'mk', 'mn', 'ru', 'sr', 'sh', 'uk',
-]  # type: List[unicode]
-
 logger = logging.getLogger(__name__)
 
 
@@ -293,23 +232,7 @@ def finish(self):
         self.copy_image_files()
 
         # copy TeX support files from texinputs
-        # configure usage of xindy (impacts Makefile and latexmkrc)
-        # FIXME: convert this rather to a confval with suitable default
-        #        according to language ? but would require extra documentation
-        if self.config.language:
-            xindy_lang_option = \
-                XINDY_LANG_OPTIONS.get(self.config.language[:2],
-                                       '-L general -C utf8 ')
-            xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
-        else:
-            xindy_lang_option = '-L english -C utf8 '
-            xindy_cyrillic = False
-        context = {
-            'latex_engine':      self.config.latex_engine,
-            'xindy_use':         self.config.latex_use_xindy,
-            'xindy_lang_option': xindy_lang_option,
-            'xindy_cyrillic':    xindy_cyrillic,
-        }
+        context = {'latex_engine': self.config.latex_engine}
         logger.info(bold(__('copying TeX support files...')))
         staticdirname = path.join(package_dir, 'texinputs')
         for filename in os.listdir(staticdirname):
@@ -394,12 +317,6 @@ def default_latex_docclass(config):
         return {}
 
 
-def default_latex_use_xindy(config):
-    # type: (Config) -> bool
-    """ Better default latex_use_xindy settings for specific engines. """
-    return config.latex_engine in {'xelatex', 'lualatex'}
-
-
 def setup(app):
     # type: (Sphinx) -> Dict[unicode, Any]
     app.add_builder(LaTeXBuilder)
@@ -417,7 +334,6 @@ def setup(app):
     app.add_config_value('latex_logo', None, None, string_classes)
     app.add_config_value('latex_appendices', [], None)
     app.add_config_value('latex_use_latex_multicolumn', False, None)
-    app.add_config_value('latex_use_xindy', default_latex_use_xindy, None)
     app.add_config_value('latex_toplevel_sectioning', None, None,
                          ENUM(None, 'part', 'chapter', 'section'))
     app.add_config_value('latex_domain_indices', True, None, [list])
diff --git a/sphinx/registry.py b/sphinx/registry.py
index f95a8fe7d..2c73dbbd3 100644
--- a/sphinx/registry.py
+++ b/sphinx/registry.py
@@ -39,6 +39,7 @@
     from docutils.transforms import Transform  # NOQA
     from sphinx.application import Sphinx  # NOQA
     from sphinx.builders import Builder  # NOQA
+    from sphinx.config import Config  # NOQA
     from sphinx.domains import Domain, Index  # NOQA
     from sphinx.environment import BuildEnvironment  # NOQA
     from sphinx.ext.autodoc import Documenter  # NOQA
@@ -270,7 +271,7 @@ def add_source_suffix(self, suffix, filetype, override=False):
         # type: (unicode, unicode, bool) -> None
         logger.debug('[app] adding source_suffix: %r, %r', suffix, filetype)
         if suffix in self.source_suffix and not override:
-            raise ExtensionError(__('source_parser for %r is already registered') % suffix)
+            raise ExtensionError(__('source_suffix %r is already registered') % suffix)
         else:
             self.source_suffix[suffix] = filetype
 
@@ -290,7 +291,7 @@ def add_source_parser(self, *args, **kwargs):
             parser = args[1]
 
         if suffix:
-            self.add_source_suffix(suffix, suffix)
+            self.add_source_suffix(suffix, suffix, override=True)
 
         if len(parser.supported) == 0:
             warnings.warn('Old source_parser has been detected. Please fill Parser.supported '
@@ -493,8 +494,8 @@ def get_envversion(self, app):
         return envversion
 
 
-def merge_source_suffix(app):
-    # type: (Sphinx) -> None
+def merge_source_suffix(app, config):
+    # type: (Sphinx, Config) -> None
     """Merge source_suffix which specified by user and added by extensions."""
     for suffix, filetype in iteritems(app.registry.source_suffix):
         if suffix not in app.config.source_suffix:
@@ -510,7 +511,7 @@ def merge_source_suffix(app):
 
 def setup(app):
     # type: (Sphinx) -> Dict[unicode, Any]
-    app.connect('builder-inited', merge_source_suffix)
+    app.connect('config-inited', merge_source_suffix)
 
     return {
         'version': 'builtin',
diff --git a/sphinx/templates/latex/latex.tex_t b/sphinx/templates/latex/latex.tex_t
index d219f8525..0ea75557f 100644
--- a/sphinx/templates/latex/latex.tex_t
+++ b/sphinx/templates/latex/latex.tex_t
@@ -13,11 +13,6 @@
 \ifdefined\pdfpxdimen
    \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
 \fi \sphinxpxdimen=<%= pxunit %>\relax
-<% if use_xindy -%>
-%% turn off hyperref patch of \index as sphinx.xdy xindy module takes care of
-%% suitable \hyperpage mark-up, working around hyperref-xindy incompatibility
-\PassOptionsToPackage{hyperindex=false}{hyperref}
-<% endif -%>
 <%= passoptionstopackages %>
 \PassOptionsToPackage{warn}{textcomp}
 <%= inputenc %>
@@ -36,7 +31,7 @@
 <%= hyperref %>
 <%= contentsname %>
 <%= numfig_format %>
-<%= translatablestrings %>
+<%= literalblockpto %>
 <%= pageautorefname %>
 <%= tocdepth %>
 <%= secnumdepth %>
diff --git a/sphinx/texinputs/Makefile_t b/sphinx/texinputs/Makefile_t
index 1ce4b1324..06bd6c4d7 100644
--- a/sphinx/texinputs/Makefile_t
+++ b/sphinx/texinputs/Makefile_t
@@ -22,15 +22,6 @@ export LATEXOPTS =
 # or on command line for faster builds.
 {% endif -%}
 LATEXMKOPTS =
-{% if xindy_use -%}
-export XINDYOPTS = {{ xindy_lang_option }} -M sphinx.xdy
-{% if latex_engine == 'pdflatex' and xindy_cyrillic -%}
-XINDYOPTS += -M cyrLICRutf8.xdy
-{% endif -%}
-{% if latex_engine == 'xelatex' or latex_engine == 'lualatex' -%}
-XINDYOPTS += -I xelatex
-{% endif -%}
-{% endif -%}
 # format: pdf or dvi (used only by archive targets)
 FMT = pdf
 
diff --git a/sphinx/texinputs/cyrLICRutf8.xdy b/sphinx/texinputs/cyrLICRutf8.xdy
deleted file mode 100644
index 86d8cd87b..000000000
--- a/sphinx/texinputs/cyrLICRutf8.xdy
+++ /dev/null
@@ -1,103 +0,0 @@
-;; -*- coding: utf-8; mode: Lisp; -*-
-;; style file for xindy
-;; filename: cyrLICRutf8.xdy
-;; description: style file for xindy which maps back LaTeX Internal
-;;   Character Representation of Cyrillic to utf-8
-;; usage: for use with pdflatex produced .idx files.
-;; This module must be loaded after the rule for suppressing space
-;; characters has been executed, hence after module sphinx.xdy.
-;; Contributed by the Sphinx team, July 2018.
-(merge-rule "\IeC{\'\CYRG}" "Ѓ" :string)
-(merge-rule "\IeC{\'\CYRK}" "Ќ" :string)
-(merge-rule "\IeC{\'\cyrg}" "ѓ" :string)
-(merge-rule "\IeC{\'\cyrk}" "ќ" :string)
-(merge-rule "\IeC{\CYRA}" "А" :string)
-(merge-rule "\IeC{\CYRB}" "Б" :string)
-(merge-rule "\IeC{\CYRC}" "Ц" :string)
-(merge-rule "\IeC{\CYRCH}" "Ч" :string)
-(merge-rule "\IeC{\CYRD}" "Д" :string)
-(merge-rule "\IeC{\CYRDJE}" "Ђ" :string)
-(merge-rule "\IeC{\CYRDZE}" "Ѕ" :string)
-(merge-rule "\IeC{\CYRDZHE}" "Џ" :string)
-(merge-rule "\IeC{\CYRE}" "Е" :string)
-(merge-rule "\IeC{\CYREREV}" "Э" :string)
-(merge-rule "\IeC{\CYRERY}" "Ы" :string)
-(merge-rule "\IeC{\CYRF}" "Ф" :string)
-(merge-rule "\IeC{\CYRG}" "Г" :string)
-(merge-rule "\IeC{\CYRGUP}" "Ґ" :string)
-(merge-rule "\IeC{\CYRH}" "Х" :string)
-(merge-rule "\IeC{\CYRHRDSN}" "Ъ" :string)
-(merge-rule "\IeC{\CYRI}" "И" :string)
-(merge-rule "\IeC{\CYRIE}" "Є" :string)
-(merge-rule "\IeC{\CYRII}" "І" :string)
-(merge-rule "\IeC{\CYRISHRT}" "Й" :string)
-(merge-rule "\IeC{\CYRJE}" "Ј" :string)
-(merge-rule "\IeC{\CYRK}" "К" :string)
-(merge-rule "\IeC{\CYRL}" "Л" :string)
-(merge-rule "\IeC{\CYRLJE}" "Љ" :string)
-(merge-rule "\IeC{\CYRM}" "М" :string)
-(merge-rule "\IeC{\CYRN}" "Н" :string)
-(merge-rule "\IeC{\CYRNJE}" "Њ" :string)
-(merge-rule "\IeC{\CYRO}" "О" :string)
-(merge-rule "\IeC{\CYRP}" "П" :string)
-(merge-rule "\IeC{\CYRR}" "Р" :string)
-(merge-rule "\IeC{\CYRS}" "С" :string)
-(merge-rule "\IeC{\CYRSFTSN}" "Ь" :string)
-(merge-rule "\IeC{\CYRSH}" "Ш" :string)
-(merge-rule "\IeC{\CYRSHCH}" "Щ" :string)
-(merge-rule "\IeC{\CYRT}" "Т" :string)
-(merge-rule "\IeC{\CYRTSHE}" "Ћ" :string)
-(merge-rule "\IeC{\CYRU}" "У" :string)
-(merge-rule "\IeC{\CYRUSHRT}" "Ў" :string)
-(merge-rule "\IeC{\CYRV}" "В" :string)
-(merge-rule "\IeC{\CYRYA}" "Я" :string)
-(merge-rule "\IeC{\CYRYI}" "Ї" :string)
-(merge-rule "\IeC{\CYRYO}" "Ё" :string)
-(merge-rule "\IeC{\CYRYU}" "Ю" :string)
-(merge-rule "\IeC{\CYRZ}" "З" :string)
-(merge-rule "\IeC{\CYRZH}" "Ж" :string)
-(merge-rule "\IeC{\cyra}" "а" :string)
-(merge-rule "\IeC{\cyrb}" "б" :string)
-(merge-rule "\IeC{\cyrc}" "ц" :string)
-(merge-rule "\IeC{\cyrch}" "ч" :string)
-(merge-rule "\IeC{\cyrd}" "д" :string)
-(merge-rule "\IeC{\cyrdje}" "ђ" :string)
-(merge-rule "\IeC{\cyrdze}" "ѕ" :string)
-(merge-rule "\IeC{\cyrdzhe}" "џ" :string)
-(merge-rule "\IeC{\cyre}" "е" :string)
-(merge-rule "\IeC{\cyrerev}" "э" :string)
-(merge-rule "\IeC{\cyrery}" "ы" :string)
-(merge-rule "\IeC{\cyrf}" "ф" :string)
-(merge-rule "\IeC{\cyrg}" "г" :string)
-(merge-rule "\IeC{\cyrgup}" "ґ" :string)
-(merge-rule "\IeC{\cyrh}" "х" :string)
-(merge-rule "\IeC{\cyrhrdsn}" "ъ" :string)
-(merge-rule "\IeC{\cyri}" "и" :string)
-(merge-rule "\IeC{\cyrie}" "є" :string)
-(merge-rule "\IeC{\cyrii}" "і" :string)
-(merge-rule "\IeC{\cyrishrt}" "й" :string)
-(merge-rule "\IeC{\cyrje}" "ј" :string)
-(merge-rule "\IeC{\cyrk}" "к" :string)
-(merge-rule "\IeC{\cyrl}" "л" :string)
-(merge-rule "\IeC{\cyrlje}" "љ" :string)
-(merge-rule "\IeC{\cyrm}" "м" :string)
-(merge-rule "\IeC{\cyrn}" "н" :string)
-(merge-rule "\IeC{\cyrnje}" "њ" :string)
-(merge-rule "\IeC{\cyro}" "о" :string)
-(merge-rule "\IeC{\cyrp}" "п" :string)
-(merge-rule "\IeC{\cyrr}" "р" :string)
-(merge-rule "\IeC{\cyrs}" "с" :string)
-(merge-rule "\IeC{\cyrsftsn}" "ь" :string)
-(merge-rule "\IeC{\cyrsh}" "ш" :string)
-(merge-rule "\IeC{\cyrshch}" "щ" :string)
-(merge-rule "\IeC{\cyrt}" "т" :string)
-(merge-rule "\IeC{\cyrtshe}" "ћ" :string)
-(merge-rule "\IeC{\cyru}" "у" :string)
-(merge-rule "\IeC{\cyrushrt}" "ў" :string)
-(merge-rule "\IeC{\cyrv}" "в" :string)
-(merge-rule "\IeC{\cyrya}" "я" :string)
-(merge-rule "\IeC{\cyryi}" "ї" :string)
-(merge-rule "\IeC{\cyryo}" "ё" :string)
-(merge-rule "\IeC{\cyryu}" "ю" :string)
-(merge-rule "\IeC{\cyrz}" "з" :string)
-(merge-rule "\IeC{\cyrzh}" "ж" :string)
diff --git a/sphinx/texinputs/latexmkrc_t b/sphinx/texinputs/latexmkrc_t
index d52681fbd..e3cd14f48 100644
--- a/sphinx/texinputs/latexmkrc_t
+++ b/sphinx/texinputs/latexmkrc_t
@@ -10,11 +10,7 @@ $pdflatex = 'xelatex ' . $ENV{'LATEXOPTS'} . ' %O %S';
 {% endif -%}
 $lualatex = 'lualatex ' . $ENV{'LATEXOPTS'} . ' %O %S';
 $xelatex = 'xelatex --no-pdf ' . $ENV{'LATEXOPTS'} . ' %O %S';
-{% if xindy_use -%}
-$makeindex = 'xindy ' . $ENV{'XINDYOPTS'} . ' %O -o %D %S';
-{% else -%}
 $makeindex = 'makeindex -s python.ist %O -o %D %S';
-{% endif -%}
 add_cus_dep( "glo", "gls", 0, "makeglo" );
 sub makeglo {
  return system( "makeindex -s gglo.ist -o '$_[0].gls' '$_[0].glo'" );
diff --git a/sphinx/texinputs/python.ist b/sphinx/texinputs/python.ist
index 7a1c06fbd..687d26cd4 100644
--- a/sphinx/texinputs/python.ist
+++ b/sphinx/texinputs/python.ist
@@ -3,11 +3,11 @@ headings_flag 1
 heading_prefix "  \\bigletter "
 
 preamble "\\begin{sphinxtheindex}
-\\let\\bigletter\\sphinxstyleindexlettergroup
+\\def\\bigletter#1{{\\Large\\sffamily#1}\\nopagebreak\\vspace{1mm}}
 
 "
 
 postamble "\n\n\\end{sphinxtheindex}\n"
 
-symhead_positive "{\\sphinxsymbolsname}"
-numhead_positive "{\\sphinxnumbersname}"
+symhead_positive "{Symbols}"
+numhead_positive "{Numbers}"
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index 30d8891e0..96be30338 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -6,7 +6,7 @@
 %
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesPackage{sphinx}[2018/06/30 v1.8 LaTeX package (Sphinx markup)]
+\ProvidesPackage{sphinx}[2018/03/28 v1.8 LaTeX package (Sphinx markup)]
 
 % provides \ltx@ifundefined
 % (many packages load ltxcmds: graphicx does for pdftex and lualatex but
@@ -470,11 +470,6 @@
  {\newenvironment{sphinxtheindex}{\begin{theindex}}{\end{theindex}}}%
  {}% else clause of \ltx@ifundefined
 
-% for usage with xindy: this string gets internationalized in preamble
-\newcommand*{\sphinxnonalphabeticalgroupname}{}
-% redefined in preamble, headings for makeindex produced index
-\newcommand*{\sphinxsymbolsname}{}
-\newcommand*{\sphinxnumbersname}{}
 
 %% COLOR (general)
 %
@@ -1596,13 +1591,10 @@
   {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
 
 % additional customizable styling
-\def\sphinxstyleindexentry   #1{\texttt{#1}}
-\def\sphinxstyleindexextra   #1{ \emph{(#1)}}
-\def\sphinxstyleindexpageref #1{, \pageref{#1}}
-\def\sphinxstyleindexlettergroup #1%
-    {{\Large\sffamily#1}\nopagebreak\vspace{1mm}}
-\def\sphinxstyleindexlettergroupDefault #1%
-    {{\Large\sffamily\sphinxnonalphabeticalgroupname}\nopagebreak\vspace{1mm}}
+% FIXME: convert this to package options ?
+\protected\def\sphinxstyleindexentry   #1{\texttt{#1}}
+\protected\def\sphinxstyleindexextra   #1{ \emph{(#1)}}
+\protected\def\sphinxstyleindexpageref #1{, \pageref{#1}}
 \protected\def\sphinxstyletopictitle   #1{\textbf{#1}\par\medskip}
 \let\sphinxstylesidebartitle\sphinxstyletopictitle
 \protected\def\sphinxstyleothertitle   #1{\textbf{#1}}
diff --git a/sphinx/texinputs/sphinx.xdy b/sphinx/texinputs/sphinx.xdy
deleted file mode 100644
index d9f99dc2a..000000000
--- a/sphinx/texinputs/sphinx.xdy
+++ /dev/null
@@ -1,133 +0,0 @@
-;;; -*- mode: lisp; coding: utf-8; -*-
-
-;; Unfortunately xindy is out-of-the-box hyperref-incompatible.  This
-;; configuration is a workaround, which requires to pass option
-;; hyperindex=false to hyperref.
-;; textit and emph not currently used by Sphinx LaTeX writer.
-(define-attributes (("textbf" "textit" "emph" "default")))
-(markup-locref :open "\textbf{\hyperpage{" :close "}}" :attr "textbf")
-(markup-locref :open "\textit{\hyperpage{" :close "}}" :attr "textit")
-(markup-locref :open "\emph{\hyperpage{" :close "}}" :attr "emph")
-(markup-locref :open "\hyperpage{" :close "}" :attr "default")
-
-(require "numeric-sort.xdy")
-
-;; xindy base module latex.xdy loads tex.xdy and the latter instructs
-;; xindy to ignore **all** TeX macros in .idx entries, except those
-;; explicitely described in merge rule.  But when after applying all
-;; merge rules an empty string results, xindy raises an error:
-
-;;   ERROR: CHAR: index 0 should be less than the length of the string
-
-;; For example when using pdflatex with utf-8 characters the index
-;; file will contain \IeC macros and they will get ignored except if
-;; suitable merge rules are loaded early.  The texindy script coming
-;; with xindy provides this, but only for Latin scripts.  The texindy
-;; man page says to use rather xelatex or lualatex in case of Cyrillic
-;; scripts.
-
-;; Sphinx contributes cyrLICRutf8.xdy to provide support for Cyrillic
-;; scripts for the pdflatex engine.
-
-;; Another issue caused by xindy ignoring all TeX macros except those
-;; explicitely declared reveals itself when attempting to index ">>>",
-;; as the ">" is converted to "\textgreater{}" by Sphinx's LaTeX
-;; escaping.
-
-;; To fix this, Sphinx does **not** use texindy, and does not even
-;; load the xindy latex.xdy base module.
-
-;(require "latex.xdy")
-
-;; Rather it incorporates some suitable extracts from latex.xdy and
-;; tex.xdy with additional Sphinx contributed rules.
-
-;;;;;;;; extracts from tex.xdy (discarding most original comments):
-
-;;;
-;;; TeX conventions
-;;;
-
-;; Discard leading and trailing white space. Collapse multiple white
-;; space characters to blank.
-
-(merge-rule "^ +" "" :eregexp)
-(merge-rule " +$" "" :eregexp)
-(merge-rule "  +" " " :eregexp)
-
-;; Handle TeX markup
-
-(merge-rule "\\([{}$%&#])" "\1" :eregexp)
-
-;;;;;;;; end of extracts from xindy's tex.xdy
-
-;;;;;;;; extracts from latex.xdy:
-
-;; Standard location classes: arabic and roman numbers, and alphabets.
-
-(define-location-class "arabic-page-numbers" ("arabic-numbers"))
-(define-location-class "roman-page-numbers"  ("roman-numbers-lowercase"))
-(define-location-class "Roman-page-numbers"  ("roman-numbers-uppercase"))
-(define-location-class "alpha-page-numbers"  ("alpha"))
-(define-location-class "Alpha-page-numbers"  ("ALPHA"))
-
-;; Output Markup
-
-(markup-letter-group-list :sep "~n~n  \indexspace~n")
-
-(markup-indexentry :open "~n  \item "           :depth 0)
-(markup-indexentry :open "~n    \subitem "      :depth 1)
-(markup-indexentry :open "~n      \subsubitem " :depth 2)
-
-(markup-locclass-list :open ", " :sep ", ")
-(markup-locref-list   :sep ", ")
-
-;;;;;;;; end of extracts from latex.xdy
-
-;; Sphinx additions, cf sphinx.util.texescape for rationale
-;;
-;; blanks are already ignored from above merge-rules, so no space
-;; character after TeX control words, despite the fact that they will
-;; be present in .idx file.
-
-(merge-rule "\\sphinxleftcurlybrace\{\}" "{")
-(merge-rule "\\sphinxrightcurlybrace\{\}" "}")
-(merge-rule "\\_" "_")
-(merge-rule "\{\[\}" "[")
-(merge-rule "\{\]\}" "]")
-(merge-rule "\{\}`" "`")
-(merge-rule "\\textbackslash\{\}" "\\")
-(merge-rule "\\textasciitilde\{\}" "~~")
-(merge-rule "\\textless\{\}" "<")
-(merge-rule "\\textgreater\{\}" ">")
-(merge-rule "\\textasciicircum\{\}" "^")
-(merge-rule "\\P\{\}" "¶")
-(merge-rule "\\S\{\}" "§")
-(merge-rule "\\texteuro\{\}" "€")
-(merge-rule "\\\(\\infty\\\)" "∞")
-(merge-rule "\\\(\\pm\\\)" "±")
-(merge-rule "\\\(\\rightarrow\\\)" "→")
-(merge-rule "\\\(\\checkmark\\\)" "✓")
-(merge-rule "\\textendash\{\}" "–")
-(merge-rule "\\textbar\{\}" "|")
-
-;; This xindy module provides some basic support for "see"
-(require "makeindex.xdy")
-
-;; This creates one-letter headings and works fine with utf-8 letters.
-;; For Cyrillic and pdflatex necessitates cyrLICRutf8.xdy to be loaded too.
-(require "latin-lettergroups.xdy")
-
-;; currently we don't (know how to easily) separate "Numbers" from
-;; "Symbols" with xindy as is the case with makeindex.
-(markup-index :open  "\begin{sphinxtheindex}
-\let\lettergroup\sphinxstyleindexlettergroup
-\let\lettergroupDefault\sphinxstyleindexlettergroupDefault
-
-"
-	      :close "
-
-\end{sphinxtheindex}
-"
-	      :tree)
-
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 97fa300e1..55d37da79 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -130,7 +130,7 @@
     'tocdepth':        '',
     'secnumdepth':     '',
     'pageautorefname': '',
-    'translatablestrings': '',
+    'literalblockpto': '',
 }  # type: Dict[unicode, unicode]
 
 ADDITIONAL_SETTINGS = {
@@ -497,7 +497,6 @@ def __init__(self, document, builder):
             'release':      self.encode(builder.config.release),
             'author':       document.settings.author,   # treat as a raw LaTeX code
             'indexname':    _('Index'),
-            'use_xindy':    builder.config.latex_use_xindy,
         })
         if not self.elements['releasename'] and self.elements['release']:
             self.elements.update({
@@ -668,21 +667,12 @@ def declare_package(packagename, options=None):
         if self.elements['extraclassoptions']:
             self.elements['classoptions'] += ',' + \
                                              self.elements['extraclassoptions']
-        self.elements['translatablestrings'] = (
+        self.elements['literalblockpto'] = (
             self.babel_renewcommand(
                 '\\literalblockcontinuedname', self.encode(_('continued from previous page'))
             ) +
             self.babel_renewcommand(
                 '\\literalblockcontinuesname', self.encode(_('continues on next page'))
-            ) +
-            self.babel_renewcommand(
-                '\\sphinxnonalphabeticalgroupname', self.encode(_('Non-alphabetical'))
-            ) +
-            self.babel_renewcommand(
-                '\\sphinxsymbolsname', self.encode(_('Symbols'))
-            ) +
-            self.babel_renewcommand(
-                '\\sphinxnumbersname', self.encode(_('Numbers'))
             )
         )
         self.elements['pageautorefname'] = \
@@ -866,7 +856,8 @@ def generate_indices(self):
         def generate(content, collapsed):
             # type: (List[Tuple[unicode, List[Tuple[unicode, unicode, unicode, unicode, unicode]]]], bool) -> None  # NOQA
             ret.append('\\begin{sphinxtheindex}\n')
-            ret.append('\\let\\bigletter\\sphinxstyleindexlettergroup\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')
@@ -875,8 +866,7 @@ def generate(content, collapsed):
                 for entry in entries:
                     if not entry[3]:
                         continue
-                    ret.append('\\item\\relax\\sphinxstyleindexentry{%s}' %
-                               self.encode(entry[0]))
+                    ret.append('\\item {\\sphinxstyleindexentry{%s}}' % self.encode(entry[0]))
                     if entry[4]:
                         # add "extra" info
                         ret.append('\\sphinxstyleindexextra{%s}' % self.encode(entry[4]))
@@ -1929,11 +1919,8 @@ def visit_index(self, node, scre=re.compile(r';\s*')):
         # type: (nodes.Node, Pattern) -> None
         def escape(value):
             value = self.encode(value)
-            value = value.replace(r'\{', r'\sphinxleftcurlybrace{}')
-            value = value.replace(r'\}', r'\sphinxrightcurlybrace{}')
-            value = value.replace('"', '""')
-            value = value.replace('@', '"@')
-            value = value.replace('!', '"!')
+            value = value.replace(r'\{', r'{\sphinxleftcurlybrace}')
+            value = value.replace(r'\}', r'{\sphinxrightcurlybrace}')
             return value
 
         if not node.get('inline', True):


Test patch:
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 8075bf8d0..2573a74da 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -1201,7 +1201,7 @@ def test_latex_index(app, status, warning):
     result = (app.outdir / 'Python.tex').text(encoding='utf8')
     assert 'A \\index{famous}famous \\index{equation}equation:\n' in result
     assert '\n\\index{Einstein}\\index{relativity}\\ignorespaces \nand' in result
-    assert '\n\\index{main \\sphinxleftcurlybrace{}}\\ignorespaces ' in result
+    assert '\n\\index{main {\\sphinxleftcurlybrace}}\\ignorespaces ' in result
 
 
 @pytest.mark.sphinx('latex', testroot='latex-equations')