commit a09d47b60a1009096093309d34a47f99e232dd4c Author: Joseph Wynn Date: Fri Dec 5 16:26:50 2014 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b844b14 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Gemfile.lock diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1bbd9e3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: ruby +bundler_args: --without debug +script: bundle exec rake features +rvm: + - 2.1.0 + - 2.0.0 + - 1.9.3 + - rbx-2 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..a1b6884 --- /dev/null +++ b/Gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org/' +gemspec + +group :development do + gem 'rake' + gem 'cucumber', '~> 1.3' + + gem 'simplecov', '~>0.8', :require => false + gem 'rubinius-coverage', :platform => :rbx + gem 'coveralls', :require => false +end diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..3e878e7 --- /dev/null +++ b/Rakefile @@ -0,0 +1,24 @@ +require 'bundler' + +begin + Bundler.setup(:default, :development) +rescue Bundler::BundlerError => e + $stderr.puts e.message + $stderr.puts "Run `bundle install` to install missing gems" + exit e.status_code +end + +require 'rake' +require 'jekyll/responsive_image/version' +require 'cucumber/rake/task' + +Cucumber::Rake::Task.new(:features) + +task :default => [:features] + +task :release do |t| + system "gem build jekyll-responsive-image.gemspec" + system "git tag v#{Jekyll::ResponsiveImage::VERSION}" + system "git push --tags" + system "gem push jekyll-responsive-image-#{Jekyll::ResponsiveImage::VERSION}.gem" +end diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..feeb1cf --- /dev/null +++ b/_config.yml @@ -0,0 +1,2 @@ +responsive_image: + template: _includes/responsive-image.html \ No newline at end of file diff --git a/_includes/responsive-image.html b/_includes/responsive-image.html new file mode 100644 index 0000000..7111d43 --- /dev/null +++ b/_includes/responsive-image.html @@ -0,0 +1,5 @@ +{{ alt }} diff --git a/features/responsive-image.feature b/features/responsive-image.feature new file mode 100644 index 0000000..9693380 --- /dev/null +++ b/features/responsive-image.feature @@ -0,0 +1,16 @@ +Feature: Jekyll responsive-image tag + As a Jekyll template developer + I want to include responsive images in my page + In order to best cater for devices of all sizes + + Scenario: Simple image tag + Given I have a responsive_image configuration with: + """ + template: _includes/responsive-image.html + """ + And I have a file "index.html" with: + """ + {% responsive_image path: assets/test.jpg %} + """ + When I run Jekyll + Then I should see "\"\"" in "_site/index.html" diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb new file mode 100644 index 0000000..7bbdaeb --- /dev/null +++ b/features/step_definitions/jekyll_steps.rb @@ -0,0 +1,22 @@ +When /^I run Jekyll$/ do + run_jekyll +end + +Given /^I have a responsive_image configuration with:$/ do |config| + write_file('_config.yml', "responsive_image:\n#{config}") +end + +Given /^I have a file "([^\"]+)" with:$/ do |path, contents| + write_file(path, contents) +end + +Then /^I should see "(.*)" in "(.*)"$/ do |text, file| + assert_match(Regexp.new(text), File.open(file).readlines.join) +end + +def write_file(path, contents) + File.open(path, 'w') do |f| + f.write(contents) + f.close + end +end diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100644 index 0000000..0456472 --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,14 @@ +require 'test/unit' +require 'jekyll/responsive_image' + +TEST_DIR = File.join('/', 'tmp', 'jekyll') + +def run_jekyll(options = {}) + options['source'] ||= TEST_DIR + options['destination'] ||= File.join(TEST_DIR, '_site') + + options = Jekyll.configuration(options) + + site = Jekyll::Site.new(options) + site.process +end diff --git a/features/support/hooks.rb b/features/support/hooks.rb new file mode 100644 index 0000000..c2911e8 --- /dev/null +++ b/features/support/hooks.rb @@ -0,0 +1,9 @@ +Before do + FileUtils.rm_rf(TEST_DIR) if File.exist?(TEST_DIR) + FileUtils.mkdir_p(TEST_DIR) + Dir.chdir(TEST_DIR) +end + +After do + FileUtils.rm_rf(TEST_DIR) if File.exist?(TEST_DIR) +end diff --git a/index.html b/index.html new file mode 100644 index 0000000..a151ad1 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + {% responsive_image path: assets/test.jpg %} \ No newline at end of file diff --git a/jekyll-responsive-image.gemspec b/jekyll-responsive-image.gemspec new file mode 100644 index 0000000..b722172 --- /dev/null +++ b/jekyll-responsive-image.gemspec @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +lib = File.expand_path('../lib/', __FILE__) +$:.unshift lib unless $:.include?(lib) + +require 'jekyll/responsive_image/version' + +Gem::Specification.new do |spec| + spec.name = 'jekyll-responsive-image' + spec.version = Jekyll::ResponsiveImage::VERSION + spec.authors = ['Joseph Wynn'] + spec.email = ['joseph@wildlyinaccurate.com'] + spec.summary = 'Responsive images for Jekyll via srcset' + spec.homepage = 'https://github.com/wildlyinaccurate/jekyll-responsive-image' + spec.licenses = ['MIT'] + spec.description = %q{ + + } + + spec.files = `git ls-files`.split($/) + spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + spec.executables = [] + spec.require_paths = ['lib'] + + spec.add_runtime_dependency 'jekyll', '~> 2.0' + spec.add_runtime_dependency 'rmagick' +end diff --git a/lib/jekyll/responsive_image.rb b/lib/jekyll/responsive_image.rb new file mode 100644 index 0000000..18c7a58 --- /dev/null +++ b/lib/jekyll/responsive_image.rb @@ -0,0 +1,96 @@ +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(path, config) + output_dir = config['output_dir'] + ensure_output_dir_exists!(output_dir) + + resized = [] + img = Magick::Image::read(path).first + + 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(path, width, height) + newpath = "#{output_dir}/#{filename}" + + next unless needs_resizing?(img, width) + + resized.push({ + 'width' => width, + 'height' => height, + 'path' => newpath, + }) + + # Don't resize images more than once + next if File.exists?(newpath) + + Jekyll.logger.info "Generating #{newpath}" + + i = img.scale(ratio) + i.write(newpath) 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 + + def render(context) + config = context.registers[:site].config['responsive_image'] + config['output_dir'] ||= 'assets/resized' + config['sizes'] ||= [] + + @attributes['resized'] = resize_image(@attributes['path'], config) + + partial = File.read(config['template']) + template = Liquid::Template.parse(partial) + + template.render!(@attributes) + end + end + end +end + +Liquid::Template.register_tag('responsive_image', Jekyll::ResponsiveImage::Tag) diff --git a/lib/jekyll/responsive_image/version.rb b/lib/jekyll/responsive_image/version.rb new file mode 100644 index 0000000..95e9358 --- /dev/null +++ b/lib/jekyll/responsive_image/version.rb @@ -0,0 +1,5 @@ +module Jekyll + class ResponsiveImage + VERSION = '0.9.0'.freeze + end +end diff --git a/test-index.html b/test-index.html new file mode 100644 index 0000000..a151ad1 --- /dev/null +++ b/test-index.html @@ -0,0 +1 @@ + {% responsive_image path: assets/test.jpg %} \ No newline at end of file