Module: JekyllAutoThumbnails::Scanner

Defined in:
lib/jekyll-auto-thumbnails/scanner.rb

Overview

HTML scanning for images

Class Method Summary collapse

Class Method Details

.calculate_dimensions(url, width, height, site_source) ⇒ Array<Integer, Integer>

Calculate missing dimension based on aspect ratio

Parameters:

  • url (String)

    image URL

  • width (Integer, nil)

    specified width

  • height (Integer, nil)

    specified height

  • site_source (String)

    site source directory

Returns:

  • (Array<Integer, Integer>)

    [width, height] with calculated dimension



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 92

def self.calculate_dimensions(url, width, height, site_source)
  file_path = UrlResolver.to_filesystem_path(url, site_source)
  return [width, height] unless file_path && File.exist?(file_path)

  actual_width, actual_height = image_dimensions(file_path)
  return [width, height] unless actual_height

  # Calculate missing dimension preserving aspect ratio
  if width && !height
    # Width specified, calculate height
    aspect_ratio = actual_height.to_f / actual_width
    height = (width * aspect_ratio).round
  elsif height && !width
    # Height specified, calculate width
    aspect_ratio = actual_width.to_f / actual_height
    width = (height * aspect_ratio).round
  end

  [width, height]
end

.check_and_register_oversized(url, registry, config, site_source) ⇒ Object

Check if image exceeds max dimensions and register if so

Parameters:

  • url (String)

    image URL

  • registry (Registry)

    image registry

  • config (Configuration)

    configuration

  • site_source (String)

    site source directory



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 51

def self.check_and_register_oversized(url, registry, config, site_source)
  file_path = UrlResolver.to_filesystem_path(url, site_source)
  return unless file_path && File.exist?(file_path)

  actual_width, actual_height = image_dimensions(file_path)
  return unless actual_height

  # Check if exceeds max dimensions
  exceeds_width = config.max_width && actual_width > config.max_width
  exceeds_height = config.max_height && actual_height > config.max_height

  return unless exceeds_width || exceeds_height

  # Register with max dimensions (preserving aspect ratio logic in Generator)
  registry.register(url, config.max_width, config.max_height)
end

.dimensions_match_original?(url, width, height, site_source) ⇒ Boolean

Check if requested dimensions match original dimensions

Parameters:

  • url (String)

    image URL

  • width (Integer)

    requested width

  • height (Integer)

    requested height

  • site_source (String)

    site source directory

Returns:

  • (Boolean)

    true if dimensions match original



132
133
134
135
136
137
138
139
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 132

def self.dimensions_match_original?(url, width, height, site_source)
  file_path = UrlResolver.to_filesystem_path(url, site_source)
  return false unless file_path && File.exist?(file_path)

  actual_width, actual_height = image_dimensions(file_path)

  width == actual_width && height == actual_height
end

.image_dimensions(file_path) ⇒ Array<Integer, Integer>?

Get image dimensions from file

Parameters:

  • file_path (String)

    path to image file

Returns:

  • (Array<Integer, Integer>, nil)

    [width, height] or nil



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 72

def self.image_dimensions(file_path)
  # Use ImageMagick identify command (shell-free, cross-platform)
  # Use [0] to get only first frame (important for animated GIFs)
  # Wrapper handles both ImageMagick v6 and v7
  output, status = ImageMagickWrapper.execute_identify("-format", "%wx%h", "#{file_path}[0]")
  return nil unless status.success?

  match = output.match(/\A\s*(\d+)x(\d+)\s*\z/)
  [Integer(match[1]), Integer(match[2])]
rescue StandardError
  nil
end

.parse_dimension(value) ⇒ Integer?

Parse dimension attribute (width or height)

Parameters:

  • value (String, nil)

    attribute value

Returns:

  • (Integer, nil)

    parsed integer or nil



117
118
119
120
121
122
123
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 117

def self.parse_dimension(value)
  # Strip non-numeric characters (e.g., "300px" -> 300)
  numeric = value.to_s.gsub(/[^\d]/, "")
  return nil if numeric.empty?

  Integer(numeric)
end

.scan_html(html, registry, config, site_source = nil) ⇒ Object

Scan HTML for images needing optimization

Parameters:

  • html (String)

    HTML content

  • registry (Registry)

    image registry

  • config (Configuration)

    configuration

  • site_source (String) (defaults to: nil)

    Jekyll site source (optional, for unsized image checking)



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/jekyll-auto-thumbnails/scanner.rb', line 17

def self.scan_html(html, registry, config, site_source = nil)
  doc = HtmlParser.parse(html, config.parser)

  # Only process images in <article> tags
  doc.css("article img").each do |img|
    src = img["src"]
    next unless src
    next if UrlResolver.external?(src)

    # Check for explicit dimensions
    width = parse_dimension(img["width"])
    height = parse_dimension(img["height"])

    if width || height
      # Only identify for aspect-ratio fill when a dimension is missing
      width, height = calculate_dimensions(src, width, height, site_source) if site_source && (!width || !height)

      # Skip if dimensions match original (no thumbnail needed)
      next if site_source && dimensions_match_original?(src, width, height, site_source)

      registry.register(src, width, height)
    elsif site_source && (config.max_width || config.max_height)
      # Unsized but max config exists - check actual dimensions
      check_and_register_oversized(src, registry, config, site_source)
    end
  end
end