Table of Contents

Copyright Statement and Ebook License

Chapter 1: Pre-requisites

Chapter 2: A Whirlwind Overview

Chapter 3: Ebook Development Cycle

Chapter 4: Ebook Layout with CSS

Chapter 5: Porting to Kindle

Chapter 6: Workflow and Debugging

Appendix A: Manual Ebook Creation

Appendix B: NCX Navigation Control

Appendix C: Font Embedding

Appendix D: XHTML vs HTML

Appendix E: Character Entity References

Index

Copyright Statement and Ebook License

This ebook is provided for the exclusive use of the purchaser or licensee.

Huw Thomas and Velluminous Press have published this ebook without any DRM (digital rights management) because we respect your right to access the ebooks you have purchased, today and in the future. Please respect our rights too, by ensuring that the copy you are reading is properly licensed:

1. If you have obtained an unlicensed copy of this ebook and wish to read it, you must buy a license.

2. If you wish to give a copy of this ebook as a gift to someone else, you must buy them a license.

You can purchase a license for this ebook at www.velluminous.com

Copyright © Huw Thomas 2010. All Rights Reserved.

Version 1.1

Chapter 1: Pre-requisites

This book is aimed at ebook designers targeting ePub and Kindle, who must work at code level. That can mean building your content from scratch with a text editor, or it can mean hand-tuning ebook files that have been exported from a word processor or page layout program, to produce an ebook that’s as attractive, usable and portable as possible.

To use this book, you’ll need familiarity with basic computing tasks such as downloading, unzipping, installing and configuring software, and:

1. A text editor to prepare the various files that will go into your ebook.

2. A web browser to preview the results of changes you make to your book content.

3. Software to compile your content into an ePub or Kindle ebook that can be loaded onto the targeted e-reader devices and software.

4. Validation software to confirm that your ePub files are structurally correct.

5. E-reader devices and software to test the ePub and Kindle ebooks you generate.

6. Basic familiarity with (or a willingness to learn) web-development technologies such as HTML/XHTML and CSS.

I’ll discuss each of these requirements in turn, below.

Text Editor

Creating ebooks has a lot in common with creating web pages, so if you’ve done any web development you may already have a preferred coding environment – but any text editor will do, including the one that probably came free with your operating system.

In fact, plain text editors have the advantage that they don’t mess with your code, unlike specialist web design programs that sometimes think they know better than you. Controlling the details is important because e-reading systems are less standardized than web-browsers, and the fact that an ebook layout looks good in the preview pane of a web-authoring program, doesn’t guarantee anything once it’s been transferred to a reader.

Web Browser

Despite the fact that web browsers can’t give you a perfect preview, they’re still the most convenient way to get an idea of how a particular page looks, without having to generate an ebook each time you make a change. If you have enough screen real-estate, a comfortable way to work is to have a browser window open for preview, and an editor window open for making changes.

Ebook Compiler

The ebook compiler used in this book is eCub, a free, easy-to-use, cross-platform ebook compiler. You can download it from the website of its creator – juliansmart.com. While you’re there, check out his other ebook- and writing-related software. If you want to generate Kindle ebooks as well as ePubs, you’ll need a program called kindlegen, which can be downloaded from within eCub as explained in Chapter 3.

ePub vs Kindle

While the opening chapters of this book focus on ePub, it would be foolish to ignore another important format – Kindle – that can be leveraged using the same files and tools. However, ePub and Kindle require different approaches: with ePub you must separate style from content, while Kindle often demands that you combine them. Chapter 5 addresses the challenge of ePub - Kindle portability, and shows one approach to maintaining a single set of source files that can generate both formats.

Validation Software

Any errors in the files you use to build an ePub project will be reflected in the ePub file itself, so it’s wise to run the final product through validation software to ensure it’s internally correct. Like kindlegen, this software can be downloaded from within the eCub program.

Test Devices and Software

One of the most intractable problems that you face as an ebook designer, is ensuring that your book looks good (or is at least usable) on a wide range of e-readers.

Unfortunately, standardization is patchy, with a variety of device-specific quirks. It’s impossible to cater for the vagaries of every conceivable current and future e-reader, so there’s a lot to be said for the pragmatic, sanity-preserving approach of prioritizing formats and devices according to how important they are for your project.

For example, iPad users have access to both ePub (via iBooks or Stanza) and Kindle formats, so if your book works well in iBooks and Stanza, you don’t necessarily want to put a lot of effort into working around quirks that only exist on the iPad Kindle reader. On the other hand, problems on an actual Kindle device are more serious, because the user doesn’t have the option to read the ePub instead.

That doesn’t mean ignoring other platforms, but it does mean being aware that sometimes there’s a trade-off to be made; that your time and effort are best applied to areas where you and your customers will realize the most benefit; and that sometimes you reach a point of diminishing returns.

Here’s a possible test strategy:

1. As you work, continually preview your results in a web browser.

2. Once you’ve compiled your book, run it past the ePub validation software and fix any errors or warnings.

3. Check the ePub version on the Firefox web browser (download the EPUBReader plug-in).

4. Check the ePub version on iBooks, using whatever Apple platforms you’re targeting. Unfortunately, at the time of writing I’m not aware of any preview software for the iPad or other Apple devices.

5. Don’t forget Stanza, which renders differently from iBooks even on the same platform.

6. Check the ePub version using Adobe Digital Editions (ADE) on a Windows or Mac OS X computer. Among other things, testing with ADE helps ensure that your ePub meets the file-size limitations that are built in to Adobe-based devices. If you have access to an Adobe-based device such as a Sony Reader, by all means test on it.

7. You can test your Kindle ebook layouts using Amazon’s software-based Kindle Previewer, while bearing in mind that the subtler aspects (such as tone and contrast) of Kindle’s reflective e-ink display can’t be duplicated on a regular computer monitor. The Previewer has the advantage of being able to simulate various Kindle models and versions, including Kindle for iPhone. You can also test on a real Kindle if you have access to one, and on the various software-based Kindle/Mobi readers that are available from Amazon and others.

8. Calibre, which is actually a multi-purpose ebook management, conversion and viewing system, is also a valuable test-bed for previewing ebooks.

Skills

The ebook creation techniques covered here are based on XHTML and CSS coding, and it will be helpful if you have at least some familiarity with these technologies. If not, consider following the tutorials at w3schools.com which are a great way to get up to speed or to brush up rusty skills:

- XHTML Tutorials

- CSS Tutorials

If you’re familiar with CSS rules and understand what they do, or if you’re willing to consult tutorials such as the ones listed above when needed, then you should be fine. One thing to watch out for is that ebooks are coded in XHTML, which is slightly different from HTML (though the fundamentals and most of the syntax is the same – see Appendix D for a summary of the differences).

Important!

If you’re already an experienced CSS designer, be aware that several things that you’d hope would work across all ePub readers, don’t. In general the best approach is to test (on all the platforms you’re targeting) any slightly exotic CSS feature that you plan to use, before committing to a design based on that feature. See Chapter 4 for information on the features and quirks of a number of CSS properties that are particularly applicable to ebook layout.

Chapter 2: A Whirlwind Overview

Note to CSS Experts

This chapter provides a crash or refresher course in XHTML markup and CSS styling. If you already have a good knowledge of these then you might wish to skip or skim it, and proceed to the next chapter which is where you can get your hands dirty with installing the ebook development environment, and modifying and compiling code.

Imagine that you have some text that’s to be converted into ePub format (this chapter primarily concerns ePub; I’ll cover Kindle conversion in Chapter 5):

The Hound of the Baskervilles

Sir Arthur Conan Doyle

Chapter 1

Mr. Sherlock Holmes

Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table. I stood upon the hearth-rug and picked up the stick which our visitor had left behind him the night before. It was a fine, thick piece of wood, bulbous-headed, of the sort which is known as a "Penang lawyer." Just under the head was a broad silver band nearly an inch across. "To James Mortimer, M.R.C.S., from his friends of the C.C.H.," was engraved upon it, with the date "1884." It was just such a stick as the old-fashioned family practitioner used to carry–dignified, solid, and reassuring.

“Well, Watson, what do you make of it?”

Holmes was sitting with his back to me, and I had given him no sign of my occupation.

“How did you know what I was doing? I believe you have eyes in the back of your head.”

You can see several elements that must be dealt with here: firstly the book title, then the author’s name, a chapter heading, a sub-title, and finally a block of text. You could just feed the whole thing into an ebook-reader, but it would come out pretty much as you see it above – far different from the typography and layout that most human readers would prefer.

There are two main tasks involved in turning raw text into formatted ebook content that displays well on a variety of systems and devices:

1. Tagging or marking-up each item to identify what kind of component it represents within the book (‘Chapter 1’ is a component that we might call a chapter-title, for example).

2. Styling each component to control how it appears (we might decide to center chapter-title components between the left and right margins, and set them in a bold typeface, for example).

The first task – tagging or mark-up– is handled by XHTML. The second task – styling – is handled by CSS. In the remainder of this chapter I will give a brief, example-driven overview of these two tasks, enough to offer a flavor of what’s involved. I’ll delve deeper into specific aspects of XHTML and CSS in later chapters, but in the meantime remember that this book is not a tutorial or reference on either technology – there are plenty of existing sources for those things.

Tagging with XHTML Mark-up

Examine the (partial) listing shown (as you can see, the headers have been truncated to minimize screen clutter; you can download a template file with the full headers from:
www.velluminous.com/heb).

<?xml version="1.0".../>

<!DOCTYPE html.../>

<html xmlns=.../>

<head>

<meta http-equiv.../>

<title>Chapter 1</title>

<link href="ebook.css" rel="stylesheet" type="text/css"/>

</head>

<body>

<div>

<h1>The Hound of the Baskervilles</h1>

<h2>Sir Arthur Conan Doyle</h2>

<h3>Chapter 1</h3>

<h4>Mr. Sherlock Holmes.</h4>

<p>Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table...</p>

<p>"Well, Watson, what do you make of it?"/p>

<p>Holmes was sitting with his back to me, and I had given him no sign of my occupation./p>

<p>"How did you know what I was doing? I believe you have eyes in the back of your head."</p>

</div>

</body>

</html>

Let’s zoom in to the actual content. Here’s the relevant part of the code…

<h1>The Hound of the Baskervilles</h1>

<h2>Sir Arthur Conan Doyle</h2>

<h3>Chapter 1</h3>

<h4>Mr. Sherlock Holmes.</h4>

<p>Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table...</p>

<p>"Well, Watson, what do you make of it?"/p>

<p>Holmes was sitting with his back to me, and I had given him no sign of my occupation./p>

<p>"How did you know what I was doing? I believe you have eyes in the back of your head."/p>

…and here’s an example of how it might appear, once rendered by an e-reader:

The Hound of the Baskervilles

Sir Arthur Conan Doyle

Chapter 1

Mr. Sherlock Holmes

Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table...

“Well, Watson, what do you make of it?”

Holmes was sitting with his back to me, and I had given him no sign of my occupation.

“How did you know what I was doing? I believe you have eyes in the back of your head.”

Notice how the code that was tagged with <h1> ... </h1> was rendered as the main heading – Heading 1 – while the tags <p> ... </p> enclose a paragraph of body-level text.

We’ve now provided information about the role each piece of text plays in our ebook, but we haven’t yet specified how we want those roles to be rendered on-screen. Lacking this information, an e-reader will fall back on defaults: headings of a certain size, body text indented in a certain way, and so on.

If you care about how your ebook looks, these defaults are unlikely to be satisfactory and you’ll want to be able to override the default ‘look-and-feel’ of each particular reader. This is where the second major task of ebook layout –styling – comes in.

Styling with CSS definitions

Before going further, let’s look at a refined version of the XHTML file from before, updated to override the default styling. This has been done by inserting class="..." references to each element whose appearance we wish to change. The styling applied by these overrides is specified (separately) by rules that define the desired visual properties of each class.

<h1 class="booktitle">The Hound of the Baskervilles</h1>

<h2 class="author">Sir Arthur Conan Doyle</h2>

<h3 class="chapter">Chapter 1</h3>

<h4 class="subhead">Mr. Sherlock Holmes.</h4>

<p class="body1">Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table...</p>

With the mark-up in place, the next question is: where do we define these visual properties? The answer is found in the XHTML header at the top of the file (among the lines that I truncated above). Specifically, it’s the line of code that reads:

<link href="ebook.css" rel="stylesheet" type="text/css"/>

which indicates that the styling information is to be found in a file called ebook.css.

Taken together, the above coding tells the e-reader that in order to render the book title, ‘The Hound of the Baskervilles’, instead of relying on its own preprogrammed notion of what a <h1> ... </h1> element is, it should check in the style sheet file ebook.css, for the book designer’s definition of what should be done with a h1.booktitle element; and similarly for the others: h2.author, h3.chapter, h4.subhead, and p.body1.

You’re free to use your own style sheet filename, as long your header references that file. Also, when working with eCub projects, choose file names that will remain distinct even when the file-type extensions (such as .css or .html) have been stripped off. For example, if you have a style sheet called ebook.css, avoid having a content file called ebook.html in the same project folder.

Warning!

By default, the eCub ebook compiler generates (and may overwrite, unless configured not to) a style sheet called style.css in the main project directory. Because of this, you may wish to avoid this name for your own custom style sheets.

You can also embed your CSS style sheet directly in your main XHTML file, but that’s not recommended as it stops you from sharing the same style sheet between several XHTML files. In this book, I will assume that all style sheets are stored in external files.

To get a flavor of what CSS can do, let’s examine the CSS rules that were used to style the Sherlock Holmes example output (commentary is interspersed between each entry). Firstly, here is the example output again, as rendered by your current e-reader :

The Hound of the Baskervilles

Sir Arthur Conan Doyle

Chapter 1

Mr. Sherlock Holmes

Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table...

“Well, Watson, what do you make of it?”

Holmes was sitting with his back to me, and I had given him no sign of my occupation.

“How did you know what I was doing? I believe you have eyes in the back of your head.”

And here is each segment of the CSS:

body {

font-family:Caslon, Palatino, serif;

font-size:medium;

font-weight:normal;

}

The body rule sets up several CSS properties that (unless subsequently overridden) apply to everything tagged <body> ... </body> – in other words, everything in the body of your XHTML file. So, the font we're requesting for this ePub will be Caslon, Palatino, or a fallback serif family. We're also asking for a medium-sized font, and a normal (not bold) font weight.

h1.booktitle {

font-size:100%;

font-variant:small-caps;

font-weight:bold;

text-align:center;

margin:0 0 0.5em 0;

}

The h1.booktitle rule controls how the book title, tagged <h1 class = "booktitle"> ... </h1>, will appear. The font will be sized at 100% of the base font size; the text will be displayed in small caps if available, and bolded; it will be centered between the left and right margins; and a 0.5em bottom margin will be applied (the four numbers that follow the margin keyword define top, right, bottom, and left margins respectively).

Ems and Relative Measurements

Traditionally derived from the width of the capital ‘M’, in modern usage the em corresponds to the point size of the current font. With 12pt text, one em = 12 points; with 20pt text, one em = 20 points. This scalability means that if the user switches to a different font size, the size of the em alters to match. Using relative measurements like ems or percentages, instead of absolute ones like points or pixels, means your design spacings will shrink or expand as needed to cope with different user selections.

h2.author {

font-size:90%;

font-weight:bold;

text-align:center;

margin:0 0 0.5em 0;

}

The h2.author rule controls how the author’s name will appear: sized at 90% of the base font size, bold, centered, and with the same margin settings as those used for the book title.

h3.chapter {

font-size:80%;

font-weight:bold;

text-align:center;

margin:0;

}

The h3.chapter rule controls how chapter titles will appear: sized at 80% of the base font size, bold, centered, and with zero margin all round.

h4.subhead {

font-size:70%;

font-style:italic;

text-align:center;

margin:0;

}

The h4.subhead rule controls how chapter subheadings will appear: sized at 70% of the base font size, italic, centered, and with zero margin all round.

p.body1 {

font-size:70%;

margin:0;

text-indent:0;

}

p.body2 {

font-size:70%;

margin:0;

text-indent:0.5em;

}

These two CSS rules control how the initial paragraph (tagged <p class = "body1"> ... </p>) and subsequent paragraphs (tagged <p class = "body2"> ... </p>) will appear. Both are displayed at 70% of the base font size, and with zero margins. The only difference is that initial paragraphs (such as the first paragraph in a chapter) are not indented; subsequent paragraphs are set off by a 0.5 em indent.

Note that the example font sizes were chosen to scale ePub output for the purposes of this chapter. Larger font sizes would be advisable for a real ebook.

Chapter 3: Ebook Development Cycle

It’s time to get down to the nuts and bolts of editing, compiling and testing your own ebooks. To do that, you’ll install and configure a development environment, set up a test project, compile it, and view the results on various programs and devices. I’ll cover each of these steps in the rest of this chapter.

Set up a Development Environment

I’ll assume that your operating system came with at least one text editor and one web browser, and that you’ll be able to choose and install alternatives to suit your own tastes, if desired.

One additional system-level component is required to run the ePub checking software: the Java Runtime Environment. This may well already be installed on your computer; if you’re not sure, open a command prompt/terminal window and enter the following command:

java -version

If you see a message similar to the following, you should be good to go:

java version "1.6.0_21"

Java(TM) SE Runtime Environment (build 1.6.0_21-b07)

Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

If not, you can download and install the software from www.java.com.

Online ePub Checking

If you don’t wish to install Java and the validation software on your computer, you can (at the time of writing) access them online through Threepress Consulting Inc’s online validator; however installing the software locally will be faster and more convenient in the long run, and is highly recommended.

Finally, make sure you’ve installed whatever software and drivers are needed to support any physical e-readers you wish to use. In my case that’s Apple’s iTunes, as well as Macroplant’s free iPhone Explorer. I also have a Kindle available for testing, but I find the Kindle Previewer to be much more convenient for rapid change-test cycles. In any case, the Kindle needs no drivers.

With the basic software environment configured, we’re left with the following components still to be installed:

- An ePub compiler – we’ll be using eCub.

- A sample book to compile and view.

- Programs to preview generated ebooks on the development computer. Since this is a limited test-bed for instructional purposes, we’ll keep things simple and restrict our test programs to the Firefox EPUBReader addon and the Kindle Previewer. For real-world testing, you’ll want more than this; I’ll offer some further suggestions when we get to installing the software.

Let’s take each item in turn.

Download and Install eCub

Download the free eCub ebook compiler from www.juliansmart.com and install it on your system. Julian Smart also offers a paid-for ebook development system called Jutoh, which is well worth a look, but I have written this book around free, basic software that works ‘close-to-the-metal’, and eCub is ideal for this. I happen to be running it on Windows 7, but it’s available for a variety of operating systems, including Mac OS X and Linux. Once you’ve successfully installed the program:

1. Run the eCub program and click the Options toolbar button to open the Preferences dialog.

2. Click the Helpers tab to open the Helper Applications panel.

Helper Applications

3. Use the links on the panel to Get Epub Checker and Get Preflight Epub Checker (not strictly needed if you’re opting to use an online validator such as the one mentioned above, but highly recommended). At the time of writing, the ePub checker files you need are:
epubcheck-1.0.5.zip and
epubpreflight-0.1.0.zip.

4. Also use the link to Get kindlegen. You’ll end up on Amazon’s web site, where you will be able to download kindlegen; while you’re there, grab Kindle Previewer as well, so it’s ready to install when the time comes.

5. Unzip both the ePub checkers and also kindlegen into a convenient directory from where they can be run.

6. Enter the paths to the ePub checkers, and to kindlegen, on the eCub Helper Applications panel.

7. Check the Use Preflight Checking box and click OK.

The eCub compiler is now ready to use.

Download the Sample Project

The sample project is located here:

www.velluminous.com/heb/xanadu.zip

Create a new, empty project directory on your desktop or somewhere else where it will be easy to access, then download and unzip the above file into it. You will now have the following three files:

- KublaKhan.html – the content that our sample book will display

- poem.css – the style sheet that will define how the content is rendered.

- cover.jpg – the cover image.

If you’re curious, take a look at the content of the files – either with a text editor, or by previewing the HTML file with a web browser.

Install Ebook Viewing Software

This tutorial relies on the two programs listed below, so install at least those. For real-world testing, install a variety of viewers to give you the coverage you need.

1. Install Kindle Previewer (the program you downloaded along with kindlegen, above) using the usual procedures for your operating system.

2. If you don’t already have Mozilla Firefox, download and install it, then use the Addons option from Firefox’s Tools menu to find and install the EPUBReader addon.

Other programs you should consider downloading for your real-world projects include Adobe Digital Editions, Amazon’s desktop-based Kindle viewer, Calibre, Mobipocket Reader, and possibly Sony Reader Library (Adobe-based).

Note for Linux Users

Adobe Digital Editions is currently available for Windows and Mac OS X, but Linux users have reported success in running it under WINE.

Configure and Compile the Sample Project

Our next task is to create an eCub project that contains the above files, so that we can compile them into ePub format.

1. If eCub is not already running, start it up.

2. Click the New button, or select File, New...

3. The New Project Wizard opens:

Create New eCub Project

4. Fill in at least the compulsory details: Book Title, Identifier, and Author. In this case we’re entering the title in the Identifier field, but it can be any unique identifier – if you already publish a print edition of the book, then you can use its ISBN. The description in this case comes from Wikipedia.

5. Click Next> to proceed to the Project Location dialog:

Project Location

6. Enter the desired ePub file name and the path to the project folder, and activate the check boxes corresponding to the formats you wish to create. In this case, we want to create both ePub and Mobipocket (Kindle) formats, so check both boxes, then click Next> to proceed to the Choose Import Method dialog:

Choose Import Method

7. We’ll be adding our files manually, so select From Scratch (an intially empty project). Then click Next> to proceed to the Cover Design dialog:

Cover Design

8. Select Use an Existing File and click Finish to exit the New Project Wizard.

9. eCub creates the new project and keeps it open. There are a couple more options to configure, so click the Edit button to open the Project Properties dialog and select the Files tab:

Project Properties (Files)

10. The CSS for the sample project is stored in poem.css so enter that file name. Similarly, enter the name of the cover image file – cover.jpg. Next, select the Options tab:

Project Properties (Options)

11. The only change here is to clear the Generate CSS File check box, since we’re providing our own style sheet. Once that’s done, click OK to close the Project Properties dialog.

12. We need to tell eCub which files should be in the project. On the main eCub screen, make sure the Files tab is open, and click the + button to open a file selection dialog.

13. Add these files: poem.css and KublaKhan.html. Be aware that the file selection dialog only shows HTML files by default, so in order to see image files you’d need to select ‘All files (*.*)’ from the drop-down menu.

14. Once the files have been loaded into the project, highlight Kubla Khan in the Files list and select a Guide type of text to indicate that this is the beginning of our short book. If we had additional files such as a foreword or glossary, we’d tag them too.

15. Click Save to update the stored project information.

16. Click the Compile button. If everything is configured correctly, you’ll see the compilation run and two files will be generated: KublaKhan.epub and KublaKhan.mobi.

Content Ordering

eCub handles navigation at the level of XHTML files, so in larger projects it’s best to place each chapter in its own file. Initial navigation headings are taken from each file’s <title> element. To re-order files within eCub, use the up- and down-arrow buttons below the file list. The current release of eCub doesn’t support drag-and-drop re-ordering, however if you select an entry in the list before clicking the + button, additions will appear immediately after that entry.

Preview the Compiled Ebooks

Preview KublaKhan.epub using the Firefox EPUBViewer addon, and KublaKhan.mobi using the Kindle Previewer. Notice how EPUBViewer handles the indentation from the original poem properly, while Kindle Previewer (as of version 1.0, at least) doesn’t. If the EPUBViewer display looks strange, check the addin’s Preferences and make sure everything is set to As Defined in Book.

The reason for the difference between Kindle and EPUBViewer is that Kindle’s CSS support is relatively limited, with a significant amount of formatting for that device being done in-line, rather than separated out into a style sheet. Conversely, the ePub validators throw errors if they encounter in-line formatting, forcing you to use CSS if your files are to be ePub-compliant.

So unless and until Kindle’s CSS support becomes more compatible with ePub, we’re going to be stuck with having to make Kindle-specific tweaks to our ebooks. That’s unfortunate, but remember that Kindle support is a freebie in the first place, courtesy of kindlegen. They are two separate formats, so it’s hardly surprising that they’d have somewhat different formatting requirements. Chapter 5 discusses this issue further.

The various ePub platforms have their bugs and quirks too, but the work-arounds can generally coexist with one another: the code that fixes an idiosyncracy in iBooks doesn’t stop Stanza or Adobe Digital Editions from working properly. The main thing is to identify and understand the idiosyncracies of each platform, so that you can side-step them. That’s another subject I’ll be revisiting later in this book.

In the meantime, let’s take a look at the files of the sample project, to get an idea of what the CSS does.

Modify, Re-compile, and Re-test The Sample Project

Start your text editor and open poem.css, which is the sample ebook’s style sheet. Take particular note of the TOC (Table-of-Contents) rules at the bottom of the file; these are used by eCub to style TOC entries, and since we stopped the program from creating a CSS file, we need to manually include its TOC styling in our own. The other interesting parts are the paragraph definitions:

div.poempage {

max-width:30em;

}

p.line {

text-indent: -1em !important;

margin:0 0 0 1em !important;

}

p.line-indented {

text-indent: 0em !important;

margin:0 0 0 2em !important;

}

p.line-marginbelow {

text-indent: -1em !important;

margin:0 0 1em 1em !important;

}

CSS !important

The !important declaration is intended to prevent the rule from being overridden by unruly e-reader devices. Use with care at higher CSS levels, since an !important setting within your h3 definition might stop a desired override in your h3.title definition. Please consult a CSS reference book or website for more information on !important and on CSS hierarchies.

If you study the XHTML file along with the EPUBReader output, you’ll notice that there are:

- lines that are set flush-left (tagged in the XHTML file with p.line)

- lines that are set off (indented) compared to the regular lines (tagged with p.line-indented)

- and end-of-stanza lines, which have some vertical space to separate them from the next stanza (tagged with p.line-marginbelow).

(If there had been any indented lines that also needed a line-break, I would have had to create a fourth rule, perhaps named something like p.line-indented-marginbelow, though in a real project you’d be wise to choose a more compact naming scheme).

The CSS properties used in these definitions are:

text-indent:

Specifies the indentation of the first line in a text block. Note that p.line has negative indentation of -1em.

margin:

Specifies the top, right, bottom and left margins respectively (if only a single number is given, it applies to all four margins). Note that the margin setting for p.line will neutralize the previously-set negative indentation for the first rendered line, and then force a 1em margin for subsequent rendered lines if there are any, i.e. if a line of poetry wraps – which it may well, if it’s displayed on a tiny cellphone screen or similar device.

max-width:

Specifies the maximum width that this element can take up. The whole poem is wrapped in <div> ... </div> tags that use this property to limit the width of the display to 30ems on large screens; mainly this is to prevent the title and author elements from wandering too far away from the left-aligned text.

The easiest way to see these indent and margin settings in action, is to re-size your Firefox EPUBReader window to give the display less width. Notice how lines are indented to indicate that they’ve wrapped, while still preserving the distinction between indentation due to wrapping, and indentation due to typesetting.

Try changing the indents and margins in the style sheet. Experiment with the negative indent and the compensating margin to see how they interact. Save your changes, recompile the project and view the results. Change the font size in EPUBReader to see how the em-based indentation scales itself to match.

If you wish, change the measurements in the style sheet from ems to pixels or points, and re-test to to see how things change with these non-scalable design choices.

Another area where you might wish to experiment is with eCub’s cover design features. The program provides a default cover based on the image provided, but the Cover toolbar button will take you to a form where you can design your own cover, import images, and so on. Since it’s all quite straightforward, I won’t go into further detail.

Future Kindle CSS Support?

If the sample project works properly on a contemporary (as you read this) Kindle, then parts of the preceding discussion won’t make much sense. However, that’s actually good news because it means the Kindle’s CSS support has been upgraded since the publication of this book.

Chapter 4: ePub Layout with CSS

In this chapter, we’ll take a look at a number of CSS properties that perform common ePub-layout tasks such as positioning elements and controlling the white-space between them, specifying typefaces and styles, and so on, while also noting significant CSS quirks displayed by various ePub readers. I’ll mention some important aspects of Kindle portability, but please note that the majority of information in this chapter refers to ePub, not Kindle.

Before we go further, a word about the standards that define CSS, and that define the kind of CSS that can ‘properly’ be used in ePub documents. The latest standards can be found at:

1. CSS Specifications from w3.org – CSS as used on the world-wide web.

2. OPS Specifications from idpf.org – the part of the ePub specification that deals with the subset of CSS that’s supposed to be implemented by ePub readers.

Unfortunately, manufacturer support for the Open Publication Structure (OPS) standard is still patchy, and there are a number of glitches and quirks that are best addressed by using CSS from outside the OPS standard. So it’s not possible, in my view, to produce complex ebooks that limit themselves strictly to the OPS standard, while also working well on current devices. Standards-sticklers can relax, however: there is a get-out clause. The OPS standard explicitly allows the use of CSS that it doesn’t include, it merely stipulates that ePub readers that don’t implement that CSS, should handle it gracefully. So, if you use some non-standard CSS to work around a glitch on iBooks or Adobe, you shouldn’t have to worry about the impact on other ePub readers.

It’s worth glancing over the standard, to get a feel for what’s officially included.

Putting things in Boxes

CSS layout and positioning is based on a box model. There are plenty of good resources explaining this elsewhere – for example:

- Box Model Article at wikibooks

- Box Model Article at w3schools.com

In case you want to jump straight in, here’s the executive overview:

- Everything you put on a page of your ePub sits inside a notional box or enclosing rectangle.

- Boxes can be styled so as to make them visible, or they can remain invisible, revealed only by their layout-effects.

- The positioning of boxes and the white space between them can be controlled.

- The positioning of the content inside a box, and the white space between the content and the edge of the box, can also be controlled.

- Boxes can contain other boxes in a nested hierarchy.

The following example shows a simple hierarchy, in which ‘parent’ box 1 encloses ‘child’ boxes 2 and 3. The underlying CSS tries to render the two child-boxes side-by-side, though this breaks down on narrow screens or large font sizes. This is worth bearing in mind when designing layouts that rely on a particular horizontal arrangement – a design that allows content to flow naturally might look less impressive on a big screen, but it can work better on the multitude of devices it encounters in the real-world. By all means make things look good on iPad, but don’t lose sight of how many iPhones there are out there.

1

2

3

CSS Box Hierarchy

Block and Inline Elements

The elements that make up a particular page, whether they’re paragraphs, divisions, images, or anything else, will render with default sizes and positions. Each element has a display: property, which controls how it is rendered. For ebook designers, the most important display: properties are:

- block elements take up the full available width and force a following line-break, so that the subsequent element is always rendered below its predecessor. Examples: paragraphs, headings, and list items.

- inline elements only take up as much of the available width as they need, and do not force a following line-break, so that the subsequent element may be rendered to the right of its predecessor, if there’s enough space. Examples: images, spanned classes, and anchors.

- inline-block elements are positioned as if they were inline, while being rendered as a block element. In ebook terms, the most significant use of this display: value (which is omitted from the current OPS specification) is in overcoming certain iBooks quirks – more later.

It’s possible to override the default display: behavior of an element. Look at the default (inline) behavior of the following images (each digit is a separate image file, and unlike the images elsewhere in this book, the only coding involved is the <img.../> tag itself):

Let’s style them with the following rule…

img.force-display-block {

display:block;

margin:0;

}

…which we’ll apply to each image as follows:

<img class="force-display-block" src="img/1.png" alt="1"/>

<img class="force-display-block" src="img/2.png" alt="2"/>

<img class="force-display-block" src="img/3.png" alt="3"/>

As you can see, the images’ default behavior has been overridden: each one now displays on a new line. (Kindle readers: the preceding discussion is not entirely true in your case; I used Kindle-specific coding to duplicate what you’d see on an ePub reader. The same goes for several examples in this chapter, where Kindle doesn’t support the CSS required to demonstrate the ePub mechanism I’m discussing. See Chapter 5 for more details of porting your ePub files to Kindle).

If you’re wondering why I didn’t use an XHTML division (see the immediately following section) to apply the above styling, the answer is that the display: property is not inherited; it has to be applied to the specific element that you wish to affect, not to a parent element. This makes sense because when it comes to display:, the default behavior is almost always what you want.

Boxing Content with the <div> Tag

The <div> tag encloses blocks of XHTML, which are then treated as boxed divisions to which CSS formatting can be applied. For example, if you have the following rule in your style sheet…

div.framed {

font-size:0.9em;

background-color:#f0f0f0;

border:1px;

border-style:solid;

}

…then any elements you enclose within <div class = "framed" > ... </div> will be framed as follows:

This paragraph has been turned into a division by wrapping it inside <div class = "framed"> ... </div> tags, so it is styled according to the settings shown immediately above.

Cramped <div> framing

The content has been set off from its surrounding text, but the example settings have not produced a particularly attractive frame. To improve things, we’d need to tweak other properties such as margins and padding.

Margins and Padding

Here’s a modified version of the previous framed code, with some breathing space added…

div.framed-spaced {

font-size:0.9em;

background-color:#f0f0f0;

border:1px;

border-style:solid;

margin 2em 2em 0 2em;

padding 1em;

}

…and this is how the above rule works on your current ePub reader. As you can see, it has more breathing space, both between the text and the framed edge of the element (padding), and outside the border’s element (margin). The bottom margin is set at zero to avoid pushing the caption away.

Spacious <div> framing

The CSS properties responsible for these changes are:

margin:

This is the same property that we saw in Chapter 3, controlling paragraph margins when setting poetry. In this example, it’s being used to control the external margins of the frame. Recall that the four parameters specify the top, right, bottom and left margins respectively (think of it as going clockwise from twelve-o’clock, through three, six and nine-o’clock).

When working with ebooks, you should use top margins with care. Some e-readers render top-margin even at the top of a page, creating spurious white space. That’s potentially problematic, and is a subject I’ll return to later.

padding:

This property controls internal spacing that pads out the element within its border, so in our example it’s providing the extra space between the text and the frame.

Both properties use the same syntax, so you could write margin:1em; if you wanted a 1em all-round margin, rather than controlling each side individually. You can also use properties such as margin-left: and padding-top: if you want to control any single aspect of an element’s margin or padding. For full details, see your usual CSS references.

Rounded Frame Corners

The example frames had square corners, but you can request rounded corners if you like (specify the desired radius in each case):

border-radius:0.5em;

-webkit-border-radius:0.5em;

-moz-border-radius:0.5em;

Using all three variants ensures that your request will be honored on as wide a range of platforms as possible.

Tagging and Styling Headings

Headings should be based on the appropriate XHTML heading tags: <h1>, <h2>, <h3>, <h4>, <h5>, and <h6>. If you create ‘fake’ headings based on body-level tags (which might happen without your direct knowledge if you export your XHTML and CSS from a word processor or page layout program) then some e-readers will insist on treating your headings as body text, with corresponding restrictions placed on the styling you can perform.

Kindle Heading Size Quirk

Look at the following screenshots based on the same XHTML and CSS, captured from an ePub reader and then from Kindle Previewer:

Heading Scaling on ePub

Heading Scaling on Kindle

Here’s the CSS that generated the above displays:

body {

font-size:medium;

font-weight:normal;

}

h1.sizetest {font-size:100%; }

h2.sizetest {font-size:90%; }

h3.sizetest {font-size:80%; }

h4.sizetest {font-size:70%; }

h5.sizetest {font-size:60%; }

h6.sizetest {font-size:50%; }

Why are the displays so different? The answer becomes plain if we re-run the test, but with all sizes set to 100% (I’ll only show the results, and not the amended CSS, since the change is trivial).

Headings at 100% on ePub

Headings at 100% on Kindle

Both system are scaling the fonts relative to something; the difference lies in what that something is. The ePub viewer follows CSS standards by scaling relative to the parent element – the medium font size specified in the <body> definition. By contrast, the Kindle seems to scale its headings according to its internal definitions of the default size for each heading, without reference to any parent element.

This difference is only significant when you convert an ebook designed for ePub into Kindle format, and the font scaling you’ve used for headings turns out not to work acceptably well. If you test your heading choices on Kindle as you design your ePub layout, you’ll save yourself the trouble of having to make Kindle-specific changes in this area when it comes time to generate that format.

Styling and Positioning Text

This section introduces several CSS properties that are used with ePubs to style and position text. If you need more information on any of the properties described in this section, please see your usual CSS reference or the following w3schools.com tutorials:

- Fonts

- Text

Selecting and Styling Fonts

The following CSS properties apply to fonts and styling or decorating text:

font-family:

Selects fonts and font families.

font-weight:

Selects font weights such as bold, bolder or lighter.

font-style:

Controls the style of text – italic, oblique or normal.

font-size:

Controls the size of text – the value can be set in several ways, including: xx-small, x-small, small, medium, large, x-large, xx-large; or smaller or larger (than the parent element size); or as a percentage (eg 120%) of the parent element size; or as an absolute length such as 16pt.

font-variant:

Use the value small-caps to style text with the Small Caps variant.

text-decoration:

Use the values underline, overline, or line-through to apply the corresponding text decoration.

text-color:

Controls text color (many e-readers currently lack color displays, so use with care, keeping in mind how readable your text will be when rendered in grayscale). A common way to specify color is in hexadecimal red-green-blue form: #rrggbb.

Here’s a sample CSS rule that changes various font settings, followed by a filler paragraph that I’ve tagged so that you can see how the rule is rendered on your system.

p.example-font-control {

font-family:Arial, Verdana, Helvetica, "Franklin Gothic", sans-serif;

font-size:small;

font-weight:bold;

font-style:italic;

}

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Example Font Control

iBooks Font Quirk

If you happen to look at the above sample output in iBooks (as of version 1.1.2 and with a serif font selected from the iBooks Fonts menu), you’ll see that the request for a non-serif font has not been honored, and it turns out that iBooks honors the user’s selection for body text, rather than the book designer’s font-family: choice.

E-reader restrictions on what book designers can do with body text are not uncommon, and there are good reasons for them. If you override user-control inappropriately, your ebook runs the risk of becoming memorable for its failure to respect the user’s preferred settings, rather than for its content.

Still, there will be times when you need to enforce a font-choice, and then you can use one of the so-called ‘phrase tags’, which are tags that apply semantic mark-up to HTML:

- <em> – emphasized text

- <strong> – strong text

- <dfn> – definition text

- <code> – computer code

- <samp> – sample computer code

- <kbd> – keyboard text

- <var> – variable text

- <cite> – citation.

To set computer code, you could define the <code> tag as:

code {font-family: Courier, "Courier New", monospace;}

which lets you style sections of code like this:

<code>here is some sample code</code>

Although this usage is aimed at iBooks, the underlying phrase-tag mechanism is required by the OPS specification, so the same technique should work on all compliant ePub readers. Arguably, it’s better to tag code with <code> rather than with an arbitrary paragraph rule. But you can also add paragraph styling if you prefer a belt-and-braces approach or if you also need to apply context-dependent styling such as code indentation:

p.code-indent-1 {text-indent:2em !important;}

p.code-indent-2 {text-indent:4em !important;}

...

<p class="code-indent-1"><code>outer block</code></p>

<p class="code-indent-2"><code>inner block (indented)</code></p>

<p class="code-indent-1"><code>outer block</code></p>

Respecting Tag Semantics

In the previous example, choosing <code> kept the usage in line with the purpose of the tag. In general, when using these tags to work around a particular ePub reader’s restrictions, try to stay faithful to the intended tag semantics.

Positioning Text

The following CSS properties apply to the formatting and laying-out of ebook text. I’ll give some examples after the list, but in the meantime, for full details of the syntax and usage of these properties, please consult a suitable CSS reference such as w3schools.com.

text-align:

Controls text alignment: left, right, centered or justified. Certain e-readers resist applying this property to body text, preferring to keep the user (or their own defaults) in control. See the discussion in the section Body-text Alignment Quirks, below.

text-indent:

Controls the indentation of the first line of a paragraph. As with text-align:, some e-readers resist changes to this property.

line-height:

Controls the amount of vertical space that each line takes.

letter-spacing:

Controls the spacing between characters.

Let’s make a CSS rule that will test out most of the above properties, and then try it on a few ePub readers.

p.example-text-styling {

text-indent:2em;

text-decoration:underline;

line-height:1.5em;

letter-spacing:0.25em;

}

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Example text styling: current e-reader

Example text styling: iBooks

Example text styling: Stanza

Example text styling: Adobe Digital Editions

Note how the readers differ in how well they follow the rule. Stanza has not honored the requested line height, and has also kept its own default indentation, for example, while Adobe Digital Editions has ignored the requested letter spacing. Some or all of these issues could have been overcome by using !important in the CSS rule.

Another area of difference is in hyphenation: Stanza is the only reader that has attempted to hyphenate the text.

Digression: Justification and Hyphenation

At the time of writing, most e-reading platforms are not capable of automatic hyphenation, which has led to a debate about whether ebook text should be forcibly left-aligned, rather than justified.

The issue arises because in the absence of hyphenation, the only way for an e-reader to justify text is through adjusting the spacing within each line – and excessive variation in spacing leads to a more fatiguing reading experience. This problem is at its worst with narrow screens and larger font sizes, but even on an iPad with its large screen, justified text in iBooks can be more fatiguing to read than it ought to be, because of this lack of hyphenation.

There are a number of approaches to dealing with this:

Forcing Left-Alignment

You can force body text to be left-aligned with a ragged right-margin, rather than justified. This removes the need for hyphenation.

Using Soft-Hyphenation

You can insert soft hyphens – & shy; – into your body text, showing where hyphenation should occur. For example:

Mr. Sher& shy;lock Holmes, who was usu& shy;ally...

This would require a prohibitive amount of work if done manually, however there are free and open-source hyphenation tools that can insert the coding for you, including an on-line service at the time of writing.

But before investing a lot of time into this approach, you should be aware of some major drawbacks:

1. In my tests, I found that while the current version of Adobe Digital Editions (ADE) broke hyphenated words appropriately when justifying text, it failed to render the hyphens.

2. Both ADE and iBooks currently treat the soft-hyphen as being significant during searches, meaning that soft-hyphenated words will never be found through those e-readers’ search systems.

3. Kindle currently displays soft-hyphens like regular hyphens, irrespective of line breaks.

There may be cases where the benefits of soft-hyphenation outweigh these drawbacks. For example, soft-hyphenation in table headings and text can dramatically improve the appearance of XHTML- and CSS-based tables on narrow screens, while future versions of iBooks and ADE might remove the drawbacks altogether. Or even better, those future versions might implement their own internal hyphenation dictionaries.

Leaving the Choice to the User

The first option I discussed – removing the need for hyphenation by forcing left-alignment and a ragged right-margin – also removes control from the user. Taking the iPad/iBooks example, the user can normally (and may well expect to be able to) turn full-justification on or off in the iPad’s system settings. Enforcing a particular alignment for body text breaks this part of the iPad/iBooks user interface.

My own preference is to leave this decision with the user – and more generally, to avoid intrusive design features simply to work around software limitations that may well disappear in future. But this is an issue where there are strongly differing views, and in the end you must make your own choice.

Body-text Alignment Quirks

Certain e-readers, including iBooks and Stanza, tend to resist arbitrary alterations to the alignment of body text, a design-decision that makes sense in the context of the preceding discussion. Use the following guidelines if you wish to override the default treatment of body text on these platforms:

1. First, consider whether a heading-based style might be more appropriate to your purpose. A centered quotation or a line of poetry is clearly body text; a caption is a kind of heading.

2. Assuming your centered text really is body text, then add the !important modifier to the rule. When centering, force the text-indent: property to be zero, since some e-readers apply default paragraph indentation that will throw the centering off.

3. As of version 1.1.2 of iBooks, !important still doesn't center body text. You can work around this by wrapping the text with dummy <span> ... </span> tags, which causes the centering rule to be obeyed.

p.example-centered {

text-align:center !important;

text-indent:0 !important;

}

...

<p class="example-centered"><span>centered text</span></p>

iBooks Update: experiment suggests that iBooks for iPad only overrides alignment of what it considers to be the major body text style within a particular XHTML file. It seems to determine this from the proportion in which different styles have been used in the file, with the most-used paragraph style being considered as body text, while lesser-used styles can be aligned without resorting to the above work-around. This is quite clever – perhaps too clever, because it makes presentation dependent on content; adding or deleting paragraphs can change the interpretation of your CSS. If you rely on this feature, be sure to test your ePub on an iPad to make sure it works as expected, and bear in that the decision appears to be made on a file-by-file basis, rather than across an entire book.

Centering a <div> element

You can apply text alignment to a <div> element, but not every reader will apply that rule to body text inside the <div>. To center body text within a <div>, apply the centering as close as possible to its target – by styling the <p> tag itself.

Here’s an example of a paragraph styled with the example-centered rule, as rendered by your current reader:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Body-text centering on your current reader

Widows, Orphans and Page Breaks

CSS provides two properties called widows: and orphans: that control how paragraphs are split across pages.

- Orphaned lines are stranded at the end of a page, with the rest of their paragraph on the next page.

- Widowed lines are stranded at the top of a page, with the rest of their paragraph on the previous page.

Both widows: and orphans: have a default value of two, meaning that at least two lines will be widowed or orphaned together, with a line being shifted from the previous or next page if needed to avoid isolating a line by itself.

Since the default values are sensible, you won't normally need to worry about setting these properties, but be aware that not every e-reader supports them.

A related consideration is how page breaks are handled between adjacent elements, such as an image and its caption or a heading and the paragraph that follows it. CSS provides several properties to control this behavior, the most important being:

page-break-after:

Controls page breaks occurring after the element. Use a value of avoid with elements such as headings, which should not be stranded at the bottom of a page without their accompanying text.

page-break-before:

Controls page breaks occurring before the element. Assign a value of always to this property, to request that an element always appears on a new page.

Breaking to Left/Right-Hand Page

The OPS specification includes values of left and right for the above properties, to request a break to the next left- or right-hand page. Obviously this only applies to ePub readers such as iBooks, which brings us to the following iBooks quirk…

iBooks Page Break Quirk

As of version 1.1.2, iBooks ignores the page break settings described above. To discourage page-breaks between adjacent elements, wrap them in a <div> ... </div> with a display: property of inline-block. In this book, I used the following rule to wrap elements I wanted to keep on the same page:

div.nobrk {

display:inline-block;

width:100%;

}

Of course, any scheme that seeks to control page breaks only works if the desired elements actually fit onto a single page, so your intentions in this area are less likely to be respected on small screens or with large font sizes.

Vertical Margins

The look, feel and usability of a book is greatly influenced by the designer’s use of vertical spacing. Even with a simple layout such as a typical novel, which will comprise lengthy narrative passages interspersed with a relatively small number of chapter headings and scene breaks, you’ll want to keep the spacings appropriate and consistent. With more complex and busier layouts, this task can become quite challenging. Here are some of the ‘gotchas’:

- Specifying fixed top margins in your CSS, in the expectation that those margins won’t be applied by default when the element falls at the top of a page, will lead to disappointment – at least on some e-readers.

- The CSS ‘collapsing margin’ model (which determines whether adjacent margins collapse, i.e. overlap one-another, instead of nestling against one-another) is not trivial to understand, and may be buggy in implementation.

- Adobe Digital Editions requires special attention to ensure it renders margins applied to <div> elements (see screenshots below, taken from an early version of this book while in development):

Adobe Digital Editions: Top Margin Rendered Correctly

Same File, Different Zoom/Text-Flow

My recommendations to avoid the above problems are:

- Try to avoid mixing top-margin: and bottom-margin: in your design. This eliminates any need to worry about the details and vagaries of collapsing margins.

- If Adobe Digital Editions is not honoring the margins of your <div> elements, wrap them in additional dummy (classless) <div> elements as shown below.

<div>
<div class="nobrk">
...
</div>
</div>

(The problem seems to occur with <div> elements whose display: property has been set to inline-block, so the classless division above could possibly be replaced by a classed division if necessary, provided the classed division’s display: property is set appropriately).

- Use CSS ‘Adjacent Sibling Selectors’ in your style sheet, to apply margins only when the context calls for them.

Adjacent Sibling Selectors

Adjacent Sibling Selectors enable you to write CSS rules that apply to an element if, and only if, the immediately preceding element is of a specific type:

- Adjacent – the elements are adjacent, with one immediately following the other.

- Sibling – the elements are siblings, with the same parent element.

- Selector – the adjacent siblings form the selector for a CSS rule that will be applied to the second of the siblings.

Some examples should help clarify this:

div+p {margin-top:0.5em !important;}

p+h3.title {margin-top:1em !important;}

p.body+p.body {margin-top:0 !important;}

The first rule applies a top margin of 0.5em to any <p> element that follows any <div> element. The second rule applies a top margin of 1em to any <h3 class = "title"> element that follows a <p> element. The third rule applies a top margin of zero to any <p class = "body"> element that follows another <p class = "body"> element.

This may seem more complex than the alternative of hard-coding margins into the rules defining each element, but using this model has two compelling advantages:

1. Vertical spacing can automatically adjust itself depending on the adjacent elements, giving you finer control over the look of your ebook.

2. This model correctly renders elements positioned at the top of a page, while elements with a hard-coded top margin will be rendered too far down the page on some readers (including iBooks v1.1.2).

iBooks: Unexpected Image-breaking

A side effect of the above iBooks behavior is that images can break across a page, even though they apparently fit in the available space. This happens when the top margin ‘steals’ enough of the page so that the image no longer fits, and provides another good reason not to hard-code top margins into specific CSS rules.

You can gain some extra flexibility by defining <div> rules specifically to wrap elements whose margins you want to control, for example:

div.set-off {/* dummy rule so no content here */}

*+div.set-off {margin-top:2em !important;}

(the ‘*’ character acts as a wildcard selector, so the above rules mean that content wrapped within <div class = "set-off"> ... </div> will always be set off by a distance of 2em from the preceding element. Similarly, if you encounter a reader quirk that prevents Adjacent Sibling Selector rules from being honored for a certain element, wrapping the element in a division should solve the problem.

Aligning Images

Despite its name, the text-align: property can also control the alignment of non-text elements such as images. The trick is to set the text-align: property for a <div> block, which you use as a wrapper for the images you wish to align. For example:

div.example-centered {

text-align:center !important;

}

...

<div class="example-centered">

<img src="1.png" alt="1"/>

</div>

Here’s how the result looks on your current e-reader:

You could also use text-align:right if desired, to send the image to the right-hand side of the page.

Global Margins

Before we leave the subject of positioning elements within your ePub, a word about the margins that apply to pages as a whole. You can set such margins by defining a CSS rule for the <body> tag, for example:

body {

...

margin-left:5%;

margin-right:5%;

}

If you don’t define left and right margins, your pages may appear cramped when viewed with certain ePub readers, including Adobe Digital Editions and Firefox EPUBReader. Other e-readers (including iBooks, Stanza and Kindle) ignore this setting, imposing their own margins instead. This is sensible behavior on smaller devices with limited screen real-estate; it represents a rare case of where we may actually need certain ePub readers to ignore our CSS.

Drop-Caps and the float: Property

The CSS float: property lets you remove an element from the normal flow of ePub rendering, shifting them to either left or right, so that other elements can flow around them. With this, you can do things like wrapping text around images (assuming your target reader has the screen space for this), and using drop-caps for chapter openings. I'll use the latter to illustrate how to work with the float: property, since even the smallest usable screen has enough space to show a drop-cap.

But before we begin, a word of caution: the simple-sounding statement ‘remove an element from the normal flow of rendering’ begs the question of how it will be rendered. Drop-caps only work well when they're aligned with the subsequent text; small variations can throw the effect off while large variations look horrible. Different ePub readers have their own default fonts and rendering methods, as usual, while Kindle doesn’t currently support this model at all.

So please bear in mind that while the formula we’ll develop below should produce readable results on all ePub readers, it won't look as good on all of them as it does in the screenshots. You should only use drop-caps if you're prepared for some level of compromise in this area.

Borders and Text-tweaking

I used visible borders: border-width:1px; border-style:solid; while setting up the upcoming how-to screenshots, to reveal spacing and positioning as clearly as possible. However, the borders themselves take up some space, so if you use this technique, you may need to do some extra tweaking once you turn them off.

Before we delve into the CSS, let’s take a look at the properties involved. The first two shown below are at the heart of this method of rendering drop-caps:

float:

This property specifies whether an element should float within its containing block. A drop-cap letter is floated to the left of its paragraph, which then flows around it.

line-height:

This property specifies the total height of each line. The total height includes:

- the height of the text itself

- the vertical spacing or ‘leading’ between adjacent lines.

Increasing this property adds extra vertical spacing (the so-called ‘leading’) above and below the rendered type, so that individual lines move further apart. The opposite also applies. If the line height is reduced far enough, then there will be no leading and the descenders from one line will collide with the risers from the line below. If it’s reduced further, the lines will begin to overwrite one another. A typical default line-height: would be around 1.2ems.

height:

This property also specifies the height of an element. Unlike line-height:, it's not specific to text, knows nothing of leading, and makes no attempt to render text with spacing above and below. I don't use it in the model presented below, but you might come across drop-cap techniques that rely on it, so I've listed it here for completeness.

Here's the line of text we'll be using, tagged in readiness for its drop-cap:

<p class="dropcap"><span class="drop-letter">T</span>here was an old woman who lived in a shoe; she had so many children she didn't know what to do.</p>

From this you can see that we need a dropcap rule to tag the whole paragraph, and a drop-letter rule to tag the drop-cap. What we're doing here is quite fiddly, so let’s take it from the top. Here are the initial CSS rules:

p {

line-height:1.2em !important;

}

p.dropcap {

text-indent:0em !important;

margin:0 !important;

}

span.drop-letter {

border-width:1px;

border-style:solid;

}

They don't do much at the moment, apart from defining some basic settings, and drawing borders around the drop-cap as a tuning/debugging aid. The text-indent:0em !important; rule is to suppress Stanza’s default indentation. As yet, we’re not attempting to enlarge or position the drop-cap character. Before we do so, let's look at the output of our basic ‘scene-setting’ rules.

Drop-Cap - Step 0

To turn the initial letter into a drop-cap, we need to remove it from the normal flow of its containing paragraph. As mentioned above, this is done by using the float: property.

span.drop-letter {

border-width:1px;

border-style:solid;

float:left;

}

We haven’t re-sized the character yet, but it’s been cut loose from the rest of the containing paragraph’s text, and is now floating at the left of the paragraph. You will see in the next screenshot how the second line of text has been pushed over, because the bounding box of the floating ‘T’ character extends down into the space that the line’s top-leading would normally occupy.

You might have to look closely to see it, but floating the character has also nudged it down by a pixel or two (I tried several readers, and each rendered the floated character in a slightly different place or with a slightly altered bounding box. This should begin to explain why drop-caps are so difficult to keep consistent across different platforms).

Drop-Cap - Step 1

Let’s resize the character and zoom in for a closer look at the result.

span.drop-letter {

border-width:1px;

border-style:solid;

float:left;

font-size:285%;

}

Drop-Cap - Step 2

Oops. What’s happened here? Recall that our base paragraph rule contains the following line:

line-height:1.2em !important;

By setting that property for the base paragraph class, we ensure our chosen value gets inherited by all other paragraph-based styles (which is exactly what we want, since we’d like paragraphs to look consistent). But it also means that our enlarged drop-cap still has a line-height: of 1.2em, the same as the adjacent, smaller text. In this case, the rendering engine has tried to center the letter in the available vertical space, but the precise alignment can vary between fonts and systems.

We’ll set the new line height in ems, not forgetting that the em measurement is relative to the newly enlarged font size. Choosing a good value takes some trial and error, but the following guidelines apply:

- Larger values extend the box downward, eventually displacing lines to the right and rendering the drop-cap too far down the page.

- Smaller values shrink the box upward, eventually pulling lines to the left and rendering the drop-cap too far up the page.

With the settings we’ve chosen, and considering the target ePub readers and their default fonts, it turns out that a value of 0.8em works quite well.

span.drop-letter {

border-width:1px;

border-style:solid;

float:left;

font-size:285%;

line-height:0.8em;

}

Drop-Cap - Step 3

Finally, we need to remove the visible border and tweak the top margin (because the character moves slightly, taking up the space vacated by the now-invisible border).

span.drop-letter {

float:left;

font-size:285%;

line-height:0.8em;

margin-top:0.02em;

}

Drop-Cap - Step 4

The screenshots so far have all been from Firefox EPUBReader with its default font (on my Windows system) of Times New Roman. Here’s how the final example renders on the other targeted ePub readers:

Drop-Cap - iBooks (Baskerville - default font)

Drop-Cap - Stanza on iPad (Palatino - default font)

Drop-Cap - Adobe Digital Editions

The worst results from among this small sample seem to be with Palatino. Here’s a zoomed screenshot from iBooks with Palatino selected from the font menu. You can see the drop-cap is visibly (though perhaps not horribly) misaligned. Other fonts on other e-readers will potentially be much worse.

Drop-Cap - iBooks (Palatino)

Why is this happening? We can control the drop-cap’s bounding box, but we can’t control how the rendering engine and font interact to display the character within that box. With Palatino on the iPad ePub readers, the cross-bar of the ‘T’ character is rendered partially outside its bounding box. We could compensate for this, but only at the cost of making the other fonts look worse.

We could also try to force the use of a suitable font by using font-family: in the drop-letter rule, with a list of fonts that we believe will work acceptable well:

span.drop-letter {

font-family: "Times New Roman" ... serif !important;

float:left;

font-size:285%;

line-height:0.8em;

margin-top:0.02em;

}

However, there’s no guarantee that a particular ePub reader will honor this request (for example, recall that iBooks resists font changes that override user-settings unless you apply the previously-explained work-around). There’s also no guarantee that your chosen font will work well with the font in which the remainder of the text is displayed.

You could address this latter problem by taking control of the font used for the rest of the body text, too. However, the same argument applies here as before: such enforcement (even if honored by a particular e-reader) breaks an important feature – user-selectable fonts – that human readers may have grown to expect, and which they could use themselves to solve the Palatino problem.

Drop-Caps: Following up with Small-Caps

Book designers sometimes use the small-caps font variant to style the initial line (or the first few words) of a drop-cap paragraph. You can achieve the same effect in an ePub by wrapping the first few words within <span> ... </span> tags that apply the required styling. However, this static approach might break down on narrow displays, where your small-cap text could wrap beyond the first line, so if you use this technique, it’s best to limit yourself to a fairly small number of words.

A more adaptable approach is to style the paragraph’s entire first line, by creating a separate CSS rule using the first-line pseudo-element. The syntax is as follows:

p.dropcap:first-line {font-variant:small-caps;}

With the above rule in place, the first line of any paragraph tagged with <p class = "dropcap"> will be rendered in small caps on e-readers that support this CSS. Be aware that this use of small-caps substantially changes the look-and-feel of your drop-cap paragraphs; if you wish to use it, then it might be better to make this decision before putting a lot of effort into tuning other aspects of your design.

The first-letter Pseudo-Property

This pseudo-property is similar to first-line but it applies to a paragraph’s first character. In principle you could use it instead of <span>, to tag drop-caps. The advantage is that the first word will then be searchable. However, first-letter (like first-line) is not universally supported, and you’d still need to resort to <span> for the kind of fine-tuning I discuss below.

Drop-Caps: Per-Letter Tuning

If you’re going to use drop-caps in an ebook, you might as well do as elegant as job of it as possible. Consider the following screenshot:

Ahead or a head?

The slope of the ‘A’ character has created an apparent break within the word ‘Ahead’. A similar problem can happen with ‘L’ and to some extent, with ‘I’.

Passages that begin with one-letter words such as ‘A’ ‘I’ or ‘O’ (used as an exclamation) can also cause confusion because the space character gets ‘orphaned’ when the drop-cap is floated, and may not be rendered.

Both of these issues can be dealt with by creating rules that control the left margin of the letter that follows the drop-cap. The following rule reduces the space between the leading ‘A’ and the rest of the word(I’ve bolded the characters that are of particular interest):

span.drop-A-continued-word {

margin-left:-0.3em;

}

<p class="dropcap"><span class="drop-letter">A</span><span class="drop-A-continued-word">h</span>ead must be rendered in this paragraph as a single word.</p>

Note the negative left-margin, which nudges the second part of the word back toward the drop-cap by 0.3em. The following rule deals with the opposite problem of an inter-word space not being rendered, by pushing the subsequent word away from the drop-cap by 0.2em:

span.drop-A-new-word {

margin-left:0.2em;

}

<p class="dropcap"><span class="drop-letter">A</span><span class="drop-A-new-word">n</span>ew word receives additional space.</p>

To implement a complete drop-cap scheme, you’d need to create similar rules for the other letters that have odd spacing requirements, too, and then test against your targeted e-readers and fonts.

There's one last oddball drop-cap that I'll discuss: the letter ‘Q’, which can take up more vertical space than other drop-caps because of its relatively long tail. The easiest way to deal with this is to choose a smaller font size:

span.drop-letter-q {

float:left;

font-size:260%;

line-height:0.8em;

}

Drop-Caps: Dealing with Quote Marks

When using a drop-cap in a paragraph that begins with dialogue or a quotation, you have two characters to deal with: the opening punctuation, and the drop-cap letter itself.

The simple approach – treating the quote mark as part of the drop-cap by jamming them together in the same <span> ... </span> – is not ideal since the quote mark will then look over-sized; you’ll get better results if you tune it separately.

Here’s our previous example, with a typographic quote mark (& lsquo;) added and a new rule to handle it:

<p class="dropcap">

<span class="drop-quote">& lsquo;</span>

<span class="drop-letter">T</span>

here was an old woman who...

</p>

...

span.drop-quote {

float:left;

margin-top:0.06em;

}

Here’s a screenshot showing the result from iBooks with it’s default font:

Quoted Drop-cap - iBooks (Baskerville)

Drop-Caps: A Final Word

Before leaving this subject, I want to re-iterate that the results depend at least as much on the font used, as they do on the ePub reader. Asking questions such as, ‘Do my drop-caps look good in iBooks?’, is not the most sensible query when, as we've seen, different fonts can give very different results on the same reader. Compromise, with some devices and fonts being emhpasized over others, is inevitable in this area.

Chapter 5: Porting to Kindle

As we saw in Chapter 3, the eCub compiler – combined with Amazon’s kindlegen conversion program – is capable of converting your ePub project into Kindle format. The results of a straight conversion will depend on how complex your layout is and what CSS features you used. While it’s possible that a simple click of eCub’s Compile button will produce usable results, getting your book to look as good as possible on Kindle is probably going to take some work.

To get a sense of what’s involved, consult the latest version of the Amazon document, Amazon Kindle Publishing Guidelines. At the time of writing, you can access this from the main Amazon Kindle Publishing Page, along with kindlegen and Kindle Previewer. The document contains a large number of guidelines that you might already have broken (and rightly so – there’s no reason to restrict your ePubs to what Kindle supports; if you did, you’d never write a CSS rule that specified a font).

Also in the document is a list of supported HTML tags and formatting, which I won’t reproduce here as you’ll be better served by downloading the most up-to-date list from Amazon. As for CSS, all the current guidelines say is that there is ‘very basic support’ and that ‘if you do not obtain the desired behavior using CSS, try using inline HTML tags instead’.

That being the case, it would be optimistic to expect great results from a software-based ePub conversion. If you followed the instructions in Chapter 3, you’ll already be set up to generate Kindle (.mobi) files and probably have one ready. If not, set up your development environment now and generate what will be the first-cut of your ebook’s Kindle version. Depending on what test environment you plan to use, either load it onto a Kindle, or check it with the Kindle Previewer.

If you didn’t have an idea of what to expect, the results would almost certainly be disappointing.

Some CSS is ignored by Kindle; some actually messes things up. The chances are that most of your ePub CSS will be nothing more than dead-weight to a Kindle version of your ebook. So I recommend providing a different, Kindle-specific CSS file. A simple way to handle this is to have three CSS files, for example:

1. ebook.css, the CSS file referenced from your XHTML content files.

2. epub.css, the full, ePub-specific CSS file.

3. kindle.css, a Kindle-specific (possibly empty, possibly stripped down) version of the full ePub CSS file, from which all rules that create problems for Kindle have been removed, and additional rules needed to support Kindle have been inserted.

Then, copy the contents of the appropriate platform-specific file into the ebook.css file, before running eCub to generate either an ePub or Kindle file.

Note

When running eCub to generate a Kindle ebook, be aware that it also generates an intermediate ePub file as part of the process. Since this ePub may contain undesired Kindle-specific formatting, ensure that your real ePub file is not overwritten, by copying it to a different folder or regenerating it after you’re done with the Kindle version.

Some Kindle Formatting Tips

If you wish to port anything more than the simplest ePub layout on Kindle, you’ll probably need to revise your XHTML files, adding Kindle-specific styling to your content. In doing so, you don’t want to mess up your ePub content, so later in this chapter, I’ll show you how to get that Kindle styling out again. But before we get to that, let’s take a look at some Kindle-specific formatting:

Margins

Kindle understands simple CSS margins such as:

h3 {margin-bottom:1em;}

Unfortunately, it doesn’t yet support the Adjacent Sibling Selector model, and it renders top margin even at the top of the page, so I recommend that when you have a choice, you prefer bottom margin. You can also (and will probably need to) hand-code margins in your XHTML content:

<p style="margin-bottom:1em">

I find it useful to add an extra ‘dummy’ property that does nothing beyond acting as a signpost to Kindle-specific changes:

<p style="margin-bottom:1em;kindle:1">

Requests for fine adjustments are not currently honored, with positioning being restricted to a grid apparently based on the current line height. Margins of 1em, 2em and so on work as expected, but fractional ems are rounded up or down.

Paragraph Indentation

By default, Kindle indents every body paragraph. This is how I forced the first paragraph of each section in the Kindle version of this book to be flush-left:

<p class="body" style="text-indent:0;kindle:1">

The first part, class = "body", refers to a rule in the ePub-specific CSS style sheet, and is not used by Kindle. Again, note that I tagged the change with the dummy kindle:1 property, to make life easier later when using this file to create the ePub rather than the Kindle version of the book.

Setting off Content

Borders and shading such as I used in the ePub version of this book are not supported on Kindle, and the recommended way to set off content is to use horizontal rules (<hr/>) above and below.

You can also set paragraphs off by indenting them compared to the surrounding text:

<p style="left-margin:5%;kindle:1">

Right margins do not seem to be supported at the moment. Also, if you specify a left margin, any top margin you also specify for that paragraph is apparently ignored, however this is not a major problem since it’s generally better to use bottom margins anyway.

Finally, you can set off brief sections by varying text styling, for example by setting text in italics with <em> ... </em>.. It’s best to avoid over-using this kind of thing, since it can affect readability.

Text Alignment

The Kindle Guidelines discourage text alignment, but you can override the default alignment (justified) on specific paragraphs:

<p style="text-align:left;kindle:1">

Drop Caps

The ePub drop-cap model from Chapter 4 doesn’t work on Kindle. If you’re using drop-caps, be sure to remove the related rules from the Kindle-specific CSS style sheet, otherwise you’ll get odd looking results.

Inline Coding vs CSS

When preparing an ebook for Kindle, you’re faced with a choice that’s largely made for you with ePub: should you mix formatting with your XHTML content, or should you try to move it into your kindle.css file? It’s possible to imagine a scheme in which a significant amount of shared formatting is performed by CSS, using style sheets that share their naming schemes but differ in implementation. To take a simple example:

(kindle.css)

p.lastpara {margin-bottom:1em;}

(epub.css)

p.lastpara {margin-bottom:0.5em;}

Here, two identically-named rules apply the same basic formatting, while also respecting Kindle’s limitation of only being able to adjust spacing by whole numbers of ems.

There’s a clear benefit here: you don’t have to worry about the corresponding margins when porting from ePub to Kindle. The trade-off is that you’ve had to restrict your ePub formatting to a ‘lowest common denominator’ supported by Kindle. At the time of writing, you wouldn’t be able to use Adjacent Sibling Selectors, for example. Also, given Kindle’s current level of CSS support, you wouldn’t be able to eliminate inline formatting altogether.

I’m going to avoid making a specific recommendation here, because I haven’t personally made fully common CSS style sheets for the two formats; such a project is beyond the scope of this book. However, if I had to prepare several complex titles with similar formatting, I’d certainly spend some time investigating whether a common CSS scheme might handle as much formatting as possible on both platforms.

Using the Kindle Previewer

The Kindle Previewer can currently simulate the ebook display of the following devices and programs:

- Kindle

- Kindle DX

- Kindle for iPhone

- Kindle for iPad

- Custom.

The Kindle, Kindle DX and Custom settings seem to differ only in the screen size, and most likely use the same rendering engine behind the scenes. The Kindle for iPhone and iPad settings produce significantly different rendering and a buggier display, and while the ‘Gold Standard’ is inarguably the display produced on an actual Kindle, it’s worth at least checking how your book will look, if viewed on these non-native readers.

Maintaining Common Source Files

The need to move at least some Kindle styling into your XHTML source files raises the prospect that you could end up with two sets of files: one for ePub and one for Kindle, with duplicate content but different styling methods.

This might not seem so bad with a single ebook that you don’t ever intend to update, but for many projects – including all the ones that you don’t think you’ll need to change, but end up needing to – having a second set of source files just means more headaches as you try (and occasionally, forget) to keep the versions in sync.

So it’s usually better to grasp the nettle from the outset, by inserting Kindle formatting in a way that can be made compatible with your existing ePub files.

There are several ways in which you could approach this problem. I’ll show you one of the simplest. Imagine that we’ve written a rule called shaded-box that defines a background color, padding and border to make the centered content stand out within its own shaded box. Using the rule in an ePub should be familiar by now:

<div class="shaded-box">

<p class="centered"><span>This is the box content.</span></p>

</div>

As I mentioned earlier, the current Kindle guidelines state that borders and background colors cannot be set, and they make no mention of padding at all. Therefore we can’t expect the shaded-box formatting to work, and we either have to accept that the content will look like regular text, or find another way to set it off. Let’s follow the recommendation from the guidelines, and use <hr/> to create horizontal rules above and below the text that is to be differentiated:

<hr/>

<div class="shaded-box">

<p class="centered"><span>This is the box content.</span></p>

</div>

<hr/>

(Recall that the <span> ... </span> in the example code is required to force iBooks to center the body text). Here’s how the above coding displays on Kindle Previewer:

Setting Off Kindle Content

That sets the content off from surrounding text, but I mentioned that the ePub rule centered the text, so this still isn’t quite right. Let’s tweak the formatting, applying the recommended method from the Kindle Guidelines:

<hr/>

<div class="shaded-box">

<p class="centered"><center><span>This is the box content.</span></center></p>

</div>

<hr/>

Now it’s properly centered, and as good as a result as we’re likely to get, given the limitations of the device:

Setting Off Kindle Content, Centered

We’ve solved this particular Kindle formatting problem, but now we have Kindle formatting embedded in the XHTML file. The <hr/> elements will render in any ePub we generate from this file, and <center> ... </center> is not ePub compliant and will trigger epubcheck warnings. We need a way to generate a ‘clean’ version of the file for ePub, while still being able to work with the modified version for Kindle. In terms of our example, we need to be able to automatically generate a new file from this one, with every instance of each of the following tags deleted:

- <hr/>

- <center>

- </center>.

If any of the above strings exist in the file apart from as Kindle modifications (whether as metadata, styling or content), then a straightforward automated removal will delete them too. If this is a problem, it could be solved by adding XHTML comments to provide extra hints to the automated conversion tool we’re about to configure. For example, if the ePub used <hr/> for its own purposes, then we could tag the Kindle-specific additions as follows:

<hr/><!--kindle-->

<div class="shaded-box">

<p class="centered"><center><span>This is the box content.</span></center></p>

</div>

<hr/><!--kindle-->

Now we can ensure that only the tagged instances of <hr/> are automatically removed.

The final puzzle piece (once you’ve been through the lengthy process of testing your initial book on Kindle, finding the instances where the ePub formatting fails, and correcting them by adding Kindle-compliant styling) is the automatic removal of the Kindle-specific tags. There are several possible approaches to this; if you already have a working system for automatic text processing then by all means use it. The method I will discuss here is based on a freely available text processing program called sed.

Digression: Using the Command Line

I’m going to be discussing the use of command-line tools, which enable simple, efficient and powerful text processing on all of today’s popular desktop operating systems: Windows, Mac OS X, and Linux. The idea of using the command line can seem intimidating if you’re not used to it, but there’s no real justification for that: if you can master the ideas behind CSS, then you can master the art of typing commands into a terminal window. The payoff is the ability to share your source files between ePub and Kindle; the choice about whether to take that payoff is yours.

There are many online tutorials available to help you master your operating system’s command line, and also numerous commercially published books. If you own a book about your operating system with words like ‘Bible’ or ‘Missing Manual’ in the title, then you might already have the material you need.

If you really object to leaving the comfort of point-and-click behind, you might find that the search-and-replace facility of a word processor or programmer’s text-editor could be a usable alternative, as long as the program offers editable scripts or macros to automate the process. Such software tends to be operating-system specific, and also dependant on each user’s preferences and pocket, so I won’t be exploring that subject any further.

Stripping out Kindle Formatting with sed

sed is a stream editor that can:

1. read a stream of text (such as an XHTML file that contains Kindle formatting)

2. apply editing rules to each line of text (rules that we will write to strip the Kindle formatting)

3. write the edited stream of text to a new file (which will be the clean ePub version of the file).

Here is a sample sed rule:

s%search-string%replacement-string%

Without such a rule, sed would simply copy its input to its output, but provided with our example rule, it would also substitute the first occurrence on any line of search-string, replacing it with replacement-string. If we wanted to replace all occurrences, rather than just the first one on each line, we’d append g (stands for global) to the rule, thus:

s%search-string%replacement-string%g

If our search string contained a ‘%’ character, we could either use a different character to delimit the search and replacement strings (probably the simplest option), or we could protect the ‘%’ in the search string by prepending it with ‘\’. These two alternatives are both shown below:

s/%/percent/g

s%\%%percent%g

It’s possible to specify other options, but that’s the basic syntax, and all we need for our relatively simple task of stripping Kindle formatting to automatically generate an ePub file.

How to get sed

If you’re on a Unix-derived system such as MacOS X or Linux, sed should already be installed and available from the command line. If you’re on Windows, you can download an open-source version from the GnuWin project, and install it in a suitable location.

Returning to our previous example, recall that we needed to strip the following tags out of our source file:

- <hr/> if it’s immediately followed by <!--kindle-->

- <center>

- </center>.

With this scheme, we’re free to use <hr/> in our ePub files if we wish, since only Kindle-specific occurrences will be stripped. We can’t use <center> ... </center>, unless we take similar measures for those tags too, but since ePub centering is done with CSS, that’s unlikely to be a concern. For a real-world project, you’d obviously need to define additional rules to handle any other Kindle-specific formatting you’ve used, but the essentials would remain the same.

Here is a sed script that removes the tags we’re targeting in this example:

s%<hr/><!--kindle-->%%g

s%<center>%%g

s%</center>%%g

I chose ‘%’ as a delimiter character because it doesn’t occur in any of the tags to be removed, obviously a character like ‘/’ or ‘!’ would have been more awkward. Let’s try the script out now:

1. Enter the example script into a text file and save it in a convenient empty folder under the name StripKindle.sed

2. Copy one of your XHTML files to the folder (or create a new XHTML file there) and add some tags such as <center> ... </center> to center text, and some horizontal rules with <hr/>. Tag some of the horizontal rules by appending them with the <!--kindle--> comment. Save the file as StripKindleTest.html.

3. Open a command window and change directory (cd) to the folder where your files are stored.

4. Enter the following command (which must be entered as a single line even though it might have wrapped on your display):

sed -f StripKindle.sed StripKindleTest.html > ePubVersion.html

You should now have a new file called ePubVersion.html (which will be overwritten each time you run the command), containing a stripped (of Kindle-formatting) copy of your StripKindleTest.html file. In a real-world project, the stripped file would go to build your ePub ebook, while the original file would perhaps be processed by a different sed script to generate a Kindle version. The unstripped version remains the ‘master’ copy that’s kept up-to-date; the ePub and Kindle versions are re-generated each time they’re needed.

Regular Expressions and Pattern Matching

sed isn’t restricted to matching specific strings, you can use it to delete arbitrary text that matches a pattern you specify. This is extremely useful because, among other things, it lets you tag entire lines as being Kindle-only or ePub-only. Then, when running sed to prepare for a Kindle compilation, you can make it remove all the ePub-specific lines, and vice-versa. Here are a couple of example rules:

s%^<!--epub-->.*%%g

s% style=".*;kindle:1">%>%

Note that the ‘^’ character matches the beginning of a line; the ‘.’ character is a wildcard that can stand for any single character; while the ‘*’ character stands for any number of repetitions of the previous character. So, ‘^xyz’ matches ‘xyz’ as long as it’s at the beginning of a line; ‘.*’ matches any string; and:

- The first of the example commands deletes the content of any line that begins with <!--epub-->, in other words we can use that comment to tag ePub-specific lines that we want removed in their entirety when generating a Kindle ebook.

- The second example deletes text such as style="...;kindle:1", in other words it removes Kindle-specific formatting applied at paragraph level. Note how the kindle: pseudo property helps ensure that only Kindle-specific formatting is affected.

When using this kind of technique, you need to choose your codings and rules carefully bearing your subject matter in mind, to ensure that you don’t inadvertently strip out content as well as formatting. Using <!--kindle--> is a much better idea than using something like [kindle], not only because the former doesn’t invalidate your source XHTML file, but also since its string representation would have to be encoded differently if it were to appear in your content rather than your markup.

Take particular care when using pattern patching, since sed performs ‘greedy’ matching. If we tried to use the following rule to strip out Kindle-specific paragraph formatting:

s% style=".*;kindle:1"%%

then the input line shown below would undergo deletion as indicated:

<p style="text-indent:1em;kindle:1">This line contains the text ";kindle:1"</p>

because sed matches the second occurrence of the text ;kindle:1". The rule I showed you earlier doesn’t suffer from this problem because it matches the closing angle bracket (>) too, which would be encoded as & gt; within XHTML content and thus would not be matched. Even so, take particular care when using sedwith wildcards. Make sure that each XHTML element that contains Kindle formatting appears on its own line, and keep your deletion rules in mind as you create your content.

sed Not Found?

If your system can’t find sed, check your PATH environment variable. On Mac OS X and Linux, sed is installed somewhere like /usr/bin and on your path by default. On Windows, check PATH in your Environment Variables, under the Advanced Section of your Control Panel’s System Settings.

That concludes the briefest introduction to sed, but the program is capable of much more, and once you’ve learned it, you may well find it useful for many other text processing tasks. Bruce Barnett’s ‘Sed - An Introduction and Tutorial’ is a great resource for expanding your knowledge of this venerable, versatile text-processing tool.

Portable File Organization

If you use sed or a similar tool as outlined here, you need to keep your source files separate from the files that sed generates and that are used in your eCub project. One scheme would be to have 1.html, 2.htmland so on as the source files that you edit directly, and chapter01.html, chapter02.html and so on as the files generated by sed, containing Kindle or ePub content as appropriate. Take care always to edit the master files and not the generated files, otherwise your changes will be lost.

You’ll probably also want to use the script, batch-file or make facilities of your operating system to automate the preparation of the Kindle or ePub files, along the lines of:

- make_kindle - a script that runs sed on each source file to generate Kindle versions of the eCub project XHTML files, and also copies the Kindle CSS style sheet into the style sheet referenced by those files.

- make_epub - a script that runs sed on each source file to generate ePub versions of the eCub project XHTML files, and also copies the ePub CSS style sheet into the style sheet referenced by those files.

Finally, if your Kindle project uses different files from your ePub project (Kindle-specific images, for example) then you’ll want to create a separate eCub project for the Kindle version, with each project receiving only the files that it actually uses.

Chapter 6: Workflow and Debugging

In this chapter I will offer some advice on making your edit-compile-test cycle go more smoothly, and will also cover some ‘gotchas’ you might encounter while setting up eCub projects. I’ll also offer some guidance on how to track down problems in your XHTML.

Use Browser Preview

It’s useful to have a browser window open, displaying the XHTML file on which you’re currently working. If you’re using Firefox, you can usefully make the display auto-refresh by adding the following line in the <head> ... </head> section of your XHTML file:

<meta http-equiv="refresh" content="1"/>

which asks the browser to refresh the page every second; if you prefer a slower refresh rate, assign the required value in seconds to the content property. Other browsers also understand this syntax, but Firefox (as of version 3.6) has the advantage that its refresh doesn’t force the display back to the top of the file, unlike the current releases of Internet Explorer and Google Chrome. Since you’ll probably be using Firefox for its EPUBReader plugin, it’s no great hardship to use it as a basic XHTML/CSS previewer as well.

With auto-refresh in place, you can arrange your editor and browser side-by-side on your screen, and benefit from a helpful (if imperfect, given the differences between browsers and ebook readers) preview of your XHTML and CSS changes.

It’s advisable to remove the line from your XHTML header before compiling and testing your project. Failing to do so won’t stop your ePub from working, but it seems to cause slightly odd behavior on some platforms. If you’re using sed to strip out Kindle- and ePub-specific formatting as I explained in Chapter 5, then it’s easy to strip this line out too, by including the following line in the appropriate sed scripts:

s%<meta http-equiv="refresh" content="."/>%%

(since the wildcard ‘.’ matches any single character, the above sed command will work for refresh intervals of between one and nine seconds).

Check your XHTML

The HTML Tidy program provides a useful initial check for your XHTML files. If you’re using an editor that supports external tools, then it’s worth configuring it so that you can run HTML Tidy from within an editing session. This program often picks up the same errors as the ePub checker and preflight checker (accessible from eCub’s Check button), but it has the advantage of a much faster turnaround, and of pinpointing problems while your attention is directed at the file in question, rather than at the project as a whole. With Kindle projects, the Check button will produce spurious warnings concerning non-ePub-compliant coding, but it’s still worth using as it can detect genuine errors as well.

As well as using HTML Tidy, it’s worth getting into the habit of using the Check button in eCub too, particularly after you’ve compiled a new version of your project following substantial changes.

On the subject of XHTML checking: it’s important that your sed commands don’t change the line numbering between their input and output files, otherwise line numbers reported by epubcheck or other checking software will be useless to you. Instead, stick to the class of sed commands shown in this book, which leave blank lines behind rather than deleting them altogether.

Choose a Programming Editor

Any text editor will work for producing XHTML and CSS files, but for serious work it’s worth choosing an editor that’s oriented toward programming work, rather than general ‘Notepad-style’ use. Features such as macros and syntax highlighting save time and stress; if you consider the tag that I used to style the paragraph you’re now reading:

<p class="body" style="text-indent:0;margin-bottom:1em;kindle:1">

then you’ll see the advantage of using an editor with a macro facility that allows such strings to be entered with a few keystrokes.

Programming editors offer many other advantages, typically including more powerful (regular-expression based) search-and-replace, integration of external tools, browser integration, and more.

Streamline the iBooks Development Cycle

The official way to transfer ePub files to an Apple device such as an iPhone or an iPad is via Apple’s iTunes program. Unfortunately, syncing iBooks content via iTunes slows down the edit-transfer-test cycle considerably.

The best solution I have found (Windows and Mac OS X only at the moment, unfortunately) is a free program called iPhone Explorer, which lets you drag individual XHTML, CSS or other content files into the iBooks folder structure, rather than having to compile your ePub and then sync the whole thing. I find it best to use this program to load iBooks content, while using iTunes to put Stanza content on the device.

Whichever method you use to load iBooks content, try to remember to close iBooks before updating its files; changing files that iBooks has open can (unsurprisingly) lead to unpredictable results. If using iTunes to load iBooks content, I recommend the following sequence:

1. Close iBooks

2. With iTunes, delete the old version of the book you’re testing, then load the new version.

3. Open iBooks to view the results.

Once or twice when pushing iTunes and iPad hard (in terms of rapid edit-test cycles), I found that iBooks got confused, as if it still had old information cached in its working memory. Running other software for a while cleared the problem.

Turn off Kindle Generation

While working on the ePub version of your ebook, there’s no reason to generate Kindle (.mobi) files, and turning the option off within eCub can make compilations run significantly faster.

Create a Test Ebook

If you create a small eCub project in its own test directory, you can use it to experiment with snippets of XHTML and CSS in isolation from any other distractions or clutter that might be introduced by other files in your main project.

Delve Deeper into eCub

When setting up the above test- (or any) eCub project as of version 1.11 of the program, be aware that path or file names (excluding extensions) are used to generate internal identifiers within the build folder, and as such certain path- and file name choices can lead to invalid ePub files.

To prevent this, avoid path or file names that differ only by file extension, and make sure they begin with alphabetic characters:

- 1.png in the project folder is problematic (produces a syntactically invalid id of 1).

- 1.png stored in an img sub-folder is okay (generated id is img_1)

- test.html and test.css in the project folder are problematic (results in identical ids).

- test.html stored in a html sub-folder, and test.css stored in a css sub-folder, are okay (generates distinct ids of test_test and css_test).

The eCub configuration used in this book takes complete control of the project’s CSS style sheet, rather than allowing eCub to generate its own style sheet. This means that eCub has no opportunity to create the entries it needs to style its generated table-of-contents (TOC):

.toc_heading {...}

.p_toc {...}

so you will need to provide the above rules in your own ePub CSS style sheet, suitably fleshed-out to provide the TOC styling you require. Alternatively, you can change your eCub configuration so that it generates its own style sheet, which will then be included in the project along with yours.

I haven’t covered every eCub feature in this book, so you may wish to explore this program further on your own. You can also investigate the files it generates in your project directory’s build sub-folder, which contains the structure and files that are zipped into the corresponding ePub file See Appendix A for more details.

Zero-in on Problems

Often, HTML Check or epubcheck will pinpoint a faulty line of code, making it fairly easy to find and correct the problem. But occasionally there will be something wrong with the structure of an XHTML file that prevents the error’s location from being reported properly.

When this happens, you need a way to locate the source of the trouble. If you’re using an editor such as Notepad++ (a free Windows editor) that understands XHTML syntax and exposes its structure, this will be quite easy. But if you’re using a more basic editor, or a programmer’s editor that’s oriented toward programming languages rather than layout, then you’ll need to conduct a methodical search for the offending line.

This kind of problem is often caused by missing </div> tags, which by their nature cannot be detected by software until the end of the file is reached, but similar problems can happen with other missing or malformed closing tags.

A well-known method that helps you zero-in on the problem is the so-called binary chop technique:

1. Create a copy of your source file and store it somewhere safe.

2. Chop out (delete) either the top or bottom half of your working content, ensuring that the remaining structure is not compromised – that you haven’t orphaned one of a pair of <div> ... </div> tags, for example, and that you didn’t delete the XHTML code that defines the file’s header or footer.

3. Re-check to see if the error still occurs.

4. If so, the problem must be in the remaining half of the file. Go back to step 2 and continue chopping and searching.

5. If not, the problem must be in the content you previously chopped. Restore that content and delete the good half instead; then go back to step 2 and continue chopping and searching.

This process of fault-finding through elimination also works in other contexts. For example, if you have a lengthy CSS rule that’s not performing as expected on one platform or another, you can use a sequence of chops and re-tests to identify where the trouble lies. This technique works just as well for finding reader bugs (as in, the particular piece of CSS that they can’t handle properly) as it does for finding bugs in your own code.

When investigating mismatched opening and closing <div> tags, it can also be helpful to see how the tags match up and nest within one another. Again, some editors can handle this automatically. But if you’re using a programmer’s editor that isn’t HTML-aware but that supports bracket matching, then you may find the following procedure helpful when tracking down mismatched tags in a long file:

1. Create a copy of your source file and store it somewhere safe.

2. Choose a bracket variant – for example, ( ), [ ], or { } – that’s otherwise unused in your source file, and that works with your text editor’s bracket matching. If all the bracket variants are already used, globally replace one of the variants within your source file, to ‘get it out of the way’.

3. Use search-and-replace to globally prepend your chosen opening bracket to every occurrence of <div. Note: you also want to change occurrences of <div class = "...">, which is why <div> is not used as the search pattern. This is safe as long as you have only used this sequence of characters within actual <div> tags.

4. Use search-and-replace to globally append your chosen closing bracket to every occurrence of </div>.

5. All your <div> ... </div> elements are now wrapped within brackets, exposing the structure of your XHTML to your text editor’s bracket matching feature, which can be used to check whether the actual <div> nesting in your file, corresponds to what you believe it to be.

Here’s a fragment of a file that’s been through the above process:

{<div class="nobrkH">

{<div class="nobrk">

...

</div>}

</div>}

Of course, the source file won’t be compilable until you’ve removed the brackets again (though if you modified the search-and-replace slightly to wrap the brackets within HTML comments, then this limitation could also be removed).

Appendix A: Manual Ebook Generation

Once you’ve run eCub to compile your ebook, your project folder will contain a build sub-folder with all the information that ends up packaged into the final ePub file. The build folder contains a mimetype file and two further sub-folders:

- META-INF

- OPS.

If you haven’t already done so, take a few minutes to explore this structure and the files it contains. The stuff that’s of interest to us as book designers – content, formatting or presentation, and navigation information – is all stored within the OPS folder (note that while eCub calls its content folder OPS, ePubs from other sources often use alternative names, the most common being OEBPS).

An ePub file is a ZIP archive

ZIP is the compression/archiving format that’s used to package ePubs. If you rename mybook.epub to mybook.zip, you can unzip it and examine its contents, in which case you will see a folder structure similar to the one from your project’s build folder. Furthermore, if you correctly zip the contents of your build folder, and name the resulting archive with the extension .epub, you have a brand new ePub file (and have duplicated the final step that eCub performs when it compiles your project).

This leads to the possibility of tweaking the contents of your project’s build folder and re-creating the ePub file to reflect your manual changes. Appendix B and Appendix C explain how to do this in two areas: navigation, and embedded fonts.

The rest of this Appendix will explain how to zip eCub’s build folder into a valid ePub file.

ePub ZIP File Requirements

The mimetype file must not be compressed, must be the first item in the ZIP archive, and its text must start at offset 38). Don’t worry too much about these details; the procedure I give below takes care of them and you can use epubcheck to confirm that it’s worked.

I recommend a command-line version of zip, which lends itself to automation through scripts or batch files. If you use a GUI-based zip, be sure that it duplicates the effects of the commands shown below. Unix-derived systems will include a suitable zip program, or have one available on their installation media. Windows users can download a free zip program from stahlforce.com; having done so, they should install it in a suitable location on their PATH.

With zip installed and accessible, you can create an ePub from your eCub build folder as follows:

1. Open a terminal window and change directory (cd) to your project folder, then to the build folder.

2. On Windows, enter the following commands:

zip -X0 ..\mybook.epub mimetype

zip -r ..\mybook.epub META-INF OPS

On Mac OS X or Linux, enter the following commands:

zip -X0 ../mybook.epub mimetype

zip -r ../mybook.epub META-INF OPS -x \*.DS_Store

The -X0 options (note: numeric zero, not the letter ‘O’) exclude extra attributes and prevent compression from being applied to the mimetype file. The -r option recurses into folders, ensuring that deeper levels of content are added to the ePub file. The bold part of the final command is intended for Mac OS X, to prevent hidden .DS_Store files from being written into the ePub, though it does no harm on other platforms.

3. You’ll see the zip program running twice as the ePub file is created in your project directory. Change to that directory and run epubcheck on the file. The easiest way to do this is from within eCub, though for this to work you must use the same ePub file name as your eCub project uses. Otherwise, see the penultimate section of this Appendix.

4. Test your newly created file with whatever e-readers you are using.

Note that any obsolete files hanging around in your project’s build folder will be included in your newly-created ePub, so before running the above procedure you might want to delete the build folder and run eCub to re-create everything from scratch. Obsolete files might have been left from a previous version of your project, or they could be Kindle- or ePub-specific files that were written to your build folder by a previous compilation of the corresponding version.

Similarly, the zip command doesn’t recreate the target ePub archive each time, it simply updates it with new or changed content. To avoid any possibility that obsolete content gets packaged into your manually-created ePubs, move or delete the old ePub file before you create each new version.

Manual Kindle Generation

Once you’ve taken the step of creating an ePub file manually, you can no longer rely on eCub’s Kindle conversion, since eCub rebuilds an intermediate ePub file each time and would overwrite your changes.

Luckily, the kindlegen mechanism used by eCub is also accessible from the command line. Assuming that kindlegen is installed correctly and on your path, entering:

kindlegen

provides a screen of usage information, while

kindlegen book.epub

converts your newly created book.epub into its Kindle-formatted .mobi equivalent.

Manual ePub Check

Copy your ePub file (book.epub in the following example) into the folder where you installed epubcheck. Alternatively, place a copy of epubcheck in your project folder; this might well be easier in the long run. At the time of writing, the latest version of the file is named epubcheck-1.0.5.jar, which is the version assumed below. Open a command window and change directory (cd) to the appropriate folder, then enter the following command:

java -jar epubcheck-1.0.5.jar book.epub

If everything checks out, you’ll see:

Epubcheck Version 1.0.5

No errors or warnings detected

If java isn’t found, make sure the program is installed and on your search path. The epubcheck Wiki Errors page will be helpful in understanding any epubcheck errors you may receive

Running eCub from the Command Line

If you spend much time tweaking and re-zipping eCub projects, you might well end up using the script or batch-file facilities of your operating system to take some of the strain.

If so, it’s worth knowing that eCub can run from the command line, too, leading to the possibility that your scripts could be largely self-contained (though the current version of eCub pops up a ‘Success’ dialog that must be dismissed). Check the program’s built-in help for details.

Appendix B: NCX Navigation Control

Kindle and ePub books offer two complementary methods for the user to navigate through the book content:

- An XHTML-based Table-of-Contents (TOC) file that’s positioned at the beginning of the book.

- An XML NCX (Navigation Control for XML) file that maps the internal structure of the book into various levels of waypoint. This so-called ‘Nav Map’ file is included in the ebook, but the waypoints are accessed through the e-reader’s interface, rather than being exposed directly to the user as happens with the TOC.

The easiest way to understand the job that NCX files do, is to look at one in action. Here’s an example of the NCX view offered by Kindle Previewer:

Kindle Previewer NCX View

By clicking on the arrow-heads in Kindle Previewer, you can expand and collapse sections to reveal or hide nested waypoints, while double-clicking an entry navigates to the corresponding section in the book. This level of random access isn’t currently supported by real Kindles, which only allow linear traversal of the Nav Map: you can skip ahead to the next section, or back to the previous section, but the tree-like NCX view is not exposed. Various ePub readers take different approaches to waypoint navigation, too.

Taking a pragmatic view, the important thing for us is that eCub automatically generates a basic Nav Map called toc.ncx, which serves perfectly well for many projects. If you have files that sit at different navigational levels, or that should be excluded either from the Nav Map or the TOC, you can configure this on the program’s Files tab, by highlighting the relevant file and then setting the appropriate options with Level, Show in TOC, and Show in NavMap.

Also on the Files tab, you can assign guide types to your content. For example, assign the text guide type to the XHTML file that contains the beginning of your book text.

A word about eCub’s navigation model: there is no automatic way to make a TOC or Nav Map entry refer to a target inside a file; eCub expects that every referenced section will be broken out into its own source file. This approach generally suits Kindles, and projects with relatively simple navigation needs, since it maps navigation to the units (files or chapters) that humans often work with. However, if your files contain internal navigational structure you want to expose via NCX, then it falls short and you have the following options:

1. Break up your content into smaller files, each of which maps to one navigation waypoint.

2. Create a suitable toc.ncx file yourself, and use it to replace the one generated by eCub in your ePub file.

3. Find an alternative (possibly paid-for) method of compiling ePubs.

The first option is simple in principle, and because of the flexibility that eCub offers in configuring its TOC and Nav Map, you can include a chunk of information in the Nav Map without cluttering up the TOC (simply uncheck Show in TOC for such items).

However, you might not want to split your files up into overly-small chunks, not least because your project could then become more difficult to maintain. So let’s take a look at toc.ncx and examine how it might be modified and re-incorporated into an ePub file. Here is a section of the toc.ncx file that eCub generates for the ePub version of this book (the toc.ncx file lives in the OPS subfolder of an eCub project’s build folder). I have snipped the headers, title and the end of the file to reduce clutter; what you see below is the beginning of the navigation itself.

<navMap>

<navPoint id="navPoint-1" playOrder="1">

<navLabel>

<text>Table of Contents</text>

</navLabel>

<content src="TableOfContents.html" />

</navPoint>

<navPoint id="navPoint-2" playOrder="2">

<navLabel>

<text>Chapter 1: Pre-requisites</text>

</navLabel>

<content src="a0100-Chapter01.html" />

</navPoint>

<navPoint id="navPoint-3" playOrder="3">

<navLabel>

<text>Chapter 2: A Whirlwind Overview</text>

</navLabel>

<content src="a0200-Chapter02.html" />

</navPoint>

...

Each navPoint entry establishes a link between a navigation waypoint and its corresponding book content, and contains:

- an identifier (id) that must be unique, and must begin with a letter

- a sequence number (playOrder) that determines the order in which the corresponding content will be displayed when the user browses through the book

- a text label (normally the title of the linked content) that the user will see when this navPoint is displayed by an e-reader’s navigation interface

- a path name (src) that links to the target content.

We’ll focus on a single navigation unit, Chapter 1:

<navPoint id="navPoint-2" playOrder="2">

<navLabel>

<text>Chapter 1: Pre-requisites</text>

</navLabel>

<content src="a0100-Chapter01.html" />

</navPoint>

Here, the id is navPoint-2; the play order specifies that this is the second chunk of navigational content in the book (the TOC is the first chunk), the user will see the text ‘Chapter 1: Pre-requisistes’ for this navPoint, and the linked content is in the file a0100-Chapter01.html.

What’s not clear from the listing, is that additional ‘child’ navPoints can be embedded within ‘parent’ navPoints. Before I show you how to do that, here’s the heading structure from Chapter 1 of this book, that would ideally be included in the Nav Map as well as the Chapter itself:

- Text Editor

- Web Browser

- Ebook Compiler

- Validation Software

- Test Devices and Software

- Skills.

Here’s how the first of the Chapter 1 headings could be included in the Nav Map:

<navPoint id="navPoint-2" playOrder="2">

<navLabel>

<text>Chapter 1: Pre-requisites</text>

</navLabel>

<content src="a0100-Chapter01.html" />

<navPoint id="nav3" playOrder="3">

<navLabel>

<text>Text Editor</text>

</navLabel>

<content src="a0100-Chapter01.html#TextEditor"/>

</navPoint>

...(rest of Chapter 1 Nav Points would go here)...

</navPoint>

<...>

A few points to note:

- The Nav Map in your build folder is overwritten every time you recompile your eCub project. Be sure to keep your customized toc.ncx file somewhere safe.

- You must enter suitable destination targets into the appropriate source files using the usual XHTML syntax, for example: <a id = "TextEditor"> </a>.

- Ensure that you allocate unique navPoint ids and sequential playOrders. When inserting new navPoints, you must increment all subsequent playOrders appropriately, to avoid breaking the sequence in which the navPoints appear as the user navigates through the ebook.

- navPoint ids should begin with an alphabetic character. Making the navPoint ids mirror the play order (as I did above) simplifies things and helps avoid duplication.

- Since this is a task that you only want to do once, it’s best to delay it until the final stages of a project, when the navigational structure, file names and targets have all been fully settled.

- When dealing with very large projects (or large numbers of projects) that require more complex Nav Maps than eCub supports, it may be worth seeking (or designing) an automated way of generating these.

- Kindle devices only support button-based, linear navigation through the Nav Map, which becomes fiddly and slow if the navigational units are too small. You might want to accept eCub’s defaults on a Kindle project.

- Automation is easier if you code your XHTML consistently. If you place all Nav Map headings and anchors at the beginning of their lines, while indenting other XHTML content, then it’s easy to extract navigation elements with a command-line tool such as grep:

grep "\(^<a id\) \| \(^<h3\) \| \(^<h4\)" *.html > ncx.txt

which is how I assembled the information needed to create the Nav Map for the ePub version of this book. (grep, like sed, is a Unix-derived tool that’s well-worth learning if you work a lot with text files)

Once you’ve created a customized Nav Map, use it to overwrite eCub’s automatically-generated toc.ncx file and follow the procedure from Appendix A to manually package your ePub.

Appendix C: Font Embedding

It’s possible to embed a font in an ePub file, though not every device supports this feature and it should therefore be used with caution and with justification – for example, to provide foreign-language characters that are not widely supported by e-readers. The ePub specification recommends OpenType fonts for this purpose.

Please note that you should only embed a font whose license permits re-distribution, since it’s a simple matter for a user to unzip an unencrypted ePub file and extract the embedded font.

The current version of eCub doesn’t support font embedding directly, so I will show you how to do it manually, and also offer some guidance on how to create scripts that will reduce the workload.

Before getting into the specifics of embedding fonts into an ePub, here’s a quick refresher on how to use @font-face rules to access external fonts. This is not specific to ePub, so see your usual CSS reference material for full information on how to use the @font-face rule.

Here’s the basic usage:

@font-face {

font-family:MyOrdinaryFont;

src:url(fonts/MyOrdinaryFont.otf);

}

It can be useful to explicitly state the properties of the font. For example, the following rule provides the rendering engine with a hint that it could use this font for <em> ... </em> (emphasized) text:

@font-face {

font-family:MyNonBoldItalicFont;

font-weight:normal;

font-style:italic;

src:url(fonts/MyNonBoldItalicFont.otf);

}

With the embedded font now associated with a name, it can be used like any other font:

body {font-family:MyOrdinaryFont, serif;}

Once you’ve coded your CSS and XHTML files to use an embedded font, you need to insert that font into your ePub project. Follow these steps to manually embed one or more fonts into your ePub file:

1. Delete your project’s build folder to remove any obsolete files, and then re-build it by re-compiling your eCub project.

2. Copy the required font file(s) into the OPS sub-folder of the build directory. While it’s not strictly necessary, it’s tidier to put them in their own fonts sub-folder, and that’s the procedure I’ve followed for the examples in this Appendix.

3. Manually edit the project’s content.opf (also located on the OPS folder) to reference the font(s) you copied in the previous step. Each font needs a line in the manifest section of the file, as follows:

<item id="unique-font-id" href="fonts/font-file-name" media-type="application/vnd.ms-opentype"/>

Replace unique-font-id and font-file-name with appropriate values for your font(s). Font identifiers should begin with an alphabetic character. Be sure to choose a different identifier for each font, and not to duplicate any identifiers used further down the file.

4. For safety, copy the lines you added and paste them into another file, since the changes you’ve made to the content.opf file will be overwritten when you next recompile the eCub project.

5. Follow the procedures from Appendix A to manually package your build folder into a valid ePub file.

6. Run epubcheck to validate the ePub, and then test the file with a viewer that supports embedded fonts (I used Calibre to test the file I made while researching this Appendix).

Obviously, the above manual steps are only suitable for fairly light usage of this feature. However, it is possible to automate the process with sed and batch files or shell scripts. Here is a sample sed script, followed by a Windows batch file, that should provide you with a starting point if you need to implement this on another operating system.

First, the sample sed script (note that the backslashes continue the command across multiple lines; any other line breaks you see are due to screen wrapping):

s%<manifest>%<manifest>\

<item id="font1" href="fonts/font1.otf" media-type="application/vnd.ms-opentype"/>\

<item id="font2" href="fonts/font2.otf" media-type="application/vnd.ms-opentype"/>%

The above embed.sed script replaces the string <manifest> with the same string, followed by two lines of font information. Here is the Windows batch file (intended to be run from the project directory) that calls the script and creates an ePub from eCub’s modified build folder (again, be aware that lines may have wrapped on your display):

copy build\OPS\content.opf content.opf

sed -f embed.sed content.opf > build\OPS\content.opf

cd build

zip -X0 ..\mybook.epub mimetype

zip -r ..\mybook.epub META-INF OPS

cd ..

Bear in mind that running the above script more than once, without recompiling your eCub project in the meantime, will insert duplicate font entries and identifiers into the content.opf file, leading to an invalid ePub. Only run the font-embedding script immediately after you’ve compiled the corresponding eCub project.

Also, remember to use the above technique in conjunction with the guidelines I gave you in Appendix A, paying attention to the need to delete and re-create your build folder and your ePub file as necessary, to avoid including obsolete files in your ebook. Deleting your build folder will delete any font files you’ve placed there, too, so if using a script, you might want to make it copy these files to the appropriate place as well.

Appendix D: XHTML vs HTML

The w3c XHTML 1.0 specification (section 4) describes the differences between XHTML and HTML 4.

Here’s a summary of the most important differences:

- All elements must be properly nested:
<p><em></em></p>
rather than
<p><em></p></em>.

- All elements must have closing tags. With non-enclosing elements such as <br/> and <img.../>, the closing tag is implied by the final slash character, which must be included.

- Element and attribute names must be in lower case.

- Attribute values must be enclosed in quote marks (attribute = "value").

- Leading- and trailing white space is stripped, and sequences of white space (including line breaks) are collapsed into a single space character.

Appendix E: Character Entity References

You’ll often need to encode characters to prevent them from being interpreted as XHTML syntax, or because they can’t be represented directly in the target character set, or simply because they’re not accessible from your keyboard. You do this by using character entity references, which refer to characters either by name or by number.

The following table shows some of the most commonly-used entities; for a full list, consult online sources such as w3schools.com.

Description

Entity
Name

Entity
Num

&

ampersand

&amp;

&#38;

<

less than

&lt;

&#60;

>

greater than

&gt;

&#62;

"

quotation mark

&quot;

&#34;

'

apostrophe

&apos;

&#39;

“

left double-quote

&ldquo;

&#8220;

”

right double-quote

&rdquo;

&#8221;

‘

left single-quote

&lsquo;

&#8216;

’

right single-quote

&rsquo;

&#8217;

-

soft hyphen

&shy;

&#173;

-

non-breaking hyphen

&#8209;

non-breaking space

&nbsp;

&#160;

–

en dash

&ndash;

&#8211;

—

em dash

&mdash;

&#8212;

…

horizontal ellipsis

&hellip;

&#8230;

©

copyright symbol

&copy;

&#169;

®

registered trademark

&reg;

&#174;

™

trademark

&trade;

&#8482;

The above entity names or numbers, used in a string, will be rendered as the corresponding character (assuming the character is supported on the e-reader in question). If you wished to display an ampersand, you’d code it as &amp; while if you wish to display the literal string ‘&amp;’ you’d code it as &amp;amp;. The character sets on a particular e-reader may or may not support some of the more exotic character entity codes, so it’s important to check the results on your target platforms.

The current release of Stanza for iPad re-interprets the string so that &amp;amp; collapses first to &amp; and then to &. For the epub version of this book, I placed a soft-hyphen (spanned with a class that reduces its size to one pixel and sets its visibility: property to hidden) immediately after the &amp; character entity, to quarantine subsequent characters from this spurious effect.

Index

A

Adjacent Sibling Selectors

Adobe Digital Editions:

File Size Limitations

Margin Quirk

Soft-hyphenation Quirk

Aligning Images

Auto Refresh

B

Block Elements

Box Model

Browser Preview

C

Centering Text

Kindle Centering

Character Entity References

Collapsing Margin Model

Command Line

Running ZIP

CSS Properties:

border-radius:

first-line pseudo element

float:

font-family:

font-size:

font-style:

font-variant:

font-weight:

height:

letter-spacing:

line-height:

line-height: (used with drop-caps)

margin:

margin: (used with poetry)

max-width:

padding:

page-break-after:

page-break-before:

text-align:

text-color:

text-decoration:

text-indent:

text-indent: (used with poetry)

CSS Specifications

D

Debugging

Locating Problems

Development Environment

<div>

Drop-Caps

E

Ebook Compiler

Ebook Viewing Software

eCub

Delving Deeper

Running from Command Line

ePub Checking

epubcheck

epubpreflight

Fault-finding

HTML Tidy

Online ePub Checking

Running Manually

ePub Layout

F

File Organization

Font Embedding

Fonts

G

Global Margins

H

Headings

HTML Symbols

HTML Tidy

Hyphenation

I

iBooks:

Fonts

Page Breaks

Speeding up Development Cycle

Text Alignment

Unexpected Image Breaking

Images:

Alignment

Inline Behavior

!important

Indentation

Inline Elements

J

Java

Manual Epub Check

Justification

K

kindlegen

Running Manually

Kindle Navigation

Kindle Porting

Drop-Caps

Formatting Tips

Inline Coding vs CSS

Maintaining Common Source Files

Margins

Paragraph Indentation

Setting off Content

Text Alignment

Using the Kindle Previewer

Kindle Previewer

L

Layout

Line-through

M

Manual Ebook Generation

Margins

Vertical Margins

N

Nav Map

NCX

O

Online ePub Checking

OPS Specifications

Orphans

Overline

P

Padding

Page Breaks

Pattern Matching

Porting to Kindle

Prerequisites

R

Regular Expressions

Rounded Corners

Running eCub from the Command Line

S

Sample Project

sed

Semantic Mark-up

Skills

Small-Caps

Used immediately after Drop-Cap

Soft-Hyphenation

Stanza:

Ampersand Quirk

Suppressing Default Indentation

Strikethrough

Styling with CSS

Symbols

T

Table

Tagging with XHTML

Test Devices and Software

Text Editor

Programmer’s Text Editor

toc.ncx

U

Underline

V

Validation Software

Installation

Vertical Margins

W

Waypoints

Web Browser

Auto-refresh

Widows and Orphans

Workflow

X

XHTML

Z

ZIP