Mini Shell
| Direktori : /bin/ |
|
|
| Current File : //bin/yelp-build |
#!/bin/sh
# -*- indent-tabs-mode: nil -*-
#
# yelp-build
# Copyright (C) 2010-2015 Shaun McCance <shaunm@gnome.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
xsl_mal_cache='/usr/share/yelp-xsl/xslt/mallard/cache/mal-cache.xsl'
xsl_db2html='/usr/share/yelp-xsl/xslt/docbook/html/db2html.xsl'
xsl_db2xhtml='/usr/share/yelp-xsl/xslt/docbook/html/db2xhtml.xsl'
xsl_mal2html='/usr/share/yelp-xsl/xslt/mallard/html/mal2html.xsl'
xsl_mal2xhtml='/usr/share/yelp-xsl/xslt/mallard/html/mal2xhtml.xsl'
yelp_icon_dir='/usr/share/yelp-xsl/icons/hicolor/24x24/status'
yelp_js_dir='/usr/share/yelp-xsl/js'
xsl_mal_epub='/usr/share/yelp-tools/xslt/mal-epub.xsl'
xsl_mal_opf='/usr/share/yelp-tools/xslt/mal-opf.xsl'
xsl_mal_ncx='/usr/share/yelp-tools/xslt/mal-ncx.xsl'
xsl_mal_files='/usr/share/yelp-tools/xslt/mal-files.xsl'
mkdir_p () {
if [ ! -d "$1" ]; then
mkdir_p "$(dirname "$1")"
mkdir "$1"
fi
}
urlencode () {
LC_ALL=C awk '
BEGIN {
for (i = 1; i <= 255; i++) chars[sprintf("%c", i)] = i;
}
{
ret = "";
for (i = 1; i <= length($0); i++) {
c = substr($0, i, 1);
if (c ~ /[\/a-zA-Z0-9._-]/)
ret = ret c;
else
ret = ret sprintf("%%%X%X", int(chars[c] / 16), chars[c] % 16);
}
print ret;
}'
}
urldecode () {
LC_ALL=C awk '
BEGIN {
for(i = 0; i < 10; i++) hex[i] = i;
hex["A"] = hex["a"] = 10;
hex["B"] = hex["b"] = 11;
hex["C"] = hex["c"] = 12;
hex["D"] = hex["d"] = 13;
hex["E"] = hex["e"] = 14;
hex["F"] = hex["f"] = 15;
}
{
ret = "";
for (i = 1; i <= length($0); i++) {
c = substr($0, i, 1);
if (c == "+") {
ret = ret " ";
}
else if (c == "%") {
c = sprintf("%c", hex[substr($0, i + 1, 1)] * 16 + hex[substr($0, i + 2, 1)]);
ret = ret c;
i += 2;
}
else {
ret = ret c;
}
}
print ret;
}'
}
yelp_usage () {
(
echo "Usage: yelp-build <COMMAND> [OPTIONS] [FILES]"
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
}
yelp_usage_cache () {
(
echo "Usage: yelp-build cache <FILES>"
echo ""
echo " Create a Mallard cache file from the page files FILES."
echo " If FILES contains directories, all .page files in those"
echo " directories will be used."
echo ""
echo "Options:"
echo " -o OUT Output cache to the file OUT"
echo " -s Treat pages as belonging to a Mallard site"
) 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"
echo " -p PATHS Extra paths to search for files"
echo " -i Ignore missing media files"
) 1>&2
}
yelp_usage_html () {
(
echo "Usage: yelp-build <html|xhtml> [OPTIONS] <FILES>"
echo ""
echo " Create HTML or XHTML from the input files FILES."
echo " FILES can be DocBook files, Mallard page files,"
echo " or directories containing Mallard page files."
echo ""
echo "Options:"
echo " -c CACHE Use the existing Mallard cache CACHE"
echo " -o OUT Output files in the directory OUT"
echo " -x CUSTOM Import the custom XSLT file CUSTOM"
echo " -p PATHS Extra paths to search for files"
echo " -i Ignore missing media files"
) 1>&2
}
if [ $# = 0 ]; then
yelp_usage
exit 1
fi
yelp_paths_normalize () {
for path in $(echo "$1" | sed -e 's/[: ]/\n/g'); do
(cd "$path" && pwd)
done | tr '\n' ' '
}
yelp_cache_in_page () {
fbase=$(basename "$1")
fdir=$( (cd "$(dirname "$1")" && pwd) )
sdir=${fdir##${cache_site_root}}/
url=file://$(echo "$fdir/$fbase" | urlencode)
if [ "x$cache_site" = "x1" ]; then
siteattr=' site:dir="'"$sdir"'"'
fi
echo '<page cache:href="'"$url"'"'"$siteattr"'/>'
}
yelp_cache_in_site () {
for dir in "$1"/*; do
if [ -d "$dir" ]; then
if [ "$(basename "$dir")" != "__pintail__" ]; then
yelp_cache_in_site "$dir"
fi
fi
done
for page in "$1"/*.page; do
if [ -e "$page" ]; then
yelp_cache_in_page "$page"
fi
done
}
yelp_cache_in () {
echo '<cache:cache xmlns:cache="http://projectmallard.org/cache/1.0/"'
if [ "x$cache_site" = "x1" ]; then
echo ' xmlns:site="http://projectmallard.org/site/1.0/"'
fi
echo ' xmlns="http://projectmallard.org/1.0/">'
for page in "$@"; do
if [ -d "$page" ]; then
if [ "x$cache_site" = "x1" ]; then
yelp_cache_in_site "$page"
else
for sub in "$page"/*.page; do
yelp_cache_in_page "$sub"
done
fi
else
yelp_cache_in_page "$page"
fi
done
echo '</cache:cache>'
}
yelp_cache () {
cache_out="index.cache"
while [ "$#" != "0" ]; do
case "$1" in
"-o")
shift
cache_out="$1"
shift
;;
"-s")
cache_site="1"
cache_site_root=$(pwd)
shift
;;
*)
break
;;
esac
done
if [ "$#" = "0" ] ||[ "x$1" = "x--help" ] || [ "x$1" = "x-h" ]; then
yelp_usage_cache
exit 1
fi
yelp_cache_in "$@" | xsltproc --path "$html_paths" \
--xinclude -o "$cache_out" \
"$xsl_mal_cache" -
}
yelp_html_xsl_common () {
if [ "x$html_internal_datadir" != "x" ]; then
echo '<xsl:variable name="yelp.internal.datadir" select="'"'$html_internal_datadir'"'"/>'
echo '<xsl:param name="html.css.root" select="$yelp.internal.datadir"/>'
echo '<xsl:param name="html.js.root" select="$yelp.internal.datadir"/>'
else
echo '<xsl:variable name="yelp.internal.datadir" select="'"''"'"/>'
fi
if [ "x$html_internal_xsl" != "x" ]; then
echo '<xsl:include href="file://'"$(echo "$html_internal_xsl" | urlencode)"'"/>'
fi
if [ "x$html_custom" != "x" ]; then
echo '<xsl:include href="file://'"$(echo "$html_custom" | urlencode)"'"/>'
fi
echo '<xsl:template name="html.css">'
echo ' <xsl:param name="node" select="."/>'
echo ' <xsl:variable name="yelp.locale">'
echo ' <xsl:choose>'
echo ' <xsl:when test="$node/@xml:lang != '"''"'">'
echo ' <xsl:value-of select="$node/@xml:lang"/>'
echo ' </xsl:when>'
echo ' <xsl:when test="$node/@lang != '"''"'">'
echo ' <xsl:value-of select="$node/@lang"/>'
echo ' </xsl:when>'
echo ' <xsl:otherwise>'
echo ' <xsl:text>C</xsl:text>'
echo ' </xsl:otherwise>'
echo ' </xsl:choose>'
echo ' </xsl:variable>'
echo ' <exsl:document href="{$yelp.internal.datadir}{$yelp.locale}.css" method="text">'
echo ' <xsl:call-template name="html.css.content">'
echo ' <xsl:with-param name="node" select="$node"/>'
echo ' <xsl:with-param name="direction">'
echo ' <xsl:call-template name="l10n.direction">'
echo ' <xsl:with-param name="lang" select="$yelp.locale"/>'
echo ' </xsl:call-template>'
echo ' </xsl:with-param>'
echo ' </xsl:call-template>'
echo ' </exsl:document>'
echo ' <link rel="stylesheet" type="text/css" href="{$html.css.root}{$yelp.locale}.css"/>'
echo '</xsl:template>'
echo '<xsl:template name="html.js.script">'
echo ' <xsl:param name="node" select="."/>'
echo ' <exsl:document href="{$yelp.internal.datadir}yelp.js" method="text">'
echo ' <xsl:call-template name="html.js.content">'
echo ' <xsl:with-param name="node" select="$node"/>'
echo ' </xsl:call-template>'
echo ' </exsl:document>'
echo ' <script type="text/javascript" src="{$html.js.root}yelp.js"/>'
echo '</xsl:template>'
}
yelp_html_db2html () {
for xml in "$@"; do
xmldir=$(dirname "$xml")
xmldir=$( (cd "$xmldir" && pwd))
# Output HTML
(
echo '<xsl:stylesheet'
echo ' xmlns:xsl="http://www.w3.org/1999/XSL/Transform"'
echo ' xmlns:exsl="http://exslt.org/common"'
echo ' xmlns="http://www.w3.org/1999/xhtml"'
echo ' extension-element-prefixes="exsl"'
echo ' version="1.0">'
if [ "x$is_xhtml" = "x1" ]; then
xsl='file://'$(echo "$xsl_db2xhtml" | urlencode)
else
xsl='file://'$(echo "$xsl_db2html" | urlencode)
fi
echo '<xsl:import href="'"$xsl"'"/>'
yelp_html_xsl_common
echo '</xsl:stylesheet>'
) | xsltproc --path "$html_paths" --xinclude -o "$html_out"/ - "$xml"
# Copy media
if [ "x$xmldir" != "x$html_out" ]; then
(
echo '<xsl:stylesheet'
echo ' xmlns:xsl="http://www.w3.org/1999/XSL/Transform"'
echo ' xmlns:db="http://docbook.org/ns/docbook"'
echo ' exclude-result-prefixes="db"'
echo ' version="1.0">'
echo '<xsl:output method="text"/>'
echo '<xsl:template match="/">'
echo ' <xsl:for-each select="'
echo ' //audiodata | //imagedata | //videodata |'
echo ' //db:audiodata | //db:imagedata | //db:videodata">'
echo ' <xsl:value-of select="concat(@fileref, '"'
'"')"/>'
echo ' </xsl:for-each>'
echo '</xsl:template>'
echo '</xsl:stylesheet>'
) | xsltproc --path "$html_paths" --xinclude - "$xml" | while read -r media; do
mfile=$(echo "$media" | urldecode)
minput="$xmldir/$mfile"
moutput="$html_out/$mfile"
mkdir_p "$(dirname "$moutput")"
if [ ! -f "$minput" ] && [ "x$html_paths" != "x" ]; then
minput_rel=${minput#"$(pwd)/"}
if [ "x$minput_rel" != "x$minput_src" ]; then
for path in $html_paths; do
if [ -f "$path/$minput_rel" ]; then
minput="$path/$minput_rel"
break
fi
done
fi
fi
if [ -f "$minput" ] || [ "x$html_ignore_media" != "x1" ]; then
cp "$minput" "$moutput"
fi
done
fi
# Copy JavaScript
cp "${yelp_js_dir}/highlight.pack.js" "$html_out/$html_internal_datadir"
done
}
yelp_html_mal2html () {
if [ "x$html_cache_file" != "x" ]; then
html_cache_file=$( (cd "$(dirname "$html_cache_file")" && pwd))/$(basename "$html_cache_file")
else
html_cache_file_is_tmp="yes"
html_cache_file=$(mktemp "${TMPDIR:-/tmp}"/yelp-XXXXXXXX)
yelp_cache -o "$html_cache_file" "$@"
fi
html_tmp_infile=$(mktemp "${TMPDIR:-/tmp}"/yelp-XXXXXXXX)
yelp_cache_in "$@" > "$html_tmp_infile"
# Output HTML
(
echo '<xsl:stylesheet'
echo ' xmlns:xsl="http://www.w3.org/1999/XSL/Transform"'
echo ' xmlns:mal="http://projectmallard.org/1.0/"'
echo ' xmlns:cache="http://projectmallard.org/cache/1.0/"'
echo ' xmlns:exsl="http://exslt.org/common"'
echo ' xmlns="http://www.w3.org/1999/xhtml"'
echo ' exclude-result-prefixes="mal cache"'
echo ' extension-element-prefixes="exsl"'
echo ' version="1.0">'
if [ "x$is_xhtml" = "x1" ]; then
xsl='file://'$(echo "$xsl_mal2xhtml" | urlencode)
else
xsl='file://'$(echo "$xsl_mal2html" | urlencode)
fi
echo '<xsl:import href="'"$xsl"'"/>'
echo '<xsl:include href="'"$xsl_mal_files"'"/>'
echo '<xsl:output method="text"/>'
yelp_html_xsl_common
html_cache_url='file://'$(echo "$html_cache_file" | urlencode)
echo '<xsl:param name="mal.cache.file" select="'"'$html_cache_url'"'"/>'
echo '<xsl:template match="/">'
echo '<xsl:for-each select="cache:cache/mal:page">'
echo '<xsl:variable name="href" select="@cache:href"/>'
echo '<xsl:for-each select="document(@cache:href)/mal:page">'
echo '<xsl:call-template name="html.output"/>'
echo '<xsl:call-template name="mal.files.copy">'
echo ' <xsl:with-param name="href" select="substring-after($href, '\''file://'\'')"/>'
echo '</xsl:call-template>'
echo '</xsl:for-each>'
echo '</xsl:for-each>'
echo '</xsl:template>'
echo '</xsl:stylesheet>'
) | (cd "$html_out" && xsltproc "$html_profile" \
--path "$html_paths" --xinclude \
- "$html_tmp_infile") | sort | uniq | \
while read -r line; do
# Copy media from paths output by HTML transform
line_src=$(echo "$line" | cut -d' ' -f1 | urldecode)
line_dest="$html_out/"$(echo "$line" | cut -d' ' -f2)
if [ ! -f "$line_src" ] && [ "x$html_paths" != "x" ]; then
line_src_rel=${line_src#"$(pwd)/"}
if [ "x$line_src_rel" != "x$line_src" ]; then
for path in $html_paths; do
if [ -f "$path/$line_src_rel" ]; then
line_src="$path/$line_src_rel"
break
fi
done
fi
fi
line_dest=$(echo "$line_dest" | urldecode)
if [ "$line_src" != "$line_dest" ]; then
line_dir=$(dirname "$line_dest")
mkdir_p "$line_dir"
if [ -f "$line_src" ] || [ "x$html_ignore_media" != "x1" ]; then
cp "$line_src" "$line_dest"
fi
fi
done
# Copy JavaScript
cp "${yelp_js_dir}/highlight.pack.js" "$html_out/$html_internal_datadir"
# Clean up
rm "$html_tmp_infile"
if [ "x$html_cache_file_is_tmp" = "xyes" ]; then
rm "$html_cache_file"
fi
}
yelp_html () {
while [ "$#" != "0" ]; do
case "$1" in
"-c")
shift
html_cache_file="$1"
shift
;;
"-o")
shift
html_out="$1"
shift
;;
"-x")
shift
html_custom="$1"
shift
;;
"-p")
shift
html_paths=$(yelp_paths_normalize "$1")
shift
;;
"-i")
shift
html_ignore_media="1"
;;
"--profile")
html_profile="--profile"
shift
;;
*)
break
;;
esac
done
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
html_out=$( (cd "$html_out" && pwd))
if [ "x$html_custom" != "x" ]; then
html_custom_dir=$(dirname "$html_custom")
html_custom_dir=$( (cd "$html_custom_dir" && pwd))
html_custom="$html_custom_dir"/$(basename "$html_custom")
fi
if [ "$#" = "0" ] || [ "x$1" = "x--help" ] || [ "x$1" = "x-h" ]; then
yelp_usage_html
exit 1
fi
ext=$(echo "$1" | sed -e 's/.*\.//')
if [ "x$ext" = "xxml" ] || [ "x$ext" = "xdocbook" ]; then
yelp_html_db2html "$@"
else
yelp_html_mal2html "$@"
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
;;
"-p")
shift
html_paths=$(yelp_paths_normalize "$1")
shift
;;
"-i")
shift
html_ignore_media="1"
;;
*)
break
;;
esac
done
if [ "$#" = "0" ] || [ "x$1" = "x--help" ] || [ "x$1" = "x-h" ]; then
yelp_usage_epub
exit 1
fi
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 "${TMPDIR:-/tmp}"/yelp-XXXXXXXX)
yelp_cache -o "$epub_cache_file" "$@"
fi
html_cache_file="$epub_cache_file"
epub_data_out=$(mktemp -d "${TMPDIR:-/tmp}"/yelp-XXXXXXXX)
html_out="$epub_data_out/OPS"
mkdir "$html_out"
mkdir "$html_out/yelp"
html_internal_datadir="yelp/"
html_internal_xsl="$xsl_mal_epub"
yelp_html_mal2html "$@"
epub_id=$(uuidgen)
epub_data=$( (cd "$html_out" && ls yelp/*.*))
xsltproc \
--path "$html_paths" \
-o "$html_out/opf.opf" \
--stringparam opf.id "$epub_id" \
--stringparam opf.data "$epub_data" \
"$xsl_mal_opf" "$epub_cache_file"
xsltproc \
--path "$html_paths" \
-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 "$@"
;;
"xxhtml")
is_xhtml=1
yelp_html "$@"
;;
*)
yelp_usage
;;
esac