Converting SuperNote files to PDF
Posted on September 2, 2022
Writing is my primary mode of note taking and at the beginning of the pandemic, I switched from paper notebooks to digital notebooks. My primary note taking devices are SuperNote A6X, Boox Max3, and iPad Pro using Notability App (in that order, though I do prefer iPad for reviewing papers etc. because of the speed). I prefer the writing experience on Supernote, but I do miss one of the software features of Boox: In Boox, every time I save a note file, it is automatically converted to PDF and stored in a pdf directory which mirrors the layout of the notes directory. There is no such feature in SuperNote. Notes have to converted manually and get exported to a flat directory.
Now, the reason that I want automatic pdf conversion is that PDF is a universal format and can be read on any device. In contrast, all the digital notebook devices or apps use a propriety format, which cannot be read easily on other devices. That’s why I like the automatic conversion on Boox. That (along with DropSync to instantly sync the converted file) means that I always have access to the latest version of my notebooks everywhere. On SuperNote, I need to remember to manually convert the file. (And also manually since the device, but that’s another story).
I recently discovered a script called
supernote-tool, which parses the
SuperNote .note
format and converts it to PDF. So, I wrote a simple
Rakefile
to convert all .note
files to .pdf
files.
I sync SuperNote files using Dropbox and Supernote creates a directory
Dropbox/Supernote
which has the following structure:
Dropbox/Supernote
├── Document
├── EXPORT
├── INBOX
├── MyStyle
├── Note
└── SCREENSHOT
By default, all the note files are in the Note
sub-directory. I wanted to
create a sibling directory called pdfs
, which mirrors the layout of the
Notes
directory and converts each .note
file to .pdf
. I wanted to write
this as a Makefile
so that I can periodically run the conversion via cron
,
but writing complext makefiles is always wild goose chase on google. So, I
decided to write it as a Rakefile
, although I haven’t touched ruby in almost
15 years. Here is the file:
require 'fileutils'
require 'rake/clean'
SN = "$HOME/Software/supernote-tool/venv/bin/supernote-tool"
SRC_DIR = "Note"
PDF_DIR = "pdfs"
SRC = FileList["#{SRC_DIR}/**/*.note"]
PDF = SRC.pathmap("%{^#{SRC_DIR},#{PDF_DIR}}X.pdf")
directory PDF_DIR
task :pdf => PDF
rule '.pdf' => proc {|f| f.pathmap("%{^#{PDF_DIR},#{SRC_DIR}}X.note")} do |t|
mkdir_p t.name.pathmap("%d")
sh %Q{#{SN} convert -t pdf --pdf-type vector -a "#{t.source}" "#{t.name}"}
end
task :default => :pdf
CLEAN.include(PDF)
The tricky part of the writing this was to figure out how to make sure that
the converted pdfs are saved in a parallel directory with the same directory
structure as the notes directory. I was hoping that there was an easy way to
do it using rule
s, but I could not figure it out. So, I followed a very
rudimentary method.
First, collect the names of all .note
files:
SRC = FileList["#{SRC_DIR}/**/*.note"]
and then change the root directory and the extension:
PDF = SRC.pathmap("%{^#{SRC_DIR},#{PDF_DIR}}X.pdf")
This looks like black magic, but it fairly simply once your read the
documentation of
pathmap
.
Then, I specify a rule to generate the .pdf
file. To do so, I need to
specify that the corresponding .note
file is a dependency of the .pdf
file, I run the conversion if the .note
file is newer than the .pdf
file.
Rake has this super cool feature that you don’t have to explicitly list all
target names; it can regex against a specified string. See, for example, this
blog post.
However, this automatic dependency specification only works when the source
and the destination are in the same directory. But I want the .note
and
.pdf
files to be in parallel directories. Again, I found that the simplest
way to do this was to invert the conversion used to generate the name of the
.pdf
file:
rule '.pdf' => proc {|f| f.pathmap("%{^#{PDF_DIR},#{SRC_DIR}}X.note")} do |t|
mkdir_p t.name.pathmap("%d")
sh %Q{#{SN} convert -t pdf --pdf-type vector -a "#{t.source}" "#{t.name}"}
end
And that’s it! I added a cron task so that this script is run every 6 hours.
There are a few things that I don’t like about this setup:
-
AFAIK, there is no public discription of the spec of the SuperNote format. So, most likely,
supernote-tool
is a reverse engineered tool. It works well now, but break in a future release. -
Supernote provides two conversion methods: pixel conversion and vector conversion. I prefer the look of vector conversion, but that is very slow. It doesn’t really matter much in this setup, as I don’t need the PDF right away, but it is still annoying. I don’t understand why the conversion is slow from a practical point of view (it is just drawing a smooth path from a bunch of points). One of these days, I plan to look into the storage format and figure out why the vector conversion is taking too long, and if I can speed it up by using Metapost.
Nontheless, at present, this simple Rakefile
scratches the itch.
This entry was posted in Eink and tagged supernote, supernote-tool, rake, cron, max3, a6x, boox.