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 +4 -4
- data/README.md +17 -1
- data/lib/notion_to_md/blocks/block.rb +9 -3
- data/lib/notion_to_md/blocks/builder.rb +64 -0
- data/lib/notion_to_md/blocks/bulleted_list_block.rb +34 -0
- data/lib/notion_to_md/blocks/bulleted_list_item_block.rb +15 -0
- data/lib/notion_to_md/blocks/factory.rb +8 -0
- data/lib/notion_to_md/blocks/normalizer.rb +73 -0
- data/lib/notion_to_md/blocks/numbered_list_block.rb +19 -0
- data/lib/notion_to_md/blocks/numbered_list_item_block.rb +26 -0
- data/lib/notion_to_md/blocks/table_block.rb +7 -3
- data/lib/notion_to_md/blocks/table_row_block.rb +11 -0
- data/lib/notion_to_md/blocks/to_do_list_block.rb +11 -0
- data/lib/notion_to_md/blocks/to_do_list_item_block.rb +13 -0
- data/lib/notion_to_md/blocks/types.rb +6 -5
- data/lib/notion_to_md/blocks.rb +14 -33
- data/lib/notion_to_md/page.rb +25 -5
- data/lib/notion_to_md/page_property.rb +13 -3
- data/lib/notion_to_md/version.rb +1 -1
- data/lib/notion_to_md.rb +17 -0
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb94bccdf9dca4374bfaeb42164cce77f3a1963048a96b83a53e238ff9768163
|
4
|
+
data.tar.gz: '039b7d197fc03a6a04ffaf1cb90f3f758dd597a7381a2002da677065d48f2d76'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
"
|
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
|
@@ -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
|
13
|
+
[table_header, table_aligment, table_body].compact.join + newline
|
14
14
|
end
|
15
15
|
|
16
|
-
|
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('|')}
|
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
|
@@ -5,7 +5,7 @@ module NotionToMd
|
|
5
5
|
class Types
|
6
6
|
class << self
|
7
7
|
def paragraph(block)
|
8
|
-
return blank if block
|
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
|
-
|
41
|
-
|
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)
|
data/lib/notion_to_md/blocks.rb
CHANGED
@@ -1,51 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './blocks/
|
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
|
-
|
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
|
data/lib/notion_to_md/page.rb
CHANGED
@@ -29,11 +29,27 @@ module NotionToMd
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def created_time
|
32
|
-
|
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
|
-
|
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
|
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
|
data/lib/notion_to_md/version.rb
CHANGED
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.
|
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-
|
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
|