jekyll_href 1.1.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0656497a33e45341646549dc55a45747f8418acd5f84298e145134bf7c10eec5'
4
- data.tar.gz: 2c938cbc5e5f09bc2b8ea42ea11dde9d28e44e74512d7ebc203bccc2d127a8f6
3
+ metadata.gz: 9e9e6357f4c5f4d4dd7815aab9142ab5dadfbc48b3ba719fdc6b1cd70265d3d3
4
+ data.tar.gz: '068d3c6821f1f8578fee4331179be452ad50fdfd620cc990a0dbdb1359f605cc'
5
5
  SHA512:
6
- metadata.gz: cdbdfe53569e693e1a81cb3e30b773cc239f81ce05f46ad2f20fe638dfef0777ca4cbcafd79ba9faedc9af1bb416f2a9628abbf8d82f423dd66ef36233059402
7
- data.tar.gz: 1a74a3ace7f95d965a4db351501b908345257ab6138ab9ad3f4647499230e2d2a24fcd02c17fd0577376c913dc60cb3689b526046097a33a107ccea3ea3ce484
6
+ metadata.gz: d4411b3c9cfad7062eb75206f487e6e1a5589874479ae09815d044177069fd567b069875b9fabd4018dc9aafed9dc5dcc656354917c90935311ee958b6c1d5c2
7
+ data.tar.gz: abc4e78a0745ab9f455c5e1a1f85d0a41aa85c242f155c8d064503d5682df69806ef98c06c838833d37b1d3468713d5a21e798b7bf33570d48e2e27f76450fb8
data/.rubocop.yml CHANGED
@@ -1,37 +1,95 @@
1
- #require: rubocop-jekyll
2
- #inherit_gem:
3
- # rubocop-jekyll: .rubocop.yml
1
+ require:
2
+ # - rubocop-jekyll
3
+ - rubocop-md
4
+ - rubocop-performance
5
+ - rubocop-rake
6
+ - rubocop-rspec
7
+
8
+ # inherit_gem:
9
+ # rubocop-jekyll: .rubocop.yml
4
10
 
5
11
  AllCops:
6
12
  Exclude:
7
- - vendor/**/*
8
- - Gemfile*
13
+ - demo/_site/**/*
14
+ - exe/**/*
15
+ - vendor/**/*
16
+ - Gemfile*
9
17
  NewCops: enable
10
18
  TargetRubyVersion: 2.6
11
19
 
12
- # Gemspec/RequireMFA:
13
- # Enabled: false
20
+ Gemspec/DeprecatedAttributeAssignment:
21
+ Enabled: false
22
+
23
+ Gemspec/RequireMFA:
24
+ Enabled: false
14
25
 
15
26
  Layout/HashAlignment:
27
+ EnforcedColonStyle: table
16
28
  EnforcedHashRocketStyle: table
17
29
 
30
+ Layout/InitialIndentation:
31
+ Exclude:
32
+ - README.md
33
+
18
34
  Layout/LineLength:
19
35
  Max: 150
36
+ Exclude:
37
+ - spec/**/*
20
38
 
21
39
  Layout/MultilineMethodCallIndentation:
22
40
  Enabled: false
23
41
 
42
+ Lint/RedundantCopDisableDirective:
43
+ Exclude:
44
+ - jekyll_href.gemspec
45
+
24
46
  Metrics/AbcSize:
25
- Max: 25
47
+ Max: 45
48
+
49
+ Metrics/BlockLength:
50
+ Exclude:
51
+ - jekyll_href.gemspec
52
+ - spec/**/*
53
+ Max: 40
54
+
55
+ Metrics/ClassLength:
56
+ Exclude:
57
+ - spec/**/*
58
+ Max: 40
26
59
 
27
60
  Metrics/CyclomaticComplexity:
28
- Max: 10
61
+ Max: 20
29
62
 
30
63
  Metrics/MethodLength:
31
- Max: 30
64
+ Max: 40
32
65
 
33
66
  Metrics/PerceivedComplexity:
34
- Max: 10
67
+ Max: 15
68
+
69
+ Naming/FileName:
70
+ Exclude:
71
+ - Rakefile
72
+
73
+ RSpec/ExampleLength:
74
+ Max: 40
75
+
76
+ RSpec/FilePath:
77
+ Enabled: false
78
+
79
+ RSpec/MultipleExpectations:
80
+ Max: 15
81
+
82
+ RSpec/MultipleMemoizedHelpers:
83
+ Max: 20
84
+
85
+ Style/CommandLiteral:
86
+ Enabled: false
87
+
88
+ Style/CommentedKeyword:
89
+ Enabled: false
90
+
91
+ Style/Documentation:
92
+ Enabled: false
35
93
 
36
94
  Style/FrozenStringLiteralComment:
37
95
  Enabled: false
@@ -42,6 +100,10 @@ Style/PercentLiteralDelimiters:
42
100
  Style/RegexpLiteral:
43
101
  Enabled: false
44
102
 
103
+ Style/StringConcatenation:
104
+ Exclude:
105
+ - spec/**/*
106
+
45
107
  Style/StringLiterals:
46
108
  Enabled: false
47
109
 
@@ -49,4 +111,4 @@ Style/StringLiteralsInInterpolation:
49
111
  Enabled: false
50
112
 
51
113
  Style/TrailingCommaInHashLiteral:
52
- Enabled: false
114
+ EnforcedStyleForMultiline: comma
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 1.2.2 / 2023-03-25
2
+ * Added **References** capability:
3
+ * Added `summary_exclude` keyword option to `href` tag.
4
+ * Added `href_summary` tag.
5
+ * If a URL appears in more than one `href` with different `follow` values a warning is logged.
6
+
7
+ ## 1.2.1 / 2023-03-21
8
+ * Added `shy` and `wbr` options.
9
+
10
+ ## 1.2.0 / 2023-02-16
11
+ * Updated to `jekyll_plugin_support` v1.5.0
12
+
13
+ ## 1.1.1 / 2023-02-14
14
+ * Now dependent on `jekyll_plugin_support`
15
+
1
16
  ## 1.1.0 / 2023-02-03
2
17
  * Updated to `jekyll_all_collections` plugin v0.2.0.
3
18
  * Fixed insidious bug where a valid link was not used properly.
data/README.md CHANGED
@@ -5,52 +5,57 @@
5
5
  `Jekyll_href` is a Jekyll plugin that provides a new Liquid tag: `href`.
6
6
  It provides a convenient way to generate formatted and clickable URIs.
7
7
  The Liquid tag generates an `a href` HTML tag,
8
- which by default contains `target="_blank"` and `rel=nofollow`.
8
+ which by default contains `target="_blank"` and `rel="nofollow"`.
9
9
 
10
10
  If the url starts with `http`, or the `match` keyword is specified:
11
11
  - The url will open in a new tab or window.
12
- - The url will include `rel=nofollow` for SEO purposes.
12
+ - The url will include `rel="nofollow"` for SEO purposes.
13
13
 
14
14
  CAUTION: if linked text contains a single or double quote,
15
15
  you will see the error message: `Liquid Exception: Unmatched quote`.
16
- Instead, use ' (`'`), " (`"`), ‘ (`‘`),
17
- ’ (`’`), “ (`“`), and ” (`”`)
16
+ Instead, use:
18
17
 
18
+ - `'` (')
19
+ - `"` (")
20
+ - `‘` (‘)
21
+ - `’` (’)
22
+ - `“` (“)
23
+ - `”` (”)
24
+
25
+
26
+ ## Configuration
19
27
  In `_config.yml`, if a section called `plugin-vars` exists,
20
28
  then its name/value pairs are available for substitution.
21
29
  ```yaml
22
- plugin-vars:
23
- django-github: 'https://github.com/django/django/blob/3.1.7'
24
- django-oscar-github: 'https://github.com/django-oscar/django-oscar/blob/3.0.2'
30
+ plugin-vars:
31
+ django-github: 'https://github.com/django/django/blob/3.1.7'
32
+ django-oscar-github: 'https://github.com/django-oscar/django-oscar/blob/3.0.2'
25
33
  ```
26
34
 
27
35
 
28
- ## Syntax 1 (requires `url` does not have embedded spaces):
36
+ ## Syntax 1 (requires `url` does not have embedded spaces)
29
37
  ```
30
- {% href [match | [follow] [blank|notarget]] url text to display %}
38
+ {% href [match | [follow] [blank|notarget] [summary_exclude]] url text to display %}
31
39
  ```
32
40
  1. The url must be a single token, without embedded spaces.
33
41
  2. The url need not be enclosed in quotes.
34
42
  3. The square brackets denote optional keyword parameters, and should not be typed.
35
43
 
36
44
 
37
- ## Syntax 2 (always works):
45
+ ## Syntax 2 (always works)
38
46
  This syntax is recommended when the URL contains a colon (:).
39
47
  ```
40
- {% href [match | [follow] [blank|notarget]]
48
+ {% href [match | [follow] [blank|notarget]] [summary_exclude]
41
49
  url="http://link.com with space.html" some text %}
42
-
43
- {% href [match | [follow] [blank|notarget]]
44
- url='http://link.com with space.html' some text %}
45
50
  ```
46
51
  1. Each of the above examples contain an embedded newline, which is legal.
47
52
  2. The url must be enclosed by either single or double quotes.
48
53
  3. The square brackets denote optional keyword parameters, and should not be typed.
49
54
 
50
55
 
51
- ## Syntax 3 (implicit URL):
56
+ ## Syntax 3 (implicit URL)
52
57
  ```
53
- {% href [match | [follow] [blank|notarget]] www.domain.com %}
58
+ {% href [match | [follow] [blank|notarget] [summary_exclude]] [shy|wbr] www.domain.com %}
54
59
  ```
55
60
  The URI provided, for example `www.domain.com`,
56
61
  is used to form the URL by prepending `https://`,
@@ -94,6 +99,63 @@ The `match` option looks through the pages collection for a URL with containing
94
99
  `Match` implies `follow` and `notarget`.
95
100
 
96
101
 
102
+ ### `shy`
103
+ `shy` is only applicable for syntax 3 (implicit URL).
104
+ This option causes displayed urls to have an ­ inserted after each slash (/).
105
+ If both `shy` and `wbr` are specified, `wbr` prevails.
106
+
107
+ For example:
108
+ ```
109
+ {% href shy mslinn.com/path/to/page.html %}
110
+ ```
111
+ Expands to:
112
+ ```
113
+ <a href="https://mslinn.com/path/to/page.html">mslinn.com/&shy;path/&shy;to/&shy;page.html</a>
114
+ ```
115
+
116
+ ### `shy`
117
+ The `shy` keyword option is only applicable for syntax 3 (implicit URL).
118
+ This option causes displayed urls to have an [`&amp;shy;`](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens) inserted after each slash (/).
119
+ If both `shy` and `wbr` are specified, `wbr` prevails.
120
+
121
+ For example:
122
+ ```
123
+ {% href shy mslinn.com/path/to/page.html %}
124
+ ```
125
+ Expands to:
126
+ ```
127
+ <a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/&shy;path/&shy;to/&shy;page.html</a>
128
+ ```
129
+
130
+ ### `summary`
131
+ The `summary` name/value option provides an override for the linked text in the **References** section
132
+ generated by the `{% href_summary %}` tag.
133
+
134
+
135
+ ### `summary_exclude`
136
+ The `summary_exclude` keyword option prevents this `href` tag from appearing in the summary
137
+ produced by the [<code>href_summary</code> tag](#href_summary).
138
+ You probably want all of your menu items (whose links are generated by the `href` tag) to have this keyword option.
139
+
140
+ `mailto:` links are always excluded, so there is no need to use this keyword option for those types of links.
141
+
142
+
143
+ ### `wbr`
144
+ The `wbr` keyword option is only applicable for syntax 3 (implicit URL).
145
+ It add [line break opportunites](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr).
146
+ This option causes displayed urls to have an `&lt;wbr&gt;` inserted after each slash (/).
147
+ If both `shy` and `wbr` are specified, `wbr` prevails.
148
+
149
+ For example:
150
+ ```
151
+ {% href wbr mslinn.com/path/to/page.html %}
152
+ ```
153
+ Expands to:
154
+ ```
155
+ <a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/<wbr>path/<wbr>to/<wbr>page.html</a>
156
+ ```
157
+
158
+
97
159
  ## Examples
98
160
  1. Generates `nofollow` and `target` attributes:
99
161
  ```
@@ -133,6 +195,81 @@ The `match` option looks through the pages collection for a URL with containing
133
195
  Substitutions are only made to the URL, not to the linked text.
134
196
 
135
197
 
198
+ ## References Generation
199
+ The `href` usages on each page can be summarized at the bottom of the pages in a **References** section.
200
+ Links are presented in the summary in the order they appear in the page.
201
+
202
+ The summary is produced by the `href_summary` tag.
203
+ Usage is:
204
+
205
+ ```html
206
+ {% href_summary [options] %}
207
+ ```
208
+
209
+ `Href` tag options are used to generate the summary links,
210
+ just as they were in the text above the **References** summary section.
211
+ The only exception is the `summary` option, which overrides the linked text.
212
+
213
+ If more than one `href` tag specifies a URL,
214
+ the first one that appears in the page sets the value of the linked text.
215
+
216
+ If a URL appears in more than one `href` with different `follow` values, a warning is logged.
217
+
218
+
219
+ ### Included `href` Tags
220
+ The following `href` tags are included in the summary:
221
+
222
+ - Those with links that start with `http` are always included.
223
+ - Those with [relative links](https://www.w3.org/TR/WD-html40-970917/htmlweb.html#h-5.1.2),
224
+ and have the `include_local` keyword option.
225
+
226
+ ### Excluded `href` Tags
227
+ The following `href` tags are excluded from the summary:
228
+
229
+ - Those with links that start with `mailto:`.
230
+ - Those having the `summary_exclude` keyword option.
231
+
232
+
233
+ ### Example
234
+ Given these `href` and `href_summary` usages in a web page:
235
+
236
+ ```html
237
+ {% href https://rubygems.org RubyGems.org %}
238
+ {% href summary="Mothership" https://jekyllrb.com/ Jekyll %}
239
+ {% href summary="Mike Slinn" mslinn.com %}
240
+ {% href https://mslinn.com Mike Slinn %}
241
+ {% href summary="Front page of this website" / Front page %}
242
+
243
+ {% href_summary attribution include_local %}
244
+ ```
245
+
246
+ Then the generated HTML looks like the following:
247
+
248
+ ```html
249
+ <h2 id="reference">References</h2>
250
+ <ol>
251
+ <li><a href='https://rubygems.org' rel='nofollow' target='_blank'>RubyGems.org</a></li>
252
+ <li><a href='https://jekyllrb.com/' rel='nofollow' target='_blank'>Mothership</a></li>
253
+ <li><a href='https://mslinn.com/' rel='nofollow' target='_blank'><code>mslinn.com</code></a></li>
254
+ </ol>
255
+
256
+ <h2 id="local_reference">Local References</h2>
257
+ <ol>
258
+ <li><a href='/'>Front page of this website</a></li>
259
+ </ol>
260
+
261
+ <div id="jps_attribute_735866" class="jps_attribute">
262
+ <div>
263
+ <a href="https://www.mslinn.com/jekyll/3000-jekyll-plugins.html#href" target="_blank" rel="nofollow">
264
+ Generated by the jekyll_href v1.2.2 Jekyll plugin, written by Mike Slinn 2023-04-13.
265
+ </a>
266
+ </div>
267
+ </div>
268
+ ```
269
+
270
+ You can read about the `attribution` option [here](https://www.mslinn.com/jekyll/10200-jekyll-plugin-support.html#attribution).
271
+
272
+
136
273
  ## Additional Information
137
274
  More information is available on my website about
138
275
  [my Jekyll plugins](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
data/Rakefile CHANGED
@@ -1,2 +1,3 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+
2
3
  task default: %i[]
data/jekyll_href.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  require_relative 'lib/jekyll_href/version'
2
2
 
3
- Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
3
+ Gem::Specification.new do |spec|
4
4
  github = 'https://github.com/mslinn/jekyll_href'
5
5
 
6
6
  spec.authors = ['Mike Slinn']
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
10
10
  END_OF_DESC
11
11
  spec.email = ['mslinn@mslinn.com']
12
12
  spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
13
- spec.homepage = 'https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#href'
13
+ spec.homepage = 'https://www.mslinn.com/jekyll/3000-jekyll-plugins.html#href'
14
14
  spec.license = 'MIT'
15
15
  spec.metadata = {
16
16
  'allowed_push_host' => 'https://rubygems.org',
@@ -32,8 +32,6 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
32
32
  spec.version = JekyllHrefVersion::VERSION
33
33
 
34
34
  spec.add_dependency 'jekyll', '>= 3.5.0'
35
- spec.add_dependency 'jekyll_all_collections', '>= 0.2.0'
36
- spec.add_dependency 'jekyll_plugin_logger'
37
- spec.add_dependency 'key-value-parser'
38
- spec.add_dependency 'shellwords'
35
+ spec.add_dependency 'jekyll_all_collections', '~> 0.3.0', '>= 0.3.1'
36
+ spec.add_dependency 'jekyll_plugin_support', '~> 0.6.0', '>= 0.6.1'
39
37
  end
data/lib/hash_array.rb ADDED
@@ -0,0 +1,32 @@
1
+ module HashArray
2
+ def reset
3
+ @local_hrefs = {}
4
+ @global_hrefs = {}
5
+ end
6
+
7
+ def add_link_for_page(href, hash)
8
+ enclosing_page = href.path
9
+ hash[enclosing_page] = [] if hash[enclosing_page].nil?
10
+ pre_existing = hash[enclosing_page].find { |h| h.link_save == href.link_save }
11
+ if pre_existing
12
+ if pre_existing.follow != href.follow
13
+ @logger.warn "HRef tags for '#{href.link}' have inconsistent 'follow' keyword options on line #{href.line_number} of #{enclosing_page}"
14
+ end
15
+ else
16
+ hash[enclosing_page] << href unless href.summary_exclude
17
+ end
18
+ end
19
+
20
+ def add_local_link_for_page(href)
21
+ add_link_for_page(href, HashArray.instance_variable_get(:@local_hrefs))
22
+ end
23
+
24
+ def add_global_link_for_page(href)
25
+ add_link_for_page(href, HashArray.instance_variable_get(:@global_hrefs))
26
+ end
27
+
28
+ module_function :add_link_for_page, :add_local_link_for_page, :add_global_link_for_page, :reset
29
+ public :add_local_link_for_page, :add_global_link_for_page, :reset
30
+
31
+ reset
32
+ end
@@ -0,0 +1,79 @@
1
+ require 'jekyll_plugin_logger'
2
+ require 'jekyll_plugin_support'
3
+ require_relative 'jekyll_href/version'
4
+
5
+ module HrefSummaryTag
6
+ class HrefSummary < JekyllSupport::JekyllTag # rubocop:disable Metrics/ClassLength
7
+ include JekyllHrefVersion
8
+
9
+ # Class instance variables accumulate hrefs across invocations.
10
+ # These are hashes of arrays;
11
+ # the hash keys are page paths (strings) and the hash values are arrays of HRefTags.
12
+ # {
13
+ # 'path/to/page1.html': [ HRefTag1, HRefTag2 ],
14
+ # 'path/to/page2.html': [ HRefTag3, HRefTag4 ],
15
+ # }
16
+ @hrefs = {}
17
+ @hrefs_local = {}
18
+
19
+ class << self
20
+ attr_accessor :hrefs, :hrefs_local
21
+ end
22
+
23
+ include JekyllHrefVersion
24
+
25
+ # Method prescribed by the Jekyll plugin lifecycle.
26
+ # @param liquid_context [Liquid::Context]
27
+ # @return [String]
28
+ def render_impl
29
+ @helper.gem_file __FILE__ # Enables attribution
30
+ @include_local = @helper.parameter_specified? 'include_local'
31
+ global_refs = render_global_refs
32
+ local_refs = render_local_refs
33
+ have_refs = !(global_refs + local_refs).empty?
34
+ <<~END_RENDER
35
+ #{global_refs}
36
+ #{local_refs}
37
+ #{@helper.attribute if @helper.attribution && have_refs}
38
+ END_RENDER
39
+ end
40
+
41
+ def render_global_refs
42
+ hrefs = HashArray.instance_variable_get(:@global_hrefs)
43
+ path = @page['path']
44
+ entries = hrefs[path]&.select { |h| h.path == path }
45
+ return '' if entries.nil? || entries.empty?
46
+
47
+ summaries = entries.map { |href| "<li>#{href.summary_href}</li>" }
48
+
49
+ <<~END_RENDER
50
+ <h2 id="reference">References</h2>
51
+ <ol>
52
+ #{summaries.join "\n "}
53
+ </ol>
54
+ END_RENDER
55
+ rescue StandardError => e
56
+ @logger.error { "#{self.class} died with a #{e.full_message}" }
57
+ exit 1
58
+ end
59
+
60
+ def render_local_refs
61
+ return '' unless @include_local
62
+
63
+ hrefs = HashArray.instance_variable_get(:@local_hrefs)
64
+ path = @page['path']
65
+ entries = hrefs[path]&.select { |h| h.path == path }
66
+ return '' if entries.nil? || entries.empty?
67
+
68
+ summary = entries.map { |href| "<li>#{href.summary_href}</li>" }
69
+ <<~END_RENDER
70
+ <h2 id="local_reference">Local References</h2>
71
+ <ol>
72
+ #{summary.join("\n ")}
73
+ </ol>
74
+ END_RENDER
75
+ end
76
+
77
+ JekyllPluginHelper.register(self, 'href_summary')
78
+ end
79
+ end