jekyll-target-blank 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +16 -0
  5. data/.travis.yml +25 -0
  6. data/Gemfile +5 -0
  7. data/LICENSE.md +20 -0
  8. data/README.md +92 -0
  9. data/Rakefile +6 -0
  10. data/jekyll-target-blank.gemspec +27 -0
  11. data/lib/jekyll-target-blank.rb +86 -0
  12. data/lib/jekyll-target-blank/version.rb +5 -0
  13. data/scripts/cibuild +7 -0
  14. data/scripts/quality +10 -0
  15. data/scripts/test +4 -0
  16. data/spec/fixtures/_config.yml +4 -0
  17. data/spec/fixtures/_docs/document-with-a-processable-link.md +6 -0
  18. data/spec/fixtures/_docs/document-with-include.md +5 -0
  19. data/spec/fixtures/_docs/document-with-liquid-tag.md +5 -0
  20. data/spec/fixtures/_docs/test-file.txt +5 -0
  21. data/spec/fixtures/_includes/include.html +1 -0
  22. data/spec/fixtures/_layouts/default.html +14 -0
  23. data/spec/fixtures/_posts/2018-05-17-post-with-plain-text-link.md +6 -0
  24. data/spec/fixtures/_posts/2018-05-19-post-with-html-anchor-tag.md +6 -0
  25. data/spec/fixtures/_posts/2018-05-20-post-with-external-markdown-link.md +6 -0
  26. data/spec/fixtures/_posts/2018-05-21-post-with-relative-markdown-link.md +6 -0
  27. data/spec/fixtures/_posts/2018-05-22-post-with-multiple-external-markdown-links.md +6 -0
  28. data/spec/fixtures/_posts/2018-05-23-post-with-absolute-internal-markdown-link.md +6 -0
  29. data/spec/fixtures/_posts/2018-05-24-post-with-code-block.md +14 -0
  30. data/spec/fixtures/_posts/2018-05-30-post-with-mailto-link.md +6 -0
  31. data/spec/fixtures/index.md +6 -0
  32. data/spec/jekyll-target_spec.rb +154 -0
  33. data/spec/spec_helper.rb +72 -0
  34. metadata +161 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d8da96186acb1475407698753b3b1fcd72be1d6
4
+ data.tar.gz: 98cf97e09c6fbfeb0c3400c7d5603bb433ebed44
5
+ SHA512:
6
+ metadata.gz: 8d1792a7fd4dff808bfb0baeb8b09dbae3a871cb63a21433e82203c0e6cbd1c42d30dee9b3ce3862355c1958047e809caabb50c8cacd02c0a5efcd0fb98f8986
7
+ data.tar.gz: 1b53f91c41e53238f8101847240c8e0a08843713318859e8be43c0af3fc995988802e5efbb1547dd9e70204d3b248d255cc2960789649baeb3cb5504a853eee2
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .idea
2
+ /*.gem
3
+ Gemfile.lock
4
+ dev_notes.md
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --order random
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ inherit_gem:
2
+ jekyll: .rubocop.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.3
6
+ Exclude:
7
+ - vendor/**/*
8
+
9
+ Metrics/LineLength:
10
+ Exclude:
11
+ - spec/**/*
12
+ - jekyll-target-blank.gemspec
13
+
14
+ Metrics/BlockLength:
15
+ Exclude:
16
+ - spec/**/*
data/.travis.yml ADDED
@@ -0,0 +1,25 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ - 2.4
5
+ - 2.3
6
+ before_install:
7
+ - gem update --system
8
+ - gem install bundler
9
+ script: scripts/cibuild
10
+ sudo: false
11
+ cache: bundler
12
+ env:
13
+ global:
14
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
15
+ notifications:
16
+ irc:
17
+ on_success: change
18
+ on_failure: change
19
+ channels:
20
+ - irc.freenode.org#jekyll
21
+ template:
22
+ - '%{repository}#%{build_number} (%{branch}) %{message} %{build_url}'
23
+ email:
24
+ on_success: never
25
+ on_failure: never
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Keith Mifsud <mifsud.k@gmail.com> and approved contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Jekyll Target Blank
2
+
3
+ Automatically adds a `target="_blank"` attribute to all __external__ links in Jekyll Content.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/jekyll-target-blank.svg)](https://badge.fury.io/rb/jekyll-target-blank)
6
+ [![Build Status](https://travis-ci.org/keithmifsud/jekyll-target-blank.svg?branch=master)](https://travis-ci.org/keithmifsud/jekyll-target-blank)
7
+
8
+ ## Installation
9
+
10
+ Add the following to your site's `Gemfile`
11
+
12
+ ```
13
+ gem 'jekyll-target-blank'
14
+ ```
15
+
16
+ And add the following to your site's `_config.yml`
17
+
18
+ ```yml
19
+ plugins:
20
+ - jekyll-target-blank
21
+ ```
22
+
23
+ Note: if `jekyll --version` is less than `3.5` use:
24
+
25
+ ```yml
26
+ gems:
27
+ - jekyll-target-blank
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ All anchor tags and markdown links pointing to an external host, other than the one listed as `url` in jekyll's `_config.yml` will automatically open in a new tab once the site has been generated.
33
+
34
+ This includes pages, posts and collections. __Plain text links are not included__.
35
+
36
+ ### Examples
37
+
38
+ #### HTML
39
+
40
+ The following html anchor tag:
41
+
42
+ ```html
43
+ <a href="https://google.com">Google</a>
44
+ ```
45
+
46
+ will be replaced with:
47
+
48
+ ```html
49
+ <a href="https://google.com" target="_blank">Google</a>
50
+ ```
51
+
52
+ ..unless your website's URL is google.com 😉
53
+
54
+ #### Markdown
55
+
56
+ ```markdown
57
+ [Google](https://google.com)
58
+ ```
59
+
60
+ will be generated as:
61
+
62
+ ```html
63
+ <a href="https://google.com" target="_blank">Google</a>
64
+ ```
65
+
66
+ ## Support
67
+
68
+ Simply [create an issue](https://github.com/keithmifsud/jekyll-target-blank/issues/new) and I will respond as soon as possible.
69
+
70
+
71
+ ## Contributing
72
+
73
+ 1. [Fork it](https://github.com/keithmifsud/jekyll-target-blank/fork)
74
+ 2. Create your feature branch (`git checkout -b my-new-feature)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (git push origin my-new-feature)
77
+ 4. Create a new Pull Request
78
+
79
+
80
+ ### Testing
81
+
82
+ ```bash
83
+ rake spec
84
+ # or
85
+ rspec
86
+ ```
87
+
88
+ ## Legal
89
+
90
+ This software is distributed under the [MIT](LICENSE.md) license.
91
+
92
+ &copy; 2018 - Keith Mifsud <https://keith-mifsud.me> and approved contributors.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "jekyll-target-blank/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "jekyll-target-blank"
9
+ spec.version = JekyllTargetBlank::VERSION
10
+ spec.authors = ["Keith Mifsud"]
11
+ spec.email = ["mifsud.k@gmail.com"]
12
+ spec.summary = "Target Blank automatically changes the external links to open in a new browser."
13
+ spec.description = "Target Blank automatically changes the external links to open in a new browser for Jekyll sites."
14
+ spec.homepage = "https://github.com/keithmifsud/jekyll-target-blank"
15
+ spec.license = "MIT"
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.require_paths = ["lib"]
18
+ spec.required_ruby_version = ">= 2.3.0"
19
+
20
+ spec.add_dependency "jekyll", "~> 3.0"
21
+ spec.add_dependency "nokogiri", "~> 1.8.2"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake", "~> 12.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "rubocop", "0.55"
27
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require "nokogiri"
5
+ require "uri"
6
+
7
+ module Jekyll
8
+ class TargetBlank
9
+ BODY_START_TAG = "<body"
10
+ OPENING_BODY_TAG_REGEX = %r!<body(.*)>\s*!
11
+
12
+ class << self
13
+ # Public: Processes the content and updated the external links
14
+ # by adding the target="_blank" attribute.
15
+ #
16
+ # content - the document or page to be processes.
17
+ def process(content)
18
+ @site_url = content.site.config["url"]
19
+
20
+ return unless content.output.include?("<a")
21
+
22
+ content.output = if content.output.include? BODY_START_TAG
23
+ process_html(content)
24
+ else
25
+ process_anchor_tags(content.output)
26
+ end
27
+ end
28
+
29
+ # Public: Determines if the content should be processed.
30
+ #
31
+ # doc - the document being processes.
32
+ def processable?(doc)
33
+ (doc.is_a?(Jekyll::Page) || doc.write?) &&
34
+ doc.output_ext == ".html" || (doc.permalink&.end_with?("/"))
35
+ end
36
+
37
+ private
38
+
39
+ # Private: Processes html content which has a body opening tag.
40
+ #
41
+ # content - html to be processes.
42
+ def process_html(content)
43
+ head, opener, tail = content.output.partition(OPENING_BODY_TAG_REGEX)
44
+ body_content, *rest = tail.partition("</body>")
45
+
46
+ processed_markup = process_anchor_tags(body_content)
47
+
48
+ content.output = String.new(head) << opener << processed_markup << rest.join
49
+ end
50
+
51
+ # Private: Processes the anchor tags and adds the target
52
+ # attribute if the link is external.
53
+ #
54
+ # html = the html which includes the anchor tags.
55
+ def process_anchor_tags(html)
56
+ content = Nokogiri::HTML::DocumentFragment.parse(html)
57
+ anchors = content.css("a[href]")
58
+ anchors.each do |item|
59
+ if not_mailto_link?(item["href"]) && external?(item["href"])
60
+ item["target"] = "_blank"
61
+ end
62
+ end
63
+ content.to_html
64
+ end
65
+
66
+ def not_mailto_link?(link)
67
+ return true unless link.to_s.start_with?("mailto:")
68
+ end
69
+
70
+ # Private: Checks if the links points to a host
71
+ # other than that set in Jekyll's configuration.
72
+ #
73
+ # link - a url.
74
+ def external?(link)
75
+ if link =~ URI.regexp(%w(http https))
76
+ URI.parse(link).host != URI.parse(@site_url).host
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ # Hooks into Jekyll's post_render event.
84
+ Jekyll::Hooks.register %i[pages documents], :post_render do |doc|
85
+ Jekyll::TargetBlank.process(doc) if Jekyll::TargetBlank.processable?(doc)
86
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllTargetBlank
4
+ VERSION = "1.0"
5
+ end
data/scripts/cibuild ADDED
@@ -0,0 +1,7 @@
1
+ #! /bin/sh
2
+
3
+ set -e
4
+
5
+ scripts/test
6
+ scripts/quality
7
+ bundle exec rake build
data/scripts/quality ADDED
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "Rubocop $(bundle exec rubocop --version)"
5
+ bundle exec rubocop -D -E $@
6
+ success=$?
7
+ if ((success != 0)); then
8
+ echo -e "\nTry running \`scripts/quality -a\` to automatically fix errors"
9
+ fi
10
+ exit $success
data/scripts/test ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ set -ex
3
+
4
+ bundle exec rspec "$@"
@@ -0,0 +1,4 @@
1
+ url: https://keith-mifsud.me
2
+ collections:
3
+ docs:
4
+ output: true
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Document with a processable link
4
+ ---
5
+
6
+ This is a valid [link](https://google.com).
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Document with include
3
+ ---
4
+
5
+ This is a document with an include: {% include include.html %}
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Document with liquid tag
3
+ ---
4
+
5
+ This <a href="{{ page.url }}">{{ page.path }}</a> is a document with a liquid tag.
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Text file
3
+ ---
4
+
5
+ Valid [link](https://google.com).
@@ -0,0 +1 @@
1
+ This is an include.
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE HTML>
2
+ <html lang="en-US">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>{{ page.title }}</title>
6
+ <meta name="viewport" content="width=device-width,initial-scale=1">
7
+ <link rel="stylesheet" href="/css/screen.css">
8
+ </head>
9
+ <body class="wrap">
10
+ <div>Layout content started.</div>
11
+ {{ content }}
12
+ <div>Layout content ended.</div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with plain text link
4
+ ---
5
+
6
+ This is a plain text link to https://google.com.
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with html anchor tag
4
+ ---
5
+
6
+ This is an <a href="https://google.com">anchor tag</a>.
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with external markdown link
4
+ ---
5
+
6
+ Link to [Google](https://google.com).
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with relative markdown link
4
+ ---
5
+
6
+ Link to [contact page](/contact).
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with multiple external markdown links
4
+ ---
5
+
6
+ This post contains three links. The first link is to [Google](https://google.com), the second link is, well, to [my website](https://keithmifsud.github.io) and since [GitHub](https://github.com) is so awesome, why not link to them too?
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with absolute internal markdown link
4
+ ---
5
+
6
+ This is an absolute internal [link](https://keith-mifsud.me/contact).
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: Post with code block
3
+ ---
4
+
5
+ Sample code:
6
+ ```ruby
7
+ def method(link)
8
+ if link == 'https://google.com'
9
+ link
10
+ end
11
+ end
12
+ ```
13
+
14
+ Valid [link](https://google.com)
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Post with mailto link
4
+ ---
5
+
6
+ This is a <a href="mailto:mifsud.k@gmail.com?Subject=Just an email">mailto link</a>.
@@ -0,0 +1,6 @@
1
+ ---
2
+ layout: default
3
+ title: Just a page
4
+ ---
5
+
6
+ This is a valid [link](https://google.com).
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe(Jekyll::TargetBlank) do
4
+ Jekyll.logger.log_level = :error
5
+
6
+ let(:config_overrides) { {} }
7
+ let(:configs) do
8
+ Jekyll.configuration(config_overrides.merge({
9
+ "skip_config_files" => false,
10
+ "collections" => { "docs" => { "output" => true } },
11
+ "source" => fixtures_dir,
12
+ "destination" => fixtures_dir("_site"),
13
+ }))
14
+ end
15
+ let(:target_blank) { described_class }
16
+ let(:site) { Jekyll::Site.new(configs) }
17
+ let(:posts) { site.posts.docs.sort.reverse }
18
+
19
+ # get some fixtures
20
+ let(:post_with_external_markdown_link) { find_by_title(posts, "Post with external markdown link") }
21
+
22
+ let(:post_with_multiple_external_markdown_links) { find_by_title(posts, "Post with multiple external markdown links") }
23
+
24
+ let(:post_with_relative_markdown_link) { find_by_title(posts, "Post with relative markdown link") }
25
+
26
+ let(:post_with_absolute_internal_markdown_link) { find_by_title(posts, "Post with absolute internal markdown link") }
27
+
28
+ let(:post_with_html_anchor_tag) { find_by_title(posts, "Post with html anchor tag") }
29
+
30
+ let(:post_with_plain_text_link) { find_by_title(posts, "Post with plain text link") }
31
+
32
+ let(:document_with_a_processable_link) { find_by_title(site.collections["docs"].docs, "Document with a processable link") }
33
+
34
+ let(:text_file) { find_by_title(site.collections["docs"].docs, "Text file") }
35
+
36
+ let(:post_with_code_block) { find_by_title(posts, "Post with code block") }
37
+ let(:document_with_liquid_tag) { find_by_title(site.collections["docs"].docs, "Document with liquid tag") }
38
+
39
+ let(:document_with_include) { find_by_title(site.collections["docs"].docs, "Document with include") }
40
+
41
+ let(:post_with_mailto_link) { find_by_title(posts, "Post with mailto link") }
42
+
43
+ # define common wrappers.
44
+ def para(content)
45
+ "<p>#{content}</p>"
46
+ end
47
+
48
+ before(:each) do
49
+ site.reset
50
+ site.read
51
+ (site.pages | posts | site.docs_to_write).each { |p| p.content.strip! }
52
+ site.render
53
+ end
54
+
55
+ it "should add target attribute to external markdown link" do
56
+ expect(post_with_external_markdown_link.output).to include(para('Link to <a href="https://google.com" target="_blank">Google</a>.'))
57
+ end
58
+
59
+ it "should add target attribute to multiple external markdown links" do
60
+ expect(post_with_multiple_external_markdown_links.output).to include('<p>This post contains three links. The first link is to <a href="https://google.com" target="_blank">Google</a>, the second link is, well, to <a href="https://keithmifsud.github.io" target="_blank">my website</a> and since <a href="https://github.com" target="_blank">GitHub</a> is so awesome, why not link to them too?</p>')
61
+ end
62
+
63
+ it "should not add target attribute to relative markdown link" do
64
+ expect(post_with_relative_markdown_link.output).to include(para('Link to <a href="/contact">contact page</a>.'))
65
+
66
+ expect(post_with_relative_markdown_link.output).to_not include(para('Link to <a href="/contact" target="_blank">contact page</a>'))
67
+ end
68
+
69
+ it "should not add target attribute to absolute internal link" do
70
+ expect(post_with_absolute_internal_markdown_link.output).to include('<p>This is an absolute internal <a href="https://keith-mifsud.me/contact">link</a>.</p>
71
+ ')
72
+ end
73
+
74
+ it "should correctly handle existing html anchor tag" do
75
+ expect(post_with_html_anchor_tag.output).to include('<p>This is an <a href="https://google.com" target="_blank">anchor tag</a>.</p>
76
+ ')
77
+ end
78
+
79
+ it "should not interfere with plain text link" do
80
+ expect(post_with_plain_text_link.output).to include("<p>This is a plain text link to https://google.com.</p>
81
+ ")
82
+ end
83
+
84
+ it "should process external links in collections" do
85
+ expect(document_with_a_processable_link.output).to include('<p>This is a valid <a href="https://google.com" target="_blank">link</a>.</p>
86
+ ')
87
+ end
88
+
89
+ it "should process external links in pages" do
90
+ expect(site.pages.first.output).to include('<p>This is a valid <a href="https://google.com" target="_blank">link</a>.</p>')
91
+ end
92
+
93
+ it "should not process links in non html files" do
94
+ expect(text_file.output).to eq("Valid [link](https://google.com).")
95
+ end
96
+
97
+ it "should not process link in code block but process link outside of block" do
98
+ expect(post_with_code_block.output).to include("<span class=\"s1\">'https://google.com'</span>")
99
+
100
+ expect(post_with_code_block.output).not_to include("<span class=\"s1\"><a href=\"https://google.com\" target=\"_blank\">https://google.com</a></span>")
101
+
102
+ expect(post_with_code_block.output).to include('<p>Valid <a href="https://google.com" target="_blank">link</a></p>
103
+ ')
104
+ end
105
+
106
+ it "should not break layouts" do
107
+ expect(site.pages.first.output).to include('<html lang="en-US">')
108
+ expect(site.pages.first.output).to include('<body class="wrap">')
109
+ end
110
+
111
+ it "should not interfere with liquid tags" do
112
+ expect(document_with_liquid_tag.output).to include('<p>This <a href="/docs/document-with-liquid-tag.html">_docs/document-with-liquid-tag.md</a> is a document with a liquid tag.</p>')
113
+ end
114
+
115
+ it "should not interfere with includes" do
116
+ expect(document_with_include.output).to include("<p>This is a document with an include: This is an include.</p>")
117
+ end
118
+
119
+ it "should not break layout content" do
120
+ expect(site.pages.first.output).to include("<div>Layout content started.</div>")
121
+
122
+ expect(site.pages.first.output).to include("<div>Layout content ended.</div>")
123
+ end
124
+
125
+ it "should not duplicate post content" do
126
+ expect(post_with_external_markdown_link.output).to eq(post_with_layout_result)
127
+ end
128
+
129
+ it "should ignore mailto links" do
130
+ expect(post_with_mailto_link.output).to include(para('This is a <a href="mailto:mifsud.k@gmail.com?Subject=Just%20an%20email">mailto link</a>.'))
131
+ end
132
+
133
+ private
134
+
135
+ def post_with_layout_result
136
+ <<-RESULT
137
+ <!DOCTYPE HTML>
138
+ <html lang="en-US">
139
+ <head>
140
+ <meta charset="UTF-8">
141
+ <title>Post with external markdown link</title>
142
+ <meta name="viewport" content="width=device-width,initial-scale=1">
143
+ <link rel="stylesheet" href="/css/screen.css">
144
+ </head>
145
+ <body class="wrap">
146
+ <div>Layout content started.</div>
147
+ <p>Link to <a href="https://google.com" target="_blank">Google</a>.</p>
148
+
149
+ <div>Layout content ended.</div>
150
+ </body>
151
+ </html>
152
+ RESULT
153
+ end
154
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("../lib/jekyll-target-blank.rb", __dir__)
4
+
5
+ RSpec.configure do |config|
6
+ FIXTURES_DIR = File.expand_path("fixtures", __dir__)
7
+ def fixtures_dir(*paths)
8
+ File.join(FIXTURES_DIR, *paths)
9
+ end
10
+
11
+ def find_by_title(docs, title)
12
+ docs.find { |d| d.data["title"] == title }
13
+ end
14
+
15
+ # rspec-expectations config goes here. You can use an alternate
16
+ # assertion/expectation library such as wrong or the stdlib/minitest
17
+ # assertions if you prefer.
18
+ config.expect_with :rspec do |expectations|
19
+ # This option will default to `true` in RSpec 4. It makes the `description`
20
+ # and `failure_message` of custom matchers include text for helper methods
21
+ # defined using `chain`, e.g.:
22
+ # be_bigger_than(2).and_smaller_than(4).description
23
+ # # => "be bigger than 2 and smaller than 4"
24
+ # ...rather than:
25
+ # # => "be bigger than 2"
26
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
27
+ end
28
+
29
+ # rspec-mocks config goes here. You can use an alternate test double
30
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
31
+ config.mock_with :rspec do |mocks|
32
+ # Prevents you from mocking or stubbing a method that does not exist on
33
+ # a real object. This is generally recommended, and will default to
34
+ # `true` in RSpec 4.
35
+ mocks.verify_partial_doubles = true
36
+ end
37
+
38
+ # These two settings work together to allow you to limit a spec run
39
+ # to individual examples or groups you care about by tagging them with
40
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
41
+ # get run.
42
+ config.filter_run :focus
43
+ config.run_all_when_everything_filtered = true
44
+
45
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
46
+ # For more details, see:
47
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
48
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
49
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
50
+ config.disable_monkey_patching!
51
+
52
+ # This setting enables warnings. It's recommended, but in some cases may
53
+ # be too noisy due to issues in dependencies.
54
+ config.warnings = false
55
+
56
+ # Print the 10 slowest examples and example groups at the
57
+ # end of the spec run, to help surface which specs are running
58
+ # particularly slow.
59
+ # config.profile_examples = 10
60
+
61
+ # Run specs in random order to surface order dependencies. If you find an
62
+ # order dependency and want to debug it, you can fix the order by providing
63
+ # the seed, which is printed after each run.
64
+ # --seed 1234
65
+ config.order = :random
66
+
67
+ # Seed global randomization in this process using the `--seed` CLI option.
68
+ # Setting this allows you to use `--seed` to deterministically reproduce
69
+ # test failures related to randomization by passing the same `--seed` value
70
+ # as the one that triggered the failure.
71
+ Kernel.srand config.seed
72
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-target-blank
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Keith Mifsud
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: '0.55'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: '0.55'
97
+ description: Target Blank automatically changes the external links to open in a new
98
+ browser for Jekyll sites.
99
+ email:
100
+ - mifsud.k@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".rspec"
107
+ - ".rubocop.yml"
108
+ - ".travis.yml"
109
+ - Gemfile
110
+ - LICENSE.md
111
+ - README.md
112
+ - Rakefile
113
+ - jekyll-target-blank.gemspec
114
+ - lib/jekyll-target-blank.rb
115
+ - lib/jekyll-target-blank/version.rb
116
+ - scripts/cibuild
117
+ - scripts/quality
118
+ - scripts/test
119
+ - spec/fixtures/_config.yml
120
+ - spec/fixtures/_docs/document-with-a-processable-link.md
121
+ - spec/fixtures/_docs/document-with-include.md
122
+ - spec/fixtures/_docs/document-with-liquid-tag.md
123
+ - spec/fixtures/_docs/test-file.txt
124
+ - spec/fixtures/_includes/include.html
125
+ - spec/fixtures/_layouts/default.html
126
+ - spec/fixtures/_posts/2018-05-17-post-with-plain-text-link.md
127
+ - spec/fixtures/_posts/2018-05-19-post-with-html-anchor-tag.md
128
+ - spec/fixtures/_posts/2018-05-20-post-with-external-markdown-link.md
129
+ - spec/fixtures/_posts/2018-05-21-post-with-relative-markdown-link.md
130
+ - spec/fixtures/_posts/2018-05-22-post-with-multiple-external-markdown-links.md
131
+ - spec/fixtures/_posts/2018-05-23-post-with-absolute-internal-markdown-link.md
132
+ - spec/fixtures/_posts/2018-05-24-post-with-code-block.md
133
+ - spec/fixtures/_posts/2018-05-30-post-with-mailto-link.md
134
+ - spec/fixtures/index.md
135
+ - spec/jekyll-target_spec.rb
136
+ - spec/spec_helper.rb
137
+ homepage: https://github.com/keithmifsud/jekyll-target-blank
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: 2.3.0
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.6.14.1
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Target Blank automatically changes the external links to open in a new browser.
161
+ test_files: []