Skip to content

Commit 11a674f

Browse files
authored
Merge pull request #5437 from rtfd/humitos/build-pdf-latexmk
Build PDF files using latexmk
2 parents 56a26f5 + d9ccf27 commit 11a674f

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

docs/guides/feature-flags.rst

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ or disable one or more of these featured flags for a particular project.
1212
Available Flags
1313
---------------
1414

15+
``USE_PDF_LATEXMK``: :featureflags:`USE_PDF_LATEXMK`
16+
1517
``USE_SPHINX_LATEST``: :featureflags:`USE_SPHINX_LATEST`
1618

1719
``USE_SETUPTOOLS_LATEST``: :featureflags:`USE_SETUPTOOLS_LATEST`

readthedocs/doc_builder/backends/sphinx.py

+66
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
.. _Sphinx: http://www.sphinx-doc.org/
77
"""
88
import codecs
9+
import itertools
910
import logging
1011
import os
1112
import shutil
1213
import sys
1314
import zipfile
1415
from glob import glob
16+
from pathlib import Path
1517

1618
from django.conf import settings
1719
from django.template import loader as template_loader
@@ -151,6 +153,9 @@ def get_config_params(self):
151153
'dont_overwrite_sphinx_context': self.project.has_feature(
152154
Feature.DONT_OVERWRITE_SPHINX_CONTEXT,
153155
),
156+
'use_pdf_latexmk': self.project.has_feature(
157+
Feature.USE_PDF_LATEXMK,
158+
),
154159
}
155160

156161
finalize_sphinx_context_data.send(
@@ -394,6 +399,67 @@ def build(self):
394399
raise BuildEnvironmentError('No TeX files were found')
395400

396401
# Run LaTeX -> PDF conversions
402+
if self.project.has_feature(Feature.USE_PDF_LATEXMK):
403+
return self._build_latexmk(cwd, latex_cwd)
404+
405+
return self._build_pdflatex(tex_files, latex_cwd)
406+
407+
def _build_latexmk(self, cwd, latex_cwd):
408+
# These steps are copied from the Makefile generated by Sphinx >= 1.6
409+
# https://github.com/sphinx-doc/sphinx/blob/master/sphinx/texinputs/Makefile_t
410+
latex_path = Path(latex_cwd)
411+
images = []
412+
for extension in ('png', 'gif', 'jpg', 'jpeg'):
413+
images.extend(latex_path.glob(f'*.{extension}'))
414+
415+
# FIXME: instead of checking by language here, what we want to check if
416+
# ``latex_engine`` is ``platex``
417+
pdfs = []
418+
if self.project.language == 'ja':
419+
# Japanese language is the only one that requires this extra
420+
# step. I don't know exactly why but most of the documentation that
421+
# I read differentiate this language from the others. I suppose
422+
# it's because it mix kanji (Chinese) with its own symbols.
423+
pdfs = latex_path.glob('*.pdf')
424+
425+
for image in itertools.chain(images, pdfs):
426+
self.run(
427+
'extractbb',
428+
image.name,
429+
cwd=latex_cwd,
430+
record=False,
431+
)
432+
433+
rcfile = 'latexmkrc'
434+
if self.project.language == 'ja':
435+
rcfile = 'latexmkjarc'
436+
437+
self.run(
438+
'cat',
439+
rcfile,
440+
cwd=latex_cwd,
441+
)
442+
443+
cmd = self.run(
444+
'latexmk',
445+
'-r',
446+
rcfile,
447+
448+
# FIXME: check for platex here as well
449+
'-pdfdvi' if self.project.language == 'ja' else '-pdf',
450+
451+
'-dvi-',
452+
'-ps-',
453+
f'-jobname={self.project.slug}',
454+
warn_only=True,
455+
cwd=latex_cwd,
456+
)
457+
458+
self.pdf_file_name = f'{self.project.slug}.pdf'
459+
460+
return cmd.successful
461+
462+
def _build_pdflatex(self, tex_files, latex_cwd):
397463
pdflatex_cmds = [
398464
['pdflatex', '-interaction=nonstopmode', tex_file]
399465
for tex_file in tex_files

readthedocs/doc_builder/templates/doc_builder/conf.py.tmpl

+35
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,38 @@ if 'extensions' in globals():
140140
extensions.insert(0, "readthedocs_ext.readthedocs")
141141
else:
142142
extensions = ["readthedocs_ext.readthedocs"]
143+
144+
{% if use_pdf_latexmk %}
145+
project_language = '{{ project.language }}'
146+
147+
# User's Sphinx configurations
148+
language_user = globals().get('language', None)
149+
latex_engine_user = globals().get('latex_engine', None)
150+
latex_elements_user = globals().get('latex_elements', None)
151+
152+
chinese = any([
153+
language_user in ('zh_CN', 'zh_TW'),
154+
project_language in ('zh_CN', 'zh_TW'),
155+
])
156+
157+
japanase = any([
158+
language_user == 'ja',
159+
project_language == 'ja',
160+
])
161+
162+
if chinese:
163+
latex_engine = latex_engine_user or 'xelatex'
164+
165+
# Remove this once xindy gets installed in Docker image and XINDYOPS
166+
# env variable is supported
167+
# https://github.com/rtfd/readthedocs-docker-images/pull/98
168+
latex_use_xindy = False
169+
170+
latex_elements_rtd = {
171+
'preamble': '\\usepackage[UTF8]{ctex}\n',
172+
}
173+
latex_elements = latex_elements_user or latex_elements_rtd
174+
elif japanase:
175+
latex_engine = latex_engine_user or 'platex'
176+
latex_use_xindy = False
177+
{% endif %}

readthedocs/projects/models.py

+2
Original file line numberDiff line numberDiff line change
@@ -1315,10 +1315,12 @@ def add_features(sender, **kwargs):
13151315
DONT_SHALLOW_CLONE = 'dont_shallow_clone'
13161316
USE_TESTING_BUILD_IMAGE = 'use_testing_build_image'
13171317
SHARE_SPHINX_DOCTREE = 'share_sphinx_doctree'
1318+
USE_PDF_LATEXMK = 'use_pdf_latexmk'
13181319

13191320
FEATURES = (
13201321
(USE_SPHINX_LATEST, _('Use latest version of Sphinx')),
13211322
(USE_SETUPTOOLS_LATEST, _('Use latest version of setuptools')),
1323+
(USE_PDF_LATEXMK, _('Use latexmk to build the PDF')),
13221324
(ALLOW_DEPRECATED_WEBHOOKS, _('Allow deprecated webhook views')),
13231325
(PIP_ALWAYS_UPGRADE, _('Always run pip install --upgrade')),
13241326
(SKIP_SUBMODULES, _('Skip git submodule checkout')),

0 commit comments

Comments
 (0)