diff --git a/lib/jekyll/responsive_image.rb b/lib/jekyll/responsive_image.rb index 272b809..d5bb0eb 100644 --- a/lib/jekyll/responsive_image.rb +++ b/lib/jekyll/responsive_image.rb @@ -1,103 +1,8 @@ require 'jekyll' require 'rmagick' -module Jekyll - class ResponsiveImage - class Tag < Liquid::Tag - DEFAULT_QUALITY = 85 - - def initialize(tag_name, markup, tokens) - super - - @attributes = {} - @markup = markup - - @markup.scan(::Liquid::TagAttributes) do |key, value| - # Strip quotes from around attribute values - @attributes[key] = value.gsub(/^['"]|['"]$/, '') - end - end - - def resize_image(img, config) - output_dir = config['output_dir'] - ensure_output_dir_exists!(output_dir) - - resized = [] - - config['sizes'].each do |size| - width = size['width'] - ratio = width.to_f / img.columns.to_f - height = (img.rows.to_f * ratio).round - - filename = resized_filename(img.filename, width, height) - filepath = "#{output_dir}/#{filename}" - - next unless needs_resizing?(img, width) - - resized.push(image_hash(filepath, width, height)) - - # Don't resize images more than once - next if File.exists?(filepath) - - Jekyll.logger.info "Generating #{filepath}" - - i = img.scale(ratio) - i.write(filepath) do |f| - f.quality = size['quality'] || DEFAULT_QUALITY - end - - i.destroy! - end - - resized - end - - # Insert resize information into a file path - # - # resized_filename(/foo/bar/file.name.jpg, 500, 300) - # => /foo/bar/file.name-500x300.jpg - # - def resized_filename(path, width, height) - File.basename(path).sub(/\.([^.]+)$/, "-#{width}x#{height}.\\1") - end - - def needs_resizing?(img, width) - img.columns > width - end - - def ensure_output_dir_exists!(dir) - unless Dir.exists?(dir) - Jekyll.logger.info "Creating output directory #{dir}" - Dir.mkdir(dir) - end - end - - # Build a hash containing image information - def image_hash(path, width, height) - { - 'path' => path, - 'width' => width, - 'height' => height, - } - end - - def render(context) - config = context.registers[:site].config['responsive_image'] - config['output_dir'] ||= 'assets/resized' - config['sizes'] ||= [] - - img = Magick::Image::read(@attributes['path']).first - @attributes['original'] = image_hash(@attributes['path'], img.columns, img.rows) - @attributes['resized'] = resize_image(img, config) - @attributes['template'] ||= config['template'] - - partial = File.read(@attributes['template']) - template = Liquid::Template.parse(partial) - - template.render!(@attributes) - end - end - end -end +require 'jekyll/responsive_image/version' +require 'jekyll/responsive_image/defaults' +require 'jekyll/responsive_image/tag' Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag) diff --git a/lib/jekyll/responsive_image/defaults.rb b/lib/jekyll/responsive_image/defaults.rb new file mode 100644 index 0000000..94464f7 --- /dev/null +++ b/lib/jekyll/responsive_image/defaults.rb @@ -0,0 +1,13 @@ +module Jekyll + class ResponsiveImage + @defaults = { + 'default_quality' => 85, + 'output_dir' => 'assets/resized', + 'sizes' => [], + }.freeze + + class << self + attr_reader :defaults + end + end +end diff --git a/lib/jekyll/responsive_image/tag.rb b/lib/jekyll/responsive_image/tag.rb new file mode 100644 index 0000000..0d2cfd8 --- /dev/null +++ b/lib/jekyll/responsive_image/tag.rb @@ -0,0 +1,95 @@ +module Jekyll + class ResponsiveImage + class Tag < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + + @attributes = {} + @markup = markup + + @markup.scan(::Liquid::TagAttributes) do |key, value| + # Strip quotes from around attribute values + @attributes[key] = value.gsub(/^['"]|['"]$/, '') + end + end + + def resize_image(img, config) + output_dir = config['output_dir'] + ensure_output_dir_exists!(output_dir) + + resized = [] + + config['sizes'].each do |size| + width = size['width'] + ratio = width.to_f / img.columns.to_f + height = (img.rows.to_f * ratio).round + + filename = resized_filename(img.filename, width, height) + filepath = "#{output_dir}/#{filename}" + + next unless needs_resizing?(img, width) + + resized.push(image_hash(filepath, width, height)) + + # Don't resize images more than once + next if File.exists?(filepath) + + Jekyll.logger.info "Generating #{filepath}" + + i = img.scale(ratio) + i.write(filepath) do |f| + f.quality = size['quality'] || config['default_quality'] + end + + i.destroy! + end + + resized + end + + # Insert resize information into a file path + # + # resized_filename(/foo/bar/file.name.jpg, 500, 300) + # => /foo/bar/file.name-500x300.jpg + # + def resized_filename(path, width, height) + File.basename(path).sub(/\.([^.]+)$/, "-#{width}x#{height}.\\1") + end + + def needs_resizing?(img, width) + img.columns > width + end + + def ensure_output_dir_exists!(dir) + unless Dir.exists?(dir) + Jekyll.logger.info "Creating output directory #{dir}" + Dir.mkdir(dir) + end + end + + # Build a hash containing image information + def image_hash(path, width, height) + { + 'path' => path, + 'width' => width, + 'height' => height, + } + end + + def render(context) + config = ResponsiveImage.defaults.dup + config.merge!(context.registers[:site].config['responsive_image']) + + img = Magick::Image::read(@attributes['path']).first + @attributes['original'] = image_hash(@attributes['path'], img.columns, img.rows) + @attributes['resized'] = resize_image(img, config) + @attributes['template'] ||= config['template'] + + partial = File.read(@attributes['template']) + template = Liquid::Template.parse(partial) + + template.render!(@attributes) + end + end + end +end