#!/bin/sh # Generate a book from man pages. # Copyright (C) 2006 Marc Vertes # 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, 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. # release 1.5.6 man() { cat << \EOT NAME bookman - Generate a book from man pages SYNOPSIS bookman [-pPxn] [-o outfile] [-a author] [-d date] [-r release] [-t title] [-v volume] [-c coverfile] [manfile] DESCRIPTION bookman compiles a set of man pages files specified by manfile arguments, or if no manfile is given, filenames are read from standard input. OPTIONS -p PDF output format. -P Postscript output format. -x X11 previewing, using gxditview(1). -n no format, output is direct gtroff intermediate format. -o outfile Output in file outfile. Default is standard output. -a author Set the author, on the cover page. -d date Set the date on the cover page. -r release Set the book name and release on the cover page. -t title Set the title on the cover page. -v volume Specify the name of the volume. -c coverfile Uses the file coverfile to generate the cover page, i.e. all pages preceding the table of content. coverfile must be in groff_ms(7) format. ENVIRONMENT SOURCE_DATE_EPOCH Unix timestamp that is used for date in header instead of current date. EXAMPLE To build a reference manual from section 2 man, do: $ cd /usr/share/man/man2 $ bookman -p -t 'Unix Reference Manual' * >book.pdf SEE ALSO man(1), mandoc(7), groff_ms(7), groff(1), troff(1), grops(1), gxditview(1), ps2pdf(1). AUTHOR Marc Vertes EOT } post="grops" while getopts :a:c:d:mno:pPr:t:v:x opt do case $opt in (a) author=$OPTARG;; (c) cover=$OPTARG;; (d) date=$OPTARG;; (m) man; exit;; (n) post=cat;; (o) outfile=$OPTARG;; (p) post='grops | ps2pdf -';; (P) post=grops;; (x) post='gxditview -';; (r) release=$OPTARG;; (t) title=$OPTARG;; (v) volume=$OPTARG;; (*) man; exit;; esac done shift $(($OPTIND - 1)) if [ -n "$SOURCE_DATE_EPOCH" ]; then date=$(LC_ALL=C date -u -d "@$SOURCE_DATE_EPOCH" +'%d %B %Y') fi date=${date:-$(date +'%d %B %Y')} [ $1 ] || set -- $(while read REPLY; do echo "$REPLY"; done) [ $outfile ] && post="$post >$outfile" { # Compute table of content from postscript output. # Generate output in gtroff intermediate format, so # it can be merged with content. { [ -f "$cover" ] && cat "$cover" || { printf ".af %% i\n.P1\n" printf ".OH ||%s||\n" "$volume" printf ".EH ||%s||\n" "$volume" printf ".OF |%s|%s|%%|\n" "$release" "$date" printf ".EF |%s|%s|%%|\n" "$release" "$date" printf ".TL\n%s\n" "$title" printf ".AU\n%s\n.AB no\n.AE\n" "$author" } for f do case $f in (*.Z|*.gz) zcat $f;; (*.bz2) bzcat $f;; (*) cat $f;; esac done | groff -man -rC1 -Tps | awk ' $1 == "%%Page:" {page = $2} /%%EndPageSetup/ { getline l; getline; $0 = l $0 # extract first word (disgard everything # outside braces). sub(/^[^\(]*\(/, "") gsub(/\)[^\(]*\(/, "") gsub(/\\214/, "fi") gsub(/\\215/, "fl") sub(/\)[^\(]*/, "") sub(/\\\(.*/, "") if (name != $0) { print (page == 1) ? ".XS 1" : ".XA " page print $0 } name = $0 } END {print ".XE"; print ".PX"}' } | groff -Z -ms | head --lines=-1 # Output content, in gtroff intermediate format. for f do case $f in (*.Z|*.gz) zcat $f;; (*.bz2) bzcat $f;; (*) cat $f;; esac done | groff -Z -man -rC1 | awk 'NR >3' } | eval $post