jekyll-picture-tag 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/robwierzbowski/jekyll-picture-tag/trend.png)](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: []
|