Make site2html.xsl import mal2html.xsl so overrides work correctly
[projectmallard:j1mcs-mallard-site-tool.git] / mallard-site-tool.in
1 #!/bin/sh
2 # -*- indent-tabs-mode: nil -*-
3 # mallard-site-tool  Build web sites from collections of Mallard documents
4 # Copyright (C) 2006-2010 Shaun McCance <shaunm@gnome.org>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 progname=`echo "$0" | sed 's%^.*/%%'`
21
22 PROGRAM=mallard-site-tool
23 VERSION=@VERSION@
24 prefix=@prefix@
25 datarootdir=@datarootdir@
26 datadir=@datadir@
27
28 # This is important to make sure string manipulation is handled
29 # byte-by-byte.
30 export LANG=C
31
32 XSL_CACHE='
33 <xsl:stylesheet
34   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
35   xmlns:cache="http://projectmallard.org/cache/1.0/"
36   xmlns:site="http://projectmallard.org/site/1.0/"
37   xmlns:mal="http://projectmallard.org/1.0/"
38   version="1.0">
39 <xsl:import href="'$(pkg-config --variable xsltdir yelp-xsl)'/mallard/cache/mal-cache.xsl"/>
40 <xsl:template name="mal.cache.id">
41   <xsl:param name="node" select="."/>
42   <xsl:param name="node_in"/>
43   <xsl:choose>
44     <xsl:when test="not($node/@id)"/>
45     <xsl:when test="$node/self::mal:page">
46       <xsl:attribute name="id">
47         <xsl:value-of select="$node_in/@site:dir"/>
48         <xsl:value-of select="$node/@id"/>
49       </xsl:attribute>
50     </xsl:when>
51     <xsl:otherwise>
52       <xsl:attribute name="id">
53         <xsl:value-of select="$node_in/@site:dir"/>
54         <xsl:value-of select="ancestor::mal:page[1]/@id"/>
55         <xsl:text>#</xsl:text>
56         <xsl:value-of select="@id"/>
57       </xsl:attribute>
58     </xsl:otherwise>
59   </xsl:choose>
60   <xsl:copy-of select="$node_in/@site:dir"/>
61 </xsl:template>
62 <xsl:template name="mal.cache.xref">
63   <xsl:param name="node" select="."/>
64   <xsl:param name="node_in"/>
65   <xsl:attribute name="xref">
66     <xsl:choose>
67       <xsl:when test="starts-with($node/@xref, '\''/'\'')">
68         <xsl:value-of select="$node/@xref"/>
69       </xsl:when>
70       <xsl:when test="starts-with($node/@xref, '\''#'\'')">
71         <xsl:value-of select="$node/@xref"/>
72       </xsl:when>
73       <xsl:otherwise>
74         <xsl:value-of select="$node_in/@site:dir"/>
75         <xsl:value-of select="$node/@xref"/>
76       </xsl:otherwise>
77     </xsl:choose>
78   </xsl:attribute>
79 </xsl:template>
80 </xsl:stylesheet>'
81
82
83 XSL_CSS='<xsl:stylesheet
84   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
85   xmlns:mal="http://projectmallard.org/1.0/"
86   version="1.0">
87 <xsl:import href="'$(pkg-config --variable xsltdir yelp-xsl)'/common/theme.xsl"/>
88 <xsl:import href="'$(pkg-config --variable xsltdir yelp-xsl)'/gettext/gettext.xsl"/>
89 <xsl:import href="'$(pkg-config --variable xsltdir yelp-xsl)'/mallard/html/mal2html-css.xsl"/>
90 <xsl:output method="text"/>
91 <xsl:template match="/">
92 <xsl:call-template name="mal2html.css.content"/>
93 </xsl:template>
94 </xsl:stylesheet>'
95
96 XSL_MALLARD_MEDIA='
97 <xsl:stylesheet
98   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
99   xmlns:mal="http://projectmallard.org/1.0/"
100   version="1.0">
101 <xsl:output method="text" encoding="utf-8"/>
102 <xsl:template match="/">
103   <xsl:for-each select="//mal:media">
104     <xsl:value-of select="@src"/>
105     <xsl:text>&#x000A;</xsl:text>
106   </xsl:for-each>
107 </xsl:template>
108 </xsl:stylesheet>'
109
110 XSL_GET_ROOT='
111 <xsl:stylesheet
112   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
113   xmlns:site="http://projectmallard.org/site/1.0/"
114   version="1.0">
115 <xsl:output method="text" encoding="utf-8"/>
116 <xsl:template match="/site:site">
117 <xsl:value-of select="site:link[@type='\'site-root\'']/@href"/>
118 </xsl:template>
119 </xsl:stylesheet>'
120
121 XSL_GET_CUSTOM='
122 <xsl:stylesheet
123   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
124   xmlns:site="http://projectmallard.org/site/1.0/"
125   version="1.0">
126 <xsl:output method="text" encoding="utf-8"/>
127 <xsl:template match="/site:site">
128 <xsl:value-of select="site:link[@type='\'site-custom-xsl\'']/@href"/>
129 </xsl:template>
130 </xsl:stylesheet>'
131
132 error() {
133     echo "$progname: $1" 1>&2;
134     exit 1;
135 }
136
137 print_help() {
138     cat <<EOF
139 Usage: $progname <COMMAND> [OPTIONS] FILES...
140 Process a Mallard site.
141
142 COMMAND is one of:
143   cache        generate a Mallard site cache file
144   css          generate the index.css file
145   html         convert the site to HTML
146   help         display this help and exit
147 EOF
148 }
149
150 print_help_html() {
151     format="$1"
152     upformat=`echo $format | tr a-z A-Z`
153     cat <<EOF
154 Usage: $progname $format [OPTIONS] FILE
155 Convert FILE into $upformat.
156
157   -s, --site=SITE                 base name of the site file
158 EOF
159 }
160
161 print_help_cache() {
162     cat <<EOF
163 Usage: $progname cache [OPTIONS]
164 Create a Mallard site cache file.
165
166   -s, --site=SITE                 base name of the site file
167 EOF
168 }
169
170 print_help_css() {
171     cat <<EOF
172 Usage: $progname css [OPTIONS]
173 Create the index.css file for a site.
174
175   -s, --site=SITE                 base name of the site file
176 EOF
177 }
178
179 mkdir_p() {
180     __dir__='';
181     echo $1 | sed -e 's/\//\n/g' | while read d; do
182         __dir__="$__dir__$d/"
183         if [ ! -d "$__dir__" ]; then
184             mkdir "$__dir__" || error "Could not create directory"
185         fi
186     done || exit 1;
187 }
188
189 urlencode() {
190     echo "$1" | awk --posix '
191 BEGIN {
192   for (i = 1; i <= 256; i++) {
193     bytes[sprintf("%c", i)] = i;
194   }
195 }
196 {
197   for (i = 1; i <= length($0); i++) {
198     c = substr($0, i, 1);
199     if (c ~ /[a-zA-Z0-9:_\.\-\/]/)
200       printf("%s", c);
201     else
202       printf("%%%02X", bytes[c]);
203   }
204 }
205 '
206 }
207
208 locate_site_file() {
209     site_directory=`pwd`
210     while [ "x${site_directory}" != "x" -a ! -f "${site_directory}/${site_site}.site" ]; do
211         if [ "x${site_directory}" = "x/" ]; then
212             site_directory=""
213         else
214             site_directory=`dirname "$site_directory"`
215         fi
216     done
217     site_file="${site_directory}/${site_site}.site"
218     if [ ! -f "$site_file" ]; then
219         error "Could not locate ${site_site}.site"
220     fi
221 }
222
223 create_cache() {
224     longopts='
225       -lsite:
226       -lhelp
227     ';
228     options=`getopt -qn$progname $longopts -- s:Vh "$@"`
229     if [ "$?" != "0" ]; then print_help_cache 1>&2; exit 1; fi
230     eval set -- "$options";
231     while [ "$1" != "--" ]; do
232         case "$1" in
233             -s | --site)
234                 site_site="$2";;
235             -h | --help)
236                 print_help_cache
237                 exit 0;;
238             --)
239                 print_help_cache 1>&2
240                 exit 1;;
241         esac
242         shift
243     done
244     shift
245     locate_site_file
246     site_cache="${site_directory}/${site_site}.cache"
247     (
248         echo '<cache:cache xmlns:cache="http://projectmallard.org/cache/1.0/"'
249         echo '             xmlns:site="http://projectmallard.org/site/1.0/"'
250         echo '             xmlns="http://projectmallard.org/1.0/">'
251         find "$site_directory" -name '*.page' | while read page; do
252             page_esc=$(urlencode "$page" | sed -e 's/\&/\&amp;/g' -e 's/</\&lt;/g' -e "s/'/\&apos;/g")
253             page_dir=$(urlencode $(dirname $(echo "$page" | cut -c${#site_directory}- | cut -c2-)))
254             if [ "x${page_dir}" != "x/" ]; then
255                 page_dir="$page_dir/"
256             fi
257             echo "<page cache:href='file://$page_esc' site:dir='${page_dir}'/>"
258         done
259         echo '</cache:cache>'
260     ) > "${site_cache}.in"
261     echo "$XSL_CACHE" | xsltproc --xinclude - "${site_cache}.in" | xmllint --format - > "$site_cache"
262 }
263
264 create_css() {
265     longopts='
266       -lsite:
267       -lhelp
268     ';
269     options=`getopt -qn$progname $longopts -- s:Vh "$@"`
270     if [ "$?" != "0" ]; then print_help_css 1>&2; exit 1; fi
271     eval set -- "$options";
272     while [ "$1" != "--" ]; do
273         case "$1" in
274             -s | --site)
275                 site_site="$2";;
276             -h | --help)
277                 print_help_css
278                 exit 0;;
279             --)
280                 print_help_css 1>&2
281                 exit 1;;
282         esac
283         shift
284     done
285     shift
286     locate_site_file
287     echo "$XSL_CSS" | xsltproc -o "${site_directory}/index.css" - "${site_directory}/index.page"
288 }
289
290 copy_icons() {
291     if [ "x$doc_copy_icons" = "x1" ]; then
292         if [ "x$doc_icons_admon_path" = "x" ]; then
293             p="$pkgdatadir/icons/hicolor/"
294             if [ "x$doc_icons_admon_size" != "x" ]; then
295                 doc_icons_admon_path="${p}${doc_icons_admon_size}x${doc_icons_admon_size}/status"
296             else
297                 doc_icons_admon_path="${p}48x48/status"
298             fi
299             unset p
300         fi
301         for doc_icon in $(echo $doc_icons_to_copy | tr ' ' '\n' | grep '^admon-' | sort | uniq); do
302             doc_icon_file="${doc_icon}.png"
303             cmd="cp \"$doc_icons_admon_path/$doc_icon_file\" \"$doc_outdir/$doc_icon_file\""
304             echo_verbose "$cmd"
305             eval "$cmd"
306         done
307     fi
308 }
309
310 list_icons() {
311     while [ "$#" != "0" ]; do
312         if [ -d "$1" ]; then
313             list_icons "$1/"*.page
314         else
315             echo "$XSL_ICONS" | xsltproc --nonet --xinclude - "$1"
316         fi
317         shift
318     done | sort | uniq
319 }
320
321 list_media() {
322     if [ "x$(echo "$1" | sed -e 's/.*\.//')" = "xpage" -o -d "$1" ]; then
323         XSL_MEDIA="$XSL_MALLARD_MEDIA"
324     else
325         XSL_MEDIA="$XSL_DOCBOOK_MEDIA"
326     fi
327     while [ "$#" != "0" ]; do
328         if [ -d "$1" ]; then
329             list_media "$1/"*.page
330         else
331             doc_indir=$(dirname "$1")
332             if [ "$doc_indir" = "." ]; then
333                 doc_indir=""
334             else
335                 doc_indir="$doc_indir/"
336             fi
337             echo "$XSL_MEDIA" | xsltproc --nonet --xinclude - "$1" \
338                 | while read doc_media; do
339                 echo "$doc_indir$doc_media"
340             done
341         fi
342         shift
343     done | sort | uniq
344 }
345
346 convert_html_xsl() {
347     echo '
348 <xsl:stylesheet
349   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
350   xmlns:site="http://projectmallard.org/site/1.0/"
351   version="1.0">
352 <xsl:import href="'${datadir}/mallard-site-tool/site2html.xsl'"/>'
353     if [ "x$site_custom" != "x" ]; then
354         echo "<xsl:include href='${site_directory}/${site_custom}'/>"
355     fi;
356     echo '</xsl:stylesheet>'
357 }
358
359 convert_html() {
360     site_format="$1"
361     shift
362     longopts='
363       -lsite:
364       -loutput:
365       -lhelp
366     ';
367     options=`getopt -qn$progname $longopts -- s:o:Vh "$@"`
368     if [ "$?" != "0" ]; then print_help_html 1>&2; exit 1; fi
369     eval set -- "$options";
370     site_output_dir=`pwd`
371     while [ "$1" != "--" ]; do
372         case "$1" in
373             -s | --site)
374                 site_site="$2";;
375             -o | --output)
376                 site_output_dir="$2";;
377             -h | --help)
378                 print_help_cache
379                 exit 0;;
380             --)
381                 print_help_cache 1>&2
382                 exit 1;;
383         esac
384         shift
385     done
386     shift
387     locate_site_file
388     site_cache="${site_directory}/${site_site}.cache"
389     site_root=`echo "$XSL_GET_ROOT" | xsltproc - "$site_file"`
390     site_custom=`echo "$XSL_GET_CUSTOM" | xsltproc - "$site_file"`
391     if [ "x$site_root" = "x" ]; then
392         site_root="file://"$(urlencode "$site_directory")
393     fi
394
395     for page in $(find $(pwd) -name '*.page'); do
396         page_dir=$(dirname $(echo "$page" | cut -c${#site_directory}- | cut -c2-))/
397         page_base=$(basename "$page" .page)
398         page_output="$site_output_dir$page_dir$page_base.$site_format"
399         mkdir_p $(dirname "$page_output")
400         convert_html_xsl | xsltproc \
401             --xinclude \
402             -o "$page_output" \
403             --stringparam mal.site.dir "$page_dir" \
404             --stringparam mal.site.root "$site_root" \
405             --stringparam mal.cache.file "$site_cache" \
406             - "$page"
407     done
408 }
409
410 site_site="index"
411
412 command="$1";
413 if [ "x$command" = "x" ]; then
414     print_help 1>&2;
415     exit 1;
416 fi;
417 shift;
418 if [ "x$command" = "xhelp" -o "x$command" = "x--help" -o "x$command" = "x-h" ]; then
419     print_help;
420     exit 0;
421 elif [ "x$command" = "xhtml" ]; then
422     convert_html "$command" $@;
423 elif [ "x$command" = "xcache" ]; then
424     create_cache $@;
425 elif [ "x$command" = "xcss" ]; then
426     create_css $@;
427 else
428     print_help 1>&2;
429     exit 1;
430 fi;
431