Skip to content

Commit

Permalink
Item892: Convert GenPDFAddOn - Rewrite recursive code to use %SEARCH
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.foswiki.org/trunk/GenPDFAddOn@2406 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
GeorgeClark authored and GeorgeClark committed Feb 8, 2009
1 parent 9977322 commit 660d308
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 136 deletions.
2 changes: 1 addition & 1 deletion data/System/GenPDFAddOn.txt
@@ -1,4 +1,4 @@
%META:TOPICINFO{author="BaseUserMapping_333" date="1233206526" format="1.1" version="1.2"}%
%META:TOPICINFO{author="ProjectContributor" date="1233206526" format="1.1" version="1.2"}%
<!-- PDFSTART -->
---+!! Generate PDF Add-On
<!-- PDFSTOP -->
Expand Down
53 changes: 27 additions & 26 deletions data/System/GenPDFAddOnDemo.txt
@@ -1,4 +1,5 @@
%META:TOPICINFO{author="WadeTurland" date="1118713770" format="1.0" version="1.1"}%
%META:TOPICINFO{author="ProjectContributor" date="1233972234" format="1.1" version="1.2"}%
%META:TOPICPARENT{name="GenPDFAddOn"}%
%TOC%

---+ GenPDFAddOnDemo
Expand Down Expand Up @@ -26,11 +27,11 @@ Foswiki only goes this far :-( HTMLDOC goes to level 15 :-) %BR%

---++ Features
Some of the cool features are:
* Title topic is a fully rendered Foswiki topic, editable from within Foswiki's normal edit mechanism.
* Headers/Footers are fully rendered Foswiki variables embedded in HTMLDOC special comments, but defined in a normal Foswiki topic.
* Images are included
* Margins can be defined
* PDF permissions can be restricted (this has 'print,no-copy' so you can't copy and paste the text)
* Title topic is a fully rendered Foswiki topic, editable from within Foswiki's normal edit mechanism.
* Headers/Footers are fully rendered Foswiki variables embedded in HTMLDOC special comments, but defined in a normal Foswiki topic.
* Images are included
* Margins can be defined
* PDF permissions can be restricted (this has 'print,no-copy' so you can't copy and paste the text)

---++ Limitations
There are a few limitations, like
Expand Down Expand Up @@ -112,26 +113,26 @@ Generated: %DISPLAYTIME%

---++ Preferences
<verbatim>
* Foswiki.GenPDFAddOn Settings
* Set GENPDFADDON_BANNER = Our Slogan %ORANGE%Rocks!!!%ENDCOLOR%
* Set GENPDFADDON_TITLE = %BASETOPIC%
* Set GENPDFADDON_SUBTITLE = %REVINFO{web="%WEB%" topic="%BASETOPIC%"}%
* Set GENPDFADDON_TITLETOPIC = %SYSTEMWEB%.GenPDFExampleTitleTopic
* Set GENPDFADDON_HEADERTOPIC = %SYSTEMWEB%.GenPDFExampleHeaderFooterTopic
* Set GENPDFADDON_HEADFOOTFONT = helvetica-bold
* Set GENPDFADDON_LOGOIMAGE = http://localhost/Foswiki/pub/Foswiki/ProjectLogos/FoswikiRobot46x50.gif
* Set GENPDFADDON_FORMAT = pdf14
* Set GENPDFADDON_PERMISSIONS = print,no-copy
* Set GENPDFADDON_ORIENTATION = portrait
* Set GENPDFADDON_PAGESIZE = a4
* Set GENPDFADDON_SKIN = print.pattern
* Set GENPDFADDON_TOCHEADER = l..
* Set GENPDFADDON_TOCFOOTER = ..i
* Set GENPDFADDON_NUMBEREDTOC = True
* Set GENPDFADDON_TOCLEVELS = 5
* Set GENPDFADDON_HEADERSHIFT = 0
* Set GENPDFADDON_MARGINS = top:20mm,left:80pt,right:1in,bottom:5cm
* Set GENPDFADDON_WIDTH = 1060
* Foswiki.GenPDFAddOn Settings
* Set GENPDFADDON_BANNER = Our Slogan %ORANGE%Rocks!!!%ENDCOLOR%
* Set GENPDFADDON_TITLE = %BASETOPIC%
* Set GENPDFADDON_SUBTITLE = %REVINFO{web="%WEB%" topic="%BASETOPIC%"}%
* Set GENPDFADDON_TITLETOPIC = %SYSTEMWEB%.GenPDFExampleTitleTopic
* Set GENPDFADDON_HEADERTOPIC = %SYSTEMWEB%.GenPDFExampleHeaderFooterTopic
* Set GENPDFADDON_HEADFOOTFONT = helvetica-bold
* Set GENPDFADDON_LOGOIMAGE = http://localhost/Foswiki/pub/Foswiki/ProjectLogos/FoswikiRobot46x50.gif
* Set GENPDFADDON_FORMAT = pdf14
* Set GENPDFADDON_PERMISSIONS = print,no-copy
* Set GENPDFADDON_ORIENTATION = portrait
* Set GENPDFADDON_PAGESIZE = a4
* Set GENPDFADDON_SKIN = print.pattern
* Set GENPDFADDON_TOCHEADER = l..
* Set GENPDFADDON_TOCFOOTER = ..i
* Set GENPDFADDON_NUMBEREDTOC = True
* Set GENPDFADDON_TOCLEVELS = 5
* Set GENPDFADDON_HEADERSHIFT = 0
* Set GENPDFADDON_MARGINS = top:20mm,left:80pt,right:1in,bottom:5cm
* Set GENPDFADDON_WIDTH = 1060
</verbatim>

---++ Form fields
Expand Down
156 changes: 53 additions & 103 deletions lib/Foswiki/Contrib/GenPDF.pm
Expand Up @@ -64,7 +64,7 @@ $VERSION = '$Rev$';
# This is a free-form string you can use to "name" your own plugin version.
# It is *not* used by the build automation tools, but is reported as part
# of the version number in PLUGINDESCRIPTIONS.
$RELEASE = 'Dakar';
$RELEASE = 'Foswiki 1.0';

$| = 1; # Autoflush buffers

Expand Down Expand Up @@ -429,10 +429,10 @@ sub _fixImages {
catch Foswiki::AccessControlException with {

# ignore access errors - htmldoc will ignore empty files, but log an error
print STDERR "File Access Exception"
. $imgInfo->{web} . " "
. $imgInfo->{topic} . " "
. $imgInfo->{file};
_writeDebug( "File Access Exception"
. $imgInfo->{web} . " "
. $imgInfo->{topic} . " "
. $imgInfo->{file} );
};

# replace all instances of url with the temporary filename
Expand Down Expand Up @@ -815,8 +815,6 @@ This is the core method to convert the current page into PDF format.
=cut

sub viewPDF {
open( STDERR, ">>$Foswiki::cfg{DataDir}/error.log" )
; # redirect errors to a log file

# initialize module wide variables
$query = new CGI;
Expand Down Expand Up @@ -860,20 +858,7 @@ sub viewPDF {
# Get header/footer data
my $hfData = _getHeaderFooterData($webName);

my $fgrepCmd;
my $htmldocCmd;
if ( defined $Foswiki::cfg{DataDir} ) {

# Foswiki-4 or more recent
$fgrepCmd = $Foswiki::cfg{RCS}{FgrepCmd};
$htmldocCmd = $Foswiki::cfg{Extensions}{GenPDFAddOn}{htmldocCmd};
}
else {

# Cairo or earlier
$fgrepCmd = $Foswiki::fgrepCmd;
$htmldocCmd = $Foswiki::htmldocCmd;
}
my $htmldocCmd = $Foswiki::cfg{Extensions}{GenPDFAddOn}{htmldocCmd};

die "Path to htmldoc command not defined" unless $htmldocCmd;

Expand All @@ -885,78 +870,22 @@ sub viewPDF {
}

if ( $prefs{'recursive'} ) {

# Include all descendents of this topic
use Cwd 'cwd';
my $cwd = cwd; # we need to chdir back after searching

# Get a list of possibilities (all files in the web)
chdir( Foswiki::Func::getDataDir() . "/$webName" );
opendir( DIR, "." ) or die "$!";
my @files = grep { /\.txt$/ && -f "$_" } readdir(DIR);
closedir DIR;

#for (@files) { print STDERR "file: '$_'\n"; } # DEBUG
#print STDERR scalar @files," files found\n"; # DEBUG

# Now build a hash of arrays mapping children to parents
# Eg. $tree{$parent} = @children
($fgrepCmd) =
split( / /, $fgrepCmd ); # only want the /path/to/command portion
while (@files) {
my @search =
splice( @files, 0, 512 ); # only search 512 files at a time
unshift @search, '%META:TOPICPARENT{'; #}
# this is basically ripped straight out of Foswiki::readFromProcessArray
# This code follows the safe pipe construct found in perlipc(1).
my $pipe;
my $pid = open $pipe, '-|';
my @data;
if ($pid) { # parent
@data =
map { chomp $_; $_ } <$pipe>; # remove newline characters.
close $pipe;
}
else {
exec {$fgrepCmd} $fgrepCmd, @search;

# Usually not reached.
exit 127;
}

#print STDERR scalar @data, " files have parent topics\n"; # DEBUG
for (@data) {

#print STDERR "data: '$_'\n"; # DEBUG
my $tainted = $_;
$tainted =~ /(\w+).txt:.*?name=\"(\w+)\"/ && do {
push @{ $tree{$2} }, $1;

#push @{ $tree{$parent} }, $child;
}
}
}
chdir($cwd); # return to previous working dir
my $list = Foswiki::Func::expandCommonVariables(
'%SEARCH{ "^%META:TOPICPARENT"
type="regex"
multiple="on"
format="$topic:$parent"
separator="|"
header=""
nonoise="on"}%'
);
map {
my ( $ch, $par ) = split( /:/, $_ );
push @{ $tree{$par} }, $ch if $par;
# _writeDebug ( "Parent |$par| Child |$ch|");
} split( /\|/, $list );
}

# Do a recursive depth first walk through the ancestors in the tree
# sub is defined here for clarity
sub _depthFirst {
my $parent = shift;
my $topics = shift; # ref to @topics
# the grep gets around a perl dereferencing bug when using strict refs
my @children = grep { $_; } @{ $tree{$parent} };
for ( sort @children ) {

#print STDERR "new child of $parent: '$_'\n"; # DEBUG
push @$topics, $_;
if ( defined $tree{$_} ) {

# this child is also a parent so bring them in too
_depthFirst( $_, $topics );
}
}
}
my @topics;
push @topics, $topic;
_depthFirst( $topic, \@topics );
Expand All @@ -967,8 +896,8 @@ sub viewPDF {
my @contentFiles;
for $topic (@topics) {

#print STDERR "preparing $topic\n"; # DEBUG
# Get ready to display HTML topic
_writeDebug("preparing $topic"); # DEBUG
# Get ready to display HTML topic
my $htmlData = _getRenderedView( $webName, $topic );

# Fix topic text (i.e. correct any problems with the HTML that htmldoc might not like
Expand Down Expand Up @@ -1041,19 +970,13 @@ sub viewPDF {

push @htmldocArgs, @contentFiles;

#print STDERR "Calling htmldoc with args: @htmldocArgs\n";

#try the 4.2 sandbox
my $sandbox = $Foswiki::sandbox;
if ( !defined($sandbox) ) { #must be 4.1 or before.
$sandbox = $Foswiki::Plugins::SESSION->{sandbox};
}
_writeDebug("Calling htmldoc with args: @htmldocArgs");

# Disable CGI feature of newer versions of htmldoc
# (thanks to Brent Roberts for this fix)
$ENV{HTMLDOC_NOCGI} = "yes";
my ( $Output, $exit ) =
$sandbox->sysCommand( $htmldocCmd . ' ' . join( ' ', @htmldocArgs ) );
my ( $Output, $exit ) = Foswiki::Sandbox->sysCommand(
$htmldocCmd . ' ' . join( ' ', @htmldocArgs ) );
if ( !-e $outputFile ) {
die "error running htmldoc ($htmldocCmd): $Output\n";
}
Expand Down Expand Up @@ -1093,6 +1016,33 @@ sub viewPDF {
unlink @contentFiles;
}

### sub _writeDebug
##
## Writes a common format debug message if debug is enabled

sub _writeDebug {
&Foswiki::Func::writeDebug( "GenPDF - " . $_[0] ); # if $debugDefault;
} ### SUB _writeDebug


# Do a recursive depth first walk through the ancestors in the tree
# sub is defined here for clarity
sub _depthFirst {
my $parent = shift;
my $topics = shift; # ref to @topics
# the grep gets around a perl dereferencing bug when using strict refs
my @children = grep { $_; } @{ $tree{$parent} };
for ( sort @children ) {

_writeDebug("new child of $parent: '$_'"); # DEBUG
push @$topics, $_;
if ( defined $tree{$_} ) {

# this child is also a parent so bring them in too
_depthFirst( $_, $topics );
}
}
}

1;

# vim:et:sw=3:ts=3:tw=0
12 changes: 6 additions & 6 deletions lib/Foswiki/Contrib/GenPDFAddOn/MANIFEST
@@ -1,8 +1,8 @@
bin/genpdf 0755 Script to generate PDF in place of view
data/System/GenPDFAddOn.txt Add-on topic
data/System/GenPDFExampleTitleTopic.txt Example title topic
data/System/GenPDFExampleHeaderFooterTopic.txt Example header and footer topic
data/System/GenPDFAddOnDemo.txt 0644 Demonstration topic
data/System/GenPDFExampleHeaderFooterTopic.txt 0644 Example document header/footer
data/System/GenPDFExampleTitleTopic.txt 0644 Example Title Topic
lib/Foswiki/Contrib/GenPDF.pm 0644 Primary module
templates/view.genpdf.tmpl 0644 Alternative view template

bin/genpdf Add-on script
lib/Foswiki/Contrib/GenPDF.pm Add-on perl package
lib/Foswiki/Contrib/GenPDFAddOn/Config.spec
templates/view.genpdf.tmpl

0 comments on commit 660d308

Please sign in to comment.