jekyll_img 0.2.7 → 0.2.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ec131406e5dce078a0d63a5a821f73b8de66ece127990a8c3fa34a348c9d819
4
- data.tar.gz: ed9c9f00d0df3b50ea9409593ccc58fa6aca91d2e8c200a4ece28a8b3fc21aa3
3
+ metadata.gz: 2fceb334580b84bf7a4238093ab6fb718d1b5fc84a087b1f554764be2ddae477
4
+ data.tar.gz: b0a489a01ee502e0bb4c6006610a8d82faf3561086fa4f57ce752158e0b9770a
5
5
  SHA512:
6
- metadata.gz: 256b5e033e1f7ab3b08a0e37df0091eb39c67430397da6fb44745cd29e0dbc46fa104efe88b4230ca8d17ecb47014006ae11031895f14cf7031632e702f8cf0d
7
- data.tar.gz: 15a4431e31fdef70e180dc0a774f9a9eff410276768d42a7f3b727a72f1b1c30fd87a6242199ddf0898bb1e0fa17aa43ce70cf67b727b3981d85be1aa4ede188
6
+ metadata.gz: 14a147fe5e8ee74caffa3c4919d31fc28389ed9c4d5571357fc4797f1efaba10960eb2cefe9a3ebc68a85e76a339acdc9916d1191df11a2f9d1381412fff085a
7
+ data.tar.gz: 9e7b3b29ea91638fd8f54e5320c9fc14ceef0456057cbd40d7b1d5e9c6803cfa65a01c7c76567e147be5cefcf270ce9721c328e65944b8c873ae63591956a180
data/.rubocop.yml CHANGED
@@ -53,13 +53,13 @@ Metrics/BlockLength:
53
53
  - spec/img_props_spec.rb
54
54
 
55
55
  Metrics/CyclomaticComplexity:
56
- Max: 10
56
+ Max: 15
57
57
 
58
58
  Metrics/MethodLength:
59
59
  Max: 40
60
60
 
61
61
  Metrics/PerceivedComplexity:
62
- Max: 10
62
+ Max: 15
63
63
 
64
64
  Naming/FileName:
65
65
  Exclude:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.9 / 2025-05-19
4
+
5
+ * `max-width` option added.
6
+ * `width` option added as an alias for `size`.
7
+ This requires new CSS classes to be defined:
8
+ `max_eighthsize`, `max_fullsize`, `max_halfsize`, and `max_quartersize`.
9
+ * More CSS classes defined and more tests added to the Demo app to support `max-width`.
10
+ * `width='calc(something)'` added.
11
+
12
+
13
+ ## 0.2.8 / 2025-05-16
14
+
15
+ * An image can now be lazily loaded by providing the `lazy` keyword.
16
+ * An image can now be fetched with high priority by providing the `priority` keyword.
17
+
18
+
3
19
  ## 0.2.7 / 2024-09-11
4
20
 
5
21
  * Further tweaking of the generated HTML.
data/README.md CHANGED
@@ -100,6 +100,108 @@ the following would result in the same image being displayed:
100
100
  {% img src="./images/blah" %}
101
101
  ```
102
102
 
103
+ ### Lazy Loading
104
+
105
+ An image can be lazily loaded by providing the `lazy` keyword.
106
+ This feature relies upon the lazy loading capability built into all modern browsers and does not rely upon JavaScript.
107
+
108
+ From [Browser-level image lazy loading for the web](https://web.dev/articles/browser-level-image-lazy-loading#dimension-attributes)
109
+ on `web.dev`:
110
+
111
+ > While the browser loads an image, it doesn't immediately know the image's dimensions,
112
+ > unless they're explicitly specified.
113
+ > To let the browser reserve enough space on a page for images, and avoid disruptive layout shifts,
114
+ > we recommend adding width and height attributes to all tags.
115
+ >
116
+ > <img src="image.png" loading="lazy" alt="…" width="200" height="200">
117
+ Alternatively, specify their values directly in an inline style:
118
+ >
119
+ > <img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">
120
+
121
+ This would translate to:
122
+
123
+ ```html
124
+ {% img lazy
125
+ src="blah.webp"
126
+ style="height:200px; width:200px"
127
+ %}
128
+ ```
129
+
130
+ Note that the image must be fetched in order for HTML `img` attributes `height='auto'` and `width='auto'` to work.
131
+ Thus lazy loading is incompatible with a dimension whose value is specified as `auto`.
132
+ This means that, for lazily loaded images,
133
+ `height` and `width` must have values that are computable without loading the image.
134
+ Because the Jekyll `img` tag's `size` attribute only specifies the `width` attribute,
135
+ and sets `height` to `auto`, it should not be used with the `lazy` keyword.
136
+
137
+ The following examples of implicit and explicit `auto` dimensions will all give problems:
138
+
139
+ ```html
140
+ {% img lazy
141
+ caption="A warning will be written to the logger"
142
+ size="200px"
143
+ src="blah.webp"
144
+ %}
145
+
146
+ {% img lazy
147
+ src="blah.webp"
148
+ style="height:auto; width:200px"
149
+ %}
150
+
151
+ {% img lazy
152
+ src="blah.webp"
153
+ style="height:200px; width:auto"
154
+ %}
155
+
156
+ {% img lazy
157
+ src="blah.webp"
158
+ style="height:200px"
159
+ %}
160
+
161
+ {% img lazy
162
+ src="blah.webp"
163
+ style="width:200px"
164
+ %}
165
+ ```
166
+
167
+
168
+ ### High Priority Loading
169
+
170
+ An image can be fetched with high priority by providing the `priority` keyword.
171
+
172
+ Sample usage:
173
+
174
+ ```html
175
+ {% img priority src="blah.webp" %}
176
+ ```
177
+
178
+ The above generates an HTML `img` tag with a `fetchpriority='high'` attribute.
179
+
180
+ From [Browser-level image lazy loading for the web](https://web.dev/articles/browser-level-image-lazy-loading#loading-priority)
181
+ on `web.dev`:
182
+
183
+ > If you want to increase the fetch priority of an important image, use `fetchpriority="high"`.
184
+ >
185
+ > An image with `loading="lazy"` and `fetchpriority="high"` is still delayed while it's off-screen,
186
+ > and then fetched with a high priority when it's almost within the viewport.
187
+ > This combination isn't really necessary because the browser would likely load that image with high priority anyway.
188
+
189
+
190
+ Note that the image must be fetched in order for `img` attributes `height='auto'` and `width='auto'` to work.
191
+ This means that `height` and `width` must have values that are computable without loading
192
+ the image or lazy loading will not work properly.
193
+ Because the `img` tag's `size` attribute only specifies the `width` attribute, and sets `height` to `auto`,
194
+ it should not be used.
195
+
196
+ Sample usage combining lazy and high priority loading:
197
+
198
+ ```html
199
+ {% img lazy priority
200
+ src="blah.webp"
201
+ style="height:200px; width:200px"
202
+ %}
203
+ ```
204
+
103
205
 
104
206
  ## Supported Filetypes
105
207
 
@@ -147,12 +249,17 @@ $ demo/_bin/debug -r
147
249
  - `caption="A caption"` No default value
148
250
  - `classes="class1 class2 classN"` Extra <img> classes; default is `rounded shadow`
149
251
  - `id="someId"` No default value
150
- - `nofollow` Generates `rel='nofollow'`; only applicable when `url` is specified
151
- - `size='eighthsize|fullsize|halfsize|initial|quartersize|XXXYY|XXX%'`
252
+ - `max-width='eighthsize|fullsize|halfsize|initial|quartersize|XXXYY|XXX%'`
152
253
  Defines width of image.
153
254
  - `initial` is the default behavior.
154
255
  - `eighthsize`, `fullsize`, `halfsize`, and `quartersize` are relative to the enclosing tag's width.
155
256
  - CSS units can also be used, for those cases `XXX` is a float and `YY` is `unit` (see below)
257
+ - `nofollow` Generates `rel='nofollow'`; only applicable when `url` is specified
258
+ - `width='eighthsize|fullsize|halfsize|initial|quartersize|XXXYY|XXX%'`
259
+ Defines width of image (alias for `size`).
260
+ - `initial` is the default behavior.
261
+ - `eighthsize`, `fullsize`, `halfsize`, and `quartersize` are relative to the enclosing tag's width.
262
+ - CSS units can also be used, for those cases `XXX` is a float and `YY` is `unit` (see below)
156
263
  - `style='css goes here'` CSS style for <img>; no default
157
264
  - `target='none|whatever'` Only applicable when `url` is specified; default value is `_blank`
158
265
  - `title="A title"` Default value is `caption` text, if provided
@@ -212,8 +319,9 @@ Within the wrapper `<div />`, the embedded `<img />` is displayed with `width=10
212
319
  If a caption is required, the generated `<figure />` only makes the space taken by the generated HTML longer;
213
320
  the image&rsquo;s width and height are not affected.
214
321
 
215
- The wrapper will not exceed the width of the tag that encloses it if the `size` parameter has values
322
+ The wrapper will not exceed the width of the tag that encloses it if the `width` parameter has values
216
323
  `eighthsize`, `fullsize`, `halfsize`, `initial` or `quartersize`.
324
+ You can also use the `max-width` option.
217
325
 
218
326
  The wrapper's width can be defined independently of its enclosing tag by using
219
327
  [CSS units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#numbers_lengths_and_percentages)
@@ -226,7 +334,7 @@ Using CSS units means that large enough values could cause the image to exceed t
226
334
 
227
335
  ## Installation
228
336
 
229
- Add this line to your Jekyll project's Gemfile, within the `jekyll_plugins` group:
337
+ Add this line to your Jekyll project's `Gemfile`, within the `jekyll_plugins` group:
230
338
 
231
339
  ```ruby
232
340
  group :jekyll_plugins do
data/jekyll_img.gemspec CHANGED
@@ -3,11 +3,11 @@ require_relative 'lib/jekyll_img/version'
3
3
  Gem::Specification.new do |spec|
4
4
  github = 'https://github.com/mslinn/jekyll_img'
5
5
 
6
- spec.authors = ['Mike Slinn']
7
- spec.email = ['mslinn@mslinn.com']
8
- spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
6
+ spec.authors = ['Mike Slinn']
7
+ spec.email = ['mslinn@mslinn.com']
8
+ spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
9
9
  spec.homepage = 'https://www.mslinn.com/jekyll_plugins/jekyll_img.html'
10
- spec.license = 'MIT'
10
+ spec.license = 'MIT'
11
11
  spec.metadata = {
12
12
  'allowed_push_host' => 'https://rubygems.org',
13
13
  'bug_tracker_uri' => "#{github}/issues",
@@ -15,18 +15,20 @@ Gem::Specification.new do |spec|
15
15
  'homepage_uri' => spec.homepage,
16
16
  'source_code_uri' => github,
17
17
  }
18
- spec.name = 'jekyll_img'
18
+ spec.name = 'jekyll_img'
19
+ spec.platform = Gem::Platform::RUBY
19
20
  spec.post_install_message = <<~END_MESSAGE
20
21
 
21
22
  Thanks for installing #{spec.name}!
22
23
 
23
24
  END_MESSAGE
24
- spec.require_paths = ['lib']
25
+ spec.require_paths = ['lib']
25
26
  spec.required_ruby_version = '>= 2.6.0'
26
- spec.summary = 'Provides a Jekyll tag that generates images.'
27
- spec.test_files = spec.files.grep %r{^(test|spec|features)/}
28
- spec.version = JekyllImgVersion::VERSION
27
+ spec.summary = 'Provides a Jekyll tag that generates images.'
28
+ spec.test_files = spec.files.grep %r{^(test|spec|features)/}
29
+ spec.version = JekyllImgVersion::VERSION
29
30
 
30
31
  spec.add_dependency 'jekyll', '>= 3.5.0'
31
- spec.add_dependency 'jekyll_plugin_support', '>= 1.0.0'
32
+ spec.add_dependency 'jekyll_draft', '>= 3.0.0'
33
+ spec.add_dependency 'jekyll_plugin_support', '>= 3.0.0'
32
34
  end
data/lib/img_builder.rb CHANGED
@@ -11,11 +11,12 @@ end
11
11
 
12
12
  # Constructs HTML img tag from properties
13
13
  class ImgBuilder
14
- attr_reader :source
14
+ attr_reader :img, :props, :source
15
15
 
16
- def initialize(props)
17
- props.compute_dependant_properties
16
+ def initialize(img, props)
17
+ @img = img
18
18
  @props = props
19
+ @props.compute_dependant_properties
19
20
  @source = Source.new @props.src
20
21
  end
21
22
 
@@ -35,12 +36,24 @@ class ImgBuilder
35
36
  src="#{@source.src_fallback}"
36
37
  #{@props.attr_style_img}
37
38
  #{@props.attr_title}
39
+ #{@props.lazy}
40
+ #{@props.priority}
38
41
  />
39
42
  END_IMG
40
43
  end
41
44
 
42
45
  # See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture
43
46
  def generate_picture
47
+ if @props.lazy && (@props.size || @props.max_width)
48
+ @img.logger.warn do
49
+ <<~END_MSG.squish
50
+ Warning: lazy loading was specified, but the size or max_width attribute was specified for the href tag
51
+ on line #{@img.line_number} (after front matter) of #{@img.page['path']}.
52
+ Specify dimensions via style or class attributes instead.
53
+ END_MSG
54
+ end
55
+ end
56
+
44
57
  return generate_img if @props.src.start_with? 'http'
45
58
 
46
59
  # avif is not well supported yet
@@ -71,9 +84,11 @@ class ImgBuilder
71
84
  end
72
85
 
73
86
  def generate_wrapper
74
- classes = "imgWrapper #{@props.img_display} #{@props.align} #{@props.attr_size_class} #{@props.wrapper_class}".squish
87
+ classes = ("imgWrapper #{@props.img_display} #{@props.align} #{@props.attr_size_class} " +
88
+ "#{@props.attr_max_width_class} #{@props.wrapper_class}").squish
89
+ styles = "#{@props.attr_width_style} #{@props.attr_max_width_style} #{@props.wrapper_style}".squish
75
90
  <<~END_HTML.remove_blank_lines
76
- <div class='#{classes}' style='#{@props.attr_width_style} #{@props.wrapper_style}'>
91
+ <div class='#{classes}' style='#{styles}'>
77
92
  #{"<figure>\n" if @props.caption}
78
93
  #{@props.url ? generate_url_wrapper : generate_picture}
79
94
  #{generate_figcaption if @props.caption}
data/lib/img_props.rb CHANGED
@@ -6,8 +6,8 @@ require 'uri'
6
6
  # All methods except compute_dependant_properties can be called in any order
7
7
  class ImgProperties
8
8
  attr_accessor :align, :alt, :attr_wrapper_align_class, :attribute, :attribution, :caption, :classes, :die_on_img_error,
9
- :id, :img_display, :local_src, :nofollow, :src, :size, :style, :target, :title,
10
- :url, :wrapper_class, :wrapper_style
9
+ :id, :img_display, :lazy, :local_src, :max_width, :nofollow, :priority, :src, :size, :style,
10
+ :target, :title, :url, :wrapper_class, :wrapper_style
11
11
 
12
12
  SIZES = %w[eighthsize fullsize halfsize initial quartersize].freeze
13
13
  UNITS = %w[Q ch cm em dvh dvw ex in lh lvh lvw mm pc px pt rem rlh svh svw vb vh vi vmax vmin vw %].freeze
@@ -29,6 +29,16 @@ class ImgProperties
29
29
  " rel='nofollow'" if @nofollow
30
30
  end
31
31
 
32
+ def attr_max_width_class
33
+ return nil if @max_width == false || @max_width.nil? || max_width_unit_specified?
34
+
35
+ unless SIZES.include?(@max_width)
36
+ msg = "'#{@max_width}' is not a recognized size; must be one of #{SIZES.join(', ')}, or an explicit unit."
37
+ raise Jekyll::ImgError, msg
38
+ end
39
+ "max_#{@max_width}"
40
+ end
41
+
32
42
  def attr_size_class
33
43
  return nil if @size == false || @size.nil? || size_unit_specified?
34
44
 
@@ -54,6 +64,10 @@ class ImgProperties
54
64
  "title='#{@title}'" if @title && !@title.empty?
55
65
  end
56
66
 
67
+ def attr_max_width_style
68
+ "max-width: #{@max_width};" if max_width_unit_specified?
69
+ end
70
+
57
71
  def attr_width_style
58
72
  "width: #{@size};" if size_unit_specified?
59
73
  end
@@ -98,10 +112,18 @@ class ImgProperties
98
112
  # raise Jekyll::ImgError, "#{@src} does not exist" unless File.exist?(src)
99
113
  end
100
114
 
115
+ def max_width_unit_specified?
116
+ max_width_not_specified = @max_width == false || @max_width.to_s.strip.empty?
117
+ return false if max_width_not_specified
118
+
119
+ @max_width&.end_with?(*UNITS) || @max_width&.start_with?('calc')
120
+ end
121
+
101
122
  def size_unit_specified?
102
- return false if @size == false || @size.to_s.strip.empty?
123
+ size_not_specified = @size == false || @size.to_s.strip.empty?
124
+ return false if size_not_specified
103
125
 
104
- @size.end_with?(*UNITS)
126
+ @size&.end_with?(*UNITS) || @size&.start_with?('calc')
105
127
  end
106
128
 
107
129
  def url?(src)
@@ -1,3 +1,3 @@
1
1
  module JekyllImgVersion
2
- VERSION = '0.2.7'.freeze
2
+ VERSION = '0.2.9'.freeze
3
3
  end
data/lib/jekyll_img.rb CHANGED
@@ -35,8 +35,13 @@ module Jekyll
35
35
  props.classes = @helper.parameter_specified? 'class'
36
36
  props.die_on_img_error = @die_on_img_error
37
37
  props.id = @helper.parameter_specified? 'id'
38
+ props.lazy = ' loading="lazy"' if @helper.parameter_specified?('lazy')
39
+ props.max_width = @helper.parameter_specified?('max-width')
38
40
  props.nofollow = @helper.parameter_specified? 'nofollow'
39
- props.size = @helper.parameter_specified?('size') || @helper.parameter_specified?('_size')
41
+ props.priority = ' fetchpriority="high"' if @helper.parameter_specified?('priority')
42
+ props.size = @helper.parameter_specified?('size') ||
43
+ @helper.parameter_specified?('_size') ||
44
+ @helper.parameter_specified?('width')
40
45
  props.src = @helper.parameter_specified? 'src'
41
46
  props.style = @helper.parameter_specified? 'style'
42
47
  props.target = @helper.parameter_specified? 'target'
@@ -45,7 +50,7 @@ module Jekyll
45
50
  props.wrapper_class = @helper.parameter_specified? 'wrapper_class'
46
51
  props.wrapper_style = @helper.parameter_specified? 'wrapper_style'
47
52
 
48
- @builder = ImgBuilder.new(props)
53
+ @builder = ImgBuilder.new(self, props)
49
54
  @builder.to_s
50
55
  rescue ImgError => e # jekyll_plugin_support handles StandardError
51
56
  @logger.error { e.logger_message }
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll_img
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Slinn
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-09-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: jekyll
@@ -24,21 +23,34 @@ dependencies:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
25
  version: 3.5.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: jekyll_draft
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 3.0.0
27
40
  - !ruby/object:Gem::Dependency
28
41
  name: jekyll_plugin_support
29
42
  requirement: !ruby/object:Gem::Requirement
30
43
  requirements:
31
44
  - - ">="
32
45
  - !ruby/object:Gem::Version
33
- version: 1.0.0
46
+ version: 3.0.0
34
47
  type: :runtime
35
48
  prerelease: false
36
49
  version_requirements: !ruby/object:Gem::Requirement
37
50
  requirements:
38
51
  - - ">="
39
52
  - !ruby/object:Gem::Version
40
- version: 1.0.0
41
- description:
53
+ version: 3.0.0
42
54
  email:
43
55
  - mslinn@mslinn.com
44
56
  executables: []
@@ -89,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
101
  - !ruby/object:Gem::Version
90
102
  version: '0'
91
103
  requirements: []
92
- rubygems_version: 3.5.17
93
- signing_key:
104
+ rubygems_version: 3.7.1
94
105
  specification_version: 4
95
106
  summary: Provides a Jekyll tag that generates images.
96
107
  test_files: