xmlgraphics-fop-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From paul womack <pwom...@papermule.co.uk>
Subject page property page-height=indefinite
Date Fri, 08 Jul 2011 10:06:34 GMT
I note (google!) that subsequent to my questions on this
(in 2008), this feature remains unimplemented,
and has been asked about a few times.

In the interests of repaying the community,
I offer this perl script (written for my own purposes)
which generates output of the "right" height,
by performing an initial pass, and parsing the resulting
area tree.

The information from the area tree is used to generate
a custom XSL based on the desired XSL, with the
height "dropped in".

My script happens to generate EPS, which means there's
a small piece of FILTHY perl search-and-replace
on FOP's generated postscript, which is a print stream.

This script is based heavily on information and advice
from Jeremias Maerki and Andreas Delmelle, to whom
my thanks are due.

    BugBear

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
use Carp;
use XML::LibXML;

my $fop = "../fop-1.0/fop";

my $main_mime = "application/postscript";
my $main_format = "-ps";

# preliminary H+J to get dimensions
sub measure_pass {
     my ($style, $data) = @_;
     my $atfile = "measure.xml";
     my $cmd = "${fop} -xsl ${style} -xml ${data} -at ${main_mime} ${atfile}";
     system($cmd);
     return $atfile;
}

sub find_depth_mm {
     my ($atfile) = @_;
     my $parser = XML::LibXML->new(recover=>1, validation=>0, no_network => 1);
     my $doc = $parser->parse_file ($atfile);
     my @page = $doc->findnodes("//page");
     my $page = $page[0];
     my @span = $page->findnodes("regionViewport/regionBody/mainReference/span");
     my $depth;
     foreach my $s (@span) {
	$depth += $s->getAttribute("bpd");
     }
     # units are 1000th pts.
     return $depth / 1000 / 72 * 25.4;
}

sub new_style {
     my ($style, $depth) = @_;
     my ($os, $ns);
     my $new_xsl_file = "right_height.xsl";
     open $os, "<", $style;
     open $ns, ">", $new_xsl_file;
     while(<$os>) {
	s/page-height="[^"]+"/page-height="${depth}mm"/g;
	print $ns $_;
     }
     close($ns);
     close($os);
     return $new_xsl_file;
}

sub final_pass {
     my ($style, $data) = @_;
     my $ps = "output.ps";
     my $cmd = "${fop} -xsl ${style} -xml ${data} ${main_format} ${ps}";
     system($cmd);
     return $ps;
}

sub make_epsf {
     my ($psfile, $epsf) = @_;

     local $/; # slurp!
     my $pstream;
     open $pstream, "<", $psfile || die "cannot open $psfile $!";
     my $ps = <$pstream>;
     close($pstream);
     # call it EPSF
     $ps =~ s/^(%!PS-Adobe-[\d.]+)$/$1-EPSF/m;
     # pick up the bounding box from where it's been put
     $ps =~ m/^(%%PageBoundingBox:\s+[\d\s]+)$/m;
     my $bb = $1;
     $bb =~ s/PageBoundingBox/BoundingBox/g;
     # insert it where we want it
     $ps =~ s/(%%LanguageLevel:\s+\d+)$/$1\n$bb/m;
     $ps =~ s/>> setpagedevice/>> pop/g;
     # disable the nasty setpagedevice call

     my $ostream;
     open $ostream, ">$epsf" || die "cannot open $epsf $!";
     print $ostream $ps;
     close($ostream);
}

sub usage {
croak <<EOF
"Usage $0 <stylesheet(.xsl)> <data(.xml)> <epsffile(.eps)>"
EOF
}

unless(scalar(@ARGV) == 3) {
     usage();
}

my ($style, $data, $eps) = @ARGV;

my $at = measure_pass($style, $data);
my $depth = find_depth_mm($at);
my $ns = new_style($style, $depth);
my $ps = final_pass ($ns, $data);
make_epsf($ps, $eps);

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-users-help@xmlgraphics.apache.org


Mime
View raw message