jekyll-picture-tag 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +24 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/examples/_config.yml +53 -0
- data/examples/layout.html +51 -0
- data/examples/output.html +11 -0
- data/examples/post.md +16 -0
- data/jekyll-picture-tag.gemspec +32 -0
- data/lib/jekyll-picture-tag.rb +240 -0
- data/readme.md +211 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d5973c7f85a12ce7efb0a109d27a102012fd8d11
|
4
|
+
data.tar.gz: cab2315e25e0140dcf35aed001b1d6acd8204531
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9401800983de613fc69419effd1fd0ad44d4c8698b103368e01adb459e9104448ee9fc2acb05d84ccc68b53a2b00b71baed0a2177fb6972ad221fb03695836f1
|
7
|
+
data.tar.gz: a9f21424491affe44ec6f58ead9aeb4ee1794a28fb2e6b602f8ed1608d63b1ea6af1fc579926909bcac9a1793021acb70ecede32f6706d73047ecb786a20ab70
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2013, Robert Wierzbowski
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the <organization> nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "jekyll-picture-tag"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Sample Jekyll Picture Tag settings
|
2
|
+
|
3
|
+
name: A responsive Jekyll blog
|
4
|
+
pygments: true
|
5
|
+
markdown: redcarpet
|
6
|
+
|
7
|
+
picture:
|
8
|
+
source: assets/images/_fullsize
|
9
|
+
output: generated
|
10
|
+
markup: picture
|
11
|
+
presets:
|
12
|
+
# Full width pictures
|
13
|
+
default:
|
14
|
+
ppi: [1, 1.5]
|
15
|
+
attr:
|
16
|
+
class: blog-full
|
17
|
+
itemprop: image
|
18
|
+
source_lrg:
|
19
|
+
media: "(min-width: 40em)"
|
20
|
+
width: 700
|
21
|
+
source_med:
|
22
|
+
media: "(min-width: 30em)"
|
23
|
+
width: 450
|
24
|
+
source_default:
|
25
|
+
width: 350
|
26
|
+
height: 200
|
27
|
+
# Half width pictures
|
28
|
+
half:
|
29
|
+
ppi: [1, 1.5]
|
30
|
+
attr:
|
31
|
+
data-location: "{{location}}"
|
32
|
+
data-active: nil
|
33
|
+
source_lrg:
|
34
|
+
media: "(min-width: 40em)"
|
35
|
+
width: 400
|
36
|
+
source_med:
|
37
|
+
media: "(min-width: 30em)"
|
38
|
+
width: 250
|
39
|
+
source_default:
|
40
|
+
width: 350
|
41
|
+
# Self-set resolution sources. Useful if you don't want a 1:1 image size to dppx ratio.
|
42
|
+
gallery:
|
43
|
+
source_wide_hi:
|
44
|
+
media: "(min-width: 40em) and (min-resolution: 1.5dppx)"
|
45
|
+
width: 900
|
46
|
+
height: 600
|
47
|
+
source_wide:
|
48
|
+
media: "(min-width: 40em)"
|
49
|
+
width: 600
|
50
|
+
height: 400
|
51
|
+
source_default:
|
52
|
+
width: 250
|
53
|
+
height: 250
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
6
|
+
<title>{{ page.title }}</title>
|
7
|
+
<meta name="viewport" content="width=device-width">
|
8
|
+
|
9
|
+
<!-- syntax highlighting CSS -->
|
10
|
+
<link rel="stylesheet" href="/css/syntax.css">
|
11
|
+
|
12
|
+
<!-- Custom CSS -->
|
13
|
+
<link rel="stylesheet" href="/css/main.css">
|
14
|
+
|
15
|
+
<!-- Picturefill libraries for Jekyll Picture Tag -->
|
16
|
+
<script src="/assets/matchmedia.js"></script>
|
17
|
+
<script src="/assets/picturefill.js"></script>
|
18
|
+
<!-- -------------------------------------------- -->
|
19
|
+
|
20
|
+
</head>
|
21
|
+
<body>
|
22
|
+
|
23
|
+
<div class="container">
|
24
|
+
<div class="site">
|
25
|
+
<div class="header">
|
26
|
+
<h1 class="title"><a href="/">{{ site.name }}</a></h1>
|
27
|
+
<a class="extra" href="/">home</a>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
{{ content }}
|
31
|
+
|
32
|
+
<div class="footer">
|
33
|
+
<div class="contact">
|
34
|
+
<p>
|
35
|
+
Your Name<br />
|
36
|
+
What You Are<br />
|
37
|
+
your@email.com
|
38
|
+
</p>
|
39
|
+
</div>
|
40
|
+
<div class="contact">
|
41
|
+
<p>
|
42
|
+
<a href="http://github.com/yourusername/">github.com/yourusername</a><br />
|
43
|
+
<a href="http://twitter.com/yourusername/">twitter.com/yourusername</a><br />
|
44
|
+
</p>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
</div> <!-- /container -->
|
49
|
+
|
50
|
+
</body>
|
51
|
+
</html>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!-- Example picture output, {% picture portrait.jpg alt="An example of picturefill markup" %} -->
|
2
|
+
|
3
|
+
<picture>
|
4
|
+
<source srcset="/generated/portrait-1050by1050-092483.jpg" media="(min-width: 40em) and (-webkit-min-device-pixel-ratio: 1.5), (min-width: 40em) and (min-resolution: 144dpi)">
|
5
|
+
<source srcset="/generated/portrait-700by700-092483.jpg" media="(min-width: 40em)">
|
6
|
+
<source srcset="/generated/portrait-675by675-092483.jpg" media="(min-width: 30em) and (-webkit-min-device-pixel-ratio: 1.5), (min-width: 30em) and (min-resolution: 144dpi)">
|
7
|
+
<source srcset="/generated/portrait-450by450-092483.jpg" media="(min-width: 30em)">
|
8
|
+
<source srcset="/generated/portrait-525by300-092483.jpg" media="(-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi)">
|
9
|
+
<source srcset="/generated/portrait-350by200-092483.jpg">
|
10
|
+
<img srcset="/generated/portrait-350by200-092483.jpg" alt="">
|
11
|
+
</picture>
|
data/examples/post.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: Tag examples
|
4
|
+
---
|
5
|
+
|
6
|
+
{% picture portrait.jpg alt="An unsual picture" %}
|
7
|
+
|
8
|
+
What was the narrative that this representation was meant to embellish and complete? As I regarded the work, I slowly sensed that the underlying tale was the picture itself. The painting wasn’t the extension of a story at all, it was something in its own right.
|
9
|
+
|
10
|
+
### Variations
|
11
|
+
|
12
|
+
With a preset specified:
|
13
|
+
{% picture gallery portrait.jpg alt="An unsual picture" data-downloadable="true" %}
|
14
|
+
|
15
|
+
With an alternate source images:
|
16
|
+
{% picture half portrait.jpg source_lrg: dream-fullpage.jpg source_med: dream-midrange.jpg alt="An unsual picture" data-downloadable="true" %}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jekyll-picture-tag"
|
8
|
+
spec.version = '0.2.3'
|
9
|
+
spec.authors = ['Robert Wierzbowski', "Brendan Tobolaski"]
|
10
|
+
spec.email = ['hello@robwierzbowski.com', "brendan@tobolaski.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Easy responsive images for Jekyll.}
|
13
|
+
spec.description = <<-EOF
|
14
|
+
Jekyll Picture Tag is a liquid tag that adds responsive images to your Jekyll static site. It follows the picture
|
15
|
+
element pattern, and polyfills older browsers with Picturefill. Jekyll Picture Tag automatically creates resized
|
16
|
+
source images, is fully configurable, and covers all use cases — including art direction and resolution switching —
|
17
|
+
with a little YAML configuration and a simple template tag.
|
18
|
+
EOF
|
19
|
+
spec.homepage = 'https://github.com/robwierzbowski/jekyll-picture-tag'
|
20
|
+
spec.license = 'BSD-3-Clause'
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
|
29
|
+
spec.add_dependency 'mini_magick', '~> 3.8.0'
|
30
|
+
spec.add_dependency 'fastimage', '~> 1.6.4'
|
31
|
+
spec.add_runtime_dependency 'jekyll', '< 3'
|
32
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# Title: Jekyll Picture Tag
|
2
|
+
# Authors: Rob Wierzbowski : @robwierzbowski
|
3
|
+
# Justin Reese : @justinxreese
|
4
|
+
# Welch Canavan : @xiwcx
|
5
|
+
#
|
6
|
+
# Description: Easy responsive images for Jekyll.
|
7
|
+
#
|
8
|
+
# Download: https://github.com/robwierzbowski/jekyll-picture-tag
|
9
|
+
# Documentation: https://github.com/robwierzbowski/jekyll-picture-tag/readme.md
|
10
|
+
# Issues: https://github.com/robwierzbowski/jekyll-picture-tag/issues
|
11
|
+
#
|
12
|
+
# Syntax: {% picture [preset] path/to/img.jpg [source_key: path/to/alt-img.jpg] [attr="value"] %}
|
13
|
+
# Example: {% picture poster.jpg alt="The strange case of responsive images" %}
|
14
|
+
# {% picture gallery poster.jpg source_small: poster_closeup.jpg
|
15
|
+
# alt="The strange case of responsive images" class="gal-img" data-selected %}
|
16
|
+
#
|
17
|
+
# See the documentation for full configuration and usage instructions.
|
18
|
+
|
19
|
+
require 'fileutils'
|
20
|
+
require 'pathname'
|
21
|
+
require 'digest/md5'
|
22
|
+
require 'mini_magick'
|
23
|
+
require 'fastimage'
|
24
|
+
|
25
|
+
module Jekyll
|
26
|
+
|
27
|
+
class Picture < Liquid::Tag
|
28
|
+
|
29
|
+
def initialize(tag_name, markup, tokens)
|
30
|
+
@markup = markup
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def render(context)
|
35
|
+
|
36
|
+
# Render any liquid variables in tag arguments and unescape template code
|
37
|
+
render_markup = Liquid::Template.parse(@markup).render(context).gsub(/\\\{\\\{|\\\{\\%/, '\{\{' => '{{', '\{\%' => '{%')
|
38
|
+
|
39
|
+
# Gather settings
|
40
|
+
site = context.registers[:site]
|
41
|
+
settings = site.config['picture']
|
42
|
+
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)
|
43
|
+
preset = settings['presets'][ markup[:preset] ] || settings['presets']['default']
|
44
|
+
|
45
|
+
raise "Picture Tag can't read this tag. Try {% picture [preset] path/to/img.jpg [source_key: path/to/alt-img.jpg] [attr=\"value\"] %}." unless markup
|
46
|
+
|
47
|
+
# Assign defaults
|
48
|
+
settings['source'] ||= '.'
|
49
|
+
settings['output'] ||= 'generated'
|
50
|
+
settings['markup'] ||= 'picturefill'
|
51
|
+
|
52
|
+
# Prevent Jekyll from erasing our generated files
|
53
|
+
site.config['keep_files'] << settings['output'] unless site.config['keep_files'].include?(settings['output'])
|
54
|
+
|
55
|
+
# Deep copy preset for single instance manipulation
|
56
|
+
instance = Marshal.load(Marshal.dump(preset))
|
57
|
+
|
58
|
+
# Process alternate source images
|
59
|
+
source_src = if markup[:source_src]
|
60
|
+
Hash[ *markup[:source_src].gsub(/:/, '').split ]
|
61
|
+
else
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
|
65
|
+
# Process html attributes
|
66
|
+
html_attr = if markup[:html_attr]
|
67
|
+
Hash[ *markup[:html_attr].scan(/(?<attr>[^\s="]+)(?:="(?<value>[^"]+)")?\s?/).flatten ]
|
68
|
+
else
|
69
|
+
{}
|
70
|
+
end
|
71
|
+
|
72
|
+
if instance['attr']
|
73
|
+
html_attr = instance.delete('attr').merge(html_attr)
|
74
|
+
end
|
75
|
+
|
76
|
+
if settings['markup'] == 'picturefill'
|
77
|
+
html_attr['data-picture'] = nil
|
78
|
+
html_attr['data-alt'] = html_attr.delete('alt')
|
79
|
+
end
|
80
|
+
|
81
|
+
html_attr_string = html_attr.inject('') { |string, attrs|
|
82
|
+
if attrs[1]
|
83
|
+
string << "#{attrs[0]}=\"#{attrs[1]}\" "
|
84
|
+
else
|
85
|
+
string << "#{attrs[0]} "
|
86
|
+
end
|
87
|
+
}
|
88
|
+
|
89
|
+
# Prepare ppi variables
|
90
|
+
ppi = if instance['ppi'] then instance.delete('ppi').sort.reverse else nil end
|
91
|
+
# this might work??? ppi = instance.delete('ppi'){ |ppi| [nil] }.sort.reverse
|
92
|
+
ppi_sources = {}
|
93
|
+
|
94
|
+
# Switch width and height keys to the symbols that generate_image() expects
|
95
|
+
instance.each { |key, source|
|
96
|
+
raise "Preset #{key} is missing a width or a height" if !source['width'] and !source['height']
|
97
|
+
instance[key][:width] = instance[key].delete('width') if source['width']
|
98
|
+
instance[key][:height] = instance[key].delete('height') if source['height']
|
99
|
+
}
|
100
|
+
|
101
|
+
# Store keys in an array for ordering the instance sources
|
102
|
+
source_keys = instance.keys
|
103
|
+
# used to escape markdown parsing rendering below
|
104
|
+
markdown_escape = "\ "
|
105
|
+
|
106
|
+
# Raise some exceptions before we start expensive processing
|
107
|
+
raise "Picture Tag can't find the \"#{markup[:preset]}\" preset. Check picture: presets in _config.yml for a list of presets." unless preset
|
108
|
+
raise "Picture Tag can't find this preset source. Check picture: presets: #{markup[:preset]} in _config.yml for a list of sources." unless (source_src.keys - source_keys).empty?
|
109
|
+
|
110
|
+
# Process instance
|
111
|
+
# Add image paths for each source
|
112
|
+
instance.each_key { |key|
|
113
|
+
instance[key][:src] = source_src[key] || markup[:image_src]
|
114
|
+
}
|
115
|
+
|
116
|
+
# Construct ppi sources
|
117
|
+
# Generates -webkit-device-ratio and resolution: dpi media value for cross browser support
|
118
|
+
# Reference: http://www.brettjankord.com/2012/11/28/cross-browser-retinahigh-resolution-media-queries/
|
119
|
+
if ppi
|
120
|
+
instance.each { |key, source|
|
121
|
+
ppi.each { |p|
|
122
|
+
if p != 1
|
123
|
+
ppi_key = "#{key}-x#{p}"
|
124
|
+
|
125
|
+
ppi_sources[ppi_key] = {
|
126
|
+
:width => if source[:width] then (source[:width].to_f * p).round else nil end,
|
127
|
+
:height => if source[:height] then (source[:height].to_f * p).round else nil end,
|
128
|
+
'media' => if source['media']
|
129
|
+
"#{source['media']} and (-webkit-min-device-pixel-ratio: #{p}), #{source['media']} and (min-resolution: #{(p * 96).round}dpi)"
|
130
|
+
else
|
131
|
+
"(-webkit-min-device-pixel-ratio: #{p}), (min-resolution: #{(p * 96).to_i}dpi)"
|
132
|
+
end,
|
133
|
+
:src => source[:src]
|
134
|
+
}
|
135
|
+
|
136
|
+
# Add ppi_key to the source keys order
|
137
|
+
source_keys.insert(source_keys.index(key), ppi_key)
|
138
|
+
end
|
139
|
+
}
|
140
|
+
}
|
141
|
+
instance.merge!(ppi_sources)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Generate resized images
|
145
|
+
instance.each { |key, source|
|
146
|
+
instance[key][:generated_src] = generate_image(source, site.source, site.dest, settings['source'], settings['output'], site.config["baseurl"])
|
147
|
+
}
|
148
|
+
|
149
|
+
# Construct and return tag
|
150
|
+
if settings['markup'] == 'picture'
|
151
|
+
|
152
|
+
source_tags = ''
|
153
|
+
source_keys.each { |source|
|
154
|
+
media = " media=\"#{instance[source]['media']}\"" unless source == 'source_default'
|
155
|
+
source_tags += "#{markdown_escape * 4}<source srcset=\"#{instance[source][:generated_src]}\"#{media}>\n"
|
156
|
+
}
|
157
|
+
|
158
|
+
# Note: we can't indent html output because markdown parsers will turn 4 spaces into code blocks
|
159
|
+
# Note: Added backslash+space escapes to bypass markdown parsing of indented code below -WD
|
160
|
+
picture_tag = "<picture>\n"\
|
161
|
+
"#{source_tags}"\
|
162
|
+
"#{markdown_escape * 4}<img srcset=\"#{instance['source_default'][:generated_src]}\" #{html_attr_string}>\n"\
|
163
|
+
"#{markdown_escape * 2}</picture>\n"
|
164
|
+
|
165
|
+
elsif settings['markup'] == 'img'
|
166
|
+
# TODO implement <img srcset/sizes>
|
167
|
+
end
|
168
|
+
|
169
|
+
# Return the markup!
|
170
|
+
picture_tag
|
171
|
+
end
|
172
|
+
|
173
|
+
def generate_image(instance, site_source, site_dest, image_source, image_dest, baseurl)
|
174
|
+
digest = Digest::MD5.hexdigest(File.read(File.join(site_source, image_source, instance[:src]))).slice!(0..5)
|
175
|
+
|
176
|
+
image_dir = File.dirname(instance[:src])
|
177
|
+
ext = File.extname(instance[:src])
|
178
|
+
basename = File.basename(instance[:src], ext)
|
179
|
+
|
180
|
+
size = FastImage.size(File.join(site_source, image_source, instance[:src]))
|
181
|
+
orig_width = size[0]
|
182
|
+
orig_height = size[1]
|
183
|
+
orig_ratio = orig_width*1.0/orig_height
|
184
|
+
|
185
|
+
gen_width = if instance[:width]
|
186
|
+
instance[:width].to_f
|
187
|
+
elsif instance[:height]
|
188
|
+
orig_ratio * instance[:height].to_f
|
189
|
+
else
|
190
|
+
orig_width
|
191
|
+
end
|
192
|
+
gen_height = if instance[:height]
|
193
|
+
instance[:height].to_f
|
194
|
+
elsif instance[:width]
|
195
|
+
instance[:width].to_f / orig_ratio
|
196
|
+
else
|
197
|
+
orig_height
|
198
|
+
end
|
199
|
+
gen_ratio = gen_width/gen_height
|
200
|
+
|
201
|
+
# Don't allow upscaling. If the image is smaller than the requested dimensions, recalculate.
|
202
|
+
if orig_width < gen_width || orig_height < gen_height
|
203
|
+
undersize = true
|
204
|
+
gen_width = if orig_ratio < gen_ratio then orig_width else orig_height * gen_ratio end
|
205
|
+
gen_height = if orig_ratio > gen_ratio then orig_height else orig_width/gen_ratio end
|
206
|
+
end
|
207
|
+
|
208
|
+
gen_name = "#{basename}-#{gen_width.round}by#{gen_height.round}-#{digest}#{ext}"
|
209
|
+
gen_dest_dir = File.join(site_dest, image_dest, image_dir)
|
210
|
+
gen_dest_file = File.join(gen_dest_dir, gen_name)
|
211
|
+
|
212
|
+
# Generate resized files
|
213
|
+
unless File.exists?(gen_dest_file)
|
214
|
+
|
215
|
+
warn "Warning:".yellow + " #{instance[:src]} is smaller than the requested output file. It will be resized without upscaling." if undersize
|
216
|
+
|
217
|
+
# If the destination directory doesn't exist, create it
|
218
|
+
FileUtils.mkdir_p(gen_dest_dir) unless File.exist?(gen_dest_dir)
|
219
|
+
|
220
|
+
# Let people know their images are being generated
|
221
|
+
puts "Generating #{gen_name}"
|
222
|
+
|
223
|
+
image = MiniMagick::Image.open(File.join(site_source, image_source, instance[:src]))
|
224
|
+
# Scale and crop
|
225
|
+
image.combine_options do |i|
|
226
|
+
i.resize "#{gen_width}x#{gen_height}^"
|
227
|
+
i.gravity "center"
|
228
|
+
i.crop "#{gen_width}x#{gen_height}+0+0"
|
229
|
+
end
|
230
|
+
|
231
|
+
image.write gen_dest_file
|
232
|
+
end
|
233
|
+
|
234
|
+
# Return path relative to the site root for html
|
235
|
+
Pathname.new(File.join(baseurl, image_dest, image_dir, gen_name)).cleanpath
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
Liquid::Template.register_tag('picture', Jekyll::Picture)
|
data/readme.md
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# Jekyll Picture Tag
|
2
|
+
|
3
|
+
**Easy responsive images for Jekyll.**
|
4
|
+
|
5
|
+
Jekyll Picture Tag is a liquid tag that adds responsive images to your [Jekyll](http://jekyllrb.com) static site. It follows the [picture element](http://picture.responsiveimages.org/) pattern, and polyfills older browsers with [Picturefill](https://github.com/scottjehl/picturefill). Jekyll Picture Tag automatically creates resized source images, is fully configurable, and covers all use cases — including art direction and resolution switching — with a little YAML configuration and a simple template tag.
|
6
|
+
|
7
|
+
For non-responsive images in Jekyll, take a look at [Jekyll Img Tag](https://github.com/robwierzbowski/jekyll-img-tag).
|
8
|
+
|
9
|
+
## Why use Jekyll Picture Tag?
|
10
|
+
|
11
|
+
**Performance:** Static sites can be can be blazingly fast. If we're not using responsive images we're throwing those performance gains away by serving kilobytes of pixels a user will never see.
|
12
|
+
|
13
|
+
**Proof:** The picture element covers more responsive image use cases than any other proposed solution. As a result, the markup is more verbose. This plugin shows that in practice picture can be easy for website authors to use and maintain.
|
14
|
+
|
15
|
+
**Need more convincing?** Read [Tim Kadlec's](https://twitter.com/tkadlec) article [Why We Need Responsive Images](http://timkadlec.com/2013/06/why-we-need-responsive-images/). For an introduction to the picture element and responsive images in general see [Mo’ Pixels Mo’ Problems](http://alistapart.com/article/mo-pixels-mo-problems) and the follow up article [Ughck. Images](http://daverupert.com/2013/06/ughck-images/) by [Dave Rupert](https://twitter.com/davatron5000).
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add `jekyll-picture-tag` to your Gemfile in the `:jekyll_plugins` group. For example:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
group :jekyll_plugins do
|
23
|
+
gem 'jekyll-picture-tag', '~> 0.2.3'
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
It also requires an HTML5 Markdown parser. If you're not using one already, install [Redcarpet](https://github.com/vmg/redcarpet) and add `markdown: redcarpet` to your _config.yml.
|
28
|
+
|
29
|
+
Once you have the requirements installed, copy picture_tag.rb into your Jekyll _plugins folder.
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
There are three parts to Jekyll Picture Tag:
|
34
|
+
|
35
|
+
- [Polyfill](#polyfill)
|
36
|
+
- [Liquid Tag](#liquid-tag)
|
37
|
+
- [Configuration](#configuration)
|
38
|
+
|
39
|
+
### Polyfill
|
40
|
+
|
41
|
+
For full browser support, the `picture` markup requires Scott Jehl's [Picturefill](https://github.com/scottjehl/picturefill) polyfill. Download the library and add the script to your site.
|
42
|
+
|
43
|
+
The Jekyll Picture Tag requires Picturefill 2.0 and above. If you want to use Picturefill 1.x, you must use [Jekyll Picture Tag 0.2.2](https://github.com/robwierzbowski/jekyll-picture-tag/tree/0.2.2)
|
44
|
+
|
45
|
+
### Liquid Tag
|
46
|
+
|
47
|
+
```
|
48
|
+
{% picture [preset] path/to/img.jpg [source_key: path/to/alt/img.jpg] [attribute="value"] %}
|
49
|
+
```
|
50
|
+
|
51
|
+
The tag takes a mix of user input and pointers to configuration settings.
|
52
|
+
|
53
|
+
#### picture
|
54
|
+
|
55
|
+
Tells Liquid this is a Jekyll Picture Tag.
|
56
|
+
|
57
|
+
#### preset
|
58
|
+
|
59
|
+
Optionally specify a picture [preset](#presets) to use, or leave blank for the `default` preset.
|
60
|
+
|
61
|
+
#### path/to/img.jpg
|
62
|
+
|
63
|
+
The base image that will be resized for your picture sources. Can be a jpeg, png, or gif.
|
64
|
+
|
65
|
+
#### source_key: path/to/alt/img.jpg
|
66
|
+
|
67
|
+
Optionally specify an alternate base image for a specific picture source. This is one of of picture's strongest features, often reffered to as the [art direction use case](http://usecases.responsiveimages.org/#art-direction).
|
68
|
+
|
69
|
+
#### attribute="value"
|
70
|
+
|
71
|
+
Optionally specify any number of HTML attributes. These will be merged with any [attributes you've set in a preset](#attr). An attribute set in a tag will override the same attribute set in a preset.
|
72
|
+
|
73
|
+
You can set any attribute except for `data-picture`, `data-alt`, `data-src`, and `data-media`.
|
74
|
+
|
75
|
+
### Configuration
|
76
|
+
|
77
|
+
Jekyll Picture Tag stores settings in an `picture` key in your _config.yml. It takes a minute to set up your presets, but after that generating complex markup with a liquid tag is easy.
|
78
|
+
|
79
|
+
**Example settings**
|
80
|
+
|
81
|
+
```yml
|
82
|
+
picture:
|
83
|
+
source: "assets/images/_fullsize"
|
84
|
+
output: "generated"
|
85
|
+
markup: "picture"
|
86
|
+
presets:
|
87
|
+
default:
|
88
|
+
...
|
89
|
+
main:
|
90
|
+
...
|
91
|
+
gallery:
|
92
|
+
...
|
93
|
+
```
|
94
|
+
|
95
|
+
**Example preset**
|
96
|
+
|
97
|
+
```yml
|
98
|
+
gallery:
|
99
|
+
ppi: [1, 1.5]
|
100
|
+
attr:
|
101
|
+
class: "gallery-pict"
|
102
|
+
itemprop: "image"
|
103
|
+
source_medium:
|
104
|
+
media: "(min-width: 40em)"
|
105
|
+
width: "600"
|
106
|
+
height: "300"
|
107
|
+
source_default:
|
108
|
+
width: "300"
|
109
|
+
```
|
110
|
+
|
111
|
+
#### source
|
112
|
+
|
113
|
+
To make writing tags easier you can specify a source directory for your assets. Base images in the tag will be relative to the `source` directory.
|
114
|
+
|
115
|
+
For example, if `source` is set to `assets/images/_fullsize`, the tag `{% picture enishte/portrait.jpg alt="An unsual picture" %}` will look for a file at `assets/images/_fullsize/enishte/portrait.jpg`.
|
116
|
+
|
117
|
+
Defaults to the site source directory.
|
118
|
+
|
119
|
+
#### output
|
120
|
+
|
121
|
+
Jekyll Picture Tag generates resized images to the `output` directory in your compiled site. The organization of your `source` directory is maintained in the output directory.
|
122
|
+
|
123
|
+
Defaults to `{compiled Jekyll site}/generated`.
|
124
|
+
|
125
|
+
*__NOTE:__ `output` must be in a directory that contains other files or it will be erased. This is a [known bug](https://github.com/mojombo/jekyll/issues/1297) in Jekyll.*
|
126
|
+
|
127
|
+
#### markup
|
128
|
+
|
129
|
+
Choose `picture` to output markup based on the `<picture>` element. Future options may include `srcset` but have not yet been implemented.
|
130
|
+
|
131
|
+
#### presets
|
132
|
+
|
133
|
+
Presets contain reusable settings for a Jekyll Picture Tag. Each is made up of a list of sources, and an optional attributes list and ppi array.
|
134
|
+
|
135
|
+
For example, a `gallery` preset might configure the picture sources for all responsive gallery images on your site, and set a class and some required metadata attributes. If the design changes, you can edit the `gallery` preset and the new settings will apply to every tag that references it.
|
136
|
+
|
137
|
+
The `default` preset will be used if no preset is specified in the liquid tag, and is required. A preset name can't contain the `.`, `:`, or `/` characters.
|
138
|
+
|
139
|
+
#### attr
|
140
|
+
|
141
|
+
Optionally add a list of html attributes to add to the main picturefill span or picture element when the preset is used.
|
142
|
+
|
143
|
+
Set the value of standalone attributes to `nil`. You can set any attribute except for `data-picture`, `data-alt`, `data-src`, and `data-media`.
|
144
|
+
|
145
|
+
An attribute set in a tag will override the same attribute set in a preset.
|
146
|
+
|
147
|
+
#### ppi
|
148
|
+
|
149
|
+
Optionally add an array of resolutions to automatically generate high ppi images and sources.
|
150
|
+
|
151
|
+
For example, the setting `[1, 1.5, 2]` will create sources that switch to 1.5x sized images on devices with a minimum resolution of 1.5dppx, and 2x images on devices with a minimum resolution of 2dppx. For finer grained control omit `ppi` and write resolution sources by hand.
|
152
|
+
|
153
|
+
#### sources
|
154
|
+
|
155
|
+
The picture tag uses multiple source elements with individual `src` and `media` attributes. The first source with a matching `media` attribute will be used. Each `source_*` becomes a source element in HTML.
|
156
|
+
|
157
|
+
All sources must be prefixed with `source_`. A `source_default` is required. Source names can't contain the `.`, `:`, or `/` characters.
|
158
|
+
|
159
|
+
Remember to arrange your sources from most restrictive `media` to the least restrictive. `source_default` does not accept a `media` key, and should always be last.
|
160
|
+
|
161
|
+
#### media
|
162
|
+
|
163
|
+
Specify a CSS media query in quotes. Each source except for `source_default` requires a `media` attribute. The first source with a matching media attribute will be displayed. You can use any CSS media query.
|
164
|
+
|
165
|
+
#### width and height
|
166
|
+
|
167
|
+
Set a pixel width and height to resize each source's image appropriately. A single value will scale proportionately; setting both will scale and crop.
|
168
|
+
|
169
|
+
## Using Liquid variables and JavaScript templating
|
170
|
+
|
171
|
+
You can use liquid variables in a picture tag:
|
172
|
+
|
173
|
+
```html
|
174
|
+
{% picture {{ post.featured_image }} alt="our project" %}
|
175
|
+
```
|
176
|
+
|
177
|
+
If you're using a JavaScript templating library such as Handlebars.js, the templating expression's opening braces must be escaped with backslashes like `\{\{` or `\{\%`. They'll be output as normal `{{ }}` expressions in HTML:
|
178
|
+
|
179
|
+
```
|
180
|
+
{% picture {{ post.featured_image }} alt="\{\{ user_name }}" %}.
|
181
|
+
```
|
182
|
+
|
183
|
+
## Managing Generated Images
|
184
|
+
|
185
|
+
Jekyll Picture Tag creates resized versions of your images when you build the site. It uses a smart caching system to speed up site compilation, and re-uses images as much as possible.
|
186
|
+
|
187
|
+
Try to use a base image that is larger than the largest resized image you need. Jekyll Picture Tag will warn you if a base image is too small, and won't upscale images.
|
188
|
+
|
189
|
+
By specifying a `source` directory that is ignored by Jekyll you can prevent huge base images from being copied to the compiled site. For example, `source: assets/images/_fullsize` and `output: generated` will result in a compiled site that contains resized images but not the originals.
|
190
|
+
|
191
|
+
The `output` directory is never deleted by Jekyll. You may want to manually clean it every once in a while to remove unused images.
|
192
|
+
|
193
|
+
Responsive images are a good first step to improve performance, but you should still use a build process to optimize site assets before deploying. If you're a cool kid, take a look at [Yeoman](http://yeoman.io/) and [generator-jekyllrb](https://github.com/robwierzbowski/generator-jekyllrb).
|
194
|
+
|
195
|
+
## Contribute
|
196
|
+
|
197
|
+
Report bugs and feature proposals in the [Github issue tracker](https://github.com/robwierzbowski/jekyll-picture-tag/issues). In lieu of a formal styleguide, take care to maintain the existing coding style.
|
198
|
+
|
199
|
+
## Release History
|
200
|
+
|
201
|
+
0.2.2, Aug 2, 2013: Bugfixes.
|
202
|
+
0.2.1, July 17, 2013: Refactor again, add Liquid parsing.
|
203
|
+
0.2.0, July 14, 2013: Rewrite code base, bring in line with Jekyll Image Tag.
|
204
|
+
0.1.1, July 5, 2013: Quick round of code improvements.
|
205
|
+
0.1.0, July 5, 2013: Initial release.
|
206
|
+
|
207
|
+
## License
|
208
|
+
|
209
|
+
[BSD-NEW](http://en.wikipedia.org/wiki/BSD_License)
|
210
|
+
|
211
|
+
[](https://bitdeli.com/free "Bitdeli Badge")
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-picture-tag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Wierzbowski
|
8
|
+
- Brendan Tobolaski
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.8'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.8'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: mini_magick
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 3.8.0
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 3.8.0
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: fastimage
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.6.4
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.6.4
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: jekyll
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '3'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "<"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3'
|
84
|
+
description: |2
|
85
|
+
Jekyll Picture Tag is a liquid tag that adds responsive images to your Jekyll static site. It follows the picture
|
86
|
+
element pattern, and polyfills older browsers with Picturefill. Jekyll Picture Tag automatically creates resized
|
87
|
+
source images, is fully configurable, and covers all use cases — including art direction and resolution switching —
|
88
|
+
with a little YAML configuration and a simple template tag.
|
89
|
+
email:
|
90
|
+
- hello@robwierzbowski.com
|
91
|
+
- brendan@tobolaski.com
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- ".gitignore"
|
97
|
+
- Gemfile
|
98
|
+
- LICENSE.txt
|
99
|
+
- Rakefile
|
100
|
+
- bin/console
|
101
|
+
- bin/setup
|
102
|
+
- examples/_config.yml
|
103
|
+
- examples/layout.html
|
104
|
+
- examples/output.html
|
105
|
+
- examples/post.md
|
106
|
+
- jekyll-picture-tag.gemspec
|
107
|
+
- lib/jekyll-picture-tag.rb
|
108
|
+
- readme.md
|
109
|
+
homepage: https://github.com/robwierzbowski/jekyll-picture-tag
|
110
|
+
licenses:
|
111
|
+
- BSD-3-Clause
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.4.5
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Easy responsive images for Jekyll.
|
133
|
+
test_files: []
|