[LON-CAPA-cvs] cvs: loncom /interface printout.pl

foxr lon-capa-cvs@mail.lon-capa.org
Mon, 12 Jun 2006 11:21:09 -0000


foxr		Mon Jun 12 07:21:09 2006 EDT

  Modified files:              
    /loncom/interface	printout.pl 
  Log:
  I think this repaginates correctly but need to test further and
  certainly need to get a status display up while it's doing it.
  It certainly appears to do no harm in any event.
  
  
Index: loncom/interface/printout.pl
diff -u loncom/interface/printout.pl:1.99 loncom/interface/printout.pl:1.100
--- loncom/interface/printout.pl:1.99	Tue Jun  6 07:04:18 2006
+++ loncom/interface/printout.pl	Mon Jun 12 07:21:07 2006
@@ -668,20 +668,120 @@
 #     the maximum number of pages.
 #   
 sub repaginate_postscript {
-    # For now just strip out the STARTOFSTUDENTSTAMP
-    # ENDOFSTUDENTSTAMP markers in the postscript.
+
+    # We will try to do this in 2 passes through the postscript since
+    # the postscript is potentially large, to do 2 passes, the first pass
+    # must be able to calculate the total number of document pages so that
+    # at the beginning of the second pass we already know how to replace
+    #  %%Pages:
+
+    #  Figure out
+    #    1. Number of pages in the document
+    #    2. Maximum number of pages in a student
+    #    3. Number of pages in each student.
 
     my ($postscript_filename) = @_;
     open(PSFILE, "<$postscript_filename");
-    my @psfilelines = <PSFILE>;
+    my $line;
+    my $total_pages;		# Total pages in document.
+    my $seen_pages        = 0;	# There are several %%Pages only the first is useful
+    my $student_number    = 0;	# Index of student we're working on.
+    my @pages_in_student;	# For each student his/her initial page count.
+    my $max_pages = 0;		# Pages in 'longest' student.
+    while ($line = <PSFILE>) {
+	my $page_number = 0;
+	
+	# Check for total pages (%%Pages:)
+
+	if (($line =~ "^%%Pages:") && (!$seen_pages)) {
+	    my @pageinfo = split(/ /,$line);
+	    $total_pages = $pageinfo[1];
+	    $seen_pages  = 1;
+	}
+	#  Check for %%Page: n m  $page_number will be the
+	#  biggest of these until we see an endofstudent.
+	#  Note that minipages generate spurious %Page: 1 1's so
+	#  we only are looking for the largest n (n is page number at the
+	#  bottom of the page, m the page number within the document.
+	#
+	if ($line =~ "^%%Page:") {
+	    my @pageinfo = split(/ /, $line);
+	    if ($page_number < $pageinfo[1]) {
+		$page_number = $pageinfo[1];
+	    }
+	}
+	#  ENDOFSTUDENTSTAMP - save the page_number, reset and, if necessary
+	#                      udpate max_pages.
+	#
+	if ($line =~ "ENDOFSTUDENTSTAMP") {
+	    $pages_in_student[$student_number] = $page_number;
+	    $student_number++;
+
+	    if ($page_number > $max_pages) {
+		$max_pages = $page_number;
+	    }
+	    $page_number = 0;
+	 
+	}
+
+	
+    }
     close(PSFILE);
-    my $psbody = join('', @psfilelines);
-    $psbody =~ s/STARTOFSTUDENTSTAMP//g;
-    $psbody =~ s/ENDOFSTUDENTSTAMP//g;
+    
+    #   Figure out how many total pages we need to add and adjust the
+    #   $total_pages accordingly:
+    #
+    my $add_pages  = 0;
+    for (my $i =0; $i < $student_number; $i++) {
+	$add_pages += ($max_pages - $pages_in_student[$i]);
+    }    
+    #  If we don't need to add any pages, we're done!
+    #  You  might think that we don't need to do anything if 
+    #  there are no pages to add, however we still need to at least strip out
+    #   the ENDOFSTUDENTSTAMP stamps...as they are not postscript comments!!
 
-    open(PSFILE, ">$postscript_filename");
-    print PSFILE $psbody;
+  
+    #  Now pass 2; we're going to write the new. ps file:
+    #  -  Modify its first %%Pages: line so that it has the new correct number of
+    #     pages
+    #  -  For each student, insert as many blank pages as needed (and
+    #     associated structured comments) to expand a  student out to
+    #     max_pages pages.
+    #  -  Remove the ENDOFSTUDENTSTAMP lines.
+    #
 
+    $total_pages += $add_pages;
+    $student_number = 0;
+ 
+   open(PSFILE, "<$postscript_filename");
+    open(PSOFILE,">$postscript_filename"."repaginating"); # unique if original fname is.
+    $seen_pages = 0;		# Reset seen %%Pages flag...
+    while ($line = <PSFILE>) {
+	if (($line =~ "^%%Pages:") && (!$seen_pages)) {
+	    $line = "%%Pages: $total_pages\n";
+	    $seen_pages = 1;
+	}
+	if ($line =~ "ENDOFSTUDENTSTAMP") {
+	    $add_pages = ($max_pages - $pages_in_student[$student_number]);
+	    $line = "\n";
+	    my $last_student_page = $pages_in_student[$student_number];
+	    my $last_total_page   = $student_number*$max_pages + $last_student_page;
+	    while ($add_pages) {
+		$line .= "%Page: $last_student_page $last_total_page\n";
+		my $bop = $last_total_page-1;
+		$line .= "TeXDict begin $last_student_page $bop bop eop end\n";
+		$last_student_page++;
+		$last_total_page++;
+		$add_pages--;
+	    }
+	    $student_number++;
+	}
+	print PSOFILE $line;
+    }
+    close PSOFILE;
     close PSFILE;
+
+    rename($postscript_filename."repaginating", $postscript_filename);
+
 }