<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">###############################################################################
#
#   Package: NaturalDocs::Builder
#
###############################################################################
#
#   A package that takes parsed source file and builds the output for it.
#
#   Usage and Dependencies:
#
#       - &lt;Add()&gt; can be called immediately.
#       - &lt;OutputPackages()&gt; and &lt;OutputPackageOf()&gt; can be called once all sub-packages have been registered via &lt;Add()&gt;.
#         Since this is normally done in their INIT functions, they should be available to all normal functions immediately.
#
#       - Prior to calling &lt;Run()&gt;, &lt;NaturalDocs::Settings&gt;, &lt;NaturalDocs::Project&gt;, &lt;NaturalDocs::Menu&gt;, and
#         &lt;NaturalDocs::Parser&gt; must be initialized.  &lt;NaturalDocs::Settings-&gt;GenerateDirectoryNames()&gt; must be called.
#         &lt;NaturalDocs::SymbolTable&gt; and &lt;NaturalDocs::ClassHierarchy&gt; must be initialized and fully resolved.
#
###############################################################################

# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
# Natural Docs is licensed under the GPL


use strict;
use integer;

use NaturalDocs::Builder::Base;
use NaturalDocs::Builder::HTML;
use NaturalDocs::Builder::FramedHTML;

package NaturalDocs::Builder;


###############################################################################
# Group: Variables

#
#   Array: outputPackages
#
#   An array of the output packages available for use.
#
my @outputPackages;


###############################################################################
# Group: Functions


#
#   Function: OutputPackages
#
#   Returns an arrayref of the output packages available for use.  The arrayref is not a copy of the data, so don't change it.
#
#   Add output packages to this list with the &lt;Add()&gt; function.
#
sub OutputPackages
    {  return \@outputPackages;  };


#
#   Function: OutputPackageOf
#
#   Returns the output package corresponding to the passed command line option, or undef if none.
#
sub OutputPackageOf #(commandLineOption)
    {
    my ($self, $commandLineOption) = @_;

    $commandLineOption = lc($commandLineOption);

    foreach my $package (@outputPackages)
        {
        if (lc($package-&gt;CommandLineOption()) eq $commandLineOption)
            {  return $package;  };
        };

    return undef;
    };



#
#   Function: Add
#
#   Adds an output package to those available for use.  All output packages must call this function in order to be recognized.
#
#   Parameters:
#
#       package - The package name.
#
sub Add #(package)
    {
    my ($self, $package) = @_;

    # Output packages shouldn't register themselves more than once, so we don't need to check for it.
    push @outputPackages, $package;
    };


#
#   Function: Run
#
#   Runs the build process.  This must be called *every time* Natural Docs is run, regardless of whether any source files changed
#   or not.  Some output packages have dependencies on files outside of the source tree that need to be checked.
#
#   Since there are multiple stages to the build process, this function will handle its own status messages.  There's no need to print
#   "Building files..." or something similar beforehand.
#
sub Run
    {
    my ($self) = @_;


    # Determine what we're doing.

    my $buildTargets = NaturalDocs::Settings-&gt;BuildTargets();

    my $filesToBuild = NaturalDocs::Project-&gt;FilesToBuild();
    my $numberOfFilesToBuild = (scalar keys %$filesToBuild) * (scalar @$buildTargets);

    my $filesToPurge = NaturalDocs::Project-&gt;FilesToPurge();
    my $numberOfFilesToPurge = (scalar keys %$filesToPurge) * (scalar @$buildTargets);

    my $imagesToUpdate = NaturalDocs::Project-&gt;ImageFilesToUpdate();
    my $numberOfImagesToUpdate = (scalar keys %$imagesToUpdate) * (scalar @$buildTargets);

    my $imagesToPurge = NaturalDocs::Project-&gt;ImageFilesToPurge();
    my $numberOfImagesToPurge = (scalar keys %$imagesToPurge) * (scalar @$buildTargets);

    my %indexesToBuild;
    my %indexesToPurge;

    my $currentIndexes = NaturalDocs::Menu-&gt;Indexes();
    my $previousIndexes = NaturalDocs::Menu-&gt;PreviousIndexes();

    foreach my $index (keys %$currentIndexes)
        {
        if (NaturalDocs::SymbolTable-&gt;IndexChanged($index) || !exists $previousIndexes-&gt;{$index})
            {
            $indexesToBuild{$index} = 1;
            };
        };

    # All indexes that still exist should have been deleted.
    foreach my $index (keys %$previousIndexes)
        {
        if (!exists $currentIndexes-&gt;{$index})
            {
            $indexesToPurge{$index} = 1;
            };
        };

    my $numberOfIndexesToBuild = (scalar keys %indexesToBuild) * (scalar @$buildTargets);
    my $numberOfIndexesToPurge = (scalar keys %indexesToPurge) * (scalar @$buildTargets);


    # Start the build process

    foreach my $buildTarget (@$buildTargets)
        {
        $buildTarget-&gt;Builder()-&gt;BeginBuild( $numberOfFilesToBuild || $numberOfFilesToPurge ||
                                                               $numberOfImagesToUpdate || $numberOfImagesToPurge ||
                                                               $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
                                                               NaturalDocs::Menu-&gt;HasChanged() );
        };

    if ($numberOfFilesToPurge)
        {
        NaturalDocs::StatusMessage-&gt;Start('Purging ' . $numberOfFilesToPurge
                                                          . ' file' . ($numberOfFilesToPurge &gt; 1 ? 's' : '') . '...',
                                                             scalar @$buildTargets);

        foreach my $buildTarget (@$buildTargets)
            {
            $buildTarget-&gt;Builder()-&gt;PurgeFiles($filesToPurge);
            NaturalDocs::StatusMessage-&gt;CompletedItem();
            };
        };

    if ($numberOfIndexesToPurge)
        {
        NaturalDocs::StatusMessage-&gt;Start('Purging ' . $numberOfIndexesToPurge
                                                           . ' index' . ($numberOfIndexesToPurge &gt; 1 ? 'es' : '') . '...',
                                                             scalar @$buildTargets);

        foreach my $buildTarget (@$buildTargets)
            {
            $buildTarget-&gt;Builder()-&gt;PurgeIndexes(\%indexesToPurge);
            NaturalDocs::StatusMessage-&gt;CompletedItem();
            };
        };

    if ($numberOfImagesToPurge)
        {
        NaturalDocs::StatusMessage-&gt;Start('Purging ' . $numberOfImagesToPurge
                                                          . ' image' . ($numberOfImagesToPurge &gt; 1 ? 's' : '') . '...',
                                                             scalar @$buildTargets);

        foreach my $buildTarget (@$buildTargets)
            {
            $buildTarget-&gt;Builder()-&gt;PurgeImages($imagesToPurge);
            NaturalDocs::StatusMessage-&gt;CompletedItem();
            };
        };

    if ($numberOfFilesToBuild)
        {
        NaturalDocs::StatusMessage-&gt;Start('Building ' . $numberOfFilesToBuild
                                                           . ' file' . ($numberOfFilesToBuild &gt; 1 ? 's' : '') . '...',
                                                             $numberOfFilesToBuild);

        foreach my $file (keys %$filesToBuild)
            {
            my $parsedFile = NaturalDocs::Parser-&gt;ParseForBuild($file);

            NaturalDocs::Error-&gt;OnStartBuilding($file);

            foreach my $buildTarget (@$buildTargets)
                {
                $buildTarget-&gt;Builder()-&gt;BuildFile($file, $parsedFile);
                NaturalDocs::StatusMessage-&gt;CompletedItem();
                };

            NaturalDocs::Error-&gt;OnEndBuilding($file);
            };
        };

    if ($numberOfIndexesToBuild)
        {
        NaturalDocs::StatusMessage-&gt;Start('Building ' . $numberOfIndexesToBuild
                                                          . ' index' . ($numberOfIndexesToBuild &gt; 1 ? 'es' : '') . '...',
                                                             $numberOfIndexesToBuild);

        foreach my $index (keys %indexesToBuild)
            {
            foreach my $buildTarget (@$buildTargets)
                {
                $buildTarget-&gt;Builder()-&gt;BuildIndex($index);
                NaturalDocs::StatusMessage-&gt;CompletedItem();
                };
            };
        };

    if ($numberOfImagesToUpdate)
        {
        NaturalDocs::StatusMessage-&gt;Start('Updating ' . $numberOfImagesToUpdate
                                                          . ' image' . ($numberOfImagesToUpdate &gt; 1 ? 's' : '') . '...',
                                                             $numberOfImagesToUpdate);

        foreach my $image (keys %$imagesToUpdate)
            {
            foreach my $buildTarget (@$buildTargets)
                {
                $buildTarget-&gt;Builder()-&gt;UpdateImage($image);
                NaturalDocs::StatusMessage-&gt;CompletedItem();
                };
            };
        };

    if (NaturalDocs::Menu-&gt;HasChanged())
        {
        if (!NaturalDocs::Settings-&gt;IsQuiet())
            {  print "Updating menu...\n";  };

        foreach my $buildTarget (@$buildTargets)
            {  $buildTarget-&gt;Builder()-&gt;UpdateMenu();  };
        };

    foreach my $buildTarget (@$buildTargets)
        {
        $buildTarget-&gt;Builder()-&gt;EndBuild($numberOfFilesToBuild || $numberOfFilesToPurge ||
                                                           $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
                                                           $numberOfImagesToUpdate || $numberOfImagesToPurge ||
                                                           NaturalDocs::Menu-&gt;HasChanged());
        };
    };


1;
</pre></body></html>