[yelp-tools] yelp-build: Added epub build code



commit 2cf4c475ead66ca184073aed37227340863e6b4d
Author: Shaun McCance <shaunm gnome org>
Date:   Sun May 15 14:33:46 2011 -0400

    yelp-build: Added epub build code

 .gitignore          |    2 +
 configure.ac        |    2 +
 tools/yelp-build.in |   97 ++++++++++++++++++++++++-
 xslt/Makefile.am    |    9 ++-
 xslt/mal-ncx.xsl.in |  114 +++++++++++++++++++++++++++++
 xslt/mal-opf.xsl.in |  198 +++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 418 insertions(+), 4 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index c2c0393..ea4bd01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,5 @@ Makefile.in
 /tools/yelp-build
 /tools/yelp-check
 /tools/yelp-new
+/xslt/mal-ncx.xsl
+/xslt/mal-opf.xsl
diff --git a/configure.ac b/configure.ac
index 5bca26a..2fdf4cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,6 +92,8 @@ tools/yelp-build
 tools/yelp-check
 tools/yelp-new
 xslt/Makefile
+xslt/mal-ncx.xsl
+xslt/mal-opf.xsl
 ])
 
 AC_OUTPUT
diff --git a/tools/yelp-build.in b/tools/yelp-build.in
index 3d4776a..0e94cb4 100755
--- a/tools/yelp-build.in
+++ b/tools/yelp-build.in
@@ -23,6 +23,8 @@ xsl_mal2html='@XSL_MAL2HTML@'
 xsl_mal2xhtml='@XSL_MAL2XHTML@'
 yelp_icon_dir='@YELP_ICON_DIR@'
 yelp_js_dir='@YELP_JS_DIR@'
+xsl_mal_opf='@DATADIR@/xslt/mal-opf.xsl'
+xsl_mal_ncx='@DATADIR@/xslt/mal-ncx.xsl'
 
 mkdir_p () {
     if [ ! -d "$1" ]; then
@@ -86,6 +88,7 @@ yelp_usage () {
         echo ""
         echo "Commands:"
         echo "  cache         Create a Mallard cache file"
+        echo "  epub          Create an EPUB file for Mallard"
         echo "  html          Convert input files to HTML"
         echo "  xhtml         Convert input files to XHTML"
     ) 1>&2
@@ -102,6 +105,18 @@ yelp_usage_cache () {
         echo "  -o OUT        Output cache to the file OUT"
     ) 1>&2
 }
+yelp_usage_epub () {
+    (
+        echo "Usage: yelp-build epub [OPTIONS] <FILES>"
+        echo ""
+        echo "  Create and EPUB file from the Mallard page files FILES."
+        echo ""
+        echo "Options:"
+        echo "  -c CACHE      Use the existing Mallard cache CACHE"
+        echo "  -o OUT        Output en EPUB file named OUT"
+        echo "  -x CUSTOM     Import the custom XSLT file CUSTOM"
+    ) 1>&2
+}
 yelp_usage_html () {
     (
         echo "Usage: yelp-build <html|xhtml> [OPTIONS] <FILES>"
@@ -446,7 +461,6 @@ yelp_html_mal2html () {
 }
 
 yelp_html () {
-    html_out="."
     while [ "$#" != "0" ]; do
         case "$1" in
             "-c")
@@ -469,7 +483,9 @@ yelp_html () {
                 ;;
         esac
     done
-    if [ ! -d "$html_out" ]; then
+    if [ "x$html_out" = "x" ]; then
+        html_out="."
+    elif [ ! -d "$html_out" ]; then
         echo "Error: output must be a directory." 1>&2
         exit 1
     fi
@@ -491,12 +507,89 @@ yelp_html () {
     fi
 }
 
+yelp_epub () {
+    while [ "$#" != "0" ]; do
+        case "$1" in
+            "-c")
+                shift
+                epub_cache_file="$1"
+                shift
+                ;;
+            "-o")
+                shift
+                epub_out="$1"
+                shift
+                ;;
+            "-x")
+                shift
+                html_custom="$1"
+                shift
+                ;;
+            *)
+                break
+                ;;
+        esac
+    done
+    if [ "x$epub_cache_file" != "x" ]; then
+        epub_cache_file=`(cd $(dirname "$epub_cache_file") && pwd)`/`basename "$epub_cache_file"`
+    else
+        epub_cache_file_is_tmp="yes"
+        epub_cache_file=`mktemp`
+        yelp_cache -o "$epub_cache_file" "$@"
+    fi
+    html_cache_file="$epub_cache_file"
+    epub_data_out=`mktemp -d`
+    html_out="$epub_data_out/OPS"
+    mkdir "$html_out"
+    yelp_html_mal2html "$@"
+
+    epub_id=`uuidgen`
+    epub_icons=`(cd "$html_out" && ls yelp-*.png)`
+    xsltproc \
+        -o "$html_out/opf.opf" \
+        --stringparam opf.id "$epub_id" \
+        --stringparam opf.icons "$epub_icons" \
+        "$xsl_mal_opf" "$epub_cache_file"
+    xsltproc \
+        -o "$html_out/ncx.ncx" \
+        --stringparam ncx.id "$epub_id" \
+        "$xsl_mal_ncx" "$epub_cache_file"
+
+    echo "application/epub+zip" > "$epub_data_out/mimetype"
+
+    mkdir "$epub_data_out/META-INF"
+    (
+        echo "<?xml version='1.0' encoding='UTF-8'?>"
+        echo "<container version='1.0' xmlns='urn:oasis:names:tc:opendocument:xmlns:container'>"
+        echo "<rootfiles>"
+        echo "<rootfile full-path='OPS/opf.opf' media-type='application/oebps-package+xml'/>"
+        echo "</rootfiles>"
+        echo "</container>"
+    ) > "$epub_data_out/META-INF/container.xml"
+
+    if [ "x$epub_out" = "x" ]; then
+        epub_out=`pwd`/index.epub
+    else
+        epub_out=`(cd $(dirname "$epub_out") && pwd)`/`basename "$epub_out"`
+    fi
+    (cd "$epub_data_out" && zip -q -r "$epub_out" mimetype META-INF OPS)
+
+    if [ "x$epub_cache_file_is_tmp" = "xyes" ]; then
+        rm "$epub_cache_file"
+    fi
+    rm -rf "$html_out"
+}
+
 cmd="$1"
 shift
 case "x$cmd" in
     "xcache")
         yelp_cache "$@"
         ;;
+    "xepub")
+        is_xhtml=1
+        yelp_epub "$@"
+        ;;
     "xhtml")
         is_xhtml=0
         yelp_html "$@"
diff --git a/xslt/Makefile.am b/xslt/Makefile.am
index 31384d7..4edcc83 100644
--- a/xslt/Makefile.am
+++ b/xslt/Makefile.am
@@ -1,6 +1,11 @@
 xsldir=$(datadir)/yelp-tools/xslt
 
-xsl_DATA =				\
+xsl_DATA =		\
+	mal-opf.xsl	\
+	mal-ncx.xsl	\
 	mal-rng.xsl
 
-EXTRA_DIST=$(xsl_DATA)
+EXTRA_DIST =		\
+	mal-ncx.xsl.in	\
+	mal-opf.xsl.in	\
+	$(xsl_DATA)
diff --git a/xslt/mal-ncx.xsl.in b/xslt/mal-ncx.xsl.in
new file mode 100644
index 0000000..5ea15bf
--- /dev/null
+++ b/xslt/mal-ncx.xsl.in
@@ -0,0 +1,114 @@
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+    xmlns:mal="http://projectmallard.org/1.0/";
+    xmlns:cache="http://projectmallard.org/cache/1.0/";
+    xmlns:e="http://projectmallard.org/experimental/";
+    xmlns:exsl="http://exslt.org/common";
+    xmlns:str="http://exslt.org/strings";
+    xmlns="http://www.daisy.org/z3986/2005/ncx/";
+    exclude-result-prefixes="mal cache e exsl str"
+    version="1.0">
+
+<xsl:output method="xml"
+            doctype-public="-//NISO//DTD ncx 2005-1//EN"
+            doctype-system="http://www.daisy.org/z3986/2005/ncx-2005-1.dtd"/>
+
+<xsl:param name="ncx.id"/>
+
+<xsl:include href="file://@XSL_MAL_LINK@"/>
+<xsl:include href="file://@XSL_MAL_SORT@"/>
+
+<xsl:param name="mal.cache" select="/cache:cache"/>
+
+<xsl:template match="cache:cache">
+  <xsl:variable name="root" select="mal:page[ id = 'index']"/>
+  <ncx version="2005-1">
+    <xsl:for-each select="document($root/@cache:href)/mal:page">
+      <xsl:attribute name="xml:lang">
+        <xsl:choose>
+          <xsl:when test="@xml:lang">
+            <xsl:value-of select="@xml:lang"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>en</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+
+      <head>
+        <meta name="dtb:uid" content="{$ncx.id}"/>
+        <meta name="dtb:depth" content="1"/>
+        <meta name="dtb:totalPageCount" content="0"/>
+        <meta name="dtb:maxPageNumber" content="0"/>
+      </head>
+ 
+      <docTitle>
+        <text>
+          <xsl:choose>
+            <xsl:when test="mal:info/mal:title[ type = 'text']">
+              <xsl:value-of select="mal:info/mal:title[ type = 'text'][1]"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="mal:title[1]"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </text>
+      </docTitle>
+ 
+      <xsl:for-each select="mal:info/mal:credit">
+        <docAuthor>
+          <text>
+            <xsl:value-of select="normalize-space(mal:name)"/>
+          </text>
+        </docAuthor>
+      </xsl:for-each>
+    </xsl:for-each>
+ 
+    <navMap>
+      <xsl:variable name="sorted">
+        <xsl:call-template name="mal.sort.tsort">
+          <xsl:with-param name="node" select="$root"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:variable name="nodes" select="exsl:node-set($sorted)/mal:link"/>
+      <xsl:for-each select="$nodes">
+        <xsl:variable name="id" select="@xref"/>
+        <xsl:variable name="node" select="$mal.cache/mal:page[ id = $id]"/>
+        <navPoint id="page-{$id}" playOrder="{position()}">
+          <navLabel>
+            <text>
+              <xsl:choose>
+                <xsl:when test="$node/mal:info/mal:title[ type = 'text']">
+                  <xsl:value-of select="$node/mal:info/mal:title[ type = 'text'][1]"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="$node/mal:title[1]"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </text>
+          </navLabel>
+          <content src="{$id}.xhtml"/>
+        </navPoint>
+      </xsl:for-each>
+      <xsl:for-each select="mal:page[not(@id = $nodes/@xref)]">
+        <navPoint id="page-{ id}" playOrder="{count($nodes) + position()}">
+          <navLabel>
+            <text>
+              <xsl:choose>
+                <xsl:when test="mal:info/mal:title[ type = 'text']">
+                  <xsl:value-of select="mal:info/mal:title[ type = 'text'][1]"/>
+                </xsl:when>
+                <xsl:otherwise>
+                  <xsl:value-of select="mal:title[1]"/>
+                </xsl:otherwise>
+              </xsl:choose>
+            </text>
+          </navLabel>
+          <content src="{ id} xhtml"/>
+        </navPoint>
+      </xsl:for-each>
+    </navMap>
+  </ncx>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/xslt/mal-opf.xsl.in b/xslt/mal-opf.xsl.in
new file mode 100644
index 0000000..c6ab921
--- /dev/null
+++ b/xslt/mal-opf.xsl.in
@@ -0,0 +1,198 @@
+<xsl:stylesheet
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+    xmlns:mal="http://projectmallard.org/1.0/";
+    xmlns:cache="http://projectmallard.org/cache/1.0/";
+    xmlns:e="http://projectmallard.org/experimental/";
+    xmlns:exsl="http://exslt.org/common";
+    xmlns:str="http://exslt.org/strings";
+    xmlns:opf="http://www.idpf.org/2007/opf";
+    xmlns="http://www.idpf.org/2007/opf";
+    exclude-result-prefixes="mal cache e exsl str"
+    version="1.0">
+
+<xsl:param name="opf.id"/>
+<xsl:param name="opf.icons"/>
+
+<xsl:include href="file://@XSL_MAL_LINK@"/>
+<xsl:include href="file://@XSL_MAL_SORT@"/>
+
+<xsl:param name="mal.cache" select="/cache:cache"/>
+
+<xsl:template match="cache:cache">
+  <xsl:variable name="root" select="mal:page[ id = 'index']"/>
+
+  <package version="2.0" unique-identifier="id">
+    <metadata xmlns:dc="http://purl.org/dc/elements/1.1/"; xmlns:opf="http://www.idpf.org/2007/opf";>
+      <xsl:for-each select="document($root/@cache:href)/mal:page">
+        <dc:title>
+          <xsl:choose>
+            <xsl:when test="mal:info/mal:title[ type = 'text']">
+              <xsl:value-of select="mal:info/mal:title[ type = 'text'][1]"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="mal:title[1]"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </dc:title>
+        <dc:language>
+          <xsl:choose>
+            <xsl:when test="@xml:lang">
+              <xsl:value-of select="@xml:lang"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text>en</xsl:text>
+            </xsl:otherwise>
+          </xsl:choose>
+        </dc:language>
+        <dc:identifier id="id" opf:scheme="uuid">
+          <xsl:value-of select="$opf.id"/>
+        </dc:identifier>
+        <xsl:for-each select="mal:info/mal:credit">
+          <xsl:variable name="type" select="concat(' ', @type, ' ')"/>
+          <xsl:choose>
+            <xsl:when test="contains($type, ' author ')">
+              <dc:creator opf:role="aut">
+                <xsl:if test="opf:file-as">
+                  <xsl:attribute name="opf:file-as" select="normalize-space(opf:file-as)"/>
+                </xsl:if>
+                <xsl:value-of select="normalize-space(mal:name)"/>
+              </dc:creator>
+            </xsl:when>
+            <xsl:otherwise>
+              <dc:contributor>
+                <xsl:if test="opf:file-as">
+                  <xsl:attribute name="opf:file-as" select="normalize-space(opf:file-as)"/>
+                </xsl:if>
+                <xsl:attribute name="opf:role">
+                  <xsl:choose>
+                    <xsl:when test="contains($type, ' editor ')">
+                      <xsl:text>edt</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="contains($type, ' collaborator ')">
+                      <xsl:text>clb</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="contains($type, ' translator ')">
+                      <xsl:text>trl</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                      <xsl:text>oth</xsl:text>
+                    </xsl:otherwise>
+                  </xsl:choose>
+                </xsl:attribute>
+                <xsl:value-of select="normalize-space(mal:name)"/>
+              </dc:contributor>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:for-each>
+      </xsl:for-each>
+    </metadata>
+ 
+    <manifest>
+      <item id="ncx" href="ncx.ncx" media-type="application/x-dtbncx+xml"/>
+
+      <xsl:for-each select="mal:page/@xml:lang[not(. = ../preceding-sibling::mal:page/@xml:lang)]">
+        <item id="stylesheet-{.}.css" href="{.}.css" media-type="text/css"/>
+      </xsl:for-each>
+      <xsl:if test="mal:page[not(@xml:lang)] and not(mal:page[ xml:lang = 'C'])">
+        <item id="stylesheet-C.css" href="C.css" media-type="text/css"/>
+      </xsl:if>
+
+      <item id="data-jquery.js" href="jquery.js" media-type="text/javascript"/>
+      <item id="data-jquery.syntax.js" href="jquery.syntax.js" media-type="text/javascript"/>
+      <item id="data-yelp.js" href="yelp.js" media-type="text/javascript"/>
+
+      <xsl:for-each select="str:split(normalize-space($opf.icons))">
+        <item id="data-{.}" href="{.}" media-type="image/png"/>
+      </xsl:for-each>
+
+      <xsl:variable name="media">
+        <xsl:for-each select="mal:page">
+          <xsl:for-each select="document(@cache:href)/mal:page">
+            <xsl:for-each select="//mal:media | //e:mouseover">
+              <item id="media-{translate(@src, '/', '-')}" href="{ src}">
+                <xsl:attribute name="media-type">
+                  <xsl:choose>
+                    <xsl:when test="@mime">
+                      <xsl:value-of select="@mime"/>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 3),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.png'">
+                      <xsl:text>image/png</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 3),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.jpg'">
+                      <xsl:text>image/jpeg</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 4),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.jpeg'">
+                      <xsl:text>image/jpeg</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 3),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.gif'">
+                      <xsl:text>image/gif</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 3),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.ogg'">
+                      <xsl:text>audio/ogg</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 3),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.ogv'">
+                      <xsl:text>video/ogg</xsl:text>
+                    </xsl:when>
+                    <xsl:when test="translate(substring(@src, string-length(@src) - 4),
+                                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')
+                                    = '.webm'">
+                      <xsl:text>video/webm</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                      <xsl:text>application/octet-stream</xsl:text>
+                    </xsl:otherwise>
+                  </xsl:choose>
+                </xsl:attribute>
+              </item>
+            </xsl:for-each>
+          </xsl:for-each>
+        </xsl:for-each>
+      </xsl:variable>
+      <xsl:for-each select="exsl:node-set($media)/*">
+        <xsl:sort select="@id"/>
+        <xsl:if test="not(@id = preceding-sibling::*/@id)">
+          <xsl:copy-of select="."/>
+        </xsl:if>
+      </xsl:for-each>
+
+      <xsl:for-each select="mal:page">
+        <item id="page-{ id}" href="{ id} xhtml" media-type="application/xhtml+xml"/>
+      </xsl:for-each>
+    </manifest>
+ 
+    <spine toc="ncx">
+      <xsl:variable name="sorted">
+        <xsl:call-template name="mal.sort.tsort">
+          <xsl:with-param name="node" select="$root"/>
+        </xsl:call-template>
+      </xsl:variable>
+      <xsl:variable name="nodes" select="exsl:node-set($sorted)/mal:link"/>
+      <xsl:for-each select="$nodes">
+        <itemref idref="page-{ xref}"/>
+      </xsl:for-each>
+      <xsl:for-each select="mal:page[not(@id = $nodes/@xref)]">
+        <itemref idref="page-{ id}" linear="no"/>
+      </xsl:for-each>
+    </spine>
+ 
+    <guide>
+      <!--
+          <reference type="loi" title="List Of Illustrations" href="appendix.html#figures" />
+      -->
+    </guide>
+  </package>
+</xsl:template>
+
+</xsl:stylesheet>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]