From e7aee6e82a36de18085327df72b9931aee16d60d Mon Sep 17 00:00:00 2001 From: jfbu Date: Mon, 14 Jan 2019 16:04:04 +0100 Subject: [PATCH 1/2] LaTeX: remove usage of \scalebox by incorporating scale in height/width Closes: #5954 --- CHANGES | 1 + sphinx/writers/latex.py | 52 ++++++++++++++++++++++++--------------- tests/test_build_latex.py | 2 +- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 32c3d5135..337a3f0e8 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,7 @@ Bugs fixed * #5936: LaTeX: PDF build broken by inclusion of image taller than page height in an admonition * #5231: "make html" does not read and build "po" files in "locale" dir +* #5954: ``:scale:`` image option may break PDF build if image in an admonition Testing -------- diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 33cdb3d23..88afe07ee 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -424,21 +424,32 @@ def escape_abbr(text): return re.sub(r'\.(?=\s|$)', r'.\@', text) -def rstdim_to_latexdim(width_str): - # type: (unicode) -> unicode +def rstdim_to_latexdim(width_str, scale = 100): + # type: (unicode, int) -> unicode """Convert `width_str` with rst length to LaTeX length.""" match = re.match(r'^(\d*\.?\d*)\s*(\S*)$', width_str) if not match: raise ValueError res = width_str amount, unit = match.groups()[:2] - float(amount) # validate amount is float - if unit in ('', "px"): - res = "%s\\sphinxpxdimen" % amount - elif unit == 'pt': - res = '%sbp' % amount # convert to 'bp' - elif unit == "%": - res = "%.3f\\linewidth" % (float(amount) / 100.0) + if scale == 100: + float(amount) # validate amount is float + if unit in ('', "px"): + res = "%s\\sphinxpxdimen" % amount + elif unit == 'pt': + res = '%sbp' % amount # convert to 'bp' + elif unit == "%": + res = "%.3f\\linewidth" % (float(amount) / 100.0) + else: + amount = float(amount) * scale / 100.0 + if unit in ('', "px"): + res = "%.5f\\sphinxpxdimen" % amount + elif unit == 'pt': + res = '%.5fbp' % amount + elif unit == "%": + res = "%.5f\\linewidth" % (amount / 100.0) + else: + res = "%.5f%s" % (amount, unit) return res @@ -1624,10 +1635,10 @@ class LaTeXTranslator(nodes.NodeVisitor): # type: (nodes.Node) -> None pass - def latex_image_length(self, width_str): - # type: (nodes.Node) -> unicode + def latex_image_length(self, width_str, scale = 100): + # type: (nodes.Node, int) -> unicode try: - return rstdim_to_latexdim(width_str) + return rstdim_to_latexdim(width_str, scale) except ValueError: logger.warning(__('dimension unit %s is invalid. Ignored.'), width_str) return None @@ -1646,20 +1657,21 @@ class LaTeXTranslator(nodes.NodeVisitor): include_graphics_options = [] is_inline = self.is_inline(node) if 'width' in attrs: - w = self.latex_image_length(attrs['width']) + if 'scale' in attrs: + w = self.latex_image_length(attrs['width'], attrs['scale']) + else: + w = self.latex_image_length(attrs['width']) if w: include_graphics_options.append('width=%s' % w) if 'height' in attrs: - h = self.latex_image_length(attrs['height']) + if 'scale' in attrs: + h = self.latex_image_length(attrs['height'], attrs['scale']) + else: + h = self.latex_image_length(attrs['height']) if h: include_graphics_options.append('height=%s' % h) if 'scale' in attrs: - if include_graphics_options: - # unfortunately passing "height=1cm,scale=2.0" to \includegraphics - # does not result in a height of 2cm. We must scale afterwards. - pre.append('\\scalebox{%f}{' % (attrs['scale'] / 100.0,)) - post.append('}') - else: + if not include_graphics_options: # if no "width" nor "height", \sphinxincludegraphics will fit # to the available text width if oversized after rescaling. include_graphics_options.append('scale=%s' diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 443f6ea27..fb481371c 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -1225,7 +1225,7 @@ def test_latex_image_in_parsed_literal(app, status, warning): result = (app.outdir / 'Python.tex').text(encoding='utf8') assert ('{\\sphinxunactivateextrasandspace \\raisebox{-0.5\\height}' - '{\\scalebox{2.000000}{\\sphinxincludegraphics[height=1cm]{{pic}.png}}}' + '{\\sphinxincludegraphics[height=2.00000cm]{{pic}.png}}' '}AFTER') in result From ecf5d7622b00349e1e95d7030fcb90a13e6c2825 Mon Sep 17 00:00:00 2001 From: jfbu Date: Mon, 14 Jan 2019 16:44:35 +0100 Subject: [PATCH 2/2] Make mypy happy, but I protest ! modified: sphinx/writers/latex.py --- sphinx/writers/latex.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 88afe07ee..3ada12c4d 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -441,15 +441,15 @@ def rstdim_to_latexdim(width_str, scale = 100): elif unit == "%": res = "%.3f\\linewidth" % (float(amount) / 100.0) else: - amount = float(amount) * scale / 100.0 + amount_float = float(amount) * scale / 100.0 if unit in ('', "px"): - res = "%.5f\\sphinxpxdimen" % amount + res = "%.5f\\sphinxpxdimen" % amount_float elif unit == 'pt': - res = '%.5fbp' % amount + res = '%.5fbp' % amount_float elif unit == "%": - res = "%.5f\\linewidth" % (amount / 100.0) + res = "%.5f\\linewidth" % (amount_float / 100.0) else: - res = "%.5f%s" % (amount, unit) + res = "%.5f%s" % (amount_float, unit) return res