1#!/bin/sh -e
2# gendocs.sh -- generate a GNU manual in many formats.  This script is
3#   mentioned in maintain.texi.  See the help message below for usage details.
4
5scriptversion=2012-10-27.11
6
7# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
8# Free Software Foundation, Inc.
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22#
23# Original author: Mohit Agarwal.
24# Send bug reports and any other correspondence to bug-texinfo@gnu.org.
25#
26# The latest version of this script, and the companion template, is
27# available from Texinfo CVS:
28# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs.sh
29# http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs_template
30#
31# An up-to-date copy is also maintained in Gnulib (gnu.org/software/gnulib).
32
33# TODO:
34# - image importation was only implemented for HTML generated by
35#   makeinfo.  But it should be simple enough to adjust.
36# - images are not imported in the source tarball.  All the needed
37#   formats (PDF, PNG, etc.) should be included.
38
39prog=`basename "$0"`
40srcdir=`pwd`
41
42scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs.sh"
43templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs_template"
44
45: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="}
46: ${MAKEINFO="makeinfo"}
47: ${TEXI2DVI="texi2dvi -t @finalout"}
48: ${DOCBOOK2HTML="docbook2html"}
49: ${DOCBOOK2PDF="docbook2pdf"}
50: ${DOCBOOK2TXT="docbook2txt"}
51: ${GENDOCS_TEMPLATE_DIR="."}
52: ${PERL='perl'}
53: ${TEXI2HTML="texi2html"}
54unset CDPATH
55unset use_texi2html
56
57version="gendocs.sh $scriptversion
58
59Copyright 2012 Free Software Foundation, Inc.
60There is NO warranty.  You may redistribute this software
61under the terms of the GNU General Public License.
62For more information about these matters, see the files named COPYING."
63
64usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
65
66Generate output in various formats from PACKAGE.texinfo (or .texi or
67.txi) source.  See the GNU Maintainers document for a more extensive
68discussion:
69  http://www.gnu.org/prep/maintain_toc.html
70
71Options:
72  -s SRCFILE  read Texinfo from SRCFILE, instead of PACKAGE.{texinfo|texi|txi}
73  -o OUTDIR   write files into OUTDIR, instead of manual/.
74  -I DIR      append DIR to the Texinfo search path.
75  --email ADR use ADR as contact in generated web pages.
76  --docbook   convert through DocBook too (xml, txt, html, pdf).
77  --html ARG  pass indicated ARG to makeinfo or texi2html for HTML targets.
78  --info ARG  pass indicated ARG to makeinfo for Info, instead of --no-split.
79  --texi2html use texi2html to generate HTML targets.
80  --help      display this help and exit successfully.
81  --version   display version information and exit successfully.
82
83Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\"
84
85Typical sequence:
86  cd PACKAGESOURCE/doc
87  wget \"$scripturl\"
88  wget \"$templateurl\"
89  $prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\"
90
91Output will be in a new subdirectory \"manual\" (by default;
92use -o OUTDIR to override).  Move all the new files into your web CVS
93tree, as explained in the Web Pages node of maintain.texi.
94
95Please do use the --email ADDRESS option to specify your bug-reporting
96address in the generated HTML pages.
97
98MANUAL-TITLE is included as part of the HTML <title> of the overall
99manual/index.html file.  It should include the name of the package being
100documented.  manual/index.html is created by substitution from the file
101$GENDOCS_TEMPLATE_DIR/gendocs_template.  (Feel free to modify the
102generic template for your own purposes.)
103
104If you have several manuals, you'll need to run this script several
105times with different MANUAL values, specifying a different output
106directory with -o each time.  Then write (by hand) an overall index.html
107with links to them all.
108
109If a manual's Texinfo sources are spread across several directories,
110first copy or symlink all Texinfo sources into a single directory.
111(Part of the script's work is to make a tar.gz of the sources.)
112
113As implied above, by default monolithic Info files are generated.
114If you want split Info, or other Info options, use --info to override.
115
116You can set the environment variables MAKEINFO, TEXI2DVI, TEXI2HTML,
117and PERL to control the programs that get executed, and
118GENDOCS_TEMPLATE_DIR to control where the gendocs_template file is
119looked for.  With --docbook, the environment variables DOCBOOK2HTML,
120DOCBOOK2PDF, and DOCBOOK2TXT are also respected.
121
122By default, makeinfo and texi2dvi are run in the default (English)
123locale, since that's the language of most Texinfo manuals.  If you
124happen to have a non-English manual and non-English web site, see the
125SETLANG setting in the source.
126
127Email bug reports or enhancement requests to bug-texinfo@gnu.org.
128"
129
130MANUAL_TITLE=
131PACKAGE=
132EMAIL=webmasters@gnu.org  # please override with --email
133commonarg= # Options passed to all the tools (-I dir).
134dirs=      # -I's directories.
135htmlarg=
136infoarg=--no-split
137outdir=manual
138srcfile=
139
140while test $# -gt 0; do
141  case $1 in
142    --email) shift; EMAIL=$1;;
143    --help) echo "$usage"; exit 0;;
144    --version) echo "$version"; exit 0;;
145    -s) shift; srcfile=$1;;
146    -o) shift; outdir=$1;;
147    -I) shift; commonarg="$commonarg -I '$1'"; dirs="$dirs $1";;
148    --docbook) docbook=yes;;
149    --html) shift; htmlarg=$1;;
150    --info) shift; infoarg=$1;;
151    --texi2html) use_texi2html=1;;
152    -*)
153      echo "$0: Unknown option \`$1'." >&2
154      echo "$0: Try \`--help' for more information." >&2
155      exit 1;;
156    *)
157      if test -z "$PACKAGE"; then
158        PACKAGE=$1
159      elif test -z "$MANUAL_TITLE"; then
160        MANUAL_TITLE=$1
161      else
162        echo "$0: extra non-option argument \`$1'." >&2
163        exit 1
164      fi;;
165  esac
166  shift
167done
168
169# For most of the following, the base name is just $PACKAGE
170base=$PACKAGE
171
172if test -n "$srcfile"; then
173  # but here, we use the basename of $srcfile
174  base=`basename "$srcfile"`
175  case $base in
176    *.txi|*.texi|*.texinfo) base=`echo "$base"|sed 's/\.[texinfo]*$//'`;;
177  esac
178  PACKAGE=$base
179elif test -s "$srcdir/$PACKAGE.texinfo"; then
180  srcfile=$srcdir/$PACKAGE.texinfo
181elif test -s "$srcdir/$PACKAGE.texi"; then
182  srcfile=$srcdir/$PACKAGE.texi
183elif test -s "$srcdir/$PACKAGE.txi"; then
184  srcfile=$srcdir/$PACKAGE.txi
185else
186  echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
187  exit 1
188fi
189
190if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
191  echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
192  echo "$0: it is available from $templateurl." >&2
193  exit 1
194fi
195
196# Function to return size of $1 in something resembling kilobytes.
197calcsize()
198{
199  size=`ls -ksl $1 | awk '{print $1}'`
200  echo $size
201}
202
203# copy_images OUTDIR HTML-FILE...
204# -------------------------------
205# Copy all the images needed by the HTML-FILEs into OUTDIR.  Look
206# for them in the -I directories.
207copy_images()
208{
209  local odir
210  odir=$1
211  shift
212  $PERL -n -e "
213BEGIN {
214  \$me = '$prog';
215  \$odir = '$odir';
216  @dirs = qw($dirs);
217}
218" -e '
219/<img src="(.*?)"/g && ++$need{$1};
220
221END {
222  #print "$me: @{[keys %need]}\n";  # for debugging, show images found.
223  FILE: for my $f (keys %need) {
224    for my $d (@dirs) {
225      if (-f "$d/$f") {
226        use File::Basename;
227        my $dest = dirname ("$odir/$f");
228        #
229        use File::Path;
230        -d $dest || mkpath ($dest)
231          || die "$me: cannot mkdir $dest: $!\n";
232        #
233        use File::Copy;
234        copy ("$d/$f", $dest)
235          || die "$me: cannot copy $d/$f to $dest: $!\n";
236        next FILE;
237      }
238    }
239    die "$me: $ARGV: cannot find image $f\n";
240  }
241}
242' -- "$@" || exit 1
243}
244
245case $outdir in
246  /*) abs_outdir=$outdir;;
247  *)  abs_outdir=$srcdir/$outdir;;
248esac
249
250echo "Generating output formats for $srcfile"
251
252cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\""
253echo "Generating info file(s)... ($cmd)"
254eval "$cmd"
255mkdir -p "$outdir/"
256tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info*
257info_tgz_size=`calcsize "$outdir/$PACKAGE.info.tar.gz"`
258# do not mv the info files, there's no point in having them available
259# separately on the web.
260
261cmd="$SETLANG $TEXI2DVI $commonarg \"$srcfile\""
262echo "Generating dvi ... ($cmd)"
263eval "$cmd"
264
265# compress/finish dvi:
266gzip -f -9 $PACKAGE.dvi
267dvi_gz_size=`calcsize $PACKAGE.dvi.gz`
268mv $PACKAGE.dvi.gz "$outdir/"
269
270cmd="$SETLANG $TEXI2DVI --pdf $commonarg \"$srcfile\""
271echo "Generating pdf ... ($cmd)"
272eval "$cmd"
273pdf_size=`calcsize $PACKAGE.pdf`
274mv $PACKAGE.pdf "$outdir/"
275
276opt="-o $PACKAGE.txt --no-split --no-headers $commonarg"
277cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
278echo "Generating ASCII... ($cmd)"
279eval "$cmd"
280ascii_size=`calcsize $PACKAGE.txt`
281gzip -f -9 -c $PACKAGE.txt >"$outdir/$PACKAGE.txt.gz"
282ascii_gz_size=`calcsize "$outdir/$PACKAGE.txt.gz"`
283mv $PACKAGE.txt "$outdir/"
284
285html_split()
286{
287  opt="--split=$1 $commonarg $htmlarg --node-files"
288  cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\""
289  echo "Generating html by $1... ($cmd)"
290  eval "$cmd"
291  split_html_dir=$PACKAGE.html
292  (
293    cd ${split_html_dir} || exit 1
294    ln -sf ${PACKAGE}.html index.html
295    tar -czf "$abs_outdir/${PACKAGE}.html_$1.tar.gz" -- *.html
296  )
297  eval html_$1_tgz_size=`calcsize "$outdir/${PACKAGE}.html_$1.tar.gz"`
298  rm -f "$outdir"/html_$1/*.html
299  mkdir -p "$outdir/html_$1/"
300  mv ${split_html_dir}/*.html "$outdir/html_$1/"
301  rmdir ${split_html_dir}
302}
303
304if test -z "$use_texi2html"; then
305  opt="--no-split --html -o $PACKAGE.html $commonarg $htmlarg"
306  cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
307  echo "Generating monolithic html... ($cmd)"
308  rm -rf $PACKAGE.html  # in case a directory is left over
309  eval "$cmd"
310  html_mono_size=`calcsize $PACKAGE.html`
311  gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz"
312  html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"`
313  copy_images "$outdir/" $PACKAGE.html
314  mv $PACKAGE.html "$outdir/"
315
316  opt="--html -o $PACKAGE.html $commonarg $htmlarg"
317  cmd="$SETLANG $MAKEINFO $opt \"$srcfile\""
318  echo "Generating html by node... ($cmd)"
319  eval "$cmd"
320  split_html_dir=$PACKAGE.html
321  copy_images $split_html_dir/ $split_html_dir/*.html
322  (
323    cd $split_html_dir || exit 1
324    tar -czf "$abs_outdir/$PACKAGE.html_node.tar.gz" -- *
325  )
326  html_node_tgz_size=`calcsize "$outdir/$PACKAGE.html_node.tar.gz"`
327  rm -rf "$outdir/html_node/"
328  mv $split_html_dir "$outdir/html_node/"
329else
330  opt="--output $PACKAGE.html $commonarg $htmlarg"
331  cmd="$SETLANG $TEXI2HTML $opt \"$srcfile\""
332  echo "Generating monolithic html... ($cmd)"
333  rm -rf $PACKAGE.html  # in case a directory is left over
334  eval "$cmd"
335  html_mono_size=`calcsize $PACKAGE.html`
336  gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz"
337  html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"`
338  mv $PACKAGE.html "$outdir/"
339
340  html_split node
341  html_split chapter
342  html_split section
343fi
344
345echo Making .tar.gz for sources...
346d=`dirname $srcfile`
347(
348  cd "$d"
349  srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null` || true
350  tar cvzfh "$abs_outdir/$PACKAGE.texi.tar.gz" $srcfiles
351)
352texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"`
353
354if test -n "$docbook"; then
355  opt="-o - --docbook $commonarg"
356  cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml"
357  echo "Generating docbook XML... ($cmd)"
358  eval "$cmd"
359  docbook_xml_size=`calcsize $PACKAGE-db.xml`
360  gzip -f -9 -c $PACKAGE-db.xml >"$outdir/$PACKAGE-db.xml.gz"
361  docbook_xml_gz_size=`calcsize "$outdir/$PACKAGE-db.xml.gz"`
362  mv $PACKAGE-db.xml "$outdir/"
363
364  split_html_db_dir=html_node_db
365  opt="$commonarg -o $split_html_db_dir"
366  cmd="$DOCBOOK2HTML $opt \"${outdir}/$PACKAGE-db.xml\""
367  echo "Generating docbook HTML... ($cmd)"
368  eval "$cmd"
369  (
370    cd ${split_html_db_dir} || exit 1
371    tar -czf "$abs_outdir/${PACKAGE}.html_node_db.tar.gz" -- *.html
372  )
373  html_node_db_tgz_size=`calcsize "$outdir/${PACKAGE}.html_node_db.tar.gz"`
374  rm -f "$outdir"/html_node_db/*.html
375  mkdir -p "$outdir/html_node_db"
376  mv ${split_html_db_dir}/*.html "$outdir/html_node_db/"
377  rmdir ${split_html_db_dir}
378
379  cmd="$DOCBOOK2TXT \"${outdir}/$PACKAGE-db.xml\""
380  echo "Generating docbook ASCII... ($cmd)"
381  eval "$cmd"
382  docbook_ascii_size=`calcsize $PACKAGE-db.txt`
383  mv $PACKAGE-db.txt "$outdir/"
384
385  cmd="$DOCBOOK2PDF \"${outdir}/$PACKAGE-db.xml\""
386  echo "Generating docbook PDF... ($cmd)"
387  eval "$cmd"
388  docbook_pdf_size=`calcsize $PACKAGE-db.pdf`
389  mv $PACKAGE-db.pdf "$outdir/"
390fi
391
392echo "Writing index file..."
393if test -z "$use_texi2html"; then
394   CONDS="/%%IF  *HTML_SECTION%%/,/%%ENDIF  *HTML_SECTION%%/d;\
395          /%%IF  *HTML_CHAPTER%%/,/%%ENDIF  *HTML_CHAPTER%%/d"
396else
397   CONDS="/%%ENDIF.*%%/d;/%%IF  *HTML_SECTION%%/d;/%%IF  *HTML_CHAPTER%%/d"
398fi
399
400curdate=`$SETLANG date '+%B %d, %Y'`
401sed \
402   -e "s!%%TITLE%%!$MANUAL_TITLE!g" \
403   -e "s!%%EMAIL%%!$EMAIL!g" \
404   -e "s!%%PACKAGE%%!$PACKAGE!g" \
405   -e "s!%%DATE%%!$curdate!g" \
406   -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
407   -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
408   -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
409   -e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \
410   -e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \
411   -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
412   -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
413   -e "s!%%PDF_SIZE%%!$pdf_size!g" \
414   -e "s!%%ASCII_SIZE%%!$ascii_size!g" \
415   -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
416   -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
417   -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
418   -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
419   -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
420   -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
421   -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
422   -e "s,%%SCRIPTURL%%,$scripturl,g" \
423   -e "s!%%SCRIPTNAME%%!$prog!g" \
424   -e "$CONDS" \
425$GENDOCS_TEMPLATE_DIR/gendocs_template >"$outdir/index.html"
426
427echo "Done, see $outdir/ subdirectory for new files."
428
429# Local variables:
430# eval: (add-hook 'write-file-hooks 'time-stamp)
431# time-stamp-start: "scriptversion="
432# time-stamp-format: "%:y-%02m-%02d.%02H"
433# time-stamp-end: "$"
434# End:
435