jekyll-link-decorator 1.5.1 → 1.5.2

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: 86487049f93f8629a147eb1951acfd42988230e0be214177364a9c1b1125a369
4
- data.tar.gz: ec957d708689c5005016bee2ac210ecbd12aefa85f0454873ef28e964492ee3a
3
+ metadata.gz: 85919ec3882d487b1545ce0508fde30b74c0fd59e35f2823a8da4b4659437004
4
+ data.tar.gz: b558d2dbd36f937a5f03a670a519439d14f54625d948123977ed38ec67076af4
5
5
  SHA512:
6
- metadata.gz: 6c419799160ddd533b6119a3182959b3961b101c2a0d3fd7aba9ab0be4c271451eda7cf637eab717f1dfbd4ca59ff0fbe20a1e13fac7c66a67ad88f57f1fab08
7
- data.tar.gz: 36b2e3c4a30442c7bf603a3607fa6591b6e347b5471139a71a22626ebce4e7004060783d473848dba9c48e196778691457b06c6ae65f6c682b2e59c1d0409b39
6
+ metadata.gz: 5a1011beabc1ebf913123b8aff0c38c747afd70c2ee572e16aa35c0d5cebd9ae9226d92ee47fda28dd7a6ac5a6ddd77956d29906faee86b62a1bfc08977cd98e
7
+ data.tar.gz: 6498a39d46641219f4939b9c3becf8b5693441c9b69ed0726d1c49cb7bfff0635df4817b13e1fe6c66befd6e5ca5bda64f500abdd681a443199bb28cbbe52408
@@ -6,6 +6,6 @@ module Jekyll
6
6
  # Regenerated alongside the gemspec on every `make gemspec` run (locally
7
7
  # or in CI), so it always matches spec.version in the built gem. Any
8
8
  # hand edit is overwritten on the next run.
9
- VERSION = '1.5.1'
9
+ VERSION = '1.5.2'
10
10
  end
11
11
  end
@@ -1,54 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This Jekyll plugin, `link_decorator`, automatically enhances `<a>` tags
4
- # within Markdown content by adding specific Bootstrap-related CSS classes and
5
- # external-link icons. This functionality is conditional, applying different
6
- # sets of classes based on whether a link is located inside a Bootstrap alert
7
- # box or is a regular link. It explicitly avoids modifying elements that are
8
- # designated as buttons by having the `.btn` class.
3
+ # This Jekyll plugin, `link_decorator`, enhances `<a>` tags in Markdown content
4
+ # with Bootstrap CSS classes and external-link icons. It applies different
5
+ # classes depending on whether a link sits inside a Bootstrap alert box or
6
+ # stands alone, and skips elements with the `.btn` class.
9
7
  #
10
8
  # === External Link Icon Support ===
11
9
  #
12
10
  # For links pointing to external domains (different from site.url), the plugin
13
- # automatically adds a Font Awesome external-link icon (fa-solid fa-external-link)
14
- # at the end of the link text, similar to the link component behavior.
11
+ # adds a Font Awesome external-link icon (fa-solid fa-external-link) at the
12
+ # end of the link text.
15
13
  #
16
14
  # === External Link Detection & Target Management ===
17
15
  #
18
- # The plugin automatically detects external links and manages their behavior:
16
+ # The plugin detects external links and manages their behavior:
19
17
  # - Relative URLs (starting with /, ../) and same-domain absolute URLs open in the same window
20
- # - Absolute URLs pointing to different domains (http:// or https://) automatically get target="_blank"
21
- # - Links with target="_blank" automatically receive rel="noopener noreferrer" protection
22
- # against security vulnerabilities (window.opener access, referrer leakage)
18
+ # - Absolute URLs pointing to different domains (http:// or https://) get target="_blank"
19
+ # - Links with target="_blank" receive rel="noopener noreferrer" protection against
20
+ # security vulnerabilities (window.opener access, referrer leakage)
23
21
  #
24
22
  # === Configuration ===
25
23
  #
26
- # You can customize the classes applied by this plugin by adding
27
- # `with_link_decorator` and `with_link_decorator_data` sections to your `_config.yml` file.
24
+ # Customize the plugin's classes by adding `with_link_decorator` and
25
+ # `with_link_decorator_data` to your `_config.yml`.
28
26
  #
29
27
  # * `with_link_decorator`: Boolean (default: true) that controls whether the plugin runs.
30
28
  # Set to false to disable automatic link styling and icon insertion.
31
29
  #
32
30
  # * `with_link_decorator_data`: A dictionary containing optional configuration keys:
33
- # - `default_link_classes`: Defines the classes to be applied to all links that are not
34
- # inside an .alert. Example: `default_link_classes: "text-decoration-none"`
35
- # - `alert_link_classes`: Defines the classes for links specifically located within an
36
- # .alert box. Example: `alert_link_classes: "text-decoration-underline"`
37
- # - `external_link_icon`: Boolean (default: true) that controls whether external-link
38
- # icons are added to cross-domain external links. Set to false to disable.
31
+ # - `default_link_classes`: Classes applied to links outside an .alert.
32
+ # Example: `default_link_classes: "text-decoration-none"`
33
+ # If a link already carries its own `link-{color}`, `link-underline-*`,
34
+ # `link-offset-*`, `link-underline-opacity-*`, or `link-opacity-*` class,
35
+ # the plugin skips the matching default token automatically see LINK_CLASS_FAMILIES.
36
+ # - `alert_link_classes`: Classes applied to links inside an .alert box.
37
+ # Example: `alert_link_classes: "text-decoration-underline"`
38
+ # - `external_link_icon`: Boolean (default: true) — show the icon on cross-domain
39
+ # external links. Set to false to disable.
39
40
  # - `external_link_icon_excluded_tags`: List of HTML child tag names (default: []) whose presence
40
41
  # inside an anchor suppresses the external-link icon. Security attributes
41
- # (target="_blank", rel="noopener noreferrer") are still applied.
42
+ # (target="_blank", rel="noopener noreferrer") still apply.
42
43
  # Example: `external_link_icon_excluded_tags: ["img", "svg"]`
43
44
  #
44
45
  # === Heading Anchor Support ===
45
46
  #
46
- # The plugin can inject a permalink icon inside each heading (h1–h6), giving
47
- # users a direct, linkable URL to every section. This feature is configured
48
- # via two top-level keys (separate from `with_link_decorator_data`):
47
+ # The plugin can inject a permalink icon inside each heading (h1–h6) so every
48
+ # section gets a shareable URL. Configure it via two top-level keys (separate
49
+ # from `with_link_decorator_data`):
49
50
  #
50
- # * `with_heading_anchor`: Boolean (default: false) that controls whether heading anchors
51
- # are injected. Set to true to enable.
51
+ # * `with_heading_anchor`: Boolean (default: false) set to true to inject heading anchors.
52
52
  #
53
53
  # * `with_heading_anchor_data`: A dictionary containing optional configuration keys:
54
54
  # - `icon`: CSS classes applied to the anchor's glyph element (default:
@@ -58,10 +58,10 @@
58
58
  # want an icon-font glyph instead.
59
59
  # - `icon_size`: Optional size modifier class appended after the icon classes.
60
60
  #
61
- # If no configuration is provided, the plugin will use default fallback classes
62
- # and enable external link icons.
61
+ # Without configuration, the plugin uses its default classes and enables
62
+ # external-link icons.
63
63
  #
64
- # Here is an example `_config.yml` setup:
64
+ # Example `_config.yml`:
65
65
  #
66
66
  # ```yaml
67
67
  # with_link_decorator: true
@@ -92,14 +92,47 @@ EXISTING_ICON_SELECTORS = [
92
92
 
93
93
  module Jekyll
94
94
  module Converters
95
- # This custom converter applies specific CSS classes to <a> tags
96
- # based on their context (e.g., inside an alert box) and excludes
97
- # buttons, all done via Nokogiri's powerful CSS selectors.
98
- # It also adds external-link icons for cross-domain external links.
95
+ # Applies CSS classes to <a> tags based on context (e.g., inside an alert
96
+ # box) via Nokogiri CSS selectors, excluding buttons. Also adds
97
+ # external-link icons for cross-domain links.
99
98
  class LinkDecorator < Jekyll::Converters::Markdown
100
99
  DEFAULT_LINK_CLASSES = 'link link-offset-3 link-offset-3-hover link-underline-primary ' \
101
100
  'link-underline-opacity-0 link-underline-opacity-100-hover'
102
101
  DEFAULT_ALERT_LINK_CLASSES = 'alert-link'
102
+
103
+ # Bootstrap 5 link-utility "families" whose defaults must not silently
104
+ # override an author's own explicit class from the same family — see
105
+ # classes_to_add_for.
106
+ #
107
+ # Each entry carries a single `pattern:` regex, anchored \A...\z and
108
+ # matched per class token (not against the whole class string), so a
109
+ # compound name like "social-link-danger" or "sidebar-link-offset-2" is
110
+ # never mistaken for an override.
111
+ #
112
+ # Enumerated families (offset, both opacity families) lock to Bootstrap's
113
+ # fixed value set, so an out-of-range value like "link-opacity-42" isn't
114
+ # recognized as an override either. Color families (link-{color},
115
+ # link-underline-{color}) stay generic (\S+) since Bootstrap themes can
116
+ # define arbitrary custom color names.
117
+ LINK_CLASS_FAMILIES = [
118
+ { # link-{color}, e.g. link-primary, link-body-emphasis (bare colored-link class;
119
+ # excludes link-underline-*, link-offset-*, and link-opacity-* families)
120
+ pattern: /\Alink-(?!underline\b|offset-|opacity-)\S+\z/
121
+ },
122
+ { # link-underline-{color}, e.g. link-underline-success (excludes -opacity-*)
123
+ pattern: /\Alink-underline-(?!opacity)\S+\z/
124
+ },
125
+ { # link-offset-{1,2,3}, each with an optional -hover variant
126
+ pattern: /\Alink-offset-[123](-hover)?\z/
127
+ },
128
+ { # link-underline-opacity-{0,10,25,50,75,100}, each with an optional -hover variant
129
+ pattern: /\Alink-underline-opacity-(?:0|10|25|50|75|100)(-hover)?\z/
130
+ },
131
+ { # link-opacity-{10,25,50,75,100}, each with an optional -hover variant
132
+ # (controls link-text opacity, distinct from link-underline-opacity-*)
133
+ pattern: /\Alink-opacity-(?:10|25|50|75|100)(-hover)?\z/
134
+ }
135
+ ].freeze
103
136
  DEFAULT_EXTERNAL_LINK_ICON = true
104
137
  DEFAULT_EXTERNAL_LINK_ICON_EXCLUDED_TAGS = [].freeze
105
138
  DEFAULT_HEADING_ANCHOR = false
@@ -177,9 +210,8 @@ module Jekyll
177
210
  link['target'] = '_blank'
178
211
  end
179
212
 
180
- # Add security attributes to links with target="_blank"
181
- # Adds rel="noopener noreferrer" to prevent security vulnerabilities
182
- # Preserves any existing rel attribute values
213
+ # Add rel="noopener noreferrer" to target="_blank" links, preserving
214
+ # any existing rel attribute values
183
215
  def add_external_target_protection(link)
184
216
  target = link['target'].to_s
185
217
 
@@ -256,12 +288,20 @@ module Jekyll
256
288
  doc.css('a:not(.btn)').each do |link|
257
289
  next if link.ancestors('p.alert, blockquote.alert').any?
258
290
 
259
- classes_to_add = if link['class'].to_s.match?(/\blink-underline-(?!opacity)\S+/)
260
- default_classes.split.grep_v(/\Alink-underline-(?!opacity)/).join(' ')
261
- else
262
- default_classes
263
- end
264
- add_classes(link, classes_to_add)
291
+ add_classes(link, classes_to_add_for(link, default_classes))
292
+ end
293
+ end
294
+
295
+ # Drops any default class belonging to a family the link already customizes,
296
+ # so the author's explicit class wins instead of losing silently to a
297
+ # same-specificity Bootstrap !important rule declared later in the sheet.
298
+ # See LINK_CLASS_FAMILIES for how each family's pattern is matched.
299
+ def classes_to_add_for(link, default_classes)
300
+ link_classes = link['class'].to_s.split
301
+ LINK_CLASS_FAMILIES.reduce(default_classes) do |classes, family|
302
+ next classes unless link_classes.any? { |token| token.match?(family[:pattern]) }
303
+
304
+ classes.split.grep_v(family[:pattern]).join(' ')
265
305
  end
266
306
  end
267
307
 
@@ -347,7 +387,7 @@ module Jekyll
347
387
 
348
388
  private :add_heading_anchors, :resolve_heading_id, :slugify
349
389
 
350
- # Add external-link icon to cross-domain external links
390
+ # Add external-link icon to cross-domain links
351
391
  def add_external_icon(link, site_domain, config, doc)
352
392
  external_link_icon = config.fetch('external_link_icon', DEFAULT_EXTERNAL_LINK_ICON)
353
393
 
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.5.1
4
+ version: 1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alain Reguera Delgado