notion_to_md 2.5.0 → 3.0.0.beta1
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 -82
- data/lib/notion_to_md/blocks/block.rb +47 -15
- data/lib/notion_to_md/blocks/factory.rb +51 -14
- data/lib/notion_to_md/blocks/normalizer.rb +97 -16
- data/lib/notion_to_md/blocks/numbered_list_item_block.rb +1 -3
- data/lib/notion_to_md/blocks/{types.rb → renderer.rb} +21 -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 +85 -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 +68 -93
- data/lib/notion_to_md/support/frontmatter.rb +119 -0
- data/lib/notion_to_md/support/metadata_properties.rb +107 -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 +30 -1
- 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 -64
- data/lib/notion_to_md/blocks.rb +0 -32
- data/lib/notion_to_md/converter.rb +0 -72
- data/lib/notion_to_md/helpers/yaml_sanitizer.rb +0 -17
- data/lib/notion_to_md/helpers.rb +0 -1
- data/lib/notion_to_md/page_property.rb +0 -106
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class NotionToMd
|
4
|
+
module Support
|
5
|
+
# === NotionToMd::Support::Frontmatter
|
6
|
+
#
|
7
|
+
# Mixin module responsible for generating YAML frontmatter for
|
8
|
+
# Notion pages and databases. Combines default metadata (id, title,
|
9
|
+
# timestamps, cover, icon, etc.) with supported custom properties.
|
10
|
+
#
|
11
|
+
# @example Use in a page class
|
12
|
+
# class Page
|
13
|
+
# include NotionToMd::Support::MetadataProperties
|
14
|
+
# include NotionToMd::Support::Frontmatter
|
15
|
+
# attr_reader :metadata
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# page = Page.new(metadata: notion_page_hash)
|
19
|
+
# puts page.frontmatter
|
20
|
+
# # =>
|
21
|
+
# # ---
|
22
|
+
# # id: 1234
|
23
|
+
# # title: "Hello World"
|
24
|
+
# # created_time: 2025-01-01 00:00:00 +0000
|
25
|
+
# # ...
|
26
|
+
# # ---
|
27
|
+
#
|
28
|
+
# @see NotionToMd::Support::YamlSanitizer
|
29
|
+
# @see NotionToMd::MetadataType
|
30
|
+
module Frontmatter
|
31
|
+
include YamlSanitizer
|
32
|
+
|
33
|
+
# Generate the YAML frontmatter string by merging default and custom properties.
|
34
|
+
#
|
35
|
+
# @return [String] YAML frontmatter block, surrounded by `---` markers.
|
36
|
+
def frontmatter
|
37
|
+
@frontmatter ||= <<~CONTENT
|
38
|
+
---
|
39
|
+
#{frontmatter_properties.to_a.map do |k, v|
|
40
|
+
"#{k}: #{v}"
|
41
|
+
end.join("\n")}
|
42
|
+
---
|
43
|
+
CONTENT
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Merge custom and default properties into the final set of frontmatter properties.
|
49
|
+
#
|
50
|
+
# @return [Hash{String => Object}]
|
51
|
+
def frontmatter_properties
|
52
|
+
@frontmatter_properties ||= frontmatter_custom_properties.deep_merge(frontmatter_default_properties)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Retrieve sanitized custom properties.
|
56
|
+
#
|
57
|
+
# @return [Hash{String => Object}]
|
58
|
+
def frontmatter_custom_properties
|
59
|
+
@frontmatter_custom_properties ||= compact_frontmatter_custom_properties
|
60
|
+
end
|
61
|
+
|
62
|
+
# Remove nil/blank values from custom properties.
|
63
|
+
#
|
64
|
+
# @return [Hash{String => Object}]
|
65
|
+
def compact_frontmatter_custom_properties
|
66
|
+
build_frontmatter_custom_properties.reject { |_k, v| v.presence.nil? }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Build supported custom properties based on their type.
|
70
|
+
#
|
71
|
+
# @return [Hash{String => Object}]
|
72
|
+
def build_frontmatter_custom_properties
|
73
|
+
properties.each_with_object({}) do |(name, value), memo|
|
74
|
+
type = value.type
|
75
|
+
next unless valid_custom_property_type?(type)
|
76
|
+
|
77
|
+
key = name.parameterize.underscore
|
78
|
+
memo[key] = build_custom_property(type, value)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Determine whether a custom property type is supported.
|
83
|
+
#
|
84
|
+
# @param type [String, Symbol]
|
85
|
+
# @return [Boolean]
|
86
|
+
def valid_custom_property_type?(type)
|
87
|
+
MetadataType.respond_to?(type.to_sym)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Convert a Notion property into a YAML-safe value.
|
91
|
+
#
|
92
|
+
# @param type [String, Symbol] The property type.
|
93
|
+
# @param value [Object] The raw Notion property value.
|
94
|
+
# @return [Object] The normalized value suitable for YAML.
|
95
|
+
def build_custom_property(type, value)
|
96
|
+
MetadataType.send(type, value)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Default frontmatter properties derived from metadata.
|
100
|
+
#
|
101
|
+
# @return [Hash{String => Object}]
|
102
|
+
def frontmatter_default_properties
|
103
|
+
@frontmatter_default_properties ||= {
|
104
|
+
'id' => id,
|
105
|
+
'title' => escape_frontmatter_value(title),
|
106
|
+
'created_time' => created_time,
|
107
|
+
'cover' => cover,
|
108
|
+
'icon' => icon,
|
109
|
+
'last_edited_time' => last_edited_time,
|
110
|
+
'archived' => archived,
|
111
|
+
'created_by_object' => created_by_object,
|
112
|
+
'created_by_id' => created_by_id,
|
113
|
+
'last_edited_by_object' => last_edited_by_object,
|
114
|
+
'last_edited_by_id' => last_edited_by_id
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class NotionToMd
|
4
|
+
module Support
|
5
|
+
# === NotionToMd::Support::MetadataProperties
|
6
|
+
#
|
7
|
+
# Mixin module providing convenience accessors for Notion page or
|
8
|
+
# database metadata. It extracts common properties (id, title, timestamps,
|
9
|
+
# cover, icon, etc.) from the `metadata` hash returned by the Notion API.
|
10
|
+
#
|
11
|
+
# When included, this module delegates `#properties` to the `metadata`
|
12
|
+
# attribute of the including class.
|
13
|
+
#
|
14
|
+
# @example Include in a model
|
15
|
+
# class Page
|
16
|
+
# include NotionToMd::Support::MetadataProperties
|
17
|
+
# attr_reader :metadata
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# page = Page.new(metadata: notion_page_hash)
|
21
|
+
# page.title # => "My Notion Page"
|
22
|
+
#
|
23
|
+
# @see NotionToMd::MetadataType
|
24
|
+
module MetadataProperties
|
25
|
+
def self.included(base)
|
26
|
+
base.extend Forwardable
|
27
|
+
base.def_delegators :metadata, :properties
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] The Notion record ID.
|
31
|
+
def id
|
32
|
+
metadata[:id]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Extract the page or database title.
|
36
|
+
#
|
37
|
+
# @return [String] Plain text concatenated from `title` property.
|
38
|
+
def title
|
39
|
+
title_list =
|
40
|
+
metadata[:title] ||
|
41
|
+
metadata.dig(:properties, :Name, :title) ||
|
42
|
+
metadata.dig(:properties, :title, :title)
|
43
|
+
|
44
|
+
title_list.inject('') do |acc, slug|
|
45
|
+
acc + slug[:plain_text]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Time] Creation timestamp.
|
50
|
+
def created_time
|
51
|
+
metadata[:created_time]
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String, nil] Object type of creator.
|
55
|
+
def created_by_object
|
56
|
+
metadata.dig(:created_by, :object)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [String, nil] ID of creator.
|
60
|
+
def created_by_id
|
61
|
+
metadata.dig(:created_by, :id)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Time] Last edited timestamp.
|
65
|
+
def last_edited_time
|
66
|
+
metadata[:last_edited_time]
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [String, nil] Object type of last editor.
|
70
|
+
def last_edited_by_object
|
71
|
+
metadata.dig(:last_edited_by, :object)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [String, nil] ID of last editor.
|
75
|
+
def last_edited_by_id
|
76
|
+
metadata.dig(:last_edited_by, :id)
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [String] Public URL of the record.
|
80
|
+
def url
|
81
|
+
metadata[:url]
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [Boolean] Whether the record is archived.
|
85
|
+
def archived
|
86
|
+
metadata[:archived]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Extract the cover image URL, from either external or file source.
|
90
|
+
#
|
91
|
+
# @return [String, nil] Cover URL or nil if not present.
|
92
|
+
def cover
|
93
|
+
MetadataType.external(metadata[:cover]) ||
|
94
|
+
MetadataType.file(metadata[:cover])
|
95
|
+
end
|
96
|
+
|
97
|
+
# Extract the icon (emoji, external, or file).
|
98
|
+
#
|
99
|
+
# @return [String, nil] Icon value or nil if not present.
|
100
|
+
def icon
|
101
|
+
MetadataType.emoji(metadata[:icon]) ||
|
102
|
+
MetadataType.external(metadata[:icon]) ||
|
103
|
+
MetadataType.file(metadata[:icon])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class NotionToMd
|
4
|
+
module Support
|
5
|
+
##
|
6
|
+
# The Pagination module provides a helper for iterating through paginated
|
7
|
+
# Notion API responses.
|
8
|
+
#
|
9
|
+
# Many Notion API endpoints (e.g., `block_children`, `database_query`) return
|
10
|
+
# a limited set of results and include `has_more` and `next_cursor` fields.
|
11
|
+
# This module encapsulates the common logic to repeatedly fetch all pages
|
12
|
+
# until no more results are available.
|
13
|
+
#
|
14
|
+
# @example Paginate through all blocks of a page
|
15
|
+
# include NotionToMd::Support::Pagination
|
16
|
+
#
|
17
|
+
# all_blocks = paginate do |cursor|
|
18
|
+
# notion_client.block_children(
|
19
|
+
# block_id: "xxxx-xxxx",
|
20
|
+
# start_cursor: cursor
|
21
|
+
# )
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# all_blocks.each { |block| puts block.type }
|
25
|
+
#
|
26
|
+
module Pagination
|
27
|
+
##
|
28
|
+
# Iterates through all pages of a paginated Notion API response.
|
29
|
+
#
|
30
|
+
# The given block is called with the current cursor (or `nil` for the
|
31
|
+
# first call). It must return a response object that responds to
|
32
|
+
# `results`, `has_more`, and `next_cursor`.
|
33
|
+
#
|
34
|
+
# @yieldparam [String, nil] cursor the current cursor to start fetching from
|
35
|
+
# @yieldreturn [Object] a response object containing `results`, `has_more`, and `next_cursor`
|
36
|
+
# @return [Array] a flat array of all accumulated results from each page
|
37
|
+
def paginate
|
38
|
+
results = []
|
39
|
+
cursor = nil
|
40
|
+
|
41
|
+
loop do
|
42
|
+
resp = yield(cursor)
|
43
|
+
|
44
|
+
results.concat(resp.results)
|
45
|
+
|
46
|
+
break unless resp.has_more && resp.next_cursor
|
47
|
+
|
48
|
+
cursor = resp.next_cursor
|
49
|
+
end
|
50
|
+
|
51
|
+
results
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class NotionToMd
|
4
|
+
module Support
|
5
|
+
# === NotionToMd::Support::YamlSanitizer
|
6
|
+
#
|
7
|
+
# Provides helpers to sanitize values before inserting them into
|
8
|
+
# YAML frontmatter. This prevents syntax errors when values contain
|
9
|
+
# characters that YAML treats specially (e.g. colons, dashes).
|
10
|
+
#
|
11
|
+
# @example Escape a simple value
|
12
|
+
# include NotionToMd::Support::YamlSanitizer
|
13
|
+
#
|
14
|
+
# escape_frontmatter_value("Hello World")
|
15
|
+
# # => "Hello World"
|
16
|
+
#
|
17
|
+
# @example Escape a value containing a colon
|
18
|
+
# escape_frontmatter_value("Title: Subtitle")
|
19
|
+
# # => "\"Title: Subtitle\""
|
20
|
+
#
|
21
|
+
# @example Escape a value containing dash + space
|
22
|
+
# escape_frontmatter_value("- item")
|
23
|
+
# # => "\"- item\""
|
24
|
+
#
|
25
|
+
module YamlSanitizer
|
26
|
+
# Escape a frontmatter value if it contains a colon (`:`) followed by
|
27
|
+
# a space, or a dash followed by a space (`- `). Wraps the string in
|
28
|
+
# double quotes and escapes any embedded quotes.
|
29
|
+
#
|
30
|
+
# @param value [String] The raw value to escape.
|
31
|
+
# @return [String] A safe string suitable for inclusion in YAML frontmatter.
|
32
|
+
def escape_frontmatter_value(value)
|
33
|
+
if value.match?(/: |-\s/)
|
34
|
+
# Escape embedded double quotes to keep valid YAML
|
35
|
+
"\"#{value.gsub('"', '\"')}\""
|
36
|
+
else
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/notion_to_md/text.rb
CHANGED
@@ -1,12 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class NotionToMd
|
4
|
+
# === NotionToMd::Text
|
5
|
+
#
|
6
|
+
# Utility class to render inline Notion text elements into Markdown.
|
7
|
+
# Used by {NotionToMd::Blocks::Renderer} when processing `rich_text` arrays.
|
8
|
+
#
|
9
|
+
# Supported types:
|
10
|
+
# * `text` → plain text
|
11
|
+
# * `equation` → LaTeX inline math, wrapped as `$`…`$`
|
12
|
+
#
|
13
|
+
# @example Render plain text
|
14
|
+
# NotionToMd::Text.text({ plain_text: "Hello" })
|
15
|
+
# # => "Hello"
|
16
|
+
#
|
17
|
+
# @example Render an inline equation
|
18
|
+
# NotionToMd::Text.equation({ plain_text: "E=mc^2" })
|
19
|
+
# # => "$`E=mc^2`$"
|
20
|
+
#
|
21
|
+
# @see NotionToMd::Blocks::Renderer
|
22
|
+
# @see NotionToMd::TextAnnotation
|
2
23
|
class Text
|
3
24
|
class << self
|
25
|
+
# Render a plain text element.
|
26
|
+
#
|
27
|
+
# @param text [Hash] A Notion text object with key `:plain_text`.
|
28
|
+
# @return [String] The raw text.
|
4
29
|
def text(text)
|
5
30
|
text[:plain_text]
|
6
31
|
end
|
7
32
|
|
33
|
+
# Render an inline equation element.
|
34
|
+
#
|
35
|
+
# @param text [Hash] A Notion text object with key `:plain_text`.
|
36
|
+
# @return [String] Inline math expression wrapped with `$...$`.
|
8
37
|
def equation(text)
|
9
|
-
"
|
38
|
+
"$`#{text[:plain_text]}`$"
|
10
39
|
end
|
11
40
|
end
|
12
41
|
end
|
@@ -1,37 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class NotionToMd
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# *
|
11
|
-
# *
|
12
|
-
|
4
|
+
# === NotionToMd::TextAnnotation
|
5
|
+
#
|
6
|
+
# Utility class to wrap text with Markdown (or HTML) syntax
|
7
|
+
# corresponding to Notion's text annotations.
|
8
|
+
#
|
9
|
+
# Supported annotations:
|
10
|
+
# * `italic` → `*text*`
|
11
|
+
# * `bold` → `**text**`
|
12
|
+
# * `strikethrough` → `~~text~~`
|
13
|
+
# * `underline` → `<u>text</u>` (HTML, since Markdown does not support underline)
|
14
|
+
# * `code` → `` `text` ``
|
15
|
+
# * `color` → (not supported, returns text as-is)
|
16
|
+
#
|
17
|
+
# @example Apply bold and italic
|
18
|
+
# NotionToMd::TextAnnotation.bold("Hello") # => "**Hello**"
|
19
|
+
# NotionToMd::TextAnnotation.italic("World") # => "*World*"
|
20
|
+
#
|
21
|
+
# @example Apply underline
|
22
|
+
# NotionToMd::TextAnnotation.underline("Note") # => "<u>Note</u>"
|
23
|
+
#
|
24
|
+
# @see NotionToMd::Blocks::Renderer
|
13
25
|
class TextAnnotation
|
14
26
|
class << self
|
27
|
+
# Apply italic annotation.
|
28
|
+
# @param text [String]
|
29
|
+
# @return [String]
|
15
30
|
def italic(text)
|
16
31
|
"*#{text}*"
|
17
32
|
end
|
18
33
|
|
34
|
+
# Apply bold annotation.
|
35
|
+
# @param text [String]
|
36
|
+
# @return [String]
|
19
37
|
def bold(text)
|
20
38
|
"**#{text}**"
|
21
39
|
end
|
22
40
|
|
41
|
+
# Apply strikethrough annotation.
|
42
|
+
# @param text [String]
|
43
|
+
# @return [String]
|
23
44
|
def strikethrough(text)
|
24
45
|
"~~#{text}~~"
|
25
46
|
end
|
26
47
|
|
48
|
+
# Apply underline annotation (HTML).
|
49
|
+
# @param text [String]
|
50
|
+
# @return [String]
|
27
51
|
def underline(text)
|
28
52
|
"<u>#{text}</u>"
|
29
53
|
end
|
30
54
|
|
55
|
+
# Apply inline code annotation.
|
56
|
+
# @param text [String]
|
57
|
+
# @return [String]
|
31
58
|
def code(text)
|
32
59
|
"`#{text}`"
|
33
60
|
end
|
34
61
|
|
62
|
+
# Color annotation is not supported in Markdown.
|
63
|
+
# Currently returns text unchanged.
|
64
|
+
#
|
65
|
+
# @param text [String]
|
66
|
+
# @return [String]
|
35
67
|
def color(text)
|
36
68
|
text
|
37
69
|
end
|
data/lib/notion_to_md/version.rb
CHANGED
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
|