Convert Notion pages to markdown using Ruby
Wanna export your articles to local markdown files but found the built-in export function hard to use? Use Ruby with the notoin-sdk-ruby
gem and scripts below to achieve that easily.
Assuming you are familiar with Ruby, here is a brief guide:
Step 1: get a token and authorize it
For simplicity, create a new integration here and get it’s internal integration token.
Authorize the integration by inviting it to the target page or database.
Reference: Notion’s getting started for developers
Step 2: install the Notion SDK for Ruby
gem install notion-sdk-ruby
Step 3: patch the gem with to_md
method
It’s just a monkey-patch. Feel free to modify according to your need:
require 'notion-sdk-ruby'
class Notion::Block
def to_md
prefix = ''
suffix = ''
case type
when 'paragraph'
# do nothing
when /heading_(\d)/
prefix = '#' * Regexp.last_match(1).to_i + ' '
self[type]['rich_text'].map { _1['annotations']['bold'] = false } # unbold headings
when 'callout'
# do nothing
when 'quote'
prefix = '> '
when 'bulleted_list_item'
prefix = '- '
when 'numbered_list_item'
prefix = '1. '
when 'to_do'
prefix = to_do['checked'] ? '- [x] ' : '- [ ] '
when 'toggle'
# do nothing
when 'code'
prefix = "```#{code['language'].split.first}\n"
suffix = "\n```"
when 'image'
return "![#{RichText.to_md(image['caption'])}](#{image[image['type']]['url']})"
when 'equation'
return "$$#{equation['expression']}$$"
when 'divider'
return '---'
else
raise 'Unable to convert the block'
end
# Only for types with rich_text, others should return in `case`
prefix + RichText.to_md(self[type]['rich_text']) + suffix
rescue RuntimeError => e
puts "#{e.message}: #{JSON.pretty_generate(to_h)}"
"```json\n#{JSON.pretty_generate(to_h)}\n```"
end
end
class Notion::RichText
ATTRIBUTES = %w[
plain_text href annotations type text mention equation
].each { attr_reader _1 }
def self.to_md(obj)
obj.is_a?(Array) ? obj.map { |item| new(item).to_md }.join : new(obj).to_md
end
def initialize(data)
ATTRIBUTES.each { instance_variable_set("@#{_1}", data[_1]) }
end
def to_md
md = plain_text
# Shortcut for equation
return "$#{md}$" if type == 'equation'
md = "<u>#{md}</u>" if annotations['underline']
md = "`#{md}`" if annotations['code']
md = "**#{md}**" if annotations['bold']
md = "*#{md}*" if annotations['italic']
md = "~~#{md}~~" if annotations['strikethrough']
md = "[#{md}](#{href}){:target=\"_blank\"}" if href
md
end
end
Check the latest version of this script on GitHub Gist
Step 4: begin with this starter
That’s all you need. Begin with your own script with following starter:
# Create a client for Notion APIs
client = Notion::Client.new(token: 'PUT_YOUR_TOKEN_HERE'))
# A simplest example
pages = client.databases.query_all('YOUR_DATABASE_ID')
blocks = client.blocks.children.list(page.first.id)
puts blocks.map(&:to_md).join("\n\n")
Check the latest version of this script on GitHub Gist
That’s all you need to convert Notion pages to markdown with Ruby.