Home / Blog Menu ↓

Blog: #epub2pdf

Scroll

A couple weeks ago I built my own EPUB reader called Scroll, and since then have pretty much moved off Marvin. Here’s what Scroll looks like (light and dark themes):

scroll.png

Thus far I’ve read two books using it, and while there are still a few small issues, overall I’m very happy with it. I don’t plan to release it anytime soon, but as a not-even-close-to-the-same-thing substitute, here are some notes:

  • I’d made decent enough progress with epub2pdf that it was usable, but reflowability and theme-changing are nice, and having quick navigation between books is even nicer, and printing a book to PDF in Firefox is slow, and browsers already natively support the HTML that’s inside EPUBs, so I abandoned the PDF route.
  • Scroll (after both the noun and the verb) is a PWA without a backend. It’s actually just static HTML files: I wrote a script that concatenates all the HTML in an EPUB into one long HTML file, with some processing to fix links and wrap things and bake the table of contents out. Then there’s a little bit of vanilla JS for the reader functionality (saving the debounced current scroll location to localStorage (I wish Safari supported scrollend), restoring it on the pageshow event, calculating pagination, jumping to pages, switching themes, etc.), and another vanilla JS file listing the current books (so that I don’t have to re-build all the other book files when I start reading a new book).
  • While I said “pagination” above, I’m not actually chunking the book into pages; I’ve chosen to stick with vertical scrolling for now instead of horizontal paging, primarily because being able to make sub-page progress is nicer than I realized. That said, I still want to know how many “pages” I’ve read, so I use the scroll percentage (scrollTop divided by scrollHeight, super simple) multiplied by a rough heuristic of 1,200 characters per page, ignoring whitespace. It’s not perfect but it’s good enough for my needs.
  • I added a slight blur to the text so that it feels a little less digital. For now I’ve opted against a background image, but I may change my mind about that.
  • Whenever I add/remove a book, I copy the baked files to a private directory on my server
  • I’ve saved the root HTML file (which is just a list of the current books, loaded via JS) to my home screen as a PWA

Reply via email

I’ve been playing around with making EPUBs look more like print:

Two book pages. At left is a page from a digital PDF. At right is the same page but modified to look less digital.

Why the madness: ebooks feel kind of sterile to me, and I’m intrigued by the idea of giving them a more analog feel.

The experiment is still early on (I’ve only automated the first step so far), but at this point the process involves:

  1. Turning the EPUB into a PDF (concatenating each file in the EPUB into a single HTML file, setting some print CSS rules, and printing from HTML to PDF in a browser)
  2. Turning each page into an image (at left in the above image)
  3. Eroding/dilating the image to simulate ink spread
  4. Adding a very slight ripple
  5. Blurring the next page, flipping it backwards, and compositing it at a low opacity
  6. Adding some paper texture (at right in the above image)
  7. Compiling all the page images back into a PDF

Other notes:

  • This does mean larger file sizes, but not prohibitively so. (For me, anyway.)
  • Right now I’m experimenting with doing this statically, in PDF but I imagine most if not all of it could be done dynamically in-browser. (filter: blur(0.25px) contrast(3) in CSS applied twice to text can give a roughly similar effect to erosion/dilation, for example.)
  • The current erosion/dilation method is acceptable, but I feel like there’s more room for improvement here.
  • A shortcut to doing the full process is to export a blurred backwards page image, composite it onto the paper texture, and then use that as the background image on each page. You lose the variety, but it’s probably not noticeable.

Reply via email