qiita-markdown 0.44.1 → 1.0.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 +4 -4
- data/.github/workflows/test.yml +2 -2
- data/.rubocop.yml +0 -4
- data/.rubocop_todo.yml +6 -44
- data/CHANGELOG.md +10 -0
- data/README.md +3 -1
- data/lib/qiita/markdown/filters/checkbox.rb +5 -1
- data/lib/qiita/markdown/filters/custom_block.rb +7 -6
- data/lib/qiita/markdown/filters/final_sanitizer.rb +8 -2
- data/lib/qiita/markdown/filters/heading_anchor.rb +44 -0
- data/lib/qiita/markdown/filters/html_toc.rb +67 -0
- data/lib/qiita/markdown/filters/qiita_marker.rb +55 -0
- data/lib/qiita/markdown/filters/user_input_sanitizer.rb +14 -9
- data/lib/qiita/markdown/processor.rb +2 -1
- data/lib/qiita/markdown/summary_processor.rb +1 -1
- data/lib/qiita/markdown/version.rb +1 -1
- data/lib/qiita/markdown.rb +4 -5
- data/qiita-markdown.gemspec +2 -3
- data/spec/qiita/markdown/filters/checkbox_spec.rb +28 -0
- data/spec/qiita/markdown/filters/heading_anchor_spec.rb +73 -0
- data/spec/qiita/markdown/filters/html_toc_spec.rb +223 -0
- data/spec/qiita/markdown/filters/qiita_marker_spec.rb +60 -0
- data/spec/qiita/markdown/processor_spec.rb +48 -54
- data/spec/qiita/markdown/summary_processor_spec.rb +2 -2
- metadata +23 -39
- data/benchmark/heading_anchor_rendering.rb +0 -248
- data/benchmark/sample.md +0 -317
- data/lib/qiita/markdown/filters/greenmat.rb +0 -38
- data/lib/qiita/markdown/greenmat/heading_rendering.rb +0 -61
- data/lib/qiita/markdown/greenmat/html_renderer.rb +0 -60
- data/lib/qiita/markdown/greenmat/html_toc_renderer.rb +0 -78
- data/spec/qiita/markdown/filters/greenmat_spec.rb +0 -15
- data/spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb +0 -156
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 196cc261921bae3253f06a912b56e96a5912ed4552ec6352415756bcca1d98ed
|
4
|
+
data.tar.gz: '018a907a21f827e68a814ce0d15ff96f3cdccb4e6e52411b7ff63399c5c55f4b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 267fcb94bfc63e83b1f42bb42d01f61744d3979be9a92b1df767fc3c7ff3beed8b6299958677835f113abed3c6990bced41618c916650f34c31d5d125e16750d
|
7
|
+
data.tar.gz: 4a072057a0d55751e5b9e52357641930b1fd0301fe779720820705d453aaaae4fe5cd20bfec3354bb47eb8981ff3742b8a200b8bc647c3b42c5b99e27930458c
|
data/.github/workflows/test.yml
CHANGED
@@ -20,7 +20,7 @@ jobs:
|
|
20
20
|
- uses: actions/checkout@v3
|
21
21
|
- uses: ruby/setup-ruby@v1
|
22
22
|
with:
|
23
|
-
ruby-version: '2.
|
23
|
+
ruby-version: '2.7'
|
24
24
|
bundler-cache: true
|
25
25
|
- name: Test & publish code coverage
|
26
26
|
if: "${{ env.CC_TEST_REPORTER_ID != '' }}"
|
@@ -37,7 +37,7 @@ jobs:
|
|
37
37
|
fail-fast: false
|
38
38
|
matrix:
|
39
39
|
os: ['ubuntu-18.04', 'ubuntu-latest', 'macos-latest']
|
40
|
-
ruby: ['2.
|
40
|
+
ruby: ['2.7', '3.0', '3.1']
|
41
41
|
experimental: [false]
|
42
42
|
include:
|
43
43
|
- os: 'ubuntu-latest'
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config --exclude-limit 99999`
|
3
|
-
# on 2022-11-
|
3
|
+
# on 2022-11-15 12:42:36 UTC using RuboCop version 1.39.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -13,12 +13,12 @@ Gemspec/RequiredRubyVersion:
|
|
13
13
|
Exclude:
|
14
14
|
- 'qiita-markdown.gemspec'
|
15
15
|
|
16
|
-
# Offense count:
|
16
|
+
# Offense count: 8
|
17
17
|
# Configuration parameters: AllowedMethods, AllowedPatterns, IgnoredMethods, CountRepeatedAttributes.
|
18
18
|
Metrics/AbcSize:
|
19
|
-
Max:
|
19
|
+
Max: 26
|
20
20
|
|
21
|
-
# Offense count:
|
21
|
+
# Offense count: 10
|
22
22
|
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, AllowedMethods, AllowedPatterns, IgnoredMethods.
|
23
23
|
Metrics/MethodLength:
|
24
24
|
Max: 20
|
@@ -36,23 +36,13 @@ Naming/FileName:
|
|
36
36
|
Exclude:
|
37
37
|
- 'lib/qiita-markdown.rb'
|
38
38
|
|
39
|
-
# Offense count:
|
39
|
+
# Offense count: 21
|
40
40
|
# Configuration parameters: ForbiddenDelimiters.
|
41
41
|
# ForbiddenDelimiters: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
|
42
42
|
Naming/HeredocDelimiterNaming:
|
43
43
|
Exclude:
|
44
|
-
- 'spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb'
|
45
44
|
- 'spec/qiita/markdown/summary_processor_spec.rb'
|
46
45
|
|
47
|
-
# Offense count: 3
|
48
|
-
# Configuration parameters: EnforcedStyleForLeadingUnderscores.
|
49
|
-
# SupportedStylesForLeadingUnderscores: disallowed, required, optional
|
50
|
-
Naming/MemoizedInstanceVariableName:
|
51
|
-
Exclude:
|
52
|
-
- 'benchmark/heading_anchor_rendering.rb'
|
53
|
-
- 'lib/qiita/markdown/filters/greenmat.rb'
|
54
|
-
- 'lib/qiita/markdown/greenmat/heading_rendering.rb'
|
55
|
-
|
56
46
|
# Offense count: 1
|
57
47
|
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
|
58
48
|
# AllowedNames: as, at, by, db, id, if, in, io, ip, of, on, os, pp, to
|
@@ -60,7 +50,7 @@ Naming/MethodParameterName:
|
|
60
50
|
Exclude:
|
61
51
|
- 'lib/qiita/markdown/filters/footnote.rb'
|
62
52
|
|
63
|
-
# Offense count:
|
53
|
+
# Offense count: 37
|
64
54
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
65
55
|
# Configuration parameters: EnforcedStyle.
|
66
56
|
# SupportedStyles: always, always_true, never
|
@@ -68,7 +58,6 @@ Style/FrozenStringLiteralComment:
|
|
68
58
|
Exclude:
|
69
59
|
- 'Gemfile'
|
70
60
|
- 'Rakefile'
|
71
|
-
- 'benchmark/heading_anchor_rendering.rb'
|
72
61
|
- 'lib/qiita-markdown.rb'
|
73
62
|
- 'lib/qiita/markdown.rb'
|
74
63
|
- 'lib/qiita/markdown/base_processor.rb'
|
@@ -81,12 +70,9 @@ Style/FrozenStringLiteralComment:
|
|
81
70
|
- 'lib/qiita/markdown/embed/youtube.rb'
|
82
71
|
- 'lib/qiita/markdown/filters/checkbox.rb'
|
83
72
|
- 'lib/qiita/markdown/filters/code_block.rb'
|
84
|
-
- 'lib/qiita/markdown/filters/custom_block.rb'
|
85
73
|
- 'lib/qiita/markdown/filters/emoji.rb'
|
86
74
|
- 'lib/qiita/markdown/filters/external_link.rb'
|
87
|
-
- 'lib/qiita/markdown/filters/final_sanitizer.rb'
|
88
75
|
- 'lib/qiita/markdown/filters/footnote.rb'
|
89
|
-
- 'lib/qiita/markdown/filters/greenmat.rb'
|
90
76
|
- 'lib/qiita/markdown/filters/group_mention.rb'
|
91
77
|
- 'lib/qiita/markdown/filters/image_link.rb'
|
92
78
|
- 'lib/qiita/markdown/filters/inline_code_color.rb'
|
@@ -95,10 +81,6 @@ Style/FrozenStringLiteralComment:
|
|
95
81
|
- 'lib/qiita/markdown/filters/syntax_highlight.rb'
|
96
82
|
- 'lib/qiita/markdown/filters/toc.rb'
|
97
83
|
- 'lib/qiita/markdown/filters/truncate.rb'
|
98
|
-
- 'lib/qiita/markdown/filters/user_input_sanitizer.rb'
|
99
|
-
- 'lib/qiita/markdown/greenmat/heading_rendering.rb'
|
100
|
-
- 'lib/qiita/markdown/greenmat/html_renderer.rb'
|
101
|
-
- 'lib/qiita/markdown/greenmat/html_toc_renderer.rb'
|
102
84
|
- 'lib/qiita/markdown/processor.rb'
|
103
85
|
- 'lib/qiita/markdown/summary_processor.rb'
|
104
86
|
- 'lib/qiita/markdown/transformers/filter_attributes.rb'
|
@@ -107,9 +89,7 @@ Style/FrozenStringLiteralComment:
|
|
107
89
|
- 'lib/qiita/markdown/transformers/strip_invalid_node.rb'
|
108
90
|
- 'lib/qiita/markdown/version.rb'
|
109
91
|
- 'qiita-markdown.gemspec'
|
110
|
-
- 'spec/qiita/markdown/filters/greenmat_spec.rb'
|
111
92
|
- 'spec/qiita/markdown/filters/inline_code_color_spec.rb'
|
112
|
-
- 'spec/qiita/markdown/greenmat/html_toc_renderer_spec.rb'
|
113
93
|
- 'spec/qiita/markdown/processor_spec.rb'
|
114
94
|
- 'spec/qiita/markdown/summary_processor_spec.rb'
|
115
95
|
- 'spec/spec_helper.rb'
|
@@ -131,24 +111,6 @@ Style/MutableConstant:
|
|
131
111
|
- 'lib/qiita/markdown/filters/syntax_highlight.rb'
|
132
112
|
- 'lib/qiita/markdown/version.rb'
|
133
113
|
|
134
|
-
# Offense count: 5
|
135
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
136
|
-
# Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns, IgnoredMethods.
|
137
|
-
# SupportedStyles: predicate, comparison
|
138
|
-
Style/NumericPredicate:
|
139
|
-
Exclude:
|
140
|
-
- 'spec/**/*'
|
141
|
-
- 'benchmark/heading_anchor_rendering.rb'
|
142
|
-
- 'lib/qiita/markdown/greenmat/heading_rendering.rb'
|
143
|
-
- 'lib/qiita/markdown/greenmat/html_toc_renderer.rb'
|
144
|
-
|
145
|
-
# Offense count: 1
|
146
|
-
# Configuration parameters: AllowedMethods.
|
147
|
-
# AllowedMethods: respond_to_missing?
|
148
|
-
Style/OptionalBooleanParameter:
|
149
|
-
Exclude:
|
150
|
-
- 'lib/qiita/markdown/greenmat/heading_rendering.rb'
|
151
|
-
|
152
114
|
# Offense count: 1
|
153
115
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
154
116
|
# Configuration parameters: Methods.
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
- Drop Ruby 2.6 support
|
6
|
+
- Change markdown parser from Greenmat to Qiita Marker
|
7
|
+
- Fix bug on rendering loose tasklist
|
8
|
+
|
9
|
+
### Braking change on HTML output
|
10
|
+
|
11
|
+
Some notations will be changed between Greenmat and Qiita Marker and rendering results may change. More details, see [#130](https://github.com/increments/qiita-markdown/issues/130).
|
12
|
+
|
3
13
|
## 0.44.1
|
4
14
|
|
5
15
|
- Rename package name from `Qiita::Markdown` to `Qiita Markdown` in README
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Qiita-specified markdown processor.
|
|
16
16
|
- Syntax highlighting
|
17
17
|
- Mention
|
18
18
|
- Footnotes
|
19
|
+
- Note notation's custom block
|
19
20
|
|
20
21
|
## Basic Usage
|
21
22
|
|
@@ -68,7 +69,8 @@ processor.call(text)
|
|
68
69
|
:inline_code_color_class_name - Class name for inline code color. (String)
|
69
70
|
:language_aliases - Alias table for some language names. (Hash)
|
70
71
|
:markdown - A hash for enabling / disabling optional Markdown syntax. (Hash)
|
71
|
-
Currently
|
72
|
+
Currently :footnotes (default: true) and :sourcepos (defalut: false) are supported.
|
73
|
+
For more information on these options, please see [increments/qiita_marker](https://github.com/increments/qiita_marker).
|
72
74
|
:rule - Sanitization rule table. (Hash)
|
73
75
|
:script - A flag to allow to embed script element. (Boolean)
|
74
76
|
```
|
@@ -55,7 +55,11 @@ module Qiita
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def first_text_node
|
58
|
-
|
58
|
+
is_loose_list_node = @node.children.first&.text == "\n" && @node.children[1]&.name == "p"
|
59
|
+
|
60
|
+
if is_loose_list_node
|
61
|
+
@node.children[1].children.first
|
62
|
+
elsif @node.children.first && @node.children.first.name == "p"
|
59
63
|
@node.children.first.children.first
|
60
64
|
else
|
61
65
|
@node.children.first
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Qiita
|
2
4
|
module Markdown
|
3
5
|
module Filters
|
@@ -31,7 +33,7 @@ module Qiita
|
|
31
33
|
attr_reader :node, :type
|
32
34
|
|
33
35
|
ALLOWED_TYPES = %w[info warn alert].freeze
|
34
|
-
DEFAULT_TYPE = "info"
|
36
|
+
DEFAULT_TYPE = "info"
|
35
37
|
|
36
38
|
# @param node [Nokogiri::XML::Node]
|
37
39
|
# @param type [String, nil]
|
@@ -41,17 +43,16 @@ module Qiita
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def convert
|
44
|
-
|
46
|
+
children = node.children
|
47
|
+
children.each(&:unlink)
|
48
|
+
node.add_child("<div></div>")
|
49
|
+
node.children.first.children = children
|
45
50
|
node["class"] = "note #{type}"
|
46
51
|
node.children.first.add_previous_sibling(icon) if icon
|
47
52
|
end
|
48
53
|
|
49
54
|
private
|
50
55
|
|
51
|
-
def message
|
52
|
-
"<p>#{node.text}</p>"
|
53
|
-
end
|
54
|
-
|
55
56
|
def icon
|
56
57
|
{
|
57
58
|
info: %(<span class="fa fa-fw fa-check-circle"></span>),
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Qiita
|
2
4
|
module Markdown
|
3
5
|
module Filters
|
@@ -9,7 +11,7 @@ module Qiita
|
|
9
11
|
# generated by other filters.
|
10
12
|
#
|
11
13
|
# @see Qiita::Markdown::Filters::UserInputSanitizerr
|
12
|
-
class FinalSanitizer < HTML::Pipeline::Filter
|
14
|
+
class FinalSanitizer < ::HTML::Pipeline::Filter
|
13
15
|
RULE = {
|
14
16
|
attributes: {
|
15
17
|
"a" => %w[
|
@@ -23,6 +25,7 @@ module Qiita
|
|
23
25
|
allowfullscreen
|
24
26
|
frameborder
|
25
27
|
height
|
28
|
+
loading
|
26
29
|
marginheight
|
27
30
|
marginwidth
|
28
31
|
scrolling
|
@@ -81,6 +84,7 @@ module Qiita
|
|
81
84
|
cols
|
82
85
|
colspan
|
83
86
|
data-lang
|
87
|
+
data-sourcepos
|
84
88
|
datetime
|
85
89
|
height
|
86
90
|
hreflang
|
@@ -107,6 +111,7 @@ module Qiita
|
|
107
111
|
b
|
108
112
|
blockquote
|
109
113
|
br
|
114
|
+
caption
|
110
115
|
code
|
111
116
|
dd
|
112
117
|
del
|
@@ -142,6 +147,7 @@ module Qiita
|
|
142
147
|
samp
|
143
148
|
script
|
144
149
|
iframe
|
150
|
+
section
|
145
151
|
span
|
146
152
|
strike
|
147
153
|
strong
|
@@ -200,7 +206,7 @@ module Qiita
|
|
200
206
|
rule[:attributes][:all] = rule[:attributes][:all] + [:data]
|
201
207
|
rule[:elements] = RULE[:elements] + ["video"]
|
202
208
|
rule[:transformers] = rule[:transformers] - [Transformers::FilterScript, Transformers::FilterIframe]
|
203
|
-
end
|
209
|
+
end.freeze
|
204
210
|
|
205
211
|
def call
|
206
212
|
::Sanitize.clean_node!(doc, rule)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qiita
|
4
|
+
module Markdown
|
5
|
+
module Filters
|
6
|
+
class HeadingAnchor < ::HTML::Pipeline::Filter
|
7
|
+
def call
|
8
|
+
doc.search("h1, h2, h3, h4, h5, h6").each do |heading|
|
9
|
+
heading["id"] = suffixed_id(heading)
|
10
|
+
end
|
11
|
+
|
12
|
+
doc
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def counter
|
18
|
+
@counter ||= ::Hash.new(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_count(id)
|
22
|
+
counter[id]
|
23
|
+
end
|
24
|
+
|
25
|
+
def increment_count(id)
|
26
|
+
counter[id] += 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def heading_id(node)
|
30
|
+
node.text.downcase.gsub(/[^\p{Word}\- ]/u, "").tr(" ", "-")
|
31
|
+
end
|
32
|
+
|
33
|
+
def suffixed_id(node)
|
34
|
+
id = heading_id(node)
|
35
|
+
count = get_count(id)
|
36
|
+
suffix = count.positive? ? "-#{count}" : ""
|
37
|
+
increment_count(id)
|
38
|
+
|
39
|
+
"#{id}#{suffix}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qiita
|
4
|
+
module Markdown
|
5
|
+
module Filters
|
6
|
+
class HtmlToc < ::HTML::Pipeline::Filter
|
7
|
+
# @return [Nokogiri::HTML::DocumentFragment]
|
8
|
+
def call
|
9
|
+
headings = doc.search("h1, h2, h3, h4, h5, h6")
|
10
|
+
return "" if headings.empty?
|
11
|
+
|
12
|
+
toc = %W[<ul>\n]
|
13
|
+
top_level = nil
|
14
|
+
last_level = nil
|
15
|
+
depth = 1
|
16
|
+
|
17
|
+
headings.each do |node|
|
18
|
+
heading_rank = node.name.match(/h(\d)/)[1].to_i
|
19
|
+
|
20
|
+
# The first heading is displayed as the top level.
|
21
|
+
# The following headings, of higher rank than the first, are placed as top level.
|
22
|
+
top_level ||= heading_rank
|
23
|
+
current_level = [heading_rank, top_level].max
|
24
|
+
|
25
|
+
link = toc_with_link(node.text, node.attributes["id"]&.value)
|
26
|
+
toc << (nest_string(last_level, current_level) + link)
|
27
|
+
|
28
|
+
depth += current_level - last_level if last_level
|
29
|
+
|
30
|
+
last_level = current_level
|
31
|
+
end
|
32
|
+
|
33
|
+
toc << ("</li>\n</ul>\n" * depth)
|
34
|
+
toc.join
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# @param text [String]
|
40
|
+
# @param id [String]
|
41
|
+
# @return [String]
|
42
|
+
def toc_with_link(text, id)
|
43
|
+
%(<a href="##{id}">#{CGI.escapeHTML(text)}</a>\n)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param last_level [Integer, nil]
|
47
|
+
# @param current_level [Integer]
|
48
|
+
# @return [String]
|
49
|
+
def nest_string(last_level, current_level)
|
50
|
+
if last_level.nil?
|
51
|
+
return "<li>\n"
|
52
|
+
elsif current_level == last_level
|
53
|
+
return "</li>\n<li>\n"
|
54
|
+
elsif current_level > last_level
|
55
|
+
level_difference = current_level - last_level
|
56
|
+
return "<ul>\n<li>\n" * level_difference
|
57
|
+
elsif current_level < last_level
|
58
|
+
level_difference = last_level - current_level
|
59
|
+
return %(#{"</li>\n</ul>\n" * level_difference}</li>\n<li>\n)
|
60
|
+
end
|
61
|
+
|
62
|
+
""
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qiita
|
4
|
+
module Markdown
|
5
|
+
module Filters
|
6
|
+
class QiitaMarker < ::HTML::Pipeline::TextFilter
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
footnotes: true,
|
9
|
+
sourcepos: false,
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
# @return [Nokogiri::HTML::DocumentFragment]
|
13
|
+
def call
|
14
|
+
::Nokogiri::HTML.fragment(render(@text))
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# @param text [String]
|
20
|
+
# @return [String]
|
21
|
+
def render(text)
|
22
|
+
::QiitaMarker.render_html(text, qiita_marker_options, qiita_marker_extensions)
|
23
|
+
end
|
24
|
+
|
25
|
+
def qiita_marker_options
|
26
|
+
options_to_append = (options[:footnotes] ? [:FOOTNOTES] : [])
|
27
|
+
.concat(options[:sourcepos] ? [:SOURCEPOS] : [])
|
28
|
+
@qiita_marker_options ||= %i[
|
29
|
+
HARDBREAKS
|
30
|
+
UNSAFE
|
31
|
+
LIBERAL_HTML_TAG
|
32
|
+
STRIKETHROUGH_DOUBLE_TILDE
|
33
|
+
TABLE_PREFER_STYLE_ATTRIBUTES
|
34
|
+
CODE_DATA_METADATA
|
35
|
+
MENTION_NO_EMPHASIS
|
36
|
+
AUTOLINK_CLASS_NAME
|
37
|
+
].concat(options_to_append)
|
38
|
+
end
|
39
|
+
|
40
|
+
def qiita_marker_extensions
|
41
|
+
@qiita_marker_extensions ||= %i[
|
42
|
+
table
|
43
|
+
strikethrough
|
44
|
+
autolink
|
45
|
+
custom_block
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
def options
|
50
|
+
@options ||= DEFAULT_OPTIONS.merge(context[:markdown] || {})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Qiita
|
2
4
|
module Markdown
|
3
5
|
module Filters
|
4
6
|
# Sanitizes user input if :strict context is given.
|
5
|
-
class UserInputSanitizer < HTML::Pipeline::Filter
|
7
|
+
class UserInputSanitizer < ::HTML::Pipeline::Filter
|
6
8
|
RULE = {
|
7
9
|
elements: %w[
|
8
|
-
a b blockquote br code dd del details div dl dt em font h1 h2 h3 h4 h5 h6
|
9
|
-
hr i img ins kbd li ol p pre q rp rt ruby s samp script iframe strike strong sub
|
10
|
+
a b blockquote br caption code dd del details div dl dt em font h1 h2 h3 h4 h5 h6
|
11
|
+
hr i img ins kbd li ol p pre q rp rt ruby s samp script iframe section strike strong sub
|
10
12
|
summary sup table tbody td tfoot th thead tr ul var
|
11
13
|
],
|
12
14
|
attributes: {
|
13
|
-
"a" => %w[class href rel title],
|
15
|
+
"a" => %w[class href rel title id],
|
14
16
|
"blockquote" => %w[cite] + Embed::Tweet::ATTRIBUTES,
|
15
17
|
"code" => %w[data-metadata],
|
16
18
|
"div" => %w[class data-type data-metadata],
|
@@ -26,11 +28,16 @@ module Qiita
|
|
26
28
|
"li" => %w[id],
|
27
29
|
"p" => Embed::CodePen::ATTRIBUTES,
|
28
30
|
"q" => %w[cite],
|
29
|
-
"
|
31
|
+
"section" => %w[class],
|
32
|
+
"script" => %w[async src id].concat(
|
33
|
+
Embed::SpeekerDeck::ATTRIBUTES,
|
34
|
+
Embed::Docswell::ATTRIBUTES,
|
35
|
+
),
|
30
36
|
"iframe" => %w[
|
31
37
|
allowfullscreen
|
32
38
|
frameborder
|
33
39
|
height
|
40
|
+
loading
|
34
41
|
marginheight
|
35
42
|
marginwidth
|
36
43
|
scrolling
|
@@ -41,6 +48,7 @@ module Qiita
|
|
41
48
|
"sup" => %w[id],
|
42
49
|
"td" => %w[colspan rowspan style],
|
43
50
|
"th" => %w[colspan rowspan style],
|
51
|
+
all: %w[data-sourcepos],
|
44
52
|
},
|
45
53
|
protocols: {
|
46
54
|
"a" => { "href" => ["http", "https", "mailto", :relative] },
|
@@ -48,10 +56,7 @@ module Qiita
|
|
48
56
|
"q" => { "cite" => ["http", "https", :relative] },
|
49
57
|
},
|
50
58
|
css: {
|
51
|
-
properties: %w[
|
52
|
-
text-align
|
53
|
-
border
|
54
|
-
],
|
59
|
+
properties: %w[text-align border],
|
55
60
|
},
|
56
61
|
transformers: [
|
57
62
|
Transformers::FilterAttributes,
|
data/lib/qiita/markdown.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "cgi"
|
2
|
-
require "greenmat"
|
3
2
|
require "html/pipeline"
|
4
3
|
require "linguist"
|
5
4
|
require "mem"
|
6
5
|
require "nokogiri"
|
6
|
+
require "qiita_marker"
|
7
7
|
require "rouge"
|
8
8
|
require "sanitize"
|
9
9
|
|
@@ -27,19 +27,18 @@ require "qiita/markdown/filters/emoji"
|
|
27
27
|
require "qiita/markdown/filters/external_link"
|
28
28
|
require "qiita/markdown/filters/final_sanitizer"
|
29
29
|
require "qiita/markdown/filters/footnote"
|
30
|
-
require "qiita/markdown/filters/greenmat"
|
31
30
|
require "qiita/markdown/filters/group_mention"
|
31
|
+
require "qiita/markdown/filters/heading_anchor"
|
32
|
+
require "qiita/markdown/filters/html_toc"
|
32
33
|
require "qiita/markdown/filters/image_link"
|
33
34
|
require "qiita/markdown/filters/inline_code_color"
|
34
35
|
require "qiita/markdown/filters/mention"
|
36
|
+
require "qiita/markdown/filters/qiita_marker"
|
35
37
|
require "qiita/markdown/filters/simplify"
|
36
38
|
require "qiita/markdown/filters/syntax_highlight"
|
37
39
|
require "qiita/markdown/filters/toc"
|
38
40
|
require "qiita/markdown/filters/truncate"
|
39
41
|
require "qiita/markdown/filters/user_input_sanitizer"
|
40
|
-
require "qiita/markdown/greenmat/heading_rendering"
|
41
|
-
require "qiita/markdown/greenmat/html_renderer"
|
42
|
-
require "qiita/markdown/greenmat/html_toc_renderer"
|
43
42
|
require "qiita/markdown/base_processor"
|
44
43
|
require "qiita/markdown/processor"
|
45
44
|
require "qiita/markdown/summary_processor"
|
data/qiita-markdown.gemspec
CHANGED
@@ -15,21 +15,20 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
-
spec.required_ruby_version = ">= 2.
|
18
|
+
spec.required_ruby_version = ">= 2.7.0"
|
19
19
|
|
20
20
|
spec.add_dependency "addressable"
|
21
21
|
spec.add_dependency "gemoji"
|
22
22
|
spec.add_dependency "github-linguist", "~> 4.0"
|
23
|
-
spec.add_dependency "greenmat", "3.5.1.4"
|
24
23
|
spec.add_dependency "html-pipeline", "~> 2.0"
|
25
24
|
spec.add_dependency "mem"
|
26
25
|
spec.add_dependency "rouge", "3.26.0"
|
27
26
|
spec.add_dependency "sanitize"
|
28
27
|
spec.add_development_dependency "activesupport", "~> 5.2.7"
|
29
|
-
spec.add_development_dependency "benchmark-ips", "~> 1.2"
|
30
28
|
spec.add_development_dependency "bundler"
|
31
29
|
spec.add_development_dependency "codeclimate-test-reporter", "0.4.4"
|
32
30
|
spec.add_development_dependency "pry"
|
31
|
+
spec.add_development_dependency "qiita_marker", "~> 0.23.6"
|
33
32
|
spec.add_development_dependency "rake", "~> 10.0"
|
34
33
|
spec.add_development_dependency "rspec", "~> 3.1"
|
35
34
|
spec.add_development_dependency "rubocop", "~> 1.39.0"
|
@@ -26,6 +26,34 @@ describe Qiita::Markdown::Filters::Checkbox do
|
|
26
26
|
expect(filter.call.to_s).to eq(output_html)
|
27
27
|
end
|
28
28
|
|
29
|
+
context "when list is loose" do
|
30
|
+
let(:input_html) do
|
31
|
+
<<~HTML
|
32
|
+
<li>
|
33
|
+
<p>[ ] a</p>
|
34
|
+
</li>
|
35
|
+
<li>
|
36
|
+
<p>[x] b</p>
|
37
|
+
</li>
|
38
|
+
HTML
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:output_html) do
|
42
|
+
<<~HTML
|
43
|
+
<li class="task-list-item">
|
44
|
+
<p><input type="checkbox" class="task-list-item-checkbox" disabled>a</p>
|
45
|
+
</li>
|
46
|
+
<li class="task-list-item">
|
47
|
+
<p><input type="checkbox" class="task-list-item-checkbox" checked disabled>b</p>
|
48
|
+
</li>
|
49
|
+
HTML
|
50
|
+
end
|
51
|
+
|
52
|
+
it "replaces checkboxes" do
|
53
|
+
expect(filter.call.to_s).to eq(output_html)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
29
57
|
context "when input html has many spaces after checkbox mark" do
|
30
58
|
let(:input_html) do
|
31
59
|
<<~HTML
|