jekyll_href 1.2.5 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,4 @@
1
- `Jekyll_href`
2
- [![Gem Version](https://badge.fury.io/rb/jekyll_href.svg)](https://badge.fury.io/rb/jekyll_href)
3
- ===========
1
+ # `Jekyll_href` [![Gem Version](https://badge.fury.io/rb/jekyll_href.svg)](https://badge.fury.io/rb/jekyll_href)
4
2
 
5
3
  `Jekyll_href` is a Jekyll plugin that provides a new Liquid tag: `href`.
6
4
  It provides a convenient way to generate formatted and clickable URIs.
@@ -8,55 +6,77 @@ The Liquid tag generates an `a href` HTML tag,
8
6
  which by default contains `target="_blank"` and `rel="nofollow"`.
9
7
 
10
8
  If the url starts with `http`, or the `match` keyword is specified:
11
- - The url will open in a new tab or window.
12
- - The url will include `rel="nofollow"` for SEO purposes.
9
+
10
+ - The url will open in a new tab or window.
11
+ - The url will include `rel="nofollow"` for SEO purposes.
13
12
 
14
13
  CAUTION: if linked text contains a single or double quote,
15
14
  you will see the error message: `Liquid Exception: Unmatched quote`.
16
- Instead, use:
15
+ Instead, use one of the following:
17
16
 
18
- - `'` (')
19
- - `"` (")
20
- - `‘` (‘)
21
- - `’` (’)
22
- - `“` (“)
23
- - `”` (”)
17
+ - `'` (')
18
+ - `"` (")
19
+ - `‘` (‘)
20
+ - `’` (’)
21
+ - `“` (“)
22
+ - `”` (”)
24
23
 
25
24
 
26
25
  ## Configuration
26
+
27
27
  In `_config.yml`, if a section called `plugin-vars` exists,
28
28
  then its name/value pairs are available for substitution.
29
+
29
30
  ```yaml
30
31
  plugin-vars:
31
32
  django-github: 'https://github.com/django/django/blob/3.1.7'
32
33
  django-oscar-github: 'https://github.com/django-oscar/django-oscar/blob/3.0.2'
33
34
  ```
34
35
 
36
+ The following sections and settings can be set:
37
+ `Pry_on_href_error` has priority over `die_on_href_error`.
35
38
 
36
- ## Syntax 1 (requires `url` does not have embedded spaces)
39
+ ```yaml
40
+ href:
41
+ die_on_href_error: false # Default value is false
42
+ die_on_nomatch: true # Default value is false
43
+ pry_on_href_error: true # Default value is false
44
+ href_summary:
45
+ die_on_href_error: false # Default value is false
46
+ pry_on_href_error: true # Default value is false
37
47
  ```
38
- {% href [match | [follow] [blank|notarget] [summary_exclude]] url text to display %}
48
+
49
+ ## Syntax 1 (requires `url` without embedded spaces)
50
+
51
+ ```html
52
+ {% href [match | [follow] [blank|notarget] [page_title] [summary_exclude]] url text to display %}
39
53
  ```
40
- 1. The url must be a single token, without embedded spaces.
41
- 2. The url need not be enclosed in quotes.
42
- 3. The square brackets denote optional keyword parameters, and should not be typed.
54
+
55
+ 1. The url must be a single token, without embedded spaces.
56
+ 2. The url need not be enclosed in quotes.
57
+ 3. The square brackets denote optional keyword parameters, and should not be typed.
43
58
 
44
59
 
45
60
  ## Syntax 2 (always works)
61
+
46
62
  This syntax is recommended when the URL contains a colon (:).
47
- ```
48
- {% href [match | [follow] [blank|notarget]] [summary_exclude]
63
+
64
+ ```html
65
+ {% href [match | [follow] [blank|notarget]] [page_title] [summary_exclude]
49
66
  url="http://link.com with space.html" some text %}
50
67
  ```
51
- 1. Each of the above examples contain an embedded newline, which is legal.
52
- 2. The url must be enclosed by either single or double quotes.
53
- 3. The square brackets denote optional keyword parameters, and should not be typed.
68
+
69
+ 1. Each of the above examples contain an embedded newline, which is legal.
70
+ 2. The url must be enclosed by either single or double quotes.
71
+ 3. The square brackets denote optional keyword parameters, and should not be typed.
54
72
 
55
73
 
56
74
  ## Syntax 3 (implicit URL)
75
+
76
+ ```html
77
+ {% href [match | [follow] [blank|notarget] [page_title] [summary_exclude]] [shy|wbr] www.domain.com %}
57
78
  ```
58
- {% href [match | [follow] [blank|notarget] [summary_exclude]] [shy|wbr] www.domain.com %}
59
- ```
79
+
60
80
  The URI provided, for example `www.domain.com`,
61
81
  is used to form the URL by prepending `https://`,
62
82
  in this case the result would be `https://www.domain.com`.
@@ -65,9 +85,11 @@ so the resulting text is `<code>www.domain.com</code>`.
65
85
 
66
86
 
67
87
  ## Environment Variable Expansion
88
+
68
89
  URLs can contain environment variable references.
69
90
  For example, if `$domain`, `$uri` and `$USER` are environment variables:
70
- ```
91
+
92
+ ```html
71
93
  {% href http://$domain.html some text %}
72
94
 
73
95
  {% href url="$uri" some text %}
@@ -75,151 +97,199 @@ For example, if `$domain`, `$uri` and `$USER` are environment variables:
75
97
  {% href https://mslinn.html <code>USER=$USER</code> %}
76
98
  ```
77
99
 
100
+
78
101
  ## Optional Parameters
102
+
103
+ ### `page_title`
104
+
105
+ For local pages, use the linked page title as the link text.
106
+ This value overrides any provided link text.
107
+
108
+
79
109
  ### `blank`
110
+
80
111
  The `target='_blank'` attribute is not normally generated for relative links.
81
112
  To enforce the generation of this attribute, preface the link with the word `blank`.
82
113
  The `blank` and `notarget` parameters are mutually exclusive.
83
114
  If both are specified, `blank` prevails.
84
115
 
116
+
85
117
  ### `class`
118
+
86
119
  This option allows CSS classes to be added to the HTML generated by the `href` tag.
87
120
  It has no effect on the `href_summary` tag output.
88
121
 
89
122
  For example:
90
123
 
91
- ```
124
+ ```html
92
125
  {% href class='bg_yellow' https://mslinn.com click here %}
93
126
  ```
127
+
94
128
  Expands to:
95
- ```
129
+
130
+ ```html
96
131
  <a href="https://mslinn.com" class="bg_yellow" rel="nofollow" target="_blank">click here</a>
97
132
  ```
98
133
 
134
+
99
135
  ### `follow`
136
+
100
137
  To suppress the `nofollow` attribute, preface the link with the word `follow`.
101
138
 
139
+
102
140
  ### `label='whatever you want'`
141
+
103
142
  If the text to be linked contains an optional keyword argument,
104
143
  for example `summary`, that word will be removed from the displayed link text,
105
144
  unless the link text is provided via the `label` option.
106
145
  Both of the following produce the same output:
107
- ```
146
+
147
+ ```html
108
148
  {% href https://mslinn.com label="This is a summary" %}
109
149
  {% href label="This is a summary" https://mslinn.com %}
110
150
  ```
111
151
 
112
- ### `notarget`
113
- To suppress the `target` attribute, preface the link with the word `notarget`.
114
- The `blank` and `notarget` parameters are mutually exclusive.
115
- If both are specified, `blank` prevails.
116
-
117
152
 
118
153
  ### `match`
154
+
119
155
  `match` will attempt to match the url fragment (specified as a regex) to a URL in any collection.
120
156
  If multiple documents have matching URL an error is thrown.
121
157
  The `match` option looks through the pages collection for a URL with containing the provided substring.
122
158
  `Match` implies `follow` and `notarget`.
123
159
 
124
160
 
161
+ ### `notarget`
162
+
163
+ To suppress the `target` attribute, preface the link with the word `notarget`.
164
+ The `blank` and `notarget` parameters are mutually exclusive.
165
+ If both are specified, `blank` prevails.
166
+
167
+
125
168
  ### `shy`
169
+
126
170
  The `shy` keyword option is only applicable for syntax 3 (implicit URL).
127
- This option causes displayed urls to have an [`&amp;shy;`](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens) inserted after each slash (/).
171
+ This option causes displayed urls to have an
172
+ [`&amp;shy;`](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens)
173
+ inserted after each slash (/).
128
174
  If both `shy` and `wbr` are specified, `wbr` prevails.
129
175
 
130
176
  For example:
131
- ```
177
+
178
+ ```html
132
179
  {% href shy mslinn.com/path/to/page.html %}
133
180
  ```
181
+
134
182
  Expands to:
135
- ```
183
+
184
+ ```html
136
185
  <a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/&shy;path/&shy;to/&shy;page.html</a>
137
186
  ```
138
187
 
188
+
139
189
  ### `style`
190
+
140
191
  This option allows CSS styling to be added to the HTML generated by the `href` tag.
141
192
  It has no effect on the `href_summary` tag output.
142
193
 
143
194
  For example:
144
195
 
145
- ```
196
+ ```html
146
197
  {% href style='color: red; font-weight: bold;' https://mslinn.com click here %}
147
198
  ```
199
+
148
200
  Expands to:
149
- ```
201
+
202
+ ```html
150
203
  <a href="https://mslinn.com" rel="nofollow" style="color: ref; font-weight: bold" target="_blank">click here</a>
151
204
  ```
152
205
 
206
+
153
207
  ### `summary`
208
+
154
209
  The `summary` name/value option provides an override for the linked text in the **References** section
155
210
  generated by the `{% href_summary %}` tag.
156
211
  If the value is the empty string, or no value is provided, the `href` tag is not included in the page summary.
157
212
 
158
213
 
159
214
  ### `summary_exclude`
215
+
160
216
  The `summary_exclude` keyword option prevents this `href` tag from appearing in the summary
161
- produced by the [<code>href_summary</code> tag](#href_summary).
217
+ produced by the [`href_summary` tag](#href_summary).
162
218
  You probably want all of your menu items (whose links are generated by the `href` tag) to have this keyword option.
163
219
 
164
220
  `mailto:` links are always excluded, so there is no need to use this keyword option for those types of links.
165
221
 
166
222
 
167
223
  ### `wbr`
224
+
168
225
  The `wbr` keyword option is only applicable for syntax 3 (implicit URL).
169
226
  It add [line break opportunites](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr).
170
227
  This option causes displayed urls to have an `&lt;wbr&gt;` inserted after each slash (/).
171
228
  If both `shy` and `wbr` are specified, `wbr` prevails.
172
229
 
173
230
  For example:
174
- ```
231
+
232
+ ```html
175
233
  {% href wbr mslinn.com/path/to/page.html %}
176
234
  ```
235
+
177
236
  Expands to:
178
- ```
237
+
238
+ ```html
179
239
  <a href="https://mslinn.com/path/to/page.html" rel="nofollow" target="_blank">mslinn.com/<wbr>path/<wbr>to/<wbr>page.html</a>
180
240
  ```
181
241
 
182
242
 
183
243
  ## Examples
184
- 1. Generates `nofollow` and `target` attributes:
185
- ```
186
- {% href https://mslinn.com The Awesome %}
187
- ```
188
244
 
189
- 2. Does not generate `nofollow` or `target` attributes.
190
- ```
191
- {% href follow notarget https://mslinn.com The Awesome %}
192
- ```
245
+ 1. Generates `nofollow` and `target` attributes:
193
246
 
194
- 3. Does not generate `nofollow` attribute.
195
- ```
196
- {% href follow https://mslinn.com The Awesome %}
197
- ```
247
+ ```html
248
+ {% href https://mslinn.com The Awesome %}
249
+ ```
198
250
 
199
- 4. Does not generate `target` attribute.
200
- ```
201
- {% href notarget https://mslinn.com The Awesome %}
202
- ```
251
+ 2. Does not generate `nofollow` or `target` attributes.
203
252
 
204
- 5. Matches page with URL containing abc.
205
- ```
206
- {% href match abc The Awesome %}
207
- ```
253
+ ```html
254
+ {% href follow notarget https://mslinn.com The Awesome %}
255
+ ```
208
256
 
209
- 6. Matches page with URL containing abc.
210
- ```
211
- {% href match abc.html#tag The Awesome %}
212
- ```
257
+ 3. Does not generate `nofollow` attribute.
213
258
 
214
- 7. Substitute name/value pair for the `django-github` variable defined above:
215
- ```
216
- {% href {{django-github}}/django/core/management/__init__.py#L398-L401
217
- <code>django.core.management.execute_from_command_line</code> %}
218
- ```
219
- Substitutions are only made to the URL, not to the linked text.
259
+ ```html
260
+ {% href follow https://mslinn.com The Awesome %}
261
+ ```
262
+
263
+ 4. Does not generate `target` attribute.
264
+
265
+ ```html
266
+ {% href notarget https://mslinn.com The Awesome %}
267
+ ```
268
+
269
+ 5. Matches page with URL containing abc.
270
+
271
+ ```html
272
+ {% href match abc The Awesome %}
273
+ ```
274
+
275
+ 6. Matches page with URL containing abc.
276
+
277
+ ```html
278
+ {% href match abc.html#tag The Awesome %}
279
+ ```
280
+
281
+ 7. Substitute name/value pair for the `django-github` variable defined above:
282
+
283
+ ```html
284
+ {% href {{django-github}}/django/core/management/__init__.py#L398-L401
285
+ <code>django.core.management.execute_from_command_line</code> %}
286
+ ```
287
+
288
+ Substitutions are only made to the URL, not to the linked text.
220
289
 
221
290
 
222
291
  ## References Generation
292
+
223
293
  The `href` usages on each page can be summarized at the bottom of the pages in a **References** section.
224
294
  Links are presented in the summary in the order they appear in the page.
225
295
 
@@ -241,20 +311,23 @@ If a URL appears in more than one `href` with different `follow` values, a warni
241
311
 
242
312
 
243
313
  ### Included `href` Tags
314
+
244
315
  The following `href` tags are included in the summary:
245
316
 
246
- - Those with links that start with `http` are always included.
247
- - Those with [relative links](https://www.w3.org/TR/WD-html40-970917/htmlweb.html#h-5.1.2),
248
- and have the `include_local` keyword option.
317
+ - Those with links that start with `http` are always included.
318
+ - Those with [relative links](https://www.w3.org/TR/WD-html40-970917/htmlweb.html#h-5.1.2),
319
+ and have the `include_local` keyword option.
249
320
 
250
321
  ### Excluded `href` Tags
322
+
251
323
  The following `href` tags are excluded from the summary:
252
324
 
253
- - Those with links that start with `mailto:`.
254
- - Those having the `summary_exclude` keyword option.
325
+ - Those with links that start with `mailto:`.
326
+ - Those having the `summary_exclude` keyword option.
255
327
 
256
328
 
257
329
  ### Example
330
+
258
331
  Given these `href` and `href_summary` usages in a web page:
259
332
 
260
333
  ```html
@@ -295,6 +368,7 @@ You can read about the `attribution` option [here](https://www.mslinn.com/jekyll
295
368
 
296
369
 
297
370
  ## Additional Information
371
+
298
372
  More information is available on my website about
299
373
  [my Jekyll plugins](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
300
374
 
@@ -311,17 +385,21 @@ end
311
385
 
312
386
  And then execute:
313
387
 
314
- $ bundle install
388
+ ```shell
389
+ $ bundle
390
+ ```
315
391
 
316
392
 
317
393
  ## Generated HTML
318
394
 
319
395
  ### Without Keywords
320
- ```
396
+
397
+ ```html
321
398
  {% href https://mslinn.com The Awesome %}
322
399
  ```
323
400
 
324
401
  Expands to this:
402
+
325
403
  ```html
326
404
  <a href='https://mslinn.com' target='_blank' rel='nofollow'>The Awesome</a>
327
405
  ```
@@ -329,56 +407,69 @@ Expands to this:
329
407
  Which renders as this: <a href='https://mslinn.com' target='_blank' rel='nofollow'>The Awesome</a>
330
408
 
331
409
  ### With `follow`
332
- ```
410
+
411
+ ```html
333
412
  {% href follow https://mslinn.com The Awesome %}
334
413
  ```
335
414
 
336
415
  Expands to this:
416
+
337
417
  ```html
338
418
  <a href='https://mslinn.com' target='_blank'>The Awesome</a>
339
419
  ```
340
420
 
341
421
 
342
422
  ### With `notarget`
343
- ```
423
+
424
+ ```html
344
425
  {% href notarget https://mslinn.com The Awesome %}
345
426
  ```
346
427
 
347
428
  Expands to this:
429
+
348
430
  ```html
349
431
  <a href='https://mslinn.com' rel='nofollow'>The Awesome</a>
350
432
  ```
351
433
 
352
434
 
353
435
  ### With `follow notarget`
354
- ```
436
+
437
+ ```html
355
438
  {% href follow notarget https://mslinn.com The Awesome %}
356
439
  ```
357
440
 
358
441
  Expands to this:
442
+
359
443
  ```html
360
444
  <a href='https://mslinn.com'>The Awesome</a>
361
445
  ```
362
446
 
363
447
  ### With `match`
448
+
364
449
  Looks for a post with a matching URL.
365
- ```
450
+
451
+ ```html
366
452
  {% href match setting-up-django-oscar.html tutorial site %}
367
453
  ```
368
454
 
369
455
  Might expand to this:
456
+
370
457
  ```html
371
458
  <a href='/blog/2021/02/11/setting-up-django-oscar.html'>tutorial site</a>
372
459
  ```
373
460
 
374
461
  ### URI
462
+
375
463
  ```html
376
464
  {% href mslinn.com %}
377
465
  ```
466
+
378
467
  Expands to this:
468
+
379
469
  ```html
380
470
  <a href='https://mslinn.com' target='_blank' rel='nofollow'><code>mslinn.com</code></a>
381
471
  ```
472
+
382
473
  Which renders as: [`mslinn.com`](https://mslinn.com)
383
474
 
384
475
 
@@ -388,39 +479,46 @@ After checking out the repo, run `bin/setup` to install dependencies.
388
479
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
389
480
 
390
481
  Install development dependencies like this:
391
- ```
392
- $ BUNDLE_WITH="development" bundle install
482
+
483
+ ```shell
484
+ $ BUNDLE_WITH="development" bundle
393
485
  ```
394
486
 
395
487
  To install this gem onto your local machine, run:
488
+
396
489
  ```shell
397
490
  $ bundle exec rake install
398
491
  ```
399
492
 
400
493
  ## Test
494
+
401
495
  A test website is provided in the `demo` directory.
402
- 1. Set breakpoints.
403
496
 
404
- 2. Initiate a debug session from the command line:
405
- ```shell
406
- $ bin/attach demo
407
- ```
497
+ 1. Set breakpoints.
498
+ 2. Initiate a debug session from the command line:
408
499
 
409
- 3. Once the `Fast Debugger` signon appears, launch the test configuration called `Attach rdebug-ide`.
500
+ ```shell
501
+ $ bin/attach demo
502
+ ```
410
503
 
411
- 4. View the generated website at [`http://localhost:4444`](http://localhost:4444)
504
+ 3. Once the `Fast Debugger` signon appears, launch the test configuration called `Attach rdebug-ide`.
505
+ 4. View the generated website at [`http://localhost:4444`](http://localhost:4444)
412
506
 
413
507
 
414
508
  ## Release
509
+
415
510
  To release a new version,
416
- 1. Update the version number in `version.rb`.
417
- 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
418
- 3. Run the following:
419
- ```shell
420
- $ bundle exec rake release
421
- ```
422
- The above creates a git tag for the version, commits the created tag,
423
- and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
511
+
512
+ 1. Update the version number in `version.rb`.
513
+ 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
514
+ 3. Run the following:
515
+
516
+ ```shell
517
+ $ bundle exec rake release
518
+ ```
519
+
520
+ The above creates a git tag for the version, commits the created tag,
521
+ and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
424
522
 
425
523
 
426
524
  ## Contributing
data/jekyll_href.gemspec CHANGED
@@ -32,6 +32,6 @@ Gem::Specification.new do |spec|
32
32
 
33
33
  spec.add_dependency 'ipaddress'
34
34
  spec.add_dependency 'jekyll', '>= 3.5.0'
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'
35
+ spec.add_dependency 'jekyll_all_collections', '>= 0.3.3'
36
+ spec.add_dependency 'jekyll_plugin_support', '>= 0.8.1'
37
37
  end
data/lib/href_match.rb ADDED
@@ -0,0 +1,43 @@
1
+ module MSlinn
2
+ class HRefTag
3
+ private
4
+
5
+ def compute_link_and_text(all_urls)
6
+ url_matches = all_urls.select { |url| url&.include? @path }
7
+ case url_matches.length
8
+ when 0
9
+ abort "href error: No url matches '#{@link}', found on line #{@line_number} (after front matter) of #{@path}" if @die_if_nomatch
10
+ @link_save = @link = '#'
11
+ @text = "<i>#{@link} is not available</i>"
12
+ when 1
13
+ @link = url_matches.first
14
+ @link = "#{@link}##{@fragment}" if @fragment
15
+ @link_save = @link
16
+ else
17
+ abort "Error: More than one url matched '#{@path}': #{url_matches.join(', ')}"
18
+ end
19
+ end
20
+
21
+ def handle_match
22
+ match_post
23
+ @follow = ''
24
+ @target = '' unless @blank
25
+ end
26
+
27
+ # Might set @link and @text
28
+ def match_post
29
+ @path, @fragment = @link.split('#')
30
+
31
+ @logger.debug do
32
+ <<~END_DEBUG
33
+ @link=#{@link}
34
+ @site.posts.docs[0].url = #{@site.posts.docs[0].url}
35
+ @site.posts.docs[0].path = #{@site.posts.docs[0].path}
36
+ END_DEBUG
37
+ end
38
+
39
+ all_urls = @site.all_collections.map(&:url)
40
+ compute_link_and_text(all_urls)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ module MSlinn
2
+ class HRefTag
3
+ private
4
+
5
+ @hrefs = {}
6
+
7
+ def find_page(path)
8
+ all_pages = @site.all_collections + @site.pages
9
+ pages = if @match
10
+ all_pages.select { |page| page.url&.include? path }
11
+ elsif @label_source == :from_page_title
12
+ all_pages.select { |page| page.url == path }
13
+ end
14
+ pages&.first
15
+ end
16
+
17
+ def handle_page_title(linkk)
18
+ @follow = @target = ''
19
+ @external_link = linkk.start_with? 'http'
20
+ @local_link = !@external_link
21
+ raise HRefError, 'href tags with page_title require local links.' unless @local_link
22
+
23
+ page = find_page linkk
24
+ unless page
25
+ msg = "There is no page at path #{linkk}"
26
+ @text = "<div class='href_error'>HRefError: #{msg}</div>\n<pre> {% href #{@argument_string.strip} %}</pre>"
27
+ raise HRefError, msg
28
+ end
29
+ @text = @label = page.title
30
+ rescue HRefError => e
31
+ msg = format_error_message "#{e.message}\n<pre> {% href #{@argument_string.strip} %}</pre>"
32
+ @text = "<div class='href_error'>#{msg}</div>"
33
+ @link = linkk
34
+
35
+ e.shorten_backtrace
36
+ @logger.error { "#{e.class} raised #{JekyllPluginHelper.remove_html_tags msg}" }
37
+ raise e if @die_on_href_error
38
+
39
+ "<div class='href_error'>HRefError raised in #{self.class};\n#{msg}</div>"
40
+ ensure
41
+ if @text.to_s.empty?
42
+ handle_empty_text linkk
43
+ else
44
+ handle_text linkk
45
+ end
46
+ @label
47
+ end
48
+ end
49
+ end