I’ve kept some quotes in DayOne for years, and I frequently find myself coming back to them when I’m writing, either to actually use them or to just remember an idea. I thought it’d be handy to have them in my writing tool, so I used ChatGPT to help me write a quick exporter.
I’ll include that below, but the other thing to link to before your eyes glaze over with a hunk of Ruby is this useful post on using consult-ripgrep with org-roam for fulltext search from the org-roam Discourse. I’ve been careful to tag everything I’ve put in so far, but I won’t get to that with this batch of files, and I usually remember a keyword, anyhow. So they’re just tagged with “quotes” and “commonplace” for now.
The script just consumes the JSON that DayOne’s export function provides and coughs out formatted org-roam nodes. It uses DayOne’s uuid’s, but tacks on a few words – just in case? Maybe over time I’ll go clean up the titles but for now they’re just there to provide a hint when I search.
#!/usr/bin/env ruby
require 'json'
require 'date'
# Set these up before running
src_json = "/path/to/file.json"
destination_dir = "/path/to/export/dir"
# Read the JSON file
json_str = File.read(src_json)
# Parse the JSON string
data = JSON.parse(json_str)
def write_json_to_org_roam_files(json_str, path)
data = JSON.parse(json_str)
entries = data['entries']
entries.each do |entry|
created_date = DateTime.parse(entry['creationDate']).strftime('%Y%m%d%H%M%S')
title = entry['text'].gsub(/^"/, '').gsub(/"$/, '').gsub(/[^a-zA-Z0-9 ]/, ' ').squeeze(' ').strip # replace non-alphanumeric with space, remove extra spaces
first_words = title.split.first(5).join(' ').gsub(/[^a-zA-Z0-9]/, '-') # replace non-alphanumeric with dash
uuid = first_words + '-' + entry['uuid']
content = JSON.parse(entry['richText'])['contents'].map { |c| c['text'] }.join("\n")
filename = "#{created_date}-#{first_words}.org".gsub(/^-/, '').gsub(/-$/, '').gsub(/-{2,}/,'-') # remove leading/trailing dashes and collapse multiple dashes
file_content = <<~ORG_NODE.gsub(/^\s*/, '')
:PROPERTIES:
:ID: #{uuid}
:END:
#+title: #{first_words}
#+filetags: :commonplace:quotes:
#{content}
ORG_NODE
file = File.open(File.join(path, filename), 'w')
file.write(file_content)
file.close
end
end
# Iterate over each entry
data['entries'].each do |entry|
write_json_to_org_roam_files(json_str, File.expand_path(destination_dir))
end