From 08557ce751ac35418f73fbe4650cef4ec973b1e9 Mon Sep 17 00:00:00 2001 From: Joseph Wynn Date: Tue, 27 Sep 2016 22:04:09 +0100 Subject: [PATCH] dear god what am i doing --- .travis.yml | 2 +- Gemfile | 8 ++-- Rakefile | 5 +- features/step_definitions/jekyll_steps.rb | 2 - features/support/env.rb | 4 +- features/test-site/_includes/base-url.html | 2 +- .../test-site/_includes/responsive-image.html | 2 +- lib/jekyll/responsive_image.rb | 6 +-- lib/jekyll/responsive_image/block.rb | 4 +- lib/jekyll/responsive_image/config.rb | 22 +++++++++ .../responsive_image/extra_image_generator.rb | 4 +- lib/jekyll/responsive_image/image.rb | 27 +++++++++++ .../responsive_image/image_processor.rb | 25 +++++----- lib/jekyll/responsive_image/image_resizer.rb | 47 +++++++++++++++++++ lib/jekyll/responsive_image/renderer.rb | 33 +++++-------- lib/jekyll/responsive_image/resize_handler.rb | 2 - lib/jekyll/responsive_image/tag.rb | 2 +- 17 files changed, 138 insertions(+), 59 deletions(-) create mode 100644 lib/jekyll/responsive_image/config.rb create mode 100644 lib/jekyll/responsive_image/image.rb create mode 100644 lib/jekyll/responsive_image/image_resizer.rb diff --git a/.travis.yml b/.travis.yml index 96f6e15..b7f5c2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ sudo: false language: ruby bundler_args: --without debug before_script: bundle exec jekyll --version -script: bundle exec rake features_with_coveralls +script: bundle exec rake rubocop features_with_coveralls rvm: - 2.2 - 2.1 diff --git a/Gemfile b/Gemfile index 19aa13b..3bfa90b 100644 --- a/Gemfile +++ b/Gemfile @@ -3,10 +3,10 @@ gemspec group :development do gem 'rake' - gem 'cucumber', '~> 2.1' - gem 'test-unit', '~> 3.1' - - gem 'coveralls', :require => false + gem 'cucumber', '~> 2.4' + gem 'test-unit', '~> 3.1', require: false + gem 'rubocop', '~> 0.43', require: false + gem 'coveralls', require: false platform :ruby_18, :ruby_19 do gem 'simplecov', '>= 0.10', '< 0.12' diff --git a/Rakefile b/Rakefile index 9d00a37..07ba923 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ require 'bundler' +require 'rubocop/rake_task' begin Bundler.setup(:default, :development) @@ -13,12 +14,14 @@ require 'jekyll/responsive_image/version' require 'cucumber/rake/task' require 'coveralls/rake/task' +RuboCop::RakeTask.new + Cucumber::Rake::Task.new(:features) Coveralls::RakeTask.new task :features_with_coveralls => [:features, 'coveralls:push'] -task :default => [:features] +task :default => [:rubocop, :features] task :release do |t| system "gem build jekyll-responsive_image.gemspec" diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb index 5ca4529..6612ba9 100644 --- a/features/step_definitions/jekyll_steps.rb +++ b/features/step_definitions/jekyll_steps.rb @@ -1,5 +1,3 @@ -include Test::Unit::Assertions - When /^I run Jekyll$/ do run_jekyll end diff --git a/features/support/env.rb b/features/support/env.rb index eaed1ae..d686c8e 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -3,7 +3,7 @@ if ENV['CI'] Coveralls.wear! end -require 'test/unit' +require 'test/unit/assertions' require 'jekyll/responsive_image' TEST_DIR = File.join('/', 'tmp', 'jekyll') @@ -14,3 +14,5 @@ def run_jekyll(options = {}) site = Jekyll::Site.new(options) site.process end + +World(Test::Unit::Assertions) diff --git a/features/test-site/_includes/base-url.html b/features/test-site/_includes/base-url.html index e3e6485..1fa4aed 100644 --- a/features/test-site/_includes/base-url.html +++ b/features/test-site/_includes/base-url.html @@ -1 +1 @@ - + diff --git a/features/test-site/_includes/responsive-image.html b/features/test-site/_includes/responsive-image.html index 277fb39..f2df49e 100644 --- a/features/test-site/_includes/responsive-image.html +++ b/features/test-site/_includes/responsive-image.html @@ -1 +1 @@ -{{ alt }} +{{ alt }} diff --git a/lib/jekyll/responsive_image.rb b/lib/jekyll/responsive_image.rb index 0224bcf..52a217f 100644 --- a/lib/jekyll/responsive_image.rb +++ b/lib/jekyll/responsive_image.rb @@ -5,11 +5,11 @@ require 'jekyll' require 'rmagick' require 'jekyll/responsive_image/version' -require 'jekyll/responsive_image/defaults' -require 'jekyll/responsive_image/utils' +require 'jekyll/responsive_image/config' require 'jekyll/responsive_image/render_cache' +require 'jekyll/responsive_image/image' require 'jekyll/responsive_image/image_processor' -require 'jekyll/responsive_image/resize_handler' +require 'jekyll/responsive_image/image_resizer' require 'jekyll/responsive_image/renderer' require 'jekyll/responsive_image/tag' require 'jekyll/responsive_image/block' diff --git a/lib/jekyll/responsive_image/block.rb b/lib/jekyll/responsive_image/block.rb index c5d07ad..91069f1 100644 --- a/lib/jekyll/responsive_image/block.rb +++ b/lib/jekyll/responsive_image/block.rb @@ -1,11 +1,9 @@ module Jekyll module ResponsiveImage class Block < Liquid::Block - include Jekyll::ResponsiveImage::Utils - def render(context) attributes = YAML.load(super) - Renderer.new(context.registers[:site], attributes).render_responsive_image + Renderer.new(context.registers[:site], attributes).render end end end diff --git a/lib/jekyll/responsive_image/config.rb b/lib/jekyll/responsive_image/config.rb new file mode 100644 index 0000000..72592a2 --- /dev/null +++ b/lib/jekyll/responsive_image/config.rb @@ -0,0 +1,22 @@ +module Jekyll + module ResponsiveImage + class Config + DEFAULTS = { + 'default_quality' => 85, + 'base_path' => 'assets', + 'output_path_format' => 'assets/resized/%{filename}-%{width}x%{height}.%{extension}', + 'sizes' => [], + 'extra_images' => [] + } + + def initialize(site) + @site = site + end + + def to_h + DEFAULTS.merge(@site.config['responsive_image']) + .merge(site_source: @site.source, site_dest: @site.dest) + end + end + end +end diff --git a/lib/jekyll/responsive_image/extra_image_generator.rb b/lib/jekyll/responsive_image/extra_image_generator.rb index 9a15703..550bf3f 100644 --- a/lib/jekyll/responsive_image/extra_image_generator.rb +++ b/lib/jekyll/responsive_image/extra_image_generator.rb @@ -1,11 +1,9 @@ module Jekyll module ResponsiveImage class ExtraImageGenerator < Jekyll::Generator - include Jekyll::ResponsiveImage::Utils - def generate(site) renderer = Renderer.new(site, {}) - config = renderer.make_config + config = Config.new(site).to_h config['extra_images'].each do |pathspec| Dir.glob(site.in_source_dir(pathspec)) do |image_path| diff --git a/lib/jekyll/responsive_image/image.rb b/lib/jekyll/responsive_image/image.rb new file mode 100644 index 0000000..b6e110b --- /dev/null +++ b/lib/jekyll/responsive_image/image.rb @@ -0,0 +1,27 @@ +module Jekyll + module ResponsiveImage + class Image + def initialize(width, height, config) + @width = width + @height = height + @config = config + end + + def to_h + { + 'path' => '', + 'width' => @width, + 'height' => @height, + 'basename' => '', + 'dirname' => '', + 'filename' => '', + 'extension' => '' + } + end + + def to_liquid + to_h + end + end + end +end diff --git a/lib/jekyll/responsive_image/image_processor.rb b/lib/jekyll/responsive_image/image_processor.rb index dcaaada..d59e387 100644 --- a/lib/jekyll/responsive_image/image_processor.rb +++ b/lib/jekyll/responsive_image/image_processor.rb @@ -1,22 +1,19 @@ module Jekyll module ResponsiveImage class ImageProcessor - include ResponsiveImage::Utils - - def process(absolute_image_path, relative_image_path, config) - raise SyntaxError.new("Invalid image path specified: #{absolute_image_path}") unless File.file?(absolute_image_path) - - resize_handler = ResizeHandler.new - img = Magick::Image::read(absolute_image_path).first - - { - original: image_hash(config['base_path'], relative_image_path, img.columns, img.rows), - resized: resize_handler.resize_image(img, config), - } + def self.process(path, config) + self.new.process(path, config) end - def self.process(absolute_image_path, relative_image_path, config) - self.new.process(absolute_image_path, relative_image_path, config) + def process(path, config) + raise SyntaxError.new("Invalid image path specified: #{path}") unless File.file?(path) + + image = Magick::Image::read(path).first + + { + original: Image.new, + resized: ImageResizer.resize(image, config), + } end end end diff --git a/lib/jekyll/responsive_image/image_resizer.rb b/lib/jekyll/responsive_image/image_resizer.rb new file mode 100644 index 0000000..4d46335 --- /dev/null +++ b/lib/jekyll/responsive_image/image_resizer.rb @@ -0,0 +1,47 @@ +module Jekyll + module ResponsiveImage + class ImageResizer + def self.resize(image, config) + self.new.resize(image, config) + end + + def resize(image, config) + resized = [] + + config['sizes'].each do |size| + width = size['width'] + ratio = width.to_f / image.columns.to_f + height = (image.rows.to_f * ratio).round + + next unless needs_resizing?(image, width) + + image_path = image.filename.force_encoding(Encoding::UTF_8) + output_path = image_path + + resized.push(Image.new(width, height, config)) + + # Don't resize images more than once + next if File.exist?(output_path) + + resized = image.scale(ratio) + resized.write(output_path) do |i| + i.quality = size['quality'] || config['default_quality'] + end + end + + resized + end + + def needs_resizing?(image, width) + image.columns > width + end + + def ensure_output_dir_exists!(dir) + unless Dir.exist?(dir) + Jekyll.logger.info "Creating output directory #{dir}" + FileUtils.mkdir_p(dir) + end + end + end + end +end diff --git a/lib/jekyll/responsive_image/renderer.rb b/lib/jekyll/responsive_image/renderer.rb index a03201c..b54fb9b 100644 --- a/lib/jekyll/responsive_image/renderer.rb +++ b/lib/jekyll/responsive_image/renderer.rb @@ -1,38 +1,27 @@ module Jekyll module ResponsiveImage class Renderer - include Jekyll::ResponsiveImage::Utils + attr_reader :site, :attributes def initialize(site, attributes) @site = site @attributes = attributes end - def make_config - ResponsiveImage.defaults.dup - .merge(@site.config['responsive_image']) - .merge(:site_source => @site.source, :site_dest => @site.dest) - end - - def render_responsive_image - cache_key = @attributes.to_s - result = @attributes['cache'] ? RenderCache.get(cache_key) : nil + def render + cache_key = attributes.to_s + result = attributes['cache'] ? RenderCache.get(cache_key) : nil if result.nil? - config = make_config + config = Config.new(site).to_h - absolute_image_path = @site.in_source_dir(@attributes['path'].to_s) - image = ImageProcessor.process(absolute_image_path, @attributes['path'], config) - @attributes['original'] = image[:original] - @attributes['resized'] = image[:resized] + image = ImageProcessor.process(attributes['path'], config) + template_vars = attributes.merge(site.site_payload) + .merge('original' => image[:original], 'resized' => image[:resized]) - @attributes['resized'].each { |resized| keep_resized_image!(@site, resized) } - - image_template = @site.in_source_dir(@attributes['template'] || config['template']) - partial = File.read(image_template) - template = Liquid::Template.parse(partial) - - result = template.render!(@attributes.merge(@site.site_payload)) + image_template = site.in_source_dir(attributes['template'] || config['template']) + template = Liquid::Template.parse(File.read(image_template)) + result = template.render(template_vars) RenderCache.set(cache_key, result) end diff --git a/lib/jekyll/responsive_image/resize_handler.rb b/lib/jekyll/responsive_image/resize_handler.rb index 3358b72..b896042 100644 --- a/lib/jekyll/responsive_image/resize_handler.rb +++ b/lib/jekyll/responsive_image/resize_handler.rb @@ -1,8 +1,6 @@ module Jekyll module ResponsiveImage class ResizeHandler - include ResponsiveImage::Utils - def resize_image(img, config) resized = [] diff --git a/lib/jekyll/responsive_image/tag.rb b/lib/jekyll/responsive_image/tag.rb index 6ba8147..8ae0553 100644 --- a/lib/jekyll/responsive_image/tag.rb +++ b/lib/jekyll/responsive_image/tag.rb @@ -13,7 +13,7 @@ module Jekyll end def render(context) - Renderer.new(context.registers[:site], @attributes).render_responsive_image + Renderer.new(context.registers[:site], @attributes).render end end end