Commit 0cf8d45e authored by Jan-Philipp Stauffert's avatar Jan-Philipp Stauffert
Browse files

Init plugin

parents
# frozen_string_literal: true
source "https://rubygems.org"
gemspec
Gem::Specification.new do |spec|
spec.name = "jekyll-img-srcset"
spec.version = "0.1.0"
spec.authors = ["Jan-Philipp Stauffert"]
spec.email = ["jan-philipp.stauffert@uni-wuerzburg.de"]
spec.summary = "Resizes images and puts all sizes into a srcset."
spec.homepage = "https://hci.uni-wuerzburg.de"
spec.license = "Apache-2.0"
spec.files = ['lib/jekyll-img-srcset.rb']
spec_require_paths = ['lib']
spec.add_runtime_dependency "jekyll", "~> 4.0"
spec.add_runtime_dependency "mini_magick"
spec.add_development_dependency "bundler", "~> 1.16"
spec.add_development_dependency "rake", "~> 12.0"
end
\ No newline at end of file
require 'mini_magick'
def resize_image(url, widths, dest, base_image_path)
image = MiniMagick::Image.open(File.join(base_image_path, url))
w = image.dimensions[0]
aspect = image.dimensions[1] / w
new_widths = widths.select {|x| x <= w}
new_widths.map do |width|
[width, File.join(dest, base_image_path, "#{width}", url)]
end.select do |width, target|
not File.exists? target
end.each do |width, target|
image = MiniMagick::Image.open(File.join(base_image_path, url))
image.resize "#{width}x#{width*aspect}"
if not Dir.exists? File.dirname(target)
FileUtils.mkdir_p File.dirname(target)
end
image.write target
end
return new_widths, w
end
def parse_identifier(ident)
i = {
classes: [],
sizes: "(min-width: 1180px) 1024px, (min-width: 980px) 844px, (min-width: 740px) 604, 100vw"
}
if ident.nil?
return i
end
ident.scan(/#[^\s\}]+|\.[^\s\}]+|[^\s\}]+="[^"]+"/) do | match |
if match.start_with? "#"
match[0] = ''
i[:id] = match
elsif match.start_with? "."
match[0] = ''
i[:classes] << match
else
parts = match.split '='
i[parts[0].to_sym] = parts[1].gsub(/^"/, '').gsub(/"$/, '')
end
end
return i
end
def format_image(ident, sizes, original_width, url, caption, title, baseurl, base_image_path)
srcset = sizes.map {|s| "#{baseurl}/#{base_image_path}/#{s}/#{url} #{s}w"}
srcset << "#{baseurl}/#{base_image_path}/#{url} #{original_width}w"
srcset = srcset.join ", "
classes = "image #{ident[:dimension]} #{ident[:classes].join " "}"
content = "<div class=\"#{classes}\""
if not ident['style'].nil?
content += " style=\"#{ident[:style]}\""
end
content += ">"
content += "<div>"
if not caption.nil? and caption != ""
content += "<figure>
<img
src = \"#{baseurl}/#{base_image_path}/#{sizes[0]}/#{url}\"
alt = \"#{title}\"
sizes = \"#{ident[:sizes]}\"
srcset = \"#{srcset}\"
/>
<figcaption>#{caption}</figcaption>
</figure>"
else
content += "<img
src = \"#{baseurl}/#{base_image_path}/#{sizes[0]}/#{url}\"
alt = \"#{title}\"
sizes = \"#{sizes}\"
srcset = \"#{srcset}\"
/>"
end
content += "</div>"
content += "</div>"
return content
end
def format_svg_image(url, ident, title, baseurl, base_image_path)
content = "<img "
if not ident['style'].nil?
content += "style=\"#{ident[:style]}\" "
end
if not ident["classes"].empty?
content += "class=\"#{ident[:classes].join " "}\" "
end
content += "src = \"#{baseurl}/#{base_image_path}/#{url}\" "
content += "alt = \"#{title}\""
content += "/>"
end
def process_page(document, payload)
# see https://gist.github.com/mmistakes/77c68fbb07731a456805a7b473f47841
doc_ext = document.extname.tr('.', '')
if payload['site']['markdown_ext'].include? doc_ext
content = document.content
base_image_path = document.site.config["base_image_path"] || "assets/images"
image_regex = /!\[(?<caption>.*?)?\]\((?<url>\S+?)(?<title> .+?)?\)(?<identifier>\{.+?\})?/
content = content.gsub(image_regex) do | img |
img = image_regex.match img
if (/\.(jpe?g|png)$/i =~ img["url"]).nil?
"#{base_image_path}/#{img[0]}"
elsif img["url"].start_with? "http"
img[0]
elsif img["url"].end_with? ".svg"
ident = parse_identifier img[:identifier]
format_svg_image(img["url"], ident, img["title"],
document.site.baseurl)
else
if File.exists?(File.join base_image_path, img['url'])
widths, original_width = resize_image(img['url'],
document.site.config["widths"],
document.site.config["destination"],
base_image_path)
document.site.keep_files.concat(widths.map do |w|
File.join(base_image_path, "#{w}", img['url'])
end)
ident = parse_identifier img[:identifier]
format_image(ident, widths, original_width,
img["url"], img["caption"], img["title"],
document.site.baseurl, base_image_path)
else
img[0]
end
end
end
# puts content
document.content = content
end
end
Jekyll::Hooks.register [:pages, :posts, :documents], :pre_render do |document, payload|
process_page(document, payload)
end
# Jekyll::Hooks.register [:pages, :posts, :documents], :post_render do |document, payload|
# # puts "Post"
# # puts document
# process_page(document, payload)
# end
module Jekyll
class ImgSrcsetTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
@text = text
end
def render(context)
config = context.registers[:site].config
base_image_path = config["base_image_path"] || "assets/images"
attr_regex = /(\S+)="([^"]+?)"/
attrs = {
classes: [],
}
@text.scan(attr_regex) do | key, value |
if key == "class"
attrs[:classes] << value
else
attrs[key.to_sym] = value
end
end
if context.key? attrs[:src]
attrs[:src] = context[attrs[:src]]
end
if File.exists?(File.join base_image_path, attrs[:src])
widths, original_width = resize_image(
attrs[:src],
config["widths"],
config["destination"], base_image_path)
context.registers[:site].keep_files.concat(widths.map do |w|
File.join(base_image_path, "#{w}", attrs[:src])
end)
format_image(attrs, widths, original_width,
attrs[:src], attrs[:caption], attrs[:title],
context.registers[:site].baseurl, base_image_path)
else
puts "image not found: #{attrs[:src]}"
""
end
end
end
end
Liquid::Template.register_tag('imgsrcset', Jekyll::ImgSrcsetTag)
# /![(?<caption>.*?)?]\((?<url>[^\s]+?)(?<title> .+?)?\)(?<identifier>{.+?})?/
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment