Module: JekyllRelativeLinks::Hooks

Defined in:
lib/jekyll-relative-links/hooks.rb

Constant Summary collapse

CONVERTER_CLASS =
Jekyll::Converters::Markdown
CONFIG_KEY =
"relative_links"
ENABLED_KEY =
"enabled"
COLLECTIONS_KEY =
"collections"
%r!<a\s+([^>]*?\s+)?href="([^"]+\.md)(#[^"]*)?"\s*([^>]*)>!m.freeze

Class Method Summary collapse

Class Method Details

.collections_enabled?(config) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/jekyll-relative-links/hooks.rb', line 51

def self.collections_enabled?(config)
  config[CONFIG_KEY] && config[CONFIG_KEY][COLLECTIONS_KEY] == true
end

.disabled?(config) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/jekyll-relative-links/hooks.rb', line 47

def self.disabled?(config)
  config[CONFIG_KEY] && config[CONFIG_KEY][ENABLED_KEY] == false
end

.excluded?(document, config, site) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/jekyll-relative-links/hooks.rb', line 60

def self.excluded?(document, config, site)
  return false unless config[CONFIG_KEY] && config[CONFIG_KEY]["exclude"]

  entry_filter = if document.respond_to?(:collection)
                   document.collection.entry_filter
                 else
                   Jekyll::EntryFilter.new(site)
                 end

  entry_filter.glob_include?(config[CONFIG_KEY]["exclude"], document.relative_path)
end

.markdown_extension?(extension, site) ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
58
# File 'lib/jekyll-relative-links/hooks.rb', line 55

def self.markdown_extension?(extension, site)
  converter = site.find_converter_instance(CONVERTER_CLASS)
  converter.matches(extension)
end

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
# File 'lib/jekyll-relative-links/hooks.rb', line 73

def self.process_html_links(html, document, site)
  return html if html.nil? || html.empty?

  url_base = File.dirname(document.relative_path)
  potential_targets = site.pages + site.static_files + site.docs_to_write

  # Process <a href="*.md"> links that were added via includes
  # rubocop:disable Metrics/BlockLength
  html.gsub(MARKDOWN_LINK_IN_HTML) do |match|
    attributes_before = Regexp.last_match[1] || ""
    relative_path = Regexp.last_match[2]
    fragment = Regexp.last_match[3] || ""
    attributes_after = Regexp.last_match[4] || ""

    # Skip absolute URLs
    begin
      next match if Addressable::URI.parse(relative_path).absolute?
    rescue Addressable::URI::InvalidURIError
      next match
    end

    # Calculate path from root
    is_absolute = relative_path.start_with?("/")
    relative_path_clean = relative_path.delete_prefix("/")
    base = is_absolute ? "" : url_base
    absolute_path = File.expand_path(relative_path_clean, base)
    path = absolute_path.sub(%r!\A#{Regexp.escape(Dir.pwd)}/!, "")

    # Find the target page and get its URL
    path = CGI.unescape(path)
    target = potential_targets.find { |p| p.relative_path.delete_prefix("/") == path }

    if target&.url
      # Use Jekyll's URL
      url = target.url
      url = "/#{url}" unless url.start_with?("/")

      # Build the replacement ensuring proper spacing
      attrs = []
      attrs << attributes_before.strip unless attributes_before.empty?
      attrs << "href=\"#{url}#{fragment}\""
      attrs << attributes_after.strip unless attributes_after.empty?
      "<a #{attrs.join(" ")}>"
    else
      match
    end
  end
  # rubocop:enable Metrics/BlockLength
end

.should_process?(page, config) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
# File 'lib/jekyll-relative-links/hooks.rb', line 30

def self.should_process?(page, config)
  return false if disabled?(config)
  return false unless markdown_extension?(page.extname, page.site)
  return false if excluded?(page, config, page.site)

  true
end

.should_process_document?(document, config) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
# File 'lib/jekyll-relative-links/hooks.rb', line 38

def self.should_process_document?(document, config)
  return false if disabled?(config)
  return false unless collections_enabled?(config)
  return false unless markdown_extension?(document.extname, document.site)
  return false if excluded?(document, config, document.site)

  true
end