summaryrefslogtreecommitdiff
path: root/contrib/fixps.m4
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fixps.m4')
-rw-r--r--contrib/fixps.m4315
1 files changed, 315 insertions, 0 deletions
diff --git a/contrib/fixps.m4 b/contrib/fixps.m4
new file mode 100644
index 0000000..002449e
--- /dev/null
+++ b/contrib/fixps.m4
@@ -0,0 +1,315 @@
+include(shell.m4)dnl -*- shell-script -*-
+#! /bin/sh -e
+
+# fixps --- fix as much as possible PS errors that break the psutils
+
+GPL([Copyright (c) 1998-2000 Akim Demaille, Miguel Santana])
+
+# Author: Akim Demaille <Akim.Demaille@freefriends.org>
+
+# Get the name of the program
+program=`echo $0 | sed 's#.*/##g'`
+
+# Local vars
+debug=
+file=
+# Look for a running ghostscript
+gs=${GHOSTSCRIPT:-${GS:-gs}}
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if ($gs -v) >/dev/null 2>&1; then :; else
+ gs=
+fi
+output=- # Default is stdout
+run_gs=0
+# What action to perform: fixps, cat, check, and gs
+task=fixps
+tmpdir=`mktemp -d -t fixps.XXXXXX` || { echo "$program: Cannot create temporary dir!" >&2 ; exit 1; }
+verbose=echo
+
+# The version/usage strings
+version="fixps 1.5 (@GNU_PACKAGE@ @VERSION@)
+Written by Akim Demaille.
+
+Copyright (c) 1998-2000 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."
+
+usage=["\
+Usage: $program [OPTIONS] FILE
+Try 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
+ -f, --force force full rewrite by ghostscript
+ -n, --no-fix don't fix the FILE, but still honor \`-o'
+ -c, --check, --dry-run don't perform any action
+
+Fixes:
+ - Remove junk before and after PostScript content
+ - Use only Unix end of lines (\\n)
+ - Remove empty lines
+ - Fix Apple prologue (fixmacps)
+ - Fix FrameMaker prologue (fixfmps)
+ - Fix CorelDraw prologue (fixnt)
+ - Fix Windows NT 3.5/4.0 prologue (fixnt)
+ - Fix Windows 95 prologue
+ - Ensure there is a \`%%BeginSetup/%%EndSetup' section
+ - Removes Canvas' extraneaous \`%%EndDocument:' comments
+ - Split too long lines
+
+If the FILE seems really in a bad state, ghostscript may be used to perform
+a full rewrite. The output might then be significantly bigger, but much
+safer.
+
+Report bugs to <bug-a2ps@gnu.org>"]
+
+help="Try \`$program --help' for more information."
+
+# Parse command line arguments.
+option_without_arguments='vhsqDfn'
+
+GETOPT([ -v | --v*) echo "$version"; exit 0;;
+ -h | --h*) echo "$usage"; exit 0;;
+ -q | -s | --s* | --q*) verbose=:;;
+ # Delay debugging so that options parsing does not appear
+ -D | --debug) debug=: ;;
+ -o | --output) shift ; output=$1 ;;
+ -c | --check | --dry-run) task=check ;;
+ -n | --no-fix) task=cat ;;
+ -f | --force)
+ # Refuse if gs does not seem to work
+ if test "x$gs" = x; then
+ echo "$program: error: ghostscript does not work." >&2
+ exit 1
+ else
+ run_gs=1
+ fi
+ ;;
+ -) # We are working with stdin ;;
+ set dummy "$@" "$1"; shift;;])
+
+# Check the number of arguments.
+case $# in
+ 0) file=-;;
+ 1) file=$1;;
+ *) echo "$program: too many arguments" 1>&2
+ echo "$help" 1>&2
+ 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
+
+fixps_sed=$tmpdir/fixps.sed
+
+# 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 by hand what is not part of the PS.
+# Beware of the non Unix end of lines.
+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. Use only '\n'.
+ tr '\015' '\012' < $file | sed -n -e '/%!/,/^%%EOF$/{
+ s/^.*%!/%!/
+ s/^%!$/%!PS/
+ p
+}' > $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 comment everything can be done with a pipe. ##
+## ------------------------------------------------------- ##
+
+
+: >$fixps_sed
+
+# For a start, use only '\n'. Don't try to remove multiple end of
+# line, since you may break valid PostScript code (think of binary
+# sections).
+command="tr '\015' '\012' < $file | sed -f $fixps_sed"
+
+# 1. Broken end-of-line (Mac?)
+if sed 20q $file | grep ' %%' > /dev/null; then
+ $verbose "$program: fixing Macintosh broken end of line." >&2
+fi
+
+# 2. Remove the ^M$, because they prevent some parsers to work normally
+if sed 20q $file | grep ' $' > /dev/null; then #'
+ $verbose "$program: fixing PC broken end of line." >&2
+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 '1p;/^%%/p;/FMDEFINEFONT/p;/FMBEGINPAGE/p'`
+
+# If the file does not appear to have enough of the DSC features, just
+# let it be rewritten by gs.
+if echo "$comments" | grep "EPSF" >/dev/null 2>&1; then
+ # EPS files need at least the BBox
+ patterns="^%%BoundingBox:";
+else
+ # PS files really need page separation information
+ patterns="^%%Pages: ^%%Page:"
+fi
+
+# If some required DSC comments are not present, ask for a full rewrite.
+for pattern in $patterns
+do
+ if echo "$comments" | grep "$pattern" >/dev/null; then :; else
+ $verbose "$program: DSC broken. $gs will be asked a full rewrite of the file." >&2
+ run_gs=1
+ break;
+ fi
+done
+
+if test $run_gs = 1 && test "x$gs" = x; then
+ echo "$program: warning: cannot run gs, except failures downstream." >&2
+ run_gs=0
+fi
+
+# The cleanup is to be made by hand.
+if test $run_gs = 0; then
+ # If there are lines too long, split them.
+ maxlen_awk=$tmpdir/maxlen.awk
+ cat >$maxlen_awk <<EOF
+length > max { max = length ; }
+END { print max ; }
+EOF
+ # Compute the max line length.
+ maxlen=`eval "$command" | awk -f $maxlen_awk`
+ if test "$maxlen" -ge "128"; then
+ cutline_sed=$tmpdir/cut.sed
+ # A script that split in piece hexa lines longer than 81 chars.
+ cat >$cutline_sed <<'EOF'
+[/^[A-Fa-f0-9]\{81,\}$/b big
+ p
+ b
+:big
+ h
+ s/^\([A-Fa-f0-9]\{72\}\).*/\1/
+ p
+ g
+ s/^[A-Fa-f0-9]\{72\}\(.*\)/\1/
+t big]
+EOF
+ $verbose "$program: splitting lines too long." >&2
+ command="$command | sed -n -f $cutline_sed"
+ fi
+
+ # 7. Broken AppleDict procset
+ if echo $comments | fgrep 'AppleDict' > /dev/null; then
+ $verbose "$program: fixing Macintosh broken prologue." >&2
+ command="$command | fixmacps"
+ fi
+
+ # 8. Broken Frame Maker procset
+ if echo $comments | fgrep 'Frame' > /dev/null; then
+ $verbose "$program: fixing Frame Maker broken prologue." >&2
+ command="$command | fixfmps"
+ fi
+
+ # 9. Broken CorelDRAW ps, with fixnt
+ if echo "$comments" | grep '^%%Title:.*CorelDRAW' > /dev/null; then
+ $verbose "$program: fixing CorelDRAW broken prologue." >&2
+ command="$command | fixnt"
+ # 10. 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"
+ # 11. 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
+ echo 's/NTPSOct94/NTPSOct95/g' >>$fixps_sed
+ command="$command | fixnt"
+ fi
+
+ # 12. Broken Windows 95 PS driver v4.0
+ if echo "$comments" | grep 'Pscript_Win_Utils' > /dev/null; then
+ $verbose "$program: fixing Broken Windows 95 PS driver v4.0 prologue." >&2
+ echo 's!|/LH/showpage ,!|/LH {showpage}!' >>$fixps_sed
+ fi
+
+ # 14. Canvas' superfluous `EndDocument:'
+ if echo "$comments" | grep 'CanvasDict' >/dev/null; then
+ $verbose "$program: removing Canvas' extraneous \`%%EndDocument:' comment." >&2
+ echo '/^%%EndDocument:/d' >>$fixps_sed
+ fi
+
+ # This should be the last one.
+ # 13. Missing BeginSetup/EndSetup
+ if echo "$comments" | grep '^%%BeginSetup' >/dev/null; then :; else
+ $verbose "$program: adding a %%BeginSetup/%%EndSetup section." >&2
+ # Because the command will be `eval'ed, it is hard to keep the eol.
+ # Making a script is much easier.
+ cat >>$fixps_sed <<EOF
+/^%%EndProlog/a\\
+%%BeginSetup\\
+%%EndSetup
+EOF
+ fi
+fi
+
+test $run_gs = 1 && task=gs
+
+# For dry runs, the output should not even be redirected
+if test $task != check; then
+ (
+ test "$output" != "-" && exec >"$output"
+ case $task in
+ cat)
+ cat "$file" ;;
+ fixps)
+ # FIXME: We should fail when the program fails
+ eval "$command" ;;
+ gs)
+ $verbose "$program: making a full rewrite of the file ($gs)." >&2
+ $gs -q -dNOPAUSE -dBATCH -sDEVICE=pswrite -sOutputFile=- -c save pop -f $file ;;
+ esac
+ )
+fi
+
+exit 0