qiita-markdown 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of qiita-markdown might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +2 -0
- data/lib/qiita/markdown.rb +1 -0
- data/lib/qiita/markdown/base_processor.rb +42 -0
- data/lib/qiita/markdown/filters/external_link.rb +1 -1
- data/lib/qiita/markdown/filters/greenmat.rb +9 -1
- data/lib/qiita/markdown/filters/sanitize.rb +2 -0
- data/lib/qiita/markdown/processor.rb +19 -41
- data/lib/qiita/markdown/summary_processor.rb +19 -14
- data/lib/qiita/markdown/version.rb +1 -1
- data/spec/qiita/markdown/processor_spec.rb +34 -15
- data/spec/qiita/markdown/summary_processor_spec.rb +15 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 739494b992f30301e63c329ca71f822ef80bd67a
|
4
|
+
data.tar.gz: 6f925bef2e51205cec9f663e71ddae50ef6d2097
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f002a9b803ff192b9139c8060dde2116e945aec2aec1fd9f02e3a09d45ad85c5654a7fdf8f2f7b31bd44a9f48293c693506d4b0cbeca15c9d41a2d4ae66cadf9
|
7
|
+
data.tar.gz: b718ef753796afa29aaed9dc72122a0bc88daa33db71cceea242ffe8192ff4f6238766e54ebe0f91821ebff7680b231457ce200ff7f6a0f3c38bb2936192d4af
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
## 0.16.0
|
2
|
+
- Add rel=noopener to all external a tags
|
3
|
+
- Support HTML5 `<details>` and `<summary>` elements
|
4
|
+
- Enable to change settings for footnotes
|
5
|
+
|
1
6
|
## 0.15.0
|
2
|
-
- Append rel=nofollow and target=_blank to
|
7
|
+
- Append `rel=nofollow` and `target=_blank` to `a` tags for external link
|
3
8
|
|
4
9
|
## 0.14.0
|
5
10
|
- Add some attributes to mentions for rendering hovercard
|
data/README.md
CHANGED
@@ -57,6 +57,8 @@ processor.call(text)
|
|
57
57
|
The original implementation is used when the generator returned a falsey value.
|
58
58
|
:hostname - FQDN. Used to check whether or not each URL of `href` attributes is external site. (String)
|
59
59
|
:language_aliases - Alias table for some language names. (Hash)
|
60
|
+
:markdown - A hash for enabling / disabling optional Markdown syntax. (Hash)
|
61
|
+
Currently only :footnotes (default: true) is supported.
|
60
62
|
:rule - Sanitization rule table. (Hash)
|
61
63
|
:script - A flag to allow to embed script element. (Boolean)
|
62
64
|
```
|
data/lib/qiita/markdown.rb
CHANGED
@@ -23,6 +23,7 @@ require "qiita/markdown/filters/truncate"
|
|
23
23
|
require "qiita/markdown/greenmat/heading_rendering"
|
24
24
|
require "qiita/markdown/greenmat/html_renderer"
|
25
25
|
require "qiita/markdown/greenmat/html_toc_renderer"
|
26
|
+
require "qiita/markdown/base_processor"
|
26
27
|
require "qiita/markdown/processor"
|
27
28
|
require "qiita/markdown/summary_processor"
|
28
29
|
require "qiita/markdown/version"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
# An abstract base processor for rendering a Markdown document.
|
4
|
+
class BaseProcessor
|
5
|
+
# @return [Hash] the default context for HTML::Pipeline
|
6
|
+
def self.default_context
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array<Class>] the default HTML::Pipeline filter classes
|
11
|
+
def self.default_fiters
|
12
|
+
raise NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Hash] context Optional context for HTML::Pipeline.
|
16
|
+
def initialize(context = {})
|
17
|
+
@context = self.class.default_context.merge(context)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Converts Markdown text into HTML string with extracted metadata.
|
21
|
+
#
|
22
|
+
# @param [String] input Markdown text.
|
23
|
+
# @param [Hash] context Optional context merged into default context.
|
24
|
+
# @return [Hash] Process result.
|
25
|
+
# @example
|
26
|
+
# Qiita::Markdown::Processor.new.call(markdown) #=> {
|
27
|
+
# codes: [...],
|
28
|
+
# mentioned_usernames: [...],
|
29
|
+
# output: "...",
|
30
|
+
# }
|
31
|
+
def call(input, context = {})
|
32
|
+
HTML::Pipeline.new(filters, @context).call(input, context)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @note Modify filters if you want.
|
36
|
+
# @return [Array<HTML::Pipeline::Filter>]
|
37
|
+
def filters
|
38
|
+
@filters ||= self.class.default_filters
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -2,6 +2,10 @@ module Qiita
|
|
2
2
|
module Markdown
|
3
3
|
module Filters
|
4
4
|
class Greenmat < HTML::Pipeline::TextFilter
|
5
|
+
DEFAULT_OPTIONS = {
|
6
|
+
footnotes: true,
|
7
|
+
}.freeze
|
8
|
+
|
5
9
|
# @return [Nokogiri::HTML::DocumentFragment]
|
6
10
|
def call
|
7
11
|
Nokogiri::HTML.fragment(greenmat.render(@text))
|
@@ -16,13 +20,17 @@ module Qiita
|
|
16
20
|
Qiita::Markdown::Greenmat::HTMLRenderer.new(hard_wrap: true, with_toc_data: true),
|
17
21
|
autolink: true,
|
18
22
|
fenced_code_blocks: true,
|
19
|
-
footnotes:
|
23
|
+
footnotes: options[:footnotes],
|
20
24
|
no_intra_emphasis: true,
|
21
25
|
no_mention_emphasis: true,
|
22
26
|
strikethrough: true,
|
23
27
|
tables: true,
|
24
28
|
)
|
25
29
|
end
|
30
|
+
|
31
|
+
def options
|
32
|
+
@options ||= DEFAULT_OPTIONS.merge(context[:markdown] || {})
|
33
|
+
end
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -1,48 +1,26 @@
|
|
1
1
|
module Qiita
|
2
2
|
module Markdown
|
3
|
-
class Processor
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
DEFAULT_FILTERS = [
|
9
|
-
Filters::Greenmat,
|
10
|
-
Filters::ImageLink,
|
11
|
-
Filters::Footnote,
|
12
|
-
Filters::Code,
|
13
|
-
Filters::Checkbox,
|
14
|
-
Filters::Emoji,
|
15
|
-
Filters::SyntaxHighlight,
|
16
|
-
Filters::Mention,
|
17
|
-
Filters::GroupMention,
|
18
|
-
Filters::ExternalLink,
|
19
|
-
Filters::Sanitize,
|
20
|
-
]
|
21
|
-
|
22
|
-
# @param [Hash] context Optional context for HTML::Pipeline.
|
23
|
-
def initialize(context = {})
|
24
|
-
@context = DEFAULT_CONTEXT.merge(context)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Converts Markdown text into HTML string with extracted metadata.
|
28
|
-
#
|
29
|
-
# @param [String] input Markdown text.
|
30
|
-
# @param [Hash] context Optional context merged into default context.
|
31
|
-
# @return [Hash] Process result.
|
32
|
-
# @example
|
33
|
-
# Qiita::Markdown::Processor.new.call(markdown) #=> {
|
34
|
-
# codes: [...],
|
35
|
-
# mentioned_usernames: [...],
|
36
|
-
# output: "...",
|
37
|
-
# }
|
38
|
-
def call(input, context = {})
|
39
|
-
HTML::Pipeline.new(filters, @context).call(input, context)
|
3
|
+
class Processor < BaseProcessor
|
4
|
+
def self.default_context
|
5
|
+
{
|
6
|
+
asset_root: "/images",
|
7
|
+
}
|
40
8
|
end
|
41
9
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
10
|
+
def self.default_filters
|
11
|
+
[
|
12
|
+
Filters::Greenmat,
|
13
|
+
Filters::ImageLink,
|
14
|
+
Filters::Footnote,
|
15
|
+
Filters::Code,
|
16
|
+
Filters::Checkbox,
|
17
|
+
Filters::Emoji,
|
18
|
+
Filters::SyntaxHighlight,
|
19
|
+
Filters::Mention,
|
20
|
+
Filters::GroupMention,
|
21
|
+
Filters::ExternalLink,
|
22
|
+
Filters::Sanitize,
|
23
|
+
]
|
46
24
|
end
|
47
25
|
end
|
48
26
|
end
|
@@ -3,21 +3,26 @@ module Qiita
|
|
3
3
|
# A processor for rendering a summary of markdown document. This simplifies
|
4
4
|
# a document by removing complex markups and also truncates it to a
|
5
5
|
# specific length without breaking the document structure.
|
6
|
-
class SummaryProcessor <
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
]
|
6
|
+
class SummaryProcessor < BaseProcessor
|
7
|
+
def self.default_context
|
8
|
+
{
|
9
|
+
asset_root: "/images",
|
10
|
+
markdown: {
|
11
|
+
footnotes: false,
|
12
|
+
},
|
13
|
+
}
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
def self.default_filters
|
17
|
+
[
|
18
|
+
Filters::Greenmat,
|
19
|
+
Filters::Simplify,
|
20
|
+
Filters::Emoji,
|
21
|
+
Filters::Mention,
|
22
|
+
Filters::ExternalLink,
|
23
|
+
Filters::Sanitize,
|
24
|
+
Filters::Truncate,
|
25
|
+
]
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
@@ -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" rel="nofollow" target="_blank">@alice/bob</a></p>
|
485
|
+
<p><a href="https://alice.example.com/groups/bob" rel="nofollow noopener" target="_blank">@alice/bob</a></p>
|
486
486
|
EOS
|
487
487
|
expect(result[:mentioned_groups]).to eq [{
|
488
488
|
group_url_name: "bob",
|
@@ -789,6 +789,25 @@ describe Qiita::Markdown::Processor do
|
|
789
789
|
end
|
790
790
|
end
|
791
791
|
|
792
|
+
context "with markdown: { footnotes: false } context" do
|
793
|
+
before do
|
794
|
+
context[:markdown] = { footnotes: false }
|
795
|
+
end
|
796
|
+
|
797
|
+
let(:markdown) do
|
798
|
+
<<-EOS.strip_heredoc
|
799
|
+
[^1]
|
800
|
+
[^1]: test
|
801
|
+
EOS
|
802
|
+
end
|
803
|
+
|
804
|
+
it "does not generate footnote elements" do
|
805
|
+
should eq <<-EOS.strip_heredoc
|
806
|
+
<p><a href="test">^1</a></p>
|
807
|
+
EOS
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
792
811
|
context "with data-attributes" do
|
793
812
|
let(:markdown) do
|
794
813
|
<<-EOS.strip_heredoc
|
@@ -857,7 +876,7 @@ describe Qiita::Markdown::Processor do
|
|
857
876
|
{ hostname: "qiita.com" }
|
858
877
|
end
|
859
878
|
|
860
|
-
it "creates link which does not have rel='nofollow' and target='_blank'" do
|
879
|
+
it "creates link which does not have rel='nofollow noopener' and target='_blank'" do
|
861
880
|
should eq(
|
862
881
|
'<p><a href="http://qiita.com/?a=b" class="autolink">' \
|
863
882
|
"http://qiita.com/?a=b</a></p>\n"
|
@@ -874,9 +893,9 @@ describe Qiita::Markdown::Processor do
|
|
874
893
|
{ hostname: "qiita.com" }
|
875
894
|
end
|
876
895
|
|
877
|
-
it "creates link which has rel='nofollow' and target='_blank'" do
|
896
|
+
it "creates link which has rel='nofollow noopener' and target='_blank'" do
|
878
897
|
should eq(
|
879
|
-
'<p><a href="http://external.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
|
898
|
+
'<p><a href="http://external.com/?a=b" class="autolink" rel="nofollow noopener" target="_blank">' \
|
880
899
|
"http://external.com/?a=b</a></p>\n"
|
881
900
|
)
|
882
901
|
end
|
@@ -891,7 +910,7 @@ describe Qiita::Markdown::Processor do
|
|
891
910
|
{ hostname: "qiita.com" }
|
892
911
|
end
|
893
912
|
|
894
|
-
it "creates link which does not have rel='nofollow' and target='_blank'" do
|
913
|
+
it "creates link which does not have rel='nofollow noopener' and target='_blank'" do
|
895
914
|
should eq(
|
896
915
|
"<p><a href=\"http://qiita.com/?a=b\">foobar</a></p>\n"
|
897
916
|
)
|
@@ -907,9 +926,9 @@ describe Qiita::Markdown::Processor do
|
|
907
926
|
{ hostname: "qiita.com" }
|
908
927
|
end
|
909
928
|
|
910
|
-
it "creates link which has rel='nofollow' and target='_blank'" do
|
929
|
+
it "creates link which has rel='nofollow noopener' and target='_blank'" do
|
911
930
|
should eq(
|
912
|
-
"<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
|
931
|
+
"<p><a href=\"http://external.com/?a=b\" rel=\"nofollow noopener\" target=\"_blank\">foobar</a></p>\n"
|
913
932
|
)
|
914
933
|
end
|
915
934
|
end
|
@@ -923,9 +942,9 @@ describe Qiita::Markdown::Processor do
|
|
923
942
|
{ hostname: "qiita.com" }
|
924
943
|
end
|
925
944
|
|
926
|
-
it "creates link which has rel='nofollow' and target='_blank'" do
|
945
|
+
it "creates link which has rel='nofollow noopener' and target='_blank'" do
|
927
946
|
should eq(
|
928
|
-
'<p><a href="http://qqqqqqiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
|
947
|
+
'<p><a href="http://qqqqqqiita.com/?a=b" class="autolink" rel="nofollow noopener" target="_blank">' \
|
929
948
|
"http://qqqqqqiita.com/?a=b</a></p>\n"
|
930
949
|
)
|
931
950
|
end
|
@@ -940,9 +959,9 @@ describe Qiita::Markdown::Processor do
|
|
940
959
|
{ hostname: "qiita.com" }
|
941
960
|
end
|
942
961
|
|
943
|
-
it "creates link which has rel='nofollow' and target='_blank'" do
|
962
|
+
it "creates link which has rel='nofollow noopener' and target='_blank'" do
|
944
963
|
should eq(
|
945
|
-
"<p><a href=\"http://qqqqqqiita.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
|
964
|
+
"<p><a href=\"http://qqqqqqiita.com/?a=b\" rel=\"nofollow noopener\" target=\"_blank\">foobar</a></p>\n"
|
946
965
|
)
|
947
966
|
end
|
948
967
|
end
|
@@ -956,9 +975,9 @@ describe Qiita::Markdown::Processor do
|
|
956
975
|
{ hostname: "qiita.com" }
|
957
976
|
end
|
958
977
|
|
959
|
-
it "creates link which has rel='nofollow' and target='_blank'" do
|
978
|
+
it "creates link which has rel='nofollow noopener' and target='_blank'" do
|
960
979
|
should eq(
|
961
|
-
'<p><a href="http://sub.qiita.com/?a=b" class="autolink" rel="nofollow" target="_blank">' \
|
980
|
+
'<p><a href="http://sub.qiita.com/?a=b" class="autolink" rel="nofollow noopener" target="_blank">' \
|
962
981
|
"http://sub.qiita.com/?a=b</a></p>\n"
|
963
982
|
)
|
964
983
|
end
|
@@ -973,9 +992,9 @@ describe Qiita::Markdown::Processor do
|
|
973
992
|
{ hostname: "qiita.com" }
|
974
993
|
end
|
975
994
|
|
976
|
-
it "creates link which has rel='nofollow' and target='_blank', and rel value is overwritten" do
|
995
|
+
it "creates link which has rel='nofollow noopener' and target='_blank', and rel value is overwritten" do
|
977
996
|
should eq(
|
978
|
-
"<p><a href=\"http://external.com/?a=b\" rel=\"nofollow\" target=\"_blank\">foobar</a></p>\n"
|
997
|
+
"<p><a href=\"http://external.com/?a=b\" rel=\"nofollow noopener\" target=\"_blank\">foobar</a></p>\n"
|
979
998
|
)
|
980
999
|
end
|
981
1000
|
end
|
@@ -243,5 +243,20 @@ describe Qiita::Markdown::SummaryProcessor do
|
|
243
243
|
should eq %{<a href="/alice" class="user-mention js-hovercard" title="alice" data-hovercard-target-type="user" data-hovercard-target-name="alice">@alice</a>\n}
|
244
244
|
end
|
245
245
|
end
|
246
|
+
|
247
|
+
context "with footenote syntax" do
|
248
|
+
let(:markdown) do
|
249
|
+
<<-EOS.strip_heredoc
|
250
|
+
[^1]
|
251
|
+
[^1]: test
|
252
|
+
EOS
|
253
|
+
end
|
254
|
+
|
255
|
+
it "does not generate footnote elements by default" do
|
256
|
+
should eq <<-EOS.strip_heredoc
|
257
|
+
<a href="test">^1</a>
|
258
|
+
EOS
|
259
|
+
end
|
260
|
+
end
|
246
261
|
end
|
247
262
|
end
|
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.
|
4
|
+
version: 0.16.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-
|
11
|
+
date: 2016-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gemoji
|
@@ -261,6 +261,7 @@ files:
|
|
261
261
|
- benchmark/sample.md
|
262
262
|
- lib/qiita-markdown.rb
|
263
263
|
- lib/qiita/markdown.rb
|
264
|
+
- lib/qiita/markdown/base_processor.rb
|
264
265
|
- lib/qiita/markdown/filters/checkbox.rb
|
265
266
|
- lib/qiita/markdown/filters/code.rb
|
266
267
|
- lib/qiita/markdown/filters/emoji.rb
|