qiita-markdown 0.35.0 → 0.36.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/qiita/markdown.rb +1 -0
- data/lib/qiita/markdown/filters/custom_block.rb +63 -0
- data/lib/qiita/markdown/filters/greenmat.rb +1 -0
- data/lib/qiita/markdown/filters/user_input_sanitizer.rb +1 -1
- data/lib/qiita/markdown/processor.rb +1 -0
- data/lib/qiita/markdown/version.rb +1 -1
- data/qiita-markdown.gemspec +1 -1
- data/spec/qiita/markdown/processor_spec.rb +113 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c87f030f51598557770e12094601817c916a8e468cd030aeead44855b982dd14
|
4
|
+
data.tar.gz: 93a458246834fe89530ae20396dbffc98436be494331df2505359727e4fea92d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c94ef6737d7881c6ab6ebb7078eb9b24be05d3804362cdde38d37f16397cb2a635f1b1d7a215d61e57effa0f1043eb2c6f901d70dff6b70ae2595e2c446208e0
|
7
|
+
data.tar.gz: 7e8941da6683eb93716e05ecb89528b6208ceac2f02107c43aa3792ff6ddc302ed0fba27a7bf8a0cd488e8c66e27dc53a7c6432981e7c9b7961e24c41094cee3
|
data/CHANGELOG.md
CHANGED
data/lib/qiita/markdown.rb
CHANGED
@@ -20,6 +20,7 @@ require "qiita/markdown/transformers/filter_iframe"
|
|
20
20
|
require "qiita/markdown/transformers/strip_invalid_node"
|
21
21
|
require "qiita/markdown/filters/checkbox"
|
22
22
|
require "qiita/markdown/filters/code_block"
|
23
|
+
require "qiita/markdown/filters/custom_block"
|
23
24
|
require "qiita/markdown/filters/emoji"
|
24
25
|
require "qiita/markdown/filters/external_link"
|
25
26
|
require "qiita/markdown/filters/final_sanitizer"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Qiita
|
2
|
+
module Markdown
|
3
|
+
module Filters
|
4
|
+
class CustomBlock < HTML::Pipeline::Filter
|
5
|
+
ALLOWED_TYPES = %(message).freeze
|
6
|
+
|
7
|
+
def call
|
8
|
+
doc.search('div[data-type="customblock"]').each do |div|
|
9
|
+
metadata = Metadata.new(div["data-metadata"])
|
10
|
+
next unless ALLOWED_TYPES.include?(metadata.type)
|
11
|
+
klass = Object.const_get("#{self.class}::#{metadata.type.capitalize}")
|
12
|
+
klass.new(div, metadata.subtype).convert
|
13
|
+
end
|
14
|
+
doc
|
15
|
+
end
|
16
|
+
|
17
|
+
class Metadata
|
18
|
+
attr_reader :type, :subtype
|
19
|
+
|
20
|
+
# @param text [String, nil]
|
21
|
+
def initialize(text)
|
22
|
+
# Discared after the second word.
|
23
|
+
@type, @subtype = text.split(" ")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Message
|
28
|
+
attr_reader :node, :type
|
29
|
+
|
30
|
+
ALLOWED_TYPES = %w[info warn alert].freeze
|
31
|
+
DEFAULT_TYPE = "info".freeze
|
32
|
+
|
33
|
+
# @param node [Nokogiri::XML::Node]
|
34
|
+
# @param type [String, nil]
|
35
|
+
def initialize(node, type)
|
36
|
+
@node = node
|
37
|
+
@type = ALLOWED_TYPES.include?(type) ? type : DEFAULT_TYPE
|
38
|
+
end
|
39
|
+
|
40
|
+
def convert
|
41
|
+
node.inner_html = message
|
42
|
+
node["class"] = "message #{type}"
|
43
|
+
node.children.first.add_previous_sibling(icon) if icon
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def message
|
49
|
+
"<p>#{node.text}</p>"
|
50
|
+
end
|
51
|
+
|
52
|
+
def icon
|
53
|
+
{
|
54
|
+
info: %(<span class="fa fa-fw fa-check-circle"></span>),
|
55
|
+
warn: %(<span class="fa fa-fw fa-exclamation-circle"></span>),
|
56
|
+
alert: %(<span class="fa fa-fw fa-times-circle"></span>),
|
57
|
+
}[type.to_sym]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -20,6 +20,7 @@ module Qiita
|
|
20
20
|
Qiita::Markdown::Greenmat::HTMLRenderer.new(hard_wrap: true, with_toc_data: true),
|
21
21
|
autolink: true,
|
22
22
|
fenced_code_blocks: true,
|
23
|
+
fenced_custom_blocks: true,
|
23
24
|
footnotes: options[:footnotes],
|
24
25
|
no_intra_emphasis: true,
|
25
26
|
no_mention_emphasis: true,
|
@@ -13,7 +13,7 @@ module Qiita
|
|
13
13
|
"a" => %w[class href rel title],
|
14
14
|
"blockquote" => %w[cite] + Embed::Tweet::ATTRIBUTES,
|
15
15
|
"code" => %w[data-metadata],
|
16
|
-
"div" => %w[class],
|
16
|
+
"div" => %w[class data-type data-metadata],
|
17
17
|
"font" => %w[color],
|
18
18
|
"h1" => %w[id],
|
19
19
|
"h2" => %w[id],
|
data/qiita-markdown.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "html-pipeline", "~> 2.0"
|
24
24
|
spec.add_dependency "mem"
|
25
25
|
spec.add_dependency "pygments.rb", "~> 1.0"
|
26
|
-
spec.add_dependency "greenmat", "3.5.1.
|
26
|
+
spec.add_dependency "greenmat", "3.5.1.2"
|
27
27
|
spec.add_dependency "sanitize"
|
28
28
|
spec.add_dependency "addressable"
|
29
29
|
spec.add_development_dependency "activesupport", "4.2.6"
|
@@ -1677,6 +1677,115 @@ describe Qiita::Markdown::Processor do
|
|
1677
1677
|
end
|
1678
1678
|
end
|
1679
1679
|
|
1680
|
+
shared_examples_for "custom block" do |allowed:|
|
1681
|
+
context "with custom block" do
|
1682
|
+
let(:type) { "" }
|
1683
|
+
let(:subtype) { "" }
|
1684
|
+
|
1685
|
+
let(:markdown) do
|
1686
|
+
<<-MARKDOWN.strip_heredoc
|
1687
|
+
:::#{[type, subtype].join(' ').rstrip}
|
1688
|
+
Some kind of text is here.
|
1689
|
+
:::
|
1690
|
+
MARKDOWN
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
context "when type is not allowed" do
|
1694
|
+
let(:type) { "anytype" }
|
1695
|
+
|
1696
|
+
if allowed
|
1697
|
+
it "returns simple div element" do
|
1698
|
+
should eq <<-HTML.strip_heredoc
|
1699
|
+
<div data-type="customblock" data-metadata="anytype">Some kind of text is here.
|
1700
|
+
</div>
|
1701
|
+
HTML
|
1702
|
+
end
|
1703
|
+
else
|
1704
|
+
it "returns simple div element" do
|
1705
|
+
should eq <<-HTML.strip_heredoc
|
1706
|
+
<div>Some kind of text is here.
|
1707
|
+
</div>
|
1708
|
+
HTML
|
1709
|
+
end
|
1710
|
+
end
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
context "when type is message" do
|
1714
|
+
let(:type) { "message" }
|
1715
|
+
|
1716
|
+
context "when subtype is empty" do
|
1717
|
+
if allowed
|
1718
|
+
it "returns info message block with class including icon as default type" do
|
1719
|
+
should eq <<-HTML.strip_heredoc
|
1720
|
+
<div data-type="customblock" data-metadata="message" class="message info">
|
1721
|
+
<span class="fa fa-fw fa-check-circle"></span><p>Some kind of text is here.
|
1722
|
+
</p>
|
1723
|
+
</div>
|
1724
|
+
HTML
|
1725
|
+
end
|
1726
|
+
else
|
1727
|
+
it "returns message block with class including icon" do
|
1728
|
+
should eq <<-HTML.strip_heredoc
|
1729
|
+
<div class="message info">
|
1730
|
+
<span class="fa fa-fw fa-check-circle"></span><p>Some kind of text is here.
|
1731
|
+
</p>
|
1732
|
+
</div>
|
1733
|
+
HTML
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
context "when subtype is warn" do
|
1739
|
+
let(:subtype) { "warn" }
|
1740
|
+
|
1741
|
+
if allowed
|
1742
|
+
it "returns warning message block with class including icon" do
|
1743
|
+
should eq <<-HTML.strip_heredoc
|
1744
|
+
<div data-type="customblock" data-metadata="message warn" class="message warn">
|
1745
|
+
<span class="fa fa-fw fa-exclamation-circle"></span><p>Some kind of text is here.
|
1746
|
+
</p>
|
1747
|
+
</div>
|
1748
|
+
HTML
|
1749
|
+
end
|
1750
|
+
else
|
1751
|
+
it "returns message block with class including icon" do
|
1752
|
+
should eq <<-HTML.strip_heredoc
|
1753
|
+
<div class="message warn">
|
1754
|
+
<span class="fa fa-fw fa-exclamation-circle"></span><p>Some kind of text is here.
|
1755
|
+
</p>
|
1756
|
+
</div>
|
1757
|
+
HTML
|
1758
|
+
end
|
1759
|
+
end
|
1760
|
+
end
|
1761
|
+
|
1762
|
+
context "when subtype is alert" do
|
1763
|
+
let(:subtype) { "alert" }
|
1764
|
+
|
1765
|
+
if allowed
|
1766
|
+
it "returns alerting message block with class including icon" do
|
1767
|
+
should eq <<-HTML.strip_heredoc
|
1768
|
+
<div data-type="customblock" data-metadata="message alert" class="message alert">
|
1769
|
+
<span class="fa fa-fw fa-times-circle"></span><p>Some kind of text is here.
|
1770
|
+
</p>
|
1771
|
+
</div>
|
1772
|
+
HTML
|
1773
|
+
end
|
1774
|
+
else
|
1775
|
+
it "returns message block with class including icon" do
|
1776
|
+
should eq <<-HTML.strip_heredoc
|
1777
|
+
<div class="message alert">
|
1778
|
+
<span class="fa fa-fw fa-times-circle"></span><p>Some kind of text is here.
|
1779
|
+
</p>
|
1780
|
+
</div>
|
1781
|
+
HTML
|
1782
|
+
end
|
1783
|
+
end
|
1784
|
+
end
|
1785
|
+
end
|
1786
|
+
end
|
1787
|
+
end
|
1788
|
+
|
1680
1789
|
context "without script and strict context" do
|
1681
1790
|
let(:context) do
|
1682
1791
|
super().merge(script: false, strict: false)
|
@@ -1691,6 +1800,7 @@ describe Qiita::Markdown::Processor do
|
|
1691
1800
|
include_examples "class attribute", allowed: true
|
1692
1801
|
include_examples "background-color", allowed: true
|
1693
1802
|
include_examples "override embed code attributes", allowed: false
|
1803
|
+
include_examples "custom block", allowed: false
|
1694
1804
|
end
|
1695
1805
|
|
1696
1806
|
context "with script context" do
|
@@ -1707,6 +1817,7 @@ describe Qiita::Markdown::Processor do
|
|
1707
1817
|
include_examples "class attribute", allowed: true
|
1708
1818
|
include_examples "background-color", allowed: true
|
1709
1819
|
include_examples "override embed code attributes", allowed: true
|
1820
|
+
include_examples "custom block", allowed: true
|
1710
1821
|
end
|
1711
1822
|
|
1712
1823
|
context "with strict context" do
|
@@ -1723,6 +1834,7 @@ describe Qiita::Markdown::Processor do
|
|
1723
1834
|
include_examples "class attribute", allowed: false
|
1724
1835
|
include_examples "background-color", allowed: false
|
1725
1836
|
include_examples "override embed code attributes", allowed: false
|
1837
|
+
include_examples "custom block", allowed: false
|
1726
1838
|
end
|
1727
1839
|
|
1728
1840
|
context "with script and strict context" do
|
@@ -1739,6 +1851,7 @@ describe Qiita::Markdown::Processor do
|
|
1739
1851
|
include_examples "class attribute", allowed: false
|
1740
1852
|
include_examples "background-color", allowed: false
|
1741
1853
|
include_examples "override embed code attributes", allowed: false
|
1854
|
+
include_examples "custom block", allowed: true
|
1742
1855
|
end
|
1743
1856
|
end
|
1744
1857
|
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.36.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: 2021-
|
11
|
+
date: 2021-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gemoji
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - '='
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3.5.1.
|
89
|
+
version: 3.5.1.2
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3.5.1.
|
96
|
+
version: 3.5.1.2
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: sanitize
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -265,6 +265,7 @@ files:
|
|
265
265
|
- lib/qiita/markdown/embed/youtube.rb
|
266
266
|
- lib/qiita/markdown/filters/checkbox.rb
|
267
267
|
- lib/qiita/markdown/filters/code_block.rb
|
268
|
+
- lib/qiita/markdown/filters/custom_block.rb
|
268
269
|
- lib/qiita/markdown/filters/emoji.rb
|
269
270
|
- lib/qiita/markdown/filters/external_link.rb
|
270
271
|
- lib/qiita/markdown/filters/final_sanitizer.rb
|
@@ -315,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
315
316
|
- !ruby/object:Gem::Version
|
316
317
|
version: '0'
|
317
318
|
requirements: []
|
318
|
-
rubygems_version: 3.
|
319
|
+
rubygems_version: 3.1.4
|
319
320
|
signing_key:
|
320
321
|
specification_version: 4
|
321
322
|
summary: Qiita-specified markdown processor.
|