qiita-markdown 0.14.0 → 0.15.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.

Potentially problematic release.


This version of qiita-markdown might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f54a09d35de11e6c0b8048cfe8dde77a4b909896
4
- data.tar.gz: 367ea2b6458da0baaa0bd09d80713110bcdee391
3
+ metadata.gz: aeafaca650b98a99a00e0735bde849f99faff1fb
4
+ data.tar.gz: 2911b685bc654da88a608ba1ee7c4636027c9a40
5
5
  SHA512:
6
- metadata.gz: e9e187cc785090db99d4b1b9197a8b3f1f148ff681ddfd7be4ca84d66593e5e14a2921362228ee69e8cb577076bdb42a9d7884563d3a3feed8c6a87d86cf9983
7
- data.tar.gz: 6a54122f245928bd01551fbc2734da61643d77942238020cbc4045bb807eda27b0b62b3b44d27977dd7d0fa38b009be3aa32b05d9eb0bbb8c1579d5be50778ce
6
+ metadata.gz: 019f1dd78735350a0e5c43f0c869fc3656ae858aaeec5d659b9eab64a1d040f3e0685a26313facb6fa750b526aecf676ad5b874aca06a49e18867fa384a60030
7
+ data.tar.gz: 26232bd99bac696a6eb05cd37054a53c0227773db46f78f0406abc63f0076d1b84ad06ca0058d53d8d2dcb18a4fbc5966f3f867f1f49f7d50f65f8d2eacbe7ff
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 0.15.0
2
+ - Append rel=nofollow and target=_blank to all external a tags
3
+
1
4
  ## 0.14.0
2
5
  - Add some attributes to mentions for rendering hovercard
3
6
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ Qiita-specified markdown processor.
15
15
  Qiita::Markdown::Processor provides markdown rendering logic.
16
16
 
17
17
  ```ruby
18
- processor = Qiita::Markdown::Processor.new
18
+ processor = Qiita::Markdown::Processor.new(hostname: "example.com")
19
19
  processor.call(markdown)
20
20
  # => {
21
21
  # codes: [
@@ -38,7 +38,7 @@ Qiita::Markdown is built on [jch/html-pipeline](https://github.com/jch/html-pipe
38
38
  Add your favorite html-pipeline-compatible filters.
39
39
 
40
40
  ```ruby
41
- processor = Qiita::Markdown::Processor.new
41
+ processor = Qiita::Markdown::Processor.new(hostname: "example.com")
42
42
  processor.filters << HTML::Pipeline::ImageMaxWidthFilter
43
43
  processor.call(text)
44
44
  ```
@@ -55,13 +55,14 @@ processor.call(text)
55
55
  :emoji_names - A list of allowed emoji names. (Array<String>)
56
56
  :emoji_url_generator - #call'able object that accepts emoji name as argument and returns emoji image URL. (#call)
57
57
  The original implementation is used when the generator returned a falsey value.
58
+ :hostname - FQDN. Used to check whether or not each URL of `href` attributes is external site. (String)
58
59
  :language_aliases - Alias table for some language names. (Hash)
59
60
  :rule - Sanitization rule table. (Hash)
60
61
  :script - A flag to allow to embed script element. (Boolean)
61
62
  ```
62
63
 
63
64
  ```ruby
64
- processor = Qiita::Markdown::Processor.new(asset_root: "http://example.com/assets")
65
+ processor = Qiita::Markdown::Processor.new(asset_root: "http://example.com/assets", hostname: "example.com")
65
66
  processor.call(text)
66
67
  ```
67
68
 
@@ -87,6 +88,6 @@ SummaryProcessor accepts the following context in addition to the Processor's co
87
88
  ```
88
89
 
89
90
  ```ruby
90
- processor = Qiita::Markdown::SummaryProcessor.new(truncate: { length: 80 })
91
+ processor = Qiita::Markdown::SummaryProcessor.new(truncate: { length: 80 }, hostname: "example.com")
91
92
  processor.call(text)
92
93
  ```
@@ -10,6 +10,7 @@ require "sanitize"
10
10
  require "qiita/markdown/filters/checkbox"
11
11
  require "qiita/markdown/filters/code"
12
12
  require "qiita/markdown/filters/emoji"
13
+ require "qiita/markdown/filters/external_link"
13
14
  require "qiita/markdown/filters/footnote"
14
15
  require "qiita/markdown/filters/greenmat"
15
16
  require "qiita/markdown/filters/group_mention"
@@ -0,0 +1,41 @@
1
+ require "addressable/uri"
2
+
3
+ module Qiita
4
+ module Markdown
5
+ module Filters
6
+ class ExternalLink < HTML::Pipeline::Filter
7
+ def call
8
+ doc.search("a").each do |anchor|
9
+ next unless anchor["href"]
10
+ href = anchor["href"].strip
11
+ href_host = host_of(href)
12
+ next unless href_host
13
+ if href_host != hostname
14
+ anchor["rel"] = "nofollow"
15
+ anchor["target"] = "_blank"
16
+ end
17
+ end
18
+
19
+ doc
20
+ end
21
+
22
+ def validate
23
+ needs :hostname
24
+ end
25
+
26
+ private
27
+
28
+ def host_of(url)
29
+ uri = Addressable::URI.parse(url)
30
+ uri.host
31
+ rescue Addressable::URI::InvalidURIError
32
+ nil
33
+ end
34
+
35
+ def hostname
36
+ context[:hostname]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -49,6 +49,7 @@ module Qiita
49
49
  "data-hovercard-target-name",
50
50
  "data-hovercard-target-type",
51
51
  "href",
52
+ "rel",
52
53
  ],
53
54
  "iframe" => [
54
55
  "allowfullscreen",
@@ -15,6 +15,7 @@ module Qiita
15
15
  Filters::SyntaxHighlight,
16
16
  Filters::Mention,
17
17
  Filters::GroupMention,
18
+ Filters::ExternalLink,
18
19
  Filters::Sanitize,
19
20
  ]
20
21
 
@@ -9,6 +9,7 @@ module Qiita
9
9
  Filters::Simplify,
10
10
  Filters::Emoji,
11
11
  Filters::Mention,
12
+ Filters::ExternalLink,
12
13
  Filters::Sanitize,
13
14
  Filters::Truncate,
14
15
  ]
@@ -1,5 +1,5 @@
1
1
  module Qiita
2
2
  module Markdown
3
- VERSION = "0.14.0"
3
+ VERSION = "0.15.0"
4
4
  end
5
5
  end
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency "pygments.rb"
26
26
  spec.add_dependency "greenmat", ">= 3.2.0.2", "< 4"
27
27
  spec.add_dependency "sanitize"
28
+ spec.add_dependency "addressable"
28
29
  spec.add_development_dependency "activesupport", "4.2.6"
29
30
  spec.add_development_dependency "benchmark-ips", "~> 1.2"
30
31
  spec.add_development_dependency "bundler", "~> 1.7"
@@ -7,7 +7,7 @@ describe Qiita::Markdown::Processor do
7
7
  end
8
8
 
9
9
  let(:context) do
10
- {}
10
+ { hostname: "example.com" }
11
11
  end
12
12
 
13
13
  let(:markdown) do
@@ -482,7 +482,7 @@ describe Qiita::Markdown::Processor do
482
482
 
483
483
  it "replaces it with preferred link and updates :mentioned_groups" do
484
484
  is_expected.to eq <<-EOS.strip_heredoc
485
- <p><a href="https://alice.example.com/groups/bob">@alice/bob</a></p>
485
+ <p><a href="https://alice.example.com/groups/bob" rel="nofollow" target="_blank">@alice/bob</a></p>
486
486
  EOS
487
487
  expect(result[:mentioned_groups]).to eq [{
488
488
  group_url_name: "bob",
@@ -517,13 +517,13 @@ describe Qiita::Markdown::Processor do
517
517
 
518
518
  context "with raw URL" do
519
519
  let(:markdown) do
520
- "http://qiita.com/search?q=日本語"
520
+ "http://example.com/search?q=日本語"
521
521
  end
522
522
 
523
523
  it "creates link for that with .autolink class" do
524
524
  should eq(
525
- '<p><a href="http://qiita.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E" class="autolink">' \
526
- "http://qiita.com/search?q=日本語</a></p>\n"
525
+ '<p><a href="http://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E" class="autolink">' \
526
+ "http://example.com/search?q=日本語</a></p>\n"
527
527
  )
528
528
  end
529
529
  end
@@ -745,7 +745,7 @@ describe Qiita::Markdown::Processor do
745
745
 
746
746
  it "generates footnotes elements" do
747
747
  should eq <<-EOS.strip_heredoc
748
- <p><sup id="fnref1"><a href="#fn1" title="test">1</a></sup></p>
748
+ <p><sup id="fnref1"><a href="#fn1" rel="footnote" title="test">1</a></sup></p>
749
749
 
750
750
  <div class="footnotes">
751
751
  <hr>
@@ -764,13 +764,13 @@ describe Qiita::Markdown::Processor do
764
764
  context "with manually written link inside of <sup> tag" do
765
765
  let(:markdown) do
766
766
  <<-EOS.strip_heredoc
767
- <sup>[Qiita](http://qiita.com/)</sup>
767
+ <sup>[Example](http://example.com/)</sup>
768
768
  EOS
769
769
  end
770
770
 
771
771
  it "does not confuse the structure with automatically generated footnote reference" do
772
772
  should eq <<-EOS.strip_heredoc
773
- <p><sup><a href="http://qiita.com/">Qiita</a></sup></p>
773
+ <p><sup><a href="http://example.com/">Example</a></sup></p>
774
774
  EOS
775
775
  end
776
776
  end
@@ -847,5 +847,137 @@ describe Qiita::Markdown::Processor do
847
847
  )
848
848
  end
849
849
  end
850
+
851
+ context "with internal URL" do
852
+ let(:markdown) do
853
+ "http://qiita.com/?a=b"
854
+ end
855
+
856
+ let(:context) do
857
+ { hostname: "qiita.com" }
858
+ end
859
+
860
+ it "creates link which does not have rel='nofollow' and target='_blank'" do
861
+ should eq(
862
+ '<p><a href="http://qiita.com/?a=b" class="autolink">' \
863
+ "http://qiita.com/?a=b</a></p>\n"
864
+ )
865
+ end
866
+ end
867
+
868
+ context "with external URL" do
869
+ let(:markdown) do
870
+ "http://external.com/?a=b"
871
+ end
872
+
873
+ let(:context) do
874
+ { hostname: "qiita.com" }
875
+ end
876
+
877
+ it "creates link which has rel='nofollow' and target='_blank'" do
878
+ should eq(
879
+ '<p><a href="http://external.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
880
+ "http://external.com/?a=b</a></p>\n"
881
+ )
882
+ end
883
+ end
884
+
885
+ context "with internal anchor tag" do
886
+ let(:markdown) do
887
+ '<a href="http://qiita.com/?a=b">foobar</a>'
888
+ end
889
+
890
+ let(:context) do
891
+ { hostname: "qiita.com" }
892
+ end
893
+
894
+ it "creates link which does not have rel='nofollow' and target='_blank'" do
895
+ should eq(
896
+ "<p><a href=\"http://qiita.com/?a=b\">foobar</a></p>\n"
897
+ )
898
+ end
899
+ end
900
+
901
+ context "with external anchor tag" do
902
+ let(:markdown) do
903
+ '<a href="http://external.com/?a=b">foobar</a>'
904
+ end
905
+
906
+ let(:context) do
907
+ { hostname: "qiita.com" }
908
+ end
909
+
910
+ it "creates link which has rel='nofollow' and target='_blank'" do
911
+ should eq(
912
+ "<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
913
+ )
914
+ end
915
+ end
916
+
917
+ context "with external URL which ends with the hostname parameter" do
918
+ let(:markdown) do
919
+ "http://qqqqqqiita.com/?a=b"
920
+ end
921
+
922
+ let(:context) do
923
+ { hostname: "qiita.com" }
924
+ end
925
+
926
+ it "creates link which has rel='nofollow' and target='_blank'" do
927
+ should eq(
928
+ '<p><a href="http://qqqqqqiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
929
+ "http://qqqqqqiita.com/?a=b</a></p>\n"
930
+ )
931
+ end
932
+ end
933
+
934
+ context "with external anchor tag which ends with the hostname parameter" do
935
+ let(:markdown) do
936
+ '<a href="http://qqqqqqiita.com/?a=b">foobar</a>'
937
+ end
938
+
939
+ let(:context) do
940
+ { hostname: "qiita.com" }
941
+ end
942
+
943
+ it "creates link which has rel='nofollow' and target='_blank'" do
944
+ should eq(
945
+ "<p><a href=\"http://qqqqqqiita.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
946
+ )
947
+ end
948
+ end
949
+
950
+ context "with sub-domain URL of hostname parameter" do
951
+ let(:markdown) do
952
+ "http://sub.qiita.com/?a=b"
953
+ end
954
+
955
+ let(:context) do
956
+ { hostname: "qiita.com" }
957
+ end
958
+
959
+ it "creates link which has rel='nofollow' and target='_blank'" do
960
+ should eq(
961
+ '<p><a href="http://sub.qiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
962
+ "http://sub.qiita.com/?a=b</a></p>\n"
963
+ )
964
+ end
965
+ end
966
+
967
+ context "with external anchor tag which has rel attribute" do
968
+ let(:markdown) do
969
+ '<a href="http://external.com/?a=b" rel="url">foobar</a>'
970
+ end
971
+
972
+ let(:context) do
973
+ { hostname: "qiita.com" }
974
+ end
975
+
976
+ it "creates link which has rel='nofollow' and target='_blank', and rel value is overwritten" do
977
+ should eq(
978
+ "<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
979
+ )
980
+ end
981
+ end
850
982
  end
851
983
  end
@@ -7,7 +7,7 @@ describe Qiita::Markdown::SummaryProcessor do
7
7
  end
8
8
 
9
9
  let(:context) do
10
- {}
10
+ { hostname: "example.com" }
11
11
  end
12
12
 
13
13
  let(:markdown) do
@@ -185,17 +185,17 @@ describe Qiita::Markdown::SummaryProcessor do
185
185
 
186
186
  context "with a long document consisting of nested elements" do
187
187
  before do
188
- context[:truncate] = { length: 10 }
188
+ context[:truncate] = { length: 12 }
189
189
  end
190
190
 
191
191
  let(:markdown) do
192
192
  <<-EOS.strip_heredoc
193
- _[Qiita](http://qiita.com/) is **a technical knowledge sharing and collaboration platform for programmers**._
193
+ _[Example](http://example.com/) is **a technical knowledge sharing and collaboration platform for programmers**._
194
194
  EOS
195
195
  end
196
196
 
197
197
  it "truncates it while honoring the document structure" do
198
- should eq '<em><a href="http://qiita.com/">Qiita</a> is <strong>…</strong></em>'
198
+ should eq '<em><a href="http://example.com/">Example</a> is <strong>…</strong></em>'
199
199
  end
200
200
  end
201
201
 
@@ -206,13 +206,13 @@ describe Qiita::Markdown::SummaryProcessor do
206
206
 
207
207
  let(:markdown) do
208
208
  <<-EOS.strip_heredoc
209
- **12** 4 [ 6](http://qiita.com/)_7
209
+ **12** 4 [ 6](http://example.com/)_7
210
210
  9_ 123
211
211
  EOS
212
212
  end
213
213
 
214
214
  it "truncates it while counting the consecutive whilespaces as one" do
215
- should eq "<strong>12</strong> 4 <a href=\"http://qiita.com/\"> 6</a><em>7\n9</em>…"
215
+ should eq "<strong>12</strong> 4 <a href=\"http://example.com/\"> 6</a><em>7\n9</em>…"
216
216
  end
217
217
  end
218
218
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita-markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-22 00:00:00.000000000 Z
11
+ date: 2016-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gemoji
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: addressable
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: activesupport
119
133
  requirement: !ruby/object:Gem::Requirement
@@ -250,6 +264,7 @@ files:
250
264
  - lib/qiita/markdown/filters/checkbox.rb
251
265
  - lib/qiita/markdown/filters/code.rb
252
266
  - lib/qiita/markdown/filters/emoji.rb
267
+ - lib/qiita/markdown/filters/external_link.rb
253
268
  - lib/qiita/markdown/filters/footnote.rb
254
269
  - lib/qiita/markdown/filters/greenmat.rb
255
270
  - lib/qiita/markdown/filters/group_mention.rb
@@ -301,4 +316,3 @@ test_files:
301
316
  - spec/qiita/markdown/processor_spec.rb
302
317
  - spec/qiita/markdown/summary_processor_spec.rb
303
318
  - spec/spec_helper.rb
304
- has_rdoc: