diff --git a/features/image-generation.feature b/features/image-generation.feature
index 4fbfb51..c9d511f 100644
--- a/features/image-generation.feature
+++ b/features/image-generation.feature
@@ -39,16 +39,18 @@ Feature: Responsive image generation
And the file "_site/assets/resized/subdir/test-100.png" should exist
Scenario: Honouring Jekyll 'source' configuration
- Given I have copied my site to "sub-dir/my-site-copy"
+ Given I have copied my site to "my-site-copy/src"
And I have a configuration with:
"""
- source: sub-dir/my-site-copy
+ source: my-site-copy/src
responsive_image:
+ base_path: assets
template: _includes/responsive-image.html
+ output_path_format: assets/resized/%{dirname}/%{width}/%{basename}
sizes:
- width: 100
"""
- And I have a file "sub-dir/my-site-copy/index.html" with "{% responsive_image path: assets/everybody-loves-jalapeño-pineapple-cornbread.png %}"
+ And I have a file "my-site-copy/src/index.html" with "{% responsive_image path: assets/subdir/test.png %}"
When I run Jekyll
- Then the image "sub-dir/my-site-copy/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should have the dimensions "100x50"
- And the file "_site/assets/resized/everybody-loves-jalapeño-pineapple-cornbread-100x50.png" should exist
+ Then the image "my-site-copy/src/assets/resized/subdir/100/test.png" should have the dimensions "100x50"
+ And the file "_site/assets/resized/subdir/100/test.png" should exist
diff --git a/features/image-hashes.feature b/features/image-hashes.feature
new file mode 100644
index 0000000..fa0a615
--- /dev/null
+++ b/features/image-hashes.feature
@@ -0,0 +1,75 @@
+Feature: Image hashes inside responsive image templates
+ As a Jekyll user
+ I want to have access to image hashes
+ In order to create custom responsive image templates
+
+ Scenario: Using the {% responsive_image %} tag
+ Given I have a configuration with:
+ """
+ responsive_image:
+ template: _includes/hash.html
+ output_path_format: assets/resized/%{dirname}/%{width}/%{basename}
+ sizes:
+ - width: 100
+ - width: 120
+ """
+ And I have a file "index.html" with "{% responsive_image path: assets/subdir/test.png %}"
+ When I run Jekyll
+ Then the file "_site/index.html" should contain:
+ """
+ path: assets/subdir/test.png
+ width: 300
+ height: 150
+ basename: test.png
+ dirname: subdir
+ filename: test
+ extension: png
+
+ path: assets/resized/subdir/100/test.png
+ width: 100
+ height: 50
+ basename: test.png
+ dirname: resized/subdir/100
+ filename: test
+ extension: png
+
+ path: assets/resized/subdir/120/test.png
+ width: 120
+ height: 60
+ basename: test.png
+ dirname: resized/subdir/120
+ filename: test
+ extension: png
+ """
+
+ Scenario: Honouring Jekyll 'source' configuration
+ Given I have copied my site to "my-site-copy/src"
+ And I have a configuration with:
+ """
+ source: my-site-copy/src
+ responsive_image:
+ template: _includes/hash.html
+ output_path_format: assets/resized/%{dirname}/%{width}/%{basename}
+ sizes:
+ - width: 100
+ """
+ And I have a file "my-site-copy/src/index.html" with "{% responsive_image path: assets/subdir/test.png %}"
+ When I run Jekyll
+ Then the file "_site/index.html" should contain:
+ """
+ path: assets/subdir/test.png
+ width: 300
+ height: 150
+ basename: test.png
+ dirname: subdir
+ filename: test
+ extension: png
+
+ path: assets/resized/subdir/100/test.png
+ width: 100
+ height: 50
+ basename: test.png
+ dirname: resized/subdir/100
+ filename: test
+ extension: png
+ """
diff --git a/features/step_definitions/jekyll_steps.rb b/features/step_definitions/jekyll_steps.rb
index 5ca4529..ca86251 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
@@ -43,6 +41,10 @@ Then /^I should see "(.+)" in "(.*)"$/ do |text, file|
assert contents.inspect.include?(text), "Expected to find #{text.inspect} in #{contents.inspect}"
end
+Then /^the file "(.+)" should contain:$/ do |file, contents|
+ assert_equal contents.strip, File.open(file).readlines.join.strip
+end
+
Then /^the file "(.+)" should exist$/ do |path|
assert File.exist?(path)
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/hash.html b/features/test-site/_includes/hash.html
new file mode 100644
index 0000000..2fa786e
--- /dev/null
+++ b/features/test-site/_includes/hash.html
@@ -0,0 +1,16 @@
+path: {{ original.path }}
+width: {{ original.width }}
+height: {{ original.height }}
+basename: {{ original.basename }}
+dirname: {{ original.dirname }}
+filename: {{ original.filename }}
+extension: {{ original.extension }}
+{% for i in resized %}
+path: {{ i.path }}
+width: {{ i.width }}
+height: {{ i.height }}
+basename: {{ i.basename }}
+dirname: {{ i.dirname }}
+filename: {{ i.filename }}
+extension: {{ i.extension }}
+{% endfor %}
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 @@
-
+
diff --git a/lib/jekyll/responsive_image.rb b/lib/jekyll/responsive_image.rb
index 70c3de9..1913060 100644
--- a/lib/jekyll/responsive_image.rb
+++ b/lib/jekyll/responsive_image.rb
@@ -5,12 +5,12 @@ require 'jekyll'
require 'rmagick'
require 'jekyll/responsive_image/version'
-require 'jekyll/responsive_image/defaults'
+require 'jekyll/responsive_image/config'
require 'jekyll/responsive_image/utils'
require 'jekyll/responsive_image/render_cache'
require 'jekyll/responsive_image/image_processor'
require 'jekyll/responsive_image/resize_handler'
-require 'jekyll/responsive_image/common'
+require 'jekyll/responsive_image/renderer'
require 'jekyll/responsive_image/tag'
require 'jekyll/responsive_image/block'
require 'jekyll/responsive_image/extra_image_generator'
diff --git a/lib/jekyll/responsive_image/block.rb b/lib/jekyll/responsive_image/block.rb
index 935635f..c5d07ad 100644
--- a/lib/jekyll/responsive_image/block.rb
+++ b/lib/jekyll/responsive_image/block.rb
@@ -1,20 +1,11 @@
-
-
-
-
-
-
-
-
-
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
class Block < Liquid::Block
- include Jekyll::ResponsiveImage::Common
+ include Jekyll::ResponsiveImage::Utils
def render(context)
attributes = YAML.load(super)
- render_responsive_image(context, attributes)
+ Renderer.new(context.registers[:site], attributes).render_responsive_image
end
end
end
diff --git a/lib/jekyll/responsive_image/common.rb b/lib/jekyll/responsive_image/common.rb
deleted file mode 100644
index 60bc103..0000000
--- a/lib/jekyll/responsive_image/common.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Jekyll
- class ResponsiveImage
- module Common
- include Jekyll::ResponsiveImage::Utils
-
- def make_config(site)
- ResponsiveImage.defaults.dup
- .merge(site.config['responsive_image'])
- .merge(:site_source => site.source, :site_dest => site.dest)
- end
-
- def keep_resized_image!(site, image)
- keep_dir = File.dirname(image['path'])
- site.config['keep_files'] << keep_dir unless site.config['keep_files'].include?(keep_dir)
- end
-
- def render_responsive_image(context, attributes)
- cache_key = attributes.to_s
- result = attributes['cache'] ? RenderCache.get(cache_key) : nil
-
- if result.nil?
- site = context.registers[:site]
- config = make_config(site)
-
- 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]
-
- 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))
-
-
- RenderCache.set(cache_key, result)
- end
-
- result
- end
- 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/defaults.rb b/lib/jekyll/responsive_image/defaults.rb
deleted file mode 100644
index c8ddc5f..0000000
--- a/lib/jekyll/responsive_image/defaults.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-module Jekyll
- class ResponsiveImage
- @defaults = {
- 'default_quality' => 85,
- 'base_path' => 'assets',
- 'output_path_format' => 'assets/resized/%{filename}-%{width}x%{height}.%{extension}',
- 'sizes' => [],
- 'extra_images' => []
- }.freeze
-
- class << self
- attr_reader :defaults
- end
- end
-end
diff --git a/lib/jekyll/responsive_image/extra_image_generator.rb b/lib/jekyll/responsive_image/extra_image_generator.rb
index 70932fe..5ea6c43 100644
--- a/lib/jekyll/responsive_image/extra_image_generator.rb
+++ b/lib/jekyll/responsive_image/extra_image_generator.rb
@@ -1,16 +1,18 @@
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
class ExtraImageGenerator < Jekyll::Generator
- include Jekyll::ResponsiveImage::Common
+ include Jekyll::ResponsiveImage::Utils
def generate(site)
- config = make_config(site)
+ config = Config.new(site).to_h
+ site_source = Pathname.new(site.source)
config['extra_images'].each do |pathspec|
Dir.glob(site.in_source_dir(pathspec)) do |image_path|
- relative_image_path = image_path.sub(/^#{Regexp.escape(image_path)}/, '')
+ path = Pathname.new(image_path)
+ relative_image_path = path.relative_path_from(site_source)
- result = ImageProcessor.process(image_path, relative_image_path, config)
+ result = ImageProcessor.process(relative_image_path, config)
result[:resized].each { |image| keep_resized_image!(site, image) }
end
end
diff --git a/lib/jekyll/responsive_image/image_processor.rb b/lib/jekyll/responsive_image/image_processor.rb
index 86a2b3a..ca102be 100644
--- a/lib/jekyll/responsive_image/image_processor.rb
+++ b/lib/jekyll/responsive_image/image_processor.rb
@@ -1,22 +1,24 @@
module Jekyll
- class ResponsiveImage
+ 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)
+ def process(image_path, config)
+ absolute_image_path = File.expand_path(image_path.to_s, config[:site_source])
+
+ raise SyntaxError.new("Invalid image path specified: #{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),
+ original: image_hash(config, image_path, img.columns, img.rows),
resized: resize_handler.resize_image(img, config),
}
end
- def self.process(absolute_image_path, relative_image_path, config)
- self.new.process(absolute_image_path, relative_image_path, config)
+ def self.process(image_path, config)
+ self.new.process(image_path, config)
end
end
end
diff --git a/lib/jekyll/responsive_image/render_cache.rb b/lib/jekyll/responsive_image/render_cache.rb
index 6de1768..467a7f2 100644
--- a/lib/jekyll/responsive_image/render_cache.rb
+++ b/lib/jekyll/responsive_image/render_cache.rb
@@ -1,5 +1,5 @@
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
class RenderCache
attr_accessor :store
diff --git a/lib/jekyll/responsive_image/renderer.rb b/lib/jekyll/responsive_image/renderer.rb
new file mode 100644
index 0000000..06a3263
--- /dev/null
+++ b/lib/jekyll/responsive_image/renderer.rb
@@ -0,0 +1,37 @@
+module Jekyll
+ module ResponsiveImage
+ class Renderer
+ include Jekyll::ResponsiveImage::Utils
+
+ def initialize(site, attributes)
+ @site = site
+ @attributes = attributes
+ end
+
+ def render_responsive_image
+ cache_key = @attributes.to_s
+ result = @attributes['cache'] ? RenderCache.get(cache_key) : nil
+
+ if result.nil?
+ config = Config.new(@site).to_h
+
+ image = ImageProcessor.process(@attributes['path'], config)
+ @attributes['original'] = image[:original]
+ @attributes['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))
+
+ RenderCache.set(cache_key, result)
+ end
+
+ result
+ end
+ end
+ end
+end
diff --git a/lib/jekyll/responsive_image/resize_handler.rb b/lib/jekyll/responsive_image/resize_handler.rb
index 04b5e8d..1fc411f 100644
--- a/lib/jekyll/responsive_image/resize_handler.rb
+++ b/lib/jekyll/responsive_image/resize_handler.rb
@@ -1,5 +1,5 @@
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
class ResizeHandler
include ResponsiveImage::Utils
@@ -14,8 +14,8 @@ module Jekyll
next unless needs_resizing?(img, width)
image_path = img.filename.force_encoding(Encoding::UTF_8)
- filepath = format_output_path(config['output_path_format'], config['base_path'], image_path, width, height)
- resized.push(image_hash(config['base_path'], filepath, width, height))
+ filepath = format_output_path(config['output_path_format'], config, image_path, width, height)
+ resized.push(image_hash(config, filepath, width, height))
site_source_filepath = File.expand_path(filepath, config[:site_source])
site_dest_filepath = File.expand_path(filepath, config[:site_dest])
@@ -23,10 +23,10 @@ module Jekyll
# Don't resize images more than once
next if File.exist?(site_source_filepath)
- ensure_output_dir_exists!(File.dirname(site_source_filepath))
- ensure_output_dir_exists!(File.dirname(site_dest_filepath))
+ ensure_output_dir_exists!(site_source_filepath)
+ ensure_output_dir_exists!(site_dest_filepath)
- Jekyll.logger.info "Generating #{filepath}"
+ Jekyll.logger.info "Generating #{site_source_filepath}"
i = img.scale(ratio)
i.write(site_source_filepath) do |f|
@@ -34,6 +34,7 @@ module Jekyll
end
# Ensure the generated file is copied to the _site directory
+ Jekyll.logger.info "Copying resized image to #{site_dest_filepath}"
FileUtils.copy_file(site_source_filepath, site_dest_filepath)
i.destroy!
@@ -44,11 +45,19 @@ module Jekyll
resized
end
+ def format_output_path(format, config, image_path, width, height)
+ params = symbolize_keys(image_hash(config, image_path, width, height))
+
+ Pathname.new(format % params).cleanpath.to_s
+ end
+
def needs_resizing?(img, width)
img.columns > width
end
- def ensure_output_dir_exists!(dir)
+ def ensure_output_dir_exists!(path)
+ dir = File.dirname(path)
+
unless Dir.exist?(dir)
Jekyll.logger.info "Creating output directory #{dir}"
FileUtils.mkdir_p(dir)
diff --git a/lib/jekyll/responsive_image/tag.rb b/lib/jekyll/responsive_image/tag.rb
index 7994c2b..6ba8147 100644
--- a/lib/jekyll/responsive_image/tag.rb
+++ b/lib/jekyll/responsive_image/tag.rb
@@ -1,8 +1,6 @@
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
class Tag < Liquid::Tag
- include Jekyll::ResponsiveImage::Common
-
def initialize(tag_name, markup, tokens)
super
@@ -15,7 +13,7 @@ module Jekyll
end
def render(context)
- render_responsive_image(context, @attributes)
+ Renderer.new(context.registers[:site], @attributes).render_responsive_image
end
end
end
diff --git a/lib/jekyll/responsive_image/utils.rb b/lib/jekyll/responsive_image/utils.rb
index fbe612e..d940806 100644
--- a/lib/jekyll/responsive_image/utils.rb
+++ b/lib/jekyll/responsive_image/utils.rb
@@ -1,8 +1,13 @@
require 'pathname'
module Jekyll
- class ResponsiveImage
+ module ResponsiveImage
module Utils
+ def keep_resized_image!(site, image)
+ keep_dir = File.dirname(image['path'])
+ site.config['keep_files'] << keep_dir unless site.config['keep_files'].include?(keep_dir)
+ end
+
def symbolize_keys(hash)
result = {}
hash.each_key do |key|
@@ -11,17 +16,11 @@ module Jekyll
result
end
- def format_output_path(format, base_path, image_path, width, height)
- params = symbolize_keys(image_hash(base_path, image_path, width, height))
-
- Pathname.new(format % params).cleanpath.to_s
- end
-
# Build a hash containing image information
- def image_hash(base_path, image_path, width, height)
+ def image_hash(config, image_path, width, height)
{
'path' => image_path,
- 'dirname' => relative_dirname(base_path, image_path),
+ 'dirname' => relative_dirname(config, image_path),
'basename' => File.basename(image_path),
'filename' => File.basename(image_path, '.*'),
'extension' => File.extname(image_path).delete('.'),
@@ -30,9 +29,9 @@ module Jekyll
}
end
- def relative_dirname(base_path, image_path)
- path = Pathname.new(image_path).expand_path
- base = Pathname.new(base_path).expand_path
+ def relative_dirname(config, image_path)
+ path = Pathname.new(File.expand_path(image_path, config[:site_source]))
+ base = Pathname.new(File.expand_path(config['base_path'], config[:site_source]))
path.relative_path_from(base).dirname.to_s.delete('.')
end
diff --git a/lib/jekyll/responsive_image/version.rb b/lib/jekyll/responsive_image/version.rb
index 2a793e9..fb1cb99 100644
--- a/lib/jekyll/responsive_image/version.rb
+++ b/lib/jekyll/responsive_image/version.rb
@@ -1,5 +1,5 @@
module Jekyll
- class ResponsiveImage
- VERSION = '1.0.0.pre3'.freeze
+ module ResponsiveImage
+ VERSION = '1.0.0.pre4'.freeze
end
end