mato 2.2.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d94a4026d7fadd8bc561d9489f2a89238ce6b4100e4e8d887832be86304feb33
4
- data.tar.gz: fb26a18fa1f92dfc655f2b53a5aac5af2b3fe945bf2a42cbc8c0966d8f964044
3
+ metadata.gz: a0009a682500eef0ba90fc7166044321a21e0dc8cde9e290938466d81e5d93a9
4
+ data.tar.gz: 44dfea37fc148c34c423d91d496316618f24d911dbc340ebba691cd17632a980
5
5
  SHA512:
6
- metadata.gz: d698ea373d885e1c9716077dffd1aefc50426c398b68038c288e83f05fb016f26aa1302a1fc93447ec9d8c1b409f2c6f03e2474315075cfdb6e72037c20dfb1a
7
- data.tar.gz: c39ed1a90becdb01f2d3b8447b67b79f3ce6efa8dcfbfce39d4c4c5d7e315ae69941655ff0d831829e955b6fd0102db592923501354c6cc74208f3065b8926ad
6
+ metadata.gz: 703fb8e5f8132eb78887d30d8245c0738ff8b5e14e4662bef1e6f572571429465472b18fe853e3ac58ee1d15f87ef32460f6f2bc716db44e568ffdccd8bd02c1
7
+ data.tar.gz: 265481153e3404d01049e6f79550573839024095597168180c6310a8bbc8d9b2ed491dad9723fee3a4d57ca38888b64341c173054c8418ae1eb04497cfc9802a
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ require:
3
3
  - rubocop-performance
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.4
6
+ TargetRubyVersion: 2.7
7
7
  DisplayCopNames: true
8
8
  Exclude:
9
9
  - bin/**/*
data/.travis.yml CHANGED
@@ -1,9 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.4
4
- - 2.5
5
- - 2.6
6
3
  - 2.7
4
+ - 3.0
7
5
  - ruby-head
8
6
 
9
7
  matrix:
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
@@ -7,6 +7,7 @@ gemspec
7
7
 
8
8
  gem "sanitize", ">= 3.0"
9
9
 
10
+ gem 'activesupport'
10
11
  gem "bundler", ">= 1.14"
11
12
  gem "m"
12
13
  gem "minitest"
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::HTML::DocumentFragment`
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::HTML::DocumentFragment>]
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::HTML::DocumentFragment
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::HTML::DocumentFragment]
9
+ # @return [Nokogiri::HTML4::DocumentFragment]
10
10
  attr_reader :fragment
11
11
 
12
12
  def self.empty
13
- new(Nokogiri::HTML.fragment(''))
13
+ new(Nokogiri::HTML4.fragment(''))
14
14
  end
15
15
 
16
- # @param [Nokogiri::HTML::DocumentFragment] fragment
16
+ # @param [Nokogiri::HTML4::DocumentFragment] fragment
17
17
  def initialize(fragment)
18
18
  @fragment = fragment
19
19
  end
20
20
 
21
- # @return [Nokogiri::HTML::DocumentFragment] A copy of fragment that are modified by html_filters
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::HTML.fragment(data[:fragment]).freeze)
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::HTML.fragment('<p/>')
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::HTML::DocumentFragment] doc
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
  @anchor_icon_element = anchor_icon_element
13
13
  end
14
14
 
15
- # @param [Nokogiri::HTML::DocumentFragment] doc
15
+ # @param [Nokogiri::HTML4::DocumentFragment] doc
16
16
  def call(doc)
17
17
  anchor_builder = AnchorBuilder.new(@anchor_icon_element)
18
18
 
@@ -12,7 +12,7 @@ module Mato
12
12
  @on_rouge_error = on_rouge_error
13
13
  end
14
14
 
15
- # @param [Nokogiri::HTML::DocumentFragment] doc
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::HTML.fragment(%{<div class="code-frame"/>})
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::HTML.fragment(%{<div class="code-label"/>}).tap do |fragment|
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 = "[x] "
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::HTML::DocumentFragment] doc
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&.start_with?(CHECKED_MARK)
43
+ text_node&.content&.match?(checked_mark)
41
44
  end
42
45
 
43
46
  def has_unchecked_mark?(text_node)
44
- text_node&.content&.start_with?(UNCHECKED_MARK)
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(CHECKED_MARK, '')
52
+ content.sub(checked_mark, '')
50
53
  else
51
- content.sub(UNCHECKED_MARK, '')
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::HTML.fragment('<input type="checkbox"/>').tap do |fragment|
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'
@@ -20,7 +20,7 @@ module Mato
20
20
  @builder = builder
21
21
  end
22
22
 
23
- # @param [Nokogiri::HTML::DocumentFragment] doc
23
+ # @param [Nokogiri::HTML4::DocumentFragment] doc
24
24
  def call(doc)
25
25
  doc.xpath('.//text()').each do |text_node|
26
26
  next if has_ancestor?(text_node, 'a', 'code')
@@ -55,7 +55,7 @@ module Mato
55
55
  end
56
56
 
57
57
  # @param [String] html
58
- # @return [Nokogiri::HTML::DocumentFragment]
58
+ # @return [Nokogiri::HTML4::DocumentFragment]
59
59
  def parse_html(html)
60
60
  config.html_parser.parse(html)
61
61
  end
@@ -3,7 +3,7 @@
3
3
  module Mato
4
4
  module Renderers
5
5
  class HtmlRenderer
6
- # @param [Nokogiri::HTML::DocumentFragment] doc
6
+ # @param [Nokogiri::HTML4::DocumentFragment] doc
7
7
  # @return [String]
8
8
  def call(doc)
9
9
  doc.to_html
@@ -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::HTML::DocumentFragment] doc
12
+ # @param [Nokogiri::HTML4::DocumentFragment] doc
13
13
  # @return [String]
14
14
  def call(doc)
15
15
  s = +''
data/lib/mato/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mato
4
- VERSION = "2.2.0"
4
+ VERSION = "2.4.0"
5
5
  end
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.4"
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.6"
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.2.0
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: 2020-05-08 00:00:00.000000000 Z
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.6'
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.6'
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.4'
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.0.pre1
116
+ rubygems_version: 3.1.2
113
117
  signing_key:
114
118
  specification_version: 4
115
119
  summary: MArkdown TOolkit