Skip to content

Commit

Permalink
Add toc.ncx files
Browse files Browse the repository at this point in the history
This adds code to generate toc.ncx files for EPUB2
readers. Unfortunately, visual results are likely to be unpleasant
given the quality of rendering in EPUB2 readers.

Affects: #13
  • Loading branch information
io7m committed Jun 27, 2021
1 parent 18a1965 commit b54c78e
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 4 deletions.
4 changes: 2 additions & 2 deletions com.io7m.xstructural.documentation/pom.xml
Expand Up @@ -136,7 +136,7 @@
<resource>
<directory>${project.build.directory}/epub/</directory>
<includes>
<include>${project.artifactId}-${project.version}.epub</include>
<include>documentation.epub</include>
</includes>
</resource>
</resources>
Expand Down Expand Up @@ -278,7 +278,7 @@
<argument>--outputDirectory</argument>
<argument>${project.build.directory}/epub</argument>
<argument>--outputFileName</argument>
<argument>${project.artifactId}-${project.version}.epub</argument>
<argument>documentation.epub</argument>
</arguments>
</configuration>
</execution>
Expand Down
Expand Up @@ -458,7 +458,7 @@ private void copyOEBPS()
try (var fileStream =
Files.list(this.request.outputDirectory())) {
final var xhtmlFiles =
fileStream.filter(p -> p.toString().endsWith(".xhtml"))
fileStream.filter(XSEPUBCreator::isOEBPSCopyable)
.collect(Collectors.toList());

for (final var file : xhtmlFiles) {
Expand All @@ -471,6 +471,13 @@ private void copyOEBPS()
}
}

private static boolean isOEBPSCopyable(
final Path p)
{
final var pathText = p.toString();
return pathText.endsWith(".xhtml") || pathText.endsWith(".ncx");
}

private void writePackageFile()
throws XSTransformException
{
Expand Down
Expand Up @@ -69,6 +69,9 @@
<xsl:call-template name="topLevelDocumentFile"/>
</xsl:if>

<item href="OEBPS/toc.ncx"
id="ncx"
media-type="application/x-dtbncx+xml"/>
<item href="OEBPS/toc.xhtml"
id="nav"
media-type="application/xhtml+xml"
Expand All @@ -81,7 +84,7 @@
media-type="application/xhtml+xml"/>
</manifest>

<spine>
<spine toc="ncx">
<itemref idref="cover"/>
<itemref idref="colophon"/>
<itemref idref="nav"/>
Expand Down
Expand Up @@ -371,6 +371,7 @@
<xsl:call-template name="documentCover"/>
<xsl:call-template name="documentColophon"/>
<xsl:call-template name="documentTableOfContents"/>
<xsl:call-template name="documentTableOfContentsNCX"/>
<xsl:call-template name="documentResources"/>
</xsl:template>

Expand Down Expand Up @@ -739,4 +740,128 @@
</li>
</xsl:template>

<xd:doc>
Generate an EPUB2-style NCX table of contents for the document.
</xd:doc>

<xsl:template name="documentTableOfContentsNCX">
<xsl:variable name="tocFilePath"
as="xs:string"
select="concat($outputDirectory,'/toc.ncx')"/>

<xsl:message>
<xsl:value-of select="concat('create ', $tocFilePath)"/>
</xsl:message>

<xsl:result-document href="{$tocFilePath}"
exclude-result-prefixes="#all"
include-content-type="no"
method="xml"
indent="true">
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/"
version="2005-1">
<head>
<xsl:element name="meta">
<xsl:attribute name="content">
<xsl:apply-templates select="s70:Metadata|s71:Metadata"
mode="documentTOCId"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:text>dtb:uid</xsl:text>
</xsl:attribute>
</xsl:element>
</head>
<docTitle>
<text>
<xsl:apply-templates select="s70:Metadata|s71:Metadata"
mode="documentTOCTitle"/>
</text>
</docTitle>
<navMap id="navmap">
<navPoint id="navpoint-1"
playOrder="1">
<navLabel>
<text>Cover</text>
</navLabel>
<content src="cover.xhtml"/>
</navPoint>
<navPoint id="navpoint-2"
playOrder="2">
<navLabel>
<text>Colophon</text>
</navLabel>
<content src="colophon.xhtml"/>
</navPoint>
<navPoint id="navpoint-3"
playOrder="3">
<navLabel>
<text>Table Of Contents</text>
</navLabel>
<content src="toc.xhtml"/>
</navPoint>

<xsl:variable name="offset"
select="3"/>

<xsl:for-each select=".//s70:Section|.//s70:Subsection">
<xsl:variable name="pos"
select="position() + $offset"/>
<xsl:variable name="label">
<xsl:apply-templates select="."
mode="documentTableOfContentsNCXTitle"/>
</xsl:variable>
<xsl:variable name="file"
select="sxc:anchorOf(.)"/>

<navPoint>
<xsl:attribute name="id">
<xsl:value-of select="concat('navpoint-', $pos)"/>
</xsl:attribute>
<xsl:attribute name="playOrder">
<xsl:value-of select="$pos"/>
</xsl:attribute>
<navLabel>
<text>
<xsl:value-of select="$label"/>
</text>
</navLabel>
<xsl:element name="content">
<xsl:attribute name="src">
<xsl:value-of select="$file"/>
</xsl:attribute>
</xsl:element>
</navPoint>
</xsl:for-each>
</navMap>
</ncx>
</xsl:result-document>
</xsl:template>

<xsl:template match="s70:Metadata|s71:Metadata"
mode="documentTOCId">
<xsl:value-of select="dc:identifier"/>
</xsl:template>

<xsl:template match="s70:Section"
mode="documentTableOfContentsNCXTitle">
<xsl:variable name="number">
<xsl:call-template name="sxc:sectionNumberTitleOf">
<xsl:with-param name="section"
select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($number,'. ',@title)"/>
</xsl:template>

<xsl:template match="s70:Subsection"
mode="documentTableOfContentsNCXTitle">
<xsl:variable name="number">
<xsl:call-template name="sxc:subsectionNumberTitleOf">
<xsl:with-param name="subsection"
select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($number,'. ',@title)"/>
</xsl:template>

</xsl:stylesheet>
1 change: 1 addition & 0 deletions src/site/resources/documentation.xml
Expand Up @@ -5,5 +5,6 @@
<ul>
<li><a href="documentation/index-m.xhtml">XHTML - one page per section</a></li>
<li><a href="documentation/index.xhtml">XHTML - single page</a></li>
<li><a href="documentation/documentation.epub">EPUB 3</a></li>
</ul>
</div>

0 comments on commit b54c78e

Please sign in to comment.