Skip to content

Instantly share code, notes, and snippets.

@mmower
Last active March 30, 2020 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmower/e1af40cb84b9189fadf402ee4dc5c690 to your computer and use it in GitHub Desktop.
Save mmower/e1af40cb84b9189fadf402ee4dc5c690 to your computer and use it in GitHub Desktop.
Ruby script that converts a JSON export of Pinboard.in bookmarks into a properly tagged Markdown file to import into Roam
#!/usr/bin/env ruby -w
# frozen_string_literal: true
#
# usage
# chmod +x pinboard_converter.rb
# ./pinboard_converter.rb -t [pinboard_export_file] > tag_map.yml
# edit tag_map.yml
# ./pinboard_converter.rb [pinboard_export_file] tag_map.yml > [roam_import_file]
# import [roam_import_file] into Roam
#
# optionally pass -d and a file with a list of URL filters (one per line) for
# links that should not pass through into the markdown file
#
require 'optparse'
require 'json'
require 'yaml'
options = {}
optparse = OptionParser.new do |opts|
opts.banner = 'Usage: pinboard_converter [options] pinboard_export_file tag_map_file'
options[:tag_map] = false
opts.on('-t', '--tags', 'Output a tag map file') do
options[:tag_map] = true
end
opts.on('-d', '--domain-filter FILTER', 'Filter link domains using FILTER') do |filter_file|
options[:domain_filter] = filter_file
end
end
optparse.parse!
filters = if options[:domain_filter]
File.readlines(options[:domain_filter]).map { |filter| Regexp.new(filter.strip) }
else
[]
end
def filter_link(filters, href)
filters.find { |filter| filter =~ href }
end
def non_empty_str(s)
s == '' ? nil : s
end
def convert_tags(tag_map, tags)
tags.strip.split(/\s+/).map { |tag| non_empty_str(tag_map[tag]) }.compact.uniq.map do |tag|
if tag =~ /\s+/
"#[[#{tag}]]"
else
"##{tag}"
end
end
end
pins = JSON.parse(File.read(ARGV[0]))
if options[:tag_map]
tags = pins.each_with_object({}) do |pin, tag_acc|
pin['tags'].split(/\s+/).map { |tag| tag }.each do |tag|
tag_acc[tag] = tag
end
end.sort.to_h
puts YAML.dump(tags)
else
tag_map = YAML.safe_load(File.read(ARGV[1]))
items = pins.map do |pin|
href = pin['href'].strip
if filter_link(filters, href)
nil
else
desc = pin['description'].strip
link = "- [#{desc}](#{href})"
tags = convert_tags( tag_map, pin['tags'] )
if tags.empty?
link
else
"#{link} #{tags.join(' ')}"
end
end
end
puts items.compact.join("\n")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment