diff options
author | Shaun McCance <shaunm@gnome.org> | 2011-05-15 14:33:46 -0400 |
---|---|---|
committer | Shaun McCance <shaunm@gnome.org> | 2011-05-15 14:33:46 -0400 |
commit | 2cf4c475ead66ca184073aed37227340863e6b4d (patch) | |
tree | 8c5f74b8e1a325e3bcb0e08b8dc19025d3981089 | |
parent | abfef2172ccf93f17c391dccedb81941d43b3044 (diff) | |
download | yelp-tools-2cf4c475ead66ca184073aed37227340863e6b4d.tar.gz |
yelp-build: Added epub build code
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | tools/yelp-build.in | 97 | ||||
-rw-r--r-- | xslt/Makefile.am | 9 | ||||
-rw-r--r-- | xslt/mal-ncx.xsl.in | 114 | ||||
-rw-r--r-- | xslt/mal-opf.xsl.in | 198 |
6 files changed, 418 insertions, 4 deletions
@@ -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> |