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
data/benchmark/sample.md DELETED
@@ -1,317 +0,0 @@
1
- Markdown記法 チートシート
2
- Markdown記法のチートシートです。
3
- 本ページではQiitaで使用可能なMarkdownのみ掲載しているため、一部原文と異なります。
4
- Markdownの原文については、[Daring Fireball: Markdown Syntax Documentation]
5
- (http://daringfireball.net/projects/markdown/syntax.php)をご覧下さい。
6
- また、コードに関する記法は[GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/)に準拠しています。
7
- Qiitaでシンタックスハイライト可能な言語一覧については、 [シンタックスハイライト可能な言語](http://qiita.com/Qiita/items/e84f5aad7757afce82ba) をご覧下さい。
8
-
9
- ## Code - コードの挿入
10
-
11
- たとえば、Rubyで記述したコードをファイル名「qiita.rb」として投稿したいときは、 **バッククオート** を使用して以下のように投稿するとシンタックスハイライトが適用されます。
12
- **コードブロック上下に空行を挿入しないと正しく表示されないことがあります。**
13
-
14
- > (空行)
15
- > \`\`\`ruby:qiita.rb
16
- > puts 'The best way to log and share programmers knowledge.'
17
- > \`\`\`
18
- > (空行)
19
-
20
- **結果**
21
-
22
- ```ruby:qiita.rb
23
- puts 'The best way to log and share programmers knowledge.'
24
- ```
25
-
26
- また、コードをインライン表示することも可能です。
27
-
28
- > \` puts 'Qiita'` はプログラマのための技術情報共有サービスです。
29
-
30
- **結果**
31
-
32
- ` puts 'Qiita'` はプログラマのための技術情報共有サービスです。
33
-
34
- インラインコードがn個連続するバッククオートを含む場合、n+1連続のバッククオートで囲みます。
35
-
36
- > \`\` \`バッククオート\` \`\` や \`\`\` \`\`2連続バッククオート\`\` \`\`\` も記述できます。
37
-
38
- **結果**
39
-
40
- `` `バッククオート` `` や ``` ``2連続バッククオート`` ``` も記述できます。
41
-
42
- ### Gist連携について
43
-
44
- ##### GitHubアカウントでQiitaにログインされている場合
45
-
46
- 投稿時、Octocatアイコンにチェックを入れていただくと連携を行います。
47
- コードを含むアイテムを投稿するとコード部分を抽出し、同じ内容がGistにも投稿される仕組みになっています。
48
-
49
- Gistとの連携は、
50
-
51
- * コードの投稿
52
- * Qiita側でのコードの編集
53
-
54
- の2点について連携しています。
55
- Gist側でコードを編集されても、 **Qiitaには反映されません** のでご注意下さい。
56
-
57
- ## Format Text - テキストの装飾
58
-
59
- ### Headers - 見出し
60
-
61
- * \# これはH1タグです
62
- * \## これはH2タグです
63
- * \###### これはH6タグです
64
-
65
- ### Emphasis - 強調
66
-
67
- ```markdown
68
- _イタリック体_を使うには _ か * で囲みます。
69
- **太字**を使うには __ か ** で囲みます。
70
- ```
71
-
72
- _イタリック体_を使うには _ か * で囲みます。
73
- **太字**を使うには __ か ** で囲みます。
74
-
75
- ### Strikethrough - 打ち消し線
76
-
77
- ```markdown
78
- 打ち消し線を使うには ~~ で囲みます。 ~~打ち消し~~
79
- ```
80
-
81
- 打ち消し線を使うには ~~ で囲みます。 ~~打ち消し~~
82
-
83
- イタリックや太文字と同様に前後に **半角スペース** か **改行文字** が必要です。
84
-
85
- ## Lists - リスト
86
-
87
- ### Disc型
88
-
89
- * 文頭に「*」「+」「-」のいずれかを入れるとDisc型リストになります
90
- * 要点をまとめる際に便利です
91
- * リストを挿入する際は、 **リストの上下に空行がないと正しく表示されません。また「*」「+」「-」の後にはスペースが必要です**
92
-
93
- ### Decimal型
94
-
95
- 1. 文頭に「数字.」を入れるとDecimal型リストになります
96
- 2. 後からの挿入/移動を考慮して、1. 2. 3. と順番にするのではなく、1. 1. 1. という風に同じ数字にしておくといい具合です。
97
- 3. リストを挿入する際は、 **リストの上下に空行がないと正しく表示されません。また「数字.」の後にはスペースが必要です**
98
-
99
- ### Definition型
100
-
101
- HTMLの`<dl>`タグをそのまま使うことで実現できます。
102
-
103
- ```html
104
- <dl>
105
- <dt>リンゴ</dt>
106
- <dd>赤いフルーツ</dd>
107
- <dt>オレンジ</dt>
108
- <dd>橙色のフルーツ</dd>
109
- </dl>
110
- ```
111
- 次のようになります。
112
-
113
- <dl>
114
- <dt>リンゴ</dt>
115
- <dd>赤いフルーツ</dd>
116
- <dt>オレンジ</dt>
117
- <dd>橙色フルーツ</dd>
118
- </dl>
119
-
120
- 注意するべきは、Definition型のリスト内ではMarkdown記法が使えないということです。例えば以下のように書いてはなりません。
121
-
122
- ```html
123
- <dl>
124
- <dt>リンゴ</dt>
125
- <dd> とても **赤い** フルーツ </dd>
126
- </dl>
127
- ```
128
-
129
- 次のようになってしまいます。
130
-
131
- <dl>
132
- <dt>リンゴ</dt>
133
- <dd> とても **赤い** フルーツ </dd>
134
- </dl>
135
-
136
- Definition型リスト内ではMarkdown記法ではなくて、HTMLタグを使って修飾しなければならないので、正しくは次のようになります。
137
-
138
- ```html
139
- <dl>
140
- <dt>リンゴ</dt>
141
- <dd> とても<strong>赤い</strong>フルーツ </dd>
142
- </dl>
143
- ```
144
-
145
- <dl>
146
- <dt>リンゴ</dt>
147
- <dd> とても<strong>赤い</strong>フルーツ</dd>
148
- </dl>
149
-
150
- Markdown記法とHTMLタグの対応は次のようになっています。
151
-
152
- | 修飾 | Markdown | HTML |
153
- |:----------:|:---------------:|:------------------------:|
154
- | ボールド | `** **` | `<strong></strong>` |
155
- | イタリック | `_ _` | `<em></em>` |
156
- | コード | <code>``</code> | `<code></code>` |
157
- | リンク | `[text](url)` | `<a href="url">text</a>` |
158
-
159
- ## Blockquotes - 引用
160
-
161
- > \> 文頭に>を置くことで引用になります。
162
- > \> 複数行にまたがる場合、改行のたびにこの記号を置く必要があります。
163
- > \> **引用の上下にはリストと同じく空行がないと正しく表示されません**
164
- > \> 引用の中に別のMarkdownを使用することも可能です。
165
-
166
- > > これはネストされた引用です。
167
-
168
- ## Horizontal rules - 水平線
169
-
170
- 下記は全て水平線として表示されます
171
-
172
- > \* * *
173
- > \***
174
- > \*****
175
- > \- - -
176
- > \---------------------------------------
177
-
178
- ## Links - リンク
179
-
180
- * \[リンクテキスト](URL "タイトル")
181
- * タイトル付きのリンクを投稿できます。
182
-
183
- **例**
184
-
185
- > *Markdown:* \[Qiita]\(http://qiita.com "Qiita")
186
- > *結果:* [Qiita](http://qiita.com "Qiita")
187
-
188
- * \[リンクテキスト](URL)
189
- * こちらはタイトル無しのリンクになります。
190
-
191
- **例**
192
-
193
- > *Markdown:* \[Qiita]\(http://qiita.com)
194
- > *結果:* [Qiita](http://qiita.com)
195
-
196
- - \[リンクテキスト]\[名前]
197
- - \[名前]:URL
198
- - 同じURLへのリンクを複数箇所に設定することができます
199
-
200
- **例**
201
-
202
- >
203
- *Markdown:*
204
- \[ここ]\[link-1] と \[この]\[link-1] リンクは同じになります。
205
- \[link-1][\] も可能です。
206
- \[link-1]:http://qiita.com/drafts/c686397e4a0f4f11683d
207
- >
208
- *結果:*
209
- [ここ][link-1] と [この][link-1] リンクは同じになります。
210
- [link-1][] も可能です。
211
- [link-1]:http://qiita.com/drafts/c686397e4a0f4f11683d
212
-
213
- ## Images - 画像埋め込み
214
-
215
- * \![代替テキスト]\(画像のURL)
216
- * タイトル無しの画像を埋め込む
217
- * \![代替テキスト]\(画像のURL "画像タイトル")
218
- * タイトル有りの画像を埋め込む
219
-
220
- **例**
221
-
222
- > *Markdown:* \![Qiita]\(http://qiita.com/icons/favicons/public/apple-touch-icon.png "Qiita")
223
- > *結果:*
224
- > ![Qiita](http://qiita.com/icons/favicons/public/apple-touch-icon.png "Qiita")
225
-
226
- ## テーブル記法
227
- ```
228
- | Left align | Right align | Center align |
229
- |:-----------|------------:|:------------:|
230
- | This | This | This |
231
- | column | column | column |
232
- | will | will | will |
233
- | be | be | be |
234
- | left | right | center |
235
- | aligned | aligned | aligned |
236
- ```
237
-
238
- 上記のように書くと,以下のように表示されます.
239
-
240
- | Left align | Right align | Center align |
241
- |:-----------|------------:|:------------:|
242
- | This | This | This |
243
- | column | column | column |
244
- | will | will | will |
245
- | be | be | be |
246
- | left | right | center |
247
- | aligned | aligned | aligned |
248
-
249
- ## 数式の挿入
250
-
251
- コードブロックの言語指定に "math" を指定することでTeX記法を用いて数式を記述することができます。
252
-
253
- > \`\`\`math
254
- > \left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq
255
- > \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
256
- > \`\`\`
257
-
258
- ```math
259
- \left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq
260
- \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
261
- ```
262
-
263
- `$2^3$` のように数式を "$" で挟むと行中に数式を埋め込むこともできます。
264
-
265
- > x^2 + y^2 = 1 をインライン表示すると $x^2 + y^2 = 1$ になります。
266
-
267
- ただしインライン数式の中でコントロールシンボル(`\{`のような、バックスラッシュの後に記号が続くもの)を使うと、後述のバックスラッシュによるMarkdownのエスケープと衝突してしまいます。
268
-
269
- ```
270
- $a = \{1, 2, 3\}$
271
- ```
272
-
273
- > $a = \{1, 2, 3\}$
274
-
275
- なので次のように二つのバックスラッシュを使います。
276
-
277
- ```
278
- $a = \\{1, 2, 3\\}$
279
- ```
280
-
281
- > $a = \\{1, 2, 3\\}$
282
-
283
- ## 目次(TOC)の自動挿入
284
-
285
- 目次は記事内の見出しを元に自動生成し、右上に自動挿入されます。詳細は[目次機能の紹介記事](http://blog.qiita.com/post/77055935852/qiita-toc)をご覧ください。
286
-
287
- ## 注釈
288
- 本文中に `[^1]` のように文字列を記述することで、脚注へのリンクを表現できます。注釈内容は、同じく本文中に `[^1]: ...` というように記述します[^1]。
289
-
290
- [^1]: 注釈内容を記述する位置は、本文の途中でも末尾でも構いません。
291
-
292
- ## 絵文字
293
- 厳密には Markdown 記法の外ですが、`:` で囲って、絵文字を埋め込めます。
294
-
295
- **例**
296
-
297
- ```
298
- \:kissing_closed_eyes: chu☆
299
- ```
300
-
301
- > \:kissing_closed_eyes: chu☆
302
-
303
-
304
- 絵文字チートシート
305
- http://www.emoji-cheat-sheet.com/
306
-
307
-
308
- ## その他
309
-
310
- バックスラッシュ[\\]をMarkdownの前に挿入することで、Markdownをエスケープ(無効化)することができます。
311
-
312
- **例**
313
-
314
- > \# H1
315
- > エスケープされています
316
-
317
- また本文では一部のHTMLタグも利用可能です。
@@ -1,38 +0,0 @@
1
- module Qiita
2
- module Markdown
3
- module Filters
4
- class Greenmat < HTML::Pipeline::TextFilter
5
- DEFAULT_OPTIONS = {
6
- footnotes: true,
7
- }.freeze
8
-
9
- # @return [Nokogiri::HTML::DocumentFragment]
10
- def call
11
- Nokogiri::HTML.fragment(greenmat.render(@text))
12
- end
13
-
14
- private
15
-
16
- # Memoize.
17
- # @return [Greenmat::Markdown]
18
- def greenmat
19
- @renderer ||= ::Greenmat::Markdown.new(
20
- Qiita::Markdown::Greenmat::HTMLRenderer.new(hard_wrap: true, with_toc_data: true),
21
- autolink: true,
22
- fenced_code_blocks: true,
23
- fenced_custom_blocks: true,
24
- footnotes: options[:footnotes],
25
- no_intra_emphasis: true,
26
- no_mention_emphasis: true,
27
- strikethrough: true,
28
- tables: true,
29
- )
30
- end
31
-
32
- def options
33
- @options ||= DEFAULT_OPTIONS.merge(context[:markdown] || {})
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,61 +0,0 @@
1
- module Qiita
2
- module Markdown
3
- module Greenmat
4
- module HeadingRendering
5
- def heading_counter
6
- @counter ||= Hash.new(0)
7
- end
8
-
9
- class AbstractHeading
10
- attr_reader :raw_body, :level, :counter, :escape_html
11
- alias 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
-
20
- def to_s
21
- fail NotImplementedError
22
- end
23
-
24
- def increment
25
- fail NotImplementedError
26
- end
27
-
28
- private
29
-
30
- def count
31
- counter[id]
32
- end
33
-
34
- def has_count?
35
- count > 0
36
- end
37
-
38
- def body
39
- escape_html? ? CGI.escape_html(raw_body) : raw_body
40
- end
41
-
42
- def id
43
- @id ||= text.downcase.gsub(/[^\p{Word}\- ]/u, "").tr(" ", "-")
44
- end
45
-
46
- def text
47
- Nokogiri::HTML.fragment(raw_body).text
48
- end
49
-
50
- def suffix
51
- has_count? ? "-#{count}" : ""
52
- end
53
-
54
- def suffixed_id
55
- @suffixed_id ||= "#{id}#{suffix}"
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,60 +0,0 @@
1
- require "uri"
2
-
3
- module Qiita
4
- module Markdown
5
- module Greenmat
6
- class HTMLRenderer < ::Greenmat::Render::HTML
7
- include HeadingRendering
8
-
9
- def initialize(extensions = {})
10
- super
11
- @with_toc_data = extensions[:with_toc_data]
12
- end
13
-
14
- # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L76-L116
15
- def autolink(link, link_type)
16
- if link_type == :email
17
- %(<a href="mailto:#{link}" class="autolink">#{link}</a>)
18
- else
19
- %(<a href="#{link}" class="autolink">#{link}</a>)
20
- end
21
- end
22
-
23
- def header(text, level)
24
- heading = heading_class.new(text, level, heading_counter)
25
- heading.to_s.tap do
26
- heading.increment
27
- end
28
- end
29
-
30
- private
31
-
32
- def heading_class
33
- @heading_class ||= (@with_toc_data ? HeadingWithAnchor : Heading)
34
- end
35
-
36
- class Heading < AbstractHeading
37
- # For reference, C implementation of Redcarpet::Render::HTML#header is the following:
38
- # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L281-L296
39
- def to_s
40
- "\n<h#{level}>#{body}</h#{level}>\n"
41
- end
42
-
43
- def increment
44
- # No-op
45
- end
46
- end
47
-
48
- class HeadingWithAnchor < AbstractHeading
49
- def to_s
50
- %(\n<h#{level} id="#{suffixed_id}">#{body}</h#{level}>\n)
51
- end
52
-
53
- def increment
54
- counter[id] += 1
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,78 +0,0 @@
1
- module Qiita
2
- module Markdown
3
- module Greenmat
4
- class HTMLToCRenderer < ::Greenmat::Render::HTML_TOC
5
- include HeadingRendering
6
-
7
- def initialize(extensions = {})
8
- super
9
- @extensions = extensions
10
- @last_level = 0
11
- end
12
-
13
- # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L609-L642
14
- def header(text, level)
15
- @level_offset = level - 1 unless @level_offset
16
-
17
- level -= @level_offset
18
- level = 1 if level < 1
19
-
20
- difference = level - @last_level
21
- @last_level = level
22
-
23
- generate_heading_html(text, level, difference)
24
- end
25
-
26
- # https://github.com/vmg/redcarpet/blob/v3.2.3/ext/redcarpet/html.c#L652-L661
27
- def doc_footer
28
- "</li>\n</ul>\n" * @last_level
29
- end
30
-
31
- private
32
-
33
- def generate_heading_html(text, level, level_difference)
34
- html = list_item_preceding_html(level_difference)
35
-
36
- anchor = HeadingAnchor.new(text, level, heading_counter, escape_html?)
37
- html << anchor.to_s
38
- anchor.increment
39
-
40
- html
41
- end
42
-
43
- def list_item_preceding_html(level_difference)
44
- html = case
45
- when level_difference > 0
46
- "<ul>\n" * level_difference
47
- when level_difference < 0
48
- "</li>\n" << ("</ul>\n</li>\n" * level_difference.abs)
49
- else
50
- "</li>\n"
51
- end
52
-
53
- html << "<li>\n"
54
- end
55
-
56
- def escape_html?
57
- @extensions[:escape_html]
58
- end
59
-
60
- class HeadingAnchor < AbstractHeading
61
- def to_s
62
- "<a href=\"##{suffixed_id}\">#{body}</a>\n"
63
- end
64
-
65
- def increment
66
- counter[id] += 1
67
- end
68
-
69
- private
70
-
71
- def body
72
- escape_html? ? CGI.escape_html(text) : raw_body
73
- end
74
- end
75
- end
76
- end
77
- end
78
- end
@@ -1,15 +0,0 @@
1
- describe Qiita::Markdown::Filters::Greenmat do
2
- subject(:filter) do
3
- described_class.new(markdown)
4
- end
5
-
6
- context "with headings" do
7
- let(:markdown) do
8
- "# foo"
9
- end
10
-
11
- it "does not generate FontAwesome classes so that we can say that they're inputted by user" do
12
- expect(filter.call.to_s).to eq(%(\n<h1 id="foo">foo</h1>\n))
13
- end
14
- end
15
- end