jekyll-auto-thumbnails 0.3.3 → 2.0.0

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: 9a8f6d099b2d5685d864827584c661c6583950e6e269fd8e7ca4bf7a3c9b21c1
4
- data.tar.gz: 36dddb91f054252e9591bc5428030370c5ec3fb8a3ad480920dee74d53a2422a
3
+ metadata.gz: f285f00df661aa19adac0316e235ad5ea58717b392be088295a457db9ded92bc
4
+ data.tar.gz: 92e7da98bbc220773e6247977815724733e5319b2ed9ad54dfe32a61c1a9cdfc
5
5
  SHA512:
6
- metadata.gz: f1c424f69eb58e7e3fbcf68835fe32e07b6967b5bd1d34e3712d955ece86d5301afa0a40714c0d7a3ef547a30afb93e5a580f1ef66d9d54446c240fc4c65a6a8
7
- data.tar.gz: 2deed4d50f48b3f57222d332130c882723f1dfc2fd82d537e428e9949b4dce1225f5b97ffe7a75eaddbaca52736dfdb3c13c833e62edd0f5a604a1727cf505a7
6
+ metadata.gz: 936bb03d186071967c2379bdfff539737602926eeff35776af90a29d32d102f9fc68dde50eb8aaeab12ee7c9c3a92501f00cd41746f2715d78e1cc1827d5f121
7
+ data.tar.gz: 06546f50fca9d6da941da5eccbae7577ed3e4167f34ebce3d670718ab070dcc6744bb4e94ff7f3950fdaca5474e520dcba976a76e05251f37e8d22eee7484bd3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.0](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v1.0.0...v2.0.0) (2026-04-24)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * Incorrectly round-tripped all content through HTML4 parser ([#30](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/30))
9
+
10
+ ### Bug Fixes
11
+
12
+ * **deps:** bump nokogiri from 1.19.0 to 1.19.1 in the production-deps group ([#20](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/20)) ([0ed6c0c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/0ed6c0cf65aa17ed0182ff7eb1f85d8b053188e1))
13
+ * **deps:** bump nokogiri from 1.19.1 to 1.19.2 in the production-deps group across 1 directory ([#24](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/24)) ([023882c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/023882c815b26f1d1143635c56f2adc78a124b85))
14
+ * **deps:** bump nokogiri in the production-deps group ([023882c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/023882c815b26f1d1143635c56f2adc78a124b85))
15
+ * **deps:** bump nokogiri in the production-deps group ([0ed6c0c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/0ed6c0cf65aa17ed0182ff7eb1f85d8b053188e1))
16
+ * Incorrectly round-tripped all content through HTML4 parser ([#30](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/30)) ([75640c8](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/75640c8c0de097e1ebb9e615e1acf8a00c0ef7e6))
17
+
18
+ ## [1.0.0](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v0.3.3...v1.0.0) (2026-01-18)
19
+
20
+
21
+ ### ⚠ BREAKING CHANGES
22
+
23
+ * standardize config across Jekyll gem repos ([#16](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/16))
24
+ * Drop ostensible support for Ruby 3.1; only 3.3+ is promised
25
+
26
+ ### Features
27
+
28
+ * standardize config across Jekyll gem repos ([#16](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/16)) ([3fa892b](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/3fa892b5a7c292eae2d58db9283acae99ec919dd))
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * **deps-dev:** bump rubocop from 1.81.7 to 1.82.0 in the dev-deps-minor-patch group ([#12](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/12)) ([965c63c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/965c63c3bd20737a81465e52f64f46ab8c2631e2))
34
+ * **deps-dev:** bump rubocop from 1.82.0 to 1.82.1 in the dev-deps-minor-patch group ([#14](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/14)) ([7cb95c7](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/7cb95c70a6982cd33ea5c76470417d1def5fb48f))
35
+ * **deps-dev:** bump rubocop in the dev-deps-minor-patch group ([7cb95c7](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/7cb95c70a6982cd33ea5c76470417d1def5fb48f))
36
+ * **deps-dev:** bump rubocop in the dev-deps-minor-patch group ([965c63c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/965c63c3bd20737a81465e52f64f46ab8c2631e2))
37
+ * **deps-dev:** bump rubocop-rspec from 3.8.0 to 3.9.0 in the dev-deps-minor-patch group ([#15](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/15)) ([65c2acc](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/65c2acc066b3566e24bed6bbbb2a3459f0664d5b))
38
+ * **deps-dev:** bump rubocop-rspec in the dev-deps-minor-patch group ([65c2acc](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/65c2acc066b3566e24bed6bbbb2a3459f0664d5b))
39
+ * **deps:** bump nokogiri from 1.18.10 to 1.19.0 in the production-deps group ([#17](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/17)) ([c3b213c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/c3b213c3f96b9b3fd452e3f63feca57f29ebf419))
40
+ * **deps:** bump nokogiri in the production-deps group ([c3b213c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/c3b213c3f96b9b3fd452e3f63feca57f29ebf419))
41
+ * **docs:** Tighten up gemspec description ([0b4d66e](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/0b4d66eab4bcdeed84ccea75b13245b0e5d99926))
42
+
43
+
44
+ ### Miscellaneous Chores
45
+
46
+ * standardize config across Jekyll gem repos ([3fa892b](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/3fa892b5a7c292eae2d58db9283acae99ec919dd))
47
+
3
48
  ## [0.3.3](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v0.3.2...v0.3.3) (2025-12-21)
4
49
 
5
50
 
data/README.md CHANGED
@@ -43,8 +43,25 @@ auto_thumbnails:
43
43
 
44
44
  # JPEG quality for generated thumbnails (0-100)
45
45
  quality: 85 # default: 85
46
+
47
+ # HTML parser used for scanning and rewriting.
48
+ # - html5 (default, CRuby only): standards-compliant, does not inject a
49
+ # <meta http-equiv="Content-Type"> when serializing.
50
+ # - html4: legacy libxml2-based parser; re-inserts the encoding meta tag
51
+ # on serialize. Required on JRuby.
52
+ parser: html5 # default: html5
46
53
  ```
47
54
 
55
+ ### HTML parser (`parser: html5 | html4`)
56
+
57
+ As of `v2.0.0`, `jekyll-auto-thumbnails` parses and serializes HTML with Nokogiri's HTML5 parser by default.
58
+
59
+ Set `parser: html4` to restore the previous behavior (the libxml2-based `Nokogiri::HTML` parser) if you depended on its serialization quirks.
60
+
61
+ **JRuby note**: `Nokogiri::HTML5` is not available on JRuby. Under JRuby, you **must** explicitly set `parser: html4`; otherwise the plugin will raise a configuration error at build time.
62
+
63
+ Pages that contain no replaceable `<article><img>` are no longer re-serialized at all - they are passed through byte-for-byte, regardless of which parser is selected.
64
+
48
65
  ## How It Works
49
66
 
50
67
  1. **HTML Scanning**: After all plugins run, scans `<article>` tags for images
@@ -10,11 +10,10 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = "Automatic image optimization for Jekyll sites"
12
12
  spec.description = "Jekyll plugin that automatically generates and serves optimized image thumbnails " \
13
- "for faster page loads. Scans rendered HTML, generates thumbnails with intelligent " \
14
- "caching, and seamlessly replaces img src attributes."
13
+ "for faster page loads."
15
14
  spec.homepage = "https://github.com/Texarkanine/jekyll-auto-thumbnails"
16
15
  spec.license = "AGPL-3.0-or-later"
17
- spec.required_ruby_version = ">= 3.1.0"
16
+ spec.required_ruby_version = ">= 3.3.0"
18
17
 
19
18
  spec.metadata["homepage_uri"] = spec.homepage
20
19
  spec.metadata["source_code_uri"] = "https://github.com/Texarkanine/jekyll-auto-thumbnails"
@@ -6,7 +6,9 @@ module JekyllAutoThumbnails
6
6
  # Parses Jekyll site config for auto_thumbnails options and provides
7
7
  # accessor methods with appropriate defaults and validation.
8
8
  class Configuration
9
- attr_reader :max_width, :max_height, :quality, :cache_dir
9
+ VALID_PARSERS = %i[html4 html5].freeze
10
+
11
+ attr_reader :max_width, :max_height, :quality, :cache_dir, :parser
10
12
 
11
13
  # Initialize configuration from Jekyll site
12
14
  #
@@ -18,6 +20,7 @@ module JekyllAutoThumbnails
18
20
  @max_width = parse_dimension(config_hash["max_width"])
19
21
  @max_height = parse_dimension(config_hash["max_height"])
20
22
  @quality = parse_quality(config_hash.fetch("quality", 85))
23
+ @parser = parse_parser(config_hash.fetch("parser", "html5"))
21
24
  @cache_dir = File.join(site.source, ".jekyll-cache", "jekyll-auto-thumbnails")
22
25
  end
23
26
 
@@ -47,5 +50,39 @@ module JekyllAutoThumbnails
47
50
  val = value.to_i
48
51
  val.between?(0, 100) ? val : 85
49
52
  end
53
+
54
+ # Parse and validate the HTML parser choice.
55
+ #
56
+ # Accepts "html4" or "html5" (case-insensitive). Raises on any other
57
+ # input so HTML correctness is never silently traded for availability.
58
+ # JRuby cannot use the HTML5 parser (Nokogiri::HTML5 is CRuby-only),
59
+ # so selecting it under JRuby also raises, directing the user to set
60
+ # `auto_thumbnails.parser: html4` explicitly.
61
+ #
62
+ # @param value [Object] parser value from config
63
+ # @return [Symbol] :html4 or :html5
64
+ # @raise [ArgumentError] for invalid values or JRuby + :html5
65
+ def parse_parser(value)
66
+ unless value.is_a?(String)
67
+ raise ArgumentError,
68
+ "auto_thumbnails: parser must be a string (\"html4\" or \"html5\"); got #{value.inspect}"
69
+ end
70
+
71
+ symbol = value.downcase.to_sym
72
+ unless VALID_PARSERS.include?(symbol)
73
+ raise ArgumentError,
74
+ "auto_thumbnails: parser must be one of #{VALID_PARSERS.join(", ")}; " \
75
+ "got #{value.inspect}"
76
+ end
77
+
78
+ if symbol == :html5 && RUBY_ENGINE == "jruby"
79
+ raise ArgumentError,
80
+ "auto_thumbnails: parser: html5 is not supported on JRuby " \
81
+ "(Nokogiri::HTML5 is CRuby-only). " \
82
+ "Set auto_thumbnails.parser: html4 in _config.yml to run on JRuby."
83
+ end
84
+
85
+ symbol
86
+ end
50
87
  end
51
88
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "html_parser"
4
+
3
5
  module JekyllAutoThumbnails
4
6
  # Jekyll hook integration
5
7
  module Hooks
@@ -72,7 +74,7 @@ module JekyllAutoThumbnails
72
74
  next unless doc.output
73
75
  next unless html_document?(doc)
74
76
 
75
- doc.output = replace_urls(doc.output, url_map)
77
+ doc.output = replace_urls(doc.output, url_map, parser: config.parser)
76
78
  end
77
79
 
78
80
  Jekyll.logger.info "AutoThumbnails:", "Generated #{url_map.size} thumbnails"
@@ -105,28 +107,37 @@ module JekyllAutoThumbnails
105
107
  Jekyll.logger.info "AutoThumbnails:", "All thumbnails copied"
106
108
  end
107
109
 
108
- # Replace image URLs in HTML
110
+ # Replace image URLs in HTML.
111
+ #
112
+ # Returns the input string unchanged (object identity) when no replacement
113
+ # was actually made. This is both a perf win for pages with no matching
114
+ # images and a correctness win: the HTML4 path otherwise round-trips every
115
+ # page through libxml2's serializer, which injects a spurious
116
+ # `<meta http-equiv="Content-Type">` on HTML5 sites.
109
117
  #
110
118
  # @param html [String] HTML content
111
119
  # @param url_map [Hash] original URL => thumbnail URL
112
- # @return [String] modified HTML
113
- def self.replace_urls(html, url_map)
114
- # Return early if no replacements needed
120
+ # @param parser [Symbol] :html5 (default) or :html4
121
+ # @return [String] modified HTML (or the input itself, unchanged)
122
+ def self.replace_urls(html, url_map, parser: :html5)
115
123
  return html if url_map.empty?
124
+ return html unless html.match?(/<img/i)
116
125
 
117
- doc = Nokogiri::HTML(html)
126
+ doc = HtmlParser.parse(html, parser)
118
127
 
128
+ modified = false
119
129
  doc.css("article img").each do |img|
120
130
  src = img["src"]
121
131
  next unless src
122
132
 
123
- # Find thumbnail URL for this image
124
133
  thumb_url = url_map[src]
125
- img["src"] = thumb_url if thumb_url
134
+ next unless thumb_url
135
+
136
+ img["src"] = thumb_url
137
+ modified = true
126
138
  end
127
139
 
128
- # Serialize with encoding declaration to match Jekyll output
129
- doc.to_html
140
+ modified ? doc.to_html : html
130
141
  end
131
142
 
132
143
  # Check if a document outputs HTML (not CSS, JS, etc.)
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+ # Nokogiri::HTML5 ships with Nokogiri on CRuby but is not available on JRuby.
5
+ # Configuration rejects `parser: :html5` under JRuby, so this require only
6
+ # needs to succeed on CRuby. On JRuby, the HTML4 branch is the only path
7
+ # that ever runs.
8
+ require "nokogiri/html5" unless RUBY_ENGINE == "jruby"
9
+
10
+ module JekyllAutoThumbnails
11
+ # Dispatch between Nokogiri's HTML5 and libxml2-based HTML4 parsers.
12
+ #
13
+ # HTML5 is the default throughout the gem; HTML4 is kept as an opt-in for
14
+ # users who depended on libxml2's serialization quirks (notably the
15
+ # injected `<meta http-equiv="Content-Type">`).
16
+ module HtmlParser
17
+ module_function
18
+
19
+ # Parse an HTML string with the selected parser.
20
+ #
21
+ # @param html [String] HTML source
22
+ # @param parser [Symbol] :html5 or :html4
23
+ # @return [Nokogiri::HTML5::Document, Nokogiri::HTML4::Document]
24
+ # @raise [ArgumentError] for an unknown parser symbol
25
+ # @raise [NameError] if :html5 is requested under JRuby (should be
26
+ # prevented by Configuration validation; this is a belt-and-suspenders
27
+ # guard)
28
+ def parse(html, parser)
29
+ case parser
30
+ when :html5
31
+ Nokogiri::HTML5.parse(html)
32
+ when :html4
33
+ Nokogiri::HTML(html)
34
+ else
35
+ raise ArgumentError, "Unknown HTML parser: #{parser.inspect}"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "nokogiri"
4
4
  require "open3"
5
+ require_relative "html_parser"
5
6
  require_relative "imagemagick_wrapper"
6
7
 
7
8
  module JekyllAutoThumbnails
@@ -14,7 +15,7 @@ module JekyllAutoThumbnails
14
15
  # @param config [Configuration] configuration
15
16
  # @param site_source [String] Jekyll site source (optional, for unsized image checking)
16
17
  def self.scan_html(html, registry, config, site_source = nil)
17
- doc = Nokogiri::HTML(html)
18
+ doc = HtmlParser.parse(html, config.parser)
18
19
 
19
20
  # Only process images in <article> tags
20
21
  doc.css("article img").each do |img|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllAutoThumbnails
4
- VERSION = "0.3.3"
4
+ VERSION = "2.0.0"
5
5
  end
@@ -4,6 +4,7 @@ require "jekyll"
4
4
  require "nokogiri"
5
5
 
6
6
  require_relative "jekyll-auto-thumbnails/version"
7
+ require_relative "jekyll-auto-thumbnails/html_parser"
7
8
  require_relative "jekyll-auto-thumbnails/configuration"
8
9
  require_relative "jekyll-auto-thumbnails/url_resolver"
9
10
  require_relative "jekyll-auto-thumbnails/digest_calculator"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-auto-thumbnails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Texarkanine
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-12-21 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
@@ -143,8 +142,7 @@ dependencies:
143
142
  - !ruby/object:Gem::Version
144
143
  version: '3.1'
145
144
  description: Jekyll plugin that automatically generates and serves optimized image
146
- thumbnails for faster page loads. Scans rendered HTML, generates thumbnails with
147
- intelligent caching, and seamlessly replaces img src attributes.
145
+ thumbnails for faster page loads.
148
146
  email:
149
147
  - texarkanine@protonmail.com
150
148
  executables: []
@@ -160,6 +158,7 @@ files:
160
158
  - lib/jekyll-auto-thumbnails/digest_calculator.rb
161
159
  - lib/jekyll-auto-thumbnails/generator.rb
162
160
  - lib/jekyll-auto-thumbnails/hooks.rb
161
+ - lib/jekyll-auto-thumbnails/html_parser.rb
163
162
  - lib/jekyll-auto-thumbnails/imagemagick_wrapper.rb
164
163
  - lib/jekyll-auto-thumbnails/registry.rb
165
164
  - lib/jekyll-auto-thumbnails/scanner.rb
@@ -173,7 +172,6 @@ metadata:
173
172
  source_code_uri: https://github.com/Texarkanine/jekyll-auto-thumbnails
174
173
  changelog_uri: https://github.com/Texarkanine/jekyll-auto-thumbnails/blob/main/CHANGELOG.md
175
174
  rubygems_mfa_required: 'true'
176
- post_install_message:
177
175
  rdoc_options: []
178
176
  require_paths:
179
177
  - lib
@@ -181,15 +179,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
179
  requirements:
182
180
  - - ">="
183
181
  - !ruby/object:Gem::Version
184
- version: 3.1.0
182
+ version: 3.3.0
185
183
  required_rubygems_version: !ruby/object:Gem::Requirement
186
184
  requirements:
187
185
  - - ">="
188
186
  - !ruby/object:Gem::Version
189
187
  version: '0'
190
188
  requirements: []
191
- rubygems_version: 3.3.27
192
- signing_key:
189
+ rubygems_version: 3.6.9
193
190
  specification_version: 4
194
191
  summary: Automatic image optimization for Jekyll sites
195
192
  test_files: []