Created
May 20, 2017 16:14
-
-
Save angelamancini/c42996c0db9d50c9d73e61422daca801 to your computer and use it in GitHub Desktop.
Converts Quiver notebook exports to Evernote *.enex files. Only tested with text and code cells. This *was not tested* with any other cell types.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Before running this script, go to Quiver and export all notebooks into json/quiver format | |
# Place them in a folder called `exports` in the same directory as this script. | |
# In terminal, run `ruby quiver-to-evernote.rb` | |
# Check for presence of required gems. | |
# If not present, install the gems | |
["rubygems", "sanitize"].each do |gem| | |
begin | |
gem "#{gem}" | |
rescue Gem::LoadError | |
`gem install #{gem}` | |
Gem.clear_paths | |
end | |
end | |
require 'date' | |
require 'json' | |
require 'rubygems' | |
require 'sanitize' | |
# Read the exports folder | |
Dir.chdir('exports') | |
# find all the notebooks as .qvbotebook files | |
notebooks = Dir.glob('*').select {|f| File.directory? f} | |
# Loop through the notebooks and find all the notes | |
notebooks.each do |notebook| | |
name = notebook.gsub(/.qvnotebook$/,'') | |
file_name = "../imports/#{name}.enex" | |
puts "Reading Notebook: #{name}" | |
file_date = File.mtime(notebook).to_time.utc.strftime("%Y%m%dT%H%M%SZ") | |
# create the imports/notebook.enex file | |
file = File.open(file_name, 'w') | |
# write the file header | |
file_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<!DOCTYPE en-export SYSTEM \"http://xml.evernote.com/pub/evernote-export3.dtd\"> | |
<en-export export-date=\"#{file_date}\" application=\"Evernote\" version=\"Evernote Mac 6.11 (454874)\">\n\n\n" | |
file << file_header | |
notes = Dir.glob("#{notebook}/*").select {|f| File.directory? f} | |
puts "#{notes.count} notes" | |
# loop through each note folder and read the content.json and meta.json | |
notes.each do |note| | |
puts "Reading Note: #{note}" | |
content = JSON.parse(File.read("#{note}/content.json")) | |
meta = JSON.parse(File.read("#{note}/meta.json")) | |
text = "" | |
content['cells'].each do |cell| | |
# If the cells are code, wrap in temporary code blocks, they will be replaced later | |
if cell['type'] == 'code' | |
text += "<code>#{cell['data'].gsub("\n","<br/>")}</code>" | |
else | |
text += cell['data'] | |
end | |
end | |
# Sanatize the text of most html tags. I found that some styles really make evernote go nuts | |
sanitized_text = Sanitize.clean(text, Sanitize::Config::BASIC).strip | |
# I really hate this, the code blocks in evernote are not just <code> tags, they are this awful and ugly thing that would've gotten stripped out of our sanatized text. | |
code_bock_begining = '<div><br/></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial;-en-codeblock:true;"><div>' | |
code_block_end = '<br/></div></div><div><br/></div>' | |
# Replace the problem characeters. This list can be changed except for the code tags. | |
replace = { '&' => '&', '<br>' => '<br />', '<br /><br />' => '<br />', '<code>' => code_bock_begining, '</code>' => code_block_end } | |
re = Regexp.new(replace.keys.map { |x| Regexp.escape(x) }.join('|')) | |
clean_text = sanitized_text.gsub(re, replace) | |
tags = "" | |
# Write the tags | |
meta['tags'].map { |t| tags += "<tag>#{t}</tag>"} | |
# write the note into the file, making sure no ampersands are in the title, that messed my import up | |
file << "<note><title>#{content['title'].gsub('&','&')}</title><content><![CDATA[ <en-note>#{clean_text}</en-note>]]></content><created>#{Time.at(meta['created_at']).to_time.utc.strftime('%Y%m%dT%H%M%SZ')}</created><updated>#{Time.at(meta['updated_at']).to_time.utc.strftime('%Y%m%dT%H%M%SZ')}</updated>#{tags}<note-attributes></note-attributes></note>\n\n\n" | |
end | |
# write the end tag on the file and close | |
file << "\n</en-export>" | |
file.close | |
end | |
# You should have a directory called `imports` and one *.enex file for every quiver notebook. | |
# In evernote, go to File > Import and import in the file. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I just used this to move from quiver to evernote, mostly because I want a note taking app with Linux desktop options, really appreciate this. However, I had two issues that I had to fix before the script would work (I'm on OSX):
File.open()
does not seem to create missing directories, so I had to manually create the exports folder.Thanks again!