xref: /plan9/sys/src/cmd/gs/lib/fixmswrd.pl (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1#!/usr/bin/perl
2# $Id: fixmswrd.pl,v 1.4 2002/02/21 21:53:01 giles Exp $
3
4#   (C) 1997 Anthony Shipman
5#
6#   This software is provided 'as-is', without any express or implied
7#   warranty.  In no event will the authors be held liable for any damages
8#   arising from the use of this software.
9#
10#   Permission is granted to anyone to use this software for any purpose,
11#   including commercial applications, and to alter it and redistribute it
12#   freely, subject to the following restrictions:
13#
14#   1. The origin of this software must not be misrepresented; you must not
15#      claim that you wrote the original software. If you use this software
16#      in a product, an acknowledgment in the product documentation would be
17#      appreciated but is not required.
18#   2. Altered source versions must be plainly marked as such, and must not be
19#      misrepresented as being the original software.
20#   3. This notice may not be removed or altered from any source distribution.
21#
22#   Anthony Shipman    shipmana@acm.org
23
24# This program patches the postscript generated by MS Word printer drivers
25# so that they work with ghostview 1.5.  The problem is that the document
26# structuring conventions are not followed by Word.  The pages are supposed
27# to be independent but they depend on a dictionary being opened outside
28# of the pages.  The erroneous structure is
29#
30# 	%%EndSetup
31# 	NTPSOct95 begin
32# 	%%Page: 1 1
33# 	<text>
34# 	showpage
35# 	%%Page: 2 2
36# 	<text>
37# 	showpage
38# 	......
39# 	%%Trailer
40# 	...
41# 	end
42# 	%%EOF
43#
44# This only works if the all of the structure around the pages is preserved.
45# The opening of NTPSOct95 happens outside of any structured section so
46# it is never seen by ghostview.  We change the structure to
47#
48# 	%%EndSetup
49# 	%%Page: 1 1
50# 	NTPSOct95 begin
51# 	<text>
52# 	showpage
53# 	end
54# 	%%Page: 2 2
55# 	NTPSOct95 begin
56# 	<text>
57# 	showpage
58# 	end
59# 	......
60# 	%%Trailer
61# 	...
62# 	%%EOF
63#
64# That is the dictionary opening is repeated inside each page.
65#
66# We add a comment to the document to mark that it has been converted.
67# This has the form
68#	%LOCALGhostviewPatched
69#
70# Usage:
71#	fixmswrd [-v] [file [output-file]]
72
73require 'getopts.pl';
74
75#=================================================================
76
77$program = "fixmswrd";
78
79sub usage {
80    die "Usage: $program [-v] [file [output-file]]\n";
81}
82
83#=================================================================
84
85&Getopts("v") || &usage;
86
87$verbose = $opt_v;
88
89
90$infile = shift(@ARGV);
91if ($infile)
92{
93    open(INFILE, $infile) || die "$program: Cannot read from $infile\n";
94    $handle = "INFILE";
95}
96else
97{
98    $handle = "STDIN";
99}
100
101
102$outfile = shift(@ARGV);
103if ($outfile)
104{
105    open(OUTFILE, ">$outfile") || die "$program: Cannot write to $outfile\n";
106    select(OUTFILE);
107}
108
109#  This reads the header comments and detects the presence of the marker.
110$have_marker = 0;
111
112undef $dict_name;
113undef $dict_line;
114
115&read_comments;
116&put_comments;
117
118if ($have_marker)
119{
120    $verbose && print STDERR "$program: Warning - already converted\n";
121
122    while(<$handle>)		# pass the file through unchanged.
123    {
124	print;
125    }
126}
127else
128{
129    $seen_trailer = 0;
130
131    while(<$handle>)		# massage the file
132    {
133	if ($dict_line)
134	{
135	    next if (/$dict_line/o);		# drop the old begin line
136	    $seen_trailer = 1 if (/^%%Trailer/);
137	    next if ($seen_trailer and /^end/);	# drop the old end line
138	}
139
140	print;
141
142	if (/^%%Page:/)
143	{
144	    print "$dict_name begin\n";	# add at the start of the page
145	}
146	elsif (/^showpage/)
147	{
148	    print "end\n";			# add at the end of the page
149	}
150	elsif (/^%%BeginResource: procset (\S+)/)
151	{
152	    $dict_name = $1;
153	    $dict_line = "^$dict_name begin";
154	}
155	elsif (/^%%BeginProcSet: (\S+)/)	# for older document versions
156	{
157	    $dict_name = $1;
158	    $dict_line = "^$dict_name begin";
159	}
160	elsif (/^%%EndProlog:/)
161	{
162	    unless ($dict_line)
163	    {
164		$verbose &&
165		    print STDERR "$program: Warning - unrecognised document structure\n";
166	    }
167	}
168    }
169}
170
171exit 0;
172
173#=================================================================
174
175
176#  This reads all of the header comments into an array which we can write
177#  out again later.  In addition we detect the presence of the marker comment.
178
179sub read_comments
180{
181    @headers = ();
182
183    while (<$handle>)
184    {				# without chopping
185	push(@headers, $_);
186	if (/^%LOCALGhostviewPatched/)
187	{
188	    $have_marker = 1;
189	}
190	last if /^%%EndComments/;
191    }
192}
193
194
195
196sub put_comments
197{
198    foreach $h (@headers)
199    {
200	if (!$have_marker and ($h =~ /^%%EndComments/))
201	{
202	    print "%LOCALGhostviewPatched\n";
203	}
204	print $h;		# contains the newline
205    }
206}
207