Making man pages easier to read

The abundance of man (short for manual) pages in Unix and Linux systems is amazing, (almost) all commands are well-documented, and so are the programming APIs that a developer like me need to access on a daily basis. The only problem is that the default reader for them, the man command, displays them as text in a terminal window.

You can coerce the GNU man program to output manual pages as PostScript, however, but you need to feed that into a program that can display the PostScript. I use evince, the GNOME Document Viewer, for that. Unfortunately, there is some sort of interoperability issue here that, at least on my installation, blocks copy-paste from the generated PostScript.

I found that if I convert the PostScript to PDF using ps2pdf, copy-paste works. This is a lot to type to open a single manual page, however, so I ended up writing a script for it. Since I used to write a lot of Perl scripts earlier, the script also lets me look up the Perl manual using perldoc (which can be told to output nroff, the input format for manual pages, so that it can then go through the whole chain and end up as PDF).

This is what my little script has evolved to now. Since I have it running on several different machines, it does some detection of which software is installed, but it does need GNU man and GNOME evince at the very least (or you can replace it with the PS/PDF viewer of your choice). If ps2pdf is installed, it displays a PDF version for better interoperability. You can ask it for a manual page, to read perldoc from a file, or look up the perldoc manual by entering perldoc entry as the parameters. YMMV.

#!/bin/bash
# gman: Display manual page as PDF
# Written by Peter Krefting <peter AT softwolves.pp.se>
# SPDX-License-Identifier: BSD-2-Clause

if [ -z "$1" ]; then
  echo "Usage: gman perldoc <page>"
  echo "Usage: gman <file> | <manpage>..."
  echo
  echo "  Displays manual or perldoc documents as PDF"
  echo "  <page>     Perldoc page to display"
  echo "  <file>     File to open (perldoc or man)"
  echo "  <manpage>  Manual page to display"
  exit 0
fi

if [ -x /usr/bin/mktemp ]; then
  TEMPFILE="$(mktemp "$TMPDIR/XXXXXXXXXX.ps")"
elif [ -x /usr/bin/tempfile ]; then
  # Disable "tempfile is deprecated. Use mktemp instead", since we tried that...
  # shellcheck disable=SC2186
  TEMPFILE="$(tempfile --suffix .ps)"
else
  echo 'FIXME: Unable to create temporary file!' >&2
  exit 1
fi
if [ -f "$1" ]; then
  # Perldoc on file, unless manual file
  if [[ "$1" == *.[0-9]* ]]; then
    man -Tps "$1" > "$TEMPFILE"
  else
    perldoc -onroff -d"$TEMPFILE.nroff" "$1"
    man -Tps "$TEMPFILE.nroff" > "$TEMPFILE"
    rm "$TEMPFILE.nroff"
  fi
elif [ "$1" = "perldoc" ]; then
  # Perldoc manual
  if [ -n "$3" ]; then
    perldoc -onroff -d"$TEMPFILE.nroff" "$2" "$3"
  else
    perldoc -onroff -d"$TEMPFILE.nroff" "$2"
  fi
  man -Tps "$TEMPFILE.nroff" > "$TEMPFILE"
  rm "$TEMPFILE.nroff"
else
  # Assume manual page
  man -Tps "$@" > "$TEMPFILE"
fi
if [ -x /usr/bin/ps2pdf ]; then
  ps2pdf "$TEMPFILE" "$TEMPFILE.pdf"
  ( evince "$TEMPFILE.pdf" 2> /dev/null ; rm "$TEMPFILE.pdf" ) &
  rm "$TEMPFILE"
else
  ( evince "$TEMPFILE" 2> /dev/null ; rm "$TEMPFILE" ) &
fi