md_to_notion 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9bd284bd98dbb6ec740f9f0cd2deebb57798ea9e0c0ab0793ae7bbe60af54fab
4
+ data.tar.gz: 3b561a30fcf2b69cdcce42ae2520a02bfccb3b275752d7e3afea4b8b2714fffe
5
+ SHA512:
6
+ metadata.gz: 17f5672cd71bf21d6957cd2e1b9e36730e41ba2b2bafe5052a3a4a6bfa74557e74c5cbe90110f55673558425e11c8e7773c58bf9c260d2436eb5b0d0296e3d6d
7
+ data.tar.gz: 57bdcf190ded5abda03ecab6f5cc3d6562c6d4f8c7155722cf55147c5284467303f60b4fdcbddfc28bfd1c8dd12a8a5e578dc98f716e407fd1d85e64cf70c8ba
data/.eslintrc.json ADDED
@@ -0,0 +1 @@
1
+ {}
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in md_to_notion.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rubocop", "~> 1.21"
13
+
14
+ gem "pry"
data/Gemfile.lock ADDED
@@ -0,0 +1,64 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ md-to-notion (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.2)
10
+ coderay (1.1.3)
11
+ diff-lcs (1.5.0)
12
+ json (2.6.3)
13
+ method_source (1.0.0)
14
+ parallel (1.22.1)
15
+ parser (3.2.0.0)
16
+ ast (~> 2.4.1)
17
+ pry (0.14.1)
18
+ coderay (~> 1.1)
19
+ method_source (~> 1.0)
20
+ rainbow (3.1.1)
21
+ rake (13.0.6)
22
+ regexp_parser (2.6.1)
23
+ rexml (3.2.5)
24
+ rspec (3.12.0)
25
+ rspec-core (~> 3.12.0)
26
+ rspec-expectations (~> 3.12.0)
27
+ rspec-mocks (~> 3.12.0)
28
+ rspec-core (3.12.0)
29
+ rspec-support (~> 3.12.0)
30
+ rspec-expectations (3.12.1)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.12.0)
33
+ rspec-mocks (3.12.1)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.12.0)
36
+ rspec-support (3.12.0)
37
+ rubocop (1.42.0)
38
+ json (~> 2.3)
39
+ parallel (~> 1.10)
40
+ parser (>= 3.1.2.1)
41
+ rainbow (>= 2.2.2, < 4.0)
42
+ regexp_parser (>= 1.8, < 3.0)
43
+ rexml (>= 3.2.5, < 4.0)
44
+ rubocop-ast (>= 1.24.1, < 2.0)
45
+ ruby-progressbar (~> 1.7)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.24.1)
48
+ parser (>= 3.1.1.0)
49
+ ruby-progressbar (1.11.0)
50
+ unicode-display_width (2.4.2)
51
+
52
+ PLATFORMS
53
+ arm64-darwin-20
54
+ x86_64-linux
55
+
56
+ DEPENDENCIES
57
+ md-to-notion!
58
+ pry
59
+ rake (~> 13.0)
60
+ rspec (~> 3.0)
61
+ rubocop (~> 1.21)
62
+
63
+ BUNDLED WITH
64
+ 2.3.26
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 rieg-ec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # MdToNotion: Markdown to Notion
2
+
3
+ Dependency-free gem to convert markdown and GitHub flavoured Markdown to Notion API blocks and richtext.
4
+
5
+ NOTE: this is a work in progress. It works for simple markdown, but has not been tested with all markdown syntax.
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+
11
+ $ bundle add md_to_notion
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ $ gem install md_to_notion
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ MdToNotion::Parser.markdown_to_notion_blocks(
21
+ "# heading 1"
22
+ )
23
+ ```
24
+
25
+ <details>
26
+ <summary>result</summary>
27
+
28
+ ```json
29
+ {
30
+ "type": "heading_1",
31
+ "heading_1": {
32
+ "rich_text": [
33
+ {
34
+ "type": "text",
35
+ "text": {
36
+ "content": "heading 1",
37
+ "link": null
38
+ },
39
+ "annotations": {
40
+ "bold": false,
41
+ "italic": false,
42
+ "strikethrough": false,
43
+ "underline": false,
44
+ "code": false
45
+ },
46
+ "href": null
47
+ }
48
+ ]
49
+ }
50
+ }
51
+ ```
52
+ </details>
53
+
54
+ <br>
55
+
56
+ ```ruby
57
+ MdToNotion::Parser.markdown_to_notion_blocks(
58
+ "> quote with *italic"
59
+ )
60
+ ```
61
+ <details>
62
+ <summary>result</summary>
63
+
64
+ ```json
65
+ {
66
+ "type": "quote",
67
+ "quote": {
68
+ "rich_text": [
69
+ {
70
+ "type": "text",
71
+ "text": {
72
+ "content": "quote with ",
73
+ "link": null
74
+ },
75
+ "annotations": {
76
+ "bold": false,
77
+ "italic": false,
78
+ "strikethrough": false,
79
+ "underline": false,
80
+ "code": false
81
+ },
82
+ "href": null
83
+ },
84
+ {
85
+ "type": "text",
86
+ "text": {
87
+ "content": "italic",
88
+ "link": null
89
+ },
90
+ "annotations": {
91
+ "bold": false,
92
+ "italic": true,
93
+ "strikethrough": false,
94
+ "underline": false,
95
+ "code": false
96
+ },
97
+ "href": null
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ ```
103
+ </details>
104
+
105
+ <br>
106
+
107
+ ```ruby
108
+ MdToNotion::Parser.markdown_to_notion_blocks <<~CODE
109
+ ``ruby
110
+ puts 'it works with code blocks too!'
111
+ ``
112
+ CODE
113
+ ```
114
+ <details>
115
+ <summary>result</summary>
116
+
117
+ ```json
118
+ {
119
+ "type": "code",
120
+ "code": {
121
+ "rich_text": [
122
+ {
123
+ "type": "text",
124
+ "text": {
125
+ "content": "puts 'it works with code blocks too!'",
126
+ "content": null
127
+ },
128
+ "annotations": {
129
+ "bold": false,
130
+ "italic": false,
131
+ "strikethrough": false,
132
+ "underline": false,
133
+ "code": false
134
+ },
135
+ "href": null
136
+ }
137
+ ],
138
+ "language": "ruby"
139
+ }
140
+ }
141
+ ```
142
+ </details>
143
+
144
+ ## Development
145
+
146
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
147
+
148
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
149
+
150
+ ## Contributing
151
+
152
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rieg-ec/md_to_notion.
153
+
154
+ ## License
155
+
156
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MdToNotion
4
+ module Block
5
+ def self.heading_1(texts)
6
+ {
7
+ type: "heading_1",
8
+ heading_1: {
9
+ rich_text: texts.map { |t| rich_text(t) }
10
+ }
11
+ }
12
+ end
13
+
14
+ def self.heading_2(texts)
15
+ {
16
+ type: "heading_2",
17
+ heading_2: {
18
+ rich_text: texts.map { |t| rich_text(t) }
19
+ }
20
+ }
21
+ end
22
+
23
+ def self.heading_3(texts)
24
+ {
25
+ type: "heading_3",
26
+ heading_3: {
27
+ rich_text: texts.map { |t| rich_text(t) }
28
+ }
29
+ }
30
+ end
31
+
32
+ def self.paragraph(texts, children: nil)
33
+ block = {
34
+ type: "paragraph",
35
+ paragraph: {
36
+ rich_text: texts.map { |t| rich_text(t) }
37
+ }
38
+ }
39
+
40
+ block[:paragraph][:children] = children if children
41
+ block
42
+ end
43
+
44
+ def self.quote(texts, children: nil)
45
+ block = {
46
+ type: "quote",
47
+ quote: {
48
+ rich_text: texts.map { |t| rich_text(t) }
49
+ }
50
+ }
51
+
52
+ block[:quote][:children] = children if children
53
+ block
54
+ end
55
+
56
+ def self.code(text, lang: nil)
57
+ {
58
+ type: "code",
59
+ code: {
60
+ rich_text: [rich_text({ text: text })],
61
+ language: lang
62
+ }
63
+ }
64
+ end
65
+
66
+ def self.bulleted_list_item(texts, children: nil)
67
+ block = {
68
+ type: "bulleted_list_item",
69
+ bulleted_list_item: {
70
+ rich_text: texts.map { |t| rich_text(t) }
71
+ }
72
+ }
73
+
74
+ block[:bulleted_list_item][:children] = children if children
75
+ block
76
+ end
77
+
78
+ def self.numbered_list(texts, children: nil)
79
+ block = {
80
+ type: "numbered_list_item",
81
+ numbered_list_item: {
82
+ rich_text: texts.map { |t| rich_text(t) }
83
+ }
84
+ }
85
+
86
+ block[:numbered_list_item][:children] = children if children
87
+ block
88
+ end
89
+
90
+ def self.image
91
+ {
92
+ type: "image",
93
+ image: {
94
+ type: "external",
95
+ external: {
96
+ url: link
97
+ }
98
+ }
99
+ }
100
+ end
101
+
102
+ def self.rich_text(token, annotations: {}, href: nil, link: nil)
103
+ default_annotations = {
104
+ bold: token[:type] == :bold,
105
+ italic: token[:type] == :italic,
106
+ strikethrough: token[:type] == :strikethrough,
107
+ underline: token[:type] == :underline,
108
+ code: token[:type] == :code
109
+ }
110
+
111
+ {
112
+ type: "text",
113
+ text: {
114
+ content: token[:text],
115
+ link: link
116
+ },
117
+ annotations: default_annotations.merge(annotations),
118
+ href: href
119
+ }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./tokens"
4
+
5
+ module MdToNotion
6
+ class Lexer
7
+ include Tokens
8
+
9
+ class InvalidTokenSyntaxError < StandardError; end
10
+
11
+ def initialize(markdown)
12
+ @markdown = markdown
13
+ @tokens = []
14
+ @stack = []
15
+ @index = 0
16
+ end
17
+
18
+ def tokenize
19
+ while @index < @markdown.length
20
+ begin
21
+ next_char = @markdown[@index]
22
+
23
+ if next_char == " "
24
+ @index += 1
25
+ next @stack << " "
26
+ elsif next_char == "#"
27
+ tokenize_heading
28
+ elsif next_char == "["
29
+ tokenize_link
30
+ elsif next_char == "!"
31
+ tokenize_image
32
+ elsif next_char == ">"
33
+ tokenize_quote
34
+ elsif next_char == "-"
35
+ tokenize_bullet_list
36
+ elsif next_char =~ /\d+/
37
+ tokenize_numbered_list
38
+ elsif next_char == "`" && peek(2) == "```"
39
+ tokenize_block_code
40
+ elsif next_char == "\n"
41
+ @index += 1
42
+ else
43
+ tokenize_paragraph
44
+ end
45
+ rescue InvalidTokenSyntaxError
46
+ tokenize_paragraph
47
+ end
48
+
49
+ @stack = []
50
+ end
51
+
52
+ @tokens
53
+ end
54
+
55
+ private
56
+
57
+ def peek(n = 1)
58
+ @markdown[@index..@index + n]
59
+ end
60
+
61
+ def tokenize_heading
62
+ line = @markdown[@index..].split("\n").first
63
+ if line =~ HEADING_1
64
+ @tokens << heading_1(::Regexp.last_match(0))
65
+ elsif line =~ HEADING_2
66
+ @tokens << heading_2(::Regexp.last_match(0))
67
+ elsif line =~ HEADING_3
68
+ @tokens << heading_3(::Regexp.last_match(0))
69
+ else
70
+ return raise InvalidTokenSyntaxError, "Invalid heading: #{line}"
71
+ end
72
+
73
+ @index += ::Regexp.last_match(0).length
74
+ end
75
+
76
+ def tokenize_block_code
77
+ raise InvalidTokenSyntaxError, "Invalid code block: #{@markdown[@index..]}" \
78
+ unless @markdown[@index..] =~ CODE_BLOCK
79
+
80
+ @tokens << code_block(::Regexp.last_match(0))
81
+ @index += ::Regexp.last_match(0).length
82
+ end
83
+
84
+ def tokenize_bullet_list
85
+ line = @markdown[@index..].split("\n").first
86
+ raise InvalidTokenSyntaxError, "Invalid bullet list: #{line}" \
87
+ unless line =~ BULLET_LIST
88
+
89
+ nesting = @stack.count(" ")
90
+ @stack = []
91
+
92
+ @tokens << bullet_list(::Regexp.last_match(0), nesting: nesting)
93
+ @index += ::Regexp.last_match(0).length
94
+ end
95
+
96
+ def tokenize_link
97
+ line = @markdown[@index..].split("\n").first
98
+ raise InvalidTokenSyntaxError, "Invalid link syntax: #{line}" \
99
+ unless line =~ LINK
100
+
101
+ @tokens << link(::Regexp.last_match(0))
102
+ @index += ::Regexp.last_match(0).length
103
+ end
104
+
105
+ def tokenize_image
106
+ line = @markdown[@index..].split("\n").first
107
+ raise InvalidTokenSyntaxError, "Invalid image syntax: #{line}" \
108
+ unless line =~ IMAGE
109
+
110
+ @tokens << image(::Regexp.last_match(0))
111
+ @index += ::Regexp.last_match(0).length
112
+ end
113
+
114
+ def tokenize_quote
115
+ line = @markdown[@index..].split("\n").first
116
+ raise InvalidTokenSyntaxError, "Invalid quote syntax: #{line}" \
117
+ unless line =~ QUOTE
118
+
119
+ @tokens << quote(::Regexp.last_match(0))
120
+ @index += ::Regexp.last_match(0).length
121
+ end
122
+
123
+ def tokenize_numbered_list
124
+ line = @markdown[@index..].split("\n").first
125
+ raise InvalidTokenSyntaxError, "Invalid numbered list: #{line}" \
126
+ unless line =~ NUMBERED_LIST
127
+
128
+ nesting = @stack.count(" ")
129
+ @stack = []
130
+
131
+ @tokens << numbered_list(::Regexp.last_match(0), nesting: nesting)
132
+ @index += ::Regexp.last_match(0).length
133
+ end
134
+
135
+ def tokenize_paragraph
136
+ line = @markdown[@index..].split("\n").first
137
+ @tokens << paragraph(line)
138
+ @index += line.length
139
+ end
140
+
141
+ def tokenize_strikethrough
142
+ line = @markdown[@index..].split("\n").first
143
+ raise InvalidTokenSyntaxError, "Invalid strikethrough syntax: #{line}" \
144
+ unless line =~ STRIKETHROUGH
145
+
146
+ @tokens << strikethrough(::Regexp.last_match(0))
147
+ @index += ::Regexp.last_match(0).length
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./lexer"
4
+ require_relative "./blocks"
5
+
6
+ module MdToNotion
7
+ module Parser
8
+ def self.markdown_to_ast(markdown)
9
+ lexer = Lexer.new(markdown)
10
+ lexer.tokenize
11
+ end
12
+
13
+ def self.markdown_to_notion_blocks(markdown)
14
+ ast = markdown_to_ast(markdown)
15
+ ast_to_notion_blocks(ast)
16
+ end
17
+
18
+ def self.ast_to_notion_blocks(ast)
19
+ ast.map do |token|
20
+ case token[:type]
21
+ when :heading_1
22
+ Block.heading_1(token[:rich_texts])
23
+ when :heading_2
24
+ Block.heading_2(token[:rich_texts])
25
+ when :heading_3
26
+ Block.heading_3(token[:rich_texts])
27
+ when :paragraph
28
+ Block.paragraph(token[:rich_texts])
29
+ when :code_block
30
+ Block.code(token[:text], lang: token[:lang])
31
+ when :bullet_list
32
+ Block.bulleted_list_item(token[:rich_texts])
33
+ when :numbered_list
34
+ Block.numbered_list(token[:rich_texts])
35
+ when :image
36
+ Block.image(token[:text], token[:rich_texts])
37
+ when :quote
38
+ Block.quote(token[:rich_texts])
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MdToNotion
4
+ module Tokens
5
+ HEADING_1 = /^# (.+)/.freeze
6
+ HEADING_2 = /^## (.+)/.freeze
7
+ HEADING_3 = /^### (.+)/.freeze
8
+ CODE_BLOCK = /^```(?:[^\n]+\n)?(.+?)\n```$/m.freeze
9
+ BULLET_LIST = /^- (.+)/.freeze
10
+ NUMBERED_LIST = /^([0-9]+)\. (.+)/.freeze
11
+ IMAGE = /!\[([^\]]+)\]\(([^)]+)\)/.freeze
12
+ QUOTE = /^> (.+)/.freeze
13
+
14
+ def heading_1(match)
15
+ { type: :heading_1, rich_texts: tokenize_rich_text(match.gsub(/^# /, "")) }
16
+ end
17
+
18
+ def heading_2(match)
19
+ { type: :heading_2, rich_texts: tokenize_rich_text(match.gsub(/^## /, "")) }
20
+ end
21
+
22
+ def heading_3(match)
23
+ { type: :heading_3, rich_texts: tokenize_rich_text(match.gsub(/^### /, "")) }
24
+ end
25
+
26
+ def code_block(match)
27
+ {
28
+ type: :code_block,
29
+ text: match.gsub(/^```[^\n]*\n/, "").gsub(/\n```$/, ""),
30
+ lang: match.gsub(/^```/, "").gsub(/\n.+$/m, "")
31
+ }
32
+ end
33
+
34
+ def bullet_list(match, nesting: 0)
35
+ {
36
+ type: :bullet_list,
37
+ rich_texts: tokenize_rich_text(match.gsub(/^- /, "")),
38
+ nesting: nesting
39
+ }
40
+ end
41
+
42
+ def numbered_list(match, nesting: 0)
43
+ {
44
+ type: :numbered_list,
45
+ rich_texts: tokenize_rich_text(match.gsub(/^[0-9]+\. /, "")),
46
+ number: match.gsub(/\..+$/, "").to_i,
47
+ nesting: nesting
48
+ }
49
+ end
50
+
51
+ def image(match)
52
+ {
53
+ type: :image,
54
+ rich_texts: tokenize_rich_text(match.gsub(/!\[([^\]]+)\]\(([^)]+)\)/, '\1')),
55
+ link: match.gsub(/!\[([^\]]+)\]\(([^)]+)\)/, '\2')
56
+ }
57
+ end
58
+
59
+ def paragraph(match)
60
+ { type: :paragraph, rich_texts: tokenize_rich_text(match) }
61
+ end
62
+
63
+ def quote(match)
64
+ { type: :quote, rich_texts: tokenize_rich_text(match.gsub(/^> /, "")) }
65
+ end
66
+
67
+ ## rich text objects
68
+
69
+ def tokenize_rich_text(text)
70
+ # use a regular expression to capture all the rich text elements and the text between them as separate groups
71
+ groups = text.scan(/(`[^`]*`|\*\*[^*]*\*\*|\*[^*]*\*|~~[^~]*~~|[^`*~]+)/).flatten
72
+
73
+ # map the groups to tokens
74
+ groups.map do |group|
75
+ case group
76
+ when /^`/
77
+ code(group)
78
+ when /^\*\*/
79
+ bold(group)
80
+ when /^\*/
81
+ italic(group)
82
+ when /^~~/
83
+ strikethrough(group)
84
+ else
85
+ text(group)
86
+ end
87
+ end
88
+ end
89
+
90
+ def code(text)
91
+ { type: :code, text: text.gsub(/^`/, "").gsub(/`$/, "") }
92
+ end
93
+
94
+ def italic(match)
95
+ { type: :italic, text: match.gsub(/\*/, "") }
96
+ end
97
+
98
+ def bold(match)
99
+ { type: :bold, text: match.gsub(/\*/, "") }
100
+ end
101
+
102
+ def text(match)
103
+ { type: :text, text: match }
104
+ end
105
+
106
+ def strikethrough(match)
107
+ { type: :strikethrough, text: match.gsub(/~~/, "") }
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MdToNotion
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "md_to_notion/version"
4
+
5
+ module MdToNotion
6
+ class Error < StandardError; end
7
+ end
@@ -0,0 +1,4 @@
1
+ module MdToNotion
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: md_to_notion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - rieg-ec
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-01-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Convert Markdown and GitHub Flavoured Markdown to Notion API Blocks and
14
+ RichText.
15
+ email:
16
+ - rieg.10199@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".eslintrc.json"
22
+ - ".rspec"
23
+ - ".rubocop.yml"
24
+ - ".ruby-version"
25
+ - Gemfile
26
+ - Gemfile.lock
27
+ - LICENSE.txt
28
+ - README.md
29
+ - Rakefile
30
+ - lib/md_to_notion.rb
31
+ - lib/md_to_notion/blocks.rb
32
+ - lib/md_to_notion/lexer.rb
33
+ - lib/md_to_notion/parser.rb
34
+ - lib/md_to_notion/tokens.rb
35
+ - lib/md_to_notion/version.rb
36
+ - sig/md_to_notion.rbs
37
+ homepage: https://github.com/rieg-ec/md-to-notion
38
+ licenses:
39
+ - MIT
40
+ metadata:
41
+ homepage_uri: https://github.com/rieg-ec/md-to-notion
42
+ source_code_uri: https://github.com/rieg-ec/md-to-notion
43
+ changelog_uri: https://github.com/rieg-ec/md-to-notion/blob/master/CHANGELOG.md
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.7.0
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.3.18
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Markdown to Notion converter.
63
+ test_files: []