notion_to_md 2.2.4 → 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: 1fb7426b97e6a8fdd9cd27cd1254939c5ccd3cb3455920ff35071d5c3429a4f1
4
- data.tar.gz: 523b5ff29517de54208a7506970115f11d087c9bb314e4b0a626650760ec89f3
3
+ metadata.gz: fb94bccdf9dca4374bfaeb42164cce77f3a1963048a96b83a53e238ff9768163
4
+ data.tar.gz: '039b7d197fc03a6a04ffaf1cb90f3f758dd597a7381a2002da677065d48f2d76'
5
5
  SHA512:
6
- metadata.gz: f9f181ba6bdbece59d9f8f5ad81c05afe86e942fcca913674ca42f04876a158091e8dc21b4eb392d9226c8839a8eea021c223a9d40c681093c9a16f153ec9793
7
- data.tar.gz: 4999b3781d9bf53357f8e5f8585beef8c4c3b501c6b35d360f2593b8596ae5b615979bb20246b2aee911342f5d97824a0c1da882c8d54a544fc14c1e0e61dbb1
6
+ metadata.gz: ce0dd31c6a1eb871468b151e2374311799b802b0f58e6e450bcc24aaa76f586f9755ad63953f3b61b45e0102d1440fa3d8f66538c014dbc921fc8ecf01a69a6f
7
+ data.tar.gz: 1a008da641c3c449b401ede3e2d65608a47192cae908888bcebd96eba7162e70f7640e549a881c459e9010cd1703248c49fa8d65d3a516489601a80c48e0e87d
data/README.md CHANGED
@@ -25,6 +25,14 @@ notion_converter = NotionToMd::Converter.new(page_id: 'b91d5...', token: 'secret
25
25
  md = notion_converter.convert
26
26
  ```
27
27
 
28
+ Since v2.3 you can also use the convenient `convert` method from the root module.
29
+
30
+ ```ruby
31
+ require 'notion_to_md'
32
+
33
+ md = NotionToMd.convert(page_id: 'b91d5...', token: 'secret_...')
34
+ ```
35
+
28
36
  If the secret token is provided as an environment variable —`NOTION_TOKEN`—, there's no need to pass it as an argument to the constructor.
29
37
 
30
38
  ```bash
@@ -36,6 +44,8 @@ require 'notion_to_md'
36
44
 
37
45
  notion_converter = NotionToMd::Converter.new(page_id: 'b91d5...')
38
46
  md = notion_converter.convert
47
+ # or
48
+ md = NotionToMd.convert(page_id: 'b91d5...')
39
49
  ```
40
50
 
41
51
  And that's all. The `md` is a string variable containing the notion page formatted in markdown.
@@ -49,7 +59,7 @@ Everything in a notion page body is a [block object](https://developers.notion.c
49
59
  * `heading_2`
50
60
  * `heading_3`
51
61
  * `bulleted_list_item`
52
- * `numbered_list_item` as `bulleted_list_item`
62
+ * `numbered_list_item` (supported since v2.3, in previous versions is displayed as `bulleted_list_item`)
53
63
  * `to_do`
54
64
  * `image`
55
65
  * `bookmark`
@@ -77,6 +87,8 @@ By default, the front matter section is not included to the document. To do so,
77
87
 
78
88
  ```ruby
79
89
  NotionToMd::Converter.new(page_id: 'b91d5...').convert(frontmatter: tue)
90
+ # or
91
+ NotionToMd.convert(page_id: 'b91d5...', frontmatter: true) # Since v2.3
80
92
  ```
81
93
 
82
94
  Default notion [properties](https://developers.notion.com/reference/page#all-pages) are page `id`, `title`, `created_time`, `last_edited_time`, `icon`, `archived` and `cover`.
@@ -90,6 +102,10 @@ created_time: 2022-01-23T12:31:00.000Z
90
102
  last_edited_time: 2022-01-23T12:31:00.000Z
91
103
  icon: 💥
92
104
  archived: false
105
+ created_by_id: db313571-0280-411f-a6de-70e826421d16
106
+ created_by_object: user
107
+ last_edited_by_id: db313571-0280-411f-a6de-70e826421d16
108
+ last_edited_by_object: user
93
109
  ---
94
110
  ```
95
111
 
@@ -9,6 +9,8 @@ module NotionToMd
9
9
 
10
10
  attr_reader :block, :children
11
11
 
12
+ def_delegators :block, :type
13
+
12
14
  # === Parameters:
13
15
  # block::
14
16
  # A {Notion::Messages::Message}[https://github.com/orbit-love/notion-ruby-client/blob/main/lib/notion/messages/message.rb] object.
@@ -32,14 +34,18 @@ module NotionToMd
32
34
  #
33
35
  def to_md(tab_width: 0)
34
36
  block_type = block.type.to_sym
35
- md = Types.send(block_type, block[block_type])
37
+ md = Types.send(block_type, block[block_type]) + newline
36
38
  md + build_nested_blocks(tab_width + 1)
37
39
  rescue NoMethodError
38
40
  Logger.info("Unsupported block type: #{block_type}")
39
41
  nil
40
42
  end
41
43
 
42
- private
44
+ protected
45
+
46
+ def newline
47
+ "\n\n"
48
+ end
43
49
 
44
50
  def build_nested_blocks(tab_width)
45
51
  mds = markdownify_children(tab_width).compact
@@ -54,7 +60,7 @@ module NotionToMd
54
60
 
55
61
  def indent_children(mds, tab_width)
56
62
  mds.map do |md|
57
- "\n\n#{"\t" * tab_width}#{md}"
63
+ "#{"\t" * tab_width}#{md}"
58
64
  end
59
65
  end
60
66
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class Builder
6
+ ##
7
+ # Array containing the block types allowed to have nested blocks (children).
8
+ BLOCKS_WITH_PERMITTED_CHILDREN = %i[
9
+ bulleted_list_item
10
+ numbered_list_item
11
+ paragraph
12
+ to_do
13
+ table
14
+ ].freeze
15
+
16
+ # === Parameters
17
+ # block::
18
+ # A {Notion::Messages::Message}[https://github.com/orbit-love/notion-ruby-client/blob/main/lib/notion/messages/message.rb] object.
19
+ #
20
+ # === Returns
21
+ # A boolean indicating if the blocked passed in
22
+ # is permitted to have children based on its type.
23
+ #
24
+ def self.permitted_children_for?(block:)
25
+ BLOCKS_WITH_PERMITTED_CHILDREN.include?(block.type.to_sym) && block.has_children
26
+ end
27
+
28
+ attr_reader :block_id, :fetch_blocks
29
+
30
+ # === Parameters
31
+ # block_id::
32
+ # A string representing a notion block id .
33
+ # fetch_blocks::
34
+ # A block that fetches the blocks from the Notion API.
35
+ #
36
+ # === Returns
37
+ # An array of NotionToMd::Blocks::Block.
38
+ #
39
+ def initialize(block_id:, &fetch_blocks)
40
+ @block_id = block_id
41
+ @fetch_blocks = fetch_blocks
42
+ end
43
+
44
+ # === Parameters
45
+ #
46
+ # === Returns
47
+ # An array of NotionToMd::Blocks::Block.
48
+ #
49
+ def build
50
+ notion_messages = fetch_blocks.call(block_id)
51
+ blocks = notion_messages.results.map do |block|
52
+ children = if Builder.permitted_children_for?(block: block)
53
+ Builder.new(block_id: block.id, &fetch_blocks).build
54
+ else
55
+ []
56
+ end
57
+ Factory.build(block: block, children: children)
58
+ end
59
+
60
+ Normalizer.normalize(blocks: blocks)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class BulletedListBlock < Block
6
+ def initialize(children: [])
7
+ @children = children
8
+ end
9
+
10
+ # === Parameters:
11
+ # tab_width::
12
+ # The number of tabs used to indent the block.
13
+ #
14
+ # === Returns
15
+ # The current block (and its children) converted to a markdown string.
16
+ #
17
+ def to_md(tab_width: 0)
18
+ if tab_width.zero?
19
+ build_nested_blocks(tab_width) + newline
20
+ else
21
+ build_nested_blocks(tab_width)
22
+ end
23
+ end
24
+
25
+ def type
26
+ 'bulleted_list'
27
+ end
28
+
29
+ def newline
30
+ "\n"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class BulletedListItemBlock < Block
6
+ def newline
7
+ "\n"
8
+ end
9
+
10
+ def indent_children(mds, _tab_width)
11
+ mds
12
+ end
13
+ end
14
+ end
15
+ end
@@ -7,6 +7,14 @@ module NotionToMd
7
7
  case block.type.to_sym
8
8
  when :table
9
9
  TableBlock.new(block: block, children: children)
10
+ when :table_row
11
+ TableRowBlock.new(block: block, children: children)
12
+ when :bulleted_list_item
13
+ BulletedListItemBlock.new(block: block, children: children)
14
+ when :numbered_list_item
15
+ NumberedListItemBlock.new(block: block, children: children)
16
+ when :to_do
17
+ ToDoListItemBlock.new(block: block, children: children)
10
18
  else
11
19
  Blocks::Block.new(block: block, children: children)
12
20
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class Normalizer
6
+ # === Parameters
7
+ # blocks::
8
+ # An array of NotionToMd::Blocks::Block.
9
+ #
10
+ def self.normalize(blocks:)
11
+ new(blocks: blocks).normalize
12
+ end
13
+
14
+ attr_reader :normalized_blocks
15
+
16
+ def initialize(blocks:)
17
+ @normalized_blocks = blocks.dup
18
+ end
19
+
20
+ def normalize
21
+ normalize_for :bulleted_list_item
22
+ normalize_for :numbered_list_item
23
+ normalize_for :to_do
24
+ end
25
+
26
+ def normalize_for(type)
27
+ new_blocks = []
28
+
29
+ normalized_blocks.each do |block|
30
+ if block.type.to_sym == type
31
+ blocks_to_normalize << block
32
+ else
33
+ # When we encounter a block that is not of the provided type,
34
+ # we need to normalize the blocks we've collected so far.
35
+ # Then we add the current block to the new blocks array.
36
+ # This is because we want to keep the order of the blocks.
37
+ new_blocks << new_block_and_reset_blocks_to_normalize(type) unless blocks_to_normalize.empty?
38
+ new_blocks << block
39
+ end
40
+ end
41
+
42
+ # If the last block is the provided type, it won't be added to the new blocks array.
43
+ # So, we need to normalize the blocks we've collected so far.
44
+ new_blocks << new_block_and_reset_blocks_to_normalize(type) unless blocks_to_normalize.empty?
45
+
46
+ normalized_blocks.replace(new_blocks)
47
+ end
48
+
49
+ private
50
+
51
+ def new_block_and_reset_blocks_to_normalize(type)
52
+ new_block = new_block_for(type, blocks_to_normalize)
53
+ @blocks_to_normalize = []
54
+ new_block
55
+ end
56
+
57
+ def blocks_to_normalize
58
+ @blocks_to_normalize ||= []
59
+ end
60
+
61
+ def new_block_for(type, children)
62
+ case type
63
+ when :bulleted_list_item
64
+ BulletedListBlock.new(children: children)
65
+ when :numbered_list_item
66
+ NumberedListBlock.new(children: children)
67
+ when :to_do
68
+ ToDoListBlock.new(children: children)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class NumberedListBlock < BulletedListBlock
6
+ def type
7
+ 'numbered_list'
8
+ end
9
+
10
+ protected
11
+
12
+ def markdownify_children(tab_width)
13
+ children.map.with_index do |nested_block, index|
14
+ nested_block.to_md(tab_width: tab_width, index: index + 1)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './bulleted_list_item_block'
4
+
5
+ module NotionToMd
6
+ module Blocks
7
+ class NumberedListItemBlock < BulletedListItemBlock
8
+ # === Parameters:
9
+ # tab_width::
10
+ # The number of tabs used to indent the block.
11
+ # index::
12
+ # The index of the block in its parent's children array used to number the item.
13
+ #
14
+ # === Returns
15
+ # The current block (and its children) converted to a markdown string.
16
+ #
17
+ def to_md(tab_width: 0, index: nil)
18
+ md = Types.numbered_list_item(block[block.type.to_sym], index) + newline
19
+ md + build_nested_blocks(tab_width + 1)
20
+ rescue NoMethodError
21
+ Logger.info("Unsupported block type: #{block.type}")
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end
@@ -10,17 +10,21 @@ module NotionToMd
10
10
  table_aligment = markdownify_aligment
11
11
  table_body = table[1..table.size]
12
12
 
13
- [table_header, table_aligment, table_body.join("\n")].compact.join("\n")
13
+ [table_header, table_aligment, table_body].compact.join + newline
14
14
  end
15
15
 
16
- private
16
+ protected
17
17
 
18
18
  def row_size
19
19
  @row_size ||= children.first.block.table_row.cells.size
20
20
  end
21
21
 
22
22
  def markdownify_aligment
23
- "|#{row_size.times.map { '---' }.join('|')}|" if block.table.has_column_header
23
+ "|#{row_size.times.map { '---' }.join('|')}|\n" if block.table.has_column_header
24
+ end
25
+
26
+ def newline
27
+ "\n"
24
28
  end
25
29
  end
26
30
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class TableRowBlock < Block
6
+ def newline
7
+ "\n"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ module Blocks
5
+ class ToDoListBlock < BulletedListBlock
6
+ def type
7
+ 'to_do_list'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './bulleted_list_item_block'
4
+
5
+ module NotionToMd
6
+ module Blocks
7
+ class ToDoListItemBlock < BulletedListItemBlock
8
+ def newline
9
+ "\n"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,7 +5,7 @@ module NotionToMd
5
5
  class Types
6
6
  class << self
7
7
  def paragraph(block)
8
- return blank if block.rich_text.empty?
8
+ return blank if block[:rich_text].empty?
9
9
 
10
10
  convert_text(block)
11
11
  end
@@ -36,9 +36,10 @@ module NotionToMd
36
36
  "- #{convert_text(block)}"
37
37
  end
38
38
 
39
- def numbered_list_item(block)
40
- Logger.info('numbered_list_item type not supported. Shown as bulleted_list_item.')
41
- bulleted_list_item(block)
39
+ def numbered_list_item(block, index = nil)
40
+ return bulleted_list_item(block) if index.nil?
41
+
42
+ "#{index}. #{convert_text(block)}"
42
43
  end
43
44
 
44
45
  def to_do(block)
@@ -123,7 +124,7 @@ module NotionToMd
123
124
  href = text[:href]
124
125
  return content if href.nil?
125
126
 
126
- "[#{content}](#{href})"
127
+ "[#{content}](#{CGI.unescape(href)})"
127
128
  end
128
129
 
129
130
  def add_annotations(text, content)
@@ -1,51 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './blocks/block'
3
+ require_relative './blocks/builder'
4
+ require_relative './blocks/normalizer'
4
5
  require_relative './blocks/factory'
5
- require_relative './blocks/table_block'
6
6
  require_relative './blocks/types'
7
+ require_relative './blocks/block'
8
+ require_relative './blocks/table_block'
9
+ require_relative './blocks/table_row_block'
10
+ require_relative './blocks/bulleted_list_block'
11
+ require_relative './blocks/bulleted_list_item_block'
12
+ require_relative './blocks/numbered_list_block'
13
+ require_relative './blocks/numbered_list_item_block'
14
+ require_relative './blocks/to_do_list_block'
15
+ require_relative './blocks/to_do_list_item_block'
7
16
 
8
17
  module NotionToMd
9
18
  module Blocks
10
- ##
11
- # Array containing the block types allowed to have nested blocks (children).
12
- PERMITTED_CHILDREN = [
13
- Types.method(:bulleted_list_item).name,
14
- Types.method(:numbered_list_item).name,
15
- Types.method(:paragraph).name,
16
- Types.method(:to_do).name,
17
- :table
18
- ].freeze
19
-
20
- # === Parameters
21
- # block::
22
- # A {Notion::Messages::Message}[https://github.com/orbit-love/notion-ruby-client/blob/main/lib/notion/messages/message.rb] object.
23
- #
24
- # === Returns
25
- # A boolean indicating if the blocked passed in
26
- # is permitted to have children based on its type.
27
- #
28
- def self.permitted_children?(block:)
29
- PERMITTED_CHILDREN.include?(block.type.to_sym) && block.has_children
30
- end
31
-
32
19
  # === Parameters
33
20
  # block_id::
34
21
  # A string representing a notion block id .
22
+ # fetch_blocks::
23
+ # A block that fetches the blocks from the Notion API.
35
24
  #
36
25
  # === Returns
37
26
  # An array of NotionToMd::Blocks::Block.
38
27
  #
39
28
  def self.build(block_id:, &fetch_blocks)
40
- blocks = fetch_blocks.call(block_id)
41
- blocks.results.map do |block|
42
- children = if permitted_children?(block: block)
43
- build(block_id: block.id, &fetch_blocks)
44
- else
45
- []
46
- end
47
- Factory.build(block: block, children: children)
48
- end
29
+ Builder.new(block_id: block_id, &fetch_blocks).build
49
30
  end
50
31
  end
51
32
  end
@@ -29,11 +29,27 @@ module NotionToMd
29
29
  end
30
30
 
31
31
  def created_time
32
- DateTime.parse(page['created_time'])
32
+ page['created_time']
33
+ end
34
+
35
+ def created_by_object
36
+ page.dig(:created_by, :object)
37
+ end
38
+
39
+ def created_by_id
40
+ page.dig(:created_by, :id)
33
41
  end
34
42
 
35
43
  def last_edited_time
36
- DateTime.parse(page['last_edited_time'])
44
+ page['last_edited_time']
45
+ end
46
+
47
+ def last_edited_by_object
48
+ page.dig(:last_edited_by, :object)
49
+ end
50
+
51
+ def last_edited_by_id
52
+ page.dig(:last_edited_by, :id)
37
53
  end
38
54
 
39
55
  def url
@@ -45,7 +61,7 @@ module NotionToMd
45
61
  end
46
62
 
47
63
  def body
48
- @body ||= blocks.map(&:to_md).compact.join("\n\n")
64
+ @body ||= blocks.map(&:to_md).compact.join
49
65
  end
50
66
 
51
67
  def frontmatter
@@ -77,12 +93,16 @@ module NotionToMd
77
93
  def default_props
78
94
  @default_props ||= {
79
95
  'id' => id,
80
- 'title' => title,
96
+ 'title' => title.dump,
81
97
  'created_time' => created_time,
82
98
  'cover' => cover,
83
99
  'icon' => icon,
84
100
  'last_edited_time' => last_edited_time,
85
- 'archived' => archived
101
+ 'archived' => archived,
102
+ 'created_by_object' => created_by_object,
103
+ 'created_by_id' => created_by_id,
104
+ 'last_edited_by_object' => last_edited_by_object,
105
+ 'last_edited_by_id' => last_edited_by_id
86
106
  }
87
107
  end
88
108
 
@@ -28,7 +28,7 @@ module NotionToMd
28
28
  end
29
29
 
30
30
  def select(prop)
31
- prop.dig(:select, :name)
31
+ prop.dig(:select, :name).dump
32
32
  rescue NoMethodError
33
33
  nil
34
34
  end
@@ -73,7 +73,16 @@ module NotionToMd
73
73
  # - end
74
74
  # - time_zone
75
75
  def date(prop)
76
- prop.dig(:date, :start)
76
+ date = prop.dig(:date, :start)
77
+
78
+ case date
79
+ when Date
80
+ date.to_time
81
+ when String
82
+ Time.parse(date)
83
+ else
84
+ date # Time or nil
85
+ end
77
86
  rescue NoMethodError
78
87
  nil
79
88
  end
@@ -85,7 +94,8 @@ module NotionToMd
85
94
  end
86
95
 
87
96
  def rich_text(prop)
88
- prop[:rich_text].map { |text| text[:plain_text] }.join
97
+ text = prop[:rich_text].map { |text| text[:plain_text] }.join
98
+ text.blank? ? nil : text.dump
89
99
  rescue NoMethodError
90
100
  nil
91
101
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NotionToMd
4
- VERSION = '2.2.4'
4
+ VERSION = '2.4.0'
5
5
  end
data/lib/notion_to_md.rb CHANGED
@@ -12,3 +12,20 @@ require_relative './notion_to_md/page'
12
12
  require_relative './notion_to_md/blocks'
13
13
  require_relative './notion_to_md/text'
14
14
  require_relative './notion_to_md/text_annotation'
15
+
16
+ module NotionToMd
17
+ # === Parameters
18
+ # page_id::
19
+ # A string representing the notion page id.
20
+ # token::
21
+ # The notion API secret token. The token can replaced by the environment variable NOTION_TOKEN.
22
+ # frontmatter::
23
+ # A boolean indicating whether to include the page properties as frontmatter.
24
+ #
25
+ # === Returns
26
+ # The string that represent the markdown document.
27
+ #
28
+ def self.convert(page_id:, token: nil, frontmatter: false)
29
+ Converter.new(page_id: page_id, token: token).convert(frontmatter: frontmatter)
30
+ end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notion_to_md
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.4
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Enrique Arias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-22 00:00:00.000000000 Z
11
+ date: 2023-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Notion Markdown Exporter in Ruby
112
126
  email: emoriarty81@gmail.com
113
127
  executables: []
@@ -118,8 +132,17 @@ files:
118
132
  - lib/notion_to_md.rb
119
133
  - lib/notion_to_md/blocks.rb
120
134
  - lib/notion_to_md/blocks/block.rb
135
+ - lib/notion_to_md/blocks/builder.rb
136
+ - lib/notion_to_md/blocks/bulleted_list_block.rb
137
+ - lib/notion_to_md/blocks/bulleted_list_item_block.rb
121
138
  - lib/notion_to_md/blocks/factory.rb
139
+ - lib/notion_to_md/blocks/normalizer.rb
140
+ - lib/notion_to_md/blocks/numbered_list_block.rb
141
+ - lib/notion_to_md/blocks/numbered_list_item_block.rb
122
142
  - lib/notion_to_md/blocks/table_block.rb
143
+ - lib/notion_to_md/blocks/table_row_block.rb
144
+ - lib/notion_to_md/blocks/to_do_list_block.rb
145
+ - lib/notion_to_md/blocks/to_do_list_item_block.rb
123
146
  - lib/notion_to_md/blocks/types.rb
124
147
  - lib/notion_to_md/converter.rb
125
148
  - lib/notion_to_md/logger.rb