Repository: readthedocs/readthedocs.org

Issue:
Feature flag to use other pdf latex binaries
This is an experiment.

I tried building https://tecs-docs.readthedocs.io/ja/latest/ with `xindy` and `xelatex` and I had some success by getting a PDF with the index full in Japanese but the content is not displayed properly.

On the other hand, building just with `pdflatex` just fail the build and/or generate just the cover page.

> `xindy` is not installed in our Docker image, so I created a PR for that at https://github.com/rtfd/readthedocs-docker-images/issues/98


Discussion:
> but the content is not displayed properly

It doesn't lookd like a solution.

I just notice that when building docs with no-ascii characters the pdf build fails too https://readthedocs.org/projects/test-builds/builds/8659499/, is that solved using any of these builders?
> I just notice that when building docs with no-ascii characters the pdf build fails too [readthedocs.org/projects/test-builds/builds/8659499](https://readthedocs.org/projects/test-builds/builds/8659499/), is that solved using any of these builders?

Yes, adding the feature flag to use `xelatex` it builds.

![captura de pantalla_2019-03-06_17-17-02](https://user-images.githubusercontent.com/244656/53896140-b83c9a80-4033-11e9-93e1-b37a1e0680b0.png)

It's not perfect, though:

![captura de pantalla_2019-03-06_17-16-22](https://user-images.githubusercontent.com/244656/53896164-c094d580-4033-11e9-8539-2b39d059045d.png)

but that's probably a problem with the font that does not have those characters.

Resolving patch:
diff --git a/readthedocs/doc_builder/backends/sphinx.py b/readthedocs/doc_builder/backends/sphinx.py
--- a/readthedocs/doc_builder/backends/sphinx.py
+++ b/readthedocs/doc_builder/backends/sphinx.py
@@ -6,12 +6,14 @@
 .. _Sphinx: http://www.sphinx-doc.org/
 """
 import codecs
+import itertools
 import logging
 import os
 import shutil
 import sys
 import zipfile
 from glob import glob
+from pathlib import Path
 
 from django.conf import settings
 from django.template import loader as template_loader
@@ -151,6 +153,9 @@ def get_config_params(self):
             'dont_overwrite_sphinx_context': self.project.has_feature(
                 Feature.DONT_OVERWRITE_SPHINX_CONTEXT,
             ),
+            'use_pdf_latexmk': self.project.has_feature(
+                Feature.USE_PDF_LATEXMK,
+            ),
         }
 
         finalize_sphinx_context_data.send(
@@ -395,6 +400,67 @@ def build(self):
             raise BuildEnvironmentError('No TeX files were found')
 
         # Run LaTeX -> PDF conversions
+        if self.project.has_feature(Feature.USE_PDF_LATEXMK):
+            return self._build_latexmk(cwd, latex_cwd)
+
+        return self._build_pdflatex(tex_files, latex_cwd)
+
+    def _build_latexmk(self, cwd, latex_cwd):
+        # These steps are copied from the Makefile generated by Sphinx >= 1.6
+        # https://github.com/sphinx-doc/sphinx/blob/master/sphinx/texinputs/Makefile_t
+        latex_path = Path(latex_cwd)
+        images = []
+        for extension in ('png', 'gif', 'jpg', 'jpeg'):
+            images.extend(latex_path.glob(f'*.{extension}'))
+
+        # FIXME: instead of checking by language here, what we want to check if
+        # ``latex_engine`` is ``platex``
+        pdfs = []
+        if self.project.language == 'ja':
+            # Japanese language is the only one that requires this extra
+            # step. I don't know exactly why but most of the documentation that
+            # I read differentiate this language from the others. I suppose
+            # it's because it mix kanji (Chinese) with its own symbols.
+            pdfs = latex_path.glob('*.pdf')
+
+        for image in itertools.chain(images, pdfs):
+            self.run(
+                'extractbb',
+                image.name,
+                cwd=latex_cwd,
+                record=False,
+            )
+
+        rcfile = 'latexmkrc'
+        if self.project.language == 'ja':
+            rcfile = 'latexmkjarc'
+
+        self.run(
+            'cat',
+            rcfile,
+            cwd=latex_cwd,
+        )
+
+        cmd = self.run(
+            'latexmk',
+            '-r',
+            rcfile,
+
+            # FIXME: check for platex here as well
+            '-pdfdvi' if self.project.language == 'ja' else '-pdf',
+
+            '-dvi-',
+            '-ps-',
+            f'-jobname={self.project.slug}',
+            warn_only=True,
+            cwd=latex_cwd,
+        )
+
+        self.pdf_file_name = f'{self.project.slug}.pdf'
+
+        return cmd.successful
+
+    def _build_pdflatex(self, tex_files, latex_cwd):
         pdflatex_cmds = [
             ['pdflatex', '-interaction=nonstopmode', tex_file]
             for tex_file in tex_files
diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py
--- a/readthedocs/projects/models.py
+++ b/readthedocs/projects/models.py
@@ -1314,10 +1314,12 @@ def add_features(sender, **kwargs):
     DONT_SHALLOW_CLONE = 'dont_shallow_clone'
     USE_TESTING_BUILD_IMAGE = 'use_testing_build_image'
     SHARE_SPHINX_DOCTREE = 'share_sphinx_doctree'
+    USE_PDF_LATEXMK = 'use_pdf_latexmk'
 
     FEATURES = (
         (USE_SPHINX_LATEST, _('Use latest version of Sphinx')),
         (USE_SETUPTOOLS_LATEST, _('Use latest version of setuptools')),
+        (USE_PDF_LATEXMK, _('Use latexmk to build the PDF')),
         (ALLOW_DEPRECATED_WEBHOOKS, _('Allow deprecated webhook views')),
         (PIP_ALWAYS_UPGRADE, _('Always run pip install --upgrade')),
         (SKIP_SUBMODULES, _('Skip git submodule checkout')),


Test patch: