1#!/usr/bin/perl
2
3eval 'exec /usr/bin/perl  -S $0 ${1+"$@"}'
4    if 0; # not running under some shell
5#########################################################################
6#        This Perl script is Copyright (c) 2002, Peter J Billam         #
7#               c/o P J B Computing, www.pjb.com.au                     #
8#                                                                       #
9#     This script is free software; you can redistribute it and/or      #
10#            modify it under the same terms as Perl itself.             #
11#########################################################################
12
13eval "require 'Math/Evol.pm';";
14if ($@) { require 'Evol.pm'; }
15
16eval "require 'Term/Clui.pm';";
17if ($@) { require 'Clui'; }
18
19my $Version       = '1.13';
20my $VersionDate   = '13jun2017';
21my $KeepAllSteps  = 0;
22my $TmpDir        = "/tmp/ps_evol.$$";
23my $Landscape     = 0;
24use open ':locale';
25
26
27while ($ARGV[$[] =~ /^-([a-z])/) {
28	if ($1 eq 'v')      { shift;
29		my $n = $0; $n =~ s{^.*/([^/]+)$}{$1};
30		print "$n version $Version $VersionDate\n";
31		exit 0;
32	} elsif ($1 eq 'k') { $KeepAllSteps = 1; shift;
33	} elsif ($1 eq 'l') { $Landscape    = 1; shift;
34	} else {
35		print "usage:\n";  my $synopsis = 0;
36		while (<DATA>) {
37			if (/^=head1 SYNOPSIS/)     { $synopsis = 1; next; }
38			if ($synopsis && /^=head1/) { last; }
39			if ($synopsis && /\S/)      { s/^\s*/   /; print $_; next; }
40		}
41		exit 0;
42	}
43}
44
45$tmpfile = "/tmp/ps_evol_$$.ps";
46if ($KeepAllSteps) {
47	if (! mkdir $TmpDir) { die "can't mkdir $TmpDir: $!\n"; }
48	if (! chdir $TmpDir) { die "can't chdir $TmpDir: $!\n"; }
49}
50
51my @PATH = split (":",$ENV{PATH});
52sub which { my $f; foreach $d (@PATH) {$f="$d/$_[0]";  return $f if -x $f; }}
53
54sub choose_best_text {
55	if (! open (T, "> $tmpfile")) { die "can't open $tmpfile: $!\n"; }
56	print T @prolog;
57	# 1.13 the -l = Landscape option should display 2x4 rather than 3x3
58	print T <<EOT;
59(Helvetica-Bold) findfont 14 scalefont setfont
60
61% HERE BEGINS YOUR LATEST BEST CHOICE
62gsave 207 289 translate 5 5 moveto (5) show 0.30 dup scale
63$_[0]
64% HERE  ENDS  YOUR LATEST BEST CHOICE
65
66grestore gsave  20 550 translate 5 5 moveto (1) show 0.30 dup scale
67$_[1]
68grestore gsave 207 550 translate 5 5 moveto (2) show 0.30 dup scale
69$_[2]
70grestore gsave 394 550 translate 5 5 moveto (3) show 0.30 dup scale
71$_[3]
72grestore gsave  20 285 translate 5 5 moveto (4) show 0.30 dup scale
73$_[4]
74grestore gsave 394 285 translate 5 5 moveto (6) show 0.30 dup scale
75$_[5]
76grestore gsave  20  20 translate 5 5 moveto (7) show 0.30 dup scale
77$_[6]
78grestore gsave 207  20 translate 5 5 moveto (8) show 0.30 dup scale
79$_[7]
80grestore gsave 394  20 translate 5 5 moveto (9) show 0.30 dup scale
81$_[8]
82grestore showpage
83%%EOF
84EOT
85	close T;
86	system "pkill -HUP gv";
87	Term::Clui::set_default('Now which drawing do you prefer ?', '5');
88	my $preference = Term::Clui::choose(
89	  'Now which drawing do you prefer ?',
90	  '1','2','3','4','5','6','7','8','9');  # if -l, should offer 1..8
91	$continue = 1 ; if (!$preference) { $continue = undef; }
92	if ($preference eq '5') { $preference = 0;
93	} elsif ((0+$preference) > 5) { $preference = -1 + $preference;
94	} else { $preference = 0 + $preference;
95	}
96	return ($preference, $continue);
97}
98
99while (<>) { push @prolog, $_; if (/EndProlog/) { last; } }
100while (<>) { push @prolog, $_; if (/EndPageSetup/) { last; } }
101while (<>) { if (/showpage/)  { last; } push @page, $_; }
102Term::Clui::inform ("Use GhostView or equivalent to view $tmpfile");
103my $new_page = Math::Evol::text_evol(join ('', @page), \&choose_best_text, 8);
104if (! open (T, "> $tmpfile")) { die "can't open $tmpfile: $!\n"; }
105print T join('', @prolog), $new_page, "showpage\n%%EOF\n";
106close T;
107system "pkill -HUP gv";
108Term::Clui::inform ("$tmpfile now contains your evolved version");
109exit 0;
110
111__END__
112
113=pod
114
115=head1 NAME
116
117ps_evol - Perl script to fine-tune A4 PostScript drawings
118
119=head1 SYNOPSIS
120
121 vi plant.ps
122 # add comments like:    % evol step 0.05 min 0.0 max 1.0
123 ps_evol plant.ps > p2.ps
124 ps_evol -k plant.ps > p2.ps   # Keep the intermediate steps
125 ps_evol -v        # print the version
126 perldoc ps_evol   # read the manual :-)
127
128=head1 DESCRIPTION
129
130I<ps_evol> was mainly intended as a demo script
131illustrating the I<text_evol> funtion in Math::Evol.pm.
132It assumes you have something like GhostView
133which allows you to view PostScript files.
134
135It creates a temporary PostScript file,
136then repeatedly generates eight variants of the original file,
137scales them smaller, numbers them, and displays them in a 3x3 array.
138The original is in the middle, as number 5.
139It asks the user which variant they prefer,
140then uses that as the original for the next iteration.
141When the user decides to call a halt,
142the latest preferred variant is written to the standard output.
143
144The parameters to be varied in the PostScript file
145must be marked out by special comments, such as
146
147 /gray_sky .87 def % evol step 0.05 min 0.0 max 1.0
148
149See I<perldoc Math::Evol> for more details,
150and as an example the PostScript file I<plant.ps>,
151included with the distribution.
152
153=head1 OPTIONS
154
155=over 3
156
157=item I<-k>
158
159B<K>eeps the intermediate steps of the evolution;
160they will be named like the source file but with an added number,
161like plant_001.ps plant_002.ps and so on.
162This can be useful if you want to make a movie of the evolution process,
163such as with:
164
165 vi plant.eps
166 # it should start with:  %%BoundingBox 0 0 1280 720
167 ps_evol -k plant.eps
168 for i in plant_*.eps   # you have enough disc, I hope ?
169 do
170     o=`echo $i | sed 's/eps$/jpg/'`
171     gs -sDEVICE=jpeg -sOutputFile=$o -q -g1280x720 $i
172 done
173 # mencoder insists on consecutive numbers, so if you want to
174 # delete one, you have to renumber all the subsequent files :-(
175 mencoder -audiofile plantmusic.wav -oac pcm -fps 24 -ofps 24 \
176   'mf://plant_*.jpg' -mf h=1280:w=720:fps=24:type=jpeg \
177   -o plant.avi -ovc lavc -lavcopts vcodec=mpeg4:aspect=1.7778
178 mplayer plant.avi
179
180=item I<-v>
181
182Prints B<V>ersion number.
183
184=back
185
186=head1 DEPENDENCIES
187
188Uses the CPAN module Term::Clui.pm to dialogue with the user.
189
190=head1 AUTHOR
191
192Peter J Billam, www.pjb.com.au/comp/contact.html
193
194=head1 CREDITS
195
196Based on Math::Evol.pm, and conceptually on
197Richard Dawkin's I<Blind Watchmaker> software.
198
199=head1 SEE ALSO
200
201Math::Evol.pm, Term::Clui.pm, http://www.pjb.com.au/, perl(1).
202
203=cut
204
205