Reading ebooks on the command line
#354 Henry, Tuesday, 06 February 2018 3:34 PM (Category: Books)
(Tags: ebook epub acroread calibre)

I live on the command line. I live in xterms almost all the time. I mostly use a GUI desktop to manage a whole slew of xterms. I do use graphical tools when they are needed, but mostly I spawn them off from the command line, and shut them down when done, and return to the command line. I am more efficient this way. Your mileage no doubt will vary, but this is how I do it.

I have been processing a lot of books lately, and this has introduced me to a number of irritations.

I use two viewers of ebooks - acroread for PDFs, and ebook-viewer for almost everything else. Ebook-viewer is a part of Calibre, and it works very nicely inside Calibre, but you can also run it from the command line. There is one irritating aspect with both of these, when I run them from the command line. If I get the filename wrong, they both start up, both display an error that the file cannot be found, and I have to click on that error dialog box, and then shut down the program. Far too many clicks to recover from a typing problem. This usually happens when I use tab-completion on the command line and there are multiple files that match the starting criteria.

This became irritating enough that I decided to stop it. First, I created two small shell scripts. I used ev for ebook-viewer, and ao for acroread (ac and ar are existing programs in Linux and I didn't want to overload them). They would check if the file exists, and stop if it isn't. If it does exist, they would fire up acroread or ebook-viewer.

#!/usr/bin/bash

F="$*"

if [ -f "$F" ]; then
  /usr/bin/acroread "$F"
else
   echo "$F does not exist"
fi

As many of the books I am processing use spaces in the filename, I had to make sure I used quotes around $F in the scripts.

That worked very nicely for a time. And then I thought why don't I combine them and make a single script that can be used to read any book, and it decides what to use to view it. So I amalgamated them and came up with this script, which I called br (book-reader):

#!/usr/bin/bash

F="$*"

if [ ! -f "$F" ]; then
   echo "$F does not exist"
   exit
fi

case $F in
  *.pdf)    /usr/bin/acroread "$F" ;;
  *.epub)   /opt/calibre/ebook-viewer "$F" ;;
  *.mobi)   /opt/calibre/ebook-viewer "$F" ;;
  *.azw)    /opt/calibre/ebook-viewer "$F" ;;
  *.azw3)   /opt/calibre/ebook-viewer "$F" ;;
  *.txt)   /usr/bin/view "$F" ;;
  *)        echo "'$F' cannot be viewed";;
esac

I threw in txt files too, and view them with the read-only version of Vim.

But once I did that, and looked at the man page for acroread, and the help for ebook-viewer, I realised that I could solve some other irritations.

Acroread, no matter what I do, is going to display errors about files not existing even when they do. I could get rid of this rubbish by redirecting stdout and stderr to /dev/null.

If I have a PDF open, and then in another xterm in another window, I open another PDF, then the two PDFs appear in the one acroread screen in tabs. And if I go to shut it down, then it complains about shutting down multiple PDFs. And if I avoid that trap and just close the PDF I no longer want, the remaining PDF is in the wrong window. I am able to solve this whole mess by using -openInNewInstance on the command line and each PDF would get its own instance and things would work the way I want them to work.

Another irritation is opening a PDF and finding that it is scaled down to 20% and it's unreadable, or scaled up to 300% and equally unreadable. This was solved by using /a "zoom=100" on the command line. And because when I am checking books for the correct names and authors I always want to start at the beginning and not where acroread last left off or where the author wants me to start reading the book, I can force it to open on page 1 too, by expanding the /a option to /a "zoom=100 & page=1".

Ebook-viewer has less start up options, probably because there are less things irritating me, so the only thing I wanted to do with it was force it to start at page 1 too, and that is done with --open-at=1.

So I added these options to my br script and ended up with something that works really well for me.

#!/usr/bin/bash

F="$*"

if [ ! -f "$F" ]; then
   echo "$F does not exist"
   exit
fi

case $F in
  *.pdf)    /usr/bin/acroread -openInNewInstance /a "page=1 & zoom=100" "$F" > /dev/null 2>&1 ;;
  *.epub)   /opt/calibre/ebook-viewer --open-at=1 "$F" > /dev/null 2>&1 ;;
  *.mobi)   /opt/calibre/ebook-viewer --open-at=1 "$F" > /dev/null 2>&1 ;;
  *.azw)    /opt/calibre/ebook-viewer --open-at=1 "$F" > /dev/null 2>&1 ;;
  *.azw3)   /opt/calibre/ebook-viewer --open-at=1 "$F" > /dev/null 2>&1 ;;
  *.txt)   /usr/bin/view "$F" ;;
  *)        echo "'$F' cannot be viewed";;
esac

If I learn new tricks, I can easily expand this script. It's a good start, and my irritation level is seriously reduced, but more importantly, I am much more efficient using this script. I can process books very quickly now.

0 comments