#! /bin/sh
# -*- ksh -*-

# fixps --- fix as much as possible PS errors that break the psutils

# Copyright (c) 1988, 89, 90, 91, 92, 93 Miguel Santana
# Copyright (c) 1995, 96, 97, 98 Akim Demaille, Miguel Santana

# $Id: fixps.in,v 1.10 1998/07/23 15:00:42 demaille Exp $

# 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, you can either send email to this
# program's maintainer or write to: The Free Software Foundation,
# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.

# Commentary:

# Author: Akim Demaille <demaille@inf.enst.fr>

# In the interest of general portability, some common bourne shell
# constructs were avoided because they weren't guaranteed to be available
# in some earlier implementations.  I've tried to make this program as
# portable as possible.  Welcome to unix, where the lowest common
# denominator is rapidly diminishing.
#
# Among the more interesting lossages I noticed with some bourne shells
# are:
#     * No shell functions.
#     * No `unset' builtin.
#     * `shift' cannot take a numeric argument, and signals an error if
#       there are no arguments to shift.

# Todo:
# Should be rewriten in perl.  It would help to handle
# (Begin|End)Document which allows several Trailers etc.

# Code:

# Minimal path.  It must be able to see the psutils.
PATH=/usr/local/bin:$PATH
export PATH

# Get the name of the program
program=`echo $0 | sed 's#.*/##g'`

# Local vars
debug=
file=
output=
tmpdir=/tmp/$program.$$
verbose=echo

# The version/usage strings
version="fixps 0.5 (a2ps 4.10.4)

Copyright (c) 1988, 89, 90, 91, 92, 93 Miguel Santana
Copyright (c) 1995, 96, 97, 98 Akim Demaille, Miguel Santana
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Written by <Akim.Demaille@inf.enst.fr> and <Miguel.Santana@st.com>
News, updates and documentation: visit http://www.inf.enst.fr/a2ps/"

usage="\
Usage: $program FILE
Tries to fix common PostScript problems that break postprocessing.

Options:
 -h, --help           display this help and exit
 -v, --version        display version information and exit
 -q, --quiet          don't print informational messages
 -o, --output=FILE    save result in FILE.  If FILE is \`-', send to stdout

Report bugs to <a2ps-bugs@inf.enst.fr>"

help="Try \`$program --help' for more information."

# Parse command line arguments.
option_without_arguments='vhsq'
while test $# -gt 0; do
  
  # Handle --option=value by splitting apart and putting back on argv.
  case "$1" in
    --*=*)
      opt=`echo "$1" | sed -e 's/=.*//'`
      val=`echo "$1" | sed -e 's/[^=]*=//'`
      shift
      set - "$opt" "$val" "$@"
      ;;

    -[$option_without_arguments]?*)
      opt=`echo "$1" | sed -e 's/-\\(.\\).*/-\1/'`
      rest=`echo "$1" | sed -e 's/-.\\(.*\\)/-\1/'`
      shift
      set - "$opt" "$rest" "$@"
      ;;

    # This case needs to be protected so that the case `-??*' does
    # not split long options without arguments
    --*)
      ;;

    # This is an option non without argument.  It can be either an error,
    # or a option with argument.  In the first case, the error will still
    # be catched though the `argument' has been separated.
    -??*)
      opt=`echo "$1" | sed -e 's/-\\(.\\).*/-\1/'`
      arg=`echo "$1" | sed -e 's/-.\\(.*\\)/\1/'`
      shift
      set - "$opt" "$arg" "$@"
      ;;
  esac
  
  # This recognizes --heltch as --help.  So what.
  case "$1" in
    --h*|-h)  echo "$usage";   exit 0  ;;
    --v*|-v)  echo "$version"; exit 0  ;;
    -s|-q|--q*|--s*) verbose=: ;;
    -D|--debug) debug=: ;;
    
    --output|-o) shift; output=$1 ;;
    
    -) # We are working with stdin
       nonopt="$nonopt $1"
       ;;
    
    -*)
      exec 1>&2
      echo "$program: Unknown or ambiguous option \`$1'."
      echo "$program: Try \`--help' for more information."
      exit 1
      ;;
    
    *) nonopt="$nonopt $1"  ;;
  esac
  shift
done

case `echo "$nonopt" | wc -w | sed -e 's/[\t ]//g'` in
  0)  file=-;;
  1)  file=$nonopt;;
  *)  exec 1>&2
     echo "$program: too many arguments"
     echo "$help"
     exit 1;;
esac

if test -n "$debug"; then
  # Set -x now if debugging
  set -x
else
  # Temp dir.  Get ready not to leave junk (if not debugging)
  trap "/bin/rm -rf $tmpdir" 0 1 2 3 13 15
fi

mkdir $tmpdir

# If printing from stdin, save into a tmp file
if test $file = '-'; then
  file=$tmpdir/stdin.ps
  cat > $file
fi

#################### Global fixes ####################

# 1. Extract what looks like a real PS file, i.e. something between
# a "%!" and a "%%EOF".  If the latter is not present, go until
# the end of the file.
# It typically remove JCL junk, but also permits to print the PS content
# of a mail without having to remove at hand what is not part of the PS.
if sed 1q $file | grep '^%!' >/dev/null; then :; else
  fix=1
  $verbose "$program: removing junk around PostScript content." >&2
  $verbose "$program: fixing broken magic number." >&2
  # At the same time, make sure the first line does start by
  # a valid magic number
  sed -n -e '/%!/,/^%%EOF$/p' $file \
   | sed 's/^.*%!/%!/' | sed 's/^%!$/%!PS/'\
   > $tmpdir/fixed-$fix.ps
  file=$tmpdir/fixed-$fix.ps
fi

# If at this point the file does not start with a real PostScript
# magic number, fail
if sed 1q $file | grep '^%!' >/dev/null; then :; else
  echo "$program: error: the file seems not to be PostScript." >&2
  exit 1
fi

############ After this line everything can be done with a pipe ##########
command="cat $file"
# 4. Broken end-of-line (Mac?)
if sed 20q $file | grep '
%%' > /dev/null; then
  $verbose "$program: fixing Macintosh broken end of line." >&2
  command="$command | tr '\r' '\n'"
fi

# 5. Remove the ^M$, because the prevent some parsers to work normally
if sed 20q $file | grep '
$' > /dev/null; then
  $verbose "$program: fixing PC broken end of line." >&2
  command="$command | sed -e 's/
$//g'"
fi
#################### Fixes on prologues/structure ####################
# Put in $COMMENT everything we will need to find out the nature
# of the file. (This is to speed up the processind)
# Fetch all the lines with ``%%'' at the beginning, but
# also words `FMDEFINE'
comments=`eval "$command" | sed -ne '/^%%/p;/FMDEFINEFONT/p;/FMBEGINPAGE/p'`

# 6. Broken AppleDict procset
if echo $comments | fgrep 'AppleDict' > /dev/null; then
  $verbose "$program: fixing Macintosh broken prologue." >&2
  command="$command | fixmacps"
fi

# 7. Broken Frame Maker procset
if echo $comments | fgrep 'Frame' > /dev/null; then
  $verbose "$program: fixing Frame Maker broken prologue." >&2
  command="$command | fixfmps"
fi

# 8. Broken CorelDRAW ps, with fixnt
if echo "$comments" | grep '^%%Title:.*CorelDRAW' > /dev/null; then
  $verbose "$program: fixing CorelDRAW broken prologue." >&2
  command="$command | fixnt"
# 9. Broken Windows NT 4.0 ps, still fixnt
elif echo "$comments" | grep 'NTPSOct95' > /dev/null; then
  $verbose "$program: fixing Windows NT 4.0 broken PostScript." >&2
  command="$command | fixnt"
# 10. Broken Windows NT 3.5 ps, yet another fixnt
elif echo "$comments" | grep 'NTPSOct94' > /dev/null; then
  $verbose "$program: fixing Windows NT 3.5 broken PostScript." >&2
  command="$command | sed -e 's/NTPSOct94/NTPSOct95/g' | fixnt"
fi

# Output the result
if test -n "$output" && test "$output" != "-"; then
  eval $command > $output || exit 1
else
  eval $command || exit 1
fi

# Don't remove files if debugging
test -n "$debug" || /bin/rm -rf $tmpdir

exit 0

