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