SF.net SVN: docutils:[9933 ] trunk/docutils
milde--- via Docutils-checkins <[email protected]>
| Newsgroups | gmane.text.docutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
Revision: 9933
http://sourceforge.net/p/docutils/code/9933
Author: milde
Date: 2024-09-20 06:30:59 +0000 (Fri, 20 Sep 2024)
Log Message:
-----------
Revise/fix handling of length specification in the ODT writer.
Use "px" as fallback unit for unitless image size attributes.
Fix conversion factor of "pc" (pica) to "cm".
Fix conversion of image width in "%" if the height is specified.
Adjust fallback DPI value (currently not used) to match CSS units.
Document that PIL/Pillow is always required if images are inserted
without specifying width and height, also if "scale" is not used.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docs/user/odt.rst
trunk/docutils/docutils/writers/odf_odt/__init__.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2024-09-19 10:20:44 UTC (rev 9932)
+++ trunk/docutils/HISTORY.rst 2024-09-20 06:30:59 UTC (rev 9933)
@@ -181,6 +181,13 @@
- `null.Writer.translate()` sets `self.output` to the empty string.
+* docutils/writers/odf_odt/__init__.py
+
+ - Use "px" as fallback unit for unitless image size attributes.
+ - Fix conversion factor of "pc" (pica) to "cm".
+ - Fix conversion of image width in "%" if the height is specified.
+ - Adjust fallback DPI value (currently not used) to match CSS units.
+
* tools/rst2odt.py
- Use `core.publish_file()` instead of `core.publish_file_to_binary()`.
Modified: trunk/docutils/docs/user/odt.rst
===================================================================
--- trunk/docutils/docs/user/odt.rst 2024-09-19 10:20:44 UTC (rev 9932)
+++ trunk/docutils/docs/user/odt.rst 2024-09-20 06:30:59 UTC (rev 9933)
@@ -39,8 +39,8 @@
highlighting of code in literal blocks. See section `Syntax
highlighting`_.
-- Optional -- `Python Imaging Library`_ (PIL) is required if on an
- image or figure directive, you specify ``scale`` but not ``width``
+- Optional -- `Python Imaging Library`_ (PIL/Pillow_) is required if
+ you use the image or figure directive but don't specify ``width``
and ``height``. See section `Images and figures`_.
@@ -975,23 +975,21 @@
Images and figures
------------------
-If on the image or the figure directive you provide the scale option
-but do not provide the width and height options, then ``odtwriter``
-will attempt to determine the size of the image using the `Python
-Imaging Library`_ (PIL). If ``odtwriter`` cannot find and import
+The ODT Writer only supports fixed `length units`_ ("cm", "mm", "in",
+"pc", "pt", "px) for the size attributes "width", and "height".
+The fallback unit (used for attribute values without unit) is "px".
+
+If on the image or the figure directive you do not provide the width
+and height options, then ``odtwriter`` will attempt to determine the
+size of the image using the Python Imaging Library (PIL/Pillow_).
+If ``odtwriter`` cannot find and import the
Python Imaging Library, it will raise an exception. If this
ocurrs, you can fix it by doing one of the following:
- Install the Python Imaging Library or
-- Remove the ``scale`` option or
-
- Add both the ``width`` and the ``height`` options.
-So, the rule is: if on any image or figure, you specify scale but
-not both width and height, you must install the `Python Imaging
-Library`_ library.
-
For more information about PIL, see: `Python Imaging Library`_.
@@ -1188,6 +1186,8 @@
tools.html#rst2odt
.. _reStructuredText:
../ref/rst/restructuredtext.html
+.. _length units:
+ ../ref/rst/restructuredtext.html#length-units
.. _`OpenDocument Text`:
https://en.wikipedia.org/wiki/OpenDocument
.. _LibreOffice:
@@ -1196,3 +1196,4 @@
https://pygments.org/
.. _`Python Imaging Library`:
https://en.wikipedia.org/wiki/Python_Imaging_Library
+.. _`Pillow`: https://pypi.org/project/pillow/
Modified: trunk/docutils/docutils/writers/odf_odt/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/odf_odt/__init__.py 2024-09-19 10:20:44 UTC (rev 9932)
+++ trunk/docutils/docutils/writers/odf_odt/__init__.py 2024-09-20 06:30:59 UTC (rev 9933)
@@ -2207,6 +2207,7 @@
'Invalid %s for image: "%s". '
'Error: "%s".' % (
attr, node.attributes[attr], exp))
+ size, unit = 0.5, 'cm' # fallback to avoid consequential error
return size, unit
def convert_to_cm(self, size):
@@ -2223,13 +2224,15 @@
elif size.endswith('pt'):
size = float(size[:-2]) * 0.035 # convert pt to cm
elif size.endswith('pc'):
- size = float(size[:-2]) * 2.371 # convert pc to cm
+ size = float(size[:-2]) * 0.423 # convert pc to cm
elif size.endswith('mm'):
size = float(size[:-2]) * 0.1 # convert mm to cm
elif size.endswith('cm'):
size = float(size[:-2])
+ elif size[-1:] in '0123456789.': # no unit, use px
+ size = float(size) * 0.026 # convert px to cm
else:
- raise ValueError('unknown unit type')
+ raise ValueError('unit not supported with ODT')
unit = 'cm'
return size, unit
@@ -2250,8 +2253,12 @@
scale = self.get_image_scale(node)
width, width_unit = self.get_image_width_height(node, 'width')
height, _ = self.get_image_width_height(node, 'height')
- dpi = (72, 72)
- if PIL is not None and source in self.image_dict:
+ dpi = (96, 96) # image resolution in pixel per inch
+ if width is None or height is None:
+ if PIL is None:
+ raise RuntimeError(
+ 'image size not fully specified and PIL not installed')
+ # TODO: catch error and warn (similar to unsupported units).
filename, destination = self.image_dict[source]
with PIL.Image.open(filename, 'r') as img:
img_size = img.size
@@ -2261,26 +2268,19 @@
iter(dpi)
except TypeError:
dpi = (dpi, dpi)
- else:
- img_size = None
- if width is None or height is None:
- if img_size is None:
- raise RuntimeError(
- 'image size not fully specified and PIL not installed')
- if width is None:
- width = img_size[0]
- width = float(width) * 0.026 # convert px to cm
+ # TODO: use dpi when converting px to cm
+ if width is None:
+ width = img_size[0] * 0.026 # convert px to cm
+ if height is None and width_unit != '%':
+ height = img_size[1] * 0.026 # convert px to cm
+ if width_unit == '%':
+ factor = width
+ line_width = self.get_page_width()
+ width = factor * line_width
if height is None:
- height = img_size[1]
- height = float(height) * 0.026 # convert px to cm
- if width_unit == '%':
- factor = width
- image_width = img_size[0]
- image_width = float(image_width) * 0.026 # convert px to cm
- image_height = img_size[1]
- image_height = float(image_height) * 0.026 # convert px to cm
- line_width = self.get_page_width()
- width = factor * line_width
+ # scale proportionally
+ image_width = img_size[0] * 0.026 # convert px to cm
+ image_height = img_size[1] * 0.026 # convert px to cm
factor = (factor * line_width) / image_width
height = factor * image_height
width *= scale
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.