Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plugin: ImageThumblinksPlugin #259

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
106 changes: 106 additions & 0 deletions hyde/ext/plugins/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,112 @@ def begin_site(self):
if match_includes(resource.path):
self.thumb(resource, dim1, dim2, prefix, crop_type, preserve_orientation)


class ImageThumblinksPlugin(PILPlugin):
"""
Generate thumbnailed links to full size images on-the-fly within documents.

Markup constructions like

[[!thumblink|{alt text}|{w?}x{h?}|{media path}]]

are parsed, where

w is wanted thumbnail width
h is wanted thumbnail height

according to the definitions in ImageThumbnailsPlugin.thumb(). Those
constructions are then replaced by

[![alt text.]([[!!{thumbnail path}]])]([[!!{media path]]])

which in turn are parsed by `TextlinksPlugin`, which needs to be loaded
_after_ `ImageThumblinksPlugin` in `site.yaml`, to yield a thumbnail image
that is linked to the full size image.

Example:

[[!thumblink|My dog.|x300|images/img_0001.jpg]]

is transformed to

[![My dog.]([[!!images/x300-img_0001.jpg]])]([[!!images/img_0001.jpg]])

which generates a thumbnail link, width 300 px, to the full size image.
"""

# Pattern matcher for `!thumblink` syntax.
thumbnail_link = re.compile(r'''
\[\[ # [[
\!thumblink\| # [[!thumblink|
([^|]*)\| # My dog.|
(\d*)x(\d*)\| # x300|
([^\]]*) # img_0001.jpg
\]\] # ]]
''', re.VERBOSE)

def __init__(self, site):
"""Initialize plugin."""
super(ImageThumblinksPlugin, self).__init__(site)

def begin_text_resource(self, resource, text):
if not resource.uses_template:
# If the resource is not to be templated, do nothing.
return text

def replace_content(match):
"""
Parse thumbnail links, generate thumbnail image and return markup
for generating a thumbnailed link to the fullsized image.
"""
self.logger.debug('!thumblink instance found, processing')
alt, width, height, fullsize_deploy_path = match.groups(1)

prefix = '{}x{}-'.format(width, height)
# `scale_aspect` (called within `ImageThumblinksPlugin.thumb()`)
# chokes on string type width or height. This should preferably be
# checked within that function in a future rewrite.
width = int(width) if width else None
height = int(height) if height else None
# Reasonable defaults. It would be possible to expand the argument
# handling of !thumblink to incorporate custom values, but I do not
# see a real use case.
crop_type = 'center'
preserve_orientation = False

relative_image_path = os.path.join(self.site.config.media_root,
fullsize_deploy_path)

image_resource = self.site.content.\
resource_from_relative_deploy_path(relative_image_path)
# Generate thumbnail if it does not exist, based on the naming
# scheme.
thumbnail_plugin = ImageThumbnailsPlugin(self.site)
thumbnail_plugin.thumb(image_resource, width, height, prefix,
crop_type, preserve_orientation)

thumb_deploy_path = self.thumbnail_deploy_path_from_fullsize(
fullsize_deploy_path, prefix)

# This needs to be interpreted by TextlinksPlugin afterwards, which
# transforms deploy paths correctly.
return '[![{}]([[!!{}]])]([[!!{}]])'.format(alt, thumb_deploy_path,
fullsize_deploy_path)

# `replace_content` is a callback function handle that is executed on
# the match object which is only generated by matching rows.
return self.thumbnail_link.sub(replace_content, text)

@staticmethod
def thumbnail_deploy_path_from_fullsize(fullsize_path, prefix):
"""
Generate thumbnail link path by splicing the prefix into the file name
of the fullsize image link.
"""
dir_path, fullsize_filename = os.path.split(fullsize_path)
return os.path.join(dir_path, '{}{}'.format(prefix, fullsize_filename))


#
# JPEG Optimization
#
Expand Down