notion_to_md 2.5.1 → 3.0.0.beta2
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 +94 -83
- data/lib/notion_to_md/blocks/block.rb +45 -16
- data/lib/notion_to_md/blocks/factory.rb +49 -17
- data/lib/notion_to_md/blocks/normalizer.rb +82 -14
- data/lib/notion_to_md/blocks/numbered_list_item_block.rb +1 -3
- data/lib/notion_to_md/blocks/{types.rb → renderer.rb} +17 -1
- data/lib/notion_to_md/blocks/to_do_list_item_block.rb +0 -2
- data/lib/notion_to_md/database/builder.rb +107 -0
- data/lib/notion_to_md/database.rb +114 -0
- data/lib/notion_to_md/logger.rb +1 -0
- data/lib/notion_to_md/metadata_type.rb +170 -0
- data/lib/notion_to_md/page/builder.rb +112 -0
- data/lib/notion_to_md/page.rb +80 -106
- data/lib/notion_to_md/support/frontmatter.rb +119 -0
- data/lib/notion_to_md/support/metadata_properties.rb +102 -0
- data/lib/notion_to_md/support/pagination.rb +55 -0
- data/lib/notion_to_md/support/yaml_sanitizer.rb +42 -0
- data/lib/notion_to_md/text.rb +27 -0
- data/lib/notion_to_md/text_annotation.rb +41 -9
- data/lib/notion_to_md/version.rb +1 -1
- data/lib/notion_to_md.rb +65 -38
- metadata +24 -103
- data/lib/notion_to_md/blocks/builder.rb +0 -67
- data/lib/notion_to_md/blocks.rb +0 -35
- data/lib/notion_to_md/converter.rb +0 -72
- data/lib/notion_to_md/helpers/yaml_sanitizer.rb +0 -19
- data/lib/notion_to_md/helpers.rb +0 -3
- data/lib/notion_to_md/page_property.rb +0 -106
data/lib/notion_to_md.rb
CHANGED
@@ -4,49 +4,76 @@ require 'notion'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'active_support/inflector'
|
6
6
|
require 'active_support/core_ext/object/blank'
|
7
|
-
require '
|
8
|
-
require_relative './notion_to_md/helpers'
|
9
|
-
require_relative './notion_to_md/version'
|
10
|
-
require_relative './notion_to_md/converter'
|
11
|
-
require_relative './notion_to_md/logger'
|
12
|
-
require_relative './notion_to_md/page_property'
|
13
|
-
require_relative './notion_to_md/page'
|
14
|
-
require_relative './notion_to_md/blocks'
|
15
|
-
require_relative './notion_to_md/text'
|
16
|
-
require_relative './notion_to_md/text_annotation'
|
17
|
-
|
18
|
-
# The NotionToMd class allows to transform notion pages to markdown documents.
|
19
|
-
class NotionToMd
|
20
|
-
include Callee
|
21
|
-
|
22
|
-
attr_reader :page_id, :token, :frontmatter
|
7
|
+
require 'zeitwerk'
|
23
8
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@frontmatter = frontmatter
|
28
|
-
end
|
9
|
+
# Load the NotionToMd classes using Zeitwerk
|
10
|
+
loader = Zeitwerk::Loader.for_gem
|
11
|
+
loader.setup
|
29
12
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
13
|
+
##
|
14
|
+
# The {NotionToMd} class is the main entry point for converting
|
15
|
+
# Notion pages and databases into Markdown documents.
|
16
|
+
#
|
17
|
+
# It provides a single class method {.call} (aliased as {.convert})
|
18
|
+
# that accepts a Notion resource type (`:page` or `:database`), an ID,
|
19
|
+
# and options to control conversion.
|
20
|
+
#
|
21
|
+
# @example Convert a single Notion page to Markdown
|
22
|
+
# markdown = NotionToMd.call(:page, id: "xxxx-xxxx", token: "secret_token")
|
23
|
+
#
|
24
|
+
# @example Convert a Notion database to Markdown and yield the result
|
25
|
+
# NotionToMd.convert(:database, id: "xxxx-xxxx").each_with_index do |md, index|
|
26
|
+
# File.write("output_#{index}.md", md)
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
class NotionToMd
|
30
|
+
##
|
31
|
+
# Supported resource types for conversion.
|
40
32
|
#
|
41
|
-
|
42
|
-
|
43
|
-
|
33
|
+
# @return [Hash{Symbol => Symbol}] mapping of friendly keys to types
|
34
|
+
TYPES = { database: :database, page: :page }.freeze
|
35
|
+
|
36
|
+
class << self
|
37
|
+
##
|
38
|
+
# Convert a Notion resource (page or database) to Markdown.
|
39
|
+
#
|
40
|
+
# @param type [Symbol] the type of Notion resource (`:page` or `:database`).
|
41
|
+
# @param id [String] the Notion page or database ID.
|
42
|
+
# @param token [String, nil] the Notion API token.
|
43
|
+
# If omitted, defaults to `ENV['NOTION_TOKEN']`.
|
44
|
+
# @param frontmatter [Boolean] whether to include YAML frontmatter
|
45
|
+
# in the generated Markdown.
|
46
|
+
#
|
47
|
+
# @yield [md] optional block to handle the generated Markdown.
|
48
|
+
# @yieldparam md [String] the Markdown output.
|
49
|
+
#
|
50
|
+
# @return [String] the Markdown representation of the Notion resource.
|
51
|
+
#
|
52
|
+
# @raise [RuntimeError] if the given +type+ is not supported.
|
53
|
+
#
|
54
|
+
def call(type, id:, token: nil, frontmatter: false)
|
55
|
+
raise "#{type} is not supported. Use :database or :page" unless TYPES.values.include?(type)
|
56
|
+
|
57
|
+
notion_client = Notion::Client.new(token: token || ENV.fetch('NOTION_TOKEN', nil))
|
58
|
+
md = case type
|
59
|
+
when TYPES[:database]
|
60
|
+
Database.call(id: id, notion_client: notion_client, frontmatter: frontmatter).to_md
|
61
|
+
when TYPES[:page]
|
62
|
+
Page.call(id: id, notion_client: notion_client, frontmatter: frontmatter).to_md
|
63
|
+
end
|
44
64
|
|
45
|
-
|
46
|
-
md = self.class.convert(page_id: page_id, token: token, frontmatter: frontmatter)
|
65
|
+
yield md if block_given?
|
47
66
|
|
48
|
-
|
67
|
+
md
|
68
|
+
end
|
49
69
|
|
50
|
-
|
70
|
+
##
|
71
|
+
# Alias for {.call}.
|
72
|
+
#
|
73
|
+
# @see .call
|
74
|
+
#
|
75
|
+
def convert(type, id:, token: nil, frontmatter: false, &block)
|
76
|
+
call(type, id: id, token: token, frontmatter: frontmatter, &block)
|
77
|
+
end
|
51
78
|
end
|
52
79
|
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:
|
4
|
+
version: 3.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Enrique Arias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '7'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: callee
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.3.6
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.3.6
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: notion-ruby-client
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,89 +39,19 @@ dependencies:
|
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '1'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop
|
42
|
+
name: zeitwerk
|
85
43
|
requirement: !ruby/object:Gem::Requirement
|
86
44
|
requirements:
|
87
|
-
- - "
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop-rspec
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov
|
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'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: vcr
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
45
|
+
- - "~>"
|
130
46
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
132
|
-
type: :
|
47
|
+
version: '2.6'
|
48
|
+
type: :runtime
|
133
49
|
prerelease: false
|
134
50
|
version_requirements: !ruby/object:Gem::Requirement
|
135
51
|
requirements:
|
136
|
-
- - "
|
52
|
+
- - "~>"
|
137
53
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
54
|
+
version: '2.6'
|
139
55
|
description: Notion Markdown Exporter in Ruby
|
140
56
|
email: emoriarty81@gmail.com
|
141
57
|
executables: []
|
@@ -144,33 +60,38 @@ extra_rdoc_files: []
|
|
144
60
|
files:
|
145
61
|
- README.md
|
146
62
|
- lib/notion_to_md.rb
|
147
|
-
- lib/notion_to_md/blocks.rb
|
148
63
|
- lib/notion_to_md/blocks/block.rb
|
149
|
-
- lib/notion_to_md/blocks/builder.rb
|
150
64
|
- lib/notion_to_md/blocks/bulleted_list_block.rb
|
151
65
|
- lib/notion_to_md/blocks/bulleted_list_item_block.rb
|
152
66
|
- lib/notion_to_md/blocks/factory.rb
|
153
67
|
- lib/notion_to_md/blocks/normalizer.rb
|
154
68
|
- lib/notion_to_md/blocks/numbered_list_block.rb
|
155
69
|
- lib/notion_to_md/blocks/numbered_list_item_block.rb
|
70
|
+
- lib/notion_to_md/blocks/renderer.rb
|
156
71
|
- lib/notion_to_md/blocks/table_block.rb
|
157
72
|
- lib/notion_to_md/blocks/table_row_block.rb
|
158
73
|
- lib/notion_to_md/blocks/to_do_list_block.rb
|
159
74
|
- lib/notion_to_md/blocks/to_do_list_item_block.rb
|
160
|
-
- lib/notion_to_md/
|
161
|
-
- lib/notion_to_md/
|
162
|
-
- lib/notion_to_md/helpers.rb
|
163
|
-
- lib/notion_to_md/helpers/yaml_sanitizer.rb
|
75
|
+
- lib/notion_to_md/database.rb
|
76
|
+
- lib/notion_to_md/database/builder.rb
|
164
77
|
- lib/notion_to_md/logger.rb
|
78
|
+
- lib/notion_to_md/metadata_type.rb
|
165
79
|
- lib/notion_to_md/page.rb
|
166
|
-
- lib/notion_to_md/
|
80
|
+
- lib/notion_to_md/page/builder.rb
|
81
|
+
- lib/notion_to_md/support/frontmatter.rb
|
82
|
+
- lib/notion_to_md/support/metadata_properties.rb
|
83
|
+
- lib/notion_to_md/support/pagination.rb
|
84
|
+
- lib/notion_to_md/support/yaml_sanitizer.rb
|
167
85
|
- lib/notion_to_md/text.rb
|
168
86
|
- lib/notion_to_md/text_annotation.rb
|
169
87
|
- lib/notion_to_md/version.rb
|
170
88
|
homepage: https://github.com/emoriarty/notion_to_md
|
171
89
|
licenses:
|
172
90
|
- MIT
|
173
|
-
metadata:
|
91
|
+
metadata:
|
92
|
+
rubygems_mfa_required: 'true'
|
93
|
+
status: beta
|
94
|
+
source_code_uri: https://github.com/emoriarty/notion_to_md
|
174
95
|
post_install_message:
|
175
96
|
rdoc_options: []
|
176
97
|
require_paths:
|
@@ -179,12 +100,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
100
|
requirements:
|
180
101
|
- - ">="
|
181
102
|
- !ruby/object:Gem::Version
|
182
|
-
version:
|
103
|
+
version: 2.7.0
|
183
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
105
|
requirements:
|
185
|
-
- - "
|
106
|
+
- - ">"
|
186
107
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
108
|
+
version: 1.3.1
|
188
109
|
requirements: []
|
189
110
|
rubygems_version: 3.1.6
|
190
111
|
signing_key:
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class NotionToMd
|
4
|
-
module Blocks
|
5
|
-
# === NotionToMd::Blocks::Builder
|
6
|
-
#
|
7
|
-
# This class is responsible for building a tree of blocks from the Notion API.
|
8
|
-
class Builder
|
9
|
-
##
|
10
|
-
# Array containing the block types allowed to have nested blocks (children).
|
11
|
-
BLOCKS_WITH_PERMITTED_CHILDREN = %i[
|
12
|
-
bulleted_list_item
|
13
|
-
numbered_list_item
|
14
|
-
paragraph
|
15
|
-
to_do
|
16
|
-
table
|
17
|
-
].freeze
|
18
|
-
|
19
|
-
# === Parameters
|
20
|
-
# block::
|
21
|
-
# A {Notion::Messages::Message}[https://github.com/orbit-love/notion-ruby-client/blob/main/lib/notion/messages/message.rb] object.
|
22
|
-
#
|
23
|
-
# === Returns
|
24
|
-
# A boolean indicating if the blocked passed in
|
25
|
-
# is permitted to have children based on its type.
|
26
|
-
#
|
27
|
-
def self.permitted_children_for?(block:)
|
28
|
-
BLOCKS_WITH_PERMITTED_CHILDREN.include?(block.type.to_sym) && block.has_children
|
29
|
-
end
|
30
|
-
|
31
|
-
attr_reader :block_id, :fetch_blocks
|
32
|
-
|
33
|
-
# === Parameters
|
34
|
-
# block_id::
|
35
|
-
# A string representing a notion block id .
|
36
|
-
# fetch_blocks::
|
37
|
-
# A block that fetches the blocks from the Notion API.
|
38
|
-
#
|
39
|
-
# === Returns
|
40
|
-
# An array of NotionToMd::Blocks::Block.
|
41
|
-
#
|
42
|
-
def initialize(block_id:, &fetch_blocks)
|
43
|
-
@block_id = block_id
|
44
|
-
@fetch_blocks = fetch_blocks
|
45
|
-
end
|
46
|
-
|
47
|
-
# === Parameters
|
48
|
-
#
|
49
|
-
# === Returns
|
50
|
-
# An array of NotionToMd::Blocks::Block.
|
51
|
-
#
|
52
|
-
def build
|
53
|
-
notion_messages = fetch_blocks.call(block_id)
|
54
|
-
blocks = notion_messages.results.map do |block|
|
55
|
-
children = if Builder.permitted_children_for?(block: block)
|
56
|
-
Builder.new(block_id: block.id, &fetch_blocks).build
|
57
|
-
else
|
58
|
-
[]
|
59
|
-
end
|
60
|
-
Factory.build(block: block, children: children)
|
61
|
-
end
|
62
|
-
|
63
|
-
Normalizer.normalize(blocks: blocks)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
data/lib/notion_to_md/blocks.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './blocks/builder'
|
4
|
-
require_relative './blocks/normalizer'
|
5
|
-
require_relative './blocks/factory'
|
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'
|
16
|
-
|
17
|
-
class NotionToMd
|
18
|
-
# === NotionToMd::Blocks
|
19
|
-
#
|
20
|
-
# This module is responsible for building Notion blocks.
|
21
|
-
module Blocks
|
22
|
-
# === Parameters
|
23
|
-
# block_id::
|
24
|
-
# A string representing a notion block id .
|
25
|
-
# fetch_blocks::
|
26
|
-
# A block that fetches the blocks from the Notion API.
|
27
|
-
#
|
28
|
-
# === Returns
|
29
|
-
# An array of NotionToMd::Blocks::Block.
|
30
|
-
#
|
31
|
-
def self.build(block_id:, &fetch_blocks)
|
32
|
-
Builder.new(block_id: block_id, &fetch_blocks).build
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class NotionToMd
|
4
|
-
# The Converter class allows to transform notion pages to markdown documents.
|
5
|
-
# Just create a new Converter instance by providing the page_id:
|
6
|
-
# page_converter = NotionToMd::Converter.new(page_id: '9dc17c9c9d2e469dbbf0f9648f3288d3')
|
7
|
-
# Then, call for convert to obtain the markdown document:
|
8
|
-
# page_converter.convert
|
9
|
-
class Converter
|
10
|
-
include Callee
|
11
|
-
|
12
|
-
attr_reader :page_id, :frontmatter
|
13
|
-
|
14
|
-
# === Parameters
|
15
|
-
# page_id::
|
16
|
-
# A string representing the notion page id.
|
17
|
-
# token::
|
18
|
-
# The notion API secret token. The token can replaced by the environment variable NOTION_TOKEN.
|
19
|
-
#
|
20
|
-
# === Returns
|
21
|
-
# A NotionToMd::Converter object.
|
22
|
-
#
|
23
|
-
def initialize(page_id:, token: nil, frontmatter: false)
|
24
|
-
@notion = Notion::Client.new(token: token || ENV['NOTION_TOKEN'])
|
25
|
-
@page_id = page_id
|
26
|
-
@frontmatter = frontmatter
|
27
|
-
end
|
28
|
-
|
29
|
-
# === Parameters
|
30
|
-
# frontmatter::
|
31
|
-
# A boolean value that indicates whether the front matter block is included in the markdown document.
|
32
|
-
#
|
33
|
-
# === Returns
|
34
|
-
# The string that represent the markdown document.
|
35
|
-
#
|
36
|
-
def convert(frontmatter: false)
|
37
|
-
md_page = Page.new(page: page, blocks: page_blocks)
|
38
|
-
<<~MD
|
39
|
-
#{md_page.frontmatter if frontmatter}
|
40
|
-
#{md_page.body}
|
41
|
-
MD
|
42
|
-
end
|
43
|
-
|
44
|
-
def call
|
45
|
-
md = convert frontmatter: frontmatter
|
46
|
-
|
47
|
-
yield md if block_given?
|
48
|
-
|
49
|
-
md
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def page
|
55
|
-
@page ||= @notion.page(page_id: page_id)
|
56
|
-
end
|
57
|
-
|
58
|
-
def page_blocks
|
59
|
-
@page_blocks ||= build_blocks(block_id: page_id)
|
60
|
-
end
|
61
|
-
|
62
|
-
def build_blocks(block_id:)
|
63
|
-
Blocks.build(block_id: block_id) do |nested_block_id|
|
64
|
-
fetch_blocks(block_id: nested_block_id)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def fetch_blocks(block_id:)
|
69
|
-
@notion.block_children(block_id: block_id)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class NotionToMd
|
4
|
-
module Helpers
|
5
|
-
module YamlSanitizer
|
6
|
-
# Escape the frontmatter value if it contains a colon or a dash followed by a space
|
7
|
-
# @param value [String] the value to escape
|
8
|
-
# @return [String] the escaped value
|
9
|
-
def escape_frontmatter_value(value)
|
10
|
-
if value.match?(/: |-\s/)
|
11
|
-
# Escape the double quotes inside the string
|
12
|
-
"\"#{value.gsub('"', '\"')}\""
|
13
|
-
else
|
14
|
-
value
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/lib/notion_to_md/helpers.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class NotionToMd
|
4
|
-
class PageProperty
|
5
|
-
class << self
|
6
|
-
include Helpers::YamlSanitizer
|
7
|
-
|
8
|
-
def file(prop)
|
9
|
-
prop.dig(:file, :url)
|
10
|
-
rescue NoMethodError
|
11
|
-
nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def external(prop)
|
15
|
-
prop.dig(:external, :url)
|
16
|
-
rescue NoMethodError
|
17
|
-
nil
|
18
|
-
end
|
19
|
-
|
20
|
-
def emoji(prop)
|
21
|
-
prop[:emoji]
|
22
|
-
rescue NoMethodError
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
|
26
|
-
def multi_select(prop)
|
27
|
-
prop[:multi_select].map { |sel| sel[:name] }
|
28
|
-
rescue NoMethodError
|
29
|
-
nil
|
30
|
-
end
|
31
|
-
|
32
|
-
def select(prop)
|
33
|
-
escape_frontmatter_value(prop.dig(:select, :name))
|
34
|
-
rescue NoMethodError
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def people(prop)
|
39
|
-
prop[:people].map { |sel| sel[:name] }
|
40
|
-
rescue NoMethodError
|
41
|
-
nil
|
42
|
-
end
|
43
|
-
|
44
|
-
def files(prop)
|
45
|
-
prop[:files].map { |f| file(f) || external(f) }
|
46
|
-
rescue NoMethodError
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def phone_number(prop)
|
51
|
-
prop[:phone_number]
|
52
|
-
rescue NoMethodError
|
53
|
-
nil
|
54
|
-
end
|
55
|
-
|
56
|
-
def number(prop)
|
57
|
-
prop[:number]
|
58
|
-
rescue NoMethodError
|
59
|
-
nil
|
60
|
-
end
|
61
|
-
|
62
|
-
def email(prop)
|
63
|
-
prop[:email]
|
64
|
-
rescue NoMethodError
|
65
|
-
nil
|
66
|
-
end
|
67
|
-
|
68
|
-
def checkbox(prop)
|
69
|
-
prop[:checkbox]&.to_s
|
70
|
-
rescue NoMethodError
|
71
|
-
nil
|
72
|
-
end
|
73
|
-
|
74
|
-
# date type properties not supported:
|
75
|
-
# - end
|
76
|
-
# - time_zone
|
77
|
-
def date(prop)
|
78
|
-
date = prop.dig(:date, :start)
|
79
|
-
|
80
|
-
case date
|
81
|
-
when Date
|
82
|
-
date.to_time
|
83
|
-
when String
|
84
|
-
Time.parse(date)
|
85
|
-
else
|
86
|
-
date # Time or nil
|
87
|
-
end
|
88
|
-
rescue NoMethodError
|
89
|
-
nil
|
90
|
-
end
|
91
|
-
|
92
|
-
def url(prop)
|
93
|
-
prop[:url]
|
94
|
-
rescue NoMethodError
|
95
|
-
nil
|
96
|
-
end
|
97
|
-
|
98
|
-
def rich_text(prop)
|
99
|
-
text = prop[:rich_text].map { |text| text[:plain_text] }.join
|
100
|
-
text.blank? ? nil : escape_frontmatter_value(text)
|
101
|
-
rescue NoMethodError
|
102
|
-
nil
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|