Skip to content

Instantly share code, notes, and snippets.

@tadamcz
Last active October 20, 2022 20:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadamcz/869802c919c72172486f219751904108 to your computer and use it in GitHub Desktop.
Save tadamcz/869802c919c72172486f219751904108 to your computer and use it in GitHub Desktop.
Jekyll picture tag hook: automatic responsive images from pure markdown
# Jekyll plugin to replace Markdown image syntax with {% picture %} tag for crafting responsive images
# Adapted from https://gist.github.com/mmistakes/77c68fbb07731a456805a7b473f47841
# Use as a gem: https://github.com/tadamcz/jekyll-markdown-responsive-image
Jekyll::Hooks.register [:pages, :documents], :pre_render do |post, payload|
file_ext = post.extname.tr('.', '')
# This regex will match all of the following correctly:
#
# ![](image.png)
# ![Alt text](image.png)
# ![Alt text!'"@#$%^&*](image.png)
# [![Alt Text](image.png)](https://example.com)
# > [![Alt Text](image.png)](https://example.com)
image_markdown = /!\[([^()]*)\]\(([^()]+)\)/
# Only process if we deal with a markdown file
if payload['site']['markdown_ext'].include? file_ext
post.content = post.content.gsub(image_markdown) do
match = Regexp.last_match
alt_text = match[1]
src = match[2]
src_extension = File.extname(src)
# SVGs are not supported by jekyll_picture_tag
if src_extension == ".svg"
next match
end
# This allows us to specify in our markdown files
# the image path relative to the location of the markdown file.
# That's the format that GUI markdown editors expect.
src_from_root = "#{File.dirname(post.relative_path)}/#{src}"
# If alt text is empty, try to infer it from the file name
# Results may not always be desirable
if alt_text == "" and src
alt_text = File.basename(src, src_extension)
alt_text = alt_text.gsub(/[_\-]/, " ").gsub("/", "")
end
"{% picture default \"#{src_from_root}\" alt=\"#{alt_text}\" %}"
end
end
end
@YJPL
Copy link

YJPL commented Oct 14, 2022

Great—I replaced postby documentto make it work for collections.

Jekyll::Hooks.register :documents, :pre_render do |document, payload|
  file_ext = document.extname.tr('.', '')

  # This regex will match all of the following correctly:
  #
  # ![](image.png)
  # ![Alt text](image.png)
  # ![Alt text!'"@#$%^&*](image.png)
  # [![Alt Text](image.png)](https://example.com)
  # > [![Alt Text](image.png)](https://example.com)
  image_markdown = /!\[([^()]*)\]\(([^()]+)\)/

  # Only process if we deal with a markdown file
  if payload['site']['markdown_ext'].include? file_ext

    document.content = document.content.gsub(image_markdown) do
      match = Regexp.last_match
      alt_text = match[1]
      src = match[2]

      # If alt text is empty, try to infer it from the file name
      # Results may not always be desirable
      if alt_text == "" and src
        alt_text = File.basename(src, File.extname(src))
        alt_text = alt_text.gsub(/[_\-]/, " ").gsub("/", "")
      end

      "{% picture default #{src} alt=\"#{alt_text}\" %}"
    end
  end
end

See also: https://gist.github.com/YJPL/48718e28d2b2fda3476aceac018c8f26

@tadamcz
Copy link
Author

tadamcz commented Oct 15, 2022

I replaced post by document to make it work for collections.

Nice tip. Updated.

@tadamcz
Copy link
Author

tadamcz commented Oct 20, 2022

This is now available as a gem! 🎉 https://github.com/tadamcz/jekyll-markdown-responsive-image

Minus the following part:

      # If alt text is empty, try to infer it from the file name
      # Results may not always be desirable
      if alt_text == "" and src
        alt_text = File.basename(src, File.extname(src))
        alt_text = alt_text.gsub(/[_\-]/, " ").gsub("/", "")
      end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment