qiita-markdown 0.5.0 → 0.6.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/benchmark/heading_anchor_rendering.rb +16 -13
- data/lib/qiita/markdown.rb +1 -0
- data/lib/qiita/markdown/greenmat/heading_rendering.rb +19 -1
- data/lib/qiita/markdown/greenmat/html_renderer.rb +2 -2
- data/lib/qiita/markdown/greenmat/html_toc_renderer.rb +8 -3
- data/lib/qiita/markdown/version.rb +1 -1
- data/spec/qiita/markdown/greenmat/html_renderer_spec.rb +15 -0
- data/spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb +40 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48dcd3a415c694cd2793884f2b1fff63a05a291c
|
4
|
+
data.tar.gz: 03ef10b80d3fff879e4fe499dc0f1e487edf0735
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(:
|
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}>#{
|
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
|
-
|
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
|
241
|
+
# rendering 14 i/100ms
|
238
242
|
# -------------------------------------------------
|
239
|
-
# post process
|
240
|
-
# rendering
|
243
|
+
# post process 44.9 (±13.4%) i/s - 224 in 5.066301s
|
244
|
+
# rendering 151.1 (±16.5%) i/s - 742 in 5.057789s
|
241
245
|
#
|
242
246
|
# Comparison:
|
243
|
-
# rendering:
|
244
|
-
# post process:
|
245
|
-
#
|
247
|
+
# rendering: 151.1 i/s
|
248
|
+
# post process: 44.9 i/s - 3.36x slower
|
data/lib/qiita/markdown.rb
CHANGED
@@ -6,7 +6,17 @@ module Qiita
|
|
6
6
|
@counter ||= Hash.new(0)
|
7
7
|
end
|
8
8
|
|
9
|
-
AbstractHeading
|
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}>#{
|
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}#{
|
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}\">#{
|
62
|
+
"<a href=\"##{suffixed_id}\">#{body}</a>\n"
|
58
63
|
end
|
59
64
|
|
60
65
|
def increment
|
@@ -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&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&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&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&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&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"><b>R&amp;B</b></a>
|
131
|
+
</li>
|
132
|
+
</ul>
|
133
|
+
EOS
|
134
|
+
end
|
135
|
+
end
|
97
136
|
end
|