qiita-markdown 0.32.0 → 0.37.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e3469d19ed195eb7a7ccdeeedaa1503154a262893c882768834c8636fad0ae7
4
- data.tar.gz: 3b9fec449730dcf1f19ec3d84247a7b1d89e1f785e9b52eace389cedfb9045c3
3
+ metadata.gz: a632599e029a2372e999818df8cf19474233cdafe5b0454b944d6fe93d4423ca
4
+ data.tar.gz: 6ee085f30d1b6008fe9ada38b62c91f6a7d5b68e0f656f20afdc69b5aa067c96
5
5
  SHA512:
6
- metadata.gz: cab8938cb167a8c41d6b68478f562f87e5c06a6f412c4f4e0b12c9450cb7506c380eb9ab7ef3ae73eca991d50bbb1da8d5d3e5da4a0e7fdece14ebea15053e1f
7
- data.tar.gz: 5e74b4610be3b012d1cd381ecc5e3efc41f581da095ae3a6d5836dc3b62297c7d7deac6d0e93d1c32d84385baea699bfff6f804e1f5924539b3468703d01cd94
6
+ metadata.gz: a7d84a2dd88cd53380b8b7c5ec3264ae3cbcdf29c718031dfb9d22038d7349ffeaa2cba6e6a8654b3d357c4c7a28994fecdc51f8381cdbff276930a4238ab866
7
+ data.tar.gz: 78bcee81ab1f08a311e7bf73f9bcbe6c79234c0ed999da679c285f10d69d482bf9c6e3373b2eb39896e2b8cdcd0890631539adf9fe6bfe69250f84ddcd1f4df1
data/CHANGELOG.md CHANGED
@@ -1,8 +1,26 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 0.37.0
4
+ - Change keyword of notation
5
+
6
+ ## 0.36.0
7
+ - Support message notation
8
+
9
+ ## 0.35.0
10
+
11
+ - Allow Relative URL in iframe src attributes
12
+
13
+ ## 0.34.0
14
+
15
+ - Delete gist embed rule to avoid XSS
16
+
17
+ ## 0.33.0
18
+
19
+ - Fix XSS possibility bug
20
+
3
21
  ## 0.32.0
4
22
 
5
- - Fixed XSS possibility bug
23
+ - Fix XSS possibility bug
6
24
  - Fix iframe width to be fixed at 100%
7
25
 
8
26
  ## 0.31.0
@@ -10,7 +10,6 @@ require "sanitize"
10
10
  require "qiita/markdown/embed/code_pen"
11
11
  require "qiita/markdown/embed/tweet"
12
12
  require "qiita/markdown/embed/asciinema"
13
- require "qiita/markdown/embed/gist"
14
13
  require "qiita/markdown/embed/youtube"
15
14
  require "qiita/markdown/embed/slide_share"
16
15
  require "qiita/markdown/embed/google_slide"
@@ -21,6 +20,7 @@ require "qiita/markdown/transformers/filter_iframe"
21
20
  require "qiita/markdown/transformers/strip_invalid_node"
22
21
  require "qiita/markdown/filters/checkbox"
23
22
  require "qiita/markdown/filters/code_block"
23
+ require "qiita/markdown/filters/custom_block"
24
24
  require "qiita/markdown/filters/emoji"
25
25
  require "qiita/markdown/filters/external_link"
26
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 = %w[note].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 Note
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"] = "note #{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],
@@ -14,6 +14,7 @@ module Qiita
14
14
  Filters::ImageLink,
15
15
  Filters::Footnote,
16
16
  Filters::CodeBlock,
17
+ Filters::CustomBlock,
17
18
  Filters::Checkbox,
18
19
  Filters::Toc,
19
20
  Filters::Emoji,
@@ -42,10 +42,10 @@ module Qiita
42
42
 
43
43
  def host_of(url)
44
44
  if url
45
- port = URI.parse(url).port
46
- Addressable::URI.parse(url).host if [443, 80].include? port
45
+ scheme = URI.parse(url).scheme
46
+ Addressable::URI.parse(url).host if ["http", "https", nil].include? scheme
47
47
  end
48
- rescue Addressable::URI::InvalidURIError
48
+ rescue Addressable::URI::InvalidURIError, URI::InvalidURIError
49
49
  nil
50
50
  end
51
51
  end
@@ -10,7 +10,6 @@ module Qiita
10
10
 
11
11
  HOST_WHITE_LIST = [
12
12
  Embed::Asciinema::SCRIPT_HOST,
13
- Embed::Gist::SCRIPT_HOST,
14
13
  ].flatten.freeze
15
14
 
16
15
  def self.call(*args)
@@ -44,10 +43,10 @@ module Qiita
44
43
 
45
44
  def host_of(url)
46
45
  if url
47
- port = URI.parse(url).port
48
- Addressable::URI.parse(url).host if [443, 80].include? port
46
+ scheme = URI.parse(url).scheme
47
+ Addressable::URI.parse(url).host if ["http", "https"].include? scheme
49
48
  end
50
- rescue Addressable::URI::InvalidURIError
49
+ rescue Addressable::URI::InvalidURIError, URI::InvalidURIError
51
50
  nil
52
51
  end
53
52
  end
@@ -1,5 +1,5 @@
1
1
  module Qiita
2
2
  module Markdown
3
- VERSION = "0.32.0"
3
+ VERSION = "0.37.0"
4
4
  end
5
5
  end
@@ -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.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"
@@ -1144,12 +1144,13 @@ describe Qiita::Markdown::Processor do
1144
1144
  end
1145
1145
 
1146
1146
  shared_examples_for "iframe element" do |allowed:|
1147
- context "with iframe" do
1147
+ shared_examples "iframe element example" do
1148
1148
  let(:markdown) do
1149
1149
  <<-MARKDOWN.strip_heredoc
1150
- <iframe width="1" height="2" src="//example.com" frameborder="0" allowfullscreen></iframe>
1150
+ <iframe width="1" height="2" src="#{url}" frameborder="0" allowfullscreen></iframe>
1151
1151
  MARKDOWN
1152
1152
  end
1153
+ let(:url) { "#{scheme}//example.com" }
1153
1154
 
1154
1155
  if allowed
1155
1156
  it "allows iframe with some attributes" do
@@ -1161,6 +1162,20 @@ describe Qiita::Markdown::Processor do
1161
1162
  end
1162
1163
  end
1163
1164
  end
1165
+
1166
+ context "with iframe" do
1167
+ context "with scheme" do
1168
+ let(:scheme) { "https:" }
1169
+
1170
+ include_examples "iframe element example"
1171
+ end
1172
+
1173
+ context "without scheme" do
1174
+ let(:scheme) { "" }
1175
+
1176
+ include_examples "iframe element example"
1177
+ end
1178
+ end
1164
1179
  end
1165
1180
 
1166
1181
  shared_examples_for "input element" do |allowed:|
@@ -1451,114 +1466,138 @@ describe Qiita::Markdown::Processor do
1451
1466
  end
1452
1467
  end
1453
1468
 
1454
- context "with HTML embed code for Gist" do
1455
- let(:markdown) do
1456
- <<-MARKDOWN.strip_heredoc
1457
- <script id="example" src="https://gist.github.com/a/example.js"></script>
1458
- MARKDOWN
1459
- end
1469
+ context "with HTML embed code for Youtube" do
1470
+ shared_examples "embed code youtube example" do
1471
+ let(:markdown) do
1472
+ <<-MARKDOWN.strip_heredoc
1473
+ <iframe width="100" height="100" src="#{url}"></iframe>
1474
+ MARKDOWN
1475
+ end
1476
+ let(:url) { "#{scheme}//www.youtube.com/embed/example" }
1460
1477
 
1461
- if allowed
1462
- it "does not sanitize embed code" do
1463
- should eq <<-HTML.strip_heredoc
1464
- <script id="example" src="https://gist.github.com/a/example.js"></script>
1465
- HTML
1478
+ if allowed
1479
+ it "does not sanitize embed code" do
1480
+ should eq <<-HTML.strip_heredoc
1481
+ <iframe width="100" height="100" src="#{url}"></iframe>
1482
+ HTML
1483
+ end
1484
+ else
1485
+ it "forces width attribute on iframe" do
1486
+ should eq <<-HTML.strip_heredoc
1487
+ <iframe width="100%" height="100" src="#{url}"></iframe>
1488
+ HTML
1489
+ end
1466
1490
  end
1467
- else
1468
- it "forces async attribute on script" do
1469
- should eq <<-HTML.strip_heredoc
1470
- <script id="example" src="https://gist.github.com/a/example.js" async="async"></script>
1471
- HTML
1491
+
1492
+ context "when url is privacy enhanced mode" do
1493
+ let(:markdown) do
1494
+ <<-MARKDOWN.strip_heredoc
1495
+ <iframe width="100" height="100" src="#{url}"></iframe>
1496
+ MARKDOWN
1497
+ end
1498
+ let(:url) { "#{scheme}//www.youtube-nocookie.com/embed/example" }
1499
+
1500
+ if allowed
1501
+ it "does not sanitize embed code" do
1502
+ should eq <<-HTML.strip_heredoc
1503
+ <iframe width="100" height="100" src="#{url}"></iframe>
1504
+ HTML
1505
+ end
1506
+ else
1507
+ it "forces width attribute on iframe" do
1508
+ should eq <<-HTML.strip_heredoc
1509
+ <iframe width="100%" height="100" src="#{url}"></iframe>
1510
+ HTML
1511
+ end
1512
+ end
1472
1513
  end
1473
1514
  end
1474
- end
1475
1515
 
1476
- context "with HTML embed code for Youtube" do
1477
- let(:markdown) do
1478
- <<-MARKDOWN.strip_heredoc
1479
- <iframe width="100" height="100" src="https://www.youtube.com/embed/example"></iframe>
1480
- MARKDOWN
1516
+ context "with scheme" do
1517
+ let(:scheme) { "https:" }
1518
+
1519
+ include_examples "embed code youtube example"
1481
1520
  end
1482
1521
 
1483
- if allowed
1484
- it "does not sanitize embed code" do
1485
- should eq <<-HTML.strip_heredoc
1486
- <iframe width="100" height="100" src="https://www.youtube.com/embed/example"></iframe>
1487
- HTML
1488
- end
1489
- else
1490
- it "forces width attribute on iframe" do
1491
- should eq <<-HTML.strip_heredoc
1492
- <iframe width="100%" height="100" src="https://www.youtube.com/embed/example"></iframe>
1493
- HTML
1494
- end
1522
+ context "without scheme" do
1523
+ let(:scheme) { "" }
1524
+
1525
+ include_examples "embed code youtube example"
1495
1526
  end
1527
+ end
1496
1528
 
1497
- context "when url is privacy enhanced mode" do
1529
+ context "with HTML embed code for SlideShare" do
1530
+ shared_examples "embed code slideshare example" do
1498
1531
  let(:markdown) do
1499
1532
  <<-MARKDOWN.strip_heredoc
1500
- <iframe width="100" height="100" src="https://www.youtube-nocookie.com/embed/example"></iframe>
1533
+ <iframe width="100" height="100" src="#{url}"></iframe>
1501
1534
  MARKDOWN
1502
1535
  end
1536
+ let(:url) { "#{scheme}//www.slideshare.net/embed/example" }
1503
1537
 
1504
1538
  if allowed
1505
1539
  it "does not sanitize embed code" do
1506
1540
  should eq <<-HTML.strip_heredoc
1507
- <iframe width="100" height="100" src="https://www.youtube-nocookie.com/embed/example"></iframe>
1541
+ <iframe width="100" height="100" src="#{url}"></iframe>
1508
1542
  HTML
1509
1543
  end
1510
1544
  else
1511
1545
  it "forces width attribute on iframe" do
1512
1546
  should eq <<-HTML.strip_heredoc
1513
- <iframe width="100%" height="100" src="https://www.youtube-nocookie.com/embed/example"></iframe>
1547
+ <iframe width="100%" height="100" src="#{url}"></iframe>
1514
1548
  HTML
1515
1549
  end
1516
1550
  end
1517
1551
  end
1518
- end
1519
1552
 
1520
- context "with HTML embed code for SlideShare" do
1521
- let(:markdown) do
1522
- <<-MARKDOWN.strip_heredoc
1523
- <iframe width="100" height="100" src="https://www.slideshare.net/embed/example"></iframe>
1524
- MARKDOWN
1553
+ context "with scheme" do
1554
+ let(:scheme) { "https:" }
1555
+
1556
+ include_examples "embed code slideshare example"
1525
1557
  end
1526
1558
 
1527
- if allowed
1528
- it "does not sanitize embed code" do
1529
- should eq <<-HTML.strip_heredoc
1530
- <iframe width="100" height="100" src="https://www.slideshare.net/embed/example"></iframe>
1531
- HTML
1532
- end
1533
- else
1534
- it "forces width attribute on iframe" do
1535
- should eq <<-HTML.strip_heredoc
1536
- <iframe width="100%" height="100" src="https://www.slideshare.net/embed/example"></iframe>
1537
- HTML
1538
- end
1559
+ context "without scheme" do
1560
+ let(:scheme) { "" }
1561
+
1562
+ include_examples "embed code slideshare example"
1539
1563
  end
1540
1564
  end
1541
1565
 
1542
1566
  context "with HTML embed code for GoogleSlide" do
1543
- let(:markdown) do
1544
- <<-MARKDOWN.strip_heredoc
1545
- <iframe src="https://docs.google.com/presentation/d/example/embed" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
1546
- MARKDOWN
1547
- end
1548
-
1549
- if allowed
1550
- it "does not sanitize embed code" do
1551
- should eq <<-HTML.strip_heredoc
1552
- <iframe src="https://docs.google.com/presentation/d/example/embed" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
1553
- HTML
1567
+ shared_examples "embed code googleslide example" do
1568
+ let(:markdown) do
1569
+ <<-MARKDOWN.strip_heredoc
1570
+ <iframe src="#{url}" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
1571
+ MARKDOWN
1554
1572
  end
1555
- else
1556
- it "forces width attribute on iframe" do
1557
- should eq <<-HTML.strip_heredoc
1558
- <iframe src="https://docs.google.com/presentation/d/example/embed" frameborder="0" width="100%" height="300" allowfullscreen="true"></iframe>
1559
- HTML
1573
+ let(:url) { "#{scheme}//docs.google.com/presentation/d/example/embed" }
1574
+
1575
+ if allowed
1576
+ it "does not sanitize embed code" do
1577
+ should eq <<-HTML.strip_heredoc
1578
+ <iframe src="#{url}" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
1579
+ HTML
1580
+ end
1581
+ else
1582
+ it "forces width attribute on iframe" do
1583
+ should eq <<-HTML.strip_heredoc
1584
+ <iframe src="#{url}" frameborder="0" width="100%" height="300" allowfullscreen="true"></iframe>
1585
+ HTML
1586
+ end
1560
1587
  end
1561
1588
  end
1589
+
1590
+ context "with scheme" do
1591
+ let(:scheme) { "https:" }
1592
+
1593
+ include_examples "embed code googleslide example"
1594
+ end
1595
+
1596
+ context "without scheme" do
1597
+ let(:scheme) { "" }
1598
+
1599
+ include_examples "embed code googleslide example"
1600
+ end
1562
1601
  end
1563
1602
 
1564
1603
  context "with HTML embed code for SpeekerDeck" do
@@ -1604,11 +1643,15 @@ describe Qiita::Markdown::Processor do
1604
1643
  <<-MARKDOWN.strip_heredoc
1605
1644
  <script async class="speakerdeck-embed" data-id="example" data-ratio="1.33333333333333" src="javascript://speakerdeck.com/assets/embed.js"></script>
1606
1645
  MARKDOWN
1646
+ end
1607
1647
 
1648
+ if allowed
1649
+ it "does not sanitize embed code" do
1650
+ should eq markdown
1651
+ end
1652
+ else
1608
1653
  it "forces width attribute on iframe" do
1609
- should eq <<-HTML.strip_heredoc
1610
- \n
1611
- HTML
1654
+ should eq "\n"
1612
1655
  end
1613
1656
  end
1614
1657
  end
@@ -1616,14 +1659,129 @@ describe Qiita::Markdown::Processor do
1616
1659
  context "with embed iframe code with xss" do
1617
1660
  let(:markdown) do
1618
1661
  <<-MARKDOWN.strip_heredoc
1619
- <iframe src="javascript://docs.google.com/presentation/d/example/embed" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
1662
+ <iframe src="javascript://docs.google.com:80/%0d%0aalert(document.domain)" frameborder="0" width="482" height="300" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
1620
1663
  MARKDOWN
1664
+ end
1621
1665
 
1622
- it "forces width attribute on iframe" do
1666
+ if allowed
1667
+ it "does not sanitize embed code" do
1623
1668
  should eq <<-HTML.strip_heredoc
1624
- \n
1669
+ <iframe src="javascript://docs.google.com:80/%0d%0aalert(document.domain)" frameborder="0" width="482" height="300" allowfullscreen="true"></iframe>
1625
1670
  HTML
1626
1671
  end
1672
+ else
1673
+ it "forces width attribute on iframe" do
1674
+ should eq "\n"
1675
+ end
1676
+ end
1677
+ end
1678
+ end
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 note" do
1714
+ let(:type) { "note" }
1715
+
1716
+ context "when subtype is empty" do
1717
+ if allowed
1718
+ it "returns info note block with class including icon as default type" do
1719
+ should eq <<-HTML.strip_heredoc
1720
+ <div data-type="customblock" data-metadata="note" class="note 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 note block with class including icon" do
1728
+ should eq <<-HTML.strip_heredoc
1729
+ <div class="note 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 note block with class including icon" do
1743
+ should eq <<-HTML.strip_heredoc
1744
+ <div data-type="customblock" data-metadata="note warn" class="note 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 note block with class including icon" do
1752
+ should eq <<-HTML.strip_heredoc
1753
+ <div class="note 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 note block with class including icon" do
1767
+ should eq <<-HTML.strip_heredoc
1768
+ <div data-type="customblock" data-metadata="note alert" class="note 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 note block with class including icon" do
1776
+ should eq <<-HTML.strip_heredoc
1777
+ <div class="note 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
1627
1785
  end
1628
1786
  end
1629
1787
  end
@@ -1642,6 +1800,7 @@ describe Qiita::Markdown::Processor do
1642
1800
  include_examples "class attribute", allowed: true
1643
1801
  include_examples "background-color", allowed: true
1644
1802
  include_examples "override embed code attributes", allowed: false
1803
+ include_examples "custom block", allowed: false
1645
1804
  end
1646
1805
 
1647
1806
  context "with script context" do
@@ -1658,6 +1817,7 @@ describe Qiita::Markdown::Processor do
1658
1817
  include_examples "class attribute", allowed: true
1659
1818
  include_examples "background-color", allowed: true
1660
1819
  include_examples "override embed code attributes", allowed: true
1820
+ include_examples "custom block", allowed: true
1661
1821
  end
1662
1822
 
1663
1823
  context "with strict context" do
@@ -1674,6 +1834,7 @@ describe Qiita::Markdown::Processor do
1674
1834
  include_examples "class attribute", allowed: false
1675
1835
  include_examples "background-color", allowed: false
1676
1836
  include_examples "override embed code attributes", allowed: false
1837
+ include_examples "custom block", allowed: false
1677
1838
  end
1678
1839
 
1679
1840
  context "with script and strict context" do
@@ -1690,6 +1851,7 @@ describe Qiita::Markdown::Processor do
1690
1851
  include_examples "class attribute", allowed: false
1691
1852
  include_examples "background-color", allowed: false
1692
1853
  include_examples "override embed code attributes", allowed: false
1854
+ include_examples "custom block", allowed: true
1693
1855
  end
1694
1856
  end
1695
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.32.0
4
+ version: 0.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-15 00:00:00.000000000 Z
11
+ date: 2021-07-07 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.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.1
96
+ version: 3.5.1.2
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: sanitize
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -234,7 +234,7 @@ dependencies:
234
234
  - - '='
235
235
  - !ruby/object:Gem::Version
236
236
  version: 0.49.1
237
- description:
237
+ description:
238
238
  email:
239
239
  - r7kamura@gmail.com
240
240
  executables: []
@@ -258,7 +258,6 @@ files:
258
258
  - lib/qiita/markdown/base_processor.rb
259
259
  - lib/qiita/markdown/embed/asciinema.rb
260
260
  - lib/qiita/markdown/embed/code_pen.rb
261
- - lib/qiita/markdown/embed/gist.rb
262
261
  - lib/qiita/markdown/embed/google_slide.rb
263
262
  - lib/qiita/markdown/embed/slide_share.rb
264
263
  - lib/qiita/markdown/embed/speeker_deck.rb
@@ -266,6 +265,7 @@ files:
266
265
  - lib/qiita/markdown/embed/youtube.rb
267
266
  - lib/qiita/markdown/filters/checkbox.rb
268
267
  - lib/qiita/markdown/filters/code_block.rb
268
+ - lib/qiita/markdown/filters/custom_block.rb
269
269
  - lib/qiita/markdown/filters/emoji.rb
270
270
  - lib/qiita/markdown/filters/external_link.rb
271
271
  - lib/qiita/markdown/filters/final_sanitizer.rb
@@ -301,7 +301,7 @@ homepage: https://github.com/increments/qiita-markdown
301
301
  licenses:
302
302
  - MIT
303
303
  metadata: {}
304
- post_install_message:
304
+ post_install_message:
305
305
  rdoc_options: []
306
306
  require_paths:
307
307
  - lib
@@ -317,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
317
317
  version: '0'
318
318
  requirements: []
319
319
  rubygems_version: 3.0.3
320
- signing_key:
320
+ signing_key:
321
321
  specification_version: 4
322
322
  summary: Qiita-specified markdown processor.
323
323
  test_files:
@@ -1,9 +0,0 @@
1
- module Qiita
2
- module Markdown
3
- module Embed
4
- module Gist
5
- SCRIPT_HOST = "gist.github.com".freeze
6
- end
7
- end
8
- end
9
- end