5

I want to print several man pages as several booklets. I need to tweak the output of the man -t command so the resulting PostScript file will have the brochurised page numbering, pages must be numerated on 'outer' edges, and 'inner' margin must be wider than 'outer'. How can I achieve this?

P.S. By "brochurised" ("booklet") numbering I mean such kind of numbering so if several printed pages are folded in half at once, the result will look like a book with proper sequental page numbering.

  • There is template from which output PS file is generated. In my Gentoo it's /usr/share/groff/1.21/font/devps/prologue, so if you know postscript you could modify it. – pbm Jul 8 '11 at 15:16
  • That will require modification of that file every time I change my mind how to print. I am actually searching for some kind of parameters that would be propagated by man down to groff to control the output. – mbaitoff Jul 10 '11 at 6:02
2

An awesome shell script written some time ago by a friend: livre.

You'll be interested in the --book and --inner options.


#!/bin/sh
#---------------
# A parametrized replacement for psnup -2 using pstops.
#
# The script computes bounding boxes using gs and deduces optimized reductions
# on two pages per sheet with given margins or scaling. Pages can be arranged
# for various kinds of folding or binding.
#---------------
# Requires: gs, bc, pstops, psbook, pdftops
#---------------

VERSION=2009-12-02

# Output parameters

PAPER=a4
WIDTH=597   # 210mm
HEIGHT=845  # 297mm
MARGIN=30
INNER=1
SCALE=
TWO=false
BIND=top
BBRANGE=-
SIG=
IN=
OUT=
DASHQ=-q
VERBOSE=false
BB_ODD=
BB_EVEN=

# Parse the command line

while [ $# -gt 0 ]; do
        case "$1" in
        --help)
                cat <<EOF
usage: livre.sh [options] input output
The input can be in PostScript or PDF, possibly gzipped.
options:
  --margin SIZE    compute scaling to get SIZE-point margins (default: 30)
  --scale FACTOR   use the given scaling FACTOR (overrides --margin)
  --inner FACTOR   set inner margin to FACTOR times the outer one (default: 1)
  --two            input is two-sided
  --top            output should be bound at the top (default)
  --left           output should be bound on the left
  --book           output should be folded into a booklet
  --sig N          select the signature for psbook (implies --book)
  --bbrange PAGES  only use the specified PAGES for bounding box computation
  --bbox BBOX      provide the bounding box explictly, disable its computation
                     (use this twice if the input is two-sided)
  --verbose        do not use quiet mode
  --version        print version number and exit
EOF
                exit 0
                ;;
        --version)
                echo $VERSION
                exit 0
                ;;
        --margin)
                shift
                MARGIN="$1"
                ;;
        --scale)
                shift
                SCALE="$1"
                ;;
        --inner)
                shift
                INNER="$1"
                ;;
        --two*)
                TWO=true
                ;;
        --top|--left|--book)
                BIND=${1#--}
                ;;
        --sig)
                shift
                SIG="-s$1"
                BIND=book
                ;;
        --bbrange)
                shift
                BBRANGE="$1"
                ;;
        --bbox)
                shift
                if [ -z "$BB_ODD" ]; then
                        BB_ODD="$1"
                else
                        TWO=true
                        BB_EVEN="$1"
                fi
                ;;
        --verbose)
                DASHQ=
                VERBOSE=true
                ;;
        -*)
                echo "unknown option: $1" >&2
                exit 1
                ;;
        *)
                if [ -z "$IN" ]
                then IN="$1"
                elif [ -z "$OUT" ]
                then OUT="$1"
                else echo "unused argument: $1" >&2
                fi
        esac
        shift
done

if [ -z "$IN" ]; then
        echo "missing input file" >&2
        exit 1
fi

# Make a teporary file if needed

TMP=

make_ps ()
{
        case $(file -bL "$IN") in
        "PostScript document"*)
                ;;
        "PDF document"*)
                $VERBOSE && echo "converting to PS..." >&2
                TMP2=$(mktemp)
                pdftops "$IN" "$TMP2"
                test -n "$TMP" && rm "$TMP"
                TMP="$TMP2"
                IN="$TMP"
                ;;
        "gzip compressed "*)
                $VERBOSE && echo "unzipping..." >&2
                TMP2=$(mktemp)
                gunzip < "$IN" > "$TMP2"
                test -n "$TMP" && rm "$TMP"
                TMP="$TMP2"
                IN="$TMP"
                make_ps
                ;;
        *)
                echo "Unknown file type!" >&2
                exit 1
        esac
}

make_ps

# Extract the bounding box for all pages of a given file.

read_bbox()
{
        gs -sDEVICE=bbox -sPAPERSIZE=$PAPER -r300x300 -q -dBATCH -dNOPAUSE "$1" 2>&1 | awk '
function min(x,y) { if (x < y) return x; else return y }
function max(x,y) { if (x > y) return x; else return y }
BEGIN {
        left = top = 10000;
        right = bottom = 0
}
/%%BoundingBox:/ {
        left = min(left, $2);
        top = min(top, $3);
        right = max(right, $4);
        bottom = max(bottom, $5);
}
END { print left, top, right, bottom }
'
}

# Compute the maximum scaling factor given the bounding box

max_scale()
{
        bc <<EOF
scale = 3
hfactor = (($HEIGHT - (2 + $INNER) * $MARGIN) / 2) / ($3 - $1)
vfactor = ($WIDTH - 2 * $MARGIN) / ($4 - $2)
if (hfactor < vfactor) print hfactor else print vfactor
EOF
}

# Make a pstops specification

spec_left()
{
        bc <<EOF
scale = 3
factor = $1
shift_x = $WIDTH / 2 + ($3 + $5) * factor / 2
vmargin = ($HEIGHT - 2 * ($4 - $2) * factor) / (2 + $INNER)
shift_y = vmargin - $2 * factor + $6 * (($4 - $2) * factor + $INNER * vmargin)
print "L@", factor, "(", shift_x, ",", shift_y, ")"
EOF
}

spec_right()
{
        bc <<EOF
scale = 3
factor = $1
shift_x = $WIDTH / 2 - ($3 + $5) * factor / 2
vmargin = ($HEIGHT - 2 * ($4 - $2) * factor) / (2 + $INNER)
shift_y = vmargin + $4 * factor + $6 * (($4 - $2) * factor + $INNER * vmargin)
print "R@", factor, "(", shift_x, ",", shift_y, ")"
EOF
}

# Compute the bounding boxes for even and odd pages

if [ -z "$BB_ODD" ]; then
        $VERBOSE && echo "computing the bounding box..." >&2
        if $TWO; then
                BB_ODD=$(psselect -o -p"$BBRANGE" "$IN" 2>/dev/null | read_bbox -)
                BB_EVEN=$(psselect -e -p"$BBRANGE" "$IN" 2>/dev/null | read_bbox -)
        else
                if [ "$BBRANGE" = "-" ]; then
                        BB_ODD=$(read_bbox "$IN")
                else
                        BB_ODD=$(psselect -p"$BBRANGE" "$IN" 2>/dev/null | read_bbox -)
                fi
        fi
fi

test -z "$BB_EVEN" && BB_EVEN="$BB_ODD"

if $VERBOSE; then
        if $TWO; then
                echo "bounding box (odd): $BB_ODD"
                echo "bounding box (even): $BB_ODD"
        else
                echo "bounding box: $BB_ODD"
        fi
fi


# Deduce the scaling factor if needed

if [ -z "$SCALE" ]; then
        if $TWO; then
                SCALE=$(bc <<EOF
scale=3
s1=$(max_scale $BB_ODD)
s2=$(max_scale $BB_EVEN)
if (s1 < s2) print s1 else print s2
EOF
)
        else
                SCALE=$(max_scale $BB_ODD)
        fi
fi

$VERBOSE && echo "scale: $SCALE" >&2

# Process the file according to the chosen style

command()
{
        $VERBOSE && echo "-- $*"
        $*
}

case $BIND in
top)
        command pstops $DASHQ -p$PAPER "2:\
0$(spec_left $SCALE $BB_ODD 0)+1$(spec_left $SCALE $BB_EVEN 1)" "$IN" "$OUT"
        ;;
left)
        command pstops $DASHQ -p$PAPER "4:\
0$(spec_left $SCALE $BB_ODD 0)+1$(spec_left $SCALE $BB_EVEN 1),\
2$(spec_right $SCALE $BB_ODD 1)+3$(spec_right $SCALE $BB_EVEN 0)" "$IN" "$OUT"
        ;;
book)
        psbook $DASHQ $SIG $IN | command pstops $DASHQ -p$PAPER "4:\
0$(spec_left $SCALE $BB_EVEN 0)+1$(spec_left $SCALE $BB_ODD 1),\
2$(spec_right $SCALE $BB_EVEN 1)+3$(spec_right $SCALE $BB_ODD 0)" /dev/stdin "$OUT"
esac

test -n "$TMP" && rm "$TMP" || true
  • The link is broken and Internet Archive does not have a copy. This is an example why answers should contain the most important parts of the answer instead of just linking to it. – Mikko Rantalainen Jan 16 at 15:59
  • @Mikko: I haven't used it in a while, dunno if it needs maintenance, but you can have a try. – Stéphane Gimenez Jan 16 at 16:34
0

It may not be the perfect answer for your question. What I did is. man -t man > foo.ps . This created a Postscript file. Which I opened in Okular (Default PDF/PS Viewer with KDE). Okular rendered foo.ps just perfectly, with page numbering. So now I can print the doc.

  • How about page margins? Are they left-right or left only? – mbaitoff Sep 2 '11 at 16:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.