1
0
mirror of https://github.com/danbee/danbarber.me synced 2025-03-04 08:59:10 +00:00

Update picture tag

This commit is contained in:
Daniel Barber 2017-08-15 23:11:42 -04:00
parent 9925ba1df5
commit ba8d038d91
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
3 changed files with 60 additions and 41 deletions

View File

@ -2,6 +2,7 @@ source 'https://rubygems.org'
gem 'rake' gem 'rake'
gem 'fastimage'
gem 'mini_magick' gem 'mini_magick'
gem 'jekyll' gem 'jekyll'

View File

@ -85,6 +85,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bourbon bourbon
facets facets
fastimage
jekyll jekyll
jekyll-archives jekyll-archives
jekyll-assets jekyll-assets

View File

@ -20,6 +20,7 @@ require 'fileutils'
require 'pathname' require 'pathname'
require 'digest/md5' require 'digest/md5'
require 'mini_magick' require 'mini_magick'
require 'fastimage'
module Jekyll module Jekyll
@ -38,6 +39,7 @@ module Jekyll
# Gather settings # Gather settings
site = context.registers[:site] site = context.registers[:site]
settings = site.config['picture'] settings = site.config['picture']
url = site.config['url']
markup = /^(?:(?<preset>[^\s.:\/]+)\s+)?(?<image_src>[^\s]+\.[a-zA-Z0-9]{3,4})\s*(?<source_src>(?:(source_[^\s.:\/]+:\s+[^\s]+\.[a-zA-Z0-9]{3,4})\s*)+)?(?<html_attr>[\s\S]+)?$/.match(render_markup) markup = /^(?:(?<preset>[^\s.:\/]+)\s+)?(?<image_src>[^\s]+\.[a-zA-Z0-9]{3,4})\s*(?<source_src>(?:(source_[^\s.:\/]+:\s+[^\s]+\.[a-zA-Z0-9]{3,4})\s*)+)?(?<html_attr>[\s\S]+)?$/.match(render_markup)
preset = settings['presets'][ markup[:preset] ] || settings['presets']['default'] preset = settings['presets'][ markup[:preset] ] || settings['presets']['default']
@ -56,17 +58,17 @@ module Jekyll
# Process alternate source images # Process alternate source images
source_src = if markup[:source_src] source_src = if markup[:source_src]
Hash[ *markup[:source_src].gsub(/:/, '').split ] Hash[ *markup[:source_src].gsub(/:/, '').split ]
else else
{} {}
end end
# Process html attributes # Process html attributes
html_attr = if markup[:html_attr] html_attr = if markup[:html_attr]
Hash[ *markup[:html_attr].scan(/(?<attr>[^\s="]+)(?:="(?<value>[^"]+)")?\s?/).flatten ] Hash[ *markup[:html_attr].scan(/(?<attr>[^\s="]+)(?:="(?<value>[^"]+)")?\s?/).flatten ]
else else
{} {}
end end
if instance['attr'] if instance['attr']
html_attr = instance.delete('attr').merge(html_attr) html_attr = instance.delete('attr').merge(html_attr)
@ -122,14 +124,14 @@ module Jekyll
ppi_key = "#{key}-x#{p}" ppi_key = "#{key}-x#{p}"
ppi_sources[ppi_key] = { ppi_sources[ppi_key] = {
:width => if source[:width] then (source[:width].to_f * p).round else nil end, :width => if source[:width] then (source[:width].to_f * p).round else nil end,
:height => if source[:height] then (source[:height].to_f * p).round else nil end, :height => if source[:height] then (source[:height].to_f * p).round else nil end,
'media' => if source['media'] 'media' => if source['media']
"#{source['media']} and (-webkit-min-device-pixel-ratio: #{p}), #{source['media']} and (min-resolution: #{(p * 96).round}dpi)" "#{source['media']} and (-webkit-min-device-pixel-ratio: #{p}), #{source['media']} and (min-resolution: #{(p * 96).round}dpi)"
else else
"(-webkit-min-device-pixel-ratio: #{p}), (min-resolution: #{(p * 96).to_i}dpi)" "(-webkit-min-device-pixel-ratio: #{p}), (min-resolution: #{(p * 96).to_i}dpi)"
end, end,
:src => source[:src] :src => source[:src]
} }
# Add ppi_key to the source keys order # Add ppi_key to the source keys order
@ -137,7 +139,7 @@ module Jekyll
end end
} }
} }
instance.merge!(ppi_sources) instance.merge!(ppi_sources)
end end
# Generate resized images # Generate resized images
@ -149,52 +151,66 @@ module Jekyll
if settings['markup'] == 'picture' if settings['markup'] == 'picture'
source_tags = '' source_tags = ''
source_keys.each { |source| source_keys.each do |source|
media = " media=\"#{instance[source]['media']}\"" unless source == 'source_default' media = " media=\"#{instance[source]['media']}\"" unless source == 'source_default'
source_tags += "#{markdown_escape * 4}<source srcset=\"#{instance[source][:generated_src]}\"#{media}>\n" source_tags += "#{markdown_escape * 4}<source srcset=\"#{url}#{instance[source][:generated_src]}\"#{media}>\n"
} end
# Note: we can't indent html output because markdown parsers will turn 4 spaces into code blocks # Note: we can't indent html output because markdown parsers will turn 4 spaces into code blocks
# Note: Added backslash+space escapes to bypass markdown parsing of indented code below -WD # Note: Added backslash+space escapes to bypass markdown parsing of indented code below -WD
picture_tag = "<picture>\n"\ picture_tag = "<picture>\n"\
"#{source_tags}"\ "#{source_tags}"\
"#{markdown_escape * 4}<img srcset=\"#{instance['source_default'][:generated_src]}\" #{html_attr_string}>\n"\ "#{markdown_escape * 4}<img src=\"#{url}#{instance['source_default'][:generated_src]}\" #{html_attr_string}>\n"\
"#{markdown_escape * 2}</picture>\n" "#{markdown_escape * 2}</picture>\n"
elsif settings['markup'] == 'interchange'
interchange_data = Array.new
source_keys.reverse.each do |source|
interchange_data << "[#{url}#{instance[source][:generated_src]}, #{source == 'source_default' ? '(default)' : instance[source]['media']}]"
end
picture_tag = %Q{<img data-interchange="#{interchange_data.join ', '}" #{html_attr_string} />\n}
picture_tag += %Q{<noscript><img src="#{url}#{instance['source_default'][:generated_src]}" #{html_attr_string} /></noscript>}
elsif settings['markup'] == 'img' elsif settings['markup'] == 'img'
# TODO implement <img srcset/sizes> # TODO implement <img srcset/sizes>
end end
# Return the markup! # Return the markup!
picture_tag picture_tag
end end
def generate_image(instance, site_source, site_dest, image_source, image_dest, baseurl) def generate_image(instance, site_source, site_dest, image_source, image_dest, baseurl)
image = MiniMagick::Image.open(File.join(site_source, image_source, instance[:src])) begin
digest = Digest::MD5.hexdigest(image.to_blob).slice!(0..5) digest = Digest::MD5.hexdigest(File.read(File.join(site_source, image_source, instance[:src]))).slice!(0..5)
rescue Errno::ENOENT
warn "Warning:".yellow + " source image #{instance[:src]} is missing."
return ""
end
image_dir = File.dirname(instance[:src]) image_dir = File.dirname(instance[:src])
ext = File.extname(instance[:src]) ext = File.extname(instance[:src])
basename = File.basename(instance[:src], ext) basename = File.basename(instance[:src], ext)
orig_width = image[:width].to_f size = FastImage.size(File.join(site_source, image_source, instance[:src]))
orig_height = image[:height].to_f orig_width = size[0]
orig_ratio = orig_width/orig_height orig_height = size[1]
orig_ratio = orig_width*1.0/orig_height
gen_width = if instance[:width] gen_width = if instance[:width]
instance[:width].to_f instance[:width].to_f
elsif instance[:height] elsif instance[:height]
orig_ratio * instance[:height].to_f orig_ratio * instance[:height].to_f
else else
orig_width orig_width
end end
gen_height = if instance[:height] gen_height = if instance[:height]
instance[:height].to_f instance[:height].to_f
elsif instance[:width] elsif instance[:width]
instance[:width].to_f / orig_ratio instance[:width].to_f / orig_ratio
else else
orig_height orig_height
end end
gen_ratio = gen_width/gen_height gen_ratio = gen_width/gen_height
# Don't allow upscaling. If the image is smaller than the requested dimensions, recalculate. # Don't allow upscaling. If the image is smaller than the requested dimensions, recalculate.
@ -219,6 +235,7 @@ module Jekyll
# Let people know their images are being generated # Let people know their images are being generated
puts "Generating #{gen_name}" puts "Generating #{gen_name}"
image = MiniMagick::Image.open(File.join(site_source, image_source, instance[:src]))
# Scale and crop # Scale and crop
image.combine_options do |i| image.combine_options do |i|
i.resize "#{gen_width}x#{gen_height}^" i.resize "#{gen_width}x#{gen_height}^"
@ -226,7 +243,7 @@ module Jekyll
i.crop "#{gen_width}x#{gen_height}+0+0" i.crop "#{gen_width}x#{gen_height}+0+0"
end end
image.quality 85 image.quality 75
image.write gen_dest_file image.write gen_dest_file
end end