jekyll_href 1.0.14 → 1.2.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.
- 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
|