package HTML::HTMLDoc; use 5.006; use strict; use warnings; use IO::File; use IPC::Open3 qw(); use HTML::HTMLDoc::PDF; use File::Temp; use vars qw(@ISA $VERSION); use constant Win32_MODE => $^O =~ /os2|Win32/i; use constant DEBUG => 0; @ISA = qw(); $VERSION = '0.11_01'; ############### # create a new Object # param: # return: object:HTML::HTMLDOC ############### sub new { my $package = shift; my $self = {}; bless($self, $package); while (my $key = shift) { my $value = shift; $self->{'config'}->{$key} = $value; } $self->_init(); return $self; } ############### # initialises the Object with the basic parameters # param: - # return: - ############### sub _init { my $self = shift; # Switch the default to file on Windows env $self->{'config'}->{'mode'} = 'file' if(!$self->{'config'}->{'mode'} && Win32_MODE); if ((not defined $self->{'config'}->{'mode'}) || ($self->{'config'}->{'mode'} ne 'file' && $self->{'config'}->{'mode'} ne 'ipc')) { $self->{'config'}->{'mode'} = 'ipc'; } if ( (!$self->{'config'}->{'tmpdir'}) || (!-d $self->{'config'}->{'tmpdir'})) { $self->{'config'}->{'tmpdir'} = '/tmp'; } if ( defined($self->{'config'}->{'bindir'}) ) { $self->{'config'}->{'bindir'} .= "/" if ( $self->{'config'}->{'bindir'} !~ /\/$/ ); } else { $self->{'config'}->{'bindir'} = ''; } $self->{'errors'} = []; $self->{'doc_config'} = {}; $self->set_page_size('a4'); $self->portrait(); $self->set_charset('iso-8859-1'); $self->_set_doc_config('quiet'); $self->set_output_format('pdf'); # standard-header and footer $self->set_footer('.', '1', '.'); $self->set_header('.', 't', '.'); } ############### # Store or get a global configuration value # testet # param: key:STRING, value:STRING # return: 1 ############### sub _config { my $self = shift; my $key = shift; my $value = shift; my $ret; if (defined $value) { $self->{'config'}->{$key} = $value; } else { $ret = $self->{'config'}->{$key}; } return $ret; } ############### # stores a specific value for formating the outputdoc # testet # param: key:STRING, value:STRING # return: 1 ############### sub _set_doc_config { my $self = shift; my $key = shift; my $value = shift; if (ref($value) && (ref($value) eq 'ARRAY') ) { # the value is an array, store it in an array too if ( !$self->{'doc_config'}->{$key} || ref($self->{'doc_config'}->{$key}) ne 'ARRAY') { # create a new array $self->{'doc_config'}->{$key} = []; } foreach my $single_value(@{$value}) { push(@{$self->{'doc_config'}->{$key}}, $single_value); } } else { $self->{'doc_config'}->{$key} = $value; } return 1; } ############### # deletes a specific config # testet # param: key:STRING # return: value:STRING ############### sub _delete_doc_config { my $self = shift; my $key = shift; my $value = shift; if (exists $self->{'doc_config'}->{$key}) { my $set_value = $self->_get_doc_config($key); if ( (ref($set_value) eq 'ARRAY') && $value ) { # remove specific value only # find the position of the value for(my $i=0; $i<@{$set_value}; $i++) { if ( $set_value->[$i] eq $value ) { splice(@{$set_value}, $i, 1); last; } } } else { # delete the singlevalue delete $self->{'doc_config'}->{$key}; } } } ############### # tells a specific value for formating the outputdoc # testet # param: key:STRING # return: value:STRING ############### sub _get_doc_config { my $self = shift; my $key = shift; return $self->{'doc_config'}->{$key}; } ############### # returns all the configuration keys # param: key:STRING # return: value:STRING ############### sub _get_doc_config_keys { my $self = shift; my @keys = keys %{$self->{'doc_config'}}; print STDERR "Keys: @keys\n" if DEBUG; return @keys; } ############### # tests if the parameter exists in the array # of allowed params # testet # param: key:STRING, \@allowed # return: 1/0 ############### sub _test_params { my $self = shift; my $param = shift; my $allowed = shift; my $ok = 0; foreach my $aparam (@{$allowed}) { if (lc($param) eq lc($aparam)) { $ok=1; last; } } return $ok; } ####################################### # public Methods for configuring behaviour and style of the # Document ####################################### ############### # sets the size of the pages - default: a4 # testet # param: letter, a4, WxH{in,cm,mm} # return: 1/0 ############### sub set_page_size { my $self = shift; my $value = shift; if ( !$value && $value ne 'a4' && $value ne 'letter' && $value!~/^\d+x\d+(?:in|cm|mm)/ ) { $self->error("unknown value for pagesize: $value"); return 0; } $self->_set_doc_config('size', $value); return 1; } ############### # reads out the page-size # param: letter, a4, WxH{in,cm,mm} # return: 1/0 ############### sub get_page_size { my $self = shift; return $self->_get_doc_config('size'); } ############### # sets the master-password of the doc # testet # param: password:STRING # return: 1/0 ############### sub set_owner_password { my $self = shift; my $value = shift; $self->_set_doc_config('owner-password', $value); return 1; } ############### # sets the user-password of the doc # testet # param: password:STRING # return: 1/0 ############### sub set_user_password { my $self = shift; my $value = shift; $self->_set_doc_config('user-password', $value); return 1; } # all,annotate,copy,modify,print,no-annotate,no-copy,no-modify,no-print,none ############### # sets the master-password of the doc # testet # param: password:STRING # return: 1/0 ############### sub set_permissions { my $self = shift; my @values = @_; my $thiskey = 'permissions'; my @allowed = ('all','annotate','copy','modify','print','no-annotate','no-copy','no-modify','no-print','none'); # test the set value if ($#values==-1) { $self->error("wrong permission set: no values"); return 0; } for( my $i=0; $i<=$#values; $i++ ) { $values[$i] = lc($values[$i]); if ( !$self->_test_params($values[$i], \@allowed) ) { # wrong permission set $self->error("wrong permission set: $values[$i]"); return 0; } } foreach my $value(@values) { # take care of the combination of the options if ( $value eq 'all' ) { # delete all $self->_delete_doc_config($thiskey); } elsif( $value eq 'none' ) { # delete all $self->_delete_doc_config($thiskey); } else { # delete the corresponding flag if ( $value =~/^no-(.+)/ ) { my $key = $1; $self->_delete_doc_config($thiskey, $key); } else { $self->_delete_doc_config($thiskey, "no-$value"); } } $self->_set_doc_config('permissions', [$value]); } # enable encryption since without it there is no effect. $self->enable_encryption(); return 1; } ############### # sets the pages to portrait # testet # param: - # return: 1/0 ############### sub landscape { my $self = shift; $self->_set_doc_config('landscape', ''); $self->_delete_doc_config('portrait'); return 1; } ############### # sets the pages to portrait # testet # param: - # return: 1/0 ############### sub portrait { my $self = shift; $self->_set_doc_config('portrait', ''); $self->_delete_doc_config('landscape'); return 1; } ############### # turns the title on # param: - # return: 1/0 ############### sub title { my $self = shift; $self->_set_doc_config('title', ''); $self->_delete_doc_config('no-title'); return 1; } ############### # turns the title off # param: - # return: 1/0 ############### sub no_title { my $self = shift; $self->_set_doc_config('no-title', ''); $self->_delete_doc_config('title'); return 1; } ############### # sets the footer # testet # param: left:CHAR, center:CHAR, right:CHAR # return: 1/0 ############### sub set_footer { my $self = shift; my $left = shift; my $center = shift; my $right = shift; my @allowed = ('.', ':', '/', '1', 'a', 'A', 'c', 'C', 'd', 'D', 'h', 'i', 'I', 'l', 't', 'T'); if (!$self->_test_params($left, \@allowed) ) { $self->error("wrong left-footer-option: $left"); return 0; } if (!$self->_test_params($center, \@allowed) ) { $self->error("wrong center-footer-option: $left"); return 0; } if (!$self->_test_params($right, \@allowed) ) { $self->error("wrong right-footer-option: $left"); return 0; } $self->_set_doc_config('footer', "${left}${center}${right}"); return 1; } ############### # sets the header # testet # param: left:CHAR, center:CHAR, right:CHAR # return: 1/0 ############### sub set_header { my $self = shift; my $left = shift; my $center = shift; my $right = shift; my @allowed = ('.', ':', '/', '1', 'a', 'A', 'c', 'C', 'd', 'D', 'h', 'i', 'I', 'l', 't', 'T'); if (!$self->_test_params($left, \@allowed) ) { $self->error("wrong left-header-option: $left"); return 0; } if (!$self->_test_params($center, \@allowed) ) { $self->error("wrong center-header-option: $left"); return 0; } if (!$self->_test_params($right, \@allowed) ) { $self->error("wrong right-header-option: $left"); return 0; } $self->_set_doc_config('header', "${left}${center}${right}"); return 1; } ############### # turns the links on # param: - # return: 1/0 ############### sub links { my $self = shift; $self->_set_doc_config('links', ''); $self->_delete_doc_config('no-links'); return 1; } ############### # turns the links off # param: - # return: 1/0 ############### sub no_links { my $self = shift; $self->_set_doc_config('no-links', ''); $self->_delete_doc_config('links'); return 1; } ############### # sets the search path for files in a document # param: - # return: 1/0 ############### sub path { my $self = shift; my $sp = shift; $self->_set_doc_config('path', $sp); return 1; } ############### # sets the right margin # testet # param: margin|NUM, messure:in,cm,mm # return: 1/0 ############### sub set_right_margin { my $self = shift; my $margin = shift; my $m = shift || 'cm'; return $self->_set_margin('right', $margin, $m); } ############### # sets the left margin # testet # param: margin|NUM, messure:in,cm,mm # return: 1/0 ############### sub set_left_margin { my $self = shift; my $margin = shift; my $m = shift || 'cm'; return $self->_set_margin('left', $margin, $m); } ############### # sets the bottom margin # param: margin|NUM, messure:in,cm,mm # return: 1/0 ############### sub set_bottom_margin { my $self = shift; my $margin = shift; my $m = shift || 'cm'; return $self->_set_margin('bottom', $margin, $m); } ############### # sets the top margin # param: margin|NUM, messure:in,cm,mm # return: 1/0 ############### sub set_top_margin { my $self = shift; my $margin = shift; my $m = shift || 'cm'; return $self->_set_margin('top', $margin, $m); } sub _set_margin { my $self = shift; my $where = shift; my $margin = shift; my $m = shift; # test the values if ( $margin!~/^\d*\.?\d+$/ || ( ($m ne 'in') && ($m ne 'cm') && ($m ne 'mm') )) { $self->error("wrong arguments for $where-margin: $margin $m"); return 0; } $self->_set_doc_config($where, "$margin$m"); return 1; } ############### # sets the color of the body # testet # param: color:hex # return: 1/0 ############### sub set_bodycolor { my $self = shift; my $ret; my $color = $self->_test_color(@_); if (!$color) { $self->error("wrong value set for bodycolor"); $ret = 0; } else { $ret = $self->_set_doc_config('bodycolor', $color); } return $ret; } ############### # internal method for testing and converting colors # testet # param: color:hex || color: rgb || color: name # return: color:hex ############### sub _test_color { my $self = shift; my @colors = @_; my $ret; if( (@colors == 1) && $colors[0]=~/^#[0-9a-f]{6}$/i ) { # got hex-color return $colors[0]; } elsif( @colors==3 ) { # 3 input values, test if regular rgb is given my ($r, $g, $b) = @colors; if ($r=~/^\d{1,3}$/ && $g=~/^\d{1,3}$/ && $b=~/^\d{1,3}$/ && $r>=0 && $r <=255 && $b>=0 && $b<=255 && $g>=0 && $g<=255) { $ret = sprintf("#%02x%02x%02x", $r, $g, $b); } } elsif( @colors==1 ) { foreach my $c( qw(red green blue cyan magenta yellow darkRed darkGreen darkBlue darkCyan darkMagenta darkYellow white lightGray gray darkGray black) ) { if ($c eq $colors[0]) { $ret = $c; last; } } } return $ret; } ############### # sets the default font for the body # testet # param: fontface:STRING # return: 1/0 ############### sub set_bodyfont { my $self = shift; my $font = shift; my $ret = 0; my @allowed = qw(Arial Courier Helvetica Monospace Sans-Serif Serif Symbol Times); if ( !$self->_test_params($font, \@allowed) ) { $self->error("illegal font set $font"); } else { $self->_set_doc_config('bodyfont', $font); $ret = 1; } return $ret; } ############### # sets the font size for body text # param: size:NUM # return: 1/0 ############### sub set_fontsize { my $self = shift; my $fsize = shift; if ($fsize =~ /^\d+(\.\d+){0,1}$/) { return $self->_set_doc_config('fontsize', $fsize); } else { $self->error("illegal font size $fsize"); return 0; } } ############### # takes an image-filename that is used as background # for all Pages # param: image:STRING # return: 1/0 ############### sub set_bodyimage { my $self = shift; my $image = shift; if ( ! -f "$image" ) { $self->error("Backgroundimage $image could not be found"); return 0; } $self->_set_doc_config('bodyimage', $image); return 1; } ############### # Defines a directory where the htmldoc executable is searching for its # data-documents. For unix-based systems the default is /usr/share/htmldoc # param: dir:STRING # return: 1/0 ############### sub set_htmldoc_datadir { my $self = shift; my $dir = shift; if ( ! -d "$dir" ) { $self->error("Datadirectory $dir does not exist"); return 0; } $self->_set_doc_config('datadir', $dir); return 1; } ############### # reads out the directory where htmldoc shall search for images and other data files # param: dir:STRING # return: 1/0 ############### sub get_htmldoc_datadir { my ($self) = @_; return $self->_set_get_config('datadir'); } ############### # takes an image-filename that is used as logoimage # param: image:STRING # return: 1/0 ############### sub set_logoimage { my $self = shift; my $image = shift; if ( ! -f "$image" ) { $self->error("Logoimage $image could not be found"); return 0; } $self->_set_doc_config('logoimage', $image); return 1; } ############### # returns a previous set logo-image # param: - # return: image:STRING ############### sub get_logoimage { my $self = shift; return $self->_get_doc_config('logoimage'); } ############### # set the witdh in px for the background image # param: width:INT # return: 1/0 ############### sub set_browserwidth { my $self = shift; my $width = shift; if ($width !~ /^\d+$/) { $self->error("wrong browserwidth $width set"); return 0; } $self->_set_doc_config('browserwidth', $width); return 1; } ############### # set the size for head and foot in points # param: size:points # return: 1/0 ############### sub set_headfootsize { my ($self, $points) = @_; if ($points !~ /^\d+$/) { $self->error("wrong headfootsize $points set"); return 0; } $self->_set_doc_config('headfootsize', $points); return 1; } ############### # get the size of head and foot # param: # return: :points ############### sub get_headfootsize { my ($self, $points) = @_; return $self->_get_doc_config('headfootsize', $points); } ############### # sets the compression level # param: # return: 1/0 ############### sub set_compression { my $self = shift; my $comp = shift; return $self->_set_doc_config('compression', $comp); } ############### # sets the JPEG-Kompression # param: 0-100 (default 50) # return: 1/0 ############### sub set_jpeg_compression { my $self = shift; my $comp = shift; $comp = 75 if (not defined $comp); return $self->_set_doc_config('jpeg', $comp); } ############### # sets the JPEG-Kompression value to the highest quality # param: - # return: 1/0 ############### sub best_image_quality { my $self = shift; return $self->set_jpeg_compression(100); } ############### # sets the JPEG-Kompression value to the highest quality # param: - # return: 1/0 ############### sub low_image_quality { my $self = shift; return $self->set_jpeg_compression(25); } ############### # sets the pagemode # param: mode:[document,outline,fullscreen] # return: 1/0 ############### sub set_pagemode { my $self = shift; my $value = shift; #--pagemode {document,outline,fullscreen} if (!$self->_test_params($value, ['document', 'outline', 'fullscreen']) ) { #if ($value ne 'document' && $value ne 'outline' && $value ne 'fullscreen') { $self->error("wrong pagemode: $value"); return 0; } $self->_set_doc_config('pagemode', $value); } ############### # sets the charset # param: charset # return: 1/0 ############### sub set_charset { my $self = shift; my $charset = shift; $self->_set_doc_config('charset', $charset); return 1; } ############### # embedding the used fonts into the pdf-file # testet # param: # return: 1/0 ############### sub embed_fonts { my $self = shift; $self->_delete_doc_config('no-embedfonts'); $self->_set_doc_config('embedfonts', ''); return 1; } ############### # no font embedding # testet # param: # return: 1/0 ############### sub no_embed_fonts { my $self = shift; $self->_delete_doc_config('embedfonts'); $self->_set_doc_config('no-embedfonts', ''); return 1; } ############### # turns colors on in doc # param: charset # return: 1/0 ############### sub color_on { my $self = shift; $self->_set_doc_config('color', ''); $self->_delete_doc_config('gray', ''); return 1; } ############### # turns colors off in doc # param: # return: 1/0 ############### sub color_off { my $self = shift; $self->_set_doc_config('gray', ''); $self->_delete_doc_config('color', ''); return 1; } ############### # turns encryption off # param: - # return: 1/0 ############### sub enable_encryption { my $self = shift; $self->_set_doc_config('encryption', ''); $self->_delete_doc_config('no-enryption', ''); return 1; } ############### # turns encryption off # param: - # return: 1/0 ############### sub disable_encryption { my $self = shift; $self->_set_doc_config('no-encryption', ''); $self->_delete_doc_config('enryption', ''); return 1; } ############### # sets the outputformat of the document # param: format:STRING # return: 1/0 ############### sub set_output_format { my $self = shift; my $f = shift; my @allowed = qw(html pdf pdf11 pdf12 pdf13 pdf14 ps ps1 ps2 ps3); if( !$self->_test_params($f, \@allowed)) { $self->error("Wrong output format set $f"); return 0; } $self->_set_doc_config('format', $f); return 1; } #################################################### # # Methods for outputting the result # #################################################### ############### # sets the html-page that should be rendered # param: html:STRING # return: 1/0 ############### sub set_html_content { my $self = shift; my $html = shift; $self->{'html'} = $html; return 1; } ############### # returns the html-content # param: - # return: html:STRING ############### sub get_html_content { my $self = shift; if (ref($self->{'html'}) eq 'SCALAR') { return ${$self->{'html'}}; } return $self->{'html'}; } ############### # sets the filename of the html-page that should be rendered # param: input_file:STRING # return: 1/0 ############### sub set_input_file { my $self = shift; my $infile = shift; if (-f $infile) { $self->{'input_file'} = $infile; $self->{'config'}->{'mode'} = 'file'; return 1; } return 0; } ############### # returns the input htmlfile # param: - # return: input_file:STRING ############### sub get_input_file { my $self = shift; return $self->{'input_file'}; } ############### # private: opens a temporary file and sets the # html-content in # param: - # return: filename:STRING ############### sub _prepare_input_file { my $self = shift; my $i=0; my $filename; return $filename if (defined ($filename = $self->{'input_file'})); my $file = new File::Temp(UNLINK => 0); if (!$file) { warn "could not open tempfile $!"; return undef; } $file->print($self->get_html_content()); $file->seek(0, SEEK_SET); #$self->{'config'}->{'tmpfile'} = $filename; return $file; } ############### # private: cleans up, deletes the tempfile # param: - # return: - ############### sub _cleanup { my $self = shift; unlink($self->{'config'}->{'tmpfile'}) if ( (defined $self->{'config'}->{'tmpfile'}) && (-f $self->{'config'}->{'tmpfile'}) ); } ############### # finaly produces the pdf-output # param: - # return: pdf:STRING ############### sub generate_pdf { my $self = shift; # save the env-var for restoring it later my $old_htmldoc_env = $ENV{'HTMLDOC_NOCGI'}; $ENV{'HTMLDOC_NOCGI'} = 'yes'; my $params = $self->_build_parameters(); my $pdf; #if ($self->{'config'}->{'mode'} eq 'ipc') { if ($self->_config('mode') eq 'ipc') { # we are in normale Mode, use IPC my ($pid, $error); ($pid,$pdf,$error) = $self->_run("$self->{'config'}->{'bindir'}htmldoc $params --webpage -", $self->get_html_content()); } else { # we are in file-mode my $file = $self->_prepare_input_file(); return undef if (!$file); my $filename = $file->filename; if (DEBUG) { print STDERR "$self->{'config'}->{'bindir'}htmldoc $params --webpage $filename"; } my $fh = IO::File->new( "$self->{'config'}->{'bindir'}htmldoc $params --webpage $filename |" ); if ( $fh ) { local($/) = undef; $fh->binmode; $pdf = <$fh>; $fh->close; } else { warn "Failed to render PDF\n"; $pdf = ''; } # $pdf = `$self->{'config'}->{'bindir'}htmldoc $params --webpage $filename`; $self->_cleanup(); } # restore old value if (not defined $old_htmldoc_env) { delete $ENV{'HTMLDOC_NOCGI'}; } else { $ENV{'HTMLDOC_NOCGI'} = $old_htmldoc_env; } my $doc = new HTML::HTMLDoc::PDF(\$pdf); return $doc; } ############### # generates a string for the configuration of htmldoc # testet # param: - # return: params:STRING ############### sub _build_parameters { my $self = shift; my $paramstring=''; foreach my $key($self->_get_doc_config_keys()) { my $value = $self->_get_doc_config($key) || ''; if ( ref($value) eq 'ARRAY' ) { # an array, set the option multiple foreach my $single_v(@{$value}) { $paramstring .= " --$key $single_v"; } } else { if ($key eq 'compression' || $key eq 'jpeg') { $paramstring .= " --$key=$value"; } else { $paramstring .= " --$key $value"; } } } return $paramstring; } sub _run { my $self = shift; my $command = shift; my $input = shift; # create new Filehandles my ($stdin,$stdout,$stderr) = (IO::Handle->new(),IO::Handle->new(),IO::Handle->new()); my $pid = IPC::Open3::open3($stdin,$stdout,$stderr, $command); if (!$pid) { $self->error("Cannot fork [COMMAND: '$command']."); return (0); } print $stdin $input; close $stdin; my $output = join('',<$stdout>); close $stdout; my $error = join('',<$stderr>); close $stderr; wait(); if (DEBUG) { print STDERR "\n********************************************************************\n"; print STDERR "COMMAND : \n$command [PID $pid]\n"; print STDERR "STDIN : \n$input\n"; print STDERR "STDOUT : \n$output\n"; print STDERR "STDERR : \n$error\n"; print STDERR "\n********************************************************************\n"; } return($pid,$output,$error); } ############### # set or retrieve an occurred error # param: - # return: pdf:STRING ############### sub error { my $self = shift; my $error = shift; if (defined $error) { push(@{$self->{'errors'}}, $error); } else { if (wantarray()) { return @{$self->{'errors'}}; } else { return $self->{'errors'}->[0]; } } } 1; __END__ =head1 NAME HTML::HTMLDoc - Perl interface to the htmldoc program for producing PDF-Files from HTML-Content =head1 SYNOPSIS use HTML::HTMLDoc; my $htmldoc = new HTML::HTMLDoc(); $htmldoc->set_html_content(qq~
A PDF file~); # $htmldoc->set_input_file($filename); # alternative to use a present file from your fs my $pdf = $htmldoc->generate_pdf(); print $pdf->to_string(); $pdf->to_file('foo.pdf'); =head1 DESCRIPTION This Module provides an OO-interface to the htmldoc programm. To install this module you have to install the htmldoc program first. You can get it from http://www.htmldoc.org . You can use it to produce PDF or PS files from a HTML-document. Currently many but not all parameters of HTMLDoc are supported. You need to have HTMLDoc installed before installing this module. All the pdf-Methods return true for success or false for failure. You can test if errors occurred by calling the error-method. Normaly this module uses IPC::Open3 for communacation with the HTMLDOC process. However, in mod_perl-environments there appear problems with this module because the standard-output can not be captured. For this problem this module provides a fix doing the communication in file-mode. For this you can specify the parameter mode in the constructor: my $htmldoc = new HTMLDoc('mode'=>'file', 'tmpdir'=>'/tmp'); =head1 METHODS =head2 new() creates a new Instance of HTML::HTMLDoc. Optional parameters are: mode=>['file'|'ipc'] defaults to ipc tmpdir=>$dir defaults to /tmp bindir=>$dir Directory to locate the htmldoc-executable. Usable if you can not influence the system path. The tmpdir is used for temporary html-files in filemode. Remember to set the file-permissions to write for the executing process. =head2 set_page_size($size) sets the desired size of the pages in the resulting PDF-document. $size is one of: =over 4 =item * a4 (default) =item * letter =item * WxH{in,cm,mm} eg '10x10cm' =back =head2 set_owner_password($password) sets the owner-password for this document. $password can be any string. This only has effect if encryption is enabled. see enable_encryption(). =head2 set_user_password($password) sets the user-password for this document. $password can be any string. If set, User will be asked for this password when opening the file. This only has effect if encryption is enabled, see enable_encryption(). =head2 set_permissions($perm) sets the permissions the user has to this document. $perm can be: =over 4 =item * all =item * annotate =item * copy =item * modify =item * print =item * no-annotate =item * no-copy =item * no-modify =item * no-print =item * none setting one of this flags automatically enables the document-encryption ($htmldoc->enable_encryption()) for you, because setting permissions will have no effect without it. Setting 'all' and 'none' will delete all other previously set options. You can set multiple options if you need, eg.: $htmldoc->set_permissions('no-copy'); $htmldoc->set_permissions('no-modify'); this one will do the same: $htmldoc->set_permissions('no-copy', 'no-modify'); =back =head2 links() turns link processing on. =head2 no_links() turns the links off. =head2 path() specify the search path for files in a document. Use this method if your images are not shown. Example: $htmldoc->path("/home/foo/www/myimages/"); =head2 set_htmldoc_datadir($dir) specify where the htmldoc-executable is searching for its data-files. On Unix-based systems the default is /usr/share/htmldoc. Please note that this setting changes a htmldoc-internal and has no influence on path to images you want to use. See the path()-method for that. =head2 landscape() sets the format of the resulting pages to landscape =head2 portrait() sets the format of the resulting pages to portrait =head2 title() turns the title on. =head2 no_title() turns the title off. =head2 set_right_margin($margin, $messure) set the right margin. $margin is a INT, $messure one of 'in', 'cm' or 'mm'. =head2 set_left_margin($margin, $messure) set the left margin. $margin is a INT, $messure one of 'in', 'cm' or 'mm'. =head2 set_bottom_margin($margin, $messure) set the bottom margin. $margin is a INT, $messure one of 'in', 'cm' or 'mm'. =head2 set_top_margin($margin, $messure) set the top margin. $margin is a INT, $messure one of 'in', 'cm' or 'mm'. =head2 set_bodycolor($color) Sets the background of all pages to this background color. $color is a hex-coded color-value (eg. #FFFFFF), a rgb-value (eg set_bodycolor(0,0,0) for black) or a color name (eg. black) =head2 set_bodyfont($font) Sets the default font of the content. Currently the following fonts are supported: Arial Courier Helvetica Monospace Sans-Serif Serif Symbol Times =head2 set_fontsize($fsize) Sets the default font size for the body text. =head2 set_headfootsize($points) Sets the size for the fonts in head and foot areas. Value is points (1 point = 1/72nd inch). =head2 get_headfootsize() Reads out the size for the fonts in head and foot areas. Value is points (1 point = 1/72nd inch). =head2 set_bodyimage($image) Sets the background image for the document. $image is the path to the image in your filesystem. =head2 set_logoimage($image) Sets the logo-image for the document. $image is the path to the image in your filesystem. The supported formats are BMP, GIF, JPEG, and PNG. Remember to specify the 'l'-option somewhere in header or footer using set_header() or/and set_footer(). $htmldoc-E
or
make sure that your perl program can find them. Note that a perl program can change the working
directory internal (See perl -f chdir). You can find out the working directory using:
use Cwd;
print Cwd::abs_path(Cwd::cwd);
The module provides a method path($p). Use this if you want to specify where the images you want to use
can be found. Example:
$htmldoc->path("/home/foo/www/myimages/");
=item * Q: How can I do a page break?
A: You can include a HTML-Comment that will do a page break for you at the point it is located:
=item * Q: The Module works in shell but not with mod_perl
A: Use htmldoc in file-Mode:
my $htmldoc = new HTML::HTMLDoc('mode'=>'file', 'tmpdir'=>'/tmp');
=head1 BUGS
Please use the following URL to report any bugs or missing functions.
L