qiita-markdown 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d82079377c4ce72ef4a32e6a1c30d7b63f6e8f87
4
- data.tar.gz: 8b080251af685ea2b9547266edfb4d6a554ca5be
3
+ metadata.gz: 48dcd3a415c694cd2793884f2b1fff63a05a291c
4
+ data.tar.gz: 03ef10b80d3fff879e4fe499dc0f1e487edf0735
5
5
  SHA512:
6
- metadata.gz: c544a2bd69d30ca9386f03b24e688a939576179e604ca0c666b122220083943c884bf8610e15e4ca904d060e75c79860b3753f832d4cc7da9f8e4e3c6b62e1ef
7
- data.tar.gz: 415900299a6b8277d64c0b60143b76277f2f26fedaf6e8698f5032843e88569b93c2ebae3d5ec2aad291cbc15cd40b0496598edeb45c02c87efd8e4cf24e0cf4
6
+ metadata.gz: 35ffe04259cc89c0c2c0980f5bc7531fc7d7d9362bfd004b31cb1d9b920703f99e03315a5093f6af63465570c7546782ed6b8557476159d437710aa082dd57e4
7
+ data.tar.gz: 2b4f1b18fd5f068f4f3c309e1afa998168459ad65ee171a3d1a8d414dcc96ddd29f628d11c00ac65f4f3118cee1200834cfde864d34c3d40e2d736b2ab6a2350
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.6.0
2
+ * Add `:escape_html` extension to Qiita::Markdown::Greenmat::HTMLToCRenderer.
3
+ * Fix backward incompatibility of fragment identifier of heading that includes special HTML characters in v0.5.0.
4
+
1
5
  ## 0.5.0
2
6
  - Add renderers Qiita::Markdown::Greenmat::HTMLRenderer and Qiita::Markdown::Greenmat::HTMLToCRenderer which can be passed to `Redcarpet::Markdown.new` and generate consistent heading fragment identifiers.
3
7
 
@@ -160,11 +160,11 @@ module Rendering
160
160
  @counter ||= Hash.new(0)
161
161
  end
162
162
 
163
- Heading = Struct.new(:text, :level, :counter) do
163
+ Heading = Struct.new(:body, :level, :counter) do
164
164
  # For reference, C implementation of Redcarpet::Render::HTML#header is the following:
165
165
  # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L281-L296
166
166
  def to_s
167
- "\n<h#{level}>#{content}</h#{level}>\n"
167
+ "\n<h#{level}>#{body}</h#{level}>\n"
168
168
  end
169
169
 
170
170
  def increment
@@ -174,21 +174,21 @@ module Rendering
174
174
  private
175
175
 
176
176
  def content
177
- text
177
+ body
178
178
  end
179
179
  end
180
180
 
181
181
  class HeadingWithAnchor < Heading
182
+ def to_s
183
+ "\n<h#{level}>#{anchor_element}#{body}</h#{level}>\n"
184
+ end
185
+
182
186
  def increment
183
187
  counter[id] += 1
184
188
  end
185
189
 
186
190
  private
187
191
 
188
- def content
189
- anchor_element + text
190
- end
191
-
192
192
  def anchor_element
193
193
  %(<span id="#{suffixed_id}" class="fragment"></span><a href="##{suffixed_id}"><i class="fa fa-link"></i></a>)
194
194
  end
@@ -205,6 +205,10 @@ module Rendering
205
205
  @id ||= text.downcase.gsub(/[^\p{Word}\- ]/u, "").gsub(" ", "-")
206
206
  end
207
207
 
208
+ def text
209
+ Nokogiri::HTML.fragment(body).text
210
+ end
211
+
208
212
  def suffix
209
213
  has_count? ? "-#{count}" : ""
210
214
  end
@@ -234,12 +238,11 @@ end
234
238
 
235
239
  # Calculating -------------------------------------
236
240
  # post process 4 i/100ms
237
- # rendering 22 i/100ms
241
+ # rendering 14 i/100ms
238
242
  # -------------------------------------------------
239
- # post process 48.316.6%) i/s - 236 in 5.027265s
240
- # rendering 227.315.8%) i/s - 1122 in 5.084983s
243
+ # post process 44.913.4%) i/s - 224 in 5.066301s
244
+ # rendering 151.116.5%) i/s - 742 in 5.057789s
241
245
  #
242
246
  # Comparison:
243
- # rendering: 227.3 i/s
244
- # post process: 48.3 i/s - 4.70x slower
245
- #
247
+ # rendering: 151.1 i/s
248
+ # post process: 44.9 i/s - 3.36x slower
@@ -1,4 +1,5 @@
1
1
  require "active_support/core_ext/object/blank"
2
+ require "cgi"
2
3
  require "greenmat"
3
4
  require "html/pipeline"
4
5
  require "linguist"
@@ -6,7 +6,17 @@ module Qiita
6
6
  @counter ||= Hash.new(0)
7
7
  end
8
8
 
9
- AbstractHeading = Struct.new(:text, :level, :counter) do
9
+ class AbstractHeading
10
+ attr_reader :raw_body, :level, :counter, :escape_html
11
+ alias_method :escape_html?, :escape_html
12
+
13
+ def initialize(raw_body, level, counter, escape_html = false)
14
+ @raw_body = raw_body
15
+ @level = level
16
+ @counter = counter
17
+ @escape_html = escape_html
18
+ end
19
+
10
20
  def to_s
11
21
  fail NotImplementedError
12
22
  end
@@ -25,10 +35,18 @@ module Qiita
25
35
  count > 0
26
36
  end
27
37
 
38
+ def body
39
+ escape_html? ? CGI.escape_html(raw_body) : raw_body
40
+ end
41
+
28
42
  def id
29
43
  @id ||= text.downcase.gsub(/[^\p{Word}\- ]/u, "").gsub(" ", "-")
30
44
  end
31
45
 
46
+ def text
47
+ Nokogiri::HTML.fragment(raw_body).text
48
+ end
49
+
32
50
  def suffix
33
51
  has_count? ? "-#{count}" : ""
34
52
  end
@@ -26,7 +26,7 @@ module Qiita
26
26
  # For reference, C implementation of Redcarpet::Render::HTML#header is the following:
27
27
  # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L281-L296
28
28
  def to_s
29
- "\n<h#{level}>#{text}</h#{level}>\n"
29
+ "\n<h#{level}>#{body}</h#{level}>\n"
30
30
  end
31
31
 
32
32
  def increment
@@ -36,7 +36,7 @@ module Qiita
36
36
 
37
37
  class HeadingWithAnchor < AbstractHeading
38
38
  def to_s
39
- "\n<h#{level}>#{anchor_element}#{text}</h#{level}>\n"
39
+ "\n<h#{level}>#{anchor_element}#{body}</h#{level}>\n"
40
40
  end
41
41
 
42
42
  def increment
@@ -4,8 +4,9 @@ module Qiita
4
4
  class HTMLToCRenderer < ::Greenmat::Render::HTML_TOC
5
5
  include HeadingRendering
6
6
 
7
- def initialize(*)
7
+ def initialize(extensions = {})
8
8
  super
9
+ @extensions = extensions
9
10
  @last_level = 0
10
11
  end
11
12
 
@@ -32,7 +33,7 @@ module Qiita
32
33
  def generate_heading_html(text, level, level_difference)
33
34
  html = list_item_preceding_html(level_difference)
34
35
 
35
- anchor = HeadingAnchor.new(text, level, heading_counter)
36
+ anchor = HeadingAnchor.new(text, level, heading_counter, escape_html?)
36
37
  html << anchor.to_s
37
38
  anchor.increment
38
39
 
@@ -52,9 +53,13 @@ module Qiita
52
53
  html << "<li>\n"
53
54
  end
54
55
 
56
+ def escape_html?
57
+ @extensions[:escape_html]
58
+ end
59
+
55
60
  class HeadingAnchor < AbstractHeading
56
61
  def to_s
57
- "<a href=\"##{suffixed_id}\">#{text}</a>\n"
62
+ "<a href=\"##{suffixed_id}\">#{body}</a>\n"
58
63
  end
59
64
 
60
65
  def increment
@@ -1,5 +1,5 @@
1
1
  module Qiita
2
2
  module Markdown
3
- VERSION = "0.5.0"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
@@ -31,6 +31,21 @@ describe Qiita::Markdown::Greenmat::HTMLRenderer do
31
31
  <h3><span id="a-3" class="fragment"></span><a href="#a-3"><i class="fa fa-link"></i></a>a</h3>
32
32
  EOS
33
33
  end
34
+
35
+ context "and heading title including special HTML characters" do
36
+ let(:markdown) do
37
+ <<-EOS.strip_heredoc
38
+ # <b>R&amp;B</b>
39
+ EOS
40
+ end
41
+
42
+ it "generates fragment identifier by sanitizing the characters in the title" do
43
+ should eq <<-EOS.strip_heredoc
44
+
45
+ <h1><span id="rb" class="fragment"></span><a href="#rb"><i class="fa fa-link"></i></a><b>R&amp;B</b></h1>
46
+ EOS
47
+ end
48
+ end
34
49
  end
35
50
 
36
51
  context "without :with_toc_data extension" do
@@ -1,7 +1,8 @@
1
1
  require "active_support/core_ext/string/strip"
2
2
 
3
3
  describe Qiita::Markdown::Greenmat::HTMLToCRenderer do
4
- let(:renderer) { described_class.new }
4
+ let(:renderer) { described_class.new(extension) }
5
+ let(:extension) { {} }
5
6
  let(:greenmat) { ::Greenmat::Markdown.new(renderer) }
6
7
  subject(:rendered_html) { greenmat.render(markdown) }
7
8
 
@@ -94,4 +95,42 @@ describe Qiita::Markdown::Greenmat::HTMLToCRenderer do
94
95
  EOS
95
96
  end
96
97
  end
98
+
99
+ context "with heading title including special HTML characters" do
100
+ let(:markdown) do
101
+ <<-EOS.strip_heredoc
102
+ # <b>R&amp;B</b>
103
+ EOS
104
+ end
105
+
106
+ it "generates fragment identifier by sanitizing the characters in the title" do
107
+ should eq <<-EOS.strip_heredoc
108
+ <ul>
109
+ <li>
110
+ <a href="#rb"><b>R&amp;B</b></a>
111
+ </li>
112
+ </ul>
113
+ EOS
114
+ end
115
+ end
116
+
117
+ context "with :escape_html extension" do
118
+ let(:extension) { { escape_html: true } }
119
+
120
+ let(:markdown) do
121
+ <<-EOS.strip_heredoc
122
+ # <b>R&amp;B</b>
123
+ EOS
124
+ end
125
+
126
+ it "escapes special HTML characters in heading title" do
127
+ should eq <<-EOS.strip_heredoc
128
+ <ul>
129
+ <li>
130
+ <a href="#rb">&lt;b&gt;R&amp;amp;B&lt;/b&gt;</a>
131
+ </li>
132
+ </ul>
133
+ EOS
134
+ end
135
+ end
97
136
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita-markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura