Transforming NCX into EPUB 3 Navigation Documents

by Keith Fahlgren

The first version of EPUB used the NCX format to describe an accessible, machine-readable Table of Contents. NCX had come to EPUB from DAISY’s DTBook standard and was a crucial navigational aide. Unfortunately, NCX was rarely understood and is not very human-readable. As part of the alignment with wider web standards, EPUB 3 has dropped the NCX format and encodes the same information in a specialization of XHTML, the EPUB Navigation Document.

Moving away from specialized ebook-only solutions was a big part of EPUB 3, so I am quite interested to see what these new EPUB Navigation Documents look like in the real world. It seemed like the easiest way to create a lot of them was to transform NCX files into the new format, so I’ve written an open-source (BSD) stylesheet to do just that:

ncx2end-0.1.xsl

Note: This ncx2end-0.1.xsl is alpha-quality software in the worst possible way—it probably won’t work correctly on your documents and is hard to use. It does produce apparently-valid output for the 100+ NCX files I had around, but I would not put much faith in that today. Enjoy!

If you find this tool useful enough to discover an error, please submit a bug report and make sure to attach your NCX file to improve the test suite.


EPUB 3 does strongly encourage Reading Systems to support EPUB (including NCX), but it would be nice to start seeing more experiments with EPUB 3 files to help encourage meaningful adoption.


Here’s an example of the input and output, just for show and tell. The EPUB Navigation Document looks normal and straightforward: that’s the point.

NCX in

<?xml version="1.0" encoding="UTF-8"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
  <head>
    <meta name="dtb:uid" content="p9780316000000"/>
    <meta name="dtb:depth" content="1"/>
    <meta name="dtb:totalPageCount" content="0"/>
    <meta name="dtb:maxPageNumber" content="0"/>
  </head>
  <docTitle>
    <text>Moby-Dick</text>
  </docTitle>
  <docAuthor>
    <text>Herman Melville</text>
  </docAuthor>
  <navMap>
    <navPoint id="cover" playOrder="1">
      <navLabel>
        <text>Cover</text>
      </navLabel>
      <content src="cover.html"/>
    </navPoint>
    <navPoint id="titlepage" playOrder="2">
      <navLabel>
        <text>Title Page</text>
      </navLabel>
      <content src="titlepage.html"/>
    </navPoint>
    <navPoint playOrder="3" id="preface_001">
      <navLabel>
        <text>Original Transcriber’s Notes:</text>
      </navLabel>
      <content src="preface_001.html"/>
    </navPoint>
    <navPoint playOrder="4" id="introduction_001">
      <navLabel>
        <text>ETYMOLOGY.</text>
      </navLabel>
      <content src="introduction_001.html"/>
    </navPoint>
    <navPoint playOrder="5" id="epigraph_001">
      <navLabel>
        <text>EXTRACTS (Supplied by a Sub-Sub-Librarian).</text>
      </navLabel>
      <content src="epigraph_001.html"/>
    </navPoint>
    <navPoint playOrder="6" id="chapter_001">
      <navLabel>
        <text>Chapter 1. Loomings.</text>
      </navLabel>
      <content src="chapter_001.html"/>
    </navPoint>
    <navPoint playOrder="7" id="chapter_002">
      <navLabel>
        <text>Chapter 2. The Carpet-Bag.</text>
      </navLabel>
      <content src="chapter_002.html"/>
    </navPoint>
    <navPoint playOrder="8" id="chapter_003">
      <navLabel>
        <text>Chapter 3. The Spouter-Inn.</text>
      </navLabel>
      <content src="chapter_003.html"/>
    </navPoint>
    <navPoint playOrder="9" id="chapter_004">
      <navLabel>
        <text>Chapter 4. The Counterpane.</text>
      </navLabel>
      <content src="chapter_004.html"/>
    </navPoint>
    <navPoint playOrder="10" id="chapter_005">
      <navLabel>
        <text>Chapter 5. Breakfast.</text>
      </navLabel>
      <content src="chapter_005.html"/>
    </navPoint>
    <navPoint playOrder="11" id="chapter_006">
      <navLabel>
        <text>Chapter 6. The Street.</text>
      </navLabel>
      <content src="chapter_006.html"/>
    </navPoint>
    <navPoint playOrder="12" id="chapter_007">
      <navLabel>
        <text>Chapter 7. The Chapel.</text>
      </navLabel>
      <content src="chapter_007.html"/>
    </navPoint>
    <navPoint playOrder="13" id="chapter_008">
      <navLabel>
        <text>Chapter 8. The Pulpit.</text>
      </navLabel>
      <content src="chapter_008.html"/>
    </navPoint>
    <navPoint id="copyright" playOrder="14">
      <navLabel>
        <text>Copyright Page</text>
      </navLabel>
      <content src="copyright.html"/>
    </navPoint>
  </navMap>
</ncx>

EPUB Navigation Document out

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:epub="http://www.idpf.org/2007/ops"
      profile="http://www.idpf.org/epub/30/profile/content/">
  <head>
    <title>Moby-Dick</title>
  </head>
  <body>
    <nav id="toc" epub:type="toc">
      <h1>Contents</h1>
      <ol>
        <li id="cover">
          <a href="cover.html">Cover</a>
        </li>
        <li id="titlepage">
          <a href="titlepage.html">Title Page</a>
        </li>
        <li id="preface_001">
          <a href="preface_001.html">Original Transcriber&#x2019;s Notes:</a>
        </li>
        <li id="introduction_001">
          <a href="introduction_001.html">ETYMOLOGY.</a>
        </li>
        <li id="epigraph_001">
          <a href="epigraph_001.html">EXTRACTS (Supplied by a Sub-Sub-Librarian).</a>
        </li>
        <li id="chapter_001">
          <a href="chapter_001.html">Chapter 1. Loomings.</a>
        </li>
        <li id="chapter_002">
          <a href="chapter_002.html">Chapter 2. The Carpet-Bag.</a>
        </li>
        <li id="chapter_003">
          <a href="chapter_003.html">Chapter 3. The Spouter-Inn.</a>
        </li>
        <li id="chapter_004">
          <a href="chapter_004.html">Chapter 4. The Counterpane.</a>
        </li>
        <li id="chapter_005">
          <a href="chapter_005.html">Chapter 5. Breakfast.</a>
        </li>
        <li id="chapter_006">
          <a href="chapter_006.html">Chapter 6. The Street.</a>
        </li>
        <li id="chapter_007">
          <a href="chapter_007.html">Chapter 7. The Chapel.</a>
        </li>
        <li id="chapter_008">
          <a href="chapter_008.html">Chapter 8. The Pulpit.</a>
        </li>
        <li id="copyright">
          <a href="copyright.html">Copyright Page</a>
        </li>
      </ol>
    </nav>
  </body>
</html>

A more complicated book might use a lot more nesting, but it’s essentially turtles the whole way down:

<li id="id2532183">
  <a href="pt03.html">III. CSS Page Layout</a>
  <ol>
    <li id="id2532206">
      <a href="ch11.html">11. Introducing CSS Layout</a>
      <ol>
        <li id="id2532230">
          <a href="ch11.html#types_of_web_page_layouts">Types of Web Page Layouts</a>
        </li>
        <li id="id2532537">
          <a href="ch11s02.html">How CSS Layout Works</a>
          <ol>
            <li id="id2532706">
              <a href="ch11s02.html#the_mighty_div_tag">The Mighty &lt;div&gt; Tag</a>
            </li>
            <li id="id2532968">
              <a href="ch11s02.html#techniques_for_css_layout">Techniques for CSS Layout</a>
            </li>
          </ol>
        </li>
        <li id="id2533080">
          <a href="ch11s03.html">Layout Strategies</a>
          <ol>
            <li id="id2533169">
              <a href="ch11s03.html#start_with_your_content">Start with Your Content</a>
            </li>
            <li id="id2533229">
              <a href="ch11s03.html#mock_up_your_design">Mock Up Your Design</a>
            </li>
            <li id="id2533293">
              <a href="ch11s03.html#identify_the_boxes">Identify the Boxes</a>
            </li>
            <li id="id2533412">
              <a href="ch11s03.html#go_with_the_flow">Go with the Flow</a>
            </li>
            <li id="id2533461">
              <a href="ch11s03.html#remember_background_images">Remember Background Images</a>
            </li>
            <li id="id2533602">
              <a href="ch11s03.html#pieces_of_a_puzzle">Pieces of a Puzzle</a>
            </li>
            <li id="id2533688">
              <a href="ch11s03.html#layering_elements">Layering Elements</a>
            </li>
            <li id="id2533747">
              <a href="ch11s03.html#dont_forget_margins_and_padding">Don't Forget Margins and Padding</a>
            </li>
          </ol>
        </li>
      </ol>
    </li>
    <li id="id2533808">
      <a href="ch12.html">12. Building Float-Based Layouts</a>
      <ol>
        <li id="id2534262">
          <a href="ch12.html#applying_floats_to_your_layouts">Applying Floats to Your Layouts</a>
          ....

Thanks to Dave Cramer for producing one of the first EPUB 3 test files.