mato 2.2.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -3
- data/CHANGELOG.md +20 -0
- data/Gemfile +1 -0
- data/README.md +1 -1
- data/lib/mato/config.rb +2 -2
- data/lib/mato/document.rb +5 -5
- data/lib/mato/html_filters/bare_inline_element.rb +1 -1
- data/lib/mato/html_filters/mention_link.rb +6 -1
- data/lib/mato/html_filters/section_anchor.rb +1 -1
- data/lib/mato/html_filters/syntax_highlight.rb +3 -3
- data/lib/mato/html_filters/task_list.rb +29 -10
- data/lib/mato/html_filters/token_link.rb +1 -1
- data/lib/mato/processor.rb +1 -1
- data/lib/mato/renderers/html_renderer.rb +1 -1
- data/lib/mato/renderers/html_toc_renderer.rb +1 -1
- data/lib/mato/version.rb +1 -1
- data/mato.gemspec +7 -2
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0009a682500eef0ba90fc7166044321a21e0dc8cde9e290938466d81e5d93a9
|
4
|
+
data.tar.gz: 44dfea37fc148c34c423d91d496316618f24d911dbc340ebba691cd17632a980
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 703fb8e5f8132eb78887d30d8245c0738ff8b5e14e4662bef1e6f572571429465472b18fe853e3ac58ee1d15f87ef32460f6f2bc716db44e568ffdccd8bd02c1
|
7
|
+
data.tar.gz: 265481153e3404d01049e6f79550573839024095597168180c6310a8bbc8d9b2ed491dad9723fee3a4d57ca38888b64341c173054c8418ae1eb04497cfc9802a
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,29 @@
|
|
1
1
|
# The revision history of Mato
|
2
2
|
|
3
|
+
## v2.4.0 - 2021/08/25
|
4
|
+
|
5
|
+
https://github.com/bitjourney/mato/compare/v2.3.2...v2.4.0
|
6
|
+
|
7
|
+
* BREAKING: Drop support for Ruby 2.4, 2.5, and 2.6
|
8
|
+
* Bump up minimum dependency of nokogiri to 1.12
|
9
|
+
|
10
|
+
## v2.3.2 - 2021/01/08
|
11
|
+
|
12
|
+
* Fix error on mention link with Nokogiri v1.11.0+. [#26](https://github.com/bitjourney/mato/pull/26)
|
13
|
+
|
14
|
+
## v2.3.1 - 2020/07/15
|
15
|
+
|
16
|
+
* Allow loose task list. [#24](https://github.com/bitjourney/mato/pull/24)
|
17
|
+
|
18
|
+
## v2.3.0 - 2020/06/16
|
19
|
+
|
20
|
+
* Add `convert_empty_task_list` option to TaskList filter to convert task list event if the text is empty. [#23](https://github.com/bitjourney/mato/pull/23)
|
21
|
+
|
3
22
|
## v2.2.0 - 2020/05/08
|
4
23
|
|
5
24
|
https://github.com/bitjourney/mato/compare/v2.1.4...v2.2.0
|
6
25
|
|
26
|
+
* BREAKING: Drop support for Ruby 2.3
|
7
27
|
* Display code block as plan text if Rouge raises an error [#21](https://github.com/bitjourney/mato/pull/21)
|
8
28
|
|
9
29
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -108,7 +108,7 @@ mato.process("Hello!").render_html # "<p>HELLO!</p>\n"
|
|
108
108
|
|
109
109
|
### HTML Filters
|
110
110
|
|
111
|
-
An HTML filter is a callable object that takes a ``Nokogiri::
|
111
|
+
An HTML filter is a callable object that takes a ``Nokogiri::HTML4::DocumentFragment`
|
112
112
|
and mutate it in the method. The return value is ignored.
|
113
113
|
|
114
114
|
```ruby
|
data/lib/mato/config.rb
CHANGED
@@ -42,7 +42,7 @@ module Mato
|
|
42
42
|
# @return [Class<CommonMarker]
|
43
43
|
attr_accessor :markdown_parser
|
44
44
|
|
45
|
-
# @return [Cass<Nokogiri::
|
45
|
+
# @return [Cass<Nokogiri::HTML4::DocumentFragment>]
|
46
46
|
attr_accessor :html_parser
|
47
47
|
|
48
48
|
# @return [Class<Mato::Document>]
|
@@ -63,7 +63,7 @@ module Mato
|
|
63
63
|
@html_filters = []
|
64
64
|
|
65
65
|
@markdown_parser = CommonMarker
|
66
|
-
@html_parser = Nokogiri::
|
66
|
+
@html_parser = Nokogiri::HTML4::DocumentFragment
|
67
67
|
|
68
68
|
@document_factory = Document
|
69
69
|
|
data/lib/mato/document.rb
CHANGED
@@ -6,19 +6,19 @@ require_relative './renderers/html_toc_renderer'
|
|
6
6
|
# Intermediate document class, which instance is *serializable*.
|
7
7
|
module Mato
|
8
8
|
class Document
|
9
|
-
# @return [Nokogiri::
|
9
|
+
# @return [Nokogiri::HTML4::DocumentFragment]
|
10
10
|
attr_reader :fragment
|
11
11
|
|
12
12
|
def self.empty
|
13
|
-
new(Nokogiri::
|
13
|
+
new(Nokogiri::HTML4.fragment(''))
|
14
14
|
end
|
15
15
|
|
16
|
-
# @param [Nokogiri::
|
16
|
+
# @param [Nokogiri::HTML4::DocumentFragment] fragment
|
17
17
|
def initialize(fragment)
|
18
18
|
@fragment = fragment
|
19
19
|
end
|
20
20
|
|
21
|
-
# @return [Nokogiri::
|
21
|
+
# @return [Nokogiri::HTML4::DocumentFragment] A copy of fragment that are modified by html_filters
|
22
22
|
def apply_html_filters(*html_filters)
|
23
23
|
new_fragment = fragment.dup
|
24
24
|
html_filters.each do |html_filter|
|
@@ -58,7 +58,7 @@ module Mato
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def marshal_load(data)
|
61
|
-
initialize(Nokogiri::
|
61
|
+
initialize(Nokogiri::HTML4.fragment(data[:fragment]).freeze)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -18,7 +18,7 @@ module Mato
|
|
18
18
|
doc.children.each do |node|
|
19
19
|
next unless STANDALONE_INLINE_ELEMENTS.include?(node.name)
|
20
20
|
|
21
|
-
parent = Nokogiri::
|
21
|
+
parent = Nokogiri::HTML4.fragment('<p/>')
|
22
22
|
parent.child.add_child(node.dup)
|
23
23
|
node.replace(parent)
|
24
24
|
end
|
@@ -22,7 +22,7 @@ module Mato
|
|
22
22
|
@link_builder = link_builder
|
23
23
|
end
|
24
24
|
|
25
|
-
# @param [Nokogiri::
|
25
|
+
# @param [Nokogiri::HTML4::DocumentFragment] doc
|
26
26
|
def call(doc)
|
27
27
|
candidate_map = {}
|
28
28
|
candidates = []
|
@@ -53,6 +53,11 @@ module Mato
|
|
53
53
|
candidates.each do |candidate_fragment|
|
54
54
|
candidate_fragment.css('span.mention-candidate').each do |node|
|
55
55
|
next unless node.child
|
56
|
+
# If link_builder calls Node#replace for a node,
|
57
|
+
# the node's parent becames nil.
|
58
|
+
# Node#replace doesn't accept node that doesn't have parent since Nokogiri v1.11.0,
|
59
|
+
# so we need to skip it.
|
60
|
+
next unless node.parent
|
56
61
|
|
57
62
|
node.replace(node.child.content)
|
58
63
|
end
|
@@ -12,7 +12,7 @@ module Mato
|
|
12
12
|
@on_rouge_error = on_rouge_error
|
13
13
|
end
|
14
14
|
|
15
|
-
# @param [Nokogiri::
|
15
|
+
# @param [Nokogiri::HTML4::DocumentFragment] doc
|
16
16
|
def call(doc)
|
17
17
|
doc.search("pre").each do |pre|
|
18
18
|
if pre.at('code')
|
@@ -64,7 +64,7 @@ module Mato
|
|
64
64
|
lexer = guess_lexer(language, filename, source)
|
65
65
|
|
66
66
|
begin
|
67
|
-
document = Nokogiri::
|
67
|
+
document = Nokogiri::HTML4.fragment(%{<div class="code-frame"/>})
|
68
68
|
div = document.at('div')
|
69
69
|
div.add_child(label_fragment(filename || language || lexer.tag)) if filename || !lexer.is_a?(Rouge::Lexers::PlainText)
|
70
70
|
div.add_child(%{<pre class="highlight"><code data-lang="#{lexer.tag}">#{format(lexer, source)}</code></pre>})
|
@@ -83,7 +83,7 @@ module Mato
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def label_fragment(label)
|
86
|
-
Nokogiri::
|
86
|
+
Nokogiri::HTML4.fragment(%{<div class="code-label"/>}).tap do |fragment|
|
87
87
|
fragment.at('div').add_child(Nokogiri::XML::Text.new(label, fragment))
|
88
88
|
end
|
89
89
|
end
|
@@ -3,18 +3,21 @@
|
|
3
3
|
module Mato
|
4
4
|
module HtmlFilters
|
5
5
|
class TaskList
|
6
|
-
CHECKED_MARK =
|
7
|
-
UNCHECKED_MARK =
|
6
|
+
CHECKED_MARK = /\A\[x\] /
|
7
|
+
UNCHECKED_MARK = /\A\[ \] /
|
8
|
+
CHECKED_MARK_FOR_EMPTY_TASK_LIST = /\A\[x\] ?/
|
9
|
+
UNCHECKED_MARK_FOR_EMPTY_TASK_LIST = /\A\[ \] ?/
|
8
10
|
|
9
11
|
DEFAULT_TASK_LIST_CLASS = "task-list-item"
|
10
12
|
DEFAULT_CHECKBOX_CLASS = "task-list-item-checkbox"
|
11
13
|
|
12
|
-
def initialize(task_list_class: DEFAULT_TASK_LIST_CLASS, checkbox_class: DEFAULT_CHECKBOX_CLASS)
|
14
|
+
def initialize(task_list_class: DEFAULT_TASK_LIST_CLASS, checkbox_class: DEFAULT_CHECKBOX_CLASS, convert_empty_task_list: false)
|
13
15
|
@task_list_class = task_list_class
|
14
16
|
@checkbox_class = checkbox_class
|
17
|
+
@convert_empty_task_list = convert_empty_task_list
|
15
18
|
end
|
16
19
|
|
17
|
-
# @param [Nokogiri::
|
20
|
+
# @param [Nokogiri::HTML4::DocumentFragment] doc
|
18
21
|
def call(doc)
|
19
22
|
doc.search("li").each do |li|
|
20
23
|
weave(li)
|
@@ -23,7 +26,7 @@ module Mato
|
|
23
26
|
|
24
27
|
# @param [Nokogiri::XML::Node] li
|
25
28
|
def weave(li)
|
26
|
-
text_node = li.xpath('.//text()').first
|
29
|
+
text_node = li.xpath('./p[1]/text()').first || li.xpath('.//text()').first
|
27
30
|
checked = has_checked_mark?(text_node)
|
28
31
|
unchecked = has_unchecked_mark?(text_node)
|
29
32
|
|
@@ -37,23 +40,39 @@ module Mato
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def has_checked_mark?(text_node)
|
40
|
-
text_node&.content&.
|
43
|
+
text_node&.content&.match?(checked_mark)
|
41
44
|
end
|
42
45
|
|
43
46
|
def has_unchecked_mark?(text_node)
|
44
|
-
text_node&.content&.
|
47
|
+
text_node&.content&.match?(unchecked_mark)
|
45
48
|
end
|
46
49
|
|
47
50
|
def trim_mark(content, checked)
|
48
51
|
if checked
|
49
|
-
content.sub(
|
52
|
+
content.sub(checked_mark, '')
|
50
53
|
else
|
51
|
-
content.sub(
|
54
|
+
content.sub(unchecked_mark, '')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def checked_mark
|
59
|
+
if @convert_empty_task_list
|
60
|
+
CHECKED_MARK_FOR_EMPTY_TASK_LIST
|
61
|
+
else
|
62
|
+
CHECKED_MARK
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def unchecked_mark
|
67
|
+
if @convert_empty_task_list
|
68
|
+
UNCHECKED_MARK_FOR_EMPTY_TASK_LIST
|
69
|
+
else
|
70
|
+
UNCHECKED_MARK
|
52
71
|
end
|
53
72
|
end
|
54
73
|
|
55
74
|
def build_checkbox_node(checked)
|
56
|
-
Nokogiri::
|
75
|
+
Nokogiri::HTML4.fragment('<input type="checkbox"/>').tap do |fragment|
|
57
76
|
checkbox = fragment.children.first
|
58
77
|
checkbox["class"] = @checkbox_class
|
59
78
|
checkbox["disabled"] = 'disabled'
|
data/lib/mato/processor.rb
CHANGED
@@ -9,7 +9,7 @@ module Mato
|
|
9
9
|
H_SELECTOR = %w(h1 h2 h3 h4 h5 h6).join(',')
|
10
10
|
ANCHOR_SELECTOR = "a.#{AnchorBuilder::CSS_CLASS_NAME}"
|
11
11
|
|
12
|
-
# @param [Nokogiri::
|
12
|
+
# @param [Nokogiri::HTML4::DocumentFragment] doc
|
13
13
|
# @return [String]
|
14
14
|
def call(doc)
|
15
15
|
s = +''
|
data/lib/mato/version.rb
CHANGED
data/mato.gemspec
CHANGED
@@ -13,6 +13,11 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/bitjourney/mato"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
+
spec.metadata["changelog_uri"] = 'https://github.com/bitjourney/mato/blob/master/CHANGELOG.md'
|
19
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/bitjourney/mato/issues'
|
20
|
+
|
16
21
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
22
|
f.match(%r{^(?:test|spec|features|example)/})
|
18
23
|
end
|
@@ -20,9 +25,9 @@ Gem::Specification.new do |spec|
|
|
20
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
26
|
spec.require_paths = ["lib"]
|
22
27
|
|
23
|
-
spec.required_ruby_version = ">= 2.
|
28
|
+
spec.required_ruby_version = ">= 2.7"
|
24
29
|
|
25
30
|
spec.add_runtime_dependency "commonmarker", ">= 0.18.1"
|
26
|
-
spec.add_runtime_dependency "nokogiri", ">= 1.
|
31
|
+
spec.add_runtime_dependency "nokogiri", ">= 1.12"
|
27
32
|
spec.add_runtime_dependency "rouge", ">= 3.0.0"
|
28
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FUJI Goro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commonmarker
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.12'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.12'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rouge
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,7 +93,11 @@ files:
|
|
93
93
|
homepage: https://github.com/bitjourney/mato
|
94
94
|
licenses:
|
95
95
|
- MIT
|
96
|
-
metadata:
|
96
|
+
metadata:
|
97
|
+
homepage_uri: https://github.com/bitjourney/mato
|
98
|
+
source_code_uri: https://github.com/bitjourney/mato
|
99
|
+
changelog_uri: https://github.com/bitjourney/mato/blob/master/CHANGELOG.md
|
100
|
+
bug_tracker_uri: https://github.com/bitjourney/mato/issues
|
97
101
|
post_install_message:
|
98
102
|
rdoc_options: []
|
99
103
|
require_paths:
|
@@ -102,14 +106,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
106
|
requirements:
|
103
107
|
- - ">="
|
104
108
|
- !ruby/object:Gem::Version
|
105
|
-
version: '2.
|
109
|
+
version: '2.7'
|
106
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
111
|
requirements:
|
108
112
|
- - ">="
|
109
113
|
- !ruby/object:Gem::Version
|
110
114
|
version: '0'
|
111
115
|
requirements: []
|
112
|
-
rubygems_version: 3.2
|
116
|
+
rubygems_version: 3.1.2
|
113
117
|
signing_key:
|
114
118
|
specification_version: 4
|
115
119
|
summary: MArkdown TOolkit
|