Module: JekyllHighlightCards::ImageSizingHooks

Defined in:
lib/jekyll-highlight-cards/image_sizing_hooks.rb

Overview

Examples:

Basic sizing

![Photo](image.jpg =300x200)

Width only

![Photo](image.jpg =400x)

Height only

![Photo](image.jpg =x300)

Constant Summary collapse

SIZED_MARKDOWN_PATTERN =

Process document content before rendering Converts ![alt](src =WxH) to alt

/!\[([^\]]*)\]\(([^)]+)[ \t]+=([^)]+)\)/
SIZED_IMG_HTML_PATTERN =
/(\s*)(<img[ \t]+[^>]*>)\s*<!--\s*IMG_SIZE:([^:]*):([^:]*)\s*-->/

Class Method Summary collapse

Class Method Details

.backtick_count_before(line, position) ⇒ Integer

Count backtick characters before a position in a line

Parameters:

  • line (String)

    the line of text

  • position (Integer)

    the position in the line

Returns:

  • (Integer)

    number of backticks before position



157
158
159
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 157

def self.backtick_count_before(line, position)
  line[0, position].count("`")
end

.fence_count_before(lines, line_idx) ⇒ Object



136
137
138
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 136

def self.fence_count_before(lines, line_idx)
  lines.first(line_idx).count { |line| line.start_with?("```", "~~~") }
end


41
42
43
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 41

def self.img_link_prefix(output, match)
  output[0, match.begin(2)]
end

.in_code_fence?(lines, line_idx) ⇒ Boolean

Check if a line is inside a code fence

Parameters:

  • lines (Array<String>)

    all lines in the document

  • line_idx (Integer)

    the current line index

Returns:

  • (Boolean)

    true if inside code fence



145
146
147
148
149
150
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 145

def self.in_code_fence?(lines, line_idx)
  return true if fence_count_before(lines, line_idx).odd?
  return false unless line_idx.positive?

  lines.slice(line_idx).start_with?("    ", "\t")
end

.in_inline_code?(line, position) ⇒ Boolean

Check if text position is inside inline code

Parameters:

  • line (String)

    the line of text

  • position (Integer)

    the position in the line

Returns:

  • (Boolean)

    true if inside inline code



166
167
168
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 166

def self.in_inline_code?(line, position)
  backtick_count_before(line, position).odd?
end

.markdown_inline_check_position(full_match) ⇒ Object



37
38
39
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 37

def self.markdown_inline_check_position(full_match)
  full_match.begin(0)
end

.process_post_render(document) ⇒ Object

Process document content after rendering Applies width/height attributes and auto-links sized images

Parameters:

  • document (Jekyll::Document)

    the document being processed



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 94

def self.process_post_render(document)
  output = document.output
  return unless output

  # Duplicate to avoid frozen string errors
  output = output.dup

  # Match <img><!-- IMG_SIZE:W:H --> patterns
  output.gsub!(SIZED_IMG_HTML_PATTERN) do
    match = Regexp.last_match
    img_tag = match[2]
    width = match[3].strip
    height = match[4].strip

    attrs = []
    attrs << %(width="#{width}") unless width.empty?
    attrs << %(height="#{height}") unless height.empty?

    modified_img = if attrs.any?
                     img_tag.sub("<img", "<img #{attrs.join(" ")}")
                   else
                     img_tag
                   end

    src = img_tag[/src=["']([^"']+)["']/, 1]
    next modified_img if src.nil?

    prefix = img_link_prefix(output, match)

    already_linked = unclosed_anchor_count(prefix).positive?

    # Auto-link if not already linked
    if already_linked
      modified_img
    else
      %(<a href="#{CGI.escapeHTML(CGI.unescapeHTML(src))}">#{modified_img}</a>)
    end
  end

  document.output = output
end

.process_pre_render(document) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 45

def self.process_pre_render(document)
  content = document.content
  return unless content

  lines = content.lines
  result = []

  lines.each_with_index do |line, idx|
    # Skip lines in code fences
    if in_code_fence?(lines, idx)
      result << line
      next
    end

    # Process the line to convert sized images
    processed_line = line

    # Match ![alt](src =dimensions) pattern
    # Use gsub with block to check each match
    processed_line.gsub!(SIZED_MARKDOWN_PATTERN) do |match|
      full_match = Regexp.last_match
      match_start = markdown_inline_check_position(full_match)

      # Skip if inside inline code
      if in_inline_code?(line, match_start)
        match
      else
        alt = full_match[1]
        src = full_match[2].strip
        size = full_match[3].strip

        # Parse dimensions using DimensionParser
        width, height = DimensionParser.parse_dimensions(size)

        # Build marker comment
        "![#{alt}](#{src})<!-- IMG_SIZE:#{width}:#{height} -->"
      end
    end

    result << processed_line
  end

  document.content = result.join
end

.unclosed_anchor_count(prefix) ⇒ Integer

Returns unclosed anchor tags in prefix.

Parameters:

  • prefix (String)

    HTML preceding an image tag

Returns:

  • (Integer)

    unclosed anchor tags in prefix



33
34
35
# File 'lib/jekyll-highlight-cards/image_sizing_hooks.rb', line 33

def self.unclosed_anchor_count(prefix)
  prefix.scan("<a ").length + prefix.scan("<a\t").length - prefix.scan("</a>").length
end