notion_to_md 0.1.0 → 0.2.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: 77ebe548eec487347104eabbac6911836cef0ec6e5ea350cb9a376ef8e07ce50
4
- data.tar.gz: b2fd0700b53683daa6e59a729418139bbdee41da8184dad57eff0f2c17578dc7
3
+ metadata.gz: d326983d99843871779f5331bab84d734bc01c21aa90b4da0cc76f1dd092c95e
4
+ data.tar.gz: 4b6a34aebbe07df627d956e9918606385e5d3952c56522ee66f3e331f8522d24
5
5
  SHA512:
6
- metadata.gz: e7f09feec62553d76c72e670aa4fa05d02e98f19e74352237c8c42a255960570f77ae530b3196be24a054fa8a55f744f0b0b96dfbfb1c5e7d06f71b1423bcdf6
7
- data.tar.gz: '09a041dab71e1fea3796ca9193c6a5fdf385de1d7fc212373f2e7cec086568935c72171ba900c90001907fdd4e1667e819b69c28740c2e5fa18a4b17821facb3'
6
+ metadata.gz: 5e4990d98adf9eaff1dafc48285430b788de0bf4088b95ecd5f6c970fc850e015e9f148c79f0603647902b96b26465b01f88e9d86133472cc154a581c6f2e907
7
+ data.tar.gz: bb63c2a623265a153e7300ca9389bf1e75773373f8221eed41e4b7a11b33f801c26d8d033f3038ac93ead0586257e7874773c9a490de436a30ea79c4e5d5ca08
data/README.md CHANGED
@@ -40,7 +40,60 @@ md = notion_converter.convert
40
40
 
41
41
  And that's all. The `md` is a string variable containing the notion page formatted in markdown.
42
42
 
43
+
44
+ ### Front matter
45
+
46
+ From version 0.2.0, notion_to_md supports front matter in markdown files.
47
+
48
+ By default, the front matter section is not included to the document. To do so, provide the `:frontmatter` option set to `true` to `convert` method.
49
+
50
+ ```ruby
51
+ NotionToMd::Converter.new(page_id: 'b91d5...').convert(frontmatter: tue)
52
+ ```
53
+
54
+ Default notion properties are page `id`, `title`, `created_time`, `last_edited_time`, `icon`, `archived` and `cover`.
55
+
56
+ ```yml
57
+ ---
58
+ id: e42383cd-4975-4897-b967-ce453760499f
59
+ title: An amazing post
60
+ cover: https://img.bank.sh/an_image.jpg
61
+ created_time: 2022-01-23T12:31:00.000Z
62
+ last_edited_time: 2022-01-23T12:31:00.000Z
63
+ icon: 💥
64
+ archived: false
65
+ ---
66
+ ```
67
+
68
+ In addition to default properties, custom properties are also supported.
69
+ Custom properties name is [parameterized](https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize) and [underscorized](https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore) before added to front matter.
70
+ For example, two properties named `Multiple Options` and `Tags` will be transformed to `multiple_options` and `tags`, respectively.
71
+
72
+ ```yml
73
+ ---
74
+ tags: tag1, tag2, tag3
75
+ multiple_options: option1, option2
76
+ ---
77
+ ```
78
+
79
+ The supported property types are:
80
+
81
+ * `number`
82
+ * `select`
83
+ * `multi_select`
84
+ * `date`
85
+ * `people`
86
+ * `files`
87
+ * `checkbox`
88
+ * `url`
89
+ * `email`
90
+ * `phone_number`
91
+
92
+ `rich_text` as advanced types like `formula`, `relation` and `rollup` are not supported.
93
+
94
+ Check notion documentation about [property values](https://developers.notion.com/reference/property-value-object#all-property-values) to know more.
95
+
43
96
  ## Test
44
97
  ```bash
45
- $ ruby -Ilib:test test/notion_to_md/converter_spec.rb
98
+ rspec
46
99
  ```
@@ -9,7 +9,16 @@ module NotionToMd
9
9
  @page_id = page_id
10
10
  end
11
11
 
12
- def convert
12
+ def convert(frontmatter: false)
13
+ <<~MD
14
+ #{parse_frontmatter if frontmatter}
15
+ #{parse_content}
16
+ MD
17
+ end
18
+
19
+ private
20
+
21
+ def parse_content
13
22
  md = page_blocks[:results].map do |block|
14
23
  next Block.blank if block[:type] == 'paragraph' && block.dig(:paragraph, :text).empty?
15
24
 
@@ -26,7 +35,19 @@ module NotionToMd
26
35
  md.compact.join("\n\n")
27
36
  end
28
37
 
29
- private
38
+ def parse_frontmatter
39
+ notion_page = Page.new(page: page)
40
+ frontmatter = notion_page.props.to_a.map { |k, v| "#{k}: #{v}" }.join("\n")
41
+ <<~CONTENT
42
+ ---
43
+ #{frontmatter}
44
+ ---
45
+ CONTENT
46
+ end
47
+
48
+ def page
49
+ @page ||= @notion.page(id: page_id)
50
+ end
30
51
 
31
52
  def page_blocks
32
53
  @page_blocks ||= @notion.block_children(id: page_id)
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotionToMd
4
+ class Page
5
+ attr_reader :page
6
+
7
+ def initialize(page:)
8
+ @page = page
9
+ end
10
+
11
+ def title
12
+ page.dig(:properties, :Name, :title).inject('') do |acc, slug|
13
+ acc + slug[:plain_text]
14
+ end
15
+ end
16
+
17
+ def cover
18
+ page.dig(:cover, :external, :url)
19
+ end
20
+
21
+ def icon
22
+ page.dig(:icon, :emoji)
23
+ end
24
+
25
+ def id
26
+ page[:id]
27
+ end
28
+
29
+ def created_time
30
+ DateTime.parse(page['created_time'])
31
+ end
32
+
33
+ def last_edited_time
34
+ DateTime.parse(page['last_edited_time'])
35
+ end
36
+
37
+ def url
38
+ page[:url]
39
+ end
40
+
41
+ def archived
42
+ page[:archived]
43
+ end
44
+
45
+ def props
46
+ @props ||= custom_props.deep_merge(default_props)
47
+ end
48
+
49
+ def custom_props
50
+ @custom_props ||= page.properties.each_with_object({}) do |prop, memo|
51
+ name = prop.first
52
+ value = prop.last # Notion::Messages::Message
53
+ type = value.type
54
+
55
+ next memo unless CustomProperty.respond_to?(type.to_sym)
56
+
57
+ memo[name.parameterize.underscore] = CustomProperty.send(type, value)
58
+ end.reject { |_k, v| v.presence.nil? }
59
+ end
60
+
61
+ def default_props
62
+ @default_props ||= {
63
+ 'id' => id,
64
+ 'title' => title,
65
+ 'created_time' => created_time,
66
+ 'cover' => cover,
67
+ 'icon' => icon,
68
+ 'last_edited_time' => last_edited_time,
69
+ 'archived' => archived
70
+ }
71
+ end
72
+
73
+ class CustomProperty
74
+ class << self
75
+ def multi_select(prop)
76
+ multi_select = prop.multi_select.map(&:name).join(', ')
77
+ "[#{multi_select}]"
78
+ end
79
+
80
+ def select(prop)
81
+ prop['select'].name
82
+ end
83
+
84
+ def people(prop)
85
+ people = prop.people.map(&:name).join(', ')
86
+ "[#{people}]"
87
+ end
88
+
89
+ def files(prop)
90
+ files = prop.files.map { |f| "\"#{f.file.url}\"" }.join(', ')
91
+ "[#{files}]"
92
+ end
93
+
94
+ def phone_number(prop)
95
+ prop.phone_number
96
+ end
97
+
98
+ def number(prop)
99
+ prop.number
100
+ end
101
+
102
+ def email(prop)
103
+ prop.email
104
+ end
105
+
106
+ def checkbox(prop)
107
+ prop.checkbox.to_s
108
+ end
109
+
110
+ # date type properties not supported:
111
+ # - end
112
+ # - time_zone
113
+ def date(prop)
114
+ prop.date.start
115
+ end
116
+
117
+ def url(prop)
118
+ prop.url
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NotionToMd
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/notion_to_md.rb CHANGED
@@ -2,9 +2,12 @@
2
2
 
3
3
  require 'notion'
4
4
  require 'logger'
5
+ require 'active_support/inflector'
6
+ require 'active_support/core_ext/object/blank'
5
7
  require_relative './notion_to_md/version'
6
8
  require_relative './notion_to_md/converter'
7
9
  require_relative './notion_to_md/logger'
10
+ require_relative './notion_to_md/page'
8
11
  require_relative './notion_to_md/block'
9
12
  require_relative './notion_to_md/text'
10
13
  require_relative './notion_to_md/text_annotation'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: notion_to_md
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.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: 2022-02-13 00:00:00.000000000 Z
11
+ date: 2022-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: notion-ruby-client
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -77,6 +91,7 @@ files:
77
91
  - lib/notion_to_md/block.rb
78
92
  - lib/notion_to_md/converter.rb
79
93
  - lib/notion_to_md/logger.rb
94
+ - lib/notion_to_md/page.rb
80
95
  - lib/notion_to_md/text.rb
81
96
  - lib/notion_to_md/text_annotation.rb
82
97
  - lib/notion_to_md/version.rb