Postscript output from Matlab R2007b is questionable. I’m finding that text strings are being split over many ‘moveto‘ and ‘show’ commands in the postscript output (simprintdiag). This causes issues when typesetting to PDF in that extra whitespace can sometimes be inserted into labels (so you can’t double click them, and aren’t found in searches!).
To avoid this problem I’ve written a Perl script to join these split ‘show’ commands back together, however, it has some problems, and I need some help please.
- Show commands like “(0) s” are not repeated correctly, and appear in the next block.
- The input postscript file is always modified by the script, even if no changes are required.
- There’s a hack at the start to get around consecutive show commands.
- It’s not very quick, and given some projects have >2000 postscript files, any speed improvements are welcome.
The DATA in my code below has four examples of split text strings in mt and s commands. I’ve included what the final output should be like at the very end. The script uses the fact that our text is written Left to Right, or in postscript, with a moving X cord and fixed Y cord. Therefore, conclude that consecutive mt commands with the same Y cord are the same text string.
Any help gratefully received.
Thanks 🙂
My Perl Script:
use strict;
use warnings;
my $debug=1;
#
## Slurp the input file into a variable
my $ps_in;
while(<DATA>) {
$ps_in .= $_; # Take a copy of input file
}
#
## HACK
## The main PS fix algorithm only works with show commands on a single
## line! Fix the input contents now by joining all show commands that
## occur over multiple lines. Examples of this are:
## 272 63 mt
## (main is an externally linked function of the ACC feature ru\
## nning every ) s
## 991 63 mt
## (100) s
my $buf;
my $no_show_split;
open(my $fh_ps, "<", \$ps_in );
while(<$fh_ps>) {
if( /^(.*)\\$/ ) { # Match on all lines ending with backslash \
$buf .= $1;
}
else {
if( $buf ) {
$no_show_split .= $buf;
undef($buf);
}
$no_show_split .= $_;
}
}
close $fh_ps;
#
## Reopen our ps input, now the show splits have been removed
open($fh_ps,"<",\$no_show_split );
my $moveto_line = qr/^\s*\d+\s+(\d+)\s+(mt|moveto)/; # Example '2831 738 mt'
my $show_line = qr/^\((.+)\)\s+(s|show)/; # Example '(chris) s'
my $ycrd; # Y-axis cords
my $pstxt; # Text to display
my $mtl; # Moveto line
my $print_text;
my $fixes=0;
my $ps_condensed;
while(<$fh_ps>) {
if( $print_text ) {
$ps_condensed .= "$mtl\n";
$ps_condensed .= "($pstxt) s\n";
print "($pstxt) s\n====================\n" if $debug;
undef($ycrd);
undef($pstxt);
$print_text=0;
++$fixes;
}
if( /$moveto_line/ ) {
chomp;
if( !$ycrd ) {
$mtl=$_; # Store this line for print later
$ycrd=$1; # Match on y-axis value
redo; # Redo this iteration so we can read the show line in
}
elsif( $1 == $ycrd ) {
<$fh_ps> =~ /$show_line/; # Read in the show line
$pstxt .= $1; # Built up string we want
print " $mtl -->$1<--\n" if $debug;
}
else {
$print_text=1; # Dropped out matching on y-cord so force a print
redo; # Need to redo this line again
}
}
else {
if( $pstxt ) { # Print if we have something in buffer
$print_text=1;
redo;
}
$ps_condensed .= $_;
}
} # End While Loop
close $fh_ps;
print $ps_condensed;
__DATA__
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 60 FMSR
11214 11653 mt
(0) s
4.5 w
156 0 2204 19229 2 MP stroke
156 0 2204 19084 2 MP stroke
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
8913 14971 mt
(Function) s
9405 14971 mt
(-) s
9441 14971 mt
(Call) s
9009 15127 mt
(Generator) s
6 w
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
4962 4747 mt
(trigger) s
5322 4747 mt
(_) s
5394 4747 mt
(scheduler) s
5934 4747 mt
(_) s
6006 4747 mt
(100) s
6222 4747 mt
(ms) s
6378 4747 mt
(_) s
6450 4747 mt
(task) s
6654 4747 mt
(_) s
6726 4747 mt
(06) s
6 w
gr
24 10 10 24 0 4 -10 24 -24 10 5806 11736 14 MP stroke
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
5454 11947 mt
(Chris_\
did_this_example_) s
5874 11947 mt
(to_test) s
5946 11947 mt
(_out) s
6 w
What the final ‘condensed’ postscript should look like:
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 60 FMSR
11214 11653 mt
(0) s
4.5 w
156 0 2204 19229 2 MP stroke
156 0 2204 19084 2 MP stroke
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
8913 14971 mt
(Function-Call) s
9009 15127 mt
(Generator) s
6 w
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
4962 4747 mt
(trigger_scheduler_100ms_task_06) s
6 w
gr
24 10 10 24 0 4 -10 24 -24 10 5806 11736 14 MP stroke
%%IncludeResource: font Helvetica
/Helvetica /WindowsLatin1Encoding 120 FMSR
5454 11947 mt
(Chris_did_this_example_to_test_out) s
6 w
I think the following will work for you.
Notes:
do { local $/; <DATA> };