Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Let's say you have defined the transformation described above. To get your
image processed, it needs to have the right CSS class:

```html
<img class="image-process-article-image" src="/images/pelican.jpg"/>
<img class="image-process-article-image" src="/images/pelican.jpg" />
```

This can be produced in Markdown with:
Expand Down Expand Up @@ -123,7 +123,6 @@ the `figure` directive:
> dashes (`-`) in class names. To make sure everything runs
> smoothly, do not use underscores in your transformation names.


#### Responsive Images

You can use *Image Process* to automatically generate a set of
Expand Down Expand Up @@ -180,7 +179,7 @@ image from the original image (the original image is the value of the
`src` attribute of the `<img>`). Image descriptions are hints
about the resolution of the associated image and must have the suffix
`x`. The `default` setting specifies the image to use to replace the `src`
attribute of the image. This is the image that will be displayed by
attribute of the image. This is the image that will be displayed by
browsers that do not support the `srcset` syntax.

The `large-photo` transformation is an example of a transformation
Expand All @@ -194,7 +193,7 @@ the original image (the original image is the value of the `src`
attribute of the `<img>`). Image descriptions are hints about the
width in pixels of the associated image and must have the suffix
`w`. The `default` setting specifies the image to use to replace the `src`
attribute of the image. This is the image that will be displayed by
attribute of the image. This is the image that will be displayed by
browsers that do not support the `srcset` syntax.

In the two examples above, the `default` setting is a string referring to
Expand All @@ -210,7 +209,7 @@ image replacement case, described above.
So, in HTML it should look like this:

```html
<img class="image-process-large-photo" src="/images/pelican.jpg"/>
<img class="image-process-large-photo" src="/images/pelican.jpg" />
```

Which can be produced in Markdown with:
Expand Down Expand Up @@ -278,7 +277,7 @@ will be used to find the URL of the original image for this source in
your article. The source may also have a `media`, which contains a
rule used by the browser to select the active source. The `default`
setting specifies the image to use to replace the `src` attribute of
the `<img>` inside the `<picture>`. This is the image that will be
the `<img>` inside the `<picture>`. This is the image that will be
displayed by browsers that do not support the `<picture>` syntax. In
this example, it will use the image `640w` from the source `default`.
A list of operations could have been specified instead of `640w`.
Expand Down Expand Up @@ -481,7 +480,7 @@ IMAGE_PROCESS_ENCODING = "utf-8"

#### Copying EXIF Tags

You may ask _Image Process_ to copy the EXIF tags from your original image to
You may ask *Image Process* to copy the EXIF tags from your original image to
the transformed images. You must have [exiftool](https://exiftool.org/) installed.

```python
Expand All @@ -491,6 +490,30 @@ IMAGE_PROCESS_COPY_EXIF_TAGS = True
Note that `exiftool` prior to version 12.46 cannot write WebP images, so if you work
with WebP images, you should use version 12.46 or later.

#### Modifying the `class` Attribute of Processed Images

By default, *Image Process* adds the `image-process-<transform>`
CSS class to transformed images. This behavior is controlled by the
`IMAGE_PROCESS_ADD_CLASS` setting (default: `True`) and the
`IMAGE_PROCESS_CLASS_PREFIX` setting (default: `"image-process-"`).

* If `IMAGE_PROCESS_ADD_CLASS` is `True`, the `<transform>` name is added
to the `class` attribute of the image.
You can customize the class prefix using `IMAGE_PROCESS_CLASS_PREFIX`.

* If `IMAGE_PROCESS_ADD_CLASS` is `False`, no class attribute will be added.

This setting allows you to control whether transformation details appear
in the HTML output or to avoid conflicts with custom styles.

```python
# Use a custom class prefix instead of "image-process-"
IMAGE_PROCESS_CLASS_PREFIX = "custom-prefix-"

# Disable adding transformation class attributes
IMAGE_PROCESS_ADD_CLASS = False
```

## Known Issues

* Pillow, when resizing animated GIF files, [does not return an animated file](https://github.com/pelican-plugins/image-process/issues/11).
Expand Down Expand Up @@ -521,6 +544,5 @@ This project is licensed under the [AGPL-3.0 license](http://www.gnu.org/license

[Pelican image](https://web.archive.org/web/20090505115626/http://www.pdphoto.org/PictureDetail.php?mat=&pg=5726) in test data by Jon Sullivan. Published under a [Creative Commons Public Domain license](https://creativecommons.org/licenses/publicdomain/).


[HTML5 responsive images]: https://www.smashingmagazine.com/2014/05/14/responsive-images-done-right-guide-picture-srcset/
[BeautifulSoup documentation on parsers]: https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser
15 changes: 15 additions & 0 deletions pelican/plugins/image_process/image_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,21 @@ def harvest_images_in_fragment(fragment, settings):
for c in img["class"]:
if c.startswith("image-process-"):
derivative = c[14:]

# Determine whether to modify the class attribute.
add_class = settings.get("IMAGE_PROCESS_ADD_CLASS", True)
if not add_class:
# Remove class if it's the only one, otherwise remove specific entry
img["class"].remove(c)
if len(img["class"]) == 0:
del img["class"]
else:
class_prefix = settings.get(
"IMAGE_PROCESS_CLASS_PREFIX", "image-process-"
)
if class_prefix != "image-process-":
img["class"].remove(c)
img["class"].append(f"{class_prefix}{derivative}")
break
else:
continue
Expand Down
54 changes: 54 additions & 0 deletions pelican/plugins/image_process/test_image_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,60 @@ def test_try_open_image():
assert not try_open_image(path.source)


@pytest.mark.parametrize(
"orig_tag, new_tag, setting_overrides",
[
(
'<img class="image-process-crop" src="/tmp/test.jpg" />',
'<img class="image-process-crop" src="/tmp/derivatives/crop/test.jpg"/>',
[ # Default settings.
{},
{"IMAGE_PROCESS_ADD_CLASS": True},
{"IMAGE_PROCESS_CLASS_PREFIX": "image-process-"},
{
"IMAGE_PROCESS_ADD_CLASS": True,
"IMAGE_PROCESS_CLASS_PREFIX": "image-process-",
},
],
),
(
'<img class="image-process-crop" src="/tmp/test.jpg" />',
'<img class="custom-prefix-crop" src="/tmp/derivatives/crop/test.jpg"/>',
[ # Custom class prefix.
{"IMAGE_PROCESS_CLASS_PREFIX": "custom-prefix-"},
{
"IMAGE_PROCESS_ADD_CLASS": True,
"IMAGE_PROCESS_CLASS_PREFIX": "custom-prefix-",
},
],
),
(
'<img class="image-process-crop" src="/tmp/test.jpg" />',
'<img class="crop" src="/tmp/derivatives/crop/test.jpg"/>',
[ # Special case: empty string as class prefix.
{"IMAGE_PROCESS_CLASS_PREFIX": ""},
],
),
(
'<img class="image-process-crop" src="/tmp/test.jpg" />',
'<img src="/tmp/derivatives/crop/test.jpg"/>',
[ # No class added.
{"IMAGE_PROCESS_ADD_CLASS": False},
{"IMAGE_PROCESS_ADD_CLASS": False, "IMAGE_PROCESS_CLASS_PREFIX": ""},
],
),
],
)
def test_class_settings(mocker, orig_tag, new_tag, setting_overrides):
"""Test the IMAGE_PROCESS_ADD_CLASS and IMAGE_PROCESS_CLASS_PREFIX settings."""
# Silence image transforms.
mocker.patch("pelican.plugins.image_process.image_process.process_image")

for override in setting_overrides:
settings = get_settings(**override)
assert harvest_images_in_fragment(orig_tag, settings) == new_tag


def generate_test_images():
settings = get_settings()
image_count = 0
Expand Down