qiita-markdown 0.44.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -2
  3. data/.rubocop.yml +0 -4
  4. data/.rubocop_todo.yml +15 -239
  5. data/CHANGELOG.md +15 -0
  6. data/README.md +5 -3
  7. data/lib/qiita/markdown/filters/checkbox.rb +5 -1
  8. data/lib/qiita/markdown/filters/code_block.rb +13 -13
  9. data/lib/qiita/markdown/filters/custom_block.rb +8 -6
  10. data/lib/qiita/markdown/filters/external_link.rb +2 -0
  11. data/lib/qiita/markdown/filters/final_sanitizer.rb +126 -120
  12. data/lib/qiita/markdown/filters/footnote.rb +2 -0
  13. data/lib/qiita/markdown/filters/group_mention.rb +2 -2
  14. data/lib/qiita/markdown/filters/heading_anchor.rb +44 -0
  15. data/lib/qiita/markdown/filters/html_toc.rb +67 -0
  16. data/lib/qiita/markdown/filters/image_link.rb +6 -6
  17. data/lib/qiita/markdown/filters/inline_code_color.rb +8 -8
  18. data/lib/qiita/markdown/filters/mention.rb +11 -9
  19. data/lib/qiita/markdown/filters/qiita_marker.rb +55 -0
  20. data/lib/qiita/markdown/filters/simplify.rb +1 -0
  21. data/lib/qiita/markdown/filters/syntax_highlight.rb +4 -4
  22. data/lib/qiita/markdown/filters/truncate.rb +1 -3
  23. data/lib/qiita/markdown/filters/user_input_sanitizer.rb +34 -29
  24. data/lib/qiita/markdown/processor.rb +2 -1
  25. data/lib/qiita/markdown/summary_processor.rb +1 -1
  26. data/lib/qiita/markdown/transformers/filter_attributes.rb +1 -0
  27. data/lib/qiita/markdown/transformers/filter_iframe.rb +1 -2
  28. data/lib/qiita/markdown/transformers/filter_script.rb +1 -1
  29. data/lib/qiita/markdown/transformers/strip_invalid_node.rb +1 -3
  30. data/lib/qiita/markdown/version.rb +1 -1
  31. data/lib/qiita/markdown.rb +4 -5
  32. data/qiita-markdown.gemspec +7 -8
  33. data/spec/qiita/markdown/filters/checkbox_spec.rb +28 -0
  34. data/spec/qiita/markdown/filters/heading_anchor_spec.rb +73 -0
  35. data/spec/qiita/markdown/filters/html_toc_spec.rb +223 -0
  36. data/spec/qiita/markdown/filters/qiita_marker_spec.rb +60 -0
  37. data/spec/qiita/markdown/processor_spec.rb +64 -70
  38. data/spec/qiita/markdown/summary_processor_spec.rb +4 -4
  39. metadata +80 -102
  40. data/benchmark/heading_anchor_rendering.rb +0 -248
  41. data/benchmark/sample.md +0 -317
  42. data/lib/qiita/markdown/filters/greenmat.rb +0 -38
  43. data/lib/qiita/markdown/greenmat/heading_rendering.rb +0 -61
  44. data/lib/qiita/markdown/greenmat/html_renderer.rb +0 -60
  45. data/lib/qiita/markdown/greenmat/html_toc_renderer.rb +0 -78
  46. data/spec/qiita/markdown/filters/greenmat_spec.rb +0 -15
  47. data/spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb +0 -156
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita-markdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.44.0
4
+ version: 1.0.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: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2022-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: gemoji
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -81,27 +95,41 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: 3.26.0
83
97
  - !ruby/object:Gem::Dependency
84
- name: greenmat
98
+ name: sanitize
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: 3.5.1.4
103
+ version: '0'
90
104
  type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '='
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: 3.5.1.4
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
- name: sanitize
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 5.2.7
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 5.2.7
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
129
  - - ">="
102
130
  - !ruby/object:Gem::Version
103
131
  version: '0'
104
- type: :runtime
132
+ type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
@@ -109,13 +137,27 @@ dependencies:
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
- name: addressable
140
+ name: codeclimate-test-reporter
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 0.4.4
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 0.4.4
153
+ - !ruby/object:Gem::Dependency
154
+ name: pry
113
155
  requirement: !ruby/object:Gem::Requirement
114
156
  requirements:
115
157
  - - ">="
116
158
  - !ruby/object:Gem::Version
117
159
  version: '0'
118
- type: :runtime
160
+ type: :development
119
161
  prerelease: false
120
162
  version_requirements: !ruby/object:Gem::Requirement
121
163
  requirements:
@@ -123,61 +165,61 @@ dependencies:
123
165
  - !ruby/object:Gem::Version
124
166
  version: '0'
125
167
  - !ruby/object:Gem::Dependency
126
- name: activesupport
168
+ name: qiita_marker
127
169
  requirement: !ruby/object:Gem::Requirement
128
170
  requirements:
129
171
  - - "~>"
130
172
  - !ruby/object:Gem::Version
131
- version: 5.2.7
173
+ version: 0.23.6
132
174
  type: :development
133
175
  prerelease: false
134
176
  version_requirements: !ruby/object:Gem::Requirement
135
177
  requirements:
136
178
  - - "~>"
137
179
  - !ruby/object:Gem::Version
138
- version: 5.2.7
180
+ version: 0.23.6
139
181
  - !ruby/object:Gem::Dependency
140
- name: benchmark-ips
182
+ name: rake
141
183
  requirement: !ruby/object:Gem::Requirement
142
184
  requirements:
143
185
  - - "~>"
144
186
  - !ruby/object:Gem::Version
145
- version: '1.2'
187
+ version: '10.0'
146
188
  type: :development
147
189
  prerelease: false
148
190
  version_requirements: !ruby/object:Gem::Requirement
149
191
  requirements:
150
192
  - - "~>"
151
193
  - !ruby/object:Gem::Version
152
- version: '1.2'
194
+ version: '10.0'
153
195
  - !ruby/object:Gem::Dependency
154
- name: bundler
196
+ name: rspec
155
197
  requirement: !ruby/object:Gem::Requirement
156
198
  requirements:
157
- - - ">="
199
+ - - "~>"
158
200
  - !ruby/object:Gem::Version
159
- version: '0'
201
+ version: '3.1'
160
202
  type: :development
161
203
  prerelease: false
162
204
  version_requirements: !ruby/object:Gem::Requirement
163
205
  requirements:
164
- - - ">="
206
+ - - "~>"
165
207
  - !ruby/object:Gem::Version
166
- version: '0'
208
+ version: '3.1'
167
209
  - !ruby/object:Gem::Dependency
168
- name: codeclimate-test-reporter
210
+ name: rubocop
169
211
  requirement: !ruby/object:Gem::Requirement
170
212
  requirements:
171
- - - '='
213
+ - - "~>"
172
214
  - !ruby/object:Gem::Version
173
- version: 0.4.4
215
+ version: 1.39.0
174
216
  type: :development
175
217
  prerelease: false
176
218
  version_requirements: !ruby/object:Gem::Requirement
177
219
  requirements:
178
- - - '='
220
+ - - "~>"
179
221
  - !ruby/object:Gem::Version
180
- version: 0.4.4
222
+ version: 1.39.0
181
223
  - !ruby/object:Gem::Dependency
182
224
  name: simplecov
183
225
  requirement: !ruby/object:Gem::Requirement
@@ -234,62 +276,6 @@ dependencies:
234
276
  - - "!="
235
277
  - !ruby/object:Gem::Version
236
278
  version: 0.19.1
237
- - !ruby/object:Gem::Dependency
238
- name: pry
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: '0'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- version: '0'
251
- - !ruby/object:Gem::Dependency
252
- name: rake
253
- requirement: !ruby/object:Gem::Requirement
254
- requirements:
255
- - - "~>"
256
- - !ruby/object:Gem::Version
257
- version: '10.0'
258
- type: :development
259
- prerelease: false
260
- version_requirements: !ruby/object:Gem::Requirement
261
- requirements:
262
- - - "~>"
263
- - !ruby/object:Gem::Version
264
- version: '10.0'
265
- - !ruby/object:Gem::Dependency
266
- name: rspec
267
- requirement: !ruby/object:Gem::Requirement
268
- requirements:
269
- - - "~>"
270
- - !ruby/object:Gem::Version
271
- version: '3.1'
272
- type: :development
273
- prerelease: false
274
- version_requirements: !ruby/object:Gem::Requirement
275
- requirements:
276
- - - "~>"
277
- - !ruby/object:Gem::Version
278
- version: '3.1'
279
- - !ruby/object:Gem::Dependency
280
- name: rubocop
281
- requirement: !ruby/object:Gem::Requirement
282
- requirements:
283
- - - "~>"
284
- - !ruby/object:Gem::Version
285
- version: 1.27.0
286
- type: :development
287
- prerelease: false
288
- version_requirements: !ruby/object:Gem::Requirement
289
- requirements:
290
- - - "~>"
291
- - !ruby/object:Gem::Version
292
- version: 1.27.0
293
279
  description:
294
280
  email:
295
281
  - r7kamura@gmail.com
@@ -307,8 +293,6 @@ files:
307
293
  - LICENSE.txt
308
294
  - README.md
309
295
  - Rakefile
310
- - benchmark/heading_anchor_rendering.rb
311
- - benchmark/sample.md
312
296
  - lib/qiita-markdown.rb
313
297
  - lib/qiita/markdown.rb
314
298
  - lib/qiita/markdown/base_processor.rb
@@ -328,19 +312,18 @@ files:
328
312
  - lib/qiita/markdown/filters/external_link.rb
329
313
  - lib/qiita/markdown/filters/final_sanitizer.rb
330
314
  - lib/qiita/markdown/filters/footnote.rb
331
- - lib/qiita/markdown/filters/greenmat.rb
332
315
  - lib/qiita/markdown/filters/group_mention.rb
316
+ - lib/qiita/markdown/filters/heading_anchor.rb
317
+ - lib/qiita/markdown/filters/html_toc.rb
333
318
  - lib/qiita/markdown/filters/image_link.rb
334
319
  - lib/qiita/markdown/filters/inline_code_color.rb
335
320
  - lib/qiita/markdown/filters/mention.rb
321
+ - lib/qiita/markdown/filters/qiita_marker.rb
336
322
  - lib/qiita/markdown/filters/simplify.rb
337
323
  - lib/qiita/markdown/filters/syntax_highlight.rb
338
324
  - lib/qiita/markdown/filters/toc.rb
339
325
  - lib/qiita/markdown/filters/truncate.rb
340
326
  - lib/qiita/markdown/filters/user_input_sanitizer.rb
341
- - lib/qiita/markdown/greenmat/heading_rendering.rb
342
- - lib/qiita/markdown/greenmat/html_renderer.rb
343
- - lib/qiita/markdown/greenmat/html_toc_renderer.rb
344
327
  - lib/qiita/markdown/processor.rb
345
328
  - lib/qiita/markdown/summary_processor.rb
346
329
  - lib/qiita/markdown/transformers/filter_attributes.rb
@@ -350,16 +333,18 @@ files:
350
333
  - lib/qiita/markdown/version.rb
351
334
  - qiita-markdown.gemspec
352
335
  - spec/qiita/markdown/filters/checkbox_spec.rb
353
- - spec/qiita/markdown/filters/greenmat_spec.rb
336
+ - spec/qiita/markdown/filters/heading_anchor_spec.rb
337
+ - spec/qiita/markdown/filters/html_toc_spec.rb
354
338
  - spec/qiita/markdown/filters/inline_code_color_spec.rb
355
- - spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb
339
+ - spec/qiita/markdown/filters/qiita_marker_spec.rb
356
340
  - spec/qiita/markdown/processor_spec.rb
357
341
  - spec/qiita/markdown/summary_processor_spec.rb
358
342
  - spec/spec_helper.rb
359
343
  homepage: https://github.com/increments/qiita-markdown
360
344
  licenses:
361
345
  - MIT
362
- metadata: {}
346
+ metadata:
347
+ rubygems_mfa_required: 'true'
363
348
  post_install_message:
364
349
  rdoc_options: []
365
350
  require_paths:
@@ -368,22 +353,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
368
353
  requirements:
369
354
  - - ">="
370
355
  - !ruby/object:Gem::Version
371
- version: 2.6.0
356
+ version: 2.7.0
372
357
  required_rubygems_version: !ruby/object:Gem::Requirement
373
358
  requirements:
374
359
  - - ">="
375
360
  - !ruby/object:Gem::Version
376
361
  version: '0'
377
362
  requirements: []
378
- rubygems_version: 3.1.4
363
+ rubygems_version: 3.1.6
379
364
  signing_key:
380
365
  specification_version: 4
381
366
  summary: Qiita-specified markdown processor.
382
- test_files:
383
- - spec/qiita/markdown/filters/checkbox_spec.rb
384
- - spec/qiita/markdown/filters/greenmat_spec.rb
385
- - spec/qiita/markdown/filters/inline_code_color_spec.rb
386
- - spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb
387
- - spec/qiita/markdown/processor_spec.rb
388
- - spec/qiita/markdown/summary_processor_spec.rb
389
- - spec/spec_helper.rb
367
+ test_files: []
@@ -1,248 +0,0 @@
1
- require "benchmark/ips"
2
- require "qiita/markdown"
3
-
4
- # The old implementation
5
- module PostProcess
6
- class Processor < Qiita::Markdown::Processor
7
- def filters
8
- @filters ||= [
9
- Filters::Greenmat,
10
- Filters::Toc,
11
- ]
12
- end
13
- end
14
-
15
- module Filters
16
- class Greenmat < HTML::Pipeline::TextFilter
17
- class << self
18
- # Memoize.
19
- # @return [Greenmat::Markdown]
20
- def renderer
21
- @renderer ||= ::Greenmat::Markdown.new(
22
- ::Greenmat::Render::HTML.new(
23
- hard_wrap: true,
24
- ),
25
- autolink: true,
26
- fenced_code_blocks: true,
27
- footnotes: true,
28
- no_intra_emphasis: true,
29
- no_mention_emphasis: true,
30
- strikethrough: true,
31
- tables: true,
32
- )
33
- end
34
- end
35
-
36
- # @return [Nokogiri::HTML::DocumentFragment]
37
- def call
38
- Nokogiri::HTML.fragment(self.class.renderer.render(@text))
39
- end
40
- end
41
-
42
- class Toc < HTML::Pipeline::Filter
43
- def call
44
- counter = Hash.new(0)
45
- doc.css("h1, h2, h3, h4, h5, h6").each do |node|
46
- heading = Heading.new(node, counter)
47
- heading.add_anchor_element if heading.has_first_child?
48
- heading.increment
49
- end
50
- doc
51
- end
52
-
53
- class Heading
54
- def initialize(node, counter)
55
- @node = node
56
- @counter = counter
57
- end
58
-
59
- def add_anchor_element
60
- first_child.add_previous_sibling(anchor_element)
61
- end
62
-
63
- def anchor_element
64
- %[<span id="#{suffixed_id}" class="fragment"></span><a href="##{suffixed_id}"><i class="fa fa-link"></i></a>]
65
- end
66
-
67
- def content
68
- @content ||= node.children.first
69
- end
70
-
71
- def count
72
- @counter[id]
73
- end
74
-
75
- def first_child
76
- @first_child ||= @node.children.first
77
- end
78
-
79
- def has_count?
80
- count > 0
81
- end
82
-
83
- def has_first_child?
84
- !!first_child
85
- end
86
-
87
- def id
88
- @node.text.downcase.gsub(/[^\p{Word}\- ]/u, "").tr(" ", "-")
89
- end
90
-
91
- def increment
92
- @counter[id] += 1
93
- end
94
-
95
- def suffix
96
- has_count? ? "-#{count}" : ""
97
- end
98
-
99
- def suffixed_id
100
- "#{id}#{suffix}"
101
- end
102
- end
103
- end
104
- end
105
- end
106
-
107
- # The new implementation
108
- module Rendering
109
- class Processor < Qiita::Markdown::Processor
110
- def filters
111
- @filters ||= [
112
- Filters::Greenmat,
113
- ]
114
- end
115
- end
116
-
117
- module Filters
118
- class Greenmat < HTML::Pipeline::TextFilter
119
- def call
120
- Nokogiri::HTML.fragment(greenmat.render(@text))
121
- end
122
-
123
- private
124
-
125
- # Memoize.
126
- # @return [Greenmat::Markdown]
127
- def greenmat
128
- @renderer ||= ::Greenmat::Markdown.new(
129
- HTMLRenderer.new(hard_wrap: true, with_toc_data: true),
130
- autolink: true,
131
- fenced_code_blocks: true,
132
- footnotes: true,
133
- no_intra_emphasis: true,
134
- no_mention_emphasis: true,
135
- strikethrough: true,
136
- tables: true,
137
- )
138
- end
139
-
140
- class HTMLRenderer < ::Greenmat::Render::HTML
141
- def initialize(extensions = {})
142
- super
143
- @with_toc_data = extensions[:with_toc_data]
144
- end
145
-
146
- def header(text, level)
147
- heading = heading_class.new(text, level, counter)
148
- heading.to_s.tap do
149
- heading.increment
150
- end
151
- end
152
-
153
- private
154
-
155
- def heading_class
156
- @heading_class ||= (@with_toc_data ? HeadingWithAnchor : Heading)
157
- end
158
-
159
- def counter
160
- @counter ||= Hash.new(0)
161
- end
162
-
163
- Heading = Struct.new(:body, :level, :counter) do
164
- # For reference, C implementation of Redcarpet::Render::HTML#header is the following:
165
- # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L281-L296
166
- def to_s
167
- "\n<h#{level}>#{body}</h#{level}>\n"
168
- end
169
-
170
- def increment
171
- # no-op
172
- end
173
-
174
- private
175
-
176
- def content
177
- body
178
- end
179
- end
180
-
181
- class HeadingWithAnchor < Heading
182
- def to_s
183
- "\n<h#{level}>#{anchor_element}#{body}</h#{level}>\n"
184
- end
185
-
186
- def increment
187
- counter[id] += 1
188
- end
189
-
190
- private
191
-
192
- def anchor_element
193
- %(<span id="#{suffixed_id}" class="fragment"></span><a href="##{suffixed_id}"><i class="fa fa-link"></i></a>)
194
- end
195
-
196
- def count
197
- counter[id]
198
- end
199
-
200
- def has_count?
201
- count > 0
202
- end
203
-
204
- def id
205
- @id ||= text.downcase.gsub(/[^\p{Word}\- ]/u, "").tr(" ", "-")
206
- end
207
-
208
- def text
209
- Nokogiri::HTML.fragment(body).text
210
- end
211
-
212
- def suffix
213
- has_count? ? "-#{count}" : ""
214
- end
215
-
216
- def suffixed_id
217
- @suffixed_id ||= "#{id}#{suffix}"
218
- end
219
- end
220
- end
221
- end
222
- end
223
- end
224
-
225
- markdown = File.read(File.join(File.dirname(__FILE__), "sample.md"))
226
-
227
- Benchmark.ips do |benchmark|
228
- benchmark.report("post process") do
229
- PostProcess::Processor.new.call(markdown)
230
- end
231
-
232
- benchmark.report("rendering") do
233
- Rendering::Processor.new.call(markdown)
234
- end
235
-
236
- benchmark.compare!
237
- end
238
-
239
- # Calculating -------------------------------------
240
- # post process 4 i/100ms
241
- # rendering 14 i/100ms
242
- # -------------------------------------------------
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
245
- #
246
- # Comparison:
247
- # rendering: 151.1 i/s
248
- # post process: 44.9 i/s - 3.36x slower