jekyll_href 1.0.14 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +76 -9
- data/CHANGELOG.md +13 -0
- data/README.md +71 -18
- data/Rakefile +1 -2
- data/jekyll_href.gemspec +17 -28
- data/lib/jekyll_href/version.rb +1 -3
- data/lib/jekyll_href.rb +51 -56
- data/spec/href_spec.rb +29 -32
- data/spec/spec_helper.rb +0 -2
- metadata +8 -45
- data/lib/jekyll_tag_helper2.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22db125f99912c6bd0a7cbbaa15ca8311cc7914a80ecbe6a828535ad5844fa96
|
4
|
+
data.tar.gz: 3ce4d813af1541bdae8269fa370233ffe21c890de48da1e8e400eba67be59823
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f4a20b4e784614fb2e21a29c274fe5a1d69f522ae728772860c8933d27305c16aa03cd4b4d2a15b49c0d65da8ce5bf5e3ca61171c6d27a073a783046b0f6c89
|
7
|
+
data.tar.gz: b5eceadcf6aabfa9f80459f79848af9176cd81dd17e073de61b8e21dc4f6ba3a09ed197d029773411a0a9ca22bf1df74119729675f6c1d4736cbeba173038529
|
data/.rubocop.yml
CHANGED
@@ -1,19 +1,36 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
|
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
|
-
|
8
|
-
|
13
|
+
- demo/_site/**/*
|
14
|
+
- exe/**/*
|
15
|
+
- vendor/**/*
|
16
|
+
- Gemfile*
|
9
17
|
NewCops: enable
|
10
18
|
TargetRubyVersion: 2.6
|
11
19
|
|
12
|
-
|
13
|
-
|
20
|
+
Gemspec/DeprecatedAttributeAssignment:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Gemspec/RequireMFA:
|
24
|
+
Enabled: false
|
14
25
|
|
15
26
|
Layout/HashAlignment:
|
16
|
-
|
27
|
+
EnforcedColonStyle: table
|
28
|
+
Exclude:
|
29
|
+
- jekyll_href.gemspec
|
30
|
+
|
31
|
+
Layout/InitialIndentation:
|
32
|
+
Exclude:
|
33
|
+
- README.md
|
17
34
|
|
18
35
|
Layout/LineLength:
|
19
36
|
Max: 150
|
@@ -21,7 +38,53 @@ Layout/LineLength:
|
|
21
38
|
Layout/MultilineMethodCallIndentation:
|
22
39
|
Enabled: false
|
23
40
|
|
41
|
+
Lint/RedundantCopDisableDirective:
|
42
|
+
Exclude:
|
43
|
+
- jekyll_href.gemspec
|
44
|
+
|
45
|
+
Metrics/AbcSize:
|
46
|
+
Max: 45
|
47
|
+
|
24
48
|
Metrics/BlockLength:
|
49
|
+
Exclude:
|
50
|
+
- jekyll_href.gemspec
|
51
|
+
- spec/**/*
|
52
|
+
Max: 40
|
53
|
+
|
54
|
+
Metrics/ClassLength:
|
55
|
+
Exclude:
|
56
|
+
- spec/**/*
|
57
|
+
Max: 40
|
58
|
+
|
59
|
+
Metrics/CyclomaticComplexity:
|
60
|
+
Max: 20
|
61
|
+
|
62
|
+
Metrics/MethodLength:
|
63
|
+
Max: 40
|
64
|
+
|
65
|
+
Metrics/PerceivedComplexity:
|
66
|
+
Max: 15
|
67
|
+
|
68
|
+
Naming/FileName:
|
69
|
+
Exclude:
|
70
|
+
- Rakefile
|
71
|
+
|
72
|
+
RSpec/ExampleLength:
|
73
|
+
Max: 20
|
74
|
+
|
75
|
+
RSpec/MultipleExpectations:
|
76
|
+
Max: 15
|
77
|
+
|
78
|
+
Style/CommandLiteral:
|
79
|
+
Enabled: false
|
80
|
+
|
81
|
+
Style/CommentedKeyword:
|
82
|
+
Enabled: false
|
83
|
+
|
84
|
+
Style/Documentation:
|
85
|
+
Enabled: false
|
86
|
+
|
87
|
+
Style/FrozenStringLiteralComment:
|
25
88
|
Enabled: false
|
26
89
|
|
27
90
|
Style/PercentLiteralDelimiters:
|
@@ -30,6 +93,10 @@ Style/PercentLiteralDelimiters:
|
|
30
93
|
Style/RegexpLiteral:
|
31
94
|
Enabled: false
|
32
95
|
|
96
|
+
Style/StringConcatenation:
|
97
|
+
Exclude:
|
98
|
+
- spec/**/*
|
99
|
+
|
33
100
|
Style/StringLiterals:
|
34
101
|
Enabled: false
|
35
102
|
|
@@ -37,4 +104,4 @@ Style/StringLiteralsInInterpolation:
|
|
37
104
|
Enabled: false
|
38
105
|
|
39
106
|
Style/TrailingCommaInHashLiteral:
|
40
|
-
|
107
|
+
EnforcedStyleForMultiline: comma
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 1.2.1 / 2023-03-21
|
2
|
+
* Added `shy` and `wbr` options.
|
3
|
+
|
4
|
+
## 1.2.0 / 2023-02-16
|
5
|
+
* Updated to `jekyll_plugin_support` v1.5.0
|
6
|
+
|
7
|
+
## 1.1.1 / 2023-02-14
|
8
|
+
* Now dependent on `jekyll_plugin_support`
|
9
|
+
|
10
|
+
## 1.1.0 / 2023-02-03
|
11
|
+
* Updated to `jekyll_all_collections` plugin v0.2.0.
|
12
|
+
* Fixed insidious bug where a valid link was not used properly.
|
13
|
+
|
1
14
|
## 1.0.14 / 2023-01-09
|
2
15
|
* Added `blank` parameter.
|
3
16
|
|
data/README.md
CHANGED
@@ -4,25 +4,36 @@
|
|
4
4
|
|
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
|
-
The Liquid tag generates an `a href` HTML tag,
|
7
|
+
The Liquid tag generates an `a href` HTML tag,
|
8
|
+
which by default contains `target="_blank"` and `rel="nofollow"`.
|
8
9
|
|
9
10
|
If the url starts with `http`, or the `match` keyword is specified:
|
10
11
|
- The url will open in a new tab or window.
|
11
|
-
- The url will include `rel=nofollow` for SEO purposes.
|
12
|
+
- The url will include `rel="nofollow"` for SEO purposes.
|
12
13
|
|
13
|
-
CAUTION: if linked text contains a single or double quote
|
14
|
-
|
14
|
+
CAUTION: if linked text contains a single or double quote,
|
15
|
+
you will see the error message: `Liquid Exception: Unmatched quote`.
|
16
|
+
Instead, use:
|
15
17
|
|
18
|
+
- `'` (')
|
19
|
+
- `"` (")
|
20
|
+
- `‘` (‘)
|
21
|
+
- `’` (’)
|
22
|
+
- `“` (“)
|
23
|
+
- `”` (”)
|
24
|
+
|
25
|
+
|
26
|
+
## Configuration
|
16
27
|
In `_config.yml`, if a section called `plugin-vars` exists,
|
17
28
|
then its name/value pairs are available for substitution.
|
18
29
|
```yaml
|
19
|
-
|
20
|
-
|
21
|
-
|
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'
|
22
33
|
```
|
23
34
|
|
24
35
|
|
25
|
-
## Syntax 1 (requires `url` does not have embedded spaces)
|
36
|
+
## Syntax 1 (requires `url` does not have embedded spaces)
|
26
37
|
```
|
27
38
|
{% href [match | [follow] [blank|notarget]] url text to display %}
|
28
39
|
```
|
@@ -31,7 +42,7 @@ then its name/value pairs are available for substitution.
|
|
31
42
|
3. The square brackets denote optional keyword parameters, and should not be typed.
|
32
43
|
|
33
44
|
|
34
|
-
## Syntax 2 (always works)
|
45
|
+
## Syntax 2 (always works)
|
35
46
|
This syntax is recommended when the URL contains a colon (:).
|
36
47
|
```
|
37
48
|
{% href [match | [follow] [blank|notarget]]
|
@@ -45,9 +56,9 @@ This syntax is recommended when the URL contains a colon (:).
|
|
45
56
|
3. The square brackets denote optional keyword parameters, and should not be typed.
|
46
57
|
|
47
58
|
|
48
|
-
## Syntax 3 (implicit URL)
|
59
|
+
## Syntax 3 (implicit URL)
|
49
60
|
```
|
50
|
-
{% href [match | [follow] [blank|notarget]] www.domain.com %}
|
61
|
+
{% href [match | [follow] [blank|notarget]] [shy|wbr] www.domain.com %}
|
51
62
|
```
|
52
63
|
The URI provided, for example `www.domain.com`,
|
53
64
|
is used to form the URL by prepending `https://`,
|
@@ -91,6 +102,50 @@ The `match` option looks through the pages collection for a URL with containing
|
|
91
102
|
`Match` implies `follow` and `notarget`.
|
92
103
|
|
93
104
|
|
105
|
+
### `shy`
|
106
|
+
`shy` is only applicable for syntax 3 (implicit URL).
|
107
|
+
This option causes displayed urls to have an ­ inserted after each slash (/).
|
108
|
+
If both `shy` and `wbr` are specified, `wbr` prevails.
|
109
|
+
|
110
|
+
For example:
|
111
|
+
```
|
112
|
+
{% href shy mslinn.com/path/to/page.html %}
|
113
|
+
```
|
114
|
+
Expands to:
|
115
|
+
```
|
116
|
+
<a href="https://mslinn.com/path/to/page.html">mslinn.com/­path/­to/­page.html</a>
|
117
|
+
```
|
118
|
+
|
119
|
+
### `shy`
|
120
|
+
`shy` is only applicable for syntax 3 (implicit URL).
|
121
|
+
This option causes displayed urls to have an [`&shy;`](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens) inserted after each slash (/).
|
122
|
+
If both `shy` and `wbr` are specified, `wbr` prevails.
|
123
|
+
|
124
|
+
For example:
|
125
|
+
```
|
126
|
+
{% href shy mslinn.com/path/to/page.html %}
|
127
|
+
```
|
128
|
+
Expands to:
|
129
|
+
```
|
130
|
+
<a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/­path/­to/­page.html</a>
|
131
|
+
```
|
132
|
+
|
133
|
+
### `wbr`
|
134
|
+
`wbr` is only applicable for syntax 3 (implicit URL).
|
135
|
+
It add [line break opportunites](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr).
|
136
|
+
This option causes displayed urls to have an `<wbr>` inserted after each slash (/).
|
137
|
+
If both `shy` and `wbr` are specified, `wbr` prevails.
|
138
|
+
|
139
|
+
For example:
|
140
|
+
```
|
141
|
+
{% href wbr mslinn.com/path/to/page.html %}
|
142
|
+
```
|
143
|
+
Expands to:
|
144
|
+
```
|
145
|
+
<a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/<wbr>path/<wbr>to/<wbr>page.html</a>
|
146
|
+
```
|
147
|
+
|
148
|
+
|
94
149
|
## Examples
|
95
150
|
1. Generates `nofollow` and `target` attributes:
|
96
151
|
```
|
@@ -131,7 +186,8 @@ The `match` option looks through the pages collection for a URL with containing
|
|
131
186
|
|
132
187
|
|
133
188
|
## Additional Information
|
134
|
-
More information is available on my
|
189
|
+
More information is available on my website about
|
190
|
+
[my Jekyll plugins](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
|
135
191
|
|
136
192
|
|
137
193
|
## Installation
|
@@ -148,10 +204,6 @@ And then execute:
|
|
148
204
|
|
149
205
|
$ bundle install
|
150
206
|
|
151
|
-
Or install it yourself as:
|
152
|
-
|
153
|
-
$ gem install jekyll_href
|
154
|
-
|
155
207
|
|
156
208
|
## Generated HTML
|
157
209
|
|
@@ -223,7 +275,8 @@ Which renders as: [`mslinn.com`](https://mslinn.com)
|
|
223
275
|
|
224
276
|
## Development
|
225
277
|
|
226
|
-
After checking out the repo, run `bin/setup` to install dependencies.
|
278
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
279
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
227
280
|
|
228
281
|
Install development dependencies like this:
|
229
282
|
```
|
@@ -236,7 +289,7 @@ $ bundle exec rake install
|
|
236
289
|
```
|
237
290
|
|
238
291
|
## Test
|
239
|
-
A test
|
292
|
+
A test website is provided in the `demo` directory.
|
240
293
|
1. Set breakpoints.
|
241
294
|
|
242
295
|
2. Initiate a debug session from the command line:
|
data/Rakefile
CHANGED
data/jekyll_href.gemspec
CHANGED
@@ -1,47 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative "lib/jekyll_href/version"
|
1
|
+
require_relative 'lib/jekyll_href/version'
|
4
2
|
|
5
3
|
Gem::Specification.new do |spec|
|
6
|
-
github =
|
4
|
+
github = 'https://github.com/mslinn/jekyll_href'
|
7
5
|
|
8
|
-
spec.authors = [
|
9
|
-
spec.bindir =
|
6
|
+
spec.authors = ['Mike Slinn']
|
7
|
+
spec.bindir = 'exe'
|
10
8
|
spec.description = <<~END_OF_DESC
|
11
9
|
Generates an 'a href' tag, possibly with target='_blank' and rel='nofollow'.
|
12
10
|
END_OF_DESC
|
13
|
-
spec.email = [
|
14
|
-
spec.files = Dir[
|
15
|
-
spec.homepage =
|
16
|
-
spec.license =
|
11
|
+
spec.email = ['mslinn@mslinn.com']
|
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'
|
14
|
+
spec.license = 'MIT'
|
17
15
|
spec.metadata = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
'allowed_push_host' => 'https://rubygems.org',
|
17
|
+
'bug_tracker_uri' => "#{github}/issues",
|
18
|
+
'changelog_uri' => "#{github}/CHANGELOG.md",
|
19
|
+
'homepage_uri' => spec.homepage,
|
20
|
+
'source_code_uri' => github,
|
23
21
|
}
|
24
|
-
spec.name =
|
22
|
+
spec.name = 'jekyll_href'
|
25
23
|
spec.post_install_message = <<~END_MESSAGE
|
26
24
|
|
27
25
|
Thanks for installing #{spec.name}!
|
28
26
|
|
29
27
|
END_MESSAGE
|
30
|
-
spec.require_paths = [
|
31
|
-
spec.required_ruby_version =
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
spec.required_ruby_version = '>= 2.6.0'
|
32
30
|
spec.summary = "Generates an 'a href' tag, possibly with target='_blank' and rel='nofollow'."
|
33
31
|
spec.test_files = spec.files.grep(%r!^(test|spec|features)/!)
|
34
32
|
spec.version = JekyllHrefVersion::VERSION
|
35
33
|
|
36
34
|
spec.add_dependency 'jekyll', '>= 3.5.0'
|
37
|
-
spec.add_dependency 'jekyll_all_collections'
|
38
|
-
spec.add_dependency 'jekyll_plugin_logger'
|
39
|
-
spec.add_dependency 'key-value-parser'
|
40
|
-
spec.add_dependency 'shellwords'
|
41
|
-
|
42
|
-
# spec.add_development_dependency 'debase'
|
43
|
-
# spec.add_development_dependency 'rubocop-jekyll'
|
44
|
-
# spec.add_development_dependency 'rubocop-rake'
|
45
|
-
# spec.add_development_dependency 'rubocop-rspec'
|
46
|
-
# spec.add_development_dependency 'ruby-debug-ide'
|
35
|
+
spec.add_dependency 'jekyll_all_collections', '~> 0.3.0', '>= 0.3.1'
|
47
36
|
end
|
data/lib/jekyll_href/version.rb
CHANGED
data/lib/jekyll_href.rb
CHANGED
@@ -1,56 +1,41 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
require_relative "jekyll_href/version"
|
7
|
-
require_relative './jekyll_tag_helper2'
|
1
|
+
require 'jekyll_all_collections'
|
2
|
+
require 'jekyll_plugin_logger'
|
3
|
+
require 'jekyll_plugin_support'
|
4
|
+
require 'liquid'
|
5
|
+
require_relative 'jekyll_href/version'
|
8
6
|
|
9
7
|
# @author Copyright 2020 Michael Slinn
|
10
8
|
# @license SPDX-License-Identifier: Apache-2.0
|
11
9
|
# Generates an href.
|
12
10
|
|
13
11
|
# Implements href Jekyll tag
|
14
|
-
class ExternalHref <
|
12
|
+
class ExternalHref < JekyllSupport::JekyllTag # rubocop:disable Metrics/ClassLength
|
15
13
|
attr_reader :follow, :helper, :line_number, :match, :page, :path, :site, :text, :target, :url
|
16
14
|
attr_accessor :link
|
17
15
|
|
18
|
-
|
19
|
-
# @param markup [String] the arguments from the web page.
|
20
|
-
# @param _tokens [Liquid::ParseContext] tokenized command line
|
21
|
-
# By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
|
22
|
-
# a boolean parameter that determines if error messages should display the line number the error occurred.
|
23
|
-
# This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
|
24
|
-
# See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
|
25
|
-
# @return [void]
|
26
|
-
def initialize(tag_name, markup, _tokens)
|
27
|
-
super
|
28
|
-
markup = '' if markup.nil?
|
29
|
-
markup.strip!
|
30
|
-
|
31
|
-
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
32
|
-
@helper = JekyllTagHelper2.new(tag_name, markup, @logger)
|
33
|
-
end
|
16
|
+
include JekyllHrefVersion
|
34
17
|
|
35
18
|
# Method prescribed by the Jekyll plugin lifecycle.
|
36
19
|
# @param liquid_context [Liquid::Context]
|
37
20
|
# @return [String]
|
38
|
-
def
|
39
|
-
|
40
|
-
globals_initial(liquid_context)
|
21
|
+
def render_impl
|
22
|
+
globals_initial
|
41
23
|
linkk = compute_linkk
|
42
24
|
linkk = replace_vars(linkk)
|
43
25
|
@link_save = linkk
|
44
26
|
@helper_save = @helper.clone
|
45
27
|
globals_update(@helper.argv, linkk) # Sets @link and @text, might clear @follow and @target
|
46
28
|
handle_match if @match
|
29
|
+
|
47
30
|
"<a href='#{@link}'#{@target}#{@follow}>#{@text}</a>"
|
48
31
|
end
|
49
32
|
|
50
33
|
private
|
51
34
|
|
52
|
-
|
53
|
-
|
35
|
+
# Does not look at or compute @link
|
36
|
+
def compute_linkk
|
37
|
+
return @link if @link
|
38
|
+
|
54
39
|
linkk = @url
|
55
40
|
if linkk.nil? || !linkk
|
56
41
|
linkk = @helper.argv&.shift
|
@@ -63,7 +48,7 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
63
48
|
linkk
|
64
49
|
end
|
65
50
|
|
66
|
-
def dump_linkk_relations(linkk)
|
51
|
+
def dump_linkk_relations(linkk)
|
67
52
|
msg = <<~END_MESSAGE
|
68
53
|
jekyll_href error: no url was provided on #{@path}:#{@line_number}.
|
69
54
|
@helper.markup=#{@helper.markup}
|
@@ -77,25 +62,23 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
77
62
|
abort msg.red
|
78
63
|
end
|
79
64
|
|
80
|
-
|
81
|
-
|
82
|
-
@helper.liquid_context = liquid_context
|
83
|
-
|
84
|
-
@page = liquid_context.registers[:page]
|
65
|
+
# Sets @follow, @helper, @match, @path, @shy, @target, @url, @wbr
|
66
|
+
def globals_initial
|
85
67
|
@path = @page['path']
|
86
|
-
@site
|
87
|
-
JekyllAllCollections.maybe_compute_all_collections(@site)
|
68
|
+
AllCollectionsHooks.compute(@site)
|
88
69
|
|
89
70
|
@follow = @helper.parameter_specified?('follow') ? '' : " rel='nofollow'"
|
90
71
|
@match = @helper.parameter_specified?('match')
|
91
72
|
@blank = @helper.parameter_specified?('blank')
|
73
|
+
@shy = @helper.parameter_specified?('shy')
|
92
74
|
@target = @blank ? " target='_blank'" : nil
|
93
75
|
@target ||= @helper.parameter_specified?('notarget') ? '' : " target='_blank'"
|
94
76
|
@url = @helper.parameter_specified?('url')
|
77
|
+
@wbr = @helper.parameter_specified?('wbr')
|
95
78
|
end
|
96
79
|
|
97
|
-
|
98
|
-
|
80
|
+
# Might set @follow, @linkk, @target, and @text
|
81
|
+
def globals_update(tokens, linkk)
|
99
82
|
if linkk.start_with? 'mailto:'
|
100
83
|
@link = linkk
|
101
84
|
@target = @follow = ''
|
@@ -106,16 +89,25 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
106
89
|
end
|
107
90
|
return
|
108
91
|
else
|
109
|
-
@text = tokens.join(
|
92
|
+
@text = tokens.join(' ').strip
|
110
93
|
if @text.to_s.empty?
|
111
|
-
|
94
|
+
text = linkk
|
95
|
+
text = linkk.gsub('/', '/­') if @shy
|
96
|
+
text = linkk.gsub('/', '/<wbr>') if @wbr
|
97
|
+
@text = "<code>#{text}</code>"
|
112
98
|
@link = "https://#{linkk}"
|
113
99
|
else
|
114
|
-
@link =
|
100
|
+
@link = if @shy
|
101
|
+
linkk.gsub('/', '/­')
|
102
|
+
elsif @wbr
|
103
|
+
linkk.gsub('/', '/<wbr>')
|
104
|
+
else
|
105
|
+
linkk
|
106
|
+
end
|
115
107
|
end
|
116
108
|
end
|
117
109
|
|
118
|
-
return if @link.start_with?
|
110
|
+
return if @link.start_with? 'http'
|
119
111
|
|
120
112
|
@follow = ''
|
121
113
|
@target = '' unless @blank
|
@@ -127,11 +119,11 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
127
119
|
@target = '' unless @blank
|
128
120
|
end
|
129
121
|
|
130
|
-
|
131
|
-
|
122
|
+
# Might set @link and @text
|
123
|
+
def match_post
|
132
124
|
config = @site.config['href']
|
133
|
-
die_if_nomatch = !config.nil? && config['nomatch'] && config['nomatch'] == 'fatal'
|
134
|
-
path, fragment = @link.split('#')
|
125
|
+
@die_if_nomatch = !config.nil? && config['nomatch'] && config['nomatch'] == 'fatal'
|
126
|
+
@path, @fragment = @link.split('#')
|
135
127
|
|
136
128
|
@logger.debug do
|
137
129
|
<<~END_DEBUG
|
@@ -142,22 +134,26 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
142
134
|
end
|
143
135
|
|
144
136
|
all_urls = @site.all_collections.map(&:url)
|
145
|
-
|
137
|
+
compute_link_and_text(all_urls)
|
138
|
+
end
|
139
|
+
|
140
|
+
def compute_link_and_text(all_urls)
|
141
|
+
url_matches = all_urls.select { |url| url&.include? @path }
|
146
142
|
case url_matches.length
|
147
143
|
when 0
|
148
|
-
abort "href error: No url matches '#{@link}'" if die_if_nomatch
|
149
|
-
@link =
|
144
|
+
abort "href error: No url matches '#{@link}'" if @die_if_nomatch
|
145
|
+
@link = '#'
|
150
146
|
@text = "<i>#{@link} is not available</i>"
|
151
147
|
when 1
|
152
148
|
@link = url_matches.first
|
153
|
-
@link = "#{@link}
|
149
|
+
@link = "#{@link}##{@fragment}" if @fragment
|
154
150
|
else
|
155
|
-
abort "Error: More than one url matched '#{path}': #{url_matches.join(
|
151
|
+
abort "Error: More than one url matched '#{@path}': #{url_matches.join(', ')}"
|
156
152
|
end
|
157
153
|
end
|
158
154
|
|
155
|
+
# Replace names in plugin-vars with values
|
159
156
|
def replace_vars(text)
|
160
|
-
# Replace names in plugin-vars with values
|
161
157
|
variables = @site.config['plugin-vars']
|
162
158
|
return text unless variables
|
163
159
|
|
@@ -167,7 +163,6 @@ class ExternalHref < Liquid::Tag # rubocop:disable Metrics/ClassLength
|
|
167
163
|
@logger.debug { "@link=#{@link}" }
|
168
164
|
text
|
169
165
|
end
|
170
|
-
end
|
171
166
|
|
172
|
-
|
173
|
-
|
167
|
+
JekyllPluginHelper.register(self, 'href')
|
168
|
+
end
|
data/spec/href_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'jekyll'
|
4
2
|
require 'jekyll_plugin_logger'
|
5
3
|
require 'yaml'
|
@@ -42,8 +40,7 @@ class TestParseContext < Liquid::ParseContext
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
|
-
|
46
|
-
class MyTest # rubocop:disable Metrics/ClassLength
|
43
|
+
class MyTest
|
47
44
|
Dir.chdir 'demo'
|
48
45
|
|
49
46
|
RSpec.describe ExternalHref do
|
@@ -62,14 +59,14 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
62
59
|
end
|
63
60
|
|
64
61
|
it "Obtains internal link with blank" do
|
65
|
-
href =
|
62
|
+
href = described_class.send(
|
66
63
|
:new,
|
67
64
|
'href',
|
68
|
-
'blank ./path/page.html internal link text'
|
65
|
+
+ 'blank ./path/page.html internal link text',
|
69
66
|
parse_context
|
70
67
|
)
|
71
|
-
href.send
|
72
|
-
linkk = href.send
|
68
|
+
href.send :globals_initial
|
69
|
+
linkk = href.send :compute_linkk
|
73
70
|
href.send(:globals_update, href.helper.argv, linkk)
|
74
71
|
expect(href.follow).to eq('')
|
75
72
|
expect(href.link).to eq('./path/page.html')
|
@@ -78,10 +75,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
78
75
|
end
|
79
76
|
|
80
77
|
it "Obtains external link with text" do
|
81
|
-
href =
|
78
|
+
href = described_class.send(
|
82
79
|
:new,
|
83
80
|
'href',
|
84
|
-
'https://feeds.soundcloud.com/users/soundcloud:users:7143896/sounds.rss SoundCloud RSS Feed'
|
81
|
+
+ 'https://feeds.soundcloud.com/users/soundcloud:users:7143896/sounds.rss SoundCloud RSS Feed',
|
85
82
|
parse_context
|
86
83
|
)
|
87
84
|
href.send(:globals_initial, parse_context)
|
@@ -94,10 +91,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
94
91
|
end
|
95
92
|
|
96
93
|
it "Obtains external link using url parameter with text" do
|
97
|
-
href =
|
94
|
+
href = described_class.send(
|
98
95
|
:new,
|
99
96
|
'href',
|
100
|
-
'url="https://feeds.soundcloud.com/users/soundcloud:users:7143896/sounds.rss" SoundCloud RSS Feed'
|
97
|
+
+ 'url="https://feeds.soundcloud.com/users/soundcloud:users:7143896/sounds.rss" SoundCloud RSS Feed',
|
101
98
|
parse_context
|
102
99
|
)
|
103
100
|
href.send(:globals_initial, parse_context)
|
@@ -110,10 +107,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
110
107
|
end
|
111
108
|
|
112
109
|
it "Obtains external link without scheme or text" do
|
113
|
-
href =
|
110
|
+
href = described_class.send(
|
114
111
|
:new,
|
115
112
|
'href',
|
116
|
-
'super-fake-merger.com'
|
113
|
+
+ 'super-fake-merger.com',
|
117
114
|
parse_context
|
118
115
|
)
|
119
116
|
href.send(:globals_initial, parse_context)
|
@@ -126,10 +123,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
126
123
|
end
|
127
124
|
|
128
125
|
it "Expands YAML hash with link text" do
|
129
|
-
href =
|
126
|
+
href = described_class.send(
|
130
127
|
:new,
|
131
128
|
'href',
|
132
|
-
'{{github}}/diasks2/confidential_info_redactor <code>confidential_info_redactor</code>'
|
129
|
+
+ '{{github}}/diasks2/confidential_info_redactor <code>confidential_info_redactor</code>',
|
133
130
|
parse_context
|
134
131
|
)
|
135
132
|
href.send(:globals_initial, parse_context)
|
@@ -143,10 +140,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
143
140
|
end
|
144
141
|
|
145
142
|
it "Obtains external link with follow" do
|
146
|
-
href =
|
143
|
+
href = described_class.send(
|
147
144
|
:new,
|
148
145
|
'href',
|
149
|
-
'follow https://www.mslinn.com Awesome'
|
146
|
+
+ 'follow https://www.mslinn.com Awesome',
|
150
147
|
parse_context
|
151
148
|
)
|
152
149
|
href.send(:globals_initial, parse_context)
|
@@ -159,10 +156,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
159
156
|
end
|
160
157
|
|
161
158
|
it "Obtains external link with follow and notarget" do
|
162
|
-
href =
|
159
|
+
href = described_class.send(
|
163
160
|
:new,
|
164
161
|
'href',
|
165
|
-
'follow notarget https://www.mslinn.com Awesome'
|
162
|
+
+ 'follow notarget https://www.mslinn.com Awesome',
|
166
163
|
parse_context
|
167
164
|
)
|
168
165
|
href.send(:globals_initial, parse_context)
|
@@ -175,10 +172,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
175
172
|
end
|
176
173
|
|
177
174
|
it "Obtains external link with blank" do
|
178
|
-
href =
|
175
|
+
href = described_class.send(
|
179
176
|
:new,
|
180
177
|
'href',
|
181
|
-
'blank https://www.mslinn.com Awesome'
|
178
|
+
+ 'blank https://www.mslinn.com Awesome',
|
182
179
|
parse_context
|
183
180
|
)
|
184
181
|
href.send(:globals_initial, parse_context)
|
@@ -191,10 +188,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
191
188
|
end
|
192
189
|
|
193
190
|
it "Implicitly computes external link from text" do
|
194
|
-
href =
|
191
|
+
href = described_class.send(
|
195
192
|
:new,
|
196
193
|
'href',
|
197
|
-
'www.mslinn.com'
|
194
|
+
+ 'www.mslinn.com',
|
198
195
|
parse_context
|
199
196
|
)
|
200
197
|
href.send(:globals_initial, parse_context)
|
@@ -207,10 +204,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
207
204
|
end
|
208
205
|
|
209
206
|
it "Implicitly computes external link from text with follow and notarget" do
|
210
|
-
href =
|
207
|
+
href = described_class.send(
|
211
208
|
:new,
|
212
209
|
'href',
|
213
|
-
'follow notarget www.mslinn.com'
|
210
|
+
+ 'follow notarget www.mslinn.com',
|
214
211
|
parse_context
|
215
212
|
)
|
216
213
|
href.send(:globals_initial, parse_context)
|
@@ -223,10 +220,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
223
220
|
end
|
224
221
|
|
225
222
|
it "Implicitly computes external link from text with blank" do
|
226
|
-
href =
|
223
|
+
href = described_class.send(
|
227
224
|
:new,
|
228
225
|
'href',
|
229
|
-
'follow blank www.mslinn.com'
|
226
|
+
+ 'follow blank www.mslinn.com',
|
230
227
|
parse_context
|
231
228
|
)
|
232
229
|
href.send(:globals_initial, parse_context)
|
@@ -239,10 +236,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
239
236
|
end
|
240
237
|
|
241
238
|
it "Obtains mailto without text" do
|
242
|
-
href =
|
239
|
+
href = described_class.send(
|
243
240
|
:new,
|
244
241
|
'href',
|
245
|
-
'mailto:mslinn@mslinn.com'
|
242
|
+
+ 'mailto:mslinn@mslinn.com',
|
246
243
|
parse_context
|
247
244
|
)
|
248
245
|
href.send(:globals_initial, parse_context)
|
@@ -255,10 +252,10 @@ class MyTest # rubocop:disable Metrics/ClassLength
|
|
255
252
|
end
|
256
253
|
|
257
254
|
it "Obtains mailto with text" do
|
258
|
-
href =
|
255
|
+
href = described_class.send(
|
259
256
|
:new,
|
260
257
|
'href',
|
261
|
-
'mailto:mslinn@mslinn.com Mike Slinn'
|
258
|
+
+ 'mailto:mslinn@mslinn.com Mike Slinn',
|
262
259
|
parse_context
|
263
260
|
)
|
264
261
|
href.send(:globals_initial, parse_context)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_href
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -28,58 +28,22 @@ dependencies:
|
|
28
28
|
name: jekyll_all_collections
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
31
|
+
- - "~>"
|
39
32
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: jekyll_plugin_logger
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
33
|
+
version: 0.3.0
|
45
34
|
- - ">="
|
46
35
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
36
|
+
version: 0.3.1
|
48
37
|
type: :runtime
|
49
38
|
prerelease: false
|
50
39
|
version_requirements: !ruby/object:Gem::Requirement
|
51
40
|
requirements:
|
52
|
-
- - "
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: key-value-parser
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
41
|
+
- - "~>"
|
60
42
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: shellwords
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
43
|
+
version: 0.3.0
|
80
44
|
- - ">="
|
81
45
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
46
|
+
version: 0.3.1
|
83
47
|
description: 'Generates an ''a href'' tag, possibly with target=''_blank'' and rel=''nofollow''.
|
84
48
|
|
85
49
|
'
|
@@ -97,7 +61,6 @@ files:
|
|
97
61
|
- jekyll_href.gemspec
|
98
62
|
- lib/jekyll_href.rb
|
99
63
|
- lib/jekyll_href/version.rb
|
100
|
-
- lib/jekyll_tag_helper2.rb
|
101
64
|
- spec/href_spec.rb
|
102
65
|
- spec/spec_helper.rb
|
103
66
|
- spec/status_persistence.txt
|
data/lib/jekyll_tag_helper2.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'shellwords'
|
4
|
-
require 'key_value_parser'
|
5
|
-
|
6
|
-
# Parses arguments and options
|
7
|
-
class JekyllTagHelper2
|
8
|
-
attr_reader :argv, :keys_values, :liquid_context, :logger, :markup, :params, :tag_name
|
9
|
-
|
10
|
-
# Expand a environment variable reference
|
11
|
-
def self.expand_env(str, die_if_undefined: false)
|
12
|
-
str.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) do
|
13
|
-
envar = Regexp.last_match(1)
|
14
|
-
raise HrefError, "jekyll_href error: #{envar} is undefined".red, [] \
|
15
|
-
if !ENV.key?(envar) && die_if_undefined # Suppress stack trace
|
16
|
-
|
17
|
-
ENV[envar]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# strip leading and trailing quotes if present
|
22
|
-
def self.remove_quotes(string)
|
23
|
-
string.strip.gsub(/\A'|\A"|'\Z|"\Z/, '').strip if string
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(tag_name, markup, logger)
|
27
|
-
# @keys_values was a Hash[Symbol, String|Boolean] but now it is Hash[String, String|Boolean]
|
28
|
-
@tag_name = tag_name
|
29
|
-
@markup = markup # Useful for debugging
|
30
|
-
@argv = Shellwords.split(JekyllTagHelper2.expand_env(markup))
|
31
|
-
@keys_values = KeyValueParser \
|
32
|
-
.new({}, { array_values: false, normalize_keys: false, separator: /=/ }) \
|
33
|
-
.parse(@argv)
|
34
|
-
@logger = logger
|
35
|
-
@logger.debug { "@keys_values='#{@keys_values}'" }
|
36
|
-
end
|
37
|
-
|
38
|
-
def delete_parameter(key)
|
39
|
-
return if @keys_values.empty?
|
40
|
-
|
41
|
-
@params.delete(key)
|
42
|
-
@argv.delete_if { |x| x == key or x.start_with?("#{key}=") }
|
43
|
-
@keys_values.delete(key)
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return if parameter was specified, removes it from the available tokens and returns value
|
47
|
-
def parameter_specified?(name)
|
48
|
-
return false if @keys_values.empty?
|
49
|
-
|
50
|
-
key = name
|
51
|
-
key = name.to_sym if @keys_values.first.first.instance_of?(Symbol)
|
52
|
-
value = @keys_values[key]
|
53
|
-
delete_parameter(name)
|
54
|
-
value
|
55
|
-
end
|
56
|
-
|
57
|
-
PREDEFINED_SCOPE_KEYS = %i[include page].freeze
|
58
|
-
|
59
|
-
# Finds variables defined in an invoking include, or maybe somewhere else
|
60
|
-
# @return variable value or nil
|
61
|
-
def dereference_include_variable(name)
|
62
|
-
@liquid_context.scopes.each do |scope|
|
63
|
-
next if PREDEFINED_SCOPE_KEYS.include? scope.keys.first
|
64
|
-
|
65
|
-
value = scope[name]
|
66
|
-
return value if value
|
67
|
-
end
|
68
|
-
nil
|
69
|
-
end
|
70
|
-
|
71
|
-
# @return value of variable, or the empty string
|
72
|
-
def dereference_variable(name)
|
73
|
-
value = @liquid_context[name] # Finds variables named like 'include.my_variable', found in @liquid_context.scopes.first
|
74
|
-
value ||= @page[name] if @page # Finds variables named like 'page.my_variable'
|
75
|
-
value ||= dereference_include_variable(name)
|
76
|
-
value ||= ''
|
77
|
-
value
|
78
|
-
end
|
79
|
-
|
80
|
-
# Sets @params by replacing any Liquid variable names with their values
|
81
|
-
def liquid_context=(context)
|
82
|
-
@liquid_context = context
|
83
|
-
@params = @keys_values.map { |k, _v| lookup_variable(k) }
|
84
|
-
end
|
85
|
-
|
86
|
-
def lookup_variable(symbol)
|
87
|
-
string = symbol.to_s
|
88
|
-
return string unless string.start_with?('{{') && string.end_with?('}}')
|
89
|
-
|
90
|
-
dereference_variable(string.delete_prefix('{{').delete_suffix('}}'))
|
91
|
-
end
|
92
|
-
|
93
|
-
def page
|
94
|
-
@liquid_context.registers[:page]
|
95
|
-
end
|
96
|
-
end
|