Kindle NCX file demystified

Kindle! Everyone wants their book on Kindle. And, everyone wants it to look gorgeous. As covered in previous posts (here for cover images, getting Kindlegen to recognize the cover image, and an introduction to the all-important OPF file), the key these days is a rather unruly piece of software called Kindlegen, which you can download from Amazon KDP for free.

Take a very deep breath, because we’re about to do a deep, deep dive!

This post describes the NCX file. The NCX is an adjunct file in addition to the Table of Contents (TOC) file that performs somewhat like a TOC on some Kindle devices. If you use the Kindle Previewer to look at your MOBI file, you’ll see three icons along the top, just to the right of the big A for resizing the font. The first icon takes you to the cover page. The second takes you to the book’s regular table of contents. The third takes you to something called the “NCX View.” In order to have something for that icon, you need to create an NCX file. In passing I point out that my iPad Kindle Reader doesn’t seem to make any use of this capability, but I suppose other Kindles do. And Kindlegen is perfectly happy to create your MOBI file without an NCX (I’ve done it). But, here we are, determined to give Amazon their due!

So…on to the NCX file. It is referenced in the OPF file. The NCX file itself is conceptually simple. Note the word “conceptually.” Everything has to be exactly perfect for it to work. The example NCX file shipped with Kindlegen 1.2 is a good place to start. For reasons known only to God and Amazon, no sample files are part of the Kindlegen 2.0 package.

The elements are in this order:

<?xml... (you can just copy from the sample file below or better yet from the sample files that came with Kindlegen 1.2)
<ncx>
<docTitle>
<docAuthor>

<navMap>
    <navPoint>
      <navLabel>
         <text></text>
      </navLabel>
      <content/>
    </navPoint>

… repeat this as many times as you want…

</navmap>
</ncx>

Seems so easy, right? Clearly, the important items are the navPoints. Each navPoint is an item in the NCX navigation feature. Note that navPoints can be nested, for example to create Chapter 2.1 or Appendix 3.1.3 or whatever. I have a TOC that’s only one deep, so we’ll skip the nesting for now. Let’s take a look at each element of a navPoint.

First, the navPoint label itself. Here’s an example of two:

<navPoint class="toc" id="toc" playOrder="1">
<navLabel>
<text>Table of Contents</text>
</navLabel>
<content src="tuttoc.html"/>
</navPoint>

<navPoint class="chapter " id=" 1" playorder=" 2">
<navLabel>
<text>Chapter 1: The Electric Sword 1</text>
</navLabel>
<content src="tut.html#__RefHeading__34774_658303778"/>
</navPoint>

Okay, the navPoint label itself. It contains a class="toc" item. Honestly, it doesn’t seem to matter what you put in there. Note that in the second example above, it’s just "chapter ". I toyed around with different things and it didn’t seem to make any difference. So just make it what you feel like. Next comes the id=" 1" tag. Similarly it seemed I could put about anything in there. But the next tag, playOrder="1" tag is critically important. You want to put these in numerical order, starting with one and incrementing until you’re done.

Now the navLabel tag. It seems to have only one content item, and that item is in between the text tags. This text is important, as this is what is displayed in the NCX display, verbatim.

Next comes the <content src="yourhtmlfile.html"/> item. This is stunningly important. This tells Kindlegen the exact location of what it’s pointing to. Note in the first example above it points to “tuttoc.html”, which is the separate TOC HTML file. But it’s the second example that’s more important. It reads:

<content src="tut.html#__RefHeading__34774_658303778"/>

Let’s deconstruct this. The scr obviously is a pointer to the location. The first part, tut.html is obvious—it’s the main body of my book. But notice the #__RefHeading__34774_658303778 part. The hash mark (#) is critically important, as this is a reference to a specific place inside tut.html. In this case it matches up with an element in tut.html that looks like this:

<a name="__RefHeading__34774_658303778"></a>

(without the hash mark). Your word processor’s TOC feature actually inserts these, but only if you tell it to so that your TOC is hyperlinked. (Heaven forbid you have to put these in manually!)

Now, you say, isn’t all this information already in your toc.html file? The answer is a resounding “yes!” But your TOC is in HTML format. So, you are faced with the incredibly tedious task of converting by hand, or you can write a little piece of software to extract the info from your TOC file and create the NCX file. (Can’t Kindlegen do this for you? Apparently not.) So, in fact, I created a little piece of software, written in BASIC (use the FreeBASIC compiler with the -lang qb feature), which you’ll probably have to modify to meet your needs.

Okay, that’s all there is to the NCX file. Kindle’s example OPF file claims that the NCX file is mandatory, although I’ve created a MOBI file with only the toc.html file. But if you want to forge ahead, here’s my example NCX file, followed by my example BASIC program to turn an HTML TOC file into an NCX file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN"
"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">

<!--
For a detailed description of NCX usage please refer to:
http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html#Section2.4.1
-->

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
<head>
<meta name="dtb:uid" content="tut"/>
<meta name="dtb:depth" content="2"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>

<docTitle><text>The Unexpected Traveler</text></docTitle>

<docAuthor><text>David Casler</text></docAuthor>

<navMap>

<navPoint class="toc" id="toc" playOrder="1">
<navLabel>
<text>Table of Contents</text>
</navLabel>
<content src="tuttoc.html"/>
</navPoint>

<navPoint class="chapter " id=" 1" playorder=" 2">
<navLabel>
<text>Chapter 1: The Electric Sword 1</text>
</navLabel>
<content src="tut.html#__RefHeading__34774_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 2" playorder=" 3">
<navLabel>
<text>Chapter 2. The Curious Little Man 12</text>
</navLabel>
<content src="tut.html#__RefHeading__34776_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 3" playorder=" 4">
<navLabel>
<text>Chapter 3: In the Bartlett Building 25</text>
</navLabel>
<content src="tut.html#__RefHeading__34778_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 4" playorder=" 5">
<navLabel>
<text>Chapter 4: The Portal 34</text>
</navLabel>
<content src="tut.html#__RefHeading__34780_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 5" playorder=" 6">
<navLabel>
<text>Chapter 5: The Vacant Castle 47</text>
</navLabel>
<content src="tut.html#__RefHeading__34782_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 6" playorder=" 7">
<navLabel>
<text>Chapter 3: The Prince and the Dwarves 62</text>
</navLabel>
<content src="tut.html#__RefHeading__34784_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 7" playorder=" 8">
<navLabel>
<text>Chapter 4. To the Dwarven Throne 75</text>
</navLabel>
<content src="tut.html#__RefHeading__34786_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 8" playorder=" 9">
<navLabel>
<text>Chapter 5: To the Library 104</text>
</navLabel>
<content src="tut.html#__RefHeading__34788_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 9" playorder=" 10">
<navLabel>
<text>Chapter 6: The Master of the Orgon Library 125</text>
</navLabel>
<content src="tut.html#__RefHeading__34790_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 10" playorder=" 11">
<navLabel>
<text>Chapter 7: The Long Road to Feldingshire 150</text>
</navLabel>
<content src="tut.html#__RefHeading__34792_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 11" playorder=" 12">
<navLabel>
<text>Chapter 8. In Rebel Territory 172</text>
</navLabel>
<content src="tut.html#__RefHeading__34794_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 12" playorder=" 13">
<navLabel>
<text>Chapter 9: The Gamble 189</text>
</navLabel>
<content src="tut.html#__RefHeading__34796_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 13" playorder=" 14">
<navLabel>
<text>Chapter 10: Into the Enemy’s Heart 195</text>
</navLabel>
<content src="tut.html#__RefHeading__34798_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 14" playorder=" 15">
<navLabel>
<text>Chapter 11: The Conspiracy 209</text>
</navLabel>
<content src="tut.html#__RefHeading__34800_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 15" playorder=" 16">
<navLabel>
<text>Chapter 12: The Remnant of Dordon 235</text>
</navLabel>
<content src="tut.html#__RefHeading__34802_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 16" playorder=" 17">
<navLabel>
<text>Chapter 13: Major Regales’s Story 262</text>
</navLabel>
<content src="tut.html#__RefHeading__34804_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 17" playorder=" 18">
<navLabel>
<text>Chapter 14. The Battle at Sperry Ford 284</text>
</navLabel>
<content src="tut.html#__RefHeading__34806_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 18" playorder=" 19">
<navLabel>
<text>Chapter 15. The Conspirators Up Close 312</text>
</navLabel>
<content src="tut.html#__RefHeading__34808_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 19" playorder=" 20">
<navLabel>
<text>Chapter 16. The Flight from Dag-Dakut 342</text>
</navLabel>
<content src="tut.html#__RefHeading__34810_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 20" playorder=" 21">
<navLabel>
<text>Chapter 17: The Prince Who Would Be King 365</text>
</navLabel>
<content src="tut.html#__RefHeading__34812_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 21" playorder=" 22">
<navLabel>
<text>Chapter 18. Escape 389</text>
</navLabel>
<content src="tut.html#__RefHeading__34814_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 22" playorder=" 23">
<navLabel>
<text>Chapter 19: Eagle’s Nest 409</text>
</navLabel>
<content src="tut.html#__RefHeading__34816_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 23" playorder=" 24">
<navLabel>
<text>Chapter 20: Overtures 420</text>
</navLabel>
<content src="tut.html#__RefHeading__34818_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 24" playorder=" 25">
<navLabel>
<text>Chapter 21: Gnomes, Faeries, Sprites, and Dragons 445</text>
</navLabel>
<content src="tut.html#__RefHeading__34820_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 25" playorder=" 26">
<navLabel>
<text>Chapter 22: Complications 473</text>
</navLabel>
<content src="tut.html#__RefHeading__34822_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 26" playorder=" 27">
<navLabel>
<text>Chapter 23: Prelude 488</text>
</navLabel>
<content src="tut.html#__RefHeading__34824_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 27" playorder=" 28">
<navLabel>
<text>Chapter 24: The Battle at High Bridge 518</text>
</navLabel>
<content src="tut.html#__RefHeading__34826_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 28" playorder=" 29">
<navLabel>
<text>Chapter 25: Dag-Dakut 546</text>
</navLabel>
<content src="tut.html#__RefHeading__35224_658303778"/>
</navPoint>

<navPoint class="chapter " id=" 29" playorder=" 30">
<navLabel>
<text>Chapter 26: Epilogue 562</text>
</navLabel>
<content src="tut.html#__RefHeading__34830_658303778"/>
</navPoint>

</navmap>
</ncx>

And here’s the BASIC file. Note that I stuck the initial several lines into a handy file called “startncx.txt”, which just copies the first several lines of the example verbatim.

rem * this program reads tuttoc.html and creates tut.ncx
open "startncx.txt" for input as #1
open "tutbas.ncx" for output as #2

while not eof(1)
line input #1, a$
print #2, a$
wend

close #1

open "tuttoc.html" for input as #1

i=0

for j=1 to 9
line input #1,dummy$
next j

while not eof(1)
line input #1, a$
if instr(a$,"<P")>0 then
line input #1,c$
a$=a$+c$
print a$
i=i+1
x=instr(a$,"Chapter")
print "x= ";x
y=instr(a$,"</A>")
print "y= ";y
z=len(a$)
print "z= ";z
b$=mid$(a$,x,y-x)

print #2, "<navPoint class=";chr$(34);"chapter ";chr$(34);
print #2, " id=";chr$(34);i;chr$(34);" playorder=";chr$(34);
print #2, i+1;chr$(34);">"
print #2, " <navLabel>"
print #2, " <text>";b$;"</text>"

x=instr(a$,"HREF")
y=instr(a$,">C")
b$=mid$(a$,x+6,38)

print #2, " </navLabel>"

print #2,"<content src=";chr$(34);b$;
print #2, chr$(34);"/>"
print #2, "</navPoint>"
print #2, ""

end if
wend
close #1
print #2, "</navmap>"
print #2, "</ncx>"

close #2
input "Enter an integer to continue",w
end

Good luck! I look forward to your comments!

This entry was posted in Computer Tips and tagged , . Bookmark the permalink.

4 Responses to Kindle NCX file demystified

  1. Dave says:

    Hi Jim, sorry, I’m a couple years out of date.

  2. Jim says:

    I’ve been trying to use kindlegen on an epub with audio. Somewhere I read that the audio needs to be referenced in the NCX file but I’m not sure how it should be placed there. For example, should it be placed after the TOC entry that proceeds it in the document? Any help would be greatly appreciated.

  3. dave says:

    Randy, interesting you should ask. An author from Montrose has hired me to guide her as she prepares her book for Amazon. We’ve had two sessions so far with another scheduled for this Friday. So, I suppose that does mean I’m available for hire! I’ll e-mail you directly with more info.

  4. Randy says:

    Great website Dave! Your info on Kindlegen are fantastic but I need some help figuring a few things out to get my ebook up to Amazon standards. Are you for hire at all? Some paid help would really be worth it. Please let me know.
    Thanks.

Leave a Reply

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