Tag Archives: read

Reading programming books on the Nook

Programming books are hard enough to read: cryptic jargon, poor phrasing, blatant omission of critical details… the list goes on. But it’s even harder to read technical books on the Nook (or any ereader for that matter), because of some limitations of HTML (ePubs are zipped XHTML files).

HTML was not designed for consideration of really small screens. Coders typically use an 80-character margin for easy viewing on medium and large screens. So when a code snippet is shown on the Web, it also assumes a medium or large screen. Textbooks are also pretty big surfaces for code. That’s why Real World Haskell and Practical Common Lisp don’t chop up their code blocks very much. Both the print versions and the electronic versions rely on a big surface for viewing–about 80 characters or more.

Not surprisingly, when this code is viewed on a Nook, the code is cut off. Here’s an example:

PRE-Normal.epub

#!/usr/bin/env runhaskell

module Magic where

import Text.Printf

magic :: String
magic = unlines $ map magic
        where
                magicN :: Int -> S
                magicN n
                        | n > 0 && n

main :: IO ()
main = putStr magic

This is not valid Haskell code. It’s not even readable Haskell code. What’s the rest of the n > 0 && n condition? What happens after that condition is met?

The solution is to instruct Nook (and any other HTML viewer) to wrap the code and set it to a reasonable size (10pt or less). Add the following to the ePub’s CSS:

pre {
	font-family: Andale Mono, "Courier New", Courier, monospace;
	font-size: 80%;

	overflow-x: auto;
	white-space: -moz-pre-wrap !important;
	white-space: -pre-wrap;
	white-space: -o-pre-wrap;
	white-space: pre-wrap;
	word-wrap: break-word;
}

Now the code is readable. Choppy, at least you can see all of it.

#!/usr/bin/env runhaskell

module Magic where

import Text.Printf

magic :: String
magic = unlines $ map magicN [1..7]
        where
                magicN :: Int -> String
                magicN n
                        | n > 0 && n <
8 && n /= 4 = "09 f9 11 02 9d
74 e3 5b d8 41 56 c5 63 56 88 " ++ printf
"%02x" (0xbc + n)
                        | otherwise                = "
                 [ redacted ]                  "

main :: IO ()
main = putStr magic

Update: I received a Kindle for Christmas (will blog Kindle vs Nook soon). It turns out the Kindle automatically wraps PRE tags, and the above CSS ruins that wrap. To reiterate, Nook books require explicit PRE wrapping, but that same explicit wrapping destroys Kindle’s excellent autowrap.