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