jekyll-link-decorator 1.0.3 → 1.1.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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jekyll-link-decorator.rb +46 -28
  3. metadata +21 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0f9b808eb1a08ff1ec662bbe580907599e65a41f0841dcd1fc00afd753b4964
4
- data.tar.gz: f013b30a4b34f9da6e30ff10f5d305513f2b2b7a8ef675ff3630a665ce069e58
3
+ metadata.gz: 619db9eef6ac8d8df96816793e684628c919b41447b01b3378035d927df5500d
4
+ data.tar.gz: 69048aacba831a96a6234cd29075b1056840ac75486c872ea82a6cfabc6b3ebe
5
5
  SHA512:
6
- metadata.gz: 1c3f7778766e27f923060547092f58a3632e46caacb21aeaa0a6c027465ef3c6fd3cf17064379cbe00c10c608a4f2c91c195096816be71bcdd40551a4e21475d
7
- data.tar.gz: 97643a1ee4b81a731e9b7f23341f30f38db54de807c94fe54322413e20877e4c675d36863dcd9f69471942706b504c401280977786148c5dd04d77313e40c131
6
+ metadata.gz: 5c3123e6476a23b53171051a05cbafc6e936d945a62ae9738c9248469bd46e3fd6511bea3b4d5aa7b88e4a0e40551a42e6c42024006e4050a8f563d45dd72d86
7
+ data.tar.gz: 4204292972a14bf0c734c713bd2ab1dde5c65216239ef1c79ce67d2fbd297c44aa286a637bbebc89cc762efe16ea1d933ad4b19e4cce8349e52069267ff67b75
@@ -52,6 +52,14 @@
52
52
 
53
53
  require 'nokogiri'
54
54
 
55
+ EXISTING_ICON_SELECTORS = [
56
+ 'i[class*="fa-external-link"]',
57
+ 'i[class*="up-right-from-square"]',
58
+ 'svg[data-icon="external-link"]',
59
+ 'svg[data-icon="up-right-from-square"]',
60
+ 'svg[data-icon="arrow-up-right-from-square"]'
61
+ ].freeze
62
+
55
63
  module Jekyll
56
64
  module Converters
57
65
  # This custom converter applies specific CSS classes to <a> tags
@@ -59,6 +67,11 @@ module Jekyll
59
67
  # buttons, all done via Nokogiri's powerful CSS selectors.
60
68
  # It also adds external-link icons for cross-domain external links.
61
69
  class LinkDecorator < Jekyll::Converters::Markdown
70
+ DEFAULT_LINK_CLASSES = 'link link-offset-3 link-offset-3-hover link-underline-primary ' \
71
+ 'link-underline-opacity-0 link-underline-opacity-100-hover'
72
+ DEFAULT_ALERT_CLASSES = 'alert-link'
73
+ DEFAULT_EXTERNAL_LINK_ICON = true
74
+
62
75
  def self.name
63
76
  'LinkDecorator'
64
77
  end
@@ -84,28 +97,24 @@ module Jekyll
84
97
  # - Link domain is different from site.url domain
85
98
  # - Link doesn't already have an external-link icon child
86
99
  def is_external_different_domain_link?(link, site_domain)
87
- href = link['href'].to_s
100
+ return false unless absolute_different_domain?(link, site_domain)
101
+ return false if EXISTING_ICON_SELECTORS.any? { |sel| link.css(sel).any? }
102
+
103
+ true
104
+ end
88
105
 
89
- # Check if it's an absolute URL with http/https
106
+ # Returns true when href is an absolute http(s) URL pointing to a domain
107
+ # different from site_domain. Shared guard used by both domain-check methods.
108
+ def absolute_different_domain?(link, site_domain)
109
+ href = link['href'].to_s
90
110
  return false unless %r{^https?://}.match?(href)
91
111
 
92
- # Extract domain from the link
93
112
  link_domain = extract_domain(href)
94
-
95
- # Check if domains are different
96
113
  return false if link_domain == site_domain || link_domain.empty?
97
114
 
98
- # Check if an icon has already been added (avoid duplicates)
99
- # Check for both new icons (fa-external-link) and old icons
100
- # (fa-external-link-alt, fa-up-right-from-square, etc.)
101
- return false if link.css('i[class*="fa-external-link"]').any?
102
- return false if link.css('i[class*="up-right-from-square"]').any?
103
- return false if link.css('svg[data-icon="external-link"]').any?
104
- return false if link.css('svg[data-icon="up-right-from-square"]').any?
105
- return false if link.css('svg[data-icon="arrow-up-right-from-square"]').any?
106
-
107
115
  true
108
116
  end
117
+ private :absolute_different_domain?
109
118
 
110
119
  # Determine if a link points to an external domain
111
120
  # Returns true if:
@@ -120,16 +129,7 @@ module Jekyll
120
129
  # Relative URLs (starting with / or ../) are internal links
121
130
  return false if %r{^(/|\.\.)}.match?(href)
122
131
 
123
- # Check if it's an absolute URL with http/https
124
- return false unless %r{^https?://}.match?(href)
125
-
126
- # Extract domain from the link
127
- link_domain = extract_domain(href)
128
-
129
- # Check if domains are different
130
- return false if link_domain == site_domain || link_domain.empty?
131
-
132
- true
132
+ absolute_different_domain?(link, site_domain)
133
133
  end
134
134
 
135
135
  # Add target="_blank" to external cross-domain links
@@ -175,6 +175,10 @@ module Jekyll
175
175
 
176
176
  def convert(content)
177
177
  html = super
178
+ decorate_html(html)
179
+ end
180
+
181
+ def decorate_html(html)
178
182
  enabled = @config.key?('with_link_decorator') ? @config['with_link_decorator'] : true
179
183
  config = @config['with_link_decorator_data'] || {}
180
184
 
@@ -206,9 +210,8 @@ module Jekyll
206
210
 
207
211
  # Apply CSS classes to links based on their context (alert or default)
208
212
  def apply_link_styles(doc, config)
209
- default_classes = config.fetch('default_link_classes',
210
- 'link link-offset-3 link-offset-3-hover link-underline-primary link-underline-opacity-0 link-underline-opacity-100-hover')
211
- alert_classes = config.fetch('alert_link_classes', 'alert-link')
213
+ default_classes = config.fetch('default_link_classes', DEFAULT_LINK_CLASSES)
214
+ alert_classes = config.fetch('alert_link_classes', DEFAULT_ALERT_CLASSES)
212
215
 
213
216
  # Apply alert classes to links inside p.alert
214
217
  doc.css('p.alert a:not(.btn)').each do |link|
@@ -246,7 +249,7 @@ module Jekyll
246
249
 
247
250
  # Add external-link icon to cross-domain external links
248
251
  def add_external_icon(link, site_domain, config, doc)
249
- external_link_icon = config.fetch('external_link_icon', true)
252
+ external_link_icon = config.fetch('external_link_icon', DEFAULT_EXTERNAL_LINK_ICON)
250
253
 
251
254
  return unless external_link_icon
252
255
  return unless is_external_different_domain_link?(link, site_domain)
@@ -257,4 +260,19 @@ module Jekyll
257
260
  end
258
261
  end
259
262
  end
263
+
264
+ module Filters
265
+ # Liquid filter that applies link decoration to already-converted HTML.
266
+ # Use after the markdownify filter to decorate links in YAML data fields:
267
+ # {{ data.message | markdownify | decorate_links }}
268
+ module LinkDecoratorFilter
269
+ def decorate_links(html)
270
+ site = @context.registers[:site]
271
+ decorator = Jekyll::Converters::LinkDecorator.new(site.config)
272
+ decorator.decorate_html(html)
273
+ end
274
+ end
275
+ end
260
276
  end
277
+
278
+ Liquid::Template.register_filter(Jekyll::Filters::LinkDecoratorFilter)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-link-decorator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ReleaseBot
@@ -53,30 +53,30 @@ dependencies:
53
53
  name: bundler
54
54
  requirement: !ruby/object:Gem::Requirement
55
55
  requirements:
56
- - - ">="
56
+ - - "~>"
57
57
  - !ruby/object:Gem::Version
58
- version: '2.0'
58
+ version: '4.0'
59
59
  type: :development
60
60
  prerelease: false
61
61
  version_requirements: !ruby/object:Gem::Requirement
62
62
  requirements:
63
- - - ">="
63
+ - - "~>"
64
64
  - !ruby/object:Gem::Version
65
- version: '2.0'
65
+ version: '4.0'
66
66
  - !ruby/object:Gem::Dependency
67
67
  name: rake
68
68
  requirement: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - "~>"
71
71
  - !ruby/object:Gem::Version
72
- version: '13.0'
72
+ version: '13.1'
73
73
  type: :development
74
74
  prerelease: false
75
75
  version_requirements: !ruby/object:Gem::Requirement
76
76
  requirements:
77
77
  - - "~>"
78
78
  - !ruby/object:Gem::Version
79
- version: '13.0'
79
+ version: '13.1'
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
82
  requirement: !ruby/object:Gem::Requirement
@@ -147,6 +147,20 @@ dependencies:
147
147
  - - "~>"
148
148
  - !ruby/object:Gem::Version
149
149
  version: '1.26'
150
+ - !ruby/object:Gem::Dependency
151
+ name: rubocop-rake
152
+ requirement: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: '0.6'
157
+ type: :development
158
+ prerelease: false
159
+ version_requirements: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '0.6'
150
164
  - !ruby/object:Gem::Dependency
151
165
  name: rubocop-rspec
152
166
  requirement: !ruby/object:Gem::Requirement