diff --git a/.rubocop.yml b/.rubocop.yml index 8d1fdd3..406a597 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 2.7 + TargetRubyVersion: 3.3 Style/StringLiterals: Enabled: true diff --git a/.ruby-version b/.ruby-version index 1effb00..9c25013 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7 +3.3.6 diff --git a/Gemfile.lock b/Gemfile.lock index 497ab0e..8a30a75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - md_to_notion (0.1.3) + md_to_notion (0.1.5) GEM remote: https://rubygems.org/ @@ -51,6 +51,7 @@ GEM PLATFORMS arm64-darwin-20 + arm64-darwin-23 x86_64-linux DEPENDENCIES @@ -61,4 +62,4 @@ DEPENDENCIES rubocop (~> 1.21) BUNDLED WITH - 2.3.26 + 2.6.6 diff --git a/lib/md_to_notion/blocks.rb b/lib/md_to_notion/blocks.rb index b5e04fe..aca5b75 100644 --- a/lib/md_to_notion/blocks.rb +++ b/lib/md_to_notion/blocks.rb @@ -99,7 +99,7 @@ def self.file(url, type:) } end - def self.rich_text(token, annotations: {}, href: nil, link: nil) + def self.rich_text(token, annotations: {}) default_annotations = { bold: token[:type] == :bold, italic: token[:type] == :italic, @@ -112,10 +112,10 @@ def self.rich_text(token, annotations: {}, href: nil, link: nil) type: "text", text: { content: token[:text], - link: link + link: token[:link] }, annotations: default_annotations.merge(annotations), - href: href + href: token[:link] } end end diff --git a/lib/md_to_notion/lexer.rb b/lib/md_to_notion/lexer.rb index d3392a4..fd8e8fa 100644 --- a/lib/md_to_notion/lexer.rb +++ b/lib/md_to_notion/lexer.rb @@ -29,8 +29,6 @@ def tokenize next @stack << " " elsif next_char == "#" tokenize_heading - elsif next_char == "[" - tokenize_link elsif next_char == "!" tokenize_image elsif ALLOWED_VIDEO_EMBED_URLS.join("").include?(peek(41)) @@ -99,15 +97,6 @@ def tokenize_bullet_list @index += ::Regexp.last_match(0).length end - def tokenize_link - line = @markdown[@index..].split("\n").first - raise InvalidTokenSyntaxError, "Invalid link syntax: #{line}" \ - unless line =~ LINK - - @tokens << link(::Regexp.last_match(0)) - @index += ::Regexp.last_match(0).length - end - def tokenize_image line = @markdown[@index..].split("\n").first raise InvalidTokenSyntaxError, "Invalid image syntax: #{line}" \ diff --git a/lib/md_to_notion/tokens.rb b/lib/md_to_notion/tokens.rb index 232df2f..3812fcd 100644 --- a/lib/md_to_notion/tokens.rb +++ b/lib/md_to_notion/tokens.rb @@ -12,6 +12,7 @@ module Tokens QUOTE = /^> (.+)/.freeze GH_EMBED_FILE = %r{https://user-images\.githubusercontent\.com/.+\.[a-zA-Z]+}.freeze EMBED_FILE_REGEXES = [GH_EMBED_FILE].freeze + LINK = /\[([^\]]+)\]\(([^)]+)\)/.freeze def heading_1(match) { type: :heading_1, rich_texts: tokenize_rich_text(match.gsub(/^# /, "")) } @@ -76,7 +77,8 @@ def embeded_file(match) def tokenize_rich_text(text) # use a regular expression to capture all the rich text elements and the text between them as separate groups - groups = text.scan(/(`[^`]*`|\*\*[^*]*\*\*|\*[^*]*\*|~~[^~]*~~|[^`*~]+)/).flatten + # use non-capturing groups (?:) instead of capturing groups () for the link parts + groups = text.scan(/(`[^`]*`|\*\*[^*]*\*\*|\*[^*]*\*|~~[^~]*~~|\[(?:[^\]]+)\]\((?:[^)]+)\)|[^`*~\[\]]+)/).flatten # map the groups to tokens groups.map do |group| @@ -89,6 +91,8 @@ def tokenize_rich_text(text) italic(group) when /^~~/ strikethrough(group) + when /^\[/ + link(group) else text(group) end @@ -99,20 +103,24 @@ def code(text) { type: :code, text: text.gsub(/^`/, "").gsub(/`$/, "") } end - def italic(match) - { type: :italic, text: match.gsub(/\*/, "") } - end - def bold(match) { type: :bold, text: match.gsub(/\*/, "") } end - def text(match) - { type: :text, text: match } + def italic(match) + { type: :italic, text: match.gsub(/\*/, "") } end def strikethrough(match) { type: :strikethrough, text: match.gsub(/~~/, "") } end + + def link(match) + { type: :link, text: match.gsub(LINK, '\1'), link: match.gsub(LINK, '\2') } + end + + def text(match) + { type: :text, text: match } + end end end diff --git a/lib/md_to_notion/version.rb b/lib/md_to_notion/version.rb index 4923033..5238f3d 100644 --- a/lib/md_to_notion/version.rb +++ b/lib/md_to_notion/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module MdToNotion - VERSION = "0.1.4" + VERSION = "0.1.5" end diff --git a/spec/fixtures/test1.md b/spec/fixtures/test1.md index 56bedd9..d1825fb 100644 --- a/spec/fixtures/test1.md +++ b/spec/fixtures/test1.md @@ -8,7 +8,7 @@ 1. number -paragraph +paragraph with a link to [Notion](https://www.notion.so/) ```c int main() { diff --git a/spec/fixtures/test1_blocks.json b/spec/fixtures/test1_blocks.json index 69d3984..deef563 100644 --- a/spec/fixtures/test1_blocks.json +++ b/spec/fixtures/test1_blocks.json @@ -139,7 +139,7 @@ { "type": "text", "text": { - "content": "paragraph", + "content": "paragraph with a link to ", "link": null }, "annotations": { @@ -150,6 +150,20 @@ "code": false }, "href": null + }, { + "type": "text", + "text": { + "content": "Notion", + "link": "https://www.notion.so/" + }, + "annotations": { + "bold": false, + "italic": false, + "strikethrough": false, + "underline": false, + "code": false + }, + "href": "https://www.notion.so/" } ] }