diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 7bfce0ad6..0fd5a43ef 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -47,6 +47,7 @@ from sphinx.highlighting import PygmentsBridge
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.writers.html import HTMLWriter, HTMLTranslator, \
SmartyPantsHTMLTranslator
+from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.environment.adapters.toctree import TocTree
from sphinx.environment.adapters.indexentries import IndexEntries
@@ -606,11 +607,12 @@ class StandaloneHTMLBuilder(Builder):
def copy_image_files(self):
# type: () -> None
- # copy image files
if self.images:
+ stringify_func = ImageAdapter(self.app.env).get_original_image_uri
ensuredir(path.join(self.outdir, self.imagedir))
for src in status_iterator(self.images, 'copying images... ', "brown",
- len(self.images), self.app.verbosity):
+ len(self.images), self.app.verbosity,
+ stringify_func=stringify_func):
dest = self.images[src]
try:
copyfile(path.join(self.srcdir, src),
diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py
index 910ac41d7..ac061e08e 100644
--- a/sphinx/builders/latex.py
+++ b/sphinx/builders/latex.py
@@ -13,8 +13,6 @@ import os
import warnings
from os import path
-from six import iteritems
-
from docutils import nodes
from docutils.io import FileOutput
from docutils.utils import new_document
@@ -22,12 +20,13 @@ from docutils.frontend import OptionParser
from sphinx import package_dir, addnodes, highlighting
from sphinx.deprecation import RemovedInSphinx17Warning
-from sphinx.util import texescape, logging
from sphinx.config import string_classes, ENUM
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
+from sphinx.environment.adapters.asset import ImageAdapter
+from sphinx.util import texescape, logging, status_iterator
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.osutil import SEP, make_filename
@@ -207,14 +206,7 @@ class LaTeXBuilder(Builder):
def finish(self):
# type: () -> None
- # copy image files
- if self.images:
- logger.info(bold('copying images...'), nonl=1)
- for src, dest in iteritems(self.images):
- logger.info(' ' + src, nonl=1)
- copy_asset_file(path.join(self.srcdir, src),
- path.join(self.outdir, dest))
- logger.info('')
+ self.copy_image_files()
# copy TeX support files from texinputs
context = {'latex_engine': self.config.latex_engine}
@@ -241,6 +233,21 @@ class LaTeXBuilder(Builder):
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
logger.info('done')
+ def copy_image_files(self):
+ # type: () -> None
+ if self.images:
+ stringify_func = ImageAdapter(self.app.env).get_original_image_uri
+ for src in status_iterator(self.images, 'copying images... ', "brown",
+ len(self.images), self.app.verbosity,
+ stringify_func=stringify_func):
+ dest = self.images[src]
+ try:
+ copy_asset_file(path.join(self.srcdir, src),
+ path.join(self.outdir, dest))
+ except Exception as err:
+ logger.warning('cannot copy image file %r: %s',
+ path.join(self.srcdir, src), err)
+
def validate_config_values(app):
# type: (Sphinx) -> None
diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py
index 823290255..4724aa9c3 100644
--- a/sphinx/builders/texinfo.py
+++ b/sphinx/builders/texinfo.py
@@ -11,8 +11,6 @@
from os import path
-from six import iteritems
-
from docutils import nodes
from docutils.io import FileOutput
from docutils.utils import new_document
@@ -22,9 +20,12 @@ from sphinx import addnodes
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
+from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.util import logging
+from sphinx.util import status_iterator
+from sphinx.util.fileutil import copy_asset_file
from sphinx.util.nodes import inline_all_toctrees
-from sphinx.util.osutil import SEP, copyfile, make_filename
+from sphinx.util.osutil import SEP, make_filename
from sphinx.util.console import bold, darkgreen # type: ignore
from sphinx.writers.texinfo import TexinfoWriter
@@ -223,14 +224,7 @@ class TexinfoBuilder(Builder):
def finish(self):
# type: () -> None
- # copy image files
- if self.images:
- logger.info(bold('copying images...'), nonl=1)
- for src, dest in iteritems(self.images):
- logger.info(' ' + src, nonl=1)
- copyfile(path.join(self.srcdir, src),
- path.join(self.outdir, dest))
- logger.info('')
+ self.copy_image_files()
logger.info(bold('copying Texinfo support files... '), nonl=True)
# copy Makefile
@@ -243,6 +237,21 @@ class TexinfoBuilder(Builder):
logger.warning("error writing file %s: %s", fn, err)
logger.info(' done')
+ def copy_image_files(self):
+ # type: () -> None
+ if self.images:
+ stringify_func = ImageAdapter(self.app.env).get_original_image_uri
+ for src in status_iterator(self.images, 'copying images... ', "brown",
+ len(self.images), self.app.verbosity,
+ stringify_func=stringify_func):
+ dest = self.images[src]
+ try:
+ copy_asset_file(path.join(self.srcdir, src),
+ path.join(self.outdir, dest))
+ except Exception as err:
+ logger.warning('cannot copy image file %r: %s',
+ path.join(self.srcdir, src), err)
+
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py
index 00d730592..303704773 100644
--- a/sphinx/environment/__init__.py
+++ b/sphinx/environment/__init__.py
@@ -257,6 +257,9 @@ class BuildEnvironment(object):
self.images = FilenameUniqDict()
self.dlfiles = FilenameUniqDict()
+ # the original URI for images
+ self.original_image_uri = {} # type: Dict[unicode, unicode]
+
# temporary data storage while reading a document
self.temp_data = {} # type: Dict[unicode, Any]
# context for cross-references (e.g. current module or class)
diff --git a/sphinx/environment/adapters/asset.py b/sphinx/environment/adapters/asset.py
new file mode 100644
index 000000000..a373205d2
--- /dev/null
+++ b/sphinx/environment/adapters/asset.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.environment.adapters.assets
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Assets adapter for sphinx.environment.
+
+ :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+if False:
+ # For type annotation
+ from sphinx.environment import BuildEnvironment # NOQA
+
+
+class ImageAdapter(object):
+ def __init__(self, env):
+ # type: (BuildEnvironment) -> None
+ self.env = env
+
+ def get_original_image_uri(self, name):
+ # type: (unicode) -> unicode
+ """Get the original image URI."""
+ while name in self.env.original_image_uri:
+ name = self.env.original_image_uri[name]
+
+ return name
diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py
index c9d6d2f95..e4f1c29cb 100644
--- a/sphinx/transforms/post_transforms/images.py
+++ b/sphinx/transforms/post_transforms/images.py
@@ -69,6 +69,8 @@ class ImageDownloader(BaseImageConverter):
logger.warning('Could not fetch remote image: %s [%d]' %
(node['uri'], r.status_code))
else:
+ self.app.env.original_image_uri[path] = node['uri']
+
with open(path, 'wb') as f:
f.write(r.content)