Simplifying PDF imports on reMarkable

By

I've been using my reMarkable 2 a lot more recently, and have gotten started with actually hacking on it. It's a bit overdue, since the main reason I purchased it in the first place was that it is built on top of Linux and doesn't require any special jailbreaking/rooting.

I found Adrian Daerr's script to import PDFs/EPUBs into a reMarkable, which is surprisingly not a straightforward operation. You need to rename the file to use a UUID as its name, create corresponding .metadata and .content files, and then empty .cache, .highlights, and .thumbnails directories.

Daerr's bash script does all of this, except it runs on a different machine, and then scps the files over to the reMarkable. Modifying it to run on the reMarkable itself didn't seem too complicated, but I try to avoid writing shell scripts as much as possible, so I took the opportunity to port it to Rust.

I first asked Claude to port it to Rust, and, probably for the first time, I was disappointed by the result.

Specifically, it generated:

if args[1] == "-r" {
    restart_xochitl = !config.restart_xochitl_default;
    files_start_index =, 2;
}

I couldn't come up with a reason on why Claude would insert a comma after the equals sign (it's not really a hallucination I think?), but rust-analyzer flagged it as a syntax error right away.

I deleted most of that code anyways since I wanted to unconditionally restart, and also use camino instead. As an aside, std::path represents paths with OsString, which is incredibly inconvenient to use anywhere else, which'll expect normal UTF-8 Strings. camino only supports paths that are fully UTF-8 (aka String instead of OsString), which should be fine for most projects that don't need to support legacy files and encodings, like this one.

Next, I had to cross-build it for the reMarkable's ARM v7 CPU. I've done it before for Raspberry Pis, but since it's been a while, I wanted to try out the cross tool, which transparently builds in a container with the necessary toolchains. And if you set a little bit of metadata, it's as simple as cross build --release.

To make the newly imported file actually show up in the reMarkable file listing, you apparently have to restart the entire thing, which does work, but surely there's a better way to tell it to look for new files...

Finally, to actually make use of it, I set up rclone to automatically fetch a folder from my Nextcloud instance, and then run rm-import over it. And now I can drop a PDF in a dedicated Nextcloud folder, and it'll end up on my reMarkable!