windows-nt/Source/XPSP1/NT/tools/x86/perl/site/lib/htmlhelp.pm
2020-09-26 16:20:57 +08:00

2049 lines
61 KiB
Perl

#####################################################################
# Library HtmlHelp.pm
# Title HtmlHelp.pm
# Version 1.0.2
# Author David Grove (pete) [pete@activestate.com]
# Company ActiveState Tool Corp. -
# Professional Tools for Perl Developers
#####################################################################
# Description Miscelaneous routines for working with Microsoft's
# HtmlHelp system.
#####################################################################
# REVISION HISTORY
#
# 1.0.0 First final release, went out with 502
# 1.0.1 Temporary, removed CSS insertion in favor of just
# adding a link to the css, since it's being built
# on the user's machine now; and temporarily added
# the hardcoded contents of the main toc to the
# built toc until I have time to build it codewise.
# 1.0.2 gsar Fixed much brokenness. Much ugliness remains.
=head1 TITLE
HtmlHelp.pm
=head1 SYNOPSIS
Routines to create HtmlHelp from HTML or POD source (including the
Pod in PM library files) using Microsoft's HtmlHelp compiler. This
creates the intermediate project files and from those creates the
htmlhelp windows 32-bit help files.
Along with this libaray comes a set of programs that can be used
either as-is or as examples for perl development. Each of the public
functions in this libray is represented by one such script.
=head1 USAGE
There are two "builds" of perl help, the core build (build for core
Perl and it's packages), and the packages build (build from a devel
directory of directories which contain blib directories to draw
upon). These are run by different people on different machines at
different times in different situations, so they are mostly separate
until the time comes within this module to actuall build the helpfiles.
There is also a build (html index) that works on the user's computer
after installing a new module.
For the core build
perl makehelp.pl
for the package build
perl makepackages.pl
for the html index build
perl makehtmlindex.pl
The functions in this module can also be called programmatically
=head1 FUNCTIONS
The individual functions that were designed with working with
html help files rather than the Perl htmlhelp documentation are
deprecated in favor of doing things with a single command. Some
of them need work in order to work again.
=over 4
=item MakeHelp
Turns a single html page into htmlhelp document.
=item MakeHelpFromDir
Turns a directory's worth of html pages into a single htmlhelp document.
=item MakeHelpFromTree
Turns a tree's worth of html pages into a single htmlhelp document.
=item MakeHelpFromHash
Creates an htmlhelp document where the labels on the folders are passed
into the program. Useful for labels like Tk::Whatsis::Gizmo to replace
the default ones looking like c:/perl/lib/site/Tk/Whatsis/Gizmo.
=item MakeHelpFromPod
Turns a single Pod or pm document into htmlhelp document.
=item MakeHelpFromPodDir
Turns a dir's worth of Pod or pm into a single htmlhelp document.
=item MakeHelpFromPodTree
Turns a tree's worth of Pod or pm into a single htmlhelp document.
=item MakeHelpFromPodHash
Like MaheHelpFromHash() but for Pod instead of html.
=item MakePerlHtmlIndex
Creates an HTML version of an index or TOC for perl help.
=item MakePerlHtml
Does everything for perl HTML works.
=back
=head1 CONFIG.PM
This library makes use of Config.pm to know where to get its stuff.
=head1 HHC.EXE
This library makes use of the HtmlHelp compiler by microsoft.
=head1 VARIABLES
=over4
=item $HtmlHelp::CSS
Determines the stylesheet to be used for the htmlhelp files. Default
is the ActiveState common stylesheet. This variable can be set to
an empty string to allow for just plain old HTML with nothing fancy.
Default is perl.css.
=item $HtmlHelp::COMPILER
Complete path and file name of the HtmlHelp compiler from Microsoft.
This is REQUIRED for this library to run. It defaults to it's install
directory within <lib>/HtmlHelp. Feel free to move this in $COMPILER
if you have the HtmlHelp workshop from Microsoft and you want to
use the compiler from a different location.
=item $HtmlHelp::FULLTEXTSEARCH
Whether to create full text search. Defaults to true.
=item $HtmlHelp::CLEANUP
Whether to clean up temporary files (and html files if building
from raw Pod) after building the htmlhelp. This can be useful,
for example, when you need to keep the intermediate files created
by the process for inclusion into a collective help file.
=back
=head1 TARGET AUDIENCE
Mostly this module is created for internal use for ActiveState Tool
Corp., but since it is a part of the standard distrib for Win32 Perl
then I expect it to be used or tried by the general public. However,
no support for this module is available for the public; and it may
be changed at any time.
=head1 INSTALLATION
First of all, this is designed for use with the Perl Resource
Kit. Use with other versions of perl should be considered
unsupported. Perl should be fully installed and configured to
use this thing
Next, Config.pm must be fully configured. Using Config.pm allows
me to program remotely for tools at ActiveState corporate office.
There were some early problems with Config.pm with the PRK and
build 500 of Perl for Win32. These need to be corrected to use
this library.
Perl needs to have $Config{privlib}/../Html and also
$Config{privlib}/../HtmlHelp to use this library. These should be
created before doing anything. Copy the html files and gif
files from this library to the Html directory. All other
files will be created during run.
Finally, copy all the files to $Config{privlib}/HtmlHelp, and the
file HtmlHelp.pm to $Config{privlib}. The former is the normal site
for the htmlhelp compiler (hhc.exe), and it is expected there.
To use this tool, you need to have the compiler's dll's installed
on your system. You should install the htmlhelp workshop from
microsoft for these. Otherwise you should get these dll's from
someone who has them. I think there's only one or two.
=head1 USAGE
=head2 Building HtmlHelp
Building HtmlHelp for main perl is done using the script
makehelp.pl. It requires no command line arguments because it
gets all its information from Config.pm.
Individual files are created as follows:
=over4
=item file2hhelp.pl for .html to .chm
=item dir2hhelp.pl for dir of .html to .chm
=item tree2hhelp.pl for tree of .html to .chm(s)
=item Pod2hhelp.pl for .Pod or .pm to .chm
=item Podd2hhelp.pl for dir of .Pod or .pm to .chm
=item Podt2hhelp.pl for tree of .Pod or .pm to .chm(s)
=back
If your forget the command line arguments for one of the
above, type:
perl <scriptfile>
and it will tell you what command line arguments are needed.
=head2 Building HTML
Building HTML for main perl is doine using the script
makehtml.pl. It requires no command line arguemtns because it
gets all its information from Config.pm.
Individual html files can be built using the normal pod2html
script by Tom Christiansen. Building html from directories
and trees is not otherwise supported.
=head1 AUTHOR
David (pete) Grove
email: pete@ActiveState.com
=head1 FIRM
ActiveState Tool Corp.
Professional Tools for Perl Programmers
=cut
#####################################################################
package HtmlHelp;
#####################################################################
use Pod::WinHtml; # My hack of TC's Pod::Html
use Config;
use File::Copy;
use File::Basename;
use File::Path;
#####################################################################
# Variables
my $CLEANUP = 1;
my $MAKE_HTML_FOR_HHELP = 0;
my $FULLTEXTSEARCH = 1;
my $LIB = $Config{'privlib'};
$LIB =~ s{\\}{/}g;
my $SITELIB = $Config{'sitelib'};
my $HTMLHELP = $LIB; $HTMLHELP =~ s{(\\|/)lib}{/HtmlHelp}i;
my $COMPILER = "$LIB/HtmlHelp/hhc.exe";
my $HTML = $LIB; $HTML =~ s{(\\|/)lib}{/Html}i;
my $TEMP = "$HTMLHELP/Temp";
my $MERGE_PACKAGES = 0;
#####################################################################
# Function PreDeclarations
sub RunCompiler;
sub MakeHelpFromPod;
sub MakeHelpFromPodDir;
sub MakeHelpFromDir;
sub MakePerlHtml;
sub MakePerlHtmlIndexCaller;
sub MakePerlHtmlIndex;
sub GetHtmlFilesFromTree;
sub MakePerlHelp;
sub MakePerlHelpMain;
sub MakeHelpFromPodTree;
sub MakeHtmlTree;
sub MakeHelpFromTree;
sub GetHtmlFileTreeList;
sub MakeHelpFromHash;
sub MakeModuleTreeHelp;
sub MakeHelp;
sub BackSlash;
sub ExtractFileName;
sub ExtractFilePath;
sub MakePackageMainFromSingleDir;
sub MakePackageMain;
sub MakePackages;
sub CopyDirStructure;
sub GetFileListForPackage;
sub CreateHHP;
sub CreateHHC;
sub CreateHHCFromHash;
sub InsertMainToc_Temporary;
#####################################################################
# FUNCTION RunCompiler
# RECEIVES Project file to compile
# RETURNS None
# SETS None
# EXPECTS $COMPILER, hhc and hhp files should be there
# PURPOSE Runs the HtmlHelp compiler to create a chm file
sub RunCompiler {
my $projfile = BackSlash(shift);
my $compiler = BackSlash($COMPILER);
print "Trying \"$compiler $projfile\"\n";
qx($compiler $projfile);
}
#####################################################################
# FUNCTION MakeHelpFromPod
# RECEIVES Helpfile (no path), Working directory, Output
# directory (path for chm file), Files to include
# RETURNS Results from running MakeHelp
# SETS None
# EXPECTS None
# PURPOSE Takes pod/pm files, turns them into html, and then
# into Htmlhelp files.
sub MakeHelpFromPod {
my ($helpfile, $workdir, $outdir, @podfiles) = @_;
my $htmlfiles;
my $htmlfile;
my $podfile;
foreach $podfile (@podfiles) {
$podfile =~ s{\\}{/}g;
$htmlfile = $podfile;
$htmlfile =~ s{(^/]*)\....?$}{$1\.html};
push(@htmlfiles, $htmlfile);
pod2html("--infile=$podfile", "--outfile=$htmlfile");
}
@htmlfiles = grep{-e $_} @htmlfiles;
unless(@htmlfiles) {
$! = "No html files were created";
return 0;
}
return MakeHelp($helpfile, $workdir, $outdir, @htmlfiles);
}
#####################################################################
# FUNCTION MakeHelpFromPodDir
# RECEIVES Helpfile (no extension), Working directory, Output
# directory (for the Helpfile), Directory to translate
# RETURNS 1|0
# SETS None
# EXPECTS None
# PURPOSE Takes a directory's worth of pod/pm files and turns
# them into html and then a single chm file
sub MakeHelpFromPodDir {
my ($helpfile, $workdir, $outdir, $fromdir) = @_;
my @podfiles;
my $htmlfile;
my @htmlfiles;
if(opendir(DIR,$fromdir)) {
@podfiles = grep {/(\.pod)|(\.pm)/i} readdir(DIR);
if(@podfiles) {
foreach $podfile (@podfiles) {
$htmlfile = $podfile;
$htmlfile =~ s{(\.pm)|(\.pod)$}{\.html}i;
$htmlfile = "$workdir/$htmlfile";
push(@htmlfiles, $htmlfile);
pod2html("--infile=$fromdir/$podfile", "--outfile=$htmlfile");
}
@htmlfiles = grep {-e $_} @htmlfiles;
MakeHelp($helpfile, $workdir, $outdir, @htmlfiles);
} else {
$! = "No files to be made from $fromdir";
return 0;
}
} else {
$! = "Could not open directory $fromdir";
return 0;
}
unlink @htmlfiles if $CLEANUP;
1;
}
#####################################################################
# FUNCTION MakeHelpFromDir
# RECEIVES Helpfile (no extension), Working directory, Output
# directory (for Helpfile), Dir of html files for input
# RETURNS 1|0
# SETS None
# EXPECTS None
# PURPOSE Takes a directory's worth of html files and binds
# them all into a chm file
sub MakeHelpFromDir {
my ($helpfile, $workdir, $outdir, $fromdir) = @_;
my @files;
if(opendir(DIR,$fromdir)) {
@files = map {"$fromdir/$_"} sort(grep {/\.html?/i} readdir(DIR));
closedir(DIR);
if(@files) {
MakeHelp($helpfile, $workdir, $outdir, @files);
} else {
$! = "No files to be made from $fromdir";
return 0;
}
} else {
$! = "Could not open directory $fromdir";
return 0;
}
1;
}
#####################################################################
# FUNCTION MakePerlHtml
# RECEIVES None
# RETURNS None
# SETS None
# EXPECTS $HTML, $LIB, $SITELIB
# PURPOSE Creates html files from pod for the entire perl
# system, and creates the main toc file.
sub MakePerlHtml {
MakeHtmlTree($LIB, "$HTML/lib", 1);
MakeHtmlTree($SITELIB, "$HTML/lib/site", 2);
MakePerlHtmlIndex("$HTML/lib", "$HTML/perltoc.html");
}
#####################################################################
# FUNCTION MakePerlHtmlIndexCaller
# RECEIVES None
# RETURNS None
# SETS None
# EXPECTS $HTML
# PURPOSE Caller for MakePerlHtmlIndex. Using this function
# releases the caller from the responsibility of
# feeding params to MakePerlHtmlIndex, which this
# library gets automagically from Config.pm
sub MakePerlHtmlIndexCaller {
#
# Changed this to reflect the "single index file" idea
#
return MakePerlHtmlIndex("$HTML/lib", "$HTML/perltoc.html");
#return MakePerlHtmlIndex("$HTML/lib", "$HTML/maintoc.html");
}
#####################################################################
# FUNCTION MakePerlHtmlIndex
# RECEIVES Base directory to look in, $index file to create
# RETURNS 1 | 0
# SETS None
# EXPECTS None
# PURPOSE Creates the main html index for the perl system. This
# is called by ppm after installing a package.
sub MakePerlHtmlIndex {
my ($basedir, $indexfile) = @_;
my %files;
my $file;
my $file_cmp;
my $dir;
my $dir_cmp;
my $dir_to_print;
my $dir_html_root;
my $counter;
my $file_to_print;
my $sitedir;
my $libdir;
my $temp;
# Get a list of all the files in the tree, list refs keyed by dir.
# These files are under c:/perl/html/lib because they have
# already been generated.
# normalize to forward slashes (NEVER use backslashes in URLs!)
$basedir =~ s{\\}{/}g;
unless(%files = GetHtmlFilesFromTree($basedir)) {
return 0;
}
# Start the html document
unless(open(HTML, ">$indexfile")) {
$! = "Couldn't write to $indexfile\n";
return 0;
}
print HTML <<'EOT';
<HTML>
<HEAD>
<TITLE>Perl Help System Index</TITLE>
<BASE TARGET="PerlDoc">
</HEAD>
<LINK REL="STYLESHEET" HREF="win32prk.css" TYPE="text/css">
<STYLE>
BODY {font-size : 8.5pt;}
P {font-size : 8.5pt;}
</STYLE>
<BODY>
EOT
foreach $dir (keys %files) {
foreach $file (@{$files{$dir}}) {
$file_cmp = $file;
$file_cmp =~ s/\.html?$//i;
if(exists $files{"$dir/$file_cmp"}) {
push(@{$files{"$dir/$file_cmp"}}, "$file_cmp/$file");
@{$files{$dir}} = grep {$_ ne $file} @{$files{$dir}};
}
}
}
# Merge the different directories if duplicate directories
# exist for lib and site. Effectively this removes lib/site
# from existence, and prepends "site" onto the file name for
# future reference. This way there is only one folder per
# heading, but I can still tell when to use "site" in
# making a html link.
$libdir = "$HTML/lib";
$sitedir = "$HTML/lib/site";
push(@{$files{$libdir}}, map {"site/$_"} @{$files{$sitedir}});
delete $files{$sitedir};
foreach $dir (keys %files) {
if($dir =~ m{/site/}i) {
$dir_cmp = $dir;
$dir_cmp =~ s{(/lib/)site/}{$1}i;
push(@{$files{$dir_cmp}}, map {"site/$_"} @{$files{$dir}});
delete $files{$dir};
}
}
InsertMainToc_Temporary();
print HTML <<EOT;
<img id="Foldergif_63" src="folder.gif">&nbsp;
<b><a name="CorePerlFAQ">Core Perl FAQ</a><BR>
</b>
EOT
foreach $file (@{$files{"$libdir/Pod"}}) {
$file_to_print = $file;
$file_to_print =~ s{\.html$}{}i;
next unless $file_to_print =~ m{^(perlfaq\d*)$};
print HTML <<EOT;
&nbsp;&nbsp;&nbsp;
<img id="Pagegif_63" src="page.gif">&nbsp;
<a href="./lib/Pod/$file_to_print.html">
$file_to_print
</a><BR>
EOT
}
print HTML <<EOT;
<img id="Foldergif_63" src="folder.gif">&nbsp;
<b><a name="CorePerlDocs">Core Perl Docs</a><BR>
</b>
EOT
foreach $file (@{$files{"$libdir/Pod"}}) {
$file_to_print = $file;
$file_to_print =~ s{\.html$}{}i;
next unless $file_to_print =~ m{^(perl[a-z0-9]*)$};
next if $file_to_print =~ /^perlfaq/;
print HTML <<EOT;
&nbsp;&nbsp;&nbsp;
<img id="Pagegif_63" src="page.gif">&nbsp;
<a href="./lib/Pod/$file_to_print.html">
$file_to_print
</a><BR>
EOT
}
print HTML <<EOT;
</p><hr>
<h4><a name="ModuleDocs">Module Docs</a></h4>
<p>
EOT
foreach $dir (sort { uc($a) cmp uc($b) } keys(%files)) {
$counter++;
$dir_to_print = $dir;
# get just the directory starting with lib/
$dir_to_print =~ s{.*/(lib/?.*$)}{$1}i;
# change slashes to double colons
$dir_to_print =~ s{/}{::}g;
# kill extra stuff lib and site
$dir_to_print =~ s{lib::}{}i;
# Don't want to see lib:: and lib::site::
$dir_to_print =~ s{(.*)(/|::)$}{$1};
if($dir_to_print =~ m{^lib(/site)?$}i) {
$dir_to_print = 'Root Libraries';
}
print HTML <<EOT;
<!-- -------------------------------------------- $dir -->
<SPAN
id="Dir_${counter}"
>
<b>
<img id="Foldergif_${counter}" src="folder.gif">&nbsp;
$dir_to_print<BR>
</b></SPAN>
<SPAN
id="Files_${counter}"
>
EOT
if (@{$files{$dir}}) {
foreach $file (sort { $c = $a;
$d = $b;
$c =~ s{^site/}{}i;
$d =~ s{^site/}{}i;
uc($c) cmp uc($d) } (@{$files{$dir}}))
{
$file_to_print = $file;
$file_to_print =~ s{\.html?}{}i;
# skip perlfunc.pod etc.
next if $file_to_print =~ m{^perl[a-z0-9]*$};
$dir_html_root = $dir;
if ($file_to_print =~ m{^site/[^/]*$}i) {
$dir_html_root =~ s{(lib/)}{$1site/}i;
$dir_html_root =~ s{/lib$}{/lib/site}i;
$file_to_print =~ s{^site/}{}i;
$file =~ s{^site/}{}i;
}
elsif ($file_to_print =~ m{^site/(.*)/}i) {
$temp = $1;
# Get rid of the site
$dir_html_root =~ s{(lib/)}{$1site/}i;
$dir_html_root =~ s{/lib$}{/lib/site}i;
$file_to_print =~ s{^site/}{}i;
$file =~ s{^site/}{}i;
# Get rid of the additional directory
$file_to_print =~ s{^[^/]*/}{}i;
$file =~ s{^[^/]*/}{}i;
$dir_html_root =~ s{/$temp/?}{}i;
}
elsif ($file_to_print =~ m{^(.*)/}) {
$temp = $1;
# $file_to_print =~ s{^[^/]/?}{}i;
# $file =~ s{^[^/]/?}{}i;
$file_to_print =~ s{^.*?/}{}i;
$file =~ s{^.*?/}{}i;
$dir_html_root =~ s{/$temp/?}{}i;
}
$dir_html_root =~ s{.*/lib$}{lib}i;
$dir_html_root =~ s{.*/(lib/.*)}{$1}i;
$dir_html_root =~ s{lib/\.\./html/}{}i;
print HTML <<EOT;
&nbsp;&nbsp;&nbsp;
<img id="Pagegif_${counter}" src="page.gif">&nbsp;
<a href="$dir_html_root/$file">
$file_to_print
</a><BR>
EOT
}
}
else {
print HTML "&nbsp;&nbsp;&nbsp;\n";
print HTML "No pod / html<BR>\n";
}
print HTML "</SPAN>\n";
}
print HTML "</p>\n";
# Close the file
print HTML "</BODY>\n";
print HTML "</HTML>\n";
close HTML;
return 1;
}
#####################################################################
# FUNCTION InsertMainToc_Temporary
# RECEIVES None
# RETURNS None
# SETS None
# EXPECTS HTML must be an open file handls
# PURPOSE Temporary (interim) function to hard code the content
# of the main toc into a single, merged toc
sub InsertMainToc_Temporary {
print HTML <<'END_OF_MAIN_TOC';
<p><a href="http://www.ActiveState.com"><img src="aslogo.gif" border="0"></a></p>
<p><img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#ActivePerlDocs" target="TOC"><b>ActivePerl Docs</b></a><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#GettingStarted" target="TOC"><b>Getting
Started</b></a><b><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#ActivePerlComponents" target="TOC">ActivePerl
Components</a><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#ActivePerlFAQ" target="TOC">ActivePerl
FAQ</a><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#CorePerlFAQ" target="TOC">Core
Perl FAQ</a><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#CorePerlDocs" target="TOC">Core
Perl Docs</a><br>
<img src="pinkbullet.gif" width="10" height="10">&nbsp;<a href="#ModuleDocs" target="TOC">Module
Docs</a></b></p>
<hr>
<h4><a name="ActivePerlDocs">ActivePerl Docs</a></h4>
<p><b><img id="Foldergif_60" src="folder.gif">&nbsp; <a name="GettingStarted">Getting
Started</a></b><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_60" src="page.gif">&nbsp; <a href="perlmain.html">
Welcome</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_60" src="page.gif">&nbsp; <a href="./Perl-Win32/release.htm">
Release Notes </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_60" src="page.gif">&nbsp; <a href="./Perl-Win32/install.htm">
Install Notes </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_60" src="page.gif">&nbsp; <a href="./Perl-Win32/readme.htm">
Readme<br>
</a>&nbsp;&nbsp;&nbsp; <img id="Pagegif_60" src="page.gif">&nbsp; <a href="./Perl-Win32/dirstructure.html">
Dir Structure</a><br>
<b> <img id="Foldergif_61" src="folder.gif" alt="Instructions and sample scripts for using PerlScript">&nbsp;
<a name="ActivePerlComponents">ActivePerl Components</a><BR>
</b>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_61" src="page.gif">&nbsp; <a href="./Perl-Win32/description.html">
Overview</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_61" src="page.gif">&nbsp; <a href="PerlScript.html">
Using PerlScript </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_61" src="page.gif">&nbsp; <a href="../eg/ie3examples/index.htm">
PerlScript Examples </a><BR>
<b> </b>&nbsp;&nbsp;&nbsp; <img id="Pagegif_68" src="page.gif">&nbsp; <a href="PerlISAPI.html">
Using Perl for ISAPI </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_68" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq2.html">
Perl for ISAPI FAQ </a><BR>
<b> </b>&nbsp;&nbsp;&nbsp; <img id="Pagegif_69" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq11.html">
Using PPM</a><br>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_68" src="page.gif">&nbsp; <a href="./lib/site/Pod/PerlEz.html">
PerlEZ</a><BR>
<b><img id="Foldergif_62" src="folder.gif" alt="FAQ for using Perl on Win95/NT">&nbsp;
<a name="ActivePerlFAQ">ActivePerl FAQ</a><BR>
</b> &nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq.html">
Introduction </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq1.html">
Availability & Install </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq2.html">
Perl for ISAPI</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq3.html">
Docs & Support </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq4.html">
Windows 95/NT </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq5.html">
Quirks </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq6.html">
Web Server Config</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq7.html">
Web programming </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq8.html">
Programming </a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq9.html">
Modules &amp; Samples</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq10.html">
Embedding &amp; Extending</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq11.html">
Using PPM</a><BR>
&nbsp;&nbsp;&nbsp; <img id="Pagegif_62" src="page.gif">&nbsp; <a href="./Perl-Win32/perlwin32faq12.html">
Using OLE with Perl</a><BR>
END_OF_MAIN_TOC
}
#####################################################################
# FUNCTION GetHtmlFilesFromTree (recursive)
# RECEIVES Base directory to look in
# RETURNS List of html files
# SETS None
# EXPECTS None
# PURPOSE Searches an entire for html files, returns a list of
# html files found including path information
sub GetHtmlFilesFromTree {
my $basedir = shift;
my @dirs;
my @htmlfiles;
my %ret;
unless(opendir(DIR, $basedir)) {
$! = "Can't read from directory $basedir\n";
return 0;
}
@files = readdir(DIR);
closedir(DIR);
@dirs = grep {-d "$basedir/$_" and /[^.]$/} @files;
@htmlfiles = grep {/\.html?$/i} @files;
foreach $dir (@dirs) {
unless(%ret = (%ret, GetHtmlFilesFromTree("$basedir/$dir"))) {
return 0;
}
}
%ret = (%ret, $basedir => \@htmlfiles);
}
#####################################################################
# FUNCTION MakePerlHelp
# RECEIVES None
# RETURNS 1 | 0
# SETS None
# EXPECTS None
# PURPOSE Creates html help for the perl system. This is the
# html help core build. If MAKE_HTML_FOR_HHELP is set
# to a true vale, then it builds the help from POD,
# otherwise it depends on the pod being there already.
sub MakePerlHelp {
if($MAKE_HTML_FOR_HHELP) {
unless(MakeHelpFromPodTree($HTMLHELP, $HTMLHELP, $LIB, "$HTML/lib")) {
return 0;
}
unless(MakeHelpFromPodTree($HTMLHELP, $HTMLHELP, $SITELIB,
"$HTML/lib/site")) {
return 0;
}
} else {
unless(MakeHelpFromTree($HTMLHELP, $HTMLHELP, "$HTML/lib")) {
return 0;
}
}
unless(MakePerlHelpMain) {
return 0;
}
# This handles MakePerlHtml too, since we've created all the html
unless(MakePerlHtmlIndex("$HTML/lib", "$HTML/perltoc.html")) {
return 0;
}
return 1;
}
#####################################################################
# FUNCTION MakePerlHelpMain;
# RECEIVES None
# RETURNS None
# SETS None
# EXPECTS None
# PURPOSE Creates the main perl helpfile from all the little
# helpfiles already created.
sub MakePerlHelpMain {
my @files;
print "Generating main library helpfile\n";
unless(opendir(DIR, $HTMLHELP)) {
$! = "Directory $HTMLHELP could not be read\n";
return 0;
}
unless(-e "$HTMLHELP/default.htm") {
copy("$HTML/libmain.html", "$HTMLHELP/default.htm");
}
@files = grep {/\.hhc/i} readdir(DIR);
closedir(DIR);
$CLEANUP=0;
$MERGE_PACKAGES = 1;
MakeHelp("libmain.chm", $HTMLHELP, $HTMLHELP, @files);
$CLEANUP = 1;
$MERGE_PACKAGES = 0;
return 1;
}
#####################################################################
# FUNCTION MakeHelpFromPodTree
# RECEIVES Working directory, Output directory, Source Diretory,
# HtmlOutput Directory
# RETURNS 0 | 1
# SETS None
# EXPECTS None
# PURPOSE Takes a tree's worth of pod and turns them first
# into html and then into htmlhelp.
sub MakeHelpFromPodTree {
my ($workdir, $outdir, $fromdir, $htmldir) = @_;
unless(MakeHtmlTree($fromdir, $htmldir)) {
return 0;
}
unless(MakeHelpFromTree($workdir, $outdir, $htmldir)) {
return 0;
}
# if(opendir(DIR, $outdir)) {
# unlink(map {"$outdir/$_"} grep {/\.hhp/i} readdir(DIR));
# closedir(DIR);
# } else {
# warn "Could not clean up project files in $outdir\n";
# }
return 1;
}
#####################################################################
# FUNCTION MakeHtmlTree
# RECEIVES Source Directory, Html Output Directory
# RETURNS 0 | 1
# SETS None
# EXPECTS None
# PURPOSE Makes a tree's worth of html from a tree's worth
# of pod.
sub MakeHtmlTree {
my ($fromdir, $htmldir, $depth) = @_;
my @files;
my @podfiles;
my @dirs;
my $podfile;
my $htmlfile;
my $dir;
my $css = '../' x$depth . 'win32prk.css';
# Get list of files and directories to process
$fromdir =~ s{\\}{/}g;
if(!-d $fromdir) {
$! = "Directory $fromdir does not exist\n";
return 0;
}
unless(opendir(DIR, $fromdir)) {
$! = "Directory $fromdir couldn't be read\n";
return 0;
}
@files = readdir(DIR);
closedir(DIR);
@podfiles = map {"$fromdir/$_"} grep {/\.pod$|\.pm$/i} @files;
@dirs = grep {-d "$fromdir/$_" and /[^.]$/} @files;
if(@podfiles) {
# Create the copy directory
if(!-d $htmldir) {
unless(mkpath($htmldir)) {
$! = "Directory $htmldir could not be created\n";
return 0;
}
}
foreach $podfile (@podfiles) {
$htmlfile = $podfile;
$htmlfile =~ s{.*/(.*)}{$1};
$htmlfile =~ s{\.pod|\.pm$}{.html}i;
$htmlfile = "$htmldir/$htmlfile";
unlink($htmlfile) if (-e $htmlfile);
pod2html("--infile=$podfile", "--outfile=$htmlfile", "--css=$css");
}
}
++$depth;
foreach $dir (@dirs) {
MakeHtmlTree("$fromdir/$dir", "$htmldir/$dir", $depth);
}
return 1;
}
#####################################################################
# FUNCTION MakeHelpFromTree
# RECEIVES Working directory, Output directory, Source directory
# RETURNS 0 | 1
# SETS None
# EXPECTS None
# PURPOSE Creates html help from a tree's worth of html
sub MakeHelpFromTree {
my ($workdir, $outdir, $fromdir) = @_;
my %files;
my $file;
my $key;
my $file_root;
$fromdir =~ s{\\}{/}g;
unless(%files = GetHtmlFileTreeList($fromdir, $fromdir)) {
return 0;
}
$file_root = $fromdir;
$file_root =~ s{(.*)/$}{$1};
foreach $key (sort(keys(%files))) {
$file = $key;
$file = substr($key, length($file_root));
$file =~ s{^/}{};
$file =~ s{/}{-}g;
$file =~ s{ }{}g;
if($file eq "") {
if($file_root =~ /lib$/i) {
$file = "lib";
} else {
$file = "lib-site";
}
} elsif ($file_root =~ /lib$/i) {
$file = "lib-" . $file;
} elsif ($file_root =~ /site$/i) {
$file = "lib-site-" . $file;
}
$file .= ".chm";
unless(MakeHelp("$file", $workdir, $outdir, map {"$key/$_"} @{$files{$key}})) {
return 0;
}
}
return 1;
}
#####################################################################
# FUNCTION GetHtmlFileTreeList (recursive)
# RECEIVES Original root (from first call), Root (successive)
# RETURNS Hash of files
# SETS None
# EXPECTS None
# PURPOSE Get a list of html files throughout a tree
sub GetHtmlFileTreeList {
my $origroot = shift;
my $root = shift;
my @files;
my @htmlfiles;
my @dirs;
my $dir;
my %ret;
$origroot =~ s{\\}{/}g;
$root =~ s{\\}{/}g;
unless(opendir(DIR, $root)) {
$! = "Can't open directory $root\n";
return undef;
}
@files = readdir(DIR);
@dirs = grep {-d "$root/$_" and /[^.]$/} @files;
@htmlfiles = grep {/\.html?/i} @files;
closedir(DIR);
%ret = ($root => \@htmlfiles) if @htmlfiles;
foreach $dir (@dirs) {
unless(%ret = (%ret, GetHtmlFileTreeList($origroot, "$root/$dir"))) {
return undef;
}
}
return %ret;
}
#####################################################################
# FUNCTION MakeHelpFromHash
# RECEIVES Helpfile name, working directory, output directory,
# and a hash containing the html files to process and
# their titles
# RETURNS 0 | 1
# SETS None
# EXPECTS None
# PURPOSE Create a helpfile from a hash rather than from a
# simple list of html files, to have better control
# over the file titles. This function is unused and
# may take some work to get it to work right.
sub MakeHelpFromHash {
my ($helpfile, $workdir, $outdir, %htmlfiles) = @_;
my $tocfile;
my $projfile;
die("MakeHelpFromHash() is not completely implemented\n");
$tocfile = $helpfile;
$tocfile =~ s/\.chm/.hhc/i;
$tocfile = "$workdir/$tocfile";
$projfile = $helpfile;
$projfile =~ s/\.chm/.hhp/i;
$projfile = "$workdir/$projfile";
$helpfile = "$outdir/$helpfile";
unless(CreateHHP($helpfile, $projfile, $tocfile, keys(%htmlfiles))) {
return 0;
}
unless(CreateHHCFromHash($helpfile, $tocfile, %htmlfiles)) {
return 0;
}
RunCompiler($helpfile);
1;
}
#####################################################################
# FUNCTION MakeModuleTreeHelp
# RECEIVES Directory to start from, regex mask for that dir
# RETURNS 1 | 0
# SETS None
# EXPECTS The directories to be right
# PURPOSE Create help from a tree of pod files for packages
sub MakeModuleTreeHelp {
my ($fromdir, $mask) = @_;
my @files;
my @htmlfiles;
my @podfiles;
my @dirs;
my $helpfile;
my $podfile;
my $htmlfile;
my $dir;
$fromdir =~ s{\\}{/}g;
print "Creating help files for $fromdir\n";
# Create the html for the directory
unless(opendir(DIR, $fromdir)) {
$! = "Can't read from directory $fromdir";
return 0;
}
@files = readdir(DIR);
closedir(DIR);
@podfiles = map {"$fromdir/$_"} grep {/\.pm/i or /\.pod/i} @files;
foreach $podfile (@podfiles) {
$htmlfile = $podfile;
$htmlfile =~ s/\.(pm|pod)$/.html/i;
pod2html("--infile=$podfile", "--outfile=$htmlfile");
}
# Create the htmlhelp for the directory
$CLEANUP = 0;
@htmlfiles = map {"$fromdir/$_"} grep {/\.html?/i} @files;
if(@htmlfiles) {
$helpfile = $fromdir;
$helpfile =~ s{$mask}{}i;
$helpfile =~ s{/}{-}g;
$helpfile .= ".chm";
MakeHelp($helpfile, $fromdir, $fromdir, @htmlfiles);
}
# Recurse
@dirs = map {"$fromdir/$_"} grep {-d and /[^.]$/} @files;
foreach $dir (@dirs) {
unless(CreateModuleTreeHelp("$fromdir/$dir")) {
return 0;
}
}
return 1;
}
#####################################################################
# FUNCTION MakeHelp
# RECEIVES Helpfile (without drive and path), Working Directory,
# Output Directory, and a list of files to include
# in the helpfile
# RETURNS None
# SETS None
# EXPECTS None
# PURPOSE Create help from a list of html files. Everything in
# this library comes through here eventually.
sub MakeHelp {
my ($helpfile, $workdir, $outdir, @htmlfiles) = @_;
my $longtocfile;
my $longprojfile;
my $longhelpfile;
my $longouthelpfile;
my $longouttocfile;
my $libdir;
my $tocfile;
my $projfile;
$libdir = ExtractFilePath($htmlfiles[0]);
$tocfile = $helpfile;
$tocfile =~ s/\.chm/.hhc/i;
if ($libdir ne "") {
$longtocfile = "$libdir/$tocfile";
}
else {
$longtocfile = "$outdir/$tocfile";
}
$longouttocfile = "$outdir/$tocfile";
$projfile = $helpfile;
$projfile =~ s/\.chm/.hhp/i;
if ($libdir ne "") {
$longprojfile = "$libdir/$projfile";
}
else {
$longprojfile = "$outdir/$projfile";
}
if ($libdir ne "") {
$longhelpfile = "$libdir/$helpfile";
}
else {
$longhelpfile = "$outdir/$helpfile";
}
$longouthelpfile = "$outdir/$helpfile";
print "----- CREATING HELP FILE $longouthelpfile -----\n";
# put in the default document
if ($libdir eq "") {
unshift(@htmlfiles, "$HTMLHELP/default.htm");
}
unless(CreateHHP($longhelpfile, $longprojfile, $longtocfile, @htmlfiles)) {
return 0;
}
unless(CreateHHC($longhelpfile, $longtocfile, @htmlfiles)) {
return 0;
}
return 0 if (!-x $COMPILER);
RunCompiler($longhelpfile);
if($libdir ne "") {
if($longhelpfile ne $longouthelpfile) {
copy($longhelpfile, $longouthelpfile);
copy($longtocfile, $longouttocfile);
}
}
# temporary for when i want to see what it's doing
# $CLEANUP = 0;
if($CLEANUP) {
unlink $longhelpfile, $longtocfile, $longprojfile;
}
1;
}
#####################################################################
# FUNCTION BackSlash
# RECEIVES string containing a path to convert
# RETURNS converted string
# SETS none
# EXPECTS none
# PURPOSE Internally, perl works better if we're using a
# front slash in paths, so I don't care what I'm
# using. But externally we need to keep everything as
# backslashes. This function does that conversion.
sub BackSlash {
my $in = shift;
$in =~ s{/}{\\}g;
return $in;
}
#####################################################################
# FUNCTION ExtractFileName
# RECEIVES FileName with (drive and) path
# RETURNS FileName portion of the file name
# SETS None
# EXPECTS None
# PURPOSE Gives the file name (anything after the last slash)
# from a given file and path
sub ExtractFileName {
my $in = shift;
$in =~ s/.*(\\|\/)(.*)/$2/;
$in;
}
#####################################################################
# FUNCTION ExtractFilePath
# RECEIVES Full file and path name
# RETURNS Path without the file name (no trailing slash)
# SETS None
# EXPECTS None
# PURPOSE Returns the path portion of a path/file combination,
# not including the last slash.
sub ExtractFilePath {
my $in = shift;
if($in =~ /\\|\//) {
$in =~ s/(.*)(\\|\/)(.*)/$1/;
} else {
$in = "";
}
$in;
}
#####################################################################
# FUNCTION MakePackageMainFromSingleDir
# RECEIVES Package helpfile directory, helpfile to create
# RETURNS 1 | 0
# SETS None
# EXPECTS None
# PURPOSE Creates the package helpfile from the directory of
# package helpfiles. Creates the master.
sub MakePackageMainFromSingleDir {
my $package_helpfile_dir = shift;
my $helpfile = shift;
my $helpfile_dir;
my @hhcfiles;
$helpfile_dir = ExtractFilePath($helpfile);
$helpfile = ExtractFileName($helpfile);
unless(opendir(DIR, $package_helpfile_dir)) {
$! = "Couldn't read from package directory $package_helpfile_dir";
return 0;
}
@hhcfiles = grep {/\.hhc$/i} readdir(DIR);
closedir(DIR);
$CLEANUP = 0;
unless(MakeHelp($helpfile, $helpfile_dir, $helpfile_dir, @hhcfiles)) {
return 0;
}
1;
}
#####################################################################
# FUNCTION MakePackageMain
# RECEIVES Packages directory (contains packages which contain
# blib directories), helpfile name to create (include
# drive and path information)
# RETURNS 1 | 0
# SETS None
# EXPECTS None
# PURPOSE For the packages build of HtmlHelp, this function
# combines all the little packages into one chm
# file linked to all the little ones per module.
sub MakePackageMain {
my $package_root_dir = shift;
my $helpfile = shift;
my $helpfile_dir;
my @files;
my @dirs;
my @dir;
my @hhcfiles;
$helpfile_dir = ExtractFilePath($helpfile);
$helpfile = ExtractFileName($helpfile);
unless(opendir(DIR, $package_root_dir)) {
$! = "Couldn't read from package directory $package_root_dir";
return 0;
}
@files = readdir(DIR);
closedir(DIR);
@dirs = map {"$package_root_dir/$_"} grep {-d "$package_root_dir/$_" and /[^.]/} @files;
foreach $dir (@dirs) {
if(opendir(DIR, "$dir/blib/HtmlHelp")) {
@files = readdir(DIR);
closedir(DIR);
@hhcfiles = (@hhcfiles, grep {/\.hhc$/i} @files);
} else {
warn "Couldn't read / didn't add $dir/blib/HtmlHelp";
}
}
$CLEANUP = 0;
unless(MakeHelp($helpfile, $helpfile_dir, $helpfile_dir, @hhcfiles)) {
return 0;
}
1;
}
#####################################################################
# FUNCTION MakePackages
# RECEIVES Name of directory containing the package dirs, which
# package directories in turn contain blib dirs.
# RETURNS None
# SETS Creates Html and HtmlHelp within the package dirs
# EXPECTS None, but there should be some pm files in blib, but
# it ignores it if there isn't
# PURPOSE Creates Html and HtmlHelp within the package dirs. We
# decided that we don't want to build the packages at
# the same time as the main htmlhelp, so this was
# needed to build them (Murray) at a different time and
# merge them in.
sub MakePackages {
my $package_root_dir = shift;
my (@files) = @_;
my $package_root_dir_mask;
my @package_dirs;
my $package_dir;
my @file;
my @dirs;
my $package_file;
my $podfile;
my $htmlfile;
my @package_file_list;
my @helphtmlfiles;
my $htmlfilecopy;
my $helpfile;
$CLEANUP = 0;
$package_root_dir =~ s{\\}{/}g;
$package_root_dir_mask = $package_root_dir;
if (!defined @files) {
unless(opendir(DIR, $package_root_dir)) {
$! = "Directory could not be opened $package_root_dir";
return 0;
}
@files = readdir(DIR);
closedir(DIR);
}
@dirs = grep {-d "$package_root_dir/$_" and /[^.]$/} @files;
@package_dirs = map {"$package_root_dir/$_"} @dirs;
foreach $package_dir (@package_dirs) {
@helphtmlfiles = ();
next if (!-d "$package_dir/blib");
print "Making help for $package_dir\n";
# Make room for the stuff
unless(-d "$package_dir/blib/HtmlHelp") {
unless(mkpath("$package_dir/blib/HtmlHelp")) {
$! = "Directory could not be created $package_dir/blib/HtmlHelp";
return 0;
}
}
unless(-d "$package_dir/blib/Html") {
unless(mkpath("$package_dir/blib/Html")) {
$! = "Directory could not be created $package_dir/blib/Html";
return 0;
}
}
unless(-d "$package_dir/blib/Html/lib") {
unless(mkpath("$package_dir/blib/Html/lib")) {
$! = "Directory could not be created $package_dir/blib/Html/lib";
return 0;
}
}
unless(-d "$package_dir/blib/Html/lib/site") {
unless(mkpath("$package_dir/blib/Html/lib/site")) {
$! = "Directory could not be created $package_dir/blib/Html/lib/site";
return 0;
}
}
# Make the structure under the html
unless(CopyDirStructure("$package_dir/blib/lib", "$package_dir/blib/Html/lib/site")) {
return 0;
}
# Get a list of all the files to be worked with
@package_file_list = GetFileListForPackage("$package_dir/blib/lib");
foreach $file (@package_file_list) {
print " ... found $file\n";
}
unless(@package_file_list) {
print " Nothing to do for this package\n";
next;
}
# Make the html
foreach $package_file (@package_file_list) {
unless(-d "$package_dir/blib/temp") {
unless(mkpath("$package_dir/blib/temp")) {
$! = "Directory could not be created $package_dir/blib/temp";
return 0;
}
}
$htmlfile = $package_file;
$htmlfile =~ s/\.(pm|pod)$/.html/i;
$htmlfile =~ s{/blib/lib/}{/blib/Html/lib/site/}i;
pod2html("--infile=$package_file", "--outfile=$htmlfile");
if (-e $htmlfile) {
unless(-d "$package_dir/blib/temp") {
unless(mkpath("$package_dir/blib/temp")) {
$! = "Directory could not be created $package_dir/blib/temp";
return 0;
}
}
$htmlfilecopy = $htmlfile;
$htmlfilecopy =~ s{.*/blib/html/}{}i;
$htmlfilecopy =~ s{/}{-}g;
copy($htmlfile, "$package_dir/blib/temp/$htmlfilecopy");
push(@helphtmlfiles, "$package_dir/blib/temp/$htmlfilecopy");
}
}
# Make the htmlhelp
$helpfile = basename($package_dir);
# $helpfile =~ s{$package_root_dir_mask/?}{};
$helpfile .= ".chm";
$helpfile = "pkg-" . $helpfile;
unless(MakeHelp($helpfile, "$package_dir/blib/temp",
"$package_dir/blib/temp", @helphtmlfiles))
{
return 0;
}
if (-e "$package_dir/blib/temp/$helpfile") {
copy("$package_dir/blib/temp/$helpfile",
"$package_dir/blib/HtmlHelp/$helpfile");
$hhcfile = $helpfile;
$hhcfile =~ s/\.chm$/.hhc/i;
if (-e "$package_dir/blib/temp/$hhcfile") {
copy("$package_dir/blib/temp/$hhcfile",
"$package_dir/blib/HtmlHelp/$hhcfile");
}
else {
warn("$package_dir/blib/temp/$hhcfile not found, "
."file will not be included");
}
}
else {
warn("No help file was generated for "
."$package_dir/blib/temp/$helpfile");
}
# Clean up the mess from making helpfiles, temp stuff and that
if (-d "$package_dir/blib/temp") {
if (opendir(DIR, "$package_dir/blib/temp")) {
unlink(map {"$package_dir/blib/temp/$_"}
grep {-f "$package_dir/blib/temp/$_"} readdir(DIR));
closedir(DIR);
unless (rmdir("$package_dir/blib/temp")) {
warn "Couldn't rmdir temp dir $package_dir/blib/temp\n";
}
}
else {
warn "Couldn't read/remove temp dir $package_dir/blib/temp\n";
}
}
}
1;
}
#####################################################################
# FUNCTION CopyDirStructure
# RECEIVES From Directory, To Directory
# RETURNS 1 | 0
# SETS None
# EXPECTS None
# PURPOSE Copies the structure of the dir tree at and below
# the Source Directory (fromdir) to the Target
# Directory (todir). This does not copy files, just
# the directory structure.
sub CopyDirStructure {
my ($fromdir, $todir) = @_;
my @files;
my @dirs;
my $dir;
unless(opendir(DIR, $fromdir)) {
$! = "Couldn't read from directory $fromdir";
return 0;
}
@files = readdir(DIR);
@dirs = grep {
-d "$fromdir/$_" and /[^.]$/ and $_ !~ /auto$/i
} @files;
closedir(DIR);
foreach $dir (@dirs) {
#
# I could make it so that it only creates the directory if
# it has pod in it, but what about directories below THAT
# if it DOES have pod in it. That would be skipped. May want
# to do some kind of lookahead. Cutting out the auto more
# or less cuts out the problem though, right?
#
unless(-e "$todir/$dir") {
unless(mkpath("$todir/$dir")) {
$! = "Directory could not be created $todir/$dir";
return 0;
}
}
unless(CopyDirStructure("$fromdir/$dir", "$todir/$dir")) {
return 0;
}
}
1;
}
#####################################################################
# FUNCTION GetFileListForPackage (recursive)
# RECEIVES Root directory
# RETURNS List of pod files contained in directories under root
# SETS None
# EXPECTS None
# PURPOSE For the packages build, this function searches a
# directory for pod files, and all directories through
# the tree beneath it. It returns the complete path
# and file name for all the pm or pod files it finds.
sub GetFileListForPackage {
my ($root) = @_;
my @podfiles;
my @dirs;
my $dir;
unless(opendir(DIR, $root)) {
$! = "Can't read from directory $root";
return undef;
}
@files = readdir(DIR);
closedir(DIR);
@podfiles = map {
"$root/$_"
} grep {
/\.pm/i or /\.pod/i
} @files;
@dirs = map {
"$root/$_"
} grep {
-d "$root/$_" and /[^.]$/ and $_ !~ /auto$/i
} @files;
foreach $dir (@dirs) {
@podfiles = (@podfiles, GetFileListForPackage("$dir"))
}
@podfiles;
}
#####################################################################
# FUNCTION CreateHHP
# RECEIVES help file name, project file name, toc file name,
# and a list of files to include
# RETURNS 1|0 for success
# SETS none
# EXPECTS none
# PURPOSE Creates the project file for the html help project.
sub CreateHHP {
my ($helpfile, $projfile, $tocfile, @files) = @_;
my $file;
my $chmfile;
my $first_html_file;
my ($shorthelpfile, $shortprojfile, $shorttocfile);
my ($shortfirstfile, $shortfile);
my @htmlfiles = grep {/\.html?$/i} @files;
my @hhcfiles = grep {/\.hhc$/i} @files;
$shorthelpfile = ExtractFileName($helpfile);
$shortprojfile = ExtractFileName($projfile);
$shorttocfile = ExtractFileName($tocfile);
$first_html_file = $htmlfiles[0];
unless(defined $first_html_file) {
warn "No default html file for $backhelp\n";
}
$shortfirstfile = ExtractFileName($first_html_file);
print "Creating $shortprojfile\n";
unless(open(HHP, ">$projfile")) {
$! = "Could not write project file";
return 0;
}
print HHP <<EOT;
[OPTIONS]
Compatibility=1.1
Compiled file=$shorthelpfile
Contents file=$shorttocfile
Display compile progress=Yes
EOT
if ($FULLTEXTSEARCH) {
print HHP "Full-text search=Yes\n";
}
print HHP <<EOT;
Language=0x409 English (United States)
Default topic=$shortfirstfile
[FILES]
EOT
foreach $file (@htmlfiles) {
$shortfile = ExtractFileName($file);
print HHP "$shortfile\n";
print " added $shortfile\n";
}
if(@hhcfiles) {
print HHP "\n";
print HHP "[MERGE FILES]\n";
foreach $file (@hhcfiles) {
$chmfile = $file;
$chmfile =~ s/\.hhc$/.chm/i;
$shortfile = ExtractFileName($chmfile);
print HHP "$shortfile\n";
print " added $shortfile\n";
}
if($MERGE_PACKAGES) {
print HHP "packages.chm\n";
print " ---> MERGED PACKAGES.CHM\n";
}
}
close(HHP);
return 1;
}
#####################################################################
# FUNCTION CreateHHC
# RECEIVES Helpfile name, TOC file name (HHC), list of files
# RETURNS 0 | 1
# SETS None
# EXPECTS None
# PURPOSE Creates the HHC (Table of Contents) file for the
# htmlhelp file to be created.
# NOTE This function is used (and abused) for every piece
# of the htmlhelp puzzle, so any change for one thing
# can break something totally unrelated. Be careful.
# This was the result of rapidly changing spex. In
# general, it's used for:
# @ Creating helpfiles from pod/pm
# @ Creating helpfiles from html
# @ Creating helpfiles from chm's and hhc's
# @ Creating child helpfiles from modules
# @ Creating main helpfiles
# @ Creating helpfile for core build
# @ Creating main for core build
# @ Creating package helpfiles for packages build
# @ Creating package main for package build
# @ General Htmlhelp file building other than AS
sub CreateHHC {
my ($helpfile, $tocfile, @files) = @_;
my $file;
my $title;
my $shorttoc;
my $shorthelp;
my $shortfile;
my $backfile;
my @libhhcs;
my @sitehhcs;
my @otherhhcs;
$helpfile =~ s{\\}{/}g;
$tocfile =~ s{\\}{/}g;
$shorttoc = ExtractFileName($tocfile);
$shorthelp = ExtractFileName($helpfile);
print "Creating $shorttoc\n";
unless(open(HHC, ">$tocfile")) {
$! = "Could not write contents file";
return 0;
}
print HHC <<'EOT';
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
<OBJECT type="text/site properties">
<param name="ImageType" value="Folder">
</OBJECT>
<UL>
EOT
foreach $file (grep {/\.html?$/i} @files) {
# don't want default.htm in the toc file
next if $file =~ /default\.html?$/i;
$file =~ s{\\}{/}g;
$title = $file;
$title =~ s{\.html$}{}i;
$title =~ s{.*/(.*)}{$1};
# Section added for packages build
# Note: this is an abuse of regexes but needed for all cases
$title =~ s/^pkg-//i;
# $title =~ s{(.*lib)$}{$1/}i;
$title =~ s{^lib-site-}{lib/site/}i;
$title =~ s{^lib-}{lib/}i;
$title =~ s{^site}{site/}i;
$title =~ s{^site-}{site/}i;
# $title =~ s{([^2])-([^x])}{${1}::${2}}ig;
$title =~ s{Win32-(?!x86)}{Win32::}ig;
#$backfile = BackSlash($file);
$shortfile = ExtractFileName($backfile);
print " adding ${shorthelp}::/${shortfile}\n";
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
<param name="Local" value="${shorthelp}::/${shortfile}">
</OBJECT>
EOT
}
foreach $file (sort(grep {/\.hhc$/i} @files)) {
if($file =~ /^lib-site-/i) {
push(@sitehhcs, $file);
} elsif($file =~ /lib-site\.hhc/i) {
unshift(@sitehhcs, $file);
} elsif($file =~ /^lib-/i) {
push(@libhhcs, $file);
} elsif($file =~ /lib\.hhc/i) {
unshift(@libhhcs, $file);
} else {
push(@otherhhcs, $file);
}
}
#
# The Lib merge files
#
if(@libhhcs) {
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Core Libraries">
</OBJECT>
<UL>
EOT
foreach $file (@libhhcs) {
$file =~ s{\\}{/}g;
next if uc($shorttoc) eq uc($file);
# Note: this is an abuse of regexes but needed for all cases
$title = $file;
$title =~ s{^pkg-}{}i;
$title =~ s{\.hhc$}{}i;
$title =~ s{(.*lib)$}{$1/}i;
$title =~ s{^lib-site-}{lib/site/}i;
$title =~ s{^lib-}{lib/}i;
$title =~ s{^site}{site/}i;
$title =~ s{^site-}{site/}i;
# $title =~ s{([^2])-([^x])}{${1}::${2}}ig;
$title =~ s{Win32-(?!x86)}{Win32::}ig;
if ($title =~ m{^lib/$}i) { $title = "Main Libraries" }
$title =~ s{^lib/}{}i;
# $backfile = BackSlash($file);
$shortfile = ExtractFileName($backfile);
print " merging ${shortfile}\n";
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="${shortfile}">
</OBJECT>
EOT
}
print HHC "</UL>\n";
}
#
# The site merge files
#
if(@sitehhcs) {
print HHC <<'EOT';
<!--Beginning of site libraries-->
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Site Libraries">
</OBJECT>
<UL>
EOT
foreach $file (@sitehhcs) {
$file =~ s{\\}{/}g;
next if uc($shorttoc) eq uc($file);
# Note: this is an abuse of regexes but needed for all cases
$title = $file;
$title =~ s{^pkg-}{}i;
$title =~ s{\.hhc$}{}i;
$title =~ s{(.*lib)$}{$1/}i;
$title =~ s{^lib-site-}{lib/site/}i;
$title =~ s{^lib-}{lib/}i;
$title =~ s{^site}{site/}i;
$title =~ s{^site-}{site/}i;
# $title =~ s{([^2])-([^x])}{${1}::${2}}ig;
$title =~ s{Win32-(?!x86)}{Win32::}ig;
if ($title =~ m{^lib/site$}i) { $title = "Main Libraries" }
$title =~ s{^lib/site/}{}i;
# $backfile = BackSlash($file);
$shortfile = ExtractFileName($backfile);
print " merging ${shortfile}\n";
print HHC <<EOT
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="${shortfile}">
</OBJECT>
EOT
}
print HHC "</UL>\n";
#
# quick fix: plop in the packages file
#
if($MERGE_PACKAGES) {
print HHC <<EOT;
<OBJECT type="text/sitemap">
<param name="Merge" value="packages.hhc">
</OBJECT>
EOT
}
print HHC "<!--End of site libraries-->\n";
}
#
# All the rest of the merge files
#
if(@otherhhcs) {
foreach $file (@otherhhcs) {
$file =~ s{\\}{/}g;
next if uc($shorttoc) eq uc($file);
# Note: this is an abuse of regexes but needed for all cases
$title = $file;
$title =~ s{^pkg-}{}i;
$title =~ s{\.hhc$}{}i;
$title =~ s{(.*lib)$}{$1/}i;
$title =~ s{^lib-site-}{lib/site/}i;
$title =~ s{^lib-}{lib/}i;
$title =~ s{^site}{site/}i;
$title =~ s{^site-}{site/}i;
# $title =~ s{([^2])-([^x])}{${1}::${2}}ig;
$title =~ s{Win32-(?!x86)}{Win32::}ig;
# $backfile = BackSlash($file);
$shortfile = ExtractFileName($backfile);
print " merging ${shortfile}\n";
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="${shortfile}">
</OBJECT>
EOT
}
}
# Close up shop and go home
print HHC "</UL>\n";
print HHC "</BODY></HTML>\n";
close(HHC);
1;
}
#####################################################################
# FUNCTION CreateHHCFromHash
# RECEIVES Helpfile, HHC filename, and assoc array of files
# where keys are files and values are file titles
# RETURNS 1|0
# SETS None
# EXPECTS None
# PURPOSE Same as CreateHHC but allows for direct control over
# the file titles
sub CreateHHCFromHash {
my ($helpfile, $tocfile, %files) = @_;
my $file;
my $title;
my $shorttoc;
my $shorthelp;
my $backfile;
$shorttoc = $tocfile;
$shorttoc =~ s{.*/(.*)}{$1};
$shorthelp = $helpfile;
$shorthelp =~ s{.*/(.*)}{$1};
print "Creating $shorttoc\n";
unless(open(HHC, ">$tocfile")) {
$! = "Could not write contents file";
return 0;
}
print HHC <<'EOT';
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
<OBJECT type="text/site properties">
<param name="ImageType" value="Folder">
</OBJECT>
<UL>
EOT
while (($file,$title) = each %files) {
next unless $file =~ /\.html?/i;
# $backfile = BackSlash($file);
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
<param name="Local" value="$backfile">
</OBJECT>
EOT
}
while (($file,$title) = each %files) {
next if uc($shorttoc) eq uc($file);
next unless $file =~ /\.hhc/i;
# $backfile = BackSlash($file);
print HHC <<EOT;
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="$title">
</OBJECT>
<OBJECT type="text/sitemap">
<param name="Merge" value="$backfile">
</OBJECT>
EOT
}
print HHC "</UL>\n";
print HHC "</BODY></HTML>\n";
close(HHC);
1;
}
#####################################################################
# DO NOT REMOVE THE FOLLOWING LINE, IT IS NEEDED TO LOAD THIS LIBRARY
1;