jekyll-target-blank 1.0

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.
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: []