jekyll-auto-thumbnails 1.0.0 → 2.0.1

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: 69d56f34b0465c7143f8785a0426c2bac56a268b633b64d901d1365c6baab476
4
- data.tar.gz: ec8b83991caa1e78aadf337e4ef9ff09c0f480767e6052abe74706e020197a38
3
+ metadata.gz: d593b4ae0f39bd0020f6656a021327666afa8ee4776a2147d36ce3f8283a1840
4
+ data.tar.gz: af035e37d27382e9a8d1d15b20ea14e3a0994f2fe1d1ff312c09b4dac924829f
5
5
  SHA512:
6
- metadata.gz: c280d35426d31fa2b9d062b085f482622a8162127d4ddad31b48d0173698067405dd00f6ab40c422a02b84444278a8b888622a6cf58b2fee6c48573f6e421d4d
7
- data.tar.gz: b0f71661e914d71dff921f6b802c425a80e3ef7289263aff18686cb61b3299059e8a2733045ee26f9ba2d42aab2e0e26ce0ecb61f5ed3021ee62e61a3432d7b0
6
+ metadata.gz: 89945f98a6e83a64ec2d4f20b96e827d4e408ffdda0f3340da9e99086ef156ef146a6617db1f3cb1ba7de8f34d4790f47783924fc3e02afb5e1f9a9c90506d33
7
+ data.tar.gz: 0b0a29fc0985c1a1930f2b1a644ed574fb4abae81fe52f0722b0a329c2731020e7cc915b7fdf8155b63e1767f2227ac409a5e2697152648d61cdca6816f59582
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.1](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v2.0.0...v2.0.1) (2026-05-14)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **deps:** bump addressable from 2.8.8 to 2.9.0 ([#31](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/31)) ([e4c0312](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/e4c03124bbe1bb18183b0ffec1039cdc4f4cefb1))
9
+ * **deps:** bump nokogiri from 1.19.2 to 1.19.3 in the production-deps group ([#34](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/34)) ([1248eb3](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/1248eb3b81b3269210fa7d1e2fc98928803030ce))
10
+ * **deps:** bump nokogiri in the production-deps group ([1248eb3](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/1248eb3b81b3269210fa7d1e2fc98928803030ce))
11
+
12
+ ## [2.0.0](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v1.0.0...v2.0.0) (2026-04-24)
13
+
14
+
15
+ ### ⚠ BREAKING CHANGES
16
+
17
+ * Incorrectly round-tripped all content through HTML4 parser ([#30](https://github.com/Texarkanine/jekyll-auto-thumbnails/issues/30))
18
+
19
+ ### Bug Fixes
20
+
21
+ * **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))
22
+ * **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))
23
+ * **deps:** bump nokogiri in the production-deps group ([023882c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/023882c815b26f1d1143635c56f2adc78a124b85))
24
+ * **deps:** bump nokogiri in the production-deps group ([0ed6c0c](https://github.com/Texarkanine/jekyll-auto-thumbnails/commit/0ed6c0cf65aa17ed0182ff7eb1f85d8b053188e1))
25
+ * 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))
26
+
3
27
  ## [1.0.0](https://github.com/Texarkanine/jekyll-auto-thumbnails/compare/v0.3.3...v1.0.0) (2026-01-18)
4
28
 
5
29
 
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
@@ -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
@@ -83,7 +83,7 @@ module JekyllAutoThumbnails
83
83
  #
84
84
  # @param cmd [String] command name
85
85
  # @return [Boolean] true if command found
86
- def self.command_exists?(cmd)
86
+ private_class_method def self.command_exists?(cmd)
87
87
  cmd_name = Gem.win_platform? ? "#{cmd}.exe" : cmd
88
88
  path_dirs = ENV["PATH"].to_s.split(File::PATH_SEPARATOR)
89
89
 
@@ -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 = "1.0.0"
4
+ VERSION = "2.0.1"
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-auto-thumbnails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Texarkanine
@@ -158,6 +158,7 @@ files:
158
158
  - lib/jekyll-auto-thumbnails/digest_calculator.rb
159
159
  - lib/jekyll-auto-thumbnails/generator.rb
160
160
  - lib/jekyll-auto-thumbnails/hooks.rb
161
+ - lib/jekyll-auto-thumbnails/html_parser.rb
161
162
  - lib/jekyll-auto-thumbnails/imagemagick_wrapper.rb
162
163
  - lib/jekyll-auto-thumbnails/registry.rb
163
164
  - lib/jekyll-auto-thumbnails/scanner.rb