|
From: <mi...@us...> - 2023-11-25 21:09:32
|
Revision: 9487
http://sourceforge.net/p/docutils/code/9487
Author: milde
Date: 2023-11-25 21:09:29 +0000 (Sat, 25 Nov 2023)
Log Message:
-----------
Adapt path before reading image file.
In order to work in the output document, relative image URIs relate
to the output directory. To determine the image size from the image or
embed the image, the writer must access the image file at build time.
The change ensures that the same URI can be used for images referenced
in the output document and embedded images also when CWD and output
directory differ.
Modified Paths:
--------------
trunk/docutils/HISTORY.txt
trunk/docutils/docutils/writers/_html_base.py
trunk/docutils/docutils/writers/html4css1/__init__.py
trunk/docutils/test/functional/expected/misc_rst_html5.html
trunk/docutils/test/functional/input/data/embed_images.txt
Modified: trunk/docutils/HISTORY.txt
===================================================================
--- trunk/docutils/HISTORY.txt 2023-11-25 21:09:17 UTC (rev 9486)
+++ trunk/docutils/HISTORY.txt 2023-11-25 21:09:29 UTC (rev 9487)
@@ -85,6 +85,9 @@
- Support for video inclusion via `<video>` tags
(moved here from writers/html5_polyglot/__init__.py).
+ - New auxiliary function `HTMLTranslator.uri2imagepath()`
+ ensures the image file can also be read when
+ CWD and output directory differ.
* docutils/writers/latex2e/__init__.py
Modified: trunk/docutils/docutils/writers/_html_base.py
===================================================================
--- trunk/docutils/docutils/writers/_html_base.py 2023-11-25 21:09:17 UTC (rev 9486)
+++ trunk/docutils/docutils/writers/_html_base.py 2023-11-25 21:09:29 UTC (rev 9487)
@@ -22,7 +22,6 @@
import os.path
import re
import urllib
-from urllib.request import url2pathname # unquote and use local path sep
import warnings
import docutils
@@ -493,6 +492,29 @@
return
child['classes'].append(class_)
+ def uri2imagepath(self, uri):
+ """Get filesystem path corresponding to an URI.
+
+ The image directive expects an image URI. Some writers require the
+ corresponding image path to read the image size from the file or to
+ embed the image in the output.
+
+ In order to work in the output document, relative image URIs relate
+ to the output directory. For access by the writer, the corresponding
+ image path must be relative to the current working directory.
+
+ Provisional: the function's location, interface and behaviour
+ may change without advance warning.
+ """
+ destination = self.settings._destination or ''
+ uri_parts = urllib.parse.urlparse(uri)
+ imagepath = urllib.request.url2pathname(uri_parts.path)
+ if not os.path.isabs(imagepath):
+ destdir = os.path.abspath(os.path.dirname(destination))
+ imagepath = utils.relative_path(None,
+ os.path.join(destdir, imagepath))
+ return imagepath
+
def visit_Text(self, node):
text = node.astext()
encoded = self.encode(text)
@@ -1004,11 +1026,13 @@
videotypes = ('video/mp4', 'video/webm', 'video/ogg')
def visit_image(self, node):
- atts = {}
uri = node['uri']
uri_parts = urllib.parse.urlparse(uri)
imagepath = ''
mimetype = mimetypes.guess_type(uri)[0]
+ atts = {} # attributes for the HTML tag
+ if 'align' in node:
+ atts['class'] = 'align-%s' % node['align']
# image size
if 'width' in node:
atts['width'] = node['width']
@@ -1027,7 +1051,7 @@
if not self.settings.file_insertion_enabled:
scaling_problems.append('Reading external files disabled.')
if not scaling_problems:
- imagepath = url2pathname(uri_parts.path)
+ imagepath = self.uri2imagepath(uri)
try:
with PIL.Image.open(imagepath) as img:
imgsize = img.size
@@ -1054,6 +1078,7 @@
atts[att_name] = '%s%s' % (
float(match.group(1)) * (float(node['scale']) / 100),
match.group(2))
+ # set size with "style" attribute (more universal, accepts dimensions)
style = []
for att_name in 'width', 'height':
if att_name in atts:
@@ -1064,17 +1089,14 @@
del atts[att_name]
if style:
atts['style'] = ' '.join(style)
+ # No newlines around inline images or if surrounded by <a>...</a>.
if (isinstance(node.parent, nodes.TextElement)
or (isinstance(node.parent, nodes.reference)
and not isinstance(node.parent.parent, nodes.TextElement))):
- # Inline context or surrounded by <a>...</a>.
suffix = ''
else:
suffix = '\n'
- if 'align' in node:
- atts['class'] = 'align-%s' % node['align']
-
# moving image -> use <video>
if mimetype in self.videotypes:
fallback = node.get('alt', uri)
@@ -1093,14 +1115,9 @@
self.document.reporter.error(
f'Cannot embed remote image "{uri}"')
# TODO: read with urllib.request?
- imagepath = imagepath or url2pathname(uri_parts.path)
- # TODO: adapt relative imagepath?
- # if not os.path.isabs(imagepath):
- # _src, _ln = utils.get_source_line(node)
- # dirname = os.path.dirname(_src or '')
- # imagepath = os.path.join(dirname, imagepath)
+ imagepath = imagepath or self.uri2imagepath(uri)
try:
- with open(url2pathname(uri), 'rb') as imagefile:
+ with open(imagepath, 'rb') as imagefile:
imagedata = imagefile.read()
except OSError as err:
self.document.reporter.error('Cannot embed image %r: %s'
@@ -1116,6 +1133,7 @@
uri = 'data:%s;base64,%s' % (mimetype, data64)
elif self.image_loading == 'lazy':
atts['loading'] = 'lazy'
+
if mimetype == 'application/x-shockwave-flash':
atts['type'] = mimetype
# do NOT use an empty tag: incorrect rendering in browsers
Modified: trunk/docutils/docutils/writers/html4css1/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/html4css1/__init__.py 2023-11-25 21:09:17 UTC (rev 9486)
+++ trunk/docutils/docutils/writers/html4css1/__init__.py 2023-11-25 21:09:29 UTC (rev 9487)
@@ -19,7 +19,7 @@
from docutils import frontend, nodes, writers
from docutils.writers import _html_base
-from docutils.writers._html_base import PIL, url2pathname
+from docutils.writers._html_base import PIL
class Writer(writers._html_base.Writer):
@@ -565,7 +565,7 @@
if 'scale' in node:
if (PIL and ('width' not in node or 'height' not in node)
and self.settings.file_insertion_enabled):
- imagepath = url2pathname(uri)
+ imagepath = self.uri2imagepath(uri)
try:
with PIL.Image.open(imagepath) as img:
img_size = img.size
Modified: trunk/docutils/test/functional/expected/misc_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/misc_rst_html5.html 2023-11-25 21:09:17 UTC (rev 9486)
+++ trunk/docutils/test/functional/expected/misc_rst_html5.html 2023-11-25 21:09:29 UTC (rev 9487)
@@ -52,7 +52,7 @@
<li><p><a class="reference internal" href="#substitutions-fail" id="toc-entry-12">Substitutions work</a></p></li>
</ul>
</li>
-<li><p><a class="reference internal" href="#embedded-images" id="toc-entry-13">Embedded Images</a></p></li>
+<li><p><a class="reference internal" href="#embedded-images" id="toc-entry-13">Embedded images</a></p></li>
<li><p><a class="reference internal" href="#moving-images-video" id="toc-entry-14">Moving images (video)</a></p></li>
</ul>
</nav>
@@ -107,11 +107,10 @@
</section>
</section>
<section id="embedded-images">
-<h2><a class="toc-backref" href="#contents" role="doc-backlink">Embedded Images</a><a class="self-link" title="link to this section" href="#embedded-images"></a></h2>
-<p>The “embed” flag tells Docutils that it should
-try to embed the image in the output document.</p>
-<p>If the image can be read from the local file system, it is <a class="reference external" href="https://en.wikipedia.org/wiki/Base64">base64</a>
-encoded and included as a <a class="reference external" href="https://en.wikipedia.org/wiki/Data_URI_scheme">data URI</a>.
+<h2><a class="toc-backref" href="#contents" role="doc-backlink">Embedded images</a><a class="self-link" title="link to this section" href="#embedded-images"></a></h2>
+<p>The <a class="reference external" href="https://docutils.sourceforge.io/docs/user/config.html#image-loading">image_loading</a> setting can be used to tell the “html5” writer to
+embed images in the output document.
+The image is <a class="reference external" href="https://en.wikipedia.org/wiki/Base64">base64</a> encoded and included as a <a class="reference external" href="https://en.wikipedia.org/wiki/Data_URI_scheme">data URI</a>.
In future, SVG images may be directly inserted into HTML5.</p>
<figure class="align-center">
<img alt="biohazard" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAANkE3LLaAgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAZQTFRF////AAAAVcLTfgAAAAF0Uk5TAEDm2GYAAAA2SURBVHicYmBRYOAQYJCQYJC+wSBjAUL2fxjq6hgueTNM7AQh3g0MzAdAiP0BUBYAAAD//wMA4pkLDrFBDzUAAAAASUVORK5CYII=" />
Modified: trunk/docutils/test/functional/input/data/embed_images.txt
===================================================================
--- trunk/docutils/test/functional/input/data/embed_images.txt 2023-11-25 21:09:17 UTC (rev 9486)
+++ trunk/docutils/test/functional/input/data/embed_images.txt 2023-11-25 21:09:29 UTC (rev 9487)
@@ -1,14 +1,12 @@
-Embedded Images
+Embedded images
===============
-The "embed" flag tells Docutils that it should
-try to embed the image in the output document.
-
-If the image can be read from the local file system, it is base64_
-encoded and included as a `data URI`_.
+The image_loading_ setting can be used to tell the "html5" writer to
+embed images in the output document.
+The image is base64_ encoded and included as a `data URI`_.
In future, SVG images may be directly inserted into HTML5.
-.. figure:: ../docs/user/rst/images/biohazard.png
+.. figure:: ../../../docs/user/rst/images/biohazard.png
:alt: biohazard
:align: center
@@ -16,8 +14,10 @@
Embedded inline image |inline-embedded| scaled to a height of 0.8 em.
-.. |inline-embedded| image:: ../docs/user/rst/images/biohazard.png
+.. |inline-embedded| image:: file:../../../docs/user/rst/images/biohazard.png
:height: 0.8 em
+.. _image_loading:
+ https://docutils.sourceforge.io/docs/user/config.html#image-loading
.. _base64: https://en.wikipedia.org/wiki/Base64
.. _data URI: https://en.wikipedia.org/wiki/Data_URI_scheme
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|