Manually Tweaking eCub’s Generated Table-of-Contents

In Handcrafted Ebooks I relied extensively on the excellent (and free) eCub program to build ePub files. eCub is an ebook builder, not an ebook layout tool — it takes the content and layout expressed in a set of .xhtml and .css files, and compiles them into a .epub file with the proper internal references and format.

One set of internal references it creates is a table-of-contents file, which can be found in the OPS subdirectory of eCub’s BUILD directory, and is called TableOfContents.html. This content file is styled by the following CSS rules, which by default are generated by eCub and placed in its own style.css file:

.toc_heading { text-align: center; margin-top: 20pt; margin-bottom: 20pt; }
.p_toc { text-indent: 10mm; margin-top: 10pt; margin-bottom: 10pt;}

I usually incorporate (variants of) these rules into my own style sheet file, instead of using eCub’s generated style.css file; that way, there’s one fewer place to look when editing the CSS for a project. Also, I never call my style sheet file style.css; that way, there’s no risk that eCub will overwrite it because I forgot to clear the relevant options check box.

The TableOfContents.html file itself contains TOC entries as follows:

<h3 class="toc_heading">Table of Contents</h3>
<p class="p_toc" style = "margin-left: 20;"><a href="a001.html">Part 1: Orientation</a></p>
<p class="p_toc" style = "margin-left: 20;"><a href="a002.html">Terminology</a></p>
<p class="p_toc" style = "margin-left: 20;"><a href="a003.html">Basic Concepts</a></p>
...

eCub’s default table-of-contents comes with default formatting and with no indentation to reflect the various levels of information (so chapter headings are shown at the same level as section headings, for example). This isn’t such a problem where NavMap navigation is available, since eCub does support multiple navigational levels in the NavMap, but where users need to navigate directly from the Table of Contents file — as with a Kindle (Mobi) file — then it would be nice to offer them something that reflects the structure of the document better. If desired, it’s also quite easy to tweak the default CSS styling so that it fits the look-and-feel of the rest of your layout. I’m inclined to close up the margins between TOC entries, for example.

To create additional levels of content you can create corresponding new CSS rules, so you might end up with:

.toc_heading { text-align: center; margin-top: 20pt; margin-bottom: 20pt; }
.p_toc { text-indent: 10mm; margin-top: 10pt; margin-bottom: 10pt;}
.p_toc1 { text-indent: 20mm; margin-top: 10pt; margin-bottom: 10pt;}

Since it’s better to specify indents in ems rather than in mm, and with some other changes applied to tweak the margins and so on, we could end up with the following rules in our custom CSS file:

.toc_heading {font-weight:bold; text-align:center; margin:0 0 0.75em 0 !important;}
.p_toc {text-indent:0.5em !important; margin: 0 0 0.49em 0 !important;}
.p_toc1 {text-indent:1.5em !important; margin: 0 0 0.49em 0 !important;}

(Note that Kindle devices displaying Mobi format only have a resolution of 1em, so 0.5em and 0.75em will round up to 1em, while 0.49em rounds down to 0em).

Next, we need to edit the TableOfContents.html file to remove the hard-coded margins, and to apply the p_toc1 style to the content lines that we want to designate as being (indented) sub-headings. Since this is a job that will ideally only be done once, leave it until a fairly late stage in your project, when the structure of your ebook won’t be changing — the last thing you want is to have to re-generate a table of contents from scratch within eCub, because then you’d have to re-apply all your TOC edits.

With the new styling applied, the previous TableOfContents.html fragment becomes:

<h3 class="toc_heading">Table of Contents</h3>
<p class="p_toc" ><a href="a001.html">Part 1: Orientation</a></p>
<p class="p_toc1"><a href="a002.html">Terminology</a></p>
<p class="p_toc1"><a href="a003.html">Basic Concepts</a></p>
...

At this point, we’re in full control of the TableOfContents.html file, so we can modify it as we wish — there’s an opportunity to put ePub-compatible, Kindle (Mobi) friendly styling in, for example.

Important! The TableOfContents.html file in your build directory gets recreated every time you compile the ebook with eCub, so you’ll need to make a copy of your custom version somewhere safe (for example in your ebook’s project directory along with the rest of your source files).

The final piece of the puzzle is: how do you incorporate the modified file into your ePub, when you know that eCub will insert its own generated copy of the file during compilation? The answer is to re-create the ePub file outside of eCub, using manual commands. I automate the process with the following Windows batch file, which needs to be run from the corresponding ebook’s project directory (it should be easy to adapt this to other platforms):

del buildOPSTableOfContents.html
copy TableOfContents.html buildOPS
attrib -r buildOPSTableOfContents.html
del book.epub
cd build
zip -X0 ..book.epub mimetype
zip -r ..book.epub META-INF OPS
cd ..
kindlegen book.epub
kindlestrip.py book.mobi strippedbook.mobi
del book.mobi
rename strippedbook.mobi book.mobi

Obviously, the various tools such as zip, kindlegen and kindlestrip.py (if you wish to strip out the kindle bloat from your generated file) need to be on your command search path. Finally, note that it’s a small tragedy if you accidentally let eCub overwrite the most up-to-date copy of your tweaked TableOfContents.html — for example, by dragging-and-moving when you meant to drag-and-copy. One way to avoid this is to make the file read-only, changing that attribute when you need to edit the content, and changing it back afterward.

Leave a Reply

Your email address will not be published. Required fields are marked *