mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Support images in Data URI on non-HTML builders
This commit is contained in:
parent
be261ed71e
commit
ebdec70dfc
3
CHANGES
3
CHANGES
@ -106,7 +106,8 @@ Features added
|
||||
``suppress_warnings``
|
||||
* #2803: Discovery of builders by entry point
|
||||
* #1764, #1676: Allow setting 'rel' and 'title' attributes for stylesheets
|
||||
* #3589: Support remote images
|
||||
* #3589: Support remote images on non-HTML builders
|
||||
* #3589: Support images in Data URI on non-HTML builders
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -227,7 +227,6 @@ General configuration
|
||||
* app.add_generic_role
|
||||
* app.add_source_parser
|
||||
* download.not_readable
|
||||
* image.data_uri
|
||||
* image.not_readable
|
||||
* ref.term
|
||||
* ref.ref
|
||||
|
@ -65,6 +65,7 @@ class Builder(object):
|
||||
#: Image files are searched in the order in which they appear here.
|
||||
supported_image_types = [] # type: List[unicode]
|
||||
supported_remote_images = True
|
||||
supported_data_uri_images = False
|
||||
|
||||
def __init__(self, app):
|
||||
# type: (Sphinx) -> None
|
||||
|
@ -103,6 +103,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
html_scaled_image_link = True
|
||||
supported_image_types = ['image/svg+xml', 'image/png',
|
||||
'image/gif', 'image/jpeg']
|
||||
supported_data_uri_images = True
|
||||
searchindex_filename = 'searchindex.js'
|
||||
add_permalinks = True
|
||||
allow_sharp_as_current_path = True
|
||||
|
@ -59,8 +59,6 @@ class ImageCollector(EnvironmentCollector):
|
||||
node['candidates'] = candidates
|
||||
imguri = node['uri']
|
||||
if imguri.startswith('data:'):
|
||||
logger.warning('image data URI found. some builders might not support',
|
||||
location=node, type='image', subtype='data_uri')
|
||||
candidates['?'] = imguri
|
||||
continue
|
||||
elif imguri.find('://') != -1:
|
||||
|
@ -10,13 +10,14 @@
|
||||
"""
|
||||
|
||||
import os
|
||||
from hashlib import sha1
|
||||
|
||||
from six import text_type
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.transforms import SphinxTransform
|
||||
from sphinx.util import logging, requests
|
||||
from sphinx.util.images import guess_mimetype
|
||||
from sphinx.util.images import guess_mimetype, get_image_extension, parse_data_uri
|
||||
from sphinx.util.osutil import ensuredir
|
||||
|
||||
if False:
|
||||
@ -43,6 +44,11 @@ class BaseImageConverter(SphinxTransform):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
@property
|
||||
def imagedir(self):
|
||||
# type: () -> unicode
|
||||
return os.path.join(self.app.doctreedir, 'images')
|
||||
|
||||
|
||||
class ImageDownloader(BaseImageConverter):
|
||||
default_priority = 100
|
||||
@ -56,14 +62,13 @@ class ImageDownloader(BaseImageConverter):
|
||||
|
||||
def handle(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
imgdir = os.path.join(self.app.doctreedir, 'images')
|
||||
basename = os.path.basename(node['uri'])
|
||||
if '?' in basename:
|
||||
basename = basename.split('?')[0]
|
||||
dirname = node['uri'].replace('://', '/').translate({ord("?"): u"/",
|
||||
ord("&"): u"/"})
|
||||
ensuredir(os.path.join(imgdir, dirname))
|
||||
path = os.path.join(imgdir, dirname, basename)
|
||||
ensuredir(os.path.join(self.imagedir, dirname))
|
||||
path = os.path.join(self.imagedir, dirname, basename)
|
||||
try:
|
||||
r = requests.get(node['uri'])
|
||||
if r.status_code != 200:
|
||||
@ -85,9 +90,43 @@ class ImageDownloader(BaseImageConverter):
|
||||
(node['uri'], text_type(exc)))
|
||||
|
||||
|
||||
class DataURIExtractor(BaseImageConverter):
|
||||
default_priority = 150
|
||||
|
||||
def match(self, node):
|
||||
# type: (nodes.Node) -> bool
|
||||
if self.app.builder.supported_data_uri_images:
|
||||
return False
|
||||
else:
|
||||
return 'data:' in node['uri']
|
||||
|
||||
def handle(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
image = parse_data_uri(node['uri'])
|
||||
ext = get_image_extension(image.mimetype)
|
||||
if ext is None:
|
||||
logger.warning('Unknown image format: %s...', node['uri'][:32],
|
||||
location=node)
|
||||
return
|
||||
|
||||
ensuredir(os.path.join(self.imagedir, 'embeded'))
|
||||
digest = sha1(image.data).hexdigest()
|
||||
path = os.path.join(self.imagedir, 'embeded', digest + ext)
|
||||
self.app.env.original_image_uri[path] = node['uri']
|
||||
|
||||
with open(path, 'wb') as f:
|
||||
f.write(image.data)
|
||||
|
||||
node['candidates'].pop('?')
|
||||
node['candidates'][image.mimetype] = path
|
||||
node['uri'] = path
|
||||
self.app.env.images.add_file(self.env.docname, path)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[unicode, Any]
|
||||
app.add_post_transform(ImageDownloader)
|
||||
app.add_post_transform(DataURIExtractor)
|
||||
|
||||
return {
|
||||
'version': 'builtin',
|
||||
|
Loading…
Reference in New Issue
Block a user