summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2011-05-15 14:33:46 -0400
committerShaun McCance <shaunm@gnome.org>2011-05-15 14:33:46 -0400
commit2cf4c475ead66ca184073aed37227340863e6b4d (patch)
tree8c5f74b8e1a325e3bcb0e08b8dc19025d3981089
parentabfef2172ccf93f17c391dccedb81941d43b3044 (diff)
downloadyelp-tools-2cf4c475ead66ca184073aed37227340863e6b4d.tar.gz
yelp-build: Added epub build code
-rw-r--r--.gitignore2
-rw-r--r--configure.ac2
-rwxr-xr-xtools/yelp-build.in97
-rw-r--r--xslt/Makefile.am9
-rw-r--r--xslt/mal-ncx.xsl.in114
-rw-r--r--xslt/mal-opf.xsl.in198
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>