From 9cc25367b832fc743f071572645fa2c56d207c91 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 3 Jan 2020 00:20:05 +0900 Subject: [PATCH] Fix #6696: html: scale option of image/figure directive not working for SVG Note: imagesize-1.2.0 or above is required --- CHANGES | 2 ++ sphinx/writers/html.py | 35 +++++++++++++++++++++-------------- sphinx/writers/html5.py | 35 +++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index fa0b2a2b11e..d4e242057c6 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,8 @@ Features added down the build * #6837: LaTeX: Support a nested table * #6966: graphviz: Support ``:class:`` option +* #6696: html: ``:scale:`` option of image/figure directive not working for SVG + images (imagesize-1.2.0 or above is required) Bugs fixed ---------- diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 47c3fdb4a80..84cdcc15bfc 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -579,6 +579,21 @@ def visit_image(self, node: Element) -> None: node['uri'] = posixpath.join(self.builder.imgpath, self.builder.images[olduri]) + if 'scale' in node: + # Try to figure out image height and width. Docutils does that too, + # but it tries the final file name, which does not necessarily exist + # yet at the time the HTML file is written. + if not ('width' in node and 'height' in node): + size = get_image_size(os.path.join(self.builder.srcdir, olduri)) + if size is None: + logger.warning(__('Could not obtain image size. :scale: option is ignored.'), # NOQA + location=node) + else: + if 'width' not in node: + node['width'] = str(size[0]) + if 'height' not in node: + node['height'] = str(size[1]) + uri = node['uri'] if uri.lower().endswith(('svg', 'svgz')): atts = {'src': uri} @@ -586,6 +601,12 @@ def visit_image(self, node: Element) -> None: atts['width'] = node['width'] if 'height' in node: atts['height'] = node['height'] + if 'scale' in node: + scale = node['scale'] / 100.0 + if 'width' in atts: + atts['width'] = int(atts['width']) * scale + if 'height' in atts: + atts['height'] = int(atts['height']) * scale atts['alt'] = node.get('alt', uri) if 'align' in node: self.body.append('
' % @@ -596,20 +617,6 @@ def visit_image(self, node: Element) -> None: self.body.append(self.emptytag(node, 'img', '', **atts)) return - if 'scale' in node: - # Try to figure out image height and width. Docutils does that too, - # but it tries the final file name, which does not necessarily exist - # yet at the time the HTML file is written. - if not ('width' in node and 'height' in node): - size = get_image_size(os.path.join(self.builder.srcdir, olduri)) - if size is None: - logger.warning(__('Could not obtain image size. :scale: option is ignored.'), # NOQA - location=node) - else: - if 'width' not in node: - node['width'] = str(size[0]) - if 'height' not in node: - node['height'] = str(size[1]) super().visit_image(node) # overwritten diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index aebe1e4286c..087c92842df 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -520,6 +520,21 @@ def visit_image(self, node: Element) -> None: node['uri'] = posixpath.join(self.builder.imgpath, self.builder.images[olduri]) + if 'scale' in node: + # Try to figure out image height and width. Docutils does that too, + # but it tries the final file name, which does not necessarily exist + # yet at the time the HTML file is written. + if not ('width' in node and 'height' in node): + size = get_image_size(os.path.join(self.builder.srcdir, olduri)) + if size is None: + logger.warning(__('Could not obtain image size. :scale: option is ignored.'), # NOQA + location=node) + else: + if 'width' not in node: + node['width'] = str(size[0]) + if 'height' not in node: + node['height'] = str(size[1]) + uri = node['uri'] if uri.lower().endswith(('svg', 'svgz')): atts = {'src': uri} @@ -527,6 +542,12 @@ def visit_image(self, node: Element) -> None: atts['width'] = node['width'] if 'height' in node: atts['height'] = node['height'] + if 'scale' in node: + scale = node['scale'] / 100.0 + if 'width' in atts: + atts['width'] = int(atts['width']) * scale + if 'height' in atts: + atts['height'] = int(atts['height']) * scale atts['alt'] = node.get('alt', uri) if 'align' in node: self.body.append('
' % @@ -537,20 +558,6 @@ def visit_image(self, node: Element) -> None: self.body.append(self.emptytag(node, 'img', '', **atts)) return - if 'scale' in node: - # Try to figure out image height and width. Docutils does that too, - # but it tries the final file name, which does not necessarily exist - # yet at the time the HTML file is written. - if not ('width' in node and 'height' in node): - size = get_image_size(os.path.join(self.builder.srcdir, olduri)) - if size is None: - logger.warning(__('Could not obtain image size. :scale: option is ignored.'), # NOQA - location=node) - else: - if 'width' not in node: - node['width'] = str(size[0]) - if 'height' not in node: - node['height'] = str(size[1]) super().visit_image(node) # overwritten